Commit bfa3c479 authored by Anton Koch's avatar Anton Koch

Add caching for generic resource store modules

parent ba9b1188
Subproject commit 9363655fb12f0c7b062380a1331e440ec81f0497
...@@ -4,3 +4,6 @@ ...@@ -4,3 +4,6 @@
[submodule "src/components/mosys"] [submodule "src/components/mosys"]
path = src/components/mosys path = src/components/mosys
url = git@gitlab.rlp.net:motionbank/mbjs/quasar-components-mosys.git url = git@gitlab.rlp.net:motionbank/mbjs/quasar-components-mosys.git
[submodule ".docker-lib"]
path = .docker-lib
url = git@gitlab.rlp.net:motionbank/tools/docker-lib.git
...@@ -12,11 +12,16 @@ npm install ...@@ -12,11 +12,16 @@ npm install
### Third-party webserver (recommended) ### Third-party webserver (recommended)
Point your webserver config to the ``dist/spa-mat`` directory. Configure your webserver to serve ``index.html`` with a 200 status code instead of a 404 error page. Point your webserver config to the ``dist/spa-mat``
directory. Configure your webserver to serve
``index.html`` with a 200 status code instead of a
404 error page.
### Standalone server ### Standalone server
Execute ``npm start`` to start the built-in webserver. Control server address through ``HOST`` and ``PORT`` env variables. Execute ``npm start`` to start the built-in webserver.
Control server address through ``HOST`` and ``PORT``
env variables.
## Build ## Build
...@@ -38,7 +43,8 @@ For the available variables see `quasar.conf.js`. ...@@ -38,7 +43,8 @@ For the available variables see `quasar.conf.js`.
## Development ## Development
Start a development server with automatic reload on localhost at port 8080. Start a development server with automatic reload on
localhost at port 8080.
```shell ```shell
npm run dev npm run dev
...@@ -46,10 +52,24 @@ npm run dev ...@@ -46,10 +52,24 @@ npm run dev
### Changelog ### Changelog
Development is tracked in [CHANGELOG.md](https://gitlab.rlp.net/motionbank/systems-frontend/blob/master/CHANGELOG.md). Development is tracked in
[CHANGELOG.md](https://gitlab.rlp.net/motionbank/systems-frontend/blob/master/CHANGELOG.md).
## Docker ## Docker
[![](https://images.microbadger.com/badges/image/motionbank/systems-frontend.svg)](https://microbadger.com/images/motionbank/systems-frontend "Get your own image badge on microbadger.com") The recommended way of deployment are our prebuilt
docker images.
The docker image can be pulled from `motionbank/systems-frontend:latest` [![](https://images.microbadger.com/badges/image/motionbank/systems-frontend.svg)](https://microbadger.com/images/motionbank/systems-frontend
"Get your own image badge on microbadger.com")
### Versions
* Stable: `motionbank/systems-frontend:release_1_2`
* Staging (beta): `motionbank/systems-frontend:staging`
* Experimental: `motionbank/systems-frontend:experimental`
### Configuration
The image is not configurable.
The application listens on port `3030`.
# Changelog # Changelog
This document tracks all important changes to the Motion Bank Systems Frontend. This document tracks all important changes to the Motion
Bank Systems Frontend.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased] ## [Unreleased]
### Added ### Added
- Metadata store module now caches responses from the transcoder service until app reload - Docker image already builds with the nginx SPA config
- 'Documents' source tab now available in MoSys (so far only shows images) - The generic Vuex modules use caching in memory
- Generic vuex resources allow selection of returned
properties through array of strings
- Metadata store module caches responses from the
transcoder service until app reload
- 'Documents' source tab available in MoSys (so far
only shows images)
- Access control menu available for MoSys grids - Access control menu available for MoSys grids
### Changed ### Changed
- Renamed 'Assets' to 'Documents' in screens and navigation, Auth0 feature now also needs to be 'documents' - Updated
- Moved delete map functionality to [mbjs-quasar](https://gitlab.rlp.net/motionbank/mbjs/quasar) module [mbjs-api-client](https://gitlab.rlp.net/motionbank/mbjs/api-client)
- Moved ACL functionality to [mbjs-quasar](https://gitlab.rlp.net/motionbank/mbjs/quasar) module to version 2.0.0
- Renamed 'Assets' to 'Documents' in screens and
navigation, Auth0 feature now also needs to be 'documents'
- Updated
[mbjs-quasar](https://gitlab.rlp.net/motionbank/mbjs/quasar)
to version 1.4.3
- Moved ACL functionality to
[mbjs-quasar](https://gitlab.rlp.net/motionbank/mbjs/quasar)
module
### Fixed ### Fixed
- Deep links into post-annotator now no longer fail when lots of annotations need to be loaded - Deep links into post-annotator no longer fail when
- Delete map no longer fails when encountering access denied errors (still suffers from [#119](https://gitlab.rlp.net/motionbank/systems-frontend/issues/119)) lots of annotations need to be loaded
- Delete map no longer fails when encountering access
denied errors (still suffers from
[#119](https://gitlab.rlp.net/motionbank/systems-frontend/issues/119))
## [1.2.1] - 2019-02-15 ## [1.2.1] - 2019-02-15
### Fixed ### Fixed
- Post-annotator timestamps now display correct values, independent of timezone or DST - Post-annotator timestamps display correct values,
- currentIndex property no longer throws when attempting to scroll to invalid annotation index independent of timezone or DST
- Timestamps in post-annotator are no longer being cut off, display hours as well - currentIndex property no longer throws when attempting
to scroll to invalid annotation index
- Timestamps in post-annotator are no longer being cut
off, display hours as well
## [1.2.0] - 2019-02-14 ## [1.2.0] - 2019-02-14
### Added ### Added
- Post annotator now accepts annotation UUIDs as a hash value and automatically jumps there on load - Post annotator accepts annotation UUIDs as a hash
- Property 'originalTitle' (if title is overridden) added to result in metadata store value and automatically jumps there on load
- Very basic search page for timelines added, accessible only with 'search' feature permission - Property 'originalTitle' (if title is overridden)
- API client (and its associated resources' "find" actions) now accept regular expressions added to result in metadata store
- Very basic search page for timelines added,
accessible only with 'search' feature permission
- API client (and its associated resources' "find"
actions) now accept regular expressions
- Resource 'documents' available in the store - Resource 'documents' available in the store
- 'Assets' feature allows uploading of files to personal S3 compatible bucket - 'Assets' feature allows uploading of files to
- 'Packager' feature allows export of MoSys grids as static packages to be hosted in any webspace, without the need of Motion Bank APIs personal S3 compatible bucket
- 'Packager' feature allows export of MoSys grids
as static packages to be hosted in any webspace,
without the need of Motion Bank APIs
### Fixed ### Fixed
- Automatic scrolling to annotations when video player plays in post annotator - Automatic scrolling to annotations when video
- Video titles are no longer removed when saving video with same title as before player plays in post annotator
- Parameter 'feature' can now be added to route metadata to allow access control through Auth0 app metadata - Video titles are no longer removed when saving
- Exception when passing an id (URI) to ACL store instead of a UUID video with same title as before
- Incompatibilities in MoSys cells (Video, AnnotationList) - Parameter 'feature' can be added to route metadata
- App startup no longer breaks on Microsoft Edge (works from version 15+) to allow access control through Auth0 app metadata
- Perform date related queries to MongoDB with properly formatted timezones (see: [#106](https://gitlab.rlp.net/motionbank/systems-frontend/issues/106)) - Exception when passing an id (URI) to ACL store
instead of a UUID
- Incompatibilities in MoSys cells (Video,
AnnotationList)
- App startup no longer breaks on Microsoft Edge
(works from version 15+)
- Perform date related queries to MongoDB with
properly formatted timezones (see:
[#106](https://gitlab.rlp.net/motionbank/systems-frontend/issues/106))
### Changed ### Changed
- userHasFeature moved to [mbjs-quasar](https://gitlab.rlp.net/motionbank/mbjs/quasar) module - userHasFeature moved to
- "More Info" button on welcome page now links to medium article [mbjs-quasar](https://gitlab.rlp.net/motionbank/mbjs/quasar)
- MoSys components now included through git submodule from [quasar-components-mosys](https://gitlab.rlp.net/motionbank/mbjs/quasar-components-mosys) - "More Info" button on welcome page now links to
- Shared components now included through git submodule from [quasar-components-shared](https://gitlab.rlp.net/motionbank/mbjs/quasar-components-shared) medium article
- MoSys components included through git submodule from
[quasar-components-mosys](https://gitlab.rlp.net/motionbank/mbjs/quasar-components-mosys)
- Shared components included through git submodule from
[quasar-components-shared](https://gitlab.rlp.net/motionbank/mbjs/quasar-components-shared)
### Updated ### Updated
- [mbjs-api-client](https://gitlab.rlp.net/motionbank/mbjs/api-client) now at version 1.1.0 - [mbjs-api-client](https://gitlab.rlp.net/motionbank/mbjs/api-client)
now at version 1.1.0
## [1.1.1] - 2019-01-28 ## [1.1.1] - 2019-01-28
### Fixed ### Fixed
- Recursive setting of ACL for a timeline's associated annotations now traverses the full relational depth. - Recursive setting of ACL for a timeline's associated
annotations now traverses the full relational depth.
## [1.1.0] - 2018-12-11 ## [1.1.0] - 2018-12-11
### Added ### Added
- Edit video screen now allows moving video to another timeline - Edit video screen allows moving video to another timeline
- Video list shows timeline title - Video list shows timeline title
- Data tables now use an optional requestTransform function to process rows on each data update - Data tables use an optional requestTransform function
- Info button in the post-annotator shows video metadata (so far only title) to process rows on each data update
- Hyperlinks in annotations are now clickable in the post-annotator - Info button in the post-annotator shows video metadata
- Limited markdown support for annotations (allowed tags: 'b', 'i', 'em', 'strong', 'a', 'br', 'p') (so far only title)
- Videos can now be tagged - Hyperlinks in annotations are clickable in the
- Vuex module 'tags' - stores and retrieves tags as annotations post-annotator
- Limited markdown support for annotations
(allowed tags: 'b', 'i', 'em', 'strong', 'a', 'br', 'p')
- Videos can be tagged
- Vuex module 'tags' - stores and retrieves tags as
annotations
### Changed ### Changed
- Video list is now sorted descending on reference date by default - Video list is sorted descending on reference
date by default
- Look of top right buttons in post-annotator - Look of top right buttons in post-annotator
- Users need to explicitly click 'edit' to change an annotation in the post-annotator - Users need to explicitly click 'edit' to change
- External titles stored as annotations are now retrieved within the metadata store module an annotation in the post-annotator
- BrowserWarning and MarkdownDisplay components moved to [mbjs-quasar](https://gitlab.rlp.net/motionbank/mbjs/quasar) - External titles stored as annotations are retrieved
within the metadata store module
- BrowserWarning and MarkdownDisplay components moved to
[mbjs-quasar](https://gitlab.rlp.net/motionbank/mbjs/quasar)
- Readme info - Readme info
- Pinned and updated runtime dependencies - Pinned and updated runtime dependencies
### Fixed ### Fixed
- Post-annotation no longer fails when the duration of a video cannot be retrieved - Post-annotation no longer fails when the duration
of a video cannot be retrieved
- Editing external title annotations - Editing external title annotations
- Tables are now properly searchable - Tables are properly searchable
- Timeline list now updates after deleting an item - Timeline list updates after deleting an item
### Removed ### Removed
......
...@@ -4,4 +4,5 @@ MAINTAINER Motion Bank ...@@ -4,4 +4,5 @@ MAINTAINER Motion Bank
RUN ln -sf /dev/stdout /var/log/nginx/access.log && \ RUN ln -sf /dev/stdout /var/log/nginx/access.log && \
ln -sf /dev/stderr /var/log/nginx/error.log ln -sf /dev/stderr /var/log/nginx/error.log
ADD ./.docker-lib/configs/nginx/quasar-spa.conf /etc/nginx/conf.d/default.conf
ADD ./dist/spa-mat /usr/html/ ADD ./dist/spa-mat /usr/html/
This diff is collapsed.
...@@ -39,14 +39,14 @@ ...@@ -39,14 +39,14 @@
"he": "1.2.0", "he": "1.2.0",
"luxon": "1.8.2", "luxon": "1.8.2",
"marked": "0.5.2", "marked": "0.5.2",
"mbjs-api-client": "1.1.0", "mbjs-api-client": "2.0.0",
"mbjs-data-models": "0.0.12", "mbjs-data-models": "0.0.12",
"mbjs-media": "0.0.19", "mbjs-media": "0.0.19",
"mbjs-quasar": "1.3.0", "mbjs-quasar": "1.4.3",
"mbjs-utils": "0.0.6", "mbjs-utils": "0.0.6",
"raven-js": "3.27.0", "raven-js": "3.27.0",
"sanitize-html": "1.19.2", "sanitize-html": "1.19.2",
"sift": "5.1.0", "sift": "^7.0.1",
"tiny-emitter": "2.0.2", "tiny-emitter": "2.0.2",
"uuid-validate": "0.0.2", "uuid-validate": "0.0.2",
"videojs-framebyframe": "git+https://github.com/fjenett/videojs-framebyframe.git#fa81d657c50067bb5af07c9cf5e42924b353a70e", "videojs-framebyframe": "git+https://github.com/fjenett/videojs-framebyframe.git#fa81d657c50067bb5af07c9cf5e42924b353a70e",
......
...@@ -81,12 +81,14 @@ ...@@ -81,12 +81,14 @@
} }
}, },
async mounted () { async mounted () {
this.$q.loading.show()
this.grid = await this.$store.dispatch('maps/get', this.$route.params.id) this.grid = await this.$store.dispatch('maps/get', this.$route.params.id)
if (process.env.IS_STAGING) { if (process.env.IS_STAGING) {
const aclQuery = {role: 'public', id: this.grid.id, permission: 'get'} const aclQuery = {role: 'public', id: this.grid.id, permission: 'get'}
const permissions = await this.$store.dispatch('acl/isRoleAllowed', aclQuery) const permissions = await this.$store.dispatch('acl/isRoleAllowed', aclQuery)
this.acl.public = permissions.get === true this.acl.public = permissions.get === true
} }
this.$q.loading.hide()
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
...@@ -129,7 +131,9 @@ ...@@ -129,7 +131,9 @@
this.$q.loading.hide() this.$q.loading.hide()
}, },
async updateACL () { async updateACL () {
this.$q.loading.show()
await aclHelper.updateACL(this, this.acl, this.grid) await aclHelper.updateACL(this, this.acl, this.grid)
this.$q.loading.hide()
} }
} }
} }
......
...@@ -83,12 +83,14 @@ ...@@ -83,12 +83,14 @@
} }
}, },
async mounted () { async mounted () {
this.$q.loading.show()
this.timeline = await this.$store.dispatch('maps/get', this.$route.params.id) this.timeline = await this.$store.dispatch('maps/get', this.$route.params.id)
if (process.env.IS_STAGING) { if (process.env.IS_STAGING) {
const aclQuery = {role: 'public', id: this.timeline.id, permission: 'get'} const aclQuery = {role: 'public', id: this.timeline.id, permission: 'get'}
const permissions = await this.$store.dispatch('acl/isRoleAllowed', aclQuery) const permissions = await this.$store.dispatch('acl/isRoleAllowed', aclQuery)
this.acl.public = permissions.get === true this.acl.public = permissions.get === true
} }
this.$q.loading.hide()
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
...@@ -128,7 +130,9 @@ ...@@ -128,7 +130,9 @@
this.$q.loading.hide() this.$q.loading.hide()
}, },
async updateACL () { async updateACL () {
this.$q.loading.show()
await aclHelper.updateACL(this, this.acl, this.timeline) await aclHelper.updateACL(this, this.acl, this.timeline)
this.$q.loading.hide()
} }
} }
} }
......
...@@ -104,8 +104,10 @@ ...@@ -104,8 +104,10 @@
}, },
async mounted () { async mounted () {
if (this.$route.params.id) { if (this.$route.params.id) {
this.$q.loading.show()
await this.getVideo() await this.getVideo()
await this.getAnnotations() await this.getAnnotations()
this.$q.loading.hide()
} }
}, },
beforeDestroy () { beforeDestroy () {
......
...@@ -74,6 +74,7 @@ ...@@ -74,6 +74,7 @@
} }
}, },
async mounted () { async mounted () {
this.$q.loading.show()
this.schema.fields.tags.autocompleteOptions = await this.$store.dispatch('tags/list') this.schema.fields.tags.autocompleteOptions = await this.$store.dispatch('tags/list')
const timelinesResult = await this.$store.dispatch('maps/find', { const timelinesResult = await this.$store.dispatch('maps/find', {
type: 'Timeline' type: 'Timeline'
...@@ -84,6 +85,7 @@ ...@@ -84,6 +85,7 @@
label: item.title label: item.title
} }
}).sort((a, b) => (a.label || '').localeCompare(b.label || '')) }).sort((a, b) => (a.label || '').localeCompare(b.label || ''))
this.$q.loading.hide()
}, },
data () { data () {
const context = this const context = this
......
import mosysGridEditorStore from './modules/mosys-grid-editor-store'
import notifications from './modules/notifications'
import forms from './modules/forms'
import makeResourceModule from './modules/make-resource-module'
import auth from './modules/auth'
import acl from './modules/acl'
import timecodes from './modules/timecodes'
import conversions from './modules/conversions'
import metadata from './modules/metadata'
import tags from './modules/tags'
import files from './modules/files'
import WebAuth from 'mbjs-api-client/src/web'
import Vue from 'vue' import Vue from 'vue'
import Vuex from 'vuex' import Vuex from 'vuex'
Vue.use(Vuex)
import WebAuth from 'mbjs-api-client/src/web'
import { makeResourceModule } from 'mbjs-quasar/src/lib'
/** Import resource Data Models */
import { import {
Annotation, Annotation,
Map, Map,
Document Document
} from 'mbjs-data-models/src/models' } from 'mbjs-data-models/src/models'
Vue.use(Vuex) /** Import custom modules */
import {
auth,
acl,
conversions,
files,
forms,
tags,
timecodes,
metadata,
mosysGridEditorStore,
notifications
} from './modules'
/** Instantiate Motion Bank API Client */
const apiClient = new WebAuth({ const apiClient = new WebAuth({
auth: { auth: {
domain: process.env.AUTH0_DOMAIN, domain: process.env.AUTH0_DOMAIN,
...@@ -35,26 +41,28 @@ const apiClient = new WebAuth({ ...@@ -35,26 +41,28 @@ const apiClient = new WebAuth({
}) })
/** /**
* Set up VueX store with API service backends * Set up VueX store
*/ */
const store = new Vuex.Store({ const store = new Vuex.Store({
modules: { modules: {
acl, /** Basic resources using API Client */
conversions,
notifications,
forms,
timecodes,
mosysGridEditorStore,
annotations: makeResourceModule(apiClient, Annotation, 'annotation'), annotations: makeResourceModule(apiClient, Annotation, 'annotation'),
maps: makeResourceModule(apiClient, Map, 'map'), maps: makeResourceModule(apiClient, Map, 'map'),
documents: makeResourceModule(apiClient, Document, 'document'), documents: makeResourceModule(apiClient, Document, 'document'),
profiles: makeResourceModule(apiClient, undefined, 'profile'), profiles: makeResourceModule(apiClient, undefined, 'profile'),
sessions: makeResourceModule(apiClient, undefined, 'session'), sessions: makeResourceModule(apiClient, undefined, 'session'),
// metadata: makeResourceModule(apiClient, undefined, 'metadata', 'metadata', process.env.TRANSCODER_HOST),
metadata, /** Custom stores */
tags, acl,
auth,
conversions,
files, files,
auth forms,
tags,
timecodes,
metadata,
mosysGridEditorStore,
notifications
} }
}) })
......
import mosysGridEditorStore from './mosys-grid-editor-store'
import notifications from './notifications'
import forms from './forms'
import auth from './auth'
import acl from './acl'
import timecodes from './timecodes'
import conversions from './conversions'
import metadata from './metadata'
import tags from './tags'
import files from './files'
export {
auth,
acl,
conversions,
files,
forms,
tags,
timecodes,
metadata,
mosysGridEditorStore,
notifications
}
// const sift = require('sift')
import { Assert } from 'mbjs-utils'
const makeResourceModule = function (client, Model, resourceName, resourceNamePluralised = undefined, overrideHost = undefined) {
const
name = resourceName,
namePlural = resourceNamePluralised || `${name}s`,
idList = `${resourceName}IDs`
const makeResourceAction = (action) => {
return async (context, args) => {
context.commit('setPending', action)