@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
package/lib/utils/Jwt.d.ts
CHANGED
|
@@ -24,6 +24,32 @@ export interface DatalayerJwtPayload {
|
|
|
24
24
|
* Returns `null` on any error (malformed token, invalid base64, etc.).
|
|
25
25
|
*/
|
|
26
26
|
export declare function parseJwtPayload<T = DatalayerJwtPayload>(token: string): T | null;
|
|
27
|
+
/**
|
|
28
|
+
* When a JWT expires, in milliseconds since the epoch.
|
|
29
|
+
*
|
|
30
|
+
* `null` when there is no token, when it cannot be decoded, or when it
|
|
31
|
+
* carries no `exp` — three different unknowns that all mean the same thing to
|
|
32
|
+
* a caller: nothing here says this token has expired.
|
|
33
|
+
*/
|
|
34
|
+
export declare function getJwtExpiryMs(token: string | null | undefined): number | null;
|
|
35
|
+
/**
|
|
36
|
+
* Whether a JWT has already expired.
|
|
37
|
+
*
|
|
38
|
+
* Answers `false` for anything it cannot read — a missing token, an opaque
|
|
39
|
+
* one, a payload with no `exp`. This is the only safe direction: a caller
|
|
40
|
+
* uses it to refuse a request before making it, and refusing on a token we
|
|
41
|
+
* failed to parse would break every non-JWT credential the API accepts.
|
|
42
|
+
*
|
|
43
|
+
* Unverified, and deliberately so. The signature is the server's business;
|
|
44
|
+
* what a client can usefully do with `exp` is avoid sending a request whose
|
|
45
|
+
* only possible answer is 401, and tell the person why in the meantime.
|
|
46
|
+
*
|
|
47
|
+
* `leewaySeconds` counts a token as expired slightly early. A request takes
|
|
48
|
+
* time to arrive, so a token with a second left on it is one the server may
|
|
49
|
+
* well reject by the time it reads it — and a typed expiry error is a better
|
|
50
|
+
* answer for the reader than an opaque 401.
|
|
51
|
+
*/
|
|
52
|
+
export declare function isJwtExpired(token: string | null | undefined, leewaySeconds?: number): boolean;
|
|
27
53
|
/**
|
|
28
54
|
* Extract the Datalayer user object from a JWT, returning `null` if the
|
|
29
55
|
* token is missing or cannot be decoded.
|
package/lib/utils/Jwt.js
CHANGED
|
@@ -29,6 +29,43 @@ export function parseJwtPayload(token) {
|
|
|
29
29
|
return null;
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* When a JWT expires, in milliseconds since the epoch.
|
|
34
|
+
*
|
|
35
|
+
* `null` when there is no token, when it cannot be decoded, or when it
|
|
36
|
+
* carries no `exp` — three different unknowns that all mean the same thing to
|
|
37
|
+
* a caller: nothing here says this token has expired.
|
|
38
|
+
*/
|
|
39
|
+
export function getJwtExpiryMs(token) {
|
|
40
|
+
if (!token)
|
|
41
|
+
return null;
|
|
42
|
+
const payload = parseJwtPayload(token);
|
|
43
|
+
const exp = payload?.exp;
|
|
44
|
+
return typeof exp === 'number' && Number.isFinite(exp) ? exp * 1000 : null;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Whether a JWT has already expired.
|
|
48
|
+
*
|
|
49
|
+
* Answers `false` for anything it cannot read — a missing token, an opaque
|
|
50
|
+
* one, a payload with no `exp`. This is the only safe direction: a caller
|
|
51
|
+
* uses it to refuse a request before making it, and refusing on a token we
|
|
52
|
+
* failed to parse would break every non-JWT credential the API accepts.
|
|
53
|
+
*
|
|
54
|
+
* Unverified, and deliberately so. The signature is the server's business;
|
|
55
|
+
* what a client can usefully do with `exp` is avoid sending a request whose
|
|
56
|
+
* only possible answer is 401, and tell the person why in the meantime.
|
|
57
|
+
*
|
|
58
|
+
* `leewaySeconds` counts a token as expired slightly early. A request takes
|
|
59
|
+
* time to arrive, so a token with a second left on it is one the server may
|
|
60
|
+
* well reject by the time it reads it — and a typed expiry error is a better
|
|
61
|
+
* answer for the reader than an opaque 401.
|
|
62
|
+
*/
|
|
63
|
+
export function isJwtExpired(token, leewaySeconds = 0) {
|
|
64
|
+
const expiryMs = getJwtExpiryMs(token);
|
|
65
|
+
if (expiryMs === null)
|
|
66
|
+
return false;
|
|
67
|
+
return expiryMs - leewaySeconds * 1000 <= Date.now();
|
|
68
|
+
}
|
|
32
69
|
/**
|
|
33
70
|
* Extract the Datalayer user object from a JWT, returning `null` if the
|
|
34
71
|
* token is missing or cannot be decoded.
|
package/lib/utils/Lazy.d.ts
CHANGED
|
@@ -2,6 +2,26 @@ import { ComponentType } from 'react';
|
|
|
2
2
|
export type PreloadableComponent<T extends ComponentType<any>> = T & {
|
|
3
3
|
preload: () => Promise<void>;
|
|
4
4
|
};
|
|
5
|
+
/**
|
|
6
|
+
* `React.lazy`, with a `preload()` that fetches the module ahead of the
|
|
7
|
+
* first render.
|
|
8
|
+
*
|
|
9
|
+
* Two rules keep it honest:
|
|
10
|
+
*
|
|
11
|
+
* - **One fetch.** `preload()` and React's own first render share a single
|
|
12
|
+
* call to `factory`. They used to call it separately, so a component that
|
|
13
|
+
* was preloaded and then rendered imported its module twice.
|
|
14
|
+
* - **One element type per mounted instance.** The component renders the
|
|
15
|
+
* loaded module directly when it was already loaded at mount — no fallback
|
|
16
|
+
* flash — and the lazy wrapper otherwise, and it keeps that choice for its
|
|
17
|
+
* lifetime. It used to switch from the wrapper to the loaded module on any
|
|
18
|
+
* render after `preload()` resolved, and React remounts on a change of
|
|
19
|
+
* element type: a component preloaded after it had mounted lost its state
|
|
20
|
+
* and ran its effects again on its next render.
|
|
21
|
+
*
|
|
22
|
+
* A failed fetch is forgotten, so the next `preload()` tries again rather
|
|
23
|
+
* than replaying the failure.
|
|
24
|
+
*/
|
|
5
25
|
export declare function lazyWithPreload<T extends ComponentType<any>>(factory: () => Promise<{
|
|
6
26
|
default: T;
|
|
7
27
|
}>): PreloadableComponent<T>;
|
package/lib/utils/Lazy.js
CHANGED
|
@@ -2,22 +2,48 @@
|
|
|
2
2
|
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
3
|
* Distributed under the terms of the Modified BSD License.
|
|
4
4
|
*/
|
|
5
|
-
import { createElement, forwardRef, lazy as reactLazy, } from 'react';
|
|
5
|
+
import { createElement, forwardRef, lazy as reactLazy, useState, } from 'react';
|
|
6
|
+
/**
|
|
7
|
+
* `React.lazy`, with a `preload()` that fetches the module ahead of the
|
|
8
|
+
* first render.
|
|
9
|
+
*
|
|
10
|
+
* Two rules keep it honest:
|
|
11
|
+
*
|
|
12
|
+
* - **One fetch.** `preload()` and React's own first render share a single
|
|
13
|
+
* call to `factory`. They used to call it separately, so a component that
|
|
14
|
+
* was preloaded and then rendered imported its module twice.
|
|
15
|
+
* - **One element type per mounted instance.** The component renders the
|
|
16
|
+
* loaded module directly when it was already loaded at mount — no fallback
|
|
17
|
+
* flash — and the lazy wrapper otherwise, and it keeps that choice for its
|
|
18
|
+
* lifetime. It used to switch from the wrapper to the loaded module on any
|
|
19
|
+
* render after `preload()` resolved, and React remounts on a change of
|
|
20
|
+
* element type: a component preloaded after it had mounted lost its state
|
|
21
|
+
* and ran its effects again on its next render.
|
|
22
|
+
*
|
|
23
|
+
* A failed fetch is forgotten, so the next `preload()` tries again rather
|
|
24
|
+
* than replaying the failure.
|
|
25
|
+
*/
|
|
6
26
|
export function lazyWithPreload(factory) {
|
|
7
|
-
const LazyComponent = reactLazy(factory);
|
|
8
27
|
let factoryPromise;
|
|
9
28
|
let LoadedComponent;
|
|
10
|
-
const
|
|
11
|
-
return createElement(LoadedComponent ?? LazyComponent, Object.assign(ref ? { ref } : {}, props));
|
|
12
|
-
});
|
|
13
|
-
Component.preload = () => {
|
|
29
|
+
const load = () => {
|
|
14
30
|
if (!factoryPromise) {
|
|
15
31
|
factoryPromise = factory().then(module => {
|
|
16
32
|
LoadedComponent = module.default;
|
|
33
|
+
return module;
|
|
34
|
+
}, error => {
|
|
35
|
+
factoryPromise = undefined;
|
|
36
|
+
throw error;
|
|
17
37
|
});
|
|
18
38
|
}
|
|
19
39
|
return factoryPromise;
|
|
20
40
|
};
|
|
41
|
+
const LazyComponent = reactLazy(load);
|
|
42
|
+
const Component = forwardRef(function LazyWithPreload(props, ref) {
|
|
43
|
+
const [Resolved] = useState(() => LoadedComponent ?? LazyComponent);
|
|
44
|
+
return createElement(Resolved, Object.assign(ref ? { ref } : {}, props));
|
|
45
|
+
});
|
|
46
|
+
Component.preload = () => load().then(() => undefined);
|
|
21
47
|
return Component;
|
|
22
48
|
}
|
|
23
49
|
export default lazyWithPreload;
|
|
@@ -7,6 +7,9 @@ export const takeHTMLNodeScreencapture = async (node) => {
|
|
|
7
7
|
const sc = html2canvas(node, {
|
|
8
8
|
width: node.getBoundingClientRect().width,
|
|
9
9
|
height: node.getBoundingClientRect().height,
|
|
10
|
+
// Cross-origin pictures are otherwise left out and their space kept, so a
|
|
11
|
+
// cell carrying an `<img>` from the web captures as a blank rectangle.
|
|
12
|
+
useCORS: true,
|
|
10
13
|
});
|
|
11
14
|
return sc.then(canvas => {
|
|
12
15
|
const croppedCanvas = document.createElement('canvas');
|
|
@@ -1,2 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* A lazily-loaded route, with something to look at while it arrives.
|
|
4
|
+
*
|
|
5
|
+
* `skeleton` was a boolean between one grey box and **nothing at all**, and
|
|
6
|
+
* nothing was the default — so every route in the application showed a blank
|
|
7
|
+
* page for as long as its chunk took, which for an editor is seconds. It now
|
|
8
|
+
* also takes a node, so a route can hand over a drawing of the thing that is
|
|
9
|
+
* coming rather than a hole where it will be.
|
|
10
|
+
*/
|
|
11
|
+
export declare const WithSuspense: (Component: any, preload?: boolean, skeleton?: boolean | ReactNode) => (props: any) => import("react").JSX.Element;
|
|
2
12
|
export default WithSuspense;
|
|
@@ -9,10 +9,20 @@ const Loading = (props) => {
|
|
|
9
9
|
const { skeleton } = props;
|
|
10
10
|
return skeleton ? (_jsx(_Fragment, { children: _jsx(SkeletonBox, { height: "100px" }) })) : (_jsx(_Fragment, {}));
|
|
11
11
|
};
|
|
12
|
+
/**
|
|
13
|
+
* A lazily-loaded route, with something to look at while it arrives.
|
|
14
|
+
*
|
|
15
|
+
* `skeleton` was a boolean between one grey box and **nothing at all**, and
|
|
16
|
+
* nothing was the default — so every route in the application showed a blank
|
|
17
|
+
* page for as long as its chunk took, which for an editor is seconds. It now
|
|
18
|
+
* also takes a node, so a route can hand over a drawing of the thing that is
|
|
19
|
+
* coming rather than a hole where it will be.
|
|
20
|
+
*/
|
|
12
21
|
export const WithSuspense = (Component, preload = true, skeleton = false) => (props) => {
|
|
13
22
|
if (preload) {
|
|
14
23
|
Component.preload();
|
|
15
24
|
}
|
|
16
|
-
|
|
25
|
+
const fallback = typeof skeleton === 'boolean' ? (_jsx(Loading, { skeleton: skeleton })) : (skeleton);
|
|
26
|
+
return (_jsx(Suspense, { fallback: fallback, children: _jsx(Component, { ...props }) }));
|
|
17
27
|
};
|
|
18
28
|
export default WithSuspense;
|
|
@@ -4,5 +4,5 @@ export type APIKeyEditProps = {
|
|
|
4
4
|
/** Whether to render the local edit title header. Defaults to true. */
|
|
5
5
|
showTitle?: boolean;
|
|
6
6
|
};
|
|
7
|
-
export declare const APIKeyEdit: ({ apiKeysListRoute, showTitle, }?: APIKeyEditProps) => import("react
|
|
7
|
+
export declare const APIKeyEdit: ({ apiKeysListRoute, showTitle, }?: APIKeyEditProps) => import("react").JSX.Element;
|
|
8
8
|
export default APIKeyEdit;
|
|
@@ -4,5 +4,5 @@ export type APIKeyNewProps = {
|
|
|
4
4
|
/** Whether to render the "New API Key" title header in create mode. Defaults to true. */
|
|
5
5
|
showTitle?: boolean;
|
|
6
6
|
};
|
|
7
|
-
export declare const APIKeyNew: ({ apiKeysListRoute, showTitle, }?: APIKeyNewProps) => import("react
|
|
7
|
+
export declare const APIKeyNew: ({ apiKeysListRoute, showTitle, }?: APIKeyNewProps) => import("react").JSX.Element;
|
|
8
8
|
export default APIKeyNew;
|
|
@@ -8,5 +8,5 @@ export type APIKeysProps = {
|
|
|
8
8
|
/** Whether to render the "New API Key" button in this component header. Defaults to true. */
|
|
9
9
|
showNewButton?: boolean;
|
|
10
10
|
};
|
|
11
|
-
export declare const APIKeys: ({ newAPIKeyRoute, apiKeysListRoute, showTitle, showNewButton, }?: APIKeysProps) => import("react
|
|
11
|
+
export declare const APIKeys: ({ newAPIKeyRoute, apiKeysListRoute, showTitle, showNewButton, }?: APIKeysProps) => import("react").JSX.Element;
|
|
12
12
|
export default APIKeys;
|
|
@@ -61,12 +61,39 @@ const APIKeysTable = ({ apiKeysListRoute, showTitle = true, }) => {
|
|
|
61
61
|
},
|
|
62
62
|
});
|
|
63
63
|
};
|
|
64
|
+
/** Where one API key is read, from wherever this table is drawn. */
|
|
65
|
+
const routeOf = (id) => apiKeysListRoute ? `${apiKeysListRoute}/${id}` : `${id}`;
|
|
66
|
+
/*
|
|
67
|
+
* A row opens the key it stands for.
|
|
68
|
+
*
|
|
69
|
+
* The click is caught on the way up rather than bound to each row: the
|
|
70
|
+
* table is drawn by `DataTable`, which owns its rows and takes no handler
|
|
71
|
+
* for them. So the row says which key it is — the name cell carries it —
|
|
72
|
+
* and this reads it back off whatever was clicked. Reading it from the row
|
|
73
|
+
* itself rather than from a position is what survives sorting.
|
|
74
|
+
*/
|
|
75
|
+
const openClickedRow = (event) => {
|
|
76
|
+
const clicked = event.target;
|
|
77
|
+
// Something that already does something on click is not a row click.
|
|
78
|
+
if (clicked.closest('button, a, input, [role="menuitem"]')) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const id = clicked
|
|
82
|
+
.closest('tr')
|
|
83
|
+
?.querySelector('[data-api-key]')?.dataset.apiKey;
|
|
84
|
+
if (id) {
|
|
85
|
+
navigate(routeOf(id));
|
|
86
|
+
}
|
|
87
|
+
};
|
|
64
88
|
return apiKeys.length === 0 ? (_jsx(Blankslate, { border: true, spacious: true, children: showInitialSpinner ? (_jsx(Box, { sx: {
|
|
65
89
|
display: 'flex',
|
|
66
90
|
alignItems: 'center',
|
|
67
91
|
justifyContent: 'center',
|
|
68
92
|
minHeight: '40px',
|
|
69
|
-
}, children: _jsx(Spinner, {}) })) : (_jsxs(_Fragment, { children: [showTitle && _jsx(Blankslate.Heading, { children: "API Keys" }), _jsx(Blankslate.Description, { children: _jsx(Text, { sx: { textAlign: 'center' }, children: "No API Keys found." }) })] })) })) : (_jsxs(_Fragment, { children: [_jsxs(Table.Container, {
|
|
93
|
+
}, children: _jsx(Spinner, {}) })) : (_jsxs(_Fragment, { children: [showTitle && _jsx(Blankslate.Heading, { children: "API Keys" }), _jsx(Blankslate.Description, { children: _jsx(Text, { sx: { textAlign: 'center' }, children: "No API Keys found." }) })] })) })) : (_jsxs(_Fragment, { children: [_jsxs(Table.Container, { onClick: openClickedRow, sx: {
|
|
94
|
+
'& tbody tr': { cursor: 'pointer' },
|
|
95
|
+
'& tbody tr:hover': { bg: 'canvas.subtle' },
|
|
96
|
+
}, children: [showTitle && (_jsxs(_Fragment, { children: [_jsx(Table.Title, { as: "h2", id: "api-keys", children: "API Keys" }), _jsx(Table.Subtitle, { as: "p", id: "api-keys-subtitle", children: "Your API keys." })] })), _jsx(DataTable, { "aria-labelledby": "api-keys", "aria-describedby": "api-keys-subtitle", data: apiKeys, columns: [
|
|
70
97
|
{
|
|
71
98
|
header: 'Type',
|
|
72
99
|
field: 'variant',
|
|
@@ -76,6 +103,7 @@ const APIKeysTable = ({ apiKeysListRoute, showTitle = true, }) => {
|
|
|
76
103
|
header: 'Name',
|
|
77
104
|
field: 'name',
|
|
78
105
|
rowHeader: true,
|
|
106
|
+
renderCell: apiKey => (_jsx(Box, { as: "span", "data-api-key": apiKey.id, children: apiKey.name })),
|
|
79
107
|
},
|
|
80
108
|
{
|
|
81
109
|
header: 'Description',
|
|
@@ -89,9 +117,7 @@ const APIKeysTable = ({ apiKeysListRoute, showTitle = true, }) => {
|
|
|
89
117
|
{
|
|
90
118
|
header: '',
|
|
91
119
|
field: 'id',
|
|
92
|
-
renderCell: apiKey => (_jsxs(Box, { display: "flex", sx: { gap: 1 }, children: [_jsx(IconButton, { icon: EditIcon, "aria-label": "Edit", size: "small", variant: "invisible", onClick: e => navigate(
|
|
93
|
-
? `${apiKeysListRoute}/${apiKey.id}`
|
|
94
|
-
: `${apiKey.id}`, e) }), _jsx(IconButton, { ref: returnFocusRef, icon: TrashIcon, "aria-label": "Delete", size: "small", variant: "invisible", sx: { color: 'danger.fg' }, onClick: () => {
|
|
120
|
+
renderCell: apiKey => (_jsxs(Box, { display: "flex", sx: { gap: 1 }, children: [_jsx(IconButton, { icon: EditIcon, "aria-label": "Edit", size: "small", variant: "invisible", onClick: e => navigate(routeOf(apiKey.id), e) }), _jsx(IconButton, { ref: returnFocusRef, icon: TrashIcon, "aria-label": "Delete", size: "small", variant: "invisible", sx: { color: 'danger.fg' }, onClick: () => {
|
|
95
121
|
setDeletingAPIKey(apiKey);
|
|
96
122
|
setDeleteNameConfirm('');
|
|
97
123
|
} })] })),
|
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
export
|
|
1
|
+
export type APIKeysStandaloneProps = {
|
|
2
|
+
/** Where the "New API Key" button goes. */
|
|
3
|
+
newKeyRoute?: string;
|
|
4
|
+
};
|
|
5
|
+
export declare const APIKeysStandalone: ({ newKeyRoute, }?: APIKeysStandaloneProps) => import("react").JSX.Element;
|
|
2
6
|
export default APIKeysStandalone;
|
|
@@ -110,8 +110,8 @@ const APIKeysTable = () => {
|
|
|
110
110
|
},
|
|
111
111
|
], children: ["Are you sure you want to delete the API key", ' ', _jsx("strong", { children: deletingAPIKey.name }), "? This action cannot be undone.", _jsxs(Text, { sx: { mt: 3, display: 'block', color: 'fg.muted' }, children: ["Type ", _jsx("strong", { children: deletingAPIKey.name }), " to confirm deletion."] }), _jsx(TextInput, { block: true, value: deleteNameConfirm, onChange: e => setDeleteNameConfirm(e.target.value), placeholder: "Retype API key name", sx: { mt: 2 }, autoFocus: true })] }))] }));
|
|
112
112
|
};
|
|
113
|
-
export const APIKeysStandalone = () => {
|
|
113
|
+
export const APIKeysStandalone = ({ newKeyRoute = '/settings/api-keys/new', } = {}) => {
|
|
114
114
|
const navigate = useNavigate();
|
|
115
|
-
return (_jsxs(PageLayout, { containerWidth: "full", padding: "normal", style: { overflow: 'visible', minHeight: 'calc(100vh - 45px)' }, children: [_jsx(PageLayout.Header, { children: _jsxs(PageHeader, { children: [_jsx(PageHeader.TitleArea, { variant: "large", children: _jsx(PageHeader.Title, { children: "API Keys" }) }), _jsx(PageHeader.Actions, { children: _jsx(Button, { size: "small", variant: "primary", onClick: e => navigate(
|
|
115
|
+
return (_jsxs(PageLayout, { containerWidth: "full", padding: "normal", style: { overflow: 'visible', minHeight: 'calc(100vh - 45px)' }, children: [_jsx(PageLayout.Header, { children: _jsxs(PageHeader, { children: [_jsx(PageHeader.TitleArea, { variant: "large", children: _jsx(PageHeader.Title, { children: "API Keys" }) }), _jsx(PageHeader.Actions, { children: _jsx(Button, { size: "small", variant: "primary", onClick: e => navigate(newKeyRoute, e), children: "New API key" }) })] }) }), _jsx(PageLayout.Content, { children: _jsx(Box, { children: _jsx(APIKeysTable, {}) }) })] }));
|
|
116
116
|
};
|
|
117
117
|
export default APIKeysStandalone;
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
export type DatasourceDetailProps = {
|
|
2
|
-
/**
|
|
3
|
-
|
|
4
|
-
/** Optional principal kind used to scope datasource reads/updates. */
|
|
5
|
-
principalKind?: 'personal' | 'organization' | 'team';
|
|
2
|
+
/** The Datasource, when not read from the `sourceUid` route parameter. */
|
|
3
|
+
sourceUid?: string;
|
|
6
4
|
};
|
|
7
|
-
|
|
5
|
+
/**
|
|
6
|
+
* A Datasource's settings: what it connects to, and the name it goes by.
|
|
7
|
+
*
|
|
8
|
+
* The connection itself is read from Contents and never includes the
|
|
9
|
+
* credential — the page shows whether one is attached and resolvable. Name,
|
|
10
|
+
* description and limits are edited conditionally on the source's ETag, so
|
|
11
|
+
* two people editing the same record do not overwrite each other. Running
|
|
12
|
+
* queries is the Contents detail's job, not this page's.
|
|
13
|
+
*/
|
|
14
|
+
export declare const DatasourceDetail: ({ sourceUid: givenUid }?: DatasourceDetailProps) => import("react").JSX.Element;
|
|
8
15
|
export default DatasourceDetail;
|
|
@@ -1,129 +1,99 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
/*
|
|
3
3
|
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
4
4
|
* Distributed under the terms of the Modified BSD License.
|
|
5
5
|
*/
|
|
6
|
-
|
|
6
|
+
/*
|
|
7
|
+
* Copyright (c) 2023-2026 Datalayer, Inc.
|
|
8
|
+
* Distributed under the terms of the Modified BSD License.
|
|
9
|
+
*/
|
|
10
|
+
import { useEffect, useState } from 'react';
|
|
7
11
|
import { useParams } from 'react-router-dom';
|
|
8
12
|
import { PageLayout, Text, Button, TextInput, FormControl, Textarea, Label, Spinner, Heading, } from '@primer/react';
|
|
9
13
|
import { Box } from '@datalayer/primer-addons';
|
|
10
|
-
import {
|
|
14
|
+
import { DATASOURCE_CONNECTOR_LABELS, } from '../../api/contents/index.js';
|
|
11
15
|
import { BoringAvatar } from '../../components/avatars/index.js';
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
import { useContentSource, useCredentialDiagnostics, useTestDatasource, useToast, useUpdateContentSource, } from '../../hooks/index.js';
|
|
17
|
+
function Row({ label, children }) {
|
|
18
|
+
return (_jsxs(Box, { sx: { display: 'grid', gridTemplateColumns: ['1fr', '200px 1fr'], gap: 1 }, children: [_jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: label }), _jsx(Box, { sx: { fontSize: 1 }, children: children })] }));
|
|
19
|
+
}
|
|
20
|
+
const frame = (children) => (_jsx(PageLayout, { containerWidth: "full", padding: "normal", style: { overflow: 'visible', minHeight: 'calc(100vh - 45px)' }, children: _jsx(PageLayout.Content, { children: _jsx(Box, { sx: { maxWidth: 960, mx: 'auto', width: '100%' }, children: children }) }) }));
|
|
21
|
+
/**
|
|
22
|
+
* A Datasource's settings: what it connects to, and the name it goes by.
|
|
23
|
+
*
|
|
24
|
+
* The connection itself is read from Contents and never includes the
|
|
25
|
+
* credential — the page shows whether one is attached and resolvable. Name,
|
|
26
|
+
* description and limits are edited conditionally on the source's ETag, so
|
|
27
|
+
* two people editing the same record do not overwrite each other. Running
|
|
28
|
+
* queries is the Contents detail's job, not this page's.
|
|
29
|
+
*/
|
|
30
|
+
export const DatasourceDetail = ({ sourceUid: givenUid } = {}) => {
|
|
31
|
+
const params = useParams();
|
|
32
|
+
const sourceUid = givenUid ?? params.sourceUid ?? params.datasourceId;
|
|
17
33
|
const { enqueueToast } = useToast();
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const [
|
|
28
|
-
const [formValues, setFormValues] = useState({
|
|
29
|
-
name: '',
|
|
30
|
-
description: '',
|
|
31
|
-
});
|
|
32
|
-
const [validationResult, setValidationResult] = useState({
|
|
33
|
-
name: undefined,
|
|
34
|
-
description: undefined,
|
|
35
|
-
});
|
|
36
|
-
const [passwordVisibility, setPasswordVisibility] = useState(false);
|
|
34
|
+
const sourceQuery = useContentSource(sourceUid);
|
|
35
|
+
const update = useUpdateContentSource();
|
|
36
|
+
const test = useTestDatasource();
|
|
37
|
+
const source = sourceQuery.data?.value.source;
|
|
38
|
+
const configuration = source?.configuration;
|
|
39
|
+
const diagnostics = useCredentialDiagnostics(configuration?.networkRoute === 'dataserver' ? undefined : sourceUid);
|
|
40
|
+
const [name, setName] = useState('');
|
|
41
|
+
const [description, setDescription] = useState('');
|
|
42
|
+
const [rowLimit, setRowLimit] = useState('');
|
|
43
|
+
const [maxSeconds, setMaxSeconds] = useState('');
|
|
37
44
|
useEffect(() => {
|
|
38
|
-
if (
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
description: datasource.description || '',
|
|
44
|
-
});
|
|
45
|
+
if (source && configuration) {
|
|
46
|
+
setName(source.name);
|
|
47
|
+
setDescription(source.description ?? '');
|
|
48
|
+
setRowLimit(configuration.defaultRowLimit ? String(configuration.defaultRowLimit) : '');
|
|
49
|
+
setMaxSeconds(configuration.maxSeconds ? String(configuration.maxSeconds) : '');
|
|
45
50
|
}
|
|
46
|
-
}, [
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}));
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
51
|
+
}, [source, configuration]);
|
|
52
|
+
if (!sourceUid) {
|
|
53
|
+
return _jsx(_Fragment, {});
|
|
54
|
+
}
|
|
55
|
+
if (sourceQuery.isPending) {
|
|
56
|
+
return frame(_jsx(Box, { sx: { display: 'flex', justifyContent: 'center', alignItems: 'center', py: 6 }, children: _jsx(Spinner, { size: "large" }) }));
|
|
57
|
+
}
|
|
58
|
+
if (sourceQuery.isError || !source || !configuration || source.kind !== 'datasource') {
|
|
59
|
+
return frame(_jsx(Box, { sx: { p: 4 }, children: _jsx(Text, { sx: { color: 'danger.fg' }, children: sourceQuery.isError
|
|
60
|
+
? sourceQuery.error.message
|
|
61
|
+
: 'Datasource not found, or this content is not a Datasource.' }) }));
|
|
62
|
+
}
|
|
63
|
+
const permissions = sourceQuery.data.value.permissions;
|
|
64
|
+
const numberOrNull = (value) => {
|
|
65
|
+
const parsed = Number.parseInt(value, 10);
|
|
66
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
|
|
58
67
|
};
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
name: formValues.name === undefined
|
|
63
|
-
? undefined
|
|
64
|
-
: formValues.name.length > 2
|
|
65
|
-
? true
|
|
66
|
-
: false,
|
|
67
|
-
description: formValues.description === undefined
|
|
68
|
-
? undefined
|
|
69
|
-
: formValues.description.length > 2
|
|
70
|
-
? true
|
|
71
|
-
: false,
|
|
72
|
-
}));
|
|
73
|
-
}, [formValues]);
|
|
74
|
-
const nameSubmit = async () => {
|
|
75
|
-
if (!datasource) {
|
|
68
|
+
const nameValid = name.trim().length > 2;
|
|
69
|
+
const save = () => {
|
|
70
|
+
if (!nameValid) {
|
|
76
71
|
return;
|
|
77
72
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
resp.success) {
|
|
90
|
-
enqueueToast('The datasource is successfully updated.', {
|
|
91
|
-
variant: 'success',
|
|
92
|
-
});
|
|
93
|
-
setDatasource(updatedDatasource);
|
|
94
|
-
}
|
|
95
|
-
},
|
|
96
|
-
onSettled: () => {
|
|
97
|
-
runStore.layout().hideBackdrop();
|
|
73
|
+
update.mutate({
|
|
74
|
+
sourceUid: source.uid,
|
|
75
|
+
etag: sourceQuery.data.etag,
|
|
76
|
+
update: {
|
|
77
|
+
name: name.trim(),
|
|
78
|
+
description: description.trim() || null,
|
|
79
|
+
configuration: {
|
|
80
|
+
...configuration,
|
|
81
|
+
defaultRowLimit: numberOrNull(rowLimit),
|
|
82
|
+
maxSeconds: numberOrNull(maxSeconds),
|
|
83
|
+
},
|
|
98
84
|
},
|
|
85
|
+
}, {
|
|
86
|
+
onSuccess: () => enqueueToast('The Datasource is updated.', { variant: 'success' }),
|
|
99
87
|
});
|
|
100
88
|
};
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}, children: _jsx(Spinner, { size: "large" }) }) }) }) }));
|
|
111
|
-
}
|
|
112
|
-
if (datasourceQuery.isError || (!datasourceQuery.isLoading && !datasource)) {
|
|
113
|
-
return (_jsx(PageLayout, { containerWidth: "full", padding: "normal", style: { overflow: 'visible', minHeight: 'calc(100vh - 45px)' }, children: _jsx(PageLayout.Content, { children: _jsx(Box, { sx: { maxWidth: 960, mx: 'auto', width: '100%' }, children: _jsx(Box, { sx: { p: 4 }, children: _jsx(Text, { sx: { color: 'danger.fg' }, children: "Datasource not found or failed to load." }) }) }) }) }));
|
|
114
|
-
}
|
|
115
|
-
return (_jsx(PageLayout, { containerWidth: "full", padding: "normal", style: { overflow: 'visible', minHeight: 'calc(100vh - 45px)' }, children: _jsx(PageLayout.Content, { children: _jsxs(Box, { sx: { maxWidth: 960, mx: 'auto', width: '100%' }, children: [_jsxs(Box, { sx: { mb: 4 }, children: [_jsx(Heading, { as: "h2", sx: { fontSize: 3, mb: 1 }, children: "Datasource" }), _jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "Update datasource connection metadata and review configured credentials." })] }), _jsx(Box, { sx: {
|
|
116
|
-
border: '1px solid',
|
|
117
|
-
borderColor: 'border.default',
|
|
118
|
-
borderRadius: 2,
|
|
119
|
-
bg: 'canvas.default',
|
|
120
|
-
p: 3,
|
|
121
|
-
}, children: _jsxs(Box, { sx: { display: 'grid', gridTemplateColumns: ['1fr', '180px 1fr'], gap: 4 }, children: [_jsxs(Box, { children: [_jsx(BoringAvatar, { displayName: datasource?.name, size: 100, style: { paddingRight: 10 } }), _jsx(Box, { mt: 3, children: _jsx(Label, { size: "large", children: datasource?.variant }) })] }), _jsx(Box, { children: _jsxs(Box, { sx: { label: { marginTop: 2 } }, children: [_jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: "Name" }), _jsx(TextInput, { block: true, value: formValues.name, onChange: nameNameChange }), validationResult.name === false && (_jsx(FormControl.Validation, { variant: "error", children: "Name must have more than 2 characters." }))] }), _jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: "Description" }), _jsx(Textarea, { block: true, value: formValues.description, onChange: nameDescriptionChange, rows: 5 }), validationResult.description === false && (_jsx(FormControl.Validation, { variant: "error", children: "Description must have more than 2 characters." }))] }), _jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: "Database" }), _jsx(TextInput, { placeholder: "Database", monospace: true, size: "large", contrast: !passwordVisibility, disabled: !passwordVisibility, type: passwordVisibility ? 'text' : 'password', value: datasource?.database || '', readOnly: true, trailingAction: _jsx(TextInput.Action, { onClick: () => {
|
|
122
|
-
setPasswordVisibility(!passwordVisibility);
|
|
123
|
-
}, icon: passwordVisibility ? EyeClosedIcon : EyeIcon, "aria-label": passwordVisibility ? 'Hide database' : 'Reveal database', sx: { color: 'var(--fgColor-muted)' } }), sx: { overflow: 'visible' } })] }), _jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: "Output bucket" }), _jsx(TextInput, { placeholder: "Output bucket", monospace: true, size: "large", contrast: !passwordVisibility, disabled: !passwordVisibility, type: passwordVisibility ? 'text' : 'password', value: datasource?.outputBucket || '', readOnly: true, trailingAction: _jsx(TextInput.Action, { onClick: () => {
|
|
124
|
-
setPasswordVisibility(!passwordVisibility);
|
|
125
|
-
}, icon: passwordVisibility ? EyeClosedIcon : EyeIcon, "aria-label": passwordVisibility
|
|
126
|
-
? 'Hide output bucket'
|
|
127
|
-
: 'Reveal output bucket', sx: { color: 'var(--fgColor-muted)' } }), sx: { overflow: 'visible' } })] }), _jsx(Box, { sx: { marginTop: 3 }, children: _jsx(Button, { variant: "primary", disabled: !validationResult.name || !validationResult.description, onClick: nameSubmit, children: "Update datasource" }) })] }) })] }) })] }) }) }));
|
|
89
|
+
const connector = DATASOURCE_CONNECTOR_LABELS[configuration.connectorType]
|
|
90
|
+
?? configuration.connectorType;
|
|
91
|
+
return frame(_jsxs(_Fragment, { children: [_jsxs(Box, { sx: { mb: 4 }, children: [_jsx(Heading, { as: "h2", sx: { fontSize: 3, mb: 1 }, children: "Datasource" }), _jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "The connection as Contents holds it. The credential is never shown; the page says whether one is attached and resolvable." })] }), _jsx(Box, { sx: {
|
|
92
|
+
border: '1px solid',
|
|
93
|
+
borderColor: 'border.default',
|
|
94
|
+
borderRadius: 2,
|
|
95
|
+
bg: 'canvas.default',
|
|
96
|
+
p: 3,
|
|
97
|
+
}, children: _jsxs(Box, { sx: { display: 'grid', gridTemplateColumns: ['1fr', '180px 1fr'], gap: 4 }, children: [_jsxs(Box, { children: [_jsx(BoringAvatar, { displayName: source.name, size: 100, style: { paddingRight: 10 } }), _jsx(Box, { mt: 3, children: _jsx(Label, { size: "large", children: connector }) })] }), _jsxs(Box, { sx: { display: 'grid', gap: 3 }, children: [_jsxs(Box, { sx: { display: 'grid', gap: 2 }, children: [_jsx(Row, { label: "Connector", children: _jsx(Text, { children: connector }) }), _jsxs(Row, { label: "Route", children: [_jsx(Label, { variant: configuration.networkRoute === 'dataserver' ? 'accent' : 'secondary', children: configuration.networkRoute === 'dataserver' ? 'Through a Dataserver' : 'Direct' }), configuration.dataServerUid && (_jsx(Text, { sx: { fontFamily: 'mono', fontSize: 0, ml: 2 }, children: configuration.dataServerUid }))] }), configuration.endpoint && (_jsx(Row, { label: "Endpoint", children: _jsx(Text, { sx: { fontFamily: 'mono', fontSize: 0 }, children: configuration.endpoint }) })), configuration.databaseOrProject && (_jsx(Row, { label: configuration.connectorType === 'bigquery' ? 'Project' : 'Database', children: _jsx(Text, { sx: { fontFamily: 'mono', fontSize: 0 }, children: configuration.databaseOrProject }) })), _jsx(Row, { label: "Allowed operations", children: _jsx(Text, { children: (configuration.allowedOperations ?? []).join(', ') || '—' }) }), _jsx(Row, { label: "Credential", children: configuration.networkRoute === 'dataserver' ? (_jsx(Text, { sx: { color: 'fg.muted' }, children: "Held by the Dataserver, in your network." })) : configuration.credentialUid ? (_jsxs(Box, { sx: { display: 'flex', gap: 2, alignItems: 'center', flexWrap: 'wrap' }, children: [diagnostics.data ? (_jsx(Label, { variant: diagnostics.data.resolvable ? 'success' : 'danger', children: diagnostics.data.resolvable ? 'Resolvable' : 'Not resolvable' })) : (_jsx(Label, { variant: "success", children: "Attached" })), _jsx(Text, { sx: { color: 'fg.muted', fontSize: 0 }, children: diagnostics.data?.credentialName ?? 'Held in Vault and resolved server-side.' })] })) : (_jsx(Label, { variant: "attention", children: "None" })) }), _jsx(Row, { label: "Connection", children: _jsxs(Box, { sx: { display: 'flex', gap: 2, alignItems: 'center', flexWrap: 'wrap' }, children: [_jsx(Button, { size: "small", disabled: test.isPending || !permissions.execute, onClick: () => test.mutate(source.uid), children: test.isPending ? 'Testing…' : 'Test connection' }), test.data && (_jsxs(_Fragment, { children: [_jsx(Label, { variant: test.data.ok ? 'success' : 'danger', children: test.data.ok ? 'Reachable' : 'Not reachable' }), _jsx(Text, { sx: { color: 'fg.muted', fontSize: 0 }, children: test.data.detail })] })), test.isError && (_jsx(Text, { sx: { color: 'danger.fg', fontSize: 0 }, children: test.error.message }))] }) })] }), _jsxs(Box, { sx: { label: { marginTop: 2 } }, children: [_jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: "Name" }), _jsx(TextInput, { block: true, value: name, disabled: !permissions.update, onChange: event => setName(event.target.value) }), !nameValid && (_jsx(FormControl.Validation, { variant: "error", children: "Name must have more than 2 characters." }))] }), _jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: "Description" }), _jsx(Textarea, { block: true, rows: 3, value: description, disabled: !permissions.update, onChange: event => setDescription(event.target.value) })] }), _jsxs(Box, { sx: { display: 'grid', gridTemplateColumns: ['1fr', '1fr 1fr'], gap: 3 }, children: [_jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: "Default row limit" }), _jsx(TextInput, { block: true, type: "number", min: 1, value: rowLimit, placeholder: "Service default", disabled: !permissions.update, onChange: event => setRowLimit(event.target.value) })] }), _jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: "Max seconds" }), _jsx(TextInput, { block: true, type: "number", min: 1, value: maxSeconds, placeholder: "Service default", disabled: !permissions.update, onChange: event => setMaxSeconds(event.target.value) })] })] }), update.isError && (_jsx(Text, { as: "p", sx: { color: 'danger.fg' }, children: update.error.message })), permissions.update && (_jsx(Box, { sx: { marginTop: 3 }, children: _jsx(Button, { variant: "primary", disabled: !nameValid || update.isPending, onClick: save, children: update.isPending ? 'Saving…' : 'Update Datasource' }) }))] })] })] }) })] }));
|
|
128
98
|
};
|
|
129
99
|
export default DatasourceDetail;
|
|
@@ -1,15 +1,21 @@
|
|
|
1
|
-
import { ReactNode } from 'react';
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
2
|
export type DatasourceNewProps = {
|
|
3
|
-
/**
|
|
3
|
+
/** Where the created Datasource is opened, as `${route}/${uid}`. Defaults to '/datasources'. */
|
|
4
4
|
datasourcesListRoute?: string;
|
|
5
|
-
/** Route to navigate to the secrets page. Defaults to '/
|
|
5
|
+
/** Route to navigate to the secrets page. Defaults to '/secrets'. */
|
|
6
6
|
secretsRoute?: string;
|
|
7
|
-
/**
|
|
8
|
-
|
|
9
|
-
/** Optional principal kind used to scope datasource creation. */
|
|
10
|
-
principalKind?: 'personal' | 'organization' | 'team';
|
|
7
|
+
/** The Space the Datasource belongs to, when created from one. */
|
|
8
|
+
spaceUid?: string;
|
|
11
9
|
/** Optional contextual principal summary rendered below the page intro. */
|
|
12
10
|
accountPrincipal?: ReactNode;
|
|
13
11
|
};
|
|
14
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Connect a Datasource: a `kind=datasource` content source.
|
|
14
|
+
*
|
|
15
|
+
* Everything but the credential lives in Contents. The credential is a
|
|
16
|
+
* Secret reference — IAM is consulted here only to list the Secrets to pick
|
|
17
|
+
* from — and a source routed through a Dataserver needs none, because the
|
|
18
|
+
* gateway holds the credential in the network the database lives in.
|
|
19
|
+
*/
|
|
20
|
+
export declare const DatasourceNew: ({ datasourcesListRoute, secretsRoute, spaceUid, accountPrincipal, }?: DatasourceNewProps) => import("react").JSX.Element;
|
|
15
21
|
export default DatasourceNew;
|