@object-ui/app-shell 6.2.3 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1229 -0
- package/README.md +292 -0
- package/dist/assistant/assistantBus.d.ts +72 -0
- package/dist/assistant/assistantBus.js +133 -0
- package/dist/chrome/CommandPalette.d.ts +1 -1
- package/dist/chrome/CommandPalette.js +26 -22
- package/dist/chrome/ConditionalAuthWrapper.d.ts +1 -1
- package/dist/chrome/ConsoleToaster.d.ts +1 -1
- package/dist/chrome/ConsoleToaster.js +3 -1
- package/dist/chrome/ErrorBoundary.d.ts +1 -1
- package/dist/chrome/KeyboardShortcutsDialog.d.ts +1 -1
- package/dist/chrome/KeyboardShortcutsDialog.js +16 -5
- package/dist/chrome/LoadingScreen.d.ts +1 -1
- package/dist/chrome/LoadingScreen.js +22 -26
- package/dist/chrome/RouteFader.d.ts +1 -1
- package/dist/chrome/ThemeProvider.d.ts +1 -1
- package/dist/components/ManagedByBadge.d.ts +1 -1
- package/dist/console/AppContent.d.ts +1 -1
- package/dist/console/AppContent.js +184 -39
- package/dist/console/ConsoleShell.d.ts +7 -7
- package/dist/console/ConsoleShell.js +32 -3
- package/dist/console/ai/AiChatPage.d.ts +88 -1
- package/dist/console/ai/AiChatPage.js +747 -66
- package/dist/console/ai/ConversationsSidebar.d.ts +26 -1
- package/dist/console/ai/ConversationsSidebar.js +149 -34
- package/dist/console/ai/LiveCanvas.d.ts +28 -0
- package/dist/console/ai/LiveCanvas.js +80 -0
- package/dist/console/ai/reconcileTurn.d.ts +8 -0
- package/dist/console/ai/reconcileTurn.js +20 -0
- package/dist/console/auth/AuthPageLayout.d.ts +1 -1
- package/dist/console/auth/ForgotPasswordPage.d.ts +1 -1
- package/dist/console/auth/LoginPage.d.ts +1 -1
- package/dist/console/auth/RegisterPage.d.ts +1 -1
- package/dist/console/auth/RegisterPage.js +23 -3
- package/dist/console/cloud-connection/CloudConnectionPanel.d.ts +1 -0
- package/dist/console/cloud-connection/CloudConnectionPanel.js +169 -0
- package/dist/console/home/AppCard.d.ts +1 -1
- package/dist/console/home/AppCard.js +6 -12
- package/dist/console/home/HomeAppsStrip.d.ts +8 -0
- package/dist/console/home/HomeAppsStrip.js +61 -0
- package/dist/console/home/HomeLayout.d.ts +1 -1
- package/dist/console/home/HomeLayout.js +3 -1
- package/dist/console/home/HomePage.d.ts +1 -2
- package/dist/console/home/HomePage.js +149 -21
- package/dist/console/home/HomeRail.d.ts +22 -0
- package/dist/console/home/HomeRail.js +62 -0
- package/dist/console/home/QuickActions.d.ts +1 -1
- package/dist/console/home/QuickActions.js +3 -11
- package/dist/console/home/RecentApps.d.ts +1 -1
- package/dist/console/home/RecentApps.js +2 -2
- package/dist/console/home/StarredApps.d.ts +1 -1
- package/dist/console/home/StarredApps.js +2 -2
- package/dist/console/marketplace/InstalledListWidget.d.ts +1 -0
- package/dist/console/marketplace/InstalledListWidget.js +93 -0
- package/dist/console/marketplace/MarkdownText.d.ts +1 -1
- package/dist/console/marketplace/MarketplaceAccessDenied.d.ts +1 -1
- package/dist/console/marketplace/MarketplaceInstalledPage.d.ts +8 -14
- package/dist/console/marketplace/MarketplaceInstalledPage.js +14 -66
- package/dist/console/marketplace/MarketplacePackagePage.d.ts +1 -1
- package/dist/console/marketplace/MarketplacePackagePage.js +249 -8
- package/dist/console/marketplace/MarketplacePage.d.ts +1 -1
- package/dist/console/marketplace/MarketplacePage.js +60 -3
- package/dist/console/marketplace/PackageIcon.d.ts +1 -1
- package/dist/console/marketplace/PluginDisclosure.d.ts +14 -0
- package/dist/console/marketplace/PluginDisclosure.js +38 -0
- package/dist/console/marketplace/marketplaceApi.d.ts +123 -0
- package/dist/console/marketplace/marketplaceApi.js +254 -1
- package/dist/console/organizations/CreateWorkspaceDialog.d.ts +1 -1
- package/dist/console/organizations/OrganizationsLayout.d.ts +1 -1
- package/dist/console/organizations/OrganizationsPage.d.ts +1 -1
- package/dist/console/organizations/manage/AcceptInvitationPage.d.ts +1 -1
- package/dist/console/organizations/manage/InvitationsPage.d.ts +1 -1
- package/dist/console/organizations/manage/InviteMemberDialog.d.ts +1 -1
- package/dist/console/organizations/manage/MembersPage.d.ts +1 -1
- package/dist/console/organizations/manage/OrganizationLayout.d.ts +1 -1
- package/dist/console/organizations/manage/SettingsPage.d.ts +1 -1
- package/dist/context/CommandPaletteProvider.d.ts +44 -0
- package/dist/context/CommandPaletteProvider.js +71 -0
- package/dist/context/FavoritesProvider.d.ts +1 -1
- package/dist/context/NavigationContext.d.ts +1 -1
- package/dist/context/RecentItemsProvider.d.ts +2 -2
- package/dist/context/UserStateAdapters.d.ts +1 -1
- package/dist/context/index.d.ts +2 -0
- package/dist/context/index.js +1 -0
- package/dist/hooks/index.d.ts +5 -2
- package/dist/hooks/index.js +4 -1
- package/dist/hooks/useActionModal.d.ts +53 -0
- package/dist/hooks/useActionModal.js +111 -0
- package/dist/hooks/useChatConversation.d.ts +137 -4
- package/dist/hooks/useChatConversation.js +316 -25
- package/dist/hooks/useConsoleActionRuntime.d.ts +70 -0
- package/dist/hooks/useConsoleActionRuntime.js +564 -0
- package/dist/hooks/useConversationList.js +61 -3
- package/dist/hooks/useHomeInbox.d.ts +13 -0
- package/dist/hooks/useHomeInbox.js +142 -0
- package/dist/hooks/useNavPins.js +17 -23
- package/dist/hooks/useNavigationSync.d.ts +33 -0
- package/dist/hooks/useNavigationSync.js +98 -12
- package/dist/hooks/useReconcileOnError.d.ts +40 -0
- package/dist/hooks/useReconcileOnError.js +37 -0
- package/dist/hooks/useRecordApprovals.d.ts +18 -19
- package/dist/hooks/useRecordApprovals.js +24 -40
- package/dist/hooks/useResponsiveSidebar.js +14 -5
- package/dist/hooks/useSettleSignal.d.ts +19 -0
- package/dist/hooks/useSettleSignal.js +20 -0
- package/dist/hooks/useTrackRouteAsRecent.js +35 -0
- package/dist/hooks/useUrlOverlay.d.ts +62 -0
- package/dist/hooks/useUrlOverlay.js +88 -0
- package/dist/index.d.ts +18 -8
- package/dist/index.js +17 -5
- package/dist/layout/ActivityFeed.d.ts +1 -1
- package/dist/layout/AppHeader.d.ts +3 -2
- package/dist/layout/AppHeader.js +237 -72
- package/dist/layout/AppSidebar.d.ts +2 -1
- package/dist/layout/AppSidebar.js +26 -46
- package/dist/layout/AppSwitcher.d.ts +2 -1
- package/dist/layout/AppSwitcher.js +9 -5
- package/dist/layout/AuthPageLayout.d.ts +1 -1
- package/dist/layout/ConnectionStatus.d.ts +1 -1
- package/dist/layout/ConnectionStatus.js +9 -6
- package/dist/layout/ConsoleChatbotFab.d.ts +19 -1
- package/dist/layout/ConsoleChatbotFab.js +16 -2
- package/dist/layout/ConsoleFloatingChatbot.d.ts +34 -2
- package/dist/layout/ConsoleFloatingChatbot.js +391 -41
- package/dist/layout/ConsoleLayout.d.ts +1 -1
- package/dist/layout/ConsoleLayout.js +27 -11
- package/dist/layout/ContextSelectors.d.ts +44 -0
- package/dist/layout/ContextSelectors.js +242 -0
- package/dist/layout/InboxPopover.d.ts +6 -1
- package/dist/layout/InboxPopover.js +25 -6
- package/dist/layout/LocaleSwitcher.d.ts +1 -1
- package/dist/layout/LocalizedSidebarTrigger.d.ts +2 -0
- package/dist/layout/LocalizedSidebarTrigger.js +15 -0
- package/dist/layout/MobileViewSwitcherContext.d.ts +1 -1
- package/dist/layout/ModeToggle.d.ts +1 -1
- package/dist/layout/PageHeader.d.ts +1 -1
- package/dist/layout/UnifiedSidebar.d.ts +2 -1
- package/dist/layout/UnifiedSidebar.js +116 -15
- package/dist/layout/agentPicker.d.ts +56 -0
- package/dist/layout/agentPicker.js +40 -0
- package/dist/observability/index.d.ts +1 -0
- package/dist/observability/index.js +1 -0
- package/dist/observability/settleSignal.d.ts +64 -0
- package/dist/observability/settleSignal.js +131 -0
- package/dist/preview/CommitTimeline.d.ts +15 -0
- package/dist/preview/CommitTimeline.js +82 -0
- package/dist/preview/DraftChangesPanel.d.ts +19 -0
- package/dist/preview/DraftChangesPanel.js +114 -0
- package/dist/preview/DraftPreviewBar.d.ts +8 -0
- package/dist/preview/DraftPreviewBar.js +86 -0
- package/dist/preview/PreviewDraftEmptyState.d.ts +16 -0
- package/dist/preview/PreviewDraftEmptyState.js +47 -0
- package/dist/preview/PreviewModeContext.d.ts +57 -0
- package/dist/preview/PreviewModeContext.js +99 -0
- package/dist/preview/UnpublishedAppBar.d.ts +8 -0
- package/dist/preview/UnpublishedAppBar.js +83 -0
- package/dist/preview/commitHistory.d.ts +28 -0
- package/dist/preview/commitHistory.js +48 -0
- package/dist/preview/draftStatus.d.ts +20 -0
- package/dist/preview/draftStatus.js +27 -0
- package/dist/preview/usePublishAllDrafts.d.ts +18 -0
- package/dist/preview/usePublishAllDrafts.js +106 -0
- package/dist/providers/AdapterProvider.d.ts +1 -1
- package/dist/providers/AdapterProvider.js +6 -1
- package/dist/providers/ExpressionProvider.d.ts +1 -1
- package/dist/providers/MetadataProvider.d.ts +17 -2
- package/dist/providers/MetadataProvider.js +192 -12
- package/dist/runtime-config.d.ts +46 -2
- package/dist/runtime-config.js +39 -2
- package/dist/services/builtinComponents.js +68 -59
- package/dist/skeletons/SkeletonDashboard.d.ts +1 -1
- package/dist/skeletons/SkeletonDetail.d.ts +1 -1
- package/dist/skeletons/SkeletonGrid.d.ts +1 -1
- package/dist/utils/appRoute.d.ts +21 -0
- package/dist/utils/appRoute.js +25 -0
- package/dist/utils/deriveRelatedLists.d.ts +54 -0
- package/dist/utils/deriveRelatedLists.js +91 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/managedByEmptyState.d.ts +8 -1
- package/dist/utils/managedByEmptyState.js +13 -7
- package/dist/utils/preferLocal.d.ts +18 -0
- package/dist/utils/preferLocal.js +24 -0
- package/dist/views/ActionConfirmDialog.d.ts +1 -1
- package/dist/views/ActionConfirmDialog.js +3 -1
- package/dist/views/ActionParamDialog.d.ts +6 -1
- package/dist/views/ActionParamDialog.js +9 -3
- package/dist/views/ActionResultDialog.d.ts +13 -0
- package/dist/views/ActionResultDialog.js +134 -0
- package/dist/views/ComponentNavView.d.ts +14 -1
- package/dist/views/CreateViewDialog.d.ts +1 -1
- package/dist/views/DashboardConfigPanel.d.ts +28 -0
- package/dist/views/DashboardConfigPanel.js +81 -0
- package/dist/views/DashboardView.d.ts +4 -3
- package/dist/views/DashboardView.js +38 -239
- package/dist/views/FlowRunner.d.ts +31 -0
- package/dist/views/FlowRunner.js +121 -0
- package/dist/views/InterfaceListPage.d.ts +49 -0
- package/dist/views/InterfaceListPage.js +347 -0
- package/dist/views/MetadataInspector.d.ts +2 -2
- package/dist/views/ObjectView.d.ts +1 -1
- package/dist/views/ObjectView.js +209 -532
- package/dist/views/PageView.d.ts +8 -3
- package/dist/views/PageView.js +45 -32
- package/dist/views/RecordDetailView.d.ts +1 -1
- package/dist/views/RecordDetailView.js +363 -148
- package/dist/views/RecordFormPage.d.ts +1 -1
- package/dist/views/RecordFormPage.js +26 -1
- package/dist/views/ReportConfigPanel.d.ts +37 -0
- package/dist/views/ReportConfigPanel.js +85 -0
- package/dist/views/ReportView.d.ts +1 -1
- package/dist/views/ReportView.js +116 -7
- package/dist/views/RuntimeDraftBar.d.ts +30 -0
- package/dist/views/RuntimeDraftBar.js +112 -0
- package/dist/views/ScreenView.d.ts +70 -0
- package/dist/views/ScreenView.js +73 -0
- package/dist/views/SearchResultsPage.d.ts +1 -1
- package/dist/views/SearchResultsPage.js +8 -18
- package/dist/views/ViewConfigPanel.d.ts +24 -17
- package/dist/views/ViewConfigPanel.js +121 -77
- package/dist/views/index.d.ts +1 -1
- package/dist/views/index.js +1 -1
- package/dist/views/metadata-admin/AuditPanel.d.ts +28 -0
- package/dist/views/metadata-admin/AuditPanel.js +79 -0
- package/dist/views/metadata-admin/DiagnosticsPage.d.ts +20 -0
- package/dist/views/metadata-admin/DiagnosticsPage.js +69 -0
- package/dist/views/metadata-admin/DirectoryPage.d.ts +16 -1
- package/dist/views/metadata-admin/DirectoryPage.js +101 -24
- package/dist/views/metadata-admin/DraftReviewPanel.d.ts +33 -0
- package/dist/views/metadata-admin/DraftReviewPanel.js +77 -0
- package/dist/views/metadata-admin/EmbeddedItemEditor.d.ts +17 -1
- package/dist/views/metadata-admin/EmbeddedItemEditor.js +15 -8
- package/dist/views/metadata-admin/JsonSourceEditor.d.ts +39 -0
- package/dist/views/metadata-admin/JsonSourceEditor.js +196 -0
- package/dist/views/metadata-admin/LayeredDiff.d.ts +39 -1
- package/dist/views/metadata-admin/LayeredDiff.js +171 -5
- package/dist/views/metadata-admin/MetadataDetailDrawer.d.ts +15 -1
- package/dist/views/metadata-admin/MetadataTypeActions.d.ts +48 -0
- package/dist/views/metadata-admin/MetadataTypeActions.js +165 -0
- package/dist/views/metadata-admin/PackagesPage.d.ts +18 -0
- package/dist/views/metadata-admin/PackagesPage.js +403 -0
- package/dist/views/metadata-admin/PageShell.d.ts +1 -1
- package/dist/views/metadata-admin/PageShell.js +9 -4
- package/dist/views/metadata-admin/PermissionMatrixEditor.d.ts +35 -1
- package/dist/views/metadata-admin/QuickFind.d.ts +21 -1
- package/dist/views/metadata-admin/QuickFind.js +6 -3
- package/dist/views/metadata-admin/RelatedPanel.d.ts +24 -1
- package/dist/views/metadata-admin/RelatedPanel.js +20 -18
- package/dist/views/metadata-admin/ResourceEditPage.d.ts +40 -1
- package/dist/views/metadata-admin/ResourceEditPage.js +1250 -60
- package/dist/views/metadata-admin/ResourceHistoryPage.d.ts +39 -1
- package/dist/views/metadata-admin/ResourceHistoryPage.js +66 -16
- package/dist/views/metadata-admin/ResourceListPage.d.ts +13 -1
- package/dist/views/metadata-admin/ResourceListPage.js +258 -30
- package/dist/views/metadata-admin/ResourceRouter.d.ts +23 -1
- package/dist/views/metadata-admin/SchemaForm.d.ts +34 -1
- package/dist/views/metadata-admin/SchemaForm.js +559 -49
- package/dist/views/metadata-admin/StudioHomePage.d.ts +22 -0
- package/dist/views/metadata-admin/StudioHomePage.js +205 -0
- package/dist/views/metadata-admin/anchors.js +255 -24
- package/dist/views/metadata-admin/clientValidation.d.ts +50 -0
- package/dist/views/metadata-admin/clientValidation.js +169 -0
- package/dist/views/metadata-admin/color-variant-field.d.ts +30 -0
- package/dist/views/metadata-admin/color-variant-field.js +38 -0
- package/dist/views/metadata-admin/createDerive.d.ts +75 -0
- package/dist/views/metadata-admin/createDerive.js +179 -0
- package/dist/views/metadata-admin/dashboard-schema.d.ts +12 -0
- package/dist/views/metadata-admin/dashboard-schema.js +80 -0
- package/dist/views/metadata-admin/datasource/DatasourceResourcePage.d.ts +35 -0
- package/dist/views/metadata-admin/datasource/DatasourceResourcePage.js +327 -0
- package/dist/views/metadata-admin/datasource/register.d.ts +1 -0
- package/dist/views/metadata-admin/datasource/register.js +24 -0
- package/dist/views/metadata-admin/default-inspector-registry.d.ts +49 -0
- package/dist/views/metadata-admin/default-inspector-registry.js +8 -0
- package/dist/views/metadata-admin/default-schemas.js +115 -10
- package/dist/views/metadata-admin/external/ExternalDatasourcePanel.d.ts +27 -0
- package/dist/views/metadata-admin/external/ExternalDatasourcePanel.js +69 -0
- package/dist/views/metadata-admin/external/ImportObjectDialog.d.ts +27 -0
- package/dist/views/metadata-admin/external/ImportObjectDialog.js +77 -0
- package/dist/views/metadata-admin/external/SchemaBrowser.d.ts +16 -0
- package/dist/views/metadata-admin/external/SchemaBrowser.js +74 -0
- package/dist/views/metadata-admin/external/ValidationPanel.d.ts +16 -0
- package/dist/views/metadata-admin/external/ValidationPanel.js +68 -0
- package/dist/views/metadata-admin/external/api.d.ts +100 -0
- package/dist/views/metadata-admin/external/api.js +124 -0
- package/dist/views/metadata-admin/i18n.d.ts +1 -0
- package/dist/views/metadata-admin/i18n.js +1252 -2
- package/dist/views/metadata-admin/index.d.ts +8 -5
- package/dist/views/metadata-admin/index.js +12 -2
- package/dist/views/metadata-admin/inspector-registry.d.ts +51 -0
- package/dist/views/metadata-admin/inspector-registry.js +11 -0
- package/dist/views/metadata-admin/inspectors/ActionDefaultInspector.d.ts +30 -0
- package/dist/views/metadata-admin/inspectors/ActionDefaultInspector.js +180 -0
- package/dist/views/metadata-admin/inspectors/AppNavInspector.d.ts +16 -0
- package/dist/views/metadata-admin/inspectors/AppNavInspector.js +110 -0
- package/dist/views/metadata-admin/inspectors/ConditionBuilder.d.ts +29 -0
- package/dist/views/metadata-admin/inspectors/ConditionBuilder.js +154 -0
- package/dist/views/metadata-admin/inspectors/DashboardDefaultInspector.d.ts +28 -0
- package/dist/views/metadata-admin/inspectors/DashboardDefaultInspector.js +110 -0
- package/dist/views/metadata-admin/inspectors/DashboardWidgetInspector.d.ts +18 -0
- package/dist/views/metadata-admin/inspectors/DashboardWidgetInspector.js +139 -0
- package/dist/views/metadata-admin/inspectors/DatasetDefaultInspector.d.ts +21 -0
- package/dist/views/metadata-admin/inspectors/DatasetDefaultInspector.js +221 -0
- package/dist/views/metadata-admin/inspectors/FlowEdgeInspector.d.ts +16 -0
- package/dist/views/metadata-admin/inspectors/FlowEdgeInspector.js +126 -0
- package/dist/views/metadata-admin/inspectors/FlowInspector.d.ts +12 -0
- package/dist/views/metadata-admin/inspectors/FlowInspector.js +9 -0
- package/dist/views/metadata-admin/inspectors/FlowKeyValueField.d.ts +30 -0
- package/dist/views/metadata-admin/inspectors/FlowKeyValueField.js +125 -0
- package/dist/views/metadata-admin/inspectors/FlowNodeConfigField.d.ts +18 -0
- package/dist/views/metadata-admin/inspectors/FlowNodeConfigField.js +40 -0
- package/dist/views/metadata-admin/inspectors/FlowNodeInspector.d.ts +14 -0
- package/dist/views/metadata-admin/inspectors/FlowNodeInspector.js +205 -0
- package/dist/views/metadata-admin/inspectors/FlowObjectListField.d.ts +26 -0
- package/dist/views/metadata-admin/inspectors/FlowObjectListField.js +105 -0
- package/dist/views/metadata-admin/inspectors/FlowReferenceField.d.ts +83 -0
- package/dist/views/metadata-admin/inspectors/FlowReferenceField.js +181 -0
- package/dist/views/metadata-admin/inspectors/FlowStringListField.d.ts +21 -0
- package/dist/views/metadata-admin/inspectors/FlowStringListField.js +60 -0
- package/dist/views/metadata-admin/inspectors/InspectorComboField.d.ts +40 -0
- package/dist/views/metadata-admin/inspectors/InspectorComboField.js +61 -0
- package/dist/views/metadata-admin/inspectors/ObjectDefaultInspector.d.ts +21 -0
- package/dist/views/metadata-admin/inspectors/ObjectDefaultInspector.js +55 -0
- package/dist/views/metadata-admin/inspectors/ObjectFieldInspector.d.ts +23 -0
- package/dist/views/metadata-admin/inspectors/ObjectFieldInspector.js +365 -0
- package/dist/views/metadata-admin/inspectors/PageBlockInspector.d.ts +48 -0
- package/dist/views/metadata-admin/inspectors/PageBlockInspector.js +332 -0
- package/dist/views/metadata-admin/inspectors/ReportDefaultInspector.d.ts +58 -0
- package/dist/views/metadata-admin/inspectors/ReportDefaultInspector.js +218 -0
- package/dist/views/metadata-admin/inspectors/ViewColumnInspector.d.ts +19 -0
- package/dist/views/metadata-admin/inspectors/ViewColumnInspector.js +144 -0
- package/dist/views/metadata-admin/inspectors/ViewInspector.d.ts +19 -0
- package/dist/views/metadata-admin/inspectors/ViewInspector.js +21 -0
- package/dist/views/metadata-admin/inspectors/ViewVariantInspector.d.ts +54 -0
- package/dist/views/metadata-admin/inspectors/ViewVariantInspector.js +191 -0
- package/dist/views/metadata-admin/inspectors/_shared.d.ts +128 -0
- package/dist/views/metadata-admin/inspectors/_shared.js +113 -0
- package/dist/views/metadata-admin/inspectors/datasetFilterCondition.d.ts +24 -0
- package/dist/views/metadata-admin/inspectors/datasetFilterCondition.js +97 -0
- package/dist/views/metadata-admin/inspectors/expression-validate.d.ts +26 -0
- package/dist/views/metadata-admin/inspectors/expression-validate.js +66 -0
- package/dist/views/metadata-admin/inspectors/flow-node-config.d.ts +143 -0
- package/dist/views/metadata-admin/inspectors/flow-node-config.js +506 -0
- package/dist/views/metadata-admin/inspectors/index.d.ts +1 -0
- package/dist/views/metadata-admin/inspectors/index.js +45 -0
- package/dist/views/metadata-admin/inspectors/json-schema-to-fields.d.ts +40 -0
- package/dist/views/metadata-admin/inspectors/json-schema-to-fields.js +227 -0
- package/dist/views/metadata-admin/inspectors/useDatasetFields.d.ts +72 -0
- package/dist/views/metadata-admin/inspectors/useDatasetFields.js +0 -0
- package/dist/views/metadata-admin/issuePath.d.ts +22 -0
- package/dist/views/metadata-admin/issuePath.js +65 -0
- package/dist/views/metadata-admin/mergeServerFields.d.ts +65 -0
- package/dist/views/metadata-admin/mergeServerFields.js +56 -0
- package/dist/views/metadata-admin/package-scope.d.ts +26 -0
- package/dist/views/metadata-admin/package-scope.js +43 -0
- package/dist/views/metadata-admin/preview-registry.d.ts +55 -0
- package/dist/views/metadata-admin/previews/ActionPreview.d.ts +25 -0
- package/dist/views/metadata-admin/previews/ActionPreview.js +238 -0
- package/dist/views/metadata-admin/previews/AddWidgetPicker.d.ts +12 -0
- package/dist/views/metadata-admin/previews/AddWidgetPicker.js +56 -0
- package/dist/views/metadata-admin/previews/AgentPreview.d.ts +24 -0
- package/dist/views/metadata-admin/previews/AgentPreview.js +100 -0
- package/dist/views/metadata-admin/previews/AppNavCanvas.d.ts +31 -0
- package/dist/views/metadata-admin/previews/AppNavCanvas.js +260 -0
- package/dist/views/metadata-admin/previews/AppPreview.d.ts +16 -1
- package/dist/views/metadata-admin/previews/AppPreview.js +23 -14
- package/dist/views/metadata-admin/previews/BookPreview.d.ts +20 -0
- package/dist/views/metadata-admin/previews/BookPreview.js +132 -0
- package/dist/views/metadata-admin/previews/DashboardPreview.d.ts +16 -1
- package/dist/views/metadata-admin/previews/DashboardPreview.js +110 -8
- package/dist/views/metadata-admin/previews/DatasetPreview.d.ts +18 -0
- package/dist/views/metadata-admin/previews/DatasetPreview.js +105 -0
- package/dist/views/metadata-admin/previews/DatasourcePreview.d.ts +23 -0
- package/dist/views/metadata-admin/previews/DatasourcePreview.js +68 -0
- package/dist/views/metadata-admin/previews/EmailTemplatePreview.d.ts +14 -1
- package/dist/views/metadata-admin/previews/FieldStub.d.ts +30 -0
- package/dist/views/metadata-admin/previews/FieldStub.js +104 -0
- package/dist/views/metadata-admin/previews/FieldsListEditor.d.ts +50 -0
- package/dist/views/metadata-admin/previews/FieldsListEditor.js +97 -0
- package/dist/views/metadata-admin/previews/FlowCanvas.d.ts +49 -0
- package/dist/views/metadata-admin/previews/FlowCanvas.js +416 -0
- package/dist/views/metadata-admin/previews/FlowPreview.d.ts +20 -0
- package/dist/views/metadata-admin/previews/FlowPreview.js +120 -0
- package/dist/views/metadata-admin/previews/FlowRunsPanel.d.ts +46 -0
- package/dist/views/metadata-admin/previews/FlowRunsPanel.js +97 -0
- package/dist/views/metadata-admin/previews/FlowSimulatorPanel.d.ts +25 -0
- package/dist/views/metadata-admin/previews/FlowSimulatorPanel.js +204 -0
- package/dist/views/metadata-admin/previews/JobPreview.d.ts +28 -0
- package/dist/views/metadata-admin/previews/JobPreview.js +290 -0
- package/dist/views/metadata-admin/previews/ObjectFormCanvas.d.ts +30 -0
- package/dist/views/metadata-admin/previews/ObjectFormCanvas.js +547 -0
- package/dist/views/metadata-admin/previews/ObjectPreview.d.ts +14 -1
- package/dist/views/metadata-admin/previews/ObjectPreview.js +5 -30
- package/dist/views/metadata-admin/previews/OutlineStrip.d.ts +32 -0
- package/dist/views/metadata-admin/previews/OutlineStrip.js +8 -0
- package/dist/views/metadata-admin/previews/PageBlockCanvas.d.ts +49 -0
- package/dist/views/metadata-admin/previews/PageBlockCanvas.js +510 -0
- package/dist/views/metadata-admin/previews/PagePreview.d.ts +10 -1
- package/dist/views/metadata-admin/previews/PagePreview.js +200 -5
- package/dist/views/metadata-admin/previews/PermissionPreview.d.ts +27 -0
- package/dist/views/metadata-admin/previews/PermissionPreview.js +115 -0
- package/dist/views/metadata-admin/previews/PreviewShell.d.ts +29 -6
- package/dist/views/metadata-admin/previews/PreviewShell.js +16 -3
- package/dist/views/metadata-admin/previews/ReportPreview.d.ts +18 -1
- package/dist/views/metadata-admin/previews/ReportPreview.js +23 -15
- package/dist/views/metadata-admin/previews/RolePreview.d.ts +19 -0
- package/dist/views/metadata-admin/previews/RolePreview.js +14 -0
- package/dist/views/metadata-admin/previews/ScreenPreview.d.ts +38 -0
- package/dist/views/metadata-admin/previews/ScreenPreview.js +61 -0
- package/dist/views/metadata-admin/previews/SkillPreview.d.ts +22 -0
- package/dist/views/metadata-admin/previews/SkillPreview.js +34 -0
- package/dist/views/metadata-admin/previews/ToolPreview.d.ts +25 -0
- package/dist/views/metadata-admin/previews/ToolPreview.js +122 -0
- package/dist/views/metadata-admin/previews/TranslationPreview.d.ts +25 -0
- package/dist/views/metadata-admin/previews/TranslationPreview.js +52 -0
- package/dist/views/metadata-admin/previews/ValidationPreview.d.ts +27 -0
- package/dist/views/metadata-admin/previews/ValidationPreview.js +110 -0
- package/dist/views/metadata-admin/previews/ViewColumnPanes.d.ts +62 -0
- package/dist/views/metadata-admin/previews/ViewColumnPanes.js +140 -0
- package/dist/views/metadata-admin/previews/ViewPreview.d.ts +23 -1
- package/dist/views/metadata-admin/previews/ViewPreview.js +101 -73
- package/dist/views/metadata-admin/previews/block-config.d.ts +82 -0
- package/dist/views/metadata-admin/previews/block-config.js +324 -0
- package/dist/views/metadata-admin/previews/block-types.d.ts +40 -0
- package/dist/views/metadata-admin/previews/block-types.js +110 -0
- package/dist/views/metadata-admin/previews/field-types.d.ts +53 -0
- package/dist/views/metadata-admin/previews/field-types.js +97 -0
- package/dist/views/metadata-admin/previews/flow-canvas-layout.d.ts +102 -0
- package/dist/views/metadata-admin/previews/flow-canvas-layout.js +227 -0
- package/dist/views/metadata-admin/previews/flow-canvas-parts.d.ts +96 -0
- package/dist/views/metadata-admin/previews/flow-canvas-parts.js +373 -0
- package/dist/views/metadata-admin/previews/form-preview.d.ts +24 -0
- package/dist/views/metadata-admin/previews/form-preview.js +29 -0
- package/dist/views/metadata-admin/previews/index.js +43 -0
- package/dist/views/metadata-admin/previews/object-fields-bridge.d.ts +66 -0
- package/dist/views/metadata-admin/previews/object-fields-bridge.js +171 -0
- package/dist/views/metadata-admin/previews/object-fields-io.d.ts +130 -0
- package/dist/views/metadata-admin/previews/object-fields-io.js +243 -0
- package/dist/views/metadata-admin/previews/screen-spec.d.ts +43 -0
- package/dist/views/metadata-admin/previews/screen-spec.js +108 -0
- package/dist/views/metadata-admin/previews/simulator/flow-sim-types.d.ts +102 -0
- package/dist/views/metadata-admin/previews/simulator/flow-sim-types.js +2 -0
- package/dist/views/metadata-admin/previews/simulator/flow-sim-validate.d.ts +15 -0
- package/dist/views/metadata-admin/previews/simulator/flow-sim-validate.js +185 -0
- package/dist/views/metadata-admin/previews/simulator/flow-simulator.d.ts +73 -0
- package/dist/views/metadata-admin/previews/simulator/flow-simulator.js +426 -0
- package/dist/views/metadata-admin/previews/useDatasetCatalog.d.ts +47 -0
- package/dist/views/metadata-admin/previews/useDatasetCatalog.js +133 -0
- package/dist/views/metadata-admin/previews/useFlowNodePalette.d.ts +44 -0
- package/dist/views/metadata-admin/previews/useFlowNodePalette.js +124 -0
- package/dist/views/metadata-admin/previews/useMetaOptions.d.ts +8 -0
- package/dist/views/metadata-admin/previews/useMetaOptions.js +50 -0
- package/dist/views/metadata-admin/previews/useObjectFields.d.ts +23 -0
- package/dist/views/metadata-admin/previews/useObjectFields.js +79 -0
- package/dist/views/metadata-admin/previews/useObjectOptions.d.ts +8 -0
- package/dist/views/metadata-admin/previews/useObjectOptions.js +43 -0
- package/dist/views/metadata-admin/previews/view-column-io.d.ts +42 -0
- package/dist/views/metadata-admin/previews/view-column-io.js +73 -0
- package/dist/views/metadata-admin/previews/widget-types.d.ts +24 -0
- package/dist/views/metadata-admin/previews/widget-types.js +40 -0
- package/dist/views/metadata-admin/registry.d.ts +140 -19
- package/dist/views/metadata-admin/report-schema.d.ts +26 -0
- package/dist/views/metadata-admin/report-schema.js +121 -0
- package/dist/views/metadata-admin/useMetadata.d.ts +100 -2
- package/dist/views/metadata-admin/useMetadata.js +155 -4
- package/dist/views/metadata-admin/view-item-normalize.d.ts +20 -0
- package/dist/views/metadata-admin/view-item-normalize.js +68 -0
- package/dist/views/metadata-admin/view-schema.d.ts +16 -0
- package/dist/views/metadata-admin/view-schema.js +107 -0
- package/dist/views/metadata-admin/view-variant-model.d.ts +23 -0
- package/dist/views/metadata-admin/view-variant-model.js +64 -0
- package/dist/views/metadata-admin/widgets.d.ts +89 -1
- package/dist/views/metadata-admin/widgets.js +491 -17
- package/dist/views/runtime-metadata-persistence.d.ts +78 -0
- package/dist/views/runtime-metadata-persistence.js +89 -0
- package/dist/views/useOpenRecordList.d.ts +18 -0
- package/dist/views/useOpenRecordList.js +36 -0
- package/dist/views/userFilterUrlState.d.ts +15 -0
- package/dist/views/userFilterUrlState.js +53 -0
- package/dist/views/view-config-adapter.d.ts +38 -0
- package/dist/views/view-config-adapter.js +80 -0
- package/package.json +52 -34
- package/dist/views/DesignDrawer.d.ts +0 -28
- package/dist/views/DesignDrawer.js +0 -51
- package/dist/views/metadata-admin/DesignerEditorWrapper.d.ts +0 -68
- package/dist/views/metadata-admin/DesignerEditorWrapper.js +0 -158
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { t } from '../i18n';
|
|
3
|
+
import { InspectorTextField, InspectorNumberField, InspectorSelectField, InspectorCheckboxField, } from './_shared';
|
|
4
|
+
import { Label } from '@object-ui/components';
|
|
5
|
+
import { FlowKeyValueField } from './FlowKeyValueField';
|
|
6
|
+
import { FlowStringListField } from './FlowStringListField';
|
|
7
|
+
import { FlowObjectListField } from './FlowObjectListField';
|
|
8
|
+
import { FlowReferenceField } from './FlowReferenceField';
|
|
9
|
+
import { validateExpressionClient } from './expression-validate';
|
|
10
|
+
export function FlowNodeConfigField({ field, value, onCommit, disabled, locale, context }) {
|
|
11
|
+
const control = (() => {
|
|
12
|
+
switch (field.kind) {
|
|
13
|
+
case 'reference':
|
|
14
|
+
return (_jsx(FlowReferenceField, { field: field, value: value, onCommit: (v) => onCommit(v), disabled: disabled, context: context }));
|
|
15
|
+
case 'keyValue':
|
|
16
|
+
return (_jsx(FlowKeyValueField, { label: field.label, value: value, onCommit: (v) => onCommit(v), disabled: disabled, addLabel: t('engine.inspector.flowNode.kv.add', locale), keyLabel: t('engine.inspector.flowNode.kv.key', locale), valueLabel: t('engine.inspector.flowNode.kv.value', locale), removeLabel: t('engine.inspector.flowNode.kv.remove', locale), emptyLabel: t('engine.inspector.flowNode.kv.empty', locale) }));
|
|
17
|
+
case 'stringList':
|
|
18
|
+
return (_jsx(FlowStringListField, { label: field.label, value: value, onCommit: (v) => onCommit(v), disabled: disabled, addLabel: t('engine.inspector.flowNode.list.add', locale), itemLabel: t('engine.inspector.flowNode.list.item', locale), removeLabel: t('engine.inspector.flowNode.list.remove', locale), emptyLabel: t('engine.inspector.flowNode.list.empty', locale) }));
|
|
19
|
+
case 'objectList':
|
|
20
|
+
return (_jsx(FlowObjectListField, { label: field.label, columns: field.columns ?? [], value: value, onCommit: (v) => onCommit(v), disabled: disabled, addLabel: t('engine.inspector.flowNode.list.add', locale), removeLabel: t('engine.inspector.flowNode.list.remove', locale), emptyLabel: t('engine.inspector.flowNode.list.empty', locale), context: context }));
|
|
21
|
+
case 'number':
|
|
22
|
+
return (_jsx(InspectorNumberField, { label: field.label, value: typeof value === 'number' ? value : value != null && value !== '' ? Number(value) : undefined, placeholder: field.placeholder, onCommit: (v) => onCommit(v), disabled: disabled }));
|
|
23
|
+
case 'boolean':
|
|
24
|
+
return (_jsx(InspectorCheckboxField, { label: field.label, value: value === true, onCommit: (v) => onCommit(v), disabled: disabled }));
|
|
25
|
+
case 'select':
|
|
26
|
+
return (_jsx(InspectorSelectField, { label: field.label, value: value != null ? String(value) : '', options: field.options ?? [], onCommit: (v) => onCommit(v), disabled: disabled }));
|
|
27
|
+
case 'textarea':
|
|
28
|
+
return (_jsxs("div", { className: "space-y-1", children: [_jsx(Label, { className: "text-xs text-muted-foreground", children: field.label }), _jsx("textarea", { value: value != null ? String(value) : '', onChange: (e) => onCommit(e.target.value), placeholder: field.placeholder, disabled: disabled, rows: 4, className: "w-full rounded border bg-background px-2 py-1.5 font-mono text-xs" })] }));
|
|
29
|
+
case 'expression':
|
|
30
|
+
case 'text':
|
|
31
|
+
default:
|
|
32
|
+
return (_jsx(InspectorTextField, { label: field.label, value: value != null ? String(value) : '', placeholder: field.placeholder, onCommit: (v) => onCommit(v), disabled: disabled, mono: field.kind === 'expression' }));
|
|
33
|
+
}
|
|
34
|
+
})();
|
|
35
|
+
// ADR-0032 — surface a malformed condition (e.g. the `{record.x}` brace-in-CEL
|
|
36
|
+
// mistake) inline, as the author types, with the same corrective message the
|
|
37
|
+
// build and the agent tool emit. Only checked for expression-bearing fields.
|
|
38
|
+
const exprIssue = field.kind === 'expression' ? validateExpressionClient('predicate', value) : null;
|
|
39
|
+
return (_jsxs("div", { className: "space-y-1", children: [control, exprIssue && (_jsx("p", { className: "text-[11px] leading-snug text-destructive", role: "alert", children: exprIssue.message })), field.help && !exprIssue && (_jsx("p", { className: "text-[11px] leading-snug text-muted-foreground", children: field.help }))] }));
|
|
40
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FlowNodeInspector — scoped editor for the selected flow node.
|
|
3
|
+
*
|
|
4
|
+
* Selection shape: { kind: 'node', id: <nodeId> }
|
|
5
|
+
* Patches: draft.nodes[i] = {...node, ...updates}
|
|
6
|
+
*
|
|
7
|
+
* Beyond id / label / type / description, each node type exposes a set of
|
|
8
|
+
* typed form fields (see `flow-node-config`) that edit scalar keys on
|
|
9
|
+
* `node.config`. Any remaining config keys (objects, arrays, bespoke flags)
|
|
10
|
+
* are surfaced in an "Advanced (JSON)" block so authors are never locked out.
|
|
11
|
+
*/
|
|
12
|
+
import * as React from 'react';
|
|
13
|
+
import type { MetadataInspectorProps } from '../inspector-registry';
|
|
14
|
+
export declare function FlowNodeInspector({ selection, draft, onPatch, onClearSelection, locale, readOnly }: MetadataInspectorProps): React.JSX.Element;
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
3
|
+
/**
|
|
4
|
+
* FlowNodeInspector — scoped editor for the selected flow node.
|
|
5
|
+
*
|
|
6
|
+
* Selection shape: { kind: 'node', id: <nodeId> }
|
|
7
|
+
* Patches: draft.nodes[i] = {...node, ...updates}
|
|
8
|
+
*
|
|
9
|
+
* Beyond id / label / type / description, each node type exposes a set of
|
|
10
|
+
* typed form fields (see `flow-node-config`) that edit scalar keys on
|
|
11
|
+
* `node.config`. Any remaining config keys (objects, arrays, bespoke flags)
|
|
12
|
+
* are surfaced in an "Advanced (JSON)" block so authors are never locked out.
|
|
13
|
+
*/
|
|
14
|
+
import * as React from 'react';
|
|
15
|
+
import { Plus } from 'lucide-react';
|
|
16
|
+
import { t } from '../i18n';
|
|
17
|
+
import { InspectorShell, InspectorTextField, InspectorSelectField, InspectorRemoveButton, InspectorEmptyState, spliceArray, } from './_shared';
|
|
18
|
+
import { fieldsForNodeType, isFieldVisible, getFieldValue, configKeyOf, FLOW_NODE_TYPE_OPTIONS, } from './flow-node-config';
|
|
19
|
+
import { jsonSchemaToFlowFields } from './json-schema-to-fields';
|
|
20
|
+
import { useActionConfigSchemas } from '../previews/useFlowNodePalette';
|
|
21
|
+
import { FlowNodeConfigField } from './FlowNodeConfigField';
|
|
22
|
+
import { ScreenPreview } from '../previews/ScreenPreview';
|
|
23
|
+
/**
|
|
24
|
+
* Mirror a decision node's `conditions` (branches) onto its outgoing sequence
|
|
25
|
+
* edges, in declared order: branch i -> the i-th out-edge. A branch whose
|
|
26
|
+
* expression is `true` marks its edge as the default/else path; an empty
|
|
27
|
+
* expression clears the guard. Fault / back edges are left untouched.
|
|
28
|
+
*
|
|
29
|
+
* This is what lets a decision authored entirely in Studio actually route at
|
|
30
|
+
* runtime: the engine and the simulator branch on `edge.condition`, NOT on
|
|
31
|
+
* `node.config.conditions` (which is only a node-local branch list). Without
|
|
32
|
+
* the mirror, every out-edge stays unconditional and all branches fire.
|
|
33
|
+
*/
|
|
34
|
+
function syncDecisionEdges(decisionId, conditions, edges) {
|
|
35
|
+
const branches = Array.isArray(conditions) ? conditions : [];
|
|
36
|
+
let bi = 0;
|
|
37
|
+
return edges.map((e) => {
|
|
38
|
+
if (e.source !== decisionId || e.type === 'fault' || e.type === 'back')
|
|
39
|
+
return e;
|
|
40
|
+
const branch = branches[bi++];
|
|
41
|
+
if (!branch || typeof branch !== 'object')
|
|
42
|
+
return e;
|
|
43
|
+
const expr = typeof branch.expression === 'string' ? branch.expression.trim() : '';
|
|
44
|
+
const label = typeof branch.label === 'string' ? branch.label.trim() : '';
|
|
45
|
+
const next = { ...e };
|
|
46
|
+
if (label)
|
|
47
|
+
next.label = label;
|
|
48
|
+
else
|
|
49
|
+
delete next.label;
|
|
50
|
+
if (expr && expr !== 'true') {
|
|
51
|
+
next.condition = expr;
|
|
52
|
+
delete next.isDefault;
|
|
53
|
+
}
|
|
54
|
+
else if (expr === 'true') {
|
|
55
|
+
next.isDefault = true;
|
|
56
|
+
delete next.condition;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
delete next.condition;
|
|
60
|
+
delete next.isDefault;
|
|
61
|
+
}
|
|
62
|
+
return next;
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
function asConfig(node) {
|
|
66
|
+
const c = node?.config;
|
|
67
|
+
return c && typeof c === 'object' && !Array.isArray(c) ? c : {};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Immutably set `value` at `path` on a plain object, pruning any intermediate
|
|
71
|
+
* object that becomes empty (so e.g. clearing the last `waitEventConfig` key
|
|
72
|
+
* removes the whole block). Empty string / null / undefined deletes the leaf.
|
|
73
|
+
*/
|
|
74
|
+
function setAtPath(obj, path, value) {
|
|
75
|
+
const [head, ...rest] = path;
|
|
76
|
+
const next = { ...obj };
|
|
77
|
+
if (rest.length === 0) {
|
|
78
|
+
if (value === undefined || value === null || value === '')
|
|
79
|
+
delete next[head];
|
|
80
|
+
else
|
|
81
|
+
next[head] = value;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
const cur = next[head];
|
|
85
|
+
const base = cur && typeof cur === 'object' && !Array.isArray(cur) ? cur : {};
|
|
86
|
+
const child = setAtPath(base, rest, value);
|
|
87
|
+
if (Object.keys(child).length === 0)
|
|
88
|
+
delete next[head];
|
|
89
|
+
else
|
|
90
|
+
next[head] = child;
|
|
91
|
+
}
|
|
92
|
+
return next;
|
|
93
|
+
}
|
|
94
|
+
export function FlowNodeInspector({ selection, draft, onPatch, onClearSelection, locale, readOnly }) {
|
|
95
|
+
const nodes = Array.isArray(draft.nodes) ? draft.nodes : [];
|
|
96
|
+
const index = nodes.findIndex((n) => n?.id === selection.id);
|
|
97
|
+
const node = index >= 0 ? nodes[index] : null;
|
|
98
|
+
// Server-driven property form: when the running engine publishes a config
|
|
99
|
+
// JSON Schema for this node type (ADR-0018 §configSchema — e.g. the ADR-0019
|
|
100
|
+
// approval node), derive the form from it so the designer stays in lock-step
|
|
101
|
+
// with the backend. Falls back to the hardcoded field group when no schema is
|
|
102
|
+
// published (offline / plugin absent / older backend).
|
|
103
|
+
const configSchemas = useActionConfigSchemas();
|
|
104
|
+
const fields = React.useMemo(() => {
|
|
105
|
+
const schema = node?.type ? configSchemas[node.type] : undefined;
|
|
106
|
+
const serverFields = schema !== undefined ? jsonSchemaToFlowFields(schema) : null;
|
|
107
|
+
return serverFields ?? fieldsForNodeType(node?.type);
|
|
108
|
+
}, [configSchemas, node?.type]);
|
|
109
|
+
const config = asConfig(node);
|
|
110
|
+
const visibleFields = fields.filter((f) => isFieldVisible(f, node, fields));
|
|
111
|
+
// `{var}` interpolation source for the screen preview — the flow's declared
|
|
112
|
+
// variables and their defaults (the designer has no live run state).
|
|
113
|
+
const screenVars = React.useMemo(() => {
|
|
114
|
+
const decls = Array.isArray(draft.variables) ? draft.variables : [];
|
|
115
|
+
const out = {};
|
|
116
|
+
for (const v of decls)
|
|
117
|
+
if (v && typeof v.name === 'string')
|
|
118
|
+
out[v.name] = v.defaultValue;
|
|
119
|
+
return out;
|
|
120
|
+
}, [draft]);
|
|
121
|
+
// Only fields stored under `config` "own" a config key; spec-structured
|
|
122
|
+
// blocks (waitEventConfig, etc.) and top-level timeoutMs never suppress an
|
|
123
|
+
// Advanced key.
|
|
124
|
+
const ownedConfigKeys = React.useMemo(() => {
|
|
125
|
+
const s = new Set();
|
|
126
|
+
for (const f of fields) {
|
|
127
|
+
const k = configKeyOf(f);
|
|
128
|
+
if (k)
|
|
129
|
+
s.add(k);
|
|
130
|
+
}
|
|
131
|
+
return s;
|
|
132
|
+
}, [fields]);
|
|
133
|
+
const extraJson = React.useMemo(() => {
|
|
134
|
+
const extra = Object.fromEntries(Object.entries(config).filter(([k]) => !ownedConfigKeys.has(k)));
|
|
135
|
+
return Object.keys(extra).length ? JSON.stringify(extra, null, 2) : '';
|
|
136
|
+
// Recompute when the node identity changes (patch) or the known keys change.
|
|
137
|
+
}, [node, ownedConfigKeys]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
138
|
+
const [advText, setAdvText] = React.useState(extraJson);
|
|
139
|
+
const [advError, setAdvError] = React.useState(null);
|
|
140
|
+
const [advOpen, setAdvOpen] = React.useState(extraJson.trim() !== '');
|
|
141
|
+
// Reveals the optional custom-keys editor on nodes that currently have none.
|
|
142
|
+
const [advReveal, setAdvReveal] = React.useState(false);
|
|
143
|
+
React.useEffect(() => {
|
|
144
|
+
setAdvText(extraJson);
|
|
145
|
+
setAdvError(null);
|
|
146
|
+
setAdvOpen(extraJson.trim() !== '');
|
|
147
|
+
setAdvReveal(false);
|
|
148
|
+
}, [extraJson]);
|
|
149
|
+
if (!node) {
|
|
150
|
+
return (_jsx(InspectorShell, { kindLabel: t('engine.inspector.flowNode.kind', locale), title: selection.label ?? selection.id, onClose: onClearSelection, closeLabel: t('engine.inspector.flowNode.close', locale), children: _jsx(InspectorEmptyState, { message: selection.id }) }));
|
|
151
|
+
}
|
|
152
|
+
const patchNode = (updates) => {
|
|
153
|
+
onPatch({ nodes: spliceArray(nodes, index, { ...node, ...updates }) });
|
|
154
|
+
};
|
|
155
|
+
const hasExtras = extraJson.trim() !== '';
|
|
156
|
+
// Screen nodes (and the `user_task` alias) get a live end-user preview.
|
|
157
|
+
const isScreen = node.type === 'screen' || node.type === 'user_task';
|
|
158
|
+
const setField = (path, value) => {
|
|
159
|
+
const nextNode = setAtPath(node, path, value);
|
|
160
|
+
const patch = { nodes: spliceArray(nodes, index, nextNode) };
|
|
161
|
+
// Decision branches drive routing — mirror them onto the node's outgoing
|
|
162
|
+
// edges so the engine/simulator can actually branch (they read
|
|
163
|
+
// edge.condition, not node.config.conditions).
|
|
164
|
+
if (node.type === 'decision' && path.length === 2 && path[0] === 'config' && path[1] === 'conditions') {
|
|
165
|
+
const draftEdges = Array.isArray(draft.edges)
|
|
166
|
+
? (draft.edges)
|
|
167
|
+
: [];
|
|
168
|
+
patch.edges = syncDecisionEdges(node.id, value, draftEdges);
|
|
169
|
+
}
|
|
170
|
+
onPatch(patch);
|
|
171
|
+
};
|
|
172
|
+
const commitAdvanced = () => {
|
|
173
|
+
try {
|
|
174
|
+
const parsed = advText.trim() === '' ? {} : JSON.parse(advText);
|
|
175
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
176
|
+
throw new Error('Must be a JSON object');
|
|
177
|
+
// Form-owned config keys always win: the Advanced block may only set keys
|
|
178
|
+
// that no form field owns, so it can never overwrite or resurrect one.
|
|
179
|
+
const knownPart = Object.fromEntries(Object.entries(config).filter(([k]) => ownedConfigKeys.has(k)));
|
|
180
|
+
const extrasPart = Object.fromEntries(Object.entries(parsed).filter(([k]) => !ownedConfigKeys.has(k)));
|
|
181
|
+
const merged = { ...knownPart, ...extrasPart };
|
|
182
|
+
setAdvError(null);
|
|
183
|
+
const nextNode = { ...node };
|
|
184
|
+
if (Object.keys(merged).length === 0)
|
|
185
|
+
delete nextNode.config;
|
|
186
|
+
else
|
|
187
|
+
nextNode.config = merged;
|
|
188
|
+
onPatch({ nodes: spliceArray(nodes, index, nextNode) });
|
|
189
|
+
}
|
|
190
|
+
catch (e) {
|
|
191
|
+
setAdvError(String(e.message));
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
const remove = () => {
|
|
195
|
+
onPatch({ nodes: spliceArray(nodes, index, null) });
|
|
196
|
+
onClearSelection();
|
|
197
|
+
};
|
|
198
|
+
const typeOptions = FLOW_NODE_TYPE_OPTIONS.includes(node.type)
|
|
199
|
+
? [...FLOW_NODE_TYPE_OPTIONS]
|
|
200
|
+
: [...FLOW_NODE_TYPE_OPTIONS, node.type ?? ''].filter(Boolean);
|
|
201
|
+
return (_jsxs(InspectorShell, { kindLabel: t('engine.inspector.flowNode.kind', locale), title: node.label || node.id, onClose: onClearSelection, closeLabel: t('engine.inspector.flowNode.close', locale), footer: _jsx(InspectorRemoveButton, { label: t('engine.inspector.flowNode.remove', locale), onClick: remove, disabled: readOnly }), children: [_jsx(InspectorTextField, { label: t('engine.inspector.flowNode.id', locale), value: node.id, onCommit: (v) => patchNode({ id: v }), disabled: readOnly, mono: true }), _jsx(InspectorTextField, { label: t('engine.inspector.flowNode.label', locale), value: node.label ?? '', onCommit: (v) => patchNode({ label: v }), disabled: readOnly }), _jsx(InspectorSelectField, { label: t('engine.inspector.flowNode.type', locale), value: node.type, options: typeOptions.map((v) => ({ value: v, label: v })), onCommit: (v) => patchNode({ type: v }), disabled: readOnly }), _jsx(InspectorTextField, { label: t('engine.inspector.flowNode.description', locale), value: node.description ?? '', onCommit: (v) => patchNode({ description: v || undefined }), disabled: readOnly }), fields.length === 0 ? (_jsx("p", { className: "pt-1 text-xs italic text-muted-foreground", children: t('engine.inspector.flowNode.noConfig', locale) })) : (visibleFields.length > 0 && (_jsxs("div", { className: "flex items-center gap-2 pt-1", children: [_jsx("span", { className: "text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: t('engine.inspector.flowNode.configuration', locale) }), _jsx("span", { className: "h-px flex-1 bg-border", "aria-hidden": true })] }))), visibleFields.map((field) => (_jsx(FlowNodeConfigField, { field: field, value: getFieldValue(node, field), onCommit: (v) => setField(field.path, v), disabled: readOnly, locale: locale, context: { draft, node } }, field.id))), isScreen && _jsx(ScreenPreview, { node: node, variables: screenVars, className: "mt-1" }), hasExtras || advReveal ? (_jsxs("details", { className: "group rounded border bg-muted/20", open: advOpen, onToggle: (e) => setAdvOpen(e.target.open), children: [_jsx("summary", { className: "cursor-pointer select-none px-2 py-1.5 text-xs font-medium text-muted-foreground", children: t('engine.inspector.flowNode.advanced', locale) }), _jsxs("div", { className: "space-y-1 border-t p-2", children: [_jsx("p", { className: "text-[11px] leading-snug text-muted-foreground", children: t('engine.inspector.flowNode.advancedHint', locale) }), _jsx("textarea", { value: advText, onChange: (e) => setAdvText(e.target.value), onBlur: commitAdvanced, disabled: readOnly, rows: 6, placeholder: "{ }", className: "w-full rounded border bg-background px-2 py-1.5 font-mono text-xs" }), advError && _jsx("div", { className: "text-xs text-destructive", children: advError })] })] })) : (!readOnly && (_jsxs("button", { type: "button", onClick: () => {
|
|
202
|
+
setAdvReveal(true);
|
|
203
|
+
setAdvOpen(true);
|
|
204
|
+
}, className: "inline-flex items-center gap-1 self-start text-[11px] text-muted-foreground transition-colors hover:text-foreground", children: [_jsx(Plus, { className: "h-3 w-3" }), t('engine.inspector.flowNode.advanced', locale)] })))] }));
|
|
205
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FlowObjectListField — a repeatable array-of-objects editor driven by a column
|
|
3
|
+
* schema (e.g. a screen node's `fields`: a list of `{name,label,type,required,
|
|
4
|
+
* visibleWhen}` definitions).
|
|
5
|
+
*
|
|
6
|
+
* Like the sibling key/value and string-list editors, rows are held in LOCAL
|
|
7
|
+
* state with a STABLE id and flushed on blur / Enter / add / remove so a row
|
|
8
|
+
* never remounts mid-keystroke. Empty per-cell values are pruned; a row with no
|
|
9
|
+
* populated cells is dropped on flush; an empty list commits `undefined`.
|
|
10
|
+
*/
|
|
11
|
+
import * as React from 'react';
|
|
12
|
+
import type { FlowConfigColumn } from './flow-node-config';
|
|
13
|
+
import { type FlowReferenceContext } from './FlowReferenceField';
|
|
14
|
+
export interface FlowObjectListFieldProps {
|
|
15
|
+
label: string;
|
|
16
|
+
columns: FlowConfigColumn[];
|
|
17
|
+
value: unknown;
|
|
18
|
+
onCommit: (value: Array<Record<string, unknown>> | undefined) => void;
|
|
19
|
+
disabled?: boolean;
|
|
20
|
+
addLabel: string;
|
|
21
|
+
removeLabel: string;
|
|
22
|
+
emptyLabel: string;
|
|
23
|
+
/** Draft + node context so `reference` columns can resolve their options. */
|
|
24
|
+
context?: FlowReferenceContext;
|
|
25
|
+
}
|
|
26
|
+
export declare function FlowObjectListField({ label, columns, value, onCommit, disabled, addLabel, removeLabel, emptyLabel, context, }: FlowObjectListFieldProps): React.JSX.Element;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
3
|
+
/**
|
|
4
|
+
* FlowObjectListField — a repeatable array-of-objects editor driven by a column
|
|
5
|
+
* schema (e.g. a screen node's `fields`: a list of `{name,label,type,required,
|
|
6
|
+
* visibleWhen}` definitions).
|
|
7
|
+
*
|
|
8
|
+
* Like the sibling key/value and string-list editors, rows are held in LOCAL
|
|
9
|
+
* state with a STABLE id and flushed on blur / Enter / add / remove so a row
|
|
10
|
+
* never remounts mid-keystroke. Empty per-cell values are pruned; a row with no
|
|
11
|
+
* populated cells is dropped on flush; an empty list commits `undefined`.
|
|
12
|
+
*/
|
|
13
|
+
import * as React from 'react';
|
|
14
|
+
import { Plus, X } from 'lucide-react';
|
|
15
|
+
import { Button, Input, Label, Checkbox } from '@object-ui/components';
|
|
16
|
+
import { uniqueId } from './_shared';
|
|
17
|
+
import { ReferenceCombobox, resolveRefKind } from './FlowReferenceField';
|
|
18
|
+
function toRows(list, columns) {
|
|
19
|
+
const ids = [];
|
|
20
|
+
return list.map((item) => {
|
|
21
|
+
const id = uniqueId('ol', ids);
|
|
22
|
+
ids.push(id);
|
|
23
|
+
const values = {};
|
|
24
|
+
for (const col of columns) {
|
|
25
|
+
const v = item[col.key];
|
|
26
|
+
if (col.kind === 'boolean')
|
|
27
|
+
values[col.key] = v === true;
|
|
28
|
+
else if (v != null)
|
|
29
|
+
values[col.key] = String(v);
|
|
30
|
+
else
|
|
31
|
+
values[col.key] = '';
|
|
32
|
+
}
|
|
33
|
+
return { id, values };
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
function rowsToList(rows, columns) {
|
|
37
|
+
const out = [];
|
|
38
|
+
for (const row of rows) {
|
|
39
|
+
const obj = {};
|
|
40
|
+
let hasValue = false;
|
|
41
|
+
for (const col of columns) {
|
|
42
|
+
const v = row.values[col.key];
|
|
43
|
+
if (col.kind === 'boolean') {
|
|
44
|
+
if (v === true) {
|
|
45
|
+
obj[col.key] = true;
|
|
46
|
+
hasValue = true;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else if (typeof v === 'string' && v.trim() !== '') {
|
|
50
|
+
obj[col.key] = v.trim();
|
|
51
|
+
hasValue = true;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (hasValue)
|
|
55
|
+
out.push(obj);
|
|
56
|
+
}
|
|
57
|
+
return out;
|
|
58
|
+
}
|
|
59
|
+
export function FlowObjectListField({ label, columns, value, onCommit, disabled, addLabel, removeLabel, emptyLabel, context, }) {
|
|
60
|
+
const external = React.useMemo(() => Array.isArray(value)
|
|
61
|
+
? value.filter((v) => v && typeof v === 'object')
|
|
62
|
+
: [], [value]);
|
|
63
|
+
const [rows, setRows] = React.useState(() => toRows(external, columns));
|
|
64
|
+
const lastCommitted = React.useRef(JSON.stringify(external));
|
|
65
|
+
React.useEffect(() => {
|
|
66
|
+
const next = JSON.stringify(external);
|
|
67
|
+
if (next !== lastCommitted.current) {
|
|
68
|
+
setRows(toRows(external, columns));
|
|
69
|
+
lastCommitted.current = next;
|
|
70
|
+
}
|
|
71
|
+
}, [external, columns]);
|
|
72
|
+
const flush = (nextRows) => {
|
|
73
|
+
const list = rowsToList(nextRows, columns);
|
|
74
|
+
lastCommitted.current = JSON.stringify(list);
|
|
75
|
+
onCommit(list.length ? list : undefined);
|
|
76
|
+
};
|
|
77
|
+
const setCell = (id, key, v) => {
|
|
78
|
+
setRows((rs) => rs.map((r) => (r.id === id ? { ...r, values: { ...r.values, [key]: v } } : r)));
|
|
79
|
+
};
|
|
80
|
+
const addRow = () => {
|
|
81
|
+
const values = {};
|
|
82
|
+
for (const col of columns)
|
|
83
|
+
values[col.key] = col.kind === 'boolean' ? false : '';
|
|
84
|
+
setRows((rs) => [...rs, { id: uniqueId('ol', rs.map((r) => r.id)), values }]);
|
|
85
|
+
};
|
|
86
|
+
const removeRow = (id) => {
|
|
87
|
+
setRows((rs) => {
|
|
88
|
+
const next = rs.filter((r) => r.id !== id);
|
|
89
|
+
flush(next);
|
|
90
|
+
return next;
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
return (_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { className: "text-xs text-muted-foreground", children: label }), _jsxs("div", { className: "space-y-2", children: [rows.length === 0 && (_jsx("p", { className: "text-[11px] italic text-muted-foreground", children: emptyLabel })), rows.map((row) => (_jsxs("div", { className: "rounded border bg-muted/30 p-2", children: [_jsx("div", { className: "mb-1 flex justify-end", children: _jsx(Button, { type: "button", variant: "ghost", size: "sm", className: "h-6 w-6 p-0 text-muted-foreground", onClick: () => removeRow(row.id), disabled: disabled, "aria-label": removeLabel, title: removeLabel, children: _jsx(X, { className: "h-3.5 w-3.5" }) }) }), _jsx("div", { className: "space-y-1.5", children: columns.map((col) => (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Label, { className: "w-24 shrink-0 text-[11px] text-muted-foreground", children: col.label }), col.kind === 'boolean' ? (_jsx(Checkbox, { checked: row.values[col.key] === true, onCheckedChange: (c) => {
|
|
94
|
+
setRows((rs) => {
|
|
95
|
+
const next = rs.map((r) => r.id === row.id
|
|
96
|
+
? { ...r, values: { ...r.values, [col.key]: c === true } }
|
|
97
|
+
: r);
|
|
98
|
+
flush(next);
|
|
99
|
+
return next;
|
|
100
|
+
});
|
|
101
|
+
}, disabled: disabled })) : col.kind === 'reference' ? (_jsx("div", { className: "flex-1", children: _jsx(ReferenceCombobox, { resolved: resolveRefKind(col.ref, (k) => row.values[k]), value: typeof row.values[col.key] === 'string' ? row.values[col.key] : '', onCommit: (v) => setCell(row.id, col.key, typeof v === 'string' ? v : ''), onBlur: () => flush(rows), placeholder: col.placeholder, disabled: disabled, context: context, showHint: false }) })) : (_jsx(Input, { value: typeof row.values[col.key] === 'string' ? row.values[col.key] : '', onChange: (e) => setCell(row.id, col.key, e.target.value), onBlur: () => flush(rows), onKeyDown: (e) => {
|
|
102
|
+
if (e.key === 'Enter')
|
|
103
|
+
e.target.blur();
|
|
104
|
+
}, placeholder: col.placeholder, disabled: disabled, className: `h-8 flex-1 text-xs${col.kind === 'expression' ? ' font-mono' : ''}` }))] }, col.key))) })] }, row.id)))] }), _jsxs(Button, { type: "button", variant: "outline", size: "sm", className: "h-7 w-full text-xs", onClick: addRow, disabled: disabled, children: [_jsx(Plus, { className: "mr-1 h-3.5 w-3.5" }), addLabel] })] }));
|
|
105
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FlowReferenceField — an *editable combobox* for flow-node config values that
|
|
3
|
+
* are really references (an object's field, an object/flow/role/user/… by name,
|
|
4
|
+
* a connector, an email template, or another node in this flow) rather than
|
|
5
|
+
* free-form strings.
|
|
6
|
+
*
|
|
7
|
+
* Why a combobox and not a strict dropdown: the designer must never trap the
|
|
8
|
+
* author. The control suggests known values (fetched per {@link ReferenceKind})
|
|
9
|
+
* but always accepts free text, so a field that doesn't exist yet, a role the
|
|
10
|
+
* current tenant hasn't populated, or an empty catalog all still let the author
|
|
11
|
+
* type a value. Implemented with a native `<datalist>` for exactly that
|
|
12
|
+
* suggest-but-allow-anything behaviour, zero extra dependencies, and built-in
|
|
13
|
+
* accessibility.
|
|
14
|
+
*
|
|
15
|
+
* Two layers:
|
|
16
|
+
* • {@link ReferenceCombobox} — the bare control, given an already-resolved
|
|
17
|
+
* concrete kind. Reused by the `objectList` repeater for per-row reference
|
|
18
|
+
* cells (e.g. an approver's value).
|
|
19
|
+
* • {@link FlowReferenceField} — the inspector field wrapper (label + hint),
|
|
20
|
+
* resolving a *polymorphic* reference against the node's own sibling config.
|
|
21
|
+
*
|
|
22
|
+
* Data sources are resolved lazily from the running backend (the same source of
|
|
23
|
+
* truth as the rest of the designer); `object-field` additionally needs to know
|
|
24
|
+
* *which* object — resolved from the reference's `objectSource` against the
|
|
25
|
+
* flow draft (trigger object) or the node's sibling config.
|
|
26
|
+
*/
|
|
27
|
+
import * as React from 'react';
|
|
28
|
+
import type { FlowReferenceSpec, ReferenceKind } from './flow-node-config';
|
|
29
|
+
/** Context the reference picker needs to resolve dynamic option sources. */
|
|
30
|
+
export interface FlowReferenceContext {
|
|
31
|
+
/** The whole flow draft — used for `$trigger` object + the node list. */
|
|
32
|
+
draft: Record<string, unknown>;
|
|
33
|
+
/** The node currently being edited — used to resolve sibling config keys. */
|
|
34
|
+
node: Record<string, unknown> | null;
|
|
35
|
+
}
|
|
36
|
+
/** A concrete (non-polymorphic) reference resolution. */
|
|
37
|
+
export interface ResolvedRef {
|
|
38
|
+
kind: ReferenceKind;
|
|
39
|
+
objectSource?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Resolve a (possibly polymorphic) reference spec to a concrete kind. For a
|
|
43
|
+
* polymorphic spec, `sibling(key)` supplies the discriminator value (the row's
|
|
44
|
+
* `type`, or a sibling config key). Returns undefined when nothing resolves —
|
|
45
|
+
* the caller then renders plain free text.
|
|
46
|
+
*/
|
|
47
|
+
export declare function resolveRefKind(ref: FlowReferenceSpec | undefined, sibling: (key: string) => unknown): ResolvedRef | undefined;
|
|
48
|
+
export interface ReferenceComboboxProps {
|
|
49
|
+
/** The resolved concrete reference, or undefined → plain free text. */
|
|
50
|
+
resolved: ResolvedRef | undefined;
|
|
51
|
+
value: unknown;
|
|
52
|
+
onCommit: (value: unknown) => void;
|
|
53
|
+
/** Optional blur handler (the `objectList` repeater flushes rows on blur). */
|
|
54
|
+
onBlur?: () => void;
|
|
55
|
+
disabled?: boolean;
|
|
56
|
+
placeholder?: string;
|
|
57
|
+
context?: FlowReferenceContext;
|
|
58
|
+
/** Show the "Fields of X." / unresolved hint under the control (default true). */
|
|
59
|
+
showHint?: boolean;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The bare reference combobox — suggestions for `resolved.kind`, always
|
|
63
|
+
* free-text editable. Hooks are called unconditionally (kind-gated args) so the
|
|
64
|
+
* component is safe to use in a repeater where the kind changes per row.
|
|
65
|
+
*/
|
|
66
|
+
export declare function ReferenceCombobox({ resolved, value, onCommit, onBlur, disabled, placeholder, context, showHint }: ReferenceComboboxProps): React.JSX.Element;
|
|
67
|
+
export interface FlowReferenceFieldProps {
|
|
68
|
+
field: {
|
|
69
|
+
label: string;
|
|
70
|
+
placeholder?: string;
|
|
71
|
+
ref?: FlowReferenceSpec;
|
|
72
|
+
};
|
|
73
|
+
value: unknown;
|
|
74
|
+
onCommit: (value: unknown) => void;
|
|
75
|
+
disabled?: boolean;
|
|
76
|
+
context?: FlowReferenceContext;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Inspector field wrapper: a labelled reference combobox. A polymorphic ref is
|
|
80
|
+
* resolved against the node's own sibling config keys (e.g. the script node's
|
|
81
|
+
* `template` follows `actionType`).
|
|
82
|
+
*/
|
|
83
|
+
export declare function FlowReferenceField({ field, value, onCommit, disabled, context }: FlowReferenceFieldProps): React.JSX.Element;
|