@datalayer/core 0.0.6 → 0.0.9
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/lib/components/display/JupyterDialog.js +23 -22
- package/lib/components/notebooks/JupyterNotebookToolbar.js +2 -2
- package/lib/components/runtimes/RuntimeCellVariables.d.ts +5 -5
- package/lib/components/runtimes/RuntimeCellVariables.js +4 -4
- package/lib/components/runtimes/RuntimeCellVariablesDialog.js +2 -2
- package/lib/components/runtimes/RuntimeLauncherDialog.d.ts +5 -5
- package/lib/components/runtimes/RuntimeLauncherDialog.js +18 -17
- package/lib/components/runtimes/RuntimePickerBase.d.ts +1 -1
- package/lib/components/runtimes/RuntimePickerBase.js +26 -26
- package/lib/components/runtimes/RuntimePickerCell.d.ts +1 -1
- package/lib/components/runtimes/RuntimePickerCell.js +14 -14
- package/lib/components/runtimes/RuntimePickerNotebook.js +26 -27
- package/lib/components/runtimes/RuntimeSimplePicker.d.ts +5 -5
- package/lib/components/runtimes/RuntimeSimplePicker.js +8 -7
- package/lib/components/subnav/SubNav.d.ts +1 -1
- package/lib/components/text-reveal/TextRevealAnimation.d.ts +1 -1
- package/lib/hooks/useToast.js +2 -2
- package/lib/state/substates/RuntimesState.d.ts +0 -9
- package/lib/state/substates/RuntimesState.js +0 -3
- package/lib/theme/DatalayerThemeProvider.d.ts +1 -9
- package/lib/theme/DatalayerThemeProvider.js +4 -60
- package/lib/theme/Palette.d.ts +0 -1
- package/lib/theme/Palette.js +0 -12
- package/package.json +2 -2
- package/lib/components/primer/Helper.d.ts +0 -32
- package/lib/components/primer/Helper.js +0 -21
- package/lib/components/primer/Portals.d.ts +0 -9
- package/lib/components/primer/Portals.js +0 -26
- package/lib/components/primer/Styles.d.ts +0 -2
- package/lib/components/primer/Styles.js +0 -11
- package/lib/components/primer/index.d.ts +0 -2
- package/lib/components/primer/index.js +0 -6
|
@@ -11,6 +11,7 @@ import { Widget } from '@lumino/widgets';
|
|
|
11
11
|
import { FocusKeys } from '@primer/behaviors';
|
|
12
12
|
import { Checkbox, FormControl, useFocusZone } from '@primer/react';
|
|
13
13
|
import { Dialog as PrimerDialog, } from '@primer/react/experimental';
|
|
14
|
+
import { JupyterReactTheme } from '@datalayer/jupyter-react';
|
|
14
15
|
function DialogFooter(props) {
|
|
15
16
|
const { checkbox, footerButtons, setChecked } = props;
|
|
16
17
|
const [checked, setLocalChecked] = useState();
|
|
@@ -58,28 +59,28 @@ export class JupyterDialog extends ReactWidget {
|
|
|
58
59
|
}) }));
|
|
59
60
|
_renderFooter = (props) => (_jsx(DialogFooter, { ...props, checkbox: this.checkbox, setChecked: this.setChecked }));
|
|
60
61
|
render() {
|
|
61
|
-
return (_jsx(PrimerDialog, { sx: {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
62
|
+
return (_jsx(JupyterReactTheme, { children: _jsx(PrimerDialog, { sx: {
|
|
63
|
+
color: 'var(--fgColor-default)',
|
|
64
|
+
backgroundColor: 'var(--bgColor-default)',
|
|
65
|
+
fontFamily: 'var(--fontStack-system)',
|
|
66
|
+
fontSize: 'var(--text-body-size-medium)',
|
|
67
|
+
lineHeight: 'var(--text-body-lineHeight-medium)',
|
|
68
|
+
}, onClose: this.close, footerButtons: this.buttons.map((but, idx) => {
|
|
69
|
+
const footerButton = {
|
|
70
|
+
buttonType: but.displayType === 'default'
|
|
71
|
+
? but.accept
|
|
72
|
+
? 'primary'
|
|
73
|
+
: 'default'
|
|
74
|
+
: 'danger',
|
|
75
|
+
onClick: () => {
|
|
76
|
+
this.handleButton(idx);
|
|
77
|
+
},
|
|
78
|
+
content: but.label,
|
|
79
|
+
'aria-label': but.ariaLabel,
|
|
80
|
+
autoFocus: but.accept,
|
|
81
|
+
};
|
|
82
|
+
return footerButton;
|
|
83
|
+
}), renderBody: this._renderBody, renderFooter: this._renderFooter, title: this.dialogTitle }) }));
|
|
83
84
|
}
|
|
84
85
|
/**
|
|
85
86
|
* Launch the dialog as a modal window.
|
|
@@ -7,7 +7,7 @@ import { CircleCurrentColorIcon, CircleGreenIcon, CircleOrangeIcon, } from '@dat
|
|
|
7
7
|
import { Text } from '@primer/react';
|
|
8
8
|
import { Box } from '@datalayer/primer-addons';
|
|
9
9
|
import { Sparklines, SparklinesBars, SparklinesLine, SparklinesReferenceLine, } from 'react-sparklines';
|
|
10
|
-
import {
|
|
10
|
+
import { JupyterReactTheme } from '@datalayer/jupyter-react';
|
|
11
11
|
function boxMullerRandom() {
|
|
12
12
|
let phase = false;
|
|
13
13
|
let x1;
|
|
@@ -34,6 +34,6 @@ function randomData(n = 30) {
|
|
|
34
34
|
const SAMPLE_DATA_30 = randomData(30);
|
|
35
35
|
const SAMPLE_DATA_100 = randomData(100);
|
|
36
36
|
export const JupyterNotebookToolbar = () => {
|
|
37
|
-
return (_jsx(
|
|
37
|
+
return (_jsx(JupyterReactTheme, { children: _jsxs(Box, { display: "flex", m: 5, children: [_jsxs(Box, { ml: 3, children: [_jsx(Box, { mb: 3, children: _jsx(Text, { children: "Notebook Kernel: python3" }) }), _jsxs(Box, { display: "flex", children: [_jsx(Box, { width: 100, height: 100, children: _jsxs(Sparklines, { data: SAMPLE_DATA_30, children: [_jsx(SparklinesLine, { color: "#fa7e17" }), _jsx(SparklinesReferenceLine, { type: "mean" })] }) }), _jsx(Box, { width: 100, height: 100, ml: 3, children: _jsxs(Sparklines, { data: SAMPLE_DATA_100, children: [_jsx(SparklinesBars, { style: { fill: '#41c3f9', fillOpacity: '.25' } }), _jsx(SparklinesLine, { style: { stroke: '#41c3f9', fill: 'none' } })] }) })] })] }), _jsxs(Box, { ml: 6, children: [_jsx(Box, { mb: 3, children: _jsx(Text, { children: "Running Cells" }) }), _jsxs(Box, { display: "flex", children: [_jsx(Box, { children: _jsx(CircleGreenIcon, {}) }), _jsx(Box, { children: _jsx(CircleCurrentColorIcon, { style: { color: 'white' } }) }), _jsx(Box, { children: _jsx(CircleCurrentColorIcon, { style: { color: 'white' } }) }), _jsx(Box, { children: _jsx(CircleOrangeIcon, {}) }), _jsx(Box, { children: _jsx(CircleGreenIcon, {}) }), _jsx(Box, { children: _jsx(CircleCurrentColorIcon, { style: { color: 'white' } }) })] })] }), _jsx(Box, { ml: 6, children: _jsx(Box, { mb: 3, children: _jsx(Text, { children: "Credit: 12/100" }) }) })] }) }));
|
|
38
38
|
};
|
|
39
39
|
export default JupyterNotebookToolbar;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ITranslator } from '@jupyterlab/translation';
|
|
2
2
|
/**
|
|
3
|
-
* {@link
|
|
3
|
+
* {@link RuntimeCellVariables} properties
|
|
4
4
|
*/
|
|
5
|
-
interface
|
|
5
|
+
interface IRuntimeCellVariablesProps {
|
|
6
6
|
/**
|
|
7
7
|
* Variable names to be imported
|
|
8
8
|
*/
|
|
@@ -33,7 +33,7 @@ interface IKernelCellVariablesProps {
|
|
|
33
33
|
translator?: ITranslator;
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
|
-
*
|
|
36
|
+
* Runtime Cell Variables Picker.
|
|
37
37
|
*/
|
|
38
|
-
export declare function
|
|
39
|
-
export default
|
|
38
|
+
export declare function RuntimeCellVariables(props: IRuntimeCellVariablesProps): JSX.Element;
|
|
39
|
+
export default RuntimeCellVariables;
|
|
@@ -9,10 +9,10 @@ import { JSONExt } from '@lumino/coreutils';
|
|
|
9
9
|
import { Autocomplete, FormControl, TextInputWithTokens } from '@primer/react';
|
|
10
10
|
import { Box } from '@datalayer/primer-addons';
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* Runtime Cell Variables Picker.
|
|
13
13
|
*/
|
|
14
|
-
export function
|
|
15
|
-
const { getInputOptions,
|
|
14
|
+
export function RuntimeCellVariables(props) {
|
|
15
|
+
const { getInputOptions, getOutputOptions, inputs, output, setInputs, setOutput, translator, } = props;
|
|
16
16
|
const trans = useMemo(() => (translator ?? nullTranslator).load('jupyterlab'), [translator]);
|
|
17
17
|
const inputForOutputRef = useRef(null);
|
|
18
18
|
const [willSaveOutput, setWillSaveOutput] = useState(false);
|
|
@@ -169,4 +169,4 @@ export function KernelCellVariables(props) {
|
|
|
169
169
|
.filter(item => item.selected)
|
|
170
170
|
.map(item => item.id), onSelectedChange: onSelectedInputsChange, "aria-labelledby": "cell-input-variables", selectionVariant: "multiple", emptyStateText: trans.__('No available variables.'), loading: inputLoading }) })] })] }), _jsxs(FormControl, { children: [_jsx(FormControl.Label, { id: "cell-output-variables", children: trans.__('Output') }), _jsxs(Autocomplete, { children: [_jsx(Autocomplete.Input, { ref: inputForOutputRef, value: output, onChange: onOutputChange }), _jsx(Autocomplete.Overlay, { children: _jsx(Autocomplete.Menu, { items: outputsState ?? [], selectedItemIds: output ? [output] : [], "aria-labelledby": "cell-output-variables", loading: getOutputOptions && !outputsState, emptyStateText: trans.__('Not among the available variables.'), onOpenChange: handleOutputMenuOpenChange }) })] })] })] }));
|
|
171
171
|
}
|
|
172
|
-
export default
|
|
172
|
+
export default RuntimeCellVariables;
|
|
@@ -9,7 +9,7 @@ import { nullTranslator } from '@jupyterlab/translation';
|
|
|
9
9
|
import { JSONExt } from '@lumino/coreutils';
|
|
10
10
|
import { KernelExecutor } from '@datalayer/jupyter-react';
|
|
11
11
|
import { RuntimeSnippetsFacade } from '../../api';
|
|
12
|
-
import {
|
|
12
|
+
import { RuntimeCellVariables } from './RuntimeCellVariables';
|
|
13
13
|
/**
|
|
14
14
|
* Dialog to define the runtime cell variables to transfer
|
|
15
15
|
*/
|
|
@@ -96,6 +96,6 @@ export function RuntimeCellVariablesDialog(props) {
|
|
|
96
96
|
onClick: setVariables,
|
|
97
97
|
autoFocus: true,
|
|
98
98
|
},
|
|
99
|
-
], children: _jsx(
|
|
99
|
+
], children: _jsx(RuntimeCellVariables, { inputs: inputs, getInputOptions: sessionContext ? getInputCandidates : undefined, setInputs: setInputs, output: output ?? undefined, getOutputOptions: getOutputCandidates, setOutput: setOutput, translator: translator }) }));
|
|
100
100
|
}
|
|
101
101
|
export default RuntimeCellVariablesDialog;
|
|
@@ -2,9 +2,9 @@ import type { IMarkdownParser, IRenderMime } from '@jupyterlab/rendermime';
|
|
|
2
2
|
import type { IRemoteServicesManager } from '../../api';
|
|
3
3
|
import type { IRuntimeSnapshot, IRuntimeDesc } from '../../models';
|
|
4
4
|
/**
|
|
5
|
-
* {@link
|
|
5
|
+
* {@link RuntimeLauncherDialog} properties.
|
|
6
6
|
*/
|
|
7
|
-
export interface
|
|
7
|
+
export interface IRuntimeLauncherDialogProps {
|
|
8
8
|
/**
|
|
9
9
|
* Dialog title
|
|
10
10
|
*/
|
|
@@ -28,7 +28,7 @@ export interface IKernelLauncherDialogProps {
|
|
|
28
28
|
*
|
|
29
29
|
* Default: `true`
|
|
30
30
|
*/
|
|
31
|
-
|
|
31
|
+
startRuntime?: boolean | 'with-example' | 'defer';
|
|
32
32
|
/**
|
|
33
33
|
* Markdown parser
|
|
34
34
|
*/
|
|
@@ -48,6 +48,6 @@ export interface IKernelLauncherDialogProps {
|
|
|
48
48
|
upgradeSubscription?: string;
|
|
49
49
|
}
|
|
50
50
|
/**
|
|
51
|
-
* Start
|
|
51
|
+
* Start Runtime Launcher Dialog.
|
|
52
52
|
*/
|
|
53
|
-
export declare function
|
|
53
|
+
export declare function RuntimeLauncherDialog(props: IRuntimeLauncherDialogProps): JSX.Element;
|
|
@@ -9,10 +9,11 @@ import { Button, FormControl, Select, Spinner, Text, TextInput, ToggleSwitch, To
|
|
|
9
9
|
import { Dialog } from '@primer/react/experimental';
|
|
10
10
|
import { AlertIcon } from '@primer/octicons-react';
|
|
11
11
|
import { Box } from '@datalayer/primer-addons';
|
|
12
|
+
import { useJupyterReactStore } from '@datalayer/jupyter-react';
|
|
12
13
|
import { USAGE_ROUTE } from '../../routes';
|
|
13
14
|
import { useNavigate } from '../../hooks';
|
|
14
15
|
import { NO_RUNTIME_AVAILABLE_LABEL } from '../../i18n';
|
|
15
|
-
import { iamStore, useCoreStore, useIAMStore
|
|
16
|
+
import { iamStore, useCoreStore, useIAMStore } from '../../state';
|
|
16
17
|
import { createNotebook, sleep } from '../../utils';
|
|
17
18
|
import { Markdown } from '../display';
|
|
18
19
|
import { Timer } from '../progress';
|
|
@@ -27,11 +28,11 @@ const NOT_AVAILABLE_INIT_RETRY = 10_000;
|
|
|
27
28
|
*/
|
|
28
29
|
const NOT_AVAILABLE_RETRIES = 5;
|
|
29
30
|
/**
|
|
30
|
-
* Start
|
|
31
|
+
* Start Runtime Launcher Dialog.
|
|
31
32
|
*/
|
|
32
|
-
export function
|
|
33
|
-
const { dialogTitle, kernelSnapshot, manager, onSubmit, markdownParser, sanitizer, upgradeSubscription,
|
|
34
|
-
const hasExample =
|
|
33
|
+
export function RuntimeLauncherDialog(props) {
|
|
34
|
+
const { dialogTitle, kernelSnapshot, manager, onSubmit, markdownParser, sanitizer, upgradeSubscription, startRuntime = true, } = props;
|
|
35
|
+
const hasExample = startRuntime === 'with-example';
|
|
35
36
|
const user = iamStore.getState().user;
|
|
36
37
|
const environments = manager.environments.get();
|
|
37
38
|
const { configuration } = useCoreStore();
|
|
@@ -45,7 +46,7 @@ export function KernelLauncherDialog(props) {
|
|
|
45
46
|
// TODO when would this component be shown outside of a react-router? navigation is only available within a react-router.
|
|
46
47
|
console.warn(reason);
|
|
47
48
|
}
|
|
48
|
-
const { jupyterLabAdapter } =
|
|
49
|
+
const { jupyterLabAdapter } = useJupyterReactStore();
|
|
49
50
|
const [selection, setSelection] = useState((kernelSnapshot?.environment || environments[0]?.name) ?? '');
|
|
50
51
|
const [timeLimit, setTimeLimit] = useState(Math.min(credits?.available ?? 0, 10));
|
|
51
52
|
const [runtimeName, setRuntimeName] = useState(environments[0]?.kernel?.givenNameTemplate || environments[0]?.title || '');
|
|
@@ -58,16 +59,16 @@ export function KernelLauncherDialog(props) {
|
|
|
58
59
|
const [flashLevel, setFlashLevel] = useState('danger');
|
|
59
60
|
const isMounted = useIsMounted();
|
|
60
61
|
useEffect(() => {
|
|
61
|
-
if (
|
|
62
|
+
if (startRuntime) {
|
|
62
63
|
refreshCredits();
|
|
63
64
|
}
|
|
64
|
-
}, [
|
|
65
|
+
}, [startRuntime]);
|
|
65
66
|
const spec = useMemo(() => environments.find(spec => spec.name === selection), [environments, selection]);
|
|
66
67
|
const description = spec?.description ?? '';
|
|
67
68
|
const burningRate = spec?.burning_rate ?? 1;
|
|
68
69
|
const creditsToMinutes = 1.0 / burningRate / 60.0;
|
|
69
70
|
const max = Math.floor((credits?.available ?? 0) * creditsToMinutes);
|
|
70
|
-
const outOfCredits =
|
|
71
|
+
const outOfCredits = startRuntime && (!credits?.available || max < Number.EPSILON);
|
|
71
72
|
const handleSelectionChange = useCallback((e) => {
|
|
72
73
|
const selection = e.target.value;
|
|
73
74
|
setSelection(selection);
|
|
@@ -76,7 +77,7 @@ export function KernelLauncherDialog(props) {
|
|
|
76
77
|
setRuntimeName(spec?.kernel?.givenNameTemplate || spec?.title || '');
|
|
77
78
|
}
|
|
78
79
|
}, [setSelection, hasCustomRuntimeName]);
|
|
79
|
-
const
|
|
80
|
+
const handleSubmitRuntime = useCallback(async () => {
|
|
80
81
|
if (selection) {
|
|
81
82
|
setError(undefined);
|
|
82
83
|
setWaitingForRuntime(true);
|
|
@@ -90,14 +91,14 @@ export function KernelLauncherDialog(props) {
|
|
|
90
91
|
const creditsLimit = Math.min(timeLimit, MAXIMAL_RUNTIME_TIME_RESERVATION_MINUTES) /
|
|
91
92
|
creditsToMinutes;
|
|
92
93
|
desc.params = {};
|
|
93
|
-
if (
|
|
94
|
+
if (startRuntime === 'defer') {
|
|
94
95
|
desc.params['creditsLimit'] = creditsLimit;
|
|
95
96
|
}
|
|
96
97
|
if (userStorage) {
|
|
97
98
|
desc.params['capabilities'] = ['user_storage'];
|
|
98
99
|
}
|
|
99
100
|
let success = true;
|
|
100
|
-
if (
|
|
101
|
+
if (startRuntime && startRuntime !== 'defer') {
|
|
101
102
|
success = false;
|
|
102
103
|
let availableTrial = 1;
|
|
103
104
|
let retryDelay = NOT_AVAILABLE_INIT_RETRY;
|
|
@@ -182,7 +183,7 @@ export function KernelLauncherDialog(props) {
|
|
|
182
183
|
}, [
|
|
183
184
|
manager,
|
|
184
185
|
selection,
|
|
185
|
-
|
|
186
|
+
startRuntime,
|
|
186
187
|
runtimeName,
|
|
187
188
|
onSubmit,
|
|
188
189
|
userStorage,
|
|
@@ -223,8 +224,8 @@ export function KernelLauncherDialog(props) {
|
|
|
223
224
|
},
|
|
224
225
|
{
|
|
225
226
|
buttonType: 'primary',
|
|
226
|
-
onClick:
|
|
227
|
-
content: waitingForRuntime ? (_jsx(Spinner, { size: "small" })) : (
|
|
227
|
+
onClick: handleSubmitRuntime,
|
|
228
|
+
content: waitingForRuntime ? (_jsx(Spinner, { size: "small" })) : (startRuntime ?? true) ? ('Launch') : ('Assign from the Environment'),
|
|
228
229
|
disabled: waitingForRuntime || outOfCredits || timeLimit < Number.EPSILON,
|
|
229
230
|
autoFocus: true,
|
|
230
231
|
},
|
|
@@ -234,9 +235,9 @@ export function KernelLauncherDialog(props) {
|
|
|
234
235
|
}
|
|
235
236
|
if (event.key === 'Enter') {
|
|
236
237
|
event.preventDefault();
|
|
237
|
-
|
|
238
|
+
handleSubmitRuntime();
|
|
238
239
|
}
|
|
239
|
-
}, children: [_jsxs(FormControl, { disabled: !!kernelSnapshot?.environment || environments.length === 0, children: [_jsx(FormControl.Label, { children: "Environment" }), _jsx(Select, { name: "environment", disabled: !!kernelSnapshot?.environment || environments.length === 0, value: selection, onChange: handleSelectionChange, block: true, children: environments.map(spec => (_jsxs(Select.Option, { value: spec.name, children: [spec.name, spec.title && (_jsxs(_Fragment, { children: [' - ', spec.title] }))] }, spec.name))) }), _jsx(FormControl.Caption, { children: _jsx(_Fragment, { children: markdownParser ? (_jsx(Box, { sx: { img: { maxWidth: '100%' } }, children: _jsx(Markdown, { text: description, markdownParser: markdownParser, sanitizer: sanitizer }) })) : (description) }) })] }),
|
|
240
|
+
}, children: [_jsxs(FormControl, { disabled: !!kernelSnapshot?.environment || environments.length === 0, children: [_jsx(FormControl.Label, { children: "Environment" }), _jsx(Select, { name: "environment", disabled: !!kernelSnapshot?.environment || environments.length === 0, value: selection, onChange: handleSelectionChange, block: true, children: environments.map(spec => (_jsxs(Select.Option, { value: spec.name, children: [spec.name, spec.title && (_jsxs(_Fragment, { children: [' - ', spec.title] }))] }, spec.name))) }), _jsx(FormControl.Caption, { children: _jsx(_Fragment, { children: markdownParser ? (_jsx(Box, { sx: { img: { maxWidth: '100%' } }, children: _jsx(Markdown, { text: description, markdownParser: markdownParser, sanitizer: sanitizer }) })) : (description) }) })] }), startRuntime && (_jsx(RuntimeReservationControl, { addCredits: navigate
|
|
240
241
|
? () => {
|
|
241
242
|
navigate(USAGE_ROUTE);
|
|
242
243
|
}
|
|
@@ -27,7 +27,7 @@ export interface IRuntimePickerBaseProps {
|
|
|
27
27
|
/**
|
|
28
28
|
* Runtime description passing this filter function will be displayed.
|
|
29
29
|
*/
|
|
30
|
-
|
|
30
|
+
filterRuntime?: (desc: IRuntimeDesc) => boolean;
|
|
31
31
|
/**
|
|
32
32
|
* Session preference.
|
|
33
33
|
*/
|
|
@@ -22,8 +22,8 @@ const RUNTIME_DISPLAY_NAME_MAX_LENGTH = 25;
|
|
|
22
22
|
* Base Kernel Picker component.
|
|
23
23
|
*/
|
|
24
24
|
export function RuntimePickerBase(props) {
|
|
25
|
-
const { disabled, display,
|
|
26
|
-
const [
|
|
25
|
+
const { disabled, display, filterRuntime, multiServiceManager, postActions, preActions, preference, runtimeDesc, sessionContext, setRuntimeDesc, translator, variant, } = props;
|
|
26
|
+
const [groupedRuntimeDescs, _] = useState(getGroupedRuntimeDescs(multiServiceManager, preference?.id, translator, filterRuntime, variant));
|
|
27
27
|
const trans = useMemo(() => (translator ?? nullTranslator).load('jupyterlab'), [translator]);
|
|
28
28
|
const [defaultSet, setDefaultSet] = useState(false);
|
|
29
29
|
// Trick because overflow is an unknown prop of ActionMenu.Overlay.
|
|
@@ -34,36 +34,36 @@ export function RuntimePickerBase(props) {
|
|
|
34
34
|
/*
|
|
35
35
|
// TODO this effect generates refresh of the react components which discards any change in the selection.
|
|
36
36
|
useEffect(() => {
|
|
37
|
-
const
|
|
37
|
+
const updateGroupedRuntimeDescs = () => {
|
|
38
38
|
setGroupedKernelDescs(getGroupedRuntimeDescs(multiServiceManager, preference?.id, translator, filterKernel, variant));
|
|
39
39
|
};
|
|
40
|
-
multiServiceManager.browser?.kernels.runningChanged.connect(
|
|
41
|
-
multiServiceManager.browser?.kernelspecs.specsChanged.connect(
|
|
42
|
-
multiServiceManager.browser?.sessions.runningChanged.connect(
|
|
43
|
-
multiServiceManager.local.kernels.runningChanged.connect(
|
|
44
|
-
multiServiceManager.local.kernelspecs.specsChanged.connect(
|
|
45
|
-
multiServiceManager.local.sessions.runningChanged.connect(
|
|
46
|
-
multiServiceManager.remote?.kernels.changed.connect(
|
|
47
|
-
multiServiceManager.remote?.environments.changed.connect(
|
|
40
|
+
multiServiceManager.browser?.kernels.runningChanged.connect(updateGroupedRuntimeDescs);
|
|
41
|
+
multiServiceManager.browser?.kernelspecs.specsChanged.connect(updateGroupedRuntimeDescs);
|
|
42
|
+
multiServiceManager.browser?.sessions.runningChanged.connect(updateGroupedRuntimeDescs);
|
|
43
|
+
multiServiceManager.local.kernels.runningChanged.connect(updateGroupedRuntimeDescs);
|
|
44
|
+
multiServiceManager.local.kernelspecs.specsChanged.connect(updateGroupedRuntimeDescs);
|
|
45
|
+
multiServiceManager.local.sessions.runningChanged.connect(updateGroupedRuntimeDescs);
|
|
46
|
+
multiServiceManager.remote?.kernels.changed.connect(updateGroupedRuntimeDescs);
|
|
47
|
+
multiServiceManager.remote?.environments.changed.connect(updateGroupedRuntimeDescs);
|
|
48
48
|
// multiServiceManager.remote?.sessions.runningChanged.connect(updateOptions);
|
|
49
49
|
return () => {
|
|
50
|
-
multiServiceManager.browser?.kernels.runningChanged.disconnect(
|
|
51
|
-
multiServiceManager.browser?.kernelspecs.specsChanged.disconnect(
|
|
52
|
-
multiServiceManager.browser?.sessions.runningChanged.disconnect(
|
|
53
|
-
multiServiceManager.local.kernels.runningChanged.disconnect(
|
|
54
|
-
multiServiceManager.local.kernelspecs.specsChanged.disconnect(
|
|
55
|
-
multiServiceManager.local.sessions.runningChanged.disconnect(
|
|
56
|
-
multiServiceManager.remote?.kernels.changed.disconnect(
|
|
57
|
-
multiServiceManager.remote?.environments.changed.disconnect(
|
|
50
|
+
multiServiceManager.browser?.kernels.runningChanged.disconnect(updateGroupedRuntimeDescs);
|
|
51
|
+
multiServiceManager.browser?.kernelspecs.specsChanged.disconnect(updateGroupedRuntimeDescs);
|
|
52
|
+
multiServiceManager.browser?.sessions.runningChanged.disconnect(updateGroupedRuntimeDescs);
|
|
53
|
+
multiServiceManager.local.kernels.runningChanged.disconnect(updateGroupedRuntimeDescs);
|
|
54
|
+
multiServiceManager.local.kernelspecs.specsChanged.disconnect(updateGroupedRuntimeDescs);
|
|
55
|
+
multiServiceManager.local.sessions.runningChanged.disconnect(updateGroupedRuntimeDescs);
|
|
56
|
+
multiServiceManager.remote?.kernels.changed.disconnect(updateGroupedRuntimeDescs);
|
|
57
|
+
multiServiceManager.remote?.environments.changed.disconnect(updateGroupedRuntimeDescs);
|
|
58
58
|
// multiServiceManager.remote?.sessions.runningChanged.disconnect(updateOptions);
|
|
59
59
|
};
|
|
60
60
|
}, [multiServiceManager, preference, translator, filterKernel, variant]);
|
|
61
61
|
*/
|
|
62
62
|
useEffect(() => {
|
|
63
|
-
if (sessionContext &&
|
|
63
|
+
if (sessionContext && groupedRuntimeDescs) {
|
|
64
64
|
const kernelId = sessionContext.session?.kernel?.id;
|
|
65
65
|
if (kernelId) {
|
|
66
|
-
Object.entries(
|
|
66
|
+
Object.entries(groupedRuntimeDescs).forEach(([group, runtimeDescs]) => {
|
|
67
67
|
runtimeDescs.forEach(runtimeDesc => {
|
|
68
68
|
if (runtimeDesc.kernelId === kernelId) {
|
|
69
69
|
setRuntimeDesc(runtimeDesc);
|
|
@@ -73,7 +73,7 @@ export function RuntimePickerBase(props) {
|
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
setDefaultSet(true);
|
|
76
|
-
}, [
|
|
76
|
+
}, [groupedRuntimeDescs]);
|
|
77
77
|
// For cell using submenu instead of group would be nice unfortunately the feature
|
|
78
78
|
// is not yet implemented in the component there has been a not-great demo story.
|
|
79
79
|
// https://github.com/primer/react/pull/3585
|
|
@@ -81,11 +81,11 @@ export function RuntimePickerBase(props) {
|
|
|
81
81
|
/*
|
|
82
82
|
* Section for Menu display.
|
|
83
83
|
*/
|
|
84
|
-
_jsxs(ActionMenu, { children: [variant === 'cell' ? (_jsx(ActionMenu.Anchor, { children: _jsx(IconButton, { disabled: disabled ||
|
|
84
|
+
_jsxs(ActionMenu, { children: [variant === 'cell' ? (_jsx(ActionMenu.Anchor, { children: _jsx(IconButton, { disabled: disabled || groupedRuntimeDescs === null,
|
|
85
85
|
// icon={() => <kernelIcon.react className="dla-Cell-runtime-icon" tag={'span'} />}
|
|
86
|
-
icon: () => (_jsx("span", { className: "dla-Cell-runtime-icon", children: _jsx(CpuIcon, {}) })), "aria-label": trans.__('Assign a Runtime to the Cell.'), title: trans.__('Assign a Runtime to the Cell.'), size: "small", variant: "invisible" }) })) : (_jsxs(ActionMenu.Button, { variant: "default", disabled: disabled ||
|
|
86
|
+
icon: () => (_jsx("span", { className: "dla-Cell-runtime-icon", children: _jsx(CpuIcon, {}) })), "aria-label": trans.__('Assign a Runtime to the Cell.'), title: trans.__('Assign a Runtime to the Cell.'), size: "small", variant: "invisible" }) })) : (_jsxs(ActionMenu.Button, { variant: "default", disabled: disabled || groupedRuntimeDescs === null, children: [_jsx(Text, { fontWeight: 'bold', children: trans.__('Runtime:') }), ' ' + (runtimeDesc?.displayName ?? trans.__('No Runtime'))] })), _jsx(ActionMenu.Overlay, { ...overlayProps, width: "medium", sx: { overflowY: 'auto' }, side: variant === 'cell' ? 'outside-left' : 'outside-right', children: _jsxs(ActionList, { selectionVariant: "single", children: [variant === 'cell' && (_jsxs(ActionList.Item, { selected: runtimeDesc === undefined, onSelect: () => {
|
|
87
87
|
setRuntimeDesc(undefined);
|
|
88
|
-
}, children: [preference?.location && (_jsx(ActionList.LeadingVisual, { children: preference.location === 'local' ? (_jsx(LaptopSimpleIcon, {})) : preference.location === 'browser' ? (_jsx(BrowserIcon, {})) : (_jsx(CloudUploadIcon, {})) })), trans.__('Assign the Notebook Runtime')] }, 'null')), !!preActions && preActions, Object.entries(
|
|
88
|
+
}, children: [preference?.location && (_jsx(ActionList.LeadingVisual, { children: preference.location === 'local' ? (_jsx(LaptopSimpleIcon, {})) : preference.location === 'browser' ? (_jsx(BrowserIcon, {})) : (_jsx(CloudUploadIcon, {})) })), trans.__('Assign the Notebook Runtime')] }, 'null')), !!preActions && preActions, Object.entries(groupedRuntimeDescs ?? {}).map(([group, runtimeDescs]) => (_jsxs(ActionList.Group, { children: [_jsx(ActionList.GroupHeading, { children: group }), runtimeDescs.map(runtimeDesc => {
|
|
89
89
|
const annotation = runtimeDesc.podName
|
|
90
90
|
? ` - ${runtimeDesc.podName.split('-', 2).reverse()[0]}`
|
|
91
91
|
: runtimeDesc.kernelId
|
|
@@ -107,7 +107,7 @@ export function RuntimePickerBase(props) {
|
|
|
107
107
|
/*
|
|
108
108
|
* Section for Radio display.
|
|
109
109
|
*/
|
|
110
|
-
_jsxs(_Fragment, { children: [defaultSet && (_jsx(RadioGroup, { name: "kernel-options", "aria-labelledby": "kernel-options", children: Object.entries(
|
|
110
|
+
_jsxs(_Fragment, { children: [defaultSet && (_jsx(RadioGroup, { name: "kernel-options", "aria-labelledby": "kernel-options", children: Object.entries(groupedRuntimeDescs ?? {}).map(([group, runtimeDescs]) => (_jsxs(Box, { children: [_jsx(Box, { as: "h4", style: { marginTop: 0 }, children: group }), runtimeDescs.map(k => {
|
|
111
111
|
return (_jsxs(Box, { title: k.name, children: [_jsxs(FormControl, { children: [_jsx(Radio, { value: k.kernelId, onChange: () => {
|
|
112
112
|
setRuntimeDesc(k);
|
|
113
113
|
}, checked: (k.location === k?.location ||
|
|
@@ -28,7 +28,7 @@ export type IRuntimePickerCellProps = Pick<IRuntimePickerBaseProps, 'multiServic
|
|
|
28
28
|
sanitizer?: IRenderMime.ISanitizer;
|
|
29
29
|
};
|
|
30
30
|
/**
|
|
31
|
-
*
|
|
31
|
+
* Runtime picker component for a cell.
|
|
32
32
|
*/
|
|
33
33
|
export declare function RuntimePickerCell(props: IRuntimePickerCellProps): JSX.Element;
|
|
34
34
|
export default RuntimePickerCell;
|
|
@@ -7,22 +7,22 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
|
7
7
|
import { nullTranslator } from '@jupyterlab/translation';
|
|
8
8
|
import { ActionList } from '@primer/react';
|
|
9
9
|
import { CloudUploadIcon } from '@datalayer/icons-react';
|
|
10
|
-
import { ExternalTokenSilentLogin } from '../../components/iam';
|
|
11
10
|
import { useCoreStore, useIAMStore } from '../../state';
|
|
12
11
|
import { isRuntimeRemote, RuntimeSnippetsFacade } from '../../api';
|
|
12
|
+
import { ExternalTokenSilentLogin } from '../../components/iam';
|
|
13
13
|
import { SnippetDialog } from './../snippets/SnippetDialog';
|
|
14
|
-
import {
|
|
14
|
+
import { RuntimeLauncherDialog } from './RuntimeLauncherDialog';
|
|
15
15
|
import { RuntimePickerBase } from './RuntimePickerBase';
|
|
16
16
|
import { RuntimeCellVariablesDialog } from './RuntimeCellVariablesDialog';
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
18
|
+
* Runtime picker component for a cell.
|
|
19
19
|
*/
|
|
20
20
|
export function RuntimePickerCell(props) {
|
|
21
21
|
const { logIn, markdownParser, model, preference, sanitizer, multiServiceManager, sessionContext, translator, } = props;
|
|
22
22
|
const { token } = useIAMStore();
|
|
23
23
|
const { configuration } = useCoreStore();
|
|
24
24
|
const [isForeign, setIsForeign] = useState(false);
|
|
25
|
-
const [
|
|
25
|
+
const [hasCellRuntime, setHasCellRuntime] = useState(false);
|
|
26
26
|
const [isKernelDialogOpen, setIsKernelDialogOpen] = useState(false);
|
|
27
27
|
const [isVariableDialogOpen, setIsVariableDialogOpen] = useState(false);
|
|
28
28
|
const [language, setLanguage] = useState('');
|
|
@@ -32,14 +32,14 @@ export function RuntimePickerCell(props) {
|
|
|
32
32
|
useEffect(() => {
|
|
33
33
|
const updateState = (model) => {
|
|
34
34
|
const datalayerMeta = model.getMetadata('datalayer') ?? {};
|
|
35
|
-
const
|
|
36
|
-
setIsForeign(!!
|
|
37
|
-
|
|
35
|
+
const runtime = datalayerMeta.kernel;
|
|
36
|
+
setIsForeign(!!runtime);
|
|
37
|
+
setHasCellRuntime(runtime?.params?.notebook === false);
|
|
38
38
|
const newSnippets = new Array();
|
|
39
|
-
if (
|
|
39
|
+
if (runtime) {
|
|
40
40
|
const spec = multiServiceManager.remote?.environments
|
|
41
41
|
.get()
|
|
42
|
-
.find(env => env.name ===
|
|
42
|
+
.find(env => env.name === runtime.name);
|
|
43
43
|
setLanguage(spec?.language ?? '');
|
|
44
44
|
if (spec?.snippets) {
|
|
45
45
|
newSnippets.push(...spec.snippets);
|
|
@@ -58,7 +58,7 @@ export function RuntimePickerCell(props) {
|
|
|
58
58
|
isRuntimeRemote(desc.location) &&
|
|
59
59
|
(!preference?.language || desc.language === preference?.language));
|
|
60
60
|
}, [preference]);
|
|
61
|
-
const
|
|
61
|
+
const setSelectedRuntimeDesc = useCallback((kernel) => {
|
|
62
62
|
const datalayerMeta = model.getMetadata('datalayer') ?? {
|
|
63
63
|
kernel: undefined,
|
|
64
64
|
};
|
|
@@ -91,13 +91,13 @@ export function RuntimePickerCell(props) {
|
|
|
91
91
|
...desc.params,
|
|
92
92
|
notebook: false,
|
|
93
93
|
};
|
|
94
|
-
|
|
94
|
+
setSelectedRuntimeDesc(desc);
|
|
95
95
|
}
|
|
96
96
|
setIsKernelDialogOpen(false);
|
|
97
|
-
}, [
|
|
97
|
+
}, [setSelectedRuntimeDesc]);
|
|
98
98
|
const datalayerMeta = model.getMetadata('datalayer') ?? {};
|
|
99
|
-
return (_jsxs(_Fragment, { children: [_jsx(RuntimePickerBase, { display: "menu",
|
|
99
|
+
return (_jsxs(_Fragment, { children: [_jsx(RuntimePickerBase, { display: "menu", filterRuntime: filterKernel, preference: preference, multiServiceManager: multiServiceManager, runtimeDesc: datalayerMeta.kernel ? datalayerMeta.kernel : undefined, setRuntimeDesc: setSelectedRuntimeDesc, variant: 'cell', preActions: _jsxs(ActionList.Item, { disabled: !multiServiceManager.remote, onSelect: setCell, selected: hasCellRuntime, title: !multiServiceManager.remote
|
|
100
100
|
? 'You are not connected with Datalayer.'
|
|
101
|
-
: 'Assign a new temporary Runtime on each Cell execution.', children: [_jsx(ActionList.LeadingVisual, { children: _jsx(CloudUploadIcon, {}) }), trans.__('Assign a Cell Runtime')] }), postActions: token || !logIn ? (_jsxs(_Fragment, { children: [RuntimeSnippetsFacade.supports(preference?.language ?? '') && (_jsx(ActionList.Item, { onSelect: openVariableDialog, disabled: !isForeign, title: trans.__('Define variables to transfer between the document kernel and the cell kernel.'), children: trans.__('Define Cell Variables Transfer') })), !configuration.whiteLabel && (_jsx(ActionList.Item, { onSelect: openSnippetDialog, disabled: snippets.length === 0, title: trans.__('Inject a code snippet at the end of the cell.'), children: trans.__('Inject Code Snippet') }))] })) : (_jsx(ActionList.Item, { onSelect: props.logIn, title: 'Connect to the Runtime provider.', children: _jsx(ExternalTokenSilentLogin, { message: "Connect to the Runtime provider" }) })), translator: translator }), isVariableDialogOpen && (_jsx(RuntimeCellVariablesDialog, { model: model, onClose: closeVariableDialog, preference: preference, sessionContext: sessionContext, translator: translator })), isSnippetDialogOpen && (_jsx(SnippetDialog, { language: language, model: model, snippets: snippets, onClose: closeSnippetDialog, markdownParser: markdownParser, sanitizer: sanitizer })), isKernelDialogOpen && (_jsx(
|
|
101
|
+
: 'Assign a new temporary Runtime on each Cell execution.', children: [_jsx(ActionList.LeadingVisual, { children: _jsx(CloudUploadIcon, {}) }), trans.__('Assign a Cell Runtime')] }), postActions: token || !logIn ? (_jsxs(_Fragment, { children: [RuntimeSnippetsFacade.supports(preference?.language ?? '') && (_jsx(ActionList.Item, { onSelect: openVariableDialog, disabled: !isForeign, title: trans.__('Define variables to transfer between the document kernel and the cell kernel.'), children: trans.__('Define Cell Variables Transfer') })), !configuration.whiteLabel && (_jsx(ActionList.Item, { onSelect: openSnippetDialog, disabled: snippets.length === 0, title: trans.__('Inject a code snippet at the end of the cell.'), children: trans.__('Inject Code Snippet') }))] })) : (_jsx(ActionList.Item, { onSelect: props.logIn, title: 'Connect to the Runtime provider.', children: _jsx(ExternalTokenSilentLogin, { message: "Connect to the Runtime provider" }) })), translator: translator }), isVariableDialogOpen && (_jsx(RuntimeCellVariablesDialog, { model: model, onClose: closeVariableDialog, preference: preference, sessionContext: sessionContext, translator: translator })), isSnippetDialogOpen && (_jsx(SnippetDialog, { language: language, model: model, snippets: snippets, onClose: closeSnippetDialog, markdownParser: markdownParser, sanitizer: sanitizer })), isKernelDialogOpen && (_jsx(RuntimeLauncherDialog, { manager: multiServiceManager.remote, onSubmit: onStartRemote, startRuntime: false, markdownParser: markdownParser, sanitizer: sanitizer }))] }));
|
|
102
102
|
}
|
|
103
103
|
export default RuntimePickerCell;
|
|
@@ -9,7 +9,6 @@ import { Box } from '@datalayer/primer-addons';
|
|
|
9
9
|
import { AlertIcon } from '@primer/octicons-react';
|
|
10
10
|
import { JSONExt } from '@lumino/coreutils';
|
|
11
11
|
import { KernelExecutor } from '@datalayer/jupyter-react';
|
|
12
|
-
import { DatalayerThemeProvider } from '../../theme';
|
|
13
12
|
import { RuntimeSnippetsFacade } from '../../api';
|
|
14
13
|
import { ExternalTokenSilentLogin } from '../../components/iam';
|
|
15
14
|
import { useCoreStore, useIAMStore } from '../../state';
|
|
@@ -138,31 +137,31 @@ export function RuntimePickerNotebook(props) {
|
|
|
138
137
|
const { kernelPreference: { canStart }, } = sessionContext;
|
|
139
138
|
const max = Math.floor((credits?.available ?? 0) / (selectedRuntimeDesc?.burningRate ?? -1) / 60.0);
|
|
140
139
|
const outOfCredits = !credits?.available || max < Number.EPSILON;
|
|
141
|
-
return (
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
140
|
+
return (_jsxs(Box, { as: "form", className: "dla-Runtimes-picker", children: [_jsx(Box, { sx: { padding: 'var(--stack-padding-condensed) 0' }, children: _jsx(RuntimePickerBase, { display: "radio", disabled: canStart === false, preference: {
|
|
141
|
+
id: sessionContext.session?.id,
|
|
142
|
+
kernelDisplayName: sessionContext.kernelPreference.shouldStart
|
|
143
|
+
? sessionContext.kernelDisplayName
|
|
144
|
+
: undefined,
|
|
145
|
+
}, sessionContext: sessionContext, multiServiceManager: multiServiceManager, translator: translator, runtimeDesc: selectedRuntimeDesc, setRuntimeDesc: setRuntimeDesc, postActions: token || !props.logIn ? (
|
|
146
|
+
/*
|
|
147
|
+
<Button
|
|
148
|
+
variant="default"
|
|
149
|
+
onClick={e => {
|
|
150
|
+
e.preventDefault();
|
|
151
|
+
commands.execute(CommandIDs.launchRemoteRuntime);
|
|
152
|
+
close();
|
|
153
|
+
}}
|
|
154
|
+
>
|
|
155
|
+
Launch a New Runtime
|
|
156
|
+
</Button>
|
|
157
|
+
*/
|
|
158
|
+
_jsx(_Fragment, {})) : (_jsx(ActionList.Item, { onSelect: props.logIn, title: 'Connect to Runtime provider.', children: _jsx(ExternalTokenSilentLogin, { message: "Connect to the Runtime provider" }) })) }) }), !selectedRuntimeDesc?.kernelId &&
|
|
159
|
+
selectedRuntimeDesc?.location === 'remote' && (_jsxs(_Fragment, { children: [_jsx(RuntimeReservationControl, { disabled: outOfCredits || selectedRuntimeDesc?.location !== 'remote', label: 'Time reservation', max: max < 0 ? 1 : max, time: timeLimit, onTimeChange: setTimeLimit, error: outOfCredits && max >= 0
|
|
160
|
+
? 'You must add credits to your account.'
|
|
161
|
+
: timeLimit === 0
|
|
162
|
+
? 'You must set a time limit.'
|
|
163
|
+
: undefined, burningRate: selectedRuntimeDesc.burningRate }), !configuration.whiteLabel && (_jsxs(FormControl, { disabled: !!selectedRuntimeDesc?.kernelId ||
|
|
164
|
+
selectedRuntimeDesc?.location !== 'remote', layout: "horizontal", children: [_jsxs(FormControl.Label, { id: "user-storage-picker-label", children: ["User storage", _jsx(Tooltip, { text: "The runtime will be slower to start.", direction: "e", style: { marginLeft: 3 }, children: _jsx(IconButton, { icon: AlertIcon, "aria-label": "", variant: "invisible" }) })] }), _jsx(ToggleSwitch, { disabled: !!selectedRuntimeDesc?.kernelId ||
|
|
165
|
+
selectedRuntimeDesc?.location !== 'remote', checked: userStorage, size: "small", onClick: handleUserStorageChange, "aria-labelledby": "user-storage-picker-label" })] }))] })), canTransferFrom && canTransferTo && (_jsx(RuntimeVariables, { selectedVariables: toTransfer, setSelectVariable: setSelectedVariables, transferVariables: transferVariables, setTransferVariable: setTransferVariable, kernelVariables: kernelVariables, translator: translator }))] }));
|
|
167
166
|
}
|
|
168
167
|
export default RuntimePickerNotebook;
|
|
@@ -2,15 +2,15 @@ import { Session } from '@jupyterlab/services';
|
|
|
2
2
|
import { IRuntimeModel, type IRuntimeDesc } from '../../models';
|
|
3
3
|
export interface IRuntimeAssignOptions {
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Runtime description.
|
|
6
6
|
*/
|
|
7
7
|
runtimeDesc?: IRuntimeDesc;
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* Runtime model to connect to.
|
|
10
10
|
*/
|
|
11
11
|
runtimeModel?: IRuntimeModel;
|
|
12
12
|
/**
|
|
13
|
-
* Whether to transfer the state to the
|
|
13
|
+
* Whether to transfer the state to the runtime model.
|
|
14
14
|
*/
|
|
15
15
|
transferState?: boolean;
|
|
16
16
|
}
|
|
@@ -19,11 +19,11 @@ export interface IRuntimeAssignOptions {
|
|
|
19
19
|
*/
|
|
20
20
|
interface IRuntimeSimplePickerProps {
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
22
|
+
* Runtime assignment callback.
|
|
23
23
|
*/
|
|
24
24
|
assignRuntime: (options: IRuntimeAssignOptions) => Promise<void>;
|
|
25
25
|
/**
|
|
26
|
-
* Connection to the active
|
|
26
|
+
* Connection to the active runtime.
|
|
27
27
|
*/
|
|
28
28
|
sessionConnection?: Session.ISessionConnection;
|
|
29
29
|
}
|
|
@@ -4,14 +4,14 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
4
4
|
* Distributed under the terms of the Modified BSD License.
|
|
5
5
|
*/
|
|
6
6
|
import { useCallback, useEffect, useState } from 'react';
|
|
7
|
-
import { KernelIndicator } from '@datalayer/jupyter-react';
|
|
7
|
+
import { KernelIndicator, useJupyterReactStore, } from '@datalayer/jupyter-react';
|
|
8
8
|
import { ISanitizer } from '@jupyterlab/apputils';
|
|
9
9
|
import { IMarkdownParser } from '@jupyterlab/rendermime';
|
|
10
10
|
import { ActionList, ActionMenu, Box, Button, Tooltip } from '@primer/react';
|
|
11
11
|
import { CloudIcon, EyeIcon, UnfoldIcon } from '@primer/octicons-react';
|
|
12
12
|
import { BrowserIcon, PlusIcon } from '@datalayer/icons-react';
|
|
13
13
|
import { ArtifactIcon } from '../../components/icons';
|
|
14
|
-
import {
|
|
14
|
+
import { RuntimeLauncherDialog } from '../../components/runtimes';
|
|
15
15
|
import { useRuntimesStore } from '../../state';
|
|
16
16
|
/**
|
|
17
17
|
* Cause to open the new runtime dialog.
|
|
@@ -23,11 +23,11 @@ var RuntimeDialogCause;
|
|
|
23
23
|
*/
|
|
24
24
|
RuntimeDialogCause[RuntimeDialogCause["None"] = 0] = "None";
|
|
25
25
|
/**
|
|
26
|
-
* Launch a new
|
|
26
|
+
* Launch a new runtime.
|
|
27
27
|
*/
|
|
28
28
|
RuntimeDialogCause[RuntimeDialogCause["New"] = 1] = "New";
|
|
29
29
|
/**
|
|
30
|
-
* Transfer the state from the current
|
|
30
|
+
* Transfer the state from the current runtime to a new runtime.
|
|
31
31
|
*/
|
|
32
32
|
RuntimeDialogCause[RuntimeDialogCause["Transfer"] = 2] = "Transfer";
|
|
33
33
|
})(RuntimeDialogCause || (RuntimeDialogCause = {}));
|
|
@@ -36,7 +36,8 @@ var RuntimeDialogCause;
|
|
|
36
36
|
*/
|
|
37
37
|
export function RuntimeSimplePicker(props) {
|
|
38
38
|
const { assignRuntime, sessionConnection } = props;
|
|
39
|
-
const { runtimeModels, multiServiceManager
|
|
39
|
+
const { runtimeModels, multiServiceManager } = useRuntimesStore();
|
|
40
|
+
const { jupyterLabAdapter } = useJupyterReactStore();
|
|
40
41
|
const [runtimeLocation, setRuntimeLocation] = useState();
|
|
41
42
|
const [luminoServices, setLuminoServices] = useState({});
|
|
42
43
|
const [dialogCause, setDialogCause] = useState(RuntimeDialogCause.None);
|
|
@@ -145,9 +146,9 @@ export function RuntimeSimplePicker(props) {
|
|
|
145
146
|
}, children: [_jsx(ActionList.LeadingVisual, { children: _jsx(ArtifactIcon, { type: "runtime" }) }), kernelModel.given_name, _jsx(ActionList.Description, { variant: "block", children: kernelModel.environment_name })] }, kernelModel.id));
|
|
146
147
|
})] })), _jsx(ActionList.Divider, {}), _jsxs(ActionList.Group, { children: [_jsxs(ActionList.Item, { selected: false, onSelect: handleLaunchRemoteKernel, children: [_jsx(ActionList.LeadingVisual, { children: _jsx(PlusIcon, {}) }), "Launch a new Runtime\u2026"] }), _jsxs(ActionList.Item, { disabled: runtimeLocation !== 'browser', selected: false, onSelect: () => {
|
|
147
148
|
setDialogCause(RuntimeDialogCause.Transfer);
|
|
148
|
-
}, title: "Transfer the state of the current Runtime to a new Remote Runtime.", children: [_jsx(ActionList.LeadingVisual, { children: _jsx(UnfoldIcon, {}) }), "Transfer state to a new Runtime\u2026"] })] })] }) })] }), multiServiceManager?.remote && dialogCause > 0 && (_jsx(
|
|
149
|
+
}, title: "Transfer the state of the current Runtime to a new Remote Runtime.", children: [_jsx(ActionList.LeadingVisual, { children: _jsx(UnfoldIcon, {}) }), "Transfer state to a new Runtime\u2026"] })] })] }) })] }), multiServiceManager?.remote && dialogCause > 0 && (_jsx(RuntimeLauncherDialog, { dialogTitle: dialogCause === RuntimeDialogCause.Transfer
|
|
149
150
|
? 'Switch to a new Cloud Runtime'
|
|
150
|
-
: undefined, manager: multiServiceManager.remote, onSubmit: handleCloseDialog, markdownParser: luminoServices[IMarkdownParser.name], sanitizer: luminoServices[ISanitizer.name],
|
|
151
|
+
: undefined, manager: multiServiceManager.remote, onSubmit: handleCloseDialog, markdownParser: luminoServices[IMarkdownParser.name], sanitizer: luminoServices[ISanitizer.name], startRuntime: dialogCause === RuntimeDialogCause.Transfer
|
|
151
152
|
? 'defer'
|
|
152
153
|
: dialogCause === RuntimeDialogCause.New }))] }));
|
|
153
154
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { type PropsWithChildren, type ReactNode, type RefObject } from 'react';
|
|
2
2
|
import { ButtonSizes, ButtonVariants, TextProps } from '@primer/react-brand';
|
|
3
|
-
import { BaseProps } from '
|
|
3
|
+
import { BaseProps } from '@datalayer/primer-addons';
|
|
4
4
|
/**
|
|
5
5
|
* Design tokens
|
|
6
6
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { BaseProps } from '
|
|
2
|
+
import { BaseProps } from '@datalayer/primer-addons';
|
|
3
3
|
export type TextRevealAnimationProps = BaseProps<HTMLSpanElement> & Omit<React.HTMLAttributes<HTMLSpanElement>, 'children'> & {
|
|
4
4
|
children: React.ReactChild;
|
|
5
5
|
};
|
package/lib/hooks/useToast.js
CHANGED
|
@@ -7,8 +7,8 @@ import React from 'react';
|
|
|
7
7
|
import { toast } from 'react-toastify';
|
|
8
8
|
import { Notification } from '@jupyterlab/apputils';
|
|
9
9
|
import { Button } from '@primer/react';
|
|
10
|
+
import { JupyterReactTheme } from '@datalayer/jupyter-react';
|
|
10
11
|
import { isInsideJupyterLab } from '../utils';
|
|
11
|
-
import { DatalayerThemeProvider } from '../theme';
|
|
12
12
|
const TOAST_POSITION = 'bottom-right';
|
|
13
13
|
const displayType2Class = {
|
|
14
14
|
accent: 'primary',
|
|
@@ -37,7 +37,7 @@ function ToastButton({ action, closeToast }) {
|
|
|
37
37
|
*/
|
|
38
38
|
function createContent(message, closeHandler, actions) {
|
|
39
39
|
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "jp-toast-message", children: message.split('\n').map((part, index) => (_jsxs(React.Fragment, { children: [index > 0 ? _jsx("br", {}) : null, part] }, `part-${index}`))) }), (actions?.length ?? 0) > 0 && (_jsxs("div", { className: "jp-toast-buttonBar", children: [_jsx("div", { className: "jp-toast-spacer" }), actions.map((action, idx) => {
|
|
40
|
-
return (_jsx(
|
|
40
|
+
return (_jsx(JupyterReactTheme, { children: _jsx(ToastButton, { action: action, closeToast: closeHandler }, 'button-' + idx) }));
|
|
41
41
|
})] }))] }));
|
|
42
42
|
}
|
|
43
43
|
export const useToast = () => {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { JupyterLabAppAdapter } from '@datalayer/jupyter-react';
|
|
2
1
|
import type { IMultiServiceManager } from '../../api';
|
|
3
2
|
import type { IRuntimesConfiguration } from '../../config';
|
|
4
3
|
import type { IRuntimePod, IRuntimeSnapshot, IRuntimeModel } from '../../models';
|
|
@@ -15,14 +14,6 @@ export type RuntimesState = {
|
|
|
15
14
|
* Runtimes RUN URL.
|
|
16
15
|
*/
|
|
17
16
|
runtimesRunUrl: string;
|
|
18
|
-
/**
|
|
19
|
-
* JupyterLabApp adapter.
|
|
20
|
-
*/
|
|
21
|
-
jupyterLabAdapter?: JupyterLabAppAdapter;
|
|
22
|
-
/**
|
|
23
|
-
* Set the JupyterLabAdapter.
|
|
24
|
-
*/
|
|
25
|
-
setJupyterLabAdapter: (jupyterLabAdapter: JupyterLabAppAdapter) => void;
|
|
26
17
|
tab: number;
|
|
27
18
|
getIntTab: () => number;
|
|
28
19
|
setTab: (tab: number) => void;
|
|
@@ -24,9 +24,6 @@ export const runtimesStore = createStore((set, get) => {
|
|
|
24
24
|
: { configuration: { ...configuration } });
|
|
25
25
|
},
|
|
26
26
|
runtimesRunUrl: coreStore.getState().configuration?.runtimesRunUrl,
|
|
27
|
-
setJupyterLabAdapter: (jupyterLabAdapter) => {
|
|
28
|
-
set(state => ({ jupyterLabAdapter }));
|
|
29
|
-
},
|
|
30
27
|
tab: 0.0,
|
|
31
28
|
getIntTab: () => Math.floor(get().tab),
|
|
32
29
|
setTab: (tab) => set(state => ({ tab })),
|
|
@@ -2,16 +2,8 @@ import { type CSSProperties } from 'react';
|
|
|
2
2
|
import { ThemeProviderProps } from '@primer/react';
|
|
3
3
|
export interface IDatalayerThemeProviderProps extends ThemeProviderProps {
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*/
|
|
7
|
-
inJupyterLab?: boolean;
|
|
8
|
-
/**
|
|
9
|
-
* Base styles
|
|
5
|
+
* Base styles.
|
|
10
6
|
*/
|
|
11
7
|
baseStyles?: CSSProperties;
|
|
12
8
|
}
|
|
13
|
-
/**
|
|
14
|
-
* ThemeProvider component changing color mode with JupyterLab theme
|
|
15
|
-
* if embedded in Jupyter or with the browser color scheme preference.
|
|
16
|
-
*/
|
|
17
9
|
export declare function DatalayerThemeProvider(props: React.PropsWithChildren<IDatalayerThemeProviderProps>): JSX.Element;
|
|
@@ -1,67 +1,11 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
2
|
-
/*
|
|
3
|
-
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
4
|
-
* Distributed under the terms of the Modified BSD License.
|
|
5
|
-
*/
|
|
6
|
-
import { useEffect, useState } from 'react';
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
7
2
|
import { BaseStyles, ThemeProvider as PrimerThemeProvider, } from '@primer/react';
|
|
8
|
-
import { loadJupyterConfig, jupyterLabTheme } from '@datalayer/jupyter-react';
|
|
9
|
-
import { datalayerTheme } from '../theme';
|
|
10
|
-
import { useRuntimesStore } from '../state';
|
|
11
|
-
/**
|
|
12
|
-
* ThemeProvider component changing color mode with JupyterLab theme
|
|
13
|
-
* if embedded in Jupyter or with the browser color scheme preference.
|
|
14
|
-
*/
|
|
15
3
|
export function DatalayerThemeProvider(props) {
|
|
16
|
-
const { children, colorMode
|
|
17
|
-
|
|
18
|
-
baseStyles, ...rest } = props;
|
|
19
|
-
const { jupyterLabAdapter } = useRuntimesStore();
|
|
20
|
-
const [colorMode, setColorMode] = useState(colorModeProps ?? 'light');
|
|
21
|
-
const [inJupyterLab, setInJupterLab] = useState(undefined);
|
|
22
|
-
useEffect(() => {
|
|
23
|
-
setInJupterLab(loadJupyterConfig().insideJupyterLab);
|
|
24
|
-
}, []);
|
|
25
|
-
useEffect(() => {
|
|
26
|
-
if (inJupyterLab !== undefined) {
|
|
27
|
-
function colorSchemeFromMedia({ matches }) {
|
|
28
|
-
setColorMode(matches ? 'dark' : 'light');
|
|
29
|
-
}
|
|
30
|
-
function updateColorMode(themeManager) {
|
|
31
|
-
setColorMode(themeManager.theme && !themeManager.isLight(themeManager.theme)
|
|
32
|
-
? 'dark'
|
|
33
|
-
: 'light');
|
|
34
|
-
}
|
|
35
|
-
if (inJupyterLab) {
|
|
36
|
-
const themeManager = jupyterLabAdapter?.service('@jupyterlab/apputils-extension:themes');
|
|
37
|
-
console.log('---------DLA', inJupyterLab, jupyterLabAdapter, themeManager);
|
|
38
|
-
if (themeManager) {
|
|
39
|
-
updateColorMode(themeManager);
|
|
40
|
-
themeManager.themeChanged.connect(updateColorMode);
|
|
41
|
-
return () => {
|
|
42
|
-
themeManager.themeChanged.disconnect(updateColorMode);
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
colorSchemeFromMedia({
|
|
48
|
-
matches: window.matchMedia('(prefers-color-scheme: dark)').matches,
|
|
49
|
-
});
|
|
50
|
-
window
|
|
51
|
-
.matchMedia('(prefers-color-scheme: dark)')
|
|
52
|
-
.addEventListener('change', colorSchemeFromMedia);
|
|
53
|
-
return () => {
|
|
54
|
-
window
|
|
55
|
-
.matchMedia('(prefers-color-scheme: dark)')
|
|
56
|
-
.removeEventListener('change', colorSchemeFromMedia);
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}, [inJupyterLab, jupyterLabAdapter]);
|
|
61
|
-
return inJupyterLab !== undefined ? (_jsx(PrimerThemeProvider, { colorMode: colorMode, theme: inJupyterLab ? jupyterLabTheme : datalayerTheme, ...rest, children: _jsx(BaseStyles, { style: {
|
|
4
|
+
const { children, colorMode, baseStyles, ...rest } = props;
|
|
5
|
+
return (_jsx(PrimerThemeProvider, { colorMode: colorMode, ...rest, children: _jsx(BaseStyles, { style: {
|
|
62
6
|
backgroundColor: 'var(--bgColor-default)',
|
|
63
7
|
color: 'var(--fgColor-default)',
|
|
64
8
|
fontSize: 'var(--text-body-size-medium)',
|
|
65
9
|
...baseStyles,
|
|
66
|
-
}, children: children }) }))
|
|
10
|
+
}, children: children }) }));
|
|
67
11
|
}
|
package/lib/theme/Palette.d.ts
CHANGED
package/lib/theme/Palette.js
CHANGED
|
@@ -2,18 +2,6 @@
|
|
|
2
2
|
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
3
|
* Distributed under the terms of the Modified BSD License.
|
|
4
4
|
*/
|
|
5
|
-
const JUPYTERLAB_COLLABORATORS_COLORS = {
|
|
6
|
-
'--jp-collaborator-color1': '#ffad8e',
|
|
7
|
-
'--jp-collaborator-color2': '#dac83d',
|
|
8
|
-
'--jp-collaborator-color3': '#72dd76',
|
|
9
|
-
'--jp-collaborator-color4': '#00e4d0',
|
|
10
|
-
'--jp-collaborator-color5': '#45d4ff',
|
|
11
|
-
'--jp-collaborator-color6': '#e2b1ff',
|
|
12
|
-
'--jp-collaborator-color7': '#ff9de6',
|
|
13
|
-
};
|
|
14
|
-
export const jpCssToColor = (cssVariableName) => {
|
|
15
|
-
return JUPYTERLAB_COLLABORATORS_COLORS[cssVariableName.replaceAll('var(', '').replaceAll(')', '')];
|
|
16
|
-
};
|
|
17
5
|
// export const RESERVATION_CIRCLE_COLOR_VAR = '--data-yellow-color';
|
|
18
6
|
export const RESERVATION_CIRCLE_COLOR = '#656D76';
|
|
19
7
|
// export const CREDITS_CIRCLE_COLOR_VAR = '--data-blue-color';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datalayer/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"workspaces": [
|
|
6
6
|
".",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"dependencies": {
|
|
84
84
|
"@datalayer/icons-react": "^1.0.6",
|
|
85
85
|
"@datalayer/jupyter-react": "^1.1.0",
|
|
86
|
-
"@datalayer/primer-addons": "^1.0.
|
|
86
|
+
"@datalayer/primer-addons": "^1.0.4",
|
|
87
87
|
"@datalayer/primer-rjsf": "^1.0.1",
|
|
88
88
|
"@jupyterlab/coreutils": "^6.0.0",
|
|
89
89
|
"@jupyterlab/services": "^7.0.0",
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import React, { Ref, PropsWithChildren } from 'react';
|
|
2
|
-
import { AnimateProps } from '@primer/react-brand';
|
|
3
|
-
/**
|
|
4
|
-
* Layout
|
|
5
|
-
*/
|
|
6
|
-
export declare const Container: ({ children, style, }: {
|
|
7
|
-
children: React.ReactElement[] | React.ReactElement;
|
|
8
|
-
style?: React.CSSProperties;
|
|
9
|
-
}) => import("react/jsx-runtime").JSX.Element;
|
|
10
|
-
type RedlineBackgroundProps = {
|
|
11
|
-
height?: number;
|
|
12
|
-
hasBorder?: boolean;
|
|
13
|
-
};
|
|
14
|
-
export declare function RedlineBackground({ height, hasBorder, ...rest }: PropsWithChildren<RedlineBackgroundProps>): import("react/jsx-runtime").JSX.Element;
|
|
15
|
-
/**
|
|
16
|
-
* Base Types
|
|
17
|
-
*
|
|
18
|
-
* Component helper type to be extended by component types, e.g.:
|
|
19
|
-
* type CustomComponentProps = BaseProps<HTMLDivElement> & { ... }
|
|
20
|
-
*
|
|
21
|
-
* Example use:
|
|
22
|
-
* const CustomComponent = forwardRef<HTMLDivElement, CustomComponentProps>(({className, ...props}, ref) => { ... })
|
|
23
|
-
* // OR:
|
|
24
|
-
* const CustomComponent = forwardRef(({className: CustomComponentProps, ...props}, ref: Ref<HTMLDivElement>) => { ... })
|
|
25
|
-
*/
|
|
26
|
-
export type BaseProps<T> = {
|
|
27
|
-
className?: string;
|
|
28
|
-
id?: string;
|
|
29
|
-
ref?: Ref<T>;
|
|
30
|
-
animate?: AnimateProps;
|
|
31
|
-
};
|
|
32
|
-
export {};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
/**
|
|
3
|
-
* Layout
|
|
4
|
-
*/
|
|
5
|
-
export const Container = ({ children, style, }) => (_jsx("div", { style: { maxWidth: 1024, margin: '0 auto', ...style }, children: children }));
|
|
6
|
-
export function RedlineBackground({ height, hasBorder = true, ...rest }) {
|
|
7
|
-
return (_jsx("div", { style: {
|
|
8
|
-
display: 'flex',
|
|
9
|
-
overflow: 'hidden',
|
|
10
|
-
border: hasBorder
|
|
11
|
-
? '1px solid var(--base-color-scale-red-2)'
|
|
12
|
-
: undefined,
|
|
13
|
-
backgroundImage: 'linear-gradient(45deg, var(--base-color-scale-red-0) 12.5%, hsla(var(--base-color-scale-red-2-hsl) / 50%) 12.5%, hsla(var(--base-color-scale-red-2-hsl) / 50%) 50%, var(--base-color-scale-red-0) 50%, var(--base-color-scale-red-0) 62.5%, hsla(var(--base-color-scale-red-2-hsl) / 50%) 62.5%, hsla(var(--base-color-scale-red-2-hsl) / 50%) 100%)',
|
|
14
|
-
backgroundSize: '5.66px 5.66px',
|
|
15
|
-
WebkitBoxPack: 'center',
|
|
16
|
-
justifyContent: 'center',
|
|
17
|
-
alignItems: 'center',
|
|
18
|
-
width: '100%',
|
|
19
|
-
height,
|
|
20
|
-
}, ...rest }));
|
|
21
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import '@primer/react-brand/lib/css/main.css';
|
|
2
|
-
/**
|
|
3
|
-
* Ensure we define a root for Primer portal root.
|
|
4
|
-
*
|
|
5
|
-
* @see https://github.com/primer/react/blob/main/packages/react/src/Portal/Portal.tsx#L23
|
|
6
|
-
* @see https://github.com/primer/react/blob/030fe020b48b7f12c2994c6614e5d4191fe764ee/src/Portal/Portal.tsx#L33
|
|
7
|
-
*/
|
|
8
|
-
export declare const setupPrimerPortals: () => void;
|
|
9
|
-
export default setupPrimerPortals;
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
|
-
* Distributed under the terms of the Modified BSD License.
|
|
4
|
-
*/
|
|
5
|
-
import { registerPortalRoot } from '@primer/react';
|
|
6
|
-
// import { render } from 'react-dom';
|
|
7
|
-
// import { Styles } from './Styles';
|
|
8
|
-
const PRIMER_PORTAL_ROOT_ID = '__primerPortalRoot__';
|
|
9
|
-
import '@primer/react-brand/lib/css/main.css';
|
|
10
|
-
/**
|
|
11
|
-
* Ensure we define a root for Primer portal root.
|
|
12
|
-
*
|
|
13
|
-
* @see https://github.com/primer/react/blob/main/packages/react/src/Portal/Portal.tsx#L23
|
|
14
|
-
* @see https://github.com/primer/react/blob/030fe020b48b7f12c2994c6614e5d4191fe764ee/src/Portal/Portal.tsx#L33
|
|
15
|
-
*/
|
|
16
|
-
export const setupPrimerPortals = () => {
|
|
17
|
-
const div = document.body;
|
|
18
|
-
div.dataset['portalRoot'] = 'true';
|
|
19
|
-
div.dataset['colorMode'] = 'light';
|
|
20
|
-
div.dataset['lightTheme'] = 'light';
|
|
21
|
-
div.dataset['darkTheme'] = 'dark';
|
|
22
|
-
div.id = PRIMER_PORTAL_ROOT_ID;
|
|
23
|
-
registerPortalRoot(div);
|
|
24
|
-
// render(<Styles/>, div);
|
|
25
|
-
};
|
|
26
|
-
export default setupPrimerPortals;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
/*
|
|
3
|
-
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
4
|
-
* Distributed under the terms of the Modified BSD License.
|
|
5
|
-
*/
|
|
6
|
-
import { ThemeProvider, BaseStyles } from '@primer/react';
|
|
7
|
-
import { jupyterLabTheme } from '@datalayer/jupyter-react';
|
|
8
|
-
export const Styles = () => {
|
|
9
|
-
return (_jsx(_Fragment, { children: _jsx(ThemeProvider, { theme: jupyterLabTheme, children: _jsx(BaseStyles, {}) }) }));
|
|
10
|
-
};
|
|
11
|
-
export default Styles;
|