@object-ui/app-shell 6.2.2 → 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 +967 -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
@@ -39,4 +39,4 @@ export interface RecordFormPageProps {
39
39
  * `formType: 'simple'` (i.e. a flat in-page form), wrapped in a page header
40
40
  * that mirrors the look of `RecordDetailView`.
41
41
  */
42
- export declare function RecordFormPage({ mode }: RecordFormPageProps): import("react/jsx-runtime").JSX.Element;
42
+ export declare function RecordFormPage({ mode }: RecordFormPageProps): import("react").JSX.Element;
@@ -174,9 +174,29 @@ export function RecordFormPage({ mode }) {
174
174
  if (!objectDef) {
175
175
  return (_jsx("div", { className: "flex h-full items-center justify-center p-4", children: _jsxs(Empty, { children: [_jsx("div", { className: "mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-muted", children: _jsx(Database, { className: "h-6 w-6 text-muted-foreground" }) }), _jsx(EmptyTitle, { children: t('empty.objectNotFound') }), _jsx(EmptyDescription, { children: t('empty.objectNotFoundDescription', { name: objectName }) }), _jsx("div", { className: "mt-4", children: _jsxs(Button, { variant: "outline", onClick: () => navigate(baseUrl), children: [_jsx(ArrowLeft, { className: "mr-2 h-4 w-4" }), t('empty.back')] }) })] }) }));
176
176
  }
177
+ // Honour the object's form view layout (#1890): wire the declared `type`
178
+ // (simple/tabbed/wizard/split) + `sections` through to ObjectForm, which
179
+ // already renders each variant. Page-level layouts only — `drawer`/`modal`
180
+ // are presentation/open-modes, not record-page layouts, so they fall back to
181
+ // `simple` here (see the form-layout-vs-presentation modelling note in #1890).
182
+ const formDef = objectDef.form ?? objectDef.formViews?.default ?? {};
183
+ const pageFormType = ['tabbed', 'wizard', 'split'].includes(formDef.type) ? formDef.type : 'simple';
184
+ const formLayoutProps = pageFormType !== 'simple' && Array.isArray(formDef.sections)
185
+ ? {
186
+ sections: formDef.sections,
187
+ defaultTab: formDef.defaultTab,
188
+ tabPosition: formDef.tabPosition,
189
+ allowSkip: formDef.allowSkip,
190
+ showStepIndicator: formDef.showStepIndicator,
191
+ splitDirection: formDef.splitDirection,
192
+ splitSize: formDef.splitSize,
193
+ splitResizable: formDef.splitResizable,
194
+ }
195
+ : {};
177
196
  return (_jsx(ExpressionProvider, { user: expressionUser, app: { name: appName }, data: {}, features: features, children: _jsxs("div", { className: "flex flex-col h-full overflow-hidden bg-background", "data-testid": "record-form-page", "data-mode": mode, children: [_jsxs("header", { className: "sticky top-0 z-10 flex items-center gap-3 border-b bg-background px-4 py-3 sm:px-6", children: [_jsx(Button, { variant: "ghost", size: "sm", onClick: goBack, "data-testid": "record-form-page-back", "aria-label": t('common.back', { defaultValue: 'Back' }), children: _jsx(ArrowLeft, { className: "h-4 w-4" }) }), _jsxs("nav", { "aria-label": "Breadcrumb", className: "flex items-center gap-2 text-sm text-muted-foreground", children: [_jsx(Link, { to: objectListUrl, className: "hover:text-foreground transition-colors", children: label }), _jsx("span", { "aria-hidden": "true", children: "/" }), _jsx("span", { className: "text-foreground font-medium", "data-testid": "record-form-page-title", children: pageTitle }), _jsx(ManagedByBadge, { managedBy: objectDef?.managedBy, className: "ml-1" })] })] }), _jsx("div", { className: "flex-1 overflow-auto p-4 sm:p-6", children: _jsx("div", { className: "mx-auto max-w-4xl", children: _jsx(ObjectForm, { schema: {
178
197
  type: 'object-form',
179
- formType: 'simple',
198
+ formType: pageFormType,
199
+ ...formLayoutProps,
180
200
  objectName: objectDef.name,
181
201
  mode,
182
202
  recordId: mode === 'edit' ? recordId : undefined,
@@ -193,6 +213,11 @@ export function RecordFormPage({ mode }) {
193
213
  }),
194
214
  layout: 'vertical',
195
215
  fields,
216
+ // Master-detail by config: if the object's form view declares
217
+ // inline child collections, ObjectForm renders them as an atomic
218
+ // master-detail form on this page — no bespoke page needed.
219
+ subforms: objectDef.form?.subforms
220
+ ?? objectDef.formViews?.default?.subforms,
196
221
  onSuccess: handleSuccess,
197
222
  onCancel: handleCancel,
198
223
  showSubmit: true,
@@ -0,0 +1,37 @@
1
+ /** Field option shape the host (ReportView) already computes. */
2
+ interface AvailableField {
3
+ value: string;
4
+ label?: string;
5
+ type?: string;
6
+ }
7
+ export interface ReportConfigPanelProps {
8
+ /** Whether the panel is open. */
9
+ open: boolean;
10
+ /** Close callback. */
11
+ onClose: () => void;
12
+ /** The current report definition (flat spec Report document). */
13
+ config: Record<string, any> | null;
14
+ /** Persist all draft changes. */
15
+ onSave: (config: Record<string, any>) => void;
16
+ /** Called on every field change so the host can drive a live preview. */
17
+ onFieldChange?: (key: string, value: any, draft?: Record<string, any>) => void;
18
+ /**
19
+ * Legacy field catalog for the pre-9.0 object-bound report editor. Kept for
20
+ * prop compatibility; a 9.0 report binds a dataset, so the inspector now
21
+ * sources its pickers from the dataset catalog instead.
22
+ */
23
+ availableFields?: AvailableField[];
24
+ /** Reserved for parity with the legacy panel; unused by the inspector. */
25
+ getFieldsForObject?: (objectName: string | undefined) => AvailableField[] | undefined;
26
+ /** Report artifact name — the `:name` for the ADR-0034 draft/publish chrome. */
27
+ name?: string;
28
+ /**
29
+ * Studio metadata client — drives the draft/publish chrome
30
+ * ({@link RuntimeDraftBar}).
31
+ */
32
+ metadataClient?: any;
33
+ /** Called after a publish / discard so the host can refresh its read. */
34
+ onAfterChange?: () => void;
35
+ }
36
+ export declare function ReportConfigPanel({ open, onClose, config, onSave, onFieldChange, name, metadataClient, onAfterChange, }: ReportConfigPanelProps): import("react").JSX.Element | null;
37
+ export {};
@@ -0,0 +1,85 @@
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
+ * ReportConfigPanel — the runtime ReportView's right-rail "report editor".
5
+ *
6
+ * MIGRATED: this panel hosts the studio's spec-driven
7
+ * {@link ReportDefaultInspector} instead of the legacy
8
+ * `buildReportSchema` / `ConfigPanelRenderer` engine in `plugin-report`, so the
9
+ * runtime and the metadata studio share ONE report-editing surface. The
10
+ * inspector renders the report config fields straight from `@objectstack/spec`
11
+ * (`reportForm` / `ReportSchema`) plus a curated type / dataset / values /
12
+ * rows layer (ADR-0021 single-form).
13
+ *
14
+ * It lives in `app-shell` (next to the studio inspector) rather than in
15
+ * `plugin-report`: `app-shell` depends on `plugin-report`, so hosting the
16
+ * inspector here avoids the circular import a plugin-side panel would need.
17
+ *
18
+ * The Report document is FLAT (label / dataset / type / values / rows / … at
19
+ * the top level), so — unlike the View migration — no shape adapter is
20
+ * required: the report config IS the inspector draft. The dataset catalog
21
+ * (binding options + measure/dimension pickers) loads through the shared
22
+ * MetadataClient.
23
+ *
24
+ * Props mirror the legacy `plugin-report` panel so it is a drop-in replacement
25
+ * for ReportView.
26
+ */
27
+ import { useCallback, useMemo, useRef, useState } from 'react';
28
+ import { Button } from '@object-ui/components';
29
+ import { useObjectTranslation } from '@object-ui/i18n';
30
+ import { X } from 'lucide-react';
31
+ import { ReportDefaultInspector } from './metadata-admin/inspectors/ReportDefaultInspector';
32
+ import { RuntimeDraftBar } from './RuntimeDraftBar';
33
+ import { detectLocale } from './metadata-admin/i18n';
34
+ export function ReportConfigPanel({ open, onClose, config, onSave, onFieldChange, name, metadataClient, onAfterChange, }) {
35
+ const { t } = useObjectTranslation();
36
+ const locale = useMemo(() => detectLocale(), []);
37
+ // Unsaved-edits flag — gates Publish (mirrors studio's "save first").
38
+ const [dirty, setDirty] = useState(false);
39
+ // Draft state seeded from `config`. Rebuilt only when the source identity
40
+ // changes (the host stabilizes `config` and bumps it on open / save) — never
41
+ // on every live field change — so in-flight edits are not clobbered.
42
+ const initialDraft = useMemo(() => ({ ...(config ?? {}) }), [config]);
43
+ const [draft, setDraft] = useState(initialDraft);
44
+ const draftRef = useRef(draft);
45
+ const lastSourceRef = useRef(initialDraft);
46
+ if (lastSourceRef.current !== initialDraft) {
47
+ lastSourceRef.current = initialDraft;
48
+ draftRef.current = initialDraft;
49
+ setDraft(initialDraft);
50
+ setDirty(false);
51
+ }
52
+ // Shallow-merge an inspector patch into the draft, then mirror each changed
53
+ // field back to the host so the live preview reflects the edit.
54
+ const handlePatch = useCallback((patch) => {
55
+ const next = { ...draftRef.current, ...patch };
56
+ draftRef.current = next;
57
+ setDraft(next);
58
+ setDirty(true);
59
+ if (onFieldChange) {
60
+ for (const [key, value] of Object.entries(patch)) {
61
+ onFieldChange(key, value, next);
62
+ }
63
+ }
64
+ }, [onFieldChange]);
65
+ const handleSave = useCallback(() => {
66
+ onSave(draftRef.current);
67
+ setDirty(false);
68
+ onClose();
69
+ }, [onSave, onClose]);
70
+ // ADR-0034 (#1515): resume a pending draft into the inspector on open
71
+ // (flag-ON only). The report document IS the inspector draft, so seed it
72
+ // directly.
73
+ const handleResumeDraft = useCallback((body) => {
74
+ const next = { ...body };
75
+ draftRef.current = next;
76
+ setDraft(next);
77
+ setDirty(false);
78
+ }, []);
79
+ const handleDiscard = useCallback(() => {
80
+ onClose();
81
+ }, [onClose]);
82
+ if (!open)
83
+ return null;
84
+ return (_jsxs("aside", { className: "hidden sm:flex w-[440px] shrink-0 flex-col border-l bg-background h-full", "data-testid": "report-config-panel", role: "complementary", "aria-label": t('report.editor.title', { defaultValue: 'Edit report' }), children: [_jsxs("div", { className: "flex items-center justify-between gap-2 border-b px-4 py-2.5 shrink-0", children: [_jsx("div", { className: "text-sm font-medium truncate", children: t('report.editor.title', { defaultValue: 'Edit report' }) }), _jsx(Button, { variant: "ghost", size: "sm", onClick: onClose, className: "h-7 w-7 p-0", "aria-label": t('common.close', { defaultValue: 'Close' }), "data-testid": "report-config-close", children: _jsx(X, { className: "h-4 w-4" }) })] }), _jsx("div", { className: "min-h-0 flex-1 overflow-auto", children: _jsx(ReportDefaultInspector, { type: "report", name: typeof draft.name === 'string' ? draft.name : '', draft: draft, readOnly: false, locale: locale, onPatch: handlePatch }) }), _jsxs("div", { "data-testid": "report-config-footer", className: "flex items-center justify-end gap-2 border-t px-4 py-2.5 shrink-0", children: [_jsx(RuntimeDraftBar, { type: "report", name: name, metadataClient: metadataClient, dirty: dirty, onResume: handleResumeDraft, onAfterChange: onAfterChange }), _jsx(Button, { variant: "ghost", size: "sm", onClick: handleDiscard, "data-testid": "report-config-discard", children: t('common.cancel', { defaultValue: 'Cancel' }) }), _jsx(Button, { size: "sm", onClick: handleSave, "data-testid": "report-config-save", children: t('common.save', { defaultValue: 'Save' }) })] })] }));
85
+ }
@@ -1,4 +1,4 @@
1
1
  import type { DataSource } from '@object-ui/types';
2
2
  export declare function ReportView({ dataSource }: {
3
3
  dataSource?: DataSource;
4
- }): import("react/jsx-runtime").JSX.Element;
4
+ }): import("react").JSX.Element;
@@ -3,13 +3,23 @@ import { useState, useEffect, useCallback, useMemo, lazy, Suspense } from 'react
3
3
  import { useParams } from 'react-router-dom';
4
4
  const ReportViewer = lazy(() => import('@object-ui/plugin-report').then((m) => ({ default: m.ReportViewer })));
5
5
  const ReportRenderer = lazy(() => import('@object-ui/plugin-report').then((m) => ({ default: m.ReportRenderer })));
6
- const ReportConfigPanel = lazy(() => import('@object-ui/plugin-report').then((m) => ({ default: m.ReportConfigPanel })));
7
6
  import { Empty, EmptyTitle, EmptyDescription } from '@object-ui/components';
7
+ // Runtime report editor — hosts the studio's spec-driven report inspector
8
+ // (lives in app-shell to avoid a circular dep on plugin-report).
9
+ import { ReportConfigPanel } from './ReportConfigPanel';
8
10
  import { Pencil, BarChart3, Loader2 } from 'lucide-react';
9
11
  import { useObjectTranslation } from '@object-ui/i18n';
10
12
  import { MetadataPanel, useMetadataInspector } from './MetadataInspector';
11
13
  import { useMetadata } from '../providers/MetadataProvider';
14
+ import { useExpressionContext } from '../providers/ExpressionProvider';
15
+ import { preferLocal } from '../utils/preferLocal';
12
16
  import { useAdapter } from '../providers/AdapterProvider';
17
+ import { useMetadataClient } from './metadata-admin/useMetadata';
18
+ import { persistRuntimeMetadata } from './runtime-metadata-persistence';
19
+ import { useAuth } from '@object-ui/auth';
20
+ import { DrillDownDrawer } from '@object-ui/plugin-dashboard';
21
+ import { DrillNavigationProvider } from '@object-ui/react';
22
+ import { useOpenRecordList } from './useOpenRecordList';
13
23
  // Fallback fields when no schema is available
14
24
  const FALLBACK_FIELDS = [
15
25
  { value: 'month', label: 'Month', type: 'text' },
@@ -26,18 +36,31 @@ export function ReportView({ dataSource }) {
26
36
  const { reportName } = useParams();
27
37
  const { showDebug } = useMetadataInspector();
28
38
  const adapter = useAdapter();
39
+ // ADR-0034: report edits persist via the metadata draft/publish model.
40
+ const metadataClient = useMetadataClient();
41
+ // Editing a report mutates the SHARED definition, so it is an admin-only
42
+ // quick-edit affordance (mirrors ObjectView's view-config gate).
43
+ const { user } = useAuth();
44
+ const isAdmin = user?.role === 'admin';
29
45
  const [configPanelOpen, setConfigPanelOpen] = useState(false);
30
46
  // Version counter — incremented on save to refresh the stable config reference
31
47
  const [configVersion, setConfigVersion] = useState(0);
32
48
  // Find report definition from API-driven metadata
33
49
  const { reports, objects, loading, refresh } = useMetadata();
34
- const initialReport = reports?.find((r) => r.name === reportName);
50
+ // ADR-0048 Phase 2 prefer the report owned by the current app's package.
51
+ const { app: activeApp } = useExpressionContext();
52
+ const initialReport = preferLocal(reports, reportName, activeApp?._packageId);
35
53
  const [reportData, setReportData] = useState(initialReport);
36
54
  // Local schema state for live preview — initialized from metadata
37
55
  const [editSchema, setEditSchema] = useState(null);
38
56
  // State for report runtime data
39
57
  const [reportRuntimeData, setReportRuntimeData] = useState([]);
40
58
  const [dataLoading, setDataLoading] = useState(false);
59
+ // Drill-through (ADR-0021 D2): clicking an aggregated row/cell opens the
60
+ // underlying records in an in-place drawer (peek without leaving the report),
61
+ // with an "Open in list →" escape hatch to the full object list page.
62
+ const openRecordList = useOpenRecordList();
63
+ const [drill, setDrill] = useState(null);
41
64
  const getFieldsForObject = useCallback((objName) => {
42
65
  if (!objName || !objects?.length)
43
66
  return undefined;
@@ -56,6 +79,78 @@ export function ReportView({ dataSource }) {
56
79
  type: def.type || 'text',
57
80
  }));
58
81
  }, [objects]);
82
+ // ADR-0021 D2 drill-down: open the dataset's object list scoped by
83
+ // `?filter[<field>]=<value>` (the same equality-filter contract the
84
+ // related-list "View All" buttons use).
85
+ //
86
+ // Preferred: the renderer hands us the base `object` + an exact field→RAW
87
+ // `objectFilter` (built from the server's drillRawRows), so we navigate
88
+ // straight away — correct for select/lookup dims, no metadata round-trip.
89
+ //
90
+ // Fallback (older server with no drill metadata): only dimension NAMES +
91
+ // DISPLAY-label bucket values arrive, so resolve them through the dataset
92
+ // definition and reverse-map labels to stored values before filtering:
93
+ // - select fields → reverse-map label → option value
94
+ // - lookup fields → the label is a record name, not the FK id; skip the
95
+ // dim (the drill lands on a superset rather than filtering wrongly)
96
+ // - granularity-bucketed dates → need a range, not equality; skip too
97
+ const handleDatasetDrill = useCallback(async ({ dataset, groupKey, object, objectFilter }) => {
98
+ try {
99
+ // Drawer header: the clicked group's display values (e.g. "West / Q3").
100
+ const titleParts = Object.values(groupKey).filter((v) => v != null).map((v) => String(v));
101
+ const title = titleParts.join(' / ')
102
+ || String(reportData?.label ?? reportData?.name ?? 'Details');
103
+ // Fast path (ADR-0021 D2): the renderer already resolved the dataset's
104
+ // base object + an exact object FIELD → RAW value filter from the
105
+ // server's drillRawRows — correct for select/lookup dims (a stored
106
+ // value, not a display label) with NO dataset-definition round-trip.
107
+ if (object && objectFilter) {
108
+ setDrill({ object, filter: objectFilter, title });
109
+ return;
110
+ }
111
+ // Fallback (older server with no drill metadata): resolve the dataset's
112
+ // object and reverse-map dimension labels → stored values ourselves.
113
+ const def = await metadataClient.get('dataset', dataset);
114
+ const objectName = typeof def?.object === 'string' ? def.object : undefined;
115
+ if (!objectName)
116
+ return;
117
+ const dims = Array.isArray(def?.dimensions) ? def.dimensions : [];
118
+ const dimByName = new Map(dims.filter((d) => d?.name).map((d) => [d.name, d]));
119
+ // Field defs of the dataset's object — the option value↔label source.
120
+ const objDef = objects?.find((o) => o.name === objectName);
121
+ const rawFields = objDef?.fields;
122
+ const fieldDef = (field) => {
123
+ if (Array.isArray(rawFields))
124
+ return rawFields.find((f) => f?.name === field);
125
+ if (rawFields && typeof rawFields === 'object')
126
+ return rawFields[field];
127
+ return undefined;
128
+ };
129
+ const filter = {};
130
+ for (const [dim, value] of Object.entries(groupKey)) {
131
+ if (value == null)
132
+ continue;
133
+ const dimDef = dimByName.get(dim);
134
+ if (dimDef?.dateGranularity)
135
+ continue;
136
+ const field = dimDef?.field || dim;
137
+ const fd = fieldDef(field);
138
+ if (fd?.type === 'lookup' || fd?.type === 'master_detail')
139
+ continue;
140
+ let stored = value;
141
+ if (Array.isArray(fd?.options)) {
142
+ const opt = fd.options.find((o) => o?.label === value || o?.value === value);
143
+ if (opt && opt.value != null)
144
+ stored = opt.value;
145
+ }
146
+ filter[field] = stored;
147
+ }
148
+ setDrill({ object: objectName, filter, title });
149
+ }
150
+ catch (err) {
151
+ console.warn('ReportView: drill failed', err);
152
+ }
153
+ }, [metadataClient, objects, reportData]);
59
154
  // Derive available fields from object schema for filter/sort editors
60
155
  // Uses live editSchema when available to respond to objectName changes
61
156
  const availableFields = useMemo(() => {
@@ -66,15 +161,19 @@ export function ReportView({ dataSource }) {
66
161
  // ---- Save helper --------------------------------------------------------
67
162
  const saveSchema = useCallback(async (schema) => {
68
163
  try {
69
- if (adapter) {
70
- await adapter.update('sys_report', reportName, schema);
164
+ if (metadataClient) {
165
+ // ADR-0034: save stages a per-item draft; an explicit Publish
166
+ // promotes it (RuntimeDraftBar). `sys_report` is retired.
167
+ await persistRuntimeMetadata('report', reportName, schema, {
168
+ metadataClient,
169
+ });
71
170
  refresh().catch(() => { });
72
171
  }
73
172
  }
74
173
  catch (err) {
75
174
  console.warn('[ReportView] Auto-save failed:', err);
76
175
  }
77
- }, [adapter, reportName, refresh]);
176
+ }, [metadataClient, reportName, refresh]);
78
177
  // ---- Open / close config panel ------------------------------------------
79
178
  const handleOpenConfigPanel = useCallback(() => {
80
179
  setEditSchema(reportData);
@@ -334,7 +433,17 @@ export function ReportView({ dataSource }) {
334
433
  // and drill protocol end-to-end. The legacy ReportViewer is only used as a
335
434
  // last resort for fully-legacy schemas that lack `objectName` (e.g. inline
336
435
  // `fields` + `data` arrays from older app code).
337
- const useSpecRenderer = Boolean(previewReport &&
436
+ // ADR-0021 single-form: a report bound to a semantic-layer `dataset` (no
437
+ // `objectName`/`columns`) still routes through the spec ReportRenderer, which
438
+ // dispatches it to the dataset path (queryDataset + grouped table / joined
439
+ // blocks). Without this it would fall to the legacy ReportViewer, which has no
440
+ // data source to fetch from → a blank page.
441
+ const isDatasetBound = Boolean(previewReport &&
442
+ (typeof previewReport.dataset === 'string' ||
443
+ (previewReport.type === 'joined' &&
444
+ Array.isArray(previewReport.blocks) &&
445
+ previewReport.blocks.some((b) => typeof b?.dataset === 'string'))));
446
+ const useSpecRenderer = isDatasetBound || Boolean(previewReport &&
338
447
  previewReport.objectName &&
339
448
  (previewReport.type === 'matrix' ||
340
449
  previewReport.type === 'joined' ||
@@ -352,5 +461,5 @@ export function ReportView({ dataSource }) {
352
461
  allowExport: true,
353
462
  loading: dataLoading, // Loading state for data fetching
354
463
  };
355
- return (_jsxs("div", { className: "flex flex-col h-full overflow-hidden bg-background", children: [_jsxs("div", { className: "flex flex-col sm:flex-row justify-between sm:items-center gap-3 sm:gap-4 p-4 sm:p-6 border-b shrink-0", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("h1", { className: "text-lg sm:text-xl md:text-2xl font-bold tracking-tight truncate", children: previewReport.title || previewReport.label || 'Report Viewer' }), previewReport.description && (_jsx("p", { className: "text-sm text-muted-foreground mt-1 line-clamp-2", children: previewReport.description }))] }), _jsx("div", { className: "shrink-0 flex items-center gap-1.5", children: _jsxs("button", { type: "button", onClick: handleOpenConfigPanel, className: "inline-flex items-center gap-1.5 rounded-md border border-input bg-background px-2.5 py-1.5 text-xs font-medium text-muted-foreground shadow-sm hover:bg-accent hover:text-accent-foreground", "data-testid": "report-edit-button", children: [_jsx(Pencil, { className: "h-3.5 w-3.5" }), t('common.edit')] }) })] }), _jsxs("div", { className: "flex-1 overflow-hidden flex flex-col sm:flex-row relative", children: [_jsx("div", { className: "flex-1 min-w-0 overflow-auto p-4 sm:p-6 lg:p-8 bg-muted/5", children: _jsx("div", { className: "w-full shadow-sm border rounded-lg sm:rounded-xl bg-background overflow-hidden min-h-150", children: _jsx(Suspense, { fallback: _jsx("div", { className: "p-8 text-sm text-muted-foreground", children: t('common.loading', { defaultValue: 'Loading…' }) }), children: useSpecRenderer ? (_jsx("div", { className: "p-4 sm:p-6", children: _jsx(ReportRenderer, { schema: previewReport, dataSource: dataSource }) })) : (_jsx(ReportViewer, { schema: viewerSchema })) }) }) }), _jsx(Suspense, { fallback: null, children: _jsx(ReportConfigPanel, { open: configPanelOpen, onClose: handleCloseConfigPanel, config: reportConfig, onSave: handleReportConfigSave, onFieldChange: handleReportFieldChange, availableFields: availableFields, getFieldsForObject: getFieldsForObject }) }), _jsx(MetadataPanel, { open: showDebug, sections: [{ title: 'Report Configuration', data: previewReport }] })] })] }));
464
+ return (_jsxs(DrillNavigationProvider, { value: { openRecordList }, children: [_jsxs("div", { className: "flex flex-col h-full overflow-hidden bg-background", children: [_jsxs("div", { className: "flex flex-col sm:flex-row justify-between sm:items-center gap-3 sm:gap-4 p-4 sm:p-6 border-b shrink-0", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("h1", { className: "text-lg sm:text-xl md:text-2xl font-bold tracking-tight truncate", children: previewReport.title || previewReport.label || 'Report Viewer' }), previewReport.description && (_jsx("p", { className: "text-sm text-muted-foreground mt-1 line-clamp-2", children: previewReport.description }))] }), _jsx("div", { className: "shrink-0 flex items-center gap-1.5", children: isAdmin && (_jsxs("button", { type: "button", onClick: handleOpenConfigPanel, className: "inline-flex items-center gap-1.5 rounded-md border border-input bg-background px-2.5 py-1.5 text-xs font-medium text-muted-foreground shadow-sm hover:bg-accent hover:text-accent-foreground", "data-testid": "report-edit-button", children: [_jsx(Pencil, { className: "h-3.5 w-3.5" }), t('common.edit')] })) })] }), _jsxs("div", { className: "flex-1 overflow-hidden flex flex-col sm:flex-row relative", children: [_jsx("div", { className: "flex-1 min-w-0 overflow-auto p-4 sm:p-6 lg:p-8 bg-muted/5", children: _jsx("div", { className: "w-full shadow-sm border rounded-lg sm:rounded-xl bg-background overflow-hidden min-h-150", children: _jsx(Suspense, { fallback: _jsx("div", { className: "p-8 text-sm text-muted-foreground", children: t('common.loading', { defaultValue: 'Loading…' }) }), children: useSpecRenderer ? (_jsx("div", { className: "p-4 sm:p-6", children: _jsx(ReportRenderer, { schema: previewReport, dataSource: dataSource, rows: reportRuntimeData, onDrill: handleDatasetDrill }) })) : (_jsx(ReportViewer, { schema: viewerSchema })) }) }) }), _jsx(ReportConfigPanel, { open: configPanelOpen && isAdmin, onClose: handleCloseConfigPanel, config: reportConfig, onSave: handleReportConfigSave, onFieldChange: handleReportFieldChange, availableFields: availableFields, getFieldsForObject: getFieldsForObject, name: reportName, metadataClient: metadataClient, onAfterChange: () => refresh().catch(() => { }) }), _jsx(MetadataPanel, { open: showDebug, sections: [{ title: 'Report Configuration', data: previewReport }] })] })] }), _jsx(DrillDownDrawer, { open: !!drill, onClose: () => setDrill(null), title: drill?.title ?? '', objectName: drill?.object ?? '', filter: drill?.filter, dataSource: dataSource })] }));
356
465
  }
@@ -0,0 +1,30 @@
1
+ import { type RuntimeArtifactType } from './runtime-metadata-persistence';
2
+ export interface RuntimeDraftBarProps {
3
+ /** Artifact type — the `:type` in `/meta/:type/:name`. */
4
+ type: RuntimeArtifactType;
5
+ /** Artifact name — the `:name`. Chrome stays inert until this is known. */
6
+ name?: string;
7
+ /** Studio metadata client (flag-ON path). */
8
+ metadataClient: any;
9
+ /**
10
+ * Disable Publish while the panel has unsaved local edits, mirroring
11
+ * studio's "save first, then publish" rule.
12
+ */
13
+ dirty?: boolean;
14
+ /**
15
+ * Seed an existing draft back into the editor when the panel opens, so a
16
+ * half-finished edit is restored. Called at most once per `name` per mount.
17
+ */
18
+ onResume?: (body: Record<string, unknown>) => void;
19
+ /** Called after a successful publish / discard so the host can refresh. */
20
+ onAfterChange?: () => void;
21
+ /**
22
+ * Monotonic counter the host bumps right after it saves a draft. The bar
23
+ * reads the pending draft only on open, so without this a save in an
24
+ * already-open panel wouldn't surface the indicator until reopen. Bumping
25
+ * this marks the indicator immediately (a save just created a draft) — no
26
+ * dependence on the fire-and-forget write's timing.
27
+ */
28
+ savedSignal?: number;
29
+ }
30
+ export declare function RuntimeDraftBar({ type, name, metadataClient, dirty, onResume, onAfterChange, savedSignal, }: RuntimeDraftBarProps): import("react").JSX.Element | null;
@@ -0,0 +1,112 @@
1
+ import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
3
+ /**
4
+ * RuntimeDraftBar — ADR-0034 step 3 (#1515): the draft/publish chrome for the
5
+ * runtime config panels (ViewConfigPanel / ReportConfigPanel /
6
+ * DashboardConfigPanel).
7
+ *
8
+ * It mirrors studio's `ResourceEditPage` affordances: on open it reads the
9
+ * pending draft (`?state=draft`), shows an "unpublished changes" indicator when
10
+ * one exists, resumes it into the editor (`onResume`), and exposes **Publish**
11
+ * and **Discard draft**. It renders nothing until there is a pending draft.
12
+ */
13
+ import { useCallback, useEffect, useRef, useState } from 'react';
14
+ import { Button } from '@object-ui/components';
15
+ import { Loader2, Send, Undo2 } from 'lucide-react';
16
+ import { publishRuntimeMetadata, discardRuntimeDraft, readRuntimeDraft, } from './runtime-metadata-persistence';
17
+ import { detectLocale, t, tFormat } from './metadata-admin/i18n';
18
+ export function RuntimeDraftBar({ type, name, metadataClient, dirty, onResume, onAfterChange, savedSignal, }) {
19
+ const locale = detectLocale();
20
+ const [hasDraft, setHasDraft] = useState(false);
21
+ const [busy, setBusy] = useState(false);
22
+ // Track the `name` we've already resumed so reopening the same item doesn't
23
+ // clobber in-flight edits with the stored draft on every effect run.
24
+ const resumedRef = useRef(null);
25
+ const refresh = useCallback(async () => {
26
+ if (!name || !metadataClient) {
27
+ setHasDraft(false);
28
+ return;
29
+ }
30
+ let body;
31
+ try {
32
+ body = await readRuntimeDraft(type, name, {
33
+ metadataClient,
34
+ });
35
+ }
36
+ catch {
37
+ // A failed draft read must not break the editor — treat as "no draft".
38
+ setHasDraft(false);
39
+ return;
40
+ }
41
+ setHasDraft(!!body);
42
+ // Resume is best-effort: a failure to seed the editor must NOT hide the
43
+ // "unpublished changes" indicator (the draft still exists on the server).
44
+ if (body && onResume && resumedRef.current !== name) {
45
+ resumedRef.current = name;
46
+ try {
47
+ onResume(body);
48
+ }
49
+ catch (err) {
50
+ console.error('[RuntimeDraftBar] Resume draft failed:', err);
51
+ }
52
+ }
53
+ }, [type, name, metadataClient, onResume]);
54
+ // Read the pending draft on open / when the edited item changes.
55
+ useEffect(() => {
56
+ void refresh();
57
+ }, [refresh]);
58
+ // A host save just wrote a draft → surface the indicator immediately,
59
+ // without waiting for a reopen or racing the fire-and-forget write.
60
+ // Skip the initial mount (savedSignal === 0 / undefined).
61
+ const lastSavedSignal = useRef(savedSignal);
62
+ useEffect(() => {
63
+ if (savedSignal === lastSavedSignal.current)
64
+ return;
65
+ lastSavedSignal.current = savedSignal;
66
+ if (savedSignal)
67
+ setHasDraft(true);
68
+ }, [savedSignal]);
69
+ const handlePublish = useCallback(async () => {
70
+ if (!name)
71
+ return;
72
+ setBusy(true);
73
+ try {
74
+ await publishRuntimeMetadata(type, name, { metadataClient });
75
+ setHasDraft(false);
76
+ onAfterChange?.();
77
+ }
78
+ catch (err) {
79
+ console.error('[RuntimeDraftBar] Publish failed:', err);
80
+ }
81
+ finally {
82
+ setBusy(false);
83
+ }
84
+ }, [type, name, metadataClient, onAfterChange]);
85
+ const handleDiscard = useCallback(async () => {
86
+ if (!name)
87
+ return;
88
+ if (typeof confirm === 'function' &&
89
+ !confirm(tFormat('engine.edit.discardDraftConfirm', locale, { type, name }))) {
90
+ return;
91
+ }
92
+ setBusy(true);
93
+ try {
94
+ await discardRuntimeDraft(type, name, { metadataClient });
95
+ setHasDraft(false);
96
+ onAfterChange?.();
97
+ }
98
+ catch (err) {
99
+ console.error('[RuntimeDraftBar] Discard draft failed:', err);
100
+ }
101
+ finally {
102
+ setBusy(false);
103
+ }
104
+ }, [type, name, metadataClient, onAfterChange, locale]);
105
+ // flag OFF, or nothing pending → render nothing (zero DOM, zero layout shift).
106
+ // Nothing pending → render nothing (no indicator, no buttons).
107
+ if (!hasDraft)
108
+ return null;
109
+ return (_jsxs("div", { className: "mr-auto flex items-center gap-2", "data-testid": "runtime-draft-bar", children: [_jsxs("span", { className: "text-xs text-amber-700 dark:text-amber-400", title: t('engine.edit.draftPending', locale), "data-testid": "runtime-draft-indicator", children: ["\u25CF ", t('engine.edit.draftPending', locale)] }), _jsx(Button, { variant: "ghost", size: "sm", onClick: handleDiscard, disabled: busy, className: "h-7 w-7 p-0 text-muted-foreground", title: t('engine.edit.discardDraft', locale), "aria-label": t('engine.edit.discardDraft', locale), "data-testid": "runtime-draft-discard", children: _jsx(Undo2, { className: "h-3.5 w-3.5" }) }), _jsx(Button, { size: "sm", onClick: handlePublish, disabled: busy || dirty, className: "h-7 px-2 bg-emerald-600 hover:bg-emerald-700 text-emerald-50", title: dirty
110
+ ? t('engine.edit.publishBlockedDirty', locale)
111
+ : t('engine.edit.publish', locale), "data-testid": "runtime-draft-publish", children: busy ? (_jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" })) : (_jsxs(_Fragment, { children: [_jsx(Send, { className: "h-3.5 w-3.5 mr-1" }), t('engine.edit.publish', locale)] })) })] }));
112
+ }
@@ -6,4 +6,4 @@
6
6
  * objects, dashboards, pages, and reports matching the query.
7
7
  * @module
8
8
  */
9
- export declare function SearchResultsPage(): import("react/jsx-runtime").JSX.Element;
9
+ export declare function SearchResultsPage(): import("react").JSX.Element;
@@ -13,6 +13,9 @@ import { Input, Card, CardContent, Badge, } from '@object-ui/components';
13
13
  import { Search, Database, LayoutDashboard, FileText, BarChart3, ArrowLeft, } from 'lucide-react';
14
14
  import { useObjectTranslation } from '@object-ui/i18n';
15
15
  import { useMetadata } from '../providers/MetadataProvider';
16
+ import { matchAppBySegment } from '../utils/appRoute';
17
+ import { resolveHref } from '@object-ui/layout';
18
+ import { useAuth } from '@object-ui/auth';
16
19
  /** Flatten nested navigation groups into a flat list of leaf items */
17
20
  function flattenNavigation(items) {
18
21
  const result = [];
@@ -46,30 +49,17 @@ export function SearchResultsPage() {
46
49
  const [query, setQuery] = useState(queryParam);
47
50
  const { apps: metadataApps } = useMetadata();
48
51
  const apps = metadataApps || [];
49
- const activeApp = apps.find((a) => a.name === appName) || apps[0];
52
+ const activeApp = matchAppBySegment(apps, appName) || apps[0];
50
53
  const baseUrl = `/apps/${appName}`;
54
+ const { user } = useAuth();
51
55
  // Build searchable items from navigation
52
56
  const allItems = useMemo(() => {
53
57
  if (!activeApp)
54
58
  return [];
55
59
  const navItems = flattenNavigation(activeApp.navigation || []);
60
+ const templateContext = { currentUserId: user?.id ?? null };
56
61
  return navItems.map((item) => {
57
- let href = '#';
58
- if (item.type === 'object') {
59
- href = `${baseUrl}/${item.objectName}`;
60
- if (item.viewName)
61
- href += `/view/${item.viewName}`;
62
- }
63
- else if (item.type === 'dashboard')
64
- href = `${baseUrl}/dashboard/${item.dashboardName}`;
65
- else if (item.type === 'page')
66
- href = `${baseUrl}/page/${item.pageName}`;
67
- else if (item.type === 'report')
68
- href = `${baseUrl}/report/${item.reportName}`;
69
- else if (item.type === 'component' && item.componentRef) {
70
- const segs = String(item.componentRef).split(':').filter(Boolean);
71
- href = `${baseUrl}/component/${segs.join('/')}`;
72
- }
62
+ const { href } = resolveHref(item, baseUrl, templateContext);
73
63
  return {
74
64
  id: item.id,
75
65
  label: item.label || item.objectName || item.dashboardName || item.pageName || item.reportName || '',
@@ -78,7 +68,7 @@ export function SearchResultsPage() {
78
68
  description: item.description,
79
69
  };
80
70
  }).filter((item) => item.href !== '#');
81
- }, [activeApp, baseUrl]);
71
+ }, [activeApp, baseUrl, user?.id]);
82
72
  // Filter results
83
73
  const results = useMemo(() => {
84
74
  if (!query.trim())