@object-ui/app-shell 6.2.2 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +967 -0
- package/README.md +292 -0
- package/dist/assistant/assistantBus.d.ts +72 -0
- package/dist/assistant/assistantBus.js +133 -0
- package/dist/chrome/CommandPalette.d.ts +1 -1
- package/dist/chrome/CommandPalette.js +26 -22
- package/dist/chrome/ConditionalAuthWrapper.d.ts +1 -1
- package/dist/chrome/ConsoleToaster.d.ts +1 -1
- package/dist/chrome/ConsoleToaster.js +3 -1
- package/dist/chrome/ErrorBoundary.d.ts +1 -1
- package/dist/chrome/KeyboardShortcutsDialog.d.ts +1 -1
- package/dist/chrome/KeyboardShortcutsDialog.js +16 -5
- package/dist/chrome/LoadingScreen.d.ts +1 -1
- package/dist/chrome/LoadingScreen.js +22 -26
- package/dist/chrome/RouteFader.d.ts +1 -1
- package/dist/chrome/ThemeProvider.d.ts +1 -1
- package/dist/components/ManagedByBadge.d.ts +1 -1
- package/dist/console/AppContent.d.ts +1 -1
- package/dist/console/AppContent.js +170 -37
- package/dist/console/ConsoleShell.d.ts +7 -7
- package/dist/console/ConsoleShell.js +32 -3
- package/dist/console/ai/AiChatPage.d.ts +88 -1
- package/dist/console/ai/AiChatPage.js +743 -66
- package/dist/console/ai/ConversationsSidebar.d.ts +26 -1
- package/dist/console/ai/ConversationsSidebar.js +149 -34
- package/dist/console/ai/LiveCanvas.d.ts +22 -0
- package/dist/console/ai/LiveCanvas.js +78 -0
- package/dist/console/ai/reconcileTurn.d.ts +8 -0
- package/dist/console/ai/reconcileTurn.js +20 -0
- package/dist/console/auth/AuthPageLayout.d.ts +1 -1
- package/dist/console/auth/ForgotPasswordPage.d.ts +1 -1
- package/dist/console/auth/LoginPage.d.ts +1 -1
- package/dist/console/auth/RegisterPage.d.ts +1 -1
- package/dist/console/auth/RegisterPage.js +23 -3
- package/dist/console/cloud-connection/CloudConnectionPanel.d.ts +1 -0
- package/dist/console/cloud-connection/CloudConnectionPanel.js +169 -0
- package/dist/console/home/AppCard.d.ts +1 -1
- package/dist/console/home/AppCard.js +6 -12
- package/dist/console/home/HomeAppsStrip.d.ts +8 -0
- package/dist/console/home/HomeAppsStrip.js +61 -0
- package/dist/console/home/HomeLayout.d.ts +1 -1
- package/dist/console/home/HomeLayout.js +3 -1
- package/dist/console/home/HomePage.d.ts +1 -2
- package/dist/console/home/HomePage.js +149 -21
- package/dist/console/home/HomeRail.d.ts +22 -0
- package/dist/console/home/HomeRail.js +62 -0
- package/dist/console/home/QuickActions.d.ts +1 -1
- package/dist/console/home/QuickActions.js +3 -11
- package/dist/console/home/RecentApps.d.ts +1 -1
- package/dist/console/home/RecentApps.js +2 -2
- package/dist/console/home/StarredApps.d.ts +1 -1
- package/dist/console/home/StarredApps.js +2 -2
- package/dist/console/marketplace/InstalledListWidget.d.ts +1 -0
- package/dist/console/marketplace/InstalledListWidget.js +93 -0
- package/dist/console/marketplace/MarkdownText.d.ts +1 -1
- package/dist/console/marketplace/MarketplaceAccessDenied.d.ts +1 -1
- package/dist/console/marketplace/MarketplaceInstalledPage.d.ts +8 -14
- package/dist/console/marketplace/MarketplaceInstalledPage.js +14 -66
- package/dist/console/marketplace/MarketplacePackagePage.d.ts +1 -1
- package/dist/console/marketplace/MarketplacePackagePage.js +249 -8
- package/dist/console/marketplace/MarketplacePage.d.ts +1 -1
- package/dist/console/marketplace/MarketplacePage.js +60 -3
- package/dist/console/marketplace/PackageIcon.d.ts +1 -1
- package/dist/console/marketplace/PluginDisclosure.d.ts +14 -0
- package/dist/console/marketplace/PluginDisclosure.js +38 -0
- package/dist/console/marketplace/marketplaceApi.d.ts +123 -0
- package/dist/console/marketplace/marketplaceApi.js +254 -1
- package/dist/console/organizations/CreateWorkspaceDialog.d.ts +1 -1
- package/dist/console/organizations/OrganizationsLayout.d.ts +1 -1
- package/dist/console/organizations/OrganizationsPage.d.ts +1 -1
- package/dist/console/organizations/manage/AcceptInvitationPage.d.ts +1 -1
- package/dist/console/organizations/manage/InvitationsPage.d.ts +1 -1
- package/dist/console/organizations/manage/InviteMemberDialog.d.ts +1 -1
- package/dist/console/organizations/manage/MembersPage.d.ts +1 -1
- package/dist/console/organizations/manage/OrganizationLayout.d.ts +1 -1
- package/dist/console/organizations/manage/SettingsPage.d.ts +1 -1
- package/dist/context/CommandPaletteProvider.d.ts +44 -0
- package/dist/context/CommandPaletteProvider.js +71 -0
- package/dist/context/FavoritesProvider.d.ts +1 -1
- package/dist/context/NavigationContext.d.ts +1 -1
- package/dist/context/RecentItemsProvider.d.ts +2 -2
- package/dist/context/UserStateAdapters.d.ts +1 -1
- package/dist/context/index.d.ts +2 -0
- package/dist/context/index.js +1 -0
- package/dist/hooks/index.d.ts +5 -2
- package/dist/hooks/index.js +4 -1
- package/dist/hooks/useActionModal.d.ts +53 -0
- package/dist/hooks/useActionModal.js +111 -0
- package/dist/hooks/useChatConversation.d.ts +107 -4
- package/dist/hooks/useChatConversation.js +253 -25
- package/dist/hooks/useConsoleActionRuntime.d.ts +70 -0
- package/dist/hooks/useConsoleActionRuntime.js +560 -0
- package/dist/hooks/useConversationList.js +61 -3
- package/dist/hooks/useHomeInbox.d.ts +13 -0
- package/dist/hooks/useHomeInbox.js +142 -0
- package/dist/hooks/useNavPins.js +17 -23
- package/dist/hooks/useNavigationSync.d.ts +33 -0
- package/dist/hooks/useNavigationSync.js +98 -12
- package/dist/hooks/useReconcileOnError.d.ts +40 -0
- package/dist/hooks/useReconcileOnError.js +37 -0
- package/dist/hooks/useRecordApprovals.d.ts +18 -19
- package/dist/hooks/useRecordApprovals.js +24 -40
- package/dist/hooks/useResponsiveSidebar.js +14 -5
- package/dist/hooks/useSettleSignal.d.ts +19 -0
- package/dist/hooks/useSettleSignal.js +20 -0
- package/dist/hooks/useTrackRouteAsRecent.js +35 -0
- package/dist/hooks/useUrlOverlay.d.ts +62 -0
- package/dist/hooks/useUrlOverlay.js +88 -0
- package/dist/index.d.ts +16 -7
- package/dist/index.js +12 -4
- package/dist/layout/ActivityFeed.d.ts +1 -1
- package/dist/layout/AppHeader.d.ts +3 -2
- package/dist/layout/AppHeader.js +237 -72
- package/dist/layout/AppSidebar.d.ts +2 -1
- package/dist/layout/AppSidebar.js +26 -46
- package/dist/layout/AppSwitcher.d.ts +2 -1
- package/dist/layout/AppSwitcher.js +9 -5
- package/dist/layout/AuthPageLayout.d.ts +1 -1
- package/dist/layout/ConnectionStatus.d.ts +1 -1
- package/dist/layout/ConnectionStatus.js +9 -6
- package/dist/layout/ConsoleChatbotFab.d.ts +19 -1
- package/dist/layout/ConsoleChatbotFab.js +16 -2
- package/dist/layout/ConsoleFloatingChatbot.d.ts +32 -2
- package/dist/layout/ConsoleFloatingChatbot.js +374 -41
- package/dist/layout/ConsoleLayout.d.ts +1 -1
- package/dist/layout/ConsoleLayout.js +27 -11
- package/dist/layout/ContextSelectors.d.ts +44 -0
- package/dist/layout/ContextSelectors.js +218 -0
- package/dist/layout/InboxPopover.d.ts +6 -1
- package/dist/layout/InboxPopover.js +25 -6
- package/dist/layout/LocaleSwitcher.d.ts +1 -1
- package/dist/layout/LocalizedSidebarTrigger.d.ts +2 -0
- package/dist/layout/LocalizedSidebarTrigger.js +15 -0
- package/dist/layout/MobileViewSwitcherContext.d.ts +1 -1
- package/dist/layout/ModeToggle.d.ts +1 -1
- package/dist/layout/PageHeader.d.ts +1 -1
- package/dist/layout/UnifiedSidebar.d.ts +2 -1
- package/dist/layout/UnifiedSidebar.js +116 -15
- package/dist/observability/index.d.ts +1 -0
- package/dist/observability/index.js +1 -0
- package/dist/observability/settleSignal.d.ts +64 -0
- package/dist/observability/settleSignal.js +131 -0
- package/dist/preview/DraftChangesPanel.d.ts +19 -0
- package/dist/preview/DraftChangesPanel.js +114 -0
- package/dist/preview/DraftPreviewBar.d.ts +8 -0
- package/dist/preview/DraftPreviewBar.js +86 -0
- package/dist/preview/PreviewDraftEmptyState.d.ts +16 -0
- package/dist/preview/PreviewDraftEmptyState.js +47 -0
- package/dist/preview/PreviewModeContext.d.ts +57 -0
- package/dist/preview/PreviewModeContext.js +99 -0
- package/dist/preview/UnpublishedAppBar.d.ts +8 -0
- package/dist/preview/UnpublishedAppBar.js +79 -0
- package/dist/preview/draftStatus.d.ts +20 -0
- package/dist/preview/draftStatus.js +27 -0
- package/dist/preview/usePublishAllDrafts.d.ts +18 -0
- package/dist/preview/usePublishAllDrafts.js +106 -0
- package/dist/providers/AdapterProvider.d.ts +1 -1
- package/dist/providers/AdapterProvider.js +6 -1
- package/dist/providers/ExpressionProvider.d.ts +1 -1
- package/dist/providers/MetadataProvider.d.ts +17 -2
- package/dist/providers/MetadataProvider.js +183 -12
- package/dist/runtime-config.d.ts +46 -2
- package/dist/runtime-config.js +39 -2
- package/dist/services/builtinComponents.js +68 -59
- package/dist/skeletons/SkeletonDashboard.d.ts +1 -1
- package/dist/skeletons/SkeletonDetail.d.ts +1 -1
- package/dist/skeletons/SkeletonGrid.d.ts +1 -1
- package/dist/utils/appRoute.d.ts +21 -0
- package/dist/utils/appRoute.js +25 -0
- package/dist/utils/deriveRelatedLists.d.ts +54 -0
- package/dist/utils/deriveRelatedLists.js +91 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/managedByEmptyState.d.ts +8 -1
- package/dist/utils/managedByEmptyState.js +13 -7
- package/dist/utils/preferLocal.d.ts +18 -0
- package/dist/utils/preferLocal.js +24 -0
- package/dist/views/ActionConfirmDialog.d.ts +1 -1
- package/dist/views/ActionConfirmDialog.js +3 -1
- package/dist/views/ActionParamDialog.d.ts +6 -1
- package/dist/views/ActionParamDialog.js +9 -3
- package/dist/views/ActionResultDialog.d.ts +13 -0
- package/dist/views/ActionResultDialog.js +134 -0
- package/dist/views/ComponentNavView.d.ts +14 -1
- package/dist/views/CreateViewDialog.d.ts +1 -1
- package/dist/views/DashboardConfigPanel.d.ts +28 -0
- package/dist/views/DashboardConfigPanel.js +81 -0
- package/dist/views/DashboardView.d.ts +4 -3
- package/dist/views/DashboardView.js +38 -239
- package/dist/views/FlowRunner.d.ts +59 -0
- package/dist/views/FlowRunner.js +153 -0
- package/dist/views/InterfaceListPage.d.ts +49 -0
- package/dist/views/InterfaceListPage.js +347 -0
- package/dist/views/MetadataInspector.d.ts +2 -2
- package/dist/views/ObjectView.d.ts +1 -1
- package/dist/views/ObjectView.js +209 -532
- package/dist/views/PageView.d.ts +8 -3
- package/dist/views/PageView.js +45 -32
- package/dist/views/RecordDetailView.d.ts +1 -1
- package/dist/views/RecordDetailView.js +363 -148
- package/dist/views/RecordFormPage.d.ts +1 -1
- package/dist/views/RecordFormPage.js +26 -1
- package/dist/views/ReportConfigPanel.d.ts +37 -0
- package/dist/views/ReportConfigPanel.js +85 -0
- package/dist/views/ReportView.d.ts +1 -1
- package/dist/views/ReportView.js +116 -7
- package/dist/views/RuntimeDraftBar.d.ts +30 -0
- package/dist/views/RuntimeDraftBar.js +112 -0
- package/dist/views/SearchResultsPage.d.ts +1 -1
- package/dist/views/SearchResultsPage.js +8 -18
- package/dist/views/ViewConfigPanel.d.ts +24 -17
- package/dist/views/ViewConfigPanel.js +121 -77
- package/dist/views/index.d.ts +1 -1
- package/dist/views/index.js +1 -1
- package/dist/views/metadata-admin/AuditPanel.d.ts +28 -0
- package/dist/views/metadata-admin/AuditPanel.js +79 -0
- package/dist/views/metadata-admin/DiagnosticsPage.d.ts +20 -0
- package/dist/views/metadata-admin/DiagnosticsPage.js +69 -0
- package/dist/views/metadata-admin/DirectoryPage.d.ts +16 -1
- package/dist/views/metadata-admin/DirectoryPage.js +113 -24
- package/dist/views/metadata-admin/DraftReviewPanel.d.ts +33 -0
- package/dist/views/metadata-admin/DraftReviewPanel.js +77 -0
- package/dist/views/metadata-admin/EmbeddedItemEditor.d.ts +17 -1
- package/dist/views/metadata-admin/EmbeddedItemEditor.js +15 -8
- package/dist/views/metadata-admin/JsonSourceEditor.d.ts +37 -0
- package/dist/views/metadata-admin/JsonSourceEditor.js +178 -0
- package/dist/views/metadata-admin/LayeredDiff.d.ts +39 -1
- package/dist/views/metadata-admin/LayeredDiff.js +171 -5
- package/dist/views/metadata-admin/MetadataDetailDrawer.d.ts +15 -1
- package/dist/views/metadata-admin/MetadataTypeActions.d.ts +48 -0
- package/dist/views/metadata-admin/MetadataTypeActions.js +165 -0
- package/dist/views/metadata-admin/PackagesPage.d.ts +18 -0
- package/dist/views/metadata-admin/PackagesPage.js +395 -0
- package/dist/views/metadata-admin/PageShell.d.ts +1 -1
- package/dist/views/metadata-admin/PageShell.js +9 -4
- package/dist/views/metadata-admin/PermissionMatrixEditor.d.ts +35 -1
- package/dist/views/metadata-admin/QuickFind.d.ts +21 -1
- package/dist/views/metadata-admin/QuickFind.js +6 -3
- package/dist/views/metadata-admin/RelatedPanel.d.ts +24 -1
- package/dist/views/metadata-admin/RelatedPanel.js +20 -18
- package/dist/views/metadata-admin/ResourceEditPage.d.ts +40 -1
- package/dist/views/metadata-admin/ResourceEditPage.js +1223 -60
- package/dist/views/metadata-admin/ResourceHistoryPage.d.ts +39 -1
- package/dist/views/metadata-admin/ResourceHistoryPage.js +66 -16
- package/dist/views/metadata-admin/ResourceListPage.d.ts +13 -1
- package/dist/views/metadata-admin/ResourceListPage.js +266 -30
- package/dist/views/metadata-admin/ResourceRouter.d.ts +23 -1
- package/dist/views/metadata-admin/SchemaForm.d.ts +34 -1
- package/dist/views/metadata-admin/SchemaForm.js +559 -49
- package/dist/views/metadata-admin/StudioHomePage.d.ts +22 -0
- package/dist/views/metadata-admin/StudioHomePage.js +213 -0
- package/dist/views/metadata-admin/anchors.js +237 -24
- package/dist/views/metadata-admin/clientValidation.d.ts +50 -0
- package/dist/views/metadata-admin/clientValidation.js +169 -0
- package/dist/views/metadata-admin/color-variant-field.d.ts +30 -0
- package/dist/views/metadata-admin/color-variant-field.js +38 -0
- package/dist/views/metadata-admin/createDerive.d.ts +75 -0
- package/dist/views/metadata-admin/createDerive.js +179 -0
- package/dist/views/metadata-admin/dashboard-schema.d.ts +12 -0
- package/dist/views/metadata-admin/dashboard-schema.js +80 -0
- package/dist/views/metadata-admin/datasource/DatasourceResourcePage.d.ts +35 -0
- package/dist/views/metadata-admin/datasource/DatasourceResourcePage.js +327 -0
- package/dist/views/metadata-admin/datasource/register.d.ts +1 -0
- package/dist/views/metadata-admin/datasource/register.js +24 -0
- package/dist/views/metadata-admin/default-inspector-registry.d.ts +49 -0
- package/dist/views/metadata-admin/default-inspector-registry.js +8 -0
- package/dist/views/metadata-admin/default-schemas.js +115 -10
- package/dist/views/metadata-admin/external/ExternalDatasourcePanel.d.ts +27 -0
- package/dist/views/metadata-admin/external/ExternalDatasourcePanel.js +69 -0
- package/dist/views/metadata-admin/external/ImportObjectDialog.d.ts +27 -0
- package/dist/views/metadata-admin/external/ImportObjectDialog.js +77 -0
- package/dist/views/metadata-admin/external/SchemaBrowser.d.ts +16 -0
- package/dist/views/metadata-admin/external/SchemaBrowser.js +74 -0
- package/dist/views/metadata-admin/external/ValidationPanel.d.ts +16 -0
- package/dist/views/metadata-admin/external/ValidationPanel.js +68 -0
- package/dist/views/metadata-admin/external/api.d.ts +100 -0
- package/dist/views/metadata-admin/external/api.js +124 -0
- package/dist/views/metadata-admin/i18n.d.ts +1 -0
- package/dist/views/metadata-admin/i18n.js +1166 -2
- package/dist/views/metadata-admin/index.d.ts +8 -5
- package/dist/views/metadata-admin/index.js +12 -2
- package/dist/views/metadata-admin/inspector-registry.d.ts +51 -0
- package/dist/views/metadata-admin/inspector-registry.js +11 -0
- package/dist/views/metadata-admin/inspectors/ActionDefaultInspector.d.ts +30 -0
- package/dist/views/metadata-admin/inspectors/ActionDefaultInspector.js +180 -0
- package/dist/views/metadata-admin/inspectors/AppNavInspector.d.ts +16 -0
- package/dist/views/metadata-admin/inspectors/AppNavInspector.js +110 -0
- package/dist/views/metadata-admin/inspectors/ConditionBuilder.d.ts +29 -0
- package/dist/views/metadata-admin/inspectors/ConditionBuilder.js +154 -0
- package/dist/views/metadata-admin/inspectors/DashboardDefaultInspector.d.ts +28 -0
- package/dist/views/metadata-admin/inspectors/DashboardDefaultInspector.js +110 -0
- package/dist/views/metadata-admin/inspectors/DashboardWidgetInspector.d.ts +18 -0
- package/dist/views/metadata-admin/inspectors/DashboardWidgetInspector.js +139 -0
- package/dist/views/metadata-admin/inspectors/DatasetDefaultInspector.d.ts +21 -0
- package/dist/views/metadata-admin/inspectors/DatasetDefaultInspector.js +107 -0
- package/dist/views/metadata-admin/inspectors/FlowEdgeInspector.d.ts +16 -0
- package/dist/views/metadata-admin/inspectors/FlowEdgeInspector.js +45 -0
- package/dist/views/metadata-admin/inspectors/FlowInspector.d.ts +12 -0
- package/dist/views/metadata-admin/inspectors/FlowInspector.js +9 -0
- package/dist/views/metadata-admin/inspectors/FlowKeyValueField.d.ts +30 -0
- package/dist/views/metadata-admin/inspectors/FlowKeyValueField.js +125 -0
- package/dist/views/metadata-admin/inspectors/FlowNodeConfigField.d.ts +18 -0
- package/dist/views/metadata-admin/inspectors/FlowNodeConfigField.js +40 -0
- package/dist/views/metadata-admin/inspectors/FlowNodeInspector.d.ts +14 -0
- package/dist/views/metadata-admin/inspectors/FlowNodeInspector.js +140 -0
- package/dist/views/metadata-admin/inspectors/FlowObjectListField.d.ts +26 -0
- package/dist/views/metadata-admin/inspectors/FlowObjectListField.js +105 -0
- package/dist/views/metadata-admin/inspectors/FlowReferenceField.d.ts +83 -0
- package/dist/views/metadata-admin/inspectors/FlowReferenceField.js +181 -0
- package/dist/views/metadata-admin/inspectors/FlowStringListField.d.ts +21 -0
- package/dist/views/metadata-admin/inspectors/FlowStringListField.js +60 -0
- package/dist/views/metadata-admin/inspectors/InspectorComboField.d.ts +40 -0
- package/dist/views/metadata-admin/inspectors/InspectorComboField.js +61 -0
- package/dist/views/metadata-admin/inspectors/ObjectDefaultInspector.d.ts +21 -0
- package/dist/views/metadata-admin/inspectors/ObjectDefaultInspector.js +54 -0
- package/dist/views/metadata-admin/inspectors/ObjectFieldInspector.d.ts +23 -0
- package/dist/views/metadata-admin/inspectors/ObjectFieldInspector.js +330 -0
- package/dist/views/metadata-admin/inspectors/PageBlockInspector.d.ts +48 -0
- package/dist/views/metadata-admin/inspectors/PageBlockInspector.js +332 -0
- package/dist/views/metadata-admin/inspectors/ReportDefaultInspector.d.ts +58 -0
- package/dist/views/metadata-admin/inspectors/ReportDefaultInspector.js +160 -0
- package/dist/views/metadata-admin/inspectors/ViewColumnInspector.d.ts +19 -0
- package/dist/views/metadata-admin/inspectors/ViewColumnInspector.js +144 -0
- package/dist/views/metadata-admin/inspectors/ViewInspector.d.ts +19 -0
- package/dist/views/metadata-admin/inspectors/ViewInspector.js +21 -0
- package/dist/views/metadata-admin/inspectors/ViewVariantInspector.d.ts +54 -0
- package/dist/views/metadata-admin/inspectors/ViewVariantInspector.js +191 -0
- package/dist/views/metadata-admin/inspectors/_shared.d.ts +124 -0
- package/dist/views/metadata-admin/inspectors/_shared.js +113 -0
- package/dist/views/metadata-admin/inspectors/expression-validate.d.ts +26 -0
- package/dist/views/metadata-admin/inspectors/expression-validate.js +66 -0
- package/dist/views/metadata-admin/inspectors/flow-node-config.d.ts +143 -0
- package/dist/views/metadata-admin/inspectors/flow-node-config.js +461 -0
- package/dist/views/metadata-admin/inspectors/index.d.ts +1 -0
- package/dist/views/metadata-admin/inspectors/index.js +45 -0
- package/dist/views/metadata-admin/inspectors/json-schema-to-fields.d.ts +40 -0
- package/dist/views/metadata-admin/inspectors/json-schema-to-fields.js +227 -0
- package/dist/views/metadata-admin/inspectors/useDatasetFields.d.ts +72 -0
- package/dist/views/metadata-admin/inspectors/useDatasetFields.js +0 -0
- package/dist/views/metadata-admin/mergeServerFields.d.ts +65 -0
- package/dist/views/metadata-admin/mergeServerFields.js +56 -0
- package/dist/views/metadata-admin/preview-registry.d.ts +55 -0
- package/dist/views/metadata-admin/previews/ActionPreview.d.ts +25 -0
- package/dist/views/metadata-admin/previews/ActionPreview.js +238 -0
- package/dist/views/metadata-admin/previews/AddWidgetPicker.d.ts +12 -0
- package/dist/views/metadata-admin/previews/AddWidgetPicker.js +56 -0
- package/dist/views/metadata-admin/previews/AgentPreview.d.ts +24 -0
- package/dist/views/metadata-admin/previews/AgentPreview.js +100 -0
- package/dist/views/metadata-admin/previews/AppNavCanvas.d.ts +31 -0
- package/dist/views/metadata-admin/previews/AppNavCanvas.js +260 -0
- package/dist/views/metadata-admin/previews/AppPreview.d.ts +16 -1
- package/dist/views/metadata-admin/previews/AppPreview.js +23 -14
- package/dist/views/metadata-admin/previews/BookPreview.d.ts +20 -0
- package/dist/views/metadata-admin/previews/BookPreview.js +132 -0
- package/dist/views/metadata-admin/previews/DashboardPreview.d.ts +16 -1
- package/dist/views/metadata-admin/previews/DashboardPreview.js +110 -8
- package/dist/views/metadata-admin/previews/DatasetPreview.d.ts +18 -0
- package/dist/views/metadata-admin/previews/DatasetPreview.js +89 -0
- package/dist/views/metadata-admin/previews/DatasourcePreview.d.ts +23 -0
- package/dist/views/metadata-admin/previews/DatasourcePreview.js +68 -0
- package/dist/views/metadata-admin/previews/EmailTemplatePreview.d.ts +14 -1
- package/dist/views/metadata-admin/previews/FieldStub.d.ts +30 -0
- package/dist/views/metadata-admin/previews/FieldStub.js +104 -0
- package/dist/views/metadata-admin/previews/FieldsListEditor.d.ts +50 -0
- package/dist/views/metadata-admin/previews/FieldsListEditor.js +97 -0
- package/dist/views/metadata-admin/previews/FlowCanvas.d.ts +43 -0
- package/dist/views/metadata-admin/previews/FlowCanvas.js +328 -0
- package/dist/views/metadata-admin/previews/FlowPreview.d.ts +20 -0
- package/dist/views/metadata-admin/previews/FlowPreview.js +92 -0
- package/dist/views/metadata-admin/previews/FlowRunsPanel.d.ts +46 -0
- package/dist/views/metadata-admin/previews/FlowRunsPanel.js +97 -0
- package/dist/views/metadata-admin/previews/FlowSimulatorPanel.d.ts +25 -0
- package/dist/views/metadata-admin/previews/FlowSimulatorPanel.js +170 -0
- package/dist/views/metadata-admin/previews/JobPreview.d.ts +28 -0
- package/dist/views/metadata-admin/previews/JobPreview.js +290 -0
- package/dist/views/metadata-admin/previews/ObjectFormCanvas.d.ts +30 -0
- package/dist/views/metadata-admin/previews/ObjectFormCanvas.js +547 -0
- package/dist/views/metadata-admin/previews/ObjectPreview.d.ts +14 -1
- package/dist/views/metadata-admin/previews/ObjectPreview.js +5 -30
- package/dist/views/metadata-admin/previews/OutlineStrip.d.ts +32 -0
- package/dist/views/metadata-admin/previews/OutlineStrip.js +8 -0
- package/dist/views/metadata-admin/previews/PageBlockCanvas.d.ts +49 -0
- package/dist/views/metadata-admin/previews/PageBlockCanvas.js +510 -0
- package/dist/views/metadata-admin/previews/PagePreview.d.ts +10 -1
- package/dist/views/metadata-admin/previews/PagePreview.js +90 -4
- package/dist/views/metadata-admin/previews/PermissionPreview.d.ts +27 -0
- package/dist/views/metadata-admin/previews/PermissionPreview.js +115 -0
- package/dist/views/metadata-admin/previews/PreviewShell.d.ts +29 -6
- package/dist/views/metadata-admin/previews/PreviewShell.js +16 -3
- package/dist/views/metadata-admin/previews/ReportPreview.d.ts +18 -1
- package/dist/views/metadata-admin/previews/ReportPreview.js +23 -15
- package/dist/views/metadata-admin/previews/RolePreview.d.ts +19 -0
- package/dist/views/metadata-admin/previews/RolePreview.js +14 -0
- package/dist/views/metadata-admin/previews/SkillPreview.d.ts +22 -0
- package/dist/views/metadata-admin/previews/SkillPreview.js +34 -0
- package/dist/views/metadata-admin/previews/ToolPreview.d.ts +25 -0
- package/dist/views/metadata-admin/previews/ToolPreview.js +122 -0
- package/dist/views/metadata-admin/previews/TranslationPreview.d.ts +25 -0
- package/dist/views/metadata-admin/previews/TranslationPreview.js +52 -0
- package/dist/views/metadata-admin/previews/ValidationPreview.d.ts +27 -0
- package/dist/views/metadata-admin/previews/ValidationPreview.js +110 -0
- package/dist/views/metadata-admin/previews/ViewColumnPanes.d.ts +62 -0
- package/dist/views/metadata-admin/previews/ViewColumnPanes.js +140 -0
- package/dist/views/metadata-admin/previews/ViewPreview.d.ts +23 -1
- package/dist/views/metadata-admin/previews/ViewPreview.js +101 -73
- package/dist/views/metadata-admin/previews/block-config.d.ts +82 -0
- package/dist/views/metadata-admin/previews/block-config.js +324 -0
- package/dist/views/metadata-admin/previews/block-types.d.ts +40 -0
- package/dist/views/metadata-admin/previews/block-types.js +110 -0
- package/dist/views/metadata-admin/previews/field-types.d.ts +53 -0
- package/dist/views/metadata-admin/previews/field-types.js +97 -0
- package/dist/views/metadata-admin/previews/flow-canvas-layout.d.ts +88 -0
- package/dist/views/metadata-admin/previews/flow-canvas-layout.js +190 -0
- package/dist/views/metadata-admin/previews/flow-canvas-parts.d.ts +88 -0
- package/dist/views/metadata-admin/previews/flow-canvas-parts.js +358 -0
- package/dist/views/metadata-admin/previews/form-preview.d.ts +24 -0
- package/dist/views/metadata-admin/previews/form-preview.js +29 -0
- package/dist/views/metadata-admin/previews/index.js +43 -0
- package/dist/views/metadata-admin/previews/object-fields-bridge.d.ts +66 -0
- package/dist/views/metadata-admin/previews/object-fields-bridge.js +171 -0
- package/dist/views/metadata-admin/previews/object-fields-io.d.ts +109 -0
- package/dist/views/metadata-admin/previews/object-fields-io.js +208 -0
- package/dist/views/metadata-admin/previews/simulator/flow-sim-types.d.ts +91 -0
- package/dist/views/metadata-admin/previews/simulator/flow-sim-types.js +2 -0
- package/dist/views/metadata-admin/previews/simulator/flow-sim-validate.d.ts +8 -0
- package/dist/views/metadata-admin/previews/simulator/flow-sim-validate.js +113 -0
- package/dist/views/metadata-admin/previews/simulator/flow-simulator.d.ts +44 -0
- package/dist/views/metadata-admin/previews/simulator/flow-simulator.js +316 -0
- package/dist/views/metadata-admin/previews/useDatasetCatalog.d.ts +47 -0
- package/dist/views/metadata-admin/previews/useDatasetCatalog.js +133 -0
- package/dist/views/metadata-admin/previews/useFlowNodePalette.d.ts +44 -0
- package/dist/views/metadata-admin/previews/useFlowNodePalette.js +124 -0
- package/dist/views/metadata-admin/previews/useMetaOptions.d.ts +8 -0
- package/dist/views/metadata-admin/previews/useMetaOptions.js +50 -0
- package/dist/views/metadata-admin/previews/useObjectFields.d.ts +23 -0
- package/dist/views/metadata-admin/previews/useObjectFields.js +79 -0
- package/dist/views/metadata-admin/previews/useObjectOptions.d.ts +8 -0
- package/dist/views/metadata-admin/previews/useObjectOptions.js +43 -0
- package/dist/views/metadata-admin/previews/view-column-io.d.ts +42 -0
- package/dist/views/metadata-admin/previews/view-column-io.js +73 -0
- package/dist/views/metadata-admin/previews/widget-types.d.ts +24 -0
- package/dist/views/metadata-admin/previews/widget-types.js +40 -0
- package/dist/views/metadata-admin/registry.d.ts +140 -19
- package/dist/views/metadata-admin/report-schema.d.ts +26 -0
- package/dist/views/metadata-admin/report-schema.js +121 -0
- package/dist/views/metadata-admin/useMetadata.d.ts +100 -2
- package/dist/views/metadata-admin/useMetadata.js +155 -4
- package/dist/views/metadata-admin/view-item-normalize.d.ts +20 -0
- package/dist/views/metadata-admin/view-item-normalize.js +68 -0
- package/dist/views/metadata-admin/view-schema.d.ts +16 -0
- package/dist/views/metadata-admin/view-schema.js +107 -0
- package/dist/views/metadata-admin/view-variant-model.d.ts +23 -0
- package/dist/views/metadata-admin/view-variant-model.js +64 -0
- package/dist/views/metadata-admin/widgets.d.ts +89 -1
- package/dist/views/metadata-admin/widgets.js +491 -17
- package/dist/views/runtime-metadata-persistence.d.ts +78 -0
- package/dist/views/runtime-metadata-persistence.js +89 -0
- package/dist/views/useOpenRecordList.d.ts +18 -0
- package/dist/views/useOpenRecordList.js +36 -0
- package/dist/views/userFilterUrlState.d.ts +15 -0
- package/dist/views/userFilterUrlState.js +53 -0
- package/dist/views/view-config-adapter.d.ts +38 -0
- package/dist/views/view-config-adapter.js +80 -0
- package/package.json +52 -34
- package/dist/views/DesignDrawer.d.ts +0 -28
- package/dist/views/DesignDrawer.js +0 -51
- package/dist/views/metadata-admin/DesignerEditorWrapper.d.ts +0 -68
- package/dist/views/metadata-admin/DesignerEditorWrapper.js +0 -158
package/README.md
CHANGED
|
@@ -75,6 +75,11 @@ function MyForm() {
|
|
|
75
75
|
- **Lightweight**: ~50KB vs 500KB+ for full console
|
|
76
76
|
- **Composable**: Mix and match components as needed
|
|
77
77
|
- **Type-Safe**: Full TypeScript support
|
|
78
|
+
- **Console AI Entry Point**: The lazy chatbot FAB keeps mobile bottom
|
|
79
|
+
navigation clear until the full assistant panel is loaded
|
|
80
|
+
- **Full-Page AI Workspace**: The `/ai` surface provides a responsive chat
|
|
81
|
+
workspace with a desktop conversation rail, mobile Chats drawer, and a
|
|
82
|
+
constrained reading width for long conversations
|
|
78
83
|
|
|
79
84
|
## Components
|
|
80
85
|
|
|
@@ -140,6 +145,164 @@ Renders forms (modal or inline).
|
|
|
140
145
|
/>
|
|
141
146
|
```
|
|
142
147
|
|
|
148
|
+
## Metadata designers
|
|
149
|
+
|
|
150
|
+
The metadata-admin engine (`src/views/metadata-admin`) renders an in-app editor
|
|
151
|
+
for each metadata type. Every type has a pure-renderer **preview** that doubles
|
|
152
|
+
as its **designer** when given `editing` + `onPatch` props — no backend round
|
|
153
|
+
trip is required to edit a draft.
|
|
154
|
+
|
|
155
|
+
### Studio package scope
|
|
156
|
+
|
|
157
|
+
Studio treats the selected package as the authoring scope. The package selector
|
|
158
|
+
is mandatory, and Studio repairs missing `?package=` query parameters from the
|
|
159
|
+
last selected package or the first project package so scoped pages do not drift
|
|
160
|
+
out of sync with the sidebar. The Studio home overview, quick-create links,
|
|
161
|
+
metadata counts, and diagnostics all follow that active package. The dedicated
|
|
162
|
+
package-management page remains the global place to create, import, publish,
|
|
163
|
+
enable, or disable packages; direct `/metadata/package` links redirect there.
|
|
164
|
+
The Studio sidebar also flattens the root Overview group so Home and package
|
|
165
|
+
navigation sit directly under the package selector.
|
|
166
|
+
|
|
167
|
+
### Visual flow canvas
|
|
168
|
+
|
|
169
|
+
The `flow` designer (`FlowPreview` → `FlowCanvas`) renders an automation as an
|
|
170
|
+
industry-standard top-down node-link diagram (think n8n / Power Automate /
|
|
171
|
+
Salesforce Flow Builder) instead of a flat step list. It is **dependency-free**
|
|
172
|
+
— no ReactFlow / `@xyflow` — so the app-shell bundle stays lean.
|
|
173
|
+
|
|
174
|
+
**JSON shape** (a `flow` draft):
|
|
175
|
+
|
|
176
|
+
```jsonc
|
|
177
|
+
{
|
|
178
|
+
"nodes": [
|
|
179
|
+
{ "id": "start", "type": "start", "label": "Start" },
|
|
180
|
+
{ "id": "decide", "type": "decision", "label": "Renew?",
|
|
181
|
+
"ui": { "x": 220, "y": 180 } }, // optional persisted canvas position
|
|
182
|
+
{ "id": "email", "type": "action", "label": "Send reminder" },
|
|
183
|
+
{ "id": "end", "type": "end", "label": "End" }
|
|
184
|
+
],
|
|
185
|
+
"edges": [
|
|
186
|
+
{ "source": "start", "target": "decide" },
|
|
187
|
+
{ "source": "decide", "target": "email", "condition": "${days <= 30}", "label": "Due" },
|
|
188
|
+
{ "source": "decide", "target": "end", "isDefault": true, "label": "Skip" },
|
|
189
|
+
{ "source": "email", "target": "end" }
|
|
190
|
+
]
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
- **Layout** — nodes without a `ui` hint are placed by a deterministic layered
|
|
195
|
+
auto-layout (cycle-guarded), so a flow always renders cleanly even before any
|
|
196
|
+
manual positioning. Dragging a node persists its position to `node.ui.{x,y}`;
|
|
197
|
+
positions degrade gracefully (they are layout hints, not required data).
|
|
198
|
+
- **Edges** — branch semantics (`condition`, `label`, `isDefault`) are rendered
|
|
199
|
+
as labels on the connectors and preserved when a node is inserted on an edge.
|
|
200
|
+
|
|
201
|
+
**Interactions** (design mode):
|
|
202
|
+
|
|
203
|
+
- **Add node** — toolbar palette (Action / Decision / Wait / Subflow / Signal /
|
|
204
|
+
End); the new node is auto-selected.
|
|
205
|
+
- **Append** — the bottom `+` handle on a node adds a connected child.
|
|
206
|
+
- **Insert on edge** — the `+` on a connector splices a node between two nodes,
|
|
207
|
+
preserving the original branch condition on the first segment.
|
|
208
|
+
- **Reposition** — drag a node (committed on pointer-up).
|
|
209
|
+
- **Delete** — `Delete` / `Backspace` removes the selected node and its edges.
|
|
210
|
+
- **Navigate** — fit-to-view, zoom in/out, and background pan.
|
|
211
|
+
|
|
212
|
+
Selecting a node opens `FlowNodeInspector`, which renders **typed form fields
|
|
213
|
+
per node type** (see `flow-node-config.ts`) rather than a raw JSON blob. Node
|
|
214
|
+
types follow the spec `FlowNodeAction` enum
|
|
215
|
+
(`@objectstack/spec/automation/flow.zod.ts`): `start`, `decision`,
|
|
216
|
+
`assignment`, `loop`, `create_record`, `update_record`, `delete_record`,
|
|
217
|
+
`get_record`, `http_request`, `script`, `screen`, `wait`, `subflow`,
|
|
218
|
+
`connector_action`, `parallel_gateway`, `join_gateway`, `boundary_event`,
|
|
219
|
+
`end`. Field keys mirror the **real production vocabulary** used by installed
|
|
220
|
+
apps (the spec leaves `config` freeform, so the app metadata is the de-facto
|
|
221
|
+
standard): a `start` node exposes *Object* / *Entry condition* (`criteria`,
|
|
222
|
+
a CEL string) / *Cron schedule* (`schedule`); the trigger **category** is a
|
|
223
|
+
flow-level concern, so `start` deliberately stores **no** `triggerType`. A
|
|
224
|
+
`decision` uses `condition`; `get_record`/`update_record`/`delete_record` use a
|
|
225
|
+
`filter` object; `loop` uses `iteratorVariable`. Spec **structured blocks** are
|
|
226
|
+
edited through dedicated fields, not JSON: a `wait` node maps `waitEventConfig.*`
|
|
227
|
+
(Wait-for / Duration / Timeout / On timeout), a `connector_action` maps
|
|
228
|
+
`connectorConfig.*` (Connector / Action / Input), and a `boundary_event` maps
|
|
229
|
+
`boundaryConfig.*`. CRUD/script/http fields live under `node.config`; spec
|
|
230
|
+
blocks and `timeoutMs` live at the node top-level. Type-specific fields sit under
|
|
231
|
+
a **Configuration** divider, and **conditional fields** (`showWhen`) only appear
|
|
232
|
+
when relevant — e.g. a `script` node switches between a *Code* / *Output
|
|
233
|
+
variables* shape and an *email/SMS* notification shape (*Template* / *Recipients*
|
|
234
|
+
/ *Template variables*) based on its *Action type* (`actionType`, defaulting to
|
|
235
|
+
`code`), and a `wait` node shows *Duration* / *Signal name* based on the selected
|
|
236
|
+
*Wait for* mode. A conditional field is never hidden while it still holds a
|
|
237
|
+
value, so existing config is always reachable.
|
|
238
|
+
|
|
239
|
+
Config keys come in three editable shapes so authors never hand-write JSON:
|
|
240
|
+
|
|
241
|
+
- **Flat object maps** — a `create_record` node's **Field values**, a
|
|
242
|
+
`connector_action`'s **Input**, a `get_record`'s **Filter** — use an inline
|
|
243
|
+
**key/value editor** (`keyValue` kind). Scalar values are auto-typed (`3` →
|
|
244
|
+
number, `true` → boolean); object/array values such as a filter operator
|
|
245
|
+
`{"$ne": null}` round-trip losslessly.
|
|
246
|
+
- **String arrays** — a script's **Recipients** / **Output variables** — use a
|
|
247
|
+
single-column **string-list editor** (`stringList` kind).
|
|
248
|
+
- **Arrays of objects** — a `screen` node's **Fields** (a list of
|
|
249
|
+
`{name,label,type,required,visibleWhen}` definitions) — use a column-driven
|
|
250
|
+
**object-list repeater** (`objectList` kind).
|
|
251
|
+
|
|
252
|
+
Anything still not covered by a field (nested objects, arrays, plugin-specific
|
|
253
|
+
keys) lives in an **optional** Advanced (JSON) escape hatch: it is shown only
|
|
254
|
+
when such keys already exist, and is otherwise reachable through a low-emphasis
|
|
255
|
+
"Advanced (JSON)" button — it never alarms authors into thinking the form is
|
|
256
|
+
incomplete, and it can never overwrite a key a form field already owns. Node
|
|
257
|
+
types with no configuration (e.g. `parallel`) show a plain "No configuration
|
|
258
|
+
needed" note instead of an empty JSON box. The `ui` layout hint is always kept
|
|
259
|
+
out of the config entirely and preserved across edits.
|
|
260
|
+
|
|
261
|
+
### Flow simulator (designer-time debug runner)
|
|
262
|
+
|
|
263
|
+
The canvas toolbar has a **Debug** toggle that opens an in-designer **flow
|
|
264
|
+
simulator** (`FlowSimulatorPanel` → `simulator/flow-simulator.ts`). It lets a
|
|
265
|
+
low-code author *test a flow draft without a backend* — answering "how do I
|
|
266
|
+
mock-run and step through this flow?".
|
|
267
|
+
|
|
268
|
+
It is a **pure, client-side interpreter**. It **never** calls a `dataSource`:
|
|
269
|
+
every side-effecting node (CRUD / `get_record` / `http_request` /
|
|
270
|
+
`connector_action` / `script`) is **MOCKED**, so a simulation can never write or
|
|
271
|
+
delete real data and never needs a live environment. Its guiding rule is *never
|
|
272
|
+
silently simulate semantics that differ from the runtime* — anything that cannot
|
|
273
|
+
be faithfully modelled is surfaced loudly instead of faked.
|
|
274
|
+
|
|
275
|
+
- **Preflight validation** — before a run, `validateFlowDraft` blocks on
|
|
276
|
+
structural errors (no resolvable entry, duplicate ids, edges to missing nodes,
|
|
277
|
+
multiple decision defaults) and warns on soft issues (unreachable nodes, a
|
|
278
|
+
decision with no default). Errors disable **Run** so problems surface up front.
|
|
279
|
+
- **Controls** — **Run** (to completion), **Step** (one node), **Reset**, and
|
|
280
|
+
**Continue** (after a pause). Flow `variables` marked `isInput` become a seed
|
|
281
|
+
form; values are auto-typed (`30` → number, `true` → boolean, `{…}` → JSON).
|
|
282
|
+
- **Set variables / Mock outputs** — because a decision often reads a value no
|
|
283
|
+
declared input produces (e.g. a computed `daysToExpiry`), the panel adds a
|
|
284
|
+
free-form **Set variables** editor that injects/overrides *any* variable at
|
|
285
|
+
start, so **every branch is reachable**. A **Mock outputs** editor lets the
|
|
286
|
+
author pin what each mocked side-effect node "returns" (written to its
|
|
287
|
+
`outputVariable` / `outputVariables`), so data-dependent logic downstream of a
|
|
288
|
+
`get_record` or `script` can be exercised too.
|
|
289
|
+
- **Semantics** — `start`/`assignment` pass through; a `decision` routes
|
|
290
|
+
**edge-first** (first truthy outgoing `condition`, else the `isDefault` edge,
|
|
291
|
+
else a surfaced dead-end), evaluating CEL via `@object-ui/core`'s
|
|
292
|
+
`ExpressionEvaluator` and **surfacing eval errors** (not swallowing them);
|
|
293
|
+
side-effect nodes write their mock to `outputVariable` / `outputVariables[]`;
|
|
294
|
+
`wait` and `screen` **pause** for manual continue; `join_gateway`, `subflow`,
|
|
295
|
+
and `boundary_event` are marked **unsupported** (token sync / nested runs are
|
|
296
|
+
not modelled) rather than faked.
|
|
297
|
+
- **Live feedback** — the panel shows a **variable watch**, a **step timeline**
|
|
298
|
+
(status badges `OK` / `MOCKED` / `PAUSED` / `SKIPPED` / `ERROR`, per-decision
|
|
299
|
+
edge diagnostics, and write summaries), while the canvas highlights the
|
|
300
|
+
**active** node (pulsing sky ring), **visited** nodes (emerald), and
|
|
301
|
+
**traversed** edges (sky), dimming nodes not yet reached.
|
|
302
|
+
|
|
303
|
+
The engine is covered by unit tests in
|
|
304
|
+
`previews/simulator/__tests__/flow-simulator.test.ts`.
|
|
305
|
+
|
|
143
306
|
## Architecture
|
|
144
307
|
|
|
145
308
|
This package sits between the low-level `@object-ui/react` (SchemaRenderer) and the high-level `apps/console` (full application):
|
|
@@ -261,6 +424,135 @@ for the adapter contract, backend schema, and how to plug in your own backend.
|
|
|
261
424
|
|
|
262
425
|
<!-- release-metadata:v3.3.0 -->
|
|
263
426
|
|
|
427
|
+
## Command palette (⌘K)
|
|
428
|
+
|
|
429
|
+
`<ConsoleShell>` mounts a global ⌘K command palette for cross-app navigation and
|
|
430
|
+
record search. Its open state and the command that opens it are provided by
|
|
431
|
+
`CommandPaletteProvider` (wired in by `ConsoleLayout`) and exposed via
|
|
432
|
+
`useCommandPalette()`.
|
|
433
|
+
|
|
434
|
+
```tsx
|
|
435
|
+
import { useCommandPalette } from '@object-ui/app-shell';
|
|
436
|
+
|
|
437
|
+
function MyToolbarButton() {
|
|
438
|
+
const { openCommandPalette } = useCommandPalette();
|
|
439
|
+
// Idempotent: calling when already open is a no-op.
|
|
440
|
+
return <button onClick={openCommandPalette}>Search…</button>;
|
|
441
|
+
}
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
Designed to be deterministic for automated (AI) browser testing — see
|
|
445
|
+
[ADR-0054 "UI testability contract"](../../docs/adr/0054-ui-testability-contract.md):
|
|
446
|
+
|
|
447
|
+
- **Idempotent, direct open (C1).** The top-bar search button, the ⌘K shortcut,
|
|
448
|
+
and the deep-link all call the *same* idempotent `openCommandPalette()`
|
|
449
|
+
(`setOpen(true)`), never a `toggle()`. The button calls the command directly —
|
|
450
|
+
it does **not** re-dispatch a synthetic `⌘K` `KeyboardEvent` (which silently
|
|
451
|
+
did nothing under automation and in ⌘K-reserving browsers). ⌘K stays a
|
|
452
|
+
keyboard *accelerator* and may still toggle (close-on-repeat).
|
|
453
|
+
- **URL-addressable (C3).** Open state lives in the `?palette=1` search param, so
|
|
454
|
+
the palette is deep-linkable (`/apps/<app>?palette=1`), restores on reload, and
|
|
455
|
+
works with browser back/forward. `?cmdk=1` is accepted as an alias on read.
|
|
456
|
+
- **Stable locators (C4).** The dialog carries `data-testid="overlay:command-palette"`
|
|
457
|
+
plus an ARIA role/name; the header trigger carries
|
|
458
|
+
`data-testid="action:command-palette:open"` (and `:open-mobile` for the compact
|
|
459
|
+
header). `CommandDialog` accepts `contentProps` to forward a `data-testid`/ARIA
|
|
460
|
+
name onto the underlying dialog element.
|
|
461
|
+
- **Trusted-input note (C6).** The palette search is a controlled + debounced
|
|
462
|
+
input. Value-injection (`el.value = …`) does **not** fire React's `onChange`;
|
|
463
|
+
drive it with a real-input / CDP-keystroke driver so the debounced fetch fires.
|
|
464
|
+
|
|
465
|
+
## URL-addressable overlays (`useUrlOverlay`)
|
|
466
|
+
|
|
467
|
+
`useUrlOverlay(key)` is the reusable building block behind the command palette's
|
|
468
|
+
URL-addressable open state (ADR-0054 C3). It stores a navigable overlay's open
|
|
469
|
+
state in a `?<key>=1` search param instead of component `useState`, so the
|
|
470
|
+
overlay is deep-linkable, restores on reload, and works with back/forward — and
|
|
471
|
+
its open path is idempotent (C1).
|
|
472
|
+
|
|
473
|
+
```tsx
|
|
474
|
+
import { useUrlOverlay } from '@object-ui/app-shell';
|
|
475
|
+
|
|
476
|
+
function HelpMenu() {
|
|
477
|
+
const { open, setOpen, openOverlay } = useUrlOverlay('shortcuts');
|
|
478
|
+
// Header button (any component under the router): onClick={openOverlay}
|
|
479
|
+
// Dialog (elsewhere, reads the same param): <Dialog open={open} onOpenChange={setOpen}>
|
|
480
|
+
// Deep-link that opens on load: /apps/foo?shortcuts=1
|
|
481
|
+
}
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
Because state lives in the URL, a trigger and the overlay it controls need no
|
|
485
|
+
shared provider or prop-drilling — they just use the same `key`. The
|
|
486
|
+
command palette (`?palette=1`, `?cmdk=1` alias) and the keyboard-shortcuts dialog
|
|
487
|
+
(`?shortcuts=1`, openable from the Help menu — no longer `?`-key-only) both build
|
|
488
|
+
on it. `replace`/`alias`/`value` are configurable.
|
|
489
|
+
|
|
490
|
+
The shared overlay primitives in `@object-ui/components`
|
|
491
|
+
(`Dialog`/`Sheet`/`Drawer`/`Popover`/`DropdownMenu`/`AlertDialog`) already forward
|
|
492
|
+
a `data-testid` onto their content element and emit Radix `data-state="open|closed"`,
|
|
493
|
+
so overlays are locatable and their open/closed state is machine-readable by
|
|
494
|
+
construction (C4).
|
|
495
|
+
|
|
496
|
+
## Settle signal (is the app idle?)
|
|
497
|
+
|
|
498
|
+
`<ConsoleShell>` exposes one global "no requests in flight" predicate so an
|
|
499
|
+
automated (AI) browser driver can wait for the app to settle instead of
|
|
500
|
+
hardcoding timeouts (ADR-0054 C5). The data layer increments a counter around
|
|
501
|
+
every outbound request (it wraps the adapter's `fetch`), mirrored onto
|
|
502
|
+
`window.__objectui`:
|
|
503
|
+
|
|
504
|
+
```js
|
|
505
|
+
// In an e2e / browser driver:
|
|
506
|
+
await page.waitForFunction(() => window.__objectui?.idle === true);
|
|
507
|
+
// or: window.__objectui.pendingRequests === 0
|
|
508
|
+
// or: await window.__objectui.whenIdle(); // resolves when settled (10s cap)
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
In React, `useSettleSignal()` returns `{ pending, idle }` for a global busy
|
|
512
|
+
indicator; the lower-level `getPendingRequests` / `subscribeSettle` / `whenIdle`
|
|
513
|
+
/ `withSettleSignal` / `installSettleSignalGlobal` are also exported.
|
|
514
|
+
|
|
515
|
+
Async data regions additionally expose region-level state for finer waits: the
|
|
516
|
+
list view and record-picker results set `aria-busy` while fetching and
|
|
517
|
+
`data-state="loading|idle"`, complementing the Radix `data-state` already on
|
|
518
|
+
overlays.
|
|
519
|
+
|
|
520
|
+
## Field locators (`field:{object}.{field}`)
|
|
521
|
+
|
|
522
|
+
Generated forms emit a metadata-derived stable locator on every field wrapper, so
|
|
523
|
+
an automated (AI) driver can target a field without relying on i18n-fragile labels
|
|
524
|
+
or positional selectors (ADR-0054 C4). The form renderer derives it from the
|
|
525
|
+
form's `objectName` and each field's name — every form (`ObjectForm`, `ModalForm`,
|
|
526
|
+
`DrawerForm`, `SplitForm`, `WizardForm`) inherits it with zero per-app work:
|
|
527
|
+
|
|
528
|
+
```html
|
|
529
|
+
<div data-testid="field:account.industry" data-field="industry"> … input … </div>
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
```js
|
|
533
|
+
// e2e / AI driver:
|
|
534
|
+
await page.getByTestId('field:account.industry').locator('input').fill('SaaS');
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
The object prefix is omitted (`field:{field}`) when a form has no owning object.
|
|
538
|
+
This complements the action/overlay locators already emitted by the renderer
|
|
539
|
+
(`overlay:command-palette`, `action:command-palette:open`, …).
|
|
540
|
+
|
|
541
|
+
## Testability ratchet
|
|
542
|
+
|
|
543
|
+
The invariants above are kept from regressing (ADR-0054 Phase 5, "counts can only
|
|
544
|
+
go down"):
|
|
545
|
+
|
|
546
|
+
- A conformance test (runs in the gating `pnpm test` job) fails the build if a new
|
|
547
|
+
**synthetic-event trigger** (`el.dispatchEvent(new KeyboardEvent/MouseEvent/
|
|
548
|
+
PointerEvent …)`) is introduced anywhere in `packages/*/src` or `apps/*/src`.
|
|
549
|
+
Legitimate `CustomEvent` / `PopStateEvent` dispatch (event bus / history nudge)
|
|
550
|
+
is allowed. Replace a synthetic trigger with a direct, idempotent command
|
|
551
|
+
(`useCommandPalette` / `useUrlOverlay`).
|
|
552
|
+
- A matching ESLint rule `object-ui/no-synthetic-event-trigger` flags the same
|
|
553
|
+
pattern in-editor (the repo `Lint` workflow is manual, so the test is the CI
|
|
554
|
+
gate).
|
|
555
|
+
|
|
264
556
|
## Compatibility
|
|
265
557
|
|
|
266
558
|
- **React:** 18.x or 19.x
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export interface AssistantEditorField {
|
|
2
|
+
name: string;
|
|
3
|
+
type?: string;
|
|
4
|
+
label?: string;
|
|
5
|
+
required?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface AssistantEditorContext {
|
|
8
|
+
/** Metadata type, e.g. 'object'. */
|
|
9
|
+
type: string;
|
|
10
|
+
/** Item primary-key name (may be empty in create mode). */
|
|
11
|
+
name: string;
|
|
12
|
+
label?: string;
|
|
13
|
+
/** Lightweight field summary — enough for the agent to reason, not the full draft. */
|
|
14
|
+
fields?: AssistantEditorField[];
|
|
15
|
+
}
|
|
16
|
+
/** A metadata item the chat has asked the host to open in review/diff. */
|
|
17
|
+
export interface AssistantReviewTarget {
|
|
18
|
+
type: string;
|
|
19
|
+
name: string;
|
|
20
|
+
}
|
|
21
|
+
export interface AssistantSnapshot {
|
|
22
|
+
/** What the user is currently editing, or null when no designer is active. */
|
|
23
|
+
editor: AssistantEditorContext | null;
|
|
24
|
+
/** Monotonic counter — bumped each time a surface requests the chat to open. */
|
|
25
|
+
openSeq: number;
|
|
26
|
+
/**
|
|
27
|
+
* Monotonic counter — bumped each time the chat asks the host to open a
|
|
28
|
+
* drafted item in review (ADR-0033 Phase B). The host (which knows the app
|
|
29
|
+
* base) watches this and navigates to the designer.
|
|
30
|
+
*/
|
|
31
|
+
reviewSeq: number;
|
|
32
|
+
/** The item to review, set alongside the latest `reviewSeq` bump. */
|
|
33
|
+
reviewTarget: AssistantReviewTarget | null;
|
|
34
|
+
}
|
|
35
|
+
export declare const assistantBus: {
|
|
36
|
+
subscribe(listener: () => void): () => void;
|
|
37
|
+
getSnapshot(): AssistantSnapshot;
|
|
38
|
+
/** Publish the currently-edited item (or null to clear). No-op if unchanged. */
|
|
39
|
+
setEditor(next: AssistantEditorContext | null): void;
|
|
40
|
+
/** Ask the global chat to open (and warm/mount the lazy FAB). */
|
|
41
|
+
requestOpen(): void;
|
|
42
|
+
/**
|
|
43
|
+
* Ask the host to open `target` in the designer's review/diff (ADR-0033
|
|
44
|
+
* Phase B). The chat calls this from the "Review N change(s)" affordance;
|
|
45
|
+
* a navigator that knows the app base performs the routing.
|
|
46
|
+
*/
|
|
47
|
+
requestReview(target: AssistantReviewTarget): void;
|
|
48
|
+
};
|
|
49
|
+
export interface CanvasInvalidation {
|
|
50
|
+
type: string;
|
|
51
|
+
name: string;
|
|
52
|
+
}
|
|
53
|
+
/** Announce that a draft artifact changed (chat hosts call this). */
|
|
54
|
+
export declare function emitCanvasInvalidate(inv: CanvasInvalidation): void;
|
|
55
|
+
/** Subscribe to draft-artifact invalidations; returns an unsubscriber. */
|
|
56
|
+
export declare function subscribeCanvasInvalidate(listener: (inv: CanvasInvalidation) => void): () => void;
|
|
57
|
+
/** Announce that the live metadata registry changed (publish / install hosts call this). */
|
|
58
|
+
export declare function emitMetadataRefresh(): void;
|
|
59
|
+
/** Subscribe to live-metadata-changed events; returns an unsubscriber. */
|
|
60
|
+
export declare function subscribeMetadataRefresh(listener: () => void): () => void;
|
|
61
|
+
/** Subscribe a component to the assistant bus snapshot. */
|
|
62
|
+
export declare function useAssistant(): AssistantSnapshot;
|
|
63
|
+
/**
|
|
64
|
+
* Publish the currently-edited item to the assistant for the lifetime of
|
|
65
|
+
* the calling component (auto-clears on unmount). Pass `null` to register
|
|
66
|
+
* nothing. Stable across renders with equal content.
|
|
67
|
+
*/
|
|
68
|
+
export declare function useRegisterAssistantEditor(ctx: AssistantEditorContext | null): void;
|
|
69
|
+
/** Open the global AI chat from anywhere (e.g. an "Ask AI" button). */
|
|
70
|
+
export declare function requestAssistantOpen(): void;
|
|
71
|
+
/** Ask the host to open a drafted item in the designer's review/diff. */
|
|
72
|
+
export declare function requestAssistantReview(target: AssistantReviewTarget): void;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
+
/**
|
|
3
|
+
* Assistant bus — a tiny framework-agnostic singleton that connects the
|
|
4
|
+
* metadata designers to the global AI chat (`ConsoleFloatingChatbot`).
|
|
5
|
+
*
|
|
6
|
+
* Two channels:
|
|
7
|
+
* 1. **Editor context** — a designer publishes *what the user is
|
|
8
|
+
* currently editing* (`{ type, name, label, fields }`). The chatbot
|
|
9
|
+
* reads it and merges it into the `context` it sends the agent, so
|
|
10
|
+
* "add a priority field" acts on the open object without the user
|
|
11
|
+
* restating which object they mean.
|
|
12
|
+
* 2. **Open signal** — a designer can ask the global chat to open (e.g.
|
|
13
|
+
* an "Ask AI" button). The lazy chat FAB arms + opens on the signal.
|
|
14
|
+
*
|
|
15
|
+
* Why a singleton bus instead of React context? The chat FAB is
|
|
16
|
+
* lazy-mounted on a different branch of the tree from the designers, and
|
|
17
|
+
* the open-signal must cross that boundary without a shared Provider
|
|
18
|
+
* being threaded through every layout. A module singleton + (subscribe,
|
|
19
|
+
* getSnapshot) reads cleanly via `useSyncExternalStore`.
|
|
20
|
+
*/
|
|
21
|
+
import { useEffect, useSyncExternalStore } from 'react';
|
|
22
|
+
let editor = null;
|
|
23
|
+
let openSeq = 0;
|
|
24
|
+
let reviewSeq = 0;
|
|
25
|
+
let reviewTarget = null;
|
|
26
|
+
// Cached snapshot — its reference only changes on a real state change so
|
|
27
|
+
// useSyncExternalStore doesn't loop.
|
|
28
|
+
let snapshot = { editor, openSeq, reviewSeq, reviewTarget };
|
|
29
|
+
const listeners = new Set();
|
|
30
|
+
function commit() {
|
|
31
|
+
snapshot = { editor, openSeq, reviewSeq, reviewTarget };
|
|
32
|
+
for (const l of listeners)
|
|
33
|
+
l();
|
|
34
|
+
}
|
|
35
|
+
function sameEditor(a, b) {
|
|
36
|
+
if (a === b)
|
|
37
|
+
return true;
|
|
38
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
39
|
+
}
|
|
40
|
+
export const assistantBus = {
|
|
41
|
+
subscribe(listener) {
|
|
42
|
+
listeners.add(listener);
|
|
43
|
+
return () => {
|
|
44
|
+
listeners.delete(listener);
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
getSnapshot() {
|
|
48
|
+
return snapshot;
|
|
49
|
+
},
|
|
50
|
+
/** Publish the currently-edited item (or null to clear). No-op if unchanged. */
|
|
51
|
+
setEditor(next) {
|
|
52
|
+
if (sameEditor(editor, next))
|
|
53
|
+
return;
|
|
54
|
+
editor = next;
|
|
55
|
+
commit();
|
|
56
|
+
},
|
|
57
|
+
/** Ask the global chat to open (and warm/mount the lazy FAB). */
|
|
58
|
+
requestOpen() {
|
|
59
|
+
openSeq += 1;
|
|
60
|
+
commit();
|
|
61
|
+
},
|
|
62
|
+
/**
|
|
63
|
+
* Ask the host to open `target` in the designer's review/diff (ADR-0033
|
|
64
|
+
* Phase B). The chat calls this from the "Review N change(s)" affordance;
|
|
65
|
+
* a navigator that knows the app base performs the routing.
|
|
66
|
+
*/
|
|
67
|
+
requestReview(target) {
|
|
68
|
+
reviewSeq += 1;
|
|
69
|
+
reviewTarget = target;
|
|
70
|
+
commit();
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
const invalidateListeners = new Set();
|
|
74
|
+
/** Announce that a draft artifact changed (chat hosts call this). */
|
|
75
|
+
export function emitCanvasInvalidate(inv) {
|
|
76
|
+
for (const l of invalidateListeners)
|
|
77
|
+
l(inv);
|
|
78
|
+
}
|
|
79
|
+
/** Subscribe to draft-artifact invalidations; returns an unsubscriber. */
|
|
80
|
+
export function subscribeCanvasInvalidate(listener) {
|
|
81
|
+
invalidateListeners.add(listener);
|
|
82
|
+
return () => {
|
|
83
|
+
invalidateListeners.delete(listener);
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
// ── Live-metadata-changed signal ─────────────────────────────
|
|
87
|
+
// The live registry just changed out-of-band from the metadata trees — a
|
|
88
|
+
// publish promoted staged drafts, or a marketplace install merged a package.
|
|
89
|
+
// Unlike the per-artifact, draft-only canvas invalidations above, this is a
|
|
90
|
+
// coarse "the live world changed, refetch" pulse: EVERY mounted
|
|
91
|
+
// MetadataProvider (nav sidebar included, not just the surface that triggered
|
|
92
|
+
// it) refetches its loaded types so already-open forms/views/nav pick up the
|
|
93
|
+
// change WITHOUT a full page reload. Fire-and-forget, off the snapshot bus
|
|
94
|
+
// (same reasoning as canvas invalidations — an event, not state).
|
|
95
|
+
const metadataRefreshListeners = new Set();
|
|
96
|
+
/** Announce that the live metadata registry changed (publish / install hosts call this). */
|
|
97
|
+
export function emitMetadataRefresh() {
|
|
98
|
+
for (const l of metadataRefreshListeners)
|
|
99
|
+
l();
|
|
100
|
+
}
|
|
101
|
+
/** Subscribe to live-metadata-changed events; returns an unsubscriber. */
|
|
102
|
+
export function subscribeMetadataRefresh(listener) {
|
|
103
|
+
metadataRefreshListeners.add(listener);
|
|
104
|
+
return () => {
|
|
105
|
+
metadataRefreshListeners.delete(listener);
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/** Subscribe a component to the assistant bus snapshot. */
|
|
109
|
+
export function useAssistant() {
|
|
110
|
+
return useSyncExternalStore(assistantBus.subscribe, assistantBus.getSnapshot, assistantBus.getSnapshot);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Publish the currently-edited item to the assistant for the lifetime of
|
|
114
|
+
* the calling component (auto-clears on unmount). Pass `null` to register
|
|
115
|
+
* nothing. Stable across renders with equal content.
|
|
116
|
+
*/
|
|
117
|
+
export function useRegisterAssistantEditor(ctx) {
|
|
118
|
+
// Serialize for a cheap, content-based effect dependency.
|
|
119
|
+
const key = ctx ? JSON.stringify(ctx) : '';
|
|
120
|
+
useEffect(() => {
|
|
121
|
+
assistantBus.setEditor(ctx);
|
|
122
|
+
return () => assistantBus.setEditor(null);
|
|
123
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
124
|
+
}, [key]);
|
|
125
|
+
}
|
|
126
|
+
/** Open the global AI chat from anywhere (e.g. an "Ask AI" button). */
|
|
127
|
+
export function requestAssistantOpen() {
|
|
128
|
+
assistantBus.requestOpen();
|
|
129
|
+
}
|
|
130
|
+
/** Ask the host to open a drafted item in the designer's review/diff. */
|
|
131
|
+
export function requestAssistantReview(target) {
|
|
132
|
+
assistantBus.requestReview(target);
|
|
133
|
+
}
|
|
@@ -17,5 +17,5 @@ interface CommandPaletteProps {
|
|
|
17
17
|
*/
|
|
18
18
|
dataSource?: any;
|
|
19
19
|
}
|
|
20
|
-
export declare function CommandPalette({ apps, activeApp, objects, onAppChange, dataSource }: CommandPaletteProps): import("react
|
|
20
|
+
export declare function CommandPalette({ apps, activeApp, objects, onAppChange, dataSource }: CommandPaletteProps): import("react").JSX.Element;
|
|
21
21
|
export {};
|
|
@@ -10,39 +10,36 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
10
10
|
import { useEffect, useState, useCallback, useMemo } from 'react';
|
|
11
11
|
import { useNavigate, useParams } from 'react-router-dom';
|
|
12
12
|
import { CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, } from '@object-ui/components';
|
|
13
|
-
import { LayoutDashboard, FileText, BarChart3, Moon, Sun, Monitor, Search,
|
|
13
|
+
import { LayoutDashboard, FileText, BarChart3, Moon, Sun, Monitor, Search, } from 'lucide-react';
|
|
14
14
|
import { useRecordSearch } from '@object-ui/react';
|
|
15
15
|
import { useTheme } from './ThemeProvider';
|
|
16
16
|
import { useExpressionContext, evaluateVisibility } from '../providers/ExpressionProvider';
|
|
17
17
|
import { useObjectTranslation } from '@object-ui/i18n';
|
|
18
|
-
import { resolveI18nLabel, getRecordDisplayName } from '../utils';
|
|
18
|
+
import { resolveI18nLabel, getRecordDisplayName, appRouteSegment } from '../utils';
|
|
19
19
|
import { getIcon } from '../utils/getIcon';
|
|
20
20
|
import { useRecentItems } from '../context/RecentItemsProvider';
|
|
21
|
+
import { useCommandPalette } from '../context/CommandPaletteProvider';
|
|
22
|
+
import { resolveHref } from '@object-ui/layout';
|
|
23
|
+
import { useAuth } from '@object-ui/auth';
|
|
21
24
|
export function CommandPalette({ apps, activeApp, objects, onAppChange, dataSource }) {
|
|
22
|
-
const
|
|
25
|
+
const { open, setOpen } = useCommandPalette();
|
|
23
26
|
const [inputValue, setInputValue] = useState('');
|
|
24
27
|
const navigate = useNavigate();
|
|
25
28
|
const { appName } = useParams();
|
|
26
29
|
const { setTheme } = useTheme();
|
|
27
30
|
const { evaluator } = useExpressionContext();
|
|
28
31
|
const { t } = useObjectTranslation();
|
|
29
|
-
//
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {
|
|
33
|
-
e.preventDefault();
|
|
34
|
-
setOpen(prev => !prev);
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
document.addEventListener('keydown', down);
|
|
38
|
-
return () => document.removeEventListener('keydown', down);
|
|
39
|
-
}, []);
|
|
32
|
+
// The ⌘K / Ctrl+K accelerator and the open-state source of truth now live in
|
|
33
|
+
// CommandPaletteProvider so the keyboard shortcut, the header button, and the
|
|
34
|
+
// ?palette=1 deep-link all drive the SAME idempotent open path (ADR-0054 C1/C3).
|
|
40
35
|
// Reset query when the palette closes so reopening doesn't show stale state.
|
|
41
36
|
useEffect(() => {
|
|
42
37
|
if (!open)
|
|
43
38
|
setInputValue('');
|
|
44
39
|
}, [open]);
|
|
45
|
-
const baseUrl = `/apps/${appName || activeApp
|
|
40
|
+
const baseUrl = `/apps/${appName || appRouteSegment(activeApp)}`;
|
|
41
|
+
const { user } = useAuth();
|
|
42
|
+
const templateContext = useMemo(() => ({ currentUserId: user?.id ?? null }), [user?.id]);
|
|
46
43
|
const runCommand = useCallback((command) => {
|
|
47
44
|
setOpen(false);
|
|
48
45
|
command();
|
|
@@ -71,7 +68,14 @@ export function CommandPalette({ apps, activeApp, objects, onAppChange, dataSour
|
|
|
71
68
|
const { recentItems } = useRecentItems();
|
|
72
69
|
const recentRecords = useMemo(() => recentItems.filter((it) => it.type === 'record').slice(0, 5), [recentItems]);
|
|
73
70
|
const showRecentRecords = open && inputValue.trim().length === 0 && recentRecords.length > 0;
|
|
74
|
-
return (_jsxs(CommandDialog, { open: open, onOpenChange: setOpen,
|
|
71
|
+
return (_jsxs(CommandDialog, { open: open, onOpenChange: setOpen,
|
|
72
|
+
// Accessible name/description (rendered visually-hidden as the required
|
|
73
|
+
// Radix DialogTitle/Description) — gives the dialog a stable ARIA name (C4).
|
|
74
|
+
title: t('console.commandPalette.title', { defaultValue: 'Command palette' }), description: t('console.commandPalette.placeholder'), contentProps: {
|
|
75
|
+
// Stable locator so the overlay is addressable by an automated driver
|
|
76
|
+
// without relying on i18n-fragile visible text (C4).
|
|
77
|
+
'data-testid': 'overlay:command-palette',
|
|
78
|
+
}, children: [_jsx(CommandInput, { placeholder: t('console.commandPalette.placeholder'), value: inputValue, onValueChange: setInputValue }), _jsxs(CommandList, { children: [_jsx(CommandEmpty, { children: isSearching ? (_jsxs("span", { className: "inline-flex items-center gap-2 text-muted-foreground", children: [_jsx("span", { "aria-hidden": true, className: "inline-block h-1.5 w-1.5 rounded-full bg-primary motion-safe:animate-pulse" }), t('console.commandPalette.searching', { defaultValue: 'Searching…' })] })) : (t('console.commandPalette.noResults')) }), showRecentRecords && (_jsx(CommandGroup, { heading: t('console.commandPalette.recentRecords', { defaultValue: 'Recently viewed' }), children: recentRecords.map((item) => (_jsxs(CommandItem, { value: `recent ${item.label} ${item.id}`, onSelect: () => runCommand(() => navigate(item.href)), children: [_jsx(Search, { className: "mr-2 h-4 w-4" }), _jsx("span", { className: "truncate", children: item.label })] }, `recent:${item.id}`))) })), recordHits.length > 0 && (_jsx(CommandGroup, { heading: _jsxs("span", { className: "inline-flex items-center gap-2", children: [t('console.commandPalette.records', { defaultValue: 'Records' }), isSearching && (_jsx("span", { "aria-hidden": true, className: "inline-block h-1.5 w-1.5 rounded-full bg-primary motion-safe:animate-pulse" }))] }), children: recordHits.map((hit) => {
|
|
75
79
|
const Icon = getIcon(hit.icon);
|
|
76
80
|
return (_jsxs(CommandItem, {
|
|
77
81
|
// Embed the live query so cmdk's client-side filter doesn't
|
|
@@ -81,19 +85,19 @@ export function CommandPalette({ apps, activeApp, objects, onAppChange, dataSour
|
|
|
81
85
|
.filter(i => i.type === 'object')
|
|
82
86
|
.map(item => {
|
|
83
87
|
const Icon = getIcon(item.icon);
|
|
84
|
-
return (_jsxs(CommandItem, { value: `object ${resolveI18nLabel(item.label, t)} ${item.objectName}`, onSelect: () => runCommand(() => navigate(
|
|
88
|
+
return (_jsxs(CommandItem, { value: `object ${resolveI18nLabel(item.label, t)} ${item.objectName}`, onSelect: () => runCommand(() => navigate(resolveHref(item, baseUrl, templateContext).href)), children: [_jsx(Icon, { className: "mr-2 h-4 w-4" }), _jsx("span", { children: resolveI18nLabel(item.label, t) })] }, item.id));
|
|
85
89
|
}) })), navItems.filter(i => i.type === 'dashboard').length > 0 && (_jsx(CommandGroup, { heading: t('console.commandPalette.dashboards'), children: navItems
|
|
86
90
|
.filter(i => i.type === 'dashboard')
|
|
87
|
-
.map(item => (_jsxs(CommandItem, { value: `dashboard ${resolveI18nLabel(item.label, t)} ${item.dashboardName}`, onSelect: () => runCommand(() => navigate(
|
|
91
|
+
.map(item => (_jsxs(CommandItem, { value: `dashboard ${resolveI18nLabel(item.label, t)} ${item.dashboardName}`, onSelect: () => runCommand(() => navigate(resolveHref(item, baseUrl, templateContext).href)), children: [_jsx(LayoutDashboard, { className: "mr-2 h-4 w-4" }), _jsx("span", { children: resolveI18nLabel(item.label, t) })] }, item.id))) })), navItems.filter(i => i.type === 'page').length > 0 && (_jsx(CommandGroup, { heading: t('console.commandPalette.pages'), children: navItems
|
|
88
92
|
.filter(i => i.type === 'page')
|
|
89
|
-
.map(item => (_jsxs(CommandItem, { value: `page ${resolveI18nLabel(item.label, t)} ${item.pageName}`, onSelect: () => runCommand(() => navigate(
|
|
93
|
+
.map(item => (_jsxs(CommandItem, { value: `page ${resolveI18nLabel(item.label, t)} ${item.pageName}`, onSelect: () => runCommand(() => navigate(resolveHref(item, baseUrl, templateContext).href)), children: [_jsx(FileText, { className: "mr-2 h-4 w-4" }), _jsx("span", { children: resolveI18nLabel(item.label, t) })] }, item.id))) })), navItems.filter(i => i.type === 'report').length > 0 && (_jsx(CommandGroup, { heading: t('console.commandPalette.reports'), children: navItems
|
|
90
94
|
.filter(i => i.type === 'report')
|
|
91
|
-
.map(item => (_jsxs(CommandItem, { value: `report ${resolveI18nLabel(item.label, t)} ${item.reportName}`, onSelect: () => runCommand(() => navigate(
|
|
95
|
+
.map(item => (_jsxs(CommandItem, { value: `report ${resolveI18nLabel(item.label, t)} ${item.reportName}`, onSelect: () => runCommand(() => navigate(resolveHref(item, baseUrl, templateContext).href)), children: [_jsx(BarChart3, { className: "mr-2 h-4 w-4" }), _jsx("span", { children: resolveI18nLabel(item.label, t) })] }, item.id))) })), apps.filter(a => a.active !== false).length > 1 && (_jsxs(_Fragment, { children: [_jsx(CommandSeparator, {}), _jsx(CommandGroup, { heading: t('console.commandPalette.switchApp'), children: apps
|
|
92
96
|
.filter(a => a.active !== false)
|
|
93
97
|
.map(app => {
|
|
94
98
|
const Icon = getIcon(app.icon);
|
|
95
|
-
return (_jsxs(CommandItem, { value: `app ${resolveI18nLabel(app.label, t)} ${app.name}`, onSelect: () => runCommand(() => onAppChange(app.name)), children: [_jsx(Icon, { className: "mr-2 h-4 w-4" }), _jsx("span", { children: resolveI18nLabel(app.label, t) }), app.name === activeApp?.name && (_jsx("span", { className: "ml-auto text-xs text-muted-foreground", children: t('console.commandPalette.current') }))] }, app.name));
|
|
96
|
-
}) })] })), _jsx(CommandSeparator, {}), _jsxs(CommandGroup, { heading: t('console.commandPalette.preferences'), children: [_jsxs(CommandItem, { value: "theme light", onSelect: () => runCommand(() => setTheme('light')), children: [_jsx(Sun, { className: "mr-2 h-4 w-4" }), _jsx("span", { children: t('console.commandPalette.lightTheme') })] }), _jsxs(CommandItem, { value: "theme dark", onSelect: () => runCommand(() => setTheme('dark')), children: [_jsx(Moon, { className: "mr-2 h-4 w-4" }), _jsx("span", { children: t('console.commandPalette.darkTheme') })] }), _jsxs(CommandItem, { value: "theme system", onSelect: () => runCommand(() => setTheme('system')), children: [_jsx(Monitor, { className: "mr-2 h-4 w-4" }), _jsx("span", { children: t('console.commandPalette.systemTheme') })] })] }), _jsx(CommandSeparator, {}),
|
|
99
|
+
return (_jsxs(CommandItem, { value: `app ${resolveI18nLabel(app.label, t)} ${app.name}`, onSelect: () => runCommand(() => onAppChange(appRouteSegment(app) ?? app.name)), children: [_jsx(Icon, { className: "mr-2 h-4 w-4" }), _jsx("span", { children: resolveI18nLabel(app.label, t) }), app.name === activeApp?.name && (_jsx("span", { className: "ml-auto text-xs text-muted-foreground", children: t('console.commandPalette.current') }))] }, app.name));
|
|
100
|
+
}) })] })), _jsx(CommandSeparator, {}), _jsxs(CommandGroup, { heading: t('console.commandPalette.preferences'), children: [_jsxs(CommandItem, { value: "theme light", onSelect: () => runCommand(() => setTheme('light')), children: [_jsx(Sun, { className: "mr-2 h-4 w-4" }), _jsx("span", { children: t('console.commandPalette.lightTheme') })] }), _jsxs(CommandItem, { value: "theme dark", onSelect: () => runCommand(() => setTheme('dark')), children: [_jsx(Moon, { className: "mr-2 h-4 w-4" }), _jsx("span", { children: t('console.commandPalette.darkTheme') })] }), _jsxs(CommandItem, { value: "theme system", onSelect: () => runCommand(() => setTheme('system')), children: [_jsx(Monitor, { className: "mr-2 h-4 w-4" }), _jsx("span", { children: t('console.commandPalette.systemTheme') })] })] }), _jsx(CommandSeparator, {}), _jsx(CommandGroup, { heading: t('console.commandPalette.actions'), children: _jsxs(CommandItem, { value: "search all results full page", onSelect: () => runCommand(() => navigate(`${baseUrl}/search`)), children: [_jsx(Search, { className: "mr-2 h-4 w-4" }), _jsx("span", { children: t('console.commandPalette.openFullSearch') })] }) })] })] }));
|
|
97
101
|
}
|
|
98
102
|
/** Flatten nested navigation groups into a flat list of leaf items */
|
|
99
103
|
function flattenNavigation(items) {
|
|
@@ -19,5 +19,5 @@ interface ConditionalAuthWrapperProps {
|
|
|
19
19
|
* 3. On failure, shows the LoadingScreen in error mode with a Retry button
|
|
20
20
|
* (no silent fallback to "auth enabled" — the user is told the server is unreachable)
|
|
21
21
|
*/
|
|
22
|
-
export declare function ConditionalAuthWrapper({ children, authUrl }: ConditionalAuthWrapperProps): import("react
|
|
22
|
+
export declare function ConditionalAuthWrapper({ children, authUrl }: ConditionalAuthWrapperProps): import("react").JSX.Element;
|
|
23
23
|
export {};
|
|
@@ -7,5 +7,5 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { Toaster as Sonner } from 'sonner';
|
|
9
9
|
type ToasterProps = React.ComponentProps<typeof Sonner>;
|
|
10
|
-
export declare function ConsoleToaster(props: ToasterProps): import("react
|
|
10
|
+
export declare function ConsoleToaster(props: ToasterProps): import("react").JSX.Element;
|
|
11
11
|
export {};
|