diff --git a/client-app/src/desktop/AppModel.ts b/client-app/src/desktop/AppModel.ts index d2adf3bf5..c6f3add49 100755 --- a/client-app/src/desktop/AppModel.ts +++ b/client-app/src/desktop/AppModel.ts @@ -179,7 +179,12 @@ export class AppModel extends BaseAppModel { {name: 'pinPad', path: '/pinPad'}, {name: 'placeholder', path: '/placeholder'}, {name: 'popups', path: '/popups'}, - {name: 'timestamp', path: '/timestamp'} + {name: 'timestamp', path: '/timestamp'}, + { + name: 'simpleRouting', + path: '/simpleRouting', + children: [{name: 'recordId', path: '/:recordId'}] + } ] }, { diff --git a/client-app/src/desktop/tabs/other/OtherTab.ts b/client-app/src/desktop/tabs/other/OtherTab.ts index 01a4d563d..873c5a7c0 100644 --- a/client-app/src/desktop/tabs/other/OtherTab.ts +++ b/client-app/src/desktop/tabs/other/OtherTab.ts @@ -17,6 +17,7 @@ import {pinPadPanel} from './PinPadPanel'; import {placeholderPanel} from './PlaceholderPanel'; import {popupsPanel} from './PopupsPanel'; import {relativeTimestampPanel} from './relativetimestamp/RelativeTimestampPanel'; +import {simpleRoutingPanel} from './routing/SimpleRoutingPanel'; export const otherTab = hoistCmp.factory(() => tabContainer({ @@ -44,7 +45,8 @@ export const otherTab = hoistCmp.factory(() => {id: 'pinPad', title: 'PIN Pad', content: pinPadPanel}, {id: 'placeholder', title: 'Placeholder', content: placeholderPanel}, {id: 'popups', content: popupsPanel}, - {id: 'timestamp', content: relativeTimestampPanel} + {id: 'timestamp', content: relativeTimestampPanel}, + {id: 'simpleRouting', content: simpleRoutingPanel} ] }, className: 'toolbox-tab' diff --git a/client-app/src/desktop/tabs/other/routing/SimpleRoutingPanel.tsx b/client-app/src/desktop/tabs/other/routing/SimpleRoutingPanel.tsx new file mode 100644 index 000000000..8119ee4a3 --- /dev/null +++ b/client-app/src/desktop/tabs/other/routing/SimpleRoutingPanel.tsx @@ -0,0 +1,90 @@ +import {HoistModel, hoistCmp, creates, XH} from '@xh/hoist/core'; +import {grid, GridModel} from '@xh/hoist/cmp/grid'; +import {StoreRecordId} from '@xh/hoist/data'; +import {Icon} from '@xh/hoist/icon'; +import {panel} from '@xh/hoist/desktop/cmp/panel'; +import {wrapper} from '../../../common'; +import React from 'react'; + +export const simpleRoutingPanel = hoistCmp.factory({ + displayName: 'SimpleRoutingPanel', + model: creates(() => new SimpleRoutingPanelModel()), + + render({model}) { + return wrapper({ + description: [ +

+ Hoist provides functionality for route parameters to interact with UI + components. Below is a simple grid whose selected record can be maintained by a + route parameter.{' '} +

, +

+ E.g. URLs like https://toolbox.xh.io/app/other/simpleRouting/123, + where 123 is a record ID and that record is (auto) selected in the + grid. Additionally, the route parameter will be updated when the user selects a + different record in the grid. +

+ ], + item: panel({ + title: 'Simple Routing', + icon: Icon.gridPanel(), + className: 'tb-simple-routing-panel', + item: grid({model: model.gridModel}), + height: 600, + width: 600 + }) + }); + } +}); + +class SimpleRoutingPanelModel extends HoistModel { + gridModel = new GridModel({ + columns: [ + {field: 'id', flex: 0}, + {field: 'company', flex: 1} + ] + }); + + constructor() { + super(); + this.addReaction({ + track: () => XH.routerState.params, + run: () => this.updateGridSelectionOnRouteChange(), + fireImmediately: true + }); + this.addReaction({ + track: () => this.gridModel.selectedId, + run: () => + this.updateRouteOnGridSelectionChange( + XH.routerState.name, + this.gridModel.selectedId + ), + fireImmediately: true + }); + } + + async updateGridSelectionOnRouteChange() { + if ( + !XH.routerState.params.recordId || + XH.routerState.params.recordId === this.gridModel.selectedId + ) + return; + await this.gridModel.selectAsync(Number(XH.routerState.params.recordId)); + } + + updateRouteOnGridSelectionChange(name: string, selectedId: StoreRecordId) { + if ( + !name.startsWith('default.other.simpleRouting') || + !selectedId || + XH.routerState.params.recordId === selectedId + ) + return; + XH.navigate('default.other.simpleRouting.recordId', {recordId: selectedId}); + } + + override async doLoadAsync(loadSpec) { + const {trades} = await XH.fetchJson({url: 'trade'}); + this.gridModel.loadData(trades); + await this.updateGridSelectionOnRouteChange(); + } +}