@object-ui/app-shell 6.2.3 → 7.0.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 (468) hide show
  1. package/CHANGELOG.md +948 -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 +170 -37
  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 +743 -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 +22 -0
  27. package/dist/console/ai/LiveCanvas.js +78 -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 +107 -4
  90. package/dist/hooks/useChatConversation.js +253 -25
  91. package/dist/hooks/useConsoleActionRuntime.d.ts +70 -0
  92. package/dist/hooks/useConsoleActionRuntime.js +560 -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 +16 -7
  110. package/dist/index.js +12 -4
  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 +32 -2
  124. package/dist/layout/ConsoleFloatingChatbot.js +374 -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 +218 -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/observability/index.d.ts +1 -0
  140. package/dist/observability/index.js +1 -0
  141. package/dist/observability/settleSignal.d.ts +64 -0
  142. package/dist/observability/settleSignal.js +131 -0
  143. package/dist/preview/DraftChangesPanel.d.ts +19 -0
  144. package/dist/preview/DraftChangesPanel.js +114 -0
  145. package/dist/preview/DraftPreviewBar.d.ts +8 -0
  146. package/dist/preview/DraftPreviewBar.js +86 -0
  147. package/dist/preview/PreviewDraftEmptyState.d.ts +16 -0
  148. package/dist/preview/PreviewDraftEmptyState.js +47 -0
  149. package/dist/preview/PreviewModeContext.d.ts +57 -0
  150. package/dist/preview/PreviewModeContext.js +99 -0
  151. package/dist/preview/UnpublishedAppBar.d.ts +8 -0
  152. package/dist/preview/UnpublishedAppBar.js +79 -0
  153. package/dist/preview/draftStatus.d.ts +20 -0
  154. package/dist/preview/draftStatus.js +27 -0
  155. package/dist/preview/usePublishAllDrafts.d.ts +18 -0
  156. package/dist/preview/usePublishAllDrafts.js +106 -0
  157. package/dist/providers/AdapterProvider.d.ts +1 -1
  158. package/dist/providers/AdapterProvider.js +6 -1
  159. package/dist/providers/ExpressionProvider.d.ts +1 -1
  160. package/dist/providers/MetadataProvider.d.ts +17 -2
  161. package/dist/providers/MetadataProvider.js +183 -12
  162. package/dist/runtime-config.d.ts +46 -2
  163. package/dist/runtime-config.js +39 -2
  164. package/dist/services/builtinComponents.js +68 -59
  165. package/dist/skeletons/SkeletonDashboard.d.ts +1 -1
  166. package/dist/skeletons/SkeletonDetail.d.ts +1 -1
  167. package/dist/skeletons/SkeletonGrid.d.ts +1 -1
  168. package/dist/utils/appRoute.d.ts +21 -0
  169. package/dist/utils/appRoute.js +25 -0
  170. package/dist/utils/deriveRelatedLists.d.ts +54 -0
  171. package/dist/utils/deriveRelatedLists.js +91 -0
  172. package/dist/utils/index.d.ts +4 -0
  173. package/dist/utils/index.js +3 -0
  174. package/dist/utils/managedByEmptyState.d.ts +8 -1
  175. package/dist/utils/managedByEmptyState.js +13 -7
  176. package/dist/utils/preferLocal.d.ts +18 -0
  177. package/dist/utils/preferLocal.js +24 -0
  178. package/dist/views/ActionConfirmDialog.d.ts +1 -1
  179. package/dist/views/ActionConfirmDialog.js +3 -1
  180. package/dist/views/ActionParamDialog.d.ts +6 -1
  181. package/dist/views/ActionParamDialog.js +9 -3
  182. package/dist/views/ActionResultDialog.d.ts +13 -0
  183. package/dist/views/ActionResultDialog.js +134 -0
  184. package/dist/views/ComponentNavView.d.ts +14 -1
  185. package/dist/views/CreateViewDialog.d.ts +1 -1
  186. package/dist/views/DashboardConfigPanel.d.ts +28 -0
  187. package/dist/views/DashboardConfigPanel.js +81 -0
  188. package/dist/views/DashboardView.d.ts +4 -3
  189. package/dist/views/DashboardView.js +38 -239
  190. package/dist/views/FlowRunner.d.ts +59 -0
  191. package/dist/views/FlowRunner.js +153 -0
  192. package/dist/views/InterfaceListPage.d.ts +49 -0
  193. package/dist/views/InterfaceListPage.js +347 -0
  194. package/dist/views/MetadataInspector.d.ts +2 -2
  195. package/dist/views/ObjectView.d.ts +1 -1
  196. package/dist/views/ObjectView.js +209 -532
  197. package/dist/views/PageView.d.ts +8 -3
  198. package/dist/views/PageView.js +45 -32
  199. package/dist/views/RecordDetailView.d.ts +1 -1
  200. package/dist/views/RecordDetailView.js +363 -148
  201. package/dist/views/RecordFormPage.d.ts +1 -1
  202. package/dist/views/RecordFormPage.js +26 -1
  203. package/dist/views/ReportConfigPanel.d.ts +37 -0
  204. package/dist/views/ReportConfigPanel.js +85 -0
  205. package/dist/views/ReportView.d.ts +1 -1
  206. package/dist/views/ReportView.js +116 -7
  207. package/dist/views/RuntimeDraftBar.d.ts +30 -0
  208. package/dist/views/RuntimeDraftBar.js +112 -0
  209. package/dist/views/SearchResultsPage.d.ts +1 -1
  210. package/dist/views/SearchResultsPage.js +8 -18
  211. package/dist/views/ViewConfigPanel.d.ts +24 -17
  212. package/dist/views/ViewConfigPanel.js +121 -77
  213. package/dist/views/index.d.ts +1 -1
  214. package/dist/views/index.js +1 -1
  215. package/dist/views/metadata-admin/AuditPanel.d.ts +28 -0
  216. package/dist/views/metadata-admin/AuditPanel.js +79 -0
  217. package/dist/views/metadata-admin/DiagnosticsPage.d.ts +20 -0
  218. package/dist/views/metadata-admin/DiagnosticsPage.js +69 -0
  219. package/dist/views/metadata-admin/DirectoryPage.d.ts +16 -1
  220. package/dist/views/metadata-admin/DirectoryPage.js +113 -24
  221. package/dist/views/metadata-admin/DraftReviewPanel.d.ts +33 -0
  222. package/dist/views/metadata-admin/DraftReviewPanel.js +77 -0
  223. package/dist/views/metadata-admin/EmbeddedItemEditor.d.ts +17 -1
  224. package/dist/views/metadata-admin/EmbeddedItemEditor.js +15 -8
  225. package/dist/views/metadata-admin/JsonSourceEditor.d.ts +37 -0
  226. package/dist/views/metadata-admin/JsonSourceEditor.js +178 -0
  227. package/dist/views/metadata-admin/LayeredDiff.d.ts +39 -1
  228. package/dist/views/metadata-admin/LayeredDiff.js +171 -5
  229. package/dist/views/metadata-admin/MetadataDetailDrawer.d.ts +15 -1
  230. package/dist/views/metadata-admin/MetadataTypeActions.d.ts +48 -0
  231. package/dist/views/metadata-admin/MetadataTypeActions.js +165 -0
  232. package/dist/views/metadata-admin/PackagesPage.d.ts +18 -0
  233. package/dist/views/metadata-admin/PackagesPage.js +395 -0
  234. package/dist/views/metadata-admin/PageShell.d.ts +1 -1
  235. package/dist/views/metadata-admin/PageShell.js +9 -4
  236. package/dist/views/metadata-admin/PermissionMatrixEditor.d.ts +35 -1
  237. package/dist/views/metadata-admin/QuickFind.d.ts +21 -1
  238. package/dist/views/metadata-admin/QuickFind.js +6 -3
  239. package/dist/views/metadata-admin/RelatedPanel.d.ts +24 -1
  240. package/dist/views/metadata-admin/RelatedPanel.js +20 -18
  241. package/dist/views/metadata-admin/ResourceEditPage.d.ts +40 -1
  242. package/dist/views/metadata-admin/ResourceEditPage.js +1223 -60
  243. package/dist/views/metadata-admin/ResourceHistoryPage.d.ts +39 -1
  244. package/dist/views/metadata-admin/ResourceHistoryPage.js +66 -16
  245. package/dist/views/metadata-admin/ResourceListPage.d.ts +13 -1
  246. package/dist/views/metadata-admin/ResourceListPage.js +266 -30
  247. package/dist/views/metadata-admin/ResourceRouter.d.ts +23 -1
  248. package/dist/views/metadata-admin/SchemaForm.d.ts +34 -1
  249. package/dist/views/metadata-admin/SchemaForm.js +559 -49
  250. package/dist/views/metadata-admin/StudioHomePage.d.ts +22 -0
  251. package/dist/views/metadata-admin/StudioHomePage.js +213 -0
  252. package/dist/views/metadata-admin/anchors.js +237 -24
  253. package/dist/views/metadata-admin/clientValidation.d.ts +50 -0
  254. package/dist/views/metadata-admin/clientValidation.js +169 -0
  255. package/dist/views/metadata-admin/color-variant-field.d.ts +30 -0
  256. package/dist/views/metadata-admin/color-variant-field.js +38 -0
  257. package/dist/views/metadata-admin/createDerive.d.ts +75 -0
  258. package/dist/views/metadata-admin/createDerive.js +179 -0
  259. package/dist/views/metadata-admin/dashboard-schema.d.ts +12 -0
  260. package/dist/views/metadata-admin/dashboard-schema.js +80 -0
  261. package/dist/views/metadata-admin/datasource/DatasourceResourcePage.d.ts +35 -0
  262. package/dist/views/metadata-admin/datasource/DatasourceResourcePage.js +327 -0
  263. package/dist/views/metadata-admin/datasource/register.d.ts +1 -0
  264. package/dist/views/metadata-admin/datasource/register.js +24 -0
  265. package/dist/views/metadata-admin/default-inspector-registry.d.ts +49 -0
  266. package/dist/views/metadata-admin/default-inspector-registry.js +8 -0
  267. package/dist/views/metadata-admin/default-schemas.js +115 -10
  268. package/dist/views/metadata-admin/external/ExternalDatasourcePanel.d.ts +27 -0
  269. package/dist/views/metadata-admin/external/ExternalDatasourcePanel.js +69 -0
  270. package/dist/views/metadata-admin/external/ImportObjectDialog.d.ts +27 -0
  271. package/dist/views/metadata-admin/external/ImportObjectDialog.js +77 -0
  272. package/dist/views/metadata-admin/external/SchemaBrowser.d.ts +16 -0
  273. package/dist/views/metadata-admin/external/SchemaBrowser.js +74 -0
  274. package/dist/views/metadata-admin/external/ValidationPanel.d.ts +16 -0
  275. package/dist/views/metadata-admin/external/ValidationPanel.js +68 -0
  276. package/dist/views/metadata-admin/external/api.d.ts +100 -0
  277. package/dist/views/metadata-admin/external/api.js +124 -0
  278. package/dist/views/metadata-admin/i18n.d.ts +1 -0
  279. package/dist/views/metadata-admin/i18n.js +1166 -2
  280. package/dist/views/metadata-admin/index.d.ts +8 -5
  281. package/dist/views/metadata-admin/index.js +12 -2
  282. package/dist/views/metadata-admin/inspector-registry.d.ts +51 -0
  283. package/dist/views/metadata-admin/inspector-registry.js +11 -0
  284. package/dist/views/metadata-admin/inspectors/ActionDefaultInspector.d.ts +30 -0
  285. package/dist/views/metadata-admin/inspectors/ActionDefaultInspector.js +180 -0
  286. package/dist/views/metadata-admin/inspectors/AppNavInspector.d.ts +16 -0
  287. package/dist/views/metadata-admin/inspectors/AppNavInspector.js +110 -0
  288. package/dist/views/metadata-admin/inspectors/ConditionBuilder.d.ts +29 -0
  289. package/dist/views/metadata-admin/inspectors/ConditionBuilder.js +154 -0
  290. package/dist/views/metadata-admin/inspectors/DashboardDefaultInspector.d.ts +28 -0
  291. package/dist/views/metadata-admin/inspectors/DashboardDefaultInspector.js +110 -0
  292. package/dist/views/metadata-admin/inspectors/DashboardWidgetInspector.d.ts +18 -0
  293. package/dist/views/metadata-admin/inspectors/DashboardWidgetInspector.js +139 -0
  294. package/dist/views/metadata-admin/inspectors/DatasetDefaultInspector.d.ts +21 -0
  295. package/dist/views/metadata-admin/inspectors/DatasetDefaultInspector.js +107 -0
  296. package/dist/views/metadata-admin/inspectors/FlowEdgeInspector.d.ts +16 -0
  297. package/dist/views/metadata-admin/inspectors/FlowEdgeInspector.js +45 -0
  298. package/dist/views/metadata-admin/inspectors/FlowInspector.d.ts +12 -0
  299. package/dist/views/metadata-admin/inspectors/FlowInspector.js +9 -0
  300. package/dist/views/metadata-admin/inspectors/FlowKeyValueField.d.ts +30 -0
  301. package/dist/views/metadata-admin/inspectors/FlowKeyValueField.js +125 -0
  302. package/dist/views/metadata-admin/inspectors/FlowNodeConfigField.d.ts +18 -0
  303. package/dist/views/metadata-admin/inspectors/FlowNodeConfigField.js +40 -0
  304. package/dist/views/metadata-admin/inspectors/FlowNodeInspector.d.ts +14 -0
  305. package/dist/views/metadata-admin/inspectors/FlowNodeInspector.js +140 -0
  306. package/dist/views/metadata-admin/inspectors/FlowObjectListField.d.ts +26 -0
  307. package/dist/views/metadata-admin/inspectors/FlowObjectListField.js +105 -0
  308. package/dist/views/metadata-admin/inspectors/FlowReferenceField.d.ts +83 -0
  309. package/dist/views/metadata-admin/inspectors/FlowReferenceField.js +181 -0
  310. package/dist/views/metadata-admin/inspectors/FlowStringListField.d.ts +21 -0
  311. package/dist/views/metadata-admin/inspectors/FlowStringListField.js +60 -0
  312. package/dist/views/metadata-admin/inspectors/InspectorComboField.d.ts +40 -0
  313. package/dist/views/metadata-admin/inspectors/InspectorComboField.js +61 -0
  314. package/dist/views/metadata-admin/inspectors/ObjectDefaultInspector.d.ts +21 -0
  315. package/dist/views/metadata-admin/inspectors/ObjectDefaultInspector.js +54 -0
  316. package/dist/views/metadata-admin/inspectors/ObjectFieldInspector.d.ts +23 -0
  317. package/dist/views/metadata-admin/inspectors/ObjectFieldInspector.js +330 -0
  318. package/dist/views/metadata-admin/inspectors/PageBlockInspector.d.ts +48 -0
  319. package/dist/views/metadata-admin/inspectors/PageBlockInspector.js +332 -0
  320. package/dist/views/metadata-admin/inspectors/ReportDefaultInspector.d.ts +58 -0
  321. package/dist/views/metadata-admin/inspectors/ReportDefaultInspector.js +160 -0
  322. package/dist/views/metadata-admin/inspectors/ViewColumnInspector.d.ts +19 -0
  323. package/dist/views/metadata-admin/inspectors/ViewColumnInspector.js +144 -0
  324. package/dist/views/metadata-admin/inspectors/ViewInspector.d.ts +19 -0
  325. package/dist/views/metadata-admin/inspectors/ViewInspector.js +21 -0
  326. package/dist/views/metadata-admin/inspectors/ViewVariantInspector.d.ts +54 -0
  327. package/dist/views/metadata-admin/inspectors/ViewVariantInspector.js +191 -0
  328. package/dist/views/metadata-admin/inspectors/_shared.d.ts +124 -0
  329. package/dist/views/metadata-admin/inspectors/_shared.js +113 -0
  330. package/dist/views/metadata-admin/inspectors/expression-validate.d.ts +26 -0
  331. package/dist/views/metadata-admin/inspectors/expression-validate.js +66 -0
  332. package/dist/views/metadata-admin/inspectors/flow-node-config.d.ts +143 -0
  333. package/dist/views/metadata-admin/inspectors/flow-node-config.js +461 -0
  334. package/dist/views/metadata-admin/inspectors/index.d.ts +1 -0
  335. package/dist/views/metadata-admin/inspectors/index.js +45 -0
  336. package/dist/views/metadata-admin/inspectors/json-schema-to-fields.d.ts +40 -0
  337. package/dist/views/metadata-admin/inspectors/json-schema-to-fields.js +227 -0
  338. package/dist/views/metadata-admin/inspectors/useDatasetFields.d.ts +72 -0
  339. package/dist/views/metadata-admin/inspectors/useDatasetFields.js +0 -0
  340. package/dist/views/metadata-admin/mergeServerFields.d.ts +65 -0
  341. package/dist/views/metadata-admin/mergeServerFields.js +56 -0
  342. package/dist/views/metadata-admin/preview-registry.d.ts +55 -0
  343. package/dist/views/metadata-admin/previews/ActionPreview.d.ts +25 -0
  344. package/dist/views/metadata-admin/previews/ActionPreview.js +238 -0
  345. package/dist/views/metadata-admin/previews/AddWidgetPicker.d.ts +12 -0
  346. package/dist/views/metadata-admin/previews/AddWidgetPicker.js +56 -0
  347. package/dist/views/metadata-admin/previews/AgentPreview.d.ts +24 -0
  348. package/dist/views/metadata-admin/previews/AgentPreview.js +100 -0
  349. package/dist/views/metadata-admin/previews/AppNavCanvas.d.ts +31 -0
  350. package/dist/views/metadata-admin/previews/AppNavCanvas.js +260 -0
  351. package/dist/views/metadata-admin/previews/AppPreview.d.ts +16 -1
  352. package/dist/views/metadata-admin/previews/AppPreview.js +23 -14
  353. package/dist/views/metadata-admin/previews/BookPreview.d.ts +20 -0
  354. package/dist/views/metadata-admin/previews/BookPreview.js +132 -0
  355. package/dist/views/metadata-admin/previews/DashboardPreview.d.ts +16 -1
  356. package/dist/views/metadata-admin/previews/DashboardPreview.js +110 -8
  357. package/dist/views/metadata-admin/previews/DatasetPreview.d.ts +18 -0
  358. package/dist/views/metadata-admin/previews/DatasetPreview.js +89 -0
  359. package/dist/views/metadata-admin/previews/DatasourcePreview.d.ts +23 -0
  360. package/dist/views/metadata-admin/previews/DatasourcePreview.js +68 -0
  361. package/dist/views/metadata-admin/previews/EmailTemplatePreview.d.ts +14 -1
  362. package/dist/views/metadata-admin/previews/FieldStub.d.ts +30 -0
  363. package/dist/views/metadata-admin/previews/FieldStub.js +104 -0
  364. package/dist/views/metadata-admin/previews/FieldsListEditor.d.ts +50 -0
  365. package/dist/views/metadata-admin/previews/FieldsListEditor.js +97 -0
  366. package/dist/views/metadata-admin/previews/FlowCanvas.d.ts +43 -0
  367. package/dist/views/metadata-admin/previews/FlowCanvas.js +328 -0
  368. package/dist/views/metadata-admin/previews/FlowPreview.d.ts +20 -0
  369. package/dist/views/metadata-admin/previews/FlowPreview.js +92 -0
  370. package/dist/views/metadata-admin/previews/FlowRunsPanel.d.ts +46 -0
  371. package/dist/views/metadata-admin/previews/FlowRunsPanel.js +97 -0
  372. package/dist/views/metadata-admin/previews/FlowSimulatorPanel.d.ts +25 -0
  373. package/dist/views/metadata-admin/previews/FlowSimulatorPanel.js +170 -0
  374. package/dist/views/metadata-admin/previews/JobPreview.d.ts +28 -0
  375. package/dist/views/metadata-admin/previews/JobPreview.js +290 -0
  376. package/dist/views/metadata-admin/previews/ObjectFormCanvas.d.ts +30 -0
  377. package/dist/views/metadata-admin/previews/ObjectFormCanvas.js +547 -0
  378. package/dist/views/metadata-admin/previews/ObjectPreview.d.ts +14 -1
  379. package/dist/views/metadata-admin/previews/ObjectPreview.js +5 -30
  380. package/dist/views/metadata-admin/previews/OutlineStrip.d.ts +32 -0
  381. package/dist/views/metadata-admin/previews/OutlineStrip.js +8 -0
  382. package/dist/views/metadata-admin/previews/PageBlockCanvas.d.ts +49 -0
  383. package/dist/views/metadata-admin/previews/PageBlockCanvas.js +510 -0
  384. package/dist/views/metadata-admin/previews/PagePreview.d.ts +10 -1
  385. package/dist/views/metadata-admin/previews/PagePreview.js +90 -4
  386. package/dist/views/metadata-admin/previews/PermissionPreview.d.ts +27 -0
  387. package/dist/views/metadata-admin/previews/PermissionPreview.js +115 -0
  388. package/dist/views/metadata-admin/previews/PreviewShell.d.ts +29 -6
  389. package/dist/views/metadata-admin/previews/PreviewShell.js +16 -3
  390. package/dist/views/metadata-admin/previews/ReportPreview.d.ts +18 -1
  391. package/dist/views/metadata-admin/previews/ReportPreview.js +23 -15
  392. package/dist/views/metadata-admin/previews/RolePreview.d.ts +19 -0
  393. package/dist/views/metadata-admin/previews/RolePreview.js +14 -0
  394. package/dist/views/metadata-admin/previews/SkillPreview.d.ts +22 -0
  395. package/dist/views/metadata-admin/previews/SkillPreview.js +34 -0
  396. package/dist/views/metadata-admin/previews/ToolPreview.d.ts +25 -0
  397. package/dist/views/metadata-admin/previews/ToolPreview.js +122 -0
  398. package/dist/views/metadata-admin/previews/TranslationPreview.d.ts +25 -0
  399. package/dist/views/metadata-admin/previews/TranslationPreview.js +52 -0
  400. package/dist/views/metadata-admin/previews/ValidationPreview.d.ts +27 -0
  401. package/dist/views/metadata-admin/previews/ValidationPreview.js +110 -0
  402. package/dist/views/metadata-admin/previews/ViewColumnPanes.d.ts +62 -0
  403. package/dist/views/metadata-admin/previews/ViewColumnPanes.js +140 -0
  404. package/dist/views/metadata-admin/previews/ViewPreview.d.ts +23 -1
  405. package/dist/views/metadata-admin/previews/ViewPreview.js +101 -73
  406. package/dist/views/metadata-admin/previews/block-config.d.ts +82 -0
  407. package/dist/views/metadata-admin/previews/block-config.js +324 -0
  408. package/dist/views/metadata-admin/previews/block-types.d.ts +40 -0
  409. package/dist/views/metadata-admin/previews/block-types.js +110 -0
  410. package/dist/views/metadata-admin/previews/field-types.d.ts +53 -0
  411. package/dist/views/metadata-admin/previews/field-types.js +97 -0
  412. package/dist/views/metadata-admin/previews/flow-canvas-layout.d.ts +88 -0
  413. package/dist/views/metadata-admin/previews/flow-canvas-layout.js +190 -0
  414. package/dist/views/metadata-admin/previews/flow-canvas-parts.d.ts +88 -0
  415. package/dist/views/metadata-admin/previews/flow-canvas-parts.js +358 -0
  416. package/dist/views/metadata-admin/previews/form-preview.d.ts +24 -0
  417. package/dist/views/metadata-admin/previews/form-preview.js +29 -0
  418. package/dist/views/metadata-admin/previews/index.js +43 -0
  419. package/dist/views/metadata-admin/previews/object-fields-bridge.d.ts +66 -0
  420. package/dist/views/metadata-admin/previews/object-fields-bridge.js +171 -0
  421. package/dist/views/metadata-admin/previews/object-fields-io.d.ts +109 -0
  422. package/dist/views/metadata-admin/previews/object-fields-io.js +208 -0
  423. package/dist/views/metadata-admin/previews/simulator/flow-sim-types.d.ts +91 -0
  424. package/dist/views/metadata-admin/previews/simulator/flow-sim-types.js +2 -0
  425. package/dist/views/metadata-admin/previews/simulator/flow-sim-validate.d.ts +8 -0
  426. package/dist/views/metadata-admin/previews/simulator/flow-sim-validate.js +113 -0
  427. package/dist/views/metadata-admin/previews/simulator/flow-simulator.d.ts +44 -0
  428. package/dist/views/metadata-admin/previews/simulator/flow-simulator.js +316 -0
  429. package/dist/views/metadata-admin/previews/useDatasetCatalog.d.ts +47 -0
  430. package/dist/views/metadata-admin/previews/useDatasetCatalog.js +133 -0
  431. package/dist/views/metadata-admin/previews/useFlowNodePalette.d.ts +44 -0
  432. package/dist/views/metadata-admin/previews/useFlowNodePalette.js +124 -0
  433. package/dist/views/metadata-admin/previews/useMetaOptions.d.ts +8 -0
  434. package/dist/views/metadata-admin/previews/useMetaOptions.js +50 -0
  435. package/dist/views/metadata-admin/previews/useObjectFields.d.ts +23 -0
  436. package/dist/views/metadata-admin/previews/useObjectFields.js +79 -0
  437. package/dist/views/metadata-admin/previews/useObjectOptions.d.ts +8 -0
  438. package/dist/views/metadata-admin/previews/useObjectOptions.js +43 -0
  439. package/dist/views/metadata-admin/previews/view-column-io.d.ts +42 -0
  440. package/dist/views/metadata-admin/previews/view-column-io.js +73 -0
  441. package/dist/views/metadata-admin/previews/widget-types.d.ts +24 -0
  442. package/dist/views/metadata-admin/previews/widget-types.js +40 -0
  443. package/dist/views/metadata-admin/registry.d.ts +140 -19
  444. package/dist/views/metadata-admin/report-schema.d.ts +26 -0
  445. package/dist/views/metadata-admin/report-schema.js +121 -0
  446. package/dist/views/metadata-admin/useMetadata.d.ts +100 -2
  447. package/dist/views/metadata-admin/useMetadata.js +155 -4
  448. package/dist/views/metadata-admin/view-item-normalize.d.ts +20 -0
  449. package/dist/views/metadata-admin/view-item-normalize.js +68 -0
  450. package/dist/views/metadata-admin/view-schema.d.ts +16 -0
  451. package/dist/views/metadata-admin/view-schema.js +107 -0
  452. package/dist/views/metadata-admin/view-variant-model.d.ts +23 -0
  453. package/dist/views/metadata-admin/view-variant-model.js +64 -0
  454. package/dist/views/metadata-admin/widgets.d.ts +89 -1
  455. package/dist/views/metadata-admin/widgets.js +491 -17
  456. package/dist/views/runtime-metadata-persistence.d.ts +78 -0
  457. package/dist/views/runtime-metadata-persistence.js +89 -0
  458. package/dist/views/useOpenRecordList.d.ts +18 -0
  459. package/dist/views/useOpenRecordList.js +36 -0
  460. package/dist/views/userFilterUrlState.d.ts +15 -0
  461. package/dist/views/userFilterUrlState.js +53 -0
  462. package/dist/views/view-config-adapter.d.ts +38 -0
  463. package/dist/views/view-config-adapter.js +80 -0
  464. package/package.json +52 -34
  465. package/dist/views/DesignDrawer.d.ts +0 -28
  466. package/dist/views/DesignDrawer.js +0 -51
  467. package/dist/views/metadata-admin/DesignerEditorWrapper.d.ts +0 -68
  468. 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
+ * FlowRunsPanel — run history for a flow, fetched from the automation engine
5
+ * (`GET /api/v1/automation/{name}/runs`, the observability surface next to
6
+ * resume/screen). Renders each run's status / start time / duration with an
7
+ * expandable per-node step log (the `ExecutionLog.steps` ADR-0019/#1479 shape),
8
+ * so authors can see where a run paused or failed without leaving the Studio.
9
+ *
10
+ * Degrades like the palette fetch: offline / plugin-absent / older backend →
11
+ * a quiet "history unavailable" note, never an error state that blocks the
12
+ * designer.
13
+ */
14
+ import * as React from 'react';
15
+ import { AlertCircle, CheckCircle2, ChevronDown, ChevronRight, Clock, Loader2, PauseCircle, RefreshCw, SkipForward } from 'lucide-react';
16
+ import { cn } from '@object-ui/components';
17
+ import { apiBase } from './useFlowNodePalette';
18
+ /** Fetch a flow's run history. Exposed for tests. */
19
+ export async function fetchFlowRuns(flowName, signal) {
20
+ try {
21
+ const res = await fetch(`${apiBase()}/automation/${encodeURIComponent(flowName)}/runs?limit=25`, { credentials: 'include', headers: { 'Content-Type': 'application/json' }, signal });
22
+ if (!res.ok)
23
+ return null; // 404/501 — plugin absent or older backend
24
+ const payload = (await res.json());
25
+ const runs = payload?.data?.runs ?? payload?.runs;
26
+ return Array.isArray(runs) ? runs : null;
27
+ }
28
+ catch {
29
+ return null; // offline / aborted
30
+ }
31
+ }
32
+ const STATUS_META = {
33
+ completed: { icon: CheckCircle2, cls: 'text-emerald-600 dark:text-emerald-400', label: 'Completed' },
34
+ failed: { icon: AlertCircle, cls: 'text-rose-600 dark:text-rose-400', label: 'Failed' },
35
+ paused: { icon: PauseCircle, cls: 'text-amber-600 dark:text-amber-400', label: 'Paused' },
36
+ running: { icon: Loader2, cls: 'text-sky-600 dark:text-sky-400', label: 'Running' },
37
+ cancelled: { icon: SkipForward, cls: 'text-muted-foreground', label: 'Cancelled' },
38
+ };
39
+ function statusMeta(status) {
40
+ return STATUS_META[status] ?? { icon: Clock, cls: 'text-muted-foreground', label: status };
41
+ }
42
+ function fmtTime(iso) {
43
+ if (!iso)
44
+ return '—';
45
+ const d = new Date(iso);
46
+ return Number.isNaN(d.getTime()) ? iso : d.toLocaleString();
47
+ }
48
+ function fmtDuration(ms) {
49
+ if (ms == null)
50
+ return null;
51
+ if (ms < 1000)
52
+ return `${ms}ms`;
53
+ if (ms < 60000)
54
+ return `${(ms / 1000).toFixed(1)}s`;
55
+ return `${Math.round(ms / 60000)}m`;
56
+ }
57
+ function StepRow({ step }) {
58
+ const cls = step.status === 'success'
59
+ ? 'text-emerald-600 dark:text-emerald-400'
60
+ : step.status === 'failure'
61
+ ? 'text-rose-600 dark:text-rose-400'
62
+ : 'text-muted-foreground';
63
+ return (_jsxs("li", { className: "flex items-baseline gap-1.5 py-0.5", children: [_jsx("span", { className: cn('shrink-0 text-[9px] font-semibold uppercase', cls), children: step.status }), _jsx("span", { className: "truncate font-mono text-[10px]", title: step.nodeId, children: step.nodeId }), step.nodeType && _jsx("span", { className: "shrink-0 text-[9px] uppercase text-muted-foreground", children: step.nodeType }), fmtDuration(step.durationMs) && (_jsx("span", { className: "ml-auto shrink-0 text-[9px] text-muted-foreground", children: fmtDuration(step.durationMs) })), step.error?.message && (_jsx("span", { className: "min-w-0 truncate text-[9px] text-rose-600", title: step.error.message, children: step.error.message }))] }));
64
+ }
65
+ function RunRow({ run }) {
66
+ const [open, setOpen] = React.useState(false);
67
+ const meta = statusMeta(run.status);
68
+ const Icon = meta.icon;
69
+ const steps = Array.isArray(run.steps) ? run.steps : [];
70
+ return (_jsxs("li", { className: "rounded border bg-background", children: [_jsxs("button", { type: "button", onClick: () => setOpen((v) => !v), className: "flex w-full items-center gap-1.5 p-1.5 text-left", "aria-expanded": open, children: [open ? (_jsx(ChevronDown, { className: "h-3 w-3 shrink-0 text-muted-foreground" })) : (_jsx(ChevronRight, { className: "h-3 w-3 shrink-0 text-muted-foreground" })), _jsx(Icon, { className: cn('h-3.5 w-3.5 shrink-0', meta.cls, run.status === 'running' && 'animate-spin') }), _jsx("span", { className: cn('shrink-0 text-[10px] font-semibold', meta.cls), children: meta.label }), _jsx("span", { className: "min-w-0 truncate text-[10px] text-muted-foreground", title: run.id, children: fmtTime(run.startedAt) }), fmtDuration(run.durationMs) && (_jsx("span", { className: "ml-auto shrink-0 text-[10px] text-muted-foreground", children: fmtDuration(run.durationMs) }))] }), open && (_jsxs("div", { className: "border-t px-2 py-1.5", children: [_jsxs("div", { className: "pb-1 font-mono text-[9px] text-muted-foreground", title: run.id, children: ["run ", run.id, run.trigger?.type && ` · trigger ${run.trigger.type}`] }), run.error?.message && (_jsx("div", { className: "pb-1 text-[10px] text-rose-600", children: run.error.message })), steps.length === 0 ? (_jsx("div", { className: "text-[10px] italic text-muted-foreground", children: "No step log recorded." })) : (_jsx("ul", { className: "divide-y divide-border/50", children: steps.map((s, i) => (_jsx(StepRow, { step: s }, `${s.nodeId}#${i}`))) }))] }))] }));
71
+ }
72
+ export function FlowRunsPanel({ flowName }) {
73
+ const [runs, setRuns] = React.useState([]);
74
+ const [state, setState] = React.useState('loading');
75
+ const [reloadKey, setReloadKey] = React.useState(0);
76
+ React.useEffect(() => {
77
+ const controller = new AbortController();
78
+ let alive = true;
79
+ setState('loading');
80
+ (async () => {
81
+ const result = await fetchFlowRuns(flowName, controller.signal);
82
+ if (!alive)
83
+ return;
84
+ if (result === null)
85
+ setState('unavailable');
86
+ else {
87
+ setRuns(result);
88
+ setState('ready');
89
+ }
90
+ })();
91
+ return () => {
92
+ alive = false;
93
+ controller.abort();
94
+ };
95
+ }, [flowName, reloadKey]);
96
+ return (_jsxs("div", { className: "flex h-full flex-col p-3 text-xs", children: [_jsxs("div", { className: "flex items-center gap-1.5 pb-2 font-medium text-muted-foreground", children: [_jsx(Clock, { className: "h-3 w-3" }), " Runs", _jsx("button", { type: "button", onClick: () => setReloadKey((k) => k + 1), title: "Refresh run history", "aria-label": "Refresh run history", className: "ml-auto rounded p-0.5 text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground", children: _jsx(RefreshCw, { className: cn('h-3 w-3', state === 'loading' && 'animate-spin') }) })] }), state === 'unavailable' ? (_jsx("div", { className: "italic text-muted-foreground", children: "Run history unavailable \u2014 the automation engine is offline or this flow hasn\u2019t been published." })) : state === 'ready' && runs.length === 0 ? (_jsx("div", { className: "italic text-muted-foreground", children: "No runs yet." })) : (_jsx("ul", { className: "min-h-0 flex-1 space-y-1.5 overflow-y-auto", children: runs.map((r) => (_jsx(RunRow, { run: r }, r.id))) }))] }));
97
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * FlowSimulatorPanel — the designer-time debug runner UI. Drives a
3
+ * `FlowSimulator` (pure engine) and lifts its highlight state up so the canvas
4
+ * can paint the active node / traversed edges. Side effects are mocked; the
5
+ * panel only collects the flow's input variables as the run seed.
6
+ */
7
+ import * as React from 'react';
8
+ import type { SimEdge, SimNode } from './simulator/flow-sim-types';
9
+ export interface FlowVariableDecl {
10
+ name: string;
11
+ type?: string;
12
+ defaultValue?: unknown;
13
+ isInput?: boolean;
14
+ }
15
+ export interface FlowSimulatorPanelProps {
16
+ nodes: SimNode[];
17
+ edges: SimEdge[];
18
+ variables: FlowVariableDecl[];
19
+ onRunStateChange?: (s: {
20
+ activeNodeId: string | null;
21
+ visitedNodeIds: string[];
22
+ traversedEdgeIds: string[];
23
+ } | null) => void;
24
+ }
25
+ export declare function FlowSimulatorPanel({ nodes, edges, variables, onRunStateChange }: FlowSimulatorPanelProps): React.JSX.Element;
@@ -0,0 +1,170 @@
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
+ * FlowSimulatorPanel — the designer-time debug runner UI. Drives a
5
+ * `FlowSimulator` (pure engine) and lifts its highlight state up so the canvas
6
+ * can paint the active node / traversed edges. Side effects are mocked; the
7
+ * panel only collects the flow's input variables as the run seed.
8
+ */
9
+ import * as React from 'react';
10
+ import { Play, StepForward, RotateCcw, ChevronRight, AlertTriangle, CircleAlert, Plus, Trash2 } from 'lucide-react';
11
+ import { Button, Input, Label, cn } from '@object-ui/components';
12
+ import { FlowSimulator } from './simulator/flow-simulator';
13
+ /** Coerce a free-text seed value: number / boolean / JSON object|array / string. */
14
+ function parseSeed(raw) {
15
+ const s = raw.trim();
16
+ if (s === '')
17
+ return undefined;
18
+ if (s === 'true')
19
+ return true;
20
+ if (s === 'false')
21
+ return false;
22
+ if (/^-?\d+(\.\d+)?$/.test(s))
23
+ return Number(s);
24
+ if ((s.startsWith('{') && s.endsWith('}')) || (s.startsWith('[') && s.endsWith(']'))) {
25
+ try {
26
+ return JSON.parse(s);
27
+ }
28
+ catch {
29
+ return raw;
30
+ }
31
+ }
32
+ return raw;
33
+ }
34
+ /** Node types whose side effects are mocked — authors can pin their output. */
35
+ const MOCKABLE = new Set([
36
+ 'create_record',
37
+ 'update_record',
38
+ 'delete_record',
39
+ 'get_record',
40
+ 'http_request',
41
+ 'connector_action',
42
+ 'script',
43
+ ]);
44
+ function mockableNodes(nodes) {
45
+ const out = [];
46
+ for (const n of nodes) {
47
+ if (!MOCKABLE.has(n.type))
48
+ continue;
49
+ const cfg = (n.config ?? {});
50
+ const outputs = [];
51
+ if (typeof cfg.outputVariable === 'string' && cfg.outputVariable)
52
+ outputs.push(cfg.outputVariable);
53
+ if (Array.isArray(cfg.outputVariables)) {
54
+ for (const o of cfg.outputVariables)
55
+ if (typeof o === 'string')
56
+ outputs.push(o);
57
+ }
58
+ out.push({ id: n.id, label: n.label || n.id, type: n.type, outputs });
59
+ }
60
+ return out;
61
+ }
62
+ const STATUS_TONE = {
63
+ ok: 'bg-emerald-100 text-emerald-700',
64
+ mocked: 'bg-violet-100 text-violet-700',
65
+ paused: 'bg-amber-100 text-amber-700',
66
+ skipped: 'bg-zinc-100 text-zinc-600',
67
+ error: 'bg-rose-100 text-rose-700',
68
+ };
69
+ export function FlowSimulatorPanel({ nodes, edges, variables, onRunStateChange }) {
70
+ const simRef = React.useRef(null);
71
+ const [snapshot, setSnapshot] = React.useState(null);
72
+ const [validation, setValidation] = React.useState(null);
73
+ const inputs = React.useMemo(() => variables.filter((v) => v.isInput), [variables]);
74
+ const mockNodes = React.useMemo(() => mockableNodes(nodes), [nodes]);
75
+ const [seed, setSeed] = React.useState({});
76
+ /** Free-form variable overrides so any branch can be exercised (e.g. a
77
+ * decision that reads a computed value no input declares). */
78
+ const [scratch, setScratch] = React.useState([]);
79
+ /** Per-node mock outputs, keyed by node id (raw text, parsed on run). */
80
+ const [mocks, setMocks] = React.useState({});
81
+ const sync = React.useCallback(() => {
82
+ const sim = simRef.current;
83
+ if (!sim)
84
+ return;
85
+ const st = sim.state;
86
+ setSnapshot({
87
+ ...st,
88
+ steps: [...st.steps],
89
+ variables: { ...st.variables },
90
+ frontier: [...st.frontier],
91
+ visitedNodeIds: [...st.visitedNodeIds],
92
+ traversedEdgeIds: [...st.traversedEdgeIds],
93
+ });
94
+ onRunStateChange?.({
95
+ activeNodeId: st.activeNodeId,
96
+ visitedNodeIds: [...st.visitedNodeIds],
97
+ traversedEdgeIds: [...st.traversedEdgeIds],
98
+ });
99
+ }, [onRunStateChange]);
100
+ const buildSeed = React.useCallback(() => {
101
+ const out = {};
102
+ for (const v of inputs) {
103
+ const raw = seed[v.name];
104
+ const parsed = raw != null ? parseSeed(raw) : undefined;
105
+ out[v.name] = parsed !== undefined ? parsed : v.defaultValue;
106
+ }
107
+ // Scratch overrides win — they let an author drive any branch.
108
+ for (const row of scratch) {
109
+ const key = row.k.trim();
110
+ if (key)
111
+ out[key] = parseSeed(row.v);
112
+ }
113
+ return out;
114
+ }, [inputs, seed, scratch]);
115
+ const buildMocks = React.useCallback(() => {
116
+ const out = {};
117
+ for (const [id, raw] of Object.entries(mocks)) {
118
+ if (raw != null && raw.trim() !== '')
119
+ out[id] = parseSeed(raw);
120
+ }
121
+ return out;
122
+ }, [mocks]);
123
+ const reset = React.useCallback(() => {
124
+ const sim = new FlowSimulator(nodes, edges);
125
+ simRef.current = sim;
126
+ setValidation(sim.reset(buildSeed(), buildMocks()));
127
+ sync();
128
+ }, [nodes, edges, buildSeed, buildMocks, sync]);
129
+ const ensure = React.useCallback(() => {
130
+ if (!simRef.current)
131
+ reset();
132
+ return simRef.current;
133
+ }, [reset]);
134
+ const onRun = () => {
135
+ // A paused run (wait / screen) continues from where it halted. Any other
136
+ // state — fresh, done, or errored — starts a clean run that re-seeds with
137
+ // the current Set-variables and Mock-outputs editors, so editing them and
138
+ // pressing Run again always reflects the new values.
139
+ let sim = simRef.current;
140
+ if (sim && sim.state.status === 'paused') {
141
+ sim.resume();
142
+ }
143
+ else {
144
+ reset();
145
+ sim = simRef.current;
146
+ }
147
+ sim.runToEnd();
148
+ sync();
149
+ };
150
+ const onStep = () => {
151
+ const sim = ensure();
152
+ sim.step();
153
+ sync();
154
+ };
155
+ const onResume = () => {
156
+ const sim = ensure();
157
+ sim.resume();
158
+ sim.runToEnd();
159
+ sync();
160
+ };
161
+ const onReset = () => {
162
+ simRef.current = null;
163
+ setSnapshot(null);
164
+ setValidation(null);
165
+ onRunStateChange?.(null);
166
+ };
167
+ const status = snapshot?.status ?? 'idle';
168
+ const blocked = (validation?.errors.length ?? 0) > 0;
169
+ return (_jsxs("div", { className: "flex h-full flex-col text-xs", children: [_jsxs("div", { className: "flex items-center gap-1.5 border-b bg-muted/30 px-3 py-2", children: [_jsxs(Button, { size: "sm", className: "h-7 gap-1 px-2", onClick: onRun, disabled: blocked, children: [_jsx(Play, { className: "h-3.5 w-3.5" }), " Run"] }), _jsxs(Button, { size: "sm", variant: "outline", className: "h-7 gap-1 px-2", onClick: onStep, disabled: blocked || status === 'done' || status === 'error', children: [_jsx(StepForward, { className: "h-3.5 w-3.5" }), " Step"] }), status === 'paused' && (_jsxs(Button, { size: "sm", variant: "outline", className: "h-7 gap-1 px-2", onClick: onResume, children: [_jsx(ChevronRight, { className: "h-3.5 w-3.5" }), " Continue"] })), _jsxs(Button, { size: "sm", variant: "ghost", className: "h-7 gap-1 px-2 text-muted-foreground", onClick: onReset, children: [_jsx(RotateCcw, { className: "h-3.5 w-3.5" }), " Reset"] }), _jsx("span", { className: cn('ml-auto rounded px-1.5 py-0.5 text-[10px] font-semibold uppercase', STATUS_TONE[status === 'idle' || status === 'running' ? 'ok' : status] ?? 'bg-muted'), children: status })] }), _jsxs("div", { className: "min-h-0 flex-1 space-y-3 overflow-auto p-3", children: [validation && (validation.errors.length > 0 || validation.warnings.length > 0) && (_jsxs("div", { className: "space-y-1", children: [validation.errors.map((d, i) => (_jsxs("div", { className: "flex items-start gap-1.5 rounded border border-rose-200 bg-rose-50 px-2 py-1 text-rose-700", children: [_jsx(CircleAlert, { className: "mt-0.5 h-3 w-3 shrink-0" }), _jsx("span", { children: d.message })] }, `e${i}`))), validation.warnings.map((d, i) => (_jsxs("div", { className: "flex items-start gap-1.5 rounded border border-amber-200 bg-amber-50 px-2 py-1 text-amber-700", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-3 w-3 shrink-0" }), _jsx("span", { children: d.message })] }, `w${i}`)))] })), inputs.length > 0 && (_jsxs("section", { className: "space-y-1.5", children: [_jsx("div", { className: "font-medium text-muted-foreground", children: "Inputs" }), inputs.map((v) => (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Label, { className: "w-24 shrink-0 truncate font-mono text-[11px]", title: v.name, children: v.name }), _jsx(Input, { value: seed[v.name] ?? (v.defaultValue != null ? String(v.defaultValue) : ''), onChange: (e) => setSeed((p) => ({ ...p, [v.name]: e.target.value })), placeholder: v.type ?? 'value', className: "h-7 flex-1 text-xs" })] }, v.name)))] })), _jsxs("section", { className: "space-y-1.5", children: [_jsxs("div", { className: "flex items-center gap-1.5 font-medium text-muted-foreground", children: [_jsx("span", { children: "Set variables" }), _jsxs("button", { type: "button", className: "ml-auto inline-flex items-center gap-0.5 rounded border px-1.5 py-0.5 text-[10px] hover:bg-muted/50", onClick: () => setScratch((p) => [...p, { k: '', v: '' }]), children: [_jsx(Plus, { className: "h-3 w-3" }), " Add"] })] }), scratch.length === 0 ? (_jsx("div", { className: "italic text-muted-foreground", children: "Override or inject any variable (wins over inputs and mocks at start)." })) : (scratch.map((row, i) => (_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx(Input, { value: row.k, onChange: (e) => setScratch((p) => p.map((r, j) => (j === i ? { ...r, k: e.target.value } : r))), placeholder: "name", className: "h-7 w-24 shrink-0 font-mono text-[11px]" }), _jsx("span", { className: "text-muted-foreground", children: "=" }), _jsx(Input, { value: row.v, onChange: (e) => setScratch((p) => p.map((r, j) => (j === i ? { ...r, v: e.target.value } : r))), placeholder: "value", className: "h-7 flex-1 text-xs" }), _jsx("button", { type: "button", className: "shrink-0 rounded p-1 text-muted-foreground hover:bg-muted/50 hover:text-rose-600", onClick: () => setScratch((p) => p.filter((_, j) => j !== i)), "aria-label": "Remove variable", children: _jsx(Trash2, { className: "h-3 w-3" }) })] }, i))))] }), mockNodes.length > 0 && (_jsxs("section", { className: "space-y-1.5", children: [_jsx("div", { className: "font-medium text-muted-foreground", children: "Mock outputs" }), mockNodes.map((m) => (_jsxs("div", { className: "space-y-0.5", children: [_jsxs(Label, { className: "flex items-baseline gap-1.5 text-[11px]", title: m.id, children: [_jsx("span", { className: "truncate font-medium", children: m.label }), _jsx("span", { className: "text-[9px] uppercase text-muted-foreground", children: m.type.replace(/_/g, ' ') }), m.outputs.length > 0 && (_jsxs("span", { className: "truncate font-mono text-[10px] text-violet-600", children: ["\u2192 ", m.outputs.join(', ')] }))] }), _jsx(Input, { value: mocks[m.id] ?? '', onChange: (e) => setMocks((p) => ({ ...p, [m.id]: e.target.value })), placeholder: m.type === 'script' && m.outputs.length ? `{ "${m.outputs[0]}": … }` : 'mocked result (JSON)', className: "h-7 w-full font-mono text-[11px]" })] }, m.id)))] })), snapshot && (_jsxs("section", { className: "space-y-1.5", children: [_jsx("div", { className: "font-medium text-muted-foreground", children: "Variables" }), Object.keys(snapshot.variables).length === 0 ? (_jsx("div", { className: "italic text-muted-foreground", children: "No variables set." })) : (_jsx("ul", { className: "space-y-1", children: Object.entries(snapshot.variables).map(([k, val]) => (_jsxs("li", { className: "flex items-baseline gap-1.5 rounded border bg-background px-1.5 py-1", children: [_jsx("span", { className: "font-mono text-[11px]", children: k }), _jsxs("span", { className: "truncate font-mono text-[10px] text-muted-foreground", children: ["= ", typeof val === 'object' ? JSON.stringify(val) : String(val)] })] }, k))) }))] })), snapshot && snapshot.steps.length > 0 && (_jsxs("section", { className: "space-y-1.5", children: [_jsx("div", { className: "font-medium text-muted-foreground", children: "Timeline" }), _jsx("ol", { className: "space-y-1", children: snapshot.steps.map((s) => (_jsxs("li", { className: "rounded border bg-background p-1.5", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: "font-mono text-[10px] text-muted-foreground", children: s.seq + 1 }), _jsx("span", { className: "truncate font-medium", children: s.label }), _jsx("span", { className: "text-[10px] uppercase text-muted-foreground", children: s.type }), _jsx("span", { className: cn('ml-auto rounded px-1 py-0.5 text-[9px] font-semibold uppercase', STATUS_TONE[s.status]), children: s.status })] }), s.note && _jsx("div", { className: "mt-0.5 text-[10px] text-muted-foreground", children: s.note }), s.error && _jsx("div", { className: "mt-0.5 text-[10px] text-rose-600", children: s.error }), s.wrote && (_jsxs("div", { className: "mt-0.5 truncate font-mono text-[10px] text-violet-600", children: ["\u2192 ", Object.keys(s.wrote).join(', ')] })), s.edges && s.edges.length > 0 && (_jsx("ul", { className: "mt-0.5 space-y-0.5", children: s.edges.map((ed) => (_jsxs("li", { className: "space-y-0.5", children: [_jsxs("div", { className: cn('flex items-center gap-1 font-mono text-[10px]', ed.selected ? 'text-sky-700' : 'text-muted-foreground'), children: [_jsx("span", { children: ed.selected ? '▶' : '·' }), _jsx("span", { className: "truncate", children: ed.isDefault ? 'else' : ed.condition }), _jsx("span", { className: cn('ml-auto', ed.error && 'text-rose-600'), children: ed.error ? 'error' : ed.result ? 'true' : 'false' })] }), ed.error && _jsx("div", { className: "pl-3 text-[10px] text-rose-600", children: ed.error })] }, ed.edgeId))) }))] }, s.seq))) })] })), !snapshot && !blocked && (_jsx("p", { className: "italic text-muted-foreground", children: "Press Run to simulate, or Step to walk node by node. Side effects are mocked \u2014 no backend is called." }))] })] }));
170
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * JobPreview — read-only summary of a Background Job draft.
3
+ *
4
+ * Canonical shape (see `packages/spec/src/system/job.zod.ts`):
5
+ * schedule: { type: 'cron', expression: string | { dialect:'cron', source:string }, timezone? }
6
+ * | { type: 'interval', intervalMs: number }
7
+ * | { type: 'once', at: string (ISO) }
8
+ * handler: string — function key registered in defineStack({ functions })
9
+ * retryPolicy?: { maxRetries, backoffMs, backoffMultiplier }
10
+ * timeout?: number (ms)
11
+ * enabled?: boolean
12
+ *
13
+ * Legacy / app-supplied flat shapes are also tolerated:
14
+ * • `cron` (string) — top-level cron expression
15
+ * • `every` / `interval` — interval like "5m" or millis number
16
+ * • `at` / `runAs` — one-shot ISO
17
+ * • `timezone` / `tz`
18
+ * • `active` / `enabled`
19
+ *
20
+ * For cron schedules we compute the **next 5 fire times** locally so
21
+ * operators can sanity-check the schedule without waiting for the
22
+ * runtime. The cron parser handles standard 5-field cron with `*`,
23
+ * `*\/N`, comma lists, and ranges (`a-b`). Special tokens like
24
+ * `@daily` / `@hourly` are also expanded.
25
+ */
26
+ import * as React from 'react';
27
+ import type { MetadataPreviewProps } from '../preview-registry';
28
+ export declare function JobPreview({ name, draft }: MetadataPreviewProps): React.JSX.Element;
@@ -0,0 +1,290 @@
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
+ * JobPreview — read-only summary of a Background Job draft.
5
+ *
6
+ * Canonical shape (see `packages/spec/src/system/job.zod.ts`):
7
+ * schedule: { type: 'cron', expression: string | { dialect:'cron', source:string }, timezone? }
8
+ * | { type: 'interval', intervalMs: number }
9
+ * | { type: 'once', at: string (ISO) }
10
+ * handler: string — function key registered in defineStack({ functions })
11
+ * retryPolicy?: { maxRetries, backoffMs, backoffMultiplier }
12
+ * timeout?: number (ms)
13
+ * enabled?: boolean
14
+ *
15
+ * Legacy / app-supplied flat shapes are also tolerated:
16
+ * • `cron` (string) — top-level cron expression
17
+ * • `every` / `interval` — interval like "5m" or millis number
18
+ * • `at` / `runAs` — one-shot ISO
19
+ * • `timezone` / `tz`
20
+ * • `active` / `enabled`
21
+ *
22
+ * For cron schedules we compute the **next 5 fire times** locally so
23
+ * operators can sanity-check the schedule without waiting for the
24
+ * runtime. The cron parser handles standard 5-field cron with `*`,
25
+ * `*\/N`, comma lists, and ranges (`a-b`). Special tokens like
26
+ * `@daily` / `@hourly` are also expanded.
27
+ */
28
+ import * as React from 'react';
29
+ import { AlarmClock, Calendar, Clock, Code2, Globe2, PlayCircle, Power, RotateCcw, Timer, } from 'lucide-react';
30
+ import { PreviewShell, PreviewMessage, PreviewErrorBoundary } from './PreviewShell';
31
+ const CRON_ALIASES = {
32
+ '@yearly': '0 0 1 1 *',
33
+ '@annually': '0 0 1 1 *',
34
+ '@monthly': '0 0 1 * *',
35
+ '@weekly': '0 0 * * 0',
36
+ '@daily': '0 0 * * *',
37
+ '@midnight': '0 0 * * *',
38
+ '@hourly': '0 * * * *',
39
+ };
40
+ function parseCronField(raw, min, max) {
41
+ const out = { values: new Set(), any: false };
42
+ if (raw === '*') {
43
+ for (let i = min; i <= max; i++)
44
+ out.values.add(i);
45
+ out.any = true;
46
+ return out;
47
+ }
48
+ for (const part of raw.split(',')) {
49
+ let stepStr;
50
+ let body = part;
51
+ if (part.includes('/')) {
52
+ const [b, s] = part.split('/');
53
+ body = b;
54
+ stepStr = s;
55
+ }
56
+ const step = stepStr ? Math.max(1, parseInt(stepStr, 10) || 1) : 1;
57
+ let lo = min;
58
+ let hi = max;
59
+ if (body !== '*') {
60
+ if (body.includes('-')) {
61
+ const [a, b] = body.split('-').map((n) => parseInt(n, 10));
62
+ if (Number.isNaN(a) || Number.isNaN(b))
63
+ return null;
64
+ lo = a;
65
+ hi = b;
66
+ }
67
+ else {
68
+ const v = parseInt(body, 10);
69
+ if (Number.isNaN(v))
70
+ return null;
71
+ lo = v;
72
+ hi = v;
73
+ }
74
+ }
75
+ for (let i = lo; i <= hi; i += step) {
76
+ if (i >= min && i <= max)
77
+ out.values.add(i);
78
+ }
79
+ }
80
+ return out;
81
+ }
82
+ function parseCron(expr) {
83
+ const aliased = CRON_ALIASES[expr.trim()] ?? expr.trim();
84
+ const parts = aliased.split(/\s+/);
85
+ if (parts.length !== 5 && parts.length !== 6)
86
+ return null;
87
+ // Strip optional 6th seconds field — we ignore second-resolution for preview.
88
+ const fields = parts.length === 6 ? parts.slice(1) : parts;
89
+ const [m, h, dom, mon, dow] = fields;
90
+ const minute = parseCronField(m, 0, 59);
91
+ const hour = parseCronField(h, 0, 23);
92
+ const domF = parseCronField(dom, 1, 31);
93
+ const month = parseCronField(mon, 1, 12);
94
+ const dowF = parseCronField(dow === '7' ? '0' : dow, 0, 6);
95
+ if (!minute || !hour || !domF || !month || !dowF)
96
+ return null;
97
+ return { minute, hour, dom: domF, month, dow: dowF };
98
+ }
99
+ function nextCronFires(expr, from, count) {
100
+ const cron = parseCron(expr);
101
+ if (!cron)
102
+ return [];
103
+ const results = [];
104
+ // Walk minute by minute up to ~366 days; bail early once we hit count.
105
+ const cursor = new Date(from.getTime());
106
+ cursor.setSeconds(0, 0);
107
+ cursor.setMinutes(cursor.getMinutes() + 1);
108
+ const limitMs = 366 * 24 * 60 * 60 * 1000;
109
+ const endAt = from.getTime() + limitMs;
110
+ while (results.length < count && cursor.getTime() <= endAt) {
111
+ if (cron.minute.values.has(cursor.getMinutes()) &&
112
+ cron.hour.values.has(cursor.getHours()) &&
113
+ cron.month.values.has(cursor.getMonth() + 1) &&
114
+ // POSIX cron OR semantics: when both DOM and DOW are restricted,
115
+ // a match in EITHER triggers; when one is `*`, the other governs.
116
+ (cron.dom.any || cron.dow.any
117
+ ? cron.dom.values.has(cursor.getDate()) && cron.dow.values.has(cursor.getDay())
118
+ : cron.dom.values.has(cursor.getDate()) || cron.dow.values.has(cursor.getDay()))) {
119
+ results.push(new Date(cursor.getTime()));
120
+ }
121
+ cursor.setMinutes(cursor.getMinutes() + 1);
122
+ }
123
+ return results;
124
+ }
125
+ function parseInterval(every) {
126
+ const m = /^(\d+)\s*(ms|s|m|h|d)$/.exec(every.trim());
127
+ if (!m)
128
+ return null;
129
+ const n = parseInt(m[1], 10);
130
+ switch (m[2]) {
131
+ case 'ms':
132
+ return n;
133
+ case 's':
134
+ return n * 1000;
135
+ case 'm':
136
+ return n * 60000;
137
+ case 'h':
138
+ return n * 3600000;
139
+ case 'd':
140
+ return n * 86400000;
141
+ default:
142
+ return null;
143
+ }
144
+ }
145
+ function nextIntervalFires(intervalMs, from, count) {
146
+ const out = [];
147
+ for (let i = 1; i <= count; i++)
148
+ out.push(new Date(from.getTime() + i * intervalMs));
149
+ return out;
150
+ }
151
+ function formatWhen(d) {
152
+ return d.toLocaleString(undefined, {
153
+ weekday: 'short',
154
+ month: 'short',
155
+ day: '2-digit',
156
+ hour: '2-digit',
157
+ minute: '2-digit',
158
+ });
159
+ }
160
+ /**
161
+ * Normalize the canonical Schedule discriminated-union and legacy flat
162
+ * shapes into `{ cron?, every?, at?, timezone? }` for rendering.
163
+ *
164
+ * Supports:
165
+ * • d.schedule = { type:'cron', expression: string | {source}, timezone? }
166
+ * • d.schedule = { type:'interval', intervalMs: number }
167
+ * • d.schedule = { type:'once', at: string }
168
+ * • d.schedule = "0 9 * * 1-5" (legacy: string cron)
169
+ * • d.cron / d.every / d.interval / d.at / d.runAt / d.timezone / d.tz
170
+ */
171
+ function normalizeSchedule(d) {
172
+ // Canonical discriminated-union schedule object.
173
+ if (d.schedule && typeof d.schedule === 'object') {
174
+ const s = d.schedule;
175
+ const t = String(s.type ?? '');
176
+ const tz = s.timezone ?? d.timezone ?? d.tz;
177
+ if (t === 'cron') {
178
+ const expr = s.expression;
179
+ const src = typeof expr === 'string'
180
+ ? expr
181
+ : expr && typeof expr === 'object' && typeof expr.source === 'string'
182
+ ? expr.source
183
+ : undefined;
184
+ return { cron: src, timezone: tz };
185
+ }
186
+ if (t === 'interval') {
187
+ const ms = Number(s.intervalMs);
188
+ return { every: Number.isFinite(ms) && ms > 0 ? humanizeMs(ms) : undefined, timezone: tz };
189
+ }
190
+ if (t === 'once') {
191
+ return { at: typeof s.at === 'string' ? s.at : undefined, timezone: tz };
192
+ }
193
+ }
194
+ // Flat legacy shapes.
195
+ const cron = typeof d.cron === 'string'
196
+ ? d.cron
197
+ : typeof d.schedule === 'string'
198
+ ? d.schedule
199
+ : undefined;
200
+ const everyRaw = d.every ?? d.interval;
201
+ const every = typeof everyRaw === 'string'
202
+ ? everyRaw
203
+ : typeof everyRaw === 'number'
204
+ ? humanizeMs(everyRaw)
205
+ : undefined;
206
+ const at = typeof d.at === 'string' ? d.at : typeof d.runAt === 'string' ? d.runAt : undefined;
207
+ const timezone = d.timezone ?? d.tz;
208
+ return { cron, every, at, timezone };
209
+ }
210
+ function humanizeMs(ms) {
211
+ if (ms % 86400000 === 0)
212
+ return `${ms / 86400000}d`;
213
+ if (ms % 3600000 === 0)
214
+ return `${ms / 3600000}h`;
215
+ if (ms % 60000 === 0)
216
+ return `${ms / 60000}m`;
217
+ if (ms % 1000 === 0)
218
+ return `${ms / 1000}s`;
219
+ return `${ms}ms`;
220
+ }
221
+ export function JobPreview({ name, draft }) {
222
+ const d = draft;
223
+ const jobName = String(d.name ?? name ?? '');
224
+ const label = String(d.label ?? jobName);
225
+ const description = d.description ?? '';
226
+ const { cron, every, at, timezone } = normalizeSchedule(d);
227
+ const handler = d.handler
228
+ ?? d.target
229
+ ?? d.function
230
+ ?? d.functionName;
231
+ const active = d.active !== false && d.enabled !== false;
232
+ // Canonical: retryPolicy.{maxRetries,backoffMs,backoffMultiplier}; legacy: flat fields.
233
+ const retryPolicy = d.retryPolicy;
234
+ const maxRetries = retryPolicy?.maxRetries
235
+ ?? d.maxRetries
236
+ ?? d.retries;
237
+ const backoffMs = retryPolicy?.backoffMs;
238
+ const timeoutMs = d.timeout ?? d.timeoutMs;
239
+ const concurrency = d.concurrency;
240
+ const intervalMs = every ? parseInterval(every) : null;
241
+ const { nextFires, deltas } = React.useMemo(() => {
242
+ const now = new Date();
243
+ let fires = [];
244
+ if (cron)
245
+ fires = nextCronFires(cron, now, 5);
246
+ else if (intervalMs)
247
+ fires = nextIntervalFires(intervalMs, now, 5);
248
+ else if (at) {
249
+ const t = Date.parse(at);
250
+ if (!Number.isNaN(t))
251
+ fires = [new Date(t)];
252
+ }
253
+ return {
254
+ nextFires: fires,
255
+ deltas: fires.map((f) => humanDelta(f.getTime() - now.getTime())),
256
+ };
257
+ }, [cron, intervalMs, at]);
258
+ const scheduleInvalid = (cron && nextFires.length === 0) || (every && !intervalMs);
259
+ if (!jobName && !cron && !every && !at && !handler) {
260
+ return (_jsx(PreviewShell, { hint: "job", children: _jsx(PreviewMessage, { children: "Set a schedule (cron / every / at) and a handler to see the job preview." }) }));
261
+ }
262
+ return (_jsx(PreviewShell, { hint: "job", children: _jsx(PreviewErrorBoundary, { children: _jsxs("div", { className: "p-3 space-y-3", children: [_jsx("div", { className: "rounded border bg-muted/30 p-3", children: _jsxs("div", { className: "flex items-start gap-2", children: [_jsx(AlarmClock, { className: "h-4 w-4 mt-0.5 text-muted-foreground shrink-0" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex flex-wrap items-baseline gap-x-2", children: [_jsx("span", { className: "text-sm font-medium truncate", children: label }), _jsx("span", { className: "font-mono text-[10px] text-muted-foreground", children: jobName })] }), description && _jsx("div", { className: "text-xs text-muted-foreground mt-0.5", children: description }), _jsxs("div", { className: "mt-1 flex flex-wrap items-center gap-x-3 gap-y-1 text-[11px]", children: [_jsx(Pill, { icon: Power, label: active ? 'Active' : 'Paused', tone: active ? 'green' : 'gray' }), timezone && _jsx(Pill, { icon: Globe2, label: timezone, mono: true }), maxRetries != null && _jsx(Pill, { icon: RotateCcw, label: `retries: ${maxRetries}${backoffMs ? ` (${humanizeMs(backoffMs)} backoff)` : ''}` }), timeoutMs != null && _jsx(Pill, { icon: Timer, label: `timeout: ${humanizeMs(timeoutMs)}` }), concurrency != null && _jsx(Pill, { label: `concurrency: ${concurrency}` })] })] })] }) }), _jsx(Section, { title: "Schedule", icon: Calendar, children: _jsxs("div", { className: "rounded border bg-background p-2.5 text-xs space-y-1", children: [cron && (_jsx(ScheduleLine, { label: "Cron", children: _jsx("code", { className: "font-mono", children: cron }) })), every && (_jsxs(ScheduleLine, { label: "Every", children: [_jsx("code", { className: "font-mono", children: every }), !intervalMs && _jsx("span", { className: "ml-2 text-amber-700", children: "unparseable" })] })), at && (_jsx(ScheduleLine, { label: "At", children: _jsx("code", { className: "font-mono", children: at }) })), !cron && !every && !at && (_jsx("div", { className: "text-muted-foreground italic", children: "No schedule set \u2014 runs only when triggered manually." }))] }) }), (cron || intervalMs || at) && (_jsx(Section, { title: `Next ${Math.max(nextFires.length, 1)} run${nextFires.length === 1 ? '' : 's'}`, icon: Clock, children: nextFires.length === 0 ? (_jsx("div", { className: "text-xs text-amber-700", children: scheduleInvalid
263
+ ? 'Could not derive any future fire time. Check the schedule syntax.'
264
+ : 'No upcoming runs in the next 366 days.' })) : (_jsx("ul", { className: "rounded border bg-background divide-y text-xs", children: nextFires.map((d, i) => (_jsxs("li", { className: "flex items-center gap-2 px-2.5 py-1.5", children: [_jsx("span", { className: "w-4 text-right text-muted-foreground text-[10px]", children: i + 1 }), _jsx(Clock, { className: "h-3 w-3 text-muted-foreground" }), _jsx("span", { className: "font-mono", children: formatWhen(d) }), _jsxs("span", { className: "ml-auto text-[10px] text-muted-foreground", children: ["in ", deltas[i]] })] }, i))) })) })), _jsx(Section, { title: "Handler", icon: Code2, children: handler ? (_jsxs("div", { className: "rounded border bg-background px-2.5 py-1.5 text-xs flex items-center gap-2", children: [_jsx(PlayCircle, { className: "h-3.5 w-3.5 text-muted-foreground" }), _jsx("code", { className: "font-mono break-all", children: handler })] })) : (_jsx("div", { className: "text-xs text-amber-700", children: "No handler bound \u2014 the job will be a no-op." })) })] }) }) }));
265
+ }
266
+ function humanDelta(ms) {
267
+ if (ms <= 0)
268
+ return 'now';
269
+ const s = Math.round(ms / 1000);
270
+ if (s < 60)
271
+ return `${s}s`;
272
+ const m = Math.round(s / 60);
273
+ if (m < 60)
274
+ return `${m}m`;
275
+ const h = Math.round(m / 60);
276
+ if (h < 48)
277
+ return `${h}h`;
278
+ const days = Math.round(h / 24);
279
+ return `${days}d`;
280
+ }
281
+ function ScheduleLine({ label, children }) {
282
+ return (_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsxs("span", { className: "text-muted-foreground w-12 shrink-0", children: [label, ":"] }), _jsx("span", { className: "break-all", children: children })] }));
283
+ }
284
+ function Section({ title, icon: Icon, children, }) {
285
+ return (_jsxs("div", { className: "space-y-1.5", children: [_jsxs("div", { className: "flex items-center gap-1.5 text-[11px] font-medium text-muted-foreground uppercase tracking-wider", children: [Icon && _jsx(Icon, { className: "h-3 w-3" }), _jsx("span", { children: title })] }), children] }));
286
+ }
287
+ function Pill({ icon: Icon, label, tone = 'gray', mono = false, }) {
288
+ const cls = tone === 'green' ? 'text-emerald-700' : 'text-foreground';
289
+ return (_jsxs("span", { className: "inline-flex items-center gap-1", children: [Icon && _jsx(Icon, { className: "h-3 w-3 text-muted-foreground" }), _jsx("span", { className: `${cls} ${mono ? 'font-mono' : ''}`, children: label })] }));
290
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * ObjectFormCanvas — form-designer-style preview for an Object
3
+ * metadata draft. Replaces the legacy CRUD grid in DesignerMode.
4
+ *
5
+ * Each field renders as the labeled input it will become at runtime
6
+ * (via {@link FieldStub}). Clicking a row selects it and the host
7
+ * swaps the inspector to {@link ObjectFieldInspector}. The trailing
8
+ * "+ Add field" button opens a categorized type picker — picking a
9
+ * type appends a fresh field and immediately selects it so authors
10
+ * can fill in name/label in the inspector.
11
+ *
12
+ * All edits go through the host's `onPatch` callback. Read-only
13
+ * surfaces (legacy tier objects, builtin objects) still render the
14
+ * preview but suppress selection chrome + the add button.
15
+ */
16
+ import * as React from 'react';
17
+ import type { MetadataSelection } from '../preview-registry';
18
+ import { toFieldName } from './object-fields-io';
19
+ export interface ObjectFormCanvasProps {
20
+ objectName: string;
21
+ draft: Record<string, unknown>;
22
+ /** Last published version, for the review/diff mode. */
23
+ baseline?: Record<string, unknown>;
24
+ onPatch?: (patch: Record<string, unknown>) => void;
25
+ selection?: MetadataSelection | null;
26
+ onSelectionChange?: (next: MetadataSelection | null) => void;
27
+ locale?: string;
28
+ }
29
+ export declare function ObjectFormCanvas({ objectName, draft, baseline, onPatch, selection, onSelectionChange, locale, }: ObjectFormCanvasProps): React.JSX.Element;
30
+ export { toFieldName };