@cohesivesystems/presentation-react-shadcn 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/document-workspace-surface-slot-renderers.d.ts +58 -0
- package/dist/document-workspace-surface-slot-renderers.d.ts.map +1 -0
- package/dist/document-workspace-surface-slot-renderers.js +206 -0
- package/dist/document-workspace-surface-slot-renderers.js.map +1 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/dist/navigation-shell-frame-renderer-registry.d.ts +8 -0
- package/dist/navigation-shell-frame-renderer-registry.d.ts.map +1 -0
- package/dist/navigation-shell-frame-renderer-registry.js +2 -0
- package/dist/navigation-shell-frame-renderer-registry.js.map +1 -0
- package/dist/navigation-shell-slot-renderer-registry.d.ts +9 -0
- package/dist/navigation-shell-slot-renderer-registry.d.ts.map +1 -0
- package/dist/navigation-shell-slot-renderer-registry.js +2 -0
- package/dist/navigation-shell-slot-renderer-registry.js.map +1 -0
- package/dist/page-host-unavailable-renderer.d.ts +10 -0
- package/dist/page-host-unavailable-renderer.d.ts.map +1 -0
- package/dist/page-host-unavailable-renderer.js +27 -0
- package/dist/page-host-unavailable-renderer.js.map +1 -0
- package/dist/presentation-action-group.d.ts +99 -0
- package/dist/presentation-action-group.d.ts.map +1 -0
- package/dist/presentation-action-group.js +214 -0
- package/dist/presentation-action-group.js.map +1 -0
- package/dist/presentation-badge-target-interpreter.d.ts +26 -0
- package/dist/presentation-badge-target-interpreter.d.ts.map +1 -0
- package/dist/presentation-badge-target-interpreter.js +17 -0
- package/dist/presentation-badge-target-interpreter.js.map +1 -0
- package/dist/presentation-component-groups.d.ts +968 -0
- package/dist/presentation-component-groups.d.ts.map +1 -0
- package/dist/presentation-component-groups.js +505 -0
- package/dist/presentation-component-groups.js.map +1 -0
- package/dist/presentation-component-system-diagnostics.d.ts +27 -0
- package/dist/presentation-component-system-diagnostics.d.ts.map +1 -0
- package/dist/presentation-component-system-diagnostics.js +399 -0
- package/dist/presentation-component-system-diagnostics.js.map +1 -0
- package/dist/presentation-component-system.d.ts +31 -0
- package/dist/presentation-component-system.d.ts.map +1 -0
- package/dist/presentation-component-system.js +61 -0
- package/dist/presentation-component-system.js.map +1 -0
- package/dist/presentation-icon-diagnostics.d.ts +12 -0
- package/dist/presentation-icon-diagnostics.d.ts.map +1 -0
- package/dist/presentation-icon-diagnostics.js +17 -0
- package/dist/presentation-icon-diagnostics.js.map +1 -0
- package/dist/presentation-icon-registry.d.ts +28 -0
- package/dist/presentation-icon-registry.d.ts.map +1 -0
- package/dist/presentation-icon-registry.js +80 -0
- package/dist/presentation-icon-registry.js.map +1 -0
- package/dist/presentation-projection-trace-panel.d.ts +10 -0
- package/dist/presentation-projection-trace-panel.d.ts.map +1 -0
- package/dist/presentation-projection-trace-panel.js +48 -0
- package/dist/presentation-projection-trace-panel.js.map +1 -0
- package/dist/presentation-routed-surface-host.d.ts +19 -0
- package/dist/presentation-routed-surface-host.d.ts.map +1 -0
- package/dist/presentation-routed-surface-host.js +12 -0
- package/dist/presentation-routed-surface-host.js.map +1 -0
- package/dist/presentation-shadcn-component-system.d.ts +22 -0
- package/dist/presentation-shadcn-component-system.d.ts.map +1 -0
- package/dist/presentation-shadcn-component-system.js +2 -0
- package/dist/presentation-shadcn-component-system.js.map +1 -0
- package/dist/presentation-standard-renderers.d.ts +168 -0
- package/dist/presentation-standard-renderers.d.ts.map +1 -0
- package/dist/presentation-standard-renderers.js +440 -0
- package/dist/presentation-standard-renderers.js.map +1 -0
- package/dist/presentation-surface-renderer.d.ts +23 -0
- package/dist/presentation-surface-renderer.d.ts.map +1 -0
- package/dist/presentation-surface-renderer.js +119 -0
- package/dist/presentation-surface-renderer.js.map +1 -0
- package/dist/presentation-value-renderers.d.ts +10 -0
- package/dist/presentation-value-renderers.d.ts.map +1 -0
- package/dist/presentation-value-renderers.js +14 -0
- package/dist/presentation-value-renderers.js.map +1 -0
- package/dist/process-task-icons.d.ts +49 -0
- package/dist/process-task-icons.d.ts.map +1 -0
- package/dist/process-task-icons.js +154 -0
- package/dist/process-task-icons.js.map +1 -0
- package/dist/projected-activity-state.d.ts +17 -0
- package/dist/projected-activity-state.d.ts.map +1 -0
- package/dist/projected-activity-state.js +22 -0
- package/dist/projected-activity-state.js.map +1 -0
- package/dist/projected-collection-action-runtime-diagnostics.d.ts +4 -0
- package/dist/projected-collection-action-runtime-diagnostics.d.ts.map +1 -0
- package/dist/projected-collection-action-runtime-diagnostics.js +9 -0
- package/dist/projected-collection-action-runtime-diagnostics.js.map +1 -0
- package/dist/projected-collection-view.d.ts +90 -0
- package/dist/projected-collection-view.d.ts.map +1 -0
- package/dist/projected-collection-view.js +532 -0
- package/dist/projected-collection-view.js.map +1 -0
- package/dist/projected-document-action-status-notices.d.ts +15 -0
- package/dist/projected-document-action-status-notices.d.ts.map +1 -0
- package/dist/projected-document-action-status-notices.js +33 -0
- package/dist/projected-document-action-status-notices.js.map +1 -0
- package/dist/projected-document-badges.d.ts +24 -0
- package/dist/projected-document-badges.d.ts.map +1 -0
- package/dist/projected-document-badges.js +53 -0
- package/dist/projected-document-badges.js.map +1 -0
- package/dist/projected-document-editor-surface.d.ts +46 -0
- package/dist/projected-document-editor-surface.d.ts.map +1 -0
- package/dist/projected-document-editor-surface.js +399 -0
- package/dist/projected-document-editor-surface.js.map +1 -0
- package/dist/projected-document-workspace-notices.d.ts +24 -0
- package/dist/projected-document-workspace-notices.d.ts.map +1 -0
- package/dist/projected-document-workspace-notices.js +14 -0
- package/dist/projected-document-workspace-notices.js.map +1 -0
- package/dist/projected-document-workspace-prompt-child-view-registry.d.ts +25 -0
- package/dist/projected-document-workspace-prompt-child-view-registry.d.ts.map +1 -0
- package/dist/projected-document-workspace-prompt-child-view-registry.js +41 -0
- package/dist/projected-document-workspace-prompt-child-view-registry.js.map +1 -0
- package/dist/projected-document-workspace-prompt-child-view-renderers.d.ts +32 -0
- package/dist/projected-document-workspace-prompt-child-view-renderers.d.ts.map +1 -0
- package/dist/projected-document-workspace-prompt-child-view-renderers.js +77 -0
- package/dist/projected-document-workspace-prompt-child-view-renderers.js.map +1 -0
- package/dist/projected-document-workspace-shell.d.ts +100 -0
- package/dist/projected-document-workspace-shell.d.ts.map +1 -0
- package/dist/projected-document-workspace-shell.js +153 -0
- package/dist/projected-document-workspace-shell.js.map +1 -0
- package/dist/projected-document-workspace.d.ts +39 -0
- package/dist/projected-document-workspace.d.ts.map +1 -0
- package/dist/projected-document-workspace.js +63 -0
- package/dist/projected-document-workspace.js.map +1 -0
- package/dist/projected-field-value-rendering.d.ts +94 -0
- package/dist/projected-field-value-rendering.d.ts.map +1 -0
- package/dist/projected-field-value-rendering.js +377 -0
- package/dist/projected-field-value-rendering.js.map +1 -0
- package/dist/projected-inline-list.d.ts +20 -0
- package/dist/projected-inline-list.d.ts.map +1 -0
- package/dist/projected-inline-list.js +149 -0
- package/dist/projected-inline-list.js.map +1 -0
- package/dist/projected-input-form.d.ts +143 -0
- package/dist/projected-input-form.d.ts.map +1 -0
- package/dist/projected-input-form.js +612 -0
- package/dist/projected-input-form.js.map +1 -0
- package/dist/projected-metric-dashboard.d.ts +26 -0
- package/dist/projected-metric-dashboard.d.ts.map +1 -0
- package/dist/projected-metric-dashboard.js +20 -0
- package/dist/projected-metric-dashboard.js.map +1 -0
- package/dist/projected-metric-strip.d.ts +20 -0
- package/dist/projected-metric-strip.d.ts.map +1 -0
- package/dist/projected-metric-strip.js +131 -0
- package/dist/projected-metric-strip.js.map +1 -0
- package/dist/projected-navigation-shell-view-host.d.ts +34 -0
- package/dist/projected-navigation-shell-view-host.d.ts.map +1 -0
- package/dist/projected-navigation-shell-view-host.js +75 -0
- package/dist/projected-navigation-shell-view-host.js.map +1 -0
- package/dist/projected-navigation-shell.d.ts +33 -0
- package/dist/projected-navigation-shell.d.ts.map +1 -0
- package/dist/projected-navigation-shell.js +112 -0
- package/dist/projected-navigation-shell.js.map +1 -0
- package/dist/projected-presentation-badges.d.ts +34 -0
- package/dist/projected-presentation-badges.d.ts.map +1 -0
- package/dist/projected-presentation-badges.js +22 -0
- package/dist/projected-presentation-badges.js.map +1 -0
- package/dist/projected-presentation-diagnostics.d.ts +10 -0
- package/dist/projected-presentation-diagnostics.d.ts.map +1 -0
- package/dist/projected-presentation-diagnostics.js +40 -0
- package/dist/projected-presentation-diagnostics.js.map +1 -0
- package/dist/projected-presentation-flow-layer.d.ts +33 -0
- package/dist/projected-presentation-flow-layer.d.ts.map +1 -0
- package/dist/projected-presentation-flow-layer.js +71 -0
- package/dist/projected-presentation-flow-layer.js.map +1 -0
- package/dist/projected-process-task-notices.d.ts +37 -0
- package/dist/projected-process-task-notices.d.ts.map +1 -0
- package/dist/projected-process-task-notices.js +225 -0
- package/dist/projected-process-task-notices.js.map +1 -0
- package/dist/projected-prompt-child-view-renderer.d.ts +101 -0
- package/dist/projected-prompt-child-view-renderer.d.ts.map +1 -0
- package/dist/projected-prompt-child-view-renderer.js +442 -0
- package/dist/projected-prompt-child-view-renderer.js.map +1 -0
- package/dist/projected-prompt-document-preview.d.ts +39 -0
- package/dist/projected-prompt-document-preview.d.ts.map +1 -0
- package/dist/projected-prompt-document-preview.js +50 -0
- package/dist/projected-prompt-document-preview.js.map +1 -0
- package/dist/projected-prompt-view.d.ts +35 -0
- package/dist/projected-prompt-view.d.ts.map +1 -0
- package/dist/projected-prompt-view.js +292 -0
- package/dist/projected-prompt-view.js.map +1 -0
- package/dist/projected-query-form.d.ts +56 -0
- package/dist/projected-query-form.d.ts.map +1 -0
- package/dist/projected-query-form.js +100 -0
- package/dist/projected-query-form.js.map +1 -0
- package/dist/projected-record-details.d.ts +20 -0
- package/dist/projected-record-details.d.ts.map +1 -0
- package/dist/projected-record-details.js +60 -0
- package/dist/projected-record-details.js.map +1 -0
- package/dist/projected-routed-surface-runtime.d.ts +86 -0
- package/dist/projected-routed-surface-runtime.d.ts.map +1 -0
- package/dist/projected-routed-surface-runtime.js +332 -0
- package/dist/projected-routed-surface-runtime.js.map +1 -0
- package/dist/projected-tabs-view.d.ts +21 -0
- package/dist/projected-tabs-view.d.ts.map +1 -0
- package/dist/projected-tabs-view.js +140 -0
- package/dist/projected-tabs-view.js.map +1 -0
- package/dist/projected-view-chrome.d.ts +15 -0
- package/dist/projected-view-chrome.d.ts.map +1 -0
- package/dist/projected-view-chrome.js +67 -0
- package/dist/projected-view-chrome.js.map +1 -0
- package/dist/projected-view-surface.d.ts +34 -0
- package/dist/projected-view-surface.d.ts.map +1 -0
- package/dist/projected-view-surface.js +40 -0
- package/dist/projected-view-surface.js.map +1 -0
- package/dist/standard-collection-chrome-slot-renderers.d.ts +26 -0
- package/dist/standard-collection-chrome-slot-renderers.d.ts.map +1 -0
- package/dist/standard-collection-chrome-slot-renderers.js +250 -0
- package/dist/standard-collection-chrome-slot-renderers.js.map +1 -0
- package/dist/standard-view-chrome-slot-renderers.d.ts +57 -0
- package/dist/standard-view-chrome-slot-renderers.d.ts.map +1 -0
- package/dist/standard-view-chrome-slot-renderers.js +614 -0
- package/dist/standard-view-chrome-slot-renderers.js.map +1 -0
- package/package.json +68 -0
- package/src/document-workspace-surface-slot-renderers.tsx +395 -0
- package/src/index.ts +53 -0
- package/src/navigation-shell-frame-renderer-registry.ts +29 -0
- package/src/navigation-shell-slot-renderer-registry.ts +46 -0
- package/src/page-host-unavailable-renderer.tsx +79 -0
- package/src/presentation-action-group.tsx +475 -0
- package/src/presentation-badge-target-interpreter.ts +54 -0
- package/src/presentation-component-groups.ts +2505 -0
- package/src/presentation-component-system-diagnostics.ts +848 -0
- package/src/presentation-component-system.ts +365 -0
- package/src/presentation-icon-diagnostics.ts +53 -0
- package/src/presentation-icon-registry.tsx +181 -0
- package/src/presentation-projection-trace-panel.tsx +140 -0
- package/src/presentation-routed-surface-host.tsx +48 -0
- package/src/presentation-shadcn-component-system.ts +102 -0
- package/src/presentation-standard-renderers.tsx +1290 -0
- package/src/presentation-surface-renderer.tsx +263 -0
- package/src/presentation-value-renderers.tsx +40 -0
- package/src/process-task-icons.tsx +258 -0
- package/src/projected-activity-state.tsx +63 -0
- package/src/projected-collection-action-runtime-diagnostics.ts +22 -0
- package/src/projected-collection-view.tsx +1273 -0
- package/src/projected-document-action-status-notices.tsx +66 -0
- package/src/projected-document-badges.tsx +134 -0
- package/src/projected-document-editor-surface.tsx +808 -0
- package/src/projected-document-workspace-notices.tsx +77 -0
- package/src/projected-document-workspace-prompt-child-view-registry.ts +99 -0
- package/src/projected-document-workspace-prompt-child-view-renderers.tsx +205 -0
- package/src/projected-document-workspace-shell.tsx +427 -0
- package/src/projected-document-workspace.tsx +216 -0
- package/src/projected-field-value-rendering.tsx +704 -0
- package/src/projected-inline-list.tsx +434 -0
- package/src/projected-input-form.tsx +1218 -0
- package/src/projected-metric-dashboard.tsx +106 -0
- package/src/projected-metric-strip.tsx +244 -0
- package/src/projected-navigation-shell-view-host.tsx +177 -0
- package/src/projected-navigation-shell.tsx +219 -0
- package/src/projected-presentation-badges.tsx +95 -0
- package/src/projected-presentation-diagnostics.tsx +120 -0
- package/src/projected-presentation-flow-layer.tsx +186 -0
- package/src/projected-process-task-notices.tsx +501 -0
- package/src/projected-prompt-child-view-renderer.tsx +698 -0
- package/src/projected-prompt-document-preview.tsx +197 -0
- package/src/projected-prompt-view.tsx +592 -0
- package/src/projected-query-form.tsx +286 -0
- package/src/projected-record-details.tsx +133 -0
- package/src/projected-routed-surface-runtime.tsx +713 -0
- package/src/projected-tabs-view.tsx +308 -0
- package/src/projected-view-chrome.tsx +148 -0
- package/src/projected-view-surface.tsx +131 -0
- package/src/standard-collection-chrome-slot-renderers.tsx +391 -0
- package/src/standard-view-chrome-slot-renderers.tsx +1064 -0
|
@@ -0,0 +1,1064 @@
|
|
|
1
|
+
import { useMemo, type ReactNode } from 'react'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
createPresentationProjectionDiagnostic,
|
|
5
|
+
createViewChromeSlotRendererRegistry,
|
|
6
|
+
findDocumentFieldNavigationRouteBinding,
|
|
7
|
+
findPresentationField,
|
|
8
|
+
findPresentationView,
|
|
9
|
+
formatPresentationValue,
|
|
10
|
+
getViewChromeSlotRendererRegistryKeys,
|
|
11
|
+
isProjectedDocumentEntityReferenceField,
|
|
12
|
+
type NavigationRouteParameters,
|
|
13
|
+
projectDocumentFieldNavigation,
|
|
14
|
+
readPresentationFieldValue,
|
|
15
|
+
resolvePresentationBadges,
|
|
16
|
+
resolvePresentationValue,
|
|
17
|
+
resolvePromptStatusMessages,
|
|
18
|
+
resolveViewChromeSlotRenderer,
|
|
19
|
+
viewChromeIconIds,
|
|
20
|
+
type DocumentEditorLayout,
|
|
21
|
+
type PresentationBadgeDefinition,
|
|
22
|
+
type PresentationDataSourceResolver,
|
|
23
|
+
type PresentationModuleDefinition,
|
|
24
|
+
type PresentationProjectionDiagnostic,
|
|
25
|
+
type ProjectedDocumentActionStatusMap,
|
|
26
|
+
type ProjectedDocumentFieldDefinitionLike,
|
|
27
|
+
type ViewChromeSlotDefinition,
|
|
28
|
+
type ViewDefinition,
|
|
29
|
+
} from '@cohesivesystems/presentation-core'
|
|
30
|
+
import {
|
|
31
|
+
PresentationActionGroup,
|
|
32
|
+
type PresentationActionGroupOptions,
|
|
33
|
+
} from './presentation-action-group'
|
|
34
|
+
import {
|
|
35
|
+
renderPresentationIcon,
|
|
36
|
+
} from './presentation-icon-registry'
|
|
37
|
+
import {
|
|
38
|
+
usePresentationNavigationRuntime,
|
|
39
|
+
useRegisterPresentationProjectionDiagnostics,
|
|
40
|
+
} from '@cohesivesystems/presentation-react'
|
|
41
|
+
import type {
|
|
42
|
+
PresentationShadcnComponentSystem as PresentationComponentSystem,
|
|
43
|
+
} from './presentation-shadcn-component-system'
|
|
44
|
+
import type { PresentationDesignSystem } from '@cohesivesystems/presentation-tailwind'
|
|
45
|
+
import {
|
|
46
|
+
interpretPresentationBadgeTarget,
|
|
47
|
+
type PresentationBadgeTargetInterpreterRegistry,
|
|
48
|
+
} from './presentation-badge-target-interpreter'
|
|
49
|
+
import {
|
|
50
|
+
ProjectedPresentationBadge,
|
|
51
|
+
} from './projected-presentation-badges'
|
|
52
|
+
import {
|
|
53
|
+
renderProjectedEntityReferenceValue,
|
|
54
|
+
} from './projected-field-value-rendering'
|
|
55
|
+
import { ProjectedStatusBlock } from './projected-activity-state'
|
|
56
|
+
import {
|
|
57
|
+
ProjectedMetricStrip,
|
|
58
|
+
type ProjectedMetricValue,
|
|
59
|
+
} from './projected-metric-strip'
|
|
60
|
+
import {
|
|
61
|
+
viewChromeSlotKinds,
|
|
62
|
+
} from '@cohesivesystems/presentation-contracts'
|
|
63
|
+
|
|
64
|
+
export type ProjectedViewChromeMetadataRole = string
|
|
65
|
+
|
|
66
|
+
export type ProjectedViewChromeMetadataBadgeRoleReader = (
|
|
67
|
+
badge: Pick<PresentationBadgeDefinition, 'Annotations'>,
|
|
68
|
+
field: Pick<ProjectedDocumentFieldDefinitionLike, 'Annotations'> | null | undefined,
|
|
69
|
+
) => ProjectedViewChromeMetadataRole | null
|
|
70
|
+
|
|
71
|
+
export type ProjectedViewChromeMetadataFieldRoleReader = (
|
|
72
|
+
field: Pick<ProjectedDocumentFieldDefinitionLike, 'Annotations'> | null | undefined,
|
|
73
|
+
) => ProjectedViewChromeMetadataRole | null
|
|
74
|
+
|
|
75
|
+
export interface ProjectedViewChromeSlotRenderContext<TActionContext> {
|
|
76
|
+
readonly actionContext: TActionContext
|
|
77
|
+
readonly actionGroupOptions?: PresentationActionGroupOptions<TActionContext>
|
|
78
|
+
readonly actionStatuses?: ProjectedDocumentActionStatusMap
|
|
79
|
+
readonly activeViewId?: string | null
|
|
80
|
+
readonly componentSystem: PresentationComponentSystem
|
|
81
|
+
readonly createHref?: (
|
|
82
|
+
routeId: string,
|
|
83
|
+
parameters?: NavigationRouteParameters,
|
|
84
|
+
) => string | null
|
|
85
|
+
readonly dataSourceResolver: PresentationDataSourceResolver
|
|
86
|
+
readonly designSystem: PresentationDesignSystem
|
|
87
|
+
readonly documentViewIds?: readonly string[]
|
|
88
|
+
readonly badgeInterpreters?: PresentationBadgeTargetInterpreterRegistry
|
|
89
|
+
readonly layout?: DocumentEditorLayout | null
|
|
90
|
+
readonly metadataEntityReferenceRole?: ProjectedViewChromeMetadataRole | null
|
|
91
|
+
readonly metricMessage?: ReactNode
|
|
92
|
+
readonly metricValues?: Readonly<Record<string, ProjectedMetricValue>>
|
|
93
|
+
readonly module: PresentationModuleDefinition | null
|
|
94
|
+
readonly navigateHref?: (href: string) => void
|
|
95
|
+
readonly onActiveViewIdChange?: (viewId: string) => void
|
|
96
|
+
readonly onLayoutChange?: (layout: DocumentEditorLayout) => void
|
|
97
|
+
readonly readMetadataBadgeRole?: ProjectedViewChromeMetadataBadgeRoleReader
|
|
98
|
+
readonly readMetadataFieldRole?: ProjectedViewChromeMetadataFieldRoleReader
|
|
99
|
+
readonly resource?: unknown
|
|
100
|
+
readonly slot: ViewChromeSlotDefinition
|
|
101
|
+
readonly view: ViewDefinition | null
|
|
102
|
+
readonly workspaceView?: ViewDefinition | null
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export const standardViewChromeSlotRenderers =
|
|
106
|
+
createViewChromeSlotRendererRegistry<
|
|
107
|
+
ProjectedViewChromeSlotRenderContext<object>,
|
|
108
|
+
ReactNode
|
|
109
|
+
>([
|
|
110
|
+
{
|
|
111
|
+
kind: viewChromeSlotKinds.actions,
|
|
112
|
+
render: renderStandardViewActions,
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
kind: viewChromeSlotKinds.badgeStrip,
|
|
116
|
+
render: renderStandardViewBadgeStrip,
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
kind: viewChromeSlotKinds.metricStrip,
|
|
120
|
+
render: renderStandardViewMetricStrip,
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
kind: viewChromeSlotKinds.viewSwitch,
|
|
124
|
+
render: renderStandardViewSwitch,
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
kind: viewChromeSlotKinds.layoutSwitch,
|
|
128
|
+
render: renderStandardLayoutSwitch,
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
kind: viewChromeSlotKinds.headingTrailing,
|
|
132
|
+
render: renderStandardViewBadgeStrip,
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
kind: viewChromeSlotKinds.status,
|
|
136
|
+
render: renderStandardViewStatus,
|
|
137
|
+
},
|
|
138
|
+
])
|
|
139
|
+
|
|
140
|
+
export const standardViewChromeSlotRendererKeys =
|
|
141
|
+
getViewChromeSlotRendererRegistryKeys(standardViewChromeSlotRenderers)
|
|
142
|
+
|
|
143
|
+
const emptyMetricValues: Readonly<Record<string, ProjectedMetricValue>> = {}
|
|
144
|
+
|
|
145
|
+
type ProjectedViewBadgeRenderingMode =
|
|
146
|
+
| 'role-interpreter'
|
|
147
|
+
| 'standard-badge'
|
|
148
|
+
| 'unrendered'
|
|
149
|
+
|
|
150
|
+
interface ProjectedViewBadgeRenderingEntry {
|
|
151
|
+
readonly badgeFieldId: string | null
|
|
152
|
+
readonly badgeId: string
|
|
153
|
+
readonly badgeName: string
|
|
154
|
+
readonly field: ProjectedDocumentFieldDefinitionLike | null
|
|
155
|
+
readonly fieldId: string
|
|
156
|
+
readonly mode: ProjectedViewBadgeRenderingMode
|
|
157
|
+
readonly node: ReactNode
|
|
158
|
+
readonly rendered: boolean
|
|
159
|
+
readonly role: ProjectedViewChromeMetadataRole | null
|
|
160
|
+
readonly value: unknown
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export function renderStandardViewChromeSlot<TActionContext>(
|
|
164
|
+
context: ProjectedViewChromeSlotRenderContext<TActionContext>,
|
|
165
|
+
) {
|
|
166
|
+
const renderer = resolveViewChromeSlotRenderer(
|
|
167
|
+
standardViewChromeSlotRenderers,
|
|
168
|
+
context.slot,
|
|
169
|
+
)
|
|
170
|
+
return renderer?.(
|
|
171
|
+
context as unknown as ProjectedViewChromeSlotRenderContext<object>,
|
|
172
|
+
) ?? null
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function renderStandardViewActions<TActionContext>({
|
|
176
|
+
actionContext,
|
|
177
|
+
actionGroupOptions,
|
|
178
|
+
componentSystem,
|
|
179
|
+
dataSourceResolver,
|
|
180
|
+
designSystem,
|
|
181
|
+
module,
|
|
182
|
+
slot,
|
|
183
|
+
view,
|
|
184
|
+
}: ProjectedViewChromeSlotRenderContext<TActionContext>) {
|
|
185
|
+
if (!actionGroupOptions || !module || !view) {
|
|
186
|
+
return null
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return componentSystem.viewChrome.ActionSlot({
|
|
190
|
+
children: (
|
|
191
|
+
<PresentationActionGroup
|
|
192
|
+
context={actionContext}
|
|
193
|
+
dataSourceResolver={dataSourceResolver}
|
|
194
|
+
module={module}
|
|
195
|
+
options={{
|
|
196
|
+
...actionGroupOptions,
|
|
197
|
+
componentSystem,
|
|
198
|
+
designSystem,
|
|
199
|
+
}}
|
|
200
|
+
view={view}
|
|
201
|
+
/>
|
|
202
|
+
),
|
|
203
|
+
slotId: slot.Id,
|
|
204
|
+
viewId: view.Id,
|
|
205
|
+
})
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function renderStandardViewBadgeStrip({
|
|
209
|
+
componentSystem,
|
|
210
|
+
createHref,
|
|
211
|
+
designSystem,
|
|
212
|
+
badgeInterpreters,
|
|
213
|
+
metadataEntityReferenceRole,
|
|
214
|
+
module,
|
|
215
|
+
navigateHref,
|
|
216
|
+
readMetadataBadgeRole,
|
|
217
|
+
readMetadataFieldRole,
|
|
218
|
+
resource,
|
|
219
|
+
slot,
|
|
220
|
+
view,
|
|
221
|
+
}: ProjectedViewChromeSlotRenderContext<object>) {
|
|
222
|
+
return (
|
|
223
|
+
<ProjectedViewBadgeStrip
|
|
224
|
+
badges={slot.Badges ?? []}
|
|
225
|
+
componentSystem={componentSystem}
|
|
226
|
+
designSystem={designSystem}
|
|
227
|
+
badgeInterpreters={badgeInterpreters}
|
|
228
|
+
createHref={createHref}
|
|
229
|
+
fieldIds={slot.FieldIds ?? []}
|
|
230
|
+
metadataEntityReferenceRole={metadataEntityReferenceRole}
|
|
231
|
+
module={module}
|
|
232
|
+
navigateHref={navigateHref}
|
|
233
|
+
readMetadataBadgeRole={readMetadataBadgeRole}
|
|
234
|
+
readMetadataFieldRole={readMetadataFieldRole}
|
|
235
|
+
resource={resource}
|
|
236
|
+
slotId={slot.Id}
|
|
237
|
+
viewId={view?.Id}
|
|
238
|
+
viewName={view?.Name}
|
|
239
|
+
/>
|
|
240
|
+
)
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function renderStandardViewMetricStrip({
|
|
244
|
+
componentSystem,
|
|
245
|
+
dataSourceResolver,
|
|
246
|
+
metricMessage,
|
|
247
|
+
metricValues = emptyMetricValues,
|
|
248
|
+
slot,
|
|
249
|
+
view,
|
|
250
|
+
}: ProjectedViewChromeSlotRenderContext<object>) {
|
|
251
|
+
if (!slot.FieldIds || slot.FieldIds.length === 0) {
|
|
252
|
+
return null
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return componentSystem.viewChrome.MetricStripSlot({
|
|
256
|
+
children: (
|
|
257
|
+
<ProjectedMetricStrip
|
|
258
|
+
className="sm:grid-cols-2 lg:grid-cols-4"
|
|
259
|
+
componentSystem={componentSystem}
|
|
260
|
+
dataSourceResolver={dataSourceResolver}
|
|
261
|
+
fieldIds={slot.FieldIds}
|
|
262
|
+
values={metricValues}
|
|
263
|
+
viewId={view?.Id}
|
|
264
|
+
/>
|
|
265
|
+
),
|
|
266
|
+
message: metricMessage,
|
|
267
|
+
slotId: slot.Id,
|
|
268
|
+
viewId: view?.Id,
|
|
269
|
+
})
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function renderStandardViewStatus({
|
|
273
|
+
actionStatuses = {},
|
|
274
|
+
componentSystem,
|
|
275
|
+
dataSourceResolver,
|
|
276
|
+
resource,
|
|
277
|
+
slot,
|
|
278
|
+
view,
|
|
279
|
+
}: ProjectedViewChromeSlotRenderContext<object>) {
|
|
280
|
+
const promptMessages = view?.PromptStatusMessages
|
|
281
|
+
? resolvePromptStatusMessages({
|
|
282
|
+
actionStatuses,
|
|
283
|
+
dataSourceResolver,
|
|
284
|
+
region: slot.StateId ?? slot.Id,
|
|
285
|
+
view,
|
|
286
|
+
})
|
|
287
|
+
: []
|
|
288
|
+
const literalValue = formatPresentationValue(resolvePresentationValue(slot.Value, resource))
|
|
289
|
+
const messages = promptMessages.length > 0
|
|
290
|
+
? promptMessages
|
|
291
|
+
: literalValue
|
|
292
|
+
? [{ label: literalValue, tone: 'default' as const }]
|
|
293
|
+
: []
|
|
294
|
+
|
|
295
|
+
if (messages.length === 0) {
|
|
296
|
+
return null
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
return (
|
|
300
|
+
<div className="grid gap-2">
|
|
301
|
+
{messages.map((message, index) => (
|
|
302
|
+
<ProjectedStatusBlock
|
|
303
|
+
componentSystem={componentSystem}
|
|
304
|
+
key={promptMessages[index]?.definition.Id ?? `${slot.Id}:${index}`}
|
|
305
|
+
label={message.label}
|
|
306
|
+
tone={message.tone}
|
|
307
|
+
/>
|
|
308
|
+
))}
|
|
309
|
+
</div>
|
|
310
|
+
)
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
function renderStandardViewSwitch({
|
|
314
|
+
activeViewId,
|
|
315
|
+
componentSystem,
|
|
316
|
+
documentViewIds,
|
|
317
|
+
module,
|
|
318
|
+
onActiveViewIdChange,
|
|
319
|
+
slot,
|
|
320
|
+
workspaceView,
|
|
321
|
+
}: ProjectedViewChromeSlotRenderContext<object>) {
|
|
322
|
+
const viewIds = documentViewIds && documentViewIds.length > 0
|
|
323
|
+
? documentViewIds
|
|
324
|
+
: slot.ViewIds
|
|
325
|
+
if (viewIds.length <= 1 || !activeViewId || !onActiveViewIdChange) {
|
|
326
|
+
return null
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return componentSystem.viewChrome.ViewSwitch({
|
|
330
|
+
ariaLabel: 'Document view',
|
|
331
|
+
items: viewIds.map((viewId) => {
|
|
332
|
+
const label = getDocumentViewLabel(module, workspaceView ?? null, viewId)
|
|
333
|
+
const icon = resolveDocumentViewIcon(label, viewId)
|
|
334
|
+
|
|
335
|
+
return {
|
|
336
|
+
icon: renderViewChromeIcon({
|
|
337
|
+
fallbackIcon: icon.fallbackIcon,
|
|
338
|
+
icon: icon.id,
|
|
339
|
+
module,
|
|
340
|
+
}),
|
|
341
|
+
id: viewId,
|
|
342
|
+
isActive: activeViewId === viewId,
|
|
343
|
+
label,
|
|
344
|
+
onSelect: () => onActiveViewIdChange(viewId),
|
|
345
|
+
}
|
|
346
|
+
}),
|
|
347
|
+
slotId: slot.Id,
|
|
348
|
+
viewId: workspaceView?.Id,
|
|
349
|
+
})
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
function renderStandardLayoutSwitch({
|
|
353
|
+
componentSystem,
|
|
354
|
+
layout,
|
|
355
|
+
module,
|
|
356
|
+
onLayoutChange,
|
|
357
|
+
slot,
|
|
358
|
+
view,
|
|
359
|
+
}: ProjectedViewChromeSlotRenderContext<object>) {
|
|
360
|
+
if (!layout || !onLayoutChange) {
|
|
361
|
+
return null
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
return componentSystem.viewChrome.LayoutSwitch({
|
|
365
|
+
ariaLabel: 'Document layout',
|
|
366
|
+
items: [
|
|
367
|
+
{
|
|
368
|
+
icon: renderViewChromeIcon({
|
|
369
|
+
fallbackIcon: 'square',
|
|
370
|
+
icon: viewChromeIconIds.layoutSingle,
|
|
371
|
+
module,
|
|
372
|
+
}),
|
|
373
|
+
id: 'single',
|
|
374
|
+
isActive: layout === 'single',
|
|
375
|
+
label: 'Single',
|
|
376
|
+
onSelect: () => onLayoutChange('single'),
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
icon: renderViewChromeIcon({
|
|
380
|
+
fallbackIcon: 'columns-2',
|
|
381
|
+
icon: viewChromeIconIds.layoutSplit,
|
|
382
|
+
module,
|
|
383
|
+
}),
|
|
384
|
+
id: 'split',
|
|
385
|
+
isActive: layout === 'split',
|
|
386
|
+
label: 'Split',
|
|
387
|
+
onSelect: () => onLayoutChange('split'),
|
|
388
|
+
},
|
|
389
|
+
],
|
|
390
|
+
slotId: slot.Id,
|
|
391
|
+
viewId: view?.Id,
|
|
392
|
+
})
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
export function ProjectedViewBadgeStrip({
|
|
396
|
+
badges,
|
|
397
|
+
componentSystem,
|
|
398
|
+
createHref,
|
|
399
|
+
designSystem,
|
|
400
|
+
badgeInterpreters,
|
|
401
|
+
fieldIds,
|
|
402
|
+
metadataEntityReferenceRole,
|
|
403
|
+
module,
|
|
404
|
+
navigateHref,
|
|
405
|
+
readMetadataBadgeRole,
|
|
406
|
+
readMetadataFieldRole,
|
|
407
|
+
resource,
|
|
408
|
+
slotId = 'adhoc',
|
|
409
|
+
viewId,
|
|
410
|
+
viewName,
|
|
411
|
+
}: {
|
|
412
|
+
readonly badges?: readonly PresentationBadgeDefinition[]
|
|
413
|
+
readonly componentSystem: PresentationComponentSystem
|
|
414
|
+
readonly createHref?: (
|
|
415
|
+
routeId: string,
|
|
416
|
+
parameters?: NavigationRouteParameters,
|
|
417
|
+
) => string | null
|
|
418
|
+
readonly designSystem: PresentationDesignSystem
|
|
419
|
+
readonly badgeInterpreters?: PresentationBadgeTargetInterpreterRegistry
|
|
420
|
+
readonly fieldIds: readonly string[]
|
|
421
|
+
readonly metadataEntityReferenceRole?: ProjectedViewChromeMetadataRole | null
|
|
422
|
+
readonly module: PresentationModuleDefinition | null
|
|
423
|
+
readonly navigateHref?: (href: string) => void
|
|
424
|
+
readonly readMetadataBadgeRole?: ProjectedViewChromeMetadataBadgeRoleReader
|
|
425
|
+
readonly readMetadataFieldRole?: ProjectedViewChromeMetadataFieldRoleReader
|
|
426
|
+
readonly resource: unknown
|
|
427
|
+
readonly slotId?: string
|
|
428
|
+
readonly viewId?: string | null
|
|
429
|
+
readonly viewName?: string | null
|
|
430
|
+
}) {
|
|
431
|
+
const navigation = usePresentationNavigationRuntime()
|
|
432
|
+
const resolvedCreateHref = createHref ?? navigation.createHref
|
|
433
|
+
const resolvedNavigateHref = navigateHref ?? navigation.navigateHref
|
|
434
|
+
const badgeDefinitions = useMemo(
|
|
435
|
+
() => badges && badges.length > 0
|
|
436
|
+
? badges
|
|
437
|
+
: fieldIds.map(createFieldBackedBadgeDefinition),
|
|
438
|
+
[badges, fieldIds],
|
|
439
|
+
)
|
|
440
|
+
const renderedBadgeEntries = useMemo(
|
|
441
|
+
(): readonly ProjectedViewBadgeRenderingEntry[] => badgeDefinitions
|
|
442
|
+
.map((badge) => {
|
|
443
|
+
const fieldId = badge.FieldId ?? badge.Id
|
|
444
|
+
const field = findPresentationField<ProjectedDocumentFieldDefinitionLike>(module, fieldId)
|
|
445
|
+
const value = readPresentationFieldValue(resource, field?.Field)
|
|
446
|
+
const resolvedBadge = resolvePresentationBadges([badge], resource, module)[0] ?? null
|
|
447
|
+
const role = readMetadataBadgeRole?.(badge, field) ?? null
|
|
448
|
+
const interpretedBadge = interpretPresentationBadgeTarget(badgeInterpreters, {
|
|
449
|
+
badge,
|
|
450
|
+
componentSystem,
|
|
451
|
+
designSystem,
|
|
452
|
+
field,
|
|
453
|
+
fieldId,
|
|
454
|
+
module,
|
|
455
|
+
resolvedBadge,
|
|
456
|
+
resource,
|
|
457
|
+
value,
|
|
458
|
+
})
|
|
459
|
+
|
|
460
|
+
if (interpretedBadge !== undefined) {
|
|
461
|
+
const node = interpretedBadge === null ? null : (
|
|
462
|
+
<span className="contents" key={fieldId}>
|
|
463
|
+
{interpretedBadge}
|
|
464
|
+
</span>
|
|
465
|
+
)
|
|
466
|
+
return {
|
|
467
|
+
badgeFieldId: badge.FieldId ?? null,
|
|
468
|
+
badgeId: badge.Id,
|
|
469
|
+
badgeName: badge.Name,
|
|
470
|
+
field,
|
|
471
|
+
fieldId,
|
|
472
|
+
mode: 'role-interpreter',
|
|
473
|
+
node,
|
|
474
|
+
rendered: Boolean(node),
|
|
475
|
+
role,
|
|
476
|
+
value,
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
const node = renderStandardBadgeNode({
|
|
481
|
+
badge,
|
|
482
|
+
componentSystem,
|
|
483
|
+
createHref: resolvedCreateHref,
|
|
484
|
+
designSystem,
|
|
485
|
+
field,
|
|
486
|
+
module,
|
|
487
|
+
navigateHref: resolvedNavigateHref,
|
|
488
|
+
resolvedBadge,
|
|
489
|
+
resource,
|
|
490
|
+
value,
|
|
491
|
+
})
|
|
492
|
+
return {
|
|
493
|
+
badgeFieldId: badge.FieldId ?? null,
|
|
494
|
+
badgeId: badge.Id,
|
|
495
|
+
badgeName: badge.Name,
|
|
496
|
+
field,
|
|
497
|
+
fieldId,
|
|
498
|
+
mode: node ? 'standard-badge' : 'unrendered',
|
|
499
|
+
node,
|
|
500
|
+
rendered: Boolean(node),
|
|
501
|
+
role,
|
|
502
|
+
value,
|
|
503
|
+
}
|
|
504
|
+
}),
|
|
505
|
+
[
|
|
506
|
+
badgeDefinitions,
|
|
507
|
+
componentSystem,
|
|
508
|
+
createHref,
|
|
509
|
+
designSystem,
|
|
510
|
+
badgeInterpreters,
|
|
511
|
+
module,
|
|
512
|
+
navigateHref,
|
|
513
|
+
resolvedCreateHref,
|
|
514
|
+
resolvedNavigateHref,
|
|
515
|
+
readMetadataBadgeRole,
|
|
516
|
+
resource,
|
|
517
|
+
],
|
|
518
|
+
)
|
|
519
|
+
const renderedBadges = renderedBadgeEntries.flatMap((entry) =>
|
|
520
|
+
entry.node ? [entry.node] : [])
|
|
521
|
+
const roleDiagnosticSource =
|
|
522
|
+
`projected-view-badge-strip:${viewId ?? 'unknown'}:${slotId}:badge-roles`
|
|
523
|
+
const roleDiagnostics = useMemo(
|
|
524
|
+
() => projectViewBadgeStripRoleDiagnostics({
|
|
525
|
+
entries: renderedBadgeEntries,
|
|
526
|
+
fieldIds,
|
|
527
|
+
metadataEntityReferenceRole,
|
|
528
|
+
module,
|
|
529
|
+
readMetadataFieldRole,
|
|
530
|
+
resource,
|
|
531
|
+
sourceId: roleDiagnosticSource,
|
|
532
|
+
slotId,
|
|
533
|
+
viewId,
|
|
534
|
+
viewName,
|
|
535
|
+
}),
|
|
536
|
+
[
|
|
537
|
+
fieldIds,
|
|
538
|
+
metadataEntityReferenceRole,
|
|
539
|
+
module,
|
|
540
|
+
readMetadataFieldRole,
|
|
541
|
+
renderedBadgeEntries,
|
|
542
|
+
resource,
|
|
543
|
+
roleDiagnosticSource,
|
|
544
|
+
slotId,
|
|
545
|
+
viewId,
|
|
546
|
+
viewName,
|
|
547
|
+
],
|
|
548
|
+
)
|
|
549
|
+
useRegisterPresentationProjectionDiagnostics(
|
|
550
|
+
roleDiagnosticSource,
|
|
551
|
+
roleDiagnostics,
|
|
552
|
+
)
|
|
553
|
+
|
|
554
|
+
if (renderedBadges.length === 0) {
|
|
555
|
+
return null
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
return componentSystem.viewChrome.BadgeStrip({
|
|
559
|
+
badges: renderedBadges,
|
|
560
|
+
slotId,
|
|
561
|
+
viewId,
|
|
562
|
+
})
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
function renderStandardBadgeNode({
|
|
566
|
+
badge,
|
|
567
|
+
componentSystem,
|
|
568
|
+
createHref,
|
|
569
|
+
designSystem,
|
|
570
|
+
field,
|
|
571
|
+
module,
|
|
572
|
+
navigateHref,
|
|
573
|
+
resolvedBadge,
|
|
574
|
+
resource,
|
|
575
|
+
value,
|
|
576
|
+
}: {
|
|
577
|
+
readonly badge: PresentationBadgeDefinition
|
|
578
|
+
readonly componentSystem: PresentationComponentSystem
|
|
579
|
+
readonly createHref?: (
|
|
580
|
+
routeId: string,
|
|
581
|
+
parameters?: NavigationRouteParameters,
|
|
582
|
+
) => string | null
|
|
583
|
+
readonly designSystem: PresentationDesignSystem
|
|
584
|
+
readonly field: ProjectedDocumentFieldDefinitionLike | null
|
|
585
|
+
readonly module: PresentationModuleDefinition | null
|
|
586
|
+
readonly navigateHref?: (href: string) => void
|
|
587
|
+
readonly resolvedBadge: ReturnType<typeof resolvePresentationBadges>[number] | null
|
|
588
|
+
readonly resource: unknown
|
|
589
|
+
readonly value: unknown
|
|
590
|
+
}) {
|
|
591
|
+
if (
|
|
592
|
+
field &&
|
|
593
|
+
navigateHref &&
|
|
594
|
+
isProjectedDocumentEntityReferenceField(field) &&
|
|
595
|
+
findDocumentFieldNavigationRouteBinding(module, field)
|
|
596
|
+
) {
|
|
597
|
+
const entityReferenceBadge = renderProjectedEntityReferenceValue({
|
|
598
|
+
componentSystem,
|
|
599
|
+
createHref,
|
|
600
|
+
field,
|
|
601
|
+
module,
|
|
602
|
+
navigateHref,
|
|
603
|
+
resource,
|
|
604
|
+
unboundEntityReferenceStyle: 'badge',
|
|
605
|
+
value,
|
|
606
|
+
})
|
|
607
|
+
|
|
608
|
+
return entityReferenceBadge ? (
|
|
609
|
+
<span className="contents" key={badge.Id}>
|
|
610
|
+
{entityReferenceBadge}
|
|
611
|
+
</span>
|
|
612
|
+
) : null
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
return resolvedBadge ? (
|
|
616
|
+
<ProjectedPresentationBadge
|
|
617
|
+
badge={resolvedBadge}
|
|
618
|
+
componentSystem={componentSystem}
|
|
619
|
+
designSystem={designSystem}
|
|
620
|
+
key={badge.Id}
|
|
621
|
+
variant="outline"
|
|
622
|
+
/>
|
|
623
|
+
) : null
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
function projectViewBadgeStripRoleDiagnostics({
|
|
627
|
+
entries,
|
|
628
|
+
fieldIds,
|
|
629
|
+
metadataEntityReferenceRole,
|
|
630
|
+
module,
|
|
631
|
+
readMetadataFieldRole,
|
|
632
|
+
resource,
|
|
633
|
+
sourceId,
|
|
634
|
+
slotId,
|
|
635
|
+
viewId,
|
|
636
|
+
viewName,
|
|
637
|
+
}: {
|
|
638
|
+
readonly entries: readonly ProjectedViewBadgeRenderingEntry[]
|
|
639
|
+
readonly fieldIds: readonly string[]
|
|
640
|
+
readonly metadataEntityReferenceRole?: ProjectedViewChromeMetadataRole | null
|
|
641
|
+
readonly module: PresentationModuleDefinition | null
|
|
642
|
+
readonly readMetadataFieldRole?: ProjectedViewChromeMetadataFieldRoleReader
|
|
643
|
+
readonly resource: unknown
|
|
644
|
+
readonly sourceId: string
|
|
645
|
+
readonly slotId: string
|
|
646
|
+
readonly viewId?: string | null
|
|
647
|
+
readonly viewName?: string | null
|
|
648
|
+
}): readonly PresentationProjectionDiagnostic[] {
|
|
649
|
+
const diagnostics: PresentationProjectionDiagnostic[] = []
|
|
650
|
+
const roleEntries = entries.filter((entry) => entry.role)
|
|
651
|
+
const unhandledRoleEntries = roleEntries.filter((entry) =>
|
|
652
|
+
entry.mode !== 'role-interpreter')
|
|
653
|
+
const referencedFieldIds = new Set(entries
|
|
654
|
+
.map((entry) => entry.badgeFieldId)
|
|
655
|
+
.filter((fieldId): fieldId is string => Boolean(fieldId)))
|
|
656
|
+
const unreferencedRoleFields = fieldIds
|
|
657
|
+
.map((fieldId) => findPresentationField<ProjectedDocumentFieldDefinitionLike>(module, fieldId))
|
|
658
|
+
.filter((field): field is ProjectedDocumentFieldDefinitionLike => Boolean(field))
|
|
659
|
+
.map((field) => ({
|
|
660
|
+
field,
|
|
661
|
+
role: readMetadataFieldRole?.(field) ?? null,
|
|
662
|
+
}))
|
|
663
|
+
.filter((entry) => entry.role && !referencedFieldIds.has(entry.field.Id))
|
|
664
|
+
|
|
665
|
+
if (roleEntries.length > 0 || unreferencedRoleFields.length > 0) {
|
|
666
|
+
const counts = countBadgeRenderingModes(roleEntries)
|
|
667
|
+
diagnostics.push(
|
|
668
|
+
createPresentationProjectionDiagnostic({
|
|
669
|
+
category: 'local-interpretation',
|
|
670
|
+
details: {
|
|
671
|
+
badges: roleEntries.map((entry) => ({
|
|
672
|
+
badgeId: entry.badgeId,
|
|
673
|
+
fieldId: entry.badgeFieldId,
|
|
674
|
+
mode: entry.mode,
|
|
675
|
+
rendered: entry.rendered,
|
|
676
|
+
role: entry.role,
|
|
677
|
+
})),
|
|
678
|
+
counts,
|
|
679
|
+
slotId,
|
|
680
|
+
viewId: viewId ?? null,
|
|
681
|
+
},
|
|
682
|
+
id: `view.${viewId ?? 'unknown'}.badge-strip.${slotId}.metadata-badge-coverage`,
|
|
683
|
+
interpretation: {
|
|
684
|
+
status: unhandledRoleEntries.length === 0 ? 'locally-interpreted' : 'unbound',
|
|
685
|
+
target: 'presentation-badge-target-interpreter',
|
|
686
|
+
},
|
|
687
|
+
message:
|
|
688
|
+
`Badge strip slot '${slotId}'${viewName ? ` on '${viewName}'` : ''} ` +
|
|
689
|
+
`renders ${roleEntries.length} metadata badge role(s): ` +
|
|
690
|
+
`${counts['role-interpreter']} via role interpreters, ` +
|
|
691
|
+
`${counts['standard-badge']} via standard badge semantics, ` +
|
|
692
|
+
`${counts.unrendered} unrendered.`,
|
|
693
|
+
severity: 'info',
|
|
694
|
+
source: sourceId,
|
|
695
|
+
subject: {
|
|
696
|
+
id: slotId,
|
|
697
|
+
kind: 'view-chrome-slot',
|
|
698
|
+
name: viewName,
|
|
699
|
+
},
|
|
700
|
+
}),
|
|
701
|
+
)
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
diagnostics.push(
|
|
705
|
+
...projectViewBadgeStripEntityReferenceDiagnostics({
|
|
706
|
+
entries: roleEntries,
|
|
707
|
+
metadataEntityReferenceRole,
|
|
708
|
+
module,
|
|
709
|
+
resource,
|
|
710
|
+
sourceId,
|
|
711
|
+
slotId,
|
|
712
|
+
viewId,
|
|
713
|
+
viewName,
|
|
714
|
+
}),
|
|
715
|
+
)
|
|
716
|
+
|
|
717
|
+
for (const entry of unhandledRoleEntries) {
|
|
718
|
+
diagnostics.push(
|
|
719
|
+
createPresentationProjectionDiagnostic({
|
|
720
|
+
category: 'missing-binding',
|
|
721
|
+
details: {
|
|
722
|
+
badgeId: entry.badgeId,
|
|
723
|
+
fieldId: entry.badgeFieldId,
|
|
724
|
+
mode: entry.mode,
|
|
725
|
+
role: entry.role,
|
|
726
|
+
slotId,
|
|
727
|
+
viewId: viewId ?? null,
|
|
728
|
+
},
|
|
729
|
+
id: `view.${viewId ?? 'unknown'}.badge-strip.${slotId}.badge.${entry.badgeId}.role-unbound`,
|
|
730
|
+
interpretation: {
|
|
731
|
+
status: 'unbound',
|
|
732
|
+
target: 'presentation-badge-target-interpreter',
|
|
733
|
+
},
|
|
734
|
+
message:
|
|
735
|
+
`Metadata badge '${entry.badgeName}' declares role '${entry.role}', ` +
|
|
736
|
+
`but no badge target interpreter handled it.`,
|
|
737
|
+
severity: 'warning',
|
|
738
|
+
source: sourceId,
|
|
739
|
+
subject: {
|
|
740
|
+
id: entry.badgeId,
|
|
741
|
+
kind: 'presentation-badge',
|
|
742
|
+
name: entry.badgeName,
|
|
743
|
+
},
|
|
744
|
+
suggestedNextStep:
|
|
745
|
+
'Bind this metadata badge role in the frontend badge target interpreter registry.',
|
|
746
|
+
}),
|
|
747
|
+
)
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
for (const { field, role } of unreferencedRoleFields) {
|
|
751
|
+
diagnostics.push(
|
|
752
|
+
createPresentationProjectionDiagnostic({
|
|
753
|
+
category: 'incomplete-projection',
|
|
754
|
+
details: {
|
|
755
|
+
fieldId: field.Id,
|
|
756
|
+
fieldPath: field.Field,
|
|
757
|
+
role,
|
|
758
|
+
slotId,
|
|
759
|
+
viewId: viewId ?? null,
|
|
760
|
+
},
|
|
761
|
+
id: `view.${viewId ?? 'unknown'}.badge-strip.${slotId}.field.${field.Id}.role-unreferenced`,
|
|
762
|
+
interpretation: {
|
|
763
|
+
status: 'unbound',
|
|
764
|
+
target: 'presentation-badge-definition',
|
|
765
|
+
},
|
|
766
|
+
message:
|
|
767
|
+
`Metadata field '${field.Label}' declares role '${role}', but no ` +
|
|
768
|
+
`badge in slot '${slotId}' references it.`,
|
|
769
|
+
severity: 'warning',
|
|
770
|
+
source: sourceId,
|
|
771
|
+
subject: {
|
|
772
|
+
id: field.Id,
|
|
773
|
+
kind: 'field',
|
|
774
|
+
name: field.Label,
|
|
775
|
+
},
|
|
776
|
+
suggestedNextStep:
|
|
777
|
+
'Add a role-annotated PresentationBadgeDefinition for this metadata field.',
|
|
778
|
+
}),
|
|
779
|
+
)
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
return diagnostics
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
function projectViewBadgeStripEntityReferenceDiagnostics({
|
|
786
|
+
entries,
|
|
787
|
+
metadataEntityReferenceRole,
|
|
788
|
+
module,
|
|
789
|
+
resource,
|
|
790
|
+
sourceId,
|
|
791
|
+
slotId,
|
|
792
|
+
viewId,
|
|
793
|
+
viewName,
|
|
794
|
+
}: {
|
|
795
|
+
readonly entries: readonly ProjectedViewBadgeRenderingEntry[]
|
|
796
|
+
readonly metadataEntityReferenceRole?: ProjectedViewChromeMetadataRole | null
|
|
797
|
+
readonly module: PresentationModuleDefinition | null
|
|
798
|
+
readonly resource: unknown
|
|
799
|
+
readonly sourceId: string
|
|
800
|
+
readonly slotId: string
|
|
801
|
+
readonly viewId?: string | null
|
|
802
|
+
readonly viewName?: string | null
|
|
803
|
+
}): readonly PresentationProjectionDiagnostic[] {
|
|
804
|
+
if (!metadataEntityReferenceRole) {
|
|
805
|
+
return []
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
const entityReferenceEntries = entries.filter((entry) =>
|
|
809
|
+
entry.role === metadataEntityReferenceRole)
|
|
810
|
+
if (entityReferenceEntries.length === 0) {
|
|
811
|
+
return []
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
const routeStates = entityReferenceEntries.map((entry) => {
|
|
815
|
+
const binding = entry.field
|
|
816
|
+
? findDocumentFieldNavigationRouteBinding(module, entry.field)
|
|
817
|
+
: null
|
|
818
|
+
const projection =
|
|
819
|
+
entry.field && binding?.RouteId
|
|
820
|
+
? projectDocumentFieldNavigation({
|
|
821
|
+
field: entry.field,
|
|
822
|
+
module,
|
|
823
|
+
resource,
|
|
824
|
+
value: entry.value,
|
|
825
|
+
})
|
|
826
|
+
: null
|
|
827
|
+
|
|
828
|
+
return {
|
|
829
|
+
binding,
|
|
830
|
+
entry,
|
|
831
|
+
projection,
|
|
832
|
+
}
|
|
833
|
+
})
|
|
834
|
+
const routeMissing = routeStates.filter((state) => !state.binding?.RouteId)
|
|
835
|
+
const unresolvedParameters = routeStates.filter((state) =>
|
|
836
|
+
(state.projection?.missingParameterNames.length ?? 0) > 0)
|
|
837
|
+
const routeReady = routeStates.filter((state) =>
|
|
838
|
+
state.binding?.RouteId &&
|
|
839
|
+
state.projection &&
|
|
840
|
+
state.projection.missingParameterNames.length === 0)
|
|
841
|
+
const fallback = routeStates.filter((state) =>
|
|
842
|
+
!state.binding?.RouteId || !state.projection)
|
|
843
|
+
const diagnostics: PresentationProjectionDiagnostic[] = [
|
|
844
|
+
createPresentationProjectionDiagnostic({
|
|
845
|
+
category: 'local-interpretation',
|
|
846
|
+
details: {
|
|
847
|
+
fallback: fallback.map(({ entry }) => entry.badgeId),
|
|
848
|
+
routeMissing: routeMissing.map(({ entry }) => entry.badgeId),
|
|
849
|
+
routeReady: routeReady.map(({ entry, projection }) => ({
|
|
850
|
+
badgeId: entry.badgeId,
|
|
851
|
+
routeId: projection?.routeId,
|
|
852
|
+
})),
|
|
853
|
+
slotId,
|
|
854
|
+
unresolvedParameters: unresolvedParameters.map(({ entry, projection }) => ({
|
|
855
|
+
badgeId: entry.badgeId,
|
|
856
|
+
missingParameterNames: projection?.missingParameterNames ?? [],
|
|
857
|
+
routeId: projection?.routeId,
|
|
858
|
+
})),
|
|
859
|
+
viewId: viewId ?? null,
|
|
860
|
+
},
|
|
861
|
+
id: `view.${viewId ?? 'unknown'}.badge-strip.${slotId}.entity-reference-badge-coverage`,
|
|
862
|
+
interpretation: {
|
|
863
|
+
status: routeMissing.length === 0 && unresolvedParameters.length === 0
|
|
864
|
+
? 'locally-interpreted'
|
|
865
|
+
: 'unbound',
|
|
866
|
+
target: 'entity-reference-badge-route-binding',
|
|
867
|
+
},
|
|
868
|
+
message:
|
|
869
|
+
`Badge strip slot '${slotId}'${viewName ? ` on '${viewName}'` : ''} ` +
|
|
870
|
+
`renders ${entityReferenceEntries.length} entity-reference badge(s): ` +
|
|
871
|
+
`${routeReady.length} route-bound link badge(s), ` +
|
|
872
|
+
`${fallback.length} non-link fallback badge(s), ` +
|
|
873
|
+
`${unresolvedParameters.length} with unresolved route parameter(s).`,
|
|
874
|
+
severity: 'info',
|
|
875
|
+
source: sourceId,
|
|
876
|
+
subject: {
|
|
877
|
+
id: slotId,
|
|
878
|
+
kind: 'view-chrome-slot',
|
|
879
|
+
name: viewName,
|
|
880
|
+
},
|
|
881
|
+
}),
|
|
882
|
+
]
|
|
883
|
+
|
|
884
|
+
for (const { entry } of routeMissing) {
|
|
885
|
+
diagnostics.push(
|
|
886
|
+
createPresentationProjectionDiagnostic({
|
|
887
|
+
category: 'missing-binding',
|
|
888
|
+
details: {
|
|
889
|
+
badgeId: entry.badgeId,
|
|
890
|
+
fieldId: entry.badgeFieldId,
|
|
891
|
+
role: entry.role,
|
|
892
|
+
slotId,
|
|
893
|
+
viewId: viewId ?? null,
|
|
894
|
+
},
|
|
895
|
+
id: `view.${viewId ?? 'unknown'}.badge-strip.${slotId}.badge.${entry.badgeId}.entity-reference-route-missing`,
|
|
896
|
+
interpretation: {
|
|
897
|
+
status: 'unbound',
|
|
898
|
+
target: 'entity-reference-badge-route-binding',
|
|
899
|
+
},
|
|
900
|
+
message:
|
|
901
|
+
`Entity-reference badge '${entry.badgeName}' has no route target binding; ` +
|
|
902
|
+
'it renders as a non-link fallback badge.',
|
|
903
|
+
severity: 'warning',
|
|
904
|
+
source: sourceId,
|
|
905
|
+
subject: {
|
|
906
|
+
id: entry.badgeId,
|
|
907
|
+
kind: 'presentation-badge',
|
|
908
|
+
name: entry.badgeName,
|
|
909
|
+
},
|
|
910
|
+
suggestedNextStep:
|
|
911
|
+
'Add a navigation route target binding for this entity-reference field.',
|
|
912
|
+
}),
|
|
913
|
+
)
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
for (const { entry, projection } of unresolvedParameters) {
|
|
917
|
+
diagnostics.push(
|
|
918
|
+
createPresentationProjectionDiagnostic({
|
|
919
|
+
category: 'unbound',
|
|
920
|
+
details: {
|
|
921
|
+
badgeId: entry.badgeId,
|
|
922
|
+
fieldId: entry.badgeFieldId,
|
|
923
|
+
missingParameterNames: projection?.missingParameterNames ?? [],
|
|
924
|
+
role: entry.role,
|
|
925
|
+
routeId: projection?.routeId,
|
|
926
|
+
slotId,
|
|
927
|
+
viewId: viewId ?? null,
|
|
928
|
+
},
|
|
929
|
+
id: `view.${viewId ?? 'unknown'}.badge-strip.${slotId}.badge.${entry.badgeId}.entity-reference-route-parameters-unresolved`,
|
|
930
|
+
interpretation: {
|
|
931
|
+
status: 'unbound',
|
|
932
|
+
target: 'entity-reference-badge-route-parameters',
|
|
933
|
+
},
|
|
934
|
+
message:
|
|
935
|
+
`Entity-reference badge '${entry.badgeName}' has unresolved route ` +
|
|
936
|
+
`parameter(s): ${(projection?.missingParameterNames ?? []).join(', ')}.`,
|
|
937
|
+
severity: 'warning',
|
|
938
|
+
source: sourceId,
|
|
939
|
+
subject: {
|
|
940
|
+
id: entry.badgeId,
|
|
941
|
+
kind: 'presentation-badge',
|
|
942
|
+
name: entry.badgeName,
|
|
943
|
+
},
|
|
944
|
+
suggestedNextStep:
|
|
945
|
+
'Update the route parameter binding for this entity-reference field or expose the required source value.',
|
|
946
|
+
}),
|
|
947
|
+
)
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
return diagnostics
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
function countBadgeRenderingModes(
|
|
954
|
+
entries: readonly ProjectedViewBadgeRenderingEntry[],
|
|
955
|
+
): Record<ProjectedViewBadgeRenderingMode, number> {
|
|
956
|
+
return entries.reduce<Record<ProjectedViewBadgeRenderingMode, number>>(
|
|
957
|
+
(counts, entry) => ({
|
|
958
|
+
...counts,
|
|
959
|
+
[entry.mode]: counts[entry.mode] + 1,
|
|
960
|
+
}),
|
|
961
|
+
{
|
|
962
|
+
'role-interpreter': 0,
|
|
963
|
+
'standard-badge': 0,
|
|
964
|
+
unrendered: 0,
|
|
965
|
+
},
|
|
966
|
+
)
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
function getDocumentViewLabel(
|
|
970
|
+
module: PresentationModuleDefinition | null,
|
|
971
|
+
workspaceView: ViewDefinition | null,
|
|
972
|
+
viewId: string,
|
|
973
|
+
) {
|
|
974
|
+
const region = workspaceView?.Regions?.find((candidate) =>
|
|
975
|
+
candidate.ViewIds?.includes(viewId),
|
|
976
|
+
)
|
|
977
|
+
return (
|
|
978
|
+
region?.Name ??
|
|
979
|
+
findPresentationView(module, viewId)?.Name ??
|
|
980
|
+
getDocumentViewFallbackLabel(viewId)
|
|
981
|
+
)
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
function getDocumentViewFallbackLabel(viewId: string) {
|
|
985
|
+
const normalized = viewId.toLocaleLowerCase()
|
|
986
|
+
if (normalized.includes('json')) {
|
|
987
|
+
return 'JSON'
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
if (normalized.includes('structure')) {
|
|
991
|
+
return 'Structure'
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
if (normalized.includes('types')) {
|
|
995
|
+
return 'Types'
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
return viewId
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
function createFieldBackedBadgeDefinition(fieldId: string): PresentationBadgeDefinition {
|
|
1002
|
+
return {
|
|
1003
|
+
Annotations: [],
|
|
1004
|
+
Content: null,
|
|
1005
|
+
FieldId: fieldId,
|
|
1006
|
+
Id: fieldId,
|
|
1007
|
+
Name: fieldId,
|
|
1008
|
+
OmitWhenEmpty: true,
|
|
1009
|
+
OmitWhenZero: false,
|
|
1010
|
+
Tone: null,
|
|
1011
|
+
Value: null,
|
|
1012
|
+
ValueTemplate: null,
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
function resolveDocumentViewIcon(label: string, viewId: string) {
|
|
1017
|
+
const normalized = `${label} ${viewId}`.toLocaleLowerCase()
|
|
1018
|
+
if (normalized.includes('json')) {
|
|
1019
|
+
return {
|
|
1020
|
+
fallbackIcon: 'braces',
|
|
1021
|
+
id: viewChromeIconIds.viewJson,
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
if (normalized.includes('type')) {
|
|
1026
|
+
return {
|
|
1027
|
+
fallbackIcon: 'box',
|
|
1028
|
+
id: viewChromeIconIds.viewTypes,
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
if (normalized.includes('structure')) {
|
|
1033
|
+
return {
|
|
1034
|
+
fallbackIcon: 'list-tree',
|
|
1035
|
+
id: viewChromeIconIds.viewStructure,
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
return {
|
|
1040
|
+
fallbackIcon: 'braces',
|
|
1041
|
+
id: viewChromeIconIds.viewDefault,
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
function renderViewChromeIcon({
|
|
1046
|
+
className = 'size-3.5',
|
|
1047
|
+
fallbackIcon,
|
|
1048
|
+
icon,
|
|
1049
|
+
module,
|
|
1050
|
+
}: {
|
|
1051
|
+
readonly className?: string
|
|
1052
|
+
readonly fallbackIcon: string
|
|
1053
|
+
readonly icon: string
|
|
1054
|
+
readonly module?: PresentationModuleDefinition | null
|
|
1055
|
+
}) {
|
|
1056
|
+
return renderPresentationIcon({
|
|
1057
|
+
className,
|
|
1058
|
+
icon,
|
|
1059
|
+
module,
|
|
1060
|
+
}) ?? renderPresentationIcon({
|
|
1061
|
+
className,
|
|
1062
|
+
icon: fallbackIcon,
|
|
1063
|
+
})
|
|
1064
|
+
}
|