@cratis/scene.engine 4.26.0 → 4.28.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 (193) hide show
  1. package/dist/cjs/editing/resolveEffectiveConfiguration.js +8 -0
  2. package/dist/cjs/editing/resolveEffectiveConfiguration.js.map +1 -1
  3. package/dist/cjs/index.js +38 -0
  4. package/dist/cjs/index.js.map +1 -1
  5. package/dist/cjs/navigation/NavigationDiagnosticCode.js +5 -0
  6. package/dist/cjs/navigation/NavigationDiagnosticCode.js.map +1 -1
  7. package/dist/cjs/navigation/NavigationEditKind.js +16 -0
  8. package/dist/cjs/navigation/NavigationEditKind.js.map +1 -0
  9. package/dist/cjs/navigation/NavigationItemOrigin.js +14 -0
  10. package/dist/cjs/navigation/NavigationItemOrigin.js.map +1 -0
  11. package/dist/cjs/navigation/NavigationSourcesKind.js +16 -0
  12. package/dist/cjs/navigation/NavigationSourcesKind.js.map +1 -0
  13. package/dist/cjs/navigation/diagnoseNavigation.js +8 -1
  14. package/dist/cjs/navigation/diagnoseNavigation.js.map +1 -1
  15. package/dist/cjs/navigation/diagnoseNavigationRegions.js +99 -0
  16. package/dist/cjs/navigation/diagnoseNavigationRegions.js.map +1 -0
  17. package/dist/cjs/navigation/effectiveNavigation.js +133 -0
  18. package/dist/cjs/navigation/effectiveNavigation.js.map +1 -0
  19. package/dist/cjs/navigation/navigationEdits.js +230 -0
  20. package/dist/cjs/navigation/navigationEdits.js.map +1 -0
  21. package/dist/cjs/navigation/navigationRegions.js +42 -0
  22. package/dist/cjs/navigation/navigationRegions.js.map +1 -0
  23. package/dist/cjs/structure/ApplicationStructureIndex.js +10 -0
  24. package/dist/cjs/structure/ApplicationStructureIndex.js.map +1 -1
  25. package/dist/cjs/toolbar/SliceDialogSource.js +14 -0
  26. package/dist/cjs/toolbar/SliceDialogSource.js.map +1 -0
  27. package/dist/cjs/toolbar/ToolbarDiagnosticCode.js +16 -0
  28. package/dist/cjs/toolbar/ToolbarDiagnosticCode.js.map +1 -0
  29. package/dist/cjs/toolbar/ToolbarDiagnosticSeverity.js +14 -0
  30. package/dist/cjs/toolbar/ToolbarDiagnosticSeverity.js.map +1 -0
  31. package/dist/cjs/toolbar/sliceDialogFor.js +38 -0
  32. package/dist/cjs/toolbar/sliceDialogFor.js.map +1 -0
  33. package/dist/cjs/toolbar/toolbarButtons.js +93 -0
  34. package/dist/cjs/toolbar/toolbarButtons.js.map +1 -0
  35. package/dist/cjs/toolbar/validateToolbarButtons.js +59 -0
  36. package/dist/cjs/toolbar/validateToolbarButtons.js.map +1 -0
  37. package/dist/cjs/validateNavigationDestinations.js +2 -0
  38. package/dist/cjs/validateNavigationDestinations.js.map +1 -1
  39. package/dist/esm/editing/resolveEffectiveConfiguration.d.ts.map +1 -1
  40. package/dist/esm/editing/resolveEffectiveConfiguration.js +8 -0
  41. package/dist/esm/editing/resolveEffectiveConfiguration.js.map +1 -1
  42. package/dist/esm/index.d.ts +1 -0
  43. package/dist/esm/index.d.ts.map +1 -1
  44. package/dist/esm/index.js +13 -0
  45. package/dist/esm/index.js.map +1 -1
  46. package/dist/esm/navigation/EffectiveNavItem.d.ts +14 -0
  47. package/dist/esm/navigation/EffectiveNavItem.d.ts.map +1 -0
  48. package/dist/esm/navigation/EffectiveNavItem.js +2 -0
  49. package/dist/esm/navigation/EffectiveNavItem.js.map +1 -0
  50. package/dist/esm/navigation/EffectiveNavigationRegion.d.ts +11 -0
  51. package/dist/esm/navigation/EffectiveNavigationRegion.d.ts.map +1 -0
  52. package/dist/esm/navigation/EffectiveNavigationRegion.js +2 -0
  53. package/dist/esm/navigation/EffectiveNavigationRegion.js.map +1 -0
  54. package/dist/esm/navigation/NavigationDiagnosticCode.d.ts +6 -1
  55. package/dist/esm/navigation/NavigationDiagnosticCode.d.ts.map +1 -1
  56. package/dist/esm/navigation/NavigationDiagnosticCode.js +5 -0
  57. package/dist/esm/navigation/NavigationDiagnosticCode.js.map +1 -1
  58. package/dist/esm/navigation/NavigationEdit.d.ts +13 -0
  59. package/dist/esm/navigation/NavigationEdit.d.ts.map +1 -0
  60. package/dist/esm/navigation/NavigationEdit.js +2 -0
  61. package/dist/esm/navigation/NavigationEdit.js.map +1 -0
  62. package/dist/esm/navigation/NavigationEditKind.d.ts +7 -0
  63. package/dist/esm/navigation/NavigationEditKind.d.ts.map +1 -0
  64. package/dist/esm/navigation/NavigationEditKind.js +14 -0
  65. package/dist/esm/navigation/NavigationEditKind.js.map +1 -0
  66. package/dist/esm/navigation/NavigationEditOutcome.d.ts +7 -0
  67. package/dist/esm/navigation/NavigationEditOutcome.d.ts.map +1 -0
  68. package/dist/esm/navigation/NavigationEditOutcome.js +2 -0
  69. package/dist/esm/navigation/NavigationEditOutcome.js.map +1 -0
  70. package/dist/esm/navigation/NavigationEditPlan.d.ts +6 -0
  71. package/dist/esm/navigation/NavigationEditPlan.d.ts.map +1 -0
  72. package/dist/esm/navigation/NavigationEditPlan.js +2 -0
  73. package/dist/esm/navigation/NavigationEditPlan.js.map +1 -0
  74. package/dist/esm/navigation/NavigationGraph.d.ts +4 -1
  75. package/dist/esm/navigation/NavigationGraph.d.ts.map +1 -1
  76. package/dist/esm/navigation/NavigationItemOrigin.d.ts +5 -0
  77. package/dist/esm/navigation/NavigationItemOrigin.d.ts.map +1 -0
  78. package/dist/esm/navigation/NavigationItemOrigin.js +12 -0
  79. package/dist/esm/navigation/NavigationItemOrigin.js.map +1 -0
  80. package/dist/esm/navigation/NavigationSources.d.ts +6 -0
  81. package/dist/esm/navigation/NavigationSources.d.ts.map +1 -0
  82. package/dist/esm/navigation/NavigationSources.js +2 -0
  83. package/dist/esm/navigation/NavigationSources.js.map +1 -0
  84. package/dist/esm/navigation/NavigationSourcesKind.d.ts +7 -0
  85. package/dist/esm/navigation/NavigationSourcesKind.d.ts.map +1 -0
  86. package/dist/esm/navigation/NavigationSourcesKind.js +14 -0
  87. package/dist/esm/navigation/NavigationSourcesKind.js.map +1 -0
  88. package/dist/esm/navigation/ResolvedNavigationTarget.d.ts +6 -0
  89. package/dist/esm/navigation/ResolvedNavigationTarget.d.ts.map +1 -0
  90. package/dist/esm/navigation/ResolvedNavigationTarget.js +2 -0
  91. package/dist/esm/navigation/ResolvedNavigationTarget.js.map +1 -0
  92. package/dist/esm/navigation/diagnoseNavigation.d.ts.map +1 -1
  93. package/dist/esm/navigation/diagnoseNavigation.js +8 -1
  94. package/dist/esm/navigation/diagnoseNavigation.js.map +1 -1
  95. package/dist/esm/navigation/diagnoseNavigationRegions.d.ts +8 -0
  96. package/dist/esm/navigation/diagnoseNavigationRegions.d.ts.map +1 -0
  97. package/dist/esm/navigation/diagnoseNavigationRegions.js +97 -0
  98. package/dist/esm/navigation/diagnoseNavigationRegions.js.map +1 -0
  99. package/dist/esm/navigation/effectiveNavigation.d.ts +5 -0
  100. package/dist/esm/navigation/effectiveNavigation.d.ts.map +1 -0
  101. package/dist/esm/navigation/effectiveNavigation.js +131 -0
  102. package/dist/esm/navigation/effectiveNavigation.js.map +1 -0
  103. package/dist/esm/navigation/index.d.ts +14 -0
  104. package/dist/esm/navigation/index.d.ts.map +1 -1
  105. package/dist/esm/navigation/index.js +14 -0
  106. package/dist/esm/navigation/index.js.map +1 -1
  107. package/dist/esm/navigation/navigationEdits.d.ts +11 -0
  108. package/dist/esm/navigation/navigationEdits.d.ts.map +1 -0
  109. package/dist/esm/navigation/navigationEdits.js +225 -0
  110. package/dist/esm/navigation/navigationEdits.js.map +1 -0
  111. package/dist/esm/navigation/navigationRegions.d.ts +9 -0
  112. package/dist/esm/navigation/navigationRegions.d.ts.map +1 -0
  113. package/dist/esm/navigation/navigationRegions.js +34 -0
  114. package/dist/esm/navigation/navigationRegions.js.map +1 -0
  115. package/dist/esm/structure/ApplicationStructureIndex.d.ts +1 -0
  116. package/dist/esm/structure/ApplicationStructureIndex.d.ts.map +1 -1
  117. package/dist/esm/structure/ApplicationStructureIndex.js +10 -0
  118. package/dist/esm/structure/ApplicationStructureIndex.js.map +1 -1
  119. package/dist/esm/toolbar/ResolvedToolbarButton.d.ts +13 -0
  120. package/dist/esm/toolbar/ResolvedToolbarButton.d.ts.map +1 -0
  121. package/dist/esm/toolbar/ResolvedToolbarButton.js +2 -0
  122. package/dist/esm/toolbar/ResolvedToolbarButton.js.map +1 -0
  123. package/dist/esm/toolbar/SliceDialog.d.ts +8 -0
  124. package/dist/esm/toolbar/SliceDialog.d.ts.map +1 -0
  125. package/dist/esm/toolbar/SliceDialog.js +2 -0
  126. package/dist/esm/toolbar/SliceDialog.js.map +1 -0
  127. package/dist/esm/toolbar/SliceDialogSource.d.ts +5 -0
  128. package/dist/esm/toolbar/SliceDialogSource.d.ts.map +1 -0
  129. package/dist/esm/toolbar/SliceDialogSource.js +12 -0
  130. package/dist/esm/toolbar/SliceDialogSource.js.map +1 -0
  131. package/dist/esm/toolbar/ToolbarDiagnostic.d.ts +9 -0
  132. package/dist/esm/toolbar/ToolbarDiagnostic.d.ts.map +1 -0
  133. package/dist/esm/toolbar/ToolbarDiagnostic.js +2 -0
  134. package/dist/esm/toolbar/ToolbarDiagnostic.js.map +1 -0
  135. package/dist/esm/toolbar/ToolbarDiagnosticCode.d.ts +6 -0
  136. package/dist/esm/toolbar/ToolbarDiagnosticCode.d.ts.map +1 -0
  137. package/dist/esm/toolbar/ToolbarDiagnosticCode.js +14 -0
  138. package/dist/esm/toolbar/ToolbarDiagnosticCode.js.map +1 -0
  139. package/dist/esm/toolbar/ToolbarDiagnosticSeverity.d.ts +5 -0
  140. package/dist/esm/toolbar/ToolbarDiagnosticSeverity.d.ts.map +1 -0
  141. package/dist/esm/toolbar/ToolbarDiagnosticSeverity.js +12 -0
  142. package/dist/esm/toolbar/ToolbarDiagnosticSeverity.js.map +1 -0
  143. package/dist/esm/toolbar/index.d.ts +10 -0
  144. package/dist/esm/toolbar/index.d.ts.map +1 -0
  145. package/dist/esm/toolbar/index.js +10 -0
  146. package/dist/esm/toolbar/index.js.map +1 -0
  147. package/dist/esm/toolbar/sliceDialogFor.d.ts +5 -0
  148. package/dist/esm/toolbar/sliceDialogFor.d.ts.map +1 -0
  149. package/dist/esm/toolbar/sliceDialogFor.js +35 -0
  150. package/dist/esm/toolbar/sliceDialogFor.js.map +1 -0
  151. package/dist/esm/toolbar/toolbarButtons.d.ts +10 -0
  152. package/dist/esm/toolbar/toolbarButtons.d.ts.map +1 -0
  153. package/dist/esm/toolbar/toolbarButtons.js +89 -0
  154. package/dist/esm/toolbar/toolbarButtons.js.map +1 -0
  155. package/dist/esm/toolbar/validateToolbarButtons.d.ts +5 -0
  156. package/dist/esm/toolbar/validateToolbarButtons.d.ts.map +1 -0
  157. package/dist/esm/toolbar/validateToolbarButtons.js +57 -0
  158. package/dist/esm/toolbar/validateToolbarButtons.js.map +1 -0
  159. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  160. package/dist/esm/validateNavigationDestinations.js +2 -0
  161. package/dist/esm/validateNavigationDestinations.js.map +1 -1
  162. package/editing/resolveEffectiveConfiguration.ts +13 -0
  163. package/index.ts +1 -0
  164. package/navigation/EffectiveNavItem.ts +37 -0
  165. package/navigation/EffectiveNavigationRegion.ts +26 -0
  166. package/navigation/NavigationDiagnosticCode.ts +15 -0
  167. package/navigation/NavigationEdit.ts +36 -0
  168. package/navigation/NavigationEditKind.ts +19 -0
  169. package/navigation/NavigationEditOutcome.ts +18 -0
  170. package/navigation/NavigationEditPlan.ts +15 -0
  171. package/navigation/NavigationGraph.ts +10 -1
  172. package/navigation/NavigationItemOrigin.ts +13 -0
  173. package/navigation/NavigationSources.ts +15 -0
  174. package/navigation/NavigationSourcesKind.ts +19 -0
  175. package/navigation/ResolvedNavigationTarget.ts +19 -0
  176. package/navigation/diagnoseNavigation.ts +7 -1
  177. package/navigation/diagnoseNavigationRegions.ts +122 -0
  178. package/navigation/effectiveNavigation.ts +105 -0
  179. package/navigation/index.ts +14 -0
  180. package/navigation/navigationEdits.ts +176 -0
  181. package/navigation/navigationRegions.ts +39 -0
  182. package/package.json +3 -3
  183. package/structure/ApplicationStructureIndex.ts +11 -0
  184. package/toolbar/ResolvedToolbarButton.ts +34 -0
  185. package/toolbar/SliceDialog.ts +21 -0
  186. package/toolbar/SliceDialogSource.ts +13 -0
  187. package/toolbar/ToolbarDiagnostic.ts +22 -0
  188. package/toolbar/ToolbarDiagnosticCode.ts +17 -0
  189. package/toolbar/ToolbarDiagnosticSeverity.ts +13 -0
  190. package/toolbar/index.ts +12 -0
  191. package/toolbar/sliceDialogFor.ts +31 -0
  192. package/toolbar/toolbarButtons.ts +83 -0
  193. package/toolbar/validateToolbarButtons.ts +61 -0
@@ -0,0 +1,133 @@
1
+ 'use strict';
2
+
3
+ var scene_model = require('@cratis/scene.model');
4
+ var ApplicationStructureIndex = require('../structure/ApplicationStructureIndex.js');
5
+ var NavigationItemOrigin = require('./NavigationItemOrigin.js');
6
+ var NavigationSourcesKind = require('./NavigationSourcesKind.js');
7
+ var navigationRegions = require('./navigationRegions.js');
8
+
9
+ // Copyright (c) Cratis. All rights reserved.
10
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
11
+ /**
12
+ * Resolves the items a navigation region effectively shows, for the application or for one module.
13
+ *
14
+ * - Application (no `module`): the application items, editable, `defined here`.
15
+ * - `inherit` (the default at a module): the application items, read-only; the module's own items are cleared.
16
+ * - `extend`: the application items, read-only, followed by the module's items.
17
+ * - `override`: the module's items only.
18
+ *
19
+ * Each item carries its `origin`, whether it is `readOnly`, a `reason`, and its target resolved against the
20
+ * structure: a module target goes to the module's first feature. Sub-items belong to the sidebar; a topbar is flat
21
+ * and its sub-items are ignored. This is the one function React renderers, Stage, Studio design mode and Studio
22
+ * preview call; nothing re-implements it.
23
+ *
24
+ * The C# engine (`EffectiveNavigation.Resolve`) returns the same result; both are asserted against
25
+ * `navigation-inheritance-fixtures.json` and `navigation-targets-fixtures.json`.
26
+ *
27
+ * @param structure The modules, features and slices of the application.
28
+ * @param navigation The application and module regions.
29
+ * @param module The module to resolve for; undefined for the application.
30
+ * @param region Which region to resolve.
31
+ */ function effectiveNavigation(structure, navigation, module, region) {
32
+ const index = structure instanceof ApplicationStructureIndex.ApplicationStructureIndex ? structure : new ApplicationStructureIndex.ApplicationStructureIndex(structure);
33
+ const applicationOwned = navigationRegions.applicationItems(navigation.application, region);
34
+ if (module === undefined) {
35
+ return {
36
+ region,
37
+ sources: {
38
+ kind: NavigationSourcesKind.NavigationSourcesKind.DefinedHere,
39
+ label: 'defined here'
40
+ },
41
+ items: applicationOwned.map((item)=>resolveItem(index, region, item, NavigationItemOrigin.NavigationItemOrigin.Application, false, 'Defined here.'))
42
+ };
43
+ }
44
+ const mode = navigationRegions.modeOfModuleRegion(navigation, module, region);
45
+ const moduleOwned = navigationRegions.findNavigationRegion(navigationRegions.findModuleNavigation(navigation, module)?.regions, region)?.items ?? [];
46
+ const name = index.findModule(module)?.name ?? module;
47
+ const inherited = ()=>applicationOwned.map((item)=>resolveItem(index, region, item, NavigationItemOrigin.NavigationItemOrigin.Application, true, 'Inherited from the application; edit it there.'));
48
+ const own = ()=>moduleOwned.map((item)=>resolveItem(index, region, item, NavigationItemOrigin.NavigationItemOrigin.Module, false, `Defined in ${name}.`));
49
+ switch(mode){
50
+ case scene_model.NavigationRegionMode.Extend:
51
+ return {
52
+ region,
53
+ module,
54
+ mode,
55
+ sources: sourcesOf(NavigationSourcesKind.NavigationSourcesKind.Extended, name),
56
+ items: [
57
+ ...inherited(),
58
+ ...own()
59
+ ]
60
+ };
61
+ case scene_model.NavigationRegionMode.Override:
62
+ return {
63
+ region,
64
+ module,
65
+ mode,
66
+ sources: sourcesOf(NavigationSourcesKind.NavigationSourcesKind.Overridden, name),
67
+ items: own()
68
+ };
69
+ default:
70
+ return {
71
+ region,
72
+ module,
73
+ mode: scene_model.NavigationRegionMode.Inherit,
74
+ sources: sourcesOf(NavigationSourcesKind.NavigationSourcesKind.Inherited, name),
75
+ items: inherited()
76
+ };
77
+ }
78
+ }
79
+ function sourcesOf(kind, moduleName) {
80
+ switch(kind){
81
+ case NavigationSourcesKind.NavigationSourcesKind.Extended:
82
+ return {
83
+ kind,
84
+ label: `Application + ${moduleName}`
85
+ };
86
+ case NavigationSourcesKind.NavigationSourcesKind.Overridden:
87
+ return {
88
+ kind,
89
+ label: `${moduleName} only`
90
+ };
91
+ default:
92
+ return {
93
+ kind: NavigationSourcesKind.NavigationSourcesKind.Inherited,
94
+ label: 'inherited'
95
+ };
96
+ }
97
+ }
98
+ function resolveItem(index, region, item, origin, readOnly, reason) {
99
+ const resolved = {
100
+ id: item.id,
101
+ title: item.title,
102
+ slot: item.slot ?? navigationRegions.primarySlot,
103
+ origin,
104
+ readOnly,
105
+ reason
106
+ };
107
+ if (item.icon !== undefined) resolved.icon = item.icon;
108
+ const target = resolveTarget(index, item);
109
+ if (target) resolved.target = target;
110
+ if (region === scene_model.NavigationRegionKind.Sidebar && item.children && item.children.length > 0) {
111
+ resolved.children = item.children.map((child)=>resolveItem(index, region, child, origin, readOnly, reason));
112
+ }
113
+ return resolved;
114
+ }
115
+ function resolveTarget(index, item) {
116
+ const module = item.target?.module;
117
+ if (!module) return undefined;
118
+ const target = {
119
+ module
120
+ };
121
+ const feature = item.target?.feature;
122
+ if (feature) {
123
+ target.feature = feature;
124
+ if (index.findFeature(`${module}.${feature}`)) target.resolvedFeature = `${module}.${feature}`;
125
+ } else {
126
+ const first = index.firstFeatureId(module);
127
+ if (first !== undefined) target.resolvedFeature = first;
128
+ }
129
+ return target;
130
+ }
131
+
132
+ exports.effectiveNavigation = effectiveNavigation;
133
+ //# sourceMappingURL=effectiveNavigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effectiveNavigation.js","sources":["../../../navigation/effectiveNavigation.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 { ApplicationStructure, NavigationModel, NavigationRegionKind, NavigationRegionMode, NavItem } from '@cratis/scene.model';\nimport { ApplicationStructureIndex } from '../structure';\nimport { EffectiveNavigationRegion } from './EffectiveNavigationRegion';\nimport { EffectiveNavItem } from './EffectiveNavItem';\nimport { NavigationItemOrigin } from './NavigationItemOrigin';\nimport { NavigationSources } from './NavigationSources';\nimport { NavigationSourcesKind } from './NavigationSourcesKind';\nimport { applicationItems, findModuleNavigation, findNavigationRegion, modeOfModuleRegion, primarySlot } from './navigationRegions';\nimport { ResolvedNavigationTarget } from './ResolvedNavigationTarget';\n\n/**\n * Resolves the items a navigation region effectively shows, for the application or for one module.\n *\n * - Application (no `module`): the application items, editable, `defined here`.\n * - `inherit` (the default at a module): the application items, read-only; the module's own items are cleared.\n * - `extend`: the application items, read-only, followed by the module's items.\n * - `override`: the module's items only.\n *\n * Each item carries its `origin`, whether it is `readOnly`, a `reason`, and its target resolved against the\n * structure: a module target goes to the module's first feature. Sub-items belong to the sidebar; a topbar is flat\n * and its sub-items are ignored. This is the one function React renderers, Stage, Studio design mode and Studio\n * preview call; nothing re-implements it.\n *\n * The C# engine (`EffectiveNavigation.Resolve`) returns the same result; both are asserted against\n * `navigation-inheritance-fixtures.json` and `navigation-targets-fixtures.json`.\n *\n * @param structure The modules, features and slices of the application.\n * @param navigation The application and module regions.\n * @param module The module to resolve for; undefined for the application.\n * @param region Which region to resolve.\n */\nexport function effectiveNavigation(\n structure: ApplicationStructure | ApplicationStructureIndex,\n navigation: NavigationModel,\n module: string | undefined,\n region: NavigationRegionKind,\n): EffectiveNavigationRegion {\n const index = structure instanceof ApplicationStructureIndex ? structure : new ApplicationStructureIndex(structure);\n const applicationOwned = applicationItems(navigation.application, region);\n\n if (module === undefined) {\n return {\n region,\n sources: { kind: NavigationSourcesKind.DefinedHere, label: 'defined here' },\n items: applicationOwned.map(item => resolveItem(index, region, item, NavigationItemOrigin.Application, false, 'Defined here.')),\n };\n }\n\n const mode = modeOfModuleRegion(navigation, module, region);\n const moduleOwned = findNavigationRegion(findModuleNavigation(navigation, module)?.regions, region)?.items ?? [];\n const name = index.findModule(module)?.name ?? module;\n const inherited = (): EffectiveNavItem[] => applicationOwned.map(item => resolveItem(index, region, item, NavigationItemOrigin.Application, true, 'Inherited from the application; edit it there.'));\n const own = (): EffectiveNavItem[] => moduleOwned.map(item => resolveItem(index, region, item, NavigationItemOrigin.Module, false, `Defined in ${name}.`));\n\n switch (mode) {\n case NavigationRegionMode.Extend:\n return { region, module, mode, sources: sourcesOf(NavigationSourcesKind.Extended, name), items: [...inherited(), ...own()] };\n case NavigationRegionMode.Override:\n return { region, module, mode, sources: sourcesOf(NavigationSourcesKind.Overridden, name), items: own() };\n default:\n return { region, module, mode: NavigationRegionMode.Inherit, sources: sourcesOf(NavigationSourcesKind.Inherited, name), items: inherited() };\n }\n}\n\nfunction sourcesOf(kind: NavigationSourcesKind, moduleName: string): NavigationSources {\n switch (kind) {\n case NavigationSourcesKind.Extended: return { kind, label: `Application + ${moduleName}` };\n case NavigationSourcesKind.Overridden: return { kind, label: `${moduleName} only` };\n default: return { kind: NavigationSourcesKind.Inherited, label: 'inherited' };\n }\n}\n\nfunction resolveItem(index: ApplicationStructureIndex, region: NavigationRegionKind, item: NavItem, origin: NavigationItemOrigin, readOnly: boolean, reason: string): EffectiveNavItem {\n const resolved: EffectiveNavItem = { id: item.id, title: item.title, slot: item.slot ?? primarySlot, origin, readOnly, reason };\n if (item.icon !== undefined) resolved.icon = item.icon;\n\n const target = resolveTarget(index, item);\n if (target) resolved.target = target;\n\n if (region === NavigationRegionKind.Sidebar && item.children && item.children.length > 0) {\n resolved.children = item.children.map(child => resolveItem(index, region, child, origin, readOnly, reason));\n }\n\n return resolved;\n}\n\nfunction resolveTarget(index: ApplicationStructureIndex, item: NavItem): ResolvedNavigationTarget | undefined {\n const module = item.target?.module;\n if (!module) return undefined;\n\n const target: ResolvedNavigationTarget = { module };\n const feature = item.target?.feature;\n if (feature) {\n target.feature = feature;\n if (index.findFeature(`${module}.${feature}`)) target.resolvedFeature = `${module}.${feature}`;\n } else {\n const first = index.firstFeatureId(module);\n if (first !== undefined) target.resolvedFeature = first;\n }\n\n return target;\n}\n"],"names":["effectiveNavigation","structure","navigation","module","region","index","ApplicationStructureIndex","applicationOwned","applicationItems","application","undefined","sources","kind","NavigationSourcesKind","DefinedHere","label","items","map","item","resolveItem","NavigationItemOrigin","Application","mode","modeOfModuleRegion","moduleOwned","findNavigationRegion","findModuleNavigation","regions","name","findModule","inherited","own","Module","NavigationRegionMode","Extend","sourcesOf","Extended","Override","Overridden","Inherit","Inherited","moduleName","origin","readOnly","reason","resolved","id","title","slot","primarySlot","icon","target","resolveTarget","NavigationRegionKind","Sidebar","children","length","child","feature","findFeature","resolvedFeature","first","firstFeatureId"],"mappings":";;;;;;;;AAAA;AACA;AAYA;;;;;;;;;;;;;;;;;;;;IAqBO,SAASA,mBAAAA,CACZC,SAA2D,EAC3DC,UAA2B,EAC3BC,MAA0B,EAC1BC,MAA4B,EAAA;AAE5B,IAAA,MAAMC,KAAAA,GAAQJ,SAAAA,YAAqBK,mDAAAA,GAA4BL,SAAAA,GAAY,IAAIK,mDAAAA,CAA0BL,SAAAA,CAAAA;AACzG,IAAA,MAAMM,gBAAAA,GAAmBC,kCAAAA,CAAiBN,UAAAA,CAAWO,WAAW,EAAEL,MAAAA,CAAAA;AAElE,IAAA,IAAID,WAAWO,SAAAA,EAAW;QACtB,OAAO;AACHN,YAAAA,MAAAA;YACAO,OAAAA,EAAS;AAAEC,gBAAAA,IAAAA,EAAMC,4CAAsBC,WAAW;gBAAEC,KAAAA,EAAO;AAAe,aAAA;AAC1EC,YAAAA,KAAAA,EAAOT,gBAAAA,CAAiBU,GAAG,CAACC,CAAAA,IAAAA,GAAQC,WAAAA,CAAYd,KAAAA,EAAOD,MAAAA,EAAQc,IAAAA,EAAME,yCAAAA,CAAqBC,WAAW,EAAE,KAAA,EAAO,eAAA,CAAA;AAClH,SAAA;AACJ,IAAA;IAEA,MAAMC,IAAAA,GAAOC,oCAAAA,CAAmBrB,UAAAA,EAAYC,MAAAA,EAAQC,MAAAA,CAAAA;IACpD,MAAMoB,WAAAA,GAAcC,uCAAqBC,sCAAAA,CAAqBxB,UAAAA,EAAYC,SAASwB,OAAAA,EAASvB,MAAAA,CAAAA,EAASY,SAAS,EAAE;AAChH,IAAA,MAAMY,IAAAA,GAAOvB,KAAAA,CAAMwB,UAAU,CAAC1B,SAASyB,IAAAA,IAAQzB,MAAAA;AAC/C,IAAA,MAAM2B,SAAAA,GAAY,IAA0BvB,gBAAAA,CAAiBU,GAAG,CAACC,CAAAA,IAAAA,GAAQC,WAAAA,CAAYd,KAAAA,EAAOD,MAAAA,EAAQc,IAAAA,EAAME,yCAAAA,CAAqBC,WAAW,EAAE,IAAA,EAAM,gDAAA,CAAA,CAAA;IAClJ,MAAMU,GAAAA,GAAM,IAA0BP,WAAAA,CAAYP,GAAG,CAACC,CAAAA,IAAAA,GAAQC,YAAYd,KAAAA,EAAOD,MAAAA,EAAQc,MAAME,yCAAAA,CAAqBY,MAAM,EAAE,KAAA,EAAO,CAAC,WAAW,EAAEJ,IAAAA,CAAK,CAAC,CAAC,CAAA,CAAA;IAExJ,OAAQN,IAAAA;AACJ,QAAA,KAAKW,iCAAqBC,MAAM;YAC5B,OAAO;AAAE9B,gBAAAA,MAAAA;AAAQD,gBAAAA,MAAAA;AAAQmB,gBAAAA,IAAAA;gBAAMX,OAAAA,EAASwB,SAAAA,CAAUtB,2CAAAA,CAAsBuB,QAAQ,EAAER,IAAAA,CAAAA;gBAAOZ,KAAAA,EAAO;AAAIc,oBAAAA,GAAAA,SAAAA,EAAAA;AAAgBC,oBAAAA,GAAAA,GAAAA;AAAM;AAAC,aAAA;AAC/H,QAAA,KAAKE,iCAAqBI,QAAQ;YAC9B,OAAO;AAAEjC,gBAAAA,MAAAA;AAAQD,gBAAAA,MAAAA;AAAQmB,gBAAAA,IAAAA;gBAAMX,OAAAA,EAASwB,SAAAA,CAAUtB,2CAAAA,CAAsByB,UAAU,EAAEV,IAAAA,CAAAA;gBAAOZ,KAAAA,EAAOe,GAAAA;AAAM,aAAA;AAC5G,QAAA;YACI,OAAO;AAAE3B,gBAAAA,MAAAA;AAAQD,gBAAAA,MAAAA;AAAQmB,gBAAAA,IAAAA,EAAMW,iCAAqBM,OAAO;gBAAE5B,OAAAA,EAASwB,SAAAA,CAAUtB,2CAAAA,CAAsB2B,SAAS,EAAEZ,IAAAA,CAAAA;gBAAOZ,KAAAA,EAAOc,SAAAA;AAAY,aAAA;AACnJ;AACJ;AAEA,SAASK,SAAAA,CAAUvB,IAA2B,EAAE6B,UAAkB,EAAA;IAC9D,OAAQ7B,IAAAA;AACJ,QAAA,KAAKC,4CAAsBuB,QAAQ;YAAE,OAAO;AAAExB,gBAAAA,IAAAA;gBAAMG,KAAAA,EAAO,CAAC,cAAc,EAAE0B,UAAAA,CAAAA;AAAa,aAAA;AACzF,QAAA,KAAK5B,4CAAsByB,UAAU;YAAE,OAAO;AAAE1B,gBAAAA,IAAAA;gBAAMG,KAAAA,EAAO,CAAA,EAAG0B,UAAAA,CAAW,KAAK;AAAE,aAAA;AAClF,QAAA;YAAS,OAAO;AAAE7B,gBAAAA,IAAAA,EAAMC,4CAAsB2B,SAAS;gBAAEzB,KAAAA,EAAO;AAAY,aAAA;AAChF;AACJ;AAEA,SAASI,WAAAA,CAAYd,KAAgC,EAAED,MAA4B,EAAEc,IAAa,EAAEwB,MAA4B,EAAEC,QAAiB,EAAEC,MAAc,EAAA;AAC/J,IAAA,MAAMC,QAAAA,GAA6B;AAAEC,QAAAA,EAAAA,EAAI5B,KAAK4B,EAAE;AAAEC,QAAAA,KAAAA,EAAO7B,KAAK6B,KAAK;QAAEC,IAAAA,EAAM9B,IAAAA,CAAK8B,IAAI,IAAIC,6BAAAA;AAAaP,QAAAA,MAAAA;AAAQC,QAAAA,QAAAA;AAAUC,QAAAA;AAAO,KAAA;IAC9H,IAAI1B,IAAAA,CAAKgC,IAAI,KAAKxC,SAAAA,EAAWmC,SAASK,IAAI,GAAGhC,KAAKgC,IAAI;IAEtD,MAAMC,MAAAA,GAASC,cAAc/C,KAAAA,EAAOa,IAAAA,CAAAA;IACpC,IAAIiC,MAAAA,EAAQN,QAAAA,CAASM,MAAM,GAAGA,MAAAA;AAE9B,IAAA,IAAI/C,MAAAA,KAAWiD,gCAAAA,CAAqBC,OAAO,IAAIpC,IAAAA,CAAKqC,QAAQ,IAAIrC,IAAAA,CAAKqC,QAAQ,CAACC,MAAM,GAAG,CAAA,EAAG;AACtFX,QAAAA,QAAAA,CAASU,QAAQ,GAAGrC,IAAAA,CAAKqC,QAAQ,CAACtC,GAAG,CAACwC,CAAAA,KAAAA,GAAStC,WAAAA,CAAYd,KAAAA,EAAOD,MAAAA,EAAQqD,KAAAA,EAAOf,QAAQC,QAAAA,EAAUC,MAAAA,CAAAA,CAAAA;AACvG,IAAA;IAEA,OAAOC,QAAAA;AACX;AAEA,SAASO,aAAAA,CAAc/C,KAAgC,EAAEa,IAAa,EAAA;IAClE,MAAMf,MAAAA,GAASe,IAAAA,CAAKiC,MAAM,EAAEhD,MAAAA;IAC5B,IAAI,CAACA,QAAQ,OAAOO,SAAAA;AAEpB,IAAA,MAAMyC,MAAAA,GAAmC;AAAEhD,QAAAA;AAAO,KAAA;IAClD,MAAMuD,OAAAA,GAAUxC,IAAAA,CAAKiC,MAAM,EAAEO,OAAAA;AAC7B,IAAA,IAAIA,OAAAA,EAAS;AACTP,QAAAA,MAAAA,CAAOO,OAAO,GAAGA,OAAAA;AACjB,QAAA,IAAIrD,MAAMsD,WAAW,CAAC,CAAA,EAAGxD,MAAAA,CAAO,CAAC,EAAEuD,OAAAA,CAAAA,CAAS,CAAA,EAAGP,MAAAA,CAAOS,eAAe,GAAG,CAAA,EAAGzD,MAAAA,CAAO,CAAC,EAAEuD,OAAAA,CAAAA,CAAS;IAClG,CAAA,MAAO;QACH,MAAMG,KAAAA,GAAQxD,KAAAA,CAAMyD,cAAc,CAAC3D,MAAAA,CAAAA;AACnC,QAAA,IAAI0D,KAAAA,KAAUnD,SAAAA,EAAWyC,MAAAA,CAAOS,eAAe,GAAGC,KAAAA;AACtD,IAAA;IAEA,OAAOV,MAAAA;AACX;;"}
@@ -0,0 +1,230 @@
1
+ 'use strict';
2
+
3
+ var scene_model = require('@cratis/scene.model');
4
+ var NavigationEditKind = require('./NavigationEditKind.js');
5
+ var navigationRegions = require('./navigationRegions.js');
6
+
7
+ // Copyright (c) Cratis. All rights reserved.
8
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
9
+ const noMode = 'The application is the base of the navigation and has no region mode.';
10
+ const logoLevel = 'The logo is defined at the application level only.';
11
+ const flatTopbar = 'A topbar is flat; only a sidebar item has sub-items.';
12
+ /**
13
+ * Plans a change of a module region's mode. Switching to `inherit` clears the module's items (NAV3); switching from
14
+ * `inherit` to `override` with `copy` first copies the application's items so the module starts from them (NAV5).
15
+ * @param navigation The navigation as it is.
16
+ * @param module The module whose region changes; the application has no mode and is refused.
17
+ * @param region The region.
18
+ * @param mode The mode to switch to.
19
+ * @param options `copy` copies the application items when switching from inherit to override.
20
+ */ function switchRegionMode(navigation, module, region, mode, options = {}) {
21
+ if (module === undefined) return {
22
+ edits: [],
23
+ rejected: noMode
24
+ };
25
+ const current = navigationRegions.modeOfModuleRegion(navigation, module, region);
26
+ if (current === mode) return {
27
+ edits: []
28
+ };
29
+ const setMode = {
30
+ kind: NavigationEditKind.NavigationEditKind.SetRegionMode,
31
+ module,
32
+ region,
33
+ mode
34
+ };
35
+ if (mode === scene_model.NavigationRegionMode.Inherit) {
36
+ return {
37
+ edits: [
38
+ {
39
+ kind: NavigationEditKind.NavigationEditKind.SetRegionItems,
40
+ module,
41
+ region,
42
+ items: []
43
+ },
44
+ setMode
45
+ ]
46
+ };
47
+ }
48
+ if (mode === scene_model.NavigationRegionMode.Override && current === scene_model.NavigationRegionMode.Inherit && options.copy === true) {
49
+ return {
50
+ edits: [
51
+ {
52
+ kind: NavigationEditKind.NavigationEditKind.SetRegionItems,
53
+ module,
54
+ region,
55
+ items: structuredClone(navigationRegions.applicationItems(navigation.application, region))
56
+ },
57
+ setMode
58
+ ]
59
+ };
60
+ }
61
+ return {
62
+ edits: [
63
+ setMode
64
+ ]
65
+ };
66
+ }
67
+ /**
68
+ * Plans adding an item to a region, after the ones already there. Adding to an inheriting module region first
69
+ * switches it to `extend` (NAV6), so the application's items stay and the new item follows them.
70
+ * @param navigation The navigation as it is.
71
+ * @param module The module that gets the item; undefined for the application.
72
+ * @param region The region.
73
+ * @param item The item to add.
74
+ * @param parent The id of the item it becomes a sub-item of; sidebar only.
75
+ */ function addNavItem(navigation, module, region, item, parent) {
76
+ if (parent !== undefined && region !== scene_model.NavigationRegionKind.Sidebar) return {
77
+ edits: [],
78
+ rejected: flatTopbar
79
+ };
80
+ const own = ownItems(navigation, module, region);
81
+ const ids = navigationRegions.collectItemIds(own, region);
82
+ if (ids.includes(item.id)) return {
83
+ edits: [],
84
+ rejected: `Navigation item id '${item.id}' is already used in this region.`
85
+ };
86
+ if (parent !== undefined && !ids.includes(parent)) return {
87
+ edits: [],
88
+ rejected: `There is no item '${parent}' to add a sub-item to.`
89
+ };
90
+ const add = {
91
+ kind: NavigationEditKind.NavigationEditKind.AddItem,
92
+ module,
93
+ region,
94
+ item: structuredClone(item)
95
+ };
96
+ if (parent !== undefined) add.parent = parent;
97
+ if (module !== undefined && navigationRegions.modeOfModuleRegion(navigation, module, region) === scene_model.NavigationRegionMode.Inherit) {
98
+ return {
99
+ edits: [
100
+ {
101
+ kind: NavigationEditKind.NavigationEditKind.SetRegionMode,
102
+ module,
103
+ region,
104
+ mode: scene_model.NavigationRegionMode.Extend
105
+ },
106
+ add
107
+ ]
108
+ };
109
+ }
110
+ return {
111
+ edits: [
112
+ add
113
+ ]
114
+ };
115
+ }
116
+ /**
117
+ * Plans setting the logo. The logo is defined at the application level only, so a module is refused.
118
+ * @param navigation The navigation as it is.
119
+ * @param module The module asking; only undefined (the application) is allowed.
120
+ * @param logo The logo.
121
+ */ function setApplicationLogo(navigation, module, logo) {
122
+ return module === undefined ? {
123
+ edits: [
124
+ {
125
+ kind: NavigationEditKind.NavigationEditKind.SetLogo,
126
+ logo: {
127
+ ...logo
128
+ }
129
+ }
130
+ ]
131
+ } : {
132
+ edits: [],
133
+ rejected: logoLevel
134
+ };
135
+ }
136
+ /**
137
+ * Applies navigation edits to a copy of the model. Either every edit applies, or none does.
138
+ * @param navigation The navigation as it is; never changed.
139
+ * @param edits The edits, in order.
140
+ */ function applyNavigationEdits(navigation, edits) {
141
+ const model = structuredClone(navigation);
142
+ for (const edit of edits){
143
+ const rejected = apply(model, edit);
144
+ if (rejected !== undefined) return {
145
+ applied: false,
146
+ model: navigation,
147
+ rejected
148
+ };
149
+ }
150
+ return {
151
+ applied: true,
152
+ model
153
+ };
154
+ }
155
+ function ownItems(navigation, module, region) {
156
+ return module === undefined ? navigationRegions.applicationItems(navigation.application, region) : navigationRegions.findNavigationRegion(navigationRegions.findModuleNavigation(navigation, module)?.regions, region)?.items ?? [];
157
+ }
158
+ function regionOf(model, module, region) {
159
+ let regions;
160
+ if (module === undefined) {
161
+ regions = model.application.regions;
162
+ } else {
163
+ let block = navigationRegions.findModuleNavigation(model, module);
164
+ if (!block) {
165
+ block = {
166
+ module,
167
+ regions: []
168
+ };
169
+ model.modules.push(block);
170
+ }
171
+ regions = block.regions;
172
+ }
173
+ let found = navigationRegions.findNavigationRegion(regions, region);
174
+ if (!found) {
175
+ found = {
176
+ region,
177
+ items: []
178
+ };
179
+ regions.push(found);
180
+ }
181
+ return found;
182
+ }
183
+ function apply(model, edit) {
184
+ switch(edit.kind){
185
+ case NavigationEditKind.NavigationEditKind.SetRegionMode:
186
+ if (edit.module === undefined) return noMode;
187
+ regionOf(model, edit.module, edit.region).mode = edit.mode;
188
+ return undefined;
189
+ case NavigationEditKind.NavigationEditKind.SetRegionItems:
190
+ regionOf(model, edit.module, edit.region).items = structuredClone(edit.items ?? []);
191
+ return undefined;
192
+ case NavigationEditKind.NavigationEditKind.AddItem:
193
+ {
194
+ const target = regionOf(model, edit.module, edit.region);
195
+ const item = structuredClone(edit.item);
196
+ if (navigationRegions.collectItemIds(target.items, target.region).includes(item.id)) return `Navigation item id '${item.id}' is already used in this region.`;
197
+ if (edit.parent === undefined) {
198
+ target.items.push(item);
199
+ return undefined;
200
+ }
201
+ if (target.region !== scene_model.NavigationRegionKind.Sidebar) return flatTopbar;
202
+ const owner = findItem(target.items, edit.parent);
203
+ if (!owner) return `There is no item '${edit.parent}' to add a sub-item to.`;
204
+ (owner.children ??= []).push(item);
205
+ return undefined;
206
+ }
207
+ case NavigationEditKind.NavigationEditKind.SetLogo:
208
+ if (edit.module !== undefined) return logoLevel;
209
+ model.application.logo = {
210
+ ...edit.logo
211
+ };
212
+ return undefined;
213
+ default:
214
+ return `'${String(edit.kind)}' is not a navigation edit.`;
215
+ }
216
+ }
217
+ function findItem(items, id) {
218
+ for (const item of items){
219
+ if (item.id === id) return item;
220
+ const nested = findItem(item.children ?? [], id);
221
+ if (nested) return nested;
222
+ }
223
+ return undefined;
224
+ }
225
+
226
+ exports.addNavItem = addNavItem;
227
+ exports.applyNavigationEdits = applyNavigationEdits;
228
+ exports.setApplicationLogo = setApplicationLogo;
229
+ exports.switchRegionMode = switchRegionMode;
230
+ //# sourceMappingURL=navigationEdits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigationEdits.js","sources":["../../../navigation/navigationEdits.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 { ApplicationLogo, NavigationModel, NavigationRegion, NavigationRegionKind, NavigationRegionMode, NavItem } from '@cratis/scene.model';\nimport { NavigationEdit } from './NavigationEdit';\nimport { NavigationEditKind } from './NavigationEditKind';\nimport { NavigationEditOutcome } from './NavigationEditOutcome';\nimport { NavigationEditPlan } from './NavigationEditPlan';\nimport { applicationItems, collectItemIds, findModuleNavigation, findNavigationRegion, modeOfModuleRegion } from './navigationRegions';\n\nconst noMode = 'The application is the base of the navigation and has no region mode.';\nconst logoLevel = 'The logo is defined at the application level only.';\nconst flatTopbar = 'A topbar is flat; only a sidebar item has sub-items.';\n\n/**\n * Plans a change of a module region's mode. Switching to `inherit` clears the module's items (NAV3); switching from\n * `inherit` to `override` with `copy` first copies the application's items so the module starts from them (NAV5).\n * @param navigation The navigation as it is.\n * @param module The module whose region changes; the application has no mode and is refused.\n * @param region The region.\n * @param mode The mode to switch to.\n * @param options `copy` copies the application items when switching from inherit to override.\n */\nexport function switchRegionMode(\n navigation: NavigationModel,\n module: string | undefined,\n region: NavigationRegionKind,\n mode: NavigationRegionMode,\n options: { copy?: boolean } = {},\n): NavigationEditPlan {\n if (module === undefined) return { edits: [], rejected: noMode };\n\n const current = modeOfModuleRegion(navigation, module, region);\n if (current === mode) return { edits: [] };\n\n const setMode: NavigationEdit = { kind: NavigationEditKind.SetRegionMode, module, region, mode };\n if (mode === NavigationRegionMode.Inherit) {\n return { edits: [{ kind: NavigationEditKind.SetRegionItems, module, region, items: [] }, setMode] };\n }\n\n if (mode === NavigationRegionMode.Override && current === NavigationRegionMode.Inherit && options.copy === true) {\n return { edits: [{ kind: NavigationEditKind.SetRegionItems, module, region, items: structuredClone(applicationItems(navigation.application, region)) }, setMode] };\n }\n\n return { edits: [setMode] };\n}\n\n/**\n * Plans adding an item to a region, after the ones already there. Adding to an inheriting module region first\n * switches it to `extend` (NAV6), so the application's items stay and the new item follows them.\n * @param navigation The navigation as it is.\n * @param module The module that gets the item; undefined for the application.\n * @param region The region.\n * @param item The item to add.\n * @param parent The id of the item it becomes a sub-item of; sidebar only.\n */\nexport function addNavItem(\n navigation: NavigationModel,\n module: string | undefined,\n region: NavigationRegionKind,\n item: NavItem,\n parent?: string,\n): NavigationEditPlan {\n if (parent !== undefined && region !== NavigationRegionKind.Sidebar) return { edits: [], rejected: flatTopbar };\n\n const own = ownItems(navigation, module, region);\n const ids = collectItemIds(own, region);\n if (ids.includes(item.id)) return { edits: [], rejected: `Navigation item id '${item.id}' is already used in this region.` };\n if (parent !== undefined && !ids.includes(parent)) return { edits: [], rejected: `There is no item '${parent}' to add a sub-item to.` };\n\n const add: NavigationEdit = { kind: NavigationEditKind.AddItem, module, region, item: structuredClone(item) };\n if (parent !== undefined) add.parent = parent;\n if (module !== undefined && modeOfModuleRegion(navigation, module, region) === NavigationRegionMode.Inherit) {\n return { edits: [{ kind: NavigationEditKind.SetRegionMode, module, region, mode: NavigationRegionMode.Extend }, add] };\n }\n\n return { edits: [add] };\n}\n\n/**\n * Plans setting the logo. The logo is defined at the application level only, so a module is refused.\n * @param navigation The navigation as it is.\n * @param module The module asking; only undefined (the application) is allowed.\n * @param logo The logo.\n */\nexport function setApplicationLogo(navigation: NavigationModel, module: string | undefined, logo: ApplicationLogo): NavigationEditPlan {\n void navigation;\n return module === undefined ? { edits: [{ kind: NavigationEditKind.SetLogo, logo: { ...logo } }] } : { edits: [], rejected: logoLevel };\n}\n\n/**\n * Applies navigation edits to a copy of the model. Either every edit applies, or none does.\n * @param navigation The navigation as it is; never changed.\n * @param edits The edits, in order.\n */\nexport function applyNavigationEdits(navigation: NavigationModel, edits: NavigationEdit[]): NavigationEditOutcome {\n const model = structuredClone(navigation);\n for (const edit of edits) {\n const rejected = apply(model, edit);\n if (rejected !== undefined) return { applied: false, model: navigation, rejected };\n }\n\n return { applied: true, model };\n}\n\nfunction ownItems(navigation: NavigationModel, module: string | undefined, region: NavigationRegionKind): NavItem[] {\n return module === undefined\n ? applicationItems(navigation.application, region)\n : findNavigationRegion(findModuleNavigation(navigation, module)?.regions, region)?.items ?? [];\n}\n\nfunction regionOf(model: NavigationModel, module: string | undefined, region: NavigationRegionKind): NavigationRegion {\n let regions: NavigationRegion[];\n if (module === undefined) {\n regions = model.application.regions;\n } else {\n let block = findModuleNavigation(model, module);\n if (!block) {\n block = { module, regions: [] };\n model.modules.push(block);\n }\n\n regions = block.regions;\n }\n\n let found = findNavigationRegion(regions, region);\n if (!found) {\n found = { region, items: [] };\n regions.push(found);\n }\n\n return found;\n}\n\nfunction apply(model: NavigationModel, edit: NavigationEdit): string | undefined {\n switch (edit.kind) {\n case NavigationEditKind.SetRegionMode:\n if (edit.module === undefined) return noMode;\n regionOf(model, edit.module, edit.region!).mode = edit.mode;\n return undefined;\n case NavigationEditKind.SetRegionItems:\n regionOf(model, edit.module, edit.region!).items = structuredClone(edit.items ?? []);\n return undefined;\n case NavigationEditKind.AddItem: {\n const target = regionOf(model, edit.module, edit.region!);\n const item = structuredClone(edit.item!);\n if (collectItemIds(target.items, target.region).includes(item.id)) return `Navigation item id '${item.id}' is already used in this region.`;\n if (edit.parent === undefined) {\n target.items.push(item);\n return undefined;\n }\n\n if (target.region !== NavigationRegionKind.Sidebar) return flatTopbar;\n const owner = findItem(target.items, edit.parent);\n if (!owner) return `There is no item '${edit.parent}' to add a sub-item to.`;\n (owner.children ??= []).push(item);\n return undefined;\n }\n case NavigationEditKind.SetLogo:\n if (edit.module !== undefined) return logoLevel;\n model.application.logo = { ...edit.logo! };\n return undefined;\n default:\n return `'${String((edit as NavigationEdit).kind)}' is not a navigation edit.`;\n }\n}\n\nfunction findItem(items: NavItem[], id: string): NavItem | undefined {\n for (const item of items) {\n if (item.id === id) return item;\n const nested = findItem(item.children ?? [], id);\n if (nested) return nested;\n }\n\n return undefined;\n}\n"],"names":["noMode","logoLevel","flatTopbar","switchRegionMode","navigation","module","region","mode","options","undefined","edits","rejected","current","modeOfModuleRegion","setMode","kind","NavigationEditKind","SetRegionMode","NavigationRegionMode","Inherit","SetRegionItems","items","Override","copy","structuredClone","applicationItems","application","addNavItem","item","parent","NavigationRegionKind","Sidebar","own","ownItems","ids","collectItemIds","includes","id","add","AddItem","Extend","setApplicationLogo","logo","SetLogo","applyNavigationEdits","model","edit","apply","applied","findNavigationRegion","findModuleNavigation","regions","regionOf","block","modules","push","found","target","owner","findItem","children","String","nested"],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ 'use strict';
2
+
3
+ var scene_model = require('@cratis/scene.model');
4
+
5
+ // Copyright (c) Cratis. All rights reserved.
6
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
7
+ /** The regions in the order every result lists them. */ const navigationRegionOrder = [
8
+ scene_model.NavigationRegionKind.Topbar,
9
+ scene_model.NavigationRegionKind.Sidebar
10
+ ];
11
+ /** The slot an item renders into when it names none: the primary outlet. */ const primarySlot = 'content';
12
+ /**
13
+ * Finds the items a level defines for a region.
14
+ * @param regions The regions of the application or of a module.
15
+ * @param region The region to look for.
16
+ */ function findNavigationRegion(regions, region) {
17
+ return regions?.find((candidate)=>candidate.region === region);
18
+ }
19
+ /** Finds what a module declares; undefined when it declares nothing. */ function findModuleNavigation(navigation, module) {
20
+ return navigation.modules.find((candidate)=>candidate.module === module);
21
+ }
22
+ /** The mode of a module's region: `inherit` when the module does not declare the region or its mode. */ function modeOfModuleRegion(navigation, module, region) {
23
+ return findNavigationRegion(findModuleNavigation(navigation, module)?.regions, region)?.mode ?? scene_model.NavigationRegionMode.Inherit;
24
+ }
25
+ /** The application-level items of a region. */ function applicationItems(application, region) {
26
+ return findNavigationRegion(application.regions, region)?.items ?? [];
27
+ }
28
+ /** Every id in a list of items, depth first. Sub-items count only in the sidebar. */ function collectItemIds(items, region) {
29
+ return items.flatMap((item)=>[
30
+ item.id,
31
+ ...region === scene_model.NavigationRegionKind.Sidebar ? collectItemIds(item.children ?? [], region) : []
32
+ ]);
33
+ }
34
+
35
+ exports.applicationItems = applicationItems;
36
+ exports.collectItemIds = collectItemIds;
37
+ exports.findModuleNavigation = findModuleNavigation;
38
+ exports.findNavigationRegion = findNavigationRegion;
39
+ exports.modeOfModuleRegion = modeOfModuleRegion;
40
+ exports.navigationRegionOrder = navigationRegionOrder;
41
+ exports.primarySlot = primarySlot;
42
+ //# sourceMappingURL=navigationRegions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigationRegions.js","sources":["../../../navigation/navigationRegions.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 { ApplicationNavigation, ModuleNavigation, NavigationModel, NavigationRegion, NavigationRegionKind, NavigationRegionMode, NavItem } from '@cratis/scene.model';\n\n/** The regions in the order every result lists them. */\nexport const navigationRegionOrder: NavigationRegionKind[] = [NavigationRegionKind.Topbar, NavigationRegionKind.Sidebar];\n\n/** The slot an item renders into when it names none: the primary outlet. */\nexport const primarySlot = 'content';\n\n/**\n * Finds the items a level defines for a region.\n * @param regions The regions of the application or of a module.\n * @param region The region to look for.\n */\nexport function findNavigationRegion(regions: NavigationRegion[] | undefined, region: NavigationRegionKind): NavigationRegion | undefined {\n return regions?.find(candidate => candidate.region === region);\n}\n\n/** Finds what a module declares; undefined when it declares nothing. */\nexport function findModuleNavigation(navigation: NavigationModel, module: string): ModuleNavigation | undefined {\n return navigation.modules.find(candidate => candidate.module === module);\n}\n\n/** The mode of a module's region: `inherit` when the module does not declare the region or its mode. */\nexport function modeOfModuleRegion(navigation: NavigationModel, module: string, region: NavigationRegionKind): NavigationRegionMode {\n return findNavigationRegion(findModuleNavigation(navigation, module)?.regions, region)?.mode ?? NavigationRegionMode.Inherit;\n}\n\n/** The application-level items of a region. */\nexport function applicationItems(application: ApplicationNavigation, region: NavigationRegionKind): NavItem[] {\n return findNavigationRegion(application.regions, region)?.items ?? [];\n}\n\n/** Every id in a list of items, depth first. Sub-items count only in the sidebar. */\nexport function collectItemIds(items: NavItem[], region: NavigationRegionKind): string[] {\n return items.flatMap(item => [item.id, ...(region === NavigationRegionKind.Sidebar ? collectItemIds(item.children ?? [], region) : [])]);\n}\n"],"names":["navigationRegionOrder","NavigationRegionKind","Topbar","Sidebar","primarySlot","findNavigationRegion","regions","region","find","candidate","findModuleNavigation","navigation","module","modules","modeOfModuleRegion","mode","NavigationRegionMode","Inherit","applicationItems","application","items","collectItemIds","flatMap","item","id","children"],"mappings":";;;;AAAA;AACA;AAIA,yDACO,MAAMA,qBAAAA,GAAgD;AAACC,IAAAA,gCAAAA,CAAqBC,MAAM;AAAED,IAAAA,gCAAAA,CAAqBE;;AAEhH,6EACO,MAAMC,WAAAA,GAAc;AAE3B;;;;AAIC,IACM,SAASC,oBAAAA,CAAqBC,OAAuC,EAAEC,MAA4B,EAAA;AACtG,IAAA,OAAOD,SAASE,IAAAA,CAAKC,CAAAA,SAAAA,GAAaA,SAAAA,CAAUF,MAAM,KAAKA,MAAAA,CAAAA;AAC3D;AAEA,yEACO,SAASG,oBAAAA,CAAqBC,UAA2B,EAAEC,MAAc,EAAA;IAC5E,OAAOD,UAAAA,CAAWE,OAAO,CAACL,IAAI,CAACC,CAAAA,SAAAA,GAAaA,SAAAA,CAAUG,MAAM,KAAKA,MAAAA,CAAAA;AACrE;AAEA,yGACO,SAASE,kBAAAA,CAAmBH,UAA2B,EAAEC,MAAc,EAAEL,MAA4B,EAAA;IACxG,OAAOF,oBAAAA,CAAqBK,qBAAqBC,UAAAA,EAAYC,MAAAA,CAAAA,EAASN,SAASC,MAAAA,CAAAA,EAASQ,IAAAA,IAAQC,iCAAqBC,OAAO;AAChI;AAEA,gDACO,SAASC,gBAAAA,CAAiBC,WAAkC,EAAEZ,MAA4B,EAAA;AAC7F,IAAA,OAAOF,qBAAqBc,WAAAA,CAAYb,OAAO,EAAEC,MAAAA,CAAAA,EAASa,SAAS,EAAE;AACzE;AAEA,sFACO,SAASC,cAAAA,CAAeD,KAAgB,EAAEb,MAA4B,EAAA;AACzE,IAAA,OAAOa,KAAAA,CAAME,OAAO,CAACC,CAAAA,IAAAA,GAAQ;AAACA,YAAAA,IAAAA,CAAKC,EAAE;eAAMjB,MAAAA,KAAWN,gCAAAA,CAAqBE,OAAO,GAAGkB,cAAAA,CAAeE,IAAAA,CAAKE,QAAQ,IAAI,EAAE,EAAElB,MAAAA,CAAAA,GAAU;AAAI,SAAA,CAAA;AAC3I;;;;;;;;"}
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var scene_model = require('@cratis/scene.model');
3
4
  var StructureDiagnosticCode = require('./StructureDiagnosticCode.js');
4
5
 
5
6
  // Copyright (c) Cratis. All rights reserved.
@@ -85,6 +86,15 @@ var StructureDiagnosticCode = require('./StructureDiagnosticCode.js');
85
86
  ...this.featuresByName.get(name.toLowerCase()) ?? []
86
87
  ];
87
88
  }
89
+ /**
90
+ * Finds the state change slices that accept a command, so a command named by hand can be turned into the slice that owns it.
91
+ * @param command A command name - the slice's `command`, or its `id` when it names none - or a slice's qualified id.
92
+ * @returns The qualified ids of the matching state change slices, in declaration order.
93
+ */ findSlicesByCommand(command) {
94
+ return [
95
+ ...this.slices.entries()
96
+ ].filter(([qualified, slice])=>slice.kind === scene_model.SliceKind.StateChange && (qualified === command || (slice.command ?? slice.id) === command)).map(([qualified])=>qualified);
97
+ }
88
98
  indexContainer(path, features, slices) {
89
99
  const seen = new Map();
90
100
  const featureNames = new Map();
@@ -1 +1 @@
1
- {"version":3,"file":"ApplicationStructureIndex.js","sources":["../../../structure/ApplicationStructureIndex.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 { ApplicationStructure, FeatureNode, ModuleNode, SliceKind, SliceNode } from '@cratis/scene.model';\nimport { StructureDiagnostic } from './StructureDiagnostic';\nimport { StructureDiagnosticCode } from './StructureDiagnosticCode';\n\n/**\n * Answers the questions navigation, toolbar and template applicability ask of an {@link ApplicationStructure}:\n * does this module, feature or slice exist, which feature comes first in a module, and what kind of slice is it.\n * Pure and read-only; when ids are duplicated the first declaration wins and {@link diagnostics} reports the rest.\n *\n * The C# engine (`ApplicationStructureIndex`) answers the same questions the same way; both are asserted\n * against `application-structure-fixtures.json`.\n */\nexport class ApplicationStructureIndex {\n private readonly modules = new Map<string, ModuleNode>();\n private readonly features = new Map<string, FeatureNode>();\n private readonly slices = new Map<string, SliceNode>();\n private readonly featuresByName = new Map<string, string[]>();\n\n /** The problems found while indexing, in declaration order. */\n readonly diagnostics: StructureDiagnostic[] = [];\n\n /**\n * Initializes a new instance of the {@link ApplicationStructureIndex} class.\n * @param structure The application structure to index.\n */\n constructor(readonly structure: ApplicationStructure) {\n const seen = new Map<string, string>();\n const names = new Map<string, string>();\n\n for (const module of structure.modules) {\n const qualified = module.id;\n if (!this.claim(seen, qualified, 'module')) continue;\n\n this.modules.set(qualified, module);\n this.reportAmbiguousName(names, 'module', module.name, qualified);\n this.indexContainer(qualified, module.features, module.slices ?? []);\n }\n }\n\n /**\n * Finds a module by its id.\n * @param moduleId The module id, for example `sales`.\n * @returns The module, or undefined when there is none.\n */\n findModule(moduleId: string): ModuleNode | undefined {\n return this.modules.get(moduleId);\n }\n\n /**\n * Finds a feature by its qualified id.\n * @param qualifiedId The dotted id from the module down, for example `sales.orders` or `sales.orders.returns`.\n * @returns The feature, or undefined when there is none.\n */\n findFeature(qualifiedId: string): FeatureNode | undefined {\n return this.features.get(qualifiedId);\n }\n\n /**\n * Gets the first feature of a module - the one a navigation target that names only the module goes to.\n * @param moduleId The module id.\n * @returns The module's first top-level feature, or undefined when the module is unknown or has no features.\n */\n firstFeature(moduleId: string): FeatureNode | undefined {\n return this.findModule(moduleId)?.features[0];\n }\n\n /**\n * Gets the qualified id of the first feature of a module.\n * @param moduleId The module id.\n * @returns The qualified id, or undefined when the module is unknown or has no features.\n */\n firstFeatureId(moduleId: string): string | undefined {\n const feature = this.firstFeature(moduleId);\n return feature ? `${moduleId}.${feature.id}` : undefined;\n }\n\n /**\n * Finds a slice by its qualified id.\n * @param qualifiedId The dotted id from the module down, for example `sales.orders.PlaceOrder`.\n * @returns The slice, or undefined when there is none.\n */\n findSlice(qualifiedId: string): SliceNode | undefined {\n return this.slices.get(qualifiedId);\n }\n\n /**\n * Gets what kind a slice is.\n * @param sliceId The slice's qualified id.\n * @returns The kind, or undefined when there is no such slice.\n */\n kindOf(sliceId: string): SliceKind | undefined {\n return this.findSlice(sliceId)?.kind;\n }\n\n /**\n * Finds every feature that has a given display name, in every module, so a caller can tell when a bare name is ambiguous.\n * @param name The display name, compared without regard to case.\n * @returns The qualified ids of the features with that name, in declaration order.\n */\n findFeaturesByName(name: string): string[] {\n return [...(this.featuresByName.get(name.toLowerCase()) ?? [])];\n }\n\n private indexContainer(path: string, features: FeatureNode[], slices: SliceNode[]): void {\n const seen = new Map<string, string>();\n const featureNames = new Map<string, string>();\n const sliceNames = new Map<string, string>();\n\n for (const feature of features) {\n const qualified = `${path}.${feature.id}`;\n if (!this.claim(seen, qualified, 'feature')) continue;\n\n this.features.set(qualified, feature);\n const key = feature.name.toLowerCase();\n const byName = this.featuresByName.get(key) ?? [];\n byName.push(qualified);\n this.featuresByName.set(key, byName);\n this.reportAmbiguousName(featureNames, 'feature', feature.name, qualified);\n this.indexContainer(qualified, feature.features, feature.slices);\n }\n\n for (const slice of slices) {\n const qualified = `${path}.${slice.id}`;\n if (!this.claim(seen, qualified, 'slice')) continue;\n\n this.slices.set(qualified, slice);\n this.reportAmbiguousName(sliceNames, 'slice', slice.name, qualified);\n }\n }\n\n private claim(seen: Map<string, string>, qualified: string, kind: string): boolean {\n const first = seen.get(qualified);\n if (first === undefined) {\n seen.set(qualified, kind);\n return true;\n }\n\n this.diagnostics.push({\n code: StructureDiagnosticCode.StructureDuplicateId,\n message: `Id '${qualified}' is declared more than once; the first ${first} wins.`,\n id: qualified,\n });\n return false;\n }\n\n private reportAmbiguousName(names: Map<string, string>, kind: string, name: string, qualified: string): void {\n const key = name.toLowerCase();\n const first = names.get(key);\n if (first !== undefined) {\n this.diagnostics.push({\n code: StructureDiagnosticCode.StructureAmbiguousName,\n message: `The ${kind} name '${name}' is used by both '${first}' and '${qualified}'.`,\n id: qualified,\n });\n return;\n }\n\n names.set(key, qualified);\n }\n}\n"],"names":["ApplicationStructureIndex","modules","Map","features","slices","featuresByName","diagnostics","structure","seen","names","module","qualified","id","claim","set","reportAmbiguousName","name","indexContainer","findModule","moduleId","get","findFeature","qualifiedId","firstFeature","firstFeatureId","feature","undefined","findSlice","kindOf","sliceId","kind","findFeaturesByName","toLowerCase","path","featureNames","sliceNames","key","byName","push","slice","first","code","StructureDiagnosticCode","StructureDuplicateId","message","StructureAmbiguousName"],"mappings":"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"}
1
+ {"version":3,"file":"ApplicationStructureIndex.js","sources":["../../../structure/ApplicationStructureIndex.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 { ApplicationStructure, FeatureNode, ModuleNode, SliceKind, SliceNode } from '@cratis/scene.model';\nimport { StructureDiagnostic } from './StructureDiagnostic';\nimport { StructureDiagnosticCode } from './StructureDiagnosticCode';\n\n/**\n * Answers the questions navigation, toolbar and template applicability ask of an {@link ApplicationStructure}:\n * does this module, feature or slice exist, which feature comes first in a module, and what kind of slice is it.\n * Pure and read-only; when ids are duplicated the first declaration wins and {@link diagnostics} reports the rest.\n *\n * The C# engine (`ApplicationStructureIndex`) answers the same questions the same way; both are asserted\n * against `application-structure-fixtures.json`.\n */\nexport class ApplicationStructureIndex {\n private readonly modules = new Map<string, ModuleNode>();\n private readonly features = new Map<string, FeatureNode>();\n private readonly slices = new Map<string, SliceNode>();\n private readonly featuresByName = new Map<string, string[]>();\n\n /** The problems found while indexing, in declaration order. */\n readonly diagnostics: StructureDiagnostic[] = [];\n\n /**\n * Initializes a new instance of the {@link ApplicationStructureIndex} class.\n * @param structure The application structure to index.\n */\n constructor(readonly structure: ApplicationStructure) {\n const seen = new Map<string, string>();\n const names = new Map<string, string>();\n\n for (const module of structure.modules) {\n const qualified = module.id;\n if (!this.claim(seen, qualified, 'module')) continue;\n\n this.modules.set(qualified, module);\n this.reportAmbiguousName(names, 'module', module.name, qualified);\n this.indexContainer(qualified, module.features, module.slices ?? []);\n }\n }\n\n /**\n * Finds a module by its id.\n * @param moduleId The module id, for example `sales`.\n * @returns The module, or undefined when there is none.\n */\n findModule(moduleId: string): ModuleNode | undefined {\n return this.modules.get(moduleId);\n }\n\n /**\n * Finds a feature by its qualified id.\n * @param qualifiedId The dotted id from the module down, for example `sales.orders` or `sales.orders.returns`.\n * @returns The feature, or undefined when there is none.\n */\n findFeature(qualifiedId: string): FeatureNode | undefined {\n return this.features.get(qualifiedId);\n }\n\n /**\n * Gets the first feature of a module - the one a navigation target that names only the module goes to.\n * @param moduleId The module id.\n * @returns The module's first top-level feature, or undefined when the module is unknown or has no features.\n */\n firstFeature(moduleId: string): FeatureNode | undefined {\n return this.findModule(moduleId)?.features[0];\n }\n\n /**\n * Gets the qualified id of the first feature of a module.\n * @param moduleId The module id.\n * @returns The qualified id, or undefined when the module is unknown or has no features.\n */\n firstFeatureId(moduleId: string): string | undefined {\n const feature = this.firstFeature(moduleId);\n return feature ? `${moduleId}.${feature.id}` : undefined;\n }\n\n /**\n * Finds a slice by its qualified id.\n * @param qualifiedId The dotted id from the module down, for example `sales.orders.PlaceOrder`.\n * @returns The slice, or undefined when there is none.\n */\n findSlice(qualifiedId: string): SliceNode | undefined {\n return this.slices.get(qualifiedId);\n }\n\n /**\n * Gets what kind a slice is.\n * @param sliceId The slice's qualified id.\n * @returns The kind, or undefined when there is no such slice.\n */\n kindOf(sliceId: string): SliceKind | undefined {\n return this.findSlice(sliceId)?.kind;\n }\n\n /**\n * Finds every feature that has a given display name, in every module, so a caller can tell when a bare name is ambiguous.\n * @param name The display name, compared without regard to case.\n * @returns The qualified ids of the features with that name, in declaration order.\n */\n findFeaturesByName(name: string): string[] {\n return [...(this.featuresByName.get(name.toLowerCase()) ?? [])];\n }\n\n /**\n * Finds the state change slices that accept a command, so a command named by hand can be turned into the slice that owns it.\n * @param command A command name - the slice's `command`, or its `id` when it names none - or a slice's qualified id.\n * @returns The qualified ids of the matching state change slices, in declaration order.\n */\n findSlicesByCommand(command: string): string[] {\n return [...this.slices.entries()]\n .filter(([qualified, slice]) => slice.kind === SliceKind.StateChange && (qualified === command || (slice.command ?? slice.id) === command))\n .map(([qualified]) => qualified);\n }\n\n private indexContainer(path: string, features: FeatureNode[], slices: SliceNode[]): void {\n const seen = new Map<string, string>();\n const featureNames = new Map<string, string>();\n const sliceNames = new Map<string, string>();\n\n for (const feature of features) {\n const qualified = `${path}.${feature.id}`;\n if (!this.claim(seen, qualified, 'feature')) continue;\n\n this.features.set(qualified, feature);\n const key = feature.name.toLowerCase();\n const byName = this.featuresByName.get(key) ?? [];\n byName.push(qualified);\n this.featuresByName.set(key, byName);\n this.reportAmbiguousName(featureNames, 'feature', feature.name, qualified);\n this.indexContainer(qualified, feature.features, feature.slices);\n }\n\n for (const slice of slices) {\n const qualified = `${path}.${slice.id}`;\n if (!this.claim(seen, qualified, 'slice')) continue;\n\n this.slices.set(qualified, slice);\n this.reportAmbiguousName(sliceNames, 'slice', slice.name, qualified);\n }\n }\n\n private claim(seen: Map<string, string>, qualified: string, kind: string): boolean {\n const first = seen.get(qualified);\n if (first === undefined) {\n seen.set(qualified, kind);\n return true;\n }\n\n this.diagnostics.push({\n code: StructureDiagnosticCode.StructureDuplicateId,\n message: `Id '${qualified}' is declared more than once; the first ${first} wins.`,\n id: qualified,\n });\n return false;\n }\n\n private reportAmbiguousName(names: Map<string, string>, kind: string, name: string, qualified: string): void {\n const key = name.toLowerCase();\n const first = names.get(key);\n if (first !== undefined) {\n this.diagnostics.push({\n code: StructureDiagnosticCode.StructureAmbiguousName,\n message: `The ${kind} name '${name}' is used by both '${first}' and '${qualified}'.`,\n id: qualified,\n });\n return;\n }\n\n names.set(key, qualified);\n }\n}\n"],"names":["ApplicationStructureIndex","modules","Map","features","slices","featuresByName","diagnostics","structure","seen","names","module","qualified","id","claim","set","reportAmbiguousName","name","indexContainer","findModule","moduleId","get","findFeature","qualifiedId","firstFeature","firstFeatureId","feature","undefined","findSlice","kindOf","sliceId","kind","findFeaturesByName","toLowerCase","findSlicesByCommand","command","entries","filter","slice","SliceKind","StateChange","map","path","featureNames","sliceNames","key","byName","push","first","code","StructureDiagnosticCode","StructureDuplicateId","message","StructureAmbiguousName"],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ 'use strict';
2
+
3
+ // Copyright (c) Cratis. All rights reserved.
4
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
5
+ /**
6
+ * Where a slice's dialog template comes from.
7
+ */ var SliceDialogSource = /*#__PURE__*/ function(SliceDialogSource) {
8
+ /** The slice names its own dialog template. */ SliceDialogSource["Slice"] = "slice";
9
+ /** The slice names none, so the default form dialog is used. */ SliceDialogSource["Default"] = "default";
10
+ return SliceDialogSource;
11
+ }({});
12
+
13
+ exports.SliceDialogSource = SliceDialogSource;
14
+ //# sourceMappingURL=SliceDialogSource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SliceDialogSource.js","sources":["../../../toolbar/SliceDialogSource.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\n/**\n * Where a slice's dialog template comes from.\n */\nexport enum SliceDialogSource {\n /** The slice names its own dialog template. */\n Slice = 'slice',\n\n /** The slice names none, so the default form dialog is used. */\n Default = 'default',\n}\n"],"names":["SliceDialogSource"],"mappings":";;AAAA;AACA;AAEA;;IAGO,IAAKA,iBAAAA,iBAAAA,SAAAA,iBAAAA,EAAAA;oDACqC,iBAAA,CAAA,OAAA,CAAA,GAAA,OAAA;qEAGiB,iBAAA,CAAA,SAAA,CAAA,GAAA,SAAA;AAJtDA,IAAAA,OAAAA,iBAAAA;AAMX,CAAA,CAAA,EAAA;;"}
@@ -0,0 +1,16 @@
1
+ 'use strict';
2
+
3
+ // Copyright (c) Cratis. All rights reserved.
4
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
5
+ /**
6
+ * What is wrong with a toolbar button. The values are shared with the C# engine so both report the same code for
7
+ * the same toolbar.
8
+ */ var ToolbarDiagnosticCode = /*#__PURE__*/ function(ToolbarDiagnosticCode) {
9
+ /** A button invokes a slice the application structure does not have. */ ToolbarDiagnosticCode["ToolbarButtonSliceNotFound"] = "toolbarButtonSliceNotFound";
10
+ /** A button invokes a slice that is not a state change; state views and automations never take user input. */ ToolbarDiagnosticCode["ToolbarButtonSliceNotStateChange"] = "toolbarButtonSliceNotStateChange";
11
+ /** A button has no slice yet. It is allowed while designing, and flagged. */ ToolbarDiagnosticCode["ToolbarButtonSliceEmpty"] = "toolbarButtonSliceEmpty";
12
+ return ToolbarDiagnosticCode;
13
+ }({});
14
+
15
+ exports.ToolbarDiagnosticCode = ToolbarDiagnosticCode;
16
+ //# sourceMappingURL=ToolbarDiagnosticCode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolbarDiagnosticCode.js","sources":["../../../toolbar/ToolbarDiagnosticCode.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\n/**\n * What is wrong with a toolbar button. The values are shared with the C# engine so both report the same code for\n * the same toolbar.\n */\nexport enum ToolbarDiagnosticCode {\n /** A button invokes a slice the application structure does not have. */\n ToolbarButtonSliceNotFound = 'toolbarButtonSliceNotFound',\n\n /** A button invokes a slice that is not a state change; state views and automations never take user input. */\n ToolbarButtonSliceNotStateChange = 'toolbarButtonSliceNotStateChange',\n\n /** A button has no slice yet. It is allowed while designing, and flagged. */\n ToolbarButtonSliceEmpty = 'toolbarButtonSliceEmpty',\n}\n"],"names":["ToolbarDiagnosticCode"],"mappings":";;AAAA;AACA;AAEA;;;IAIO,IAAKA,qBAAAA,iBAAAA,SAAAA,qBAAAA,EAAAA;6EAC8D,qBAAA,CAAA,4BAAA,CAAA,GAAA,4BAAA;mHAGsC,qBAAA,CAAA,kCAAA,CAAA,GAAA,kCAAA;kFAGjC,qBAAA,CAAA,yBAAA,CAAA,GAAA,yBAAA;AAPnEA,IAAAA,OAAAA,qBAAAA;AASX,CAAA,CAAA,EAAA;;"}
@@ -0,0 +1,14 @@
1
+ 'use strict';
2
+
3
+ // Copyright (c) Cratis. All rights reserved.
4
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
5
+ /**
6
+ * How serious a toolbar diagnostic is.
7
+ */ var ToolbarDiagnosticSeverity = /*#__PURE__*/ function(ToolbarDiagnosticSeverity) {
8
+ /** The button cannot work. */ ToolbarDiagnosticSeverity["Error"] = "error";
9
+ /** The button is allowed but incomplete. */ ToolbarDiagnosticSeverity["Warning"] = "warning";
10
+ return ToolbarDiagnosticSeverity;
11
+ }({});
12
+
13
+ exports.ToolbarDiagnosticSeverity = ToolbarDiagnosticSeverity;
14
+ //# sourceMappingURL=ToolbarDiagnosticSeverity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolbarDiagnosticSeverity.js","sources":["../../../toolbar/ToolbarDiagnosticSeverity.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\n/**\n * How serious a toolbar diagnostic is.\n */\nexport enum ToolbarDiagnosticSeverity {\n /** The button cannot work. */\n Error = 'error',\n\n /** The button is allowed but incomplete. */\n Warning = 'warning',\n}\n"],"names":["ToolbarDiagnosticSeverity"],"mappings":";;AAAA;AACA;AAEA;;IAGO,IAAKA,yBAAAA,iBAAAA,SAAAA,yBAAAA,EAAAA;mCACoB,yBAAA,CAAA,OAAA,CAAA,GAAA,OAAA;iDAGc,yBAAA,CAAA,SAAA,CAAA,GAAA,SAAA;AAJlCA,IAAAA,OAAAA,yBAAAA;AAMX,CAAA,CAAA,EAAA;;"}