@object-ui/app-shell 6.2.3 → 7.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (486) hide show
  1. package/CHANGELOG.md +1229 -0
  2. package/README.md +292 -0
  3. package/dist/assistant/assistantBus.d.ts +72 -0
  4. package/dist/assistant/assistantBus.js +133 -0
  5. package/dist/chrome/CommandPalette.d.ts +1 -1
  6. package/dist/chrome/CommandPalette.js +26 -22
  7. package/dist/chrome/ConditionalAuthWrapper.d.ts +1 -1
  8. package/dist/chrome/ConsoleToaster.d.ts +1 -1
  9. package/dist/chrome/ConsoleToaster.js +3 -1
  10. package/dist/chrome/ErrorBoundary.d.ts +1 -1
  11. package/dist/chrome/KeyboardShortcutsDialog.d.ts +1 -1
  12. package/dist/chrome/KeyboardShortcutsDialog.js +16 -5
  13. package/dist/chrome/LoadingScreen.d.ts +1 -1
  14. package/dist/chrome/LoadingScreen.js +22 -26
  15. package/dist/chrome/RouteFader.d.ts +1 -1
  16. package/dist/chrome/ThemeProvider.d.ts +1 -1
  17. package/dist/components/ManagedByBadge.d.ts +1 -1
  18. package/dist/console/AppContent.d.ts +1 -1
  19. package/dist/console/AppContent.js +184 -39
  20. package/dist/console/ConsoleShell.d.ts +7 -7
  21. package/dist/console/ConsoleShell.js +32 -3
  22. package/dist/console/ai/AiChatPage.d.ts +88 -1
  23. package/dist/console/ai/AiChatPage.js +747 -66
  24. package/dist/console/ai/ConversationsSidebar.d.ts +26 -1
  25. package/dist/console/ai/ConversationsSidebar.js +149 -34
  26. package/dist/console/ai/LiveCanvas.d.ts +28 -0
  27. package/dist/console/ai/LiveCanvas.js +80 -0
  28. package/dist/console/ai/reconcileTurn.d.ts +8 -0
  29. package/dist/console/ai/reconcileTurn.js +20 -0
  30. package/dist/console/auth/AuthPageLayout.d.ts +1 -1
  31. package/dist/console/auth/ForgotPasswordPage.d.ts +1 -1
  32. package/dist/console/auth/LoginPage.d.ts +1 -1
  33. package/dist/console/auth/RegisterPage.d.ts +1 -1
  34. package/dist/console/auth/RegisterPage.js +23 -3
  35. package/dist/console/cloud-connection/CloudConnectionPanel.d.ts +1 -0
  36. package/dist/console/cloud-connection/CloudConnectionPanel.js +169 -0
  37. package/dist/console/home/AppCard.d.ts +1 -1
  38. package/dist/console/home/AppCard.js +6 -12
  39. package/dist/console/home/HomeAppsStrip.d.ts +8 -0
  40. package/dist/console/home/HomeAppsStrip.js +61 -0
  41. package/dist/console/home/HomeLayout.d.ts +1 -1
  42. package/dist/console/home/HomeLayout.js +3 -1
  43. package/dist/console/home/HomePage.d.ts +1 -2
  44. package/dist/console/home/HomePage.js +149 -21
  45. package/dist/console/home/HomeRail.d.ts +22 -0
  46. package/dist/console/home/HomeRail.js +62 -0
  47. package/dist/console/home/QuickActions.d.ts +1 -1
  48. package/dist/console/home/QuickActions.js +3 -11
  49. package/dist/console/home/RecentApps.d.ts +1 -1
  50. package/dist/console/home/RecentApps.js +2 -2
  51. package/dist/console/home/StarredApps.d.ts +1 -1
  52. package/dist/console/home/StarredApps.js +2 -2
  53. package/dist/console/marketplace/InstalledListWidget.d.ts +1 -0
  54. package/dist/console/marketplace/InstalledListWidget.js +93 -0
  55. package/dist/console/marketplace/MarkdownText.d.ts +1 -1
  56. package/dist/console/marketplace/MarketplaceAccessDenied.d.ts +1 -1
  57. package/dist/console/marketplace/MarketplaceInstalledPage.d.ts +8 -14
  58. package/dist/console/marketplace/MarketplaceInstalledPage.js +14 -66
  59. package/dist/console/marketplace/MarketplacePackagePage.d.ts +1 -1
  60. package/dist/console/marketplace/MarketplacePackagePage.js +249 -8
  61. package/dist/console/marketplace/MarketplacePage.d.ts +1 -1
  62. package/dist/console/marketplace/MarketplacePage.js +60 -3
  63. package/dist/console/marketplace/PackageIcon.d.ts +1 -1
  64. package/dist/console/marketplace/PluginDisclosure.d.ts +14 -0
  65. package/dist/console/marketplace/PluginDisclosure.js +38 -0
  66. package/dist/console/marketplace/marketplaceApi.d.ts +123 -0
  67. package/dist/console/marketplace/marketplaceApi.js +254 -1
  68. package/dist/console/organizations/CreateWorkspaceDialog.d.ts +1 -1
  69. package/dist/console/organizations/OrganizationsLayout.d.ts +1 -1
  70. package/dist/console/organizations/OrganizationsPage.d.ts +1 -1
  71. package/dist/console/organizations/manage/AcceptInvitationPage.d.ts +1 -1
  72. package/dist/console/organizations/manage/InvitationsPage.d.ts +1 -1
  73. package/dist/console/organizations/manage/InviteMemberDialog.d.ts +1 -1
  74. package/dist/console/organizations/manage/MembersPage.d.ts +1 -1
  75. package/dist/console/organizations/manage/OrganizationLayout.d.ts +1 -1
  76. package/dist/console/organizations/manage/SettingsPage.d.ts +1 -1
  77. package/dist/context/CommandPaletteProvider.d.ts +44 -0
  78. package/dist/context/CommandPaletteProvider.js +71 -0
  79. package/dist/context/FavoritesProvider.d.ts +1 -1
  80. package/dist/context/NavigationContext.d.ts +1 -1
  81. package/dist/context/RecentItemsProvider.d.ts +2 -2
  82. package/dist/context/UserStateAdapters.d.ts +1 -1
  83. package/dist/context/index.d.ts +2 -0
  84. package/dist/context/index.js +1 -0
  85. package/dist/hooks/index.d.ts +5 -2
  86. package/dist/hooks/index.js +4 -1
  87. package/dist/hooks/useActionModal.d.ts +53 -0
  88. package/dist/hooks/useActionModal.js +111 -0
  89. package/dist/hooks/useChatConversation.d.ts +137 -4
  90. package/dist/hooks/useChatConversation.js +316 -25
  91. package/dist/hooks/useConsoleActionRuntime.d.ts +70 -0
  92. package/dist/hooks/useConsoleActionRuntime.js +564 -0
  93. package/dist/hooks/useConversationList.js +61 -3
  94. package/dist/hooks/useHomeInbox.d.ts +13 -0
  95. package/dist/hooks/useHomeInbox.js +142 -0
  96. package/dist/hooks/useNavPins.js +17 -23
  97. package/dist/hooks/useNavigationSync.d.ts +33 -0
  98. package/dist/hooks/useNavigationSync.js +98 -12
  99. package/dist/hooks/useReconcileOnError.d.ts +40 -0
  100. package/dist/hooks/useReconcileOnError.js +37 -0
  101. package/dist/hooks/useRecordApprovals.d.ts +18 -19
  102. package/dist/hooks/useRecordApprovals.js +24 -40
  103. package/dist/hooks/useResponsiveSidebar.js +14 -5
  104. package/dist/hooks/useSettleSignal.d.ts +19 -0
  105. package/dist/hooks/useSettleSignal.js +20 -0
  106. package/dist/hooks/useTrackRouteAsRecent.js +35 -0
  107. package/dist/hooks/useUrlOverlay.d.ts +62 -0
  108. package/dist/hooks/useUrlOverlay.js +88 -0
  109. package/dist/index.d.ts +18 -8
  110. package/dist/index.js +17 -5
  111. package/dist/layout/ActivityFeed.d.ts +1 -1
  112. package/dist/layout/AppHeader.d.ts +3 -2
  113. package/dist/layout/AppHeader.js +237 -72
  114. package/dist/layout/AppSidebar.d.ts +2 -1
  115. package/dist/layout/AppSidebar.js +26 -46
  116. package/dist/layout/AppSwitcher.d.ts +2 -1
  117. package/dist/layout/AppSwitcher.js +9 -5
  118. package/dist/layout/AuthPageLayout.d.ts +1 -1
  119. package/dist/layout/ConnectionStatus.d.ts +1 -1
  120. package/dist/layout/ConnectionStatus.js +9 -6
  121. package/dist/layout/ConsoleChatbotFab.d.ts +19 -1
  122. package/dist/layout/ConsoleChatbotFab.js +16 -2
  123. package/dist/layout/ConsoleFloatingChatbot.d.ts +34 -2
  124. package/dist/layout/ConsoleFloatingChatbot.js +391 -41
  125. package/dist/layout/ConsoleLayout.d.ts +1 -1
  126. package/dist/layout/ConsoleLayout.js +27 -11
  127. package/dist/layout/ContextSelectors.d.ts +44 -0
  128. package/dist/layout/ContextSelectors.js +242 -0
  129. package/dist/layout/InboxPopover.d.ts +6 -1
  130. package/dist/layout/InboxPopover.js +25 -6
  131. package/dist/layout/LocaleSwitcher.d.ts +1 -1
  132. package/dist/layout/LocalizedSidebarTrigger.d.ts +2 -0
  133. package/dist/layout/LocalizedSidebarTrigger.js +15 -0
  134. package/dist/layout/MobileViewSwitcherContext.d.ts +1 -1
  135. package/dist/layout/ModeToggle.d.ts +1 -1
  136. package/dist/layout/PageHeader.d.ts +1 -1
  137. package/dist/layout/UnifiedSidebar.d.ts +2 -1
  138. package/dist/layout/UnifiedSidebar.js +116 -15
  139. package/dist/layout/agentPicker.d.ts +56 -0
  140. package/dist/layout/agentPicker.js +40 -0
  141. package/dist/observability/index.d.ts +1 -0
  142. package/dist/observability/index.js +1 -0
  143. package/dist/observability/settleSignal.d.ts +64 -0
  144. package/dist/observability/settleSignal.js +131 -0
  145. package/dist/preview/CommitTimeline.d.ts +15 -0
  146. package/dist/preview/CommitTimeline.js +82 -0
  147. package/dist/preview/DraftChangesPanel.d.ts +19 -0
  148. package/dist/preview/DraftChangesPanel.js +114 -0
  149. package/dist/preview/DraftPreviewBar.d.ts +8 -0
  150. package/dist/preview/DraftPreviewBar.js +86 -0
  151. package/dist/preview/PreviewDraftEmptyState.d.ts +16 -0
  152. package/dist/preview/PreviewDraftEmptyState.js +47 -0
  153. package/dist/preview/PreviewModeContext.d.ts +57 -0
  154. package/dist/preview/PreviewModeContext.js +99 -0
  155. package/dist/preview/UnpublishedAppBar.d.ts +8 -0
  156. package/dist/preview/UnpublishedAppBar.js +83 -0
  157. package/dist/preview/commitHistory.d.ts +28 -0
  158. package/dist/preview/commitHistory.js +48 -0
  159. package/dist/preview/draftStatus.d.ts +20 -0
  160. package/dist/preview/draftStatus.js +27 -0
  161. package/dist/preview/usePublishAllDrafts.d.ts +18 -0
  162. package/dist/preview/usePublishAllDrafts.js +106 -0
  163. package/dist/providers/AdapterProvider.d.ts +1 -1
  164. package/dist/providers/AdapterProvider.js +6 -1
  165. package/dist/providers/ExpressionProvider.d.ts +1 -1
  166. package/dist/providers/MetadataProvider.d.ts +17 -2
  167. package/dist/providers/MetadataProvider.js +192 -12
  168. package/dist/runtime-config.d.ts +46 -2
  169. package/dist/runtime-config.js +39 -2
  170. package/dist/services/builtinComponents.js +68 -59
  171. package/dist/skeletons/SkeletonDashboard.d.ts +1 -1
  172. package/dist/skeletons/SkeletonDetail.d.ts +1 -1
  173. package/dist/skeletons/SkeletonGrid.d.ts +1 -1
  174. package/dist/utils/appRoute.d.ts +21 -0
  175. package/dist/utils/appRoute.js +25 -0
  176. package/dist/utils/deriveRelatedLists.d.ts +54 -0
  177. package/dist/utils/deriveRelatedLists.js +91 -0
  178. package/dist/utils/index.d.ts +4 -0
  179. package/dist/utils/index.js +3 -0
  180. package/dist/utils/managedByEmptyState.d.ts +8 -1
  181. package/dist/utils/managedByEmptyState.js +13 -7
  182. package/dist/utils/preferLocal.d.ts +18 -0
  183. package/dist/utils/preferLocal.js +24 -0
  184. package/dist/views/ActionConfirmDialog.d.ts +1 -1
  185. package/dist/views/ActionConfirmDialog.js +3 -1
  186. package/dist/views/ActionParamDialog.d.ts +6 -1
  187. package/dist/views/ActionParamDialog.js +9 -3
  188. package/dist/views/ActionResultDialog.d.ts +13 -0
  189. package/dist/views/ActionResultDialog.js +134 -0
  190. package/dist/views/ComponentNavView.d.ts +14 -1
  191. package/dist/views/CreateViewDialog.d.ts +1 -1
  192. package/dist/views/DashboardConfigPanel.d.ts +28 -0
  193. package/dist/views/DashboardConfigPanel.js +81 -0
  194. package/dist/views/DashboardView.d.ts +4 -3
  195. package/dist/views/DashboardView.js +38 -239
  196. package/dist/views/FlowRunner.d.ts +31 -0
  197. package/dist/views/FlowRunner.js +121 -0
  198. package/dist/views/InterfaceListPage.d.ts +49 -0
  199. package/dist/views/InterfaceListPage.js +347 -0
  200. package/dist/views/MetadataInspector.d.ts +2 -2
  201. package/dist/views/ObjectView.d.ts +1 -1
  202. package/dist/views/ObjectView.js +209 -532
  203. package/dist/views/PageView.d.ts +8 -3
  204. package/dist/views/PageView.js +45 -32
  205. package/dist/views/RecordDetailView.d.ts +1 -1
  206. package/dist/views/RecordDetailView.js +363 -148
  207. package/dist/views/RecordFormPage.d.ts +1 -1
  208. package/dist/views/RecordFormPage.js +26 -1
  209. package/dist/views/ReportConfigPanel.d.ts +37 -0
  210. package/dist/views/ReportConfigPanel.js +85 -0
  211. package/dist/views/ReportView.d.ts +1 -1
  212. package/dist/views/ReportView.js +116 -7
  213. package/dist/views/RuntimeDraftBar.d.ts +30 -0
  214. package/dist/views/RuntimeDraftBar.js +112 -0
  215. package/dist/views/ScreenView.d.ts +70 -0
  216. package/dist/views/ScreenView.js +73 -0
  217. package/dist/views/SearchResultsPage.d.ts +1 -1
  218. package/dist/views/SearchResultsPage.js +8 -18
  219. package/dist/views/ViewConfigPanel.d.ts +24 -17
  220. package/dist/views/ViewConfigPanel.js +121 -77
  221. package/dist/views/index.d.ts +1 -1
  222. package/dist/views/index.js +1 -1
  223. package/dist/views/metadata-admin/AuditPanel.d.ts +28 -0
  224. package/dist/views/metadata-admin/AuditPanel.js +79 -0
  225. package/dist/views/metadata-admin/DiagnosticsPage.d.ts +20 -0
  226. package/dist/views/metadata-admin/DiagnosticsPage.js +69 -0
  227. package/dist/views/metadata-admin/DirectoryPage.d.ts +16 -1
  228. package/dist/views/metadata-admin/DirectoryPage.js +101 -24
  229. package/dist/views/metadata-admin/DraftReviewPanel.d.ts +33 -0
  230. package/dist/views/metadata-admin/DraftReviewPanel.js +77 -0
  231. package/dist/views/metadata-admin/EmbeddedItemEditor.d.ts +17 -1
  232. package/dist/views/metadata-admin/EmbeddedItemEditor.js +15 -8
  233. package/dist/views/metadata-admin/JsonSourceEditor.d.ts +39 -0
  234. package/dist/views/metadata-admin/JsonSourceEditor.js +196 -0
  235. package/dist/views/metadata-admin/LayeredDiff.d.ts +39 -1
  236. package/dist/views/metadata-admin/LayeredDiff.js +171 -5
  237. package/dist/views/metadata-admin/MetadataDetailDrawer.d.ts +15 -1
  238. package/dist/views/metadata-admin/MetadataTypeActions.d.ts +48 -0
  239. package/dist/views/metadata-admin/MetadataTypeActions.js +165 -0
  240. package/dist/views/metadata-admin/PackagesPage.d.ts +18 -0
  241. package/dist/views/metadata-admin/PackagesPage.js +403 -0
  242. package/dist/views/metadata-admin/PageShell.d.ts +1 -1
  243. package/dist/views/metadata-admin/PageShell.js +9 -4
  244. package/dist/views/metadata-admin/PermissionMatrixEditor.d.ts +35 -1
  245. package/dist/views/metadata-admin/QuickFind.d.ts +21 -1
  246. package/dist/views/metadata-admin/QuickFind.js +6 -3
  247. package/dist/views/metadata-admin/RelatedPanel.d.ts +24 -1
  248. package/dist/views/metadata-admin/RelatedPanel.js +20 -18
  249. package/dist/views/metadata-admin/ResourceEditPage.d.ts +40 -1
  250. package/dist/views/metadata-admin/ResourceEditPage.js +1250 -60
  251. package/dist/views/metadata-admin/ResourceHistoryPage.d.ts +39 -1
  252. package/dist/views/metadata-admin/ResourceHistoryPage.js +66 -16
  253. package/dist/views/metadata-admin/ResourceListPage.d.ts +13 -1
  254. package/dist/views/metadata-admin/ResourceListPage.js +258 -30
  255. package/dist/views/metadata-admin/ResourceRouter.d.ts +23 -1
  256. package/dist/views/metadata-admin/SchemaForm.d.ts +34 -1
  257. package/dist/views/metadata-admin/SchemaForm.js +559 -49
  258. package/dist/views/metadata-admin/StudioHomePage.d.ts +22 -0
  259. package/dist/views/metadata-admin/StudioHomePage.js +205 -0
  260. package/dist/views/metadata-admin/anchors.js +255 -24
  261. package/dist/views/metadata-admin/clientValidation.d.ts +50 -0
  262. package/dist/views/metadata-admin/clientValidation.js +169 -0
  263. package/dist/views/metadata-admin/color-variant-field.d.ts +30 -0
  264. package/dist/views/metadata-admin/color-variant-field.js +38 -0
  265. package/dist/views/metadata-admin/createDerive.d.ts +75 -0
  266. package/dist/views/metadata-admin/createDerive.js +179 -0
  267. package/dist/views/metadata-admin/dashboard-schema.d.ts +12 -0
  268. package/dist/views/metadata-admin/dashboard-schema.js +80 -0
  269. package/dist/views/metadata-admin/datasource/DatasourceResourcePage.d.ts +35 -0
  270. package/dist/views/metadata-admin/datasource/DatasourceResourcePage.js +327 -0
  271. package/dist/views/metadata-admin/datasource/register.d.ts +1 -0
  272. package/dist/views/metadata-admin/datasource/register.js +24 -0
  273. package/dist/views/metadata-admin/default-inspector-registry.d.ts +49 -0
  274. package/dist/views/metadata-admin/default-inspector-registry.js +8 -0
  275. package/dist/views/metadata-admin/default-schemas.js +115 -10
  276. package/dist/views/metadata-admin/external/ExternalDatasourcePanel.d.ts +27 -0
  277. package/dist/views/metadata-admin/external/ExternalDatasourcePanel.js +69 -0
  278. package/dist/views/metadata-admin/external/ImportObjectDialog.d.ts +27 -0
  279. package/dist/views/metadata-admin/external/ImportObjectDialog.js +77 -0
  280. package/dist/views/metadata-admin/external/SchemaBrowser.d.ts +16 -0
  281. package/dist/views/metadata-admin/external/SchemaBrowser.js +74 -0
  282. package/dist/views/metadata-admin/external/ValidationPanel.d.ts +16 -0
  283. package/dist/views/metadata-admin/external/ValidationPanel.js +68 -0
  284. package/dist/views/metadata-admin/external/api.d.ts +100 -0
  285. package/dist/views/metadata-admin/external/api.js +124 -0
  286. package/dist/views/metadata-admin/i18n.d.ts +1 -0
  287. package/dist/views/metadata-admin/i18n.js +1252 -2
  288. package/dist/views/metadata-admin/index.d.ts +8 -5
  289. package/dist/views/metadata-admin/index.js +12 -2
  290. package/dist/views/metadata-admin/inspector-registry.d.ts +51 -0
  291. package/dist/views/metadata-admin/inspector-registry.js +11 -0
  292. package/dist/views/metadata-admin/inspectors/ActionDefaultInspector.d.ts +30 -0
  293. package/dist/views/metadata-admin/inspectors/ActionDefaultInspector.js +180 -0
  294. package/dist/views/metadata-admin/inspectors/AppNavInspector.d.ts +16 -0
  295. package/dist/views/metadata-admin/inspectors/AppNavInspector.js +110 -0
  296. package/dist/views/metadata-admin/inspectors/ConditionBuilder.d.ts +29 -0
  297. package/dist/views/metadata-admin/inspectors/ConditionBuilder.js +154 -0
  298. package/dist/views/metadata-admin/inspectors/DashboardDefaultInspector.d.ts +28 -0
  299. package/dist/views/metadata-admin/inspectors/DashboardDefaultInspector.js +110 -0
  300. package/dist/views/metadata-admin/inspectors/DashboardWidgetInspector.d.ts +18 -0
  301. package/dist/views/metadata-admin/inspectors/DashboardWidgetInspector.js +139 -0
  302. package/dist/views/metadata-admin/inspectors/DatasetDefaultInspector.d.ts +21 -0
  303. package/dist/views/metadata-admin/inspectors/DatasetDefaultInspector.js +221 -0
  304. package/dist/views/metadata-admin/inspectors/FlowEdgeInspector.d.ts +16 -0
  305. package/dist/views/metadata-admin/inspectors/FlowEdgeInspector.js +126 -0
  306. package/dist/views/metadata-admin/inspectors/FlowInspector.d.ts +12 -0
  307. package/dist/views/metadata-admin/inspectors/FlowInspector.js +9 -0
  308. package/dist/views/metadata-admin/inspectors/FlowKeyValueField.d.ts +30 -0
  309. package/dist/views/metadata-admin/inspectors/FlowKeyValueField.js +125 -0
  310. package/dist/views/metadata-admin/inspectors/FlowNodeConfigField.d.ts +18 -0
  311. package/dist/views/metadata-admin/inspectors/FlowNodeConfigField.js +40 -0
  312. package/dist/views/metadata-admin/inspectors/FlowNodeInspector.d.ts +14 -0
  313. package/dist/views/metadata-admin/inspectors/FlowNodeInspector.js +205 -0
  314. package/dist/views/metadata-admin/inspectors/FlowObjectListField.d.ts +26 -0
  315. package/dist/views/metadata-admin/inspectors/FlowObjectListField.js +105 -0
  316. package/dist/views/metadata-admin/inspectors/FlowReferenceField.d.ts +83 -0
  317. package/dist/views/metadata-admin/inspectors/FlowReferenceField.js +181 -0
  318. package/dist/views/metadata-admin/inspectors/FlowStringListField.d.ts +21 -0
  319. package/dist/views/metadata-admin/inspectors/FlowStringListField.js +60 -0
  320. package/dist/views/metadata-admin/inspectors/InspectorComboField.d.ts +40 -0
  321. package/dist/views/metadata-admin/inspectors/InspectorComboField.js +61 -0
  322. package/dist/views/metadata-admin/inspectors/ObjectDefaultInspector.d.ts +21 -0
  323. package/dist/views/metadata-admin/inspectors/ObjectDefaultInspector.js +55 -0
  324. package/dist/views/metadata-admin/inspectors/ObjectFieldInspector.d.ts +23 -0
  325. package/dist/views/metadata-admin/inspectors/ObjectFieldInspector.js +365 -0
  326. package/dist/views/metadata-admin/inspectors/PageBlockInspector.d.ts +48 -0
  327. package/dist/views/metadata-admin/inspectors/PageBlockInspector.js +332 -0
  328. package/dist/views/metadata-admin/inspectors/ReportDefaultInspector.d.ts +58 -0
  329. package/dist/views/metadata-admin/inspectors/ReportDefaultInspector.js +218 -0
  330. package/dist/views/metadata-admin/inspectors/ViewColumnInspector.d.ts +19 -0
  331. package/dist/views/metadata-admin/inspectors/ViewColumnInspector.js +144 -0
  332. package/dist/views/metadata-admin/inspectors/ViewInspector.d.ts +19 -0
  333. package/dist/views/metadata-admin/inspectors/ViewInspector.js +21 -0
  334. package/dist/views/metadata-admin/inspectors/ViewVariantInspector.d.ts +54 -0
  335. package/dist/views/metadata-admin/inspectors/ViewVariantInspector.js +191 -0
  336. package/dist/views/metadata-admin/inspectors/_shared.d.ts +128 -0
  337. package/dist/views/metadata-admin/inspectors/_shared.js +113 -0
  338. package/dist/views/metadata-admin/inspectors/datasetFilterCondition.d.ts +24 -0
  339. package/dist/views/metadata-admin/inspectors/datasetFilterCondition.js +97 -0
  340. package/dist/views/metadata-admin/inspectors/expression-validate.d.ts +26 -0
  341. package/dist/views/metadata-admin/inspectors/expression-validate.js +66 -0
  342. package/dist/views/metadata-admin/inspectors/flow-node-config.d.ts +143 -0
  343. package/dist/views/metadata-admin/inspectors/flow-node-config.js +506 -0
  344. package/dist/views/metadata-admin/inspectors/index.d.ts +1 -0
  345. package/dist/views/metadata-admin/inspectors/index.js +45 -0
  346. package/dist/views/metadata-admin/inspectors/json-schema-to-fields.d.ts +40 -0
  347. package/dist/views/metadata-admin/inspectors/json-schema-to-fields.js +227 -0
  348. package/dist/views/metadata-admin/inspectors/useDatasetFields.d.ts +72 -0
  349. package/dist/views/metadata-admin/inspectors/useDatasetFields.js +0 -0
  350. package/dist/views/metadata-admin/issuePath.d.ts +22 -0
  351. package/dist/views/metadata-admin/issuePath.js +65 -0
  352. package/dist/views/metadata-admin/mergeServerFields.d.ts +65 -0
  353. package/dist/views/metadata-admin/mergeServerFields.js +56 -0
  354. package/dist/views/metadata-admin/package-scope.d.ts +26 -0
  355. package/dist/views/metadata-admin/package-scope.js +43 -0
  356. package/dist/views/metadata-admin/preview-registry.d.ts +55 -0
  357. package/dist/views/metadata-admin/previews/ActionPreview.d.ts +25 -0
  358. package/dist/views/metadata-admin/previews/ActionPreview.js +238 -0
  359. package/dist/views/metadata-admin/previews/AddWidgetPicker.d.ts +12 -0
  360. package/dist/views/metadata-admin/previews/AddWidgetPicker.js +56 -0
  361. package/dist/views/metadata-admin/previews/AgentPreview.d.ts +24 -0
  362. package/dist/views/metadata-admin/previews/AgentPreview.js +100 -0
  363. package/dist/views/metadata-admin/previews/AppNavCanvas.d.ts +31 -0
  364. package/dist/views/metadata-admin/previews/AppNavCanvas.js +260 -0
  365. package/dist/views/metadata-admin/previews/AppPreview.d.ts +16 -1
  366. package/dist/views/metadata-admin/previews/AppPreview.js +23 -14
  367. package/dist/views/metadata-admin/previews/BookPreview.d.ts +20 -0
  368. package/dist/views/metadata-admin/previews/BookPreview.js +132 -0
  369. package/dist/views/metadata-admin/previews/DashboardPreview.d.ts +16 -1
  370. package/dist/views/metadata-admin/previews/DashboardPreview.js +110 -8
  371. package/dist/views/metadata-admin/previews/DatasetPreview.d.ts +18 -0
  372. package/dist/views/metadata-admin/previews/DatasetPreview.js +105 -0
  373. package/dist/views/metadata-admin/previews/DatasourcePreview.d.ts +23 -0
  374. package/dist/views/metadata-admin/previews/DatasourcePreview.js +68 -0
  375. package/dist/views/metadata-admin/previews/EmailTemplatePreview.d.ts +14 -1
  376. package/dist/views/metadata-admin/previews/FieldStub.d.ts +30 -0
  377. package/dist/views/metadata-admin/previews/FieldStub.js +104 -0
  378. package/dist/views/metadata-admin/previews/FieldsListEditor.d.ts +50 -0
  379. package/dist/views/metadata-admin/previews/FieldsListEditor.js +97 -0
  380. package/dist/views/metadata-admin/previews/FlowCanvas.d.ts +49 -0
  381. package/dist/views/metadata-admin/previews/FlowCanvas.js +416 -0
  382. package/dist/views/metadata-admin/previews/FlowPreview.d.ts +20 -0
  383. package/dist/views/metadata-admin/previews/FlowPreview.js +120 -0
  384. package/dist/views/metadata-admin/previews/FlowRunsPanel.d.ts +46 -0
  385. package/dist/views/metadata-admin/previews/FlowRunsPanel.js +97 -0
  386. package/dist/views/metadata-admin/previews/FlowSimulatorPanel.d.ts +25 -0
  387. package/dist/views/metadata-admin/previews/FlowSimulatorPanel.js +204 -0
  388. package/dist/views/metadata-admin/previews/JobPreview.d.ts +28 -0
  389. package/dist/views/metadata-admin/previews/JobPreview.js +290 -0
  390. package/dist/views/metadata-admin/previews/ObjectFormCanvas.d.ts +30 -0
  391. package/dist/views/metadata-admin/previews/ObjectFormCanvas.js +547 -0
  392. package/dist/views/metadata-admin/previews/ObjectPreview.d.ts +14 -1
  393. package/dist/views/metadata-admin/previews/ObjectPreview.js +5 -30
  394. package/dist/views/metadata-admin/previews/OutlineStrip.d.ts +32 -0
  395. package/dist/views/metadata-admin/previews/OutlineStrip.js +8 -0
  396. package/dist/views/metadata-admin/previews/PageBlockCanvas.d.ts +49 -0
  397. package/dist/views/metadata-admin/previews/PageBlockCanvas.js +510 -0
  398. package/dist/views/metadata-admin/previews/PagePreview.d.ts +10 -1
  399. package/dist/views/metadata-admin/previews/PagePreview.js +200 -5
  400. package/dist/views/metadata-admin/previews/PermissionPreview.d.ts +27 -0
  401. package/dist/views/metadata-admin/previews/PermissionPreview.js +115 -0
  402. package/dist/views/metadata-admin/previews/PreviewShell.d.ts +29 -6
  403. package/dist/views/metadata-admin/previews/PreviewShell.js +16 -3
  404. package/dist/views/metadata-admin/previews/ReportPreview.d.ts +18 -1
  405. package/dist/views/metadata-admin/previews/ReportPreview.js +23 -15
  406. package/dist/views/metadata-admin/previews/RolePreview.d.ts +19 -0
  407. package/dist/views/metadata-admin/previews/RolePreview.js +14 -0
  408. package/dist/views/metadata-admin/previews/ScreenPreview.d.ts +38 -0
  409. package/dist/views/metadata-admin/previews/ScreenPreview.js +61 -0
  410. package/dist/views/metadata-admin/previews/SkillPreview.d.ts +22 -0
  411. package/dist/views/metadata-admin/previews/SkillPreview.js +34 -0
  412. package/dist/views/metadata-admin/previews/ToolPreview.d.ts +25 -0
  413. package/dist/views/metadata-admin/previews/ToolPreview.js +122 -0
  414. package/dist/views/metadata-admin/previews/TranslationPreview.d.ts +25 -0
  415. package/dist/views/metadata-admin/previews/TranslationPreview.js +52 -0
  416. package/dist/views/metadata-admin/previews/ValidationPreview.d.ts +27 -0
  417. package/dist/views/metadata-admin/previews/ValidationPreview.js +110 -0
  418. package/dist/views/metadata-admin/previews/ViewColumnPanes.d.ts +62 -0
  419. package/dist/views/metadata-admin/previews/ViewColumnPanes.js +140 -0
  420. package/dist/views/metadata-admin/previews/ViewPreview.d.ts +23 -1
  421. package/dist/views/metadata-admin/previews/ViewPreview.js +101 -73
  422. package/dist/views/metadata-admin/previews/block-config.d.ts +82 -0
  423. package/dist/views/metadata-admin/previews/block-config.js +324 -0
  424. package/dist/views/metadata-admin/previews/block-types.d.ts +40 -0
  425. package/dist/views/metadata-admin/previews/block-types.js +110 -0
  426. package/dist/views/metadata-admin/previews/field-types.d.ts +53 -0
  427. package/dist/views/metadata-admin/previews/field-types.js +97 -0
  428. package/dist/views/metadata-admin/previews/flow-canvas-layout.d.ts +102 -0
  429. package/dist/views/metadata-admin/previews/flow-canvas-layout.js +227 -0
  430. package/dist/views/metadata-admin/previews/flow-canvas-parts.d.ts +96 -0
  431. package/dist/views/metadata-admin/previews/flow-canvas-parts.js +373 -0
  432. package/dist/views/metadata-admin/previews/form-preview.d.ts +24 -0
  433. package/dist/views/metadata-admin/previews/form-preview.js +29 -0
  434. package/dist/views/metadata-admin/previews/index.js +43 -0
  435. package/dist/views/metadata-admin/previews/object-fields-bridge.d.ts +66 -0
  436. package/dist/views/metadata-admin/previews/object-fields-bridge.js +171 -0
  437. package/dist/views/metadata-admin/previews/object-fields-io.d.ts +130 -0
  438. package/dist/views/metadata-admin/previews/object-fields-io.js +243 -0
  439. package/dist/views/metadata-admin/previews/screen-spec.d.ts +43 -0
  440. package/dist/views/metadata-admin/previews/screen-spec.js +108 -0
  441. package/dist/views/metadata-admin/previews/simulator/flow-sim-types.d.ts +102 -0
  442. package/dist/views/metadata-admin/previews/simulator/flow-sim-types.js +2 -0
  443. package/dist/views/metadata-admin/previews/simulator/flow-sim-validate.d.ts +15 -0
  444. package/dist/views/metadata-admin/previews/simulator/flow-sim-validate.js +185 -0
  445. package/dist/views/metadata-admin/previews/simulator/flow-simulator.d.ts +73 -0
  446. package/dist/views/metadata-admin/previews/simulator/flow-simulator.js +426 -0
  447. package/dist/views/metadata-admin/previews/useDatasetCatalog.d.ts +47 -0
  448. package/dist/views/metadata-admin/previews/useDatasetCatalog.js +133 -0
  449. package/dist/views/metadata-admin/previews/useFlowNodePalette.d.ts +44 -0
  450. package/dist/views/metadata-admin/previews/useFlowNodePalette.js +124 -0
  451. package/dist/views/metadata-admin/previews/useMetaOptions.d.ts +8 -0
  452. package/dist/views/metadata-admin/previews/useMetaOptions.js +50 -0
  453. package/dist/views/metadata-admin/previews/useObjectFields.d.ts +23 -0
  454. package/dist/views/metadata-admin/previews/useObjectFields.js +79 -0
  455. package/dist/views/metadata-admin/previews/useObjectOptions.d.ts +8 -0
  456. package/dist/views/metadata-admin/previews/useObjectOptions.js +43 -0
  457. package/dist/views/metadata-admin/previews/view-column-io.d.ts +42 -0
  458. package/dist/views/metadata-admin/previews/view-column-io.js +73 -0
  459. package/dist/views/metadata-admin/previews/widget-types.d.ts +24 -0
  460. package/dist/views/metadata-admin/previews/widget-types.js +40 -0
  461. package/dist/views/metadata-admin/registry.d.ts +140 -19
  462. package/dist/views/metadata-admin/report-schema.d.ts +26 -0
  463. package/dist/views/metadata-admin/report-schema.js +121 -0
  464. package/dist/views/metadata-admin/useMetadata.d.ts +100 -2
  465. package/dist/views/metadata-admin/useMetadata.js +155 -4
  466. package/dist/views/metadata-admin/view-item-normalize.d.ts +20 -0
  467. package/dist/views/metadata-admin/view-item-normalize.js +68 -0
  468. package/dist/views/metadata-admin/view-schema.d.ts +16 -0
  469. package/dist/views/metadata-admin/view-schema.js +107 -0
  470. package/dist/views/metadata-admin/view-variant-model.d.ts +23 -0
  471. package/dist/views/metadata-admin/view-variant-model.js +64 -0
  472. package/dist/views/metadata-admin/widgets.d.ts +89 -1
  473. package/dist/views/metadata-admin/widgets.js +491 -17
  474. package/dist/views/runtime-metadata-persistence.d.ts +78 -0
  475. package/dist/views/runtime-metadata-persistence.js +89 -0
  476. package/dist/views/useOpenRecordList.d.ts +18 -0
  477. package/dist/views/useOpenRecordList.js +36 -0
  478. package/dist/views/userFilterUrlState.d.ts +15 -0
  479. package/dist/views/userFilterUrlState.js +53 -0
  480. package/dist/views/view-config-adapter.d.ts +38 -0
  481. package/dist/views/view-config-adapter.js +80 -0
  482. package/package.json +52 -34
  483. package/dist/views/DesignDrawer.d.ts +0 -28
  484. package/dist/views/DesignDrawer.js +0 -51
  485. package/dist/views/metadata-admin/DesignerEditorWrapper.d.ts +0 -68
  486. package/dist/views/metadata-admin/DesignerEditorWrapper.js +0 -158
@@ -0,0 +1,97 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
3
+ /**
4
+ * FieldsListEditor — the right-panel column manager (mainstream low-code
5
+ * pattern: a vertical, drag-reorderable list of fields with an inline
6
+ * "+ Add field" picker).
7
+ *
8
+ * This is the SINGLE owner of column read / write / reorder / remove / select
9
+ * logic for a View variant. It is rendered in two places so the fields list is
10
+ * always visible:
11
+ * • {@link ViewVariantInspector} (the home / variant panel) — no row is
12
+ * highlighted; clicking a row drills into the scoped column inspector.
13
+ * • {@link ViewColumnInspector} (the scoped column panel) — the selected row
14
+ * is highlighted and the column's detail props render below it.
15
+ *
16
+ * Columns round-trip in their original shape: string variants (e.g. kanban
17
+ * card fields) stay strings; object variants keep `{ field, label, … }`. The
18
+ * raw `columns` array is reordered / spliced directly — never normalised — so
19
+ * round-trips stay lossless.
20
+ */
21
+ import * as React from 'react';
22
+ import { Badge, Label } from '@object-ui/components';
23
+ import { appendArray, moveArray, spliceArray } from '../inspectors/_shared';
24
+ import { useObjectFields } from './useObjectFields';
25
+ import { AddFieldPopover, FieldListRow } from './ViewColumnPanes';
26
+ import { colFieldName, colLabel, makeColumn, remapIndexAfterMove, remapIndexAfterRemove, usedFieldNames, } from './view-column-io';
27
+ export function FieldsListEditor({ variantKey, schema, columns, allStrings, objectName, objectFieldsOverride, selectedIndex, readOnly, onPatch, onSelectionChange, }) {
28
+ const canEdit = !readOnly;
29
+ const { fields, loading, error } = useObjectFields(objectName || undefined, objectFieldsOverride);
30
+ const fieldTypeByName = React.useMemo(() => {
31
+ const m = new Map();
32
+ for (const f of fields)
33
+ m.set(f.name, f.type);
34
+ return m;
35
+ }, [fields]);
36
+ const [dragIndex, setDragIndex] = React.useState(null);
37
+ const [overIndex, setOverIndex] = React.useState(null);
38
+ const writeColumns = React.useCallback((next) => {
39
+ onPatch({ [variantKey]: { ...schema, columns: next } });
40
+ }, [onPatch, variantKey, schema]);
41
+ const addField = React.useCallback((field) => {
42
+ const col = makeColumn(allStrings, field.name, field.label);
43
+ const next = appendArray(columns, col);
44
+ writeColumns(next);
45
+ onSelectionChange?.({
46
+ kind: 'column',
47
+ id: `${variantKey}.columns[${next.length - 1}]`,
48
+ label: field.label,
49
+ });
50
+ }, [allStrings, columns, writeColumns, variantKey, onSelectionChange]);
51
+ const removeColumn = React.useCallback((index) => {
52
+ const next = spliceArray(columns, index, null);
53
+ writeColumns(next);
54
+ if (selectedIndex != null) {
55
+ const remapped = remapIndexAfterRemove(selectedIndex, index);
56
+ if (remapped == null)
57
+ onSelectionChange?.(null);
58
+ else
59
+ onSelectionChange?.({
60
+ kind: 'column',
61
+ id: `${variantKey}.columns[${remapped}]`,
62
+ label: colLabel(next[remapped], remapped),
63
+ });
64
+ }
65
+ }, [columns, writeColumns, selectedIndex, variantKey, onSelectionChange]);
66
+ const moveColumn = React.useCallback((from, to) => {
67
+ if (from === to)
68
+ return;
69
+ const next = moveArray(columns, from, to);
70
+ writeColumns(next);
71
+ if (selectedIndex != null) {
72
+ const remapped = remapIndexAfterMove(selectedIndex, from, to);
73
+ onSelectionChange?.({
74
+ kind: 'column',
75
+ id: `${variantKey}.columns[${remapped}]`,
76
+ label: colLabel(next[remapped], remapped),
77
+ });
78
+ }
79
+ }, [columns, writeColumns, selectedIndex, variantKey, onSelectionChange]);
80
+ const selectColumn = React.useCallback((index) => {
81
+ onSelectionChange?.({
82
+ kind: 'column',
83
+ id: `${variantKey}.columns[${index}]`,
84
+ label: colLabel(columns[index], index),
85
+ });
86
+ }, [columns, variantKey, onSelectionChange]);
87
+ const usedNames = usedFieldNames(columns);
88
+ return (_jsxs("div", { className: "space-y-1.5", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx(Label, { className: "text-xs text-muted-foreground", children: "Columns" }), _jsx(Badge, { variant: "outline", className: "text-[10px]", children: columns.length })] }), columns.length === 0 ? (_jsx("p", { className: "rounded-md border border-dashed bg-muted/30 px-3 py-3 text-center text-[11px] text-muted-foreground", children: "No columns yet. Add a field below." })) : (_jsx("div", { className: "space-y-1", children: columns.map((c, i) => (_jsx(FieldListRow, { index: i, label: colLabel(c, i), fieldName: colFieldName(c), fieldType: fieldTypeByName.get(colFieldName(c) ?? '') ?? 'text', selected: selectedIndex === i, canEdit: canEdit, dragging: dragIndex !== null, dropBefore: overIndex === i && dragIndex !== null && dragIndex !== i, onSelect: () => selectColumn(i), onRemove: () => removeColumn(i), onDragStart: () => setDragIndex(i), onDragEnd: () => {
89
+ setDragIndex(null);
90
+ setOverIndex(null);
91
+ }, onDragOverRow: () => setOverIndex(i), onDropRow: () => {
92
+ if (dragIndex != null && dragIndex !== i)
93
+ moveColumn(dragIndex, i);
94
+ setDragIndex(null);
95
+ setOverIndex(null);
96
+ } }, i))) })), canEdit && (_jsx(AddFieldPopover, { fields: fields, usedNames: usedNames, loading: loading, error: error, onAdd: addField }))] }));
97
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * FlowCanvas — an industry-standard visual flowchart designer for flow
3
+ * automation metadata (mirrors Power Automate / Salesforce Flow Builder).
4
+ *
5
+ * Dependency-free: no reactflow/@xyflow. Nodes are absolutely-positioned
6
+ * Shadcn cards over an SVG edge layer, laid out top-to-bottom by a
7
+ * deterministic layered algorithm (`flow-canvas-layout`). Authors can:
8
+ *
9
+ * - drag to reposition nodes (committed to `node.ui = {x,y}` on drop),
10
+ * - add nodes from a palette (toolbar or a node's bottom "+" handle),
11
+ * - insert a node on an edge ("+" at the edge midpoint splits A→B),
12
+ * - delete the selected node (Delete/Backspace) with full edge cleanup,
13
+ * - pan (background drag) and zoom / fit-to-view.
14
+ *
15
+ * Selection is delegated to the existing FlowNodeInspector via
16
+ * onSelectionChange — the canvas never duplicates the inspector.
17
+ *
18
+ * The component is a pure renderer of `draft`; all mutations go through
19
+ * `onPatch(partial)` and the host merges + persists.
20
+ */
21
+ import * as React from 'react';
22
+ import { type FlowNode, type FlowEdge } from './flow-canvas-layout';
23
+ export interface FlowCanvasProps {
24
+ nodes: FlowNode[];
25
+ edges: FlowEdge[];
26
+ editable: boolean;
27
+ designMode: boolean;
28
+ selectedId: string | null;
29
+ /** Stable key (see `edgeKey`) of the currently-selected edge, or null. */
30
+ selectedEdgeId?: string | null;
31
+ locale?: string;
32
+ /** Simulation overlay: currently-executing node. */
33
+ activeNodeId?: string | null;
34
+ /** Simulation overlay: nodes already executed. */
35
+ visitedNodeIds?: string[];
36
+ /** Simulation overlay: ids of edges that were traversed. */
37
+ traversedEdgeIds?: string[];
38
+ /** Structural-validation: node ids to paint with a red error ring. */
39
+ invalidNodeIds?: string[];
40
+ /** Structural-validation: edges (keyed `${source}->${target}`) to paint red. */
41
+ invalidEdges?: ReadonlySet<string>;
42
+ /** Structural-validation error messages shown in an inline canvas banner. */
43
+ validationErrors?: string[];
44
+ onSelect: (node: FlowNode | null) => void;
45
+ /** Select an edge (its `edgeKey`), or clear selection with `null`. */
46
+ onSelectEdge?: (edge: FlowEdge | null, key: string) => void;
47
+ onPatch?: (partial: Record<string, unknown>) => void;
48
+ }
49
+ export declare function FlowCanvas({ nodes, edges, editable, designMode, selectedId, selectedEdgeId, locale, activeNodeId, visitedNodeIds, traversedEdgeIds, invalidNodeIds, invalidEdges, validationErrors, onSelect, onSelectEdge, onPatch, }: FlowCanvasProps): React.JSX.Element;
@@ -0,0 +1,416 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
3
+ /**
4
+ * FlowCanvas — an industry-standard visual flowchart designer for flow
5
+ * automation metadata (mirrors Power Automate / Salesforce Flow Builder).
6
+ *
7
+ * Dependency-free: no reactflow/@xyflow. Nodes are absolutely-positioned
8
+ * Shadcn cards over an SVG edge layer, laid out top-to-bottom by a
9
+ * deterministic layered algorithm (`flow-canvas-layout`). Authors can:
10
+ *
11
+ * - drag to reposition nodes (committed to `node.ui = {x,y}` on drop),
12
+ * - add nodes from a palette (toolbar or a node's bottom "+" handle),
13
+ * - insert a node on an edge ("+" at the edge midpoint splits A→B),
14
+ * - delete the selected node (Delete/Backspace) with full edge cleanup,
15
+ * - pan (background drag) and zoom / fit-to-view.
16
+ *
17
+ * Selection is delegated to the existing FlowNodeInspector via
18
+ * onSelectionChange — the canvas never duplicates the inspector.
19
+ *
20
+ * The component is a pure renderer of `draft`; all mutations go through
21
+ * `onPatch(partial)` and the host merges + persists.
22
+ */
23
+ import * as React from 'react';
24
+ import { AlertTriangle, Maximize2, Plus, ZoomIn, ZoomOut } from 'lucide-react';
25
+ import { cn } from '@object-ui/components';
26
+ import { uniqueId, appendArray, spliceArray } from '../inspectors/_shared';
27
+ import { t as tr } from '../i18n';
28
+ import { computeLayout, diagramSize, bottomAnchor, topAnchor, rightAnchor, edgePath, edgeMidpoint, backEdgePath, backEdgeLabelAnchor, isBackEdge, edgeKey, conditionText, } from './flow-canvas-layout';
29
+ import { NodeCard, NodePalette, defaultNodeLabel, defaultNodeExtras } from './flow-canvas-parts';
30
+ import { useFlowNodePalette } from './useFlowNodePalette';
31
+ const MIN_ZOOM = 0.4;
32
+ const MAX_ZOOM = 1.6;
33
+ const DRAG_THRESHOLD = 4;
34
+ export function FlowCanvas({ nodes, edges, editable, designMode, selectedId, selectedEdgeId, locale, activeNodeId, visitedNodeIds, traversedEdgeIds, invalidNodeIds, invalidEdges, validationErrors, onSelect, onSelectEdge, onPatch, }) {
35
+ const viewportRef = React.useRef(null);
36
+ const [zoom, setZoom] = React.useState(1);
37
+ const [pan, setPan] = React.useState({ x: 0, y: 0 });
38
+ const [paletteOpen, setPaletteOpen] = React.useState(false);
39
+ // Node types offered by the add-node palette, driven by the engine's
40
+ // published descriptors (`GET /api/v1/automation/actions`) merged with the
41
+ // hardcoded base — so the palette reflects what the backend actually supports
42
+ // (e.g. the `approval` node, third-party connector actions).
43
+ const paletteItems = useFlowNodePalette();
44
+ // Transient drag position override (commit-on-drop) so rapid pointer moves
45
+ // never spam onPatch and never diverge from the persisted draft.
46
+ const [dragPos, setDragPos] = React.useState(null);
47
+ const dragRef = React.useRef(null);
48
+ const panRef = React.useRef(null);
49
+ const layout = React.useMemo(() => computeLayout(nodes, edges), [nodes, edges]);
50
+ const size = React.useMemo(() => diagramSize(layout), [layout]);
51
+ // Simulation overlay sets (display-only; never drives engine behavior).
52
+ const visitedSet = React.useMemo(() => new Set(visitedNodeIds ?? []), [visitedNodeIds]);
53
+ const traversedSet = React.useMemo(() => new Set(traversedEdgeIds ?? []), [traversedEdgeIds]);
54
+ const invalidNodeSet = React.useMemo(() => new Set(invalidNodeIds ?? []), [invalidNodeIds]);
55
+ const simRunning = (visitedNodeIds?.length ?? 0) > 0 || !!activeNodeId;
56
+ const positionOf = React.useCallback((id) => {
57
+ if (dragPos && dragPos.id === id)
58
+ return { x: dragPos.x, y: dragPos.y };
59
+ return layout.get(id) ?? { x: 0, y: 0 };
60
+ }, [dragPos, layout]);
61
+ // ── Mutations ────────────────────────────────────────────────────────────
62
+ const persistPosition = React.useCallback((id, x, y) => {
63
+ if (!onPatch)
64
+ return;
65
+ const idx = nodes.findIndex((n) => n.id === id);
66
+ if (idx < 0)
67
+ return;
68
+ const node = nodes[idx];
69
+ const nextNode = { ...node, ui: { ...(node.ui ?? {}), x, y } };
70
+ onPatch({ nodes: spliceArray(nodes, idx, nextNode) });
71
+ }, [nodes, onPatch]);
72
+ const addNode = React.useCallback((type, opts) => {
73
+ if (!onPatch)
74
+ return;
75
+ const existing = nodes.map((n) => n.id).filter(Boolean);
76
+ const id = uniqueId('node', existing);
77
+ const label = type === 'end' ? 'End' : defaultNodeLabel(type);
78
+ // Only an explicit `at` pins a manual position. A `from`-append is left
79
+ // unpinned so the layered auto-layout slots it below its parent and
80
+ // spaces it horizontally among siblings — pinning it directly under the
81
+ // parent (the old behavior) made every sibling stack on the same spot.
82
+ const at = opts?.at;
83
+ const newNode = { id, type, label, ...defaultNodeExtras(type), ...(at ? { ui: { x: at.x, y: at.y } } : {}) };
84
+ const nextNodes = appendArray(nodes, newNode);
85
+ const patch = { nodes: nextNodes };
86
+ if (opts?.from) {
87
+ const newEdge = {
88
+ id: uniqueId('edge', edges.map((e) => e.id).filter(Boolean)),
89
+ source: opts.from,
90
+ target: id,
91
+ };
92
+ // When the source is a decision, carry its matching branch (by order:
93
+ // the k-th out-edge takes the k-th branch) onto the new edge so it
94
+ // actually routes. The decision's config.conditions are otherwise
95
+ // disconnected from the edges, leaving every branch unconditional.
96
+ const fromNode = nodes.find((n) => n.id === opts.from);
97
+ if (fromNode?.type === 'decision') {
98
+ const branches = Array.isArray(fromNode.config?.conditions)
99
+ ? fromNode.config.conditions
100
+ : [];
101
+ const outCount = edges.filter((e) => e.source === opts.from).length;
102
+ const branch = branches[outCount];
103
+ if (branch && typeof branch === 'object') {
104
+ const expr = typeof branch.expression === 'string' ? branch.expression.trim() : '';
105
+ const label = typeof branch.label === 'string' ? branch.label.trim() : '';
106
+ if (label)
107
+ newEdge.label = label;
108
+ if (expr === 'true')
109
+ newEdge.isDefault = true;
110
+ else if (expr)
111
+ newEdge.condition = expr;
112
+ }
113
+ }
114
+ patch.edges = appendArray(edges, newEdge);
115
+ }
116
+ onPatch(patch);
117
+ onSelect(newNode);
118
+ setPaletteOpen(false);
119
+ }, [edges, nodes, onPatch, onSelect, positionOf]);
120
+ /** Split edge A→B by inserting a new node N: A→N (keeps guard) + N→B. */
121
+ const insertOnEdge = React.useCallback((edge, type = 'create_record') => {
122
+ if (!onPatch)
123
+ return;
124
+ const edgeIdx = edges.findIndex((e) => e === edge);
125
+ if (edgeIdx < 0)
126
+ return;
127
+ const existing = nodes.map((n) => n.id).filter(Boolean);
128
+ const id = uniqueId('node', existing);
129
+ const from = positionOf(edge.source);
130
+ const to = positionOf(edge.target);
131
+ const at = { x: (from.x + to.x) / 2, y: (from.y + to.y) / 2 };
132
+ const newNode = {
133
+ id,
134
+ type,
135
+ label: defaultNodeLabel(type),
136
+ ...defaultNodeExtras(type),
137
+ ui: { x: at.x, y: at.y },
138
+ };
139
+ // A→N inherits the original edge's branch semantics; N→B is plain.
140
+ const firstSegment = { ...edge, target: id };
141
+ const secondSegment = {
142
+ id: uniqueId('edge', [...edges.map((e) => e.id).filter(Boolean), 'edge']),
143
+ source: id,
144
+ target: edge.target,
145
+ };
146
+ const nextEdges = spliceArray(edges, edgeIdx, firstSegment);
147
+ onPatch({ nodes: appendArray(nodes, newNode), edges: appendArray(nextEdges, secondSegment) });
148
+ onSelect(newNode);
149
+ }, [edges, nodes, onPatch, onSelect, positionOf]);
150
+ /**
151
+ * ADR-0044 one-click "add revision loop": drop a signal `wait` node plus the
152
+ * two edges that form a send-back-for-revision loop on an approval node —
153
+ * a `revise` out-edge to the wait point, and a declared `back`-edge closing
154
+ * the loop (resubmit re-enters the approval node as round N+1). Reproduces the
155
+ * canonical `showcase_budget_approval` shape in a single gesture. The wait
156
+ * node is left unpinned so the layered auto-layout slots it among the
157
+ * approval node's other branches.
158
+ */
159
+ const addReviseLoop = React.useCallback((approvalId) => {
160
+ if (!onPatch)
161
+ return;
162
+ if (!nodes.some((n) => n.id === approvalId))
163
+ return;
164
+ const waitId = uniqueId('node', nodes.map((n) => n.id).filter(Boolean));
165
+ const waitNode = {
166
+ id: waitId,
167
+ type: 'wait',
168
+ label: 'Awaiting Revision',
169
+ // Signal-flavored wait: the submitter's resubmit signal resumes the run.
170
+ waitEventConfig: { eventType: 'signal', signalName: 'revision', onTimeout: 'fail' },
171
+ };
172
+ const existingEdgeIds = edges.map((e) => e.id).filter(Boolean);
173
+ const reviseId = uniqueId('edge', existingEdgeIds);
174
+ const backId = uniqueId('edge', [...existingEdgeIds, reviseId]);
175
+ const reviseEdge = { id: reviseId, source: approvalId, target: waitId, label: 'revise' };
176
+ const backEdge = { id: backId, source: waitId, target: approvalId, label: 'resubmit', type: 'back' };
177
+ onPatch({
178
+ nodes: appendArray(nodes, waitNode),
179
+ edges: appendArray(appendArray(edges, reviseEdge), backEdge),
180
+ });
181
+ onSelect(waitNode);
182
+ }, [edges, nodes, onPatch, onSelect]);
183
+ // Approval nodes that already declare a `revise` out-edge — used to hide the
184
+ // "add revision loop" affordance once a loop exists (avoid duplicates).
185
+ const reviseLoopSources = React.useMemo(() => {
186
+ const s = new Set();
187
+ for (const e of edges) {
188
+ if (typeof e.label === 'string' && e.label.trim().toLowerCase() === 'revise')
189
+ s.add(e.source);
190
+ }
191
+ return s;
192
+ }, [edges]);
193
+ const deleteNode = React.useCallback((id) => {
194
+ if (!onPatch)
195
+ return;
196
+ const nextNodes = nodes.filter((n) => n.id !== id);
197
+ const nextEdges = edges.filter((e) => e.source !== id && e.target !== id);
198
+ onPatch({ nodes: nextNodes, edges: nextEdges });
199
+ onSelect(null);
200
+ }, [edges, nodes, onPatch, onSelect]);
201
+ // ── Drag (reposition) — pointer capture, commit on pointer-up ──────────────
202
+ const onNodePointerDown = React.useCallback((id) => (e) => {
203
+ if (!editable || e.button !== 0)
204
+ return;
205
+ e.stopPropagation();
206
+ const origin = positionOf(id);
207
+ dragRef.current = {
208
+ nodeId: id,
209
+ startX: e.clientX,
210
+ startY: e.clientY,
211
+ originX: origin.x,
212
+ originY: origin.y,
213
+ moved: false,
214
+ };
215
+ e.currentTarget.setPointerCapture?.(e.pointerId);
216
+ }, [editable, positionOf]);
217
+ const onNodePointerMove = React.useCallback((e) => {
218
+ const d = dragRef.current;
219
+ if (!d)
220
+ return;
221
+ const dx = (e.clientX - d.startX) / zoom;
222
+ const dy = (e.clientY - d.startY) / zoom;
223
+ if (!d.moved && Math.hypot(e.clientX - d.startX, e.clientY - d.startY) < DRAG_THRESHOLD) {
224
+ return;
225
+ }
226
+ d.moved = true;
227
+ setDragPos({ id: d.nodeId, x: Math.max(0, d.originX + dx), y: Math.max(0, d.originY + dy) });
228
+ }, [zoom]);
229
+ const onNodePointerUp = React.useCallback((e) => {
230
+ const d = dragRef.current;
231
+ dragRef.current = null;
232
+ if (!d)
233
+ return;
234
+ e.currentTarget.releasePointerCapture?.(e.pointerId);
235
+ if (d.moved && dragPos) {
236
+ persistPosition(d.nodeId, Math.round(dragPos.x), Math.round(dragPos.y));
237
+ }
238
+ setDragPos(null);
239
+ }, [dragPos, persistPosition]);
240
+ // ── Pan (background drag) ──────────────────────────────────────────────────
241
+ const onBgPointerDown = React.useCallback((e) => {
242
+ if (e.button !== 0)
243
+ return;
244
+ onSelect(null);
245
+ panRef.current = { startX: e.clientX, startY: e.clientY, originX: pan.x, originY: pan.y };
246
+ e.currentTarget.setPointerCapture?.(e.pointerId);
247
+ }, [onSelect, pan.x, pan.y]);
248
+ const onBgPointerMove = React.useCallback((e) => {
249
+ const p = panRef.current;
250
+ if (!p)
251
+ return;
252
+ setPan({ x: p.originX + (e.clientX - p.startX), y: p.originY + (e.clientY - p.startY) });
253
+ }, []);
254
+ const onBgPointerUp = React.useCallback((e) => {
255
+ if (panRef.current)
256
+ e.currentTarget.releasePointerCapture?.(e.pointerId);
257
+ panRef.current = null;
258
+ }, []);
259
+ // ── Zoom / fit ─────────────────────────────────────────────────────────────
260
+ const clampZoom = (z) => Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, z));
261
+ const fitToView = React.useCallback(() => {
262
+ const vp = viewportRef.current;
263
+ if (!vp)
264
+ return;
265
+ const pad = 32;
266
+ const zx = (vp.clientWidth - pad) / size.width;
267
+ const zy = (vp.clientHeight - pad) / size.height;
268
+ const z = clampZoom(Math.min(zx, zy, 1));
269
+ setZoom(z);
270
+ setPan({
271
+ x: (vp.clientWidth - size.width * z) / 2,
272
+ y: Math.max(16, (vp.clientHeight - size.height * z) / 2),
273
+ });
274
+ }, [size.height, size.width]);
275
+ // ── Keyboard: delete selected node ─────────────────────────────────────────
276
+ const onKeyDown = React.useCallback((e) => {
277
+ if (!editable || !selectedId)
278
+ return;
279
+ if (e.key === 'Delete' || e.key === 'Backspace') {
280
+ const target = e.target;
281
+ if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {
282
+ return;
283
+ }
284
+ e.preventDefault();
285
+ deleteNode(selectedId);
286
+ }
287
+ }, [deleteNode, editable, selectedId]);
288
+ // ── Render ─────────────────────────────────────────────────────────────────
289
+ return (_jsxs("div", { className: "relative h-full min-h-[320px] w-full overflow-hidden", children: [validationErrors && validationErrors.length > 0 && (_jsxs("div", { className: "absolute left-2 top-2 z-30 max-w-[min(60%,420px)] space-y-1", children: [validationErrors.slice(0, 3).map((msg, i) => (_jsxs("div", { role: "alert", className: "flex items-start gap-1.5 rounded-lg border border-destructive/40 bg-destructive/10 px-2.5 py-1.5 text-[11px] leading-snug text-destructive shadow-sm backdrop-blur-sm", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-3.5 w-3.5 shrink-0" }), _jsx("span", { children: msg })] }, i))), validationErrors.length > 3 && (_jsxs("div", { className: "px-2.5 text-[10px] text-destructive/80", children: ["+", validationErrors.length - 3, " more\u2026"] }))] })), _jsxs("div", { className: "absolute right-2 top-2 z-30 flex items-center gap-1.5", children: [editable && (_jsxs("div", { className: "relative", children: [_jsxs("button", { type: "button", onClick: () => setPaletteOpen((v) => !v), className: "inline-flex items-center gap-1.5 rounded-lg border bg-background/90 px-2.5 py-1.5 text-xs font-medium shadow-sm backdrop-blur-sm transition-colors hover:border-primary/50 hover:bg-accent hover:text-foreground", children: [_jsx(Plus, { className: "h-3.5 w-3.5" }), tr('engine.inspector.add.node', locale)] }), paletteOpen && (_jsx(NodePalette, { locale: locale, items: paletteItems, onClose: () => setPaletteOpen(false), onPick: (type) => addNode(type, { from: selectedId ?? undefined }) }))] })), _jsxs("div", { className: "flex items-center rounded-lg border bg-background/90 shadow-sm backdrop-blur-sm", children: [_jsx("button", { type: "button", title: "Zoom out", "aria-label": "Zoom out", onClick: () => setZoom((z) => clampZoom(z - 0.15)), className: "inline-flex h-7 w-7 items-center justify-center text-muted-foreground hover:text-foreground", children: _jsx(ZoomOut, { className: "h-3.5 w-3.5" }) }), _jsxs("span", { className: "w-10 text-center text-[11px] tabular-nums text-muted-foreground", children: [Math.round(zoom * 100), "%"] }), _jsx("button", { type: "button", title: "Zoom in", "aria-label": "Zoom in", onClick: () => setZoom((z) => clampZoom(z + 0.15)), className: "inline-flex h-7 w-7 items-center justify-center text-muted-foreground hover:text-foreground", children: _jsx(ZoomIn, { className: "h-3.5 w-3.5" }) }), _jsx("button", { type: "button", title: "Fit to view", "aria-label": "Fit to view", onClick: fitToView, className: "inline-flex h-7 w-7 items-center justify-center border-l text-muted-foreground hover:text-foreground", children: _jsx(Maximize2, { className: "h-3.5 w-3.5" }) })] })] }), _jsx("div", { ref: viewportRef, tabIndex: 0, role: "application", "aria-label": "Flow canvas", onKeyDown: onKeyDown, onPointerDown: onBgPointerDown, onPointerMove: (e) => {
290
+ onBgPointerMove(e);
291
+ onNodePointerMove(e);
292
+ }, onPointerUp: (e) => {
293
+ onBgPointerUp(e);
294
+ onNodePointerUp(e);
295
+ }, className: cn('h-full w-full cursor-grab outline-none active:cursor-grabbing', 'bg-muted/15 dark:bg-background/30',
296
+ // Subtle inset vignette gives the canvas surface depth.
297
+ 'shadow-[inset_0_0_90px_rgba(0,0,0,0.05)]'), style: {
298
+ // Dot grid tied to pan + zoom so the surface tracks the diagram
299
+ // (rather than floating behind a static texture).
300
+ backgroundImage: 'radial-gradient(circle at 1px 1px, hsl(var(--border)) 1px, transparent 0)',
301
+ backgroundSize: `${18 * zoom}px ${18 * zoom}px`,
302
+ backgroundPosition: `${pan.x}px ${pan.y}px`,
303
+ }, children: _jsxs("div", { className: "relative origin-top-left", style: {
304
+ width: size.width,
305
+ height: size.height,
306
+ transform: `translate(${pan.x}px, ${pan.y}px) scale(${zoom})`,
307
+ }, children: [_jsxs("svg", { className: "pointer-events-none absolute left-0 top-0 overflow-visible", width: size.width, height: size.height, children: [_jsxs("defs", { children: [_jsx("marker", { id: "flow-arrow", viewBox: "0 0 10 10", refX: "8", refY: "5", markerWidth: "7", markerHeight: "7", orient: "auto-start-reverse", children: _jsx("path", { d: "M 0 0 L 10 5 L 0 10 z", className: "fill-muted-foreground/55" }) }), _jsx("marker", { id: "flow-arrow-back", viewBox: "0 0 10 10", refX: "8", refY: "5", markerWidth: "7", markerHeight: "7", orient: "auto-start-reverse", children: _jsx("path", { d: "M 0 0 L 10 5 L 0 10 z", className: "fill-amber-500/80" }) }), _jsx("marker", { id: "flow-arrow-error", viewBox: "0 0 10 10", refX: "8", refY: "5", markerWidth: "7", markerHeight: "7", orient: "auto-start-reverse", children: _jsx("path", { d: "M 0 0 L 10 5 L 0 10 z", className: "fill-destructive" }) })] }), edges.map((edge, i) => {
308
+ const sp = layout.get(edge.source);
309
+ const tp = layout.get(edge.target);
310
+ if (!sp || !tp)
311
+ return null;
312
+ // ADR-0044 back-edges (revise loop) re-enter an earlier node, so
313
+ // they attach to the right side of both endpoints and render as a
314
+ // dashed amber return arc — visually distinct from the forward
315
+ // top-to-bottom flow.
316
+ const back = isBackEdge(edge);
317
+ // Structural-validation error (e.g. part of an un-declared cycle).
318
+ // Back-edges are excluded from cycle detection, so they're never invalid.
319
+ const invalid = !back && !!invalidEdges?.has(`${edge.source}->${edge.target}`);
320
+ const sPos = dragPos?.id === edge.source ? positionOf(edge.source) : sp;
321
+ const tPos = dragPos?.id === edge.target ? positionOf(edge.target) : tp;
322
+ const from = back ? rightAnchor(sPos) : bottomAnchor(sPos);
323
+ const to = back ? rightAnchor(tPos) : topAnchor(tPos);
324
+ const labelPos = back ? backEdgeLabelAnchor(from, to) : edgeMidpoint(from, to);
325
+ const cond = conditionText(edge.condition);
326
+ const branchLabel = edge.isDefault ? 'else' : cond ? `if ${cond}` : edge.label;
327
+ const eid = edgeKey(edge, i);
328
+ const traversed = traversedSet.has(eid);
329
+ const selected = selectedEdgeId === eid;
330
+ const d = back ? backEdgePath(from, to) : edgePath(from, to);
331
+ // Edges are selectable in design mode; the host opens the edge
332
+ // inspector. A wide transparent hit-path widens the click target
333
+ // beyond the 1.5px visible stroke without altering the visuals.
334
+ const selectable = designMode && !!onSelectEdge;
335
+ return (_jsxs("g", { "data-invalid": invalid || undefined, children: [_jsx("path", { d: d, strokeLinecap: "round", strokeDasharray: back ? '5 4' : undefined, className: cn('fill-none transition-[stroke] duration-150', traversed
336
+ ? 'stroke-sky-500'
337
+ : selected
338
+ ? 'stroke-primary'
339
+ : invalid
340
+ ? 'stroke-destructive'
341
+ : back
342
+ ? 'stroke-amber-500/70'
343
+ : simRunning
344
+ ? 'stroke-muted-foreground/20'
345
+ : 'stroke-muted-foreground/40'), strokeWidth: traversed || selected || invalid ? 2.5 : 1.75, markerEnd: invalid ? 'url(#flow-arrow-error)' : back ? 'url(#flow-arrow-back)' : 'url(#flow-arrow)' }), selectable && (_jsx("path", { d: d, className: "pointer-events-auto cursor-pointer fill-none stroke-transparent", strokeWidth: 14, onPointerDown: (e) => e.stopPropagation(), onClick: (e) => {
346
+ e.stopPropagation();
347
+ onSelectEdge(edge, eid);
348
+ }, children: _jsx("title", { children: invalid ? `${edge.source} → ${edge.target} — part of an un-declared cycle; mark the edge that closes the loop as a back-edge` : back ? `${edge.source} ↩ ${edge.target} (back-edge)` : `${edge.source} → ${edge.target}` }) })), branchLabel && (_jsx("foreignObject", { x: labelPos.x - 60, y: labelPos.y - 11, width: 120, height: 22, className: cn(selectable && 'pointer-events-auto'), children: _jsx("div", { className: "flex justify-center", children: _jsx("span", { onPointerDown: selectable ? (e) => e.stopPropagation() : undefined, onClick: selectable ? (e) => { e.stopPropagation(); onSelectEdge(edge, eid); } : undefined, className: cn('max-w-full truncate rounded-full border bg-background/95 px-2 py-0.5 text-[10px] font-medium shadow-sm backdrop-blur-sm transition-colors', selectable && 'cursor-pointer hover:border-primary/60', selected
349
+ ? 'border-primary text-primary'
350
+ : invalid
351
+ ? 'border-destructive/60 text-destructive'
352
+ : back
353
+ ? 'border-amber-500/50 text-amber-600 dark:text-amber-400'
354
+ : 'border-border text-muted-foreground'), children: branchLabel }) }) })), editable && !back && (_jsx("foreignObject", {
355
+ // Sit the insert handle at the edge midpoint, but slide it
356
+ // to the right of the branch-label pill when one is present
357
+ // so the two don't stack on the same spot.
358
+ x: branchLabel ? labelPos.x + 66 : labelPos.x - 11, y: labelPos.y - 11, width: 22, height: 22, className: "pointer-events-auto", children: _jsx("button", { type: "button", title: "Insert node here", "aria-label": "Insert node here", onPointerDown: (e) => e.stopPropagation(), onClick: (e) => {
359
+ e.stopPropagation();
360
+ insertOnEdge(edge);
361
+ }, className: "inline-flex h-[22px] w-[22px] items-center justify-center rounded-full border bg-background/90 text-muted-foreground opacity-50 shadow-sm backdrop-blur-sm transition-all hover:scale-110 hover:border-primary hover:bg-background hover:text-primary hover:opacity-100 focus-visible:opacity-100", children: _jsx(Plus, { className: "h-3 w-3" }) }) }))] }, edge.id || `${edge.source}-${edge.target}-${i}`));
362
+ })] }), nodes.map((node) => {
363
+ const runState = activeNodeId === node.id ? 'active' : visitedSet.has(node.id) ? 'visited' : undefined;
364
+ return (_jsx(NodeCard, { id: node.id, type: node.type, label: node.label || node.id, summary: nodeSummary(node), position: positionOf(node.id), selected: selectedId === node.id, editable: editable, runState: runState, dimmed: simRunning && !runState, onPointerDown: onNodePointerDown(node.id), onSelect: () => designMode && onSelect(node), onAppend: () => addNode('create_record', { from: node.id }), onAddReviseLoop: editable && node.type === 'approval' && !reviseLoopSources.has(node.id)
365
+ ? () => addReviseLoop(node.id)
366
+ : undefined, invalid: invalidNodeSet.has(node.id) }, node.id));
367
+ })] }) })] }));
368
+ }
369
+ /** One-line config summary shown on the node card (best-effort, type-aware). */
370
+ function nodeSummary(node) {
371
+ const c = node.config;
372
+ const str = (v) => (typeof v === 'string' && v ? v : undefined);
373
+ const block = (key, inner) => {
374
+ const b = node[key];
375
+ return b && typeof b === 'object' ? str(b[inner]) : undefined;
376
+ };
377
+ const pick = (k) => (c ? str(c[k]) : undefined);
378
+ if (node.type === 'start') {
379
+ return pick('condition') || pick('criteria') || pick('objectName') || pick('cron') || pick('schedule') || pick('triggerType');
380
+ }
381
+ if (node.type === 'decision') {
382
+ const conds = c?.conditions;
383
+ if (Array.isArray(conds) && conds.length) {
384
+ const labels = conds
385
+ .map((x) => (x && typeof x === 'object' ? str(x.label) : undefined))
386
+ .filter(Boolean);
387
+ return labels.length ? labels.join(' / ') : `${conds.length} branches`;
388
+ }
389
+ return pick('condition');
390
+ }
391
+ if (node.type === 'script') {
392
+ return pick('actionType') || pick('template') || (c && c.script ? 'code' : undefined);
393
+ }
394
+ if (node.type === 'approval') {
395
+ const approvers = c?.approvers;
396
+ const n = Array.isArray(approvers) ? approvers.length : 0;
397
+ const behavior = pick('behavior');
398
+ if (n > 0)
399
+ return `${n} approver${n === 1 ? '' : 's'}${behavior === 'unanimous' ? ' · all' : ''}`;
400
+ return behavior || undefined;
401
+ }
402
+ return (pick('objectName') ||
403
+ block('connectorConfig', 'actionId') ||
404
+ block('waitEventConfig', 'timerDuration') ||
405
+ block('waitEventConfig', 'eventType') ||
406
+ block('boundaryConfig', 'eventType') ||
407
+ pick('condition') ||
408
+ pick('flowName') ||
409
+ pick('url') ||
410
+ pick('collection') ||
411
+ pick('action') ||
412
+ pick('flow') ||
413
+ pick('event') ||
414
+ pick('duration') ||
415
+ undefined);
416
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * FlowPreview — read-only summary of a Flow metadata draft.
3
+ *
4
+ * A full DAG canvas lives in `@object-ui/plugin-designer` and would
5
+ * pull in ReactFlow + its deps every time the metadata-admin loads,
6
+ * which is too heavy for a glance-preview. Instead we render:
7
+ *
8
+ * 1. A header strip with type / status / runAs / version.
9
+ * 2. A topologically ordered step list inferred from `nodes` +
10
+ * `edges`. Each step shows label, action type, branch markers,
11
+ * and outgoing edge conditions so authors can sanity-check the
12
+ * logic without launching the designer.
13
+ * 3. A variables side panel listing declared flow variables.
14
+ *
15
+ * The renderer is defensive — drafts may be mid-edit with dangling
16
+ * edges or duplicate node ids; we never throw, we just degrade.
17
+ */
18
+ import * as React from 'react';
19
+ import type { MetadataPreviewProps } from '../preview-registry';
20
+ export declare function FlowPreview({ draft, editing, selection, onSelectionChange, onPatch, locale }: MetadataPreviewProps): React.JSX.Element;