@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
|
@@ -8,15 +8,17 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
8
8
|
import { useEffect, useState } from 'react';
|
|
9
9
|
import { useNavigate, useParams } from 'react-router-dom';
|
|
10
10
|
import { Button, Badge, Card, CardContent, CardHeader, CardTitle, Skeleton, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, Label, Checkbox, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, } from '@object-ui/components';
|
|
11
|
-
import { ArrowLeft, ExternalLink, Download, AlertCircle, Package, Trash2, MoreHorizontal, CheckCircle2 } from 'lucide-react';
|
|
11
|
+
import { ArrowLeft, ExternalLink, Download, AlertCircle, Package, Trash2, MoreHorizontal, CheckCircle2, ArrowUpCircle, Database, Loader2 } from 'lucide-react';
|
|
12
12
|
import { useIsWorkspaceAdmin } from '@object-ui/auth';
|
|
13
13
|
import { useObjectTranslation } from '@object-ui/i18n';
|
|
14
14
|
import { PackageIcon } from './PackageIcon';
|
|
15
15
|
import { MarkdownText } from './MarkdownText';
|
|
16
|
+
import { PluginDisclosure } from './PluginDisclosure';
|
|
16
17
|
import { MarketplaceAccessDenied } from './MarketplaceAccessDenied';
|
|
17
18
|
import { localizePackage } from './usePackageL10n';
|
|
18
|
-
import { getMarketplacePackage, installPackage, installLocal, uninstallLocal, listLocalInstalls, listCloudEnvironments, listInstallableOrgIds, cloudInstallDeepLink, } from './marketplaceApi';
|
|
19
|
+
import { getMarketplacePackage, installPackage, installLocal, uninstallLocal, listLocalInstalls, listCloudEnvironments, listInstallableOrgIds, cloudInstallDeepLink, getCloudInstallationInfo, reseedSampleData, purgeSampleData, reseedLocalSampleData, purgeLocalSampleData, } from './marketplaceApi';
|
|
19
20
|
import { getRuntimeConfig } from '../../runtime-config';
|
|
21
|
+
import { emitMetadataRefresh } from '../../assistant/assistantBus';
|
|
20
22
|
import { useMetadata } from '../../providers/MetadataProvider';
|
|
21
23
|
export function MarketplacePackagePage() {
|
|
22
24
|
const navigate = useNavigate();
|
|
@@ -33,9 +35,27 @@ export function MarketplacePackagePage() {
|
|
|
33
35
|
const [envsLoading, setEnvsLoading] = useState(false);
|
|
34
36
|
const [envsError, setEnvsError] = useState(null);
|
|
35
37
|
const [selectedEnv, setSelectedEnv] = useState('');
|
|
38
|
+
// env id -> installed version, for annotating the picker with each env's
|
|
39
|
+
// current install state ("Installed v1.0.0" / "Update → v1.0.1"). Lets a
|
|
40
|
+
// multi-env operator see at a glance where this app already lives and which
|
|
41
|
+
// copies are out of date before choosing a target.
|
|
42
|
+
const [envInstallMap, setEnvInstallMap] = useState({});
|
|
36
43
|
const [seedSampleData, setSeedSampleData] = useState(false);
|
|
44
|
+
// PD4: a code-bearing package requires explicit acknowledgement of its
|
|
45
|
+
// requested permissions before the install button is enabled.
|
|
46
|
+
const [acknowledged, setAcknowledged] = useState(false);
|
|
37
47
|
const [installing, setInstalling] = useState(false);
|
|
38
48
|
const [installResult, setInstallResult] = useState(null);
|
|
49
|
+
// Tracks whether the package has been installed into the current
|
|
50
|
+
// environment via the cloud install path. Used to flip the primary
|
|
51
|
+
// CTA from "Install to Cloud" → "Installed" so the user gets
|
|
52
|
+
// immediate feedback after a successful install. Seeded from the
|
|
53
|
+
// install response (which echoes the installation row) and from a
|
|
54
|
+
// boot-time fetch of sys_package_installation for the current env.
|
|
55
|
+
const [cloudInstalledVersion, setCloudInstalledVersion] = useState(null);
|
|
56
|
+
const [cloudInstall, setCloudInstall] = useState(null);
|
|
57
|
+
const [sampleDataBusy, setSampleDataBusy] = useState(null);
|
|
58
|
+
const [sampleDataMsg, setSampleDataMsg] = useState(null);
|
|
39
59
|
// Local-install state (this runtime's own kernel — separate flow from cloud).
|
|
40
60
|
const [localInstalls, setLocalInstalls] = useState([]);
|
|
41
61
|
const [installingLocal, setInstallingLocal] = useState(false);
|
|
@@ -51,6 +71,29 @@ export function MarketplacePackagePage() {
|
|
|
51
71
|
})();
|
|
52
72
|
return () => { cancelled = true; };
|
|
53
73
|
}, [packageId, localResult]);
|
|
74
|
+
// Seed cloud-install state so the primary CTA renders as "Installed" on
|
|
75
|
+
// first paint instead of inviting another install.
|
|
76
|
+
// NOTE: a tenant runtime (per-subdomain ObjectOS) has NO
|
|
77
|
+
// `defaultEnvironmentId` — but getCloudInstallationInfo's same-origin
|
|
78
|
+
// `/cloud-connection/installation` path resolves the env by hostname and
|
|
79
|
+
// does not need an explicit id (only the cloud-control-plane path needs
|
|
80
|
+
// one, and it no-ops on an empty id internally). So do NOT gate the probe
|
|
81
|
+
// on `currentEnvId` — that left the detail CTA stuck on "Install to
|
|
82
|
+
// cloud…" for every already-installed package in an env console.
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
if (!packageId)
|
|
85
|
+
return;
|
|
86
|
+
const currentEnvId = getRuntimeConfig().defaultEnvironmentId ?? '';
|
|
87
|
+
let cancelled = false;
|
|
88
|
+
(async () => {
|
|
89
|
+
const info = await getCloudInstallationInfo(packageId, currentEnvId);
|
|
90
|
+
if (cancelled || !info)
|
|
91
|
+
return;
|
|
92
|
+
setCloudInstall(info);
|
|
93
|
+
setCloudInstalledVersion(info.version);
|
|
94
|
+
})();
|
|
95
|
+
return () => { cancelled = true; };
|
|
96
|
+
}, [packageId]);
|
|
54
97
|
useEffect(() => {
|
|
55
98
|
let cancelled = false;
|
|
56
99
|
(async () => {
|
|
@@ -104,6 +147,26 @@ export function MarketplacePackagePage() {
|
|
|
104
147
|
return orgId ? adminOrgIds.has(String(orgId)) : false;
|
|
105
148
|
});
|
|
106
149
|
setEnvs(installable);
|
|
150
|
+
// Annotate each installable env with its current install state (best
|
|
151
|
+
// effort, parallel; a failed lookup just omits the annotation).
|
|
152
|
+
setEnvInstallMap({});
|
|
153
|
+
const pkgId = packageId;
|
|
154
|
+
if (pkgId)
|
|
155
|
+
void Promise.all(installable.map(async (env) => {
|
|
156
|
+
try {
|
|
157
|
+
const info = await getCloudInstallationInfo(pkgId, env.id);
|
|
158
|
+
return info ? [env.id, info.version] : null;
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
})).then((pairs) => {
|
|
164
|
+
const map = {};
|
|
165
|
+
for (const pair of pairs)
|
|
166
|
+
if (pair)
|
|
167
|
+
map[pair[0]] = pair[1];
|
|
168
|
+
setEnvInstallMap(map);
|
|
169
|
+
});
|
|
107
170
|
if (list.length > 0 && installable.length === 0) {
|
|
108
171
|
setEnvsError(t('marketplace.install.noPermission'));
|
|
109
172
|
}
|
|
@@ -130,7 +193,28 @@ export function MarketplacePackagePage() {
|
|
|
130
193
|
setInstalling(true);
|
|
131
194
|
setInstallResult(null);
|
|
132
195
|
try {
|
|
133
|
-
await installPackage({ packageId, environmentId: selectedEnv, seedSampleData });
|
|
196
|
+
const installResp = await installPackage({ packageId, environmentId: selectedEnv, seedSampleData });
|
|
197
|
+
// Flip the primary CTA to "Installed" so the user sees the state
|
|
198
|
+
// change without a page refresh. Response includes the install
|
|
199
|
+
// row when the cloud handler echoes it; fall back to the package's
|
|
200
|
+
// latest version when it doesn't.
|
|
201
|
+
const installedVersion = installResp?.installation?.version
|
|
202
|
+
?? data?.package?.latest_version?.version
|
|
203
|
+
?? data?.versions?.[0]?.version
|
|
204
|
+
?? '';
|
|
205
|
+
setCloudInstalledVersion(installedVersion || 'installed');
|
|
206
|
+
// Refresh the installation handle so reseed/purge can target it
|
|
207
|
+
// without the user having to reload the page.
|
|
208
|
+
try {
|
|
209
|
+
const currentEnvId = getRuntimeConfig().defaultEnvironmentId;
|
|
210
|
+
const envId = currentEnvId || selectedEnv;
|
|
211
|
+
if (envId) {
|
|
212
|
+
const info = await getCloudInstallationInfo(packageId, envId);
|
|
213
|
+
if (info)
|
|
214
|
+
setCloudInstall(info);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
catch { /* non-fatal */ }
|
|
134
218
|
// Invalidate the metadata cache so the newly-installed app's
|
|
135
219
|
// objects/views/menus are fetched fresh on next access. Without
|
|
136
220
|
// this the user sees the new app in the switcher (the `app` list
|
|
@@ -161,6 +245,7 @@ export function MarketplacePackagePage() {
|
|
|
161
245
|
}
|
|
162
246
|
}
|
|
163
247
|
setInstallResult({ ok: true, message: t('marketplace.install.success') });
|
|
248
|
+
emitMetadataRefresh();
|
|
164
249
|
}
|
|
165
250
|
catch (e) {
|
|
166
251
|
setInstallResult({ ok: false, message: e?.message ?? String(e) });
|
|
@@ -195,6 +280,7 @@ export function MarketplacePackagePage() {
|
|
|
195
280
|
name: data?.package ? localizePackage(data.package, language).displayName : result.manifestId,
|
|
196
281
|
}),
|
|
197
282
|
});
|
|
283
|
+
emitMetadataRefresh();
|
|
198
284
|
}
|
|
199
285
|
catch (e) {
|
|
200
286
|
const code = e?.code;
|
|
@@ -248,6 +334,124 @@ export function MarketplacePackagePage() {
|
|
|
248
334
|
setInstallingLocal(false);
|
|
249
335
|
}
|
|
250
336
|
};
|
|
337
|
+
/**
|
|
338
|
+
* Re-seed sample data into the cloud environment for this install.
|
|
339
|
+
* Used when the user forgot to tick "Include sample data" during the
|
|
340
|
+
* original install. SeedLoaderService upserts by id, so calling this
|
|
341
|
+
* multiple times is safe.
|
|
342
|
+
*/
|
|
343
|
+
const doReseedSampleData = async () => {
|
|
344
|
+
if (!cloudInstall)
|
|
345
|
+
return;
|
|
346
|
+
setSampleDataBusy('reseed');
|
|
347
|
+
setSampleDataMsg(null);
|
|
348
|
+
try {
|
|
349
|
+
const r = await reseedSampleData(cloudInstall.installationId);
|
|
350
|
+
if (r.ok) {
|
|
351
|
+
setCloudInstall({ ...cloudInstall, withSampleData: true });
|
|
352
|
+
setSampleDataMsg({
|
|
353
|
+
ok: true,
|
|
354
|
+
text: t('marketplace.detail.reseedQueued') || 'Sample data will be re-seeded on next environment access.',
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
setSampleDataMsg({ ok: false, text: r.error || 'Re-seed failed' });
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
finally {
|
|
362
|
+
setSampleDataBusy(null);
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
/**
|
|
366
|
+
* Delete the sample data this package seeded. Use before going live
|
|
367
|
+
* with a clean production environment. Only records declared in the
|
|
368
|
+
* package's seed datasets are removed; user-added rows are untouched.
|
|
369
|
+
*/
|
|
370
|
+
const doPurgeSampleData = async () => {
|
|
371
|
+
if (!cloudInstall)
|
|
372
|
+
return;
|
|
373
|
+
if (!confirm(t('marketplace.detail.purgeConfirm')
|
|
374
|
+
|| 'Delete all sample records seeded by this package? User-added records will NOT be touched.')) {
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
setSampleDataBusy('purge');
|
|
378
|
+
setSampleDataMsg(null);
|
|
379
|
+
try {
|
|
380
|
+
const r = await purgeSampleData(cloudInstall.installationId);
|
|
381
|
+
if (r.ok) {
|
|
382
|
+
setCloudInstall({ ...cloudInstall, withSampleData: false });
|
|
383
|
+
const removed = r.deleted ?? 0;
|
|
384
|
+
setSampleDataMsg({
|
|
385
|
+
ok: true,
|
|
386
|
+
text: removed > 0
|
|
387
|
+
? (t('marketplace.detail.purgeSuccess', { count: removed })
|
|
388
|
+
|| `Removed ${removed} sample record(s).`)
|
|
389
|
+
: (t('marketplace.detail.purgeNoData') || 'No sample records found to purge.'),
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
else {
|
|
393
|
+
setSampleDataMsg({ ok: false, text: r.error || 'Purge failed' });
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
finally {
|
|
397
|
+
setSampleDataBusy(null);
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
const doReseedLocalSampleData = async () => {
|
|
401
|
+
if (!localInstall)
|
|
402
|
+
return;
|
|
403
|
+
setSampleDataBusy('reseed');
|
|
404
|
+
setSampleDataMsg(null);
|
|
405
|
+
try {
|
|
406
|
+
const r = await reseedLocalSampleData(localInstall.manifestId);
|
|
407
|
+
setLocalInstalls((prev) => prev.map((i) => i.manifestId === localInstall.manifestId ? { ...i, withSampleData: true } : i));
|
|
408
|
+
const inserted = r.inserted ?? 0;
|
|
409
|
+
const updated = r.updated ?? 0;
|
|
410
|
+
const errored = r.errors ?? 0;
|
|
411
|
+
const base = t('marketplace.detail.reseedLocalSuccess', { inserted, updated })
|
|
412
|
+
|| `Sample data re-seeded (inserted=${inserted}, updated=${updated}).`;
|
|
413
|
+
// A reseed can land some rows and fail others (the server only hard-fails
|
|
414
|
+
// when ZERO rows write). Don't hide the partial failures behind a green
|
|
415
|
+
// success toast — flag them so the user knows the data is incomplete.
|
|
416
|
+
setSampleDataMsg(errored > 0
|
|
417
|
+
? { ok: false, text: `${base} ${t('marketplace.detail.reseedPartialErrors', { count: errored }) || `(${errored} record(s) failed to write)`}` }
|
|
418
|
+
: { ok: true, text: base });
|
|
419
|
+
}
|
|
420
|
+
catch (err) {
|
|
421
|
+
setSampleDataMsg({ ok: false, text: err?.message || 'Re-seed failed' });
|
|
422
|
+
}
|
|
423
|
+
finally {
|
|
424
|
+
setSampleDataBusy(null);
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
const doPurgeLocalSampleData = async () => {
|
|
428
|
+
if (!localInstall)
|
|
429
|
+
return;
|
|
430
|
+
if (!confirm(t('marketplace.detail.purgeConfirm')
|
|
431
|
+
|| 'Delete all sample records seeded by this package? User-added records will NOT be touched.')) {
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
setSampleDataBusy('purge');
|
|
435
|
+
setSampleDataMsg(null);
|
|
436
|
+
try {
|
|
437
|
+
const r = await purgeLocalSampleData(localInstall.manifestId);
|
|
438
|
+
setLocalInstalls((prev) => prev.map((i) => i.manifestId === localInstall.manifestId ? { ...i, withSampleData: false } : i));
|
|
439
|
+
const removed = r.deleted ?? 0;
|
|
440
|
+
setSampleDataMsg({
|
|
441
|
+
ok: true,
|
|
442
|
+
text: removed > 0
|
|
443
|
+
? (t('marketplace.detail.purgeSuccess', { count: removed })
|
|
444
|
+
|| `Removed ${removed} sample record(s).`)
|
|
445
|
+
: (t('marketplace.detail.purgeNoData') || 'No sample records found to purge.'),
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
catch (err) {
|
|
449
|
+
setSampleDataMsg({ ok: false, text: err?.message || 'Purge failed' });
|
|
450
|
+
}
|
|
451
|
+
finally {
|
|
452
|
+
setSampleDataBusy(null);
|
|
453
|
+
}
|
|
454
|
+
};
|
|
251
455
|
if (loading) {
|
|
252
456
|
return (_jsxs("div", { className: "mx-auto w-full max-w-6xl flex flex-col gap-6 p-4 sm:p-6", children: [_jsx(Skeleton, { className: "h-8 w-32" }), _jsx(Skeleton, { className: "h-16 w-full" }), _jsx(Skeleton, { className: "h-64 w-full" })] }));
|
|
253
457
|
}
|
|
@@ -258,8 +462,16 @@ export function MarketplacePackagePage() {
|
|
|
258
462
|
const loc = localizePackage(pkg, language);
|
|
259
463
|
const latestVersion = pkg.latest_version?.version ?? data.versions[0]?.version ?? null;
|
|
260
464
|
const localInstall = localInstalls.find((i) => i.manifestId === pkg.manifest_id) ?? null;
|
|
465
|
+
// PD4 (ADR-0025 §3.11): code-bearing packages must disclose + be acknowledged.
|
|
466
|
+
const containsCode = !!pkg.latest_version?.contains_code;
|
|
467
|
+
// ADR-0010 version lifecycle: installed cloud env is on an OLDER version than
|
|
468
|
+
// the package's latest published → surface an update affordance.
|
|
469
|
+
const cloudUpdateAvailable = !!cloudInstalledVersion
|
|
470
|
+
&& cloudInstalledVersion !== 'installed'
|
|
471
|
+
&& !!latestVersion
|
|
472
|
+
&& cloudInstalledVersion !== latestVersion;
|
|
261
473
|
const supportsLocal = getRuntimeConfig().features.installLocal;
|
|
262
|
-
const primaryDisabled = !latestVersion || installingLocal || installing;
|
|
474
|
+
const primaryDisabled = !latestVersion || installingLocal || installing || (!supportsLocal && !!cloudInstalledVersion && !cloudUpdateAvailable);
|
|
263
475
|
const primaryAction = supportsLocal
|
|
264
476
|
? {
|
|
265
477
|
label: installingLocal
|
|
@@ -270,7 +482,13 @@ export function MarketplacePackagePage() {
|
|
|
270
482
|
onClick: doInstallLocal,
|
|
271
483
|
}
|
|
272
484
|
: {
|
|
273
|
-
label: installing
|
|
485
|
+
label: installing
|
|
486
|
+
? t('marketplace.action.installing')
|
|
487
|
+
: cloudInstalledVersion
|
|
488
|
+
? (cloudUpdateAvailable
|
|
489
|
+
? t('marketplace.action.updateTo', { defaultValue: 'Update', version: latestVersion })
|
|
490
|
+
: t('marketplace.action.installed', { defaultValue: 'Installed' }))
|
|
491
|
+
: t('marketplace.action.installToCloud'),
|
|
274
492
|
onClick: openInstall,
|
|
275
493
|
};
|
|
276
494
|
const categoryLabel = pkg.category
|
|
@@ -278,8 +496,31 @@ export function MarketplacePackagePage() {
|
|
|
278
496
|
: null;
|
|
279
497
|
if (!isAdmin)
|
|
280
498
|
return _jsx(MarketplaceAccessDenied, {});
|
|
281
|
-
return (_jsxs("div", { className: "mx-auto w-full max-w-6xl flex flex-col gap-6 p-4 sm:p-6", children: [_jsxs(Button, { variant: "ghost", size: "sm", className: "self-start -ml-2 text-muted-foreground hover:text-foreground", onClick: () => navigate(`${basePath}/system/marketplace`), children: [_jsx(ArrowLeft, { className: "h-4 w-4 mr-1.5", "aria-hidden": "true" }), t('marketplace.back')] }), _jsxs("div", { className: "flex items-start gap-5 flex-wrap sm:flex-nowrap rounded-2xl border bg-gradient-to-br from-primary/5 via-background to-background p-6 sm:p-8", children: [_jsx(PackageIcon, { iconUrl: pkg.icon_url, displayName: loc.displayName, manifestId: pkg.manifest_id, className: "h-20 w-20 rounded-2xl shadow-sm ring-1 ring-border shrink-0", initialClassName: "text-3xl font-bold" }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [_jsx("h1", { className: "text-2xl sm:text-3xl font-bold tracking-tight truncate", children: loc.displayName || pkg.manifest_id }), pkg.homepage_url && (_jsxs("a", { href: pkg.homepage_url, target: "_blank", rel: "noopener noreferrer", className: "inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors", title: t('marketplace.detail.homepage'), children: [_jsx(ExternalLink, { className: "h-3.5 w-3.5", "aria-hidden": "true" }), _jsx("span", { className: "hidden sm:inline", children: t('marketplace.detail.homepage') })] }))] }), _jsxs("div", { className: "text-sm text-muted-foreground mt-2 flex flex-wrap items-center gap-1.5", children: [_jsx("code", { className: "font-mono text-xs px-1.5 py-0.5 rounded bg-muted", children: pkg.manifest_id }), latestVersion && _jsx(Badge, { variant: "outline", children: t('marketplace.versionBadge', { version: latestVersion }) }), pkg.publisher && pkg.publisher !== 'private' && (_jsx(Badge, { variant: pkg.publisher === 'objectstack' ? 'default' : 'secondary', children: pkg.publisher })), categoryLabel && _jsx(Badge, { variant: "outline", children: categoryLabel }), pkg.license && _jsx(Badge, { variant: "outline", className: "font-normal", children: pkg.license }), localInstall && (_jsxs(Badge, { variant: "default", className: "bg-green-600 hover:bg-green-600 gap-1", children: [_jsx(CheckCircle2, { className: "h-3 w-3", "aria-hidden": "true" }), t('marketplace.detail.installedV', { version: localInstall.version })] }))
|
|
282
|
-
|
|
499
|
+
return (_jsxs("div", { className: "mx-auto w-full max-w-6xl flex flex-col gap-6 p-4 sm:p-6", children: [_jsxs(Button, { variant: "ghost", size: "sm", className: "self-start -ml-2 text-muted-foreground hover:text-foreground", onClick: () => navigate(`${basePath}/system/marketplace`), children: [_jsx(ArrowLeft, { className: "h-4 w-4 mr-1.5", "aria-hidden": "true" }), t('marketplace.back')] }), _jsxs("div", { className: "flex items-start gap-5 flex-wrap sm:flex-nowrap rounded-2xl border bg-gradient-to-br from-primary/5 via-background to-background p-6 sm:p-8", children: [_jsx(PackageIcon, { iconUrl: pkg.icon_url, displayName: loc.displayName, manifestId: pkg.manifest_id, className: "h-20 w-20 rounded-2xl shadow-sm ring-1 ring-border shrink-0", initialClassName: "text-3xl font-bold" }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [_jsx("h1", { className: "text-2xl sm:text-3xl font-bold tracking-tight truncate", children: loc.displayName || pkg.manifest_id }), pkg.homepage_url && (_jsxs("a", { href: pkg.homepage_url, target: "_blank", rel: "noopener noreferrer", className: "inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors", title: t('marketplace.detail.homepage'), children: [_jsx(ExternalLink, { className: "h-3.5 w-3.5", "aria-hidden": "true" }), _jsx("span", { className: "hidden sm:inline", children: t('marketplace.detail.homepage') })] }))] }), _jsxs("div", { className: "text-sm text-muted-foreground mt-2 flex flex-wrap items-center gap-1.5", children: [_jsx("code", { className: "font-mono text-xs px-1.5 py-0.5 rounded bg-muted", children: pkg.manifest_id }), latestVersion && _jsx(Badge, { variant: "outline", children: t('marketplace.versionBadge', { version: latestVersion }) }), pkg.publisher && pkg.publisher !== 'private' && (_jsx(Badge, { variant: pkg.publisher === 'objectstack' ? 'default' : 'secondary', children: pkg.publisher })), categoryLabel && _jsx(Badge, { variant: "outline", children: categoryLabel }), pkg.license && _jsx(Badge, { variant: "outline", className: "font-normal", children: pkg.license }), localInstall && (_jsxs(Badge, { variant: "default", className: "bg-green-600 hover:bg-green-600 gap-1", children: [_jsx(CheckCircle2, { className: "h-3 w-3", "aria-hidden": "true" }), t('marketplace.detail.installedV', { version: localInstall.version })] })), !localInstall && cloudInstalledVersion && (_jsxs(Badge, { variant: "default", className: "bg-green-600 hover:bg-green-600 gap-1", children: [_jsx(CheckCircle2, { className: "h-3 w-3", "aria-hidden": "true" }), t('marketplace.detail.installedV', { version: cloudInstalledVersion })] })), cloudUpdateAvailable && (_jsxs(Badge, { variant: "default", className: "bg-amber-500 hover:bg-amber-500 gap-1", children: [_jsx(ArrowUpCircle, { className: "h-3 w-3", "aria-hidden": "true" }), t('marketplace.detail.updateAvailable', { defaultValue: 'Update available' }), " \u2192 v", latestVersion] }))] }), loc.description && (_jsx("p", { className: "text-sm sm:text-base text-foreground/80 mt-3 max-w-2xl leading-relaxed", children: loc.description }))] }), _jsxs("div", { className: "flex items-center gap-2 shrink-0 self-start", children: [_jsxs(Button, { onClick: primaryAction.onClick, disabled: primaryDisabled, size: "lg", className: "min-w-[8rem]", children: [_jsx(Download, { className: "h-4 w-4 mr-1.5", "aria-hidden": "true" }), primaryAction.label] }), localInstall && (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "outline", size: "lg", className: "px-2.5", "aria-label": t('marketplace.detail.moreOptions'), children: _jsx(MoreHorizontal, { className: "h-4 w-4", "aria-hidden": "true" }) }) }), _jsxs(DropdownMenuContent, { align: "end", className: "w-56", children: [_jsxs(DropdownMenuItem, { onSelect: doReseedLocalSampleData, disabled: sampleDataBusy !== null, children: [sampleDataBusy === 'reseed'
|
|
500
|
+
? _jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin", "aria-hidden": "true" })
|
|
501
|
+
: _jsx(Database, { className: "h-4 w-4 mr-2", "aria-hidden": "true" }), localInstall.withSampleData
|
|
502
|
+
? (t('marketplace.detail.reseedAgain') || 'Re-seed sample data')
|
|
503
|
+
: (t('marketplace.detail.addSampleData') || 'Add sample data')] }), _jsxs(DropdownMenuItem, { onSelect: doPurgeLocalSampleData, disabled: sampleDataBusy !== null || !localInstall.withSampleData, className: "text-destructive focus:text-destructive", children: [sampleDataBusy === 'purge'
|
|
504
|
+
? _jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin", "aria-hidden": "true" })
|
|
505
|
+
: _jsx(Trash2, { className: "h-4 w-4 mr-2", "aria-hidden": "true" }), t('marketplace.detail.purgeSampleData') || 'Purge sample data'] }), _jsxs(DropdownMenuItem, { onSelect: doUninstallLocal, disabled: installingLocal, className: "text-destructive focus:text-destructive", children: [_jsx(Trash2, { className: "h-4 w-4 mr-2", "aria-hidden": "true" }), t('marketplace.detail.uninstallFromRuntime')] })] })] })), !localInstall && cloudInstall && !getRuntimeConfig().cloudUrl && (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "outline", size: "lg", className: "px-2.5", "aria-label": t('marketplace.detail.moreOptions') || 'More options', children: _jsx(MoreHorizontal, { className: "h-4 w-4", "aria-hidden": "true" }) }) }), _jsxs(DropdownMenuContent, { align: "end", className: "w-56", children: [_jsxs(DropdownMenuItem, { onSelect: doReseedSampleData, disabled: sampleDataBusy !== null, children: [sampleDataBusy === 'reseed'
|
|
506
|
+
? _jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin", "aria-hidden": "true" })
|
|
507
|
+
: _jsx(Database, { className: "h-4 w-4 mr-2", "aria-hidden": "true" }), cloudInstall.withSampleData
|
|
508
|
+
? (t('marketplace.detail.reseedAgain') || 'Re-seed sample data')
|
|
509
|
+
: (t('marketplace.detail.addSampleData') || 'Add sample data')] }), _jsxs(DropdownMenuItem, { onSelect: doPurgeSampleData, disabled: sampleDataBusy !== null || !cloudInstall.withSampleData, className: "text-destructive focus:text-destructive", children: [sampleDataBusy === 'purge'
|
|
510
|
+
? _jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin", "aria-hidden": "true" })
|
|
511
|
+
: _jsx(Trash2, { className: "h-4 w-4 mr-2", "aria-hidden": "true" }), t('marketplace.detail.purgeSampleData') || 'Purge sample data'] })] })] }))] })] }), sampleDataMsg && (_jsxs("div", { role: "status", className: `flex items-start gap-2 rounded-md border p-3 text-sm ${sampleDataMsg.ok ? 'border-green-500/30 bg-green-500/5 text-green-700 dark:text-green-400' : 'border-destructive/30 bg-destructive/5 text-destructive'}`, children: [sampleDataMsg.ok ? _jsx(CheckCircle2, { className: "h-4 w-4 mt-0.5 shrink-0", "aria-hidden": "true" }) : _jsx(AlertCircle, { className: "h-4 w-4 mt-0.5 shrink-0", "aria-hidden": "true" }), _jsx("div", { className: "flex-1", children: sampleDataMsg.text }), _jsx("button", { type: "button", className: "text-xs underline opacity-60 hover:opacity-100", onClick: () => setSampleDataMsg(null), children: t('marketplace.action.dismiss') })] })), localResult && (_jsxs("div", { role: "status", className: `flex items-start gap-2 rounded-md border p-3 text-sm whitespace-pre-wrap ${localResult.ok ? 'border-green-500/30 bg-green-500/5 text-green-700 dark:text-green-400' : 'border-destructive/30 bg-destructive/5 text-destructive'}`, children: [localResult.ok ? _jsx(CheckCircle2, { className: "h-4 w-4 mt-0.5 shrink-0", "aria-hidden": "true" }) : _jsx(AlertCircle, { className: "h-4 w-4 mt-0.5 shrink-0", "aria-hidden": "true" }), _jsx("div", { className: "flex-1", children: localResult.message }), _jsx("button", { type: "button", className: "text-xs underline opacity-60 hover:opacity-100", onClick: () => setLocalResult(null), children: t('marketplace.action.dismiss') })] })), _jsxs("div", { className: "grid gap-4 lg:grid-cols-3", children: [_jsx("div", { className: "lg:col-span-2 space-y-4", children: _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsx(CardTitle, { className: "text-base", children: t('marketplace.detail.about') }) }), _jsx(CardContent, { children: loc.readme ? (_jsx(MarkdownText, { source: loc.readme })) : (_jsx("p", { className: "text-sm text-muted-foreground", children: t('marketplace.detail.noReadme') })) })] }) }), _jsx("div", { className: "space-y-4", children: _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsx(CardTitle, { className: "text-base", children: t('marketplace.detail.versions') }) }), _jsx(CardContent, { children: data.versions.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: t('marketplace.detail.noApprovedVersions') })) : (_jsx("ul", { className: "space-y-3", children: data.versions.map((v) => (_jsxs("li", { className: "space-y-1 text-sm", children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsxs("span", { className: "flex items-center gap-1.5", children: [_jsx(Package, { className: "h-3.5 w-3.5 text-muted-foreground", "aria-hidden": "true" }), _jsxs("code", { className: "font-mono", children: ["v", v.version] }), v.is_prerelease && _jsx(Badge, { variant: "outline", className: "text-xs", children: t('marketplace.detail.prerelease') })] }), _jsx("span", { className: "text-xs text-muted-foreground", children: v.published_at ? new Date(v.published_at).toLocaleDateString() : '\u2014' })] }), v.release_notes && v.release_notes.trim() && (_jsx("p", { className: "whitespace-pre-line pl-5 text-xs text-muted-foreground", children: v.release_notes.trim() }))] }, v.id))) })) })] }) })] }), _jsx(Dialog, { open: installOpen, onOpenChange: (o) => { setInstallOpen(o); if (!o) {
|
|
512
|
+
setInstallResult(null);
|
|
513
|
+
setAcknowledged(false);
|
|
514
|
+
} }, children: _jsxs(DialogContent, { children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: t('marketplace.install.dialogTitle', { name: loc.displayName || pkg.manifest_id }) }), _jsx(DialogDescription, { children: getRuntimeConfig().defaultEnvironmentId
|
|
283
515
|
? t('marketplace.install.dialogDescCurrent', { host: typeof window !== 'undefined' ? window.location.host : '' })
|
|
284
|
-
: t('marketplace.install.dialogDescPicker') })] }), envsLoading ? (_jsx(Skeleton, { className: "h-10 w-full" })) : envsError ? (_jsxs("div", { className: "rounded-md border border-amber-500/30 bg-amber-500/5 p-3 text-sm space-y-2", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx(AlertCircle, { className: "h-4 w-4 mt-0.5 text-amber-600", "aria-hidden": "true" }), _jsx("div", { className: "flex-1", children: envsError })] }), _jsx("a", { href: cloudInstallDeepLink(pkg.id), target: "_blank", rel: "noopener noreferrer", children: _jsxs(Button, { variant: "outline", size: "sm", className: "w-full", children: [_jsx(ExternalLink, { className: "h-4 w-4 mr-1.5", "aria-hidden": "true" }), t('marketplace.action.openOnCloud')] }) })] })) : getRuntimeConfig().defaultEnvironmentId ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: "seed", checked: seedSampleData, onCheckedChange: (c) => setSeedSampleData(c === true) }), _jsx(Label, { htmlFor: "seed", className: "text-sm font-normal cursor-pointer", children: t('marketplace.install.includeSampleData') })] })) : envs.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: t('marketplace.install.noEnvs') })) : (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "env-select", children: t('marketplace.install.environment') }), _jsxs(Select, { value: selectedEnv, onValueChange: setSelectedEnv, children: [_jsx(SelectTrigger, { id: "env-select", children: _jsx(SelectValue, { placeholder: t('marketplace.install.environmentPlaceholder') }) }), _jsx(SelectContent, { children: envs.map((e) =>
|
|
516
|
+
: t('marketplace.install.dialogDescPicker') })] }), envsLoading ? (_jsx(Skeleton, { className: "h-10 w-full" })) : envsError ? (_jsxs("div", { className: "rounded-md border border-amber-500/30 bg-amber-500/5 p-3 text-sm space-y-2", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx(AlertCircle, { className: "h-4 w-4 mt-0.5 text-amber-600", "aria-hidden": "true" }), _jsx("div", { className: "flex-1", children: envsError })] }), _jsx("a", { href: cloudInstallDeepLink(pkg.id), target: "_blank", rel: "noopener noreferrer", children: _jsxs(Button, { variant: "outline", size: "sm", className: "w-full", children: [_jsx(ExternalLink, { className: "h-4 w-4 mr-1.5", "aria-hidden": "true" }), t('marketplace.action.openOnCloud')] }) })] })) : getRuntimeConfig().defaultEnvironmentId ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: "seed", checked: seedSampleData, onCheckedChange: (c) => setSeedSampleData(c === true) }), _jsx(Label, { htmlFor: "seed", className: "text-sm font-normal cursor-pointer", children: t('marketplace.install.includeSampleData') })] })) : envs.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: t('marketplace.install.noEnvs') })) : (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "env-select", children: t('marketplace.install.environment') }), _jsxs(Select, { value: selectedEnv, onValueChange: setSelectedEnv, children: [_jsx(SelectTrigger, { id: "env-select", children: _jsx(SelectValue, { placeholder: t('marketplace.install.environmentPlaceholder') }) }), _jsx(SelectContent, { children: envs.map((e) => {
|
|
517
|
+
const installedHere = envInstallMap[e.id];
|
|
518
|
+
const hasUpdate = !!installedHere && !!latestVersion
|
|
519
|
+
&& installedHere !== 'installed' && installedHere !== latestVersion;
|
|
520
|
+
return (_jsxs(SelectItem, { value: e.id, children: [e.display_name || e.hostname || e.id, e.plan && _jsxs("span", { className: "text-muted-foreground", children: [" \u00B7 ", e.plan] }), installedHere && (hasUpdate
|
|
521
|
+
? _jsxs("span", { className: "text-amber-600", children: [" \u00B7 ", t('marketplace.install.updateTo', { defaultValue: 'Update \u2192 v{{version}}', version: latestVersion })] })
|
|
522
|
+
: _jsxs("span", { className: "text-muted-foreground", children: [" \u00B7 ", t('marketplace.install.installedVersion', { defaultValue: 'Installed v{{version}}', version: installedHere })] }))] }, e.id));
|
|
523
|
+
}) })] })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: "seed", checked: seedSampleData, onCheckedChange: (c) => setSeedSampleData(c === true) }), _jsx(Label, { htmlFor: "seed", className: "text-sm font-normal cursor-pointer", children: t('marketplace.install.includeSampleData') })] })] })), containsCode && !envsError && (_jsxs("div", { className: "space-y-3", children: [_jsx(PluginDisclosure, { version: pkg.latest_version }), _jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Checkbox, { id: "ack-perms", checked: acknowledged, onCheckedChange: (c) => setAcknowledged(c === true) }), _jsx(Label, { htmlFor: "ack-perms", className: "text-sm font-normal cursor-pointer leading-snug", children: t('marketplace.disclosure.acknowledge', {
|
|
524
|
+
defaultValue: 'I understand this package runs code and grants the permissions above.',
|
|
525
|
+
}) })] })] })), installResult && (_jsx("div", { className: `rounded-md border p-3 text-sm ${installResult.ok ? 'border-green-500/30 bg-green-500/5 text-green-700' : 'border-destructive/30 bg-destructive/5 text-destructive'}`, children: installResult.message })), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "outline", onClick: () => setInstallOpen(false), children: t('marketplace.action.close') }), !envsError && (_jsx(Button, { onClick: doInstall, disabled: !selectedEnv || installing || installResult?.ok === true || (containsCode && !acknowledged), children: installing ? t('marketplace.action.installing') : t('marketplace.action.install') }))] })] }) })] }));
|
|
285
526
|
}
|
|
@@ -5,4 +5,4 @@
|
|
|
5
5
|
* `/api/v1/marketplace/packages` proxy (which forwards to the configured
|
|
6
6
|
* cloud control plane). Click-through opens the package detail page.
|
|
7
7
|
*/
|
|
8
|
-
export declare function MarketplacePage(): import("react
|
|
8
|
+
export declare function MarketplacePage(): import("react").JSX.Element;
|
|
@@ -15,7 +15,9 @@ import { useObjectTranslation } from '@object-ui/i18n';
|
|
|
15
15
|
import { PackageIcon } from './PackageIcon';
|
|
16
16
|
import { MarketplaceAccessDenied } from './MarketplaceAccessDenied';
|
|
17
17
|
import { localizePackage } from './usePackageL10n';
|
|
18
|
-
import { listMarketplacePackages, listLocalInstalls, } from './marketplaceApi';
|
|
18
|
+
import { listMarketplacePackages, listLocalInstalls, listOrgPackages, listInstalledPackages, installPackage, installLocal, } from './marketplaceApi';
|
|
19
|
+
import { getRuntimeConfig } from '../../runtime-config';
|
|
20
|
+
import { emitMetadataRefresh } from '../../assistant/assistantBus';
|
|
19
21
|
/**
|
|
20
22
|
* Format a published-at timestamp as a localized relative string.
|
|
21
23
|
*
|
|
@@ -64,6 +66,12 @@ export function MarketplacePage() {
|
|
|
64
66
|
const [query, setQuery] = useState('');
|
|
65
67
|
const [category, setCategory] = useState('');
|
|
66
68
|
const [installed, setInstalled] = useState([]);
|
|
69
|
+
// ADR-0007 step ②: the org's own packages (visibility org/private), shown in
|
|
70
|
+
// a "Your organization" section and installable inline (no public listing).
|
|
71
|
+
const [orgItems, setOrgItems] = useState([]);
|
|
72
|
+
const [orgInstalling, setOrgInstalling] = useState(null);
|
|
73
|
+
const [orgMsg, setOrgMsg] = useState(null);
|
|
74
|
+
const [installedIds, setInstalledIds] = useState(new Set());
|
|
67
75
|
const installedByManifestId = useMemo(() => {
|
|
68
76
|
const m = new Map();
|
|
69
77
|
for (const e of installed)
|
|
@@ -74,12 +82,21 @@ export function MarketplacePage() {
|
|
|
74
82
|
setLoading(true);
|
|
75
83
|
setError(null);
|
|
76
84
|
try {
|
|
77
|
-
const [resp, installs] = await Promise.all([
|
|
85
|
+
const [resp, installs, org, cloudInstalled] = await Promise.all([
|
|
78
86
|
listMarketplacePackages({ limit: 100 }),
|
|
79
87
|
listLocalInstalls(),
|
|
88
|
+
listOrgPackages(),
|
|
89
|
+
listInstalledPackages(),
|
|
80
90
|
]);
|
|
81
91
|
setItems(resp.items ?? []);
|
|
82
92
|
setInstalled(installs);
|
|
93
|
+
setOrgItems(org.items ?? []);
|
|
94
|
+
const ids = new Set();
|
|
95
|
+
for (const e of installs)
|
|
96
|
+
ids.add(e.manifestId);
|
|
97
|
+
for (const e of cloudInstalled.items)
|
|
98
|
+
ids.add(e.manifestId);
|
|
99
|
+
setInstalledIds(ids);
|
|
83
100
|
}
|
|
84
101
|
catch (e) {
|
|
85
102
|
setError(e?.message ?? String(e));
|
|
@@ -90,6 +107,41 @@ export function MarketplacePage() {
|
|
|
90
107
|
}
|
|
91
108
|
};
|
|
92
109
|
useEffect(() => { void load(); }, []);
|
|
110
|
+
// Install an org package into the current environment (ADR-0007 step ②).
|
|
111
|
+
//
|
|
112
|
+
// Two deployment shapes, two semantically-correct routes:
|
|
113
|
+
// - install-local runtimes (single-env / self-hosted, runtime-config
|
|
114
|
+
// features.installLocal=true): the runtime OWNS its desired state —
|
|
115
|
+
// install merges into ITS kernel via /marketplace/install-local; the
|
|
116
|
+
// bound oscc_ credential lets it fetch the org manifest (ADR-0008).
|
|
117
|
+
// The control-plane /cloud-connection/install path would 401 here
|
|
118
|
+
// (no env→cloud service key) and is the wrong semantics anyway.
|
|
119
|
+
// - cloud-managed environments: desired state lives in the control
|
|
120
|
+
// plane — /cloud-connection/install resolves the env by hostname.
|
|
121
|
+
const doOrgInstall = async (pkg) => {
|
|
122
|
+
setOrgInstalling(pkg.id);
|
|
123
|
+
setOrgMsg(null);
|
|
124
|
+
try {
|
|
125
|
+
if (getRuntimeConfig().features.installLocal) {
|
|
126
|
+
await installLocal({ packageId: pkg.manifest_id || pkg.id, versionId: 'latest' });
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
await installPackage({ packageId: pkg.id, environmentId: '', seedSampleData: true });
|
|
130
|
+
}
|
|
131
|
+
setOrgMsg({ ok: true, text: t('marketplace.org.installed', { defaultValue: `Installed ${pkg.display_name}`, name: pkg.display_name }) });
|
|
132
|
+
await load();
|
|
133
|
+
// The install merged a package into the live registry. Pulse every
|
|
134
|
+
// mounted MetadataProvider so the new app appears in the nav (and its
|
|
135
|
+
// objects/views resolve) without a manual browser refresh.
|
|
136
|
+
emitMetadataRefresh();
|
|
137
|
+
}
|
|
138
|
+
catch (e) {
|
|
139
|
+
setOrgMsg({ ok: false, text: e?.message ?? String(e) });
|
|
140
|
+
}
|
|
141
|
+
finally {
|
|
142
|
+
setOrgInstalling(null);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
93
145
|
const categories = useMemo(() => {
|
|
94
146
|
const s = new Set();
|
|
95
147
|
for (const it of items) {
|
|
@@ -123,7 +175,12 @@ export function MarketplacePage() {
|
|
|
123
175
|
? t('marketplace.installedCount', { count: installed.length })
|
|
124
176
|
: t('marketplace.installed')] }), _jsxs(Button, { variant: "outline", size: "sm", onClick: () => void load(), disabled: loading, children: [_jsx(RefreshCcw, { className: "h-4 w-4 mr-1.5", "aria-hidden": "true" }), t('marketplace.refresh')] })] })] }), _jsxs("div", { className: "flex flex-col sm:flex-row gap-3", children: [_jsxs("div", { className: "relative flex-1", children: [_jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground", "aria-hidden": "true" }), _jsx(Input, { value: query, onChange: (e) => setQuery(e.target.value), placeholder: t('marketplace.searchPlaceholder'), className: "pl-9", "aria-label": t('marketplace.searchAria') })] }), categories.length > 0 && (_jsxs("div", { className: "flex flex-wrap gap-1.5", children: [_jsx(Button, { size: "sm", variant: category === '' ? 'default' : 'outline', onClick: () => setCategory(''), children: t('marketplace.all') }), categories.map((cat) => (_jsx(Button, { size: "sm", variant: category === cat ? 'default' : 'outline', onClick: () => setCategory(cat), children: categoryLabel(cat) }, cat)))] }))] }), error && (_jsxs("div", { className: "flex items-start gap-3 rounded-md border border-destructive/30 bg-destructive/5 p-4 text-sm", children: [_jsx(AlertCircle, { className: "h-4 w-4 mt-0.5 text-destructive", "aria-hidden": "true" }), _jsxs("div", { children: [_jsx("div", { className: "font-medium text-destructive", children: t('marketplace.load.failed') }), _jsx("div", { className: "text-muted-foreground mt-1", children: error }), _jsx("div", { className: "text-xs text-muted-foreground mt-2",
|
|
125
177
|
// Hint message contains an inline <code> tag — render translated HTML safely from our own bundle.
|
|
126
|
-
dangerouslySetInnerHTML: { __html: t('marketplace.load.failedHint') } })] })] })),
|
|
178
|
+
dangerouslySetInnerHTML: { __html: t('marketplace.load.failedHint') } })] })] })), orgItems.length > 0 && (_jsxs("section", { className: "flex flex-col gap-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Store, { className: "h-5 w-5 text-primary", "aria-hidden": "true" }), _jsx("h2", { className: "text-sm font-semibold", children: t('marketplace.org.heading', { defaultValue: 'Your organization' }) }), _jsx(Badge, { variant: "secondary", className: "text-xs", children: orgItems.length })] }), orgMsg && (_jsx("div", { className: `rounded-md border p-3 text-sm ${orgMsg.ok ? 'border-green-500/30 bg-green-500/5 text-green-700 dark:text-green-400' : 'border-destructive/30 bg-destructive/5 text-destructive'}`, children: orgMsg.text })), _jsx("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3", children: orgItems.map((pkg) => {
|
|
179
|
+
const isInstalled = installedIds.has(pkg.manifest_id);
|
|
180
|
+
return (_jsxs(Card, { className: "flex flex-col", "data-testid": `org-card-${pkg.manifest_id}`, children: [_jsxs(CardHeader, { className: "flex flex-row items-start gap-3 pb-2", children: [_jsx(PackageIcon, { iconUrl: pkg.icon_url, displayName: pkg.display_name, manifestId: pkg.manifest_id }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx(CardTitle, { className: "text-base truncate", children: pkg.display_name }), _jsx(CardDescription, { className: "text-xs truncate", children: _jsx("code", { className: "font-mono", children: pkg.manifest_id }) })] }), pkg.visibility && (_jsx(Badge, { variant: "outline", className: "shrink-0 text-xs", children: pkg.visibility }))] }), _jsxs(CardContent, { className: "flex-1 flex flex-col gap-2", children: [_jsx("p", { className: "text-sm text-muted-foreground line-clamp-2", children: pkg.description || t('marketplace.noDescription') }), _jsxs("div", { className: "flex items-center gap-2 mt-auto pt-2 flex-wrap", children: [pkg.latest_version && (_jsxs(Badge, { variant: "outline", className: "text-xs", children: [_jsx(Package, { className: "h-3 w-3 mr-1", "aria-hidden": "true" }), t('marketplace.versionBadge', { version: pkg.latest_version })] })), _jsx("div", { className: "ml-auto", children: isInstalled ? (_jsxs(Badge, { variant: "default", className: "text-xs bg-green-600 hover:bg-green-600", children: [_jsx(CheckCircle2, { className: "h-3 w-3 mr-1", "aria-hidden": "true" }), t('marketplace.org.installedBadge', { defaultValue: 'Installed' })] })) : (_jsx(Button, { size: "sm", onClick: () => void doOrgInstall(pkg), disabled: orgInstalling === pkg.id, children: orgInstalling === pkg.id
|
|
181
|
+
? t('marketplace.org.installing', { defaultValue: 'Installing…' })
|
|
182
|
+
: t('marketplace.org.install', { defaultValue: 'Install' }) })) })] })] })] }, pkg.id));
|
|
183
|
+
}) }), _jsx("div", { className: "border-b pt-2" })] })), loading && items.length === 0 ? (_jsx("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3", children: Array.from({ length: 6 }).map((_, i) => (_jsxs(Card, { children: [_jsxs(CardHeader, { className: "pb-2", children: [_jsx(Skeleton, { className: "h-10 w-10 rounded-lg mb-2" }), _jsx(Skeleton, { className: "h-5 w-3/4" }), _jsx(Skeleton, { className: "h-4 w-1/2 mt-1" })] }), _jsx(CardContent, { children: _jsx(Skeleton, { className: "h-12 w-full" }) })] }, i))) })) : filtered.length === 0 ? (_jsx("div", { className: "text-center py-12 text-sm text-muted-foreground", children: items.length === 0 ? t('marketplace.noApprovedYet') : t('marketplace.noMatchFilters') })) : (_jsx("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3", children: filtered.map((pkg) => {
|
|
127
184
|
const localEntry = installedByManifestId.get(pkg.manifest_id);
|
|
128
185
|
const loc = localizePackage(pkg, language);
|
|
129
186
|
return (_jsxs(Card, { className: "cursor-pointer transition-colors hover:bg-accent/50 flex flex-col", onClick: () => navigate(`${basePath}/system/marketplace/${pkg.id}`), role: "link", tabIndex: 0, onKeyDown: (e) => {
|
|
@@ -16,4 +16,4 @@ export interface PackageIconProps {
|
|
|
16
16
|
/** Text size for the initial-letter fallback. */
|
|
17
17
|
initialClassName?: string;
|
|
18
18
|
}
|
|
19
|
-
export declare function PackageIcon({ iconUrl, displayName, manifestId, className, initialClassName, }: PackageIconProps): import("react
|
|
19
|
+
export declare function PackageIcon({ iconUrl, displayName, manifestId, className, initialClassName, }: PackageIconProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin permission disclosure (ADR-0025 PD4 §3.5 / §3.11).
|
|
3
|
+
*
|
|
4
|
+
* Rendered in the install dialog for a code-bearing package. Shows what the
|
|
5
|
+
* user is consenting to BEFORE install: that the package contains code, the
|
|
6
|
+
* trust tier it runs under, whether it is signed / marketplace-reviewed, and
|
|
7
|
+
* the exact structured permission set it requests. The control plane exposes
|
|
8
|
+
* verification STATUS only (never raw signatures); see cloud
|
|
9
|
+
* marketplace.projectVersion.
|
|
10
|
+
*/
|
|
11
|
+
import type { MarketplacePackageVersion } from './marketplaceApi';
|
|
12
|
+
export declare function PluginDisclosure({ version }: {
|
|
13
|
+
version?: MarketplacePackageVersion | null;
|
|
14
|
+
}): import("react").JSX.Element | null;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Plugin permission disclosure (ADR-0025 PD4 §3.5 / §3.11).
|
|
4
|
+
*
|
|
5
|
+
* Rendered in the install dialog for a code-bearing package. Shows what the
|
|
6
|
+
* user is consenting to BEFORE install: that the package contains code, the
|
|
7
|
+
* trust tier it runs under, whether it is signed / marketplace-reviewed, and
|
|
8
|
+
* the exact structured permission set it requests. The control plane exposes
|
|
9
|
+
* verification STATUS only (never raw signatures); see cloud
|
|
10
|
+
* marketplace.projectVersion.
|
|
11
|
+
*/
|
|
12
|
+
import { Badge } from '@object-ui/components';
|
|
13
|
+
import { Boxes, CheckCircle2, Code2, FolderTree, Network, ShieldAlert, ShieldCheck, Webhook } from 'lucide-react';
|
|
14
|
+
import { useObjectTranslation } from '@object-ui/i18n';
|
|
15
|
+
const RUNTIME_FALLBACK = {
|
|
16
|
+
node: 'In-process · full trust',
|
|
17
|
+
sandbox: 'Sandboxed',
|
|
18
|
+
worker: 'Out-of-process',
|
|
19
|
+
};
|
|
20
|
+
function PermissionGroup({ icon: Icon, label, items, }) {
|
|
21
|
+
if (!items || items.length === 0)
|
|
22
|
+
return null;
|
|
23
|
+
return (_jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Icon, { className: "h-3.5 w-3.5 mt-0.5 text-muted-foreground shrink-0", "aria-hidden": "true" }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("div", { className: "text-xs font-medium", children: label }), _jsx("div", { className: "flex flex-wrap gap-1 mt-0.5", children: items.map((it) => (_jsx("code", { className: "font-mono text-[11px] px-1 py-0.5 rounded bg-muted break-all", children: it }, it))) })] })] }));
|
|
24
|
+
}
|
|
25
|
+
export function PluginDisclosure({ version }) {
|
|
26
|
+
const { t } = useObjectTranslation();
|
|
27
|
+
if (!version?.contains_code)
|
|
28
|
+
return null;
|
|
29
|
+
const perms = version.permissions ?? {};
|
|
30
|
+
const hasAny = (perms.services?.length ?? 0) +
|
|
31
|
+
(perms.hooks?.length ?? 0) +
|
|
32
|
+
(perms.network?.length ?? 0) +
|
|
33
|
+
(perms.fs?.length ?? 0) >
|
|
34
|
+
0;
|
|
35
|
+
return (_jsxs("div", { className: "rounded-md border border-amber-500/30 bg-amber-500/5 p-3 space-y-3 text-sm", children: [_jsxs("div", { className: "flex items-center gap-2 font-medium", children: [_jsx(Code2, { className: "h-4 w-4 text-amber-600 shrink-0", "aria-hidden": "true" }), t('marketplace.disclosure.containsCode', { defaultValue: 'This package contains code' })] }), _jsxs("div", { className: "flex flex-wrap items-center gap-1.5", children: [version.runtime && (_jsx(Badge, { variant: "outline", children: t(`marketplace.disclosure.runtime.${version.runtime}`, {
|
|
36
|
+
defaultValue: RUNTIME_FALLBACK[version.runtime] ?? version.runtime,
|
|
37
|
+
}) })), version.platform_verified ? (_jsxs(Badge, { variant: "outline", className: "gap-1 border-green-500/40 text-green-700 dark:text-green-400", children: [_jsx(ShieldCheck, { className: "h-3 w-3", "aria-hidden": "true" }), t('marketplace.disclosure.reviewed', { defaultValue: 'Reviewed & approved' })] })) : (_jsxs(Badge, { variant: "outline", className: "gap-1 border-amber-500/40 text-amber-700 dark:text-amber-400", children: [_jsx(ShieldAlert, { className: "h-3 w-3", "aria-hidden": "true" }), t('marketplace.disclosure.unreviewed', { defaultValue: 'Not yet reviewed' })] })), version.signed && (_jsxs(Badge, { variant: "outline", className: "gap-1", children: [_jsx(CheckCircle2, { className: "h-3 w-3", "aria-hidden": "true" }), t('marketplace.disclosure.signed', { defaultValue: 'Signed' })] }))] }), hasAny ? (_jsxs("div", { className: "space-y-2", children: [_jsx("div", { className: "text-xs text-muted-foreground", children: t('marketplace.disclosure.grantsIntro', { defaultValue: 'On install, this package will be granted:' }) }), _jsx(PermissionGroup, { icon: Boxes, label: t('marketplace.disclosure.services', { defaultValue: 'Platform services' }), items: perms.services ?? undefined }), _jsx(PermissionGroup, { icon: Webhook, label: t('marketplace.disclosure.hooks', { defaultValue: 'Lifecycle hooks' }), items: perms.hooks ?? undefined }), _jsx(PermissionGroup, { icon: Network, label: t('marketplace.disclosure.network', { defaultValue: 'Network access' }), items: perms.network ?? undefined }), _jsx(PermissionGroup, { icon: FolderTree, label: t('marketplace.disclosure.fs', { defaultValue: 'Filesystem access' }), items: perms.fs ?? undefined })] })) : (_jsx("div", { className: "text-xs text-muted-foreground", children: t('marketplace.disclosure.noPermissions', { defaultValue: 'Requests no special permissions.' }) }))] }));
|
|
38
|
+
}
|