@object-ui/app-shell 6.2.3 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (468) hide show
  1. package/CHANGELOG.md +948 -0
  2. package/README.md +292 -0
  3. package/dist/assistant/assistantBus.d.ts +72 -0
  4. package/dist/assistant/assistantBus.js +133 -0
  5. package/dist/chrome/CommandPalette.d.ts +1 -1
  6. package/dist/chrome/CommandPalette.js +26 -22
  7. package/dist/chrome/ConditionalAuthWrapper.d.ts +1 -1
  8. package/dist/chrome/ConsoleToaster.d.ts +1 -1
  9. package/dist/chrome/ConsoleToaster.js +3 -1
  10. package/dist/chrome/ErrorBoundary.d.ts +1 -1
  11. package/dist/chrome/KeyboardShortcutsDialog.d.ts +1 -1
  12. package/dist/chrome/KeyboardShortcutsDialog.js +16 -5
  13. package/dist/chrome/LoadingScreen.d.ts +1 -1
  14. package/dist/chrome/LoadingScreen.js +22 -26
  15. package/dist/chrome/RouteFader.d.ts +1 -1
  16. package/dist/chrome/ThemeProvider.d.ts +1 -1
  17. package/dist/components/ManagedByBadge.d.ts +1 -1
  18. package/dist/console/AppContent.d.ts +1 -1
  19. package/dist/console/AppContent.js +170 -37
  20. package/dist/console/ConsoleShell.d.ts +7 -7
  21. package/dist/console/ConsoleShell.js +32 -3
  22. package/dist/console/ai/AiChatPage.d.ts +88 -1
  23. package/dist/console/ai/AiChatPage.js +743 -66
  24. package/dist/console/ai/ConversationsSidebar.d.ts +26 -1
  25. package/dist/console/ai/ConversationsSidebar.js +149 -34
  26. package/dist/console/ai/LiveCanvas.d.ts +22 -0
  27. package/dist/console/ai/LiveCanvas.js +78 -0
  28. package/dist/console/ai/reconcileTurn.d.ts +8 -0
  29. package/dist/console/ai/reconcileTurn.js +20 -0
  30. package/dist/console/auth/AuthPageLayout.d.ts +1 -1
  31. package/dist/console/auth/ForgotPasswordPage.d.ts +1 -1
  32. package/dist/console/auth/LoginPage.d.ts +1 -1
  33. package/dist/console/auth/RegisterPage.d.ts +1 -1
  34. package/dist/console/auth/RegisterPage.js +23 -3
  35. package/dist/console/cloud-connection/CloudConnectionPanel.d.ts +1 -0
  36. package/dist/console/cloud-connection/CloudConnectionPanel.js +169 -0
  37. package/dist/console/home/AppCard.d.ts +1 -1
  38. package/dist/console/home/AppCard.js +6 -12
  39. package/dist/console/home/HomeAppsStrip.d.ts +8 -0
  40. package/dist/console/home/HomeAppsStrip.js +61 -0
  41. package/dist/console/home/HomeLayout.d.ts +1 -1
  42. package/dist/console/home/HomeLayout.js +3 -1
  43. package/dist/console/home/HomePage.d.ts +1 -2
  44. package/dist/console/home/HomePage.js +149 -21
  45. package/dist/console/home/HomeRail.d.ts +22 -0
  46. package/dist/console/home/HomeRail.js +62 -0
  47. package/dist/console/home/QuickActions.d.ts +1 -1
  48. package/dist/console/home/QuickActions.js +3 -11
  49. package/dist/console/home/RecentApps.d.ts +1 -1
  50. package/dist/console/home/RecentApps.js +2 -2
  51. package/dist/console/home/StarredApps.d.ts +1 -1
  52. package/dist/console/home/StarredApps.js +2 -2
  53. package/dist/console/marketplace/InstalledListWidget.d.ts +1 -0
  54. package/dist/console/marketplace/InstalledListWidget.js +93 -0
  55. package/dist/console/marketplace/MarkdownText.d.ts +1 -1
  56. package/dist/console/marketplace/MarketplaceAccessDenied.d.ts +1 -1
  57. package/dist/console/marketplace/MarketplaceInstalledPage.d.ts +8 -14
  58. package/dist/console/marketplace/MarketplaceInstalledPage.js +14 -66
  59. package/dist/console/marketplace/MarketplacePackagePage.d.ts +1 -1
  60. package/dist/console/marketplace/MarketplacePackagePage.js +249 -8
  61. package/dist/console/marketplace/MarketplacePage.d.ts +1 -1
  62. package/dist/console/marketplace/MarketplacePage.js +60 -3
  63. package/dist/console/marketplace/PackageIcon.d.ts +1 -1
  64. package/dist/console/marketplace/PluginDisclosure.d.ts +14 -0
  65. package/dist/console/marketplace/PluginDisclosure.js +38 -0
  66. package/dist/console/marketplace/marketplaceApi.d.ts +123 -0
  67. package/dist/console/marketplace/marketplaceApi.js +254 -1
  68. package/dist/console/organizations/CreateWorkspaceDialog.d.ts +1 -1
  69. package/dist/console/organizations/OrganizationsLayout.d.ts +1 -1
  70. package/dist/console/organizations/OrganizationsPage.d.ts +1 -1
  71. package/dist/console/organizations/manage/AcceptInvitationPage.d.ts +1 -1
  72. package/dist/console/organizations/manage/InvitationsPage.d.ts +1 -1
  73. package/dist/console/organizations/manage/InviteMemberDialog.d.ts +1 -1
  74. package/dist/console/organizations/manage/MembersPage.d.ts +1 -1
  75. package/dist/console/organizations/manage/OrganizationLayout.d.ts +1 -1
  76. package/dist/console/organizations/manage/SettingsPage.d.ts +1 -1
  77. package/dist/context/CommandPaletteProvider.d.ts +44 -0
  78. package/dist/context/CommandPaletteProvider.js +71 -0
  79. package/dist/context/FavoritesProvider.d.ts +1 -1
  80. package/dist/context/NavigationContext.d.ts +1 -1
  81. package/dist/context/RecentItemsProvider.d.ts +2 -2
  82. package/dist/context/UserStateAdapters.d.ts +1 -1
  83. package/dist/context/index.d.ts +2 -0
  84. package/dist/context/index.js +1 -0
  85. package/dist/hooks/index.d.ts +5 -2
  86. package/dist/hooks/index.js +4 -1
  87. package/dist/hooks/useActionModal.d.ts +53 -0
  88. package/dist/hooks/useActionModal.js +111 -0
  89. package/dist/hooks/useChatConversation.d.ts +107 -4
  90. package/dist/hooks/useChatConversation.js +253 -25
  91. package/dist/hooks/useConsoleActionRuntime.d.ts +70 -0
  92. package/dist/hooks/useConsoleActionRuntime.js +560 -0
  93. package/dist/hooks/useConversationList.js +61 -3
  94. package/dist/hooks/useHomeInbox.d.ts +13 -0
  95. package/dist/hooks/useHomeInbox.js +142 -0
  96. package/dist/hooks/useNavPins.js +17 -23
  97. package/dist/hooks/useNavigationSync.d.ts +33 -0
  98. package/dist/hooks/useNavigationSync.js +98 -12
  99. package/dist/hooks/useReconcileOnError.d.ts +40 -0
  100. package/dist/hooks/useReconcileOnError.js +37 -0
  101. package/dist/hooks/useRecordApprovals.d.ts +18 -19
  102. package/dist/hooks/useRecordApprovals.js +24 -40
  103. package/dist/hooks/useResponsiveSidebar.js +14 -5
  104. package/dist/hooks/useSettleSignal.d.ts +19 -0
  105. package/dist/hooks/useSettleSignal.js +20 -0
  106. package/dist/hooks/useTrackRouteAsRecent.js +35 -0
  107. package/dist/hooks/useUrlOverlay.d.ts +62 -0
  108. package/dist/hooks/useUrlOverlay.js +88 -0
  109. package/dist/index.d.ts +16 -7
  110. package/dist/index.js +12 -4
  111. package/dist/layout/ActivityFeed.d.ts +1 -1
  112. package/dist/layout/AppHeader.d.ts +3 -2
  113. package/dist/layout/AppHeader.js +237 -72
  114. package/dist/layout/AppSidebar.d.ts +2 -1
  115. package/dist/layout/AppSidebar.js +26 -46
  116. package/dist/layout/AppSwitcher.d.ts +2 -1
  117. package/dist/layout/AppSwitcher.js +9 -5
  118. package/dist/layout/AuthPageLayout.d.ts +1 -1
  119. package/dist/layout/ConnectionStatus.d.ts +1 -1
  120. package/dist/layout/ConnectionStatus.js +9 -6
  121. package/dist/layout/ConsoleChatbotFab.d.ts +19 -1
  122. package/dist/layout/ConsoleChatbotFab.js +16 -2
  123. package/dist/layout/ConsoleFloatingChatbot.d.ts +32 -2
  124. package/dist/layout/ConsoleFloatingChatbot.js +374 -41
  125. package/dist/layout/ConsoleLayout.d.ts +1 -1
  126. package/dist/layout/ConsoleLayout.js +27 -11
  127. package/dist/layout/ContextSelectors.d.ts +44 -0
  128. package/dist/layout/ContextSelectors.js +218 -0
  129. package/dist/layout/InboxPopover.d.ts +6 -1
  130. package/dist/layout/InboxPopover.js +25 -6
  131. package/dist/layout/LocaleSwitcher.d.ts +1 -1
  132. package/dist/layout/LocalizedSidebarTrigger.d.ts +2 -0
  133. package/dist/layout/LocalizedSidebarTrigger.js +15 -0
  134. package/dist/layout/MobileViewSwitcherContext.d.ts +1 -1
  135. package/dist/layout/ModeToggle.d.ts +1 -1
  136. package/dist/layout/PageHeader.d.ts +1 -1
  137. package/dist/layout/UnifiedSidebar.d.ts +2 -1
  138. package/dist/layout/UnifiedSidebar.js +116 -15
  139. package/dist/observability/index.d.ts +1 -0
  140. package/dist/observability/index.js +1 -0
  141. package/dist/observability/settleSignal.d.ts +64 -0
  142. package/dist/observability/settleSignal.js +131 -0
  143. package/dist/preview/DraftChangesPanel.d.ts +19 -0
  144. package/dist/preview/DraftChangesPanel.js +114 -0
  145. package/dist/preview/DraftPreviewBar.d.ts +8 -0
  146. package/dist/preview/DraftPreviewBar.js +86 -0
  147. package/dist/preview/PreviewDraftEmptyState.d.ts +16 -0
  148. package/dist/preview/PreviewDraftEmptyState.js +47 -0
  149. package/dist/preview/PreviewModeContext.d.ts +57 -0
  150. package/dist/preview/PreviewModeContext.js +99 -0
  151. package/dist/preview/UnpublishedAppBar.d.ts +8 -0
  152. package/dist/preview/UnpublishedAppBar.js +79 -0
  153. package/dist/preview/draftStatus.d.ts +20 -0
  154. package/dist/preview/draftStatus.js +27 -0
  155. package/dist/preview/usePublishAllDrafts.d.ts +18 -0
  156. package/dist/preview/usePublishAllDrafts.js +106 -0
  157. package/dist/providers/AdapterProvider.d.ts +1 -1
  158. package/dist/providers/AdapterProvider.js +6 -1
  159. package/dist/providers/ExpressionProvider.d.ts +1 -1
  160. package/dist/providers/MetadataProvider.d.ts +17 -2
  161. package/dist/providers/MetadataProvider.js +183 -12
  162. package/dist/runtime-config.d.ts +46 -2
  163. package/dist/runtime-config.js +39 -2
  164. package/dist/services/builtinComponents.js +68 -59
  165. package/dist/skeletons/SkeletonDashboard.d.ts +1 -1
  166. package/dist/skeletons/SkeletonDetail.d.ts +1 -1
  167. package/dist/skeletons/SkeletonGrid.d.ts +1 -1
  168. package/dist/utils/appRoute.d.ts +21 -0
  169. package/dist/utils/appRoute.js +25 -0
  170. package/dist/utils/deriveRelatedLists.d.ts +54 -0
  171. package/dist/utils/deriveRelatedLists.js +91 -0
  172. package/dist/utils/index.d.ts +4 -0
  173. package/dist/utils/index.js +3 -0
  174. package/dist/utils/managedByEmptyState.d.ts +8 -1
  175. package/dist/utils/managedByEmptyState.js +13 -7
  176. package/dist/utils/preferLocal.d.ts +18 -0
  177. package/dist/utils/preferLocal.js +24 -0
  178. package/dist/views/ActionConfirmDialog.d.ts +1 -1
  179. package/dist/views/ActionConfirmDialog.js +3 -1
  180. package/dist/views/ActionParamDialog.d.ts +6 -1
  181. package/dist/views/ActionParamDialog.js +9 -3
  182. package/dist/views/ActionResultDialog.d.ts +13 -0
  183. package/dist/views/ActionResultDialog.js +134 -0
  184. package/dist/views/ComponentNavView.d.ts +14 -1
  185. package/dist/views/CreateViewDialog.d.ts +1 -1
  186. package/dist/views/DashboardConfigPanel.d.ts +28 -0
  187. package/dist/views/DashboardConfigPanel.js +81 -0
  188. package/dist/views/DashboardView.d.ts +4 -3
  189. package/dist/views/DashboardView.js +38 -239
  190. package/dist/views/FlowRunner.d.ts +59 -0
  191. package/dist/views/FlowRunner.js +153 -0
  192. package/dist/views/InterfaceListPage.d.ts +49 -0
  193. package/dist/views/InterfaceListPage.js +347 -0
  194. package/dist/views/MetadataInspector.d.ts +2 -2
  195. package/dist/views/ObjectView.d.ts +1 -1
  196. package/dist/views/ObjectView.js +209 -532
  197. package/dist/views/PageView.d.ts +8 -3
  198. package/dist/views/PageView.js +45 -32
  199. package/dist/views/RecordDetailView.d.ts +1 -1
  200. package/dist/views/RecordDetailView.js +363 -148
  201. package/dist/views/RecordFormPage.d.ts +1 -1
  202. package/dist/views/RecordFormPage.js +26 -1
  203. package/dist/views/ReportConfigPanel.d.ts +37 -0
  204. package/dist/views/ReportConfigPanel.js +85 -0
  205. package/dist/views/ReportView.d.ts +1 -1
  206. package/dist/views/ReportView.js +116 -7
  207. package/dist/views/RuntimeDraftBar.d.ts +30 -0
  208. package/dist/views/RuntimeDraftBar.js +112 -0
  209. package/dist/views/SearchResultsPage.d.ts +1 -1
  210. package/dist/views/SearchResultsPage.js +8 -18
  211. package/dist/views/ViewConfigPanel.d.ts +24 -17
  212. package/dist/views/ViewConfigPanel.js +121 -77
  213. package/dist/views/index.d.ts +1 -1
  214. package/dist/views/index.js +1 -1
  215. package/dist/views/metadata-admin/AuditPanel.d.ts +28 -0
  216. package/dist/views/metadata-admin/AuditPanel.js +79 -0
  217. package/dist/views/metadata-admin/DiagnosticsPage.d.ts +20 -0
  218. package/dist/views/metadata-admin/DiagnosticsPage.js +69 -0
  219. package/dist/views/metadata-admin/DirectoryPage.d.ts +16 -1
  220. package/dist/views/metadata-admin/DirectoryPage.js +113 -24
  221. package/dist/views/metadata-admin/DraftReviewPanel.d.ts +33 -0
  222. package/dist/views/metadata-admin/DraftReviewPanel.js +77 -0
  223. package/dist/views/metadata-admin/EmbeddedItemEditor.d.ts +17 -1
  224. package/dist/views/metadata-admin/EmbeddedItemEditor.js +15 -8
  225. package/dist/views/metadata-admin/JsonSourceEditor.d.ts +37 -0
  226. package/dist/views/metadata-admin/JsonSourceEditor.js +178 -0
  227. package/dist/views/metadata-admin/LayeredDiff.d.ts +39 -1
  228. package/dist/views/metadata-admin/LayeredDiff.js +171 -5
  229. package/dist/views/metadata-admin/MetadataDetailDrawer.d.ts +15 -1
  230. package/dist/views/metadata-admin/MetadataTypeActions.d.ts +48 -0
  231. package/dist/views/metadata-admin/MetadataTypeActions.js +165 -0
  232. package/dist/views/metadata-admin/PackagesPage.d.ts +18 -0
  233. package/dist/views/metadata-admin/PackagesPage.js +395 -0
  234. package/dist/views/metadata-admin/PageShell.d.ts +1 -1
  235. package/dist/views/metadata-admin/PageShell.js +9 -4
  236. package/dist/views/metadata-admin/PermissionMatrixEditor.d.ts +35 -1
  237. package/dist/views/metadata-admin/QuickFind.d.ts +21 -1
  238. package/dist/views/metadata-admin/QuickFind.js +6 -3
  239. package/dist/views/metadata-admin/RelatedPanel.d.ts +24 -1
  240. package/dist/views/metadata-admin/RelatedPanel.js +20 -18
  241. package/dist/views/metadata-admin/ResourceEditPage.d.ts +40 -1
  242. package/dist/views/metadata-admin/ResourceEditPage.js +1223 -60
  243. package/dist/views/metadata-admin/ResourceHistoryPage.d.ts +39 -1
  244. package/dist/views/metadata-admin/ResourceHistoryPage.js +66 -16
  245. package/dist/views/metadata-admin/ResourceListPage.d.ts +13 -1
  246. package/dist/views/metadata-admin/ResourceListPage.js +266 -30
  247. package/dist/views/metadata-admin/ResourceRouter.d.ts +23 -1
  248. package/dist/views/metadata-admin/SchemaForm.d.ts +34 -1
  249. package/dist/views/metadata-admin/SchemaForm.js +559 -49
  250. package/dist/views/metadata-admin/StudioHomePage.d.ts +22 -0
  251. package/dist/views/metadata-admin/StudioHomePage.js +213 -0
  252. package/dist/views/metadata-admin/anchors.js +237 -24
  253. package/dist/views/metadata-admin/clientValidation.d.ts +50 -0
  254. package/dist/views/metadata-admin/clientValidation.js +169 -0
  255. package/dist/views/metadata-admin/color-variant-field.d.ts +30 -0
  256. package/dist/views/metadata-admin/color-variant-field.js +38 -0
  257. package/dist/views/metadata-admin/createDerive.d.ts +75 -0
  258. package/dist/views/metadata-admin/createDerive.js +179 -0
  259. package/dist/views/metadata-admin/dashboard-schema.d.ts +12 -0
  260. package/dist/views/metadata-admin/dashboard-schema.js +80 -0
  261. package/dist/views/metadata-admin/datasource/DatasourceResourcePage.d.ts +35 -0
  262. package/dist/views/metadata-admin/datasource/DatasourceResourcePage.js +327 -0
  263. package/dist/views/metadata-admin/datasource/register.d.ts +1 -0
  264. package/dist/views/metadata-admin/datasource/register.js +24 -0
  265. package/dist/views/metadata-admin/default-inspector-registry.d.ts +49 -0
  266. package/dist/views/metadata-admin/default-inspector-registry.js +8 -0
  267. package/dist/views/metadata-admin/default-schemas.js +115 -10
  268. package/dist/views/metadata-admin/external/ExternalDatasourcePanel.d.ts +27 -0
  269. package/dist/views/metadata-admin/external/ExternalDatasourcePanel.js +69 -0
  270. package/dist/views/metadata-admin/external/ImportObjectDialog.d.ts +27 -0
  271. package/dist/views/metadata-admin/external/ImportObjectDialog.js +77 -0
  272. package/dist/views/metadata-admin/external/SchemaBrowser.d.ts +16 -0
  273. package/dist/views/metadata-admin/external/SchemaBrowser.js +74 -0
  274. package/dist/views/metadata-admin/external/ValidationPanel.d.ts +16 -0
  275. package/dist/views/metadata-admin/external/ValidationPanel.js +68 -0
  276. package/dist/views/metadata-admin/external/api.d.ts +100 -0
  277. package/dist/views/metadata-admin/external/api.js +124 -0
  278. package/dist/views/metadata-admin/i18n.d.ts +1 -0
  279. package/dist/views/metadata-admin/i18n.js +1166 -2
  280. package/dist/views/metadata-admin/index.d.ts +8 -5
  281. package/dist/views/metadata-admin/index.js +12 -2
  282. package/dist/views/metadata-admin/inspector-registry.d.ts +51 -0
  283. package/dist/views/metadata-admin/inspector-registry.js +11 -0
  284. package/dist/views/metadata-admin/inspectors/ActionDefaultInspector.d.ts +30 -0
  285. package/dist/views/metadata-admin/inspectors/ActionDefaultInspector.js +180 -0
  286. package/dist/views/metadata-admin/inspectors/AppNavInspector.d.ts +16 -0
  287. package/dist/views/metadata-admin/inspectors/AppNavInspector.js +110 -0
  288. package/dist/views/metadata-admin/inspectors/ConditionBuilder.d.ts +29 -0
  289. package/dist/views/metadata-admin/inspectors/ConditionBuilder.js +154 -0
  290. package/dist/views/metadata-admin/inspectors/DashboardDefaultInspector.d.ts +28 -0
  291. package/dist/views/metadata-admin/inspectors/DashboardDefaultInspector.js +110 -0
  292. package/dist/views/metadata-admin/inspectors/DashboardWidgetInspector.d.ts +18 -0
  293. package/dist/views/metadata-admin/inspectors/DashboardWidgetInspector.js +139 -0
  294. package/dist/views/metadata-admin/inspectors/DatasetDefaultInspector.d.ts +21 -0
  295. package/dist/views/metadata-admin/inspectors/DatasetDefaultInspector.js +107 -0
  296. package/dist/views/metadata-admin/inspectors/FlowEdgeInspector.d.ts +16 -0
  297. package/dist/views/metadata-admin/inspectors/FlowEdgeInspector.js +45 -0
  298. package/dist/views/metadata-admin/inspectors/FlowInspector.d.ts +12 -0
  299. package/dist/views/metadata-admin/inspectors/FlowInspector.js +9 -0
  300. package/dist/views/metadata-admin/inspectors/FlowKeyValueField.d.ts +30 -0
  301. package/dist/views/metadata-admin/inspectors/FlowKeyValueField.js +125 -0
  302. package/dist/views/metadata-admin/inspectors/FlowNodeConfigField.d.ts +18 -0
  303. package/dist/views/metadata-admin/inspectors/FlowNodeConfigField.js +40 -0
  304. package/dist/views/metadata-admin/inspectors/FlowNodeInspector.d.ts +14 -0
  305. package/dist/views/metadata-admin/inspectors/FlowNodeInspector.js +140 -0
  306. package/dist/views/metadata-admin/inspectors/FlowObjectListField.d.ts +26 -0
  307. package/dist/views/metadata-admin/inspectors/FlowObjectListField.js +105 -0
  308. package/dist/views/metadata-admin/inspectors/FlowReferenceField.d.ts +83 -0
  309. package/dist/views/metadata-admin/inspectors/FlowReferenceField.js +181 -0
  310. package/dist/views/metadata-admin/inspectors/FlowStringListField.d.ts +21 -0
  311. package/dist/views/metadata-admin/inspectors/FlowStringListField.js +60 -0
  312. package/dist/views/metadata-admin/inspectors/InspectorComboField.d.ts +40 -0
  313. package/dist/views/metadata-admin/inspectors/InspectorComboField.js +61 -0
  314. package/dist/views/metadata-admin/inspectors/ObjectDefaultInspector.d.ts +21 -0
  315. package/dist/views/metadata-admin/inspectors/ObjectDefaultInspector.js +54 -0
  316. package/dist/views/metadata-admin/inspectors/ObjectFieldInspector.d.ts +23 -0
  317. package/dist/views/metadata-admin/inspectors/ObjectFieldInspector.js +330 -0
  318. package/dist/views/metadata-admin/inspectors/PageBlockInspector.d.ts +48 -0
  319. package/dist/views/metadata-admin/inspectors/PageBlockInspector.js +332 -0
  320. package/dist/views/metadata-admin/inspectors/ReportDefaultInspector.d.ts +58 -0
  321. package/dist/views/metadata-admin/inspectors/ReportDefaultInspector.js +160 -0
  322. package/dist/views/metadata-admin/inspectors/ViewColumnInspector.d.ts +19 -0
  323. package/dist/views/metadata-admin/inspectors/ViewColumnInspector.js +144 -0
  324. package/dist/views/metadata-admin/inspectors/ViewInspector.d.ts +19 -0
  325. package/dist/views/metadata-admin/inspectors/ViewInspector.js +21 -0
  326. package/dist/views/metadata-admin/inspectors/ViewVariantInspector.d.ts +54 -0
  327. package/dist/views/metadata-admin/inspectors/ViewVariantInspector.js +191 -0
  328. package/dist/views/metadata-admin/inspectors/_shared.d.ts +124 -0
  329. package/dist/views/metadata-admin/inspectors/_shared.js +113 -0
  330. package/dist/views/metadata-admin/inspectors/expression-validate.d.ts +26 -0
  331. package/dist/views/metadata-admin/inspectors/expression-validate.js +66 -0
  332. package/dist/views/metadata-admin/inspectors/flow-node-config.d.ts +143 -0
  333. package/dist/views/metadata-admin/inspectors/flow-node-config.js +461 -0
  334. package/dist/views/metadata-admin/inspectors/index.d.ts +1 -0
  335. package/dist/views/metadata-admin/inspectors/index.js +45 -0
  336. package/dist/views/metadata-admin/inspectors/json-schema-to-fields.d.ts +40 -0
  337. package/dist/views/metadata-admin/inspectors/json-schema-to-fields.js +227 -0
  338. package/dist/views/metadata-admin/inspectors/useDatasetFields.d.ts +72 -0
  339. package/dist/views/metadata-admin/inspectors/useDatasetFields.js +0 -0
  340. package/dist/views/metadata-admin/mergeServerFields.d.ts +65 -0
  341. package/dist/views/metadata-admin/mergeServerFields.js +56 -0
  342. package/dist/views/metadata-admin/preview-registry.d.ts +55 -0
  343. package/dist/views/metadata-admin/previews/ActionPreview.d.ts +25 -0
  344. package/dist/views/metadata-admin/previews/ActionPreview.js +238 -0
  345. package/dist/views/metadata-admin/previews/AddWidgetPicker.d.ts +12 -0
  346. package/dist/views/metadata-admin/previews/AddWidgetPicker.js +56 -0
  347. package/dist/views/metadata-admin/previews/AgentPreview.d.ts +24 -0
  348. package/dist/views/metadata-admin/previews/AgentPreview.js +100 -0
  349. package/dist/views/metadata-admin/previews/AppNavCanvas.d.ts +31 -0
  350. package/dist/views/metadata-admin/previews/AppNavCanvas.js +260 -0
  351. package/dist/views/metadata-admin/previews/AppPreview.d.ts +16 -1
  352. package/dist/views/metadata-admin/previews/AppPreview.js +23 -14
  353. package/dist/views/metadata-admin/previews/BookPreview.d.ts +20 -0
  354. package/dist/views/metadata-admin/previews/BookPreview.js +132 -0
  355. package/dist/views/metadata-admin/previews/DashboardPreview.d.ts +16 -1
  356. package/dist/views/metadata-admin/previews/DashboardPreview.js +110 -8
  357. package/dist/views/metadata-admin/previews/DatasetPreview.d.ts +18 -0
  358. package/dist/views/metadata-admin/previews/DatasetPreview.js +89 -0
  359. package/dist/views/metadata-admin/previews/DatasourcePreview.d.ts +23 -0
  360. package/dist/views/metadata-admin/previews/DatasourcePreview.js +68 -0
  361. package/dist/views/metadata-admin/previews/EmailTemplatePreview.d.ts +14 -1
  362. package/dist/views/metadata-admin/previews/FieldStub.d.ts +30 -0
  363. package/dist/views/metadata-admin/previews/FieldStub.js +104 -0
  364. package/dist/views/metadata-admin/previews/FieldsListEditor.d.ts +50 -0
  365. package/dist/views/metadata-admin/previews/FieldsListEditor.js +97 -0
  366. package/dist/views/metadata-admin/previews/FlowCanvas.d.ts +43 -0
  367. package/dist/views/metadata-admin/previews/FlowCanvas.js +328 -0
  368. package/dist/views/metadata-admin/previews/FlowPreview.d.ts +20 -0
  369. package/dist/views/metadata-admin/previews/FlowPreview.js +92 -0
  370. package/dist/views/metadata-admin/previews/FlowRunsPanel.d.ts +46 -0
  371. package/dist/views/metadata-admin/previews/FlowRunsPanel.js +97 -0
  372. package/dist/views/metadata-admin/previews/FlowSimulatorPanel.d.ts +25 -0
  373. package/dist/views/metadata-admin/previews/FlowSimulatorPanel.js +170 -0
  374. package/dist/views/metadata-admin/previews/JobPreview.d.ts +28 -0
  375. package/dist/views/metadata-admin/previews/JobPreview.js +290 -0
  376. package/dist/views/metadata-admin/previews/ObjectFormCanvas.d.ts +30 -0
  377. package/dist/views/metadata-admin/previews/ObjectFormCanvas.js +547 -0
  378. package/dist/views/metadata-admin/previews/ObjectPreview.d.ts +14 -1
  379. package/dist/views/metadata-admin/previews/ObjectPreview.js +5 -30
  380. package/dist/views/metadata-admin/previews/OutlineStrip.d.ts +32 -0
  381. package/dist/views/metadata-admin/previews/OutlineStrip.js +8 -0
  382. package/dist/views/metadata-admin/previews/PageBlockCanvas.d.ts +49 -0
  383. package/dist/views/metadata-admin/previews/PageBlockCanvas.js +510 -0
  384. package/dist/views/metadata-admin/previews/PagePreview.d.ts +10 -1
  385. package/dist/views/metadata-admin/previews/PagePreview.js +90 -4
  386. package/dist/views/metadata-admin/previews/PermissionPreview.d.ts +27 -0
  387. package/dist/views/metadata-admin/previews/PermissionPreview.js +115 -0
  388. package/dist/views/metadata-admin/previews/PreviewShell.d.ts +29 -6
  389. package/dist/views/metadata-admin/previews/PreviewShell.js +16 -3
  390. package/dist/views/metadata-admin/previews/ReportPreview.d.ts +18 -1
  391. package/dist/views/metadata-admin/previews/ReportPreview.js +23 -15
  392. package/dist/views/metadata-admin/previews/RolePreview.d.ts +19 -0
  393. package/dist/views/metadata-admin/previews/RolePreview.js +14 -0
  394. package/dist/views/metadata-admin/previews/SkillPreview.d.ts +22 -0
  395. package/dist/views/metadata-admin/previews/SkillPreview.js +34 -0
  396. package/dist/views/metadata-admin/previews/ToolPreview.d.ts +25 -0
  397. package/dist/views/metadata-admin/previews/ToolPreview.js +122 -0
  398. package/dist/views/metadata-admin/previews/TranslationPreview.d.ts +25 -0
  399. package/dist/views/metadata-admin/previews/TranslationPreview.js +52 -0
  400. package/dist/views/metadata-admin/previews/ValidationPreview.d.ts +27 -0
  401. package/dist/views/metadata-admin/previews/ValidationPreview.js +110 -0
  402. package/dist/views/metadata-admin/previews/ViewColumnPanes.d.ts +62 -0
  403. package/dist/views/metadata-admin/previews/ViewColumnPanes.js +140 -0
  404. package/dist/views/metadata-admin/previews/ViewPreview.d.ts +23 -1
  405. package/dist/views/metadata-admin/previews/ViewPreview.js +101 -73
  406. package/dist/views/metadata-admin/previews/block-config.d.ts +82 -0
  407. package/dist/views/metadata-admin/previews/block-config.js +324 -0
  408. package/dist/views/metadata-admin/previews/block-types.d.ts +40 -0
  409. package/dist/views/metadata-admin/previews/block-types.js +110 -0
  410. package/dist/views/metadata-admin/previews/field-types.d.ts +53 -0
  411. package/dist/views/metadata-admin/previews/field-types.js +97 -0
  412. package/dist/views/metadata-admin/previews/flow-canvas-layout.d.ts +88 -0
  413. package/dist/views/metadata-admin/previews/flow-canvas-layout.js +190 -0
  414. package/dist/views/metadata-admin/previews/flow-canvas-parts.d.ts +88 -0
  415. package/dist/views/metadata-admin/previews/flow-canvas-parts.js +358 -0
  416. package/dist/views/metadata-admin/previews/form-preview.d.ts +24 -0
  417. package/dist/views/metadata-admin/previews/form-preview.js +29 -0
  418. package/dist/views/metadata-admin/previews/index.js +43 -0
  419. package/dist/views/metadata-admin/previews/object-fields-bridge.d.ts +66 -0
  420. package/dist/views/metadata-admin/previews/object-fields-bridge.js +171 -0
  421. package/dist/views/metadata-admin/previews/object-fields-io.d.ts +109 -0
  422. package/dist/views/metadata-admin/previews/object-fields-io.js +208 -0
  423. package/dist/views/metadata-admin/previews/simulator/flow-sim-types.d.ts +91 -0
  424. package/dist/views/metadata-admin/previews/simulator/flow-sim-types.js +2 -0
  425. package/dist/views/metadata-admin/previews/simulator/flow-sim-validate.d.ts +8 -0
  426. package/dist/views/metadata-admin/previews/simulator/flow-sim-validate.js +113 -0
  427. package/dist/views/metadata-admin/previews/simulator/flow-simulator.d.ts +44 -0
  428. package/dist/views/metadata-admin/previews/simulator/flow-simulator.js +316 -0
  429. package/dist/views/metadata-admin/previews/useDatasetCatalog.d.ts +47 -0
  430. package/dist/views/metadata-admin/previews/useDatasetCatalog.js +133 -0
  431. package/dist/views/metadata-admin/previews/useFlowNodePalette.d.ts +44 -0
  432. package/dist/views/metadata-admin/previews/useFlowNodePalette.js +124 -0
  433. package/dist/views/metadata-admin/previews/useMetaOptions.d.ts +8 -0
  434. package/dist/views/metadata-admin/previews/useMetaOptions.js +50 -0
  435. package/dist/views/metadata-admin/previews/useObjectFields.d.ts +23 -0
  436. package/dist/views/metadata-admin/previews/useObjectFields.js +79 -0
  437. package/dist/views/metadata-admin/previews/useObjectOptions.d.ts +8 -0
  438. package/dist/views/metadata-admin/previews/useObjectOptions.js +43 -0
  439. package/dist/views/metadata-admin/previews/view-column-io.d.ts +42 -0
  440. package/dist/views/metadata-admin/previews/view-column-io.js +73 -0
  441. package/dist/views/metadata-admin/previews/widget-types.d.ts +24 -0
  442. package/dist/views/metadata-admin/previews/widget-types.js +40 -0
  443. package/dist/views/metadata-admin/registry.d.ts +140 -19
  444. package/dist/views/metadata-admin/report-schema.d.ts +26 -0
  445. package/dist/views/metadata-admin/report-schema.js +121 -0
  446. package/dist/views/metadata-admin/useMetadata.d.ts +100 -2
  447. package/dist/views/metadata-admin/useMetadata.js +155 -4
  448. package/dist/views/metadata-admin/view-item-normalize.d.ts +20 -0
  449. package/dist/views/metadata-admin/view-item-normalize.js +68 -0
  450. package/dist/views/metadata-admin/view-schema.d.ts +16 -0
  451. package/dist/views/metadata-admin/view-schema.js +107 -0
  452. package/dist/views/metadata-admin/view-variant-model.d.ts +23 -0
  453. package/dist/views/metadata-admin/view-variant-model.js +64 -0
  454. package/dist/views/metadata-admin/widgets.d.ts +89 -1
  455. package/dist/views/metadata-admin/widgets.js +491 -17
  456. package/dist/views/runtime-metadata-persistence.d.ts +78 -0
  457. package/dist/views/runtime-metadata-persistence.js +89 -0
  458. package/dist/views/useOpenRecordList.d.ts +18 -0
  459. package/dist/views/useOpenRecordList.js +36 -0
  460. package/dist/views/userFilterUrlState.d.ts +15 -0
  461. package/dist/views/userFilterUrlState.js +53 -0
  462. package/dist/views/view-config-adapter.d.ts +38 -0
  463. package/dist/views/view-config-adapter.js +80 -0
  464. package/package.json +52 -34
  465. package/dist/views/DesignDrawer.d.ts +0 -28
  466. package/dist/views/DesignDrawer.js +0 -51
  467. package/dist/views/metadata-admin/DesignerEditorWrapper.d.ts +0 -68
  468. package/dist/views/metadata-admin/DesignerEditorWrapper.js +0 -158
@@ -15,14 +15,14 @@ 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
28
  const DOMAIN_ICONS = {
@@ -52,8 +52,12 @@ const DOMAIN_ORDER = [
52
52
  * `field` is managed in-context via the parent object's edit form
53
53
  * (master-detail widget). A flat global list of every field across
54
54
  * every object is rarely useful and clutters the admin surface.
55
+ *
56
+ * `package` is the Studio scope container itself. It has a dedicated
57
+ * management surface for create/publish/import/export flows, so exposing it
58
+ * as scoped metadata would mean "view packages inside a package".
55
59
  */
56
- const HIDDEN_TYPES = new Set(['field']);
60
+ const HIDDEN_TYPES = new Set(['field', 'package']);
57
61
  export function MetadataDirectoryPage() {
58
62
  const client = useMetadataClient();
59
63
  const { loading, error, entries } = useMetadataTypes(client);
@@ -61,21 +65,94 @@ export function MetadataDirectoryPage() {
61
65
  const [query, setQuery] = React.useState('');
62
66
  const [domainFilter, setDomainFilter] = React.useState('all');
63
67
  const [writableOnly, setWritableOnly] = React.useState(false);
68
+ const [searchParams, setSearchParams] = useSearchParams();
69
+ // Studio is scoped to a single *project* package at a time (the sidebar
70
+ // `active_package` selector owns the scope via `?package=`). Load the
71
+ // installed packages and keep only project-scoped ones — anything not
72
+ // tagged `system`/`cloud` (a missing scope counts as project). System
73
+ // metadata therefore never appears on the directory landing.
74
+ const [projectPackages, setProjectPackages] = React.useState(null);
75
+ React.useEffect(() => {
76
+ let cancelled = false;
77
+ (async () => {
78
+ try {
79
+ const list = await client.list('package');
80
+ if (cancelled)
81
+ return;
82
+ const SYSTEM_SCOPES = new Set(['system', 'cloud']);
83
+ const rows = (list ?? [])
84
+ .map((raw) => {
85
+ const item = raw && typeof raw === 'object' && 'item' in raw ? raw.item : raw;
86
+ const m = (item?.manifest ?? item ?? {});
87
+ return {
88
+ id: m.id,
89
+ scope: m.scope,
90
+ name: m.name || m.id,
91
+ };
92
+ })
93
+ .filter((p) => p.id && !SYSTEM_SCOPES.has(p.scope));
94
+ rows.sort((a, b) => a.name.localeCompare(b.name));
95
+ setProjectPackages(rows.map((p) => ({ id: p.id, name: p.name })));
96
+ }
97
+ catch {
98
+ if (!cancelled)
99
+ setProjectPackages([]);
100
+ }
101
+ })();
102
+ return () => {
103
+ cancelled = true;
104
+ };
105
+ }, [client]);
106
+ // Resolve the active package from the URL, validated against the project
107
+ // package set. `null` while packages are still loading (fail closed).
108
+ const urlPackage = searchParams.get('package');
109
+ const activePackage = React.useMemo(() => {
110
+ if (!projectPackages)
111
+ return null;
112
+ if (urlPackage && projectPackages.some((p) => p.id === urlPackage))
113
+ return urlPackage;
114
+ return projectPackages[0]?.id ?? null;
115
+ }, [projectPackages, urlPackage]);
116
+ // Repair `?package=` so the sidebar selector and deep-links agree on the
117
+ // active scope. Runs once packages resolve and the URL holds no valid
118
+ // project package.
119
+ React.useEffect(() => {
120
+ if (!projectPackages || projectPackages.length === 0)
121
+ return;
122
+ if (urlPackage && projectPackages.some((p) => p.id === urlPackage))
123
+ return;
124
+ const next = new URLSearchParams(searchParams);
125
+ next.set('package', projectPackages[0].id);
126
+ setSearchParams(next, { replace: true });
127
+ // eslint-disable-next-line react-hooks/exhaustive-deps
128
+ }, [projectPackages, urlPackage]);
129
+ // Scope the diagnostics sweep to the active project package so tile
130
+ // counts (and locked/invalid badges) reflect *that package only* and
131
+ // match what the scoped list pages show. `undefined` while packages are
132
+ // still resolving keeps the page in its loading state below.
133
+ const { byType: invalidByType, warnByType, summary: diagSummary, countsByType, lockedByType, packagesByType, loading: diagLoading, } = useGlobalDiagnostics(client, 'warning', activePackage ?? undefined);
134
+ // Base set: visible (non-hidden) metadata types contributed by the active
135
+ // project package. Fail closed — show nothing until a concrete project
136
+ // package is active, so system-only types never surface.
137
+ const scopedEntries = React.useMemo(() => entries.filter((e) => {
138
+ if (HIDDEN_TYPES.has(e.type))
139
+ return false;
140
+ if (!activePackage)
141
+ return false;
142
+ return (packagesByType[e.type] ?? []).includes(activePackage);
143
+ }), [entries, activePackage, packagesByType]);
64
144
  // Counts per domain for the filter chip bar.
65
145
  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) {
146
+ const c = { all: scopedEntries.length };
147
+ for (const e of scopedEntries) {
69
148
  const d = e.domain ?? 'other';
70
149
  c[d] = (c[d] ?? 0) + 1;
71
150
  }
72
151
  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)
152
+ }, [scopedEntries]);
153
+ const writableCount = scopedEntries.filter((e) => e.allowOrgOverride || e.allowRuntimeCreate).length;
154
+ const filtered = scopedEntries.filter((e) => {
155
+ if (writableOnly && !(e.allowOrgOverride || e.allowRuntimeCreate))
79
156
  return false;
80
157
  if (domainFilter !== 'all' && (e.domain ?? 'other') !== domainFilter)
81
158
  return false;
@@ -83,6 +160,7 @@ export function MetadataDirectoryPage() {
83
160
  const q = query.toLowerCase();
84
161
  const hit = e.type.toLowerCase().includes(q) ||
85
162
  (e.label ?? '').toLowerCase().includes(q) ||
163
+ translateMetadataType(e.type, locale, e.label).toLowerCase().includes(q) ||
86
164
  (e.description ?? '').toLowerCase().includes(q);
87
165
  if (!hit)
88
166
  return false;
@@ -101,7 +179,7 @@ export function MetadataDirectoryPage() {
101
179
  return (ai === -1 ? 99 : ai) - (bi === -1 ? 99 : bi);
102
180
  });
103
181
  }, [filtered]);
104
- if (loading) {
182
+ if (loading || projectPackages === null || (activePackage && diagLoading)) {
105
183
  return _jsx("div", { className: "p-6 text-sm text-muted-foreground", children: t('engine.directory.loading', locale) });
106
184
  }
107
185
  if (error) {
@@ -109,12 +187,17 @@ export function MetadataDirectoryPage() {
109
187
  }
110
188
  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
189
  __html: tFormat('engine.directory.description', locale, {
112
- count: `<strong class="text-foreground">${entries.filter((e) => !HIDDEN_TYPES.has(e.type)).length}</strong>`,
190
+ count: `<strong class="text-foreground">${scopedEntries.length}</strong>`,
113
191
  writable: writableCount,
114
192
  }),
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]) => {
193
+ } }), _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
194
  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));
195
+ 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) => {
196
+ // Carry the active project package into the list-page
197
+ // deep-link so scope survives navigation.
198
+ const totalCount = countsByType[e.type] ?? 0;
199
+ 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));
200
+ }) })] }, domain));
118
201
  })] }), _jsx(MetadataQuickFind, {})] }));
119
202
  }
120
203
  function DomainChip({ domain, label, active, count, onClick, }) {
@@ -123,13 +206,19 @@ function DomainChip({ domain, label, active, count, onClick, }) {
123
206
  ? 'bg-primary text-primary-foreground border-primary'
124
207
  : 'bg-background hover:bg-accent border-border text-muted-foreground'), children: [label ?? domain, " ", _jsxs("span", { className: "opacity-70 ml-0.5", children: ["(", count, ")"] })] }));
125
208
  }
126
- function TypeTile({ entry, locale }) {
209
+ function TypeTile({ entry, locale, invalidCount = 0, warnCount = 0, itemCount = 0, lockedCount = 0, packageFilter, }) {
127
210
  // Prefer the locale-table translation; fall back to server's `label` (typically English).
128
211
  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 }))] }));
212
+ const href = packageFilter
213
+ ? `./${encodeURIComponent(entry.type)}?package=${encodeURIComponent(packageFilter)}`
214
+ : `./${encodeURIComponent(entry.type)}`;
215
+ return (_jsxs(Link, { to: href, className: 'block p-4 border rounded-lg hover:bg-accent transition-colors ' +
216
+ (invalidCount > 0
217
+ ? 'border-destructive/40 hover:border-destructive'
218
+ : '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] ' +
219
+ (entry.overrideSource === 'env'
220
+ ? 'bg-amber-100 text-amber-800 hover:bg-amber-100'
221
+ : 'bg-emerald-100 text-emerald-800 hover:bg-emerald-100'), title: entry.overrideSource === 'env'
222
+ ? 'Writable via OBJECTSTACK_METADATA_WRITABLE env var'
223
+ : '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
224
  }
@@ -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,37 @@
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
+ }
36
+ export declare function JsonSourceEditor({ value, onChange, readOnly, issues, height, }: JsonSourceEditorProps): React.JSX.Element;
37
+ export default JsonSourceEditor;
@@ -0,0 +1,178 @@
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
+ /**
10
+ * JsonSourceEditor — Monaco-backed JSON editor for the metadata
11
+ * designer's "Source" tab. Replaces the old textarea so power users
12
+ * get syntax highlighting, bracket matching, folding, and inline
13
+ * error squigglies driven by the server-side `_diagnostics` payload.
14
+ *
15
+ * Markers: `issues[]` use dotted (or array) JSON paths matching the
16
+ * Zod issue shape. We resolve each path to a Monaco range with
17
+ * `jsonc-parser` so the squiggle lands on the offending value (or
18
+ * the property key when the value is absent). Unresolved paths fall
19
+ * back to a marker on line 1, so nothing is silently lost.
20
+ */
21
+ import React from 'react';
22
+ import { Skeleton } from '@object-ui/components';
23
+ import * as jsonc from 'jsonc-parser';
24
+ import { detectLocale, t } from './i18n';
25
+ // Lazy: Monaco's React wrapper itself pulls in the editor core
26
+ // (~3MB), so we keep it out of the initial app-shell chunk.
27
+ const LazyMonaco = React.lazy(async () => {
28
+ const mod = await import('@monaco-editor/react');
29
+ return { default: mod.default };
30
+ });
31
+ function stringify(v) {
32
+ try {
33
+ return JSON.stringify(v ?? {}, null, 2);
34
+ }
35
+ catch {
36
+ return '{}';
37
+ }
38
+ }
39
+ /** Parse a dotted JSON path like `fields.owner.0.type` to segments. */
40
+ function splitPath(p) {
41
+ if (!p)
42
+ return [];
43
+ return p.split('.').map((seg) => {
44
+ const n = Number(seg);
45
+ return Number.isInteger(n) && String(n) === seg ? n : seg;
46
+ });
47
+ }
48
+ export function JsonSourceEditor({ value, onChange, readOnly, issues, height = '60vh', }) {
49
+ const locale = React.useMemo(() => detectLocale(), []);
50
+ const [text, setText] = React.useState(() => stringify(value));
51
+ const [parseError, setParseError] = React.useState(null);
52
+ const lastCommittedRef = React.useRef(text);
53
+ // Hold onto Monaco's editor + namespace so we can repaint markers
54
+ // when either the source text or the issues prop changes.
55
+ const editorRef = React.useRef(null);
56
+ const monacoRef = React.useRef(null);
57
+ // Match against the dark class our app-shell toggles on <html>; pick
58
+ // a Monaco theme that doesn't fight the rest of the chrome.
59
+ const [theme, setTheme] = React.useState(() => {
60
+ if (typeof document === 'undefined')
61
+ return 'light';
62
+ return document.documentElement.classList.contains('dark') ? 'vs-dark' : 'light';
63
+ });
64
+ React.useEffect(() => {
65
+ if (typeof document === 'undefined')
66
+ return;
67
+ const root = document.documentElement;
68
+ const update = () => setTheme(root.classList.contains('dark') ? 'vs-dark' : 'light');
69
+ const obs = new MutationObserver(update);
70
+ obs.observe(root, { attributes: true, attributeFilter: ['class'] });
71
+ return () => obs.disconnect();
72
+ }, []);
73
+ // Push markers from `issues` onto Monaco's model. We rebuild on
74
+ // every relevant change rather than diffing — sweeping `setModelMarkers`
75
+ // is cheap and avoids stale squigglies when issues drop off.
76
+ const applyMarkers = React.useCallback(() => {
77
+ const editor = editorRef.current;
78
+ const monaco = monacoRef.current;
79
+ if (!editor || !monaco)
80
+ return;
81
+ const model = editor.getModel();
82
+ if (!model)
83
+ return;
84
+ if (!issues || issues.length === 0) {
85
+ monaco.editor.setModelMarkers(model, 'objectui-diagnostics', []);
86
+ return;
87
+ }
88
+ let tree;
89
+ try {
90
+ tree = jsonc.parseTree(text);
91
+ }
92
+ catch {
93
+ tree = undefined;
94
+ }
95
+ const markers = issues.map((iss) => {
96
+ const segs = splitPath(iss.path);
97
+ let startLine = 1;
98
+ let startCol = 1;
99
+ let endLine = 1;
100
+ let endCol = 2;
101
+ const node = tree ? jsonc.findNodeAtLocation(tree, segs) : undefined;
102
+ if (node) {
103
+ const start = model.getPositionAt(node.offset);
104
+ const end = model.getPositionAt(node.offset + node.length);
105
+ startLine = start.lineNumber;
106
+ startCol = start.column;
107
+ endLine = end.lineNumber;
108
+ endCol = end.column;
109
+ }
110
+ const sev = iss.severity === 'warning'
111
+ ? monaco.MarkerSeverity.Warning
112
+ : monaco.MarkerSeverity.Error;
113
+ return {
114
+ severity: sev,
115
+ message: iss.path ? `${iss.path}: ${iss.message}` : iss.message,
116
+ startLineNumber: startLine,
117
+ startColumn: startCol,
118
+ endLineNumber: endLine,
119
+ endColumn: endCol,
120
+ source: 'metadata',
121
+ };
122
+ });
123
+ monaco.editor.setModelMarkers(model, 'objectui-diagnostics', markers);
124
+ }, [issues, text]);
125
+ React.useEffect(() => {
126
+ applyMarkers();
127
+ }, [applyMarkers]);
128
+ // Resync the buffer when the parent draft changes externally (Save,
129
+ // Reset, inspector-driven patches). Only sync when the upstream
130
+ // value differs from what we last committed so user keystrokes
131
+ // aren't clobbered while typing.
132
+ React.useEffect(() => {
133
+ const next = stringify(value);
134
+ if (next !== lastCommittedRef.current) {
135
+ setText(next);
136
+ lastCommittedRef.current = next;
137
+ setParseError(null);
138
+ }
139
+ }, [value]);
140
+ const handleChange = (next) => {
141
+ const v = next ?? '';
142
+ setText(v);
143
+ try {
144
+ const parsed = JSON.parse(v);
145
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
146
+ setParseError(null);
147
+ lastCommittedRef.current = v;
148
+ onChange(parsed);
149
+ }
150
+ else {
151
+ setParseError(t('engine.form.rootJsonObject', locale));
152
+ }
153
+ }
154
+ catch (err) {
155
+ setParseError(err?.message ?? t('engine.form.invalidJson', locale));
156
+ }
157
+ };
158
+ const handleMount = (editor, monaco) => {
159
+ editorRef.current = editor;
160
+ monacoRef.current = monaco;
161
+ // Defer one tick so the model has settled before the first paint.
162
+ setTimeout(applyMarkers, 0);
163
+ };
164
+ return (_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx("div", { className: "border rounded overflow-hidden bg-background", style: { height: typeof height === 'number' ? `${height}px` : height }, children: _jsx(React.Suspense, { fallback: _jsx(Skeleton, { className: "w-full h-full" }), children: _jsx(LazyMonaco, { value: text, language: "json", theme: theme, onChange: handleChange, onMount: handleMount, options: {
165
+ readOnly,
166
+ minimap: { enabled: false },
167
+ fontSize: 12,
168
+ lineNumbers: 'on',
169
+ scrollBeyondLastLine: false,
170
+ automaticLayout: true,
171
+ folding: true,
172
+ wordWrap: 'on',
173
+ tabSize: 2,
174
+ renderLineHighlight: 'line',
175
+ scrollbar: { verticalScrollbarSize: 10, horizontalScrollbarSize: 10 },
176
+ } }) }) }), parseError && (_jsxs("div", { className: "text-xs text-destructive flex items-start gap-1.5", children: [_jsx("span", { "aria-hidden": true, children: "\u26A0" }), _jsx("span", { children: parseError })] }))] }));
177
+ }
178
+ export default JsonSourceEditor;