@datalayer/core 0.0.3 → 0.0.4
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 +114 -3
- package/lib/App.css +2 -2
- package/lib/App.d.ts +1 -1
- package/lib/App.js +9 -9
- package/lib/__tests__/index.test.js +5 -5
- package/lib/api/DatalayerApi.d.ts +1 -1
- package/lib/api/DatalayerApi.js +3 -3
- package/lib/api/index.d.ts +3 -3
- package/lib/api/index.js +3 -3
- package/lib/api/runtimes/actions.js +22 -23
- package/lib/api/runtimes/settings.js +3 -3
- package/lib/api/runtimes/snapshots.d.ts +1 -1
- package/lib/api/runtimes/snapshots.js +8 -8
- package/lib/api/runtimes/utils.js +1 -4
- package/lib/collaboration/DatalayerCollaboration.d.ts +9 -0
- package/lib/collaboration/DatalayerCollaboration.js +28 -0
- package/lib/collaboration/DatalayerCollaborationProvider.d.ts +54 -0
- package/lib/collaboration/DatalayerCollaborationProvider.js +162 -0
- package/lib/collaboration/index.d.ts +2 -0
- package/lib/collaboration/index.js +6 -0
- package/lib/components/avatars/BoringAvatar.d.ts +1 -1
- package/lib/components/avatars/BoringAvatar.js +2 -2
- package/lib/components/avatars/UserProfileAvatar.js +2 -9
- package/lib/components/banners/NoAutomationBanner.js +4 -4
- package/lib/components/buttons/DownloadCSVButton.js +1 -1
- package/lib/components/buttons/UploadButton.js +1 -1
- package/lib/components/checkout/StripeCheckout.d.ts +1 -1
- package/lib/components/checkout/StripeCheckout.js +6 -6
- package/lib/components/confetti/ConfettiSuccess.js +1 -1
- package/lib/components/context/OrganizationSelect.js +5 -5
- package/lib/components/context/SpaceSelect.js +7 -7
- package/lib/components/display/AvatarSkeleton.js +1 -1
- package/lib/components/display/CenteredSpinner.js +4 -4
- package/lib/components/display/CodePreview.js +4 -4
- package/lib/components/display/DatalayerBox.js +13 -14
- package/lib/components/display/HorizontalCenter.d.ts +1 -1
- package/lib/components/display/HorizontalCenter.js +1 -1
- package/lib/components/display/JupyterDialog.js +17 -15
- package/lib/components/display/NavLink.d.ts +4 -2
- package/lib/components/display/NavLink.js +6 -4
- package/lib/components/display/NotebookSkeleton.js +2 -2
- package/lib/components/display/Placeholder.js +1 -1
- package/lib/components/display/ToTopBranded.js +1 -1
- package/lib/components/echarts/EChartsReact.d.ts +1 -1
- package/lib/components/echarts/EChartsReact.js +1 -1
- package/lib/components/flashes/FlashClosable.js +11 -11
- package/lib/components/flashes/FlashDisclaimer.js +2 -3
- package/lib/components/flashes/FlashGuest.js +3 -4
- package/lib/components/flashes/FlashSurveys.js +3 -4
- package/lib/components/flashes/FlashUnauthorized.js +2 -2
- package/lib/components/flashes/surveys/Survey2025_1.d.ts +1 -1
- package/lib/components/flashes/surveys/Survey2025_1.js +62 -85
- package/lib/components/iam/ExternalTokenSilentLogin.js +6 -4
- package/lib/components/icons/ArtifactIcon.d.ts +2 -2
- package/lib/components/icons/ArtifactIcon.js +39 -39
- package/lib/components/labels/VisibilityLabel.js +2 -5
- package/lib/components/landings/StepBlock.d.ts +1 -1
- package/lib/components/landings/StepBlock.js +1 -1
- package/lib/components/navbar/NavigationVisbilityObserver.js +2 -2
- package/lib/components/navbar/SubdomainNavBar.js +45 -23
- package/lib/components/navbar/SubdomainNavBar.module.css +33 -14
- package/lib/components/nbgrader/NbGradesDetails.d.ts +1 -1
- package/lib/components/nbgrader/NbGradesDetails.js +5 -8
- package/lib/components/notebooks/JupyterNotebook.js +5 -5
- package/lib/components/notebooks/JupyterNotebookToolbar.js +3 -3
- package/lib/components/primer/Helper.d.ts +1 -1
- package/lib/components/primer/Helper.js +5 -3
- package/lib/components/primer/Portals.d.ts +1 -1
- package/lib/components/primer/Portals.js +2 -2
- package/lib/components/primer/Styles.js +1 -1
- package/lib/components/progress/ConsumptionBar.js +2 -2
- package/lib/components/progress/CreditsIndicator.d.ts +1 -1
- package/lib/components/progress/CreditsIndicator.js +4 -7
- package/lib/components/progress/ProgressRing.js +2 -2
- package/lib/components/runtimes/RuntimeCellVariables.js +9 -9
- package/lib/components/runtimes/RuntimeCellVariablesDialog.js +3 -3
- package/lib/components/runtimes/RuntimeLauncherDialog.js +30 -34
- package/lib/components/runtimes/RuntimePickerBase.js +42 -31
- package/lib/components/runtimes/RuntimePickerCell.js +9 -12
- package/lib/components/runtimes/RuntimePickerNotebook.js +44 -44
- package/lib/components/runtimes/RuntimeReservationControl.js +10 -15
- package/lib/components/runtimes/RuntimeSimplePicker.js +9 -12
- package/lib/components/runtimes/RuntimeUtils.js +22 -12
- package/lib/components/runtimes/RuntimeVariables.js +7 -7
- package/lib/components/screenshot/ScreenCapture.js +9 -13
- package/lib/components/screenshot/ScreenCaptureButton.d.ts +1 -1
- package/lib/components/screenshot/ScreenCaptureButton.js +14 -8
- package/lib/components/snapshots/RuntimeSnapshotMenu.js +19 -17
- package/lib/components/snippets/SnippetDialog.js +5 -5
- package/lib/components/storage/ContentsBrowser.js +63 -56
- package/lib/components/storage/ContentsItems.js +10 -8
- package/lib/components/students/StudentItemStatus.d.ts +1 -1
- package/lib/components/students/StudentItemStatus.js +35 -16
- package/lib/components/subnav/SubNav.d.ts +1 -1
- package/lib/components/subnav/SubNav.js +30 -15
- package/lib/components/subnav/SubNav.module.css +55 -21
- package/lib/components/tables/DataTable.js +1 -4
- package/lib/components/text-reveal/TextRevealAnimation.js +7 -2
- package/lib/components/text-reveal/TextRevealAnimation.module.css +4 -2
- package/lib/components/tokens/SpaceVariantToken.d.ts +1 -1
- package/lib/components/tokens/SpaceVariantToken.js +5 -5
- package/lib/components/toolbars/AssignmentEditorToolbar.js +1 -3
- package/lib/components/users/PeerIndicator.d.ts +1 -1
- package/lib/components/users/PeerIndicator.js +5 -5
- package/lib/config/Configuration.d.ts +48 -0
- package/lib/config/Configuration.js +42 -0
- package/lib/config/integrations/Loom.js +3 -3
- package/lib/examples/CellExample.d.ts +2 -2
- package/lib/examples/CellExample.js +34 -3
- package/lib/examples/DatalayerNotebookExample.d.ts +16 -0
- package/lib/examples/DatalayerNotebookExample.js +75 -0
- package/lib/examples/NativeNavigationExample.d.ts +8 -0
- package/lib/examples/NativeNavigationExample.js +97 -0
- package/lib/examples/NotebookExample.d.ts +1 -3
- package/lib/examples/NotebookExample.js +9 -7
- package/lib/examples/NotebookMutationsKernel.d.ts +2 -0
- package/lib/examples/NotebookMutationsKernel.js +115 -0
- package/lib/examples/NotebookMutationsServiceManager.d.ts +2 -0
- package/lib/examples/NotebookMutationsServiceManager.js +107 -0
- package/lib/examples/ReactRouterExample.d.ts +6 -0
- package/lib/examples/ReactRouterExample.js +175 -0
- package/lib/examples/example-selector.d.ts +22 -0
- package/lib/examples/example-selector.js +45 -0
- package/lib/examples/index.d.ts +2 -0
- package/lib/examples/index.js +6 -0
- package/lib/examples/main.js +153 -0
- package/lib/examples/notebooks/IPyWidgetsExample.ipynb.json +101 -0
- package/lib/examples/notebooks/IPyWidgetsExampleWithState.ipynb.json +112 -0
- package/lib/examples/{NotebookExample1.ipynb.json → notebooks/Lite.ipynb.json} +45 -53
- package/lib/examples/notebooks/Matplotlib.ipynb.json +137 -0
- package/lib/examples/notebooks/NotebookExample1.ipynb.json +126 -0
- package/lib/examples/notebooks/NotebookExample2.ipynb.json +48 -0
- package/lib/examples/notebooks/NotebookOutputs.ipynb.json +49 -0
- package/lib/examples/notebooks/NotebookToCExample.ipynb.json +102 -0
- package/lib/examples/notebooks/OutputIPyWidgetsExample.d.ts +145 -0
- package/lib/examples/notebooks/OutputIPyWidgetsExample.js +153 -0
- package/lib/examples/notebooks/PyGWalker.ipynb.json +55 -0
- package/lib/hooks/assets/OutputshotPlaceholders.d.ts +10 -10
- package/lib/hooks/assets/OutputshotPlaceholders.js +10 -10
- package/lib/hooks/index.d.ts +29 -28
- package/lib/hooks/index.js +29 -28
- package/lib/hooks/layouts/LayoutBackdrop.js +3 -6
- package/lib/hooks/layouts/LayoutScreenshot.css +1 -1
- package/lib/hooks/layouts/LayoutScreenshot.js +6 -6
- package/lib/hooks/useAIAgents.d.ts +1 -1
- package/lib/hooks/useAIAgents.js +6 -6
- package/lib/hooks/useAuthorization.js +4 -4
- package/lib/hooks/useBackdrop.js +7 -7
- package/lib/hooks/useBackdropJupyterLab.d.ts +1 -1
- package/lib/hooks/useBackdropJupyterLab.js +4 -4
- package/lib/hooks/useCache.d.ts +6 -2
- package/lib/hooks/useCache.js +233 -179
- package/lib/hooks/useCellOutputshot.js +3 -6
- package/lib/hooks/useContainsFocus.js +2 -1
- package/lib/hooks/useDatalayer.js +5 -3
- package/lib/hooks/useError.d.ts +1 -1
- package/lib/hooks/useError.js +2 -2
- package/lib/hooks/useExternalScript.js +4 -4
- package/lib/hooks/useFocusTrap.js +2 -1
- package/lib/hooks/useIAM.js +4 -5
- package/lib/hooks/useId.js +3 -3
- package/lib/hooks/useJupyterLabTheme.js +3 -1
- package/lib/hooks/useLocation.d.ts +22 -0
- package/lib/hooks/useLocation.js +149 -0
- package/lib/hooks/useLocationHandles.d.ts +2 -2
- package/lib/hooks/useLocationHandles.js +6 -4
- package/lib/hooks/useNavigate.d.ts +5 -1
- package/lib/hooks/useNavigate.js +62 -7
- package/lib/hooks/useNotebookAIAgent.js +3 -1
- package/lib/hooks/useParams.d.ts +5 -0
- package/lib/hooks/useParams.js +152 -0
- package/lib/hooks/useRuntimes.js +2 -2
- package/lib/hooks/useScreenshot.js +5 -5
- package/lib/hooks/useToast.js +15 -13
- package/lib/hooks/useUpload.js +9 -9
- package/lib/hooks/useUser.js +1 -1
- package/lib/index.css +1 -1
- package/lib/index.d.ts +6 -3
- package/lib/index.js +7 -3
- package/lib/mocks/components/FlashMock.js +4 -4
- package/lib/mocks/hooks/rests/rests.js +15 -18
- package/lib/mocks/hooks/useDatalayerMock.d.ts +2 -2
- package/lib/mocks/hooks/useDatalayerMock.js +7 -7
- package/lib/mocks/models/CodeBlockMock.js +1 -1
- package/lib/mocks/models/CodelineMock.js +1 -1
- package/lib/mocks/models/CourseMock.d.ts +1 -1
- package/lib/mocks/models/CourseMock.js +10 -10
- package/lib/mocks/models/InviteMock.d.ts +1 -1
- package/lib/mocks/models/InviteMock.js +21 -6
- package/lib/mocks/models/JupyterLabUserMock.js +2 -2
- package/lib/mocks/models/OrganisationMock.d.ts +1 -1
- package/lib/mocks/models/OrganisationMock.js +11 -7
- package/lib/mocks/models/SchoolMock.d.ts +1 -1
- package/lib/mocks/models/SchoolMock.js +6 -6
- package/lib/mocks/models/SpaceMock.d.ts +1 -1
- package/lib/mocks/models/SpaceMock.js +9 -9
- package/lib/mocks/models/TeamMock.d.ts +1 -1
- package/lib/mocks/models/TeamMock.js +6 -6
- package/lib/mocks/models/UserMock.d.ts +1 -1
- package/lib/mocks/models/UserMock.js +4 -6
- package/lib/mocks/views/ActionMenuMock.js +1 -1
- package/lib/mocks/views/ChartMock.js +3 -3
- package/lib/mocks/views/ChartMockOptions.js +24 -24
- package/lib/mocks/views/DashboardMock.js +74 -74
- package/lib/mocks/views/FormMock.js +1 -1
- package/lib/mocks/views/TableMock.js +1 -1
- package/lib/models/Account.d.ts +2 -2
- package/lib/models/Assignment.d.ts +2 -2
- package/lib/models/Cell.d.ts +1 -1
- package/lib/models/CodeBlock.d.ts +1 -1
- package/lib/models/CodefeedBlocks.d.ts +2 -2
- package/lib/models/Contact.d.ts +1 -1
- package/lib/models/Contact.js +14 -14
- package/lib/models/ContactIAMProvider.js +2 -2
- package/lib/models/Course.d.ts +7 -7
- package/lib/models/Dataset.d.ts +1 -1
- package/lib/models/Dean.d.ts +1 -1
- package/lib/models/Document.d.ts +1 -1
- package/lib/models/Environment.d.ts +2 -2
- package/lib/models/Exercise.d.ts +1 -1
- package/lib/models/IAMProviderLinked.js +1 -1
- package/lib/models/Instructor.d.ts +1 -1
- package/lib/models/Invite.d.ts +2 -2
- package/lib/models/Invite.js +1 -1
- package/lib/models/Item.d.ts +5 -5
- package/lib/models/LandingRoles.js +18 -18
- package/lib/models/Lesson.d.ts +1 -1
- package/lib/models/Member.d.ts +1 -1
- package/lib/models/Notebook.d.ts +1 -1
- package/lib/models/Organization.d.ts +4 -4
- package/lib/models/Organization.js +2 -2
- package/lib/models/OrganizationMember.d.ts +2 -2
- package/lib/models/Page.js +4 -2
- package/lib/models/PageTag.d.ts +1 -1
- package/lib/models/PageTag.js +56 -9
- package/lib/models/Profile.d.ts +1 -1
- package/lib/models/RolesOrganization.d.ts +1 -1
- package/lib/models/RolesOrganization.js +4 -12
- package/lib/models/RolesPlatform.d.ts +1 -1
- package/lib/models/RolesPlatform.js +12 -34
- package/lib/models/RolesTeam.d.ts +1 -1
- package/lib/models/RolesTeam.js +3 -10
- package/lib/models/Runtime.js +4 -4
- package/lib/models/RuntimeSnapshot.js +1 -1
- package/lib/models/School.d.ts +4 -4
- package/lib/models/Space.d.ts +5 -5
- package/lib/models/Space.js +3 -3
- package/lib/models/SpaceItem.d.ts +8 -8
- package/lib/models/SpaceMember.d.ts +2 -2
- package/lib/models/Student.d.ts +2 -2
- package/lib/models/StudentItem.d.ts +3 -3
- package/lib/models/Team.d.ts +3 -3
- package/lib/models/Team.js +2 -2
- package/lib/models/TeamMember.d.ts +2 -2
- package/lib/models/URN.js +1 -1
- package/lib/models/User.d.ts +2 -2
- package/lib/models/User.js +5 -3
- package/lib/models/UserOnboarding.d.ts +1 -1
- package/lib/models/UserOnboarding.js +7 -7
- package/lib/models/UserSettings.js +2 -2
- package/lib/models/index.d.ts +2 -2
- package/lib/models/index.js +2 -2
- package/lib/navigation/adapters/native.d.ts +11 -0
- package/lib/navigation/adapters/native.js +48 -0
- package/lib/navigation/adapters/nextjs.d.ts +9 -0
- package/lib/navigation/adapters/nextjs.js +35 -0
- package/lib/navigation/adapters/react-router.d.ts +4 -0
- package/lib/navigation/adapters/react-router.js +12 -0
- package/lib/navigation/components.d.ts +20 -0
- package/lib/navigation/components.js +36 -0
- package/lib/navigation/index.d.ts +4 -0
- package/lib/navigation/index.js +12 -0
- package/lib/routes/index.d.ts +1 -1
- package/lib/routes/index.js +1 -1
- package/lib/services/DatalayerServiceManager.d.ts +22 -0
- package/lib/services/DatalayerServiceManager.js +79 -0
- package/lib/services/index.d.ts +4 -0
- package/lib/services/index.js +7 -0
- package/lib/services/reconnectToRuntime.d.ts +32 -0
- package/lib/services/reconnectToRuntime.js +59 -0
- package/lib/state/State.d.ts +1 -1
- package/lib/state/State.js +1 -1
- package/lib/state/index.d.ts +1 -1
- package/lib/state/index.js +1 -1
- package/lib/state/storage/IAMStorage.js +14 -2
- package/lib/state/storage/index.d.ts +1 -1
- package/lib/state/storage/index.js +1 -1
- package/lib/state/substates/AIAgentState.js +4 -2
- package/lib/state/substates/CellState.js +6 -5
- package/lib/state/substates/CoreState.d.ts +1 -1
- package/lib/state/substates/CoreState.js +23 -15
- package/lib/state/substates/DatasourceState.js +1 -1
- package/lib/state/substates/IAMState.d.ts +4 -0
- package/lib/state/substates/IAMState.js +75 -56
- package/lib/state/substates/JupyterLabState.js +1 -1
- package/lib/state/substates/LayoutState.d.ts +2 -2
- package/lib/state/substates/LayoutState.js +41 -28
- package/lib/state/substates/OrganizationState.js +1 -1
- package/lib/state/substates/RuntimesState.js +6 -5
- package/lib/state/substates/SpaceState.js +1 -1
- package/lib/state/substates/SurveysState.js +4 -4
- package/lib/state/substates/TeamState.js +1 -1
- package/lib/test-setup.js +25 -3
- package/lib/theme/DatalayerTheme.js +1 -1
- package/lib/theme/DatalayerThemeProvider.js +17 -14
- package/lib/theme/Palette.js +1 -1
- package/lib/utils/Avatar.js +2 -2
- package/lib/utils/Browser.js +6 -6
- package/lib/utils/Cells.d.ts +1 -1
- package/lib/utils/Cookie.js +1 -1
- package/lib/utils/Date.js +2 -2
- package/lib/utils/Download.js +5 -3
- package/lib/utils/DownloadFile.js +4 -2
- package/lib/utils/Env.js +2 -1
- package/lib/utils/Lazy.d.ts +1 -1
- package/lib/utils/Lazy.js +2 -2
- package/lib/utils/Name.js +10 -8
- package/lib/utils/Notebook.d.ts +1 -1
- package/lib/utils/Notebook.js +3 -3
- package/lib/utils/Number.js +13 -9
- package/lib/utils/Plots.js +4 -4
- package/lib/utils/Screenshot.js +1 -1
- package/lib/utils/Sleep.js +1 -1
- package/lib/utils/Snapshot.js +2 -2
- package/lib/utils/String.js +2 -2
- package/lib/utils/Uri.js +1 -1
- package/lib/utils/WithSuspense.js +3 -6
- package/package.json +41 -5
- package/lib/__tests__/App.test.js +0 -17
- /package/lib/{__tests__/App.test.d.ts → examples/main.d.ts} +0 -0
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
import { Poll } from '@lumino/polling';
|
|
6
6
|
import { useStore } from 'zustand';
|
|
7
7
|
import { createStore } from 'zustand/vanilla';
|
|
8
|
-
import { ANONYMOUS_USER_TOKEN, ANONYMOUS_USER, asUser, IAMProvidersSpecs } from '../../models';
|
|
9
|
-
import { getStoredToken, getStoredUser, loadRefreshTokenFromCookie, storeToken, storeUser } from '../storage';
|
|
8
|
+
import { ANONYMOUS_USER_TOKEN, ANONYMOUS_USER, asUser, IAMProvidersSpecs, } from '../../models';
|
|
9
|
+
import { getStoredToken, getStoredUser, loadRefreshTokenFromCookie, storeToken, storeUser, } from '../storage';
|
|
10
10
|
import { requestDatalayerAPI } from '../../api';
|
|
11
11
|
import { getCookie, setCookie, deleteCookie } from '../../utils';
|
|
12
12
|
import { coreStore } from './CoreState';
|
|
@@ -24,16 +24,19 @@ export const iamStore = createStore((set, get) => {
|
|
|
24
24
|
iamRunUrl: coreStore.getState().configuration?.iamRunUrl,
|
|
25
25
|
iamProvidersAuthorizationURL: {},
|
|
26
26
|
version: '',
|
|
27
|
+
isLoginInProgress: false,
|
|
27
28
|
addIAMProviderAuthorizationURL: (provider, authorizationURL) => {
|
|
28
29
|
set(state => ({
|
|
29
30
|
iamProvidersAuthorizationURL: {
|
|
30
31
|
...state.iamProvidersAuthorizationURL,
|
|
31
32
|
[provider]: authorizationURL,
|
|
32
|
-
}
|
|
33
|
+
},
|
|
33
34
|
}));
|
|
34
35
|
},
|
|
35
36
|
login: async (token) => {
|
|
36
37
|
const { refreshUserByToken, iamRunUrl, logout } = get();
|
|
38
|
+
// Set flag to prevent interference from automatic token refresh
|
|
39
|
+
set({ isLoginInProgress: true });
|
|
37
40
|
try {
|
|
38
41
|
const resp = await requestDatalayerAPI({
|
|
39
42
|
url: `${iamRunUrl}/api/iam/v1/login`,
|
|
@@ -41,7 +44,7 @@ export const iamStore = createStore((set, get) => {
|
|
|
41
44
|
body: { token },
|
|
42
45
|
});
|
|
43
46
|
if (resp.success && resp.token) {
|
|
44
|
-
refreshUserByToken(resp.token);
|
|
47
|
+
await refreshUserByToken(resp.token);
|
|
45
48
|
}
|
|
46
49
|
else {
|
|
47
50
|
throw new Error('Invalid Token.');
|
|
@@ -49,12 +52,16 @@ export const iamStore = createStore((set, get) => {
|
|
|
49
52
|
}
|
|
50
53
|
catch (error) {
|
|
51
54
|
console.debug('Failed to login.', error);
|
|
52
|
-
if (error.name === 'RunResponseError' &&
|
|
55
|
+
if (error.name === 'RunResponseError' &&
|
|
56
|
+
error.response.status === 401) {
|
|
53
57
|
console.debug('Received 401 error - Logging out.');
|
|
54
58
|
logout();
|
|
55
59
|
}
|
|
56
60
|
throw error;
|
|
57
61
|
}
|
|
62
|
+
finally {
|
|
63
|
+
set({ isLoginInProgress: false });
|
|
64
|
+
}
|
|
58
65
|
},
|
|
59
66
|
logout: () => {
|
|
60
67
|
storeUser();
|
|
@@ -97,7 +104,7 @@ export const iamStore = createStore((set, get) => {
|
|
|
97
104
|
user: {
|
|
98
105
|
...state.user,
|
|
99
106
|
...user,
|
|
100
|
-
}
|
|
107
|
+
},
|
|
101
108
|
};
|
|
102
109
|
/*
|
|
103
110
|
if (state.user?.email && !updatedState.user.email) {
|
|
@@ -115,9 +122,9 @@ export const iamStore = createStore((set, get) => {
|
|
|
115
122
|
token,
|
|
116
123
|
headers: externalToken
|
|
117
124
|
? {
|
|
118
|
-
'X-External-Token': externalToken
|
|
125
|
+
'X-External-Token': externalToken,
|
|
119
126
|
}
|
|
120
|
-
: undefined
|
|
127
|
+
: undefined,
|
|
121
128
|
});
|
|
122
129
|
const { credits, reservations: creditsReservations = [] } = creditsRaw;
|
|
123
130
|
let available = credits.quota !== null
|
|
@@ -126,7 +133,7 @@ export const iamStore = createStore((set, get) => {
|
|
|
126
133
|
available -= creditsReservations.reduce((consumed, reservation) => consumed + reservation.credits, 0);
|
|
127
134
|
set({
|
|
128
135
|
credits: { ...credits, available: Math.max(0, available) },
|
|
129
|
-
creditsReservations: creditsReservations
|
|
136
|
+
creditsReservations: creditsReservations,
|
|
130
137
|
});
|
|
131
138
|
}
|
|
132
139
|
catch (error) {
|
|
@@ -162,7 +169,7 @@ export const iamStore = createStore((set, get) => {
|
|
|
162
169
|
}
|
|
163
170
|
},
|
|
164
171
|
refreshUserByToken: async (token) => {
|
|
165
|
-
const { iamRunUrl, logout } = get();
|
|
172
|
+
const { iamRunUrl, logout, isLoginInProgress } = get();
|
|
166
173
|
try {
|
|
167
174
|
const data = await requestDatalayerAPI({
|
|
168
175
|
url: `${iamRunUrl}/api/iam/v1/whoami`,
|
|
@@ -188,16 +195,21 @@ export const iamStore = createStore((set, get) => {
|
|
|
188
195
|
else {
|
|
189
196
|
console.debug('Failed to fetch user identity.', error);
|
|
190
197
|
}
|
|
191
|
-
logout
|
|
198
|
+
// Only logout if we're not in the middle of a login attempt
|
|
199
|
+
if (!isLoginInProgress) {
|
|
200
|
+
logout();
|
|
201
|
+
}
|
|
192
202
|
}
|
|
193
203
|
},
|
|
194
|
-
setExternalToken: (externalToken) => set((state) => {
|
|
204
|
+
setExternalToken: (externalToken) => set((state) => {
|
|
205
|
+
return { externalToken };
|
|
206
|
+
}),
|
|
195
207
|
setLogin: (user, token) => set((state) => {
|
|
196
208
|
storeUser(user);
|
|
197
209
|
storeToken(token);
|
|
198
210
|
return {
|
|
199
211
|
user,
|
|
200
|
-
token
|
|
212
|
+
token,
|
|
201
213
|
};
|
|
202
214
|
}),
|
|
203
215
|
setVersion: version => {
|
|
@@ -218,52 +230,57 @@ const creditsPoll = new Poll({
|
|
|
218
230
|
frequency: {
|
|
219
231
|
interval: 60 * 1000,
|
|
220
232
|
backoff: true,
|
|
221
|
-
max: 600 * 1000
|
|
233
|
+
max: 600 * 1000,
|
|
222
234
|
},
|
|
223
|
-
standby: () => (iamStore.getState().user?.id ? 'when-hidden' : true)
|
|
235
|
+
standby: () => (iamStore.getState().user?.id ? 'when-hidden' : true),
|
|
224
236
|
});
|
|
225
237
|
// Initialize the IAM store with the stored token if it is valid.
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
238
|
+
// Delay initialization slightly to allow apps to set up first
|
|
239
|
+
setTimeout(() => {
|
|
240
|
+
iamStore
|
|
241
|
+
.getState()
|
|
242
|
+
.refreshUserByTokenStored()
|
|
243
|
+
.catch(reason => {
|
|
244
|
+
console.error('Failed to refresh to validate the stored token.', reason);
|
|
245
|
+
})
|
|
246
|
+
.finally(() => {
|
|
247
|
+
const { externalToken, iamRunUrl, checkIAMToken, token } = iamStore.getState();
|
|
248
|
+
// If the stored token is invalid and an external token exists, try authenticating with it.
|
|
249
|
+
if (!token && externalToken) {
|
|
250
|
+
console.debug('Can not login with token - Trying with the external token.');
|
|
251
|
+
requestDatalayerAPI({
|
|
252
|
+
url: `${iamRunUrl}/api/iam/v1/login`,
|
|
253
|
+
method: 'POST',
|
|
254
|
+
body: { token: externalToken },
|
|
255
|
+
})
|
|
256
|
+
.then(response => {
|
|
257
|
+
if (response.token) {
|
|
258
|
+
checkIAMToken(response.token);
|
|
259
|
+
}
|
|
260
|
+
})
|
|
261
|
+
.catch(reason => {
|
|
262
|
+
console.debug('Can not login with token.', token, reason);
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
if (token) {
|
|
266
|
+
console.log('Logged in with token and external token.');
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
console.debug('Failed to login with token and no external token available.');
|
|
270
|
+
}
|
|
271
|
+
// Start the credits poll in any case after trying to validate the user token.
|
|
272
|
+
creditsPoll.start();
|
|
273
|
+
// Force a refresh when the user comeback to the application tab
|
|
274
|
+
// Useful for checkout platform redirecting to another tab to add credits.
|
|
275
|
+
if (typeof document !== 'undefined') {
|
|
276
|
+
document.addEventListener('visibilitychange', () => {
|
|
277
|
+
if (!document.hidden && iamStore.getState().user?.id) {
|
|
278
|
+
creditsPoll.refresh();
|
|
279
|
+
}
|
|
280
|
+
});
|
|
264
281
|
}
|
|
265
282
|
});
|
|
266
|
-
});
|
|
283
|
+
}, 100); // 100ms delay to allow app initialization
|
|
267
284
|
// Connect the core store with the iam store.
|
|
268
285
|
coreStore.subscribe((state, prevState) => {
|
|
269
286
|
if (state.configuration?.iamRunUrl &&
|
|
@@ -273,14 +290,16 @@ coreStore.subscribe((state, prevState) => {
|
|
|
273
290
|
iamStore.setState({ iamRunUrl });
|
|
274
291
|
// Check the token is valid with the new server.
|
|
275
292
|
if (iamStore.getState().externalToken) {
|
|
276
|
-
iamStore
|
|
293
|
+
iamStore
|
|
294
|
+
.getState()
|
|
277
295
|
.login(iamStore.getState().externalToken)
|
|
278
296
|
.catch(reason => {
|
|
279
297
|
console.error('Failed to refresh the user after updating the IAM RUN URL.', reason);
|
|
280
298
|
});
|
|
281
299
|
}
|
|
282
300
|
else {
|
|
283
|
-
iamStore
|
|
301
|
+
iamStore
|
|
302
|
+
.getState()
|
|
284
303
|
.refreshUser()
|
|
285
304
|
.catch(reason => {
|
|
286
305
|
console.error('Failed to refresh the user after updating the IAM server URL.', reason);
|
|
@@ -9,7 +9,7 @@ export const jupyterLabStore = createStore((set, get) => ({
|
|
|
9
9
|
setJupyterLabAdapter: (jupyterLabAdapter) => set((state) => ({ jupyterLabAdapter })),
|
|
10
10
|
plugin: (id) => {
|
|
11
11
|
return get().jupyterLabAdapter?.plugin(id);
|
|
12
|
-
}
|
|
12
|
+
},
|
|
13
13
|
}));
|
|
14
14
|
export function useJupyterLabStore(selector) {
|
|
15
15
|
return useStore(jupyterLabStore, selector);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ReactPortal } from
|
|
2
|
-
import { IAnyOrganization, IAnySpace, IAnyTeam, ISpaceItem } from
|
|
1
|
+
import { ReactPortal } from 'react';
|
|
2
|
+
import { IAnyOrganization, IAnySpace, IAnyTeam, ISpaceItem } from '../../models';
|
|
3
3
|
export type BannerDisplayVariant = 'danger' | 'info' | 'success' | 'warning';
|
|
4
4
|
export type LeftSidebarVariant = 'codefeed' | 'course' | 'empty' | 'guess-account' | 'guess-space' | 'guess-spaces' | 'organization' | 'organization-space' | 'organization-spaces' | 'organizations' | 'public' | 'unchanged' | 'user' | 'user-space' | 'user-spaces';
|
|
5
5
|
export type BackdropDisplay = {
|
|
@@ -17,8 +17,12 @@ export const layoutStore = createStore((set, get) => ({
|
|
|
17
17
|
screenCapture: undefined,
|
|
18
18
|
space: undefined,
|
|
19
19
|
team: undefined,
|
|
20
|
-
hideBackdrop: () => set((state) => ({
|
|
21
|
-
|
|
20
|
+
hideBackdrop: () => set((state) => ({
|
|
21
|
+
backdrop: { open: false, message: undefined },
|
|
22
|
+
})),
|
|
23
|
+
hideScreenshot: () => set((state) => ({
|
|
24
|
+
screenshot: { open: false, message: undefined },
|
|
25
|
+
})),
|
|
22
26
|
setBootstrapped: (bootstrapped) => set((state) => ({ bootstrapped })),
|
|
23
27
|
showBackdrop: (message) => set((state) => ({ backdrop: { open: true, message } })),
|
|
24
28
|
showScreenshot: (message) => set((state) => ({ screenshot: { open: true, message } })),
|
|
@@ -27,46 +31,55 @@ export const layoutStore = createStore((set, get) => ({
|
|
|
27
31
|
timestamp: new Date(),
|
|
28
32
|
message: bannerDisplay.message,
|
|
29
33
|
variant: bannerDisplay.variant,
|
|
30
|
-
}
|
|
34
|
+
},
|
|
31
35
|
})),
|
|
32
36
|
setLeftPortal: (leftPortal) => set((state) => ({ leftPortal })),
|
|
33
37
|
setRightPortal: (rightPortal) => set((state) => ({ rightPortal })),
|
|
34
|
-
resetLeftPortal: () => set((state) => ({
|
|
35
|
-
|
|
38
|
+
resetLeftPortal: () => set((state) => ({
|
|
39
|
+
leftPortal: state.leftPortal?.pinned ? state.leftPortal : undefined,
|
|
40
|
+
})),
|
|
41
|
+
resetRightPortal: () => set((state) => ({
|
|
42
|
+
rightPortal: state.rightPortal?.pinned ? state.rightPortal : undefined,
|
|
43
|
+
})),
|
|
36
44
|
resetForcedLeftPortal: () => set((state) => ({ leftPortal: undefined })),
|
|
37
45
|
resetForcedRightPortal: () => set((state) => ({ rightPortal: undefined })),
|
|
38
46
|
setLeftSidebarVariant: (leftSidebarVariant) => set((state) => ({ leftSidebarVariant })),
|
|
39
47
|
updateLayoutOrganization: (organization) => set((state) => {
|
|
40
|
-
return
|
|
41
|
-
organization: organization
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
48
|
+
return {
|
|
49
|
+
organization: organization
|
|
50
|
+
? {
|
|
51
|
+
...state.organization,
|
|
52
|
+
...organization,
|
|
53
|
+
}
|
|
54
|
+
: undefined,
|
|
55
|
+
};
|
|
47
56
|
}),
|
|
48
57
|
updateLayoutTeam: (team) => set((state) => {
|
|
49
|
-
return
|
|
50
|
-
team: team
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
58
|
+
return {
|
|
59
|
+
team: team
|
|
60
|
+
? {
|
|
61
|
+
...state.team,
|
|
62
|
+
...team,
|
|
63
|
+
}
|
|
64
|
+
: undefined,
|
|
65
|
+
};
|
|
56
66
|
}),
|
|
57
67
|
updateLayoutSpace: (space) => set((state) => {
|
|
58
|
-
return
|
|
59
|
-
space: space
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
68
|
+
return {
|
|
69
|
+
space: space
|
|
70
|
+
? {
|
|
71
|
+
...state.space,
|
|
72
|
+
...space,
|
|
73
|
+
}
|
|
74
|
+
: undefined,
|
|
75
|
+
};
|
|
65
76
|
}),
|
|
66
77
|
setItem: (item) => set((state) => ({ item })),
|
|
67
|
-
triggerItemsRefresh: () => set((state) => ({
|
|
78
|
+
triggerItemsRefresh: () => set((state) => ({
|
|
79
|
+
itemsRefreshCount: state.itemsRefreshCount + 1,
|
|
80
|
+
})),
|
|
68
81
|
setScreenCapture: (screenCapture) => set((state) => ({ screenCapture })),
|
|
69
|
-
reset: () => set((state) => ({ bootstrapped: false
|
|
82
|
+
reset: () => set((state) => ({ bootstrapped: false })),
|
|
70
83
|
}));
|
|
71
84
|
export function useLayoutStore(selector) {
|
|
72
85
|
return useStore(layoutStore, selector);
|
|
@@ -7,7 +7,7 @@ import { useStore } from 'zustand';
|
|
|
7
7
|
export const organizationStore = createStore((set, get) => ({
|
|
8
8
|
organizations: [],
|
|
9
9
|
updateOrganizations: (organizations) => set((state) => ({
|
|
10
|
-
organizations
|
|
10
|
+
organizations,
|
|
11
11
|
})),
|
|
12
12
|
}));
|
|
13
13
|
export function useOrganizationStore(selector) {
|
|
@@ -16,7 +16,7 @@ export const runtimesStore = createStore((set, get) => {
|
|
|
16
16
|
return {
|
|
17
17
|
configuration: {
|
|
18
18
|
maxNotebookRuntimes: 5,
|
|
19
|
-
maxCellRuntimes: 3
|
|
19
|
+
maxCellRuntimes: 3,
|
|
20
20
|
},
|
|
21
21
|
setConfiguration: (configuration) => {
|
|
22
22
|
set(state => JSONExt.deepEqual(state.configuration, configuration)
|
|
@@ -127,7 +127,7 @@ export const runtimesStore = createStore((set, get) => {
|
|
|
127
127
|
if (version && !get().version) {
|
|
128
128
|
set(state => ({ version }));
|
|
129
129
|
}
|
|
130
|
-
}
|
|
130
|
+
},
|
|
131
131
|
};
|
|
132
132
|
});
|
|
133
133
|
// Poll remote kernels
|
|
@@ -137,12 +137,12 @@ const kernelsPoll = new Poll({
|
|
|
137
137
|
frequency: {
|
|
138
138
|
interval: 61 * 1000,
|
|
139
139
|
backoff: true,
|
|
140
|
-
max: 300 * 1000
|
|
140
|
+
max: 300 * 1000,
|
|
141
141
|
},
|
|
142
142
|
name: '@datalayer/jupyter-kernels:KernelsManager#kernels',
|
|
143
143
|
standby: () => iamStore.getState().token || runtimesStore.getState().runtimesRunUrl
|
|
144
144
|
? 'when-hidden'
|
|
145
|
-
: true
|
|
145
|
+
: true,
|
|
146
146
|
});
|
|
147
147
|
// Force refresh at expiration date if next tick is after it.
|
|
148
148
|
runtimesStore.subscribe((state, prevState) => {
|
|
@@ -160,7 +160,8 @@ runtimesStore.subscribe((state, prevState) => {
|
|
|
160
160
|
});
|
|
161
161
|
coreStore.subscribe((state, prevState) => {
|
|
162
162
|
if (state.configuration.runtimesRunUrl &&
|
|
163
|
-
state.configuration.runtimesRunUrl !==
|
|
163
|
+
state.configuration.runtimesRunUrl !==
|
|
164
|
+
prevState.configuration.runtimesRunUrl) {
|
|
164
165
|
const runtimesRunUrl = state.configuration.runtimesRunUrl;
|
|
165
166
|
console.log(`Updating runtimesRunUrl with new value ${runtimesRunUrl}`);
|
|
166
167
|
runtimesStore.setState({ runtimesRunUrl });
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { createStore } from 'zustand/vanilla';
|
|
6
6
|
import { useStore } from 'zustand';
|
|
7
7
|
import { requestDatalayerAPI } from '../../api';
|
|
8
|
-
import { asSurvey } from '../../models';
|
|
8
|
+
import { asSurvey, } from '../../models';
|
|
9
9
|
import { coreStore } from './CoreState';
|
|
10
10
|
import { iamStore } from './IAMState';
|
|
11
11
|
export const surveysStore = createStore((set, get) => ({
|
|
@@ -65,9 +65,9 @@ export const surveysStore = createStore((set, get) => ({
|
|
|
65
65
|
set((state) => ({ surveys }));
|
|
66
66
|
}
|
|
67
67
|
else {
|
|
68
|
-
set((state) => ({
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
set((state) => ({
|
|
69
|
+
surveys: new Map([[survey.name, survey]]),
|
|
70
|
+
}));
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
else {
|
package/lib/test-setup.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// Test setup for unit tests
|
|
6
6
|
// Add any global test configuration here
|
|
7
7
|
// Define webpack globals that are expected by some dependencies
|
|
8
|
-
global.__webpack_public_path__ =
|
|
8
|
+
global.__webpack_public_path__ = '';
|
|
9
9
|
// Define other globals that might be needed
|
|
10
10
|
global.global = globalThis;
|
|
11
11
|
// Mock DragEvent and other DOM APIs not available in jsdom
|
|
@@ -13,7 +13,7 @@ class MockDragEvent extends Event {
|
|
|
13
13
|
dataTransfer = null;
|
|
14
14
|
constructor(type, init) {
|
|
15
15
|
super(type, init);
|
|
16
|
-
this.dataTransfer =
|
|
16
|
+
this.dataTransfer = init?.dataTransfer || null;
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
// Mock DataTransfer if not available
|
|
@@ -24,7 +24,9 @@ class MockDataTransfer {
|
|
|
24
24
|
items = [];
|
|
25
25
|
types = [];
|
|
26
26
|
clearData(format) { }
|
|
27
|
-
getData(format) {
|
|
27
|
+
getData(format) {
|
|
28
|
+
return '';
|
|
29
|
+
}
|
|
28
30
|
setData(format, data) { }
|
|
29
31
|
setDragImage(image, x, y) { }
|
|
30
32
|
}
|
|
@@ -53,5 +55,25 @@ vi.mock('@datalayer/jupyter-react', () => ({
|
|
|
53
55
|
serviceManager: null,
|
|
54
56
|
}),
|
|
55
57
|
JupyterReactTheme: ({ children }) => children,
|
|
58
|
+
CollaborationProviderBase: class CollaborationProviderBase {
|
|
59
|
+
},
|
|
60
|
+
CollaborationStatus: {
|
|
61
|
+
IDLE: 'idle',
|
|
62
|
+
CONNECTING: 'connecting',
|
|
63
|
+
CONNECTED: 'connected',
|
|
64
|
+
DISCONNECTED: 'disconnected',
|
|
65
|
+
},
|
|
56
66
|
}));
|
|
57
67
|
vi.mock('@jupyter/web-components', () => ({}));
|
|
68
|
+
vi.mock('@jupyter/ydoc', () => ({
|
|
69
|
+
YNotebook: class YNotebook {
|
|
70
|
+
},
|
|
71
|
+
}));
|
|
72
|
+
vi.mock('y-websocket', () => ({
|
|
73
|
+
WebsocketProvider: class WebsocketProvider {
|
|
74
|
+
constructor() { }
|
|
75
|
+
connect() { }
|
|
76
|
+
disconnect() { }
|
|
77
|
+
destroy() { }
|
|
78
|
+
},
|
|
79
|
+
}));
|
|
@@ -4,7 +4,7 @@ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
|
4
4
|
* Distributed under the terms of the Modified BSD License.
|
|
5
5
|
*/
|
|
6
6
|
import { useEffect, useState } from 'react';
|
|
7
|
-
import { BaseStyles, ThemeProvider as PrimerThemeProvider } from '@primer/react';
|
|
7
|
+
import { BaseStyles, ThemeProvider as PrimerThemeProvider, } from '@primer/react';
|
|
8
8
|
import { loadJupyterConfig, jupyterLabTheme } from '@datalayer/jupyter-react';
|
|
9
9
|
import { datalayerTheme } from '../theme';
|
|
10
10
|
import { useRuntimesStore } from '../state';
|
|
@@ -28,7 +28,9 @@ export function DatalayerThemeProvider(props) {
|
|
|
28
28
|
setColorMode(matches ? 'dark' : 'light');
|
|
29
29
|
}
|
|
30
30
|
function updateColorMode(themeManager) {
|
|
31
|
-
setColorMode(themeManager.theme && !themeManager.isLight(themeManager.theme)
|
|
31
|
+
setColorMode(themeManager.theme && !themeManager.isLight(themeManager.theme)
|
|
32
|
+
? 'dark'
|
|
33
|
+
: 'light');
|
|
32
34
|
}
|
|
33
35
|
if (inJupyterLab) {
|
|
34
36
|
// TODO remove the try/catch for JupyterLab > 4.1.
|
|
@@ -48,22 +50,23 @@ export function DatalayerThemeProvider(props) {
|
|
|
48
50
|
}
|
|
49
51
|
else {
|
|
50
52
|
colorSchemeFromMedia({
|
|
51
|
-
matches: window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
53
|
+
matches: window.matchMedia('(prefers-color-scheme: dark)').matches,
|
|
52
54
|
});
|
|
53
|
-
window
|
|
55
|
+
window
|
|
56
|
+
.matchMedia('(prefers-color-scheme: dark)')
|
|
57
|
+
.addEventListener('change', colorSchemeFromMedia);
|
|
54
58
|
return () => {
|
|
55
|
-
window
|
|
59
|
+
window
|
|
60
|
+
.matchMedia('(prefers-color-scheme: dark)')
|
|
61
|
+
.removeEventListener('change', colorSchemeFromMedia);
|
|
56
62
|
};
|
|
57
63
|
}
|
|
58
64
|
}
|
|
59
65
|
}, [inJupyterLab, jupyterLabAdapter]);
|
|
60
|
-
return
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}, children: children }) })
|
|
67
|
-
:
|
|
68
|
-
_jsx(_Fragment, {}));
|
|
66
|
+
return inJupyterLab !== undefined ? (_jsx(PrimerThemeProvider, { colorMode: colorMode, theme: inJupyterLab ? jupyterLabTheme : datalayerTheme, ...rest, children: _jsx(BaseStyles, { style: {
|
|
67
|
+
backgroundColor: 'var(--bgColor-default)',
|
|
68
|
+
color: 'var(--fgColor-default)',
|
|
69
|
+
fontSize: 'var(--text-body-size-medium)',
|
|
70
|
+
...baseStyles,
|
|
71
|
+
}, children: children }) })) : (_jsx(_Fragment, {}));
|
|
69
72
|
}
|
package/lib/theme/Palette.js
CHANGED
|
@@ -9,7 +9,7 @@ const JUPYTERLAB_COLLABORATORS_COLORS = {
|
|
|
9
9
|
'--jp-collaborator-color4': '#00e4d0',
|
|
10
10
|
'--jp-collaborator-color5': '#45d4ff',
|
|
11
11
|
'--jp-collaborator-color6': '#e2b1ff',
|
|
12
|
-
'--jp-collaborator-color7': '#ff9de6'
|
|
12
|
+
'--jp-collaborator-color7': '#ff9de6',
|
|
13
13
|
};
|
|
14
14
|
export const jpCssToColor = (cssVariableName) => {
|
|
15
15
|
return JUPYTERLAB_COLLABORATORS_COLORS[cssVariableName.replaceAll('var(', '').replaceAll(')', '')];
|
package/lib/utils/Avatar.js
CHANGED
|
@@ -26,8 +26,8 @@ export function stringAvatar(name) {
|
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
export function getAvatarURL(url) {
|
|
29
|
-
return url
|
|
30
|
-
url.startsWith('https://www.gravatar.com/avatar')
|
|
29
|
+
return url
|
|
30
|
+
? url.startsWith('https://www.gravatar.com/avatar')
|
|
31
31
|
? `${url}?v=4&s=200&d=${DEFAULT_AVATAR_URL_ENCODED}` // Use gravatar syntax - sizing works for Gravatar and GitHub
|
|
32
32
|
: url
|
|
33
33
|
: DEFAULT_AVATAR_URL; // This fallback should barely be used - hence we allow decoding the URI.
|
package/lib/utils/Browser.js
CHANGED
|
@@ -8,22 +8,22 @@ export const detectBrowser = () => {
|
|
|
8
8
|
const userAgent = navigator.userAgent;
|
|
9
9
|
let browserName;
|
|
10
10
|
if (userAgent.match(/chrome|chromium|crios/i)) {
|
|
11
|
-
browserName =
|
|
11
|
+
browserName = 'chrome';
|
|
12
12
|
}
|
|
13
13
|
else if (userAgent.match(/firefox|fxios/i)) {
|
|
14
|
-
browserName =
|
|
14
|
+
browserName = 'firefox';
|
|
15
15
|
}
|
|
16
16
|
else if (userAgent.match(/safari/i)) {
|
|
17
|
-
browserName =
|
|
17
|
+
browserName = 'safari';
|
|
18
18
|
}
|
|
19
19
|
else if (userAgent.match(/opr\//i)) {
|
|
20
|
-
browserName =
|
|
20
|
+
browserName = 'opera';
|
|
21
21
|
}
|
|
22
22
|
else if (userAgent.match(/edg/i)) {
|
|
23
|
-
browserName =
|
|
23
|
+
browserName = 'edge';
|
|
24
24
|
}
|
|
25
25
|
else {
|
|
26
|
-
browserName =
|
|
26
|
+
browserName = 'Unknow browser.';
|
|
27
27
|
}
|
|
28
28
|
return browserName;
|
|
29
29
|
};
|
package/lib/utils/Cells.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { IDataset } from
|
|
1
|
+
import { IDataset } from '../models';
|
|
2
2
|
export declare const getDatasetCell: (dataset: IDataset) => string;
|
package/lib/utils/Cookie.js
CHANGED
|
@@ -16,7 +16,7 @@ export function getCookie(cname) {
|
|
|
16
16
|
return cookie;
|
|
17
17
|
}
|
|
18
18
|
// From https://www.w3schools.com/js/js_cookies.asp
|
|
19
|
-
const name = cname +
|
|
19
|
+
const name = cname + '=';
|
|
20
20
|
const decodedCookie = decodeURIComponent(document.cookie);
|
|
21
21
|
const ca = decodedCookie.split(';');
|
|
22
22
|
for (let i = 0; i < ca.length; i++) {
|
package/lib/utils/Date.js
CHANGED
|
@@ -10,11 +10,11 @@ const units = {
|
|
|
10
10
|
day: 24 * 60 * 60 * 1000,
|
|
11
11
|
hour: 60 * 60 * 1000,
|
|
12
12
|
minute: 60 * 1000,
|
|
13
|
-
second: 1000
|
|
13
|
+
second: 1000,
|
|
14
14
|
};
|
|
15
15
|
const rtf = new Intl.RelativeTimeFormat(undefined, {
|
|
16
16
|
numeric: 'auto',
|
|
17
|
-
style: 'short'
|
|
17
|
+
style: 'short',
|
|
18
18
|
});
|
|
19
19
|
export const getRelativeTime = (d1, d2 = new Date()) => {
|
|
20
20
|
const elapsed = d1.getTime() - d2.getTime();
|