@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.
Files changed (262) hide show
  1. package/LICENSE +55 -0
  2. package/dist/document-workspace-surface-slot-renderers.d.ts +58 -0
  3. package/dist/document-workspace-surface-slot-renderers.d.ts.map +1 -0
  4. package/dist/document-workspace-surface-slot-renderers.js +206 -0
  5. package/dist/document-workspace-surface-slot-renderers.js.map +1 -0
  6. package/dist/index.d.ts +53 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +53 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/navigation-shell-frame-renderer-registry.d.ts +8 -0
  11. package/dist/navigation-shell-frame-renderer-registry.d.ts.map +1 -0
  12. package/dist/navigation-shell-frame-renderer-registry.js +2 -0
  13. package/dist/navigation-shell-frame-renderer-registry.js.map +1 -0
  14. package/dist/navigation-shell-slot-renderer-registry.d.ts +9 -0
  15. package/dist/navigation-shell-slot-renderer-registry.d.ts.map +1 -0
  16. package/dist/navigation-shell-slot-renderer-registry.js +2 -0
  17. package/dist/navigation-shell-slot-renderer-registry.js.map +1 -0
  18. package/dist/page-host-unavailable-renderer.d.ts +10 -0
  19. package/dist/page-host-unavailable-renderer.d.ts.map +1 -0
  20. package/dist/page-host-unavailable-renderer.js +27 -0
  21. package/dist/page-host-unavailable-renderer.js.map +1 -0
  22. package/dist/presentation-action-group.d.ts +99 -0
  23. package/dist/presentation-action-group.d.ts.map +1 -0
  24. package/dist/presentation-action-group.js +214 -0
  25. package/dist/presentation-action-group.js.map +1 -0
  26. package/dist/presentation-badge-target-interpreter.d.ts +26 -0
  27. package/dist/presentation-badge-target-interpreter.d.ts.map +1 -0
  28. package/dist/presentation-badge-target-interpreter.js +17 -0
  29. package/dist/presentation-badge-target-interpreter.js.map +1 -0
  30. package/dist/presentation-component-groups.d.ts +968 -0
  31. package/dist/presentation-component-groups.d.ts.map +1 -0
  32. package/dist/presentation-component-groups.js +505 -0
  33. package/dist/presentation-component-groups.js.map +1 -0
  34. package/dist/presentation-component-system-diagnostics.d.ts +27 -0
  35. package/dist/presentation-component-system-diagnostics.d.ts.map +1 -0
  36. package/dist/presentation-component-system-diagnostics.js +399 -0
  37. package/dist/presentation-component-system-diagnostics.js.map +1 -0
  38. package/dist/presentation-component-system.d.ts +31 -0
  39. package/dist/presentation-component-system.d.ts.map +1 -0
  40. package/dist/presentation-component-system.js +61 -0
  41. package/dist/presentation-component-system.js.map +1 -0
  42. package/dist/presentation-icon-diagnostics.d.ts +12 -0
  43. package/dist/presentation-icon-diagnostics.d.ts.map +1 -0
  44. package/dist/presentation-icon-diagnostics.js +17 -0
  45. package/dist/presentation-icon-diagnostics.js.map +1 -0
  46. package/dist/presentation-icon-registry.d.ts +28 -0
  47. package/dist/presentation-icon-registry.d.ts.map +1 -0
  48. package/dist/presentation-icon-registry.js +80 -0
  49. package/dist/presentation-icon-registry.js.map +1 -0
  50. package/dist/presentation-projection-trace-panel.d.ts +10 -0
  51. package/dist/presentation-projection-trace-panel.d.ts.map +1 -0
  52. package/dist/presentation-projection-trace-panel.js +48 -0
  53. package/dist/presentation-projection-trace-panel.js.map +1 -0
  54. package/dist/presentation-routed-surface-host.d.ts +19 -0
  55. package/dist/presentation-routed-surface-host.d.ts.map +1 -0
  56. package/dist/presentation-routed-surface-host.js +12 -0
  57. package/dist/presentation-routed-surface-host.js.map +1 -0
  58. package/dist/presentation-shadcn-component-system.d.ts +22 -0
  59. package/dist/presentation-shadcn-component-system.d.ts.map +1 -0
  60. package/dist/presentation-shadcn-component-system.js +2 -0
  61. package/dist/presentation-shadcn-component-system.js.map +1 -0
  62. package/dist/presentation-standard-renderers.d.ts +168 -0
  63. package/dist/presentation-standard-renderers.d.ts.map +1 -0
  64. package/dist/presentation-standard-renderers.js +440 -0
  65. package/dist/presentation-standard-renderers.js.map +1 -0
  66. package/dist/presentation-surface-renderer.d.ts +23 -0
  67. package/dist/presentation-surface-renderer.d.ts.map +1 -0
  68. package/dist/presentation-surface-renderer.js +119 -0
  69. package/dist/presentation-surface-renderer.js.map +1 -0
  70. package/dist/presentation-value-renderers.d.ts +10 -0
  71. package/dist/presentation-value-renderers.d.ts.map +1 -0
  72. package/dist/presentation-value-renderers.js +14 -0
  73. package/dist/presentation-value-renderers.js.map +1 -0
  74. package/dist/process-task-icons.d.ts +49 -0
  75. package/dist/process-task-icons.d.ts.map +1 -0
  76. package/dist/process-task-icons.js +154 -0
  77. package/dist/process-task-icons.js.map +1 -0
  78. package/dist/projected-activity-state.d.ts +17 -0
  79. package/dist/projected-activity-state.d.ts.map +1 -0
  80. package/dist/projected-activity-state.js +22 -0
  81. package/dist/projected-activity-state.js.map +1 -0
  82. package/dist/projected-collection-action-runtime-diagnostics.d.ts +4 -0
  83. package/dist/projected-collection-action-runtime-diagnostics.d.ts.map +1 -0
  84. package/dist/projected-collection-action-runtime-diagnostics.js +9 -0
  85. package/dist/projected-collection-action-runtime-diagnostics.js.map +1 -0
  86. package/dist/projected-collection-view.d.ts +90 -0
  87. package/dist/projected-collection-view.d.ts.map +1 -0
  88. package/dist/projected-collection-view.js +532 -0
  89. package/dist/projected-collection-view.js.map +1 -0
  90. package/dist/projected-document-action-status-notices.d.ts +15 -0
  91. package/dist/projected-document-action-status-notices.d.ts.map +1 -0
  92. package/dist/projected-document-action-status-notices.js +33 -0
  93. package/dist/projected-document-action-status-notices.js.map +1 -0
  94. package/dist/projected-document-badges.d.ts +24 -0
  95. package/dist/projected-document-badges.d.ts.map +1 -0
  96. package/dist/projected-document-badges.js +53 -0
  97. package/dist/projected-document-badges.js.map +1 -0
  98. package/dist/projected-document-editor-surface.d.ts +46 -0
  99. package/dist/projected-document-editor-surface.d.ts.map +1 -0
  100. package/dist/projected-document-editor-surface.js +399 -0
  101. package/dist/projected-document-editor-surface.js.map +1 -0
  102. package/dist/projected-document-workspace-notices.d.ts +24 -0
  103. package/dist/projected-document-workspace-notices.d.ts.map +1 -0
  104. package/dist/projected-document-workspace-notices.js +14 -0
  105. package/dist/projected-document-workspace-notices.js.map +1 -0
  106. package/dist/projected-document-workspace-prompt-child-view-registry.d.ts +25 -0
  107. package/dist/projected-document-workspace-prompt-child-view-registry.d.ts.map +1 -0
  108. package/dist/projected-document-workspace-prompt-child-view-registry.js +41 -0
  109. package/dist/projected-document-workspace-prompt-child-view-registry.js.map +1 -0
  110. package/dist/projected-document-workspace-prompt-child-view-renderers.d.ts +32 -0
  111. package/dist/projected-document-workspace-prompt-child-view-renderers.d.ts.map +1 -0
  112. package/dist/projected-document-workspace-prompt-child-view-renderers.js +77 -0
  113. package/dist/projected-document-workspace-prompt-child-view-renderers.js.map +1 -0
  114. package/dist/projected-document-workspace-shell.d.ts +100 -0
  115. package/dist/projected-document-workspace-shell.d.ts.map +1 -0
  116. package/dist/projected-document-workspace-shell.js +153 -0
  117. package/dist/projected-document-workspace-shell.js.map +1 -0
  118. package/dist/projected-document-workspace.d.ts +39 -0
  119. package/dist/projected-document-workspace.d.ts.map +1 -0
  120. package/dist/projected-document-workspace.js +63 -0
  121. package/dist/projected-document-workspace.js.map +1 -0
  122. package/dist/projected-field-value-rendering.d.ts +94 -0
  123. package/dist/projected-field-value-rendering.d.ts.map +1 -0
  124. package/dist/projected-field-value-rendering.js +377 -0
  125. package/dist/projected-field-value-rendering.js.map +1 -0
  126. package/dist/projected-inline-list.d.ts +20 -0
  127. package/dist/projected-inline-list.d.ts.map +1 -0
  128. package/dist/projected-inline-list.js +149 -0
  129. package/dist/projected-inline-list.js.map +1 -0
  130. package/dist/projected-input-form.d.ts +143 -0
  131. package/dist/projected-input-form.d.ts.map +1 -0
  132. package/dist/projected-input-form.js +612 -0
  133. package/dist/projected-input-form.js.map +1 -0
  134. package/dist/projected-metric-dashboard.d.ts +26 -0
  135. package/dist/projected-metric-dashboard.d.ts.map +1 -0
  136. package/dist/projected-metric-dashboard.js +20 -0
  137. package/dist/projected-metric-dashboard.js.map +1 -0
  138. package/dist/projected-metric-strip.d.ts +20 -0
  139. package/dist/projected-metric-strip.d.ts.map +1 -0
  140. package/dist/projected-metric-strip.js +131 -0
  141. package/dist/projected-metric-strip.js.map +1 -0
  142. package/dist/projected-navigation-shell-view-host.d.ts +34 -0
  143. package/dist/projected-navigation-shell-view-host.d.ts.map +1 -0
  144. package/dist/projected-navigation-shell-view-host.js +75 -0
  145. package/dist/projected-navigation-shell-view-host.js.map +1 -0
  146. package/dist/projected-navigation-shell.d.ts +33 -0
  147. package/dist/projected-navigation-shell.d.ts.map +1 -0
  148. package/dist/projected-navigation-shell.js +112 -0
  149. package/dist/projected-navigation-shell.js.map +1 -0
  150. package/dist/projected-presentation-badges.d.ts +34 -0
  151. package/dist/projected-presentation-badges.d.ts.map +1 -0
  152. package/dist/projected-presentation-badges.js +22 -0
  153. package/dist/projected-presentation-badges.js.map +1 -0
  154. package/dist/projected-presentation-diagnostics.d.ts +10 -0
  155. package/dist/projected-presentation-diagnostics.d.ts.map +1 -0
  156. package/dist/projected-presentation-diagnostics.js +40 -0
  157. package/dist/projected-presentation-diagnostics.js.map +1 -0
  158. package/dist/projected-presentation-flow-layer.d.ts +33 -0
  159. package/dist/projected-presentation-flow-layer.d.ts.map +1 -0
  160. package/dist/projected-presentation-flow-layer.js +71 -0
  161. package/dist/projected-presentation-flow-layer.js.map +1 -0
  162. package/dist/projected-process-task-notices.d.ts +37 -0
  163. package/dist/projected-process-task-notices.d.ts.map +1 -0
  164. package/dist/projected-process-task-notices.js +225 -0
  165. package/dist/projected-process-task-notices.js.map +1 -0
  166. package/dist/projected-prompt-child-view-renderer.d.ts +101 -0
  167. package/dist/projected-prompt-child-view-renderer.d.ts.map +1 -0
  168. package/dist/projected-prompt-child-view-renderer.js +442 -0
  169. package/dist/projected-prompt-child-view-renderer.js.map +1 -0
  170. package/dist/projected-prompt-document-preview.d.ts +39 -0
  171. package/dist/projected-prompt-document-preview.d.ts.map +1 -0
  172. package/dist/projected-prompt-document-preview.js +50 -0
  173. package/dist/projected-prompt-document-preview.js.map +1 -0
  174. package/dist/projected-prompt-view.d.ts +35 -0
  175. package/dist/projected-prompt-view.d.ts.map +1 -0
  176. package/dist/projected-prompt-view.js +292 -0
  177. package/dist/projected-prompt-view.js.map +1 -0
  178. package/dist/projected-query-form.d.ts +56 -0
  179. package/dist/projected-query-form.d.ts.map +1 -0
  180. package/dist/projected-query-form.js +100 -0
  181. package/dist/projected-query-form.js.map +1 -0
  182. package/dist/projected-record-details.d.ts +20 -0
  183. package/dist/projected-record-details.d.ts.map +1 -0
  184. package/dist/projected-record-details.js +60 -0
  185. package/dist/projected-record-details.js.map +1 -0
  186. package/dist/projected-routed-surface-runtime.d.ts +86 -0
  187. package/dist/projected-routed-surface-runtime.d.ts.map +1 -0
  188. package/dist/projected-routed-surface-runtime.js +332 -0
  189. package/dist/projected-routed-surface-runtime.js.map +1 -0
  190. package/dist/projected-tabs-view.d.ts +21 -0
  191. package/dist/projected-tabs-view.d.ts.map +1 -0
  192. package/dist/projected-tabs-view.js +140 -0
  193. package/dist/projected-tabs-view.js.map +1 -0
  194. package/dist/projected-view-chrome.d.ts +15 -0
  195. package/dist/projected-view-chrome.d.ts.map +1 -0
  196. package/dist/projected-view-chrome.js +67 -0
  197. package/dist/projected-view-chrome.js.map +1 -0
  198. package/dist/projected-view-surface.d.ts +34 -0
  199. package/dist/projected-view-surface.d.ts.map +1 -0
  200. package/dist/projected-view-surface.js +40 -0
  201. package/dist/projected-view-surface.js.map +1 -0
  202. package/dist/standard-collection-chrome-slot-renderers.d.ts +26 -0
  203. package/dist/standard-collection-chrome-slot-renderers.d.ts.map +1 -0
  204. package/dist/standard-collection-chrome-slot-renderers.js +250 -0
  205. package/dist/standard-collection-chrome-slot-renderers.js.map +1 -0
  206. package/dist/standard-view-chrome-slot-renderers.d.ts +57 -0
  207. package/dist/standard-view-chrome-slot-renderers.d.ts.map +1 -0
  208. package/dist/standard-view-chrome-slot-renderers.js +614 -0
  209. package/dist/standard-view-chrome-slot-renderers.js.map +1 -0
  210. package/package.json +68 -0
  211. package/src/document-workspace-surface-slot-renderers.tsx +395 -0
  212. package/src/index.ts +53 -0
  213. package/src/navigation-shell-frame-renderer-registry.ts +29 -0
  214. package/src/navigation-shell-slot-renderer-registry.ts +46 -0
  215. package/src/page-host-unavailable-renderer.tsx +79 -0
  216. package/src/presentation-action-group.tsx +475 -0
  217. package/src/presentation-badge-target-interpreter.ts +54 -0
  218. package/src/presentation-component-groups.ts +2505 -0
  219. package/src/presentation-component-system-diagnostics.ts +848 -0
  220. package/src/presentation-component-system.ts +365 -0
  221. package/src/presentation-icon-diagnostics.ts +53 -0
  222. package/src/presentation-icon-registry.tsx +181 -0
  223. package/src/presentation-projection-trace-panel.tsx +140 -0
  224. package/src/presentation-routed-surface-host.tsx +48 -0
  225. package/src/presentation-shadcn-component-system.ts +102 -0
  226. package/src/presentation-standard-renderers.tsx +1290 -0
  227. package/src/presentation-surface-renderer.tsx +263 -0
  228. package/src/presentation-value-renderers.tsx +40 -0
  229. package/src/process-task-icons.tsx +258 -0
  230. package/src/projected-activity-state.tsx +63 -0
  231. package/src/projected-collection-action-runtime-diagnostics.ts +22 -0
  232. package/src/projected-collection-view.tsx +1273 -0
  233. package/src/projected-document-action-status-notices.tsx +66 -0
  234. package/src/projected-document-badges.tsx +134 -0
  235. package/src/projected-document-editor-surface.tsx +808 -0
  236. package/src/projected-document-workspace-notices.tsx +77 -0
  237. package/src/projected-document-workspace-prompt-child-view-registry.ts +99 -0
  238. package/src/projected-document-workspace-prompt-child-view-renderers.tsx +205 -0
  239. package/src/projected-document-workspace-shell.tsx +427 -0
  240. package/src/projected-document-workspace.tsx +216 -0
  241. package/src/projected-field-value-rendering.tsx +704 -0
  242. package/src/projected-inline-list.tsx +434 -0
  243. package/src/projected-input-form.tsx +1218 -0
  244. package/src/projected-metric-dashboard.tsx +106 -0
  245. package/src/projected-metric-strip.tsx +244 -0
  246. package/src/projected-navigation-shell-view-host.tsx +177 -0
  247. package/src/projected-navigation-shell.tsx +219 -0
  248. package/src/projected-presentation-badges.tsx +95 -0
  249. package/src/projected-presentation-diagnostics.tsx +120 -0
  250. package/src/projected-presentation-flow-layer.tsx +186 -0
  251. package/src/projected-process-task-notices.tsx +501 -0
  252. package/src/projected-prompt-child-view-renderer.tsx +698 -0
  253. package/src/projected-prompt-document-preview.tsx +197 -0
  254. package/src/projected-prompt-view.tsx +592 -0
  255. package/src/projected-query-form.tsx +286 -0
  256. package/src/projected-record-details.tsx +133 -0
  257. package/src/projected-routed-surface-runtime.tsx +713 -0
  258. package/src/projected-tabs-view.tsx +308 -0
  259. package/src/projected-view-chrome.tsx +148 -0
  260. package/src/projected-view-surface.tsx +131 -0
  261. package/src/standard-collection-chrome-slot-renderers.tsx +391 -0
  262. package/src/standard-view-chrome-slot-renderers.tsx +1064 -0
@@ -0,0 +1,501 @@
1
+ import { Fragment, useMemo, type ReactNode } from 'react'
2
+
3
+ import {
4
+ findPresentationAction,
5
+ findPresentationField,
6
+ resolvePresentationContent,
7
+ resolvePresentationFieldValueTone,
8
+ } from '@cohesivesystems/presentation-core'
9
+ import {
10
+ projectPresentationIconDiagnostics,
11
+ } from './presentation-icon-diagnostics'
12
+ import type {
13
+ ActionPlacementDefinition,
14
+ DocumentProcessTaskNoticeDefinition,
15
+ DocumentProcessTaskNoticeActionDefinition,
16
+ DocumentProcessTaskNoticeActionTargetKind,
17
+ DocumentProfileProjection,
18
+ FieldPresentationDefinition,
19
+ ProcessTask,
20
+ ProcessTaskSelector,
21
+ ProcessTaskSelectorDefinition,
22
+ } from '@cohesivesystems/presentation-core'
23
+ import {
24
+ usePresentationModule,
25
+ usePresentationNavigationRuntime,
26
+ useRegisterPresentationProjectionDiagnostics,
27
+ } from '@cohesivesystems/presentation-react'
28
+ import type { PresentationDesignSystem } from '@cohesivesystems/presentation-tailwind'
29
+ import type {
30
+ PresentationShadcnComponentSystem as PresentationComponentSystem,
31
+ } from './presentation-shadcn-component-system'
32
+ import {
33
+ renderProcessIcon,
34
+ renderProjectedProcessStatusIcon,
35
+ renderProcessStatusIcon,
36
+ resolveProcessTaskNoticeIconSubjects,
37
+ processIconIds,
38
+ } from './process-task-icons'
39
+ import {
40
+ documentProcessTaskNoticeActionTargetKinds,
41
+ } from '@cohesivesystems/presentation-contracts'
42
+
43
+ export interface ProjectedProcessTaskNoticeRenderContext {
44
+ readonly notice: DocumentProcessTaskNoticeDefinition
45
+ readonly selector: ProcessTaskSelector
46
+ readonly selectorDefinition: ProcessTaskSelectorDefinition
47
+ readonly task: ProcessTask
48
+ }
49
+
50
+ export type ProjectedProcessTaskNoticeRenderer = (
51
+ context: ProjectedProcessTaskNoticeRenderContext,
52
+ ) => ReactNode
53
+
54
+ export interface ProjectedProcessTaskNoticesProps<TContext> {
55
+ readonly className?: string
56
+ readonly componentSystem: PresentationComponentSystem
57
+ readonly context: TContext
58
+ readonly designSystem: PresentationDesignSystem
59
+ readonly findActiveTask: (selector: ProcessTaskSelector) => ProcessTask | null
60
+ readonly profile: Pick<
61
+ DocumentProfileProjection,
62
+ 'ProcessTaskNotices' | 'ProcessTaskSelectors'
63
+ > | null
64
+ readonly projectSelector: (
65
+ selector: ProcessTaskSelectorDefinition | null | undefined,
66
+ context: TContext,
67
+ ) => ProcessTaskSelector | null
68
+ readonly region?: string
69
+ readonly renderNotice?: ProjectedProcessTaskNoticeRenderer
70
+ }
71
+
72
+ /**
73
+ * Projects document-profile process task notices into concrete task notice UI.
74
+ *
75
+ * The profile declares which notices exist and which selector supplies each
76
+ * task. The host only provides the runtime document context, process-task
77
+ * lookup service, and renderer for a resolved task notice.
78
+ */
79
+ export function ProjectedProcessTaskNotices<TContext>({
80
+ className,
81
+ componentSystem,
82
+ context,
83
+ designSystem,
84
+ findActiveTask,
85
+ profile,
86
+ projectSelector,
87
+ region,
88
+ renderNotice,
89
+ }: ProjectedProcessTaskNoticesProps<TContext>) {
90
+ const notices = resolveProcessTaskNoticeRenderContexts({
91
+ context,
92
+ findActiveTask,
93
+ profile,
94
+ projectSelector,
95
+ region,
96
+ })
97
+ if (notices.length === 0) {
98
+ return null
99
+ }
100
+
101
+ const rootClassName = className ? `grid gap-2 ${className}` : 'grid gap-2'
102
+ return (
103
+ <div className={rootClassName}>
104
+ {notices.map((notice) => (
105
+ <Fragment key={notice.notice.Id}>
106
+ {renderNotice?.(notice) ?? (
107
+ <ProjectedProcessTaskNotice
108
+ componentSystem={componentSystem}
109
+ designSystem={designSystem}
110
+ notice={notice.notice}
111
+ task={notice.task}
112
+ />
113
+ )}
114
+ </Fragment>
115
+ ))}
116
+ </div>
117
+ )
118
+ }
119
+
120
+ export function ProjectedProcessTaskNotice({
121
+ componentSystem,
122
+ designSystem,
123
+ notice,
124
+ task,
125
+ }: {
126
+ readonly componentSystem: PresentationComponentSystem
127
+ readonly designSystem: PresentationDesignSystem
128
+ readonly notice?: DocumentProcessTaskNoticeDefinition | null
129
+ readonly task: ProcessTask
130
+ }) {
131
+ const module = usePresentationModule()
132
+ const statusField = useMemo(
133
+ () => resolveProcessTaskNoticeStatusField(module, notice),
134
+ [
135
+ module,
136
+ notice,
137
+ ],
138
+ )
139
+ const iconDiagnostics = useMemo(
140
+ () => projectPresentationIconDiagnostics({
141
+ icons: resolveProcessTaskNoticeIconSubjects(task, statusField, notice),
142
+ module,
143
+ source: `projected-process-task-notice-icons:${task.id}`,
144
+ surfaceId: task.id,
145
+ surfaceName: task.title,
146
+ }),
147
+ [
148
+ module,
149
+ notice,
150
+ statusField,
151
+ task,
152
+ ],
153
+ )
154
+ useRegisterPresentationProjectionDiagnostics(
155
+ `projected-process-task-notice-icons:${task.id}`,
156
+ iconDiagnostics,
157
+ )
158
+ const content = resolveProcessTaskNoticeContent(notice, task)
159
+
160
+ return componentSystem.processes.ProcessTaskNotice({
161
+ actions: (
162
+ <ProjectedProcessTaskActionButtons
163
+ componentSystem={componentSystem}
164
+ module={module}
165
+ notice={notice}
166
+ task={task}
167
+ />
168
+ ),
169
+ className: resolveProcessTaskNoticeClassName({ designSystem, statusField, task }),
170
+ description: content.description,
171
+ icon: (
172
+ <ProjectedProcessTaskStatusIcon
173
+ module={module}
174
+ statusField={statusField}
175
+ task={task}
176
+ />
177
+ ),
178
+ title: content.title,
179
+ })
180
+ }
181
+
182
+ function resolveProcessTaskNoticeClassName({
183
+ designSystem,
184
+ statusField,
185
+ task,
186
+ }: {
187
+ readonly designSystem: PresentationDesignSystem
188
+ readonly statusField?: FieldPresentationDefinition | null
189
+ readonly task: ProcessTask
190
+ }) {
191
+ const projectedTone = statusField
192
+ ? resolvePresentationFieldValueTone(statusField, task.status)
193
+ : null
194
+ const toneClassName = projectedTone
195
+ ? designSystem.classNames.statusNotice.tone({ tone: projectedTone })
196
+ : getNoticeToneClass(task)
197
+
198
+ return cn('rounded-lg border px-4 py-3 text-sm', toneClassName)
199
+ }
200
+
201
+ function resolveProcessTaskNoticeContent(
202
+ notice: DocumentProcessTaskNoticeDefinition | null | undefined,
203
+ task: ProcessTask,
204
+ ) {
205
+ const content = resolvePresentationContent(notice?.Content, task)
206
+ const title = content.title ?? task.title
207
+ const description = content.description ?? content.subtitle ??
208
+ `${task.statusLabel}. Process ${task.id}.`
209
+
210
+ return {
211
+ description,
212
+ title,
213
+ }
214
+ }
215
+
216
+ function resolveProcessTaskNoticeRenderContexts<TContext>({
217
+ context,
218
+ findActiveTask,
219
+ profile,
220
+ projectSelector,
221
+ region,
222
+ }: Omit<
223
+ ProjectedProcessTaskNoticesProps<TContext>,
224
+ 'className' | 'componentSystem' | 'designSystem' | 'renderNotice'
225
+ >) {
226
+ return getRegionProcessTaskNotices(profile, region).flatMap((notice) => {
227
+ const selectorDefinition = findProcessTaskSelectorDefinition(
228
+ profile,
229
+ notice.ProcessTaskSelectorId,
230
+ )
231
+ const selector = projectSelector(selectorDefinition, context)
232
+ const task = selector ? findActiveTask(selector) : null
233
+
234
+ return task && selector && selectorDefinition
235
+ ? [{
236
+ notice,
237
+ selector,
238
+ selectorDefinition,
239
+ task,
240
+ }]
241
+ : []
242
+ })
243
+ }
244
+
245
+ function getRegionProcessTaskNotices(
246
+ profile: Pick<DocumentProfileProjection, 'ProcessTaskNotices'> | null,
247
+ region?: string,
248
+ ) {
249
+ return profile?.ProcessTaskNotices?.filter((notice) => !region || notice.Region === region) ?? []
250
+ }
251
+
252
+ function findProcessTaskSelectorDefinition(
253
+ profile: Pick<DocumentProfileProjection, 'ProcessTaskSelectors'> | null,
254
+ selectorId: string,
255
+ ) {
256
+ return profile?.ProcessTaskSelectors?.find((selector) => selector.Id === selectorId) ?? null
257
+ }
258
+
259
+ function ProjectedProcessTaskStatusIcon({
260
+ module,
261
+ statusField,
262
+ task,
263
+ }: {
264
+ readonly module: ReturnType<typeof usePresentationModule>
265
+ readonly statusField?: FieldPresentationDefinition | null
266
+ readonly task: ProcessTask
267
+ }) {
268
+ const className = task.lifecycleStatus === 'pending' || task.lifecycleStatus === 'running'
269
+ ? 'mt-0.5 size-4 shrink-0 animate-spin'
270
+ : 'mt-0.5 size-4 shrink-0'
271
+
272
+ if (statusField) {
273
+ return renderProjectedProcessStatusIcon({
274
+ className,
275
+ field: statusField,
276
+ module,
277
+ value: task.status,
278
+ })
279
+ }
280
+
281
+ return renderProcessStatusIcon({
282
+ className,
283
+ module,
284
+ status: task.lifecycleStatus,
285
+ })
286
+ }
287
+
288
+ function resolveProcessTaskNoticeStatusField(
289
+ module: ReturnType<typeof usePresentationModule>,
290
+ notice: DocumentProcessTaskNoticeDefinition | null | undefined,
291
+ ) {
292
+ return notice?.StatusFieldId
293
+ ? findPresentationField<FieldPresentationDefinition>(module, notice.StatusFieldId)
294
+ : null
295
+ }
296
+
297
+ function ProjectedProcessTaskActionButtons({
298
+ componentSystem,
299
+ module,
300
+ notice,
301
+ task,
302
+ }: {
303
+ readonly componentSystem: PresentationComponentSystem
304
+ readonly module: ReturnType<typeof usePresentationModule>
305
+ readonly notice?: DocumentProcessTaskNoticeDefinition | null
306
+ readonly task: ProcessTask
307
+ }) {
308
+ const actions = notice?.Actions ?? []
309
+ if (actions.length > 0) {
310
+ return (
311
+ <>
312
+ {actions.map((action) => (
313
+ <ProjectedProcessTaskActionButton
314
+ action={action}
315
+ componentSystem={componentSystem}
316
+ key={action.Placement.ActionId}
317
+ module={module}
318
+ task={task}
319
+ />
320
+ ))}
321
+ </>
322
+ )
323
+ }
324
+
325
+ return (
326
+ <LegacyProcessTaskActionButton
327
+ componentSystem={componentSystem}
328
+ module={module}
329
+ task={task}
330
+ />
331
+ )
332
+ }
333
+
334
+ function ProjectedProcessTaskActionButton({
335
+ action,
336
+ componentSystem,
337
+ module,
338
+ task,
339
+ }: {
340
+ readonly action: DocumentProcessTaskNoticeActionDefinition
341
+ readonly componentSystem: PresentationComponentSystem
342
+ readonly module: ReturnType<typeof usePresentationModule>
343
+ readonly task: ProcessTask
344
+ }) {
345
+ const { navigateHref } = usePresentationNavigationRuntime()
346
+ const ActionButton = componentSystem.actions.ActionButton
347
+ const href = resolveProcessTaskNoticeActionHref(action, task)
348
+ if (!href) {
349
+ return null
350
+ }
351
+
352
+ const placement = action.Placement
353
+ const actionDefinition = findPresentationAction(module, placement.ActionId)
354
+ const label = placement.Label ?? actionDefinition?.Name ?? placement.ActionId
355
+ const icon = placement.Icon
356
+ ? renderProcessIcon({
357
+ className: 'size-4',
358
+ fallbackIcon: 'chevron-right',
359
+ icon: placement.Icon,
360
+ module,
361
+ })
362
+ : null
363
+ const iconOnly = isIconOnlyActionPlacement(placement)
364
+
365
+ return (
366
+ <ActionButton
367
+ aria-label={iconOnly ? label : undefined}
368
+ onClick={() => navigateHref(href)}
369
+ size={iconOnly ? 'icon-sm' : 'sm'}
370
+ type="button"
371
+ variant={resolveProcessTaskNoticeActionVariant(placement)}
372
+ >
373
+ {icon}
374
+ {iconOnly ? null : label}
375
+ </ActionButton>
376
+ )
377
+ }
378
+
379
+ function LegacyProcessTaskActionButton({
380
+ componentSystem,
381
+ module,
382
+ task,
383
+ }: {
384
+ readonly componentSystem: PresentationComponentSystem
385
+ readonly module: ReturnType<typeof usePresentationModule>
386
+ readonly task: ProcessTask
387
+ }) {
388
+ const { navigateHref } = usePresentationNavigationRuntime()
389
+ const ActionButton = componentSystem.actions.ActionButton
390
+ const targetHref = task.detailsHref ?? task.targetHref ?? task.sourceHref
391
+ if (!targetHref) {
392
+ return null
393
+ }
394
+
395
+ return (
396
+ <ActionButton
397
+ aria-label="Open process details"
398
+ onClick={() => navigateHref(targetHref)}
399
+ size="icon-sm"
400
+ type="button"
401
+ variant="ghost"
402
+ >
403
+ {renderProcessIcon({
404
+ className: 'size-4',
405
+ fallbackIcon: 'chevron-right',
406
+ icon: processIconIds.noticeOpenDetails,
407
+ module,
408
+ })}
409
+ </ActionButton>
410
+ )
411
+ }
412
+
413
+ function resolveProcessTaskNoticeActionHref(
414
+ action: DocumentProcessTaskNoticeActionDefinition,
415
+ task: ProcessTask,
416
+ ) {
417
+ const targetPreference =
418
+ action.TargetPreference.length > 0
419
+ ? action.TargetPreference
420
+ : [
421
+ documentProcessTaskNoticeActionTargetKinds.details,
422
+ documentProcessTaskNoticeActionTargetKinds.target,
423
+ documentProcessTaskNoticeActionTargetKinds.source,
424
+ ]
425
+
426
+ for (const target of targetPreference) {
427
+ const href = readProcessTaskNoticeActionTargetHref(target, task)
428
+ if (href) {
429
+ return href
430
+ }
431
+ }
432
+
433
+ return null
434
+ }
435
+
436
+ function readProcessTaskNoticeActionTargetHref(
437
+ target: DocumentProcessTaskNoticeActionTargetKind,
438
+ task: ProcessTask,
439
+ ) {
440
+ if (matchesNoticeActionTarget(target, documentProcessTaskNoticeActionTargetKinds.details, 'Details')) {
441
+ return task.detailsHref ?? null
442
+ }
443
+
444
+ if (matchesNoticeActionTarget(target, documentProcessTaskNoticeActionTargetKinds.target, 'Target')) {
445
+ return task.targetHref ?? null
446
+ }
447
+
448
+ if (matchesNoticeActionTarget(target, documentProcessTaskNoticeActionTargetKinds.source, 'Source')) {
449
+ return task.sourceHref ?? null
450
+ }
451
+
452
+ return null
453
+ }
454
+
455
+ function matchesNoticeActionTarget(
456
+ value: DocumentProcessTaskNoticeActionTargetKind,
457
+ numericValue: DocumentProcessTaskNoticeActionTargetKind,
458
+ label: string,
459
+ ) {
460
+ return value === numericValue ||
461
+ String(value) === String(numericValue) ||
462
+ value?.toString().toLocaleLowerCase() === label.toLocaleLowerCase()
463
+ }
464
+
465
+ function isIconOnlyActionPlacement(placement: ActionPlacementDefinition) {
466
+ return placement.Intent?.toLocaleLowerCase() === 'icon'
467
+ }
468
+
469
+ function resolveProcessTaskNoticeActionVariant(
470
+ placement: ActionPlacementDefinition,
471
+ ): 'default' | 'ghost' | 'outline' {
472
+ const intent = placement.Intent?.toLocaleLowerCase()
473
+ if (intent === 'primary') {
474
+ return 'default'
475
+ }
476
+
477
+ if (intent === 'ghost' || intent === 'icon') {
478
+ return 'ghost'
479
+ }
480
+
481
+ return 'outline'
482
+ }
483
+
484
+ function getNoticeToneClass(task: ProcessTask) {
485
+ switch (task.lifecycleStatus) {
486
+ case 'success':
487
+ return 'border-teal-300/50 bg-teal-50 text-teal-800'
488
+ case 'error':
489
+ return 'border-red-300/60 bg-red-50 text-red-800'
490
+ case 'waiting':
491
+ case 'paused':
492
+ return 'border-amber-300/50 bg-amber-50 text-amber-900'
493
+ case 'pending':
494
+ case 'running':
495
+ return 'border-sky-300/50 bg-sky-50 text-sky-800'
496
+ }
497
+ }
498
+
499
+ function cn(...values: readonly (false | null | string | undefined)[]) {
500
+ return values.filter(Boolean).join(' ')
501
+ }