@object-ui/app-shell 6.2.3 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1229 -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 +184 -39
- 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 +747 -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 +28 -0
- package/dist/console/ai/LiveCanvas.js +80 -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 +137 -4
- package/dist/hooks/useChatConversation.js +316 -25
- package/dist/hooks/useConsoleActionRuntime.d.ts +70 -0
- package/dist/hooks/useConsoleActionRuntime.js +564 -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 +18 -8
- package/dist/index.js +17 -5
- 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 +34 -2
- package/dist/layout/ConsoleFloatingChatbot.js +391 -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 +242 -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/layout/agentPicker.d.ts +56 -0
- package/dist/layout/agentPicker.js +40 -0
- 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/CommitTimeline.d.ts +15 -0
- package/dist/preview/CommitTimeline.js +82 -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 +83 -0
- package/dist/preview/commitHistory.d.ts +28 -0
- package/dist/preview/commitHistory.js +48 -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 +192 -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 +31 -0
- package/dist/views/FlowRunner.js +121 -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/ScreenView.d.ts +70 -0
- package/dist/views/ScreenView.js +73 -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 +101 -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 +39 -0
- package/dist/views/metadata-admin/JsonSourceEditor.js +196 -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 +403 -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 +1250 -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 +258 -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 +205 -0
- package/dist/views/metadata-admin/anchors.js +255 -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 +1252 -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 +221 -0
- package/dist/views/metadata-admin/inspectors/FlowEdgeInspector.d.ts +16 -0
- package/dist/views/metadata-admin/inspectors/FlowEdgeInspector.js +126 -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 +205 -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 +55 -0
- package/dist/views/metadata-admin/inspectors/ObjectFieldInspector.d.ts +23 -0
- package/dist/views/metadata-admin/inspectors/ObjectFieldInspector.js +365 -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 +218 -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 +128 -0
- package/dist/views/metadata-admin/inspectors/_shared.js +113 -0
- package/dist/views/metadata-admin/inspectors/datasetFilterCondition.d.ts +24 -0
- package/dist/views/metadata-admin/inspectors/datasetFilterCondition.js +97 -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 +506 -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/issuePath.d.ts +22 -0
- package/dist/views/metadata-admin/issuePath.js +65 -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/package-scope.d.ts +26 -0
- package/dist/views/metadata-admin/package-scope.js +43 -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 +105 -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 +49 -0
- package/dist/views/metadata-admin/previews/FlowCanvas.js +416 -0
- package/dist/views/metadata-admin/previews/FlowPreview.d.ts +20 -0
- package/dist/views/metadata-admin/previews/FlowPreview.js +120 -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 +204 -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 +200 -5
- 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/ScreenPreview.d.ts +38 -0
- package/dist/views/metadata-admin/previews/ScreenPreview.js +61 -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 +102 -0
- package/dist/views/metadata-admin/previews/flow-canvas-layout.js +227 -0
- package/dist/views/metadata-admin/previews/flow-canvas-parts.d.ts +96 -0
- package/dist/views/metadata-admin/previews/flow-canvas-parts.js +373 -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 +130 -0
- package/dist/views/metadata-admin/previews/object-fields-io.js +243 -0
- package/dist/views/metadata-admin/previews/screen-spec.d.ts +43 -0
- package/dist/views/metadata-admin/previews/screen-spec.js +108 -0
- package/dist/views/metadata-admin/previews/simulator/flow-sim-types.d.ts +102 -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 +15 -0
- package/dist/views/metadata-admin/previews/simulator/flow-sim-validate.js +185 -0
- package/dist/views/metadata-admin/previews/simulator/flow-simulator.d.ts +73 -0
- package/dist/views/metadata-admin/previews/simulator/flow-simulator.js +426 -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
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
3
|
+
/**
|
|
4
|
+
* DashboardConfigPanel — the runtime DashboardView's right-rail
|
|
5
|
+
* "dashboard editor".
|
|
6
|
+
*
|
|
7
|
+
* MIGRATED: this single panel replaces BOTH legacy `plugin-dashboard`
|
|
8
|
+
* panels (the dashboard-level `DashboardConfigPanel` and the per-widget
|
|
9
|
+
* `WidgetConfigPanel`). Instead of the `buildWidgetSchema` /
|
|
10
|
+
* `ConfigPanelRenderer` engine it hosts the studio's spec-driven
|
|
11
|
+
* inspectors so the runtime and the metadata studio share ONE
|
|
12
|
+
* dashboard-editing surface:
|
|
13
|
+
*
|
|
14
|
+
* - no widget selected → {@link DashboardDefaultInspector} (dashboard level)
|
|
15
|
+
* - widget selected → {@link DashboardWidgetInspector} (widget level)
|
|
16
|
+
*
|
|
17
|
+
* It lives in `app-shell` (next to the studio inspectors) rather than in
|
|
18
|
+
* `plugin-dashboard`: `app-shell` depends on `plugin-dashboard`, so hosting
|
|
19
|
+
* the inspectors here avoids the circular import a plugin-side panel would
|
|
20
|
+
* need.
|
|
21
|
+
*
|
|
22
|
+
* Unlike the legacy panel, this component is CONTROLLED: it holds no draft
|
|
23
|
+
* state of its own. Both inspectors edit the FULL nested dashboard `schema`
|
|
24
|
+
* (`{...,widgets:[{id,...}]}`) directly — the dashboard-level inspector via a
|
|
25
|
+
* shallow top-level `onPatch`, the widget inspector by addressing
|
|
26
|
+
* `schema.widgets` by `w.id`. Because the inspectors work on the spec-shaped
|
|
27
|
+
* draft, the runtime's old flatten / unflatten / extract adapters are gone.
|
|
28
|
+
*/
|
|
29
|
+
import { useCallback, useMemo, useState } from 'react';
|
|
30
|
+
import { Button } from '@object-ui/components';
|
|
31
|
+
import { useObjectTranslation } from '@object-ui/i18n';
|
|
32
|
+
import { ArrowLeft, Trash2, X } from 'lucide-react';
|
|
33
|
+
import { DashboardDefaultInspector } from './metadata-admin/inspectors/DashboardDefaultInspector';
|
|
34
|
+
import { DashboardWidgetInspector } from './metadata-admin/inspectors/DashboardWidgetInspector';
|
|
35
|
+
import { RuntimeDraftBar } from './RuntimeDraftBar';
|
|
36
|
+
import { detectLocale } from './metadata-admin/i18n';
|
|
37
|
+
export function DashboardConfigPanel({ open, onClose, schema, selectedWidgetId, onSelectWidget, onSave, onChange, onRemoveWidget, name: artifactName, metadataClient, onAfterChange, }) {
|
|
38
|
+
const { t } = useObjectTranslation();
|
|
39
|
+
const locale = useMemo(() => detectLocale(), []);
|
|
40
|
+
// Unsaved-edits flag — gates Publish (mirrors studio's "save first"). The
|
|
41
|
+
// panel unmounts on close, so this resets to false on each open.
|
|
42
|
+
const [dirty, setDirty] = useState(false);
|
|
43
|
+
// Bumped on save so the draft chrome surfaces the indicator immediately.
|
|
44
|
+
const [savedSignal, setSavedSignal] = useState(0);
|
|
45
|
+
// Controlled: merge an inspector patch into the current schema and bubble it
|
|
46
|
+
// back up. No local draft state — `schema` is the single source of truth.
|
|
47
|
+
const handlePatch = useCallback((patch) => {
|
|
48
|
+
setDirty(true);
|
|
49
|
+
onChange({ ...(schema ?? {}), ...patch });
|
|
50
|
+
}, [schema, onChange]);
|
|
51
|
+
// ADR-0034 (#1515): resume a pending draft into the editor on open
|
|
52
|
+
// (flag-ON only). The dashboard document IS the controlled schema, so push
|
|
53
|
+
// it up as a live edit (preview only — no save) and treat it as the clean
|
|
54
|
+
// baseline.
|
|
55
|
+
const handleResumeDraft = useCallback((body) => {
|
|
56
|
+
onChange(body);
|
|
57
|
+
setDirty(false);
|
|
58
|
+
}, [onChange]);
|
|
59
|
+
const handleSelectionChange = useCallback((sel) => {
|
|
60
|
+
onSelectWidget(sel && sel.kind === 'widget' ? sel.id : null);
|
|
61
|
+
}, [onSelectWidget]);
|
|
62
|
+
const widgets = Array.isArray(schema?.widgets) ? schema.widgets : [];
|
|
63
|
+
const selectedWidget = selectedWidgetId
|
|
64
|
+
? widgets.find((w) => w?.id === selectedWidgetId)
|
|
65
|
+
: null;
|
|
66
|
+
if (!open)
|
|
67
|
+
return null;
|
|
68
|
+
const name = typeof schema?.name === 'string' ? schema.name : '';
|
|
69
|
+
const title = selectedWidget
|
|
70
|
+
? t('widget.editor.title', { defaultValue: 'Edit widget' })
|
|
71
|
+
: t('dashboard.editor.title', { defaultValue: 'Edit dashboard' });
|
|
72
|
+
return (_jsxs("aside", { className: "hidden sm:flex w-[440px] shrink-0 flex-col border-l bg-background h-full", "data-testid": "dashboard-config-panel", role: "complementary", "aria-label": title, children: [_jsxs("div", { className: "flex items-center justify-between gap-2 border-b px-4 py-2.5 shrink-0", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-1.5", children: [selectedWidget && (_jsx(Button, { variant: "ghost", size: "sm", onClick: () => onSelectWidget(null), className: "h-7 w-7 p-0", "aria-label": t('dashboard.editor.backToDashboard', {
|
|
73
|
+
defaultValue: 'Back to dashboard',
|
|
74
|
+
}), title: t('dashboard.editor.backToDashboard', {
|
|
75
|
+
defaultValue: 'Back to dashboard',
|
|
76
|
+
}), "data-testid": "dashboard-config-back", children: _jsx(ArrowLeft, { className: "h-4 w-4" }) })), _jsx("div", { className: "text-sm font-medium truncate", children: title })] }), _jsxs("div", { className: "flex items-center gap-1 shrink-0", children: [selectedWidget && onRemoveWidget && (_jsx(Button, { variant: "ghost", size: "sm", onClick: () => onRemoveWidget(selectedWidgetId), className: "h-7 w-7 p-0 text-destructive hover:text-destructive", "aria-label": t('widget.editor.delete', { defaultValue: 'Delete widget' }), title: t('widget.editor.delete', { defaultValue: 'Delete widget' }), "data-testid": "widget-delete-button", children: _jsx(Trash2, { className: "h-3.5 w-3.5" }) })), _jsx(Button, { variant: "ghost", size: "sm", onClick: onClose, className: "h-7 w-7 p-0", "aria-label": t('common.close', { defaultValue: 'Close' }), "data-testid": "dashboard-config-close", children: _jsx(X, { className: "h-4 w-4" }) })] })] }), _jsx("div", { className: "min-h-0 flex-1 overflow-auto p-4", children: selectedWidget ? (_jsx(DashboardWidgetInspector, { type: "dashboard", name: name, draft: schema ?? {}, selection: { kind: 'widget', id: selectedWidgetId }, onPatch: handlePatch, onClearSelection: () => onSelectWidget(null), onSelectionChange: handleSelectionChange, readOnly: false, locale: locale })) : (_jsx(DashboardDefaultInspector, { type: "dashboard", name: name, draft: schema ?? {}, onPatch: handlePatch, onSelectionChange: handleSelectionChange, readOnly: false, locale: locale })) }), _jsxs("div", { "data-testid": "dashboard-config-footer", className: "flex items-center justify-end gap-2 border-t px-4 py-2.5 shrink-0", children: [_jsx(RuntimeDraftBar, { type: "dashboard", name: artifactName || name || undefined, metadataClient: metadataClient, dirty: dirty, onResume: handleResumeDraft, savedSignal: savedSignal, onAfterChange: onAfterChange }), _jsx(Button, { size: "sm", onClick: () => {
|
|
77
|
+
onSave((schema ?? {}));
|
|
78
|
+
setDirty(false);
|
|
79
|
+
setSavedSignal((s) => s + 1);
|
|
80
|
+
}, "data-testid": "dashboard-config-save", children: t('common.save', { defaultValue: 'Save' }) })] })] }));
|
|
81
|
+
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Dashboard View Component
|
|
3
3
|
* Renders a dashboard based on the dashboardName parameter.
|
|
4
|
-
* Edit mode shows
|
|
5
|
-
*
|
|
4
|
+
* Edit mode shows a single inline config panel (DashboardConfigPanel) on the
|
|
5
|
+
* right side that hosts the studio's dashboard / widget inspectors, following
|
|
6
|
+
* the same pattern as ReportView.
|
|
6
7
|
*/
|
|
7
8
|
export declare function DashboardView({ dataSource }: {
|
|
8
9
|
dataSource?: any;
|
|
9
|
-
}): import("react
|
|
10
|
+
}): import("react").JSX.Element;
|
|
@@ -2,21 +2,29 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
/**
|
|
3
3
|
* Dashboard View Component
|
|
4
4
|
* Renders a dashboard based on the dashboardName parameter.
|
|
5
|
-
* Edit mode shows
|
|
6
|
-
*
|
|
5
|
+
* Edit mode shows a single inline config panel (DashboardConfigPanel) on the
|
|
6
|
+
* right side that hosts the studio's dashboard / widget inspectors, following
|
|
7
|
+
* the same pattern as ReportView.
|
|
7
8
|
*/
|
|
8
9
|
import { useState, useEffect, useCallback, useMemo } from 'react';
|
|
9
10
|
import { useParams } from 'react-router-dom';
|
|
10
|
-
import { DashboardRenderer
|
|
11
|
+
import { DashboardRenderer } from '@object-ui/plugin-dashboard';
|
|
12
|
+
import { DrillNavigationProvider } from '@object-ui/react';
|
|
13
|
+
import { useOpenRecordList } from './useOpenRecordList';
|
|
11
14
|
import { ModalForm } from '@object-ui/plugin-form';
|
|
15
|
+
import { DashboardConfigPanel } from './DashboardConfigPanel';
|
|
16
|
+
import { useAuth } from '@object-ui/auth';
|
|
12
17
|
import { toast } from 'sonner';
|
|
13
18
|
import { Empty, EmptyTitle, EmptyDescription, Button, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, } from '@object-ui/components';
|
|
14
|
-
import { LayoutDashboard, Pencil, TrendingUp, BarChart3, LineChart, PieChart, Table2, LayoutGrid, Plus,
|
|
19
|
+
import { LayoutDashboard, Pencil, TrendingUp, BarChart3, LineChart, PieChart, Table2, LayoutGrid, Plus, } from 'lucide-react';
|
|
15
20
|
import { MetadataPanel, useMetadataInspector } from './MetadataInspector';
|
|
16
21
|
import { SkeletonDashboard } from '../skeletons';
|
|
17
22
|
import { useMetadata } from '../providers/MetadataProvider';
|
|
18
|
-
import {
|
|
23
|
+
import { useExpressionContext } from '../providers/ExpressionProvider';
|
|
24
|
+
import { resolveI18nLabel, preferLocal } from '../utils';
|
|
19
25
|
import { useAdapter } from '../providers/AdapterProvider';
|
|
26
|
+
import { useMetadataClient } from './metadata-admin/useMetadata';
|
|
27
|
+
import { persistRuntimeMetadata } from './runtime-metadata-persistence';
|
|
20
28
|
import { useObjectTranslation, useObjectLabel } from '@object-ui/i18n';
|
|
21
29
|
// ---------------------------------------------------------------------------
|
|
22
30
|
// Widget type palette for the add-widget toolbar
|
|
@@ -55,127 +63,25 @@ function defaultWidgetTitle(type) {
|
|
|
55
63
|
return entry ? `New ${entry.label}` : 'New Widget';
|
|
56
64
|
}
|
|
57
65
|
// ---------------------------------------------------------------------------
|
|
58
|
-
// Helpers: flatten / unflatten widget config for WidgetConfigPanel
|
|
59
|
-
// ---------------------------------------------------------------------------
|
|
60
|
-
// Top-level widget schema keys that the config panel exposes as flat fields.
|
|
61
|
-
// Anything outside this set (e.g. pivot rowField/columnField, table searchable,
|
|
62
|
-
// chart xAxisField/yAxisFields, list itemTemplate, custom component) is stored
|
|
63
|
-
// under `widget.options` per the spec and round-tripped via spread.
|
|
64
|
-
const TOP_LEVEL_WIDGET_KEYS = new Set([
|
|
65
|
-
'title',
|
|
66
|
-
'description',
|
|
67
|
-
'type',
|
|
68
|
-
'object',
|
|
69
|
-
'categoryField',
|
|
70
|
-
'valueField',
|
|
71
|
-
'aggregate',
|
|
72
|
-
'colorVariant',
|
|
73
|
-
'actionUrl',
|
|
74
|
-
'layoutW',
|
|
75
|
-
'layoutH',
|
|
76
|
-
'id',
|
|
77
|
-
// Spec-declared top-level fields that the renderer reads directly off the
|
|
78
|
-
// widget (not from options). Keeping them here ensures the unflatten path
|
|
79
|
-
// does not silently drop them into options where the renderer ignores them.
|
|
80
|
-
'searchable',
|
|
81
|
-
'pagination',
|
|
82
|
-
// Drill-down virtual flat keys are handled explicitly below — listing them
|
|
83
|
-
// here keeps the generic options-collector from duplicating them.
|
|
84
|
-
'drillDownEnabled',
|
|
85
|
-
'drillDownTarget',
|
|
86
|
-
]);
|
|
87
|
-
function flattenWidgetConfig(widget) {
|
|
88
|
-
// Spread options first so explicit top-level widget fields take precedence
|
|
89
|
-
// on collision. This surfaces type-specific options (pivot/table/chart axes,
|
|
90
|
-
// list itemTemplate, etc.) so they appear pre-filled in the config panel.
|
|
91
|
-
const options = (widget.options ?? {});
|
|
92
|
-
const drillDown = (options.drillDown ?? {});
|
|
93
|
-
return {
|
|
94
|
-
...options,
|
|
95
|
-
title: widget.title ?? '',
|
|
96
|
-
description: widget.description ?? '',
|
|
97
|
-
type: widget.type ?? 'metric',
|
|
98
|
-
object: widget.object ?? '',
|
|
99
|
-
categoryField: widget.categoryField ?? options.categoryField ?? '',
|
|
100
|
-
valueField: widget.valueField ?? options.valueField ?? '',
|
|
101
|
-
aggregate: widget.aggregate ?? options.aggregate ?? 'count',
|
|
102
|
-
layoutW: widget.layout?.w ?? 1,
|
|
103
|
-
layoutH: widget.layout?.h ?? 1,
|
|
104
|
-
colorVariant: widget.colorVariant ?? options.colorVariant ?? 'default',
|
|
105
|
-
actionUrl: widget.actionUrl ?? options.actionUrl ?? '',
|
|
106
|
-
searchable: widget.searchable ?? options.searchable ?? false,
|
|
107
|
-
pagination: widget.pagination ?? options.pagination ?? false,
|
|
108
|
-
// Surface drill-down nested shape as flat switches for the panel
|
|
109
|
-
drillDownEnabled: drillDown.enabled ?? false,
|
|
110
|
-
drillDownTarget: drillDown.target ?? 'drawer',
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
function unflattenWidgetConfig(config, base) {
|
|
114
|
-
// Collect any unknown keys (pivot/table/chart-specific) into options so the
|
|
115
|
-
// serialized widget keeps the spec-compliant nested shape.
|
|
116
|
-
const baseOptions = (base.options ?? {});
|
|
117
|
-
const newOptions = { ...baseOptions };
|
|
118
|
-
for (const [key, value] of Object.entries(config)) {
|
|
119
|
-
if (TOP_LEVEL_WIDGET_KEYS.has(key))
|
|
120
|
-
continue;
|
|
121
|
-
if (value === undefined)
|
|
122
|
-
continue;
|
|
123
|
-
newOptions[key] = value;
|
|
124
|
-
}
|
|
125
|
-
// Re-nest drill-down flat keys back under options.drillDown so the renderer
|
|
126
|
-
// (which reads `options.drillDown`) picks them up.
|
|
127
|
-
const drillDownEnabled = config.drillDownEnabled;
|
|
128
|
-
const drillDownTarget = config.drillDownTarget;
|
|
129
|
-
if (drillDownEnabled !== undefined || drillDownTarget !== undefined) {
|
|
130
|
-
newOptions.drillDown = {
|
|
131
|
-
...(baseOptions.drillDown || {}),
|
|
132
|
-
...(drillDownEnabled !== undefined ? { enabled: !!drillDownEnabled } : {}),
|
|
133
|
-
...(drillDownTarget !== undefined ? { target: drillDownTarget } : {}),
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
return {
|
|
137
|
-
title: config.title,
|
|
138
|
-
description: config.description,
|
|
139
|
-
type: config.type,
|
|
140
|
-
object: config.object,
|
|
141
|
-
categoryField: config.categoryField,
|
|
142
|
-
valueField: config.valueField,
|
|
143
|
-
aggregate: config.aggregate,
|
|
144
|
-
layout: { ...(base.layout || {}), w: config.layoutW, h: config.layoutH },
|
|
145
|
-
colorVariant: config.colorVariant,
|
|
146
|
-
actionUrl: config.actionUrl,
|
|
147
|
-
...(config.searchable !== undefined ? { searchable: !!config.searchable } : {}),
|
|
148
|
-
...(config.pagination !== undefined ? { pagination: !!config.pagination } : {}),
|
|
149
|
-
...(Object.keys(newOptions).length > 0 ? { options: newOptions } : {}),
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
function extractDashboardConfig(schema) {
|
|
153
|
-
const s = (schema ?? {});
|
|
154
|
-
return {
|
|
155
|
-
columns: s.columns ?? 3,
|
|
156
|
-
gap: s.gap ?? 4,
|
|
157
|
-
rowHeight: String(s.rowHeight ?? '120'),
|
|
158
|
-
refreshInterval: String(s.refreshInterval ?? '0'),
|
|
159
|
-
title: s.title ?? '',
|
|
160
|
-
description: s.description ?? '',
|
|
161
|
-
showDescription: s.showDescription ?? true,
|
|
162
|
-
theme: s.theme ?? 'auto',
|
|
163
|
-
};
|
|
164
|
-
}
|
|
165
|
-
// ---------------------------------------------------------------------------
|
|
166
66
|
// Component
|
|
167
67
|
// ---------------------------------------------------------------------------
|
|
168
68
|
export function DashboardView({ dataSource }) {
|
|
69
|
+
// Drill "escape hatch": lets the drill drawers open an object's full list page.
|
|
70
|
+
const openRecordList = useOpenRecordList();
|
|
169
71
|
const { dashboardName } = useParams();
|
|
170
72
|
const { showDebug } = useMetadataInspector();
|
|
171
73
|
const adapter = useAdapter();
|
|
74
|
+
// ADR-0034: dashboard edits persist via the metadata draft/publish model.
|
|
75
|
+
const metadataClient = useMetadataClient();
|
|
172
76
|
const { t } = useObjectTranslation();
|
|
173
77
|
const { dashboardLabel, dashboardDescription } = useObjectLabel();
|
|
78
|
+
// Editing a dashboard mutates the SHARED definition, so it is an admin-only
|
|
79
|
+
// quick-edit affordance (mirrors ObjectView's view-config gate).
|
|
80
|
+
const { user } = useAuth();
|
|
81
|
+
const isAdmin = user?.role === 'admin';
|
|
174
82
|
const [isLoading, setIsLoading] = useState(true);
|
|
175
83
|
const [configPanelOpen, setConfigPanelOpen] = useState(false);
|
|
176
84
|
const [selectedWidgetId, setSelectedWidgetId] = useState(null);
|
|
177
|
-
// Version counter — incremented on save to refresh the stable config reference
|
|
178
|
-
const [configVersion, setConfigVersion] = useState(0);
|
|
179
85
|
// Modal state for header action buttons that request a modal (e.g. New Opportunity)
|
|
180
86
|
const [modalState, setModalState] = useState(null);
|
|
181
87
|
const closeModal = useCallback((result) => {
|
|
@@ -235,7 +141,9 @@ export function DashboardView({ dataSource }) {
|
|
|
235
141
|
queueMicrotask(() => setIsLoading(false));
|
|
236
142
|
}, [dashboardName]);
|
|
237
143
|
const { dashboards, objects: metadataObjects, refresh } = useMetadata();
|
|
238
|
-
|
|
144
|
+
// ADR-0048 Phase 2 — prefer the dashboard owned by the current app's package.
|
|
145
|
+
const { app: activeApp } = useExpressionContext();
|
|
146
|
+
const dashboard = preferLocal(dashboards, dashboardName, activeApp?._packageId);
|
|
239
147
|
// Local schema state for live preview — initialized from metadata
|
|
240
148
|
const [editSchema, setEditSchema] = useState(null);
|
|
241
149
|
// When metadata refreshes (dashboard reference changes), discard stale
|
|
@@ -249,12 +157,12 @@ export function DashboardView({ dataSource }) {
|
|
|
249
157
|
// ---- Save helper --------------------------------------------------------
|
|
250
158
|
const saveSchema = useCallback(async (schema) => {
|
|
251
159
|
try {
|
|
252
|
-
if (
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
160
|
+
if (metadataClient) {
|
|
161
|
+
// ADR-0034: save stages a per-item draft; an explicit Publish
|
|
162
|
+
// promotes it (RuntimeDraftBar). `sys_dashboard` is retired.
|
|
163
|
+
await persistRuntimeMetadata('dashboard', dashboardName, schema, {
|
|
164
|
+
metadataClient,
|
|
165
|
+
});
|
|
258
166
|
}
|
|
259
167
|
// Refresh metadata cache so closing the config panel shows saved data
|
|
260
168
|
refresh().catch(() => { });
|
|
@@ -267,12 +175,11 @@ export function DashboardView({ dataSource }) {
|
|
|
267
175
|
console.warn('[DashboardView] Auto-save failed:', err);
|
|
268
176
|
toast.error(`Failed to save dashboard: ${message}`);
|
|
269
177
|
}
|
|
270
|
-
}, [
|
|
178
|
+
}, [metadataClient, dashboardName, refresh]);
|
|
271
179
|
// ---- Open / close config panel ------------------------------------------
|
|
272
180
|
const handleOpenConfigPanel = useCallback(() => {
|
|
273
181
|
setEditSchema(ensureWidgetIds(dashboard));
|
|
274
182
|
setConfigPanelOpen(true);
|
|
275
|
-
setConfigVersion((v) => v + 1);
|
|
276
183
|
}, [dashboard]);
|
|
277
184
|
const handleCloseConfigPanel = useCallback(() => {
|
|
278
185
|
setConfigPanelOpen(false);
|
|
@@ -298,7 +205,6 @@ export function DashboardView({ dataSource }) {
|
|
|
298
205
|
setEditSchema(newSchema);
|
|
299
206
|
saveSchema(newSchema);
|
|
300
207
|
setSelectedWidgetId(id);
|
|
301
|
-
setConfigVersion((v) => v + 1);
|
|
302
208
|
}, [editSchema, saveSchema]);
|
|
303
209
|
const removeWidget = useCallback((widgetId) => {
|
|
304
210
|
if (!editSchema)
|
|
@@ -325,119 +231,12 @@ export function DashboardView({ dataSource }) {
|
|
|
325
231
|
setEditSchema(newSchema);
|
|
326
232
|
saveSchema(newSchema);
|
|
327
233
|
}, [editSchema, dashboard, saveSchema]);
|
|
328
|
-
// ----
|
|
329
|
-
//
|
|
330
|
-
//
|
|
331
|
-
//
|
|
332
|
-
//
|
|
333
|
-
const
|
|
334
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
335
|
-
[configVersion]);
|
|
336
|
-
const handleDashboardConfigSave = useCallback((config) => {
|
|
337
|
-
if (!editSchema)
|
|
338
|
-
return;
|
|
339
|
-
const toNum = (v, fallback) => {
|
|
340
|
-
const n = Number(v);
|
|
341
|
-
return Number.isFinite(n) ? n : fallback;
|
|
342
|
-
};
|
|
343
|
-
const newSchema = {
|
|
344
|
-
...editSchema,
|
|
345
|
-
columns: toNum(config.columns, editSchema.columns),
|
|
346
|
-
gap: toNum(config.gap, editSchema.gap),
|
|
347
|
-
rowHeight: toNum(config.rowHeight, editSchema.rowHeight),
|
|
348
|
-
refreshInterval: toNum(config.refreshInterval, 0) ?? 0,
|
|
349
|
-
title: config.title,
|
|
350
|
-
description: config.description,
|
|
351
|
-
showDescription: config.showDescription,
|
|
352
|
-
theme: config.theme,
|
|
353
|
-
};
|
|
354
|
-
setEditSchema(newSchema);
|
|
355
|
-
saveSchema(newSchema);
|
|
356
|
-
setConfigVersion((v) => v + 1);
|
|
357
|
-
}, [editSchema, saveSchema]);
|
|
358
|
-
const handleDashboardFieldChange = useCallback((field, value) => {
|
|
359
|
-
if (!editSchema)
|
|
360
|
-
return;
|
|
361
|
-
// Map config field keys to proper DashboardSchema updates for live preview.
|
|
362
|
-
// Coerce numeric layout fields so previews/save payloads stay typed.
|
|
363
|
-
setEditSchema((prev) => {
|
|
364
|
-
if (!prev)
|
|
365
|
-
return prev;
|
|
366
|
-
const numericFields = new Set(['columns', 'gap', 'rowHeight', 'refreshInterval']);
|
|
367
|
-
if (numericFields.has(field)) {
|
|
368
|
-
const n = Number(value);
|
|
369
|
-
return { ...prev, [field]: Number.isFinite(n) ? n : prev[field] };
|
|
370
|
-
}
|
|
371
|
-
return { ...prev, [field]: value };
|
|
372
|
-
});
|
|
373
|
-
}, [editSchema]);
|
|
374
|
-
// ---- Widget config panel handlers ---------------------------------------
|
|
375
|
-
const selectedWidget = editSchema?.widgets?.find((w) => w.id === selectedWidgetId);
|
|
376
|
-
// Stabilize widget config: only recompute after explicit actions (widget
|
|
377
|
-
// switch, save, add). configVersion is incremented on save/add, and
|
|
378
|
-
// selectedWidgetId changes on widget switch — this prevents useConfigDraft
|
|
379
|
-
// from resetting the draft on every live field change.
|
|
380
|
-
const widgetConfig = useMemo(() => (selectedWidget ? flattenWidgetConfig(selectedWidget) : {}),
|
|
381
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
382
|
-
[selectedWidgetId, configVersion]);
|
|
383
|
-
const handleWidgetConfigSave = useCallback((config) => {
|
|
384
|
-
if (!editSchema || !selectedWidgetId || !selectedWidget)
|
|
385
|
-
return;
|
|
386
|
-
const updates = unflattenWidgetConfig(config, selectedWidget);
|
|
387
|
-
const newSchema = {
|
|
388
|
-
...editSchema,
|
|
389
|
-
widgets: editSchema.widgets.map((w) => w.id === selectedWidgetId ? { ...w, ...updates } : w),
|
|
390
|
-
};
|
|
391
|
-
setEditSchema(newSchema);
|
|
392
|
-
saveSchema(newSchema);
|
|
393
|
-
setConfigVersion((v) => v + 1);
|
|
394
|
-
}, [editSchema, selectedWidgetId, selectedWidget, saveSchema]);
|
|
395
|
-
const handleWidgetFieldChange = useCallback((field, value) => {
|
|
396
|
-
if (!selectedWidgetId)
|
|
397
|
-
return;
|
|
398
|
-
setEditSchema((prev) => {
|
|
399
|
-
if (!prev)
|
|
400
|
-
return prev;
|
|
401
|
-
const widget = prev.widgets?.find((w) => w.id === selectedWidgetId);
|
|
402
|
-
if (!widget)
|
|
403
|
-
return prev;
|
|
404
|
-
const flat = flattenWidgetConfig(widget);
|
|
405
|
-
flat[field] = value;
|
|
406
|
-
const updates = unflattenWidgetConfig(flat, widget);
|
|
407
|
-
return {
|
|
408
|
-
...prev,
|
|
409
|
-
widgets: prev.widgets.map((w) => w.id === selectedWidgetId ? { ...w, ...updates } : w),
|
|
410
|
-
};
|
|
411
|
-
});
|
|
412
|
-
}, [selectedWidgetId]);
|
|
413
|
-
// ---- Metadata-driven dropdown options -----------------------------------
|
|
414
|
-
const availableObjects = useMemo(() => {
|
|
415
|
-
if (!metadataObjects?.length)
|
|
416
|
-
return undefined;
|
|
417
|
-
return metadataObjects.map((obj) => ({
|
|
418
|
-
value: obj.name,
|
|
419
|
-
label: obj.label || obj.name,
|
|
420
|
-
}));
|
|
421
|
-
}, [metadataObjects]);
|
|
422
|
-
const availableFields = useMemo(() => {
|
|
423
|
-
const objectName = selectedWidget?.object;
|
|
424
|
-
if (!objectName || !metadataObjects?.length)
|
|
425
|
-
return undefined;
|
|
426
|
-
const obj = metadataObjects.find((o) => o.name === objectName);
|
|
427
|
-
if (!obj?.fields)
|
|
428
|
-
return undefined;
|
|
429
|
-
const fields = obj.fields;
|
|
430
|
-
if (Array.isArray(fields)) {
|
|
431
|
-
return fields
|
|
432
|
-
.filter((f) => f.name)
|
|
433
|
-
.map((f) => ({ value: f.name, label: f.label || f.name }));
|
|
434
|
-
}
|
|
435
|
-
// fields can be Record<string, FieldMetadata>
|
|
436
|
-
return Object.entries(fields).map(([key, f]) => ({
|
|
437
|
-
value: key,
|
|
438
|
-
label: f.label || key,
|
|
439
|
-
}));
|
|
440
|
-
}, [selectedWidget?.object, metadataObjects]);
|
|
234
|
+
// ---- Live-edit schema for the config panel ------------------------------
|
|
235
|
+
// The single controlled config panel hosts the studio inspectors, which edit
|
|
236
|
+
// the FULL nested dashboard draft directly (dashboard-level via shallow patch,
|
|
237
|
+
// widget-level by addressing `widgets` by id). No flatten / unflatten / config
|
|
238
|
+
// extraction is required anymore.
|
|
239
|
+
const panelSchema = (editSchema || dashboard) ?? null;
|
|
441
240
|
// ---- Runtime capability gate (must run before guards to respect Rules of Hooks)
|
|
442
241
|
// Hide widgets whose `requiresObject` is not registered (mirrors
|
|
443
242
|
// NavigationItem.requiresObject for nav entries). Defaults to widget.object
|
|
@@ -495,7 +294,7 @@ export function DashboardView({ dataSource }) {
|
|
|
495
294
|
description: resolveI18nLabel(rawDesc, t),
|
|
496
295
|
});
|
|
497
296
|
return desc ? (_jsx("p", { className: "text-sm text-muted-foreground mt-1 line-clamp-2", children: desc })) : null;
|
|
498
|
-
})()] }), _jsxs("div", { className: "shrink-0 flex items-center gap-1.5", children: [configPanelOpen && (_jsx("div", { className: "flex items-center gap-1 mr-2", role: "toolbar", "aria-label": "Add widgets", "data-testid": "dashboard-widget-toolbar", children: WIDGET_TYPES.map(({ type, label, Icon }) => (_jsxs("button", { type: "button", "data-testid": `dashboard-add-${type}`, onClick: () => addWidget(type), className: "inline-flex items-center gap-1 rounded-md border border-input bg-background px-2 py-1.5 text-[11px] font-medium text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", title: `Add ${label}`, "aria-label": `Add ${label} widget`, children: [_jsx(Plus, { className: "h-3 w-3" }), _jsx(Icon, { className: "h-3 w-3" })] }, type))) })), _jsxs("button", { type: "button", onClick: handleOpenConfigPanel, className: "inline-flex items-center gap-1.5 rounded-md border border-input bg-background px-2.5 py-1.5 text-xs font-medium text-muted-foreground shadow-sm hover:bg-accent hover:text-accent-foreground", "data-testid": "dashboard-edit-button", children: [_jsx(Pencil, { className: "h-3.5 w-3.5" }), t('common.edit', { defaultValue: 'Edit' })] })] })] }), _jsxs("div", { className: "flex-1 overflow-hidden flex flex-col sm:flex-row relative", children: [_jsx("div", { className: "flex-1 min-w-0 overflow-auto p-2 sm:p-4 md:p-6", children: _jsx(DashboardRenderer, { schema: previewSchema, dataSource: dataSource, designMode: configPanelOpen, selectedWidgetId: selectedWidgetId, onWidgetClick: setSelectedWidgetId, onWidgetsReorder: handleWidgetsReorder, modalHandler: modalHandler, scriptHandlers: scriptHandlers, hideHeaderText: true }) }),
|
|
297
|
+
})()] }), _jsxs("div", { className: "shrink-0 flex items-center gap-1.5", children: [configPanelOpen && (_jsx("div", { className: "flex items-center gap-1 mr-2", role: "toolbar", "aria-label": "Add widgets", "data-testid": "dashboard-widget-toolbar", children: WIDGET_TYPES.map(({ type, label, Icon }) => (_jsxs("button", { type: "button", "data-testid": `dashboard-add-${type}`, onClick: () => addWidget(type), className: "inline-flex items-center gap-1 rounded-md border border-input bg-background px-2 py-1.5 text-[11px] font-medium text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", title: `Add ${label}`, "aria-label": `Add ${label} widget`, children: [_jsx(Plus, { className: "h-3 w-3" }), _jsx(Icon, { className: "h-3 w-3" })] }, type))) })), isAdmin && (_jsxs("button", { type: "button", onClick: handleOpenConfigPanel, className: "inline-flex items-center gap-1.5 rounded-md border border-input bg-background px-2.5 py-1.5 text-xs font-medium text-muted-foreground shadow-sm hover:bg-accent hover:text-accent-foreground", "data-testid": "dashboard-edit-button", children: [_jsx(Pencil, { className: "h-3.5 w-3.5" }), t('common.edit', { defaultValue: 'Edit' })] }))] })] }), _jsxs("div", { className: "flex-1 overflow-hidden flex flex-col sm:flex-row relative", children: [_jsx("div", { className: "flex-1 min-w-0 overflow-auto p-2 sm:p-4 md:p-6", children: _jsx(DrillNavigationProvider, { value: { openRecordList }, children: _jsx(DashboardRenderer, { schema: previewSchema, dataSource: dataSource, designMode: configPanelOpen, selectedWidgetId: selectedWidgetId, onWidgetClick: setSelectedWidgetId, onWidgetsReorder: handleWidgetsReorder, modalHandler: modalHandler, scriptHandlers: scriptHandlers, hideHeaderText: true }) }) }), _jsx(DashboardConfigPanel, { open: configPanelOpen && isAdmin, onClose: handleCloseConfigPanel, schema: panelSchema, selectedWidgetId: selectedWidgetId, onSelectWidget: setSelectedWidgetId, onSave: saveSchema, onChange: setEditSchema, onRemoveWidget: removeWidget, name: dashboardName, metadataClient: metadataClient, onAfterChange: () => refresh().catch(() => { }) }), _jsx(MetadataPanel, { open: showDebug, sections: [{ title: 'Dashboard Configuration', data: previewSchema }] })] }), modalState && modalState.schema?.objectName ? (_jsx(ModalForm, { schema: {
|
|
499
298
|
type: 'object-form',
|
|
500
299
|
formType: 'modal',
|
|
501
300
|
objectName: modalState.schema.objectName,
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type ScreenSpec } from './ScreenView';
|
|
2
|
+
export type { ScreenSpec, ScreenFieldSpec } from './ScreenView';
|
|
3
|
+
export interface ScreenFlowState {
|
|
4
|
+
flowName: string;
|
|
5
|
+
runId: string;
|
|
6
|
+
screen: ScreenSpec;
|
|
7
|
+
}
|
|
8
|
+
export interface FlowRunnerProps {
|
|
9
|
+
/** The paused screen-flow to drive, or `null` when closed. */
|
|
10
|
+
state: ScreenFlowState | null;
|
|
11
|
+
/** Authenticated fetch (shared with the host view). */
|
|
12
|
+
authFetch: (url: string, init?: RequestInit) => Promise<Response>;
|
|
13
|
+
/** API base (e.g. `import.meta.env.VITE_SERVER_URL || ''`). */
|
|
14
|
+
baseUrl: string;
|
|
15
|
+
/** User dismissed the runner without completing. */
|
|
16
|
+
onClose: () => void;
|
|
17
|
+
/** The flow ran to completion — host should refresh. */
|
|
18
|
+
onComplete: () => void;
|
|
19
|
+
/**
|
|
20
|
+
* Data source — required to render `object-form` wizard steps. ObjectForm
|
|
21
|
+
* fetches the object schema and persists (incl. atomic master-detail batch)
|
|
22
|
+
* through this adapter.
|
|
23
|
+
*/
|
|
24
|
+
dataSource?: any;
|
|
25
|
+
/**
|
|
26
|
+
* Object definitions — used to derive an `object-form` step's inline
|
|
27
|
+
* master-detail `subforms` (mirrors RecordFormPage's create form).
|
|
28
|
+
*/
|
|
29
|
+
objects?: any[];
|
|
30
|
+
}
|
|
31
|
+
export declare function FlowRunner({ state, authFetch, baseUrl, onClose, onComplete, dataSource, objects }: FlowRunnerProps): import("react").JSX.Element | null;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* FlowRunner — renders the interactive `screen` of a paused screen-flow run
|
|
4
|
+
* (framework screen-flow runtime, ADR-0019) and resumes it with the collected
|
|
5
|
+
* input.
|
|
6
|
+
*
|
|
7
|
+
* A `type: 'flow'` action launches a flow; when the run pauses at a `screen`
|
|
8
|
+
* node the launch response carries `{ status: 'paused', runId, screen }`. The
|
|
9
|
+
* host view (ObjectView / RecordDetailView) opens this modal with that state.
|
|
10
|
+
* On submit it POSTs `/api/v1/automation/{flow}/runs/{runId}/resume` with the
|
|
11
|
+
* field values as `inputs`; a `paused` response renders the next screen
|
|
12
|
+
* (multi-screen wizards), a terminal response closes and refreshes the view.
|
|
13
|
+
*
|
|
14
|
+
* The screen BODY (flat fields / object-form) is rendered by the shared
|
|
15
|
+
* {@link ScreenView} — the same renderer the Studio design preview reuses, so
|
|
16
|
+
* the two can never drift (cf. #1927).
|
|
17
|
+
*/
|
|
18
|
+
import { useEffect, useState } from 'react';
|
|
19
|
+
import { Dialog, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription, Button, } from '@object-ui/components';
|
|
20
|
+
import { toast } from 'sonner';
|
|
21
|
+
import { ScreenView, isObjectFormScreen, initialScreenValues } from './ScreenView';
|
|
22
|
+
export function FlowRunner({ state, authFetch, baseUrl, onClose, onComplete, dataSource, objects }) {
|
|
23
|
+
const [screen, setScreen] = useState(null);
|
|
24
|
+
const [runId, setRunId] = useState('');
|
|
25
|
+
const [flowName, setFlowName] = useState('');
|
|
26
|
+
const [values, setValues] = useState({});
|
|
27
|
+
const [submitting, setSubmitting] = useState(false);
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
if (state) {
|
|
30
|
+
setScreen(state.screen);
|
|
31
|
+
setRunId(state.runId);
|
|
32
|
+
setFlowName(state.flowName);
|
|
33
|
+
setValues(initialScreenValues(state.screen));
|
|
34
|
+
}
|
|
35
|
+
}, [state]);
|
|
36
|
+
if (!state || !screen)
|
|
37
|
+
return null;
|
|
38
|
+
const setVal = (name, v) => setValues((p) => ({ ...p, [name]: v }));
|
|
39
|
+
// Resume the paused run with `inputs` (applied as bare flow variables) and
|
|
40
|
+
// advance: render the next screen (multi-step wizard) or finish + refresh.
|
|
41
|
+
// Shared by the flat-field submit and the object-form save callback.
|
|
42
|
+
const resumeWith = async (inputs) => {
|
|
43
|
+
const res = await authFetch(`${baseUrl}/api/v1/automation/${encodeURIComponent(flowName)}/runs/${encodeURIComponent(runId)}/resume`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ inputs }) });
|
|
44
|
+
const json = await res.json().catch(() => null);
|
|
45
|
+
if (!res.ok || json?.success === false) {
|
|
46
|
+
// Transport / envelope failure — possibly transient (network, 5xx), so
|
|
47
|
+
// keep the dialog open and let the user retry the same run.
|
|
48
|
+
toast.error(json?.error || `Resume failed (HTTP ${res.status})`);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const data = json?.data ?? {};
|
|
52
|
+
// The HTTP envelope is `{ success:true, data: AutomationResult }`; a flow
|
|
53
|
+
// that errored downstream surfaces as `data.success === false`. That is
|
|
54
|
+
// TERMINAL: the engine consumes the suspension before running downstream
|
|
55
|
+
// nodes (resume-once), so this run can never be resumed again — a retry
|
|
56
|
+
// would only hit "No suspended run". Close the runner instead of leaving
|
|
57
|
+
// a dead form open.
|
|
58
|
+
if (data.success === false || data.status === 'failed') {
|
|
59
|
+
// Prefer the flow's friendly `errorMessage`; fall back to the raw error.
|
|
60
|
+
toast.error(data.errorMessage || data.error || 'The flow failed to complete.');
|
|
61
|
+
onClose();
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (data.status === 'paused' && data.screen) {
|
|
65
|
+
setScreen(data.screen);
|
|
66
|
+
setRunId(data.runId || runId);
|
|
67
|
+
setValues(initialScreenValues(data.screen));
|
|
68
|
+
toast.success('Saved — next step');
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// Terminal success — show the flow's declared completion message.
|
|
72
|
+
toast.success(data.successMessage || 'Done');
|
|
73
|
+
onComplete();
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
const submit = async () => {
|
|
77
|
+
const missing = screen.fields.filter((f) => f.required && (values[f.name] === undefined || values[f.name] === '' || values[f.name] === null));
|
|
78
|
+
if (missing.length) {
|
|
79
|
+
toast.error(`Please fill: ${missing.map((f) => f.label || f.name).join(', ')}`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
setSubmitting(true);
|
|
83
|
+
try {
|
|
84
|
+
await resumeWith(values);
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
toast.error(err.message);
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
setSubmitting(false);
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
// Object-form step: ObjectForm has already persisted the record (and its
|
|
94
|
+
// children, atomically). Resume the run with the new record's id bound to the
|
|
95
|
+
// step's `idVariable` so later steps can reference it (e.g. the Opportunity
|
|
96
|
+
// form's `account` FK = the Customer step's new id).
|
|
97
|
+
const onObjectFormSaved = async (saved) => {
|
|
98
|
+
const id = saved?.id ?? saved?.data?.id ?? saved?.record?.id;
|
|
99
|
+
const inputs = screen.idVariable && id != null ? { [screen.idVariable]: id } : {};
|
|
100
|
+
setSubmitting(true);
|
|
101
|
+
try {
|
|
102
|
+
await resumeWith(inputs);
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
toast.error(err.message);
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
setSubmitting(false);
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
const isObjectForm = isObjectFormScreen(screen);
|
|
112
|
+
return (_jsx(Dialog, { open: true, onOpenChange: (o) => { if (!o && !submitting)
|
|
113
|
+
onClose(); }, children: _jsxs(DialogContent, { className: isObjectForm ? 'sm:max-w-3xl max-h-[90vh] overflow-y-auto' : 'sm:max-w-md', children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: screen.title || 'Input' }), screen.description && _jsx(DialogDescription, { children: screen.description })] }), _jsx(ScreenView, { screen: screen, values: values, onValueChange: setVal, dataSource: dataSource, objects: objects, objectForm: {
|
|
114
|
+
onSuccess: onObjectFormSaved,
|
|
115
|
+
onCancel: onClose,
|
|
116
|
+
showSubmit: true,
|
|
117
|
+
showCancel: true,
|
|
118
|
+
submitText: 'Save & Continue',
|
|
119
|
+
cancelText: 'Cancel',
|
|
120
|
+
} }), !isObjectForm && (_jsxs(DialogFooter, { children: [_jsx(Button, { variant: "outline", onClick: onClose, disabled: submitting, children: "Cancel" }), _jsx(Button, { onClick: submit, disabled: submitting, children: submitting ? 'Submitting…' : 'Submit' })] }))] }) }));
|
|
121
|
+
}
|