@cohesivesystems/presentation-react 0.1.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +55 -0
- package/dist/collection-chrome-slot-renderer-registry.d.ts +12 -0
- package/dist/collection-chrome-slot-renderer-registry.d.ts.map +1 -0
- package/dist/collection-chrome-slot-renderer-registry.js +12 -0
- package/dist/collection-chrome-slot-renderer-registry.js.map +1 -0
- package/dist/collection-selection-state-context.d.ts +6 -0
- package/dist/collection-selection-state-context.d.ts.map +1 -0
- package/dist/collection-selection-state-context.js +25 -0
- package/dist/collection-selection-state-context.js.map +1 -0
- package/dist/collection-selection-state.d.ts +3 -0
- package/dist/collection-selection-state.d.ts.map +1 -0
- package/dist/collection-selection-state.js +52 -0
- package/dist/collection-selection-state.js.map +1 -0
- package/dist/document-workspace-runtime.d.ts +262 -0
- package/dist/document-workspace-runtime.d.ts.map +1 -0
- package/dist/document-workspace-runtime.js +699 -0
- package/dist/document-workspace-runtime.js.map +1 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/input-form-endpoint-runtime.d.ts +140 -0
- package/dist/input-form-endpoint-runtime.d.ts.map +1 -0
- package/dist/input-form-endpoint-runtime.js +280 -0
- package/dist/input-form-endpoint-runtime.js.map +1 -0
- package/dist/local-flow-state-data-source-projection.d.ts +21 -0
- package/dist/local-flow-state-data-source-projection.d.ts.map +1 -0
- package/dist/local-flow-state-data-source-projection.js +65 -0
- package/dist/local-flow-state-data-source-projection.js.map +1 -0
- package/dist/navigation-runtime-context.d.ts +22 -0
- package/dist/navigation-runtime-context.d.ts.map +1 -0
- package/dist/navigation-runtime-context.js +23 -0
- package/dist/navigation-runtime-context.js.map +1 -0
- package/dist/navigation-shell-frame-renderer-registry.d.ts +20 -0
- package/dist/navigation-shell-frame-renderer-registry.d.ts.map +1 -0
- package/dist/navigation-shell-frame-renderer-registry.js +9 -0
- package/dist/navigation-shell-frame-renderer-registry.js.map +1 -0
- package/dist/navigation-shell-region-component-registry.d.ts +50 -0
- package/dist/navigation-shell-region-component-registry.d.ts.map +1 -0
- package/dist/navigation-shell-region-component-registry.js +44 -0
- package/dist/navigation-shell-region-component-registry.js.map +1 -0
- package/dist/navigation-shell-slot-renderer-registry.d.ts +22 -0
- package/dist/navigation-shell-slot-renderer-registry.d.ts.map +1 -0
- package/dist/navigation-shell-slot-renderer-registry.js +9 -0
- package/dist/navigation-shell-slot-renderer-registry.js.map +1 -0
- package/dist/page-host-projection.d.ts +127 -0
- package/dist/page-host-projection.d.ts.map +1 -0
- package/dist/page-host-projection.js +59 -0
- package/dist/page-host-projection.js.map +1 -0
- package/dist/page-host-renderer-registry.d.ts +72 -0
- package/dist/page-host-renderer-registry.d.ts.map +1 -0
- package/dist/page-host-renderer-registry.js +63 -0
- package/dist/page-host-renderer-registry.js.map +1 -0
- package/dist/presentation-action-group-runtime-options.d.ts +36 -0
- package/dist/presentation-action-group-runtime-options.d.ts.map +1 -0
- package/dist/presentation-action-group-runtime-options.js +50 -0
- package/dist/presentation-action-group-runtime-options.js.map +1 -0
- package/dist/presentation-action-runtime.d.ts +52 -0
- package/dist/presentation-action-runtime.d.ts.map +1 -0
- package/dist/presentation-action-runtime.js +78 -0
- package/dist/presentation-action-runtime.js.map +1 -0
- package/dist/presentation-data-source-binding-runtime.d.ts +3 -0
- package/dist/presentation-data-source-binding-runtime.d.ts.map +1 -0
- package/dist/presentation-data-source-binding-runtime.js +65 -0
- package/dist/presentation-data-source-binding-runtime.js.map +1 -0
- package/dist/presentation-data-source-binding.d.ts +12 -0
- package/dist/presentation-data-source-binding.d.ts.map +1 -0
- package/dist/presentation-data-source-binding.js +13 -0
- package/dist/presentation-data-source-binding.js.map +1 -0
- package/dist/presentation-flow-runtime.d.ts +139 -0
- package/dist/presentation-flow-runtime.d.ts.map +1 -0
- package/dist/presentation-flow-runtime.js +514 -0
- package/dist/presentation-flow-runtime.js.map +1 -0
- package/dist/presentation-module-context.d.ts +4 -0
- package/dist/presentation-module-context.d.ts.map +1 -0
- package/dist/presentation-module-context.js +6 -0
- package/dist/presentation-module-context.js.map +1 -0
- package/dist/presentation-module-provider.d.ts +7 -0
- package/dist/presentation-module-provider.d.ts.map +1 -0
- package/dist/presentation-module-provider.js +7 -0
- package/dist/presentation-module-provider.js.map +1 -0
- package/dist/presentation-projection-diagnostics-context.d.ts +8 -0
- package/dist/presentation-projection-diagnostics-context.d.ts.map +1 -0
- package/dist/presentation-projection-diagnostics-context.js +3 -0
- package/dist/presentation-projection-diagnostics-context.js.map +1 -0
- package/dist/presentation-projection-diagnostics-hooks.d.ts +4 -0
- package/dist/presentation-projection-diagnostics-hooks.d.ts.map +1 -0
- package/dist/presentation-projection-diagnostics-hooks.js +17 -0
- package/dist/presentation-projection-diagnostics-hooks.js.map +1 -0
- package/dist/presentation-projection-diagnostics-runtime.d.ts +12 -0
- package/dist/presentation-projection-diagnostics-runtime.d.ts.map +1 -0
- package/dist/presentation-projection-diagnostics-runtime.js +54 -0
- package/dist/presentation-projection-diagnostics-runtime.js.map +1 -0
- package/dist/presentation-projection-trace.d.ts +27 -0
- package/dist/presentation-projection-trace.d.ts.map +1 -0
- package/dist/presentation-projection-trace.js +54 -0
- package/dist/presentation-projection-trace.js.map +1 -0
- package/dist/presentation-query-form-runtime.d.ts +30 -0
- package/dist/presentation-query-form-runtime.d.ts.map +1 -0
- package/dist/presentation-query-form-runtime.js +75 -0
- package/dist/presentation-query-form-runtime.js.map +1 -0
- package/dist/presentation-query-form-state-adapter-registry.d.ts +4 -0
- package/dist/presentation-query-form-state-adapter-registry.d.ts.map +1 -0
- package/dist/presentation-query-form-state-adapter-registry.js +13 -0
- package/dist/presentation-query-form-state-adapter-registry.js.map +1 -0
- package/dist/presentation-query-form-state-context.d.ts +20 -0
- package/dist/presentation-query-form-state-context.d.ts.map +1 -0
- package/dist/presentation-query-form-state-context.js +20 -0
- package/dist/presentation-query-form-state-context.js.map +1 -0
- package/dist/presentation-query-form-state.d.ts +29 -0
- package/dist/presentation-query-form-state.d.ts.map +1 -0
- package/dist/presentation-query-form-state.js +99 -0
- package/dist/presentation-query-form-state.js.map +1 -0
- package/dist/presentation-renderer-registry.d.ts +109 -0
- package/dist/presentation-renderer-registry.d.ts.map +1 -0
- package/dist/presentation-renderer-registry.js +25 -0
- package/dist/presentation-renderer-registry.js.map +1 -0
- package/dist/presentation-standards-context.d.ts +4 -0
- package/dist/presentation-standards-context.d.ts.map +1 -0
- package/dist/presentation-standards-context.js +12 -0
- package/dist/presentation-standards-context.js.map +1 -0
- package/dist/presentation-standards-provider.d.ts +14 -0
- package/dist/presentation-standards-provider.d.ts.map +1 -0
- package/dist/presentation-standards-provider.js +16 -0
- package/dist/presentation-standards-provider.js.map +1 -0
- package/dist/projected-document-action-runtime-bindings.d.ts +20 -0
- package/dist/projected-document-action-runtime-bindings.d.ts.map +1 -0
- package/dist/projected-document-action-runtime-bindings.js +88 -0
- package/dist/projected-document-action-runtime-bindings.js.map +1 -0
- package/dist/projected-document-action-runtime.d.ts +76 -0
- package/dist/projected-document-action-runtime.d.ts.map +1 -0
- package/dist/projected-document-action-runtime.js +224 -0
- package/dist/projected-document-action-runtime.js.map +1 -0
- package/dist/projected-document-process-preview-action-runtime-bindings.d.ts +26 -0
- package/dist/projected-document-process-preview-action-runtime-bindings.d.ts.map +1 -0
- package/dist/projected-document-process-preview-action-runtime-bindings.js +106 -0
- package/dist/projected-document-process-preview-action-runtime-bindings.js.map +1 -0
- package/dist/projected-document-process-preview-action-runtime.d.ts +321 -0
- package/dist/projected-document-process-preview-action-runtime.d.ts.map +1 -0
- package/dist/projected-document-process-preview-action-runtime.js +729 -0
- package/dist/projected-document-process-preview-action-runtime.js.map +1 -0
- package/dist/projected-document-process-preview-capability-runtime.d.ts +47 -0
- package/dist/projected-document-process-preview-capability-runtime.d.ts.map +1 -0
- package/dist/projected-document-process-preview-capability-runtime.js +49 -0
- package/dist/projected-document-process-preview-capability-runtime.js.map +1 -0
- package/dist/projected-document-workspace-action-runtime.d.ts +87 -0
- package/dist/projected-document-workspace-action-runtime.d.ts.map +1 -0
- package/dist/projected-document-workspace-action-runtime.js +150 -0
- package/dist/projected-document-workspace-action-runtime.js.map +1 -0
- package/dist/projected-document-workspace-projection-renderer-diagnostics.d.ts +18 -0
- package/dist/projected-document-workspace-projection-renderer-diagnostics.d.ts.map +1 -0
- package/dist/projected-document-workspace-projection-renderer-diagnostics.js +207 -0
- package/dist/projected-document-workspace-projection-renderer-diagnostics.js.map +1 -0
- package/dist/projected-document-workspace-runtime-binding-diagnostics.d.ts +19 -0
- package/dist/projected-document-workspace-runtime-binding-diagnostics.d.ts.map +1 -0
- package/dist/projected-document-workspace-runtime-binding-diagnostics.js +124 -0
- package/dist/projected-document-workspace-runtime-binding-diagnostics.js.map +1 -0
- package/dist/projected-navigation-provider.d.ts +16 -0
- package/dist/projected-navigation-provider.d.ts.map +1 -0
- package/dist/projected-navigation-provider.js +51 -0
- package/dist/projected-navigation-provider.js.map +1 -0
- package/dist/projected-presentation-flow-host.d.ts +16 -0
- package/dist/projected-presentation-flow-host.d.ts.map +1 -0
- package/dist/projected-presentation-flow-host.js +14 -0
- package/dist/projected-presentation-flow-host.js.map +1 -0
- package/dist/projected-query-form-state-adapter.d.ts +12 -0
- package/dist/projected-query-form-state-adapter.d.ts.map +1 -0
- package/dist/projected-query-form-state-adapter.js +361 -0
- package/dist/projected-query-form-state-adapter.js.map +1 -0
- package/dist/react-router-binding.d.ts +133 -0
- package/dist/react-router-binding.d.ts.map +1 -0
- package/dist/react-router-binding.js +76 -0
- package/dist/react-router-binding.js.map +1 -0
- package/dist/react-router-path.d.ts +4 -0
- package/dist/react-router-path.d.ts.map +1 -0
- package/dist/react-router-path.js +11 -0
- package/dist/react-router-path.js.map +1 -0
- package/dist/scope-selection-context.d.ts +28 -0
- package/dist/scope-selection-context.d.ts.map +1 -0
- package/dist/scope-selection-context.js +13 -0
- package/dist/scope-selection-context.js.map +1 -0
- package/dist/scope-selection-provider.d.ts +33 -0
- package/dist/scope-selection-provider.d.ts.map +1 -0
- package/dist/scope-selection-provider.js +162 -0
- package/dist/scope-selection-provider.js.map +1 -0
- package/dist/scope-selection-request.d.ts +6 -0
- package/dist/scope-selection-request.d.ts.map +1 -0
- package/dist/scope-selection-request.js +12 -0
- package/dist/scope-selection-request.js.map +1 -0
- package/dist/standard-navigation-shell-frame-renderers.d.ts +15 -0
- package/dist/standard-navigation-shell-frame-renderers.d.ts.map +1 -0
- package/dist/standard-navigation-shell-frame-renderers.js +22 -0
- package/dist/standard-navigation-shell-frame-renderers.js.map +1 -0
- package/dist/standard-navigation-shell-slot-renderers.d.ts +59 -0
- package/dist/standard-navigation-shell-slot-renderers.d.ts.map +1 -0
- package/dist/standard-navigation-shell-slot-renderers.js +67 -0
- package/dist/standard-navigation-shell-slot-renderers.js.map +1 -0
- package/dist/view-chrome-slot-renderer-registry.d.ts +12 -0
- package/dist/view-chrome-slot-renderer-registry.d.ts.map +1 -0
- package/dist/view-chrome-slot-renderer-registry.js +12 -0
- package/dist/view-chrome-slot-renderer-registry.js.map +1 -0
- package/package.json +60 -0
- package/src/collection-chrome-slot-renderer-registry.ts +66 -0
- package/src/collection-selection-state-context.ts +51 -0
- package/src/collection-selection-state.tsx +101 -0
- package/src/document-workspace-runtime.tsx +1505 -0
- package/src/index.ts +50 -0
- package/src/input-form-endpoint-runtime.ts +632 -0
- package/src/local-flow-state-data-source-projection.ts +133 -0
- package/src/navigation-runtime-context.ts +40 -0
- package/src/navigation-shell-frame-renderer-registry.ts +54 -0
- package/src/navigation-shell-region-component-registry.tsx +127 -0
- package/src/navigation-shell-slot-renderer-registry.ts +88 -0
- package/src/page-host-projection.ts +356 -0
- package/src/page-host-renderer-registry.tsx +353 -0
- package/src/presentation-action-group-runtime-options.ts +121 -0
- package/src/presentation-action-runtime.ts +190 -0
- package/src/presentation-data-source-binding-runtime.ts +109 -0
- package/src/presentation-data-source-binding.tsx +24 -0
- package/src/presentation-flow-runtime.tsx +835 -0
- package/src/presentation-module-context.ts +10 -0
- package/src/presentation-module-provider.tsx +19 -0
- package/src/presentation-projection-diagnostics-context.ts +17 -0
- package/src/presentation-projection-diagnostics-hooks.ts +29 -0
- package/src/presentation-projection-diagnostics-runtime.tsx +95 -0
- package/src/presentation-projection-trace.ts +117 -0
- package/src/presentation-query-form-runtime.ts +148 -0
- package/src/presentation-query-form-state-adapter-registry.ts +25 -0
- package/src/presentation-query-form-state-context.ts +56 -0
- package/src/presentation-query-form-state.tsx +250 -0
- package/src/presentation-renderer-registry.ts +214 -0
- package/src/presentation-standards-context.ts +21 -0
- package/src/presentation-standards-provider.tsx +44 -0
- package/src/projected-document-action-runtime-bindings.ts +132 -0
- package/src/projected-document-action-runtime.ts +414 -0
- package/src/projected-document-process-preview-action-runtime-bindings.ts +231 -0
- package/src/projected-document-process-preview-action-runtime.ts +1725 -0
- package/src/projected-document-process-preview-capability-runtime.ts +216 -0
- package/src/projected-document-workspace-action-runtime.ts +402 -0
- package/src/projected-document-workspace-projection-renderer-diagnostics.ts +342 -0
- package/src/projected-document-workspace-runtime-binding-diagnostics.ts +208 -0
- package/src/projected-navigation-provider.tsx +104 -0
- package/src/projected-presentation-flow-host.tsx +46 -0
- package/src/projected-query-form-state-adapter.ts +578 -0
- package/src/react-router-binding.tsx +417 -0
- package/src/react-router-path.ts +16 -0
- package/src/scope-selection-context.ts +58 -0
- package/src/scope-selection-provider.tsx +324 -0
- package/src/scope-selection-request.ts +21 -0
- package/src/standard-navigation-shell-frame-renderers.tsx +106 -0
- package/src/standard-navigation-shell-slot-renderers.tsx +289 -0
- package/src/view-chrome-slot-renderer-registry.ts +66 -0
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
PresentationModuleDefinition,
|
|
3
|
+
} from '@cohesivesystems/presentation-core'
|
|
4
|
+
import type {
|
|
5
|
+
DocumentWorkspaceProjectionRendererRegistry,
|
|
6
|
+
DocumentWorkspaceProjectionRendererResolution,
|
|
7
|
+
DocumentWorkspaceRuntimeSnapshot,
|
|
8
|
+
} from './document-workspace-runtime'
|
|
9
|
+
import {
|
|
10
|
+
resolveDocumentWorkspaceProjectionCapability,
|
|
11
|
+
resolveDocumentWorkspaceProjectionRenderer,
|
|
12
|
+
} from './document-workspace-runtime'
|
|
13
|
+
import type {
|
|
14
|
+
PresentationProjectionDiagnostic,
|
|
15
|
+
} from '@cohesivesystems/presentation-core'
|
|
16
|
+
import {
|
|
17
|
+
createPresentationEnumDiscriminator,
|
|
18
|
+
matchesPresentationEnum,
|
|
19
|
+
} from '@cohesivesystems/presentation-core'
|
|
20
|
+
import {
|
|
21
|
+
coordinationActionKinds,
|
|
22
|
+
coordinationTriggerKinds,
|
|
23
|
+
} from '@cohesivesystems/presentation-contracts'
|
|
24
|
+
|
|
25
|
+
export interface ProjectDocumentWorkspaceProjectionRendererDiagnosticsOptions<
|
|
26
|
+
TContext,
|
|
27
|
+
TComponentSystem = unknown,
|
|
28
|
+
TDesignSystem = unknown,
|
|
29
|
+
> {
|
|
30
|
+
readonly componentSet?: string | null
|
|
31
|
+
readonly module: PresentationModuleDefinition | null
|
|
32
|
+
readonly projectionRenderers: DocumentWorkspaceProjectionRendererRegistry<
|
|
33
|
+
TContext,
|
|
34
|
+
TComponentSystem,
|
|
35
|
+
TDesignSystem
|
|
36
|
+
>
|
|
37
|
+
readonly runtime: DocumentWorkspaceRuntimeSnapshot
|
|
38
|
+
readonly sourceId?: string
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Reports projection renderer coverage for the document views exposed by the
|
|
43
|
+
* active workspace runtime. The same semantic resolver used for rendering is
|
|
44
|
+
* used here so the developer toolbar reports stale component bindings and
|
|
45
|
+
* unhandled IR projection semantics as actionable frontend TODOs.
|
|
46
|
+
*/
|
|
47
|
+
export function projectDocumentWorkspaceProjectionRendererDiagnostics<
|
|
48
|
+
TContext,
|
|
49
|
+
TComponentSystem = unknown,
|
|
50
|
+
TDesignSystem = unknown,
|
|
51
|
+
>({
|
|
52
|
+
componentSet,
|
|
53
|
+
module,
|
|
54
|
+
projectionRenderers,
|
|
55
|
+
runtime,
|
|
56
|
+
sourceId = 'document-workspace-projection-renderers',
|
|
57
|
+
}: ProjectDocumentWorkspaceProjectionRendererDiagnosticsOptions<
|
|
58
|
+
TContext,
|
|
59
|
+
TComponentSystem,
|
|
60
|
+
TDesignSystem
|
|
61
|
+
>): readonly PresentationProjectionDiagnostic[] {
|
|
62
|
+
return [
|
|
63
|
+
...runtime.projectionViewIds.flatMap((viewId) =>
|
|
64
|
+
projectProjectionRendererDiagnostics({
|
|
65
|
+
componentSet,
|
|
66
|
+
module,
|
|
67
|
+
projectionRenderers,
|
|
68
|
+
runtime,
|
|
69
|
+
sourceId,
|
|
70
|
+
viewId,
|
|
71
|
+
}),
|
|
72
|
+
),
|
|
73
|
+
...projectProjectionCoordinationDiagnostics({
|
|
74
|
+
componentSet,
|
|
75
|
+
module,
|
|
76
|
+
projectionRenderers,
|
|
77
|
+
runtime,
|
|
78
|
+
sourceId,
|
|
79
|
+
}),
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function projectProjectionRendererDiagnostics<
|
|
84
|
+
TContext,
|
|
85
|
+
TComponentSystem = unknown,
|
|
86
|
+
TDesignSystem = unknown,
|
|
87
|
+
>({
|
|
88
|
+
componentSet,
|
|
89
|
+
module,
|
|
90
|
+
projectionRenderers,
|
|
91
|
+
runtime,
|
|
92
|
+
sourceId,
|
|
93
|
+
viewId,
|
|
94
|
+
}: ProjectDocumentWorkspaceProjectionRendererDiagnosticsOptions<
|
|
95
|
+
TContext,
|
|
96
|
+
TComponentSystem,
|
|
97
|
+
TDesignSystem
|
|
98
|
+
> & {
|
|
99
|
+
readonly viewId: string
|
|
100
|
+
}) {
|
|
101
|
+
const resolution = resolveDocumentWorkspaceProjectionRenderer({
|
|
102
|
+
componentSet,
|
|
103
|
+
module,
|
|
104
|
+
registry: projectionRenderers,
|
|
105
|
+
runtime,
|
|
106
|
+
viewId,
|
|
107
|
+
})
|
|
108
|
+
const projection = resolution.projection
|
|
109
|
+
|
|
110
|
+
if (!projection) {
|
|
111
|
+
return [
|
|
112
|
+
{
|
|
113
|
+
details: { viewId },
|
|
114
|
+
id: `document-projection.${viewId}.missing-projection`,
|
|
115
|
+
message:
|
|
116
|
+
`Document workspace view '${viewId}' does not resolve to a declared ` +
|
|
117
|
+
'document projection.',
|
|
118
|
+
severity: 'warning',
|
|
119
|
+
source: sourceId ?? 'document-workspace-projection-renderers',
|
|
120
|
+
subject: {
|
|
121
|
+
id: viewId,
|
|
122
|
+
kind: 'document-projection-view',
|
|
123
|
+
},
|
|
124
|
+
} satisfies PresentationProjectionDiagnostic,
|
|
125
|
+
]
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const diagnostics: PresentationProjectionDiagnostic[] = []
|
|
129
|
+
if (!resolution.renderer) {
|
|
130
|
+
diagnostics.push({
|
|
131
|
+
details: createProjectionRendererDiagnosticDetails(resolution, viewId),
|
|
132
|
+
id: `document-projection.${projection.Id}.missing-renderer`,
|
|
133
|
+
message: `Document projection '${projection.Name}' has no frontend renderer binding.`,
|
|
134
|
+
severity: 'warning',
|
|
135
|
+
source: sourceId ?? 'document-workspace-projection-renderers',
|
|
136
|
+
subject: {
|
|
137
|
+
id: projection.Id,
|
|
138
|
+
kind: 'document-projection',
|
|
139
|
+
name: projection.Name,
|
|
140
|
+
},
|
|
141
|
+
})
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (resolution.renderer && isCompatibilityRendererSource(resolution.resolutionSource)) {
|
|
145
|
+
diagnostics.push({
|
|
146
|
+
details: createProjectionRendererDiagnosticDetails(resolution, viewId),
|
|
147
|
+
id: `document-projection.${projection.Id}.semantic-renderer-fallback`,
|
|
148
|
+
category: resolution.componentRole ? 'unbound' : 'missing-binding',
|
|
149
|
+
interpretation: {
|
|
150
|
+
status: resolution.componentRole ? 'unbound' : 'locally-interpreted',
|
|
151
|
+
target: 'document-projection-component-role',
|
|
152
|
+
},
|
|
153
|
+
message: resolution.componentRole
|
|
154
|
+
? `Document projection '${projection.Name}' declares component role ` +
|
|
155
|
+
`'${resolution.componentRole}', but rendering fell back to ` +
|
|
156
|
+
`'${resolution.resolutionSource}'.`
|
|
157
|
+
: `Document projection '${projection.Name}' rendered through ` +
|
|
158
|
+
`'${resolution.resolutionSource}' because it has no ProjectionRenderer ` +
|
|
159
|
+
'target component role binding.',
|
|
160
|
+
severity: 'warning',
|
|
161
|
+
source: sourceId ?? 'document-workspace-projection-renderers',
|
|
162
|
+
suggestedNextStep: resolution.componentRole
|
|
163
|
+
? `Bind frontend component role '${resolution.componentRole}' in the document projection component pack.`
|
|
164
|
+
: 'Declare a ProjectionRenderer target binding with ComponentRole for this projection and bind that role in the frontend component pack.',
|
|
165
|
+
subject: {
|
|
166
|
+
id: projection.Id,
|
|
167
|
+
kind: 'document-projection',
|
|
168
|
+
name: projection.Name,
|
|
169
|
+
},
|
|
170
|
+
})
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (
|
|
174
|
+
resolution.renderer &&
|
|
175
|
+
resolution.componentKey &&
|
|
176
|
+
resolution.resolutionSource === 'component-key'
|
|
177
|
+
) {
|
|
178
|
+
diagnostics.push({
|
|
179
|
+
category: 'escape-hatch',
|
|
180
|
+
details: createProjectionRendererDiagnosticDetails(resolution, viewId),
|
|
181
|
+
id: `document-projection.${projection.Id}.component-key-escape-hatch`,
|
|
182
|
+
interpretation: {
|
|
183
|
+
status: 'escape-hatch',
|
|
184
|
+
target: 'document-projection-component-key',
|
|
185
|
+
},
|
|
186
|
+
message:
|
|
187
|
+
`Document projection '${projection.Name}' rendered through concrete ` +
|
|
188
|
+
`component key '${resolution.componentKey}' as an escape hatch.`,
|
|
189
|
+
severity: 'warning',
|
|
190
|
+
source: sourceId ?? 'document-workspace-projection-renderers',
|
|
191
|
+
suggestedNextStep:
|
|
192
|
+
'Prefer ComponentRole for document projections and keep ComponentKey only for adapter-specific overrides.',
|
|
193
|
+
subject: {
|
|
194
|
+
id: projection.Id,
|
|
195
|
+
kind: 'document-projection',
|
|
196
|
+
name: projection.Name,
|
|
197
|
+
},
|
|
198
|
+
})
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (resolution.rendererKey) {
|
|
202
|
+
diagnostics.push({
|
|
203
|
+
category: 'escape-hatch',
|
|
204
|
+
details: createProjectionRendererDiagnosticDetails(resolution, viewId),
|
|
205
|
+
id: `document-projection.${projection.Id}.legacy-renderer-key`,
|
|
206
|
+
interpretation: {
|
|
207
|
+
status: 'escape-hatch',
|
|
208
|
+
target: 'document-projection-component-role',
|
|
209
|
+
},
|
|
210
|
+
message:
|
|
211
|
+
`Document projection '${projection.Name}' declares renderer key ` +
|
|
212
|
+
`'${resolution.rendererKey}'. Document projection dispatch now uses ` +
|
|
213
|
+
'ProjectionRenderer target component roles and semantic projection interpretation.',
|
|
214
|
+
severity: 'warning',
|
|
215
|
+
source: sourceId ?? 'document-workspace-projection-renderers',
|
|
216
|
+
suggestedNextStep:
|
|
217
|
+
'Replace the renderer key with a ProjectionRenderer target binding that declares ComponentRole.',
|
|
218
|
+
subject: {
|
|
219
|
+
id: projection.Id,
|
|
220
|
+
kind: 'document-projection',
|
|
221
|
+
name: projection.Name,
|
|
222
|
+
},
|
|
223
|
+
})
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return diagnostics
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function isCompatibilityRendererSource(
|
|
230
|
+
source: DocumentWorkspaceProjectionRendererResolution<
|
|
231
|
+
unknown,
|
|
232
|
+
unknown,
|
|
233
|
+
unknown
|
|
234
|
+
>['resolutionSource'],
|
|
235
|
+
) {
|
|
236
|
+
return source === 'projection-kind' ||
|
|
237
|
+
source === 'semantic-reference-kind' ||
|
|
238
|
+
source === 'subject-kind'
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function projectProjectionCoordinationDiagnostics<
|
|
242
|
+
TContext,
|
|
243
|
+
TComponentSystem = unknown,
|
|
244
|
+
TDesignSystem = unknown,
|
|
245
|
+
>({
|
|
246
|
+
componentSet,
|
|
247
|
+
module,
|
|
248
|
+
projectionRenderers,
|
|
249
|
+
runtime,
|
|
250
|
+
sourceId = 'document-workspace-projection-renderers',
|
|
251
|
+
}: ProjectDocumentWorkspaceProjectionRendererDiagnosticsOptions<
|
|
252
|
+
TContext,
|
|
253
|
+
TComponentSystem,
|
|
254
|
+
TDesignSystem
|
|
255
|
+
>) {
|
|
256
|
+
const revealTargetProjectionIds = new Set(
|
|
257
|
+
runtime.documentProfile.Coordination
|
|
258
|
+
.filter((coordination) =>
|
|
259
|
+
matchesPresentationEnum(coordination.Trigger.Kind, selectionChangedTriggerKind) &&
|
|
260
|
+
matchesPresentationEnum(coordination.Action.Kind, revealSemanticSelectionActionKind),
|
|
261
|
+
)
|
|
262
|
+
.flatMap((coordination) => coordination.Action.TargetProjectionIds),
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
return [...revealTargetProjectionIds].flatMap((projectionId) => {
|
|
266
|
+
const projection = runtime.projections.find((candidate) => candidate.Id === projectionId)
|
|
267
|
+
if (!projection) {
|
|
268
|
+
return []
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const hasRevealCapability = resolveDocumentWorkspaceProjectionCapability({
|
|
272
|
+
capability: 'revealSemanticSelection',
|
|
273
|
+
componentSet,
|
|
274
|
+
module,
|
|
275
|
+
projection,
|
|
276
|
+
registry: projectionRenderers,
|
|
277
|
+
})
|
|
278
|
+
if (hasRevealCapability) {
|
|
279
|
+
return []
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return [
|
|
283
|
+
{
|
|
284
|
+
details: {
|
|
285
|
+
coordinationActionKind: 'RevealSemanticSelection',
|
|
286
|
+
projectionKind: projection.Kind,
|
|
287
|
+
semanticReferenceKind: projection.Coordinates?.SemanticReferenceKind ?? null,
|
|
288
|
+
subjectKind: projection.Subject.Kind,
|
|
289
|
+
viewId: projection.ViewId,
|
|
290
|
+
},
|
|
291
|
+
id: `document-projection.${projection.Id}.missing-reveal-semantic-selection`,
|
|
292
|
+
message:
|
|
293
|
+
`Document projection '${projection.Name}' is targeted by semantic ` +
|
|
294
|
+
'selection reveal coordination, but this frontend adapter has not ' +
|
|
295
|
+
'declared a reveal interpretation for it.',
|
|
296
|
+
severity: 'warning',
|
|
297
|
+
source: sourceId,
|
|
298
|
+
subject: {
|
|
299
|
+
id: projection.Id,
|
|
300
|
+
kind: 'document-projection',
|
|
301
|
+
name: projection.Name,
|
|
302
|
+
},
|
|
303
|
+
} satisfies PresentationProjectionDiagnostic,
|
|
304
|
+
]
|
|
305
|
+
})
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
function createProjectionRendererDiagnosticDetails<
|
|
309
|
+
TContext,
|
|
310
|
+
TComponentSystem,
|
|
311
|
+
TDesignSystem,
|
|
312
|
+
>(
|
|
313
|
+
resolution: DocumentWorkspaceProjectionRendererResolution<
|
|
314
|
+
TContext,
|
|
315
|
+
TComponentSystem,
|
|
316
|
+
TDesignSystem
|
|
317
|
+
>,
|
|
318
|
+
viewId: string,
|
|
319
|
+
) {
|
|
320
|
+
return {
|
|
321
|
+
componentKey: resolution.componentKey,
|
|
322
|
+
componentRole: resolution.componentRole,
|
|
323
|
+
projectionKind: resolution.projection?.Kind ?? null,
|
|
324
|
+
rendererKey: resolution.rendererKey,
|
|
325
|
+
resolutionSource: resolution.resolutionSource,
|
|
326
|
+
semanticReferenceKind: resolution.projection?.Coordinates?.SemanticReferenceKind ?? null,
|
|
327
|
+
subjectKind: resolution.projection?.Subject.Kind ?? null,
|
|
328
|
+
viewId,
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const selectionChangedTriggerKind = createPresentationEnumDiscriminator(
|
|
333
|
+
coordinationTriggerKinds,
|
|
334
|
+
'selectionChanged',
|
|
335
|
+
'SelectionChanged',
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
const revealSemanticSelectionActionKind = createPresentationEnumDiscriminator(
|
|
339
|
+
coordinationActionKinds,
|
|
340
|
+
'revealSemanticSelection',
|
|
341
|
+
'RevealSemanticSelection',
|
|
342
|
+
)
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
PresentationModuleDefinition,
|
|
3
|
+
} from '@cohesivesystems/presentation-core'
|
|
4
|
+
import {
|
|
5
|
+
createPresentationProjectionDiagnostic,
|
|
6
|
+
type PresentationProjectionDiagnostic,
|
|
7
|
+
} from '@cohesivesystems/presentation-core'
|
|
8
|
+
import {
|
|
9
|
+
createPresentationEnumDiscriminator,
|
|
10
|
+
findPresentationComponentBinding,
|
|
11
|
+
} from '@cohesivesystems/presentation-core'
|
|
12
|
+
import type {
|
|
13
|
+
DocumentWorkspaceRuntimeSnapshot,
|
|
14
|
+
} from './document-workspace-runtime'
|
|
15
|
+
import {
|
|
16
|
+
workspaceRuntimeComponentRoles,
|
|
17
|
+
} from '@cohesivesystems/presentation-contracts'
|
|
18
|
+
import {
|
|
19
|
+
presentationBindingKinds,
|
|
20
|
+
presentationTargetKinds,
|
|
21
|
+
} from '@cohesivesystems/presentation-contracts'
|
|
22
|
+
|
|
23
|
+
export interface ProjectDocumentWorkspaceRuntimeBindingDiagnosticsOptions {
|
|
24
|
+
readonly componentSet?: string | null
|
|
25
|
+
readonly module: PresentationModuleDefinition | null
|
|
26
|
+
readonly runtime: DocumentWorkspaceRuntimeSnapshot
|
|
27
|
+
readonly sourceId?: string
|
|
28
|
+
readonly supportedComponentRoles?: readonly string[]
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const defaultSupportedDocumentWorkspaceRuntimeRoles = [
|
|
32
|
+
workspaceRuntimeComponentRoles.documentWorkspace,
|
|
33
|
+
] as const
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Reports whether the backend WorkspaceRuntime target binding is projected as
|
|
37
|
+
* a semantic component role that this frontend document workspace host
|
|
38
|
+
* interprets. The host still mounts the runtime locally, but this diagnostic
|
|
39
|
+
* keeps the target binding honest and prevents concrete ComponentKey bindings
|
|
40
|
+
* from quietly lingering.
|
|
41
|
+
*/
|
|
42
|
+
export function projectDocumentWorkspaceRuntimeBindingDiagnostics({
|
|
43
|
+
componentSet,
|
|
44
|
+
module,
|
|
45
|
+
runtime,
|
|
46
|
+
sourceId = 'document-workspace-runtime-binding',
|
|
47
|
+
supportedComponentRoles = defaultSupportedDocumentWorkspaceRuntimeRoles,
|
|
48
|
+
}: ProjectDocumentWorkspaceRuntimeBindingDiagnosticsOptions): readonly PresentationProjectionDiagnostic[] {
|
|
49
|
+
if (!module) {
|
|
50
|
+
return []
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const binding = findPresentationComponentBinding(module, {
|
|
54
|
+
bindingKind: createPresentationEnumDiscriminator(
|
|
55
|
+
presentationBindingKinds,
|
|
56
|
+
'workspaceRuntime',
|
|
57
|
+
'WorkspaceRuntime',
|
|
58
|
+
),
|
|
59
|
+
componentSet,
|
|
60
|
+
id: runtime.workspace.Id,
|
|
61
|
+
targetKind: createPresentationEnumDiscriminator(
|
|
62
|
+
presentationTargetKinds,
|
|
63
|
+
'react',
|
|
64
|
+
'React',
|
|
65
|
+
),
|
|
66
|
+
})
|
|
67
|
+
const componentKey = binding?.ComponentKey ?? null
|
|
68
|
+
const componentRole = binding?.ComponentRole ?? null
|
|
69
|
+
const supportedRoleSet = new Set(supportedComponentRoles)
|
|
70
|
+
const diagnostics: PresentationProjectionDiagnostic[] = []
|
|
71
|
+
|
|
72
|
+
if (!binding) {
|
|
73
|
+
diagnostics.push(
|
|
74
|
+
createWorkspaceRuntimeDiagnostic({
|
|
75
|
+
category: 'missing-binding',
|
|
76
|
+
componentKey,
|
|
77
|
+
componentRole,
|
|
78
|
+
idSuffix: 'missing-binding',
|
|
79
|
+
message:
|
|
80
|
+
`Document workspace '${runtime.workspace.Id}' has no WorkspaceRuntime ` +
|
|
81
|
+
'target binding for the active frontend target.',
|
|
82
|
+
severity: 'warning',
|
|
83
|
+
sourceId,
|
|
84
|
+
status: 'unbound',
|
|
85
|
+
suggestedNextStep:
|
|
86
|
+
'Declare a WorkspaceRuntime target binding with ComponentRole for this document workspace.',
|
|
87
|
+
runtime,
|
|
88
|
+
}),
|
|
89
|
+
)
|
|
90
|
+
return diagnostics
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (componentKey) {
|
|
94
|
+
diagnostics.push(
|
|
95
|
+
createWorkspaceRuntimeDiagnostic({
|
|
96
|
+
category: 'escape-hatch',
|
|
97
|
+
componentKey,
|
|
98
|
+
componentRole,
|
|
99
|
+
idSuffix: 'component-key-escape-hatch',
|
|
100
|
+
message:
|
|
101
|
+
`Document workspace '${runtime.workspace.Id}' declares concrete ` +
|
|
102
|
+
`workspace runtime component key '${componentKey}'.`,
|
|
103
|
+
severity: 'warning',
|
|
104
|
+
sourceId,
|
|
105
|
+
status: 'escape-hatch',
|
|
106
|
+
suggestedNextStep:
|
|
107
|
+
'Use WorkspaceRuntime ComponentRole for document workspace runtimes and reserve ComponentKey for adapter-specific overrides.',
|
|
108
|
+
runtime,
|
|
109
|
+
}),
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (!componentRole) {
|
|
114
|
+
diagnostics.push(
|
|
115
|
+
createWorkspaceRuntimeDiagnostic({
|
|
116
|
+
category: 'missing-binding',
|
|
117
|
+
componentKey,
|
|
118
|
+
componentRole,
|
|
119
|
+
idSuffix: 'missing-component-role',
|
|
120
|
+
message:
|
|
121
|
+
`Document workspace '${runtime.workspace.Id}' WorkspaceRuntime binding ` +
|
|
122
|
+
'does not declare a component role.',
|
|
123
|
+
severity: 'warning',
|
|
124
|
+
sourceId,
|
|
125
|
+
status: 'unbound',
|
|
126
|
+
suggestedNextStep:
|
|
127
|
+
`Set ComponentRole to '${workspaceRuntimeComponentRoles.documentWorkspace}'.`,
|
|
128
|
+
runtime,
|
|
129
|
+
}),
|
|
130
|
+
)
|
|
131
|
+
return diagnostics
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const isSupportedRole = supportedRoleSet.has(componentRole)
|
|
135
|
+
|
|
136
|
+
diagnostics.push(
|
|
137
|
+
createWorkspaceRuntimeDiagnostic({
|
|
138
|
+
category: isSupportedRole ? 'local-interpretation' : 'missing-binding',
|
|
139
|
+
componentKey,
|
|
140
|
+
componentRole,
|
|
141
|
+
idSuffix: 'component-role-coverage',
|
|
142
|
+
message: isSupportedRole
|
|
143
|
+
? `Document workspace '${runtime.workspace.Id}' WorkspaceRuntime role ` +
|
|
144
|
+
`'${componentRole}' is interpreted by the local document workspace host.`
|
|
145
|
+
: `Document workspace '${runtime.workspace.Id}' WorkspaceRuntime role ` +
|
|
146
|
+
`'${componentRole}' is not interpreted by the local document workspace host.`,
|
|
147
|
+
severity: isSupportedRole ? 'info' : 'warning',
|
|
148
|
+
sourceId,
|
|
149
|
+
status: isSupportedRole ? 'locally-interpreted' : 'unbound',
|
|
150
|
+
suggestedNextStep: isSupportedRole
|
|
151
|
+
? undefined
|
|
152
|
+
: 'Bind this WorkspaceRuntime component role in the frontend document workspace host adapter.',
|
|
153
|
+
runtime,
|
|
154
|
+
}),
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
return diagnostics
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function createWorkspaceRuntimeDiagnostic({
|
|
161
|
+
category,
|
|
162
|
+
componentKey,
|
|
163
|
+
componentRole,
|
|
164
|
+
idSuffix,
|
|
165
|
+
message,
|
|
166
|
+
runtime,
|
|
167
|
+
severity,
|
|
168
|
+
sourceId,
|
|
169
|
+
status,
|
|
170
|
+
suggestedNextStep,
|
|
171
|
+
}: {
|
|
172
|
+
readonly category: PresentationProjectionDiagnostic['category']
|
|
173
|
+
readonly componentKey: string | null
|
|
174
|
+
readonly componentRole: string | null
|
|
175
|
+
readonly idSuffix: string
|
|
176
|
+
readonly message: string
|
|
177
|
+
readonly runtime: DocumentWorkspaceRuntimeSnapshot
|
|
178
|
+
readonly severity: PresentationProjectionDiagnostic['severity']
|
|
179
|
+
readonly sourceId: string
|
|
180
|
+
readonly status: NonNullable<PresentationProjectionDiagnostic['interpretation']>['status']
|
|
181
|
+
readonly suggestedNextStep?: string
|
|
182
|
+
}) {
|
|
183
|
+
return createPresentationProjectionDiagnostic({
|
|
184
|
+
category,
|
|
185
|
+
details: {
|
|
186
|
+
componentKey,
|
|
187
|
+
componentRole,
|
|
188
|
+
documentProfileId: runtime.documentProfile.Id,
|
|
189
|
+
pageViewId: runtime.pageView.Id,
|
|
190
|
+
workspaceId: runtime.workspace.Id,
|
|
191
|
+
workspaceViewId: runtime.workspaceView.Id,
|
|
192
|
+
},
|
|
193
|
+
id: `document-workspace-runtime.${runtime.workspace.Id}.${idSuffix}`,
|
|
194
|
+
interpretation: {
|
|
195
|
+
status,
|
|
196
|
+
target: 'workspace-runtime-component-role',
|
|
197
|
+
},
|
|
198
|
+
message,
|
|
199
|
+
severity,
|
|
200
|
+
source: sourceId,
|
|
201
|
+
subject: {
|
|
202
|
+
id: runtime.workspace.Id,
|
|
203
|
+
kind: 'document-workspace-runtime',
|
|
204
|
+
name: runtime.workspace.Name,
|
|
205
|
+
},
|
|
206
|
+
suggestedNextStep,
|
|
207
|
+
})
|
|
208
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { useCallback, useMemo, type Context, type PropsWithChildren } from 'react'
|
|
2
|
+
import { useNavigate, useResolvedPath } from 'react-router'
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
createNavigationHref,
|
|
6
|
+
type NavigationDefinitionProjection,
|
|
7
|
+
type PresentationNavigationRuntime,
|
|
8
|
+
} from '@cohesivesystems/presentation-core'
|
|
9
|
+
import {
|
|
10
|
+
PresentationNavigationRuntimeContext,
|
|
11
|
+
} from './navigation-runtime-context'
|
|
12
|
+
|
|
13
|
+
export interface ProjectedNavigationContextValue<TNavigation extends NavigationDefinitionProjection = NavigationDefinitionProjection> extends PresentationNavigationRuntime {
|
|
14
|
+
readonly navigation: TNavigation | null
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface ProjectedNavigationProviderProps<
|
|
18
|
+
TNavigation extends NavigationDefinitionProjection,
|
|
19
|
+
> extends PropsWithChildren {
|
|
20
|
+
readonly context?: Context<ProjectedNavigationContextValue<TNavigation>>
|
|
21
|
+
readonly navigation: TNavigation | null
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Generic React binding for semantic navigation definitions. App-specific
|
|
26
|
+
* navigation contexts can be layered on top, but href creation and route
|
|
27
|
+
* execution stay owned by the presentation projection runtime.
|
|
28
|
+
*/
|
|
29
|
+
export function ProjectedNavigationProvider<
|
|
30
|
+
TNavigation extends NavigationDefinitionProjection,
|
|
31
|
+
>({
|
|
32
|
+
children,
|
|
33
|
+
context,
|
|
34
|
+
navigation,
|
|
35
|
+
}: ProjectedNavigationProviderProps<TNavigation>) {
|
|
36
|
+
const navigate = useNavigate()
|
|
37
|
+
const rootPath = useResolvedPath('/')
|
|
38
|
+
const createHref = useCallback<ProjectedNavigationContextValue['createHref']>(
|
|
39
|
+
(routeId, parameters) =>
|
|
40
|
+
navigation ? createNavigationHref(navigation, routeId, parameters) : null,
|
|
41
|
+
[navigation],
|
|
42
|
+
)
|
|
43
|
+
const navigateHref = useCallback<ProjectedNavigationContextValue['navigateHref']>(
|
|
44
|
+
(href) => {
|
|
45
|
+
if (href.length > 0) {
|
|
46
|
+
void navigate(toRootRelativeHref(href, rootPath.pathname), {
|
|
47
|
+
flushSync: true,
|
|
48
|
+
relative: 'path',
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
[navigate, rootPath.pathname],
|
|
53
|
+
)
|
|
54
|
+
const navigateRoute = useCallback<ProjectedNavigationContextValue['navigateRoute']>(
|
|
55
|
+
(routeId, parameters) => {
|
|
56
|
+
const href = createHref(routeId, parameters)
|
|
57
|
+
if (href) {
|
|
58
|
+
navigateHref(href)
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
[createHref, navigateHref],
|
|
62
|
+
)
|
|
63
|
+
const runtime = useMemo<PresentationNavigationRuntime>(
|
|
64
|
+
() => ({
|
|
65
|
+
createHref,
|
|
66
|
+
navigateHref,
|
|
67
|
+
navigateRoute,
|
|
68
|
+
}),
|
|
69
|
+
[createHref, navigateHref, navigateRoute],
|
|
70
|
+
)
|
|
71
|
+
const contextValue = useMemo<ProjectedNavigationContextValue<TNavigation>>(
|
|
72
|
+
() => ({
|
|
73
|
+
...runtime,
|
|
74
|
+
navigation,
|
|
75
|
+
}),
|
|
76
|
+
[navigation, runtime],
|
|
77
|
+
)
|
|
78
|
+
const ApplicationNavigationContext = context
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<PresentationNavigationRuntimeContext.Provider value={runtime}>
|
|
82
|
+
{ApplicationNavigationContext ? (
|
|
83
|
+
<ApplicationNavigationContext.Provider value={contextValue}>
|
|
84
|
+
{children}
|
|
85
|
+
</ApplicationNavigationContext.Provider>
|
|
86
|
+
) : (
|
|
87
|
+
children
|
|
88
|
+
)}
|
|
89
|
+
</PresentationNavigationRuntimeContext.Provider>
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function toRootRelativeHref(href: string, rootPathname: string) {
|
|
94
|
+
if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(href) || href.startsWith('//')) {
|
|
95
|
+
return href
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (href.startsWith('/')) {
|
|
99
|
+
return href
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const root = rootPathname === '/' ? '' : rootPathname.replace(/\/+$/g, '')
|
|
103
|
+
return `${root}/${href.replace(/^\/+/g, '')}`
|
|
104
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ReactNode } from 'react'
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
FlowDefinition,
|
|
5
|
+
FlowStateDefinition,
|
|
6
|
+
ViewDefinition,
|
|
7
|
+
} from '@cohesivesystems/presentation-core'
|
|
8
|
+
import type {
|
|
9
|
+
PresentationFlowInstance,
|
|
10
|
+
PresentationFlowRuntimeSnapshot,
|
|
11
|
+
} from './presentation-flow-runtime'
|
|
12
|
+
|
|
13
|
+
export interface ProjectedPresentationFlowHostProps {
|
|
14
|
+
readonly fallback?: ReactNode
|
|
15
|
+
readonly renderView: (context: ProjectedPresentationFlowViewRenderContext) => ReactNode
|
|
16
|
+
readonly runtime: PresentationFlowRuntimeSnapshot
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface ProjectedPresentationFlowViewRenderContext {
|
|
20
|
+
readonly flow: FlowDefinition
|
|
21
|
+
readonly instance: PresentationFlowInstance
|
|
22
|
+
readonly state: FlowStateDefinition
|
|
23
|
+
readonly view: ViewDefinition
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function ProjectedPresentationFlowHost({
|
|
27
|
+
fallback = null,
|
|
28
|
+
renderView,
|
|
29
|
+
runtime,
|
|
30
|
+
}: ProjectedPresentationFlowHostProps) {
|
|
31
|
+
const { activeFlow, activeInstance, activeState, activeView } = runtime
|
|
32
|
+
if (!activeFlow || !activeInstance || !activeState || !activeView) {
|
|
33
|
+
return <>{fallback}</>
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<>
|
|
38
|
+
{renderView({
|
|
39
|
+
flow: activeFlow,
|
|
40
|
+
instance: activeInstance,
|
|
41
|
+
state: activeState,
|
|
42
|
+
view: activeView,
|
|
43
|
+
})}
|
|
44
|
+
</>
|
|
45
|
+
)
|
|
46
|
+
}
|