@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,332 @@
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
+ * PageBlockInspector — scoped editor for the selected page block /
5
+ * component subtree.
6
+ *
7
+ * Selection shape: { kind: 'block', id: 'children[i]' | 'children[i].children[j]' | … }
8
+ *
9
+ * A Page schema is a SDUI tree; "blocks" are children nodes. The id
10
+ * is a dotted path of `children[i]` hops, identical in spirit to
11
+ * AppNavInspector but always rooted at top-level `children`.
12
+ */
13
+ import * as React from 'react';
14
+ import { t } from '../i18n';
15
+ import { InspectorShell, InspectorReorderButtons, InspectorTextField, InspectorNumberField, InspectorSelectField, InspectorCheckboxField, InspectorRemoveButton, InspectorEmptyState, moveArray, } from './_shared';
16
+ import { BLOCK_CONFIG, blockHasConfig } from '../previews/block-config';
17
+ import { ColorVariantPicker } from '../color-variant-field';
18
+ import { ConditionBuilder } from './ConditionBuilder';
19
+ import { useObjectOptions } from '../previews/useObjectOptions';
20
+ import { useObjectFields } from '../previews/useObjectFields';
21
+ import { Button, Input, Label, Select, SelectTrigger, SelectContent, SelectItem, SelectValue, } from '@object-ui/components';
22
+ import { Plus, X, Trash2 } from 'lucide-react';
23
+ // ── Schema-driven picker fields ──────────────────────────────────────────────
24
+ /** Field options for an object (visible fields), as {value,label}. */
25
+ function useFieldOptions(objectName) {
26
+ const { fields } = useObjectFields(objectName);
27
+ return React.useMemo(() => fields
28
+ .filter((f) => !f.hidden)
29
+ .map((f) => ({ value: f.name, label: f.label && f.label !== f.name ? `${f.label} (${f.name})` : f.name })), [fields]);
30
+ }
31
+ /** Object dropdown; falls back to a free-text input when the list is empty. */
32
+ function ObjectPickerField({ label, value, onCommit, disabled }) {
33
+ const { options } = useObjectOptions();
34
+ if (options.length === 0) {
35
+ return _jsx(InspectorTextField, { label: label, value: value ?? '', placeholder: "snake_case object", onCommit: onCommit, disabled: disabled, mono: true });
36
+ }
37
+ return _jsx(InspectorSelectField, { label: label, value: value || undefined, options: options, onCommit: onCommit, disabled: disabled });
38
+ }
39
+ /** Field dropdown for `objectName`; falls back to free text when unresolved. */
40
+ function FieldPickerField({ label, objectName, value, onCommit, disabled }) {
41
+ const options = useFieldOptions(objectName);
42
+ if (!objectName || options.length === 0) {
43
+ return _jsx(InspectorTextField, { label: label, value: value ?? '', onCommit: onCommit, disabled: disabled, mono: true });
44
+ }
45
+ return _jsx(InspectorSelectField, { label: label, value: value || undefined, options: options, onCommit: onCommit, disabled: disabled });
46
+ }
47
+ /** Editable list of field names — each row a field dropdown (or text fallback). */
48
+ function FieldListField({ label, objectName, value, onChange, disabled }) {
49
+ const options = useFieldOptions(objectName);
50
+ const arr = Array.isArray(value) ? value : [];
51
+ return (_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { className: "text-xs text-muted-foreground", children: label }), arr.map((s, i) => (_jsxs("div", { className: "flex items-center gap-1.5", children: [options.length > 0 ? (_jsx("div", { className: "flex-1", children: _jsxs(Select, { value: s ? String(s) : '', onValueChange: (v) => { const n = [...arr]; n[i] = v; onChange(n); }, disabled: disabled, children: [_jsx(SelectTrigger, { className: "h-8", children: _jsx(SelectValue, { placeholder: "\u2014" }) }), _jsx(SelectContent, { children: options.map((o) => _jsx(SelectItem, { value: o.value, children: o.label }, o.value)) })] }) })) : (_jsx(Input, { className: "h-8 text-sm", value: String(s ?? ''), placeholder: "field name", disabled: disabled, onChange: (e) => { const n = [...arr]; n[i] = e.target.value; onChange(n); } })), _jsx(Button, { type: "button", variant: "ghost", size: "icon", className: "h-8 w-8", disabled: disabled, "aria-label": "Remove", onClick: () => onChange(arr.filter((_, j) => j !== i)), children: _jsx(X, { className: "h-4 w-4" }) })] }, i))), !disabled && (_jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: () => onChange([...arr, '']), children: [_jsx(Plus, { className: "mr-1 h-3.5 w-3.5" }), " Add"] }))] }));
52
+ }
53
+ /** Pretty-print a value for the JSON editor; undefined → empty string. */
54
+ function safeStringify(value) {
55
+ if (value === undefined)
56
+ return '';
57
+ try {
58
+ return JSON.stringify(value, null, 2);
59
+ }
60
+ catch {
61
+ return '';
62
+ }
63
+ }
64
+ /** Editable JSON field for object/array properties — commits on blur so a
65
+ * half-typed value never trips the parser. Empty clears the property. */
66
+ function InspectorJsonField({ label, value, onCommit, disabled }) {
67
+ const initial = React.useMemo(() => safeStringify(value), [value]);
68
+ const [text, setText] = React.useState(initial);
69
+ const [error, setError] = React.useState(null);
70
+ React.useEffect(() => { setText(initial); setError(null); }, [initial]);
71
+ const commit = () => {
72
+ if (disabled)
73
+ return;
74
+ const trimmed = text.trim();
75
+ if (trimmed === '') {
76
+ setError(null);
77
+ onCommit(undefined);
78
+ return;
79
+ }
80
+ try {
81
+ const parsed = JSON.parse(trimmed);
82
+ setError(null);
83
+ onCommit(parsed);
84
+ }
85
+ catch {
86
+ setError('Invalid JSON');
87
+ }
88
+ };
89
+ return (_jsxs("div", { className: "space-y-1", children: [_jsx(Label, { className: "text-xs text-muted-foreground", children: label }), _jsx("textarea", { value: text, onChange: (e) => setText(e.target.value), onBlur: commit, disabled: disabled, spellCheck: false, rows: Math.min(12, Math.max(2, text.split('\n').length)), className: "w-full rounded border border-input bg-background px-2 py-1.5 text-xs font-mono outline-none focus:ring-1 focus:ring-primary resize-y disabled:opacity-60" }), error && _jsx("div", { className: "text-[11px] text-destructive", children: error })] }));
90
+ }
91
+ /** Renders one arbitrary block property by inferring an editor from its
92
+ * runtime type. Guarantees the inspector can edit anything visible in the
93
+ * source, even block types with no curated BLOCK_CONFIG entry. */
94
+ function GenericPropField({ name, value, onCommit, disabled }) {
95
+ if (typeof value === 'boolean') {
96
+ return _jsx(InspectorCheckboxField, { label: name, value: value, onCommit: onCommit, disabled: disabled });
97
+ }
98
+ if (typeof value === 'number') {
99
+ return _jsx(InspectorNumberField, { label: name, value: value, onCommit: (v) => onCommit(v), disabled: disabled });
100
+ }
101
+ if (value === null || typeof value === 'string') {
102
+ return _jsx(InspectorTextField, { label: name, value: value == null ? '' : value, onCommit: onCommit, disabled: disabled, mono: true });
103
+ }
104
+ return _jsx(InspectorJsonField, { label: name, value: value, onCommit: onCommit, disabled: disabled });
105
+ }
106
+ /** Block `properties` keys whose values are nested block trees — these are
107
+ * edited visually on the canvas, so they are excluded from the generic
108
+ * property editor to avoid two conflicting editors for the same data. */
109
+ const STRUCTURAL_PROP_KEYS = new Set(['children', 'body']);
110
+ const REMOVE = Symbol('remove');
111
+ /** A segment is `key` (object) or `key[i]` (array). */
112
+ export function parsePath(id) {
113
+ const segs = id.split('.');
114
+ const hops = [];
115
+ for (const s of segs) {
116
+ const m = /^([a-zA-Z_]\w*)(?:\[(\d+)\])?$/.exec(s);
117
+ if (!m)
118
+ return null;
119
+ hops.push({ key: m[1], index: m[2] != null ? Number(m[2]) : -1 });
120
+ }
121
+ return hops.length > 0 ? hops : null;
122
+ }
123
+ /** Flatten hops to a JSON-pointer-like path: object key, then index if any. */
124
+ export function hopsToPath(hops) {
125
+ const p = [];
126
+ for (const h of hops) {
127
+ p.push(h.key);
128
+ if (h.index >= 0)
129
+ p.push(h.index);
130
+ }
131
+ return p;
132
+ }
133
+ export function getByPath(root, path) {
134
+ let node = root;
135
+ for (const seg of path) {
136
+ if (node == null)
137
+ return null;
138
+ node = node[seg];
139
+ }
140
+ return node ?? null;
141
+ }
142
+ /** Immutable set/remove along a path. `value === REMOVE` deletes the leaf. */
143
+ export function setByPath(root, path, value) {
144
+ if (path.length === 0)
145
+ return value;
146
+ const [head, ...rest] = path;
147
+ if (typeof head === 'number') {
148
+ const arr = Array.isArray(root) ? [...root] : [];
149
+ if (rest.length === 0) {
150
+ if (value === REMOVE)
151
+ arr.splice(head, 1);
152
+ else
153
+ arr[head] = value;
154
+ }
155
+ else
156
+ arr[head] = setByPath(arr[head], rest, value);
157
+ return arr;
158
+ }
159
+ const obj = { ...(root || {}) };
160
+ if (rest.length === 0) {
161
+ if (value === REMOVE)
162
+ delete obj[head];
163
+ else
164
+ obj[head] = value;
165
+ }
166
+ else
167
+ obj[head] = setByPath(obj[head], rest, value);
168
+ return obj;
169
+ }
170
+ export function readAt(root, hops) {
171
+ return getByPath(root, hopsToPath(hops));
172
+ }
173
+ /** Returns a shallow patch `{ [topKey]: newValue }` for onPatch. */
174
+ export function writeAt(root, hops, replacement) {
175
+ const path = hopsToPath(hops);
176
+ const next = setByPath(root, path, replacement === null ? REMOVE : replacement);
177
+ const topKey = path[0];
178
+ return { [topKey]: next[topKey] };
179
+ }
180
+ export function readSiblings(root, hops) {
181
+ const path = hopsToPath(hops);
182
+ const last = path[path.length - 1];
183
+ if (typeof last !== 'number')
184
+ return null;
185
+ const siblings = getByPath(root, path.slice(0, -1));
186
+ if (!Array.isArray(siblings))
187
+ return null;
188
+ return { siblings: siblings, index: last };
189
+ }
190
+ export function writeSiblings(root, hops, nextSiblings) {
191
+ const path = hopsToPath(hops);
192
+ const next = setByPath(root, path.slice(0, -1), nextSiblings);
193
+ const topKey = path[0];
194
+ return { [topKey]: next[topKey] };
195
+ }
196
+ export function PageBlockInspector({ selection, draft, onPatch, onClearSelection, onSelectionChange, locale, readOnly }) {
197
+ // Slotted record page: selection ids are `slot:<name>:<index>` and address
198
+ // `draft.slots.<name>` (a single component is normalised to a 1-element array).
199
+ // `slot:<name>:<idx>` optionally followed by a nested sub-path within the
200
+ // slot's block (e.g. `slot:tabs:0.properties.items[0].children[0]`), so a
201
+ // block inside a slotted container is addressable too (issue #1499).
202
+ const slotMatch = /^slot:([a-zA-Z_]+):(\d+)(?:\.(.+))?$/.exec(selection.id);
203
+ const hops = slotMatch ? null : parsePath(selection.id);
204
+ const slotName = slotMatch ? slotMatch[1] : '';
205
+ const slotIdx = slotMatch ? Number(slotMatch[2]) : -1;
206
+ const slotSub = slotMatch ? slotMatch[3] : undefined;
207
+ const subHops = slotSub ? parsePath(slotSub) : null;
208
+ const slotsObj = draft.slots && typeof draft.slots === 'object' ? draft.slots : {};
209
+ const slotArr = slotMatch
210
+ ? Array.isArray(slotsObj[slotName])
211
+ ? slotsObj[slotName]
212
+ : slotsObj[slotName] != null
213
+ ? [slotsObj[slotName]]
214
+ : []
215
+ : [];
216
+ const slotBase = slotMatch ? (slotArr[slotIdx] ?? null) : null;
217
+ // Write the slot's whole array back (delete the base block when null).
218
+ const writeSlot = (nextArr) => onPatch({ slots: { ...slotsObj, [slotName]: nextArr } });
219
+ const writeSlotBase = (nextBase) => writeSlot(nextBase === null ? slotArr.filter((_, i) => i !== slotIdx) : slotArr.map((b, i) => (i === slotIdx ? nextBase : b)));
220
+ const block = slotMatch
221
+ ? subHops
222
+ ? readAt((slotBase || {}), subHops)
223
+ : slotBase
224
+ : hops
225
+ ? readAt(draft, hops)
226
+ : null;
227
+ const sibInfo = slotMatch
228
+ ? subHops
229
+ ? readSiblings((slotBase || {}), subHops)
230
+ : { siblings: slotArr, index: slotIdx }
231
+ : hops
232
+ ? readSiblings(draft, hops)
233
+ : null;
234
+ if ((!slotMatch && !hops) || !block) {
235
+ return (_jsx(InspectorShell, { kindLabel: t('engine.inspector.pageBlock.kind', locale), title: selection.label ?? selection.id, onClose: onClearSelection, closeLabel: t('engine.inspector.pageBlock.close', locale), children: _jsx(InspectorEmptyState, { message: selection.id }) }));
236
+ }
237
+ const patch = (updates) => {
238
+ if (!slotMatch)
239
+ return onPatch(writeAt(draft, hops, { ...block, ...updates }));
240
+ if (subHops)
241
+ return writeSlotBase({ ...slotBase, ...writeAt((slotBase || {}), subHops, { ...block, ...updates }) });
242
+ return writeSlotBase({ ...block, ...updates });
243
+ };
244
+ // Per-block configurable properties (spec `properties`). The renderer hoists
245
+ // `properties.*` to the top level, so we read from either and always write
246
+ // back to `properties` (the canonical shape).
247
+ const blockProps = block.properties || {};
248
+ // The record page's bound object — drives `field-picker`/`field-list` with
249
+ // objectFrom:'page'. (objectFrom:'self' reads a sibling block property.)
250
+ const pageObject = typeof draft?.object === 'string' ? draft.object : undefined;
251
+ const resolveObject = (src) => src.objectFrom === 'page'
252
+ ? pageObject
253
+ : src.objectProp != null && blockProps[src.objectProp] != null
254
+ ? String(blockProps[src.objectProp])
255
+ : undefined;
256
+ const readProp = (name) => blockProps[name] ?? block[name];
257
+ const patchProp = (name, value) => patch({ properties: { ...blockProps, [name]: value } });
258
+ // Properties already handled by curated fields — excluded from the generic
259
+ // "Advanced" section so each property has exactly one editor.
260
+ const curatedNames = new Set((blockHasConfig(block.type) ? BLOCK_CONFIG[block.type] : []).map((f) => f.name));
261
+ const advancedKeys = Object.keys(blockProps).filter((key) => !curatedNames.has(key) && !STRUCTURAL_PROP_KEYS.has(key));
262
+ // Generic, recursive field renderer. `read`/`write` abstract the value source
263
+ // (the block's `properties` at the top level, or an item object inside an
264
+ // `array` field), so the same code drives nested array-item editors.
265
+ const renderField = (f, read, write, keyPrefix = '') => {
266
+ const k = `${keyPrefix}${f.name}`;
267
+ switch (f.kind) {
268
+ case 'number':
269
+ return (_jsx(InspectorNumberField, { label: f.label, value: typeof read(f.name) === 'number' ? read(f.name) : undefined, placeholder: f.placeholder, onCommit: (v) => write(f.name, v), disabled: readOnly }, k));
270
+ case 'boolean':
271
+ return (_jsx(InspectorCheckboxField, { label: f.label, value: !!read(f.name), onCommit: (v) => write(f.name, v), disabled: readOnly }, k));
272
+ case 'color':
273
+ return (_jsxs("div", { className: "space-y-1", children: [_jsx(Label, { className: "text-xs text-muted-foreground", children: f.label }), _jsx(ColorVariantPicker, { value: read(f.name) != null ? String(read(f.name)) : undefined, onChange: (v) => write(f.name, v), disabled: readOnly, options: f.options })] }, k));
274
+ case 'select':
275
+ return (_jsx(InspectorSelectField, { label: f.label, value: read(f.name) != null ? String(read(f.name)) : undefined, options: f.options, onCommit: (v) => write(f.name, v), disabled: readOnly }, k));
276
+ case 'string-list': {
277
+ const arr = Array.isArray(read(f.name)) ? read(f.name) : [];
278
+ return (_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { className: "text-xs text-muted-foreground", children: f.label }), arr.map((s, i) => (_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx(Input, { className: "h-8 text-sm", value: String(s ?? ''), placeholder: f.placeholder, disabled: readOnly, onChange: (e) => { const next = [...arr]; next[i] = e.target.value; write(f.name, next); } }), _jsx(Button, { type: "button", variant: "ghost", size: "icon", className: "h-8 w-8", disabled: readOnly, "aria-label": "Remove", onClick: () => write(f.name, arr.filter((_, j) => j !== i)), children: _jsx(X, { className: "h-4 w-4" }) })] }, i))), !readOnly && (_jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: () => write(f.name, [...arr, '']), children: [_jsx(Plus, { className: "mr-1 h-3.5 w-3.5" }), " Add"] }))] }, k));
279
+ }
280
+ case 'array': {
281
+ const arr = Array.isArray(read(f.name)) ? read(f.name) : [];
282
+ return (_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { className: "text-xs text-muted-foreground", children: f.label }), arr.map((item, i) => {
283
+ const itemObj = item && typeof item === 'object' ? item : {};
284
+ return (_jsxs("div", { className: "space-y-2 rounded-md border border-border p-2", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("span", { className: "text-xs text-muted-foreground", children: ["#", i + 1] }), _jsx(Button, { type: "button", variant: "ghost", size: "icon", className: "h-7 w-7", disabled: readOnly, "aria-label": "Remove item", onClick: () => write(f.name, arr.filter((_, j) => j !== i)), children: _jsx(Trash2, { className: "h-3.5 w-3.5" }) })] }), f.itemFields.map((itf) => renderField(itf, (n) => itemObj[n], (n, v) => { const next = [...arr]; next[i] = { ...itemObj, [n]: v }; write(f.name, next); }, `${k}-${i}-`))] }, i));
285
+ }), !readOnly && (_jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: () => write(f.name, [...arr, {}]), children: [_jsx(Plus, { className: "mr-1 h-3.5 w-3.5" }), " ", f.addLabel || 'Add'] }))] }, k));
286
+ }
287
+ case 'object-picker':
288
+ return (_jsx(ObjectPickerField, { label: f.label, value: read(f.name) != null ? String(read(f.name)) : undefined, onCommit: (v) => write(f.name, v), disabled: readOnly }, k));
289
+ case 'field-picker':
290
+ return (_jsx(FieldPickerField, { label: f.label, objectName: resolveObject(f), value: read(f.name) != null ? String(read(f.name)) : undefined, onCommit: (v) => write(f.name, v), disabled: readOnly }, k));
291
+ case 'field-list':
292
+ return (_jsx(FieldListField, { label: f.label, objectName: resolveObject(f), value: read(f.name), onChange: (v) => write(f.name, v), disabled: readOnly }, k));
293
+ default:
294
+ return (_jsx(InspectorTextField, { label: f.label, value: read(f.name) != null ? String(read(f.name)) : '', placeholder: f.placeholder, onCommit: (v) => write(f.name, v), disabled: readOnly }, k));
295
+ }
296
+ };
297
+ const remove = () => {
298
+ if (slotMatch) {
299
+ if (subHops)
300
+ writeSlotBase({ ...slotBase, ...writeAt((slotBase || {}), subHops, null) });
301
+ else
302
+ writeSlotBase(null);
303
+ }
304
+ else
305
+ onPatch(writeAt(draft, hops, null));
306
+ onClearSelection();
307
+ };
308
+ // Re-serialise hops to an id, honouring object hops (index < 0 → no `[i]`).
309
+ const fmtHops = (hs) => hs.map((h) => (h.index >= 0 ? `${h.key}[${h.index}]` : h.key)).join('.');
310
+ const move = (to) => {
311
+ if (!sibInfo)
312
+ return;
313
+ if (slotMatch) {
314
+ if (subHops) {
315
+ const next = moveArray(sibInfo.siblings, sibInfo.index, to);
316
+ writeSlotBase({ ...slotBase, ...writeSiblings((slotBase || {}), subHops, next) });
317
+ const newSub = fmtHops([...subHops.slice(0, -1), { key: subHops[subHops.length - 1].key, index: to }]);
318
+ onSelectionChange?.({ kind: 'block', id: `slot:${slotName}:${slotIdx}.${newSub}`, label: String(block.id || block.type || to) });
319
+ }
320
+ else {
321
+ writeSlot(moveArray(slotArr, slotIdx, to));
322
+ onSelectionChange?.({ kind: 'block', id: `slot:${slotName}:${to}`, label: String(block.id || block.type || to) });
323
+ }
324
+ return;
325
+ }
326
+ const next = moveArray(sibInfo.siblings, sibInfo.index, to);
327
+ onPatch(writeSiblings(draft, hops, next));
328
+ const newId = fmtHops([...hops.slice(0, -1), { key: hops[hops.length - 1].key, index: to }]);
329
+ onSelectionChange?.({ kind: 'block', id: newId, label: String(block.id || block.type || newId) });
330
+ };
331
+ return (_jsxs(InspectorShell, { kindLabel: t('engine.inspector.pageBlock.kind', locale), title: String(block.id || block.type || selection.id), onClose: onClearSelection, closeLabel: t('engine.inspector.pageBlock.close', locale), headerActions: sibInfo ? (_jsx(InspectorReorderButtons, { index: sibInfo.index, total: sibInfo.siblings.length, onMove: move, upLabel: t('engine.inspector.reorder.up', locale), downLabel: t('engine.inspector.reorder.down', locale), disabled: readOnly })) : undefined, footer: _jsx(InspectorRemoveButton, { label: t('engine.inspector.pageBlock.remove', locale), onClick: remove, disabled: readOnly }), children: [_jsx(InspectorTextField, { label: t('engine.inspector.pageBlock.type', locale), value: block.type ?? '', onCommit: (v) => patch({ type: v }), disabled: readOnly, mono: true }), _jsx(InspectorTextField, { label: t('engine.inspector.pageBlock.id', locale), value: block.id ?? '', onCommit: (v) => patch({ id: v }), disabled: readOnly, mono: true }), _jsx(InspectorTextField, { label: t('engine.inspector.pageBlock.className', locale), value: block.className ?? '', onCommit: (v) => patch({ className: v }), disabled: readOnly, mono: true }), _jsx(ConditionBuilder, { label: t('engine.inspector.pageBlock.hidden', locale), value: block.hidden ?? '', onCommit: (v) => patch({ hidden: v || undefined }), objectName: pageObject, disabled: readOnly }), blockHasConfig(block.type) && (_jsxs("div", { className: "space-y-3 border-t border-border pt-3", children: [_jsx("div", { className: "text-xs font-medium uppercase tracking-wide text-muted-foreground", children: t('engine.inspector.pageBlock.properties', locale) }), BLOCK_CONFIG[block.type].map((f) => renderField(f, readProp, patchProp))] })), advancedKeys.length > 0 && (_jsxs("div", { className: "space-y-3 border-t border-border pt-3", children: [_jsx("div", { className: "text-xs font-medium uppercase tracking-wide text-muted-foreground", children: t('engine.inspector.pageBlock.advanced', locale) }), advancedKeys.map((key) => (_jsx(GenericPropField, { name: key, value: blockProps[key], onCommit: (v) => patchProp(key, v), disabled: readOnly }, key)))] }))] }));
332
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * ReportDefaultInspector — the curated "home" panel for a Report.
3
+ *
4
+ * Shown as the DEFAULT right panel (no selection) for a report. Mirrors
5
+ * {@link ViewVariantInspector} but for the flat Report document.
6
+ *
7
+ * SPEC-DRIVEN: the per-report-type config fields are NOT hardcoded. They are
8
+ * rendered by feeding the spec's canonical authoring form (`reportForm`) and
9
+ * the spec-derived Report JSONSchema into the generic {@link SchemaForm}. The
10
+ * form's type-conditional `visibleOn` section (joined blocks) automatically
11
+ * surfaces the right fields — adding a new report type or prop to
12
+ * `@objectstack/spec` flows through with zero code changes here.
13
+ *
14
+ * ADR-0021 single-form: a 9.0 report is dataset-bound — it binds a
15
+ * semantic-layer `dataset` and selects its `values` (measure names) grouped
16
+ * by `rows` (dimension names). The inspector keeps a thin curated layer for
17
+ * the concerns the spec form can't express well on its own:
18
+ * 1. the REPORT TYPE picker (options sourced from the spec `type` enum),
19
+ * 2. the DATASET binding (drives the measure/dimension catalogs), and
20
+ * 3. the VALUES / ROWS lists — add / remove / reorder from the bound
21
+ * dataset's measures and dimensions.
22
+ * Those fields are pruned from the spec form to avoid double-editing.
23
+ *
24
+ * Unlike a View (a nested document with a variant BODY), a Report is FLAT:
25
+ * label / dataset / type / values / rows all live at the draft top level, so
26
+ * every write is a plain shallow `onPatch`.
27
+ */
28
+ import * as React from 'react';
29
+ import type { MetadataDefaultInspectorProps } from '../default-inspector-registry';
30
+ import type { ObjectFieldInfo } from '../previews/useObjectFields';
31
+ import { type DatasetCatalogEntry } from '../previews/useDatasetCatalog';
32
+ export interface ReportDefaultInspectorProps extends MetadataDefaultInspectorProps {
33
+ /**
34
+ * Pre-resolved dataset catalog. When supplied, the inspector skips the
35
+ * network fetches (`useDatasetCatalog`) and uses this list instead. Hosts
36
+ * that already hold the catalog pass it to keep the inspector free of any
37
+ * network dependency.
38
+ */
39
+ datasetCatalogOverride?: DatasetCatalogEntry[];
40
+ }
41
+ /**
42
+ * A reorderable list of dataset member names (the report's `values` or
43
+ * `rows`) with an add-popover fed by the bound dataset's catalog. Exported so
44
+ * the Dashboard widget inspector can bind the same governed dimensions/measures
45
+ * the same way (single source of truth for dataset-member editing).
46
+ */
47
+ export declare function DatasetNamesEditor({ label, emptyText, names, options, loading, error, readOnly, onCommit, }: {
48
+ label: string;
49
+ emptyText: string;
50
+ names: string[];
51
+ /** Picker options from the dataset's semantic layer. */
52
+ options: ObjectFieldInfo[];
53
+ loading: boolean;
54
+ error: string | null;
55
+ readOnly?: boolean;
56
+ onCommit: (next: string[]) => void;
57
+ }): React.JSX.Element;
58
+ export declare function ReportDefaultInspector({ name, draft, onPatch, readOnly, locale, datasetCatalogOverride, serverSchema, }: ReportDefaultInspectorProps): React.JSX.Element;
@@ -0,0 +1,218 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
3
+ /**
4
+ * ReportDefaultInspector — the curated "home" panel for a Report.
5
+ *
6
+ * Shown as the DEFAULT right panel (no selection) for a report. Mirrors
7
+ * {@link ViewVariantInspector} but for the flat Report document.
8
+ *
9
+ * SPEC-DRIVEN: the per-report-type config fields are NOT hardcoded. They are
10
+ * rendered by feeding the spec's canonical authoring form (`reportForm`) and
11
+ * the spec-derived Report JSONSchema into the generic {@link SchemaForm}. The
12
+ * form's type-conditional `visibleOn` section (joined blocks) automatically
13
+ * surfaces the right fields — adding a new report type or prop to
14
+ * `@objectstack/spec` flows through with zero code changes here.
15
+ *
16
+ * ADR-0021 single-form: a 9.0 report is dataset-bound — it binds a
17
+ * semantic-layer `dataset` and selects its `values` (measure names) grouped
18
+ * by `rows` (dimension names). The inspector keeps a thin curated layer for
19
+ * the concerns the spec form can't express well on its own:
20
+ * 1. the REPORT TYPE picker (options sourced from the spec `type` enum),
21
+ * 2. the DATASET binding (drives the measure/dimension catalogs), and
22
+ * 3. the VALUES / ROWS lists — add / remove / reorder from the bound
23
+ * dataset's measures and dimensions.
24
+ * Those fields are pruned from the spec form to avoid double-editing.
25
+ *
26
+ * Unlike a View (a nested document with a variant BODY), a Report is FLAT:
27
+ * label / dataset / type / values / rows all live at the draft top level, so
28
+ * every write is a plain shallow `onPatch`.
29
+ */
30
+ import * as React from 'react';
31
+ import { Badge, Label } from '@object-ui/components';
32
+ import { InspectorShell, InspectorTextField, InspectorSelectField, appendArray, moveArray, spliceArray, } from './_shared';
33
+ import { AddFieldPopover, FieldListRow } from '../previews/ViewColumnPanes';
34
+ import { toFieldName } from '../previews/object-fields-io';
35
+ import { SchemaForm } from '../SchemaForm';
36
+ import { useDatasetCatalog, useDatasetSemantics, } from '../previews/useDatasetCatalog';
37
+ import { getReportForm, getReportSchema } from '../report-schema';
38
+ import { mergeServerFields } from '../mergeServerFields';
39
+ import { t } from '../i18n';
40
+ /**
41
+ * Top-level report fields this inspector renders with its own dedicated
42
+ * controls (type / dataset / values / rows + identity), so the spec-form
43
+ * graft never double-renders them. Mirrors the `hiddenFields` passed to
44
+ * SchemaForm.
45
+ */
46
+ const REPORT_CURATED_FIELDS = new Set([
47
+ 'type',
48
+ 'label',
49
+ 'name',
50
+ 'dataset',
51
+ 'values',
52
+ 'rows',
53
+ 'columns', // matrix across-dimensions — dedicated list below
54
+ 'chart', // dedicated Chart panel below (type + dataset-aware X/Y pickers)
55
+ ]);
56
+ /**
57
+ * Chart types offered in the curated Chart panel. A dataset-bound report plots
58
+ * one measure (yAxis) across one dimension (xAxis), so we surface the families
59
+ * that fit that shape; the renderer maps the rest. (`''` = no chart / table-only.)
60
+ */
61
+ const REPORT_CHART_TYPES = ['bar', 'column', 'line', 'area', 'pie', 'donut'];
62
+ /** i18n keys for the spec `type` enum (falls back to the raw value). */
63
+ const TYPE_LABEL_KEYS = {
64
+ tabular: 'engine.inspector.report.type.tabular',
65
+ summary: 'engine.inspector.report.type.summary',
66
+ matrix: 'engine.inspector.report.type.matrix',
67
+ joined: 'engine.inspector.report.type.joined',
68
+ };
69
+ /** Build the Report-type <select> options from the spec `type` enum. */
70
+ function useTypeOptions(currentType, locale) {
71
+ return React.useMemo(() => {
72
+ const schema = getReportSchema();
73
+ const rawEnum = schema?.properties?.type?.enum;
74
+ const values = Array.isArray(rawEnum) && rawEnum.length
75
+ ? rawEnum.filter((v) => typeof v === 'string')
76
+ : ['tabular', 'summary', 'matrix', 'joined'];
77
+ const opts = values.map((v) => {
78
+ const key = TYPE_LABEL_KEYS[v];
79
+ // i18n with a raw-value fallback (`t` echoes unknown keys verbatim).
80
+ const label = key ? t(key, locale) : v;
81
+ return { value: v, label: label === key ? v : label };
82
+ });
83
+ if (!opts.some((o) => o.value === currentType) && currentType) {
84
+ opts.push({ value: currentType, label: currentType });
85
+ }
86
+ return opts;
87
+ }, [currentType, locale]);
88
+ }
89
+ /** Read a `string[]` draft field defensively. */
90
+ function readNames(value) {
91
+ return Array.isArray(value) ? value.filter((v) => typeof v === 'string') : [];
92
+ }
93
+ /**
94
+ * A reorderable list of dataset member names (the report's `values` or
95
+ * `rows`) with an add-popover fed by the bound dataset's catalog. Exported so
96
+ * the Dashboard widget inspector can bind the same governed dimensions/measures
97
+ * the same way (single source of truth for dataset-member editing).
98
+ */
99
+ export function DatasetNamesEditor({ label, emptyText, names, options, loading, error, readOnly, onCommit, }) {
100
+ const [dragIndex, setDragIndex] = React.useState(null);
101
+ const [overIndex, setOverIndex] = React.useState(null);
102
+ const used = React.useMemo(() => new Set(names), [names]);
103
+ const typeByName = React.useMemo(() => {
104
+ const m = new Map();
105
+ for (const o of options)
106
+ m.set(o.name, o.type);
107
+ return m;
108
+ }, [options]);
109
+ return (_jsxs("div", { className: "border-t pt-3 space-y-1.5", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx(Label, { className: "text-xs text-muted-foreground", children: label }), _jsx(Badge, { variant: "outline", className: "text-[10px]", children: names.length })] }), names.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: emptyText })) : (_jsx("div", { className: "space-y-1", children: names.map((name, i) => (_jsx(FieldListRow, { index: i, label: name, fieldName: name, fieldType: typeByName.get(name) ?? 'number', selected: false, canEdit: !readOnly, dragging: dragIndex !== null, dropBefore: overIndex === i && dragIndex !== null && dragIndex !== i, onSelect: () => { }, onRemove: () => onCommit(spliceArray(names, i, null)), onDragStart: () => setDragIndex(i), onDragEnd: () => {
110
+ setDragIndex(null);
111
+ setOverIndex(null);
112
+ }, onDragOverRow: () => setOverIndex(i), onDropRow: () => {
113
+ if (dragIndex != null && dragIndex !== i)
114
+ onCommit(moveArray(names, dragIndex, i));
115
+ setDragIndex(null);
116
+ setOverIndex(null);
117
+ } }, `${name}-${i}`))) })), !readOnly && (_jsx(AddFieldPopover, { fields: options, usedNames: used, loading: loading, error: error, onAdd: (f) => onCommit(appendArray(names, f.name)) }))] }));
118
+ }
119
+ export function ReportDefaultInspector({ name, draft, onPatch, readOnly, locale, datasetCatalogOverride, serverSchema, }) {
120
+ const tr = React.useCallback((key) => t(key, locale), [locale]);
121
+ // In create mode the host passes an empty `name` (the PK is assigned on
122
+ // first save). Mirror ObjectDefaultInspector: expose an editable Name that
123
+ // auto-derives a snake_case slug from the label until the author edits it
124
+ // directly. Without this, a report created through the canvas would save
125
+ // with an empty name and fail the snake_case identity rule (the create flow
126
+ // would dead-end exactly the way it did before report-create used the canvas).
127
+ const createMode = !name;
128
+ const nameTouched = React.useRef(false);
129
+ const nameValue = typeof draft.name === 'string' ? draft.name : '';
130
+ const reportType = typeof draft.type === 'string' ? draft.type : 'tabular';
131
+ const typeOptions = useTypeOptions(reportType, locale);
132
+ const labelValue = typeof draft.label === 'string' ? draft.label : '';
133
+ const datasetName = typeof draft.dataset === 'string' ? draft.dataset : '';
134
+ const values = React.useMemo(() => readNames(draft.values), [draft.values]);
135
+ const rows = React.useMemo(() => readNames(draft.rows), [draft.rows]);
136
+ const columnsAcross = React.useMemo(() => readNames(draft.columns), [draft.columns]);
137
+ // Dataset catalog (binding options) + the bound dataset's semantic layer
138
+ // (measure/dimension picker options).
139
+ const catalog = useDatasetCatalog(datasetCatalogOverride);
140
+ const semantics = useDatasetSemantics(datasetName || undefined, catalog);
141
+ const datasetOptions = React.useMemo(() => {
142
+ const opts = catalog.datasets.map((d) => ({
143
+ value: d.name,
144
+ label: d.label && d.label !== d.name ? `${d.label} (${d.name})` : d.name,
145
+ }));
146
+ if (datasetName && !opts.some((o) => o.value === datasetName)) {
147
+ opts.push({ value: datasetName, label: datasetName });
148
+ }
149
+ return opts;
150
+ }, [catalog.datasets, datasetName]);
151
+ const measureOptions = React.useMemo(() => semantics.measures.map((m) => ({
152
+ name: m.name,
153
+ label: m.aggregate ? `${m.name} · ${m.aggregate}` : m.name,
154
+ type: 'number',
155
+ hidden: false,
156
+ })), [semantics.measures]);
157
+ const dimensionOptions = React.useMemo(() => semantics.dimensions.map((d) => ({
158
+ name: d.name,
159
+ label: d.name,
160
+ type: d.type ?? 'text',
161
+ hidden: false,
162
+ })), [semantics.dimensions]);
163
+ // Embedded chart (ADR-0021) — edited via the dedicated panel below so authors
164
+ // pick the X dimension / Y measure from dropdowns sourced from the bound
165
+ // dataset (instead of free-typing field names), and the generic spec-form
166
+ // graft excludes `chart`. Patching merges into the chart object; clearing the
167
+ // type drops the chart entirely.
168
+ const chart = draft.chart && typeof draft.chart === 'object'
169
+ ? draft.chart
170
+ : {};
171
+ const chartType = typeof chart.type === 'string' ? chart.type : '';
172
+ const chartX = typeof chart.xAxis === 'string' ? chart.xAxis : '';
173
+ const chartY = typeof chart.yAxis === 'string' ? chart.yAxis : '';
174
+ const chartTitle = typeof chart.title === 'string' ? chart.title : '';
175
+ const commitChart = (patch) => {
176
+ const next = { ...chart, ...patch };
177
+ onPatch({ chart: next.type ? next : undefined });
178
+ };
179
+ const chartXOptions = React.useMemo(() => {
180
+ const opts = dimensionOptions.map((d) => ({ value: d.name, label: d.label || d.name }));
181
+ if (chartX && !opts.some((o) => o.value === chartX))
182
+ opts.push({ value: chartX, label: chartX });
183
+ return opts;
184
+ }, [dimensionOptions, chartX]);
185
+ const chartYOptions = React.useMemo(() => {
186
+ const opts = measureOptions.map((m) => ({ value: m.name, label: m.label || m.name }));
187
+ if (chartY && !opts.some((o) => o.value === chartY))
188
+ opts.push({ value: chartY, label: chartY });
189
+ return opts;
190
+ }, [measureOptions, chartY]);
191
+ // A `joined` report carries its data on dataset-bound `blocks` (edited via
192
+ // the spec form's repeater) — the top-level binding only applies otherwise.
193
+ const datasetBound = reportType !== 'joined';
194
+ // Graft any server-only top-level fields onto the bundled-spec form so they
195
+ // are directly editable here even when the bundled `@objectstack/spec` lags
196
+ // the running server (skew root-cure).
197
+ const { schema, form } = React.useMemo(() => mergeServerFields({
198
+ bundledSchema: getReportSchema(),
199
+ bundledForm: getReportForm(),
200
+ serverSchema,
201
+ excludeFields: REPORT_CURATED_FIELDS,
202
+ sectionTitle: t('engine.inspector.moreFields', locale),
203
+ }), [serverSchema, locale]);
204
+ return (_jsxs(InspectorShell, { kindLabel: tr('engine.inspector.report.kind'), title: String(labelValue || draft.name || tr('engine.inspector.report.kind')), onClose: () => { }, closeLabel: tr('engine.inspector.report.close'), hideClose: true, children: [createMode && (_jsx(InspectorTextField, { label: tr('engine.inspector.report.name'), value: nameValue, onCommit: (v) => {
205
+ nameTouched.current = true;
206
+ onPatch({ name: toFieldName(v) });
207
+ }, placeholder: tr('engine.inspector.report.namePlaceholder'), disabled: readOnly, mono: true })), _jsx(InspectorTextField, { label: tr('engine.inspector.report.label'), value: labelValue, onCommit: (v) => {
208
+ // Live-derive the snake_case name from the label until the author
209
+ // edits the Name field directly (create mode only).
210
+ const patch = { label: v };
211
+ if (createMode && !nameTouched.current)
212
+ patch.name = toFieldName(v);
213
+ onPatch(patch);
214
+ }, placeholder: tr('engine.inspector.report.labelPlaceholder'), disabled: readOnly }), _jsx(InspectorSelectField, { label: tr('engine.inspector.report.type'), value: reportType, options: typeOptions, onCommit: (v) => onPatch({ type: v }), disabled: readOnly }), datasetBound && (_jsxs(_Fragment, { children: [catalog.datasets.length > 0 || datasetName ? (_jsx(InspectorSelectField, { label: tr('engine.inspector.report.dataset'), value: datasetName, options: datasetOptions, onCommit: (v) => onPatch({ dataset: v }), disabled: readOnly })) : (_jsx(InspectorTextField, { label: tr('engine.inspector.report.dataset'), value: datasetName, onCommit: (v) => onPatch({ dataset: v }), placeholder: tr('engine.inspector.report.datasetPlaceholder'), disabled: readOnly, mono: true })), _jsx(DatasetNamesEditor, { label: tr('engine.inspector.report.values'), emptyText: tr('engine.inspector.report.valuesEmpty'), names: values, options: measureOptions, loading: semantics.loading, error: semantics.error, readOnly: readOnly, onCommit: (next) => onPatch({ values: next }) }), _jsx(DatasetNamesEditor, { label: tr('engine.inspector.report.rows'), emptyText: tr('engine.inspector.report.rowsEmpty'), names: rows, options: dimensionOptions, loading: semantics.loading, error: semantics.error, readOnly: readOnly, onCommit: (next) => onPatch({ rows: next }) }), reportType === 'matrix' && (_jsx(DatasetNamesEditor, { label: tr('engine.inspector.report.columnsAcross'), emptyText: tr('engine.inspector.report.columnsAcrossEmpty'), names: columnsAcross, options: dimensionOptions, loading: semantics.loading, error: semantics.error, readOnly: readOnly, onCommit: (next) => onPatch({ columns: next }) })), _jsxs("div", { className: "border-t pt-3 space-y-2", children: [_jsx(Label, { className: "text-xs text-muted-foreground", children: tr('engine.inspector.report.chart') }), _jsx(InspectorSelectField, { label: tr('engine.inspector.report.chartType'), value: chartType, options: [
215
+ { value: '', label: tr('engine.inspector.report.chartNone') },
216
+ ...REPORT_CHART_TYPES.map((tp) => ({ value: tp, label: tp })),
217
+ ], onCommit: (v) => commitChart({ type: v || undefined }), disabled: readOnly }), chartType ? (_jsxs(_Fragment, { children: [_jsx(InspectorTextField, { label: tr('engine.inspector.report.chartTitle'), value: chartTitle, onCommit: (v) => commitChart({ title: v || undefined }), disabled: readOnly }), _jsx(InspectorSelectField, { label: tr('engine.inspector.report.chartX'), value: chartX, options: chartXOptions, onCommit: (v) => commitChart({ xAxis: v }), disabled: readOnly }), _jsx(InspectorSelectField, { label: tr('engine.inspector.report.chartY'), value: chartY, options: chartYOptions, onCommit: (v) => commitChart({ yAxis: v }), disabled: readOnly })] })) : null] })] })), _jsx("div", { className: "border-t pt-3", children: schema ? (_jsx(SchemaForm, { schema: schema, form: form, value: draft, hiddenFields: ['type', 'label', 'name', 'dataset', 'values', 'rows', 'columns', 'chart'], readOnly: readOnly, onChange: (next) => onPatch(next) })) : (_jsx("p", { className: "text-[11px] text-muted-foreground", children: tr('engine.inspector.report.noSchema') })) })] }));
218
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * ViewColumnInspector — scoped editor for the selected View column.
3
+ *
4
+ * Selection shape: { kind: 'column', id: '<variant>.columns[<i>]' }
5
+ *
6
+ * SPEC-DRIVEN: the column's detail properties (width / align / pinned /
7
+ * summary / sortable / …) are rendered from the spec's `ListColumn`
8
+ * JSONSchema via the generic {@link SchemaForm}, NOT a hardcoded field
9
+ * list. New ListColumn props in `@objectstack/spec` appear automatically.
10
+ *
11
+ * A thin curated layer stays on top for the column IDENTITY (field key +
12
+ * label) because those round-trip through two shapes: the ObjectStack
13
+ * canonical `{ field, label }` and the legacy TanStack `{ accessorKey,
14
+ * header }`. A column that is a bare string (e.g. a kanban card field) is
15
+ * kept as a string until the author edits a detail prop.
16
+ */
17
+ import * as React from 'react';
18
+ import type { MetadataInspectorProps } from '../inspector-registry';
19
+ export declare function ViewColumnInspector({ selection, draft, onPatch, onClearSelection, onSelectionChange, locale, readOnly, }: MetadataInspectorProps): React.JSX.Element;