@datalayer/core 1.1.60 → 1.2.10
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/README.md +41 -18
- package/lib/api/DatalayerApi.d.ts +42 -1
- package/lib/api/DatalayerApi.js +90 -3
- package/lib/api/constants.d.ts +19 -1
- package/lib/api/constants.js +19 -1
- package/lib/api/contents/attachments.d.ts +9 -0
- package/lib/api/contents/attachments.js +39 -0
- package/lib/api/contents/bridges.d.ts +22 -0
- package/lib/api/contents/bridges.js +79 -0
- package/lib/api/contents/capabilities.d.ts +11 -0
- package/lib/api/contents/capabilities.js +21 -0
- package/lib/api/contents/cloudStorage.d.ts +31 -0
- package/lib/api/contents/cloudStorage.js +89 -0
- package/lib/api/contents/dataservers.d.ts +37 -0
- package/lib/api/contents/dataservers.js +121 -0
- package/lib/api/contents/datasets.d.ts +63 -0
- package/lib/api/contents/datasets.js +82 -0
- package/lib/api/contents/datasources.d.ts +70 -0
- package/lib/api/contents/datasources.js +149 -0
- package/lib/api/contents/generated.d.ts +1070 -0
- package/lib/api/contents/index.d.ts +16 -0
- package/lib/api/contents/index.js +20 -0
- package/lib/api/contents/mcp.d.ts +46 -0
- package/lib/api/contents/mcp.js +157 -0
- package/lib/api/contents/objects.d.ts +31 -0
- package/lib/api/contents/objects.js +88 -0
- package/lib/api/contents/operations.d.ts +3 -0
- package/lib/api/contents/operations.js +19 -0
- package/lib/api/contents/runtimeMounts.d.ts +40 -0
- package/lib/api/contents/runtimeMounts.js +59 -0
- package/lib/api/contents/sandboxUid.d.ts +21 -0
- package/lib/api/contents/sandboxUid.js +27 -0
- package/lib/api/contents/sources.d.ts +19 -0
- package/lib/api/contents/sources.js +119 -0
- package/lib/api/contents/sync.d.ts +18 -0
- package/lib/api/contents/sync.js +69 -0
- package/lib/api/contents/transfers.d.ts +38 -0
- package/lib/api/contents/transfers.js +123 -0
- package/lib/api/evals/client.d.ts +402 -0
- package/lib/api/evals/client.js +359 -0
- package/lib/api/evals/index.d.ts +10 -0
- package/lib/api/evals/index.js +18 -0
- package/lib/api/evals/request.d.ts +43 -0
- package/lib/api/evals/request.js +67 -0
- package/lib/api/evals/status.d.ts +27 -0
- package/lib/api/evals/status.js +122 -0
- package/lib/api/evals/types.d.ts +1335 -0
- package/lib/api/evals/types.js +5 -0
- package/lib/api/iam/connectedAgents.d.ts +68 -0
- package/lib/api/iam/connectedAgents.js +87 -0
- package/lib/api/iam/identityProviders.d.ts +76 -0
- package/lib/api/iam/identityProviders.js +187 -0
- package/lib/api/iam/index.d.ts +3 -1
- package/lib/api/iam/index.js +3 -1
- package/lib/api/iam/mcpAlertRules.d.ts +51 -0
- package/lib/api/iam/mcpAlertRules.js +198 -0
- package/lib/api/iam/mcpAuditSettings.d.ts +46 -0
- package/lib/api/iam/mcpAuditSettings.js +120 -0
- package/lib/api/iam/mcpPolicy.d.ts +181 -0
- package/lib/api/iam/mcpPolicy.js +168 -0
- package/lib/api/iam/organizationTeams.d.ts +13 -0
- package/lib/api/iam/organizationTeams.js +43 -0
- package/lib/api/iam/profile.d.ts +17 -1
- package/lib/api/iam/profile.js +27 -0
- package/lib/api/iam/scimTokens.d.ts +79 -0
- package/lib/api/iam/scimTokens.js +141 -0
- package/lib/api/iam/secrets.js +9 -21
- package/lib/api/iam/serviceAgents.d.ts +68 -0
- package/lib/api/iam/serviceAgents.js +119 -0
- package/lib/api/iam/trials.d.ts +38 -0
- package/lib/api/iam/trials.js +66 -0
- package/lib/api/index.d.ts +8 -1
- package/lib/api/index.js +7 -1
- package/lib/api/mcp/activity.d.ts +37 -0
- package/lib/api/mcp/activity.js +26 -0
- package/lib/api/mcp/alerts.d.ts +25 -0
- package/lib/api/mcp/alerts.js +51 -0
- package/lib/api/mcp/audit.d.ts +29 -0
- package/lib/api/mcp/audit.js +55 -0
- package/lib/api/mcp/bindings.d.ts +18 -0
- package/lib/api/mcp/bindings.js +42 -0
- package/lib/api/mcp/forwarding.d.ts +25 -0
- package/lib/api/mcp/forwarding.js +46 -0
- package/lib/api/mcp/gateway.d.ts +16 -0
- package/lib/api/mcp/gateway.js +70 -0
- package/lib/api/mcp/generated.d.ts +22 -0
- package/lib/api/mcp/generated.js +213 -0
- package/lib/api/mcp/index.d.ts +17 -0
- package/lib/api/mcp/index.js +25 -0
- package/lib/api/mcp/observability.d.ts +141 -0
- package/lib/api/mcp/observability.js +267 -0
- package/lib/api/mcp/operations.d.ts +83 -0
- package/lib/api/mcp/operations.js +50 -0
- package/lib/api/mcp/organizations.d.ts +102 -0
- package/lib/api/mcp/organizations.js +46 -0
- package/lib/api/mcp/policy.d.ts +9 -0
- package/lib/api/mcp/policy.js +23 -0
- package/lib/api/mcp/tasks.d.ts +49 -0
- package/lib/api/mcp/tasks.js +147 -0
- package/lib/api/orchestration/client.d.ts +53 -0
- package/lib/api/orchestration/client.js +105 -0
- package/lib/api/orchestration/events.d.ts +88 -0
- package/lib/api/orchestration/events.js +245 -0
- package/lib/api/orchestration/generated.d.ts +693 -0
- package/lib/api/orchestration/generated.js +687 -0
- package/lib/api/orchestration/index.d.ts +30 -0
- package/lib/api/orchestration/index.js +34 -0
- package/lib/api/orchestration/lifecycle.d.ts +39 -0
- package/lib/api/orchestration/lifecycle.js +57 -0
- package/lib/api/orchestration/measures.d.ts +55 -0
- package/lib/api/orchestration/measures.js +99 -0
- package/lib/api/otel/dashboards.d.ts +56 -0
- package/lib/api/otel/dashboards.js +50 -0
- package/lib/api/otel/index.d.ts +1 -0
- package/lib/api/otel/index.js +1 -0
- package/lib/api/otel/metrics.d.ts +16 -0
- package/lib/api/otel/metrics.js +15 -0
- package/lib/api/scheduler/client.d.ts +32 -0
- package/lib/api/scheduler/client.js +42 -0
- package/lib/api/scheduler/index.d.ts +8 -0
- package/lib/api/scheduler/index.js +16 -0
- package/lib/api/scheduler/request.d.ts +28 -0
- package/lib/api/scheduler/request.js +50 -0
- package/lib/api/scheduler/types.d.ts +88 -0
- package/lib/api/scheduler/types.js +5 -0
- package/lib/api/spacer/comments.d.ts +97 -0
- package/lib/api/spacer/comments.js +45 -0
- package/lib/api/spacer/index.d.ts +9 -0
- package/lib/api/spacer/index.js +17 -0
- package/lib/api/spacer/notebooks.d.ts +33 -0
- package/lib/api/spacer/notebooks.js +39 -0
- package/lib/api/spacer/request.d.ts +25 -0
- package/lib/api/spacer/request.js +46 -0
- package/lib/api/spacer/spaces.d.ts +68 -0
- package/lib/api/spacer/spaces.js +45 -0
- package/lib/api/utils/validation.d.ts +4 -4
- package/lib/api/utils/validation.js +10 -7
- package/lib/client/auth/index.js +0 -5
- package/lib/client/auth/storage.js +0 -5
- package/lib/client/auth/strategies.js +0 -5
- package/lib/client/base.d.ts +6 -0
- package/lib/client/base.js +8 -0
- package/lib/client/constants.d.ts +1 -0
- package/lib/client/constants.js +1 -0
- package/lib/client/index.d.ts +0 -10
- package/lib/client/index.js +2 -2
- package/lib/client/mixins/ContentsMixin.d.ts +71 -0
- package/lib/client/mixins/ContentsMixin.js +157 -0
- package/lib/client/mixins/IAMMixin.d.ts +0 -31
- package/lib/client/mixins/IAMMixin.js +0 -58
- package/lib/components/animation/AnimatedText.d.ts +2 -44
- package/lib/components/animation/AnimatedText.js +6 -126
- package/lib/components/anonymous/AnonymousKeyExpired.d.ts +56 -0
- package/lib/components/anonymous/AnonymousKeyExpired.js +96 -0
- package/lib/components/anonymous/AnonymousKeyTimer.d.ts +63 -0
- package/lib/components/anonymous/AnonymousKeyTimer.js +140 -0
- package/lib/components/anonymous/index.d.ts +7 -0
- package/lib/components/anonymous/index.js +15 -0
- package/lib/components/auth/SigInAPIKey.d.ts +1 -0
- package/lib/components/auth/SigInAPIKey.js +0 -6
- package/lib/components/auth/SignIn.d.ts +1 -0
- package/lib/components/auth/SignIn.js +0 -4
- package/lib/components/auth/SignIn.stories.d.ts +2 -2
- package/lib/components/avatars/BoringAvatar.d.ts +1 -1
- package/lib/components/avatars/BoringAvatar.stories.d.ts +1 -1
- package/lib/components/avatars/DLAvatar.d.ts +1 -1
- package/lib/components/avatars/DLAvatar.js +0 -4
- package/lib/components/avatars/UserAvatar.d.ts +16 -1
- package/lib/components/avatars/UserAvatar.js +15 -13
- package/lib/components/avatars/UserProfileAvatar.d.ts +1 -1
- package/lib/components/banners/NoAutomationBanner.d.ts +1 -1
- package/lib/components/billing/BillingEntitySelect.d.ts +16 -0
- package/lib/components/billing/BillingEntitySelect.js +49 -27
- package/lib/components/billing/eligibility.d.ts +22 -0
- package/lib/components/billing/eligibility.js +27 -0
- package/lib/components/billing/index.d.ts +1 -0
- package/lib/components/billing/index.js +1 -4
- package/lib/components/buttons/DownloadCSVButton.d.ts +1 -1
- package/lib/components/buttons/DownloadJsonButton.d.ts +1 -1
- package/lib/components/buttons/LongActionButton.d.ts +1 -0
- package/lib/components/buttons/LongActionButton.js +0 -4
- package/lib/components/buttons/UploadButton.d.ts +1 -0
- package/lib/components/buttons/UploadButton.js +0 -4
- package/lib/components/checkout/StripeCheckout.d.ts +1 -1
- package/lib/components/collaboration/LiveEditorCollaborators.d.ts +36 -0
- package/lib/components/collaboration/LiveEditorCollaborators.js +88 -53
- package/lib/components/collaboration/index.js +0 -4
- package/lib/components/confetti/ConfettiSuccess.d.ts +1 -1
- package/lib/components/contents/ContentSourceCard.d.ts +8 -0
- package/lib/components/contents/ContentSourceCard.js +23 -0
- package/lib/components/contents/HomeFolderObjectsBrowser.d.ts +10 -0
- package/lib/components/contents/HomeFolderObjectsBrowser.js +148 -0
- package/lib/components/contents/index.d.ts +2 -0
- package/lib/components/contents/index.js +6 -0
- package/lib/components/context/OrganizationSelect.d.ts +1 -1
- package/lib/components/display/AvatarSkeleton.d.ts +1 -1
- package/lib/components/display/BusyDots.d.ts +1 -1
- package/lib/components/display/CenteredSpinner.d.ts +1 -1
- package/lib/components/display/CodePreview.d.ts +1 -1
- package/lib/components/display/DatalayerBox.d.ts +7 -3
- package/lib/components/display/DatalayerBox.js +7 -7
- package/lib/components/display/HorizontalCenter.d.ts +1 -1
- package/lib/components/display/JupyterDialog.d.ts +1 -0
- package/lib/components/display/JupyterDialog.js +1 -7
- package/lib/components/display/Markdown.d.ts +1 -0
- package/lib/components/display/NavLink.js +3 -2
- package/lib/components/display/NotebookSkeleton.d.ts +1 -1
- package/lib/components/display/Placeholder.d.ts +1 -1
- package/lib/components/display/ToTopBranded.d.ts +1 -1
- package/lib/components/echarts/EChartsReact.d.ts +1 -1
- package/lib/components/flashes/FlashClosable.d.ts +1 -0
- package/lib/components/flashes/FlashClosable.js +0 -4
- package/lib/components/flashes/FlashGuest.d.ts +1 -1
- package/lib/components/flashes/FlashSurveys.d.ts +1 -1
- package/lib/components/flashes/FlashUnauthorized.d.ts +1 -0
- package/lib/components/flashes/FlashUnauthorized.js +0 -6
- package/lib/components/flashes/surveys/Survey2025_1.d.ts +1 -1
- package/lib/components/iam/ExternalTokenSilentLogin.d.ts +1 -1
- package/lib/components/index.d.ts +2 -0
- package/lib/components/index.js +2 -0
- package/lib/components/labels/StatusLabels.d.ts +2 -9
- package/lib/components/labels/StatusLabels.js +2 -26
- package/lib/components/labels/VisibilityLabel.d.ts +1 -1
- package/lib/components/landings/StepBlock.d.ts +1 -1
- package/lib/components/mcp/ClientBadge.d.ts +41 -0
- package/lib/components/mcp/ClientBadge.js +33 -0
- package/lib/components/mcp/McpErrorBlankslate.d.ts +21 -0
- package/lib/components/mcp/McpErrorBlankslate.js +17 -0
- package/lib/components/mcp/ScopeList.d.ts +28 -0
- package/lib/components/mcp/ScopeList.js +14 -0
- package/lib/components/mcp/index.d.ts +10 -0
- package/lib/components/mcp/index.js +18 -0
- package/lib/components/navbar/NavigationVisbilityObserver.d.ts +2 -1
- package/lib/components/navbar/SubdomainNavBar.d.ts +10 -5
- package/lib/components/navbar/SubdomainNavBar.js +2 -1
- package/lib/components/notebooks/JupyterNotebook.d.ts +1 -1
- package/lib/components/notebooks/JupyterNotebookToolbar.d.ts +1 -1
- package/lib/components/principal/PrincipalAppearance.d.ts +22 -42
- package/lib/components/principal/PrincipalAppearance.js +232 -182
- package/lib/components/principal/PrincipalAvatar.d.ts +9 -1
- package/lib/components/principal/PrincipalAvatar.js +18 -10
- package/lib/components/principal/PrincipalBadge.d.ts +1 -1
- package/lib/components/principal/PrincipalBanner.d.ts +1 -1
- package/lib/components/principal/PrincipalDetailsOverlay.d.ts +38 -1
- package/lib/components/principal/PrincipalDetailsOverlay.js +64 -33
- package/lib/components/principal/PrincipalHoverCard.d.ts +31 -0
- package/lib/components/principal/PrincipalHoverCard.js +52 -0
- package/lib/components/principal/PrincipalSwitcherMenu.d.ts +1 -0
- package/lib/components/principal/PrincipalSwitcherMenu.js +5 -14
- package/lib/components/principal/index.d.ts +2 -1
- package/lib/components/principal/index.js +2 -1
- package/lib/components/progress/ConsumptionBar.d.ts +1 -0
- package/lib/components/progress/ConsumptionBar.js +0 -4
- package/lib/components/progress/ProgressRing.d.ts +1 -0
- package/lib/components/progress/SpinnerBar.d.ts +1 -1
- package/lib/components/progress/Timer.d.ts +1 -0
- package/lib/components/progress/Timer.js +0 -4
- package/lib/components/screencapture/Screencapture.js +46 -3
- package/lib/components/screencapture/ScreencaptureButton.d.ts +1 -1
- package/lib/components/sharing/ShareAccessComponent.d.ts +58 -3
- package/lib/components/sharing/ShareAccessComponent.js +143 -98
- package/lib/components/sharing/SharingEditor.d.ts +21 -0
- package/lib/components/sharing/SharingEditor.js +9 -28
- package/lib/components/sharing/index.d.ts +1 -0
- package/lib/components/sharing/index.js +1 -0
- package/lib/components/sharing/sandboxSharing.d.ts +26 -0
- package/lib/components/sharing/sandboxSharing.js +41 -0
- package/lib/components/spaces/SpaceDetailsOverlay.d.ts +39 -0
- package/lib/components/spaces/SpaceDetailsOverlay.js +80 -0
- package/lib/components/spaces/SpaceDisplay.d.ts +38 -0
- package/lib/components/spaces/SpaceDisplay.js +92 -0
- package/lib/components/spaces/index.d.ts +4 -0
- package/lib/components/spaces/index.js +7 -0
- package/lib/components/spaces/spaceDisplayModel.d.ts +93 -0
- package/lib/components/spaces/spaceDisplayModel.js +170 -0
- package/lib/components/sparklines/Sparklines.js +3 -4
- package/lib/components/sparklines/index.js +0 -4
- package/lib/components/storage/ContentsBrowser.d.ts +25 -1
- package/lib/components/storage/ContentsBrowser.js +145 -52
- package/lib/components/storage/ContentsBrowserMock.d.ts +3 -0
- package/lib/components/storage/ContentsBrowserMock.js +75 -0
- package/lib/components/storage/ContentsItems.d.ts +2 -1
- package/lib/components/storage/ContentsItems.js +0 -4
- package/lib/components/storage/ContentsTable.d.ts +50 -0
- package/lib/components/storage/ContentsTable.js +134 -0
- package/lib/components/storage/HomeFolderDrive.d.ts +71 -0
- package/lib/components/storage/HomeFolderDrive.js +248 -0
- package/lib/components/storage/index.d.ts +2 -0
- package/lib/components/storage/index.js +2 -0
- package/lib/components/students/StudentItemStatus.d.ts +1 -1
- package/lib/components/students/StudentResultCircle.d.ts +1 -1
- package/lib/components/subnav/SubNav.d.ts +5 -5
- package/lib/components/subnav/SubNav.js +11 -9
- package/lib/components/tables/DataTable.d.ts +1 -1
- package/lib/components/text-reveal/TextRevealAnimation.d.ts +2 -2
- package/lib/components/text-reveal/useTextRevealAnimationLines.d.ts +1 -1
- package/lib/components/time/LiveRelativeTime.d.ts +1 -0
- package/lib/components/time/LiveRelativeTime.js +0 -8
- package/lib/components/time/index.js +0 -4
- package/lib/components/timeline/Timeline.d.ts +1 -1
- package/lib/components/timeline/index.js +0 -4
- package/lib/components/users/PeerIndicator.d.ts +1 -0
- package/lib/components/users/PeerIndicator.js +0 -4
- package/lib/config/Configuration.d.ts +15 -17
- package/lib/config/Configuration.js +7 -0
- package/lib/hooks/cacheConverters.d.ts +0 -7
- package/lib/hooks/cacheConverters.js +0 -25
- package/lib/hooks/index.d.ts +3 -0
- package/lib/hooks/index.js +3 -0
- package/lib/hooks/layouts/LayoutBackdrop.d.ts +1 -1
- package/lib/hooks/layouts/LayoutScreencapture.d.ts +1 -1
- package/lib/hooks/useBackdrop.d.ts +1 -1
- package/lib/hooks/useBackdropJupyterLab.d.ts +3 -2
- package/lib/hooks/useBackdropJupyterLab.js +0 -4
- package/lib/hooks/useBillingEntityStore.js +3 -0
- package/lib/hooks/useCache.d.ts +478 -130
- package/lib/hooks/useCache.js +1580 -676
- package/lib/hooks/useContainsFocus.d.ts +1 -1
- package/lib/hooks/useContents.d.ts +334 -0
- package/lib/hooks/useContents.js +1033 -0
- package/lib/hooks/useFocusTrap.d.ts +4 -4
- package/lib/hooks/useFocusTrap.js +1 -1
- package/lib/hooks/useMcp.d.ts +315 -0
- package/lib/hooks/useMcp.js +891 -0
- package/lib/hooks/useMobile.js +0 -5
- package/lib/hooks/useNavigate.d.ts +41 -3
- package/lib/hooks/useNavigate.js +106 -52
- package/lib/hooks/usePrincipalCacheStore.js +3 -0
- package/lib/hooks/usePrincipalStore.js +3 -0
- package/lib/hooks/useProjectStore.d.ts +3 -3
- package/lib/hooks/useProjectStore.js +4 -4
- package/lib/hooks/useRef.d.ts +1 -1
- package/lib/hooks/useRef.js +3 -0
- package/lib/hooks/useScreencapture.d.ts +2 -1
- package/lib/hooks/useScreencapture.js +0 -4
- package/lib/hooks/useSpaceCacheStore.d.ts +50 -0
- package/lib/hooks/useSpaceCacheStore.js +85 -0
- package/lib/hooks/useToast.js +0 -4
- package/lib/hooks/useVisibilityObserver.d.ts +1 -1
- package/lib/index.d.ts +4 -1
- package/lib/index.js +3 -1
- package/lib/mocks/components/FlashMock.d.ts +1 -1
- package/lib/mocks/views/ActionMenuMock.d.ts +1 -1
- package/lib/mocks/views/ChartMock.d.ts +1 -1
- package/lib/mocks/views/DashboardMock.d.ts +1 -1
- package/lib/mocks/views/FormMock.d.ts +1 -1
- package/lib/mocks/views/TableMock.d.ts +1 -1
- package/lib/mocks/views/WipMock.d.ts +1 -1
- package/lib/models/Credits.d.ts +16 -0
- package/lib/models/Credits.js +22 -0
- package/lib/models/CreditsDTO.d.ts +6 -5
- package/lib/models/CreditsDTO.js +7 -5
- package/lib/models/McpAuditEvent.d.ts +52 -0
- package/lib/models/McpAuditEvent.js +5 -0
- package/lib/models/McpBinding.d.ts +57 -0
- package/lib/models/McpBinding.js +5 -0
- package/lib/models/McpPolicy.d.ts +77 -0
- package/lib/models/McpPolicy.js +5 -0
- package/lib/models/McpTask.d.ts +94 -0
- package/lib/models/McpTask.js +7 -0
- package/lib/models/Organization.d.ts +69 -0
- package/lib/models/Organization.js +96 -0
- package/lib/models/Secret.d.ts +1 -2
- package/lib/models/Secret.js +2 -18
- package/lib/models/StartedBy.d.ts +91 -0
- package/lib/models/StartedBy.js +117 -0
- package/lib/models/Team.d.ts +2 -0
- package/lib/models/Team.js +2 -0
- package/lib/models/User.d.ts +4 -0
- package/lib/models/User.js +3 -0
- package/lib/models/UserDTO.js +4 -2
- package/lib/models/UserSettings.d.ts +13 -0
- package/lib/models/UserSettings.js +9 -0
- package/lib/models/contents/__fixtures__/solr-codec.json +57 -0
- package/lib/models/contents/__fixtures__/v1-contracts.json +194 -0
- package/lib/models/contents/fieldCase.d.ts +8 -0
- package/lib/models/contents/fieldCase.js +37 -0
- package/lib/models/contents/index.d.ts +2 -0
- package/lib/models/contents/index.js +6 -0
- package/lib/models/contents/permissions.d.ts +16 -0
- package/lib/models/contents/permissions.js +34 -0
- package/lib/models/index.d.ts +5 -1
- package/lib/models/index.js +5 -1
- package/lib/navigation/components.js +2 -3
- package/lib/routes/publicPaths.js +4 -0
- package/lib/state/index.d.ts +1 -0
- package/lib/state/index.js +1 -0
- package/lib/state/sessionEnd.d.ts +55 -0
- package/lib/state/sessionEnd.js +162 -0
- package/lib/state/substates/CoreState.d.ts +15 -7
- package/lib/state/substates/CoreState.js +21 -17
- package/lib/state/substates/IAMState.d.ts +1 -1
- package/lib/state/substates/IAMState.js +12 -5
- package/lib/state/substates/LayoutState.js +12 -0
- package/lib/state/substates/ProfileState.d.ts +1 -0
- package/lib/state/substates/ProfileState.js +1 -4
- package/lib/state/substates/index.d.ts +0 -1
- package/lib/state/substates/index.js +0 -1
- package/lib/utils/Jwt.d.ts +26 -0
- package/lib/utils/Jwt.js +37 -0
- package/lib/utils/Lazy.d.ts +20 -0
- package/lib/utils/Lazy.js +32 -6
- package/lib/utils/Screencapture.js +3 -0
- package/lib/utils/WithSuspense.d.ts +11 -1
- package/lib/utils/WithSuspense.js +11 -1
- package/lib/views/api-keys/APIKeyEdit.d.ts +1 -1
- package/lib/views/api-keys/APIKeyNew.d.ts +1 -1
- package/lib/views/api-keys/APIKeys.d.ts +1 -1
- package/lib/views/api-keys/APIKeys.js +30 -4
- package/lib/views/api-keys/APIKeysStandalone.d.ts +5 -1
- package/lib/views/api-keys/APIKeysStandalone.js +2 -2
- package/lib/views/datasources/DatasourceDetail.d.ts +12 -5
- package/lib/views/datasources/DatasourceDetail.js +80 -110
- package/lib/views/datasources/DatasourceNew.d.ts +14 -8
- package/lib/views/datasources/DatasourceNew.js +129 -118
- package/lib/views/datasources/Datasources.d.ts +39 -7
- package/lib/views/datasources/Datasources.js +95 -40
- package/lib/views/datasources/DatasourcesMock.d.ts +3 -0
- package/lib/views/datasources/DatasourcesMock.js +57 -0
- package/lib/views/iam/SignInSimple.d.ts +12 -0
- package/lib/views/iam/SignInSimple.js +4 -4
- package/lib/views/index.d.ts +1 -0
- package/lib/views/index.js +1 -0
- package/lib/views/mcp/AdmittedClients.d.ts +44 -0
- package/lib/views/mcp/AdmittedClients.js +59 -0
- package/lib/views/mcp/AlertDestinations.d.ts +34 -0
- package/lib/views/mcp/AlertDestinations.js +75 -0
- package/lib/views/mcp/AlertRules.d.ts +32 -0
- package/lib/views/mcp/AlertRules.js +245 -0
- package/lib/views/mcp/ApprovalQueue.d.ts +66 -0
- package/lib/views/mcp/ApprovalQueue.js +95 -0
- package/lib/views/mcp/AuditLog.d.ts +42 -0
- package/lib/views/mcp/AuditLog.js +144 -0
- package/lib/views/mcp/ConnectedAgents.d.ts +34 -0
- package/lib/views/mcp/ConnectedAgents.js +135 -0
- package/lib/views/mcp/EnterpriseConsole.d.ts +74 -0
- package/lib/views/mcp/EnterpriseConsole.js +195 -0
- package/lib/views/mcp/IdentityProviders.d.ts +33 -0
- package/lib/views/mcp/IdentityProviders.js +299 -0
- package/lib/views/mcp/McpDashboard.d.ts +50 -0
- package/lib/views/mcp/McpDashboard.js +430 -0
- package/lib/views/mcp/McpHome.d.ts +92 -0
- package/lib/views/mcp/McpHome.js +153 -0
- package/lib/views/mcp/McpObservability.d.ts +79 -0
- package/lib/views/mcp/McpObservability.js +236 -0
- package/lib/views/mcp/NotebookRuns.d.ts +39 -0
- package/lib/views/mcp/NotebookRuns.js +44 -0
- package/lib/views/mcp/OrganizationPolicy.d.ts +45 -0
- package/lib/views/mcp/OrganizationPolicy.js +108 -0
- package/lib/views/mcp/OrganizationUsage.d.ts +69 -0
- package/lib/views/mcp/OrganizationUsage.js +113 -0
- package/lib/views/mcp/PersonalPolicy.d.ts +54 -0
- package/lib/views/mcp/PersonalPolicy.js +126 -0
- package/lib/views/mcp/Policies.d.ts +53 -0
- package/lib/views/mcp/Policies.js +210 -0
- package/lib/views/mcp/PolicyForm.d.ts +83 -0
- package/lib/views/mcp/PolicyForm.js +113 -0
- package/lib/views/mcp/PolicyHistory.d.ts +58 -0
- package/lib/views/mcp/PolicyHistory.js +75 -0
- package/lib/views/mcp/RunDetail.d.ts +87 -0
- package/lib/views/mcp/RunDetail.js +186 -0
- package/lib/views/mcp/ScimProvisioning.d.ts +54 -0
- package/lib/views/mcp/ScimProvisioning.js +173 -0
- package/lib/views/mcp/ServiceAgents.d.ts +46 -0
- package/lib/views/mcp/ServiceAgents.js +194 -0
- package/lib/views/mcp/TeamPolicies.d.ts +33 -0
- package/lib/views/mcp/TeamPolicies.js +159 -0
- package/lib/views/mcp/ToolAccess.d.ts +60 -0
- package/lib/views/mcp/ToolAccess.js +101 -0
- package/lib/views/mcp/TraceTimeline.d.ts +81 -0
- package/lib/views/mcp/TraceTimeline.js +132 -0
- package/lib/views/mcp/format.d.ts +25 -0
- package/lib/views/mcp/format.js +77 -0
- package/lib/views/mcp/index.d.ts +34 -0
- package/lib/views/mcp/index.js +42 -0
- package/lib/views/mcp/types.d.ts +66 -0
- package/lib/views/mcp/types.js +5 -0
- package/lib/views/otel/simpleAuthStore.js +3 -0
- package/lib/views/secrets/SecretEdit.d.ts +5 -1
- package/lib/views/secrets/SecretEdit.js +5 -4
- package/lib/views/secrets/SecretNew.d.ts +11 -1
- package/lib/views/secrets/SecretNew.js +7 -3
- package/lib/views/secrets/Secrets.d.ts +12 -1
- package/lib/views/secrets/Secrets.js +2 -2
- package/package.json +269 -260
- package/scripts/generate-contents-types.py +169 -0
- package/scripts/generate-mcp-types.py +233 -0
- package/scripts/generate-orchestration-types.py +920 -0
- package/lib/api/iam/datasources.d.ts +0 -86
- package/lib/api/iam/datasources.js +0 -185
- package/lib/components/toolbars/index.d.ts +0 -1
- package/lib/models/Datasource.d.ts +0 -181
- package/lib/models/Datasource.js +0 -154
- package/lib/state/substates/DatasourceState.d.ts +0 -11
- package/lib/state/substates/DatasourceState.js +0 -16
- /package/lib/{components/toolbars/index.js → api/contents/generated.js} +0 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { Button, Heading, Label, Link, Spinner, Text, Textarea, RelativeTime, } from '@primer/react';
|
|
4
|
+
import { Box } from '@datalayer/primer-addons';
|
|
5
|
+
import { useNavigate } from 'react-router-dom';
|
|
6
|
+
import { McpErrorBlankslate } from '../../components/mcp/index.js';
|
|
7
|
+
import { useAnswerTask, useCancelTask, useRunTrace, useTask, useTaskEvents, } from '../../hooks/useMcp.js';
|
|
8
|
+
import { TraceTimelineSection } from './TraceTimeline.js';
|
|
9
|
+
/** How a run's status is drawn. Shared with the runs list. */
|
|
10
|
+
export const RUN_STATUS_LOOK = {
|
|
11
|
+
working: { label: 'Working', variant: 'success' },
|
|
12
|
+
input_required: { label: 'Waiting on you', variant: 'attention' },
|
|
13
|
+
completed: { label: 'Completed', variant: 'secondary' },
|
|
14
|
+
failed: { label: 'Failed', variant: 'danger' },
|
|
15
|
+
cancelled: { label: 'Cancelled', variant: 'secondary' },
|
|
16
|
+
};
|
|
17
|
+
/** Whether the run has stopped for good. */
|
|
18
|
+
export const isRunOver = (status) => status === 'completed' || status === 'failed' || status === 'cancelled';
|
|
19
|
+
/**
|
|
20
|
+
* Everything the run has printed, as text.
|
|
21
|
+
*
|
|
22
|
+
* Two shapes reach here and both are the run's output: the streamed
|
|
23
|
+
* `outputs`, and the `result` a finished tool returned. A cancelled run has
|
|
24
|
+
* the first and usually the second — the partial output is promoted to the
|
|
25
|
+
* result when it stops — so they are concatenated rather than chosen
|
|
26
|
+
* between, and de-duplicated by text so a promoted partial is not printed
|
|
27
|
+
* twice.
|
|
28
|
+
*/
|
|
29
|
+
export const outputTextOf = (task) => {
|
|
30
|
+
const lines = [];
|
|
31
|
+
for (const output of task.outputs ?? []) {
|
|
32
|
+
if (output.text) {
|
|
33
|
+
lines.push(output.text);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const result = task.result;
|
|
37
|
+
if (result && typeof result === 'object') {
|
|
38
|
+
for (const part of result.content ?? []) {
|
|
39
|
+
const text = part.text;
|
|
40
|
+
if (typeof text === 'string') {
|
|
41
|
+
lines.push(text);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const seen = new Set();
|
|
46
|
+
return lines
|
|
47
|
+
.filter(line => {
|
|
48
|
+
if (seen.has(line)) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
seen.add(line);
|
|
52
|
+
return true;
|
|
53
|
+
})
|
|
54
|
+
.join('');
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* A run for the documentation to draw: cancelled mid-flight, holding the
|
|
58
|
+
* lines it printed before it stopped.
|
|
59
|
+
*
|
|
60
|
+
* Cancelled rather than completed on purpose. It is the state that shows
|
|
61
|
+
* both halves of what this view is for — the output a run keeps when it is
|
|
62
|
+
* stopped, and the reason it stopped — and it is the one a reader is most
|
|
63
|
+
* likely to be looking at when they open the documentation.
|
|
64
|
+
*/
|
|
65
|
+
export const SAMPLE_RUN = {
|
|
66
|
+
uid: 'tsk_0980147b852244d098b04efd',
|
|
67
|
+
status: 'cancelled',
|
|
68
|
+
statusMessage: 'cancelled by the client',
|
|
69
|
+
tool: 'execute_cell',
|
|
70
|
+
notebookUid: '01KW96PZYRVKZXT8FS644GFD0D',
|
|
71
|
+
cellId: 'fdcac494',
|
|
72
|
+
initiatingUser: '01JV1VE1T5VG22Z05F6EFBMW8E',
|
|
73
|
+
createdAt: '2026-09-07T12:00:00Z',
|
|
74
|
+
lastUpdatedAt: '2026-09-07T12:00:22Z',
|
|
75
|
+
outputs: [
|
|
76
|
+
{
|
|
77
|
+
index: 0,
|
|
78
|
+
outputType: 'stream',
|
|
79
|
+
text: 'tick 0\ntick 1\ntick 2\ntick 3\ntick 4\ntick 5\n',
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
result: {
|
|
83
|
+
content: [{ type: 'text', text: 'tick 6\ntick 7\nKeyboardInterrupt\n' }],
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* The spans that run left behind, for the documentation to draw.
|
|
88
|
+
*
|
|
89
|
+
* The shape is the one a reader needs to recognise: the gateway's twenty-two
|
|
90
|
+
* seconds are almost entirely the sandbox's, and the durable step between
|
|
91
|
+
* them explains the gap. A timeline drawn from an empty trace would teach
|
|
92
|
+
* nobody what the timeline is for.
|
|
93
|
+
*/
|
|
94
|
+
export const SAMPLE_TRACE = (() => {
|
|
95
|
+
const at = (second, millisecond = 0) => new Date(Date.UTC(2026, 8, 7, 12, 0, second, millisecond)).toISOString();
|
|
96
|
+
const span = (id, name, service, from, to) => ({
|
|
97
|
+
trace_id: '4f7a1c9d2b8e40a5b6c3d1e0f9a8b7c6',
|
|
98
|
+
span_id: id,
|
|
99
|
+
span_name: name,
|
|
100
|
+
service_name: service,
|
|
101
|
+
kind: 'SPAN_KIND_INTERNAL',
|
|
102
|
+
start_time: from,
|
|
103
|
+
end_time: to,
|
|
104
|
+
duration_ms: Date.parse(to) - Date.parse(from),
|
|
105
|
+
});
|
|
106
|
+
return [
|
|
107
|
+
{
|
|
108
|
+
span: span('01', 'mcp.tools/call execute_cell', 'jupyter-mcp-server', at(0), at(22)),
|
|
109
|
+
children: [
|
|
110
|
+
{
|
|
111
|
+
span: span('02', 'mcp.authorize', 'jupyter-mcp-server', at(0), at(0, 4)),
|
|
112
|
+
children: [],
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
span: span('03', 'durable.workflow.start', 'datalayer-durable', at(0, 120), at(0, 480)),
|
|
116
|
+
children: [
|
|
117
|
+
{
|
|
118
|
+
span: span('04', 'durable.step.execute', 'datalayer-durable', at(0, 500), at(22)),
|
|
119
|
+
children: [
|
|
120
|
+
{
|
|
121
|
+
span: span('05', 'runtimes.kernel.execute', 'datalayer-runtimes', at(1, 200), at(21, 900)),
|
|
122
|
+
children: [],
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
},
|
|
128
|
+
],
|
|
129
|
+
},
|
|
130
|
+
];
|
|
131
|
+
})();
|
|
132
|
+
export const RunDetail = ({ taskUid, errorState, routes, mock = false, }) => {
|
|
133
|
+
const navigate = useNavigate();
|
|
134
|
+
const run = useTask(mock ? undefined : taskUid);
|
|
135
|
+
const cancel = useCancelTask();
|
|
136
|
+
const answer = useAnswerTask();
|
|
137
|
+
// Asked for whatever the run's own trace holds; the hook itself stops
|
|
138
|
+
// polling when the run reaches a terminal state, and asks for nothing at
|
|
139
|
+
// all in `mock`.
|
|
140
|
+
const trace = useRunTrace(mock ? undefined : taskUid, { enabled: !mock });
|
|
141
|
+
const [reply, setReply] = useState('');
|
|
142
|
+
// Live while it runs, and it ends itself when the run is over. Never for
|
|
143
|
+
// the documentation's copy: it names a run that does not exist.
|
|
144
|
+
useTaskEvents(taskUid, {
|
|
145
|
+
enabled: !mock && Boolean(run.data) && !isRunOver(run.data.status),
|
|
146
|
+
});
|
|
147
|
+
if (!mock && run.isError) {
|
|
148
|
+
return (_jsx(McpErrorBlankslate, { state: errorState(run.error, 'Run'), onRetry: () => run.refetch() }));
|
|
149
|
+
}
|
|
150
|
+
if (!mock && (run.isLoading || !run.data)) {
|
|
151
|
+
return (_jsx(Box, { sx: { display: 'flex', justifyContent: 'center', p: 4 }, children: _jsx(Spinner, {}) }));
|
|
152
|
+
}
|
|
153
|
+
const task = mock ? SAMPLE_RUN : run.data;
|
|
154
|
+
const look = RUN_STATUS_LOOK[task.status];
|
|
155
|
+
const over = isRunOver(task.status);
|
|
156
|
+
const output = outputTextOf(task);
|
|
157
|
+
return (_jsxs(Box, { sx: { display: 'grid', gap: 3, minWidth: 0 }, children: [_jsxs(Box, { children: [_jsx(Link, { href: routes.runs, onClick: event => {
|
|
158
|
+
event.preventDefault();
|
|
159
|
+
navigate(routes.runs);
|
|
160
|
+
}, sx: { fontSize: 0 }, children: "All runs" }), _jsx(Heading, { as: "h2", sx: { fontSize: 3, mt: 1, mb: 1 }, children: task.tool || 'Run' }), _jsxs(Box, { sx: {
|
|
161
|
+
display: 'flex',
|
|
162
|
+
gap: 2,
|
|
163
|
+
alignItems: 'center',
|
|
164
|
+
flexWrap: 'wrap',
|
|
165
|
+
}, children: [_jsx(Label, { size: "small", variant: look.variant, children: look.label }), _jsx(Text, { sx: { fontFamily: 'mono', fontSize: 0, color: 'fg.muted' }, children: task.uid }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["updated ", _jsx(RelativeTime, { datetime: task.lastUpdatedAt })] })] }), task.statusMessage && (_jsx(Text, { as: "p", sx: { fontSize: 1, color: 'fg.muted', mt: 2 }, children: task.statusMessage }))] }), task.status === 'input_required' && (_jsxs(Box, { sx: {
|
|
166
|
+
borderWidth: 1,
|
|
167
|
+
borderStyle: 'solid',
|
|
168
|
+
borderColor: 'attention.emphasis',
|
|
169
|
+
borderRadius: 2,
|
|
170
|
+
p: 3,
|
|
171
|
+
display: 'grid',
|
|
172
|
+
gap: 2,
|
|
173
|
+
}, children: [_jsx(Heading, { as: "h3", sx: { fontSize: 1 }, children: "This run is waiting on you" }), _jsx(Textarea, { "aria-label": "Your answer", value: reply, onChange: event => setReply(event.target.value), placeholder: "Your answer", rows: 3 }), _jsx(Box, { children: _jsx(Button, { variant: "primary", disabled: !reply.trim() || answer.isPending, onClick: () => answer.mutate({ taskUid: task.uid, input: { answer: reply } }, { onSuccess: () => setReply('') }), children: answer.isPending ? 'Answering…' : 'Answer' }) })] })), _jsxs(Box, { children: [_jsx(Heading, { as: "h3", sx: { fontSize: 1, mb: 2 }, children: "Output" }), output ? (_jsx(Box, { as: "pre", sx: {
|
|
174
|
+
fontFamily: 'mono',
|
|
175
|
+
fontSize: 0,
|
|
176
|
+
whiteSpace: 'pre-wrap',
|
|
177
|
+
overflowX: 'auto',
|
|
178
|
+
bg: 'canvas.subtle',
|
|
179
|
+
borderRadius: 2,
|
|
180
|
+
p: 3,
|
|
181
|
+
m: 0,
|
|
182
|
+
}, children: output })) : (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: over
|
|
183
|
+
? 'This run printed nothing.'
|
|
184
|
+
: 'Nothing printed yet. Output appears here as it arrives.' }))] }), task.error && (_jsxs(Box, { children: [_jsx(Heading, { as: "h3", sx: { fontSize: 1, mb: 2 }, children: "Why it failed" }), _jsx(Text, { sx: { fontFamily: 'mono', fontSize: 0, color: 'danger.fg' }, children: task.error })] })), _jsx(TraceTimelineSection, { tree: mock ? SAMPLE_TRACE : (trace.data?.tree ?? []), traceId: mock ? SAMPLE_TRACE[0].span.trace_id : trace.data?.traceId, live: !over }), !over && (_jsxs(Box, { children: [_jsx(Button, { variant: "danger", disabled: cancel.isPending, onClick: () => cancel.mutate(task.uid), children: cancel.isPending ? 'Cancelling…' : 'Cancel this run' }), _jsx(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', mt: 2 }, children: "Cancelling interrupts the work itself, so the sandbox stops being billed for it. What it has already printed is kept." })] }))] }));
|
|
185
|
+
};
|
|
186
|
+
export default RunDetail;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The directory's other half: who exists, and who has left.
|
|
3
|
+
*
|
|
4
|
+
* The identity provider above signs people in. It can only ever act on
|
|
5
|
+
* somebody who *arrives* — which makes it useless for the thing an
|
|
6
|
+
* organization actually needs from a directory, because the person who left
|
|
7
|
+
* is exactly the person who does not turn up. That is what SCIM is for, and
|
|
8
|
+
* why this sits under the same page rather than somewhere else.
|
|
9
|
+
*
|
|
10
|
+
* **The status line is the point of this view, not the table.** A table of
|
|
11
|
+
* tokens looks almost identical in three quite different situations: a live
|
|
12
|
+
* integration; one whose every token has been revoked; and one configured
|
|
13
|
+
* months ago that has never once been called. In the last two, nobody is
|
|
14
|
+
* being deprovisioned — and an administrator reading rows would have to
|
|
15
|
+
* notice an empty "last used" column to know it. So the state is computed
|
|
16
|
+
* (`scimStatus`) and said in a sentence, in the colour that matches.
|
|
17
|
+
*
|
|
18
|
+
* **The secret is shown once.** Only a SHA-256 of it is stored, so there is
|
|
19
|
+
* no call that could show it again and this view offers none. The dialog
|
|
20
|
+
* says so before the value, not after it.
|
|
21
|
+
*
|
|
22
|
+
* @module views/mcp/ScimProvisioning
|
|
23
|
+
*/
|
|
24
|
+
import type { JSX } from 'react';
|
|
25
|
+
import { scimStatus } from '../../api/iam/scimTokens';
|
|
26
|
+
import type { McpErrorStateFn } from './types';
|
|
27
|
+
export interface ScimProvisioningProps {
|
|
28
|
+
errorState: McpErrorStateFn;
|
|
29
|
+
orgUid: string;
|
|
30
|
+
/**
|
|
31
|
+
* Read-only for anybody who is not an owner. A SCIM token *is* the
|
|
32
|
+
* organization's provisioning authority — whoever holds one can remove
|
|
33
|
+
* anybody from it.
|
|
34
|
+
*/
|
|
35
|
+
readOnly?: boolean;
|
|
36
|
+
showTitle?: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* What the status line says, and how alarming it looks.
|
|
40
|
+
*
|
|
41
|
+
* Exported because these sentences *are* the feature. The table below them
|
|
42
|
+
* is nearly identical in all four states, and the whole reason this view
|
|
43
|
+
* exists is that "a SCIM token is configured" and "people are actually being
|
|
44
|
+
* removed" are different facts. A message that reassured in a state where
|
|
45
|
+
* nobody is being deprovisioned would be worse than no view at all, so it is
|
|
46
|
+
* held by a test rather than by care taken while writing it.
|
|
47
|
+
*/
|
|
48
|
+
export declare const SCIM_STATUS_MESSAGES: Record<ReturnType<typeof scimStatus>['state'], {
|
|
49
|
+
variant: 'default' | 'success' | 'warning';
|
|
50
|
+
heading: string;
|
|
51
|
+
body: string;
|
|
52
|
+
}>;
|
|
53
|
+
export declare const ScimProvisioning: ({ errorState, orgUid, readOnly, showTitle, }: ScimProvisioningProps) => JSX.Element;
|
|
54
|
+
export default ScimProvisioning;
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo, useRef, useState } from 'react';
|
|
3
|
+
import { ActionList, ActionMenu, Button, Flash, FormControl, Heading, IconButton, Label, Spinner, Text, TextInput, } from '@primer/react';
|
|
4
|
+
import { Blankslate, DataTable, Dialog, Table, } from '@primer/react/experimental';
|
|
5
|
+
import { Box } from '@datalayer/primer-addons';
|
|
6
|
+
import { KebabHorizontalIcon, PeopleIcon } from '@primer/octicons-react';
|
|
7
|
+
import { McpErrorBlankslate } from '../../components/mcp/index.js';
|
|
8
|
+
import { useCoreStore } from '../../state/index.js';
|
|
9
|
+
import { useToast } from '../../hooks/index.js';
|
|
10
|
+
import { useCreateScimToken, useRevokeScimToken, useRotateScimToken, useScimTokens, } from '../../hooks/useMcp.js';
|
|
11
|
+
import { scimBaseUrl, scimStatus } from '../../api/iam/scimTokens.js';
|
|
12
|
+
import { timeAgo } from './format.js';
|
|
13
|
+
/**
|
|
14
|
+
* What the status line says, and how alarming it looks.
|
|
15
|
+
*
|
|
16
|
+
* Exported because these sentences *are* the feature. The table below them
|
|
17
|
+
* is nearly identical in all four states, and the whole reason this view
|
|
18
|
+
* exists is that "a SCIM token is configured" and "people are actually being
|
|
19
|
+
* removed" are different facts. A message that reassured in a state where
|
|
20
|
+
* nobody is being deprovisioned would be worse than no view at all, so it is
|
|
21
|
+
* held by a test rather than by care taken while writing it.
|
|
22
|
+
*/
|
|
23
|
+
export const SCIM_STATUS_MESSAGES = {
|
|
24
|
+
none: {
|
|
25
|
+
variant: 'default',
|
|
26
|
+
heading: 'No directory is provisioning into this organization',
|
|
27
|
+
body: 'People are added and removed by hand. Issue a token to let the ' +
|
|
28
|
+
'directory do it — and, more importantly, to have it remove people ' +
|
|
29
|
+
'when they leave.',
|
|
30
|
+
},
|
|
31
|
+
revoked: {
|
|
32
|
+
variant: 'warning',
|
|
33
|
+
heading: 'Every SCIM token is revoked — nobody is being deprovisioned',
|
|
34
|
+
body: 'The directory can no longer reach this organization. Anybody it ' +
|
|
35
|
+
'removes stays a member here until somebody does it by hand. Rotate a ' +
|
|
36
|
+
'token, or issue a new one, and reconfigure the directory with it.',
|
|
37
|
+
},
|
|
38
|
+
'never-used': {
|
|
39
|
+
variant: 'warning',
|
|
40
|
+
heading: 'A token exists and the directory has never used it',
|
|
41
|
+
body: 'Nothing has been provisioned or deprovisioned through it. Either the ' +
|
|
42
|
+
'directory has not been configured with it yet, or it was configured ' +
|
|
43
|
+
'with a token that has since been rotated.',
|
|
44
|
+
},
|
|
45
|
+
active: {
|
|
46
|
+
variant: 'success',
|
|
47
|
+
heading: 'The directory is provisioning into this organization',
|
|
48
|
+
body: 'People it adds become members; people it removes lose their ' +
|
|
49
|
+
'membership and, with it, every agent grant this organization gave ' +
|
|
50
|
+
'them.',
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
export const ScimProvisioning = ({ errorState, orgUid, readOnly = false, showTitle = true, }) => {
|
|
54
|
+
const { enqueueToast } = useToast();
|
|
55
|
+
const iamUrl = useCoreStore(state => state.configuration.iamUrl);
|
|
56
|
+
const tokens = useScimTokens(orgUid);
|
|
57
|
+
const create = useCreateScimToken(orgUid);
|
|
58
|
+
const rotate = useRotateScimToken(orgUid);
|
|
59
|
+
const revoke = useRevokeScimToken(orgUid);
|
|
60
|
+
const [creating, setCreating] = useState(false);
|
|
61
|
+
const [name, setName] = useState('');
|
|
62
|
+
/** The one moment a secret exists in this process. Cleared on close. */
|
|
63
|
+
const [secret, setSecret] = useState('');
|
|
64
|
+
// Primer's Dialog wants a non-nullable `RefObject<HTMLElement>`. React
|
|
65
|
+
// 19's `useRef(null)` is nullable, and this ref only ever reaches Dialog,
|
|
66
|
+
// so narrow it once here — the same way `IdentityProviders` does.
|
|
67
|
+
const returnFocusRef = useRef(null);
|
|
68
|
+
const rows = useMemo(() => (tokens.data ?? []).map(entry => ({ ...entry, id: entry.uid })), [tokens.data]);
|
|
69
|
+
const status = useMemo(() => scimStatus(tokens.data ?? []), [tokens.data]);
|
|
70
|
+
const closeSecret = () => setSecret('');
|
|
71
|
+
const openCreate = () => {
|
|
72
|
+
setName('');
|
|
73
|
+
setCreating(true);
|
|
74
|
+
};
|
|
75
|
+
const submitCreate = async () => {
|
|
76
|
+
try {
|
|
77
|
+
const minted = await create.mutateAsync(name.trim() || 'SCIM');
|
|
78
|
+
setCreating(false);
|
|
79
|
+
// Straight into the one dialog that will ever hold it.
|
|
80
|
+
setSecret(minted.secret);
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
enqueueToast(error instanceof Error
|
|
84
|
+
? error.message
|
|
85
|
+
: 'The token could not be created.', { variant: 'error' });
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
const doRotate = async (uid) => {
|
|
89
|
+
try {
|
|
90
|
+
const minted = await rotate.mutateAsync(uid);
|
|
91
|
+
setSecret(minted.secret);
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
enqueueToast(error instanceof Error
|
|
95
|
+
? error.message
|
|
96
|
+
: 'The token could not be rotated.', { variant: 'error' });
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
const doRevoke = async (uid) => {
|
|
100
|
+
try {
|
|
101
|
+
await revoke.mutateAsync(uid);
|
|
102
|
+
enqueueToast('SCIM token revoked.', { variant: 'success' });
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
enqueueToast(error instanceof Error
|
|
106
|
+
? error.message
|
|
107
|
+
: 'The token could not be revoked.', { variant: 'error' });
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
const columns = [
|
|
111
|
+
{
|
|
112
|
+
header: 'Name',
|
|
113
|
+
field: 'name',
|
|
114
|
+
rowHeader: true,
|
|
115
|
+
renderCell: row => (_jsxs(Box, { sx: { display: 'grid', gap: 1 }, children: [_jsx(Text, { sx: { fontWeight: 'semibold' }, children: row.name || 'SCIM' }), row.revoked && (_jsx(Label, { variant: "danger", size: "small", children: "Revoked" }))] })),
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
header: 'Last used',
|
|
119
|
+
field: 'lastUsedAt',
|
|
120
|
+
renderCell: row => row.revoked ? (_jsx(Text, { sx: { color: 'fg.muted' }, children: "\u2014" })) : row.lastUsedAt ? (_jsx(Text, { children: timeAgo(row.lastUsedAt) })) : (
|
|
121
|
+
// Said rather than left blank. An empty cell reads as "no data
|
|
122
|
+
// yet"; this is the difference between a working integration and
|
|
123
|
+
// one nobody ever pointed a directory at.
|
|
124
|
+
_jsx(Text, { sx: { color: 'attention.fg' }, children: "Never" })),
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
header: 'Secret rotated',
|
|
128
|
+
field: 'rotatedAt',
|
|
129
|
+
renderCell: row => _jsx(Text, { children: timeAgo(row.rotatedAt) || '—' }),
|
|
130
|
+
},
|
|
131
|
+
...(readOnly
|
|
132
|
+
? []
|
|
133
|
+
: [
|
|
134
|
+
{
|
|
135
|
+
header: '',
|
|
136
|
+
field: 'uid',
|
|
137
|
+
renderCell: (row) => (_jsxs(ActionMenu, { children: [_jsx(ActionMenu.Anchor, { children: _jsx(IconButton, { icon: KebabHorizontalIcon, "aria-label": `Actions for ${row.name || 'this token'}`, variant: "invisible" }) }), _jsx(ActionMenu.Overlay, { width: "medium", children: _jsxs(ActionList, { children: [_jsxs(ActionList.Item, { disabled: row.revoked, onSelect: () => void doRotate(row.uid), children: ["Rotate secret", _jsx(ActionList.Description, { variant: "block", children: "The old secret stops at once. The directory must be reconfigured with the new one." })] }), _jsxs(ActionList.Item, { variant: "danger", disabled: row.revoked, onSelect: () => void doRevoke(row.uid), children: ["Revoke", _jsx(ActionList.Description, { variant: "block", children: "Provisioning through it stops. The rows it wrote stay readable." })] })] }) })] })),
|
|
138
|
+
},
|
|
139
|
+
]),
|
|
140
|
+
];
|
|
141
|
+
if (tokens.isError) {
|
|
142
|
+
return (_jsx(McpErrorBlankslate, { state: errorState(tokens.error, 'SCIM provisioning'), onRetry: () => tokens.refetch() }));
|
|
143
|
+
}
|
|
144
|
+
const shown = SCIM_STATUS_MESSAGES[status.state];
|
|
145
|
+
return (_jsxs(Box, { sx: { display: 'grid', gap: 3, minWidth: 0 }, children: [showTitle && (_jsxs(Box, { sx: {
|
|
146
|
+
display: 'flex',
|
|
147
|
+
alignItems: 'start',
|
|
148
|
+
justifyContent: 'space-between',
|
|
149
|
+
gap: 3,
|
|
150
|
+
}, children: [_jsxs(Box, { children: [_jsx(Heading, { as: "h2", sx: { fontSize: 3, mb: 1 }, children: "Directory provisioning" }), _jsx(Text, { as: "p", sx: { color: 'fg.muted', fontSize: 1, m: 0 }, children: "Over SCIM. Sign-in can only act on somebody who turns up; this is what removes the person who does not." })] }), !readOnly && (_jsx(Button, { variant: "primary", ref: returnFocusRef, onClick: openCreate, children: "New SCIM token" }))] })), tokens.isPending && !tokens.data ? (_jsx(Box, { sx: { display: 'flex', justifyContent: 'center', py: 5 }, children: _jsx(Spinner, {}) })) : (_jsxs(_Fragment, { children: [_jsxs(Flash, { variant: shown.variant, children: [_jsx(Text, { as: "p", sx: { fontWeight: 'semibold', m: 0 }, children: shown.heading }), _jsx(Text, { as: "p", sx: { fontSize: 1, mt: 1, mb: 0 }, children: shown.body }), status.lastUsedAt && (_jsxs(Text, { as: "p", sx: { fontSize: 1, mt: 1, mb: 0, color: 'fg.muted' }, children: ["Last provisioning call ", timeAgo(status.lastUsedAt), "."] }))] }), rows.length > 0 ? (_jsxs(_Fragment, { children: [_jsxs(Table.Container, { children: [_jsx(Table.Title, { as: "h3", id: "scim-tokens", children: "SCIM tokens" }), _jsx(Table.Subtitle, { as: "p", id: "scim-tokens-subtitle", children: "A revoked token is kept rather than deleted, so the provisioning it did stays attributable." }), _jsx(DataTable, { "aria-labelledby": "scim-tokens", "aria-describedby": "scim-tokens-subtitle", data: rows, columns: columns })] }), _jsxs(Box, { sx: {
|
|
151
|
+
border: '1px solid',
|
|
152
|
+
borderColor: 'border.default',
|
|
153
|
+
borderRadius: 2,
|
|
154
|
+
p: 3,
|
|
155
|
+
display: 'grid',
|
|
156
|
+
gap: 2,
|
|
157
|
+
}, children: [_jsx(Text, { sx: { fontWeight: 'semibold', fontSize: 1 }, children: "What to give the directory" }), _jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: "SCIM base URL" }), _jsx(TextInput, { block: true, readOnly: true, value: scimBaseUrl(iamUrl), "aria-describedby": "scim-base-url-note" }), _jsxs(FormControl.Caption, { id: "scim-base-url-note", children: ["Okta and Entra append ", _jsx("code", { children: "/Users" }), " themselves. Use the token as a bearer credential; the token is what says which organization is being provisioned, so nothing else names this one."] })] }), _jsxs(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', m: 0 }, children: ["Groups are not provisioned over SCIM \u2014 this server answers them ", _jsx("code", { children: "501" }), " saying so. Roles come from the sign-in token\u2019s groups claim and the provider\u2019s role mappings, above; a second source of the same fact would eventually disagree with the first."] })] })] })) : (_jsxs(Blankslate, { border: true, spacious: true, children: [_jsx(Blankslate.Visual, { children: _jsx(PeopleIcon, { size: "medium" }) }), _jsx(Blankslate.Heading, { children: "No SCIM token" }), _jsx(Blankslate.Description, { children: _jsx(Text, { sx: { textAlign: 'center' }, children: "Issue one to let this organization\u2019s directory add people when they join and \u2014 the part sign-in cannot do \u2014 remove them when they leave." }) }), !readOnly && (_jsx(Button, { size: "small", onClick: openCreate, children: "New SCIM token" }))] }))] })), creating && (_jsx(Dialog, { title: "New SCIM token", onClose: () => setCreating(false), returnFocusRef: returnFocusRef, footerButtons: [
|
|
158
|
+
{
|
|
159
|
+
buttonType: 'default',
|
|
160
|
+
content: 'Cancel',
|
|
161
|
+
onClick: () => setCreating(false),
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
buttonType: 'primary',
|
|
165
|
+
content: 'Issue token',
|
|
166
|
+
onClick: () => void submitCreate(),
|
|
167
|
+
disabled: create.isPending,
|
|
168
|
+
},
|
|
169
|
+
], children: _jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: "Name" }), _jsx(TextInput, { block: true, autoFocus: true, value: name, placeholder: "Okta", onChange: event => setName(event.target.value) }), _jsx(FormControl.Caption, { children: "Whatever tells this directory from another. Only for your own reading \u2014 it is not part of the credential." })] }) })), secret && (_jsx(Dialog, { title: "Copy this token now", onClose: closeSecret, footerButtons: [
|
|
170
|
+
{ buttonType: 'primary', content: 'Done', onClick: closeSecret },
|
|
171
|
+
], children: _jsxs(Box, { sx: { display: 'grid', gap: 2 }, children: [_jsx(Flash, { variant: "warning", children: "This is the only time this token is shown. Only a hash of it is stored, so it cannot be shown again \u2014 if it is lost, rotate." }), _jsx(TextInput, { block: true, readOnly: true, value: secret, "aria-label": "SCIM token", sx: { fontFamily: 'mono' }, onFocus: event => event.target.select() }), _jsxs(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', m: 0 }, children: ["Give it to the directory as a bearer token, with the base URL", ' ', _jsx("code", { children: scimBaseUrl(iamUrl) }), "."] })] }) }))] }));
|
|
172
|
+
};
|
|
173
|
+
export default ScimProvisioning;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The organization's service agents: principals rather than proxies.
|
|
3
|
+
*
|
|
4
|
+
* The Agents page next door lists *grants* — somebody's authority narrowed
|
|
5
|
+
* to one client, dying with their account. This page lists the other kind:
|
|
6
|
+
* an agent that belongs to the organization, holds its own key, spends
|
|
7
|
+
* under its own name and outlives whoever set it up. An organization whose
|
|
8
|
+
* nightly pipeline runs on an engineer's grant loses the pipeline when the
|
|
9
|
+
* engineer leaves, and its spend shows against somebody who was asleep.
|
|
10
|
+
*
|
|
11
|
+
* Three things this page has to get right, all of them about the key:
|
|
12
|
+
*
|
|
13
|
+
* **It is shown once**, in the dialog that creates or rotates it, and the
|
|
14
|
+
* dialog says so before it says anything else. IAM stores a hash and cannot
|
|
15
|
+
* show it again, so somebody who does not read that sentence stores nothing
|
|
16
|
+
* and rotates an hour later.
|
|
17
|
+
*
|
|
18
|
+
* **Rotating breaks the old key immediately.** There is no grace period, by
|
|
19
|
+
* design, so the confirmation says what will stop rather than asking a
|
|
20
|
+
* yes/no about a word.
|
|
21
|
+
*
|
|
22
|
+
* **Revoking does not remove the row.** Its audit rows name it, and a uid
|
|
23
|
+
* that resolves to nothing makes a year-old row unreadable. Revoked is a
|
|
24
|
+
* state in the table, never a reason to hide it.
|
|
25
|
+
*
|
|
26
|
+
* @module views/mcp/ServiceAgents
|
|
27
|
+
*/
|
|
28
|
+
import type { JSX } from 'react';
|
|
29
|
+
import type { McpErrorStateFn } from './types';
|
|
30
|
+
export interface ServiceAgentsProps {
|
|
31
|
+
/** The application's words for a failed request. */
|
|
32
|
+
errorState: McpErrorStateFn;
|
|
33
|
+
/** The organization whose agents these are. */
|
|
34
|
+
orgUid: string;
|
|
35
|
+
/**
|
|
36
|
+
* Read-only for anybody who is not an owner. Members may *see* the list —
|
|
37
|
+
* an agent spending their organization's budget is one they will ask
|
|
38
|
+
* about — and IAM refuses their writes either way; this only keeps the
|
|
39
|
+
* page from offering an action that would be refused.
|
|
40
|
+
*/
|
|
41
|
+
readOnly?: boolean;
|
|
42
|
+
/** Drawn without its heading, when the page around it carries one. */
|
|
43
|
+
showTitle?: boolean;
|
|
44
|
+
}
|
|
45
|
+
export declare const ServiceAgents: ({ errorState, orgUid, readOnly, showTitle, }: ServiceAgentsProps) => JSX.Element;
|
|
46
|
+
export default ServiceAgents;
|