@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
|
@@ -1,25 +1,127 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
3
3
|
/**
|
|
4
|
-
* DashboardPreview —
|
|
4
|
+
* DashboardPreview — interactive design surface for a Dashboard
|
|
5
|
+
* metadata draft. Clicking a widget emits a {@link MetadataSelection}
|
|
6
|
+
* so the host swaps the right-side inspector to that widget's form.
|
|
5
7
|
*
|
|
6
8
|
* Uses the same DashboardRenderer the runtime DashboardView uses, with
|
|
7
9
|
* the adapter from app-shell's AdapterProvider so widgets can query
|
|
8
|
-
* live data. `designMode` is
|
|
10
|
+
* live data. `designMode` is ON whenever the host is editing —
|
|
11
|
+
* read-only / view mode falls back to a plain runtime preview so the
|
|
12
|
+
* canvas looks identical to what end users see.
|
|
9
13
|
*
|
|
10
14
|
* The plugin is loaded lazily to avoid pulling its dep graph into
|
|
11
15
|
* every metadata-admin page load.
|
|
12
16
|
*/
|
|
13
17
|
import * as React from 'react';
|
|
14
|
-
import { Loader2 } from 'lucide-react';
|
|
18
|
+
import { Loader2, Pencil, X, Check } from 'lucide-react';
|
|
15
19
|
import { useAdapter } from '../../../providers/AdapterProvider';
|
|
16
20
|
import { PreviewShell, PreviewErrorBoundary, PreviewMessage } from './PreviewShell';
|
|
21
|
+
import { uniqueId, appendArray } from '../inspectors/_shared';
|
|
22
|
+
import { t as tr } from '../i18n';
|
|
23
|
+
import { AddWidgetPicker } from './AddWidgetPicker';
|
|
24
|
+
import { WIDGET_TYPE_META } from './widget-types';
|
|
17
25
|
const DashboardRenderer = React.lazy(() => import('@object-ui/plugin-dashboard').then((m) => ({ default: m.DashboardRenderer })));
|
|
18
|
-
export function DashboardPreview({ draft }) {
|
|
26
|
+
export function DashboardPreview({ draft, editing, onPatch, selection, onSelectionChange, locale, }) {
|
|
19
27
|
const adapter = useAdapter();
|
|
20
|
-
const widgets = Array.isArray(draft.widgets)
|
|
28
|
+
const widgets = Array.isArray(draft.widgets)
|
|
29
|
+
? draft.widgets
|
|
30
|
+
: [];
|
|
31
|
+
// Design mode is opt-in: only active while the host edits AND the
|
|
32
|
+
// host supplied a selection channel. In read-only / drawer-preview
|
|
33
|
+
// contexts we render the runtime presentation untouched.
|
|
34
|
+
const designMode = !!(editing && onSelectionChange);
|
|
35
|
+
const canEdit = designMode && !!onPatch;
|
|
36
|
+
const selectedWidgetId = selection && selection.kind === 'widget' ? selection.id : null;
|
|
37
|
+
const handleWidgetClick = React.useCallback((widgetId) => {
|
|
38
|
+
if (!onSelectionChange)
|
|
39
|
+
return;
|
|
40
|
+
if (!widgetId) {
|
|
41
|
+
onSelectionChange(null);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const w = widgets.find((wi) => wi?.id === widgetId);
|
|
45
|
+
onSelectionChange({
|
|
46
|
+
kind: 'widget',
|
|
47
|
+
id: widgetId,
|
|
48
|
+
label: w?.title || widgetId,
|
|
49
|
+
});
|
|
50
|
+
}, [onSelectionChange, widgets]);
|
|
51
|
+
const handleReorder = React.useCallback((next) => {
|
|
52
|
+
if (!onPatch)
|
|
53
|
+
return;
|
|
54
|
+
onPatch({ widgets: next });
|
|
55
|
+
}, [onPatch]);
|
|
56
|
+
const handleAddWidget = React.useCallback((type) => {
|
|
57
|
+
if (!canEdit)
|
|
58
|
+
return;
|
|
59
|
+
const existingIds = widgets.map((w) => w?.id).filter(Boolean);
|
|
60
|
+
const id = uniqueId('widget', existingIds);
|
|
61
|
+
const meta = WIDGET_TYPE_META[type];
|
|
62
|
+
const title = meta ? `New ${meta.label.toLowerCase()}` : 'New widget';
|
|
63
|
+
const newWidget = { id, type, title, ...(meta?.defaults ?? {}) };
|
|
64
|
+
const next = appendArray(widgets, newWidget);
|
|
65
|
+
onPatch({ widgets: next });
|
|
66
|
+
onSelectionChange?.({ kind: 'widget', id, label: title });
|
|
67
|
+
}, [canEdit, widgets, onPatch, onSelectionChange]);
|
|
68
|
+
const handleRenameWidget = React.useCallback((id, nextTitle) => {
|
|
69
|
+
if (!canEdit)
|
|
70
|
+
return;
|
|
71
|
+
const trimmed = nextTitle.trim();
|
|
72
|
+
const next = widgets.map((w) => w?.id === id ? { ...w, title: trimmed } : w);
|
|
73
|
+
onPatch({ widgets: next });
|
|
74
|
+
onSelectionChange?.({ kind: 'widget', id, label: trimmed || id });
|
|
75
|
+
}, [canEdit, widgets, onPatch, onSelectionChange]);
|
|
76
|
+
const selectedWidget = selectedWidgetId
|
|
77
|
+
? widgets.find((w) => w?.id === selectedWidgetId) ?? null
|
|
78
|
+
: null;
|
|
79
|
+
const addButton = canEdit ? (_jsx(AddWidgetPicker, { onAdd: handleAddWidget, label: tr('engine.inspector.add.widget', locale) })) : null;
|
|
21
80
|
if (widgets.length === 0) {
|
|
22
|
-
return (_jsx(PreviewShell, { hint:
|
|
81
|
+
return (_jsx(PreviewShell, { hint: `dashboard${designMode ? ' · design' : ''}`, toolbar: addButton, children: _jsx(PreviewMessage, { children: "Add at least one widget to see a preview." }) }));
|
|
23
82
|
}
|
|
24
|
-
return (_jsx(PreviewShell, { hint: `dashboard · ${widgets.length} widget${widgets.length === 1 ? '' : 's'}`, children:
|
|
83
|
+
return (_jsx(PreviewShell, { hint: `dashboard · ${widgets.length} widget${widgets.length === 1 ? '' : 's'}${designMode ? ' · design' : ''}`, toolbar: addButton, children: _jsxs(PreviewErrorBoundary, { fallbackHint: "A widget references an object or field that doesn't resolve.", children: [canEdit && selectedWidget ? (_jsx(SelectedWidgetStrip, { widget: selectedWidget, onRename: (nextTitle) => handleRenameWidget(selectedWidget.id, nextTitle), onClose: () => onSelectionChange?.(null) })) : null, _jsx(React.Suspense, { fallback: _jsxs("div", { className: "p-6 text-sm text-muted-foreground flex items-center gap-2", children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin" }), " Loading dashboard renderer\u2026"] }), children: _jsx("div", { className: "p-3 max-h-[70vh] overflow-auto", children: _jsx("div", { className: "min-w-[768px]", children: _jsx(DashboardRenderer, { schema: draft, dataSource: adapter, designMode: designMode, selectedWidgetId: selectedWidgetId, onWidgetClick: designMode ? handleWidgetClick : undefined, onWidgetsReorder: designMode && onPatch ? handleReorder : undefined, hideHeaderText: true }) }) }) })] }) }));
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Floating strip that appears above the dashboard whenever a widget
|
|
87
|
+
* is selected in design mode. Lets the author rename the widget
|
|
88
|
+
* inline (Enter commits, Esc cancels) without diving into the right-
|
|
89
|
+
* side inspector for a single text edit.
|
|
90
|
+
*/
|
|
91
|
+
function SelectedWidgetStrip({ widget, onRename, onClose, }) {
|
|
92
|
+
const currentTitle = widget.title ?? widget.id ?? '';
|
|
93
|
+
const [editing, setEditing] = React.useState(false);
|
|
94
|
+
const [draft, setDraft] = React.useState(currentTitle);
|
|
95
|
+
const inputRef = React.useRef(null);
|
|
96
|
+
// Sync local state when the externally-selected widget changes.
|
|
97
|
+
React.useEffect(() => {
|
|
98
|
+
setDraft(currentTitle);
|
|
99
|
+
setEditing(false);
|
|
100
|
+
}, [widget.id, currentTitle]);
|
|
101
|
+
React.useEffect(() => {
|
|
102
|
+
if (editing)
|
|
103
|
+
inputRef.current?.select();
|
|
104
|
+
}, [editing]);
|
|
105
|
+
const commit = () => {
|
|
106
|
+
const v = draft.trim();
|
|
107
|
+
if (v && v !== currentTitle)
|
|
108
|
+
onRename(v);
|
|
109
|
+
setEditing(false);
|
|
110
|
+
};
|
|
111
|
+
const cancel = () => {
|
|
112
|
+
setDraft(currentTitle);
|
|
113
|
+
setEditing(false);
|
|
114
|
+
};
|
|
115
|
+
const meta = WIDGET_TYPE_META[widget.type];
|
|
116
|
+
const TypeIcon = meta?.icon ?? null;
|
|
117
|
+
return (_jsxs("div", { className: "sticky top-0 z-10 flex items-center gap-2 border-b bg-primary/5 px-3 py-1.5 text-xs", children: [TypeIcon ? _jsx(TypeIcon, { className: "h-3.5 w-3.5 text-primary" }) : null, _jsx("span", { className: "rounded bg-primary px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-primary-foreground", children: "Selected" }), editing ? (_jsxs(_Fragment, { children: [_jsx("input", { ref: inputRef, value: draft, onChange: (e) => setDraft(e.target.value), onBlur: commit, onKeyDown: (e) => {
|
|
118
|
+
if (e.key === 'Enter') {
|
|
119
|
+
e.preventDefault();
|
|
120
|
+
commit();
|
|
121
|
+
}
|
|
122
|
+
else if (e.key === 'Escape') {
|
|
123
|
+
e.preventDefault();
|
|
124
|
+
cancel();
|
|
125
|
+
}
|
|
126
|
+
}, className: "flex-1 min-w-0 rounded border bg-background px-2 py-0.5 text-xs outline-none focus:ring-1 focus:ring-primary" }), _jsx("button", { type: "button", onClick: commit, className: "rounded p-1 hover:bg-primary/10", "aria-label": "Save title", children: _jsx(Check, { className: "h-3.5 w-3.5" }) })] })) : (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: () => setEditing(true), className: "flex-1 min-w-0 truncate text-left font-medium hover:underline", title: "Click to rename", children: currentTitle || _jsx("span", { className: "italic text-muted-foreground", children: "untitled" }) }), _jsx("button", { type: "button", onClick: () => setEditing(true), className: "rounded p-1 hover:bg-primary/10", "aria-label": "Rename widget", children: _jsx(Pencil, { className: "h-3.5 w-3.5" }) })] })), _jsx("button", { type: "button", onClick: onClose, className: "rounded p-1 hover:bg-primary/10", "aria-label": "Clear selection", children: _jsx(X, { className: "h-3.5 w-3.5" }) })] }));
|
|
25
127
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DatasetPreview — runs the live `dataset` draft (ADR-0021) against the server
|
|
3
|
+
* and shows the resulting rows, so authors can see their semantic layer work
|
|
4
|
+
* before saving.
|
|
5
|
+
*
|
|
6
|
+
* It posts the (possibly unsaved) draft inline to
|
|
7
|
+
* `POST /api/v1/analytics/dataset/query` via the AdapterProvider data source
|
|
8
|
+
* (`adapter.queryDataset`). The server compiles the dataset → Cube, applies the
|
|
9
|
+
* tenant/RLS read scope (ADR-0021 D-C), and returns chart-ready rows.
|
|
10
|
+
*
|
|
11
|
+
* Unlike the legacy single-object aggregation, dataset queries are cross-object
|
|
12
|
+
* and only run server-side — so a failure is surfaced as an error banner (the
|
|
13
|
+
* compile error, e.g. "relationship not declared in include") rather than
|
|
14
|
+
* silently falling back to wrong numbers.
|
|
15
|
+
*/
|
|
16
|
+
import * as React from 'react';
|
|
17
|
+
import type { MetadataPreviewProps } from '../preview-registry';
|
|
18
|
+
export declare function DatasetPreview({ draft }: MetadataPreviewProps): React.JSX.Element;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.
|
|
3
|
+
/**
|
|
4
|
+
* DatasetPreview — runs the live `dataset` draft (ADR-0021) against the server
|
|
5
|
+
* and shows the resulting rows, so authors can see their semantic layer work
|
|
6
|
+
* before saving.
|
|
7
|
+
*
|
|
8
|
+
* It posts the (possibly unsaved) draft inline to
|
|
9
|
+
* `POST /api/v1/analytics/dataset/query` via the AdapterProvider data source
|
|
10
|
+
* (`adapter.queryDataset`). The server compiles the dataset → Cube, applies the
|
|
11
|
+
* tenant/RLS read scope (ADR-0021 D-C), and returns chart-ready rows.
|
|
12
|
+
*
|
|
13
|
+
* Unlike the legacy single-object aggregation, dataset queries are cross-object
|
|
14
|
+
* and only run server-side — so a failure is surfaced as an error banner (the
|
|
15
|
+
* compile error, e.g. "relationship not declared in include") rather than
|
|
16
|
+
* silently falling back to wrong numbers.
|
|
17
|
+
*/
|
|
18
|
+
import * as React from 'react';
|
|
19
|
+
import { Loader2, BarChart3, AlertTriangle } from 'lucide-react';
|
|
20
|
+
import { useAdapter } from '../../../providers/AdapterProvider';
|
|
21
|
+
import { PreviewShell, PreviewEmptyState, PreviewErrorBoundary } from './PreviewShell';
|
|
22
|
+
import { formatMeasure, formatDimensionValue, buildDatasetFieldHelpers, } from '@object-ui/core';
|
|
23
|
+
import { useSafeFieldLabel } from '@object-ui/i18n';
|
|
24
|
+
// Lazy-loaded so the (recharts-backed) chart bundle only loads when a dataset
|
|
25
|
+
// preview actually renders a chart — keeps the metadata-admin bundle small.
|
|
26
|
+
const ChartRenderer = React.lazy(() => import('@object-ui/plugin-charts').then((m) => ({ default: m.ChartRenderer })));
|
|
27
|
+
export function DatasetPreview({ draft }) {
|
|
28
|
+
const adapter = useAdapter();
|
|
29
|
+
const { fieldLabel } = useSafeFieldLabel();
|
|
30
|
+
const objectName = draft.object;
|
|
31
|
+
const measureNames = React.useMemo(() => {
|
|
32
|
+
const m = Array.isArray(draft.measures) ? draft.measures : [];
|
|
33
|
+
return m.map((x) => String(x?.name ?? '')).filter(Boolean);
|
|
34
|
+
}, [draft]);
|
|
35
|
+
const dimensionNames = React.useMemo(() => {
|
|
36
|
+
const d = Array.isArray(draft.dimensions) ? draft.dimensions : [];
|
|
37
|
+
return d.map((x) => String(x?.name ?? '')).filter(Boolean);
|
|
38
|
+
}, [draft]);
|
|
39
|
+
const canRun = !!objectName && measureNames.length > 0;
|
|
40
|
+
const [state, setState] = React.useState({ status: 'idle', rows: [] });
|
|
41
|
+
const run = React.useCallback(async () => {
|
|
42
|
+
if (!canRun)
|
|
43
|
+
return;
|
|
44
|
+
setState({ status: 'loading', rows: [] });
|
|
45
|
+
try {
|
|
46
|
+
const result = await adapter.queryDataset(draft, { dimensions: dimensionNames, measures: measureNames });
|
|
47
|
+
setState({
|
|
48
|
+
status: 'ok',
|
|
49
|
+
rows: Array.isArray(result?.rows) ? result.rows : [],
|
|
50
|
+
fields: Array.isArray(result?.fields) ? result.fields : [],
|
|
51
|
+
object: result?.object,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
catch (e) {
|
|
55
|
+
setState({ status: 'error', rows: [], error: String(e?.message ?? e) });
|
|
56
|
+
}
|
|
57
|
+
}, [adapter, draft, dimensionNames, measureNames, canRun]);
|
|
58
|
+
// Auto-run a live preview whenever the meaningful selection signature changes.
|
|
59
|
+
const signature = `${objectName ?? ''}|${dimensionNames.join(',')}|${measureNames.join(',')}`;
|
|
60
|
+
React.useEffect(() => {
|
|
61
|
+
if (canRun)
|
|
62
|
+
void run();
|
|
63
|
+
// Intentionally keyed on `signature` only — re-run when the dataset's
|
|
64
|
+
// object/dimensions/measures change, not on every unrelated draft edit.
|
|
65
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
66
|
+
}, [signature]);
|
|
67
|
+
if (!objectName) {
|
|
68
|
+
return (_jsx(PreviewShell, { children: _jsx(PreviewEmptyState, { icon: _jsx(BarChart3, { className: "h-8 w-8" }), title: "Pick a base object", description: "Set the dataset's `object` to preview it against live data." }) }));
|
|
69
|
+
}
|
|
70
|
+
if (measureNames.length === 0) {
|
|
71
|
+
return (_jsx(PreviewShell, { children: _jsx(PreviewEmptyState, { icon: _jsx(BarChart3, { className: "h-8 w-8" }), title: "Add a measure", description: "A dataset needs at least one measure (e.g. revenue = sum(amount)) to preview." }) }));
|
|
72
|
+
}
|
|
73
|
+
// Display labels + currency-aware formatting, shared with the dashboard widget
|
|
74
|
+
// and the report renderer (@object-ui/core). Falls back to the raw name / plain
|
|
75
|
+
// number when the server result carries no field metadata.
|
|
76
|
+
const resultFields = state.status === 'ok' ? state.fields : undefined;
|
|
77
|
+
const resultObject = state.status === 'ok' ? state.object : undefined;
|
|
78
|
+
const { measureField, headerLabel } = buildDatasetFieldHelpers(resultFields, resultObject, fieldLabel);
|
|
79
|
+
const columns = [...dimensionNames, ...measureNames];
|
|
80
|
+
// A ratio/percent measure (format like `0.0%`) on the same axis as a
|
|
81
|
+
// magnitude measure (currency in the hundred-thousands) renders as an
|
|
82
|
+
// invisible sliver. When the selection MIXES the two scales, plot the ratio
|
|
83
|
+
// measures as a line on a secondary (right) Y axis via the `combo` chart —
|
|
84
|
+
// bars (magnitude) keep the left axis. Same-scale selections stay a plain bar.
|
|
85
|
+
const isRatioMeasure = (m) => {
|
|
86
|
+
const f = measureField(m)?.format;
|
|
87
|
+
return typeof f === 'string' && f.includes('%');
|
|
88
|
+
};
|
|
89
|
+
const ratioMeasures = measureNames.filter(isRatioMeasure);
|
|
90
|
+
const mixedScale = ratioMeasures.length > 0 && ratioMeasures.length < measureNames.length;
|
|
91
|
+
return (_jsx(PreviewShell, { hint: `dataset · ${objectName}${dimensionNames.length ? ' · by ' + dimensionNames.join(', ') : ''}`, children: _jsxs("div", { className: "p-3 space-y-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("button", { type: "button", onClick: () => void run(), disabled: state.status === 'loading', className: "inline-flex items-center gap-1.5 rounded-md border bg-background px-3 py-1.5 text-xs font-medium hover:bg-accent disabled:opacity-50", children: [state.status === 'loading'
|
|
92
|
+
? _jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" })
|
|
93
|
+
: _jsx(BarChart3, { className: "h-3.5 w-3.5" }), "Run preview"] }), _jsxs("span", { className: "text-[11px] text-muted-foreground", children: [measureNames.length, " measure", measureNames.length === 1 ? '' : 's', " \u00B7 ", dimensionNames.length, " dimension", dimensionNames.length === 1 ? '' : 's'] })] }), state.status === 'error' && (_jsxs("div", { role: "alert", className: "flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-xs text-destructive", children: [_jsx(AlertTriangle, { className: "h-3.5 w-3.5 mt-0.5 shrink-0" }), _jsx("span", { className: "break-words", children: state.error })] })), state.status === 'ok' && state.rows.length === 0 && (_jsx(PreviewEmptyState, { icon: _jsx(BarChart3, { className: "h-8 w-8" }), title: "No rows", description: "The dataset returned no rows for the current scope." })), state.rows.length > 0 && dimensionNames.length >= 1 && (_jsx(PreviewErrorBoundary, { fallbackHint: "Couldn't render the chart for this result \u2014 the table below still shows the data.", children: _jsx(React.Suspense, { fallback: _jsx("div", { className: "h-[260px] flex items-center justify-center text-xs text-muted-foreground", children: _jsx(Loader2, { className: "h-4 w-4 animate-spin" }) }), children: _jsxs("div", { className: "rounded-md border p-2", children: [_jsx(ChartRenderer, { schema: {
|
|
94
|
+
data: state.rows,
|
|
95
|
+
xAxisKey: dimensionNames[0],
|
|
96
|
+
chartType: mixedScale ? 'combo' : 'bar',
|
|
97
|
+
series: measureNames.map((m) => ({
|
|
98
|
+
dataKey: m,
|
|
99
|
+
label: headerLabel(m),
|
|
100
|
+
chartType: mixedScale ? (isRatioMeasure(m) ? 'line' : 'bar') : 'bar',
|
|
101
|
+
})),
|
|
102
|
+
} }), mixedScale && (_jsxs("p", { className: "mt-1 px-1 text-[10px] text-muted-foreground", children: ["Ratio measures (", ratioMeasures.map(headerLabel).join(', '), ") use the right axis."] }))] }) }) })), state.rows.length > 0 && (_jsx("div", { className: "overflow-auto max-h-[60vh] rounded-md border", children: _jsxs("table", { className: "w-full text-xs", children: [_jsx("thead", { className: "bg-muted/40", children: _jsx("tr", { children: columns.map((c) => (_jsx("th", { className: "px-2 py-1.5 text-left font-medium whitespace-nowrap", children: headerLabel(c) }, c))) }) }), _jsx("tbody", { children: state.rows.map((row, i) => (_jsx("tr", { className: "border-t", children: columns.map((c) => (_jsx("td", { className: "px-2 py-1 tabular-nums whitespace-nowrap", children: measureNames.includes(c)
|
|
103
|
+
? formatMeasure(row[c], measureField(c)?.format, measureField(c)?.currency)
|
|
104
|
+
: formatDimensionValue(row[c]) }, c))) }, i))) })] }) }))] }) }));
|
|
105
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DatasourcePreview — read-only summary of a Datasource draft.
|
|
3
|
+
*
|
|
4
|
+
* Datasources hold connection material, so the preview's most
|
|
5
|
+
* important contract is "show enough to verify the binding, never
|
|
6
|
+
* leak secrets". Concretely:
|
|
7
|
+
*
|
|
8
|
+
* • Header: driver pill (postgres/mysql/mongo/…), name, label,
|
|
9
|
+
* active flag, default-flag.
|
|
10
|
+
* • Connection card: a redacted config table where any key whose
|
|
11
|
+
* name matches /pass|secret|key|token|credential/i is replaced
|
|
12
|
+
* with `••••••` and a "redacted" badge. Other primitives render
|
|
13
|
+
* verbatim; nested objects render as their key count.
|
|
14
|
+
* • Pool, SSL, retry, health-check pills derived from optional
|
|
15
|
+
* sibling blocks.
|
|
16
|
+
* • Read-replica count and capabilities chip strip.
|
|
17
|
+
*
|
|
18
|
+
* The preview never attempts a live "test connection" — it runs
|
|
19
|
+
* inside the editor sandbox and must remain side-effect free.
|
|
20
|
+
*/
|
|
21
|
+
import * as React from 'react';
|
|
22
|
+
import type { MetadataPreviewProps } from '../preview-registry';
|
|
23
|
+
export declare function DatasourcePreview({ name, draft }: MetadataPreviewProps): React.JSX.Element;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Activity, Copy, Database, HardDrive, Lock, Power, RotateCcw, ShieldCheck, Star, } from 'lucide-react';
|
|
3
|
+
import { PreviewShell, PreviewMessage, PreviewErrorBoundary } from './PreviewShell';
|
|
4
|
+
import { ExternalDatasourcePanel } from '../external/ExternalDatasourcePanel';
|
|
5
|
+
const SECRET_RE = /pass|secret|key|token|credential|auth/i;
|
|
6
|
+
function isSecretKey(k) {
|
|
7
|
+
return SECRET_RE.test(k);
|
|
8
|
+
}
|
|
9
|
+
function redactValue(v) {
|
|
10
|
+
if (v == null || v === '')
|
|
11
|
+
return '∅';
|
|
12
|
+
return '••••••';
|
|
13
|
+
}
|
|
14
|
+
function renderValue(v) {
|
|
15
|
+
if (v == null)
|
|
16
|
+
return '∅';
|
|
17
|
+
if (typeof v === 'string')
|
|
18
|
+
return v;
|
|
19
|
+
if (typeof v === 'number' || typeof v === 'boolean')
|
|
20
|
+
return String(v);
|
|
21
|
+
if (Array.isArray(v))
|
|
22
|
+
return `[${v.length}]`;
|
|
23
|
+
if (typeof v === 'object')
|
|
24
|
+
return `{${Object.keys(v).length} keys}`;
|
|
25
|
+
return String(v);
|
|
26
|
+
}
|
|
27
|
+
export function DatasourcePreview({ name, draft }) {
|
|
28
|
+
const d = draft;
|
|
29
|
+
const dsName = String(d.name ?? name ?? '');
|
|
30
|
+
const label = String(d.label ?? dsName);
|
|
31
|
+
const description = d.description ?? '';
|
|
32
|
+
const driver = d.driver ?? d.type ?? 'unknown';
|
|
33
|
+
const active = d.active !== false;
|
|
34
|
+
const isDefault = !!d.isDefault || !!d.default;
|
|
35
|
+
const config = d.config ?? {};
|
|
36
|
+
const pool = d.pool;
|
|
37
|
+
const ssl = d.ssl;
|
|
38
|
+
const retryPolicy = d.retryPolicy;
|
|
39
|
+
const healthCheck = d.healthCheck;
|
|
40
|
+
const readReplicas = Array.isArray(d.readReplicas) ? d.readReplicas : [];
|
|
41
|
+
const capabilities = Array.isArray(d.capabilities) ? d.capabilities : [];
|
|
42
|
+
// External Datasource Federation (ADR-0015): a non-'managed' schemaMode
|
|
43
|
+
// marks this datasource as federated. The panel keys off the *saved* item
|
|
44
|
+
// name (`name`) so its REST calls hit a persisted datasource.
|
|
45
|
+
const schemaMode = d.schemaMode ?? 'managed';
|
|
46
|
+
const isFederated = schemaMode !== 'managed';
|
|
47
|
+
const external = d.external ?? undefined;
|
|
48
|
+
const allowWrites = !!external?.allowWrites;
|
|
49
|
+
const configEntries = Object.entries(config);
|
|
50
|
+
if (!dsName && configEntries.length === 0) {
|
|
51
|
+
return (_jsx(PreviewShell, { hint: "datasource", children: _jsx(PreviewMessage, { children: "Set a name and at least a driver to see the datasource preview." }) }));
|
|
52
|
+
}
|
|
53
|
+
return (_jsx(PreviewShell, { hint: `datasource · ${driver}`, children: _jsx(PreviewErrorBoundary, { children: _jsxs("div", { className: "p-3 space-y-3", children: [_jsx("div", { className: "rounded border bg-muted/30 p-3", children: _jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Database, { className: "h-4 w-4 mt-0.5 text-muted-foreground shrink-0" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex flex-wrap items-baseline gap-x-2", children: [_jsx("span", { className: "text-sm font-medium truncate", children: label }), _jsx("span", { className: "font-mono text-[10px] text-muted-foreground", children: dsName })] }), description && (_jsx("div", { className: "text-xs text-muted-foreground mt-0.5", children: description })), _jsxs("div", { className: "mt-1.5 flex flex-wrap items-center gap-x-3 gap-y-1 text-[11px]", children: [_jsxs("span", { className: "inline-flex items-center gap-1 rounded border bg-background px-1.5 py-0.5 font-mono", children: [_jsx(HardDrive, { className: "h-3 w-3 text-muted-foreground" }), " ", driver] }), _jsx(Pill, { icon: Power, label: active ? 'Active' : 'Disabled', tone: active ? 'green' : 'gray' }), isDefault && _jsx(Pill, { icon: Star, label: "default", tone: "amber" }), readReplicas.length > 0 && (_jsx(Pill, { icon: Copy, label: `${readReplicas.length} read replica${readReplicas.length === 1 ? '' : 's'}` }))] })] })] }) }), isFederated && (_jsx(ExternalDatasourcePanel, { datasource: String(name ?? ''), schemaMode: schemaMode, allowWrites: allowWrites })), _jsx(Section, { title: "Connection", icon: Lock, children: configEntries.length === 0 ? (_jsx("div", { className: "text-xs text-muted-foreground italic", children: "No config keys set." })) : (_jsx("div", { className: "rounded border bg-background overflow-hidden", children: _jsx("table", { className: "w-full text-xs", children: _jsx("tbody", { className: "divide-y", children: configEntries.map(([k, v]) => {
|
|
54
|
+
const secret = isSecretKey(k);
|
|
55
|
+
return (_jsxs("tr", { children: [_jsx("td", { className: "px-2.5 py-1.5 align-top w-40 font-mono text-muted-foreground", children: k }), _jsx("td", { className: "px-2.5 py-1.5 font-mono break-all", children: secret ? (_jsxs("span", { className: "inline-flex items-center gap-1.5", children: [_jsx("span", { children: redactValue(v) }), _jsx("span", { className: "rounded bg-amber-50 border border-amber-200 px-1 py-0.5 text-[9px] uppercase tracking-wider text-amber-800", children: "redacted" })] })) : (renderValue(v)) })] }, k));
|
|
56
|
+
}) }) }) })) }), _jsxs("div", { className: "grid gap-2 sm:grid-cols-2", children: [_jsx(SideBlock, { title: "Pool", icon: Activity, value: pool }), _jsx(SideBlock, { title: "SSL", icon: ShieldCheck, value: typeof ssl === 'boolean' ? { enabled: ssl } : ssl }), _jsx(SideBlock, { title: "Retry Policy", icon: RotateCcw, value: retryPolicy }), _jsx(SideBlock, { title: "Health Check", icon: Activity, value: healthCheck })] }), capabilities.length > 0 && (_jsx(Section, { title: "Capabilities", icon: ShieldCheck, children: _jsx("div", { className: "flex flex-wrap gap-1", children: capabilities.map((c) => (_jsx("span", { className: "inline-flex items-center gap-1 rounded border bg-muted/40 px-1.5 py-0.5 text-[11px] font-mono", children: c }, c))) }) }))] }) }) }));
|
|
57
|
+
}
|
|
58
|
+
function SideBlock({ title, icon: Icon, value, }) {
|
|
59
|
+
const present = value && typeof value === 'object' && Object.keys(value).length > 0;
|
|
60
|
+
return (_jsxs("div", { className: `rounded border bg-background ${present ? '' : 'opacity-60'}`, children: [_jsxs("div", { className: "flex items-center gap-1.5 border-b px-2.5 py-1.5", children: [_jsx(Icon, { className: "h-3.5 w-3.5 text-muted-foreground" }), _jsx("span", { className: "text-xs font-medium", children: title })] }), _jsx("div", { className: "px-2.5 py-1.5 text-[11px]", children: !present ? (_jsx("span", { className: "text-muted-foreground italic", children: "not configured" })) : (_jsx("dl", { className: "space-y-0.5", children: Object.entries(value).slice(0, 6).map(([k, v]) => (_jsxs("div", { className: "flex items-baseline gap-2 truncate", children: [_jsxs("dt", { className: "text-muted-foreground font-mono shrink-0", children: [k, ":"] }), _jsx("dd", { className: "font-mono truncate", children: isSecretKey(k) ? redactValue(v) : renderValue(v) })] }, k))) })) })] }));
|
|
61
|
+
}
|
|
62
|
+
function Section({ title, icon: Icon, children, }) {
|
|
63
|
+
return (_jsxs("div", { className: "space-y-1.5", children: [_jsxs("div", { className: "flex items-center gap-1.5 text-[11px] font-medium text-muted-foreground uppercase tracking-wider", children: [Icon && _jsx(Icon, { className: "h-3 w-3" }), _jsx("span", { children: title })] }), children] }));
|
|
64
|
+
}
|
|
65
|
+
function Pill({ icon: Icon, label, tone = 'gray', mono = false, }) {
|
|
66
|
+
const cls = tone === 'green' ? 'text-emerald-700' : tone === 'amber' ? 'text-amber-700' : 'text-foreground';
|
|
67
|
+
return (_jsxs("span", { className: "inline-flex items-center gap-1", children: [Icon && _jsx(Icon, { className: "h-3 w-3 text-muted-foreground" }), _jsx("span", { className: `${cls} ${mono ? 'font-mono' : ''}`, children: label })] }));
|
|
68
|
+
}
|
|
@@ -1,2 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EmailTemplatePreview — sandboxed HTML preview with `{{var}}` and
|
|
3
|
+
* `${var}` substitution from a tiny variables editor.
|
|
4
|
+
*
|
|
5
|
+
* Why an iframe? Email HTML is full-document content (`<html>`, inline
|
|
6
|
+
* styles, sometimes `<head>` blocks). Injecting it inline would let it
|
|
7
|
+
* style the host page. `srcdoc` + `sandbox="allow-same-origin"` gives
|
|
8
|
+
* us a clean visual without exposing the admin UI to template CSS.
|
|
9
|
+
*
|
|
10
|
+
* Subject / from / to are surfaced above the body so authors can see
|
|
11
|
+
* the full envelope at a glance.
|
|
12
|
+
*/
|
|
13
|
+
import * as React from 'react';
|
|
1
14
|
import type { MetadataPreviewProps } from '../preview-registry';
|
|
2
|
-
export declare function EmailTemplatePreview({ draft }: MetadataPreviewProps):
|
|
15
|
+
export declare function EmailTemplatePreview({ draft }: MetadataPreviewProps): React.JSX.Element;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FieldStub — visual placeholder that mimics the *runtime input* for
|
|
3
|
+
* every supported field type. Used inside the form-designer canvas
|
|
4
|
+
* so authors see "what their form will look like" without actually
|
|
5
|
+
* mounting the real widget (which would need a ValueDataSource and
|
|
6
|
+
* may fetch records, validate, etc.).
|
|
7
|
+
*
|
|
8
|
+
* Always disabled and stateless. Switches on `type` to render the
|
|
9
|
+
* appropriate shape (text input, switch, picklist, star row, …). Any
|
|
10
|
+
* unknown type falls back to a generic input + type badge.
|
|
11
|
+
*/
|
|
12
|
+
import * as React from 'react';
|
|
13
|
+
interface FieldStubProps {
|
|
14
|
+
type: string;
|
|
15
|
+
label?: string;
|
|
16
|
+
placeholder?: string;
|
|
17
|
+
/** Picklist options for select/radio/multiselect/checkboxes. */
|
|
18
|
+
options?: Array<{
|
|
19
|
+
value: string;
|
|
20
|
+
label?: string;
|
|
21
|
+
}>;
|
|
22
|
+
/** Reference target for lookup/master_detail/tree. */
|
|
23
|
+
referenceTo?: string;
|
|
24
|
+
/** Formula expression for formula/summary. */
|
|
25
|
+
formula?: string;
|
|
26
|
+
/** Active UI locale (illustrative placeholder text is localized). */
|
|
27
|
+
locale?: string;
|
|
28
|
+
}
|
|
29
|
+
export declare function FieldStub(props: FieldStubProps): React.JSX.Element;
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Input, Switch, Badge } from '@object-ui/components';
|
|
3
|
+
import { Calendar, Clock, Link2, Image as ImageIcon, Paperclip, MapPin, Star, ChevronDown, Search, Hash, Phone, AtSign, Globe, Lock, Palette, } from 'lucide-react';
|
|
4
|
+
import { FIELD_TYPE_META } from './field-types';
|
|
5
|
+
import { t, tFormat } from '../i18n';
|
|
6
|
+
export function FieldStub(props) {
|
|
7
|
+
const { type, locale } = props;
|
|
8
|
+
switch (type) {
|
|
9
|
+
case 'text':
|
|
10
|
+
case 'password':
|
|
11
|
+
return _jsx(PlainInput, { ...props, icon: type === 'password' ? _jsx(Lock, { className: "h-3.5 w-3.5" }) : undefined });
|
|
12
|
+
case 'email':
|
|
13
|
+
return _jsx(PlainInput, { ...props, icon: _jsx(AtSign, { className: "h-3.5 w-3.5" }), placeholder: props.placeholder ?? 'name@example.com' });
|
|
14
|
+
case 'url':
|
|
15
|
+
return _jsx(PlainInput, { ...props, icon: _jsx(Globe, { className: "h-3.5 w-3.5" }), placeholder: props.placeholder ?? 'https://…' });
|
|
16
|
+
case 'phone':
|
|
17
|
+
return _jsx(PlainInput, { ...props, icon: _jsx(Phone, { className: "h-3.5 w-3.5" }), placeholder: props.placeholder ?? '+1 555 …' });
|
|
18
|
+
case 'number':
|
|
19
|
+
case 'currency':
|
|
20
|
+
case 'percent':
|
|
21
|
+
case 'autonumber':
|
|
22
|
+
return _jsx(PlainInput, { ...props, icon: _jsx(Hash, { className: "h-3.5 w-3.5" }), placeholder: props.placeholder ?? '0' });
|
|
23
|
+
case 'date':
|
|
24
|
+
case 'datetime':
|
|
25
|
+
return _jsx(PlainInput, { ...props, icon: _jsx(Calendar, { className: "h-3.5 w-3.5" }), placeholder: t('designer.stub.pickDate', locale) });
|
|
26
|
+
case 'time':
|
|
27
|
+
return _jsx(PlainInput, { ...props, icon: _jsx(Clock, { className: "h-3.5 w-3.5" }), placeholder: "hh:mm" });
|
|
28
|
+
case 'textarea':
|
|
29
|
+
case 'markdown':
|
|
30
|
+
case 'html':
|
|
31
|
+
case 'richtext':
|
|
32
|
+
case 'json':
|
|
33
|
+
case 'code':
|
|
34
|
+
return _jsx(TextareaStub, { ...props, mono: type === 'json' || type === 'code' });
|
|
35
|
+
case 'boolean':
|
|
36
|
+
case 'toggle':
|
|
37
|
+
return (_jsxs("div", { className: "flex items-center gap-2 h-8", children: [_jsx(Switch, { disabled: true }), _jsx("span", { className: "text-xs text-muted-foreground", children: props.placeholder ?? t('designer.stub.off', locale) })] }));
|
|
38
|
+
case 'select':
|
|
39
|
+
case 'radio':
|
|
40
|
+
return _jsx(PicklistStub, { ...props, single: true });
|
|
41
|
+
case 'multiselect':
|
|
42
|
+
case 'checkboxes':
|
|
43
|
+
case 'tags':
|
|
44
|
+
return _jsx(PicklistStub, { ...props, single: false });
|
|
45
|
+
case 'lookup':
|
|
46
|
+
case 'master_detail':
|
|
47
|
+
case 'tree':
|
|
48
|
+
return _jsx(LookupStub, { ...props });
|
|
49
|
+
case 'image':
|
|
50
|
+
case 'avatar':
|
|
51
|
+
return _jsx(MediaTile, { icon: _jsx(ImageIcon, { className: "h-4 w-4" }), label: t(type === 'avatar' ? 'designer.stub.uploadAvatar' : 'designer.stub.uploadImage', locale) });
|
|
52
|
+
case 'file':
|
|
53
|
+
case 'video':
|
|
54
|
+
case 'audio':
|
|
55
|
+
case 'signature':
|
|
56
|
+
return _jsx(MediaTile, { icon: _jsx(Paperclip, { className: "h-4 w-4" }), label: tFormat('designer.stub.upload', locale, { type }) });
|
|
57
|
+
case 'qrcode':
|
|
58
|
+
return _jsx(MediaTile, { icon: _jsx(Paperclip, { className: "h-4 w-4" }), label: t('designer.stub.qrcode', locale) });
|
|
59
|
+
case 'color':
|
|
60
|
+
return (_jsxs("div", { className: "flex items-center gap-2 h-8", children: [_jsx("span", { className: "inline-block h-6 w-6 rounded border", style: { background: '#3b82f6' } }), _jsx("span", { className: "text-xs text-muted-foreground", children: "#3b82f6" }), _jsx(Palette, { className: "h-3.5 w-3.5 text-muted-foreground" })] }));
|
|
61
|
+
case 'rating':
|
|
62
|
+
return (_jsx("div", { className: "flex items-center gap-0.5 h-8", children: [0, 1, 2, 3, 4].map((i) => (_jsx(Star, { className: 'h-4 w-4 ' + (i < 3 ? 'fill-amber-400 text-amber-400' : 'text-muted-foreground/40') }, i))) }));
|
|
63
|
+
case 'slider':
|
|
64
|
+
return (_jsxs("div", { className: "flex items-center gap-2 h-8", children: [_jsxs("div", { className: "relative flex-1 h-1.5 rounded bg-muted", children: [_jsx("div", { className: "absolute inset-y-0 left-0 w-2/5 rounded bg-primary" }), _jsx("div", { className: "absolute h-3 w-3 -top-[3px] left-[40%] rounded-full border-2 border-primary bg-background" })] }), _jsx("span", { className: "text-xs text-muted-foreground tabular-nums", children: "40" })] }));
|
|
65
|
+
case 'progress':
|
|
66
|
+
return (_jsxs("div", { className: "flex items-center gap-2 h-8", children: [_jsx("div", { className: "relative flex-1 h-2 rounded bg-muted", children: _jsx("div", { className: "absolute inset-y-0 left-0 w-3/5 rounded bg-emerald-500" }) }), _jsx("span", { className: "text-xs text-muted-foreground tabular-nums", children: "60%" })] }));
|
|
67
|
+
case 'location':
|
|
68
|
+
return _jsx(PlainInput, { ...props, icon: _jsx(MapPin, { className: "h-3.5 w-3.5" }), placeholder: t('designer.stub.latLng', locale) });
|
|
69
|
+
case 'address':
|
|
70
|
+
return _jsx(TextareaStub, { ...props, placeholder: props.placeholder ?? 'Street\nCity, State ZIP\nCountry' });
|
|
71
|
+
case 'formula':
|
|
72
|
+
case 'summary':
|
|
73
|
+
return (_jsx("div", { className: "h-8 px-2 flex items-center text-xs font-mono bg-muted/40 border rounded text-muted-foreground", children: props.formula ? `ƒ ${props.formula}` : `ƒ ${t('designer.stub.computed', locale)}` }));
|
|
74
|
+
case 'composite':
|
|
75
|
+
return (_jsx("div", { className: "p-2 border-dashed border-2 rounded text-[11px] text-muted-foreground italic", children: t('designer.stub.composite', locale) }));
|
|
76
|
+
case 'repeater':
|
|
77
|
+
return (_jsx("div", { className: "p-2 border-dashed border-2 rounded text-[11px] text-muted-foreground italic", children: t('designer.stub.repeater', locale) }));
|
|
78
|
+
case 'vector':
|
|
79
|
+
return (_jsxs("div", { className: "h-8 px-2 flex items-center text-xs font-mono bg-muted/40 border rounded text-muted-foreground", children: ["[0.124, 0.337, \u2026] ", props.placeholder ? `(${props.placeholder})` : ''] }));
|
|
80
|
+
default:
|
|
81
|
+
return (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Input, { disabled: true, placeholder: props.placeholder ?? `(${type})`, className: "h-8 text-sm" }), _jsx(Badge, { variant: "outline", className: "text-[10px]", children: type })] }));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function PlainInput({ placeholder, icon }) {
|
|
85
|
+
return (_jsxs("div", { className: "relative", children: [_jsx(Input, { disabled: true, placeholder: placeholder ?? '', className: 'h-8 text-sm ' + (icon ? 'pl-8' : '') }), icon && (_jsx("div", { className: "absolute left-2 top-1/2 -translate-y-1/2 text-muted-foreground", children: icon }))] }));
|
|
86
|
+
}
|
|
87
|
+
function TextareaStub({ placeholder, mono }) {
|
|
88
|
+
return (_jsx("textarea", { disabled: true, placeholder: placeholder ?? '', className: 'w-full min-h-[60px] text-sm rounded-md border bg-background px-2 py-1.5 disabled:opacity-100 ' + (mono ? 'font-mono text-xs' : '') }));
|
|
89
|
+
}
|
|
90
|
+
function PicklistStub({ options, placeholder, single, locale }) {
|
|
91
|
+
const opts = options ?? [];
|
|
92
|
+
const visible = opts.slice(0, single ? 1 : 3).filter((o) => o.value || o.label);
|
|
93
|
+
if (single) {
|
|
94
|
+
return (_jsxs("div", { className: "h-8 px-2 flex items-center justify-between text-sm border rounded bg-background text-muted-foreground", children: [_jsx("span", { className: "truncate", children: visible[0]?.label || visible[0]?.value || placeholder || t('designer.stub.select', locale) }), _jsx(ChevronDown, { className: "h-3.5 w-3.5 shrink-0" })] }));
|
|
95
|
+
}
|
|
96
|
+
return (_jsxs("div", { className: "min-h-8 px-1.5 py-1 flex items-center flex-wrap gap-1 border rounded bg-background", children: [visible.length === 0 ? (_jsx("span", { className: "text-xs text-muted-foreground px-1", children: placeholder || t('designer.stub.pickMulti', locale) })) : (visible.map((o, i) => (_jsx(Badge, { variant: "secondary", className: "text-[10px]", children: o.label || o.value }, i)))), opts.length > visible.length && (_jsxs("span", { className: "text-[10px] text-muted-foreground", children: ["+", opts.length - visible.length] }))] }));
|
|
97
|
+
}
|
|
98
|
+
function LookupStub({ referenceTo, placeholder, locale }) {
|
|
99
|
+
const meta = referenceTo ? FIELD_TYPE_META.lookup : null;
|
|
100
|
+
return (_jsxs("div", { className: "h-8 px-2 flex items-center gap-2 border rounded bg-background text-sm text-muted-foreground", children: [_jsx(Link2, { className: "h-3.5 w-3.5 shrink-0" }), _jsx("span", { className: "truncate flex-1", children: placeholder || (referenceTo ? tFormat('designer.stub.searchRef', locale, { ref: referenceTo }) : t('designer.stub.chooseRelated', locale)) }), referenceTo && (_jsxs(Badge, { variant: "outline", className: "text-[10px] shrink-0", children: ["\u2192 ", referenceTo] })), !referenceTo && _jsx(Search, { className: "h-3.5 w-3.5 shrink-0 text-amber-500" }), meta && null] }));
|
|
101
|
+
}
|
|
102
|
+
function MediaTile({ icon, label }) {
|
|
103
|
+
return (_jsxs("div", { className: "h-16 w-full border-2 border-dashed rounded flex flex-col items-center justify-center gap-1 text-muted-foreground bg-muted/20", children: [icon, _jsx("span", { className: "text-[11px]", children: label })] }));
|
|
104
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FieldsListEditor — the right-panel column manager (mainstream low-code
|
|
3
|
+
* pattern: a vertical, drag-reorderable list of fields with an inline
|
|
4
|
+
* "+ Add field" picker).
|
|
5
|
+
*
|
|
6
|
+
* This is the SINGLE owner of column read / write / reorder / remove / select
|
|
7
|
+
* logic for a View variant. It is rendered in two places so the fields list is
|
|
8
|
+
* always visible:
|
|
9
|
+
* • {@link ViewVariantInspector} (the home / variant panel) — no row is
|
|
10
|
+
* highlighted; clicking a row drills into the scoped column inspector.
|
|
11
|
+
* • {@link ViewColumnInspector} (the scoped column panel) — the selected row
|
|
12
|
+
* is highlighted and the column's detail props render below it.
|
|
13
|
+
*
|
|
14
|
+
* Columns round-trip in their original shape: string variants (e.g. kanban
|
|
15
|
+
* card fields) stay strings; object variants keep `{ field, label, … }`. The
|
|
16
|
+
* raw `columns` array is reordered / spliced directly — never normalised — so
|
|
17
|
+
* round-trips stay lossless.
|
|
18
|
+
*/
|
|
19
|
+
import * as React from 'react';
|
|
20
|
+
import { type ObjectFieldInfo } from './useObjectFields';
|
|
21
|
+
export interface FieldsListEditorProps {
|
|
22
|
+
/** Top-level variant key the columns belong to (e.g. 'list'). */
|
|
23
|
+
variantKey: string;
|
|
24
|
+
/** The variant schema; re-spread on every column write. */
|
|
25
|
+
schema: Record<string, unknown>;
|
|
26
|
+
/** Raw columns array (entries may be strings or objects). */
|
|
27
|
+
columns: unknown[];
|
|
28
|
+
/** Whether every column is a bare string (drives new-column shape). */
|
|
29
|
+
allStrings: boolean;
|
|
30
|
+
/** Bound object name — drives field icons + the Add-field picker. */
|
|
31
|
+
objectName?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Pre-resolved field catalog. When supplied, skips the network fetch and
|
|
34
|
+
* uses this list instead (host already holds the object definition).
|
|
35
|
+
*/
|
|
36
|
+
objectFieldsOverride?: ObjectFieldInfo[];
|
|
37
|
+
/** Index of the currently selected column, or null when none. */
|
|
38
|
+
selectedIndex: number | null;
|
|
39
|
+
/** Read-only mode disables drag / add / remove. */
|
|
40
|
+
readOnly?: boolean;
|
|
41
|
+
/** Apply a shallow patch to the draft. */
|
|
42
|
+
onPatch: (patch: Record<string, unknown>) => void;
|
|
43
|
+
/** Emit / redirect the column selection. */
|
|
44
|
+
onSelectionChange?: (sel: {
|
|
45
|
+
kind: string;
|
|
46
|
+
id: string;
|
|
47
|
+
label?: string;
|
|
48
|
+
} | null) => void;
|
|
49
|
+
}
|
|
50
|
+
export declare function FieldsListEditor({ variantKey, schema, columns, allStrings, objectName, objectFieldsOverride, selectedIndex, readOnly, onPatch, onSelectionChange, }: FieldsListEditorProps): React.JSX.Element;
|