@cratis/scene.react 4.28.0 → 4.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/CoreToolbar.tsx +37 -6
- package/core/coreComponentMetadata.ts +1 -0
- package/core/coreComponents.ts +2 -0
- package/core/coreDescriptors.ts +13 -0
- package/core/corePackage.ts +1 -0
- package/dist/cjs/core/CoreToolbar.js +44 -4
- package/dist/cjs/core/CoreToolbar.js.map +1 -1
- package/dist/cjs/core/coreComponentMetadata.js +6 -0
- package/dist/cjs/core/coreComponentMetadata.js.map +1 -1
- package/dist/cjs/core/coreComponents.js +3 -1
- package/dist/cjs/core/coreComponents.js.map +1 -1
- package/dist/cjs/core/coreDescriptors.js +27 -0
- package/dist/cjs/core/coreDescriptors.js.map +1 -1
- package/dist/cjs/core/corePackage.js +2 -1
- package/dist/cjs/core/corePackage.js.map +1 -1
- package/dist/cjs/index.js +36 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/navigation/SceneNavigationContext.js.map +1 -1
- package/dist/cjs/navigation/SceneNavigationHost.js +34 -18
- package/dist/cjs/navigation/SceneNavigationHost.js.map +1 -1
- package/dist/cjs/navigation/region/NavigationRegionClassNames.js +21 -0
- package/dist/cjs/navigation/region/NavigationRegionClassNames.js.map +1 -0
- package/dist/cjs/navigation/region/NavigationRegionView.js +283 -0
- package/dist/cjs/navigation/region/NavigationRegionView.js.map +1 -0
- package/dist/cjs/navigation/region/SceneNavigationModelContext.js +22 -0
- package/dist/cjs/navigation/region/SceneNavigationModelContext.js.map +1 -0
- package/dist/cjs/navigation/region/currentModuleOf.js +15 -0
- package/dist/cjs/navigation/region/currentModuleOf.js.map +1 -0
- package/dist/cjs/navigation/region/navigationDestinations.js +46 -0
- package/dist/cjs/navigation/region/navigationDestinations.js.map +1 -0
- package/dist/cjs/navigation/region/navigationItemActive.js +31 -0
- package/dist/cjs/navigation/region/navigationItemActive.js.map +1 -0
- package/dist/cjs/navigation/region/navigationItemDestination.js +34 -0
- package/dist/cjs/navigation/region/navigationItemDestination.js.map +1 -0
- package/dist/cjs/navigation/useSceneHistoryNavigation.js +3 -1
- package/dist/cjs/navigation/useSceneHistoryNavigation.js.map +1 -1
- package/dist/cjs/slices/CoreSliceDialog.js +21 -0
- package/dist/cjs/slices/CoreSliceDialog.js.map +1 -0
- package/dist/cjs/slices/SliceCommandFieldsContext.js +22 -0
- package/dist/cjs/slices/SliceCommandFieldsContext.js.map +1 -0
- package/dist/cjs/slices/SliceDialogView.js +254 -0
- package/dist/cjs/slices/SliceDialogView.js.map +1 -0
- package/dist/cjs/slices/SliceInvokerContext.js +40 -0
- package/dist/cjs/slices/SliceInvokerContext.js.map +1 -0
- package/dist/cjs/slices/createAnnouncingInvoker.js +27 -0
- package/dist/cjs/slices/createAnnouncingInvoker.js.map +1 -0
- package/dist/cjs/slices/createDryRunInvoker.js +38 -0
- package/dist/cjs/slices/createDryRunInvoker.js.map +1 -0
- package/dist/cjs/slices/sliceDialogDestination.js +41 -0
- package/dist/cjs/slices/sliceDialogDestination.js.map +1 -0
- package/dist/esm/core/CoreToolbar.d.ts.map +1 -1
- package/dist/esm/core/CoreToolbar.js +47 -7
- package/dist/esm/core/CoreToolbar.js.map +1 -1
- package/dist/esm/core/coreComponentMetadata.d.ts.map +1 -1
- package/dist/esm/core/coreComponentMetadata.js +6 -0
- package/dist/esm/core/coreComponentMetadata.js.map +1 -1
- package/dist/esm/core/coreComponents.d.ts.map +1 -1
- package/dist/esm/core/coreComponents.js +3 -1
- package/dist/esm/core/coreComponents.js.map +1 -1
- package/dist/esm/core/coreDescriptors.d.ts.map +1 -1
- package/dist/esm/core/coreDescriptors.js +27 -0
- package/dist/esm/core/coreDescriptors.js.map +1 -1
- package/dist/esm/core/corePackage.d.ts.map +1 -1
- package/dist/esm/core/corePackage.js +2 -1
- package/dist/esm/core/corePackage.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +14 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/navigation/SceneNavigationContext.d.ts +1 -0
- package/dist/esm/navigation/SceneNavigationContext.d.ts.map +1 -1
- package/dist/esm/navigation/SceneNavigationContext.js.map +1 -1
- package/dist/esm/navigation/SceneNavigationHost.d.ts +5 -1
- package/dist/esm/navigation/SceneNavigationHost.d.ts.map +1 -1
- package/dist/esm/navigation/SceneNavigationHost.js +35 -19
- package/dist/esm/navigation/SceneNavigationHost.js.map +1 -1
- package/dist/esm/navigation/SceneNavigationState.d.ts +1 -0
- package/dist/esm/navigation/SceneNavigationState.d.ts.map +1 -1
- package/dist/esm/navigation/index.d.ts +8 -0
- package/dist/esm/navigation/index.d.ts.map +1 -1
- package/dist/esm/navigation/index.js +8 -0
- package/dist/esm/navigation/index.js.map +1 -1
- package/dist/esm/navigation/region/NavigationRegionClassNames.d.ts +12 -0
- package/dist/esm/navigation/region/NavigationRegionClassNames.d.ts.map +1 -0
- package/dist/esm/navigation/region/NavigationRegionClassNames.js +19 -0
- package/dist/esm/navigation/region/NavigationRegionClassNames.js.map +1 -0
- package/dist/esm/navigation/region/NavigationRegionView.d.ts +20 -0
- package/dist/esm/navigation/region/NavigationRegionView.d.ts.map +1 -0
- package/dist/esm/navigation/region/NavigationRegionView.js +281 -0
- package/dist/esm/navigation/region/NavigationRegionView.js.map +1 -0
- package/dist/esm/navigation/region/SceneNavigationModel.d.ts +9 -0
- package/dist/esm/navigation/region/SceneNavigationModel.d.ts.map +1 -0
- package/dist/esm/navigation/region/SceneNavigationModel.js +2 -0
- package/dist/esm/navigation/region/SceneNavigationModel.js.map +1 -0
- package/dist/esm/navigation/region/SceneNavigationModelContext.d.ts +9 -0
- package/dist/esm/navigation/region/SceneNavigationModelContext.d.ts.map +1 -0
- package/dist/esm/navigation/region/SceneNavigationModelContext.js +19 -0
- package/dist/esm/navigation/region/SceneNavigationModelContext.js.map +1 -0
- package/dist/esm/navigation/region/currentModuleOf.d.ts +3 -0
- package/dist/esm/navigation/region/currentModuleOf.d.ts.map +1 -0
- package/dist/esm/navigation/region/currentModuleOf.js +13 -0
- package/dist/esm/navigation/region/currentModuleOf.js.map +1 -0
- package/dist/esm/navigation/region/navigationDestinations.d.ts +4 -0
- package/dist/esm/navigation/region/navigationDestinations.d.ts.map +1 -0
- package/dist/esm/navigation/region/navigationDestinations.js +44 -0
- package/dist/esm/navigation/region/navigationDestinations.js.map +1 -0
- package/dist/esm/navigation/region/navigationItemActive.d.ts +5 -0
- package/dist/esm/navigation/region/navigationItemActive.d.ts.map +1 -0
- package/dist/esm/navigation/region/navigationItemActive.js +29 -0
- package/dist/esm/navigation/region/navigationItemActive.js.map +1 -0
- package/dist/esm/navigation/region/navigationItemDestination.d.ts +5 -0
- package/dist/esm/navigation/region/navigationItemDestination.d.ts.map +1 -0
- package/dist/esm/navigation/region/navigationItemDestination.js +31 -0
- package/dist/esm/navigation/region/navigationItemDestination.js.map +1 -0
- package/dist/esm/navigation/useSceneHistoryNavigation.d.ts.map +1 -1
- package/dist/esm/navigation/useSceneHistoryNavigation.js +3 -1
- package/dist/esm/navigation/useSceneHistoryNavigation.js.map +1 -1
- package/dist/esm/slices/CoreSliceDialog.d.ts +3 -0
- package/dist/esm/slices/CoreSliceDialog.d.ts.map +1 -0
- package/dist/esm/slices/CoreSliceDialog.js +19 -0
- package/dist/esm/slices/CoreSliceDialog.js.map +1 -0
- package/dist/esm/slices/InvocationResult.d.ts +10 -0
- package/dist/esm/slices/InvocationResult.d.ts.map +1 -0
- package/dist/esm/slices/InvocationResult.js +2 -0
- package/dist/esm/slices/InvocationResult.js.map +1 -0
- package/dist/esm/slices/InvocationValidationError.d.ts +5 -0
- package/dist/esm/slices/InvocationValidationError.d.ts.map +1 -0
- package/dist/esm/slices/InvocationValidationError.js +2 -0
- package/dist/esm/slices/InvocationValidationError.js.map +1 -0
- package/dist/esm/slices/SliceCommandField.d.ts +7 -0
- package/dist/esm/slices/SliceCommandField.d.ts.map +1 -0
- package/dist/esm/slices/SliceCommandField.js +2 -0
- package/dist/esm/slices/SliceCommandField.js.map +1 -0
- package/dist/esm/slices/SliceCommandFieldsContext.d.ts +10 -0
- package/dist/esm/slices/SliceCommandFieldsContext.d.ts.map +1 -0
- package/dist/esm/slices/SliceCommandFieldsContext.js +19 -0
- package/dist/esm/slices/SliceCommandFieldsContext.js.map +1 -0
- package/dist/esm/slices/SliceDialogView.d.ts +12 -0
- package/dist/esm/slices/SliceDialogView.d.ts.map +1 -0
- package/dist/esm/slices/SliceDialogView.js +250 -0
- package/dist/esm/slices/SliceDialogView.js.map +1 -0
- package/dist/esm/slices/SliceInvoker.d.ts +5 -0
- package/dist/esm/slices/SliceInvoker.d.ts.map +1 -0
- package/dist/esm/slices/SliceInvoker.js +2 -0
- package/dist/esm/slices/SliceInvoker.js.map +1 -0
- package/dist/esm/slices/SliceInvokerContext.d.ts +11 -0
- package/dist/esm/slices/SliceInvokerContext.d.ts.map +1 -0
- package/dist/esm/slices/SliceInvokerContext.js +36 -0
- package/dist/esm/slices/SliceInvokerContext.js.map +1 -0
- package/dist/esm/slices/createAnnouncingInvoker.d.ts +3 -0
- package/dist/esm/slices/createAnnouncingInvoker.d.ts.map +1 -0
- package/dist/esm/slices/createAnnouncingInvoker.js +25 -0
- package/dist/esm/slices/createAnnouncingInvoker.js.map +1 -0
- package/dist/esm/slices/createDryRunInvoker.d.ts +15 -0
- package/dist/esm/slices/createDryRunInvoker.d.ts.map +1 -0
- package/dist/esm/slices/createDryRunInvoker.js +36 -0
- package/dist/esm/slices/createDryRunInvoker.js.map +1 -0
- package/dist/esm/slices/index.d.ts +12 -0
- package/dist/esm/slices/index.d.ts.map +1 -0
- package/dist/esm/slices/index.js +12 -0
- package/dist/esm/slices/index.js.map +1 -0
- package/dist/esm/slices/sliceDialogDestination.d.ts +10 -0
- package/dist/esm/slices/sliceDialogDestination.d.ts.map +1 -0
- package/dist/esm/slices/sliceDialogDestination.js +38 -0
- package/dist/esm/slices/sliceDialogDestination.js.map +1 -0
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/index.ts +1 -0
- package/navigation/SceneNavigationContext.tsx +3 -0
- package/navigation/SceneNavigationHost.tsx +35 -9
- package/navigation/SceneNavigationState.ts +3 -0
- package/navigation/index.ts +8 -0
- package/navigation/region/NavigationRegionClassNames.ts +46 -0
- package/navigation/region/NavigationRegionView.tsx +234 -0
- package/navigation/region/SceneNavigationModel.ts +29 -0
- package/navigation/region/SceneNavigationModelContext.tsx +25 -0
- package/navigation/region/currentModuleOf.ts +14 -0
- package/navigation/region/navigationDestinations.ts +41 -0
- package/navigation/region/navigationItemActive.ts +39 -0
- package/navigation/region/navigationItemDestination.ts +29 -0
- package/navigation/useSceneHistoryNavigation.ts +2 -1
- package/package.json +5 -5
- package/slices/CoreSliceDialog.tsx +14 -0
- package/slices/InvocationResult.ts +27 -0
- package/slices/InvocationValidationError.ts +13 -0
- package/slices/SliceCommandField.ts +19 -0
- package/slices/SliceCommandFieldsContext.tsx +28 -0
- package/slices/SliceDialogView.tsx +176 -0
- package/slices/SliceInvoker.ts +19 -0
- package/slices/SliceInvokerContext.tsx +47 -0
- package/slices/createAnnouncingInvoker.ts +17 -0
- package/slices/createDryRunInvoker.ts +43 -0
- package/slices/index.ts +14 -0
- package/slices/sliceDialogDestination.ts +40 -0
|
@@ -65,7 +65,8 @@ import { resolveDestination } from './resolveDestination.js';
|
|
|
65
65
|
if (resolution.kind === DestinationKind.Dialog) {
|
|
66
66
|
if (resolution.dialog) go({
|
|
67
67
|
...state,
|
|
68
|
-
dialog: resolution.dialog
|
|
68
|
+
dialog: resolution.dialog,
|
|
69
|
+
dialogParameters: resolution.parameters
|
|
69
70
|
});
|
|
70
71
|
} else if (resolution.kind !== DestinationKind.External) {
|
|
71
72
|
const screen = destination.screen ?? destination.slice ?? state.screen;
|
|
@@ -104,6 +105,7 @@ import { resolveDestination } from './resolveDestination.js';
|
|
|
104
105
|
currentUrl: state.url,
|
|
105
106
|
currentOutlet: state.outlet,
|
|
106
107
|
currentDialog: state.dialog,
|
|
108
|
+
currentDialogParameters: state.dialogParameters,
|
|
107
109
|
currentParameters: state.parameters,
|
|
108
110
|
dialogResult,
|
|
109
111
|
unresolvedUrl,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSceneHistoryNavigation.js","sources":["../../../navigation/useSceneHistoryNavigation.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { BindingScope } from '@cratis/scene.engine';\nimport { DestinationKind, DestinationReference } from '@cratis/scene.model';\nimport { DialogResult } from './DialogResult';\nimport { matchSceneRoute } from './matchSceneRoute';\nimport { placeInOutlet } from './placeInOutlet';\nimport { resolveDestination } from './resolveDestination';\nimport { SceneHistory } from './SceneHistory';\nimport { SceneNavigationContextValue } from './SceneNavigationContext';\nimport { SceneNavigationState } from './SceneNavigationState';\nimport { SceneRoute } from './SceneRoute';\n\n/**\n * Keeps a navigation host's state in a {@link SceneHistory}: every navigation and every dialog is an entry,\n * so back and forward step through them, a refresh restores the stored entry, and a deep link is matched\n * against the route table. Closing a dialog goes back to the entry that opened it.\n */\nexport function useSceneHistoryNavigation(\n history: SceneHistory,\n routes: SceneRoute[],\n initialScreen: string,\n bindingScope: BindingScope,\n outletOwners: Record<string, string> = {},\n destinations: DestinationReference[] = [],\n): SceneNavigationContextValue {\n const fromLocation = useCallback((url: string | undefined): SceneNavigationState | undefined => {\n const match = url ? matchSceneRoute(url, routes) : undefined;\n if (!match) return undefined;\n const start: SceneNavigationState = { screen: initialScreen, parameters: {} };\n const placement = placeInOutlet(start, match.route.screen, match.route.outlet, outletOwners, destinations);\n return { screen: match.route.screen, url, outlet: match.route.outlet, parameters: match.parameters, ...placement };\n }, [destinations, initialScreen, outletOwners, routes]);\n const fallback = useMemo<SceneNavigationState>(() => ({ screen: initialScreen, url: initialScreen, parameters: {} }), [initialScreen]);\n\n const [unresolvedUrl] = useState(() => {\n const url = history.location();\n return !history.state() && url && !fromLocation(url) ? url : undefined;\n });\n const [state, setState] = useState<SceneNavigationState>(() => history.state() ?? fromLocation(history.location()) ?? fallback);\n const [dialogResult, setDialogResult] = useState<DialogResult>();\n\n // Back and forward restore the stored entry, or match a URL the host never wrote against the current routes.\n const restore = useRef((url: string | undefined, stored: SceneNavigationState | undefined) => stored ?? fromLocation(url) ?? fallback);\n restore.current = (url, stored) => stored ?? fromLocation(url) ?? fallback;\n const initialState = useRef(state);\n\n // The current entry is written once, when a history is attached; later entries are written by navigate.\n useEffect(() => {\n history.replace(initialState.current);\n return history.listen((url, stored) => setState(restore.current(url, stored)));\n }, [history]);\n\n const go = useCallback((next: SceneNavigationState) => {\n history.push(next);\n setState(next);\n }, [history]);\n\n const navigate = useCallback((destination: DestinationReference) => {\n const resolution = resolveDestination(destination, bindingScope);\n if (resolution.kind === DestinationKind.Dialog) {\n if (resolution.dialog) go({ ...state, dialog: resolution.dialog });\n } else if (resolution.kind !== DestinationKind.External) {\n const screen = destination.screen ?? destination.slice ?? state.screen;\n const placement = placeInOutlet(state, screen, resolution.outlet, outletOwners, destinations);\n go({ screen, url: resolution.url, outlet: resolution.outlet, parameters: resolution.parameters, ...placement });\n }\n\n return resolution;\n }, [bindingScope, destinations, go, outletOwners, state]);\n\n const closeDialog = useCallback((result?: unknown) => {\n if (!state.dialog) return;\n setDialogResult({ dialog: state.dialog, result });\n history.back();\n }, [history, state.dialog]);\n\n return useMemo(() => ({\n currentScreen: state.screen,\n primaryScreen: state.primary ?? state.screen,\n outlets: state.outlets ?? {},\n currentUrl: state.url,\n currentOutlet: state.outlet,\n currentDialog: state.dialog,\n currentParameters: state.parameters,\n dialogResult,\n unresolvedUrl,\n bindingScope,\n navigate,\n closeDialog,\n back: () => history.back(),\n }), [bindingScope, closeDialog, dialogResult, history, navigate, state, unresolvedUrl]);\n}\n"],"names":["useSceneHistoryNavigation","history","routes","initialScreen","bindingScope","outletOwners","destinations","fromLocation","useCallback","url","match","matchSceneRoute","undefined","start","screen","placement","placeInOutlet","route","outlet","parameters","fallback","useMemo","unresolvedUrl","useState","location","state","setState","dialogResult","setDialogResult","restore","useRef","stored","current","initialState","useEffect","replace","listen","go","next","push","navigate","destination","resolution","resolveDestination","kind","DestinationKind","Dialog","dialog","External","slice","closeDialog","result","back","currentScreen","primaryScreen","primary","outlets","currentUrl","currentOutlet","currentDialog","currentParameters"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"useSceneHistoryNavigation.js","sources":["../../../navigation/useSceneHistoryNavigation.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { BindingScope } from '@cratis/scene.engine';\nimport { DestinationKind, DestinationReference } from '@cratis/scene.model';\nimport { DialogResult } from './DialogResult';\nimport { matchSceneRoute } from './matchSceneRoute';\nimport { placeInOutlet } from './placeInOutlet';\nimport { resolveDestination } from './resolveDestination';\nimport { SceneHistory } from './SceneHistory';\nimport { SceneNavigationContextValue } from './SceneNavigationContext';\nimport { SceneNavigationState } from './SceneNavigationState';\nimport { SceneRoute } from './SceneRoute';\n\n/**\n * Keeps a navigation host's state in a {@link SceneHistory}: every navigation and every dialog is an entry,\n * so back and forward step through them, a refresh restores the stored entry, and a deep link is matched\n * against the route table. Closing a dialog goes back to the entry that opened it.\n */\nexport function useSceneHistoryNavigation(\n history: SceneHistory,\n routes: SceneRoute[],\n initialScreen: string,\n bindingScope: BindingScope,\n outletOwners: Record<string, string> = {},\n destinations: DestinationReference[] = [],\n): SceneNavigationContextValue {\n const fromLocation = useCallback((url: string | undefined): SceneNavigationState | undefined => {\n const match = url ? matchSceneRoute(url, routes) : undefined;\n if (!match) return undefined;\n const start: SceneNavigationState = { screen: initialScreen, parameters: {} };\n const placement = placeInOutlet(start, match.route.screen, match.route.outlet, outletOwners, destinations);\n return { screen: match.route.screen, url, outlet: match.route.outlet, parameters: match.parameters, ...placement };\n }, [destinations, initialScreen, outletOwners, routes]);\n const fallback = useMemo<SceneNavigationState>(() => ({ screen: initialScreen, url: initialScreen, parameters: {} }), [initialScreen]);\n\n const [unresolvedUrl] = useState(() => {\n const url = history.location();\n return !history.state() && url && !fromLocation(url) ? url : undefined;\n });\n const [state, setState] = useState<SceneNavigationState>(() => history.state() ?? fromLocation(history.location()) ?? fallback);\n const [dialogResult, setDialogResult] = useState<DialogResult>();\n\n // Back and forward restore the stored entry, or match a URL the host never wrote against the current routes.\n const restore = useRef((url: string | undefined, stored: SceneNavigationState | undefined) => stored ?? fromLocation(url) ?? fallback);\n restore.current = (url, stored) => stored ?? fromLocation(url) ?? fallback;\n const initialState = useRef(state);\n\n // The current entry is written once, when a history is attached; later entries are written by navigate.\n useEffect(() => {\n history.replace(initialState.current);\n return history.listen((url, stored) => setState(restore.current(url, stored)));\n }, [history]);\n\n const go = useCallback((next: SceneNavigationState) => {\n history.push(next);\n setState(next);\n }, [history]);\n\n const navigate = useCallback((destination: DestinationReference) => {\n const resolution = resolveDestination(destination, bindingScope);\n if (resolution.kind === DestinationKind.Dialog) {\n if (resolution.dialog) go({ ...state, dialog: resolution.dialog, dialogParameters: resolution.parameters });\n } else if (resolution.kind !== DestinationKind.External) {\n const screen = destination.screen ?? destination.slice ?? state.screen;\n const placement = placeInOutlet(state, screen, resolution.outlet, outletOwners, destinations);\n go({ screen, url: resolution.url, outlet: resolution.outlet, parameters: resolution.parameters, ...placement });\n }\n\n return resolution;\n }, [bindingScope, destinations, go, outletOwners, state]);\n\n const closeDialog = useCallback((result?: unknown) => {\n if (!state.dialog) return;\n setDialogResult({ dialog: state.dialog, result });\n history.back();\n }, [history, state.dialog]);\n\n return useMemo(() => ({\n currentScreen: state.screen,\n primaryScreen: state.primary ?? state.screen,\n outlets: state.outlets ?? {},\n currentUrl: state.url,\n currentOutlet: state.outlet,\n currentDialog: state.dialog,\n currentDialogParameters: state.dialogParameters,\n currentParameters: state.parameters,\n dialogResult,\n unresolvedUrl,\n bindingScope,\n navigate,\n closeDialog,\n back: () => history.back(),\n }), [bindingScope, closeDialog, dialogResult, history, navigate, state, unresolvedUrl]);\n}\n"],"names":["useSceneHistoryNavigation","history","routes","initialScreen","bindingScope","outletOwners","destinations","fromLocation","useCallback","url","match","matchSceneRoute","undefined","start","screen","placement","placeInOutlet","route","outlet","parameters","fallback","useMemo","unresolvedUrl","useState","location","state","setState","dialogResult","setDialogResult","restore","useRef","stored","current","initialState","useEffect","replace","listen","go","next","push","navigate","destination","resolution","resolveDestination","kind","DestinationKind","Dialog","dialog","dialogParameters","External","slice","closeDialog","result","back","currentScreen","primaryScreen","primary","outlets","currentUrl","currentOutlet","currentDialog","currentDialogParameters","currentParameters"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CoreSliceDialog.d.ts","sourceRoot":"","sources":["../../../slices/CoreSliceDialog.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAOvD,wBAAgB,eAAe,CAAC,EAAE,OAAO,EAAE,EAAE,wBAAwB,+BAGpE"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { SliceDialogView } from './SliceDialogView.js';
|
|
3
|
+
|
|
4
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
5
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
6
|
+
/**
|
|
7
|
+
* The `core:sliceDialog` component: the task dialog of a state change slice. Its `slice`, `command` and `title` properties are
|
|
8
|
+
* optional - opened from a toolbar button the dialog's own parameters supply them - so one dialog template serves every slice.
|
|
9
|
+
*/ function CoreSliceDialog({ element }) {
|
|
10
|
+
const text = (name)=>typeof element.properties[name] === 'string' ? element.properties[name] : undefined;
|
|
11
|
+
return /*#__PURE__*/ jsx(SliceDialogView, {
|
|
12
|
+
slice: text('slice'),
|
|
13
|
+
command: text('command'),
|
|
14
|
+
title: text('title')
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { CoreSliceDialog };
|
|
19
|
+
//# sourceMappingURL=CoreSliceDialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CoreSliceDialog.js","sources":["../../../slices/CoreSliceDialog.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { RegisteredComponentProps } from '../renderer';\nimport { SliceDialogView } from './SliceDialogView';\n\n/**\n * The `core:sliceDialog` component: the task dialog of a state change slice. Its `slice`, `command` and `title` properties are\n * optional - opened from a toolbar button the dialog's own parameters supply them - so one dialog template serves every slice.\n */\nexport function CoreSliceDialog({ element }: RegisteredComponentProps) {\n const text = (name: string) => typeof element.properties[name] === 'string' ? element.properties[name] as string : undefined;\n return <SliceDialogView slice={text('slice')} command={text('command')} title={text('title')} />;\n}\n"],"names":["CoreSliceDialog","element","text","name","properties","undefined","_jsx","SliceDialogView","slice","command","title"],"mappings":";;;AAAA;AACA;AAKA;;;AAGC,IACM,SAASA,eAAAA,CAAgB,EAAEC,OAAO,EAA4B,EAAA;AACjE,IAAA,MAAMC,IAAAA,GAAO,CAACC,IAAAA,GAAiB,OAAOF,QAAQG,UAAU,CAACD,IAAAA,CAAK,KAAK,QAAA,GAAWF,OAAAA,CAAQG,UAAU,CAACD,KAAK,GAAaE,SAAAA;AACnH,IAAA,qBAAOC,GAAA,CAACC,eAAAA,EAAAA;AAAgBC,QAAAA,KAAAA,EAAON,IAAAA,CAAK,OAAA,CAAA;AAAUO,QAAAA,OAAAA,EAASP,IAAAA,CAAK,SAAA,CAAA;AAAYQ,QAAAA,KAAAA,EAAOR,IAAAA,CAAK,OAAA;;AACxF;;"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { InvocationValidationError } from './InvocationValidationError';
|
|
2
|
+
export interface InvocationResult {
|
|
3
|
+
succeeded: boolean;
|
|
4
|
+
validationErrors?: InvocationValidationError[];
|
|
5
|
+
message?: string;
|
|
6
|
+
payload?: Record<string, unknown>;
|
|
7
|
+
dryRun?: boolean;
|
|
8
|
+
value?: unknown;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=InvocationResult.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InvocationResult.d.ts","sourceRoot":"","sources":["../../../slices/InvocationResult.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAKxE,MAAM,WAAW,gBAAgB;IAE7B,SAAS,EAAE,OAAO,CAAC;IAGnB,gBAAgB,CAAC,EAAE,yBAAyB,EAAE,CAAC;IAG/C,OAAO,CAAC,EAAE,MAAM,CAAC;IAGjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAGlC,MAAM,CAAC,EAAE,OAAO,CAAC;IAGjB,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InvocationResult.js","sourceRoot":"","sources":["../../../slices/InvocationResult.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InvocationValidationError.d.ts","sourceRoot":"","sources":["../../../slices/InvocationValidationError.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,yBAAyB;IAEtC,KAAK,CAAC,EAAE,MAAM,CAAC;IAGf,OAAO,EAAE,MAAM,CAAC;CACnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InvocationValidationError.js","sourceRoot":"","sources":["../../../slices/InvocationValidationError.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SliceCommandField.d.ts","sourceRoot":"","sources":["../../../slices/SliceCommandField.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,iBAAiB;IAE9B,IAAI,EAAE,MAAM,CAAC;IAGb,IAAI,EAAE,MAAM,CAAC;IAGb,KAAK,CAAC,EAAE,MAAM,CAAC;IAGf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SliceCommandField.js","sourceRoot":"","sources":["../../../slices/SliceCommandField.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { SliceCommandField } from './SliceCommandField';
|
|
3
|
+
export type SliceCommandFieldsSource = (command: string, sliceId: string) => SliceCommandField[];
|
|
4
|
+
export interface SliceCommandFieldsProviderProps {
|
|
5
|
+
fieldsFor: SliceCommandFieldsSource;
|
|
6
|
+
children?: ReactNode;
|
|
7
|
+
}
|
|
8
|
+
export declare function SliceCommandFieldsProvider({ fieldsFor, children }: SliceCommandFieldsProviderProps): import("react").JSX.Element;
|
|
9
|
+
export declare function useSliceCommandFields(): SliceCommandFieldsSource | undefined;
|
|
10
|
+
//# sourceMappingURL=SliceCommandFieldsContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SliceCommandFieldsContext.d.ts","sourceRoot":"","sources":["../../../slices/SliceCommandFieldsContext.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAA6B,MAAM,OAAO,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxD,MAAM,MAAM,wBAAwB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,iBAAiB,EAAE,CAAC;AAIjG,MAAM,WAAW,+BAA+B;IAC5C,SAAS,EAAE,wBAAwB,CAAC;IACpC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACxB;AAMD,wBAAgB,0BAA0B,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,+BAA+B,+BAElG;AAGD,wBAAgB,qBAAqB,IAAI,wBAAwB,GAAG,SAAS,CAE5E"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useContext, createContext } from 'react';
|
|
3
|
+
|
|
4
|
+
const Context = /*#__PURE__*/ createContext(undefined);
|
|
5
|
+
/**
|
|
6
|
+
* Supplies the fields of a command to the task dialogs below it. The fields come from the command's metadata - Stage reads it
|
|
7
|
+
* from the generated schemas, Studio from the model - so this package does not know where commands are defined.
|
|
8
|
+
*/ function SliceCommandFieldsProvider({ fieldsFor, children }) {
|
|
9
|
+
return /*#__PURE__*/ jsx(Context.Provider, {
|
|
10
|
+
value: fieldsFor,
|
|
11
|
+
children: children
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
/** The fields source in scope, or undefined when a host supplied none. */ function useSliceCommandFields() {
|
|
15
|
+
return useContext(Context);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { SliceCommandFieldsProvider, useSliceCommandFields };
|
|
19
|
+
//# sourceMappingURL=SliceCommandFieldsContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SliceCommandFieldsContext.js","sources":["../../../slices/SliceCommandFieldsContext.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { ReactNode, createContext, useContext } from 'react';\nimport { SliceCommandField } from './SliceCommandField';\n\n/** Tells a task dialog which fields a command has. */\nexport type SliceCommandFieldsSource = (command: string, sliceId: string) => SliceCommandField[];\n\nconst Context = createContext<SliceCommandFieldsSource | undefined>(undefined);\n\nexport interface SliceCommandFieldsProviderProps {\n fieldsFor: SliceCommandFieldsSource;\n children?: ReactNode;\n}\n\n/**\n * Supplies the fields of a command to the task dialogs below it. The fields come from the command's metadata - Stage reads it\n * from the generated schemas, Studio from the model - so this package does not know where commands are defined.\n */\nexport function SliceCommandFieldsProvider({ fieldsFor, children }: SliceCommandFieldsProviderProps) {\n return <Context.Provider value={fieldsFor}>{children}</Context.Provider>;\n}\n\n/** The fields source in scope, or undefined when a host supplied none. */\nexport function useSliceCommandFields(): SliceCommandFieldsSource | undefined {\n return useContext(Context);\n}\n"],"names":["Context","createContext","undefined","SliceCommandFieldsProvider","fieldsFor","children","_jsx","Provider","value","useSliceCommandFields","useContext"],"mappings":";;;AASA,MAAMA,wBAAUC,aAAAA,CAAoDC,SAAAA,CAAAA;AAOpE;;;AAGC,IACM,SAASC,0BAAAA,CAA2B,EAAEC,SAAS,EAAEC,QAAQ,EAAmC,EAAA;IAC/F,qBAAOC,GAAA,CAACN,QAAQO,QAAQ,EAAA;QAACC,KAAAA,EAAOJ,SAAAA;AAAYC,QAAAA,QAAAA,EAAAA;;AAChD;AAEA,2EACO,SAASI,qBAAAA,GAAAA;AACZ,IAAA,OAAOC,UAAAA,CAAWV,OAAAA,CAAAA;AACtB;;"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { InvocationResult } from './InvocationResult';
|
|
2
|
+
import { SliceCommandField } from './SliceCommandField';
|
|
3
|
+
export interface SliceDialogViewProps {
|
|
4
|
+
slice?: string;
|
|
5
|
+
command?: string;
|
|
6
|
+
title?: string;
|
|
7
|
+
onClose?(result?: InvocationResult): void;
|
|
8
|
+
}
|
|
9
|
+
export declare function sliceFieldLabel(field: SliceCommandField): string;
|
|
10
|
+
export declare function slicePayload(fields: SliceCommandField[], values: Record<string, string | boolean>): Record<string, unknown>;
|
|
11
|
+
export declare function SliceDialogView({ slice: sliceProp, command: commandProp, title: titleProp, onClose }: SliceDialogViewProps): import("react").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=SliceDialogView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SliceDialogView.d.ts","sourceRoot":"","sources":["../../../slices/SliceDialogView.tsx"],"names":[],"mappings":"AAOA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAKxD,MAAM,WAAW,oBAAoB;IAEjC,KAAK,CAAC,EAAE,MAAM,CAAC;IAGf,OAAO,CAAC,EAAE,MAAM,CAAC;IAGjB,KAAK,CAAC,EAAE,MAAM,CAAC;IAGf,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;CAC7C;AAKD,wBAAgB,eAAe,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAIhE;AAYD,wBAAgB,YAAY,CAAC,MAAM,EAAE,iBAAiB,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAW3H;AAeD,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,oBAAoB,+BAsG1H"}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useContext, useMemo, useState, useRef, useId, useEffect } from 'react';
|
|
3
|
+
import { ApplicationStructureIndex } from '@cratis/scene.engine';
|
|
4
|
+
import { SceneNavigationContextInternal } from '../navigation/SceneNavigationContext.js';
|
|
5
|
+
import { useSceneNavigationModel } from '../navigation/region/SceneNavigationModelContext.js';
|
|
6
|
+
import { useSliceCommandFields } from './SliceCommandFieldsContext.js';
|
|
7
|
+
import { useSliceInvoker } from './SliceInvokerContext.js';
|
|
8
|
+
import { sliceDialogParameters } from './sliceDialogDestination.js';
|
|
9
|
+
|
|
10
|
+
const focusable = 'input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [href], [tabindex]:not([tabindex="-1"])';
|
|
11
|
+
/** A label for a command property: `customerName` becomes `Customer name`. */ function sliceFieldLabel(field) {
|
|
12
|
+
if (field.label) return field.label;
|
|
13
|
+
const spaced = field.name.replace(/([a-z0-9])([A-Z])/g, '$1 $2').replace(/[_-]+/g, ' ').trim().toLowerCase();
|
|
14
|
+
return spaced.charAt(0).toUpperCase() + spaced.slice(1);
|
|
15
|
+
}
|
|
16
|
+
function inputTypeOf(field) {
|
|
17
|
+
switch(field.type.toLowerCase()){
|
|
18
|
+
case 'number':
|
|
19
|
+
case 'int':
|
|
20
|
+
case 'integer':
|
|
21
|
+
case 'long':
|
|
22
|
+
case 'double':
|
|
23
|
+
case 'decimal':
|
|
24
|
+
case 'float':
|
|
25
|
+
case 'single':
|
|
26
|
+
case 'int32':
|
|
27
|
+
case 'int64':
|
|
28
|
+
return 'number';
|
|
29
|
+
case 'boolean':
|
|
30
|
+
case 'bool':
|
|
31
|
+
return 'checkbox';
|
|
32
|
+
case 'date':
|
|
33
|
+
case 'dateonly':
|
|
34
|
+
return 'date';
|
|
35
|
+
default:
|
|
36
|
+
return 'text';
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/** The payload a form's values make: numbers and booleans as such, an empty number left out. */ function slicePayload(fields, values) {
|
|
40
|
+
const payload = {};
|
|
41
|
+
for (const field of fields){
|
|
42
|
+
const value = values[field.name];
|
|
43
|
+
const type = inputTypeOf(field);
|
|
44
|
+
if (type === 'checkbox') payload[field.name] = value === true;
|
|
45
|
+
else if (type === 'number') {
|
|
46
|
+
if (value !== undefined && value !== '') payload[field.name] = Number(value);
|
|
47
|
+
} else payload[field.name] = value ?? '';
|
|
48
|
+
}
|
|
49
|
+
return payload;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The task dialog of a toolbar slice button (TB4): a modal card with the button's title, the slice as its subtitle, a labelled
|
|
53
|
+
* field for each command property, and Cancel and a submit button labelled with the title.
|
|
54
|
+
*
|
|
55
|
+
* - The first field takes focus when it opens, Tab stays inside, Escape cancels, and focus returns to the button that opened it.
|
|
56
|
+
* - Submit validates required fields, then calls the `SliceInvoker` in scope - real, dry-run or the announcing default. The
|
|
57
|
+
* problems it reports are shown against their fields (`aria-invalid`, `aria-describedby`) or for the form; success closes the
|
|
58
|
+
* dialog and hands the result to the host (`dialogResult`).
|
|
59
|
+
* - The fields come from the `SliceCommandFieldsProvider`; the subtitle names the slice from the navigation model.
|
|
60
|
+
*
|
|
61
|
+
* Inside a navigation host it is the content of the dialog a toolbar button opens; `core:sliceDialog` registers it so a host can
|
|
62
|
+
* author the dialog template with it.
|
|
63
|
+
*/ function SliceDialogView({ slice: sliceProp, command: commandProp, title: titleProp, onClose }) {
|
|
64
|
+
const navigation = useContext(SceneNavigationContextInternal);
|
|
65
|
+
const opened = sliceDialogParameters(navigation?.currentDialogParameters);
|
|
66
|
+
const slice = sliceProp ?? opened?.slice ?? '';
|
|
67
|
+
const command = commandProp ?? opened?.command ?? slice;
|
|
68
|
+
const title = titleProp ?? opened?.title ?? command;
|
|
69
|
+
const invoker = useSliceInvoker();
|
|
70
|
+
const fieldsFor = useSliceCommandFields();
|
|
71
|
+
const model = useSceneNavigationModel();
|
|
72
|
+
const fields = useMemo(()=>fieldsFor?.(command, slice) ?? [], [
|
|
73
|
+
command,
|
|
74
|
+
fieldsFor,
|
|
75
|
+
slice
|
|
76
|
+
]);
|
|
77
|
+
const sliceName = useMemo(()=>{
|
|
78
|
+
if (!model) return slice.split('.').pop() ?? slice;
|
|
79
|
+
const index = model.structure instanceof ApplicationStructureIndex ? model.structure : new ApplicationStructureIndex(model.structure);
|
|
80
|
+
return index.findSlice(slice)?.id ?? slice.split('.').pop() ?? slice;
|
|
81
|
+
}, [
|
|
82
|
+
model,
|
|
83
|
+
slice
|
|
84
|
+
]);
|
|
85
|
+
const [values, setValues] = useState({});
|
|
86
|
+
const [errors, setErrors] = useState([]);
|
|
87
|
+
const [submitting, setSubmitting] = useState(false);
|
|
88
|
+
const form = useRef(null);
|
|
89
|
+
const identity = useId();
|
|
90
|
+
const close = (result)=>onClose ? onClose(result) : navigation?.closeDialog(result);
|
|
91
|
+
// Focus the first field, and give focus back to whatever opened the dialog when it goes.
|
|
92
|
+
useEffect(()=>{
|
|
93
|
+
const opener = document.activeElement;
|
|
94
|
+
(form.current?.querySelector('input, select, textarea') ?? form.current?.querySelector('button'))?.focus();
|
|
95
|
+
return ()=>{
|
|
96
|
+
if (opener && opener.isConnected) opener.focus();
|
|
97
|
+
};
|
|
98
|
+
}, []);
|
|
99
|
+
const errorsOf = (name)=>errors.filter((error)=>error.field === name);
|
|
100
|
+
const fieldNames = new Set(fields.map((field)=>field.name));
|
|
101
|
+
const general = errors.filter((error)=>error.field === undefined || !fieldNames.has(error.field));
|
|
102
|
+
const submit = async (event)=>{
|
|
103
|
+
event.preventDefault();
|
|
104
|
+
if (submitting) return;
|
|
105
|
+
const missing = fields.filter((field)=>field.required && (values[field.name] === undefined || values[field.name] === '')).map((field)=>({
|
|
106
|
+
field: field.name,
|
|
107
|
+
message: `${sliceFieldLabel(field)} is required.`
|
|
108
|
+
}));
|
|
109
|
+
setErrors(missing);
|
|
110
|
+
if (missing.length > 0) {
|
|
111
|
+
form.current?.querySelector('[aria-invalid="true"]')?.focus();
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
setSubmitting(true);
|
|
115
|
+
try {
|
|
116
|
+
const result = await invoker.invoke(slice, slicePayload(fields, values), command);
|
|
117
|
+
if (result.succeeded) {
|
|
118
|
+
close(result);
|
|
119
|
+
} else {
|
|
120
|
+
const reported = result.validationErrors ?? [];
|
|
121
|
+
setErrors(reported.length > 0 || !result.message ? reported : [
|
|
122
|
+
{
|
|
123
|
+
message: result.message
|
|
124
|
+
}
|
|
125
|
+
]);
|
|
126
|
+
}
|
|
127
|
+
} finally{
|
|
128
|
+
setSubmitting(false);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
const onKeyDown = (event)=>{
|
|
132
|
+
if (event.key === 'Escape') {
|
|
133
|
+
event.preventDefault();
|
|
134
|
+
close();
|
|
135
|
+
} else if (event.key === 'Tab') {
|
|
136
|
+
const targets = Array.from(form.current?.querySelectorAll(focusable) ?? []);
|
|
137
|
+
if (targets.length === 0) return;
|
|
138
|
+
const first = targets[0];
|
|
139
|
+
const last = targets[targets.length - 1];
|
|
140
|
+
if (event.shiftKey && document.activeElement === first) {
|
|
141
|
+
event.preventDefault();
|
|
142
|
+
last.focus();
|
|
143
|
+
} else if (!event.shiftKey && document.activeElement === last) {
|
|
144
|
+
event.preventDefault();
|
|
145
|
+
first.focus();
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
return /*#__PURE__*/ jsxs("form", {
|
|
150
|
+
ref: form,
|
|
151
|
+
className: "scene-slice-dialog",
|
|
152
|
+
"data-scene-slice-dialog": slice,
|
|
153
|
+
"data-scene-command": command,
|
|
154
|
+
noValidate: true,
|
|
155
|
+
onSubmit: submit,
|
|
156
|
+
onKeyDown: onKeyDown,
|
|
157
|
+
children: [
|
|
158
|
+
/*#__PURE__*/ jsxs("header", {
|
|
159
|
+
className: "scene-slice-dialog-header",
|
|
160
|
+
children: [
|
|
161
|
+
/*#__PURE__*/ jsx("h2", {
|
|
162
|
+
className: "scene-slice-dialog-title",
|
|
163
|
+
children: title
|
|
164
|
+
}),
|
|
165
|
+
/*#__PURE__*/ jsxs("p", {
|
|
166
|
+
className: "scene-slice-dialog-subtitle",
|
|
167
|
+
children: [
|
|
168
|
+
"State Change · ",
|
|
169
|
+
sliceName
|
|
170
|
+
]
|
|
171
|
+
})
|
|
172
|
+
]
|
|
173
|
+
}),
|
|
174
|
+
/*#__PURE__*/ jsx("div", {
|
|
175
|
+
className: "scene-slice-dialog-fields",
|
|
176
|
+
children: fields.map((field)=>{
|
|
177
|
+
const id = `${identity}-${field.name}`;
|
|
178
|
+
const own = errorsOf(field.name);
|
|
179
|
+
const type = inputTypeOf(field);
|
|
180
|
+
const description = own.length > 0 ? `${id}-error` : undefined;
|
|
181
|
+
return /*#__PURE__*/ jsxs("div", {
|
|
182
|
+
className: "scene-slice-dialog-field",
|
|
183
|
+
"data-type": type,
|
|
184
|
+
children: [
|
|
185
|
+
/*#__PURE__*/ jsxs("label", {
|
|
186
|
+
htmlFor: id,
|
|
187
|
+
children: [
|
|
188
|
+
sliceFieldLabel(field),
|
|
189
|
+
field.required ? /*#__PURE__*/ jsx("span", {
|
|
190
|
+
"aria-hidden": "true",
|
|
191
|
+
children: " *"
|
|
192
|
+
}) : null
|
|
193
|
+
]
|
|
194
|
+
}),
|
|
195
|
+
/*#__PURE__*/ jsx("input", {
|
|
196
|
+
id: id,
|
|
197
|
+
name: field.name,
|
|
198
|
+
type: type,
|
|
199
|
+
required: field.required,
|
|
200
|
+
"aria-required": field.required || undefined,
|
|
201
|
+
"aria-invalid": own.length > 0 ? true : undefined,
|
|
202
|
+
"aria-describedby": description,
|
|
203
|
+
...type === 'checkbox' ? {
|
|
204
|
+
checked: values[field.name] === true
|
|
205
|
+
} : {
|
|
206
|
+
value: values[field.name] ?? ''
|
|
207
|
+
},
|
|
208
|
+
onChange: (event)=>setValues({
|
|
209
|
+
...values,
|
|
210
|
+
[field.name]: type === 'checkbox' ? event.target.checked : event.target.value
|
|
211
|
+
})
|
|
212
|
+
}),
|
|
213
|
+
own.length > 0 && /*#__PURE__*/ jsx("p", {
|
|
214
|
+
id: description,
|
|
215
|
+
className: "scene-slice-dialog-error",
|
|
216
|
+
role: "alert",
|
|
217
|
+
children: own.map((error)=>error.message).join(' ')
|
|
218
|
+
})
|
|
219
|
+
]
|
|
220
|
+
}, field.name);
|
|
221
|
+
})
|
|
222
|
+
}),
|
|
223
|
+
general.length > 0 && /*#__PURE__*/ jsx("p", {
|
|
224
|
+
className: "scene-slice-dialog-error scene-slice-dialog-summary",
|
|
225
|
+
role: "alert",
|
|
226
|
+
children: general.map((error)=>error.message).join(' ')
|
|
227
|
+
}),
|
|
228
|
+
/*#__PURE__*/ jsxs("footer", {
|
|
229
|
+
className: "scene-slice-dialog-footer",
|
|
230
|
+
children: [
|
|
231
|
+
/*#__PURE__*/ jsx("button", {
|
|
232
|
+
type: "button",
|
|
233
|
+
className: "scene-slice-dialog-cancel",
|
|
234
|
+
onClick: ()=>close(),
|
|
235
|
+
children: "Cancel"
|
|
236
|
+
}),
|
|
237
|
+
/*#__PURE__*/ jsx("button", {
|
|
238
|
+
type: "submit",
|
|
239
|
+
className: "scene-slice-dialog-submit",
|
|
240
|
+
disabled: submitting,
|
|
241
|
+
children: title
|
|
242
|
+
})
|
|
243
|
+
]
|
|
244
|
+
})
|
|
245
|
+
]
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export { SliceDialogView, sliceFieldLabel, slicePayload };
|
|
250
|
+
//# sourceMappingURL=SliceDialogView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SliceDialogView.js","sources":["../../../slices/SliceDialogView.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { FormEvent, KeyboardEvent, useContext, useEffect, useId, useMemo, useRef, useState } from 'react';\nimport { ApplicationStructureIndex } from '@cratis/scene.engine';\nimport { SceneNavigationContextInternal } from '../navigation/SceneNavigationContext';\nimport { useSceneNavigationModel } from '../navigation/region/SceneNavigationModelContext';\nimport { InvocationResult } from './InvocationResult';\nimport { InvocationValidationError } from './InvocationValidationError';\nimport { SliceCommandField } from './SliceCommandField';\nimport { useSliceCommandFields } from './SliceCommandFieldsContext';\nimport { useSliceInvoker } from './SliceInvokerContext';\nimport { sliceDialogParameters } from './sliceDialogDestination';\n\nexport interface SliceDialogViewProps {\n /** The qualified id of the slice; the open dialog's `slice` parameter when absent. */\n slice?: string;\n\n /** The command the slice accepts; the open dialog's `command` parameter when absent. */\n command?: string;\n\n /** The title - the toolbar button's - also the label of the submit button; the open dialog's `title` parameter when absent. */\n title?: string;\n\n /** Called when the dialog is cancelled or the slice accepted the command; the host's `closeDialog` when absent. */\n onClose?(result?: InvocationResult): void;\n}\n\nconst focusable = 'input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [href], [tabindex]:not([tabindex=\"-1\"])';\n\n/** A label for a command property: `customerName` becomes `Customer name`. */\nexport function sliceFieldLabel(field: SliceCommandField): string {\n if (field.label) return field.label;\n const spaced = field.name.replace(/([a-z0-9])([A-Z])/g, '$1 $2').replace(/[_-]+/g, ' ').trim().toLowerCase();\n return spaced.charAt(0).toUpperCase() + spaced.slice(1);\n}\n\nfunction inputTypeOf(field: SliceCommandField): string {\n switch (field.type.toLowerCase()) {\n case 'number': case 'int': case 'integer': case 'long': case 'double': case 'decimal': case 'float': case 'single': case 'int32': case 'int64': return 'number';\n case 'boolean': case 'bool': return 'checkbox';\n case 'date': case 'dateonly': return 'date';\n default: return 'text';\n }\n}\n\n/** The payload a form's values make: numbers and booleans as such, an empty number left out. */\nexport function slicePayload(fields: SliceCommandField[], values: Record<string, string | boolean>): Record<string, unknown> {\n const payload: Record<string, unknown> = {};\n for (const field of fields) {\n const value = values[field.name];\n const type = inputTypeOf(field);\n if (type === 'checkbox') payload[field.name] = value === true;\n else if (type === 'number') { if (value !== undefined && value !== '') payload[field.name] = Number(value); }\n else payload[field.name] = value ?? '';\n }\n\n return payload;\n}\n\n/**\n * The task dialog of a toolbar slice button (TB4): a modal card with the button's title, the slice as its subtitle, a labelled\n * field for each command property, and Cancel and a submit button labelled with the title.\n *\n * - The first field takes focus when it opens, Tab stays inside, Escape cancels, and focus returns to the button that opened it.\n * - Submit validates required fields, then calls the `SliceInvoker` in scope - real, dry-run or the announcing default. The\n * problems it reports are shown against their fields (`aria-invalid`, `aria-describedby`) or for the form; success closes the\n * dialog and hands the result to the host (`dialogResult`).\n * - The fields come from the `SliceCommandFieldsProvider`; the subtitle names the slice from the navigation model.\n *\n * Inside a navigation host it is the content of the dialog a toolbar button opens; `core:sliceDialog` registers it so a host can\n * author the dialog template with it.\n */\nexport function SliceDialogView({ slice: sliceProp, command: commandProp, title: titleProp, onClose }: SliceDialogViewProps) {\n const navigation = useContext(SceneNavigationContextInternal);\n const opened = sliceDialogParameters(navigation?.currentDialogParameters);\n const slice = sliceProp ?? opened?.slice ?? '';\n const command = commandProp ?? opened?.command ?? slice;\n const title = titleProp ?? opened?.title ?? command;\n\n const invoker = useSliceInvoker();\n const fieldsFor = useSliceCommandFields();\n const model = useSceneNavigationModel();\n const fields = useMemo(() => fieldsFor?.(command, slice) ?? [], [command, fieldsFor, slice]);\n const sliceName = useMemo(() => {\n if (!model) return slice.split('.').pop() ?? slice;\n const index = model.structure instanceof ApplicationStructureIndex ? model.structure : new ApplicationStructureIndex(model.structure);\n return index.findSlice(slice)?.id ?? slice.split('.').pop() ?? slice;\n }, [model, slice]);\n\n const [values, setValues] = useState<Record<string, string | boolean>>({});\n const [errors, setErrors] = useState<InvocationValidationError[]>([]);\n const [submitting, setSubmitting] = useState(false);\n const form = useRef<HTMLFormElement>(null);\n const identity = useId();\n\n const close = (result?: InvocationResult) => onClose ? onClose(result) : navigation?.closeDialog(result);\n\n // Focus the first field, and give focus back to whatever opened the dialog when it goes.\n useEffect(() => {\n const opener = document.activeElement as HTMLElement | null;\n (form.current?.querySelector<HTMLElement>('input, select, textarea') ?? form.current?.querySelector<HTMLElement>('button'))?.focus();\n return () => { if (opener && opener.isConnected) opener.focus(); };\n }, []);\n\n const errorsOf = (name: string | undefined) => errors.filter(error => error.field === name);\n const fieldNames = new Set(fields.map(field => field.name));\n const general = errors.filter(error => error.field === undefined || !fieldNames.has(error.field));\n\n const submit = async (event: FormEvent) => {\n event.preventDefault();\n if (submitting) return;\n\n const missing = fields.filter(field => field.required && (values[field.name] === undefined || values[field.name] === '')).map(field => ({ field: field.name, message: `${sliceFieldLabel(field)} is required.` }));\n setErrors(missing);\n if (missing.length > 0) {\n form.current?.querySelector<HTMLElement>('[aria-invalid=\"true\"]')?.focus();\n return;\n }\n\n setSubmitting(true);\n try {\n const result = await invoker.invoke(slice, slicePayload(fields, values), command);\n if (result.succeeded) {\n close(result);\n } else {\n const reported = result.validationErrors ?? [];\n setErrors(reported.length > 0 || !result.message ? reported : [{ message: result.message }]);\n }\n } finally {\n setSubmitting(false);\n }\n };\n\n const onKeyDown = (event: KeyboardEvent<HTMLFormElement>) => {\n if (event.key === 'Escape') {\n event.preventDefault();\n close();\n } else if (event.key === 'Tab') {\n const targets = Array.from(form.current?.querySelectorAll<HTMLElement>(focusable) ?? []);\n if (targets.length === 0) return;\n const first = targets[0];\n const last = targets[targets.length - 1];\n if (event.shiftKey && document.activeElement === first) { event.preventDefault(); last.focus(); }\n else if (!event.shiftKey && document.activeElement === last) { event.preventDefault(); first.focus(); }\n }\n };\n\n return <form ref={form} className='scene-slice-dialog' data-scene-slice-dialog={slice} data-scene-command={command} noValidate onSubmit={submit} onKeyDown={onKeyDown}>\n <header className='scene-slice-dialog-header'>\n <h2 className='scene-slice-dialog-title'>{title}</h2>\n <p className='scene-slice-dialog-subtitle'>State Change · {sliceName}</p>\n </header>\n <div className='scene-slice-dialog-fields'>\n {fields.map(field => {\n const id = `${identity}-${field.name}`;\n const own = errorsOf(field.name);\n const type = inputTypeOf(field);\n const description = own.length > 0 ? `${id}-error` : undefined;\n return <div key={field.name} className='scene-slice-dialog-field' data-type={type}>\n <label htmlFor={id}>{sliceFieldLabel(field)}{field.required ? <span aria-hidden='true'> *</span> : null}</label>\n <input id={id} name={field.name} type={type} required={field.required} aria-required={field.required || undefined}\n aria-invalid={own.length > 0 ? true : undefined} aria-describedby={description}\n {...(type === 'checkbox' ? { checked: values[field.name] === true } : { value: (values[field.name] as string | undefined) ?? '' })}\n onChange={event => setValues({ ...values, [field.name]: type === 'checkbox' ? event.target.checked : event.target.value })} />\n {own.length > 0 && <p id={description} className='scene-slice-dialog-error' role='alert'>{own.map(error => error.message).join(' ')}</p>}\n </div>;\n })}\n </div>\n {general.length > 0 && <p className='scene-slice-dialog-error scene-slice-dialog-summary' role='alert'>{general.map(error => error.message).join(' ')}</p>}\n <footer className='scene-slice-dialog-footer'>\n <button type='button' className='scene-slice-dialog-cancel' onClick={() => close()}>Cancel</button>\n <button type='submit' className='scene-slice-dialog-submit' disabled={submitting}>{title}</button>\n </footer>\n </form>;\n}\n"],"names":["focusable","sliceFieldLabel","field","label","spaced","name","replace","trim","toLowerCase","charAt","toUpperCase","slice","inputTypeOf","type","slicePayload","fields","values","payload","value","undefined","Number","SliceDialogView","sliceProp","command","commandProp","title","titleProp","onClose","navigation","useContext","SceneNavigationContextInternal","opened","sliceDialogParameters","currentDialogParameters","invoker","useSliceInvoker","fieldsFor","useSliceCommandFields","model","useSceneNavigationModel","useMemo","sliceName","split","pop","index","structure","ApplicationStructureIndex","findSlice","id","setValues","useState","errors","setErrors","submitting","setSubmitting","form","useRef","identity","useId","close","result","closeDialog","useEffect","opener","document","activeElement","current","querySelector","focus","isConnected","errorsOf","filter","error","fieldNames","Set","map","general","has","submit","event","preventDefault","missing","required","message","length","invoke","succeeded","reported","validationErrors","onKeyDown","key","targets","Array","from","querySelectorAll","first","last","shiftKey","_jsxs","ref","className","data-scene-slice-dialog","data-scene-command","noValidate","onSubmit","header","_jsx","h2","p","div","own","description","data-type","htmlFor","span","aria-hidden","input","aria-required","aria-invalid","aria-describedby","checked","onChange","target","role","join","footer","button","onClick","disabled"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SliceInvoker.d.ts","sourceRoot":"","sources":["../../../slices/SliceInvoker.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAOtD,MAAM,WAAW,YAAY;IAOzB,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAC1G"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SliceInvoker.js","sourceRoot":"","sources":["../../../slices/SliceInvoker.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { SliceInvoker } from './SliceInvoker';
|
|
3
|
+
export interface SliceInvokerProviderProps {
|
|
4
|
+
invoker: SliceInvoker;
|
|
5
|
+
warnEmptySlices?: boolean;
|
|
6
|
+
children?: ReactNode;
|
|
7
|
+
}
|
|
8
|
+
export declare function SliceInvokerProvider({ invoker, warnEmptySlices, children }: SliceInvokerProviderProps): import("react").JSX.Element;
|
|
9
|
+
export declare function useSliceInvoker(): SliceInvoker;
|
|
10
|
+
export declare function useWarnEmptySlices(): boolean;
|
|
11
|
+
//# sourceMappingURL=SliceInvokerContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SliceInvokerContext.d.ts","sourceRoot":"","sources":["../../../slices/SliceInvokerContext.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAsC,MAAM,OAAO,CAAC;AAEtE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAW9C,MAAM,WAAW,yBAAyB;IAEtC,OAAO,EAAE,YAAY,CAAC;IAMtB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,EAAE,SAAS,CAAC;CACxB;AAMD,wBAAgB,oBAAoB,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,EAAE,yBAAyB,+BAIrG;AAGD,wBAAgB,eAAe,IAAI,YAAY,CAE9C;AAGD,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useMemo, useContext, createContext } from 'react';
|
|
3
|
+
import { createAnnouncingInvoker } from './createAnnouncingInvoker.js';
|
|
4
|
+
|
|
5
|
+
const announcing = createAnnouncingInvoker();
|
|
6
|
+
const defaultScope = {
|
|
7
|
+
invoker: announcing,
|
|
8
|
+
warnEmptySlices: false
|
|
9
|
+
};
|
|
10
|
+
const Context = /*#__PURE__*/ createContext(defaultScope);
|
|
11
|
+
/**
|
|
12
|
+
* Supplies the `sliceInvoker` every toolbar dialog below it submits through: a real one in Stage, a dry-run one in the Studio
|
|
13
|
+
* preview. Without a provider the command is announced as `cratis.scene.command`.
|
|
14
|
+
*/ function SliceInvokerProvider({ invoker, warnEmptySlices, children }) {
|
|
15
|
+
const warn = warnEmptySlices ?? invoker.dryRun === true;
|
|
16
|
+
const value = useMemo(()=>({
|
|
17
|
+
invoker,
|
|
18
|
+
warnEmptySlices: warn
|
|
19
|
+
}), [
|
|
20
|
+
invoker,
|
|
21
|
+
warn
|
|
22
|
+
]);
|
|
23
|
+
return /*#__PURE__*/ jsx(Context.Provider, {
|
|
24
|
+
value: value,
|
|
25
|
+
children: children
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/** The invoker in scope: the provider's, or the one that announces the command. */ function useSliceInvoker() {
|
|
29
|
+
return useContext(Context).invoker;
|
|
30
|
+
}
|
|
31
|
+
/** Whether a button without a slice should show a warning badge here. */ function useWarnEmptySlices() {
|
|
32
|
+
return useContext(Context).warnEmptySlices;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export { SliceInvokerProvider, useSliceInvoker, useWarnEmptySlices };
|
|
36
|
+
//# sourceMappingURL=SliceInvokerContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SliceInvokerContext.js","sources":["../../../slices/SliceInvokerContext.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { ReactNode, createContext, useContext, useMemo } from 'react';\nimport { createAnnouncingInvoker } from './createAnnouncingInvoker';\nimport { SliceInvoker } from './SliceInvoker';\n\ninterface SliceInvokerScope {\n invoker: SliceInvoker;\n warnEmptySlices: boolean;\n}\n\nconst announcing = createAnnouncingInvoker();\nconst defaultScope: SliceInvokerScope = { invoker: announcing, warnEmptySlices: false };\nconst Context = createContext<SliceInvokerScope>(defaultScope);\n\nexport interface SliceInvokerProviderProps {\n /** The invoker toolbar dialogs submit through. */\n invoker: SliceInvoker;\n\n /**\n * Whether a toolbar button without a slice shows a warning badge. Design and preview hosts turn it on (TB5); a\n * running application never shows it. A dry-run invoker implies it.\n */\n warnEmptySlices?: boolean;\n children?: ReactNode;\n}\n\n/**\n * Supplies the `sliceInvoker` every toolbar dialog below it submits through: a real one in Stage, a dry-run one in the Studio\n * preview. Without a provider the command is announced as `cratis.scene.command`.\n */\nexport function SliceInvokerProvider({ invoker, warnEmptySlices, children }: SliceInvokerProviderProps) {\n const warn = warnEmptySlices ?? (invoker as { dryRun?: boolean }).dryRun === true;\n const value = useMemo(() => ({ invoker, warnEmptySlices: warn }), [invoker, warn]);\n return <Context.Provider value={value}>{children}</Context.Provider>;\n}\n\n/** The invoker in scope: the provider's, or the one that announces the command. */\nexport function useSliceInvoker(): SliceInvoker {\n return useContext(Context).invoker;\n}\n\n/** Whether a button without a slice should show a warning badge here. */\nexport function useWarnEmptySlices(): boolean {\n return useContext(Context).warnEmptySlices;\n}\n"],"names":["announcing","createAnnouncingInvoker","defaultScope","invoker","warnEmptySlices","Context","createContext","SliceInvokerProvider","children","warn","dryRun","value","useMemo","_jsx","Provider","useSliceInvoker","useContext","useWarnEmptySlices"],"mappings":";;;;AAYA,MAAMA,UAAAA,GAAaC,uBAAAA,EAAAA;AACnB,MAAMC,YAAAA,GAAkC;IAAEC,OAAAA,EAASH,UAAAA;IAAYI,eAAAA,EAAiB;AAAM,CAAA;AACtF,MAAMC,wBAAUC,aAAAA,CAAiCJ,YAAAA,CAAAA;AAcjD;;;IAIO,SAASK,oBAAAA,CAAqB,EAAEJ,OAAO,EAAEC,eAAe,EAAEI,QAAQ,EAA6B,EAAA;AAClG,IAAA,MAAMC,IAAAA,GAAOL,eAAAA,IAAmB,OAACD,CAAiCO,MAAM,KAAK,IAAA;IAC7E,MAAMC,KAAAA,GAAQC,OAAAA,CAAQ,KAAO;AAAET,YAAAA,OAAAA;YAASC,eAAAA,EAAiBK;AAAK,SAAA,CAAA,EAAI;AAACN,QAAAA,OAAAA;AAASM,QAAAA;AAAK,KAAA,CAAA;IACjF,qBAAOI,GAAA,CAACR,QAAQS,QAAQ,EAAA;QAACH,KAAAA,EAAOA,KAAAA;AAAQH,QAAAA,QAAAA,EAAAA;;AAC5C;AAEA,oFACO,SAASO,eAAAA,GAAAA;IACZ,OAAOC,UAAAA,CAAWX,SAASF,OAAO;AACtC;AAEA,0EACO,SAASc,kBAAAA,GAAAA;IACZ,OAAOD,UAAAA,CAAWX,SAASD,eAAe;AAC9C;;"}
|