diff --git a/frontend/src/aspects/exploration.ts b/frontend/src/aspects/exploration.ts index c9fd75ba..2b651159 100644 --- a/frontend/src/aspects/exploration.ts +++ b/frontend/src/aspects/exploration.ts @@ -1,7 +1,7 @@ -import { isString } from 'lodash'; +import { partial, isString } from 'lodash'; import channel from '../explorer/radio'; -import executeRoute from '../explorer/route-parser'; +import * as act from '../explorer/route-actions'; import router from '../global/exploration-router'; import mainRouter from '../global/main-router'; import explorer from '../global/explorer-view'; @@ -48,7 +48,25 @@ mainRouter.on('route:explore', () => { ); }); -router.on('route', (route, [serial]) => explorer.scrollOrAction( - browserHistory.state, - () => executeRoute(route, controller, serial) -)); +/** + * Common patterns for the explorer routes. + */ +function deepRoute(obtainAction, resetAction) { + return ([serial]) => explorer.scrollOrAction( + browserHistory.state, + () => resetAction(controller, obtainAction(serial)) + ); +} + +const sourceRoute = partial(deepRoute, act.getSource); +const itemRoute = partial(deepRoute, act.getItem); + +router.on('route:source:bare', sourceRoute(act.sourceWithoutAnnotations)); +router.on('route:source:annotated', sourceRoute(act.sourceWithAnnotations)); +router.on('route:item', itemRoute(act.item)); +router.on('route:item:edit', itemRoute(act.itemInEditMode)); +router.on('route:item:related', itemRoute(act.itemWithRelations)); +router.on('route:item:related:edit', itemRoute(act.itemWithEditRelations)); +router.on('route:item:external', itemRoute(act.itemWithExternal)); +router.on('route:item:external:edit', itemRoute(act.itemWithEditExternal)); +router.on('route:item:annotations', itemRoute(act.itemWithOccurrences)); diff --git a/frontend/src/explorer/route-actions.ts b/frontend/src/explorer/route-actions.ts new file mode 100644 index 00000000..c0df199f --- /dev/null +++ b/frontend/src/explorer/route-actions.ts @@ -0,0 +1,53 @@ +import View from '../core/view'; +import { source, item as itemNs } from '../jsonld/ns'; +import { Namespace } from '../jsonld/vocabulary'; +import ldChannel from '../jsonld/radio'; +import Node from '../jsonld/node'; +import Controller from './explorer-event-controller'; + +function obtainer(namespace: Namespace) { + return function(serial: string) { + return ldChannel.request('obtain', namespace(serial)); + } +} + +export const getSource = obtainer(source); +export const getItem = obtainer(itemNs); + +export function sourceWithoutAnnotations(control: Controller, node: Node) { + return control.resetSource(node, false); +} + +export function sourceWithAnnotations(control: Controller, node: Node) { + return control.resetSourcePair(node); +} + +export function item(control: Controller, node: Node) { + return control.resetItem(node); +} + +export function itemInEditMode(control: Controller, node: Node) { + return control.editAnnotation(item(control, node), node); +} + +export function itemWithRelations(control: Controller, node: Node) { + return control.listRelated(item(control, node), node); +} + +export function itemWithEditRelations(control: Controller, node: Node) { + return control.editRelated(itemWithRelations(control, node), node); +} + +export function itemWithExternal(control: Controller, node: Node) { + return control.listExternal(item(control, node), node); +} + +export function itemWithEditExternal(control: Controller, node: Node) { + return control.editExternal(itemWithExternal(control, node)); +} + +export function itemWithOccurrences(control: Controller, node: Node) { + // listItemAnnotations does not return the created panel + // see #342 + control.listItemAnnotations(item(control, node), node); +} diff --git a/frontend/src/explorer/route-parser.ts b/frontend/src/explorer/route-parser.ts deleted file mode 100644 index 8ff196dc..00000000 --- a/frontend/src/explorer/route-parser.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { each } from 'lodash'; - -import Fsm from '../core/fsm'; -import { source, item } from '../jsonld/ns'; -import ldChannel from '../jsonld/radio'; -import Controller from './explorer-event-controller'; - -const RouteParser = Fsm.extend({ - initialState: 'undecided', - states: { - undecided: { - source: 'source', - item: 'item', - }, - source: { - _onEnter() { - this.source = ldChannel.request('obtain', source(this.serial)); - }, - bare: 'sourceWithoutAnnotations', - annotated: 'sourceWithAnnotations', - }, - sourceWithoutAnnotations: { - _onEnter() { - this.panel = this.controller.resetSource(source, false); - }, - }, - sourceWithAnnotations: { - _onEnter() { - this.panel = this.controller.resetSourcePair(this.source); - }, - }, - item: { - _onEnter() { - this.item = ldChannel.request('obtain', item(this.serial)); - this.panel = this.controller.resetItem(this.item); - }, - edit: 'itemInEditMode', - related: 'itemWithRelations', - external: 'itemWithExternal', - annotations: 'itemWithOccurrences', - }, - itemInEditMode: { - _onEnter() { - this.panel = this.controller.editAnnotation( - this.panel, this.item - ); - }, - }, - itemWithRelations: { - _onEnter() { - this.panel = this.controller.listRelated(this.panel, this.item); - }, - edit: 'itemWithEditRelations', - }, - itemWithEditRelations: { - _onEnter() { - this.panel = this.controller.editRelated(this.panel, this.item); - }, - }, - itemWithExternal: { - _onEnter() { - this.panel = this.controller.listExternal( - this.panel, this.item - ); - }, - edit: 'itemWithEditExternal', - }, - itemWithEditExternal: { - _onEnter() { - this.panel = this.controller.editExternal( - this.panel, this.item - ); - }, - }, - itemWithOccurrences: { - _onEnter() { - // listItemAnnotations does not return the created panel - // see #342 - this.controller.listItemAnnotations(this.panel, this.item); - }, - }, - }, -}); - -export default function executeRoute( - route: string, - controller: Controller, - serial: string -): void { - const parser = new RouteParser({ controller, serial }); - const layers = route.split(':'); - each(layers, layer => parser.handle(layer)); -}