@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
@@ -9,13 +9,15 @@ import { jsx as _jsx } from "react/jsx-runtime";
9
9
  import { Toaster as Sonner } from 'sonner';
10
10
  import { CircleCheck, Info, LoaderCircle, OctagonX, TriangleAlert } from 'lucide-react';
11
11
  import { useTheme } from './ThemeProvider';
12
+ import { useObjectTranslation } from '@object-ui/i18n';
12
13
  export function ConsoleToaster(props) {
13
14
  const { theme = 'system' } = useTheme();
15
+ const { t } = useObjectTranslation();
14
16
  return (_jsx(Sonner, { theme: theme, className: "toaster group",
15
17
  // UX defaults chosen for an enterprise console — match the Linear /
16
18
  // Notion pattern users expect. Callers can still override any of
17
19
  // these via the spread `{...props}` below.
18
- position: "top-right", closeButton: true, richColors: true, expand: true, visibleToasts: 4, icons: {
20
+ position: "top-right", closeButton: true, richColors: true, expand: true, visibleToasts: 4, containerAriaLabel: t('notifications.regionLabel', { defaultValue: 'Notifications' }), icons: {
19
21
  success: _jsx(CircleCheck, { className: "h-4 w-4" }),
20
22
  info: _jsx(Info, { className: "h-4 w-4" }),
21
23
  warning: _jsx(TriangleAlert, { className: "h-4 w-4" }),
@@ -34,6 +34,6 @@ export declare class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBo
34
34
  static getDerivedStateFromError(error: Error): ErrorBoundaryState;
35
35
  componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
36
36
  resetErrorBoundary: () => void;
37
- render(): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null | undefined;
37
+ render(): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react").JSX.Element | null | undefined;
38
38
  }
39
39
  export {};
@@ -4,4 +4,4 @@
4
4
  * A dialog listing all available keyboard shortcuts, triggered by pressing "?".
5
5
  * @module
6
6
  */
7
- export declare function KeyboardShortcutsDialog(): import("react/jsx-runtime").JSX.Element;
7
+ export declare function KeyboardShortcutsDialog(): import("react").JSX.Element;
@@ -5,12 +5,16 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
5
  * A dialog listing all available keyboard shortcuts, triggered by pressing "?".
6
6
  * @module
7
7
  */
8
- import { useEffect, useState, useMemo } from 'react';
8
+ import { useEffect, useMemo } from 'react';
9
9
  import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, } from '@object-ui/components';
10
10
  import { useObjectTranslation } from '@object-ui/i18n';
11
+ import { useUrlOverlay } from '../hooks/useUrlOverlay';
11
12
  export function KeyboardShortcutsDialog() {
12
13
  const { t } = useObjectTranslation();
13
- const [open, setOpen] = useState(false);
14
+ // URL-addressable (?shortcuts=1) so the dialog is deep-linkable and openable
15
+ // from the header Help menu, not only via the `?` keyboard accelerator (ADR-0054
16
+ // C1/C2/C3).
17
+ const { open, setOpen, toggleOverlay } = useUrlOverlay('shortcuts');
14
18
  const shortcutGroups = useMemo(() => [
15
19
  {
16
20
  title: t('console.shortcuts.groups.general'),
@@ -35,6 +39,13 @@ export function KeyboardShortcutsDialog() {
35
39
  { keys: ['⌘', 'E'], description: t('console.shortcuts.editRecord') },
36
40
  ],
37
41
  },
42
+ {
43
+ title: t('console.shortcuts.groups.aiChat', { defaultValue: 'AI assistant' }),
44
+ shortcuts: [
45
+ { keys: ['⌘', '⇧', 'O'], description: t('console.shortcuts.newChat', { defaultValue: 'New chat' }) },
46
+ { keys: ['⌘', '⇧', 'S'], description: t('console.shortcuts.toggleChatsList', { defaultValue: 'Toggle conversations list' }) },
47
+ ],
48
+ },
38
49
  {
39
50
  title: t('console.shortcuts.groups.preferences'),
40
51
  shortcuts: [
@@ -53,11 +64,11 @@ export function KeyboardShortcutsDialog() {
53
64
  }
54
65
  if (e.key === '?' && !e.metaKey && !e.ctrlKey && !e.altKey) {
55
66
  e.preventDefault();
56
- setOpen(prev => !prev);
67
+ toggleOverlay();
57
68
  }
58
69
  }
59
70
  document.addEventListener('keydown', handleKeyDown);
60
71
  return () => document.removeEventListener('keydown', handleKeyDown);
61
- }, []);
62
- return (_jsx(Dialog, { open: open, onOpenChange: setOpen, children: _jsxs(DialogContent, { className: "sm:max-w-lg max-h-[80vh] overflow-y-auto", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: t('console.shortcuts.title') }), _jsx(DialogDescription, { children: t('console.shortcuts.description') })] }), _jsx("div", { className: "space-y-6 pt-2", children: shortcutGroups.map(group => (_jsxs("div", { children: [_jsx("h3", { className: "text-sm font-medium text-muted-foreground mb-3", children: group.title }), _jsx("div", { className: "space-y-2", children: group.shortcuts.map((shortcut, idx) => (_jsxs("div", { className: "flex items-center justify-between py-1.5", children: [_jsx("span", { className: "text-sm", children: shortcut.description }), _jsx("div", { className: "flex items-center gap-1", children: shortcut.keys.map((key, kidx) => (_jsx("kbd", { className: "inline-flex h-6 min-w-[24px] items-center justify-center rounded border bg-muted px-1.5 text-xs font-medium text-muted-foreground", children: key }, kidx))) })] }, idx))) })] }, group.title))) })] }) }));
72
+ }, [toggleOverlay]);
73
+ return (_jsx(Dialog, { open: open, onOpenChange: setOpen, children: _jsxs(DialogContent, { className: "sm:max-w-lg max-h-[80vh] overflow-y-auto", "data-testid": "overlay:keyboard-shortcuts", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: t('console.shortcuts.title') }), _jsx(DialogDescription, { children: t('console.shortcuts.description') })] }), _jsx("div", { className: "space-y-6 pt-2", children: shortcutGroups.map(group => (_jsxs("div", { children: [_jsx("h3", { className: "text-sm font-medium text-muted-foreground mb-3", children: group.title }), _jsx("div", { className: "space-y-2", children: group.shortcuts.map((shortcut, idx) => (_jsxs("div", { className: "flex items-center justify-between py-1.5", children: [_jsx("span", { className: "text-sm", children: shortcut.description }), _jsx("div", { className: "flex items-center gap-1", children: shortcut.keys.map((key, kidx) => (_jsx("kbd", { className: "inline-flex h-6 min-w-[24px] items-center justify-center rounded border bg-muted px-1.5 text-xs font-medium text-muted-foreground", children: key }, kidx))) })] }, idx))) })] }, group.title))) })] }) }));
63
74
  }
@@ -8,5 +8,5 @@ interface LoadingScreenProps {
8
8
  /** When true, disables the retry button and shows a spinner */
9
9
  retrying?: boolean;
10
10
  }
11
- export declare function LoadingScreen({ message, error, onRetry, retrying }: LoadingScreenProps): import("react/jsx-runtime").JSX.Element;
11
+ export declare function LoadingScreen({ message, error, onRetry, retrying }: LoadingScreenProps): import("react").JSX.Element;
12
12
  export {};
@@ -2,36 +2,32 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { Spinner, Button } from '@object-ui/components';
3
3
  import { Database, CheckCircle2, Loader2, AlertCircle, RefreshCw } from 'lucide-react';
4
4
  import { useState, useEffect, useMemo } from 'react';
5
+ import { getProductName } from '../runtime-config';
6
+ import { en as enLocale, zh as zhLocale } from '@object-ui/i18n';
5
7
  // Bootstrap-critical UI: must render before i18n is loaded (especially when the
6
8
  // server is unreachable, which is also when i18n can't load translations).
7
- // We deliberately do NOT use useObjectTranslation here — it suspends on first
8
- // render and would prevent the splash from rendering at all on a server-down
9
- // boot. Strings stay hardcoded English; localized error UX should happen
10
- // post-bootstrap, after i18n has loaded successfully.
11
- const STRINGS = {
12
- title: 'ObjectUI Console',
13
- initializing: 'Initializing…',
14
- steps: {
15
- connecting: 'Connecting to server',
16
- loadingConfig: 'Loading configuration',
17
- preparingWorkspace: 'Preparing workspace',
18
- },
19
- error: {
20
- connectionFailed: 'Cannot connect to server',
21
- checkServer: 'Please check your network connection or that the backend is running.',
22
- },
23
- actions: {
24
- retry: 'Retry',
25
- retrying: 'Retrying…',
26
- },
27
- };
9
+ // Do not use useObjectTranslation here — it can suspend on first render and
10
+ // prevent the splash from rendering at all on a server-down boot. Keep a small
11
+ // synchronous dictionary for the startup shell instead.
12
+ // The product name is read from the runtime-config singleton (sync) so it
13
+ // reflects server-pushed branding when available, falling back to 'ObjectOS'.
14
+ function getStartupStrings() {
15
+ if (typeof document !== 'undefined' && document.documentElement.lang?.startsWith('zh')) {
16
+ return zhLocale.console;
17
+ }
18
+ if (typeof navigator !== 'undefined' && navigator.language?.startsWith('zh')) {
19
+ return zhLocale.console;
20
+ }
21
+ return enLocale.console;
22
+ }
28
23
  export function LoadingScreen({ message, error, onRetry, retrying }) {
29
24
  const [currentStep, setCurrentStep] = useState(0);
25
+ const strings = getStartupStrings();
30
26
  const loadingSteps = useMemo(() => [
31
- STRINGS.steps.connecting,
32
- STRINGS.steps.loadingConfig,
33
- STRINGS.steps.preparingWorkspace,
34
- ], []);
27
+ strings.loadingSteps.connecting,
28
+ strings.loadingSteps.loadingConfig,
29
+ strings.loadingSteps.preparingWorkspace,
30
+ ], [strings]);
35
31
  useEffect(() => {
36
32
  if (message || error)
37
33
  return; // skip auto-progression when overridden or in error state
@@ -40,5 +36,5 @@ export function LoadingScreen({ message, error, onRetry, retrying }) {
40
36
  }, 1200);
41
37
  return () => clearInterval(timer);
42
38
  }, [message, error, loadingSteps.length]);
43
- return (_jsx("div", { className: "flex flex-col items-center justify-center h-screen bg-background", children: _jsxs("div", { className: "flex flex-col items-center gap-6", children: [_jsxs("div", { className: "relative", children: [_jsx("div", { className: "absolute inset-0 bg-primary/20 rounded-2xl blur-xl animate-pulse" }), _jsx("div", { className: "relative bg-linear-to-br from-primary to-primary/80 p-4 rounded-2xl shadow-lg", children: _jsx(Database, { className: "h-10 w-10 text-primary-foreground" }) })] }), _jsxs("div", { className: "text-center space-y-2", children: [_jsx("h1", { className: "text-2xl font-bold tracking-tight", children: STRINGS.title }), _jsx("p", { className: "text-sm text-muted-foreground", children: STRINGS.initializing })] }), error ? (_jsxs("div", { className: "flex flex-col items-center gap-4 max-w-md w-full px-6", children: [_jsxs("div", { className: "flex flex-col items-center gap-3 p-5 rounded-lg border border-destructive/30 bg-destructive/5 w-full", children: [_jsxs("div", { className: "flex items-center gap-2 text-destructive", children: [_jsx(AlertCircle, { className: "h-5 w-5 shrink-0" }), _jsx("span", { className: "text-sm font-semibold", children: STRINGS.error.connectionFailed })] }), _jsx("p", { className: "text-xs text-muted-foreground text-center break-words", children: error }), _jsx("p", { className: "text-xs text-muted-foreground text-center", children: STRINGS.error.checkServer })] }), onRetry && (_jsx(Button, { onClick: onRetry, disabled: retrying, variant: "default", size: "sm", className: "gap-2", children: retrying ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin" }), STRINGS.actions.retrying] })) : (_jsxs(_Fragment, { children: [_jsx(RefreshCw, { className: "h-4 w-4" }), STRINGS.actions.retry] })) }))] })) : message ? (_jsxs("div", { className: "flex items-center gap-3 px-4 py-2 bg-muted/50 rounded-full", children: [_jsx(Spinner, { className: "h-4 w-4 text-primary" }), _jsx("span", { className: "text-sm text-muted-foreground", children: message })] })) : (_jsx("div", { className: "flex flex-col gap-2 w-64", children: loadingSteps.map((step, index) => (_jsxs("div", { className: "flex items-center gap-2.5 text-sm transition-opacity duration-300", style: { opacity: index <= currentStep ? 1 : 0.3 }, children: [index < currentStep ? (_jsx(CheckCircle2, { className: "h-4 w-4 text-primary shrink-0" })) : index === currentStep ? (_jsx(Loader2, { className: "h-4 w-4 text-primary shrink-0 animate-spin" })) : (_jsx("div", { className: "h-4 w-4 rounded-full border border-muted-foreground/30 shrink-0" })), _jsx("span", { className: index <= currentStep ? 'text-foreground' : 'text-muted-foreground', children: step })] }, step))) }))] }) }));
39
+ return (_jsx("div", { className: "flex flex-col items-center justify-center h-screen bg-background", children: _jsxs("div", { className: "flex flex-col items-center gap-6", children: [_jsxs("div", { className: "relative", children: [_jsx("div", { className: "absolute inset-0 bg-primary/20 rounded-2xl blur-xl animate-pulse" }), _jsx("div", { className: "relative bg-linear-to-br from-primary to-primary/80 p-4 rounded-2xl shadow-lg", children: _jsx(Database, { className: "h-10 w-10 text-primary-foreground" }) })] }), _jsxs("div", { className: "text-center space-y-2", children: [_jsx("h1", { className: "text-2xl font-bold tracking-tight", children: getProductName() }), _jsx("p", { className: "text-sm text-muted-foreground", children: strings.initializing })] }), error ? (_jsxs("div", { className: "flex flex-col items-center gap-4 max-w-md w-full px-6", children: [_jsxs("div", { className: "flex flex-col items-center gap-3 p-5 rounded-lg border border-destructive/30 bg-destructive/5 w-full", children: [_jsxs("div", { className: "flex items-center gap-2 text-destructive", children: [_jsx(AlertCircle, { className: "h-5 w-5 shrink-0" }), _jsx("span", { className: "text-sm font-semibold", children: strings.error.connectionFailed })] }), _jsx("p", { className: "text-xs text-muted-foreground text-center break-words", children: error }), _jsx("p", { className: "text-xs text-muted-foreground text-center", children: strings.error.checkServer })] }), onRetry && (_jsx(Button, { onClick: onRetry, disabled: retrying, variant: "default", size: "sm", className: "gap-2", children: retrying ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin" }), strings.actions.retrying] })) : (_jsxs(_Fragment, { children: [_jsx(RefreshCw, { className: "h-4 w-4" }), strings.actions.retry] })) }))] })) : message ? (_jsxs("div", { className: "flex items-center gap-3 px-4 py-2 bg-muted/50 rounded-full", children: [_jsx(Spinner, { className: "h-4 w-4 text-primary" }), _jsx("span", { className: "text-sm text-muted-foreground", children: message })] })) : (_jsx("div", { className: "flex flex-col gap-2 w-64", children: loadingSteps.map((step, index) => (_jsxs("div", { className: "flex items-center gap-2.5 text-sm transition-opacity duration-300", style: { opacity: index <= currentStep ? 1 : 0.3 }, children: [index < currentStep ? (_jsx(CheckCircle2, { className: "h-4 w-4 text-primary shrink-0" })) : index === currentStep ? (_jsx(Loader2, { className: "h-4 w-4 text-primary shrink-0 animate-spin" })) : (_jsx("div", { className: "h-4 w-4 rounded-full border border-muted-foreground/30 shrink-0" })), _jsx("span", { className: index <= currentStep ? 'text-foreground' : 'text-muted-foreground', children: step })] }, step))) }))] }) }));
44
40
  }
@@ -29,4 +29,4 @@ export interface RouteFaderProps {
29
29
  children: React.ReactNode;
30
30
  className?: string;
31
31
  }
32
- export declare function RouteFader({ children, className }: RouteFaderProps): import("react/jsx-runtime").JSX.Element;
32
+ export declare function RouteFader({ children, className }: RouteFaderProps): React.JSX.Element;
@@ -8,6 +8,6 @@ type ThemeProviderState = {
8
8
  theme: Theme;
9
9
  setTheme: (theme: Theme) => void;
10
10
  };
11
- export declare function ThemeProvider({ children, defaultTheme, storageKey, ...props }: ThemeProviderProps): import("react/jsx-runtime").JSX.Element;
11
+ export declare function ThemeProvider({ children, defaultTheme, storageKey, ...props }: ThemeProviderProps): import("react").JSX.Element;
12
12
  export declare const useTheme: () => ThemeProviderState;
13
13
  export {};
@@ -6,5 +6,5 @@ export interface ManagedByBadgeProps {
6
6
  /** Optional extra classes. */
7
7
  className?: string;
8
8
  }
9
- export declare function ManagedByBadge({ managedBy, label, className }: ManagedByBadgeProps): import("react/jsx-runtime").JSX.Element | null;
9
+ export declare function ManagedByBadge({ managedBy, label, className }: ManagedByBadgeProps): import("react").JSX.Element | null;
10
10
  export default ManagedByBadge;
@@ -22,5 +22,5 @@ interface AppContentProps {
22
22
  */
23
23
  extraRoutesNoApp?: ReactNode;
24
24
  }
25
- export declare function AppContent({ extraRoutes, extraRoutesNoApp }?: AppContentProps): import("react/jsx-runtime").JSX.Element;
25
+ export declare function AppContent({ extraRoutes, extraRoutesNoApp }?: AppContentProps): import("react").JSX.Element;
26
26
  export {};
@@ -9,7 +9,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
9
9
  * /organizations) is provided by `createConsole` from @object-ui/app-shell.
10
10
  */
11
11
  import { Routes, Route, Navigate, useNavigate, useLocation, useParams } from 'react-router-dom';
12
- import { useState, useEffect, useCallback, lazy, Suspense, useMemo } from 'react';
12
+ import { useState, useEffect, useCallback, useRef, lazy, Suspense, useMemo } from 'react';
13
+ import { useAssistant } from '../assistant/assistantBus';
13
14
  import { ModalForm } from '@object-ui/plugin-form';
14
15
  import { Empty, EmptyTitle, EmptyDescription, Button } from '@object-ui/components';
15
16
  import { toast } from 'sonner';
@@ -18,9 +19,13 @@ import { useObjectTranslation, useObjectLabel } from '@object-ui/i18n';
18
19
  import { useAuth } from '@object-ui/auth';
19
20
  import { useMetadata } from '../providers/MetadataProvider';
20
21
  import { useAdapter } from '../providers/AdapterProvider';
22
+ import { usePreviewDrafts } from '../preview/PreviewModeContext';
23
+ import { PreviewDraftEmptyState } from '../preview/PreviewDraftEmptyState';
21
24
  import { ExpressionProvider, evaluateVisibility } from '../providers/ExpressionProvider';
22
25
  import { useTrackRouteAsRecent } from '../hooks/useTrackRouteAsRecent';
23
26
  import { resolveRecordFormTarget, resolveNavigateCreateUrl, resolveNavigateEditUrl } from '../utils/recordFormNavigation';
27
+ import { matchAppBySegment } from '../utils/appRoute';
28
+ import { resolveHref } from '@object-ui/layout';
24
29
  import { ExpressionEvaluator } from '@object-ui/core';
25
30
  // Components (eagerly loaded — always needed)
26
31
  import { ConsoleLayout } from '../layout/ConsoleLayout';
@@ -44,20 +49,42 @@ const ComponentNavView = lazy(() => import('../views/ComponentNavView').then(m =
44
49
  // level so URLs read like a normal nested resource (RFC-style) instead of
45
50
  // piggy-backing on the legacy ComponentRegistry fan-out.
46
51
  const MetadataDirectoryPage = lazy(() => import('../views/metadata-admin').then(m => ({ default: m.MetadataDirectoryPage })));
52
+ const StudioHomePage = lazy(() => import('../views/metadata-admin').then(m => ({ default: m.StudioHomePage })));
47
53
  const MetadataResourceListPage = lazy(() => import('../views/metadata-admin').then(m => ({ default: m.MetadataResourceListPage })));
48
54
  const MetadataResourceEditPage = lazy(() => import('../views/metadata-admin').then(m => ({ default: m.MetadataResourceEditPage })));
49
55
  const MetadataResourceHistoryPage = lazy(() => import('../views/metadata-admin').then(m => ({ default: m.MetadataResourceHistoryPage })));
50
- // Designer pages sourced from @object-ui/plugin-designer so third-party hosts
51
- // can opt out by not registering these routes.
56
+ const MetadataDiagnosticsPage = lazy(() => import('../views/metadata-admin').then(m => ({ default: m.MetadataDiagnosticsPage })));
57
+ // App authoring + dashboard editor pages sourced from
58
+ // @object-ui/plugin-designer so third-party hosts can opt out by not
59
+ // registering these routes.
52
60
  const CreateAppPage = lazy(() => import('@object-ui/plugin-designer').then(m => ({ default: m.CreateAppPage })));
53
61
  const EditAppPage = lazy(() => import('@object-ui/plugin-designer').then(m => ({ default: m.EditAppPage })));
54
- const PageDesignPage = lazy(() => import('@object-ui/plugin-designer').then(m => ({ default: m.PageDesignPage })));
55
62
  const DashboardDesignPage = lazy(() => import('@object-ui/plugin-designer').then(m => ({ default: m.DashboardDesignPage })));
56
63
  // Marketplace pages — first-class platform feature; mounted at `system/marketplace`
57
64
  // under any active app so admins can browse + install from inside the runtime.
58
65
  const MarketplacePage = lazy(() => import('./marketplace/MarketplacePage').then(m => ({ default: m.MarketplacePage })));
59
66
  const MarketplacePackagePage = lazy(() => import('./marketplace/MarketplacePackagePage').then(m => ({ default: m.MarketplacePackagePage })));
60
67
  const MarketplaceInstalledPage = lazy(() => import('./marketplace/MarketplaceInstalledPage').then(m => ({ default: m.MarketplaceInstalledPage })));
68
+ /**
69
+ * Bridges the global chat's "Review N change(s)" affordance (ADR-0033 Phase B)
70
+ * to the metadata designer. The chat publishes a review target on `assistantBus`;
71
+ * this navigator — which lives inside the app router and knows the app base —
72
+ * routes to `/apps/:appName/metadata/:type/:name?review=1`, where the designer
73
+ * reloads the pending draft and opens its review/diff.
74
+ */
75
+ function DraftReviewNavigator({ appName }) {
76
+ const { reviewSeq, reviewTarget } = useAssistant();
77
+ const navigate = useNavigate();
78
+ const lastSeq = useRef(reviewSeq);
79
+ useEffect(() => {
80
+ if (reviewSeq === lastSeq.current || !reviewTarget || !appName)
81
+ return;
82
+ lastSeq.current = reviewSeq;
83
+ const { type, name } = reviewTarget;
84
+ navigate(`/apps/${appName}/metadata/${encodeURIComponent(type)}/${encodeURIComponent(name)}?review=1`);
85
+ }, [reviewSeq, reviewTarget, appName, navigate]);
86
+ return null;
87
+ }
61
88
  export function AppContent({ extraRoutes, extraRoutesNoApp } = {}) {
62
89
  const [connectionState, setConnectionState] = useState('disconnected');
63
90
  const { user, getAuthConfig } = useAuth();
@@ -86,7 +113,8 @@ export function AppContent({ extraRoutes, extraRoutesNoApp } = {}) {
86
113
  const navigate = useNavigate();
87
114
  const location = useLocation();
88
115
  const { appName } = useParams();
89
- const { apps, objects: allObjects, loading: metadataLoading, ensureType } = useMetadata();
116
+ const { apps, objects: allObjects, loading: metadataLoading, ensureType, error: metadataError, refresh: refreshMetadata } = useMetadata();
117
+ const previewDrafts = usePreviewDrafts();
90
118
  const { t } = useObjectTranslation();
91
119
  const { objectLabel } = useObjectLabel();
92
120
  // Preload the metadata buckets that the routes under /apps/:appName/* assume
@@ -110,10 +138,69 @@ export function AppContent({ extraRoutes, extraRoutesNoApp } = {}) {
110
138
  });
111
139
  return () => { cancelled = true; };
112
140
  }, [ensureType]);
141
+ // Hidden apps (`App.hidden`) are excluded from app-listing surfaces
142
+ // (sidebar switcher, home grid, app switcher). The active app for the
143
+ // current route is still looked up across ALL apps so /apps/account
144
+ // resolves correctly; only the fallback (no appName → first app)
145
+ // skips hidden apps to avoid landing the user on a personal-settings
146
+ // app by default.
113
147
  const activeApps = apps.filter((a) => a.active !== false);
114
- const activeApp = apps.find((a) => a.name === appName) ||
115
- activeApps.find((a) => a.isDefault === true) ||
116
- activeApps[0];
148
+ const launcherApps = activeApps.filter((a) => a.hidden !== true);
149
+ // ADR-0048 (A) the route segment is the package id; resolve by it,
150
+ // falling back to the app name (legacy/alias URL).
151
+ // Built-in pseudo-routes under /apps/* that are NOT metadata apps (create-app,
152
+ // system/*, metadata/*, setup). They must keep working — and may fall back to
153
+ // a default app — regardless of whether the segment resolves to an app.
154
+ const isCreateAppRoute = location.pathname.endsWith('/create-app');
155
+ const isSystemRoute = location.pathname.includes('/system');
156
+ const isMetadataRoute = location.pathname.includes('/metadata');
157
+ const isSetupRoute = location.pathname === '/apps/setup' || location.pathname.startsWith('/apps/setup/');
158
+ const isSpecialRoute = isCreateAppRoute || isSystemRoute || isMetadataRoute || isSetupRoute;
159
+ const matchedApp = matchAppBySegment(apps, appName);
160
+ const activeApp = matchedApp ||
161
+ // Fall back to a default/first app only when NO specific app was requested
162
+ // (bare /apps, the default redirect) OR for a built-in pseudo-route above.
163
+ // A normal unmatched appName must NOT silently render a DIFFERENT app — the
164
+ // readiness guard below shows loading / not-available instead. (Fixes "the
165
+ // preview / nav renders the WRONG app right after building a new one".)
166
+ ((!appName || isSpecialRoute)
167
+ ? (launcherApps.find((a) => a.isDefault === true) || launcherApps[0])
168
+ : undefined);
169
+ // A normal app was requested but isn't present in the loaded metadata — the
170
+ // post-publish readiness lag, or a genuinely-missing app. Applies in BOTH
171
+ // preview and published mode (preview already guarded this; published used to
172
+ // fall through to the wrong-app fallback above — the bug). Pseudo-routes are
173
+ // excluded so they keep their default-app fallback.
174
+ const requestedAppMissing = !!appName && !matchedApp && !isSpecialRoute;
175
+ // Post-publish readiness: when a requested app isn't in the loaded metadata,
176
+ // re-check ONCE (the registry can lag a beat behind a publish) before
177
+ // concluding it's absent — so a just-built app resolves on its own instead
178
+ // of flashing "not available", while we still never render a foreign app.
179
+ const [missingRecheck, setMissingRecheck] = useState('idle');
180
+ useEffect(() => {
181
+ if (!requestedAppMissing) {
182
+ if (missingRecheck !== 'idle')
183
+ setMissingRecheck('idle');
184
+ return;
185
+ }
186
+ if (missingRecheck === 'idle' && !metadataLoading && !previewDrafts) {
187
+ setMissingRecheck('checking');
188
+ Promise.resolve(refreshMetadata()).finally(() => setMissingRecheck('done'));
189
+ }
190
+ }, [requestedAppMissing, metadataLoading, previewDrafts, missingRecheck, refreshMetadata]);
191
+ useEffect(() => {
192
+ if (!activeApp?.name)
193
+ return;
194
+ // ADR-0048 — build against the URL's own segment (`appName`, which may be the
195
+ // package id) so the match works and the redirect keeps the same segment;
196
+ // `activeApp.name` would flip a `/apps/<packageId>/…` URL to the name form.
197
+ const seg = appName ?? activeApp.name;
198
+ const packageMetadataPath = `/apps/${seg}/metadata/package`;
199
+ if (location.pathname === packageMetadataPath ||
200
+ location.pathname.startsWith(`${packageMetadataPath}/`)) {
201
+ navigate(`/apps/${seg}/component/developer/packages`, { replace: true });
202
+ }
203
+ }, [activeApp?.name, appName, location.pathname, navigate]);
117
204
  const [isDialogOpen, setIsDialogOpen] = useState(false);
118
205
  const [editingRecord, setEditingRecord] = useState(null);
119
206
  const [refreshKey, setRefreshKey] = useState(0);
@@ -236,7 +323,7 @@ export function AppContent({ extraRoutes, extraRoutesNoApp } = {}) {
236
323
  // preserved for any object without the flag.
237
324
  const target = resolveRecordFormTarget({
238
325
  objectDef: currentObjectDef,
239
- baseUrl: activeApp?.name ? `/apps/${activeApp.name}` : '',
326
+ baseUrl: appName ? `/apps/${appName}` : (activeApp?.name ? `/apps/${activeApp.name}` : ''),
240
327
  record,
241
328
  });
242
329
  if (target.kind === 'page') {
@@ -256,22 +343,66 @@ export function AppContent({ extraRoutes, extraRoutesNoApp } = {}) {
256
343
  }), [user, activeApp, editingRecord]);
257
344
  if (!dataSource || metadataLoading || !scopeMetaReady)
258
345
  return _jsx(LoadingScreen, {});
259
- const isCreateAppRoute = location.pathname.endsWith('/create-app');
260
- const isSystemRoute = location.pathname.includes('/system');
261
- if (!activeApp && !isCreateAppRoute && !isSystemRoute)
346
+ // ADR-0037 preview mode renders its OWN empty/error states and never
347
+ // falls through to the generic "No Apps Configured" guard below: inside a
348
+ // draft preview (the Live Canvas iframe, or a hand-opened ?preview=draft
349
+ // URL) that screen both lies ("nothing has been registered") and misdirects
350
+ // ("Create Your First App") about an app the AI may have just drafted.
351
+ if (previewDrafts && (requestedAppMissing || !activeApp)) {
352
+ return (_jsx(PreviewDraftEmptyState, { appName: appName, error: metadataError, onRetry: () => void refreshMetadata() }));
353
+ }
354
+ // (isCreateAppRoute / isSystemRoute / isMetadataRoute / isSetupRoute are
355
+ // computed near the top — before activeApp — so the fallback + readiness
356
+ // logic can use them. The metadata designer (Studio) in particular must stay
357
+ // reachable with no active app: a fresh env where AI just drafted everything
358
+ // has ZERO published apps, and that is the surface you review & publish from.)
359
+ // A normal app was requested but isn't in the loaded metadata. Re-check once
360
+ // for the post-publish lag, then say it's not available — NEVER render a
361
+ // different app, and don't show the misleading "no apps configured" screen
362
+ // below (there ARE apps). requestedAppMissing already excludes pseudo-routes.
363
+ if (requestedAppMissing) {
364
+ if (missingRecheck !== 'done')
365
+ return _jsx(LoadingScreen, {});
366
+ return (_jsx("div", { className: "h-screen flex items-center justify-center", children: _jsxs(Empty, { children: [_jsx(EmptyTitle, { children: t('empty.appNotAvailable', { defaultValue: 'App not available' }) }), _jsx(EmptyDescription, { children: t('empty.appNotAvailableDescription', {
367
+ defaultValue: 'This app is not available yet — it may still be publishing. Try again in a moment.',
368
+ }) }), _jsx("div", { className: "mt-4", children: _jsx(Button, { onClick: () => setMissingRecheck('idle'), "data-testid": "app-not-available-retry", children: t('common.retry', { defaultValue: 'Retry' }) }) })] }) }));
369
+ }
370
+ if (!activeApp && !isCreateAppRoute && !isSystemRoute && !isMetadataRoute)
262
371
  return (_jsx("div", { className: "h-screen flex items-center justify-center", children: _jsxs(Empty, { children: [_jsx(EmptyTitle, { children: t('empty.noAppsConfigured') }), _jsx(EmptyDescription, { children: t('empty.noAppsConfiguredDescription') }), _jsxs("div", { className: "mt-4 flex flex-col sm:flex-row items-center gap-3", children: [_jsx(Button, { onClick: () => navigate('/create-app'), "data-testid": "create-first-app-btn", children: t('empty.createFirstApp') }), _jsx(Button, { variant: "outline", onClick: () => navigate('/apps/setup'), "data-testid": "go-to-settings-btn", children: t('empty.systemSettings') })] })] }) }));
263
- if (!activeApp && (isCreateAppRoute || isSystemRoute)) {
264
- return (_jsx(Suspense, { fallback: _jsx(LoadingScreen, {}), children: _jsxs(Routes, { children: [_jsx(Route, { path: "create-app", element: _jsx(CreateAppPage, {}) }), _jsx(Route, { path: "system/marketplace", element: _jsx(MarketplacePage, {}) }), _jsx(Route, { path: "system/marketplace/installed", element: _jsx(MarketplaceInstalledPage, {}) }), _jsx(Route, { path: "system/marketplace/:packageId", element: _jsx(MarketplacePackagePage, {}) }), extraRoutesNoApp] }) }));
372
+ if (!activeApp && (isCreateAppRoute || isSystemRoute || isMetadataRoute)) {
373
+ return (_jsx(Suspense, { fallback: _jsx(LoadingScreen, {}), children: _jsxs(Routes, { children: [_jsx(Route, { path: "create-app", element: _jsx(CreateAppPage, {}) }), _jsx(Route, { path: "system/marketplace", element: _jsx(MarketplacePage, {}) }), _jsx(Route, { path: "system/marketplace/installed", element: _jsx(MarketplaceInstalledPage, {}) }), _jsx(Route, { path: "system/marketplace/:packageId", element: _jsx(MarketplacePackagePage, {}) }), _jsx(Route, { path: "metadata", element: _jsx(MetadataDirectoryPage, {}) }), _jsx(Route, { path: "metadata/_diagnostics", element: _jsx(MetadataDiagnosticsPage, {}) }), _jsx(Route, { path: "metadata/:type", element: _jsx(MetadataResourceListPage, {}) }), _jsx(Route, { path: "metadata/:type/new", element: _jsx(MetadataResourceEditPage, { createMode: true }) }), _jsx(Route, { path: "metadata/:type/:name", element: _jsx(MetadataResourceEditPage, {}) }), _jsx(Route, { path: "metadata/:type/:name/history", element: _jsx(MetadataResourceHistoryPage, {}) }), extraRoutesNoApp] }) }));
265
374
  }
266
375
  const expressionUser = user
267
376
  ? { name: user.name, email: user.email, role: user.role ?? 'user' }
268
377
  : { name: 'Anonymous', email: '', role: 'guest' };
269
- return (_jsxs(ExpressionProvider, { user: expressionUser, app: activeApp, data: {}, features: features, children: [_jsx(NavigationSyncEffect, {}), _jsxs(ConsoleLayout, { activeAppName: activeApp.name, activeApp: activeApp, onAppChange: handleAppChange, objects: allObjects, connectionState: connectionState, userId: user?.id, children: [_jsx(CommandPalette, { apps: apps, activeApp: activeApp, objects: allObjects, onAppChange: handleAppChange, dataSource: dataSource }), _jsx(KeyboardShortcutsDialog, {}), _jsx(OnboardingWalkthrough, {}), _jsx(ErrorBoundary, { children: _jsx(Suspense, { fallback: _jsx(LoadingScreen, {}), children: _jsx(RouteFader, { children: _jsxs(Routes, { children: [_jsx(Route, { path: "/", element: _jsx(Navigate, { to: resolveLandingRoute(activeApp), replace: true }) }), _jsxs(Route, { path: "metadata", children: [_jsx(Route, { index: true, element: _jsx(MetadataDirectoryPage, {}) }), _jsx(Route, { path: ":type", element: _jsx(MetadataResourceListPage, {}) }), _jsx(Route, { path: ":type/new", element: _jsx(MetadataResourceEditPage, { createMode: true }) }), _jsx(Route, { path: ":type/:name", element: _jsx(MetadataResourceEditPage, {}) }), _jsx(Route, { path: ":type/:name/history", element: _jsx(MetadataResourceHistoryPage, {}) })] }), _jsx(Route, { path: ":objectName", element: _jsx(ObjectView, { dataSource: dataSource, objects: allObjects, onEdit: handleEdit, externalRefreshKey: refreshKey }) }), _jsx(Route, { path: ":objectName/new", element: _jsx(RecordFormPage, { mode: "create" }) }), _jsx(Route, { path: ":objectName/view/:viewId", element: _jsx(ObjectView, { dataSource: dataSource, objects: allObjects, onEdit: handleEdit, externalRefreshKey: refreshKey }) }), _jsx(Route, { path: ":objectName/record/:recordId", element: _jsx(RecordDetailView, { dataSource: dataSource, objects: allObjects, onEdit: handleEdit }, refreshKey) }), _jsx(Route, { path: ":objectName/record/:recordId/edit", element: _jsx(RecordFormPage, { mode: "edit" }) }), _jsx(Route, { path: "dashboard/:dashboardName", element: _jsx(DashboardView, { dataSource: dataSource }) }), _jsx(Route, { path: "report/:reportName", element: _jsx(ReportView, { dataSource: dataSource }) }), _jsx(Route, { path: "page/:pageName", element: _jsx(PageView, {}) }), _jsx(Route, { path: "component/:ns/:name/*", element: _jsx(ComponentNavView, {}) }), _jsx(Route, { path: "component/metadata/directory", element: _jsx(LegacyMetadataRedirect, { mode: "directory" }) }), _jsx(Route, { path: "component/metadata/resource/*", element: _jsx(LegacyMetadataRedirect, { mode: "resource" }) }), _jsx(Route, { path: "design/page/:pageName", element: _jsx(PageDesignPage, {}) }), _jsx(Route, { path: "design/dashboard/:dashboardName", element: _jsx(DashboardDesignPage, {}) }), _jsx(Route, { path: "search", element: _jsx(SearchResultsPage, {}) }), _jsx(Route, { path: "create-app", element: _jsx(CreateAppPage, {}) }), _jsx(Route, { path: "edit-app/:editAppName", element: _jsx(EditAppPage, {}) }), _jsx(Route, { path: "system/marketplace", element: _jsx(MarketplacePage, {}) }), _jsx(Route, { path: "system/marketplace/installed", element: _jsx(MarketplaceInstalledPage, {}) }), _jsx(Route, { path: "system/marketplace/:packageId", element: _jsx(MarketplacePackagePage, {}) }), extraRoutes, _jsx(Route, { path: ":objectName/:maybeRecordId", element: _jsx(ShorthandRecordRedirect, {}) }), _jsx(Route, { path: "*", element: _jsx(RouteNotFound, {}) })] }) }) }) }), currentObjectDef && (_jsx(ModalForm, { schema: {
378
+ return (_jsxs(ExpressionProvider, { user: expressionUser, app: activeApp, data: {}, features: features, children: [_jsx(NavigationSyncEffect, {}), _jsxs(ConsoleLayout, { activeAppName: activeApp.name, activeApp: activeApp, onAppChange: handleAppChange, objects: allObjects, connectionState: connectionState, userId: user?.id, children: [_jsx(CommandPalette, { apps: apps, activeApp: activeApp, objects: allObjects, onAppChange: handleAppChange, dataSource: dataSource }), _jsx(KeyboardShortcutsDialog, {}), _jsx(OnboardingWalkthrough, {}), _jsx(DraftReviewNavigator, { appName: appName }), _jsx(ErrorBoundary, { children: _jsx(Suspense, { fallback: _jsx(LoadingScreen, {}), children: _jsx(RouteFader, { className: "h-full", children: _jsxs(Routes, { children: [_jsx(Route, { path: "/", element: (() => {
379
+ // When the app declares a landing target (home page or
380
+ // first nav route) honour it; otherwise — e.g. the
381
+ // metadata-admin "Studio" app whose nav is built from
382
+ // domains and has no single landing — render the rich
383
+ // overview instead of a blank `<Navigate to="">`.
384
+ const landing = resolveLandingRoute(activeApp, { currentUserId: user?.id ?? null });
385
+ return landing ? _jsx(Navigate, { to: landing, replace: true }) : _jsx(StudioHomePage, {});
386
+ })() }), _jsx(Route, { path: "metadata/package/*", element: _jsx(Navigate, { to: `/apps/${appName ?? activeApp.name}/component/developer/packages`, replace: true }) }), _jsxs(Route, { path: "metadata", children: [_jsx(Route, { index: true, element: _jsx(MetadataDirectoryPage, {}) }), _jsx(Route, { path: "_diagnostics", element: _jsx(MetadataDiagnosticsPage, {}) }), _jsx(Route, { path: ":type", element: _jsx(MetadataResourceListPage, {}) }), _jsx(Route, { path: ":type/new", element: _jsx(MetadataResourceEditPage, { createMode: true }) }), _jsx(Route, { path: ":type/:name", element: _jsx(MetadataResourceEditPage, {}) }), _jsx(Route, { path: ":type/:name/history", element: _jsx(MetadataResourceHistoryPage, {}) })] }), _jsx(Route, { path: ":objectName", element: _jsx(ObjectView, { dataSource: dataSource, objects: allObjects, onEdit: handleEdit, externalRefreshKey: refreshKey }) }), _jsx(Route, { path: ":objectName/new", element: _jsx(RecordFormPage, { mode: "create" }) }), _jsx(Route, { path: ":objectName/view/:viewId", element: _jsx(ObjectView, { dataSource: dataSource, objects: allObjects, onEdit: handleEdit, externalRefreshKey: refreshKey }) }), _jsx(Route, { path: ":objectName/record/:recordId", element: _jsx(RecordDetailView, { dataSource: dataSource, objects: allObjects, onEdit: handleEdit }, refreshKey) }), _jsx(Route, { path: ":objectName/record/:recordId/edit", element: _jsx(RecordFormPage, { mode: "edit" }) }), _jsx(Route, { path: "dashboard/:dashboardName", element: _jsx(DashboardView, { dataSource: dataSource }) }), _jsx(Route, { path: "report/:reportName", element: _jsx(ReportView, { dataSource: dataSource }) }), _jsx(Route, { path: "page/:pageName", element: _jsx(PageView, {}) }), _jsx(Route, { path: "component/:ns/:name/*", element: _jsx(ComponentNavView, {}) }), _jsx(Route, { path: "component/metadata/directory", element: _jsx(LegacyMetadataRedirect, { mode: "directory" }) }), _jsx(Route, { path: "component/metadata/resource/*", element: _jsx(LegacyMetadataRedirect, { mode: "resource" }) }), _jsx(Route, { path: "design/dashboard/:dashboardName", element: _jsx(DashboardDesignPage, {}) }), _jsx(Route, { path: "search", element: _jsx(SearchResultsPage, {}) }), _jsx(Route, { path: "create-app", element: _jsx(CreateAppPage, {}) }), _jsx(Route, { path: "edit-app/:editAppName", element: _jsx(EditAppPage, {}) }), _jsx(Route, { path: "system/marketplace", element: _jsx(MarketplacePage, {}) }), _jsx(Route, { path: "system/marketplace/installed", element: _jsx(MarketplaceInstalledPage, {}) }), _jsx(Route, { path: "system/marketplace/:packageId", element: _jsx(MarketplacePackagePage, {}) }), extraRoutes, _jsx(Route, { path: ":objectName/:maybeRecordId", element: _jsx(ShorthandRecordRedirect, {}) }), _jsx(Route, { path: "*", element: _jsx(RouteNotFound, {}) })] }) }) }) }), currentObjectDef && (_jsx(ModalForm, { schema: {
270
387
  type: 'object-form',
271
388
  formType: 'modal',
272
389
  objectName: currentObjectDef.name,
273
390
  mode: editingRecord ? 'edit' : 'create',
274
391
  recordId: editingRecord?.id,
392
+ // Master-detail by config: if the object's form view declares
393
+ // inline child collections, the standard New/Edit modal renders
394
+ // them as an atomic master-detail form (no bespoke page).
395
+ subforms: currentObjectDef.form?.subforms
396
+ ?? currentObjectDef.formViews?.default?.subforms,
397
+ // ADR-0050 (#1890): forward the default form view's layout so the
398
+ // New/Edit modal can be tabbed (not just a flat stack). `formType`
399
+ // stays 'modal' (the container); `contentLayout` carries the layout.
400
+ ...(() => {
401
+ const fd = currentObjectDef.form ?? currentObjectDef.formViews?.default;
402
+ return fd?.type === 'tabbed' && Array.isArray(fd?.sections)
403
+ ? { contentLayout: 'tabbed', sections: fd.sections }
404
+ : {};
405
+ })(),
275
406
  title: editingRecord
276
407
  ? t('form.editTitle', { object: objectLabel(currentObjectDef) })
277
408
  : t('form.createTitle', { object: objectLabel(currentObjectDef) }),
@@ -304,20 +435,20 @@ export function AppContent({ extraRoutes, extraRoutesNoApp } = {}) {
304
435
  cancelText: t('common.cancel'),
305
436
  }, dataSource: dataSource }, editingRecord?.id || 'new'))] })] }));
306
437
  }
307
- function findFirstRoute(items) {
438
+ function findFirstRoute(items, ctx) {
308
439
  if (!items || items.length === 0)
309
440
  return '';
310
441
  for (const item of items) {
311
- if (item.type === 'object')
312
- return item.viewName ? `${item.objectName}/view/${item.viewName}` : `${item.objectName}`;
313
- if (item.type === 'page')
314
- return item.pageName ? `page/${item.pageName}` : '';
315
- if (item.type === 'dashboard')
316
- return item.dashboardName ? `dashboard/${item.dashboardName}` : '';
442
+ if (item.type === 'object' || item.type === 'page' || item.type === 'dashboard' || item.type === 'report') {
443
+ const route = buildItemRoute(item, ctx);
444
+ if (route)
445
+ return route;
446
+ continue;
447
+ }
317
448
  if (item.type === 'url')
318
449
  continue;
319
450
  if (item.type === 'group' && item.children) {
320
- const childRoute = findFirstRoute(item.children);
451
+ const childRoute = findFirstRoute(item.children, ctx);
321
452
  if (childRoute !== '')
322
453
  return childRoute;
323
454
  }
@@ -326,19 +457,21 @@ function findFirstRoute(items) {
326
457
  }
327
458
  // Build the per-item route segment without recursing through groups —
328
459
  // used when `homePageId` resolved to an exact match and we just need to
329
- // know how to address it.
330
- function buildItemRoute(item) {
460
+ // know how to address it. Delegates to the layout package's resolveHref()
461
+ // so `recordId`/`recordMode`/`componentRef` semantics stay consistent
462
+ // with the sidebar.
463
+ function buildItemRoute(item, ctx) {
331
464
  if (!item)
332
465
  return '';
333
- if (item.type === 'object')
334
- return item.viewName ? `${item.objectName}/view/${item.viewName}` : `${item.objectName}`;
335
- if (item.type === 'page')
336
- return item.pageName ? `page/${item.pageName}` : '';
337
- if (item.type === 'dashboard')
338
- return item.dashboardName ? `dashboard/${item.dashboardName}` : '';
339
- if (item.type === 'report')
340
- return item.reportName ? `report/${item.reportName}` : '';
341
- return '';
466
+ if (item.type === 'url' || item.type === 'action' || item.type === 'separator' || item.type === 'group')
467
+ return '';
468
+ const { href, external } = resolveHref(item, '', ctx);
469
+ if (external || !href || href === '#')
470
+ return '';
471
+ // resolveHref returns leading-slash paths (`/sys_user/...`); the
472
+ // Navigate target inside <Routes basename="/apps/:appName"> wants a
473
+ // *relative* path so it composes with the app base.
474
+ return href.replace(/^\//, '');
342
475
  }
343
476
  function findNavItemById(items, id) {
344
477
  if (!items)
@@ -362,16 +495,16 @@ function findNavItemById(items, id) {
362
495
  * at something that doesn't yield a route. This is what lets the CRM
363
496
  * example open on the Sales Dashboard instead of the Lead list.
364
497
  */
365
- function resolveLandingRoute(activeApp) {
498
+ function resolveLandingRoute(activeApp, ctx) {
366
499
  const homePageId = activeApp?.homePageId;
367
500
  const navigation = activeApp?.navigation || [];
368
501
  if (homePageId) {
369
502
  const item = findNavItemById(navigation, homePageId);
370
- const route = buildItemRoute(item);
503
+ const route = buildItemRoute(item, ctx);
371
504
  if (route)
372
505
  return route;
373
506
  }
374
- return findFirstRoute(navigation);
507
+ return findFirstRoute(navigation, ctx);
375
508
  }
376
509
  /**
377
510
  * Heuristic: distinguish a record id from a route fragment.
@@ -10,7 +10,7 @@
10
10
  * apps/console/src/App.tsx for one with custom system routes + CreateApp.
11
11
  */
12
12
  import { type ReactNode } from 'react';
13
- export declare function LoadingFallback(): import("react/jsx-runtime").JSX.Element;
13
+ export declare function LoadingFallback(): import("react").JSX.Element;
14
14
  /**
15
15
  * ConsoleShell — top-level provider stack shared by every console route.
16
16
  * Wraps children in ThemeProvider + NavigationProvider + FavoritesProvider +
@@ -27,7 +27,7 @@ export declare function LoadingFallback(): import("react/jsx-runtime").JSX.Eleme
27
27
  */
28
28
  export declare function ConsoleShell({ children }: {
29
29
  children: ReactNode;
30
- }): import("react/jsx-runtime").JSX.Element;
30
+ }): import("react").JSX.Element;
31
31
  /**
32
32
  * ConnectedShell — mounts the data layer (AdapterProvider + MetadataProvider).
33
33
  * Use this around any route element that needs metadata access, i.e. anything
@@ -35,7 +35,7 @@ export declare function ConsoleShell({ children }: {
35
35
  */
36
36
  export declare function ConnectedShell({ children }: {
37
37
  children: ReactNode;
38
- }): import("react/jsx-runtime").JSX.Element;
38
+ }): import("react").JSX.Element;
39
39
  /**
40
40
  * RequireOrganization — redirects to /organizations when the multi-tenant
41
41
  * feature is enabled (user has orgs but no active one). Single-tenant
@@ -43,7 +43,7 @@ export declare function ConnectedShell({ children }: {
43
43
  */
44
44
  export declare function RequireOrganization({ children }: {
45
45
  children: ReactNode;
46
- }): import("react/jsx-runtime").JSX.Element;
46
+ }): import("react").JSX.Element;
47
47
  /**
48
48
  * AuthenticatedRoute — convenience wrapper composing AuthGuard + ConnectedShell
49
49
  * (+ optional RequireOrganization). Covers the common case for protected
@@ -53,14 +53,14 @@ export declare function AuthenticatedRoute({ children, requireOrganization, logi
53
53
  children: ReactNode;
54
54
  requireOrganization?: boolean;
55
55
  loginPath?: string;
56
- }): import("react/jsx-runtime").JSX.Element;
56
+ }): import("react").JSX.Element;
57
57
  /**
58
58
  * RootRedirect — element for <Route path="/" />. Waits for metadata to load
59
59
  * then sends the user to /home.
60
60
  */
61
- export declare function RootRedirect(): import("react/jsx-runtime").JSX.Element;
61
+ export declare function RootRedirect(): import("react").JSX.Element;
62
62
  /**
63
63
  * SystemRedirect — forwards legacy /system/* URLs to the canonical
64
64
  * /apps/setup/* location so bookmarks keep working. Suffix is preserved.
65
65
  */
66
- export declare function SystemRedirect(): import("react/jsx-runtime").JSX.Element;
66
+ export declare function SystemRedirect(): import("react").JSX.Element;