@object-ui/app-shell 6.2.3 → 7.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (486) hide show
  1. package/CHANGELOG.md +1229 -0
  2. package/README.md +292 -0
  3. package/dist/assistant/assistantBus.d.ts +72 -0
  4. package/dist/assistant/assistantBus.js +133 -0
  5. package/dist/chrome/CommandPalette.d.ts +1 -1
  6. package/dist/chrome/CommandPalette.js +26 -22
  7. package/dist/chrome/ConditionalAuthWrapper.d.ts +1 -1
  8. package/dist/chrome/ConsoleToaster.d.ts +1 -1
  9. package/dist/chrome/ConsoleToaster.js +3 -1
  10. package/dist/chrome/ErrorBoundary.d.ts +1 -1
  11. package/dist/chrome/KeyboardShortcutsDialog.d.ts +1 -1
  12. package/dist/chrome/KeyboardShortcutsDialog.js +16 -5
  13. package/dist/chrome/LoadingScreen.d.ts +1 -1
  14. package/dist/chrome/LoadingScreen.js +22 -26
  15. package/dist/chrome/RouteFader.d.ts +1 -1
  16. package/dist/chrome/ThemeProvider.d.ts +1 -1
  17. package/dist/components/ManagedByBadge.d.ts +1 -1
  18. package/dist/console/AppContent.d.ts +1 -1
  19. package/dist/console/AppContent.js +184 -39
  20. package/dist/console/ConsoleShell.d.ts +7 -7
  21. package/dist/console/ConsoleShell.js +32 -3
  22. package/dist/console/ai/AiChatPage.d.ts +88 -1
  23. package/dist/console/ai/AiChatPage.js +747 -66
  24. package/dist/console/ai/ConversationsSidebar.d.ts +26 -1
  25. package/dist/console/ai/ConversationsSidebar.js +149 -34
  26. package/dist/console/ai/LiveCanvas.d.ts +28 -0
  27. package/dist/console/ai/LiveCanvas.js +80 -0
  28. package/dist/console/ai/reconcileTurn.d.ts +8 -0
  29. package/dist/console/ai/reconcileTurn.js +20 -0
  30. package/dist/console/auth/AuthPageLayout.d.ts +1 -1
  31. package/dist/console/auth/ForgotPasswordPage.d.ts +1 -1
  32. package/dist/console/auth/LoginPage.d.ts +1 -1
  33. package/dist/console/auth/RegisterPage.d.ts +1 -1
  34. package/dist/console/auth/RegisterPage.js +23 -3
  35. package/dist/console/cloud-connection/CloudConnectionPanel.d.ts +1 -0
  36. package/dist/console/cloud-connection/CloudConnectionPanel.js +169 -0
  37. package/dist/console/home/AppCard.d.ts +1 -1
  38. package/dist/console/home/AppCard.js +6 -12
  39. package/dist/console/home/HomeAppsStrip.d.ts +8 -0
  40. package/dist/console/home/HomeAppsStrip.js +61 -0
  41. package/dist/console/home/HomeLayout.d.ts +1 -1
  42. package/dist/console/home/HomeLayout.js +3 -1
  43. package/dist/console/home/HomePage.d.ts +1 -2
  44. package/dist/console/home/HomePage.js +149 -21
  45. package/dist/console/home/HomeRail.d.ts +22 -0
  46. package/dist/console/home/HomeRail.js +62 -0
  47. package/dist/console/home/QuickActions.d.ts +1 -1
  48. package/dist/console/home/QuickActions.js +3 -11
  49. package/dist/console/home/RecentApps.d.ts +1 -1
  50. package/dist/console/home/RecentApps.js +2 -2
  51. package/dist/console/home/StarredApps.d.ts +1 -1
  52. package/dist/console/home/StarredApps.js +2 -2
  53. package/dist/console/marketplace/InstalledListWidget.d.ts +1 -0
  54. package/dist/console/marketplace/InstalledListWidget.js +93 -0
  55. package/dist/console/marketplace/MarkdownText.d.ts +1 -1
  56. package/dist/console/marketplace/MarketplaceAccessDenied.d.ts +1 -1
  57. package/dist/console/marketplace/MarketplaceInstalledPage.d.ts +8 -14
  58. package/dist/console/marketplace/MarketplaceInstalledPage.js +14 -66
  59. package/dist/console/marketplace/MarketplacePackagePage.d.ts +1 -1
  60. package/dist/console/marketplace/MarketplacePackagePage.js +249 -8
  61. package/dist/console/marketplace/MarketplacePage.d.ts +1 -1
  62. package/dist/console/marketplace/MarketplacePage.js +60 -3
  63. package/dist/console/marketplace/PackageIcon.d.ts +1 -1
  64. package/dist/console/marketplace/PluginDisclosure.d.ts +14 -0
  65. package/dist/console/marketplace/PluginDisclosure.js +38 -0
  66. package/dist/console/marketplace/marketplaceApi.d.ts +123 -0
  67. package/dist/console/marketplace/marketplaceApi.js +254 -1
  68. package/dist/console/organizations/CreateWorkspaceDialog.d.ts +1 -1
  69. package/dist/console/organizations/OrganizationsLayout.d.ts +1 -1
  70. package/dist/console/organizations/OrganizationsPage.d.ts +1 -1
  71. package/dist/console/organizations/manage/AcceptInvitationPage.d.ts +1 -1
  72. package/dist/console/organizations/manage/InvitationsPage.d.ts +1 -1
  73. package/dist/console/organizations/manage/InviteMemberDialog.d.ts +1 -1
  74. package/dist/console/organizations/manage/MembersPage.d.ts +1 -1
  75. package/dist/console/organizations/manage/OrganizationLayout.d.ts +1 -1
  76. package/dist/console/organizations/manage/SettingsPage.d.ts +1 -1
  77. package/dist/context/CommandPaletteProvider.d.ts +44 -0
  78. package/dist/context/CommandPaletteProvider.js +71 -0
  79. package/dist/context/FavoritesProvider.d.ts +1 -1
  80. package/dist/context/NavigationContext.d.ts +1 -1
  81. package/dist/context/RecentItemsProvider.d.ts +2 -2
  82. package/dist/context/UserStateAdapters.d.ts +1 -1
  83. package/dist/context/index.d.ts +2 -0
  84. package/dist/context/index.js +1 -0
  85. package/dist/hooks/index.d.ts +5 -2
  86. package/dist/hooks/index.js +4 -1
  87. package/dist/hooks/useActionModal.d.ts +53 -0
  88. package/dist/hooks/useActionModal.js +111 -0
  89. package/dist/hooks/useChatConversation.d.ts +137 -4
  90. package/dist/hooks/useChatConversation.js +316 -25
  91. package/dist/hooks/useConsoleActionRuntime.d.ts +70 -0
  92. package/dist/hooks/useConsoleActionRuntime.js +564 -0
  93. package/dist/hooks/useConversationList.js +61 -3
  94. package/dist/hooks/useHomeInbox.d.ts +13 -0
  95. package/dist/hooks/useHomeInbox.js +142 -0
  96. package/dist/hooks/useNavPins.js +17 -23
  97. package/dist/hooks/useNavigationSync.d.ts +33 -0
  98. package/dist/hooks/useNavigationSync.js +98 -12
  99. package/dist/hooks/useReconcileOnError.d.ts +40 -0
  100. package/dist/hooks/useReconcileOnError.js +37 -0
  101. package/dist/hooks/useRecordApprovals.d.ts +18 -19
  102. package/dist/hooks/useRecordApprovals.js +24 -40
  103. package/dist/hooks/useResponsiveSidebar.js +14 -5
  104. package/dist/hooks/useSettleSignal.d.ts +19 -0
  105. package/dist/hooks/useSettleSignal.js +20 -0
  106. package/dist/hooks/useTrackRouteAsRecent.js +35 -0
  107. package/dist/hooks/useUrlOverlay.d.ts +62 -0
  108. package/dist/hooks/useUrlOverlay.js +88 -0
  109. package/dist/index.d.ts +18 -8
  110. package/dist/index.js +17 -5
  111. package/dist/layout/ActivityFeed.d.ts +1 -1
  112. package/dist/layout/AppHeader.d.ts +3 -2
  113. package/dist/layout/AppHeader.js +237 -72
  114. package/dist/layout/AppSidebar.d.ts +2 -1
  115. package/dist/layout/AppSidebar.js +26 -46
  116. package/dist/layout/AppSwitcher.d.ts +2 -1
  117. package/dist/layout/AppSwitcher.js +9 -5
  118. package/dist/layout/AuthPageLayout.d.ts +1 -1
  119. package/dist/layout/ConnectionStatus.d.ts +1 -1
  120. package/dist/layout/ConnectionStatus.js +9 -6
  121. package/dist/layout/ConsoleChatbotFab.d.ts +19 -1
  122. package/dist/layout/ConsoleChatbotFab.js +16 -2
  123. package/dist/layout/ConsoleFloatingChatbot.d.ts +34 -2
  124. package/dist/layout/ConsoleFloatingChatbot.js +391 -41
  125. package/dist/layout/ConsoleLayout.d.ts +1 -1
  126. package/dist/layout/ConsoleLayout.js +27 -11
  127. package/dist/layout/ContextSelectors.d.ts +44 -0
  128. package/dist/layout/ContextSelectors.js +242 -0
  129. package/dist/layout/InboxPopover.d.ts +6 -1
  130. package/dist/layout/InboxPopover.js +25 -6
  131. package/dist/layout/LocaleSwitcher.d.ts +1 -1
  132. package/dist/layout/LocalizedSidebarTrigger.d.ts +2 -0
  133. package/dist/layout/LocalizedSidebarTrigger.js +15 -0
  134. package/dist/layout/MobileViewSwitcherContext.d.ts +1 -1
  135. package/dist/layout/ModeToggle.d.ts +1 -1
  136. package/dist/layout/PageHeader.d.ts +1 -1
  137. package/dist/layout/UnifiedSidebar.d.ts +2 -1
  138. package/dist/layout/UnifiedSidebar.js +116 -15
  139. package/dist/layout/agentPicker.d.ts +56 -0
  140. package/dist/layout/agentPicker.js +40 -0
  141. package/dist/observability/index.d.ts +1 -0
  142. package/dist/observability/index.js +1 -0
  143. package/dist/observability/settleSignal.d.ts +64 -0
  144. package/dist/observability/settleSignal.js +131 -0
  145. package/dist/preview/CommitTimeline.d.ts +15 -0
  146. package/dist/preview/CommitTimeline.js +82 -0
  147. package/dist/preview/DraftChangesPanel.d.ts +19 -0
  148. package/dist/preview/DraftChangesPanel.js +114 -0
  149. package/dist/preview/DraftPreviewBar.d.ts +8 -0
  150. package/dist/preview/DraftPreviewBar.js +86 -0
  151. package/dist/preview/PreviewDraftEmptyState.d.ts +16 -0
  152. package/dist/preview/PreviewDraftEmptyState.js +47 -0
  153. package/dist/preview/PreviewModeContext.d.ts +57 -0
  154. package/dist/preview/PreviewModeContext.js +99 -0
  155. package/dist/preview/UnpublishedAppBar.d.ts +8 -0
  156. package/dist/preview/UnpublishedAppBar.js +83 -0
  157. package/dist/preview/commitHistory.d.ts +28 -0
  158. package/dist/preview/commitHistory.js +48 -0
  159. package/dist/preview/draftStatus.d.ts +20 -0
  160. package/dist/preview/draftStatus.js +27 -0
  161. package/dist/preview/usePublishAllDrafts.d.ts +18 -0
  162. package/dist/preview/usePublishAllDrafts.js +106 -0
  163. package/dist/providers/AdapterProvider.d.ts +1 -1
  164. package/dist/providers/AdapterProvider.js +6 -1
  165. package/dist/providers/ExpressionProvider.d.ts +1 -1
  166. package/dist/providers/MetadataProvider.d.ts +17 -2
  167. package/dist/providers/MetadataProvider.js +192 -12
  168. package/dist/runtime-config.d.ts +46 -2
  169. package/dist/runtime-config.js +39 -2
  170. package/dist/services/builtinComponents.js +68 -59
  171. package/dist/skeletons/SkeletonDashboard.d.ts +1 -1
  172. package/dist/skeletons/SkeletonDetail.d.ts +1 -1
  173. package/dist/skeletons/SkeletonGrid.d.ts +1 -1
  174. package/dist/utils/appRoute.d.ts +21 -0
  175. package/dist/utils/appRoute.js +25 -0
  176. package/dist/utils/deriveRelatedLists.d.ts +54 -0
  177. package/dist/utils/deriveRelatedLists.js +91 -0
  178. package/dist/utils/index.d.ts +4 -0
  179. package/dist/utils/index.js +3 -0
  180. package/dist/utils/managedByEmptyState.d.ts +8 -1
  181. package/dist/utils/managedByEmptyState.js +13 -7
  182. package/dist/utils/preferLocal.d.ts +18 -0
  183. package/dist/utils/preferLocal.js +24 -0
  184. package/dist/views/ActionConfirmDialog.d.ts +1 -1
  185. package/dist/views/ActionConfirmDialog.js +3 -1
  186. package/dist/views/ActionParamDialog.d.ts +6 -1
  187. package/dist/views/ActionParamDialog.js +9 -3
  188. package/dist/views/ActionResultDialog.d.ts +13 -0
  189. package/dist/views/ActionResultDialog.js +134 -0
  190. package/dist/views/ComponentNavView.d.ts +14 -1
  191. package/dist/views/CreateViewDialog.d.ts +1 -1
  192. package/dist/views/DashboardConfigPanel.d.ts +28 -0
  193. package/dist/views/DashboardConfigPanel.js +81 -0
  194. package/dist/views/DashboardView.d.ts +4 -3
  195. package/dist/views/DashboardView.js +38 -239
  196. package/dist/views/FlowRunner.d.ts +31 -0
  197. package/dist/views/FlowRunner.js +121 -0
  198. package/dist/views/InterfaceListPage.d.ts +49 -0
  199. package/dist/views/InterfaceListPage.js +347 -0
  200. package/dist/views/MetadataInspector.d.ts +2 -2
  201. package/dist/views/ObjectView.d.ts +1 -1
  202. package/dist/views/ObjectView.js +209 -532
  203. package/dist/views/PageView.d.ts +8 -3
  204. package/dist/views/PageView.js +45 -32
  205. package/dist/views/RecordDetailView.d.ts +1 -1
  206. package/dist/views/RecordDetailView.js +363 -148
  207. package/dist/views/RecordFormPage.d.ts +1 -1
  208. package/dist/views/RecordFormPage.js +26 -1
  209. package/dist/views/ReportConfigPanel.d.ts +37 -0
  210. package/dist/views/ReportConfigPanel.js +85 -0
  211. package/dist/views/ReportView.d.ts +1 -1
  212. package/dist/views/ReportView.js +116 -7
  213. package/dist/views/RuntimeDraftBar.d.ts +30 -0
  214. package/dist/views/RuntimeDraftBar.js +112 -0
  215. package/dist/views/ScreenView.d.ts +70 -0
  216. package/dist/views/ScreenView.js +73 -0
  217. package/dist/views/SearchResultsPage.d.ts +1 -1
  218. package/dist/views/SearchResultsPage.js +8 -18
  219. package/dist/views/ViewConfigPanel.d.ts +24 -17
  220. package/dist/views/ViewConfigPanel.js +121 -77
  221. package/dist/views/index.d.ts +1 -1
  222. package/dist/views/index.js +1 -1
  223. package/dist/views/metadata-admin/AuditPanel.d.ts +28 -0
  224. package/dist/views/metadata-admin/AuditPanel.js +79 -0
  225. package/dist/views/metadata-admin/DiagnosticsPage.d.ts +20 -0
  226. package/dist/views/metadata-admin/DiagnosticsPage.js +69 -0
  227. package/dist/views/metadata-admin/DirectoryPage.d.ts +16 -1
  228. package/dist/views/metadata-admin/DirectoryPage.js +101 -24
  229. package/dist/views/metadata-admin/DraftReviewPanel.d.ts +33 -0
  230. package/dist/views/metadata-admin/DraftReviewPanel.js +77 -0
  231. package/dist/views/metadata-admin/EmbeddedItemEditor.d.ts +17 -1
  232. package/dist/views/metadata-admin/EmbeddedItemEditor.js +15 -8
  233. package/dist/views/metadata-admin/JsonSourceEditor.d.ts +39 -0
  234. package/dist/views/metadata-admin/JsonSourceEditor.js +196 -0
  235. package/dist/views/metadata-admin/LayeredDiff.d.ts +39 -1
  236. package/dist/views/metadata-admin/LayeredDiff.js +171 -5
  237. package/dist/views/metadata-admin/MetadataDetailDrawer.d.ts +15 -1
  238. package/dist/views/metadata-admin/MetadataTypeActions.d.ts +48 -0
  239. package/dist/views/metadata-admin/MetadataTypeActions.js +165 -0
  240. package/dist/views/metadata-admin/PackagesPage.d.ts +18 -0
  241. package/dist/views/metadata-admin/PackagesPage.js +403 -0
  242. package/dist/views/metadata-admin/PageShell.d.ts +1 -1
  243. package/dist/views/metadata-admin/PageShell.js +9 -4
  244. package/dist/views/metadata-admin/PermissionMatrixEditor.d.ts +35 -1
  245. package/dist/views/metadata-admin/QuickFind.d.ts +21 -1
  246. package/dist/views/metadata-admin/QuickFind.js +6 -3
  247. package/dist/views/metadata-admin/RelatedPanel.d.ts +24 -1
  248. package/dist/views/metadata-admin/RelatedPanel.js +20 -18
  249. package/dist/views/metadata-admin/ResourceEditPage.d.ts +40 -1
  250. package/dist/views/metadata-admin/ResourceEditPage.js +1250 -60
  251. package/dist/views/metadata-admin/ResourceHistoryPage.d.ts +39 -1
  252. package/dist/views/metadata-admin/ResourceHistoryPage.js +66 -16
  253. package/dist/views/metadata-admin/ResourceListPage.d.ts +13 -1
  254. package/dist/views/metadata-admin/ResourceListPage.js +258 -30
  255. package/dist/views/metadata-admin/ResourceRouter.d.ts +23 -1
  256. package/dist/views/metadata-admin/SchemaForm.d.ts +34 -1
  257. package/dist/views/metadata-admin/SchemaForm.js +559 -49
  258. package/dist/views/metadata-admin/StudioHomePage.d.ts +22 -0
  259. package/dist/views/metadata-admin/StudioHomePage.js +205 -0
  260. package/dist/views/metadata-admin/anchors.js +255 -24
  261. package/dist/views/metadata-admin/clientValidation.d.ts +50 -0
  262. package/dist/views/metadata-admin/clientValidation.js +169 -0
  263. package/dist/views/metadata-admin/color-variant-field.d.ts +30 -0
  264. package/dist/views/metadata-admin/color-variant-field.js +38 -0
  265. package/dist/views/metadata-admin/createDerive.d.ts +75 -0
  266. package/dist/views/metadata-admin/createDerive.js +179 -0
  267. package/dist/views/metadata-admin/dashboard-schema.d.ts +12 -0
  268. package/dist/views/metadata-admin/dashboard-schema.js +80 -0
  269. package/dist/views/metadata-admin/datasource/DatasourceResourcePage.d.ts +35 -0
  270. package/dist/views/metadata-admin/datasource/DatasourceResourcePage.js +327 -0
  271. package/dist/views/metadata-admin/datasource/register.d.ts +1 -0
  272. package/dist/views/metadata-admin/datasource/register.js +24 -0
  273. package/dist/views/metadata-admin/default-inspector-registry.d.ts +49 -0
  274. package/dist/views/metadata-admin/default-inspector-registry.js +8 -0
  275. package/dist/views/metadata-admin/default-schemas.js +115 -10
  276. package/dist/views/metadata-admin/external/ExternalDatasourcePanel.d.ts +27 -0
  277. package/dist/views/metadata-admin/external/ExternalDatasourcePanel.js +69 -0
  278. package/dist/views/metadata-admin/external/ImportObjectDialog.d.ts +27 -0
  279. package/dist/views/metadata-admin/external/ImportObjectDialog.js +77 -0
  280. package/dist/views/metadata-admin/external/SchemaBrowser.d.ts +16 -0
  281. package/dist/views/metadata-admin/external/SchemaBrowser.js +74 -0
  282. package/dist/views/metadata-admin/external/ValidationPanel.d.ts +16 -0
  283. package/dist/views/metadata-admin/external/ValidationPanel.js +68 -0
  284. package/dist/views/metadata-admin/external/api.d.ts +100 -0
  285. package/dist/views/metadata-admin/external/api.js +124 -0
  286. package/dist/views/metadata-admin/i18n.d.ts +1 -0
  287. package/dist/views/metadata-admin/i18n.js +1252 -2
  288. package/dist/views/metadata-admin/index.d.ts +8 -5
  289. package/dist/views/metadata-admin/index.js +12 -2
  290. package/dist/views/metadata-admin/inspector-registry.d.ts +51 -0
  291. package/dist/views/metadata-admin/inspector-registry.js +11 -0
  292. package/dist/views/metadata-admin/inspectors/ActionDefaultInspector.d.ts +30 -0
  293. package/dist/views/metadata-admin/inspectors/ActionDefaultInspector.js +180 -0
  294. package/dist/views/metadata-admin/inspectors/AppNavInspector.d.ts +16 -0
  295. package/dist/views/metadata-admin/inspectors/AppNavInspector.js +110 -0
  296. package/dist/views/metadata-admin/inspectors/ConditionBuilder.d.ts +29 -0
  297. package/dist/views/metadata-admin/inspectors/ConditionBuilder.js +154 -0
  298. package/dist/views/metadata-admin/inspectors/DashboardDefaultInspector.d.ts +28 -0
  299. package/dist/views/metadata-admin/inspectors/DashboardDefaultInspector.js +110 -0
  300. package/dist/views/metadata-admin/inspectors/DashboardWidgetInspector.d.ts +18 -0
  301. package/dist/views/metadata-admin/inspectors/DashboardWidgetInspector.js +139 -0
  302. package/dist/views/metadata-admin/inspectors/DatasetDefaultInspector.d.ts +21 -0
  303. package/dist/views/metadata-admin/inspectors/DatasetDefaultInspector.js +221 -0
  304. package/dist/views/metadata-admin/inspectors/FlowEdgeInspector.d.ts +16 -0
  305. package/dist/views/metadata-admin/inspectors/FlowEdgeInspector.js +126 -0
  306. package/dist/views/metadata-admin/inspectors/FlowInspector.d.ts +12 -0
  307. package/dist/views/metadata-admin/inspectors/FlowInspector.js +9 -0
  308. package/dist/views/metadata-admin/inspectors/FlowKeyValueField.d.ts +30 -0
  309. package/dist/views/metadata-admin/inspectors/FlowKeyValueField.js +125 -0
  310. package/dist/views/metadata-admin/inspectors/FlowNodeConfigField.d.ts +18 -0
  311. package/dist/views/metadata-admin/inspectors/FlowNodeConfigField.js +40 -0
  312. package/dist/views/metadata-admin/inspectors/FlowNodeInspector.d.ts +14 -0
  313. package/dist/views/metadata-admin/inspectors/FlowNodeInspector.js +205 -0
  314. package/dist/views/metadata-admin/inspectors/FlowObjectListField.d.ts +26 -0
  315. package/dist/views/metadata-admin/inspectors/FlowObjectListField.js +105 -0
  316. package/dist/views/metadata-admin/inspectors/FlowReferenceField.d.ts +83 -0
  317. package/dist/views/metadata-admin/inspectors/FlowReferenceField.js +181 -0
  318. package/dist/views/metadata-admin/inspectors/FlowStringListField.d.ts +21 -0
  319. package/dist/views/metadata-admin/inspectors/FlowStringListField.js +60 -0
  320. package/dist/views/metadata-admin/inspectors/InspectorComboField.d.ts +40 -0
  321. package/dist/views/metadata-admin/inspectors/InspectorComboField.js +61 -0
  322. package/dist/views/metadata-admin/inspectors/ObjectDefaultInspector.d.ts +21 -0
  323. package/dist/views/metadata-admin/inspectors/ObjectDefaultInspector.js +55 -0
  324. package/dist/views/metadata-admin/inspectors/ObjectFieldInspector.d.ts +23 -0
  325. package/dist/views/metadata-admin/inspectors/ObjectFieldInspector.js +365 -0
  326. package/dist/views/metadata-admin/inspectors/PageBlockInspector.d.ts +48 -0
  327. package/dist/views/metadata-admin/inspectors/PageBlockInspector.js +332 -0
  328. package/dist/views/metadata-admin/inspectors/ReportDefaultInspector.d.ts +58 -0
  329. package/dist/views/metadata-admin/inspectors/ReportDefaultInspector.js +218 -0
  330. package/dist/views/metadata-admin/inspectors/ViewColumnInspector.d.ts +19 -0
  331. package/dist/views/metadata-admin/inspectors/ViewColumnInspector.js +144 -0
  332. package/dist/views/metadata-admin/inspectors/ViewInspector.d.ts +19 -0
  333. package/dist/views/metadata-admin/inspectors/ViewInspector.js +21 -0
  334. package/dist/views/metadata-admin/inspectors/ViewVariantInspector.d.ts +54 -0
  335. package/dist/views/metadata-admin/inspectors/ViewVariantInspector.js +191 -0
  336. package/dist/views/metadata-admin/inspectors/_shared.d.ts +128 -0
  337. package/dist/views/metadata-admin/inspectors/_shared.js +113 -0
  338. package/dist/views/metadata-admin/inspectors/datasetFilterCondition.d.ts +24 -0
  339. package/dist/views/metadata-admin/inspectors/datasetFilterCondition.js +97 -0
  340. package/dist/views/metadata-admin/inspectors/expression-validate.d.ts +26 -0
  341. package/dist/views/metadata-admin/inspectors/expression-validate.js +66 -0
  342. package/dist/views/metadata-admin/inspectors/flow-node-config.d.ts +143 -0
  343. package/dist/views/metadata-admin/inspectors/flow-node-config.js +506 -0
  344. package/dist/views/metadata-admin/inspectors/index.d.ts +1 -0
  345. package/dist/views/metadata-admin/inspectors/index.js +45 -0
  346. package/dist/views/metadata-admin/inspectors/json-schema-to-fields.d.ts +40 -0
  347. package/dist/views/metadata-admin/inspectors/json-schema-to-fields.js +227 -0
  348. package/dist/views/metadata-admin/inspectors/useDatasetFields.d.ts +72 -0
  349. package/dist/views/metadata-admin/inspectors/useDatasetFields.js +0 -0
  350. package/dist/views/metadata-admin/issuePath.d.ts +22 -0
  351. package/dist/views/metadata-admin/issuePath.js +65 -0
  352. package/dist/views/metadata-admin/mergeServerFields.d.ts +65 -0
  353. package/dist/views/metadata-admin/mergeServerFields.js +56 -0
  354. package/dist/views/metadata-admin/package-scope.d.ts +26 -0
  355. package/dist/views/metadata-admin/package-scope.js +43 -0
  356. package/dist/views/metadata-admin/preview-registry.d.ts +55 -0
  357. package/dist/views/metadata-admin/previews/ActionPreview.d.ts +25 -0
  358. package/dist/views/metadata-admin/previews/ActionPreview.js +238 -0
  359. package/dist/views/metadata-admin/previews/AddWidgetPicker.d.ts +12 -0
  360. package/dist/views/metadata-admin/previews/AddWidgetPicker.js +56 -0
  361. package/dist/views/metadata-admin/previews/AgentPreview.d.ts +24 -0
  362. package/dist/views/metadata-admin/previews/AgentPreview.js +100 -0
  363. package/dist/views/metadata-admin/previews/AppNavCanvas.d.ts +31 -0
  364. package/dist/views/metadata-admin/previews/AppNavCanvas.js +260 -0
  365. package/dist/views/metadata-admin/previews/AppPreview.d.ts +16 -1
  366. package/dist/views/metadata-admin/previews/AppPreview.js +23 -14
  367. package/dist/views/metadata-admin/previews/BookPreview.d.ts +20 -0
  368. package/dist/views/metadata-admin/previews/BookPreview.js +132 -0
  369. package/dist/views/metadata-admin/previews/DashboardPreview.d.ts +16 -1
  370. package/dist/views/metadata-admin/previews/DashboardPreview.js +110 -8
  371. package/dist/views/metadata-admin/previews/DatasetPreview.d.ts +18 -0
  372. package/dist/views/metadata-admin/previews/DatasetPreview.js +105 -0
  373. package/dist/views/metadata-admin/previews/DatasourcePreview.d.ts +23 -0
  374. package/dist/views/metadata-admin/previews/DatasourcePreview.js +68 -0
  375. package/dist/views/metadata-admin/previews/EmailTemplatePreview.d.ts +14 -1
  376. package/dist/views/metadata-admin/previews/FieldStub.d.ts +30 -0
  377. package/dist/views/metadata-admin/previews/FieldStub.js +104 -0
  378. package/dist/views/metadata-admin/previews/FieldsListEditor.d.ts +50 -0
  379. package/dist/views/metadata-admin/previews/FieldsListEditor.js +97 -0
  380. package/dist/views/metadata-admin/previews/FlowCanvas.d.ts +49 -0
  381. package/dist/views/metadata-admin/previews/FlowCanvas.js +416 -0
  382. package/dist/views/metadata-admin/previews/FlowPreview.d.ts +20 -0
  383. package/dist/views/metadata-admin/previews/FlowPreview.js +120 -0
  384. package/dist/views/metadata-admin/previews/FlowRunsPanel.d.ts +46 -0
  385. package/dist/views/metadata-admin/previews/FlowRunsPanel.js +97 -0
  386. package/dist/views/metadata-admin/previews/FlowSimulatorPanel.d.ts +25 -0
  387. package/dist/views/metadata-admin/previews/FlowSimulatorPanel.js +204 -0
  388. package/dist/views/metadata-admin/previews/JobPreview.d.ts +28 -0
  389. package/dist/views/metadata-admin/previews/JobPreview.js +290 -0
  390. package/dist/views/metadata-admin/previews/ObjectFormCanvas.d.ts +30 -0
  391. package/dist/views/metadata-admin/previews/ObjectFormCanvas.js +547 -0
  392. package/dist/views/metadata-admin/previews/ObjectPreview.d.ts +14 -1
  393. package/dist/views/metadata-admin/previews/ObjectPreview.js +5 -30
  394. package/dist/views/metadata-admin/previews/OutlineStrip.d.ts +32 -0
  395. package/dist/views/metadata-admin/previews/OutlineStrip.js +8 -0
  396. package/dist/views/metadata-admin/previews/PageBlockCanvas.d.ts +49 -0
  397. package/dist/views/metadata-admin/previews/PageBlockCanvas.js +510 -0
  398. package/dist/views/metadata-admin/previews/PagePreview.d.ts +10 -1
  399. package/dist/views/metadata-admin/previews/PagePreview.js +200 -5
  400. package/dist/views/metadata-admin/previews/PermissionPreview.d.ts +27 -0
  401. package/dist/views/metadata-admin/previews/PermissionPreview.js +115 -0
  402. package/dist/views/metadata-admin/previews/PreviewShell.d.ts +29 -6
  403. package/dist/views/metadata-admin/previews/PreviewShell.js +16 -3
  404. package/dist/views/metadata-admin/previews/ReportPreview.d.ts +18 -1
  405. package/dist/views/metadata-admin/previews/ReportPreview.js +23 -15
  406. package/dist/views/metadata-admin/previews/RolePreview.d.ts +19 -0
  407. package/dist/views/metadata-admin/previews/RolePreview.js +14 -0
  408. package/dist/views/metadata-admin/previews/ScreenPreview.d.ts +38 -0
  409. package/dist/views/metadata-admin/previews/ScreenPreview.js +61 -0
  410. package/dist/views/metadata-admin/previews/SkillPreview.d.ts +22 -0
  411. package/dist/views/metadata-admin/previews/SkillPreview.js +34 -0
  412. package/dist/views/metadata-admin/previews/ToolPreview.d.ts +25 -0
  413. package/dist/views/metadata-admin/previews/ToolPreview.js +122 -0
  414. package/dist/views/metadata-admin/previews/TranslationPreview.d.ts +25 -0
  415. package/dist/views/metadata-admin/previews/TranslationPreview.js +52 -0
  416. package/dist/views/metadata-admin/previews/ValidationPreview.d.ts +27 -0
  417. package/dist/views/metadata-admin/previews/ValidationPreview.js +110 -0
  418. package/dist/views/metadata-admin/previews/ViewColumnPanes.d.ts +62 -0
  419. package/dist/views/metadata-admin/previews/ViewColumnPanes.js +140 -0
  420. package/dist/views/metadata-admin/previews/ViewPreview.d.ts +23 -1
  421. package/dist/views/metadata-admin/previews/ViewPreview.js +101 -73
  422. package/dist/views/metadata-admin/previews/block-config.d.ts +82 -0
  423. package/dist/views/metadata-admin/previews/block-config.js +324 -0
  424. package/dist/views/metadata-admin/previews/block-types.d.ts +40 -0
  425. package/dist/views/metadata-admin/previews/block-types.js +110 -0
  426. package/dist/views/metadata-admin/previews/field-types.d.ts +53 -0
  427. package/dist/views/metadata-admin/previews/field-types.js +97 -0
  428. package/dist/views/metadata-admin/previews/flow-canvas-layout.d.ts +102 -0
  429. package/dist/views/metadata-admin/previews/flow-canvas-layout.js +227 -0
  430. package/dist/views/metadata-admin/previews/flow-canvas-parts.d.ts +96 -0
  431. package/dist/views/metadata-admin/previews/flow-canvas-parts.js +373 -0
  432. package/dist/views/metadata-admin/previews/form-preview.d.ts +24 -0
  433. package/dist/views/metadata-admin/previews/form-preview.js +29 -0
  434. package/dist/views/metadata-admin/previews/index.js +43 -0
  435. package/dist/views/metadata-admin/previews/object-fields-bridge.d.ts +66 -0
  436. package/dist/views/metadata-admin/previews/object-fields-bridge.js +171 -0
  437. package/dist/views/metadata-admin/previews/object-fields-io.d.ts +130 -0
  438. package/dist/views/metadata-admin/previews/object-fields-io.js +243 -0
  439. package/dist/views/metadata-admin/previews/screen-spec.d.ts +43 -0
  440. package/dist/views/metadata-admin/previews/screen-spec.js +108 -0
  441. package/dist/views/metadata-admin/previews/simulator/flow-sim-types.d.ts +102 -0
  442. package/dist/views/metadata-admin/previews/simulator/flow-sim-types.js +2 -0
  443. package/dist/views/metadata-admin/previews/simulator/flow-sim-validate.d.ts +15 -0
  444. package/dist/views/metadata-admin/previews/simulator/flow-sim-validate.js +185 -0
  445. package/dist/views/metadata-admin/previews/simulator/flow-simulator.d.ts +73 -0
  446. package/dist/views/metadata-admin/previews/simulator/flow-simulator.js +426 -0
  447. package/dist/views/metadata-admin/previews/useDatasetCatalog.d.ts +47 -0
  448. package/dist/views/metadata-admin/previews/useDatasetCatalog.js +133 -0
  449. package/dist/views/metadata-admin/previews/useFlowNodePalette.d.ts +44 -0
  450. package/dist/views/metadata-admin/previews/useFlowNodePalette.js +124 -0
  451. package/dist/views/metadata-admin/previews/useMetaOptions.d.ts +8 -0
  452. package/dist/views/metadata-admin/previews/useMetaOptions.js +50 -0
  453. package/dist/views/metadata-admin/previews/useObjectFields.d.ts +23 -0
  454. package/dist/views/metadata-admin/previews/useObjectFields.js +79 -0
  455. package/dist/views/metadata-admin/previews/useObjectOptions.d.ts +8 -0
  456. package/dist/views/metadata-admin/previews/useObjectOptions.js +43 -0
  457. package/dist/views/metadata-admin/previews/view-column-io.d.ts +42 -0
  458. package/dist/views/metadata-admin/previews/view-column-io.js +73 -0
  459. package/dist/views/metadata-admin/previews/widget-types.d.ts +24 -0
  460. package/dist/views/metadata-admin/previews/widget-types.js +40 -0
  461. package/dist/views/metadata-admin/registry.d.ts +140 -19
  462. package/dist/views/metadata-admin/report-schema.d.ts +26 -0
  463. package/dist/views/metadata-admin/report-schema.js +121 -0
  464. package/dist/views/metadata-admin/useMetadata.d.ts +100 -2
  465. package/dist/views/metadata-admin/useMetadata.js +155 -4
  466. package/dist/views/metadata-admin/view-item-normalize.d.ts +20 -0
  467. package/dist/views/metadata-admin/view-item-normalize.js +68 -0
  468. package/dist/views/metadata-admin/view-schema.d.ts +16 -0
  469. package/dist/views/metadata-admin/view-schema.js +107 -0
  470. package/dist/views/metadata-admin/view-variant-model.d.ts +23 -0
  471. package/dist/views/metadata-admin/view-variant-model.js +64 -0
  472. package/dist/views/metadata-admin/widgets.d.ts +89 -1
  473. package/dist/views/metadata-admin/widgets.js +491 -17
  474. package/dist/views/runtime-metadata-persistence.d.ts +78 -0
  475. package/dist/views/runtime-metadata-persistence.js +89 -0
  476. package/dist/views/useOpenRecordList.d.ts +18 -0
  477. package/dist/views/useOpenRecordList.js +36 -0
  478. package/dist/views/userFilterUrlState.d.ts +15 -0
  479. package/dist/views/userFilterUrlState.js +53 -0
  480. package/dist/views/view-config-adapter.d.ts +38 -0
  481. package/dist/views/view-config-adapter.js +80 -0
  482. package/package.json +52 -34
  483. package/dist/views/DesignDrawer.d.ts +0 -28
  484. package/dist/views/DesignDrawer.js +0 -51
  485. package/dist/views/metadata-admin/DesignerEditorWrapper.d.ts +0 -68
  486. package/dist/views/metadata-admin/DesignerEditorWrapper.js +0 -158
@@ -0,0 +1,69 @@
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
+ * MetadataDiagnosticsPage — governance overview.
5
+ *
6
+ * Renders the cross-type `/meta/diagnostics` sweep: every metadata
7
+ * item that fails load-time Zod validation, grouped by type, with a
8
+ * deep-link to its edit page. The framework computes this server-side
9
+ * (see `protocol.getMetaDiagnostics`); the client just paints it.
10
+ *
11
+ * Counterpart surfaces:
12
+ * • DirectoryPage tile badges — per-type aggregate
13
+ * • ResourceListPage row badges — per-item flag inside one type
14
+ * • ResourceEditPage banner + inline SchemaForm errors — full
15
+ * drill-down for a single item
16
+ *
17
+ * This page is the only one that shows everything in one view, so
18
+ * ops can answer "what's broken across the whole app?" without
19
+ * clicking into 27 type pages.
20
+ */
21
+ import * as React from 'react';
22
+ import { Link } from 'react-router-dom';
23
+ import { AlertTriangle, RefreshCw, ArrowLeft } from 'lucide-react';
24
+ import { Button } from '@object-ui/components';
25
+ import { Badge } from '@object-ui/components';
26
+ import { Empty, EmptyTitle, EmptyDescription } from '@object-ui/components';
27
+ import { useMetadataClient, useMetadataTypes, useGlobalDiagnostics, } from './useMetadata';
28
+ import { t, tFormat, translateMetadataType, detectLocale } from './i18n';
29
+ export function MetadataDiagnosticsPage() {
30
+ const client = useMetadataClient();
31
+ const locale = React.useMemo(() => detectLocale(), []);
32
+ const [severity, setSeverity] = React.useState('error');
33
+ const { loading, error, summary, reload } = useGlobalDiagnostics(client, severity);
34
+ const { entries: typesEntries } = useMetadataTypes(client);
35
+ // Index by type so we can look up the human label per-type without
36
+ // scanning the typesEntries array each row.
37
+ const typeLabel = React.useMemo(() => {
38
+ const m = {};
39
+ for (const e of typesEntries) {
40
+ m[e.type] = translateMetadataType(e.type, locale, e.label);
41
+ }
42
+ return m;
43
+ }, [typesEntries, locale]);
44
+ // Group entries by type, ordered by descending count.
45
+ const groups = React.useMemo(() => {
46
+ var _a;
47
+ const map = {};
48
+ for (const e of summary.entries)
49
+ (map[_a = e.type] ?? (map[_a] = [])).push(e);
50
+ return Object.entries(map).sort(([, a], [, b]) => b.length - a.length);
51
+ }, [summary]);
52
+ return (_jsxs("div", { className: "flex flex-col h-full overflow-hidden", children: [_jsxs("div", { className: "px-6 pt-5 pb-4 border-b bg-background", children: [_jsx("nav", { className: "text-xs text-muted-foreground mb-2", children: _jsxs(Link, { to: "..", className: "hover:text-foreground inline-flex items-center gap-1", children: [_jsx(ArrowLeft, { className: "h-3 w-3" }), t('engine.diagnostics.back', locale)] }) }), _jsxs("div", { className: "flex items-center gap-3 flex-wrap", children: [_jsxs("h1", { className: "text-xl font-semibold flex items-center gap-2", children: [_jsx(AlertTriangle, { className: "h-5 w-5 text-destructive" }), t('engine.diagnostics.title', locale)] }), _jsx(Badge, { variant: "outline", className: "text-[11px] border-destructive/40 text-destructive bg-destructive/[0.06]", children: tFormat('engine.diagnostics.summary', locale, {
53
+ count: summary.total,
54
+ items: summary.scannedItems,
55
+ types: summary.scannedTypes,
56
+ }) }), _jsx("div", { className: "flex-1" }), _jsx("div", { role: "tablist", className: "inline-flex items-center rounded-md border bg-muted/40 p-0.5 text-xs", children: ['error', 'warning'].map((s) => (_jsx("button", { role: "tab", type: "button", "aria-selected": severity === s, onClick: () => setSeverity(s), className: 'px-2.5 py-1 rounded transition-colors ' +
57
+ (severity === s
58
+ ? 'bg-background shadow-sm text-foreground'
59
+ : 'text-muted-foreground hover:text-foreground'), children: t(`engine.diagnostics.severity.${s}`, locale) }, s))) }), _jsxs(Button, { variant: "ghost", size: "sm", onClick: reload, children: [_jsx(RefreshCw, { className: "h-3.5 w-3.5 mr-1" }), t('engine.diagnostics.refresh', locale)] })] }), _jsx("p", { className: "text-sm text-muted-foreground mt-2 max-w-3xl", children: t('engine.diagnostics.description', locale) })] }), _jsxs("div", { className: "flex-1 overflow-auto p-6 space-y-6", children: [loading && (_jsx("div", { className: "text-sm text-muted-foreground", children: t('engine.diagnostics.loading', locale) })), !loading && error && (_jsx("div", { className: "text-sm text-destructive border border-destructive/30 rounded p-3 bg-destructive/[0.06]", children: tFormat('engine.diagnostics.loadFailed', locale, { error }) })), !loading && !error && groups.length === 0 && (_jsxs(Empty, { children: [_jsx(EmptyTitle, { children: t('engine.diagnostics.cleanTitle', locale) }), _jsx(EmptyDescription, { children: tFormat('engine.diagnostics.cleanHint', locale, {
60
+ items: summary.scannedItems,
61
+ types: summary.scannedTypes,
62
+ }) })] })), groups.map(([type, rows]) => (_jsxs("section", { className: "space-y-2", children: [_jsxs("h2", { className: "text-xs font-semibold uppercase tracking-wider text-muted-foreground flex items-center gap-2", children: [_jsx(Link, { to: `../${encodeURIComponent(type)}`, className: "hover:text-foreground hover:underline", children: typeLabel[type] ?? type }), _jsx("span", { className: "font-mono normal-case tracking-normal text-[10px] opacity-70", children: type }), _jsx(Badge, { variant: "outline", className: "text-[10px] border-destructive/40 text-destructive bg-destructive/[0.06]", children: rows.length })] }), _jsx("div", { className: "border rounded-lg overflow-hidden", children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { className: "bg-muted/40 text-xs uppercase tracking-wider text-muted-foreground", children: _jsxs("tr", { children: [_jsx("th", { className: "px-3 py-2 text-left font-medium w-[28%]", children: t('engine.diagnostics.col.name', locale) }), _jsx("th", { className: "px-3 py-2 text-left font-medium", children: t('engine.diagnostics.col.issues', locale) })] }) }), _jsx("tbody", { className: "divide-y", children: rows.map((row) => {
63
+ const errs = row.diagnostics.errors ?? [];
64
+ const warns = row.diagnostics.warnings ?? [];
65
+ const head = (severity === 'warning' && errs.length === 0 ? warns : errs).slice(0, 3);
66
+ const rest = Math.max(0, (errs.length || warns.length) - head.length);
67
+ return (_jsxs("tr", { className: "hover:bg-accent/50 align-top", children: [_jsxs("td", { className: "px-3 py-2 align-top", children: [_jsx(Link, { to: `../${encodeURIComponent(type)}/${encodeURIComponent(row.name)}`, className: "text-primary hover:underline font-mono", children: row.name }), errs.length > 0 && (_jsx(Badge, { variant: "outline", className: "ml-2 text-[10px] border-destructive/40 text-destructive", children: tFormat('engine.diagnostics.errorN', locale, { count: errs.length }) })), warns.length > 0 && (_jsx(Badge, { variant: "outline", className: "ml-2 text-[10px] border-amber-500/40 text-amber-700 dark:text-amber-300", children: tFormat('engine.diagnostics.warnN', locale, { count: warns.length }) }))] }), _jsx("td", { className: "px-3 py-2 align-top", children: _jsxs("ul", { className: "space-y-0.5 font-mono text-[11px]", children: [head.map((d, i) => (_jsxs("li", { className: "truncate", children: [_jsx("span", { className: "text-muted-foreground", children: d.path || '(root)' }), _jsx("span", { className: "text-muted-foreground", children: ": " }), d.message] }, i))), rest > 0 && (_jsx("li", { className: "text-muted-foreground", children: tFormat('engine.diagnostics.more', locale, { count: rest }) }))] }) })] }, row.name));
68
+ }) })] }) })] }, type)))] })] }));
69
+ }
@@ -1 +1,16 @@
1
- export declare function MetadataDirectoryPage(): import("react/jsx-runtime").JSX.Element;
1
+ /**
2
+ * MetadataDirectoryPage — registry-driven landing page (Phase 3c).
3
+ *
4
+ * Replaces the Phase 3b placeholder. Improvements:
5
+ * • Search across type id + label + description.
6
+ * • Domain filter chips with counts.
7
+ * • "Writable only" toggle for admins triaging permissions work.
8
+ * • Tiles show: label, machine name, item count (lazy fetched per
9
+ * type when in view), badges (writable / overlay), description.
10
+ *
11
+ * Item counts are lazy — we only fetch when the user lands on a
12
+ * domain that has it. For MVP we just show "—" until the user clicks
13
+ * into a type. Pre-fetching all 27 counts on page load is wasteful.
14
+ */
15
+ import * as React from 'react';
16
+ export declare function MetadataDirectoryPage(): React.JSX.Element;
@@ -15,16 +15,17 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
15
15
  * into a type. Pre-fetching all 27 counts on page load is wasteful.
16
16
  */
17
17
  import * as React from 'react';
18
- import { Link } from 'react-router-dom';
19
- import { Search, Database, Layers, Workflow, Sparkles, Settings, ShieldCheck, Box } from 'lucide-react';
18
+ import { Link, useSearchParams } from 'react-router-dom';
19
+ import { Search, Database, Layers, Workflow, Sparkles, Settings, ShieldCheck, Box, AlertTriangle, Lock } from 'lucide-react';
20
20
  import { Input } from '@object-ui/components';
21
21
  import { Button } from '@object-ui/components';
22
22
  import { Badge } from '@object-ui/components';
23
23
  import { Kbd } from '@object-ui/components';
24
24
  import { Empty, EmptyTitle, EmptyDescription } from '@object-ui/components';
25
- import { useMetadataClient, useMetadataTypes, } from './useMetadata';
25
+ import { useMetadataClient, useMetadataTypes, useGlobalDiagnostics, } from './useMetadata';
26
26
  import { MetadataQuickFind } from './QuickFind';
27
27
  import { translateMetadataType, translateMetadataDomain, t, tFormat, detectLocale, } from './i18n';
28
+ import { buildPackageScopeOptions } from './package-scope';
28
29
  const DOMAIN_ICONS = {
29
30
  data: Database,
30
31
  ui: Layers,
@@ -52,8 +53,12 @@ const DOMAIN_ORDER = [
52
53
  * `field` is managed in-context via the parent object's edit form
53
54
  * (master-detail widget). A flat global list of every field across
54
55
  * every object is rarely useful and clutters the admin surface.
56
+ *
57
+ * `package` is the Studio scope container itself. It has a dedicated
58
+ * management surface for create/publish/import/export flows, so exposing it
59
+ * as scoped metadata would mean "view packages inside a package".
55
60
  */
56
- const HIDDEN_TYPES = new Set(['field']);
61
+ const HIDDEN_TYPES = new Set(['field', 'package']);
57
62
  export function MetadataDirectoryPage() {
58
63
  const client = useMetadataClient();
59
64
  const { loading, error, entries } = useMetadataTypes(client);
@@ -61,21 +66,81 @@ export function MetadataDirectoryPage() {
61
66
  const [query, setQuery] = React.useState('');
62
67
  const [domainFilter, setDomainFilter] = React.useState('all');
63
68
  const [writableOnly, setWritableOnly] = React.useState(false);
69
+ const [searchParams, setSearchParams] = useSearchParams();
70
+ // Studio is scoped to a single *project* package at a time (the sidebar
71
+ // `active_package` selector owns the scope via `?package=`). Load the
72
+ // installed packages and keep only project-scoped ones — anything not
73
+ // tagged `system`/`cloud` (a missing scope counts as project). System
74
+ // metadata therefore never appears on the directory landing.
75
+ const [projectPackages, setProjectPackages] = React.useState(null);
76
+ React.useEffect(() => {
77
+ let cancelled = false;
78
+ (async () => {
79
+ try {
80
+ const list = await client.list('package');
81
+ if (cancelled)
82
+ return;
83
+ setProjectPackages(buildPackageScopeOptions(list));
84
+ }
85
+ catch {
86
+ if (!cancelled)
87
+ setProjectPackages([]);
88
+ }
89
+ })();
90
+ return () => {
91
+ cancelled = true;
92
+ };
93
+ }, [client]);
94
+ // Resolve the active package from the URL, validated against the project
95
+ // package set. `null` while packages are still loading (fail closed).
96
+ const urlPackage = searchParams.get('package');
97
+ const activePackage = React.useMemo(() => {
98
+ if (!projectPackages)
99
+ return null;
100
+ if (urlPackage && projectPackages.some((p) => p.id === urlPackage))
101
+ return urlPackage;
102
+ return projectPackages[0]?.id ?? null;
103
+ }, [projectPackages, urlPackage]);
104
+ // Repair `?package=` so the sidebar selector and deep-links agree on the
105
+ // active scope. Runs once packages resolve and the URL holds no valid
106
+ // project package.
107
+ React.useEffect(() => {
108
+ if (!projectPackages || projectPackages.length === 0)
109
+ return;
110
+ if (urlPackage && projectPackages.some((p) => p.id === urlPackage))
111
+ return;
112
+ const next = new URLSearchParams(searchParams);
113
+ next.set('package', projectPackages[0].id);
114
+ setSearchParams(next, { replace: true });
115
+ // eslint-disable-next-line react-hooks/exhaustive-deps
116
+ }, [projectPackages, urlPackage]);
117
+ // Scope the diagnostics sweep to the active project package so tile
118
+ // counts (and locked/invalid badges) reflect *that package only* and
119
+ // match what the scoped list pages show. `undefined` while packages are
120
+ // still resolving keeps the page in its loading state below.
121
+ const { byType: invalidByType, warnByType, summary: diagSummary, countsByType, lockedByType, packagesByType, loading: diagLoading, } = useGlobalDiagnostics(client, 'warning', activePackage ?? undefined);
122
+ // Base set: visible (non-hidden) metadata types contributed by the active
123
+ // project package. Fail closed — show nothing until a concrete project
124
+ // package is active, so system-only types never surface.
125
+ const scopedEntries = React.useMemo(() => entries.filter((e) => {
126
+ if (HIDDEN_TYPES.has(e.type))
127
+ return false;
128
+ if (!activePackage)
129
+ return false;
130
+ return (packagesByType[e.type] ?? []).includes(activePackage);
131
+ }), [entries, activePackage, packagesByType]);
64
132
  // Counts per domain for the filter chip bar.
65
133
  const domainCounts = React.useMemo(() => {
66
- const visible = entries.filter((e) => !HIDDEN_TYPES.has(e.type));
67
- const c = { all: visible.length };
68
- for (const e of visible) {
134
+ const c = { all: scopedEntries.length };
135
+ for (const e of scopedEntries) {
69
136
  const d = e.domain ?? 'other';
70
137
  c[d] = (c[d] ?? 0) + 1;
71
138
  }
72
139
  return c;
73
- }, [entries]);
74
- const writableCount = entries.filter((e) => !HIDDEN_TYPES.has(e.type) && e.allowOrgOverride).length;
75
- const filtered = entries.filter((e) => {
76
- if (HIDDEN_TYPES.has(e.type))
77
- return false;
78
- if (writableOnly && !e.allowOrgOverride)
140
+ }, [scopedEntries]);
141
+ const writableCount = scopedEntries.filter((e) => e.allowOrgOverride || e.allowRuntimeCreate).length;
142
+ const filtered = scopedEntries.filter((e) => {
143
+ if (writableOnly && !(e.allowOrgOverride || e.allowRuntimeCreate))
79
144
  return false;
80
145
  if (domainFilter !== 'all' && (e.domain ?? 'other') !== domainFilter)
81
146
  return false;
@@ -83,6 +148,7 @@ export function MetadataDirectoryPage() {
83
148
  const q = query.toLowerCase();
84
149
  const hit = e.type.toLowerCase().includes(q) ||
85
150
  (e.label ?? '').toLowerCase().includes(q) ||
151
+ translateMetadataType(e.type, locale, e.label).toLowerCase().includes(q) ||
86
152
  (e.description ?? '').toLowerCase().includes(q);
87
153
  if (!hit)
88
154
  return false;
@@ -101,7 +167,7 @@ export function MetadataDirectoryPage() {
101
167
  return (ai === -1 ? 99 : ai) - (bi === -1 ? 99 : bi);
102
168
  });
103
169
  }, [filtered]);
104
- if (loading) {
170
+ if (loading || projectPackages === null || (activePackage && diagLoading)) {
105
171
  return _jsx("div", { className: "p-6 text-sm text-muted-foreground", children: t('engine.directory.loading', locale) });
106
172
  }
107
173
  if (error) {
@@ -109,12 +175,17 @@ export function MetadataDirectoryPage() {
109
175
  }
110
176
  return (_jsxs("div", { className: "flex flex-col h-full overflow-hidden", children: [_jsxs("div", { className: "px-6 pt-5 pb-4 border-b bg-background", children: [_jsx("h1", { className: "text-xl font-semibold", children: t('engine.directory.title', locale) }), _jsx("p", { className: "text-sm text-muted-foreground mt-1 max-w-3xl", dangerouslySetInnerHTML: {
111
177
  __html: tFormat('engine.directory.description', locale, {
112
- count: `<strong class="text-foreground">${entries.filter((e) => !HIDDEN_TYPES.has(e.type)).length}</strong>`,
178
+ count: `<strong class="text-foreground">${scopedEntries.length}</strong>`,
113
179
  writable: writableCount,
114
180
  }),
115
- } }), _jsxs("div", { className: "flex items-center gap-3 mt-4 flex-wrap", children: [_jsxs("div", { className: "relative flex-1 min-w-[240px] max-w-lg", children: [_jsx(Search, { className: "absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground" }), _jsx(Input, { className: "pl-8", placeholder: t('engine.directory.search', locale), value: query, onChange: (e) => setQuery(e.target.value) })] }), _jsxs(Button, { variant: writableOnly ? 'default' : 'outline', size: "sm", onClick: () => setWritableOnly((w) => !w), children: [t('engine.directory.writableOnly', locale), " (", writableCount, ")"] }), _jsxs("div", { className: "text-xs text-muted-foreground flex items-center gap-1.5", children: [t('engine.directory.quickFind', locale), " ", _jsx(Kbd, { children: "\u2318" }), _jsx(Kbd, { children: "\u21E7" }), _jsx(Kbd, { children: "M" })] })] }), _jsxs("div", { className: "flex items-center gap-1.5 mt-3 flex-wrap", children: [_jsx(DomainChip, { domain: "all", label: t('engine.directory.all', locale), active: domainFilter === 'all', count: domainCounts.all ?? 0, onClick: () => setDomainFilter('all') }), DOMAIN_ORDER.filter((d) => domainCounts[d]).map((d) => (_jsx(DomainChip, { domain: d, label: translateMetadataDomain(d, locale), active: domainFilter === d, count: domainCounts[d] ?? 0, onClick: () => setDomainFilter(d) }, d)))] })] }), _jsxs("div", { className: "flex-1 overflow-auto p-6 space-y-6", children: [filtered.length === 0 && (_jsxs(Empty, { children: [_jsx(EmptyTitle, { children: t('engine.directory.noMatches', locale) }), _jsx(EmptyDescription, { children: t('engine.directory.noMatchesHint', locale) })] })), grouped.map(([domain, group]) => {
181
+ } }), _jsxs("div", { className: "flex items-center gap-3 mt-4 flex-wrap", children: [_jsxs("div", { className: "relative flex-1 min-w-[240px] max-w-lg", children: [_jsx(Search, { className: "absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground" }), _jsx(Input, { className: "pl-8", placeholder: t('engine.directory.search', locale), value: query, onChange: (e) => setQuery(e.target.value) })] }), _jsxs(Button, { variant: writableOnly ? 'default' : 'outline', size: "sm", onClick: () => setWritableOnly((w) => !w), children: [t('engine.directory.writableOnly', locale), " (", writableCount, ")"] }), diagSummary.total > 0 && (_jsx(Button, { asChild: true, variant: "outline", size: "sm", className: "border-destructive/40 text-destructive hover:bg-destructive/10 hover:text-destructive", children: _jsxs(Link, { to: "./_diagnostics", children: [_jsx(AlertTriangle, { className: "h-3.5 w-3.5 mr-1" }), tFormat('engine.directory.diagnosticsLink', locale, { count: diagSummary.total })] }) })), _jsxs("div", { className: "text-xs text-muted-foreground flex items-center gap-1.5", children: [t('engine.directory.quickFind', locale), " ", _jsx(Kbd, { children: "\u2318" }), _jsx(Kbd, { children: "\u21E7" }), _jsx(Kbd, { children: "M" })] })] }), _jsxs("div", { className: "flex items-center gap-1.5 mt-3 flex-wrap", children: [_jsx(DomainChip, { domain: "all", label: t('engine.directory.all', locale), active: domainFilter === 'all', count: domainCounts.all ?? 0, onClick: () => setDomainFilter('all') }), DOMAIN_ORDER.filter((d) => domainCounts[d]).map((d) => (_jsx(DomainChip, { domain: d, label: translateMetadataDomain(d, locale), active: domainFilter === d, count: domainCounts[d] ?? 0, onClick: () => setDomainFilter(d) }, d)))] })] }), _jsxs("div", { className: "flex-1 overflow-auto p-6 space-y-6", children: [projectPackages.length === 0 && (_jsxs(Empty, { children: [_jsx(EmptyTitle, { children: "No project packages installed" }), _jsx(EmptyDescription, { children: "Studio only shows metadata that belongs to a project software package. Install or create a project package to manage its metadata here." })] })), projectPackages.length > 0 && filtered.length === 0 && (_jsxs(Empty, { children: [_jsx(EmptyTitle, { children: t('engine.directory.noMatches', locale) }), _jsx(EmptyDescription, { children: t('engine.directory.noMatchesHint', locale) })] })), grouped.map(([domain, group]) => {
116
182
  const Icon = DOMAIN_ICONS[domain] ?? Box;
117
- return (_jsxs("section", { className: "space-y-2", children: [_jsxs("h2", { className: "text-xs font-semibold uppercase tracking-wider text-muted-foreground flex items-center gap-1.5", children: [_jsx(Icon, { className: "h-3.5 w-3.5" }), translateMetadataDomain(domain, locale), " (", group.length, ")"] }), _jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3", children: group.map((e) => (_jsx(TypeTile, { entry: e, locale: locale }, e.type))) })] }, domain));
183
+ return (_jsxs("section", { className: "space-y-2", children: [_jsxs("h2", { className: "text-xs font-semibold uppercase tracking-wider text-muted-foreground flex items-center gap-1.5", children: [_jsx(Icon, { className: "h-3.5 w-3.5" }), translateMetadataDomain(domain, locale), " (", group.length, ")"] }), _jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3", children: group.map((e) => {
184
+ // Carry the active project package into the list-page
185
+ // deep-link so scope survives navigation.
186
+ const totalCount = countsByType[e.type] ?? 0;
187
+ return (_jsx(TypeTile, { entry: e, locale: locale, invalidCount: invalidByType[e.type] ?? 0, warnCount: warnByType[e.type] ?? 0, lockedCount: lockedByType[e.type] ?? 0, itemCount: totalCount, packageFilter: activePackage ?? undefined }, e.type));
188
+ }) })] }, domain));
118
189
  })] }), _jsx(MetadataQuickFind, {})] }));
119
190
  }
120
191
  function DomainChip({ domain, label, active, count, onClick, }) {
@@ -123,13 +194,19 @@ function DomainChip({ domain, label, active, count, onClick, }) {
123
194
  ? 'bg-primary text-primary-foreground border-primary'
124
195
  : 'bg-background hover:bg-accent border-border text-muted-foreground'), children: [label ?? domain, " ", _jsxs("span", { className: "opacity-70 ml-0.5", children: ["(", count, ")"] })] }));
125
196
  }
126
- function TypeTile({ entry, locale }) {
197
+ function TypeTile({ entry, locale, invalidCount = 0, warnCount = 0, itemCount = 0, lockedCount = 0, packageFilter, }) {
127
198
  // Prefer the locale-table translation; fall back to server's `label` (typically English).
128
199
  const label = translateMetadataType(entry.type, locale, entry.label);
129
- return (_jsxs(Link, { to: `./${encodeURIComponent(entry.type)}`, className: "block p-4 border rounded-lg hover:border-primary hover:bg-accent transition-colors", children: [_jsxs("div", { className: "flex items-start justify-between gap-2", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "font-medium truncate", children: label }), _jsx("code", { className: "text-xs text-muted-foreground font-mono", children: entry.type })] }), entry.allowOrgOverride ? (_jsx(Badge, { className: 'text-[10px] shrink-0 ' +
130
- (entry.overrideSource === 'env'
131
- ? 'bg-amber-100 text-amber-800 hover:bg-amber-100'
132
- : 'bg-emerald-100 text-emerald-800 hover:bg-emerald-100'), title: entry.overrideSource === 'env'
133
- ? 'Writable via OBJECTSTACK_METADATA_WRITABLE env var'
134
- : 'Writable per ADR-0005 overlay opt-in', children: "writable" })) : (_jsx(Badge, { variant: "outline", className: "text-[10px] shrink-0 text-muted-foreground", children: "read-only" }))] }), entry.description && (_jsx("div", { className: "text-xs text-muted-foreground mt-2 line-clamp-2", children: entry.description }))] }));
200
+ const href = packageFilter
201
+ ? `./${encodeURIComponent(entry.type)}?package=${encodeURIComponent(packageFilter)}`
202
+ : `./${encodeURIComponent(entry.type)}`;
203
+ return (_jsxs(Link, { to: href, className: 'block p-4 border rounded-lg hover:bg-accent transition-colors ' +
204
+ (invalidCount > 0
205
+ ? 'border-destructive/40 hover:border-destructive'
206
+ : 'hover:border-primary'), children: [_jsxs("div", { className: "flex items-start justify-between gap-2", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "font-medium truncate flex items-center gap-1.5", children: [invalidCount > 0 && (_jsx("span", { title: tFormat('engine.directory.invalidTooltip', locale ?? 'en', { count: invalidCount }), "aria-label": tFormat('engine.directory.invalidTooltip', locale ?? 'en', { count: invalidCount }), children: _jsx(AlertTriangle, { className: "h-3.5 w-3.5 text-destructive shrink-0" }) })), label] }), _jsx("code", { className: "text-xs text-muted-foreground font-mono", children: entry.type })] }), _jsxs("div", { className: "flex items-center gap-1 shrink-0", children: [_jsx(Badge, { variant: "secondary", className: "text-[10px] tabular-nums", title: tFormat('engine.directory.itemCountTooltip', locale ?? 'en', { count: itemCount }), children: itemCount }), invalidCount > 0 && (_jsx(Badge, { variant: "outline", className: "text-[10px] border-destructive/40 text-destructive bg-destructive/[0.06]", title: tFormat('engine.directory.invalidTooltip', locale ?? 'en', { count: invalidCount }), children: invalidCount })), warnCount > 0 && (_jsx(Badge, { variant: "outline", className: "text-[10px] border-amber-500/40 text-amber-700 dark:text-amber-300 bg-amber-500/[0.06]", title: tFormat('engine.directory.warnTooltip', locale ?? 'en', { count: warnCount }), children: warnCount })), lockedCount > 0 && (_jsxs(Badge, { variant: "outline", className: "text-[10px] border-amber-500/40 text-amber-700 dark:text-amber-300 bg-amber-500/[0.06] inline-flex items-center gap-0.5 px-1.5", title: `${lockedCount} locked item${lockedCount === 1 ? '' : 's'} — see ADR-0010`, "aria-label": `${lockedCount} locked items`, children: [_jsx(Lock, { className: "h-2.5 w-2.5" }), lockedCount] })), entry.allowOrgOverride ? (_jsx(Badge, { className: 'text-[10px] ' +
207
+ (entry.overrideSource === 'env'
208
+ ? 'bg-amber-100 text-amber-800 hover:bg-amber-100'
209
+ : 'bg-emerald-100 text-emerald-800 hover:bg-emerald-100'), title: entry.overrideSource === 'env'
210
+ ? 'Writable via OBJECTSTACK_METADATA_WRITABLE env var'
211
+ : 'Writable per ADR-0005 overlay opt-in', children: t('engine.badge.writable', locale) })) : entry.allowRuntimeCreate ? (_jsx(Badge, { className: "text-[10px] bg-sky-100 text-sky-800 hover:bg-sky-100", title: "Code-shipped items are locked; new items can be created at runtime", children: t('engine.badge.createOnly', locale) })) : (_jsx(Badge, { variant: "outline", className: "text-[10px] text-muted-foreground", children: t('engine.badge.readOnly', locale) }))] })] }), entry.description && (_jsx("div", { className: "text-xs text-muted-foreground mt-2 line-clamp-2", children: entry.description }))] }));
135
212
  }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * ObjectUI
3
+ * Copyright (c) 2024-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ *
8
+ * DraftReviewPanel — ADR-0033 Phase B, §5.
9
+ *
10
+ * A GENERIC, type-agnostic review/diff: it compares a pending DRAFT against the
11
+ * last-published value and lists added / changed / removed top-level keys. It
12
+ * works for ANY metadata type (view, dashboard, flow, …) — the object designer
13
+ * keeps its richer per-field review (`ObjectFormCanvas`); this is the host-level
14
+ * fallback so every type gets a real "what will publishing change" view.
15
+ *
16
+ * It deliberately reuses {@link computeDiffRows} from `LayeredDiff` — the same
17
+ * structural diff engine the Layers tab uses — fed `(published, draft)` so
18
+ * "added" = in the draft but not yet published, "removed" = published key the
19
+ * draft drops, "modified" = value changed.
20
+ */
21
+ import React from 'react';
22
+ import { type SupportedLocale } from './i18n';
23
+ /** Number of top-level keys that differ between the draft and the published value. */
24
+ export declare function computeDraftChangeCount(published: unknown, draft: unknown): number;
25
+ export interface DraftReviewPanelProps {
26
+ /** The last-published (effective) value — the diff baseline. */
27
+ published: unknown;
28
+ /** The pending draft body being reviewed. */
29
+ draft: unknown;
30
+ locale?: SupportedLocale | string;
31
+ className?: string;
32
+ }
33
+ export declare function DraftReviewPanel({ published, draft, locale, className }: DraftReviewPanelProps): React.JSX.Element;
@@ -0,0 +1,77 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * ObjectUI
4
+ * Copyright (c) 2024-present ObjectStack Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ *
9
+ * DraftReviewPanel — ADR-0033 Phase B, §5.
10
+ *
11
+ * A GENERIC, type-agnostic review/diff: it compares a pending DRAFT against the
12
+ * last-published value and lists added / changed / removed top-level keys. It
13
+ * works for ANY metadata type (view, dashboard, flow, …) — the object designer
14
+ * keeps its richer per-field review (`ObjectFormCanvas`); this is the host-level
15
+ * fallback so every type gets a real "what will publishing change" view.
16
+ *
17
+ * It deliberately reuses {@link computeDiffRows} from `LayeredDiff` — the same
18
+ * structural diff engine the Layers tab uses — fed `(published, draft)` so
19
+ * "added" = in the draft but not yet published, "removed" = published key the
20
+ * draft drops, "modified" = value changed.
21
+ */
22
+ import React from 'react';
23
+ import { computeDiffRows } from './LayeredDiff';
24
+ import { t } from './i18n';
25
+ const STATUS_BADGE = {
26
+ modified: 'bg-amber-100 text-amber-900 border border-amber-300 dark:bg-amber-950/60 dark:text-amber-200 dark:border-amber-800',
27
+ added: 'bg-emerald-100 text-emerald-900 border border-emerald-300 dark:bg-emerald-950/60 dark:text-emerald-200 dark:border-emerald-800',
28
+ removed: 'bg-rose-100 text-rose-900 border border-rose-300 dark:bg-rose-950/60 dark:text-rose-200 dark:border-rose-800',
29
+ };
30
+ const STATUS_ROW = {
31
+ modified: 'bg-amber-50/50 dark:bg-amber-950/20',
32
+ added: 'bg-emerald-50/50 dark:bg-emerald-950/20',
33
+ removed: 'bg-rose-50/50 dark:bg-rose-950/20',
34
+ };
35
+ function statusLabel(status, locale) {
36
+ if (status === 'added')
37
+ return t('designer.canvas.diffAdded', locale);
38
+ if (status === 'removed')
39
+ return t('designer.canvas.diffRemoved', locale);
40
+ return t('designer.canvas.diffChanged', locale);
41
+ }
42
+ function formatValue(v) {
43
+ if (v === undefined)
44
+ return '—';
45
+ if (v === null)
46
+ return 'null';
47
+ if (typeof v === 'string')
48
+ return v.length > 200 ? `${v.slice(0, 200)}…` : v;
49
+ if (typeof v === 'number' || typeof v === 'boolean')
50
+ return String(v);
51
+ try {
52
+ const s = JSON.stringify(v);
53
+ return s.length > 200 ? `${s.slice(0, 200)}…` : s;
54
+ }
55
+ catch {
56
+ return String(v);
57
+ }
58
+ }
59
+ /** Number of top-level keys that differ between the draft and the published value. */
60
+ export function computeDraftChangeCount(published, draft) {
61
+ let n = 0;
62
+ for (const row of computeDiffRows(published, draft)) {
63
+ if (row.status !== 'unchanged')
64
+ n += 1;
65
+ }
66
+ return n;
67
+ }
68
+ export function DraftReviewPanel({ published, draft, locale, className }) {
69
+ const rows = React.useMemo(() => computeDiffRows(published, draft).filter((r) => r.status !== 'unchanged'), [published, draft]);
70
+ if (rows.length === 0) {
71
+ return (_jsx("div", { className: `p-4 text-sm text-muted-foreground ${className ?? ''}`, children: t('designer.draftReview.empty', locale) }));
72
+ }
73
+ return (_jsx("div", { className: `flex flex-col gap-1.5 ${className ?? ''}`, "data-testid": "draft-review-panel", children: rows.map((row) => {
74
+ const status = row.status;
75
+ return (_jsxs("div", { className: `flex flex-wrap items-baseline gap-2 rounded-md px-2.5 py-1.5 text-xs ${STATUS_ROW[status]}`, children: [_jsx("span", { className: `inline-flex shrink-0 items-center rounded px-1.5 py-px text-[10px] font-medium uppercase tracking-wide ${STATUS_BADGE[status]}`, children: statusLabel(status, locale) }), _jsx("code", { className: "font-mono font-medium text-foreground", children: row.key }), status === 'added' ? (_jsx("ins", { className: "text-emerald-700 no-underline dark:text-emerald-400", children: formatValue(row.effectiveValue) })) : status === 'removed' ? (_jsx("del", { className: "text-rose-700 dark:text-rose-400", children: formatValue(row.codeValue) })) : (_jsxs("span", { className: "inline-flex items-baseline gap-1.5 text-muted-foreground", children: [_jsx("del", { className: "text-rose-700 dark:text-rose-400", children: formatValue(row.codeValue) }), _jsx("span", { "aria-hidden": "true", children: "\u2192" }), _jsx("ins", { className: "text-emerald-700 no-underline dark:text-emerald-400", children: formatValue(row.effectiveValue) })] }))] }, row.key));
76
+ }) }));
77
+ }
@@ -1,3 +1,19 @@
1
+ /**
2
+ * EmbeddedItemEditor — full-form editor for items that live INSIDE a
3
+ * parent metadata body (e.g. `object.fields.email`).
4
+ *
5
+ * Embedded items don't have their own HTTP endpoint (`PUT /meta/field/email`
6
+ * does NOT exist for object-scoped fields) — so we:
7
+ * 1. Re-fetch the parent's effective body.
8
+ * 2. Render a SchemaForm using the registered sub-type's schema / form
9
+ * (e.g. `field` for `object.fields`).
10
+ * 3. On save: deep-clone the parent, splice the modified item back
11
+ * under `parent.<embeddedPath>.<itemName>`, and PUT the parent.
12
+ *
13
+ * If the sub-type isn't registered (e.g. `index` has no `editAs`), we
14
+ * fall back to a raw-JSON editor so users can still hand-edit and save.
15
+ */
16
+ import * as React from 'react';
1
17
  export interface EmbeddedItemEditorProps {
2
18
  parentType: string;
3
19
  parentName: string;
@@ -12,4 +28,4 @@ export interface EmbeddedItemEditorProps {
12
28
  /** Called after a successful save with the freshly-saved item. */
13
29
  onSaved?: (item: Record<string, unknown>) => void;
14
30
  }
15
- export declare function EmbeddedItemEditor({ parentType, parentName, embeddedPath, itemName, editAs, initialRaw, onSaved, }: EmbeddedItemEditorProps): import("react/jsx-runtime").JSX.Element;
31
+ export declare function EmbeddedItemEditor({ parentType, parentName, embeddedPath, itemName, editAs, initialRaw, onSaved, }: EmbeddedItemEditorProps): React.JSX.Element;
@@ -20,7 +20,9 @@ import { Loader2, Save, AlertTriangle } from 'lucide-react';
20
20
  import { Button } from '@object-ui/components';
21
21
  import { SchemaForm } from './SchemaForm';
22
22
  import { useMetadataClient, useMetadataTypes } from './useMetadata';
23
+ import { detectLocale, t, tFormat, translateValidationMessage } from './i18n';
23
24
  export function EmbeddedItemEditor({ parentType, parentName, embeddedPath, itemName, editAs, initialRaw, onSaved, }) {
25
+ const locale = React.useMemo(() => detectLocale(), []);
24
26
  const client = useMetadataClient();
25
27
  const { entries } = useMetadataTypes(client);
26
28
  const subEntry = editAs ? entries.find((e) => e.type === editAs) : undefined;
@@ -44,10 +46,10 @@ export function EmbeddedItemEditor({ parentType, parentName, embeddedPath, itemN
44
46
  setIssues([]);
45
47
  setSavedAt(null);
46
48
  }, [initialRaw, itemName, parentType, parentName]);
47
- const readOnly = subEntry != null && !subEntry.allowOrgOverride;
49
+ const readOnly = subEntry != null && !subEntry.allowOrgOverride && !subEntry.allowRuntimeCreate;
48
50
  async function doSave() {
49
51
  if (!embeddedPath) {
50
- setError('Cannot save: this item has no embeddedPath registered.');
52
+ setError(t('engine.embedded.saveNoPath', locale));
51
53
  return;
52
54
  }
53
55
  setSaving(true);
@@ -77,10 +79,12 @@ export function EmbeddedItemEditor({ parentType, parentName, embeddedPath, itemN
77
79
  const trimmed = fullPath.startsWith(prefix)
78
80
  ? fullPath.slice(prefix.length)
79
81
  : fullPath;
80
- return { path: trimmed, message: String(x.message ?? 'Invalid') };
82
+ return { path: trimmed, message: translateValidationMessage(String(x.message ?? 'Invalid'), locale) };
81
83
  });
82
84
  setIssues(mapped);
83
- setError(`Validation failed (${mapped.length} issue${mapped.length === 1 ? '' : 's'}).`);
85
+ setError(mapped.length === 1
86
+ ? t('engine.validation.failedOne', locale)
87
+ : tFormat('engine.validation.failed', locale, { count: mapped.length }));
84
88
  }
85
89
  else {
86
90
  setError(err?.message ?? String(err));
@@ -92,17 +96,20 @@ export function EmbeddedItemEditor({ parentType, parentName, embeddedPath, itemN
92
96
  }
93
97
  // No schema registered for this sub-type: fall back to JSON editing.
94
98
  if (!schema) {
95
- return (_jsxs("div", { className: "p-4 space-y-3", children: [_jsxs("div", { className: "text-xs text-muted-foreground", children: ["No form schema is registered for", ' ', _jsx("code", { className: "font-mono", children: editAs ?? 'this item' }), ". Edit the raw JSON below; saving will splice it back into", ' ', _jsxs("span", { className: "font-mono", children: [parentType, "/", parentName, ".", embeddedPath, ".", itemName] }), "."] }), _jsx("textarea", { className: "w-full h-[60vh] font-mono text-xs border rounded p-3 bg-muted/30", value: JSON.stringify(draft, null, 2), onChange: (e) => {
99
+ return (_jsxs("div", { className: "p-4 space-y-3", children: [_jsx("div", { className: "text-xs text-muted-foreground", children: tFormat('engine.embedded.noSchema', locale, {
100
+ type: editAs ?? 'this item',
101
+ target: `${parentType}/${parentName}.${embeddedPath}.${itemName}`,
102
+ }) }), _jsx("textarea", { className: "w-full h-[60vh] font-mono text-xs border rounded p-3 bg-muted/30", value: JSON.stringify(draft, null, 2), onChange: (e) => {
96
103
  try {
97
104
  setDraft(JSON.parse(e.target.value));
98
105
  setError(null);
99
106
  }
100
107
  catch (err) {
101
- setError(`Invalid JSON: ${err.message}`);
108
+ setError(`${t('engine.form.invalidJson', locale)}: ${err.message}`);
102
109
  }
103
- } }), error && (_jsxs("div", { className: "text-sm text-destructive border border-destructive/30 rounded p-2 bg-destructive/5", children: [_jsx(AlertTriangle, { className: "h-4 w-4 inline mr-1" }), " ", error] })), _jsx("div", { className: "flex justify-end", children: _jsxs(Button, { onClick: doSave, disabled: saving || !embeddedPath, children: [saving ? (_jsx(Loader2, { className: "h-4 w-4 mr-1 animate-spin" })) : (_jsx(Save, { className: "h-4 w-4 mr-1" })), "Save into parent"] }) })] }));
110
+ } }), error && (_jsxs("div", { className: "text-sm text-destructive border border-destructive/30 rounded p-2 bg-destructive/5", children: [_jsx(AlertTriangle, { className: "h-4 w-4 inline mr-1" }), " ", error] })), _jsx("div", { className: "flex justify-end", children: _jsxs(Button, { onClick: doSave, disabled: saving || !embeddedPath, children: [saving ? (_jsx(Loader2, { className: "h-4 w-4 mr-1 animate-spin" })) : (_jsx(Save, { className: "h-4 w-4 mr-1" })), tFormat('engine.embedded.saveIntoParent', locale, { parentType: 'parent' })] }) })] }));
104
111
  }
105
- return (_jsxs("div", { className: "p-4 space-y-4", children: [error && (_jsx("div", { className: "text-sm text-destructive border border-destructive/30 rounded p-3 bg-destructive/5", children: error })), savedAt != null && !error && (_jsx("div", { className: "text-sm text-emerald-700 border border-emerald-300 bg-emerald-50 rounded p-2", children: "Saved." })), readOnly && (_jsx("div", { className: "text-xs text-amber-800 border border-amber-300 bg-amber-50 rounded p-2", children: "The parent type is read-only \u2014 saving will still attempt a PUT and may be refused by the server." })), _jsx(SchemaForm, { schema: schema, form: form, value: draft, onChange: setDraft, issues: issues }), _jsx("div", { className: "flex justify-end gap-2 pt-2 border-t", children: _jsxs(Button, { onClick: doSave, disabled: saving || !embeddedPath, children: [saving ? (_jsx(Loader2, { className: "h-4 w-4 mr-1 animate-spin" })) : (_jsx(Save, { className: "h-4 w-4 mr-1" })), "Save into ", parentType] }) }), !embeddedPath && (_jsxs("div", { className: "text-xs text-muted-foreground border rounded p-3", children: [_jsx("div", { className: "font-medium", children: "Read-only" }), _jsx("div", { children: "No embedded path registered \u2014 cannot determine where to write this item back." })] }))] }));
112
+ return (_jsxs("div", { className: "p-4 space-y-4", children: [error && (_jsx("div", { className: "text-sm text-destructive border border-destructive/30 rounded p-3 bg-destructive/5", children: error })), savedAt != null && !error && (_jsx("div", { className: "text-sm text-emerald-700 border border-emerald-300 bg-emerald-50 rounded p-2", children: t('engine.embedded.saved', locale) })), readOnly && (_jsx("div", { className: "text-xs text-amber-800 border border-amber-300 bg-amber-50 rounded p-2", children: t('engine.embedded.readOnlyParent', locale) })), _jsx(SchemaForm, { schema: schema, form: form, value: draft, onChange: setDraft, issues: issues }), _jsx("div", { className: "flex justify-end gap-2 pt-2 border-t", children: _jsxs(Button, { onClick: doSave, disabled: saving || !embeddedPath, children: [saving ? (_jsx(Loader2, { className: "h-4 w-4 mr-1 animate-spin" })) : (_jsx(Save, { className: "h-4 w-4 mr-1" })), tFormat('engine.embedded.saveIntoParent', locale, { parentType })] }) }), !embeddedPath && (_jsxs("div", { className: "text-xs text-muted-foreground border rounded p-3", children: [_jsx("div", { className: "font-medium", children: t('engine.embedded.readOnly', locale) }), _jsx("div", { children: t('engine.embedded.noPathHint', locale) })] }))] }));
106
113
  }
107
114
  /**
108
115
  * Return a NEW parent object with the embedded item replaced. The
@@ -0,0 +1,39 @@
1
+ /**
2
+ * ObjectUI
3
+ * Copyright (c) 2024-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ /**
9
+ * JsonSourceEditor — Monaco-backed JSON editor for the metadata
10
+ * designer's "Source" tab. Replaces the old textarea so power users
11
+ * get syntax highlighting, bracket matching, folding, and inline
12
+ * error squigglies driven by the server-side `_diagnostics` payload.
13
+ *
14
+ * Markers: `issues[]` use dotted (or array) JSON paths matching the
15
+ * Zod issue shape. We resolve each path to a Monaco range with
16
+ * `jsonc-parser` so the squiggle lands on the offending value (or
17
+ * the property key when the value is absent). Unresolved paths fall
18
+ * back to a marker on line 1, so nothing is silently lost.
19
+ */
20
+ import React from 'react';
21
+ export interface JsonIssue {
22
+ /** Dotted path (e.g. `fields.owner.type`) or empty for root. */
23
+ path: string;
24
+ message: string;
25
+ /** Defaults to `'error'`. */
26
+ severity?: 'error' | 'warning';
27
+ }
28
+ export interface JsonSourceEditorProps {
29
+ value: unknown;
30
+ onChange: (next: Record<string, unknown>) => void;
31
+ readOnly?: boolean;
32
+ issues?: JsonIssue[];
33
+ /** Pixel or CSS-length height. Defaults to `60vh`. */
34
+ height?: string | number;
35
+ /** Grace period (ms) before the textarea fallback engages. Test-tunable. */
36
+ fallbackDelayMs?: number;
37
+ }
38
+ export declare function JsonSourceEditor({ value, onChange, readOnly, issues, height, fallbackDelayMs, }: JsonSourceEditorProps): React.JSX.Element;
39
+ export default JsonSourceEditor;