@datalayer/core 1.0.20 → 1.0.22
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 +27 -0
- package/lib/api/DatalayerApi.d.ts +5 -1
- package/lib/api/DatalayerApi.js +55 -8
- package/lib/api/iam/oauth2.d.ts +3 -3
- package/lib/api/iam/oauth2.js +2 -2
- package/lib/api/iam/profile.d.ts +9 -1
- package/lib/api/iam/profile.js +15 -0
- package/lib/api/runtimes/checkpoints.js +1 -1
- package/lib/api/runtimes/snapshots.d.ts +7 -7
- package/lib/api/runtimes/snapshots.js +9 -9
- package/lib/client/auth/storage.js +103 -12
- package/lib/client/index.d.ts +7 -7
- package/lib/client/index.js +1 -1
- package/lib/client/mixins/RuntimesMixin.d.ts +6 -6
- package/lib/client/mixins/RuntimesMixin.js +5 -5
- package/lib/client/mixins/SpacerMixin.js +22 -1
- package/lib/collaboration/DatalayerCollaborationProvider.d.ts +4 -3
- package/lib/components/avatars/DLAvatar.d.ts +24 -0
- package/lib/components/avatars/DLAvatar.js +26 -0
- package/lib/components/avatars/UserProfileAvatar.js +4 -4
- package/lib/components/avatars/index.d.ts +1 -0
- package/lib/components/avatars/index.js +1 -0
- package/lib/components/billing/BillableAccountSelect.d.ts +35 -0
- package/lib/components/billing/BillableAccountSelect.js +340 -0
- package/lib/components/billing/index.d.ts +1 -0
- package/lib/components/billing/index.js +5 -0
- package/lib/components/checkout/StripeCheckout.d.ts +24 -3
- package/lib/components/checkout/StripeCheckout.js +1116 -55
- package/lib/components/display/DatalayerBox.js +6 -1
- package/lib/components/index.d.ts +2 -0
- package/lib/components/index.js +2 -0
- package/lib/components/principal/Principal.d.ts +37 -0
- package/lib/components/principal/Principal.js +54 -0
- package/lib/components/principal/PrincipalAvatar.d.ts +10 -0
- package/lib/components/principal/PrincipalAvatar.js +55 -0
- package/lib/components/principal/PrincipalBadge.d.ts +20 -0
- package/lib/components/principal/PrincipalBadge.js +208 -0
- package/lib/components/principal/PrincipalBanner.d.ts +7 -0
- package/lib/components/principal/PrincipalBanner.js +84 -0
- package/lib/components/principal/PrincipalDetailsOverlay.d.ts +23 -0
- package/lib/components/principal/PrincipalDetailsOverlay.js +86 -0
- package/lib/components/principal/PrincipalSwitcherMenu.d.ts +14 -0
- package/lib/components/principal/PrincipalSwitcherMenu.js +287 -0
- package/lib/components/principal/index.d.ts +7 -0
- package/lib/components/principal/index.js +10 -0
- package/lib/components/runtimes/RuntimeLauncherDialog.d.ts +2 -2
- package/lib/components/sharing/ShareAccessComponent.d.ts +18 -0
- package/lib/components/sharing/ShareAccessComponent.js +1368 -0
- package/lib/components/sharing/SharingEditor.d.ts +20 -0
- package/lib/components/sharing/SharingEditor.js +65 -0
- package/lib/components/sharing/index.d.ts +9 -0
- package/lib/components/sharing/index.js +12 -0
- package/lib/components/snapshots/{RuntimeSnapshotMenu.d.ts → SandboxSnapshotMenu.d.ts} +4 -4
- package/lib/components/snapshots/{RuntimeSnapshotMenu.js → SandboxSnapshotMenu.js} +33 -33
- package/lib/components/snapshots/index.d.ts +1 -1
- package/lib/components/snapshots/index.js +1 -1
- package/lib/components/storage/ContentsBrowser.js +2 -2
- package/lib/components/tokens/SpaceVariantToken.d.ts +1 -1
- package/lib/components/tokens/SpaceVariantToken.js +7 -4
- package/lib/components/users/PeerIndicator.js +5 -4
- package/lib/hooks/index.d.ts +5 -0
- package/lib/hooks/index.js +5 -0
- package/lib/hooks/useBillableAccountStore.d.ts +31 -0
- package/lib/hooks/useBillableAccountStore.js +53 -0
- package/lib/hooks/useCache.d.ts +125 -18
- package/lib/hooks/useCache.js +893 -120
- package/lib/hooks/useDatalayer.js +31 -3
- package/lib/hooks/useIAM.js +1 -8
- package/lib/hooks/usePrincipalStore.d.ts +41 -0
- package/lib/hooks/usePrincipalStore.js +101 -0
- package/lib/hooks/useProjects.d.ts +44 -0
- package/lib/hooks/useProjects.js +26 -2
- package/lib/hooks/useSelectedBillableAccount.d.ts +14 -0
- package/lib/hooks/useSelectedBillableAccount.js +36 -0
- package/lib/hooks/useSelectedPrincipal.d.ts +17 -0
- package/lib/hooks/useSelectedPrincipal.js +29 -0
- package/lib/hooks/useUsageRefreshStore.d.ts +8 -0
- package/lib/hooks/useUsageRefreshStore.js +16 -0
- package/lib/index.d.ts +2 -2
- package/lib/index.js +1 -1
- package/lib/mocks/components/FlashMock.js +8 -2
- package/lib/models/{RuntimeSnapshot.d.ts → CodeSandboxSnapshot.d.ts} +5 -5
- package/lib/models/{RuntimeSnapshot.js → CodeSandboxSnapshot.js} +1 -1
- package/lib/models/{RuntimeSnapshotDTO.d.ts → CodeSandboxSnapshotDTO.d.ts} +30 -30
- package/lib/models/{RuntimeSnapshotDTO.js → CodeSandboxSnapshotDTO.js} +6 -6
- package/lib/models/Environment.d.ts +4 -0
- package/lib/models/IAM.d.ts +66 -0
- package/lib/models/Organization.d.ts +1 -0
- package/lib/models/Organization.js +1 -0
- package/lib/models/Page.d.ts +2 -2
- package/lib/models/Page.js +2 -2
- package/lib/models/Profile.d.ts +1 -1
- package/lib/models/RuntimeDTO.d.ts +2 -2
- package/lib/models/Space.d.ts +1 -0
- package/lib/models/Space.js +29 -5
- package/lib/models/SpaceDTO.d.ts +4 -0
- package/lib/models/SpaceDTO.js +5 -0
- package/lib/models/Usage.d.ts +15 -0
- package/lib/models/Usage.js +9 -0
- package/lib/models/User.d.ts +21 -0
- package/lib/models/User.js +6 -2
- package/lib/models/index.d.ts +2 -2
- package/lib/models/index.js +2 -2
- package/lib/otel/auth.js +0 -4
- package/lib/services/index.d.ts +1 -1
- package/lib/services/index.js +1 -1
- package/lib/state/substates/IAMState.js +0 -7
- package/lib/state/substates/RuntimesState.d.ts +9 -9
- package/lib/state/substates/RuntimesState.js +3 -3
- package/lib/stateful/runtimes/actions.d.ts +17 -17
- package/lib/stateful/runtimes/actions.js +35 -55
- package/lib/stateful/runtimes/apis.d.ts +3 -3
- package/lib/stateful/runtimes/snapshots.d.ts +2 -2
- package/lib/stateful/runtimes/snapshots.js +7 -7
- package/lib/utils/Format.d.ts +6 -0
- package/lib/utils/Format.js +17 -0
- package/lib/utils/Handles.d.ts +3 -0
- package/lib/utils/Handles.js +53 -0
- package/lib/utils/Snapshot.d.ts +1 -1
- package/lib/utils/Snapshot.js +1 -1
- package/lib/utils/index.d.ts +1 -0
- package/lib/utils/index.js +1 -0
- package/lib/views/datasources/DatasourceDetail.d.ts +7 -1
- package/lib/views/datasources/DatasourceDetail.js +61 -23
- package/lib/views/datasources/DatasourceNew.d.ts +8 -1
- package/lib/views/datasources/DatasourceNew.js +23 -10
- package/lib/views/datasources/Datasources.d.ts +5 -1
- package/lib/views/datasources/Datasources.js +38 -30
- package/lib/views/iam-tokens/IAMTokenNew.d.ts +3 -1
- package/lib/views/iam-tokens/IAMTokenNew.js +2 -2
- package/lib/views/iam-tokens/IAMTokens.d.ts +3 -1
- package/lib/views/iam-tokens/IAMTokens.js +2 -2
- package/lib/views/otel/OtelHeader.d.ts +5 -0
- package/lib/views/otel/OtelHeader.js +3 -3
- package/lib/views/profile/UserBadge.d.ts +7 -2
- package/lib/views/profile/UserBadge.js +11 -2
- package/lib/views/secrets/Secrets.js +21 -21
- package/package.json +7 -8
|
@@ -11,6 +11,23 @@ import { requestDatalayerAPI } from '../api/DatalayerApi.js';
|
|
|
11
11
|
export function useDatalayer(props = {}) {
|
|
12
12
|
const { loginRoute = '/login', notifyOnError = true } = props;
|
|
13
13
|
const location = useLocation();
|
|
14
|
+
const resolveLoginRoute = (candidateRoute) => {
|
|
15
|
+
if (candidateRoute !== '/login') {
|
|
16
|
+
return candidateRoute;
|
|
17
|
+
}
|
|
18
|
+
const pathname = location.pathname || '';
|
|
19
|
+
const kernelsPrefix = '/jupyter/kernels';
|
|
20
|
+
const iamPrefix = '/jupyter/iam';
|
|
21
|
+
if (pathname.includes(kernelsPrefix)) {
|
|
22
|
+
const [base] = pathname.split(kernelsPrefix);
|
|
23
|
+
return `${base}${kernelsPrefix}/login`;
|
|
24
|
+
}
|
|
25
|
+
if (pathname.includes(iamPrefix)) {
|
|
26
|
+
const [base] = pathname.split(iamPrefix);
|
|
27
|
+
return `${base}${iamPrefix}/login`;
|
|
28
|
+
}
|
|
29
|
+
return candidateRoute;
|
|
30
|
+
};
|
|
14
31
|
/*
|
|
15
32
|
// TODO Fix the conditional hook call.
|
|
16
33
|
const coreStore = useCoreStore();
|
|
@@ -35,15 +52,19 @@ export function useDatalayer(props = {}) {
|
|
|
35
52
|
.catch(error => {
|
|
36
53
|
if (error.name === 'RunResponseError') {
|
|
37
54
|
const responseError = error;
|
|
55
|
+
const isForbidden = responseError.response.status === 403;
|
|
38
56
|
if (responseError.response.status === 401) {
|
|
39
57
|
console.log('Datalayer sent a 401 return code.');
|
|
40
|
-
|
|
58
|
+
const resolvedLoginRoute = resolveLoginRoute(loginRoute_);
|
|
59
|
+
const alreadyOnLoginRoute = location.pathname === resolvedLoginRoute ||
|
|
60
|
+
location.pathname.endsWith('/login');
|
|
61
|
+
if (!alreadyOnLoginRoute) {
|
|
41
62
|
iamStore.logout();
|
|
42
|
-
navigate(
|
|
63
|
+
navigate(resolvedLoginRoute);
|
|
43
64
|
}
|
|
44
65
|
}
|
|
45
66
|
else {
|
|
46
|
-
if (notifyOnError_) {
|
|
67
|
+
if (notifyOnError_ && !isForbidden) {
|
|
47
68
|
if (responseError.warnings) {
|
|
48
69
|
responseError.warnings.forEach(warning => enqueueToast(`${warning}`, { variant: 'warning' }));
|
|
49
70
|
}
|
|
@@ -64,9 +85,16 @@ export function useDatalayer(props = {}) {
|
|
|
64
85
|
}
|
|
65
86
|
}
|
|
66
87
|
const response = {
|
|
88
|
+
success: false,
|
|
67
89
|
sucess: false,
|
|
68
90
|
message: responseError.message,
|
|
69
91
|
errors: responseError.errors,
|
|
92
|
+
warnings: responseError.warnings,
|
|
93
|
+
detail: responseError.detail,
|
|
94
|
+
status: responseError.response.status,
|
|
95
|
+
code: responseError.response.status === 403
|
|
96
|
+
? 'FORBIDDEN'
|
|
97
|
+
: `HTTP_${responseError.response.status}`,
|
|
70
98
|
};
|
|
71
99
|
return response;
|
|
72
100
|
}
|
package/lib/hooks/useIAM.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { useEffect, useState } from 'react';
|
|
6
6
|
import { useCache } from './useCache.js';
|
|
7
|
-
import {
|
|
7
|
+
import { useIAMStore, useLayoutStore, useOrganizationStore, useSpaceStore, } from '../state/index.js';
|
|
8
8
|
import { asUser, ANONYMOUS_USER, ANONYMOUS_USER_TOKEN, } from '../models/index.js';
|
|
9
9
|
import { requestDatalayerAPI, } from '../api/DatalayerApi.js';
|
|
10
10
|
export const useIAM = (props = { user: undefined, token: undefined }) => {
|
|
@@ -72,13 +72,6 @@ export const useIAM = (props = { user: undefined, token: undefined }) => {
|
|
|
72
72
|
const user = asUser(whoamiData.profile);
|
|
73
73
|
setIAMState({ user, token });
|
|
74
74
|
iamStore.setLogin(user, token);
|
|
75
|
-
// TODO centralize user settings management.
|
|
76
|
-
const aiagentsRunUrl = user.settings?.aiAgentsUrl;
|
|
77
|
-
if (aiagentsRunUrl) {
|
|
78
|
-
coreStore.getState().setConfiguration({
|
|
79
|
-
aiagentsRunUrl,
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
75
|
}
|
|
83
76
|
}
|
|
84
77
|
}, [token, whoamiData, iamStore]);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The kind of principal currently selected in the Principal Switcher.
|
|
3
|
+
*
|
|
4
|
+
* A principal is the entity used for *UI scoping* — visibility, creation,
|
|
5
|
+
* and sharing of artifacts. Only user / organization / team are principals.
|
|
6
|
+
* Agents are NOT principals (an agent is owned by an account).
|
|
7
|
+
*/
|
|
8
|
+
export type PrincipalKind = 'user' | 'organization' | 'team';
|
|
9
|
+
export type PrincipalState = {
|
|
10
|
+
/** Kind of the currently selected principal. */
|
|
11
|
+
selectedPrincipalKind: PrincipalKind;
|
|
12
|
+
/** UID of the selected principal (user UID, org UID, or team UID). */
|
|
13
|
+
selectedPrincipalUid?: string;
|
|
14
|
+
/** Handle of the selected principal. */
|
|
15
|
+
selectedPrincipalHandle?: string;
|
|
16
|
+
/** Parent organization UID — set only when `selectedPrincipalKind === 'team'`. */
|
|
17
|
+
selectedTeamParentOrganizationUid?: string;
|
|
18
|
+
/** Parent organization handle — set only when `selectedPrincipalKind === 'team'`. */
|
|
19
|
+
selectedTeamParentOrganizationHandle?: string;
|
|
20
|
+
selectUserPrincipal: (uid: string, handle: string) => void;
|
|
21
|
+
selectOrganizationPrincipal: (uid: string, handle: string) => void;
|
|
22
|
+
selectTeamPrincipal: (args: {
|
|
23
|
+
teamUid: string;
|
|
24
|
+
teamHandle: string;
|
|
25
|
+
organizationUid: string;
|
|
26
|
+
organizationHandle: string;
|
|
27
|
+
}) => void;
|
|
28
|
+
resetPrincipal: () => void;
|
|
29
|
+
};
|
|
30
|
+
export declare const usePrincipalStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<PrincipalState>, "persist"> & {
|
|
31
|
+
persist: {
|
|
32
|
+
setOptions: (options: Partial<import("zustand/middleware").PersistOptions<PrincipalState, unknown>>) => void;
|
|
33
|
+
clearStorage: () => void;
|
|
34
|
+
rehydrate: () => Promise<void> | void;
|
|
35
|
+
hasHydrated: () => boolean;
|
|
36
|
+
onHydrate: (fn: (state: PrincipalState) => void) => () => void;
|
|
37
|
+
onFinishHydration: (fn: (state: PrincipalState) => void) => () => void;
|
|
38
|
+
getOptions: () => Partial<import("zustand/middleware").PersistOptions<PrincipalState, unknown>>;
|
|
39
|
+
};
|
|
40
|
+
}>;
|
|
41
|
+
export default usePrincipalStore;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
import { create } from 'zustand';
|
|
6
|
+
import { createJSONStorage, persist } from 'zustand/middleware';
|
|
7
|
+
import { useUsageRefreshStore } from './useUsageRefreshStore.js';
|
|
8
|
+
export const usePrincipalStore = create()(persist(set => ({
|
|
9
|
+
selectedPrincipalKind: 'user',
|
|
10
|
+
selectedPrincipalUid: undefined,
|
|
11
|
+
selectedPrincipalHandle: undefined,
|
|
12
|
+
selectedTeamParentOrganizationUid: undefined,
|
|
13
|
+
selectedTeamParentOrganizationHandle: undefined,
|
|
14
|
+
selectUserPrincipal: (uid, handle) => set(state => {
|
|
15
|
+
const unchanged = state.selectedPrincipalKind === 'user' &&
|
|
16
|
+
state.selectedPrincipalUid === uid &&
|
|
17
|
+
state.selectedPrincipalHandle === handle;
|
|
18
|
+
if (unchanged) {
|
|
19
|
+
return state;
|
|
20
|
+
}
|
|
21
|
+
useUsageRefreshStore
|
|
22
|
+
.getState()
|
|
23
|
+
.requestUsageRefresh('principal-user-changed');
|
|
24
|
+
return {
|
|
25
|
+
selectedPrincipalKind: 'user',
|
|
26
|
+
selectedPrincipalUid: uid,
|
|
27
|
+
selectedPrincipalHandle: handle,
|
|
28
|
+
selectedTeamParentOrganizationUid: undefined,
|
|
29
|
+
selectedTeamParentOrganizationHandle: undefined,
|
|
30
|
+
};
|
|
31
|
+
}),
|
|
32
|
+
selectOrganizationPrincipal: (uid, handle) => set(state => {
|
|
33
|
+
const unchanged = state.selectedPrincipalKind === 'organization' &&
|
|
34
|
+
state.selectedPrincipalUid === uid &&
|
|
35
|
+
state.selectedPrincipalHandle === handle;
|
|
36
|
+
if (unchanged) {
|
|
37
|
+
return state;
|
|
38
|
+
}
|
|
39
|
+
useUsageRefreshStore
|
|
40
|
+
.getState()
|
|
41
|
+
.requestUsageRefresh('principal-organization-changed');
|
|
42
|
+
return {
|
|
43
|
+
selectedPrincipalKind: 'organization',
|
|
44
|
+
selectedPrincipalUid: uid,
|
|
45
|
+
selectedPrincipalHandle: handle,
|
|
46
|
+
selectedTeamParentOrganizationUid: undefined,
|
|
47
|
+
selectedTeamParentOrganizationHandle: undefined,
|
|
48
|
+
};
|
|
49
|
+
}),
|
|
50
|
+
selectTeamPrincipal: ({ teamUid, teamHandle, organizationUid, organizationHandle, }) => set(state => {
|
|
51
|
+
const unchanged = state.selectedPrincipalKind === 'team' &&
|
|
52
|
+
state.selectedPrincipalUid === teamUid &&
|
|
53
|
+
state.selectedPrincipalHandle === teamHandle &&
|
|
54
|
+
state.selectedTeamParentOrganizationUid === organizationUid &&
|
|
55
|
+
state.selectedTeamParentOrganizationHandle === organizationHandle;
|
|
56
|
+
if (unchanged) {
|
|
57
|
+
return state;
|
|
58
|
+
}
|
|
59
|
+
useUsageRefreshStore
|
|
60
|
+
.getState()
|
|
61
|
+
.requestUsageRefresh('principal-team-changed');
|
|
62
|
+
return {
|
|
63
|
+
selectedPrincipalKind: 'team',
|
|
64
|
+
selectedPrincipalUid: teamUid,
|
|
65
|
+
selectedPrincipalHandle: teamHandle,
|
|
66
|
+
selectedTeamParentOrganizationUid: organizationUid,
|
|
67
|
+
selectedTeamParentOrganizationHandle: organizationHandle,
|
|
68
|
+
};
|
|
69
|
+
}),
|
|
70
|
+
resetPrincipal: () => set(state => {
|
|
71
|
+
const unchanged = state.selectedPrincipalKind === 'user' &&
|
|
72
|
+
state.selectedPrincipalUid === undefined &&
|
|
73
|
+
state.selectedPrincipalHandle === undefined &&
|
|
74
|
+
state.selectedTeamParentOrganizationUid === undefined &&
|
|
75
|
+
state.selectedTeamParentOrganizationHandle === undefined;
|
|
76
|
+
if (unchanged) {
|
|
77
|
+
return state;
|
|
78
|
+
}
|
|
79
|
+
useUsageRefreshStore
|
|
80
|
+
.getState()
|
|
81
|
+
.requestUsageRefresh('principal-reset');
|
|
82
|
+
return {
|
|
83
|
+
selectedPrincipalKind: 'user',
|
|
84
|
+
selectedPrincipalUid: undefined,
|
|
85
|
+
selectedPrincipalHandle: undefined,
|
|
86
|
+
selectedTeamParentOrganizationUid: undefined,
|
|
87
|
+
selectedTeamParentOrganizationHandle: undefined,
|
|
88
|
+
};
|
|
89
|
+
}),
|
|
90
|
+
}), {
|
|
91
|
+
name: 'datalayer-principal',
|
|
92
|
+
storage: createJSONStorage(() => localStorage),
|
|
93
|
+
partialize: state => ({
|
|
94
|
+
selectedPrincipalKind: state.selectedPrincipalKind,
|
|
95
|
+
selectedPrincipalUid: state.selectedPrincipalUid,
|
|
96
|
+
selectedPrincipalHandle: state.selectedPrincipalHandle,
|
|
97
|
+
selectedTeamParentOrganizationUid: state.selectedTeamParentOrganizationUid,
|
|
98
|
+
selectedTeamParentOrganizationHandle: state.selectedTeamParentOrganizationHandle,
|
|
99
|
+
}),
|
|
100
|
+
}));
|
|
101
|
+
export default usePrincipalStore;
|
|
@@ -385,6 +385,10 @@ export declare function useCreateProject(): {
|
|
|
385
385
|
mutate: import("@tanstack/react-query").UseMutateFunction<any, Error, {
|
|
386
386
|
space: Partial<import("..").IAnySpace>;
|
|
387
387
|
organization?: import("..").IAnyOrganization;
|
|
388
|
+
team?: {
|
|
389
|
+
id?: string;
|
|
390
|
+
handle?: string;
|
|
391
|
+
};
|
|
388
392
|
}, unknown>;
|
|
389
393
|
reset: () => void;
|
|
390
394
|
context: unknown;
|
|
@@ -395,6 +399,10 @@ export declare function useCreateProject(): {
|
|
|
395
399
|
mutateAsync: import("@tanstack/react-query").UseMutateAsyncFunction<any, Error, {
|
|
396
400
|
space: Partial<import("..").IAnySpace>;
|
|
397
401
|
organization?: import("..").IAnyOrganization;
|
|
402
|
+
team?: {
|
|
403
|
+
id?: string;
|
|
404
|
+
handle?: string;
|
|
405
|
+
};
|
|
398
406
|
}, unknown>;
|
|
399
407
|
} | {
|
|
400
408
|
createProject: (request: CreateProjectRequest) => Promise<any>;
|
|
@@ -402,6 +410,10 @@ export declare function useCreateProject(): {
|
|
|
402
410
|
variables: {
|
|
403
411
|
space: Partial<import("..").IAnySpace>;
|
|
404
412
|
organization?: import("..").IAnyOrganization;
|
|
413
|
+
team?: {
|
|
414
|
+
id?: string;
|
|
415
|
+
handle?: string;
|
|
416
|
+
};
|
|
405
417
|
};
|
|
406
418
|
error: null;
|
|
407
419
|
isError: false;
|
|
@@ -412,6 +424,10 @@ export declare function useCreateProject(): {
|
|
|
412
424
|
mutate: import("@tanstack/react-query").UseMutateFunction<any, Error, {
|
|
413
425
|
space: Partial<import("..").IAnySpace>;
|
|
414
426
|
organization?: import("..").IAnyOrganization;
|
|
427
|
+
team?: {
|
|
428
|
+
id?: string;
|
|
429
|
+
handle?: string;
|
|
430
|
+
};
|
|
415
431
|
}, unknown>;
|
|
416
432
|
reset: () => void;
|
|
417
433
|
context: unknown;
|
|
@@ -422,6 +438,10 @@ export declare function useCreateProject(): {
|
|
|
422
438
|
mutateAsync: import("@tanstack/react-query").UseMutateAsyncFunction<any, Error, {
|
|
423
439
|
space: Partial<import("..").IAnySpace>;
|
|
424
440
|
organization?: import("..").IAnyOrganization;
|
|
441
|
+
team?: {
|
|
442
|
+
id?: string;
|
|
443
|
+
handle?: string;
|
|
444
|
+
};
|
|
425
445
|
}, unknown>;
|
|
426
446
|
} | {
|
|
427
447
|
createProject: (request: CreateProjectRequest) => Promise<any>;
|
|
@@ -430,6 +450,10 @@ export declare function useCreateProject(): {
|
|
|
430
450
|
variables: {
|
|
431
451
|
space: Partial<import("..").IAnySpace>;
|
|
432
452
|
organization?: import("..").IAnyOrganization;
|
|
453
|
+
team?: {
|
|
454
|
+
id?: string;
|
|
455
|
+
handle?: string;
|
|
456
|
+
};
|
|
433
457
|
};
|
|
434
458
|
isError: true;
|
|
435
459
|
isIdle: false;
|
|
@@ -439,6 +463,10 @@ export declare function useCreateProject(): {
|
|
|
439
463
|
mutate: import("@tanstack/react-query").UseMutateFunction<any, Error, {
|
|
440
464
|
space: Partial<import("..").IAnySpace>;
|
|
441
465
|
organization?: import("..").IAnyOrganization;
|
|
466
|
+
team?: {
|
|
467
|
+
id?: string;
|
|
468
|
+
handle?: string;
|
|
469
|
+
};
|
|
442
470
|
}, unknown>;
|
|
443
471
|
reset: () => void;
|
|
444
472
|
context: unknown;
|
|
@@ -449,6 +477,10 @@ export declare function useCreateProject(): {
|
|
|
449
477
|
mutateAsync: import("@tanstack/react-query").UseMutateAsyncFunction<any, Error, {
|
|
450
478
|
space: Partial<import("..").IAnySpace>;
|
|
451
479
|
organization?: import("..").IAnyOrganization;
|
|
480
|
+
team?: {
|
|
481
|
+
id?: string;
|
|
482
|
+
handle?: string;
|
|
483
|
+
};
|
|
452
484
|
}, unknown>;
|
|
453
485
|
} | {
|
|
454
486
|
createProject: (request: CreateProjectRequest) => Promise<any>;
|
|
@@ -457,6 +489,10 @@ export declare function useCreateProject(): {
|
|
|
457
489
|
variables: {
|
|
458
490
|
space: Partial<import("..").IAnySpace>;
|
|
459
491
|
organization?: import("..").IAnyOrganization;
|
|
492
|
+
team?: {
|
|
493
|
+
id?: string;
|
|
494
|
+
handle?: string;
|
|
495
|
+
};
|
|
460
496
|
};
|
|
461
497
|
isError: false;
|
|
462
498
|
isIdle: false;
|
|
@@ -466,6 +502,10 @@ export declare function useCreateProject(): {
|
|
|
466
502
|
mutate: import("@tanstack/react-query").UseMutateFunction<any, Error, {
|
|
467
503
|
space: Partial<import("..").IAnySpace>;
|
|
468
504
|
organization?: import("..").IAnyOrganization;
|
|
505
|
+
team?: {
|
|
506
|
+
id?: string;
|
|
507
|
+
handle?: string;
|
|
508
|
+
};
|
|
469
509
|
}, unknown>;
|
|
470
510
|
reset: () => void;
|
|
471
511
|
context: unknown;
|
|
@@ -476,6 +516,10 @@ export declare function useCreateProject(): {
|
|
|
476
516
|
mutateAsync: import("@tanstack/react-query").UseMutateAsyncFunction<any, Error, {
|
|
477
517
|
space: Partial<import("..").IAnySpace>;
|
|
478
518
|
organization?: import("..").IAnyOrganization;
|
|
519
|
+
team?: {
|
|
520
|
+
id?: string;
|
|
521
|
+
handle?: string;
|
|
522
|
+
};
|
|
479
523
|
}, unknown>;
|
|
480
524
|
};
|
|
481
525
|
/**
|
package/lib/hooks/useProjects.js
CHANGED
|
@@ -16,6 +16,31 @@ import { useMemo, useCallback } from 'react';
|
|
|
16
16
|
import { useCache } from './useCache.js';
|
|
17
17
|
/** The space type value used to identify project spaces in Solr */
|
|
18
18
|
export const PROJECT_SPACE_VARIANT = 'project';
|
|
19
|
+
const normalizeProjectItems = (items) => {
|
|
20
|
+
if (Array.isArray(items)) {
|
|
21
|
+
return items;
|
|
22
|
+
}
|
|
23
|
+
if (items && typeof items === 'object') {
|
|
24
|
+
return [items];
|
|
25
|
+
}
|
|
26
|
+
return [];
|
|
27
|
+
};
|
|
28
|
+
const isProjectSpace = (space) => {
|
|
29
|
+
const variant = space?.variant ?? space?.variant_s;
|
|
30
|
+
if (variant !== PROJECT_SPACE_VARIANT) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
const items = normalizeProjectItems(space?.items);
|
|
34
|
+
if (items.length === 0) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
const hasNotebook = items.some(item => (item?.type_s ?? item?.type) === 'notebook');
|
|
38
|
+
const hasDocument = items.some(item => {
|
|
39
|
+
const type = item?.type_s ?? item?.type;
|
|
40
|
+
return type === 'document' || type === 'lexical';
|
|
41
|
+
});
|
|
42
|
+
return hasNotebook && hasDocument;
|
|
43
|
+
};
|
|
19
44
|
/**
|
|
20
45
|
* Hook to fetch user's projects (spaces with type "project").
|
|
21
46
|
*
|
|
@@ -29,8 +54,7 @@ export function useProjects() {
|
|
|
29
54
|
if (!allSpaces)
|
|
30
55
|
return [];
|
|
31
56
|
return allSpaces
|
|
32
|
-
.filter((space) => space
|
|
33
|
-
space.type_s === PROJECT_SPACE_VARIANT)
|
|
57
|
+
.filter((space) => isProjectSpace(space))
|
|
34
58
|
.map((space) => ({
|
|
35
59
|
uid: space.uid,
|
|
36
60
|
id: space.id ?? space.uid,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read-only selector for the currently scoped billable account.
|
|
3
|
+
*
|
|
4
|
+
* Use this for billing, quotas, plans, credits, agents, and runtime capacity.
|
|
5
|
+
* For visibility/creation/sharing scope, use {@link useSelectedPrincipal}.
|
|
6
|
+
*/
|
|
7
|
+
export declare function useSelectedBillableAccount(): {
|
|
8
|
+
billableAccountKind: string;
|
|
9
|
+
billableAccountUid: string | undefined;
|
|
10
|
+
billableAccountHandle: string | undefined;
|
|
11
|
+
isUserAccount: boolean;
|
|
12
|
+
isOrganizationAccount: boolean;
|
|
13
|
+
};
|
|
14
|
+
export default useSelectedBillableAccount;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
import { useBillableAccountStore } from './useBillableAccountStore.js';
|
|
6
|
+
import { useSelectedPrincipal } from './useSelectedPrincipal.js';
|
|
7
|
+
/**
|
|
8
|
+
* Read-only selector for the currently scoped billable account.
|
|
9
|
+
*
|
|
10
|
+
* Use this for billing, quotas, plans, credits, agents, and runtime capacity.
|
|
11
|
+
* For visibility/creation/sharing scope, use {@link useSelectedPrincipal}.
|
|
12
|
+
*/
|
|
13
|
+
export function useSelectedBillableAccount() {
|
|
14
|
+
const persistedUid = useBillableAccountStore(state => state.billableAccountUid);
|
|
15
|
+
const persistedHandle = useBillableAccountStore(state => state.billableAccountHandle);
|
|
16
|
+
const { selectedPrincipalKind, selectedPrincipalUid, selectedPrincipalHandle, selectedTeamParentOrganizationUid, selectedTeamParentOrganizationHandle, } = useSelectedPrincipal();
|
|
17
|
+
const billableAccountKind = selectedPrincipalKind === 'team'
|
|
18
|
+
? 'organization'
|
|
19
|
+
: selectedPrincipalKind === 'organization'
|
|
20
|
+
? 'organization'
|
|
21
|
+
: 'user';
|
|
22
|
+
const billableAccountUid = selectedPrincipalKind === 'team'
|
|
23
|
+
? selectedTeamParentOrganizationUid || persistedUid
|
|
24
|
+
: selectedPrincipalUid || persistedUid;
|
|
25
|
+
const billableAccountHandle = selectedPrincipalKind === 'team'
|
|
26
|
+
? selectedTeamParentOrganizationHandle || persistedHandle
|
|
27
|
+
: selectedPrincipalHandle || persistedHandle;
|
|
28
|
+
return {
|
|
29
|
+
billableAccountKind,
|
|
30
|
+
billableAccountUid,
|
|
31
|
+
billableAccountHandle,
|
|
32
|
+
isUserAccount: billableAccountKind === 'user',
|
|
33
|
+
isOrganizationAccount: billableAccountKind === 'organization',
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export default useSelectedBillableAccount;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read-only selector for the currently selected principal (UI scope).
|
|
3
|
+
*
|
|
4
|
+
* Use this for visibility, creation, and sharing of artifacts.
|
|
5
|
+
* For billing, quotas, plans, and agents, use {@link useSelectedBillableAccount}.
|
|
6
|
+
*/
|
|
7
|
+
export declare function useSelectedPrincipal(): {
|
|
8
|
+
selectedPrincipalKind: import("./usePrincipalStore").PrincipalKind;
|
|
9
|
+
selectedPrincipalUid: string | undefined;
|
|
10
|
+
selectedPrincipalHandle: string | undefined;
|
|
11
|
+
selectedTeamParentOrganizationUid: string | undefined;
|
|
12
|
+
selectedTeamParentOrganizationHandle: string | undefined;
|
|
13
|
+
isUserSelected: boolean;
|
|
14
|
+
isOrganizationSelected: boolean;
|
|
15
|
+
isTeamSelected: boolean;
|
|
16
|
+
};
|
|
17
|
+
export default useSelectedPrincipal;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
import { usePrincipalStore } from './usePrincipalStore.js';
|
|
6
|
+
/**
|
|
7
|
+
* Read-only selector for the currently selected principal (UI scope).
|
|
8
|
+
*
|
|
9
|
+
* Use this for visibility, creation, and sharing of artifacts.
|
|
10
|
+
* For billing, quotas, plans, and agents, use {@link useSelectedBillableAccount}.
|
|
11
|
+
*/
|
|
12
|
+
export function useSelectedPrincipal() {
|
|
13
|
+
const selectedPrincipalKind = usePrincipalStore(state => state.selectedPrincipalKind);
|
|
14
|
+
const selectedPrincipalUid = usePrincipalStore(state => state.selectedPrincipalUid);
|
|
15
|
+
const selectedPrincipalHandle = usePrincipalStore(state => state.selectedPrincipalHandle);
|
|
16
|
+
const selectedTeamParentOrganizationUid = usePrincipalStore(state => state.selectedTeamParentOrganizationUid);
|
|
17
|
+
const selectedTeamParentOrganizationHandle = usePrincipalStore(state => state.selectedTeamParentOrganizationHandle);
|
|
18
|
+
return {
|
|
19
|
+
selectedPrincipalKind,
|
|
20
|
+
selectedPrincipalUid,
|
|
21
|
+
selectedPrincipalHandle,
|
|
22
|
+
selectedTeamParentOrganizationUid,
|
|
23
|
+
selectedTeamParentOrganizationHandle,
|
|
24
|
+
isUserSelected: selectedPrincipalKind === 'user',
|
|
25
|
+
isOrganizationSelected: selectedPrincipalKind === 'organization',
|
|
26
|
+
isTeamSelected: selectedPrincipalKind === 'team',
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export default useSelectedPrincipal;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type UsageRefreshState = {
|
|
2
|
+
refreshToken: number;
|
|
3
|
+
lastReason?: string;
|
|
4
|
+
lastRequestedAt?: number;
|
|
5
|
+
requestUsageRefresh: (reason?: string) => void;
|
|
6
|
+
};
|
|
7
|
+
export declare const useUsageRefreshStore: import("zustand").UseBoundStore<import("zustand").StoreApi<UsageRefreshState>>;
|
|
8
|
+
export default useUsageRefreshStore;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
import { create } from 'zustand';
|
|
6
|
+
export const useUsageRefreshStore = create()(set => ({
|
|
7
|
+
refreshToken: 0,
|
|
8
|
+
lastReason: undefined,
|
|
9
|
+
lastRequestedAt: undefined,
|
|
10
|
+
requestUsageRefresh: (reason) => set(state => ({
|
|
11
|
+
refreshToken: state.refreshToken + 1,
|
|
12
|
+
lastReason: reason,
|
|
13
|
+
lastRequestedAt: Date.now(),
|
|
14
|
+
})),
|
|
15
|
+
}));
|
|
16
|
+
export default useUsageRefreshStore;
|
package/lib/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export { API_BASE_PATHS } from './api/constants';
|
|
|
11
11
|
export * as runtimesApi from './api/runtimes';
|
|
12
12
|
export * as iamApi from './api/iam';
|
|
13
13
|
export * as spacerApi from './api/spacer';
|
|
14
|
-
export { DatalayerClient, type DatalayerClientConfig, type ClientHandlers, User, Runtime, Environment, Snapshot, Space, Project, Notebook, LexicalDTO, Secret, Credits, Item, type RuntimeJSON, type EnvironmentJSON, type UserJSON, type RuntimeData, type EnvironmentData, type UserData, type SpaceData, type SpaceItem, type NotebookData, type LexicalData, type
|
|
15
|
-
export { getEnvironments, createRuntime, getRuntimes, deleteRuntime, snapshotRuntime,
|
|
14
|
+
export { DatalayerClient, type DatalayerClientConfig, type ClientHandlers, User, Runtime, Environment, Snapshot, Space, Project, Notebook, LexicalDTO, Secret, Credits, Item, type RuntimeJSON, type EnvironmentJSON, type UserJSON, type RuntimeData, type EnvironmentData, type UserData, type SpaceData, type SpaceItem, type NotebookData, type LexicalData, type CodeSandboxSnapshotData, type CreditsInfo, type CreditReservation, type CreateRuntimeRequest, type CreateRuntimeResponse, type ListRuntimesResponse, type ListEnvironmentsResponse, type CreateCodeSandboxSnapshotRequest, type CreateCodeSandboxSnapshotResponse, type GetCodeSandboxSnapshotResponse, type ListCodeSandboxSnapshotsResponse, type CreateSpaceRequest, type CreateSpaceResponse, type SpacesForUserResponse, type CollaborationSessionResponse, type DeleteSpaceItemResponse, type GetSpaceItemResponse, type GetSpaceItemsResponse, type CreateNotebookRequest, type CreateNotebookResponse, type GetNotebookResponse, type UpdateNotebookRequest, type UpdateNotebookResponse, type CreateLexicalRequest, type CreateLexicalResponse, type GetLexicalResponse, type UpdateLexicalRequest, type UpdateLexicalResponse, type CreditsResponse, type CreateDatasourceResponse, type GetDatasourceResponse, type ListDatasourcesResponse, type UpdateDatasourceResponse, type CreateSecretRequest, type CreateSecretResponse, type GetSecretResponse, type ListSecretsResponse, type UpdateSecretRequest, type UpdateSecretResponse, type SpaceJSON, type ProjectJSON, type ProjectDefaultItems, type UpdateSpaceRequest, type GetSpaceResponse, type UpdateSpaceResponse, type DeleteSpaceResponse, type GetSpaceDefaultItemsResponse, type GetSpacesByTypeResponse, type NotebookJSON, type LexicalJSON, type CodeSandboxSnapshotJSON, HealthCheck, type HealthCheckJSON, type LoginRequest, type LoginResponse, type UserMeResponse, type MembershipsResponse, type WhoAmIResponse, type HealthzPingResponse, AuthenticationManager, type IUser, type IBaseUser, type ICell, type IDatasource, type IDatasourceVariant, type ICredits, type ICreditsReservation, type ISpaceItem, type ISurvey, type ISpace, type IBaseSpace, type IAnySpace, type ISpaceVariant, type IBaseTeam, type IAnyTeam, type IOrganization, type IAnyOrganization, type IBaseOrganization, type IRuntimeModel, type IRuntimePod, type IRuntimeType, type IRuntimeLocation, type IRuntimeCapabilities, type ICodeSandboxSnapshot, type IDatalayerEnvironment, type IResources, type ISnippet, type IRole, type IAssignment, type IContact, type ICourse, type IOrganizationMember, type IPage, type PageTagName, type PageTheme, type PageVariant, type ISecret, type ISecretVariant, type SecretData, type SecretJSON, type DatasourceData, type DatasourceJSON, type DatasourceType, type CreateDatasourceRequest, type UpdateDatasourceRequest, Datasource, type IIAMToken, type IIAMTokenVariant, type IDocument, type IBaseDocument, type IEnvironment, type IExercise, type ICode, type IHelp, type IInvite, type ILesson, type INotebook, type IBaseNotebook, type ISchool, type ITeam, type TeamMember, type IUserOnboarding, type IClient, type IOnboardingPosition, type IOnboardingTours, type ITour, type ITourStatus, type IUserSettings, type IDataset, type IUsage, type IItem, type IItemType, type Member, type Profile, type SpaceMember, type IContactEvent, type IContactIAMProvider, type IStudentItem, type Instructor, type IStudent, type IDean, type IUserEvent, type IIAMProviderLinked, type IContent, type AuthResult, type TokenValidationResult, type AuthOptions, type TokenStorage, type IRuntimeOptions, type IMultiServiceManager, type IRemoteServicesManager, type IEnvironmentsManager, type IRemoteRuntimesManager, type NavigationLinkProps, type IDatalayerCoreConfig, type IRuntimesConfiguration, type IIAMProviderName, } from './client';
|
|
15
|
+
export { getEnvironments, createRuntime, getRuntimes, deleteRuntime, snapshotRuntime, getSandboxSnapshots, loadSandboxSnapshot, } from './stateful/runtimes/actions';
|
|
16
16
|
export * from './otel';
|
|
17
17
|
export * from './views';
|
package/lib/index.js
CHANGED
|
@@ -25,7 +25,7 @@ User, Runtime, Environment, Snapshot, Space, Project, Notebook, LexicalDTO, Secr
|
|
|
25
25
|
// Export auth
|
|
26
26
|
AuthenticationManager, Datasource, } from './client/index.js';
|
|
27
27
|
// Export commonly used functions directly for convenience
|
|
28
|
-
export { getEnvironments, createRuntime, getRuntimes, deleteRuntime, snapshotRuntime,
|
|
28
|
+
export { getEnvironments, createRuntime, getRuntimes, deleteRuntime, snapshotRuntime, getSandboxSnapshots, loadSandboxSnapshot, } from './stateful/runtimes/actions.js';
|
|
29
29
|
// OTEL observability components, hooks, and types
|
|
30
30
|
export * from './otel/index.js';
|
|
31
31
|
// Reusable views (sign-in pages, etc.)
|
|
@@ -4,10 +4,16 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
4
4
|
* Distributed under the terms of the Modified BSD License.
|
|
5
5
|
*/
|
|
6
6
|
import { AlertIcon } from '@primer/octicons-react';
|
|
7
|
-
import {
|
|
7
|
+
import { Box, Button, Flash } from '@primer/react';
|
|
8
8
|
import { useNavigate } from '../../hooks/index.js';
|
|
9
9
|
export const FlashMock = () => {
|
|
10
10
|
const navigate = useNavigate();
|
|
11
|
-
return (
|
|
11
|
+
return (_jsx(Flash, { variant: "warning", style: { marginBottom: 10 }, children: _jsxs(Box, { sx: {
|
|
12
|
+
display: 'flex',
|
|
13
|
+
alignItems: 'center',
|
|
14
|
+
justifyContent: 'space-between',
|
|
15
|
+
gap: 3,
|
|
16
|
+
width: '100%',
|
|
17
|
+
}, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(AlertIcon, {}), _jsx("span", { children: "This is placeholder content. Contact us to learn more about this feature." })] }), _jsx(Button, { size: "small", onClick: () => navigate('/contact'), children: "Contact Us" })] }) }));
|
|
12
18
|
};
|
|
13
19
|
export default FlashMock;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Code Sandbox snapshot from API.
|
|
3
3
|
*/
|
|
4
|
-
export interface
|
|
4
|
+
export interface IAPICodeSandboxSnapshot {
|
|
5
5
|
/**
|
|
6
6
|
* Snapshot UID
|
|
7
7
|
*/
|
|
@@ -44,9 +44,9 @@ export interface IAPIRuntimeSnapshot {
|
|
|
44
44
|
status: string;
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
|
-
*
|
|
47
|
+
* Code Sandbox snapshot model.
|
|
48
48
|
*/
|
|
49
|
-
export interface
|
|
49
|
+
export interface ICodeSandboxSnapshot {
|
|
50
50
|
/**
|
|
51
51
|
* Snapshot UID
|
|
52
52
|
*/
|
|
@@ -89,4 +89,4 @@ export interface IRuntimeSnapshot {
|
|
|
89
89
|
*/
|
|
90
90
|
status: string;
|
|
91
91
|
}
|
|
92
|
-
export declare function
|
|
92
|
+
export declare function asCodeSandboxSnapshot(s: IAPICodeSandboxSnapshot): ICodeSandboxSnapshot;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
3
|
* Distributed under the terms of the Modified BSD License.
|
|
4
4
|
*/
|
|
5
|
-
export function
|
|
5
|
+
export function asCodeSandboxSnapshot(s) {
|
|
6
6
|
const { uid, updated_at, format_version, ...others } = s;
|
|
7
7
|
return {
|
|
8
8
|
...others,
|