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 @@
[submodule "src/components/mosys"]
path = src/components/mosys
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
### 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
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
......@@ -38,7 +43,8 @@ For the available variables see `quasar.conf.js`.
## 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
npm run dev
......@@ -46,10 +52,24 @@ npm run dev
### 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
[![](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
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/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
The format is based on
[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]
### Added
- Metadata store module now caches responses from the transcoder service until app reload
- 'Documents' source tab now available in MoSys (so far only shows images)
- Docker image already builds with the nginx SPA config
- 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
### Changed
- Renamed 'Assets' to 'Documents' in screens and navigation, Auth0 feature now also needs to be 'documents'
- Moved delete map functionality to [mbjs-quasar](https://gitlab.rlp.net/motionbank/mbjs/quasar) module
- Moved ACL functionality to [mbjs-quasar](https://gitlab.rlp.net/motionbank/mbjs/quasar) module
- Updated
[mbjs-api-client](https://gitlab.rlp.net/motionbank/mbjs/api-client)
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
- Deep links into post-annotator now no longer fail when 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))
- Deep links into post-annotator no longer fail when
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
### Fixed
- Post-annotator timestamps now display correct values, independent of timezone or DST
- 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
- Post-annotator timestamps display correct values,
independent of timezone or DST
- 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
### Added
- Post annotator now accepts annotation UUIDs as a hash value and automatically jumps there on load
- Property 'originalTitle' (if title is overridden) 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
- Post annotator accepts annotation UUIDs as a hash
value and automatically jumps there on load
- Property 'originalTitle' (if title is overridden)
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
- 'Assets' feature allows uploading of files to 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
- 'Assets' feature allows uploading of files to
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
- Automatic scrolling to annotations when video player plays in post annotator
- Video titles are no longer removed when saving video with same title as before
- Parameter 'feature' can now be added to route metadata to allow access control through Auth0 app metadata
- 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))
- Automatic scrolling to annotations when video
player plays in post annotator
- Video titles are no longer removed when saving
video with same title as before
- Parameter 'feature' can be added to route metadata
to allow access control through Auth0 app metadata
- 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
- userHasFeature moved to [mbjs-quasar](https://gitlab.rlp.net/motionbank/mbjs/quasar) module
- "More Info" button on welcome page now links to medium article
- MoSys components now included through git submodule from [quasar-components-mosys](https://gitlab.rlp.net/motionbank/mbjs/quasar-components-mosys)
- Shared components now included through git submodule from [quasar-components-shared](https://gitlab.rlp.net/motionbank/mbjs/quasar-components-shared)
- userHasFeature moved to
[mbjs-quasar](https://gitlab.rlp.net/motionbank/mbjs/quasar)
- "More Info" button on welcome page now links to
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
- [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
### 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
### 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
- Data tables now use an optional requestTransform function to process rows on each data update
- Info button in the post-annotator shows video metadata (so far only title)
- Hyperlinks in annotations are now clickable in the post-annotator
- Limited markdown support for annotations (allowed tags: 'b', 'i', 'em', 'strong', 'a', 'br', 'p')
- Videos can now be tagged
- Vuex module 'tags' - stores and retrieves tags as annotations
- Data tables use an optional requestTransform function
to process rows on each data update
- Info button in the post-annotator shows video metadata
(so far only title)
- Hyperlinks in annotations are clickable in the
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
- 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
- Users need to explicitly click 'edit' to change an annotation in the post-annotator
- External titles stored as annotations are now retrieved within the metadata store module
- BrowserWarning and MarkdownDisplay components moved to [mbjs-quasar](https://gitlab.rlp.net/motionbank/mbjs/quasar)
- Users need to explicitly click 'edit' to change
an annotation in the post-annotator
- 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
- Pinned and updated runtime dependencies
### 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
- Tables are now properly searchable
- Timeline list now updates after deleting an item
- Tables are properly searchable
- Timeline list updates after deleting an item
### Removed
......
......@@ -4,4 +4,5 @@ MAINTAINER Motion Bank
RUN ln -sf /dev/stdout /var/log/nginx/access.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/
This diff is collapsed.
......@@ -39,14 +39,14 @@
"he": "1.2.0",
"luxon": "1.8.2",
"marked": "0.5.2",
"mbjs-api-client": "1.1.0",
"mbjs-api-client": "2.0.0",
"mbjs-data-models": "0.0.12",
"mbjs-media": "0.0.19",
"mbjs-quasar": "1.3.0",
"mbjs-quasar": "1.4.3",
"mbjs-utils": "0.0.6",
"raven-js": "3.27.0",
"sanitize-html": "1.19.2",
"sift": "5.1.0",
"sift": "^7.0.1",
"tiny-emitter": "2.0.2",
"uuid-validate": "0.0.2",
"videojs-framebyframe": "git+https://github.com/fjenett/videojs-framebyframe.git#fa81d657c50067bb5af07c9cf5e42924b353a70e",
......
......@@ -81,12 +81,14 @@
}
},
async mounted () {
this.$q.loading.show()
this.grid = await this.$store.dispatch('maps/get', this.$route.params.id)
if (process.env.IS_STAGING) {
const aclQuery = {role: 'public', id: this.grid.id, permission: 'get'}
const permissions = await this.$store.dispatch('acl/isRoleAllowed', aclQuery)
this.acl.public = permissions.get === true
}
this.$q.loading.hide()
},
computed: {
...mapGetters({
......@@ -129,7 +131,9 @@
this.$q.loading.hide()
},
async updateACL () {
this.$q.loading.show()
await aclHelper.updateACL(this, this.acl, this.grid)
this.$q.loading.hide()
}
}
}
......
......@@ -83,12 +83,14 @@
}
},
async mounted () {
this.$q.loading.show()
this.timeline = await this.$store.dispatch('maps/get', this.$route.params.id)
if (process.env.IS_STAGING) {
const aclQuery = {role: 'public', id: this.timeline.id, permission: 'get'}
const permissions = await this.$store.dispatch('acl/isRoleAllowed', aclQuery)
this.acl.public = permissions.get === true
}
this.$q.loading.hide()
},
computed: {
...mapGetters({
......@@ -128,7 +130,9 @@
this.$q.loading.hide()
},
async updateACL () {
this.$q.loading.show()
await aclHelper.updateACL(this, this.acl, this.timeline)
this.$q.loading.hide()
}
}
}
......
......@@ -104,8 +104,10 @@
},
async mounted () {
if (this.$route.params.id) {
this.$q.loading.show()
await this.getVideo()
await this.getAnnotations()
this.$q.loading.hide()
}
},
beforeDestroy () {
......
......@@ -74,6 +74,7 @@
}
},
async mounted () {
this.$q.loading.show()
this.schema.fields.tags.autocompleteOptions = await this.$store.dispatch('tags/list')
const timelinesResult = await this.$store.dispatch('maps/find', {
type: 'Timeline'
......@@ -84,6 +85,7 @@
label: item.title
}
}).sort((a, b) => (a.label || '').localeCompare(b.label || ''))
this.$q.loading.hide()
},
data () {
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 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 {
Annotation,
Map,
Document
} 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({
auth: {
domain: process.env.AUTH0_DOMAIN,
......@@ -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({
modules: {
acl,
conversions,
notifications,
forms,
timecodes,
mosysGridEditorStore,
/** Basic resources using API Client */
annotations: makeResourceModule(apiClient, Annotation, 'annotation'),
maps: makeResourceModule(apiClient, Map, 'map'),
documents: makeResourceModule(apiClient, Document, 'document'),
profiles: makeResourceModule(apiClient, undefined, 'profile'),
sessions: makeResourceModule(apiClient, undefined, 'session'),
// metadata: makeResourceModule(apiClient, undefined, 'metadata', 'metadata', process.env.TRANSCODER_HOST),
metadata,
tags,
/** Custom stores */
acl,
auth,
conversions,
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)
/**
* Execute action
*/
if (!Array.isArray(args)) args = [args]
try {
const response = await client[action](
namePlural,
args[0],
args.length > 1 ? args[1] : overrideHost,
args.length > 1 ? overrideHost : undefined)
if (response) {
// if (args.length > 1) context.commit(action, [response.uuid, response])
// else context.commit(action, response)
context.commit('setPending', action, false)
if (Model) {
if (response.items && Array.isArray(response.items)) {
response.items = response.items.map(item => new Model(item))
return response
}
else {
return new Model(response)
}
}
return response
}
else throw new Error(`${action} ${name} failed: empty API response`)
}
catch (err) {
context.commit('setPending', action, false)
throw err
}
}
}
return {
namespaced: true,
state: {
[namePlural]: [],
[idList]: [],
currentItem: undefined,
currentQuery: undefined,
isPending: {
find: false,
get: false,
post: false,
put: false,
patch: false,
delete: false
}
},
mutations: {
find: (state, data) => {
state[namePlural] = data.items
},
get: (state, data) => {
state.currentItem = data
},
post: (state, data) => {
state[namePlural].push(data)
},
put: (state, args) => {
let [id, data] = args
data.uuid = id
const index = state[idList].indexOf(id)
if (index > -1) {
state[namePlural][index] = data
}
else throw new Error(`Update ${name} failed: not found`)
},
patch: (state, args) => {
let [id, data] = args
data.uuid = id
// const index = state[idList].indexOf(id)
// TODO: fix the vuex caching
// if (index > -1) state[namePlural][index] = ObjectUtil.merge(state[namePlural][index], data)
// else throw new Error(`Update ${name} failed: not found`)
},
delete: (state, id) => {
console.debug('stub delete', id)
},
setPending: (state, action, status = true) => {
Assert.isType(status, 'boolean', 'setPending: status must be boolean')
state.isPending[action] = status
}
},
actions: {
find: makeResourceAction('find'),
get: makeResourceAction('get'),
post: makeResourceAction('post'),
put: makeResourceAction('put'),
patch: makeResourceAction('patch'),
delete: makeResourceAction('delete')
}
}
}
export default makeResourceModule
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment