@cratis/scene.blueprint.default 4.32.0 → 4.34.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.
Files changed (249) hide show
  1. package/ComponentName.ts +12 -0
  2. package/defaultBlueprintComponents.ts +5 -1
  3. package/dist/cjs/ComponentName.js +4 -0
  4. package/dist/cjs/ComponentName.js.map +1 -1
  5. package/dist/cjs/defaultBlueprint.js +1 -1
  6. package/dist/cjs/defaultBlueprintComponentMetadata.js +2 -2
  7. package/dist/cjs/defaultBlueprintComponents.js +10 -2
  8. package/dist/cjs/defaultBlueprintComponents.js.map +1 -1
  9. package/dist/cjs/foundation/ChartWrapper.js +520 -0
  10. package/dist/cjs/foundation/ChartWrapper.js.map +1 -0
  11. package/dist/cjs/foundation/ColumnChooser.js +156 -0
  12. package/dist/cjs/foundation/ColumnChooser.js.map +1 -0
  13. package/dist/cjs/foundation/FilterBuilder.js +307 -0
  14. package/dist/cjs/foundation/FilterBuilder.js.map +1 -0
  15. package/dist/cjs/foundation/SavedViewsMenu.js +199 -0
  16. package/dist/cjs/foundation/SavedViewsMenu.js.map +1 -0
  17. package/dist/cjs/foundation/chartGeometry.js +101 -0
  18. package/dist/cjs/foundation/chartGeometry.js.map +1 -0
  19. package/dist/cjs/foundation/columnModel.js +43 -0
  20. package/dist/cjs/foundation/columnModel.js.map +1 -0
  21. package/dist/cjs/foundation/filterModel.js +123 -0
  22. package/dist/cjs/foundation/filterModel.js.map +1 -0
  23. package/dist/cjs/foundation/foundationComponentMetadata.js +28 -0
  24. package/dist/cjs/foundation/foundationComponentMetadata.js.map +1 -1
  25. package/dist/cjs/foundation/foundationDescriptors.js +153 -0
  26. package/dist/cjs/foundation/foundationDescriptors.js.map +1 -1
  27. package/dist/cjs/foundation/foundationSamples.js +130 -0
  28. package/dist/cjs/foundation/foundationSamples.js.map +1 -1
  29. package/dist/cjs/foundation/foundationStrings.js +25 -0
  30. package/dist/cjs/foundation/foundationStrings.js.map +1 -1
  31. package/dist/cjs/foundation/useElementWidth.js +31 -0
  32. package/dist/cjs/foundation/useElementWidth.js.map +1 -0
  33. package/dist/cjs/foundation/viewModel.js +24 -0
  34. package/dist/cjs/foundation/viewModel.js.map +1 -0
  35. package/dist/cjs/index.js +91 -4
  36. package/dist/cjs/index.js.map +1 -1
  37. package/dist/cjs/preview-host/ApplicationDocument.js +17 -0
  38. package/dist/cjs/preview-host/ApplicationDocument.js.map +1 -0
  39. package/dist/cjs/preview-host/ApplicationHost.js +113 -0
  40. package/dist/cjs/preview-host/ApplicationHost.js.map +1 -0
  41. package/dist/cjs/preview-host/FlowArrangementView.js +75 -0
  42. package/dist/cjs/preview-host/FlowArrangementView.js.map +1 -0
  43. package/dist/cjs/preview-host/PreviewProblem.js +32 -0
  44. package/dist/cjs/preview-host/PreviewProblem.js.map +1 -0
  45. package/dist/cjs/preview-host/PreviewProblemsView.js +51 -0
  46. package/dist/cjs/preview-host/PreviewProblemsView.js.map +1 -0
  47. package/dist/cjs/preview-host/PreviewSliceFragment.js +55 -0
  48. package/dist/cjs/preview-host/PreviewSliceFragment.js.map +1 -0
  49. package/dist/cjs/preview-host/PreviewTarget.js +17 -0
  50. package/dist/cjs/preview-host/PreviewTarget.js.map +1 -0
  51. package/dist/cjs/preview-host/PreviewTemplate.js +49 -0
  52. package/dist/cjs/preview-host/PreviewTemplate.js.map +1 -0
  53. package/dist/cjs/preview-host/PreviewToast.js +45 -0
  54. package/dist/cjs/preview-host/PreviewToast.js.map +1 -0
  55. package/dist/cjs/preview-host/ScenePreviewHost.js +290 -0
  56. package/dist/cjs/preview-host/ScenePreviewHost.js.map +1 -0
  57. package/dist/cjs/preview-host/composeApplication.js +249 -0
  58. package/dist/cjs/preview-host/composeApplication.js.map +1 -0
  59. package/dist/cjs/preview-host/defaultApplicationChrome.js +43 -0
  60. package/dist/cjs/preview-host/defaultApplicationChrome.js.map +1 -0
  61. package/dist/cjs/preview-host/diagnosePreview.js +100 -0
  62. package/dist/cjs/preview-host/diagnosePreview.js.map +1 -0
  63. package/dist/cjs/preview-host/previewProfile.js +53 -0
  64. package/dist/cjs/preview-host/previewProfile.js.map +1 -0
  65. package/dist/cjs/preview-host/previewSampleData.js +116 -0
  66. package/dist/cjs/preview-host/previewSampleData.js.map +1 -0
  67. package/dist/cjs/preview-host/resolvePreviewPlan.js +126 -0
  68. package/dist/cjs/preview-host/resolvePreviewPlan.js.map +1 -0
  69. package/dist/cjs/preview-host/useSizeClass.js +23 -0
  70. package/dist/cjs/preview-host/useSizeClass.js.map +1 -0
  71. package/dist/esm/ComponentName.d.ts +5 -1
  72. package/dist/esm/ComponentName.d.ts.map +1 -1
  73. package/dist/esm/ComponentName.js +4 -0
  74. package/dist/esm/ComponentName.js.map +1 -1
  75. package/dist/esm/defaultBlueprint.js +1 -1
  76. package/dist/esm/defaultBlueprintComponentMetadata.js +2 -2
  77. package/dist/esm/defaultBlueprintComponents.d.ts.map +1 -1
  78. package/dist/esm/defaultBlueprintComponents.js +10 -2
  79. package/dist/esm/defaultBlueprintComponents.js.map +1 -1
  80. package/dist/esm/foundation/ChartWrapper.d.ts +5 -0
  81. package/dist/esm/foundation/ChartWrapper.d.ts.map +1 -0
  82. package/dist/esm/foundation/ChartWrapper.js +517 -0
  83. package/dist/esm/foundation/ChartWrapper.js.map +1 -0
  84. package/dist/esm/foundation/ColumnChooser.d.ts +3 -0
  85. package/dist/esm/foundation/ColumnChooser.d.ts.map +1 -0
  86. package/dist/esm/foundation/ColumnChooser.js +154 -0
  87. package/dist/esm/foundation/ColumnChooser.js.map +1 -0
  88. package/dist/esm/foundation/FilterBuilder.d.ts +3 -0
  89. package/dist/esm/foundation/FilterBuilder.d.ts.map +1 -0
  90. package/dist/esm/foundation/FilterBuilder.js +305 -0
  91. package/dist/esm/foundation/FilterBuilder.js.map +1 -0
  92. package/dist/esm/foundation/Foundation.stories.d.ts +16 -0
  93. package/dist/esm/foundation/Foundation.stories.d.ts.map +1 -1
  94. package/dist/esm/foundation/Foundation.stories.js +16 -0
  95. package/dist/esm/foundation/Foundation.stories.js.map +1 -1
  96. package/dist/esm/foundation/SavedViewsMenu.d.ts +4 -0
  97. package/dist/esm/foundation/SavedViewsMenu.d.ts.map +1 -0
  98. package/dist/esm/foundation/SavedViewsMenu.js +196 -0
  99. package/dist/esm/foundation/SavedViewsMenu.js.map +1 -0
  100. package/dist/esm/foundation/chartGeometry.d.ts +34 -0
  101. package/dist/esm/foundation/chartGeometry.d.ts.map +1 -0
  102. package/dist/esm/foundation/chartGeometry.js +93 -0
  103. package/dist/esm/foundation/chartGeometry.js.map +1 -0
  104. package/dist/esm/foundation/columnModel.d.ts +11 -0
  105. package/dist/esm/foundation/columnModel.d.ts.map +1 -0
  106. package/dist/esm/foundation/columnModel.js +38 -0
  107. package/dist/esm/foundation/columnModel.js.map +1 -0
  108. package/dist/esm/foundation/filterModel.d.ts +33 -0
  109. package/dist/esm/foundation/filterModel.d.ts.map +1 -0
  110. package/dist/esm/foundation/filterModel.js +112 -0
  111. package/dist/esm/foundation/filterModel.js.map +1 -0
  112. package/dist/esm/foundation/foundationComponentMetadata.d.ts.map +1 -1
  113. package/dist/esm/foundation/foundationComponentMetadata.js +28 -0
  114. package/dist/esm/foundation/foundationComponentMetadata.js.map +1 -1
  115. package/dist/esm/foundation/foundationDescriptors.d.ts.map +1 -1
  116. package/dist/esm/foundation/foundationDescriptors.js +154 -1
  117. package/dist/esm/foundation/foundationDescriptors.js.map +1 -1
  118. package/dist/esm/foundation/foundationSamples.d.ts.map +1 -1
  119. package/dist/esm/foundation/foundationSamples.js +130 -0
  120. package/dist/esm/foundation/foundationSamples.js.map +1 -1
  121. package/dist/esm/foundation/foundationStrings.d.ts +25 -0
  122. package/dist/esm/foundation/foundationStrings.d.ts.map +1 -1
  123. package/dist/esm/foundation/foundationStrings.js +25 -0
  124. package/dist/esm/foundation/foundationStrings.js.map +1 -1
  125. package/dist/esm/foundation/index.d.ts +9 -0
  126. package/dist/esm/foundation/index.d.ts.map +1 -1
  127. package/dist/esm/foundation/index.js +9 -0
  128. package/dist/esm/foundation/index.js.map +1 -1
  129. package/dist/esm/foundation/useElementWidth.d.ts +3 -0
  130. package/dist/esm/foundation/useElementWidth.d.ts.map +1 -0
  131. package/dist/esm/foundation/useElementWidth.js +29 -0
  132. package/dist/esm/foundation/useElementWidth.js.map +1 -0
  133. package/dist/esm/foundation/viewModel.d.ts +7 -0
  134. package/dist/esm/foundation/viewModel.d.ts.map +1 -0
  135. package/dist/esm/foundation/viewModel.js +22 -0
  136. package/dist/esm/foundation/viewModel.js.map +1 -0
  137. package/dist/esm/index.d.ts +1 -0
  138. package/dist/esm/index.d.ts.map +1 -1
  139. package/dist/esm/index.js +26 -0
  140. package/dist/esm/index.js.map +1 -1
  141. package/dist/esm/preview-host/ApplicationDocument.d.ts +7 -0
  142. package/dist/esm/preview-host/ApplicationDocument.d.ts.map +1 -0
  143. package/dist/esm/preview-host/ApplicationDocument.js +15 -0
  144. package/dist/esm/preview-host/ApplicationDocument.js.map +1 -0
  145. package/dist/esm/preview-host/ApplicationHost.d.ts +21 -0
  146. package/dist/esm/preview-host/ApplicationHost.d.ts.map +1 -0
  147. package/dist/esm/preview-host/ApplicationHost.js +111 -0
  148. package/dist/esm/preview-host/ApplicationHost.js.map +1 -0
  149. package/dist/esm/preview-host/FlowArrangementView.d.ts +7 -0
  150. package/dist/esm/preview-host/FlowArrangementView.d.ts.map +1 -0
  151. package/dist/esm/preview-host/FlowArrangementView.js +73 -0
  152. package/dist/esm/preview-host/FlowArrangementView.js.map +1 -0
  153. package/dist/esm/preview-host/PreviewProblem.d.ts +26 -0
  154. package/dist/esm/preview-host/PreviewProblem.d.ts.map +1 -0
  155. package/dist/esm/preview-host/PreviewProblem.js +28 -0
  156. package/dist/esm/preview-host/PreviewProblem.js.map +1 -0
  157. package/dist/esm/preview-host/PreviewProblemsView.d.ts +7 -0
  158. package/dist/esm/preview-host/PreviewProblemsView.d.ts.map +1 -0
  159. package/dist/esm/preview-host/PreviewProblemsView.js +49 -0
  160. package/dist/esm/preview-host/PreviewProblemsView.js.map +1 -0
  161. package/dist/esm/preview-host/PreviewSliceFragment.d.ts +3 -0
  162. package/dist/esm/preview-host/PreviewSliceFragment.d.ts.map +1 -0
  163. package/dist/esm/preview-host/PreviewSliceFragment.js +53 -0
  164. package/dist/esm/preview-host/PreviewSliceFragment.js.map +1 -0
  165. package/dist/esm/preview-host/PreviewTarget.d.ts +10 -0
  166. package/dist/esm/preview-host/PreviewTarget.d.ts.map +1 -0
  167. package/dist/esm/preview-host/PreviewTarget.js +15 -0
  168. package/dist/esm/preview-host/PreviewTarget.js.map +1 -0
  169. package/dist/esm/preview-host/PreviewTemplate.d.ts +5 -0
  170. package/dist/esm/preview-host/PreviewTemplate.d.ts.map +1 -0
  171. package/dist/esm/preview-host/PreviewTemplate.js +45 -0
  172. package/dist/esm/preview-host/PreviewTemplate.js.map +1 -0
  173. package/dist/esm/preview-host/PreviewToast.d.ts +10 -0
  174. package/dist/esm/preview-host/PreviewToast.d.ts.map +1 -0
  175. package/dist/esm/preview-host/PreviewToast.js +43 -0
  176. package/dist/esm/preview-host/PreviewToast.js.map +1 -0
  177. package/dist/esm/preview-host/ScenePreviewHost.d.ts +32 -0
  178. package/dist/esm/preview-host/ScenePreviewHost.d.ts.map +1 -0
  179. package/dist/esm/preview-host/ScenePreviewHost.js +288 -0
  180. package/dist/esm/preview-host/ScenePreviewHost.js.map +1 -0
  181. package/dist/esm/preview-host/composeApplication.d.ts +34 -0
  182. package/dist/esm/preview-host/composeApplication.d.ts.map +1 -0
  183. package/dist/esm/preview-host/composeApplication.js +239 -0
  184. package/dist/esm/preview-host/composeApplication.js.map +1 -0
  185. package/dist/esm/preview-host/defaultApplicationChrome.d.ts +4 -0
  186. package/dist/esm/preview-host/defaultApplicationChrome.d.ts.map +1 -0
  187. package/dist/esm/preview-host/defaultApplicationChrome.js +41 -0
  188. package/dist/esm/preview-host/defaultApplicationChrome.js.map +1 -0
  189. package/dist/esm/preview-host/diagnosePreview.d.ts +22 -0
  190. package/dist/esm/preview-host/diagnosePreview.d.ts.map +1 -0
  191. package/dist/esm/preview-host/diagnosePreview.js +98 -0
  192. package/dist/esm/preview-host/diagnosePreview.js.map +1 -0
  193. package/dist/esm/preview-host/index.d.ts +18 -0
  194. package/dist/esm/preview-host/index.d.ts.map +1 -0
  195. package/dist/esm/preview-host/index.js +18 -0
  196. package/dist/esm/preview-host/index.js.map +1 -0
  197. package/dist/esm/preview-host/previewProfile.d.ts +6 -0
  198. package/dist/esm/preview-host/previewProfile.d.ts.map +1 -0
  199. package/dist/esm/preview-host/previewProfile.js +49 -0
  200. package/dist/esm/preview-host/previewProfile.js.map +1 -0
  201. package/dist/esm/preview-host/previewSampleData.d.ts +22 -0
  202. package/dist/esm/preview-host/previewSampleData.d.ts.map +1 -0
  203. package/dist/esm/preview-host/previewSampleData.js +113 -0
  204. package/dist/esm/preview-host/previewSampleData.js.map +1 -0
  205. package/dist/esm/preview-host/resolvePreviewPlan.d.ts +18 -0
  206. package/dist/esm/preview-host/resolvePreviewPlan.d.ts.map +1 -0
  207. package/dist/esm/preview-host/resolvePreviewPlan.js +124 -0
  208. package/dist/esm/preview-host/resolvePreviewPlan.js.map +1 -0
  209. package/dist/esm/preview-host/useSizeClass.d.ts +3 -0
  210. package/dist/esm/preview-host/useSizeClass.d.ts.map +1 -0
  211. package/dist/esm/preview-host/useSizeClass.js +21 -0
  212. package/dist/esm/preview-host/useSizeClass.js.map +1 -0
  213. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  214. package/foundation/ChartWrapper.tsx +252 -0
  215. package/foundation/ColumnChooser.tsx +73 -0
  216. package/foundation/FilterBuilder.tsx +144 -0
  217. package/foundation/Foundation.stories.tsx +16 -0
  218. package/foundation/SavedViewsMenu.tsx +94 -0
  219. package/foundation/chartGeometry.ts +108 -0
  220. package/foundation/columnModel.ts +39 -0
  221. package/foundation/filterModel.ts +111 -0
  222. package/foundation/foundationComponentMetadata.ts +4 -0
  223. package/foundation/foundationDescriptors.ts +86 -1
  224. package/foundation/foundationSamples.ts +19 -0
  225. package/foundation/foundationStrings.ts +25 -0
  226. package/foundation/index.ts +9 -0
  227. package/foundation/useElementWidth.ts +31 -0
  228. package/foundation/viewModel.ts +21 -0
  229. package/index.ts +1 -0
  230. package/package.json +8 -8
  231. package/preview-host/ApplicationDocument.ts +31 -0
  232. package/preview-host/ApplicationHost.tsx +114 -0
  233. package/preview-host/FlowArrangementView.tsx +59 -0
  234. package/preview-host/PreviewProblem.ts +68 -0
  235. package/preview-host/PreviewProblemsView.tsx +31 -0
  236. package/preview-host/PreviewSliceFragment.ts +43 -0
  237. package/preview-host/PreviewTarget.ts +19 -0
  238. package/preview-host/PreviewTemplate.tsx +45 -0
  239. package/preview-host/PreviewToast.tsx +32 -0
  240. package/preview-host/ScenePreviewHost.tsx +250 -0
  241. package/preview-host/composeApplication.ts +273 -0
  242. package/preview-host/defaultApplicationChrome.ts +33 -0
  243. package/preview-host/diagnosePreview.ts +132 -0
  244. package/preview-host/index.ts +20 -0
  245. package/preview-host/previewProfile.ts +47 -0
  246. package/preview-host/previewSampleData.ts +144 -0
  247. package/preview-host/resolvePreviewPlan.ts +100 -0
  248. package/preview-host/useSizeClass.ts +23 -0
  249. package/shell/layout.css +307 -0
@@ -0,0 +1,288 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { useMemo, useRef, useEffect, useState, useCallback } from 'react';
3
+ import { SliceKind } from '@cratis/scene.model';
4
+ import { ApplicationStructureIndex, resolveToolbarButton } from '@cratis/scene.engine';
5
+ import { createMemorySceneHistory, createDryRunInvoker, SliceInvokerProvider, SliceCommandFieldsProvider, SceneThemeProvider, useSceneNavigation, sliceDialogDestination } from '@cratis/scene.react';
6
+ import { ComponentName } from '../ComponentName.js';
7
+ import { externalComponent } from '../gallery/elements.js';
8
+ import { SlotName } from '../layouts/SlotName.js';
9
+ import { LayoutName } from '../layouts/LayoutName.js';
10
+ import '../layouts/shellComponents.js';
11
+ import '../layouts/appShell.js';
12
+ import '../layouts/fullPage.js';
13
+ import { previewProfile } from './previewProfile.js';
14
+ import { ApplicationHost } from './ApplicationHost.js';
15
+ import { diagnosePreview } from './diagnosePreview.js';
16
+ import { PreviewProblemSeverity, PreviewProblemCode, hasBlockingProblem } from './PreviewProblem.js';
17
+ import { PreviewProblemsView } from './PreviewProblemsView.js';
18
+ import { createPreviewSampleData } from './previewSampleData.js';
19
+ import { findSliceFragment } from './PreviewSliceFragment.js';
20
+ import { PreviewToast } from './PreviewToast.js';
21
+
22
+ const previewPageScreen = '#preview-page';
23
+ const noNavigation = {
24
+ application: {
25
+ regions: []
26
+ },
27
+ modules: []
28
+ };
29
+ /** The page a slice preview happens over when its feature has no screen of its own, or a State View's fragment is shown. */ function minimalPage(layout, content) {
30
+ return {
31
+ name: previewPageScreen,
32
+ layout,
33
+ slotContent: {
34
+ [SlotName.Content]: content
35
+ },
36
+ forms: [],
37
+ contributions: []
38
+ };
39
+ }
40
+ /**
41
+ * Renders the effective application (spec 10, PRV1-PRV9) from an in-memory document: the real shell, its navigation regions, the
42
+ * first feature of a module, a feature, or a slice - a State Change slice as its task dialog over a minimal host page, a State View
43
+ * slice as its data fragment.
44
+ *
45
+ * - **One code path**: the composition and the host are the Stage's own (`composeApplicationScreen`, `ApplicationHost`); nothing
46
+ * here draws a shell, a menu or a dialog (PRV9).
47
+ * - **Read-only**: no design affordances, no edits (PRV8) - a toolbar button without a slice shows no warning badge here; it is
48
+ * reported as a problem instead. A model that cannot render - an unknown target, a feature without a screen,
49
+ * a layout or template nobody provides - gives a {@link PreviewProblemsView} and `onProblems`, not a blank screen.
50
+ * - **Navigation** keeps to an in-memory history; a different module swaps the shell's effective navigation (PRV4).
51
+ * - **Dialogs** submit through the dry-run invoker unless one is given: validation runs, nothing is sent, a toast says so (PRV5).
52
+ * - **Data** is the active sample data pack's (PRV6); the same seed shows the same rows.
53
+ * - The strip (`Previewing`, sample data, `Exit preview · Esc`) is the host application's: this reports the breadcrumb and calls
54
+ * `onExit` on Escape.
55
+ */ function ScenePreviewHost({ document: application, structure, navigation = noNavigation, target, sampleData, registry, invoker, onInvoked, fieldsFor, composition = {}, theme, isVisible, history, onProblems, onSelectProblem, onBreadcrumbChange, onExit, children }) {
56
+ const index = useMemo(()=>structure instanceof ApplicationStructureIndex ? structure : new ApplicationStructureIndex(structure), [
57
+ structure
58
+ ]);
59
+ const compose = useMemo(()=>({
60
+ logo: navigation.application.logo,
61
+ ...composition
62
+ }), [
63
+ composition,
64
+ navigation.application.logo
65
+ ]);
66
+ const diagnosis = useMemo(()=>diagnosePreview({
67
+ document: application,
68
+ structure: index,
69
+ navigation,
70
+ target,
71
+ packs: sampleData?.packs,
72
+ composition: compose
73
+ }), [
74
+ application,
75
+ compose,
76
+ index,
77
+ navigation,
78
+ sampleData?.packs,
79
+ target
80
+ ]);
81
+ const problems = useMemo(()=>{
82
+ const found = [
83
+ ...diagnosis.problems
84
+ ];
85
+ const { plan, screen } = diagnosis;
86
+ if (plan?.kind === 'stateView' && screen && plan.slice) {
87
+ const slice = index.findSlice(plan.slice);
88
+ if (slice && findSliceFragment(screen, plan.slice, slice).length === 0) {
89
+ found.push({
90
+ code: PreviewProblemCode.SliceFragmentMissing,
91
+ severity: PreviewProblemSeverity.Warning,
92
+ message: `Nothing on the screen '${screen.name}' is bound to the State View '${plan.slice}', so its page is shown.`,
93
+ nodeId: plan.slice
94
+ });
95
+ }
96
+ }
97
+ return found;
98
+ }, [
99
+ diagnosis,
100
+ index
101
+ ]);
102
+ const key = JSON.stringify(problems);
103
+ const reported = useRef(undefined);
104
+ useEffect(()=>{
105
+ if (reported.current === key) return;
106
+ reported.current = key;
107
+ onProblems?.(problems);
108
+ }, [
109
+ key,
110
+ onProblems,
111
+ problems
112
+ ]);
113
+ const breadcrumb = diagnosis.plan?.breadcrumb;
114
+ const breadcrumbKey = breadcrumb?.join('\u0000');
115
+ useEffect(()=>{
116
+ if (breadcrumb) onBreadcrumbChange?.(breadcrumb);
117
+ // `breadcrumbKey` is the value of `breadcrumb`.
118
+ }, [
119
+ breadcrumbKey,
120
+ onBreadcrumbChange
121
+ ]);
122
+ const [memoryHistory] = useState(()=>createMemorySceneHistory());
123
+ const [toast, setToast] = useState();
124
+ const dryRun = useMemo(()=>createDryRunInvoker({
125
+ onInvoked: (invocation)=>{
126
+ setToast(invocation);
127
+ onInvoked?.(invocation);
128
+ }
129
+ }), [
130
+ onInvoked
131
+ ]);
132
+ const samples = useMemo(()=>createPreviewSampleData(application, sampleData), [
133
+ application,
134
+ sampleData
135
+ ]);
136
+ const fields = useMemo(()=>(command, slice)=>samples.commandFields(command, fieldsFor?.(command, slice) ?? []), [
137
+ fieldsFor,
138
+ samples
139
+ ]);
140
+ const page = useMemo(()=>{
141
+ const { plan, screen } = diagnosis;
142
+ if (!plan) return undefined;
143
+ if (!screen) {
144
+ // A slice whose feature has no screen of its own: a minimal host page, headed with where it is.
145
+ if (plan.slice === undefined) return undefined;
146
+ const layout = previewProfile(application.uiProfiles).layout ?? LayoutName.AppShell;
147
+ const header = externalComponent('preview-page-header', ComponentName.PageHeader, {
148
+ title: plan.breadcrumb.slice(0, -1).join(' › ') || plan.breadcrumb[0]
149
+ });
150
+ return {
151
+ screens: [
152
+ ...application.screens,
153
+ minimalPage(layout, [
154
+ header
155
+ ])
156
+ ],
157
+ initial: previewPageScreen
158
+ };
159
+ }
160
+ if (plan.kind === 'stateView' && plan.slice) {
161
+ const slice = index.findSlice(plan.slice);
162
+ const fragment = slice ? findSliceFragment(screen, plan.slice, slice) : [];
163
+ if (fragment.length > 0) return {
164
+ screens: [
165
+ ...application.screens,
166
+ minimalPage(screen.layout, fragment)
167
+ ],
168
+ initial: previewPageScreen
169
+ };
170
+ }
171
+ return {
172
+ screens: application.screens,
173
+ initial: screen.name
174
+ };
175
+ }, [
176
+ application.screens,
177
+ application.uiProfiles,
178
+ diagnosis,
179
+ index
180
+ ]);
181
+ const hostApplication = useMemo(()=>page ? {
182
+ ...application,
183
+ screens: page.screens
184
+ } : application, [
185
+ application,
186
+ page
187
+ ]);
188
+ const navigationModel = useMemo(()=>({
189
+ structure: index,
190
+ navigation,
191
+ isVisible
192
+ }), [
193
+ index,
194
+ isVisible,
195
+ navigation
196
+ ]);
197
+ const onKeyDown = useCallback((event)=>{
198
+ if (event.key === 'Escape' && !event.defaultPrevented) onExit?.();
199
+ }, [
200
+ onExit
201
+ ]);
202
+ if (hasBlockingProblem(problems) || !page) {
203
+ return /*#__PURE__*/ jsx(PreviewProblemsView, {
204
+ problems: problems.filter((problem)=>problem.severity === PreviewProblemSeverity.Error),
205
+ onSelectProblem: onSelectProblem
206
+ });
207
+ }
208
+ const body = /*#__PURE__*/ jsx(SliceInvokerProvider, {
209
+ invoker: invoker ?? dryRun,
210
+ warnEmptySlices: false,
211
+ children: /*#__PURE__*/ jsx(SliceCommandFieldsProvider, {
212
+ fieldsFor: fields,
213
+ children: /*#__PURE__*/ jsx("div", {
214
+ className: "scene-preview-host",
215
+ "data-scene-preview": diagnosis.plan?.kind,
216
+ "data-preview-breadcrumb": breadcrumb?.join(' › '),
217
+ children: /*#__PURE__*/ jsxs(ApplicationHost, {
218
+ application: hostApplication,
219
+ composition: compose,
220
+ navigationModel: navigationModel,
221
+ registry: registry,
222
+ initialScreen: page.initial,
223
+ history: history ?? memoryHistory,
224
+ resolveBinding: samples.resolveBinding,
225
+ queryResults: samples.queryResults,
226
+ children: [
227
+ diagnosis.plan?.kind === 'stateChange' && /*#__PURE__*/ jsx(OpenSliceDialog, {
228
+ index: index,
229
+ plan: diagnosis.plan
230
+ }),
231
+ /*#__PURE__*/ jsx(EscapeToExit, {
232
+ onKeyDown: onKeyDown,
233
+ enabled: onExit !== undefined
234
+ }),
235
+ toast && invoker === undefined && /*#__PURE__*/ jsx(PreviewToast, {
236
+ invocation: toast,
237
+ onDismiss: ()=>setToast(undefined)
238
+ }),
239
+ children
240
+ ]
241
+ })
242
+ })
243
+ })
244
+ });
245
+ return theme ? /*#__PURE__*/ jsx(SceneThemeProvider, {
246
+ theme: theme,
247
+ children: body
248
+ }) : body;
249
+ }
250
+ /** Opens the task dialog of a State Change slice once the page is up - the slice preview (PRV3). */ function OpenSliceDialog({ index, plan }) {
251
+ const navigation = useSceneNavigation();
252
+ const opened = useRef(false);
253
+ useEffect(()=>{
254
+ if (opened.current || plan.slice === undefined) return;
255
+ const slice = index.findSlice(plan.slice);
256
+ if (!slice || slice.kind !== SliceKind.StateChange) return;
257
+ const destination = sliceDialogDestination(resolveToolbarButton(index, {
258
+ id: plan.slice,
259
+ title: slice.name,
260
+ slice: plan.slice
261
+ }));
262
+ if (destination === undefined) return;
263
+ opened.current = true;
264
+ navigation.navigate(destination);
265
+ }, [
266
+ index,
267
+ navigation,
268
+ plan.slice
269
+ ]);
270
+ return null;
271
+ }
272
+ /** Exits the preview on Escape, unless something - an open dialog - already used the key. */ function EscapeToExit({ onKeyDown, enabled }) {
273
+ const navigation = useSceneNavigation();
274
+ const dialogOpen = navigation.currentDialog !== undefined;
275
+ useEffect(()=>{
276
+ if (!enabled || dialogOpen) return undefined;
277
+ globalThis.addEventListener('keydown', onKeyDown);
278
+ return ()=>globalThis.removeEventListener('keydown', onKeyDown);
279
+ }, [
280
+ dialogOpen,
281
+ enabled,
282
+ onKeyDown
283
+ ]);
284
+ return null;
285
+ }
286
+
287
+ export { ScenePreviewHost };
288
+ //# sourceMappingURL=ScenePreviewHost.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScenePreviewHost.js","sources":["../../../preview-host/ScenePreviewHost.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, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { ApplicationStructure, NavigationModel, Screen, SliceKind, Theme } from '@cratis/scene.model';\nimport { ApplicationStructureIndex, EffectiveNavItem, resolveToolbarButton } from '@cratis/scene.engine';\nimport {\n ComponentRegistry, SceneHistory, SceneThemeProvider, SliceCommandFieldsProvider, SliceCommandFieldsSource, SliceInvoker,\n SliceInvokerProvider, createDryRunInvoker, createMemorySceneHistory, sliceDialogDestination, useSceneNavigation,\n} from '@cratis/scene.react';\nimport { ComponentName } from '../ComponentName';\nimport { externalComponent } from '../gallery/elements';\nimport { LayoutName, SlotName } from '../layouts';\nimport { previewProfile } from './previewProfile';\nimport { ApplicationDocument } from './ApplicationDocument';\nimport { ApplicationHost } from './ApplicationHost';\nimport { CompositionOptions } from './composeApplication';\nimport { diagnosePreview } from './diagnosePreview';\nimport { PreviewProblem, PreviewProblemCode, PreviewProblemSeverity, hasBlockingProblem } from './PreviewProblem';\nimport { PreviewProblemsView } from './PreviewProblemsView';\nimport { PreviewSampleData, createPreviewSampleData } from './previewSampleData';\nimport { findSliceFragment } from './PreviewSliceFragment';\nimport { PreviewTarget } from './PreviewTarget';\nimport { PreviewInvocation, PreviewToast } from './PreviewToast';\nimport { PreviewPlan } from './resolvePreviewPlan';\n\nexport interface ScenePreviewHostProps {\n /** The document to preview - the in-memory one, unsaved edits included. */\n document: ApplicationDocument;\n\n /** The modules, features and slices of the application. */\n structure: ApplicationStructure | ApplicationStructureIndex;\n\n /** The application and module navigation regions; none when absent. */\n navigation?: NavigationModel;\n\n /** What to preview: a module, a feature or a slice. */\n target: PreviewTarget;\n\n /** The sample data to preview with; none when absent. */\n sampleData?: PreviewSampleData;\n\n /** The components to draw with. */\n registry: ComponentRegistry;\n\n /** What a submitted slice dialog goes through; a dry run, which only validates and reports, when absent (PRV5). */\n invoker?: SliceInvoker;\n\n /** Called for every dry run that passes validation, with what would have been sent. */\n onInvoked?(invocation: PreviewInvocation): void;\n\n /** The fields of a command, for the slice dialogs; the preview's sample rows fill their starting values. */\n fieldsFor?: SliceCommandFieldsSource;\n\n /** What the host decides about composition, such as the packages names resolve against. */\n composition?: CompositionOptions;\n\n /** The theme to apply; Studio passes the application's selected one (PRV9). */\n theme?: Theme;\n\n /** Hides a navigation item the preview user is not allowed to see. */\n isVisible?(item: EffectiveNavItem): boolean;\n\n /** Keeps the preview's navigation; an in-memory history by default, so a preview never touches the host's address (PRV4). */\n history?: SceneHistory;\n\n /** Called with the problems found - blocking or not - whenever they change (PRV8). */\n onProblems?(problems: PreviewProblem[]): void;\n\n /** Called when the author follows a problem to its node. */\n onSelectProblem?(problem: PreviewProblem): void;\n\n /** Called with what is being previewed, `Sales`, `Orders`, ... - the strip's breadcrumb (PRV7). */\n onBreadcrumbChange?(breadcrumb: string[]): void;\n\n /** Called when Escape is pressed with no dialog open: the host exits the preview (PRV7). */\n onExit?(): void;\n\n /** Extra content inside the host, such as a design layer's strip. */\n children?: ReactNode;\n}\n\nconst previewPageScreen = '#preview-page';\nconst noNavigation: NavigationModel = { application: { regions: [] }, modules: [] };\n\n/** The page a slice preview happens over when its feature has no screen of its own, or a State View's fragment is shown. */\nfunction minimalPage(layout: string, content: Screen['slotContent'][string]): Screen {\n return {\n name: previewPageScreen,\n layout,\n slotContent: { [SlotName.Content]: content },\n forms: [],\n contributions: [],\n };\n}\n\n/**\n * Renders the effective application (spec 10, PRV1-PRV9) from an in-memory document: the real shell, its navigation regions, the\n * first feature of a module, a feature, or a slice - a State Change slice as its task dialog over a minimal host page, a State View\n * slice as its data fragment.\n *\n * - **One code path**: the composition and the host are the Stage's own (`composeApplicationScreen`, `ApplicationHost`); nothing\n * here draws a shell, a menu or a dialog (PRV9).\n * - **Read-only**: no design affordances, no edits (PRV8) - a toolbar button without a slice shows no warning badge here; it is\n * reported as a problem instead. A model that cannot render - an unknown target, a feature without a screen,\n * a layout or template nobody provides - gives a {@link PreviewProblemsView} and `onProblems`, not a blank screen.\n * - **Navigation** keeps to an in-memory history; a different module swaps the shell's effective navigation (PRV4).\n * - **Dialogs** submit through the dry-run invoker unless one is given: validation runs, nothing is sent, a toast says so (PRV5).\n * - **Data** is the active sample data pack's (PRV6); the same seed shows the same rows.\n * - The strip (`Previewing`, sample data, `Exit preview · Esc`) is the host application's: this reports the breadcrumb and calls\n * `onExit` on Escape.\n */\nexport function ScenePreviewHost({\n document: application, structure, navigation = noNavigation, target, sampleData, registry, invoker, onInvoked, fieldsFor, composition = {},\n theme, isVisible, history, onProblems, onSelectProblem, onBreadcrumbChange, onExit, children,\n}: ScenePreviewHostProps) {\n const index = useMemo(() => structure instanceof ApplicationStructureIndex ? structure : new ApplicationStructureIndex(structure), [structure]);\n const compose = useMemo<CompositionOptions>(() => ({ logo: navigation.application.logo, ...composition }), [composition, navigation.application.logo]);\n const diagnosis = useMemo(\n () => diagnosePreview({ document: application, structure: index, navigation, target, packs: sampleData?.packs, composition: compose }),\n [application, compose, index, navigation, sampleData?.packs, target]);\n\n const problems = useMemo(() => {\n const found = [...diagnosis.problems];\n const { plan, screen } = diagnosis;\n if (plan?.kind === 'stateView' && screen && plan.slice) {\n const slice = index.findSlice(plan.slice);\n if (slice && findSliceFragment(screen, plan.slice, slice).length === 0) {\n found.push({ code: PreviewProblemCode.SliceFragmentMissing, severity: PreviewProblemSeverity.Warning, message: `Nothing on the screen '${screen.name}' is bound to the State View '${plan.slice}', so its page is shown.`, nodeId: plan.slice });\n }\n }\n\n return found;\n }, [diagnosis, index]);\n\n const key = JSON.stringify(problems);\n const reported = useRef<string | undefined>(undefined);\n useEffect(() => {\n if (reported.current === key) return;\n reported.current = key;\n onProblems?.(problems);\n }, [key, onProblems, problems]);\n\n const breadcrumb = diagnosis.plan?.breadcrumb;\n const breadcrumbKey = breadcrumb?.join('\\u0000');\n useEffect(() => {\n if (breadcrumb) onBreadcrumbChange?.(breadcrumb);\n // `breadcrumbKey` is the value of `breadcrumb`.\n }, [breadcrumbKey, onBreadcrumbChange]);\n\n const [memoryHistory] = useState(() => createMemorySceneHistory());\n const [toast, setToast] = useState<PreviewInvocation>();\n const dryRun = useMemo(() => createDryRunInvoker({\n onInvoked: invocation => {\n setToast(invocation);\n onInvoked?.(invocation);\n },\n }), [onInvoked]);\n\n const samples = useMemo(() => createPreviewSampleData(application, sampleData), [application, sampleData]);\n const fields = useMemo<SliceCommandFieldsSource>(() => (command, slice) => samples.commandFields(command, fieldsFor?.(command, slice) ?? []), [fieldsFor, samples]);\n\n const page = useMemo(() => {\n const { plan, screen } = diagnosis;\n if (!plan) return undefined;\n\n if (!screen) {\n // A slice whose feature has no screen of its own: a minimal host page, headed with where it is.\n if (plan.slice === undefined) return undefined;\n const layout = previewProfile(application.uiProfiles).layout ?? LayoutName.AppShell;\n const header = externalComponent('preview-page-header', ComponentName.PageHeader, { title: plan.breadcrumb.slice(0, -1).join(' › ') || plan.breadcrumb[0] });\n return { screens: [...application.screens, minimalPage(layout, [header])], initial: previewPageScreen };\n }\n\n if (plan.kind === 'stateView' && plan.slice) {\n const slice = index.findSlice(plan.slice);\n const fragment = slice ? findSliceFragment(screen, plan.slice, slice) : [];\n if (fragment.length > 0) return { screens: [...application.screens, minimalPage(screen.layout, fragment)], initial: previewPageScreen };\n }\n\n return { screens: application.screens, initial: screen.name };\n }, [application.screens, application.uiProfiles, diagnosis, index]);\n\n const hostApplication = useMemo(() => page ? { ...application, screens: page.screens } : application, [application, page]);\n const navigationModel = useMemo(() => ({ structure: index, navigation, isVisible }), [index, isVisible, navigation]);\n\n const onKeyDown = useCallback((event: KeyboardEvent) => {\n if (event.key === 'Escape' && !event.defaultPrevented) onExit?.();\n }, [onExit]);\n\n if (hasBlockingProblem(problems) || !page) {\n return <PreviewProblemsView problems={problems.filter(problem => problem.severity === PreviewProblemSeverity.Error)} onSelectProblem={onSelectProblem} />;\n }\n\n const body = (\n <SliceInvokerProvider invoker={invoker ?? dryRun} warnEmptySlices={false}>\n <SliceCommandFieldsProvider fieldsFor={fields}>\n <div className='scene-preview-host' data-scene-preview={diagnosis.plan?.kind} data-preview-breadcrumb={breadcrumb?.join(' › ')}>\n <ApplicationHost\n application={hostApplication}\n composition={compose}\n navigationModel={navigationModel}\n registry={registry}\n initialScreen={page.initial}\n history={history ?? memoryHistory}\n resolveBinding={samples.resolveBinding}\n queryResults={samples.queryResults}>\n {diagnosis.plan?.kind === 'stateChange' && <OpenSliceDialog index={index} plan={diagnosis.plan} />}\n <EscapeToExit onKeyDown={onKeyDown} enabled={onExit !== undefined} />\n {toast && invoker === undefined && <PreviewToast invocation={toast} onDismiss={() => setToast(undefined)} />}\n {children}\n </ApplicationHost>\n </div>\n </SliceCommandFieldsProvider>\n </SliceInvokerProvider>\n );\n\n return theme ? <SceneThemeProvider theme={theme}>{body}</SceneThemeProvider> : body;\n}\n\n/** Opens the task dialog of a State Change slice once the page is up - the slice preview (PRV3). */\nfunction OpenSliceDialog({ index, plan }: { index: ApplicationStructureIndex; plan: PreviewPlan }) {\n const navigation = useSceneNavigation();\n const opened = useRef(false);\n useEffect(() => {\n if (opened.current || plan.slice === undefined) return;\n const slice = index.findSlice(plan.slice);\n if (!slice || slice.kind !== SliceKind.StateChange) return;\n\n const destination = sliceDialogDestination(resolveToolbarButton(index, { id: plan.slice, title: slice.name, slice: plan.slice }));\n if (destination === undefined) return;\n opened.current = true;\n navigation.navigate(destination);\n }, [index, navigation, plan.slice]);\n\n return null;\n}\n\n/** Exits the preview on Escape, unless something - an open dialog - already used the key. */\nfunction EscapeToExit({ onKeyDown, enabled }: { onKeyDown(event: KeyboardEvent): void; enabled: boolean }) {\n const navigation = useSceneNavigation();\n const dialogOpen = navigation.currentDialog !== undefined;\n useEffect(() => {\n if (!enabled || dialogOpen) return undefined;\n globalThis.addEventListener('keydown', onKeyDown);\n return () => globalThis.removeEventListener('keydown', onKeyDown);\n }, [dialogOpen, enabled, onKeyDown]);\n\n return null;\n}\n"],"names":["previewPageScreen","noNavigation","application","regions","modules","minimalPage","layout","content","name","slotContent","SlotName","Content","forms","contributions","ScenePreviewHost","document","structure","navigation","target","sampleData","registry","invoker","onInvoked","fieldsFor","composition","theme","isVisible","history","onProblems","onSelectProblem","onBreadcrumbChange","onExit","children","index","useMemo","ApplicationStructureIndex","compose","logo","diagnosis","diagnosePreview","packs","problems","found","plan","screen","kind","slice","findSlice","findSliceFragment","length","push","code","PreviewProblemCode","SliceFragmentMissing","severity","PreviewProblemSeverity","Warning","message","nodeId","key","JSON","stringify","reported","useRef","undefined","useEffect","current","breadcrumb","breadcrumbKey","join","memoryHistory","useState","createMemorySceneHistory","toast","setToast","dryRun","createDryRunInvoker","invocation","samples","createPreviewSampleData","fields","command","commandFields","page","previewProfile","uiProfiles","LayoutName","AppShell","header","externalComponent","ComponentName","PageHeader","title","screens","initial","fragment","hostApplication","navigationModel","onKeyDown","useCallback","event","defaultPrevented","hasBlockingProblem","_jsx","PreviewProblemsView","filter","problem","Error","body","SliceInvokerProvider","warnEmptySlices","SliceCommandFieldsProvider","div","className","data-scene-preview","data-preview-breadcrumb","_jsxs","ApplicationHost","initialScreen","resolveBinding","queryResults","OpenSliceDialog","EscapeToExit","enabled","PreviewToast","onDismiss","SceneThemeProvider","useSceneNavigation","opened","SliceKind","StateChange","destination","sliceDialogDestination","resolveToolbarButton","id","navigate","dialogOpen","currentDialog","globalThis","addEventListener","removeEventListener"],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { DestinationReference, DialogTemplate, Form, Layout, SceneElement, Screen, ScreenTemplate, UiProfile, type ApplicationLogo, type EffectiveConfiguration } from '@cratis/scene.model';
2
+ import { DescriptorCatalog, PackageCatalog } from '@cratis/scene.engine';
3
+ import { ApplicationDocument } from './ApplicationDocument';
4
+ export interface CompositionOptions {
5
+ profile?: UiProfile;
6
+ catalog?: PackageCatalog;
7
+ chrome?(screen: Screen, shell: string): Record<string, SceneElement[]>;
8
+ form?(screenName: string, form: Form): SceneElement;
9
+ trailing?: SceneElement[];
10
+ decorate?(element: SceneElement): SceneElement;
11
+ blueprintTemplates?: ScreenTemplate[];
12
+ blueprintLayouts?: Layout[];
13
+ descriptors?: DescriptorCatalog;
14
+ logo?: ApplicationLogo;
15
+ }
16
+ export interface ComposedScreen {
17
+ element: SceneElement;
18
+ configuration?: EffectiveConfiguration;
19
+ templates: string[];
20
+ }
21
+ export declare function findLayout(application: ApplicationDocument, name: string, options?: CompositionOptions): Layout | undefined;
22
+ export declare function templatesOf(application: ApplicationDocument, options?: CompositionOptions): ScreenTemplate[];
23
+ export declare function templatePoolFor(application: ApplicationDocument, screen: Screen, options?: CompositionOptions): ScreenTemplate[];
24
+ export declare function templateChainOf(application: ApplicationDocument, screen: Screen, options?: CompositionOptions): ScreenTemplate[];
25
+ export declare function screenContent(application: ApplicationDocument, screen: Screen, options?: CompositionOptions): {
26
+ content: SceneElement[];
27
+ templates: string[];
28
+ slot: string;
29
+ };
30
+ export declare function composeApplicationScreen(application: ApplicationDocument, screen: Screen, options?: CompositionOptions): ComposedScreen;
31
+ export declare function composeOutletScreen(application: ApplicationDocument, screen: Screen, options?: CompositionOptions): SceneElement;
32
+ export declare function composeDialog(application: ApplicationDocument, template: DialogTemplate, options?: CompositionOptions): SceneElement;
33
+ export declare function collectDestinations(application: ApplicationDocument): DestinationReference[];
34
+ //# sourceMappingURL=composeApplication.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composeApplication.d.ts","sourceRoot":"","sources":["../../../preview-host/composeApplication.ts"],"names":[],"mappings":"AAGA,OAAO,EACH,oBAAoB,EAAE,cAAc,EAAoB,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,SAAS,EACrH,KAAK,eAAe,EAAE,KAAK,sBAAsB,EACpD,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACH,iBAAiB,EAAE,cAAc,EACpC,MAAM,sBAAsB,CAAC;AAM9B,OAAO,EAAE,mBAAmB,EAAoB,MAAM,uBAAuB,CAAC;AAM9E,MAAM,WAAW,kBAAkB;IAE/B,OAAO,CAAC,EAAE,SAAS,CAAC;IAGpB,OAAO,CAAC,EAAE,cAAc,CAAC;IAMzB,MAAM,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;IAGvE,IAAI,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,YAAY,CAAC;IAGpD,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC;IAG1B,QAAQ,CAAC,CAAC,OAAO,EAAE,YAAY,GAAG,YAAY,CAAC;IAG/C,kBAAkB,CAAC,EAAE,cAAc,EAAE,CAAC;IAGtC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAG5B,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAGhC,IAAI,CAAC,EAAE,eAAe,CAAC;CAC1B;AAGD,MAAM,WAAW,cAAc;IAE3B,OAAO,EAAE,YAAY,CAAC;IAGtB,aAAa,CAAC,EAAE,sBAAsB,CAAC;IAGvC,SAAS,EAAE,MAAM,EAAE,CAAC;CACvB;AA8BD,wBAAgB,UAAU,CAAC,WAAW,EAAE,mBAAmB,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG,MAAM,GAAG,SAAS,CAG/H;AAOD,wBAAgB,WAAW,CAAC,WAAW,EAAE,mBAAmB,EAAE,OAAO,GAAE,kBAAuB,GAAG,cAAc,EAAE,CAGhH;AAOD,wBAAgB,eAAe,CAAC,WAAW,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG,cAAc,EAAE,CAIpI;AAWD,wBAAgB,eAAe,CAAC,WAAW,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG,cAAc,EAAE,CAkBpI;AASD,wBAAgB,aAAa,CAAC,WAAW,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG;IAAE,OAAO,EAAE,YAAY,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAmBhL;AAyBD,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG,cAAc,CAc3I;AAMD,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG,YAAY,CAIpI;AAMD,wBAAgB,aAAa,CAAC,WAAW,EAAE,mBAAmB,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,GAAE,kBAAuB,GAAG,YAAY,CAGxI;AAeD,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,mBAAmB,GAAG,oBAAoB,EAAE,CAsB5F"}
@@ -0,0 +1,239 @@
1
+ import { EditingScopeKind } from '@cratis/scene.model';
2
+ import { resolveScreenTemplates, resolveTemplateChain, resolveEffectiveConfiguration } from '@cratis/scene.engine';
3
+ import { ComponentName } from '../ComponentName.js';
4
+ import { externalComponent } from '../gallery/elements.js';
5
+ import { resolveElementComponentNames } from '../gallery/resolveElementNames.js';
6
+ import { galleryScreenTemplates } from '../gallery/screens.js';
7
+ import { SlotName } from '../layouts/SlotName.js';
8
+ import { shellComponentForLayout } from '../layouts/shellComponents.js';
9
+ import '../layouts/appShell.js';
10
+ import '../layouts/fullPage.js';
11
+ import { defaultLayouts } from '../layouts/defaultLayouts.js';
12
+ import { completeDocument } from './ApplicationDocument.js';
13
+ import { defaultApplicationChrome } from './defaultApplicationChrome.js';
14
+ import { previewTemplateComponent } from './PreviewTemplate.js';
15
+ import { previewProfile, blueprintPackageCatalog } from './previewProfile.js';
16
+
17
+ // Copyright (c) Cratis. All rights reserved.
18
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
19
+ function previewCatalog(options) {
20
+ return options.catalog ?? blueprintPackageCatalog;
21
+ }
22
+ function profileOf(application, options) {
23
+ return options.profile ?? previewProfile(application.uiProfiles);
24
+ }
25
+ function defaultForm(screenName, form) {
26
+ return externalComponent(`form-${screenName}-${form.name}`, 'commandForm', {
27
+ command: form.forCommand,
28
+ label: form.name,
29
+ generationMode: form.generationMode,
30
+ layout: form.layout,
31
+ fields: form.fields
32
+ });
33
+ }
34
+ function mergeSlots(...sources) {
35
+ const merged = {};
36
+ for (const source of sources){
37
+ for (const [slot, elements] of Object.entries(source ?? {}))merged[slot] = [
38
+ ...merged[slot] ?? [],
39
+ ...elements
40
+ ];
41
+ }
42
+ return merged;
43
+ }
44
+ /** The layout a screen names: the document's own, or one the blueprint provides. */ function findLayout(application, name, options = {}) {
45
+ return application.layouts.find((candidate)=>candidate.name === name) ?? (options.blueprintLayouts ?? defaultLayouts).find((candidate)=>candidate.name === name);
46
+ }
47
+ /**
48
+ * The templates a screen is composed with: the document's own, then the blueprint's for any name the document does not declare.
49
+ * A model that writes `template CrudList` without declaring it is naming one of the blueprint's templates; the document's
50
+ * own declaration always wins the name.
51
+ */ function templatesOf(application, options = {}) {
52
+ const own = application.screenTemplates;
53
+ return [
54
+ ...own,
55
+ ...(options.blueprintTemplates ?? galleryScreenTemplates).filter((template)=>!own.some((candidate)=>candidate.name === template.name))
56
+ ];
57
+ }
58
+ /**
59
+ * The templates a screen's template chain is worked out among: the document's own when the screen's template is one of them,
60
+ * otherwise the blueprint's as well. The blueprint's templates are never mixed into a document's own chain - several of them fit
61
+ * the same slot name, which would make every slot ambiguous.
62
+ */ function templatePoolFor(application, screen, options = {}) {
63
+ return application.screenTemplates.some((candidate)=>candidate.name === screen.screenTemplate) ? application.screenTemplates : templatesOf(application, options);
64
+ }
65
+ /** The slot of the layout a template chain's outermost template fits: its declared slot, or `content`. */ function layoutSlotOf(layout, outermost) {
66
+ const fits = outermost.fitsSlot;
67
+ if (fits === undefined) return SlotName.Content;
68
+ const slot = fits.includes('.') ? fits.slice(fits.lastIndexOf('.') + 1) : fits;
69
+ return layout === undefined || layout.slots.some((candidate)=>candidate.name === slot) ? slot : SlotName.Content;
70
+ }
71
+ /** The templates a screen's own template sits inside, outermost first, ending with the screen's own template. */ function templateChainOf(application, screen, options = {}) {
72
+ if (!screen.screenTemplate) return [];
73
+ const templates = templatePoolFor(application, screen, options);
74
+ const own = templates.find((candidate)=>candidate.name === screen.screenTemplate);
75
+ if (!own) return [];
76
+ const layout = findLayout(application, screen.layout, options);
77
+ const placements = layout ? resolveScreenTemplates(layout, templates).placements : [];
78
+ const chain = [
79
+ own
80
+ ];
81
+ for(let guard = 0; guard <= templates.length; guard++){
82
+ const placement = placements.find((candidate)=>candidate.template === chain[0].name);
83
+ if (!placement || placement.container === layout?.name) break;
84
+ const parent = templates.find((candidate)=>candidate.name === placement.container);
85
+ if (!parent || chain.includes(parent)) break;
86
+ chain.unshift(parent);
87
+ }
88
+ return chain;
89
+ }
90
+ /**
91
+ * What a screen puts in the shell's content slot: the screen - inside the template chain it names, when it names one - and the
92
+ * forms it hosts. The same content fills the shell on the primary region and a nested outlet.
93
+ *
94
+ * The innermost template takes the screen's own slot content; each template outside it holds the one inside in the slot it
95
+ * declared (`fitsSlot`), so the chain's arrangements all apply.
96
+ */ function screenContent(application, screen, options = {}) {
97
+ const form = options.form ?? defaultForm;
98
+ const forms = screen.forms.map((candidate)=>form(screen.name, candidate));
99
+ const chain = templateChainOf(application, screen, options);
100
+ if (chain.length === 0) {
101
+ return {
102
+ content: [
103
+ ...Object.values(screen.slotContent).flat(),
104
+ ...forms
105
+ ],
106
+ templates: [],
107
+ slot: SlotName.Content
108
+ };
109
+ }
110
+ let inner;
111
+ for(let index = chain.length - 1; index >= 0; index--){
112
+ const template = chain[index];
113
+ const slots = index === chain.length - 1 ? mergeSlots(template.content, screen.slotContent, {
114
+ forms
115
+ }) : mergeSlots(template.content, {
116
+ [slotName(chain[index + 1])]: [
117
+ inner
118
+ ]
119
+ });
120
+ inner = externalComponent(`template-${screen.name}-${template.name}`, previewTemplateComponent, {
121
+ arrangement: template.arrangement
122
+ }, slots);
123
+ }
124
+ const layout = findLayout(application, screen.layout, options);
125
+ return {
126
+ content: [
127
+ inner
128
+ ],
129
+ templates: chain.map((template)=>template.name),
130
+ slot: layoutSlotOf(layout, chain[0])
131
+ };
132
+ }
133
+ function slotName(template) {
134
+ const fits = template.fitsSlot ?? SlotName.Content;
135
+ return fits.includes('.') ? fits.slice(fits.lastIndexOf('.') + 1) : fits;
136
+ }
137
+ function finish(element, profile, catalog, options) {
138
+ const decorated = options.decorate ? options.decorate(element) : element;
139
+ return resolveElementComponentNames(decorated, profile, catalog);
140
+ }
141
+ /**
142
+ * Composes one screen the way the application shows it: the shell for the screen's layout, the chrome every screen shares in the
143
+ * shell's slots, and the screen - inside the template chain it names - in the slot the chain fits. Stage and the preview host
144
+ * both compose through this, so a screen is the same screen in both (spec PRV9, REN2).
145
+ *
146
+ * A layout the selected package set does not provide stays unresolved in the rendered tree: showing that missing component is
147
+ * deliberate, because silently substituting a default shell would hide a package/profile problem.
148
+ *
149
+ * @param application The document and profiles.
150
+ * @param screen The screen to compose.
151
+ * @param options What the host decides.
152
+ * @returns The element to render, the configuration its templates resolved, and the templates around the screen.
153
+ */ function composeApplicationScreen(application, screen, options = {}) {
154
+ const profile = profileOf(application, options);
155
+ const { content, templates, slot } = screenContent(application, screen, options);
156
+ const shell = shellComponentForLayout(screen.layout) ?? screen.layout;
157
+ const chrome = options.chrome ? options.chrome(screen, shell) : shell === ComponentName.FullPageShell ? {} : defaultApplicationChrome(options.logo);
158
+ const composed = externalComponent(`screen-${screen.name}`, shell, {
159
+ screenName: screen.name
160
+ }, {
161
+ ...chrome,
162
+ [slot]: [
163
+ ...chrome[slot] ?? [],
164
+ ...content,
165
+ ...slot === SlotName.Content ? options.trailing ?? [] : []
166
+ ]
167
+ });
168
+ return {
169
+ element: finish(composed, profile, previewCatalog(options), options),
170
+ configuration: configurationOf(application, screen, options),
171
+ templates
172
+ };
173
+ }
174
+ /**
175
+ * A screen as it appears inside an outlet of another screen: its content alone, without the shell the primary region wraps
176
+ * every screen in, with the same name resolution.
177
+ */ function composeOutletScreen(application, screen, options = {}) {
178
+ const { content } = screenContent(application, screen, options);
179
+ const element = content.length === 1 ? content[0] : {
180
+ id: `outlet-${screen.name}`,
181
+ children: content
182
+ };
183
+ return finish(element, profileOf(application, options), previewCatalog(options), options);
184
+ }
185
+ /**
186
+ * A dialog template as it is shown over the application: its slot content inside the template wrapper, with the arrangement the
187
+ * template wrote, names resolved - the same wrapper a screen's template gets.
188
+ */ function composeDialog(application, template, options = {}) {
189
+ const element = externalComponent(`dialog-${template.name}`, previewTemplateComponent, {
190
+ arrangement: template.arrangement
191
+ }, template.content ?? {});
192
+ return finish(element, profileOf(application, options), previewCatalog(options), options);
193
+ }
194
+ function configurationOf(application, screen, options) {
195
+ if (!options.descriptors || (application.instanceContributions ?? []).length === 0) return undefined;
196
+ const templates = templatesOf(application, options);
197
+ const document = {
198
+ ...completeDocument(application),
199
+ screenTemplates: templates,
200
+ layouts: [
201
+ ...application.layouts,
202
+ ...(options.blueprintLayouts ?? defaultLayouts).filter((layout)=>!application.layouts.some((own)=>own.name === layout.name))
203
+ ]
204
+ };
205
+ const chain = resolveTemplateChain(document, {
206
+ kind: EditingScopeKind.Screen,
207
+ name: screen.name
208
+ });
209
+ return resolveEffectiveConfiguration(chain, document.instanceContributions, options.descriptors);
210
+ }
211
+ /**
212
+ * Every destination the document authors - on actions, navigations, contributions and toolbar items - wherever it sits, so a
213
+ * route override on one of them can be deep linked.
214
+ */ function collectDestinations(application) {
215
+ const found = [];
216
+ const visit = (value)=>{
217
+ if (value === null || typeof value !== 'object') return;
218
+ if (Array.isArray(value)) {
219
+ value.forEach(visit);
220
+ return;
221
+ }
222
+ for (const [key, entry] of Object.entries(value)){
223
+ if (key === 'destination' && entry !== null && typeof entry === 'object' && !Array.isArray(entry)) found.push(entry);
224
+ visit(entry);
225
+ }
226
+ };
227
+ for (const screen of application.screens){
228
+ visit(screen.slotContent);
229
+ visit(screen.contributions);
230
+ }
231
+ for (const template of [
232
+ ...application.screenTemplates,
233
+ ...application.dialogTemplates ?? []
234
+ ])visit(template.content);
235
+ return found;
236
+ }
237
+
238
+ export { collectDestinations, composeApplicationScreen, composeDialog, composeOutletScreen, findLayout, screenContent, templateChainOf, templatePoolFor, templatesOf };
239
+ //# sourceMappingURL=composeApplication.js.map