diff --git a/packages/apputils/src/sessioncontext.tsx b/packages/apputils/src/sessioncontext.tsx index fa6783e8bb17..d3564a3b5b33 100644 --- a/packages/apputils/src/sessioncontext.tsx +++ b/packages/apputils/src/sessioncontext.tsx @@ -1665,7 +1665,7 @@ namespace Private { 'data-custom-env-vars', JSON.stringify(envConfiguration) ); - }, translator); + }, false, translator); //trans.__('Start Preferred Kernel'); //Update widget diff --git a/packages/notebook-extension/src/index.ts b/packages/notebook-extension/src/index.ts index b4489d5d67ee..01b2c364e418 100644 --- a/packages/notebook-extension/src/index.ts +++ b/packages/notebook-extension/src/index.ts @@ -114,7 +114,8 @@ import { refreshIcon, runIcon, stopIcon, - tableRowsIcon + tableRowsIcon, + CustomEnvWidget } from '@jupyterlab/ui-components'; import { ArrayExt } from '@lumino/algorithm'; import { CommandRegistry } from '@lumino/commands'; @@ -137,7 +138,6 @@ import { NotebookMetadataField } from './tool-widgets/metadataEditorFields'; import { ISpecModel } from '@jupyterlab/services/src/kernelspec/restapi'; -import { CustomEnvWidget } from '@jupyterlab/ui-components/src/components'; /** * The command IDs used by the notebook plugin. @@ -1992,9 +1992,7 @@ function activateNotebookHandler( } }); - const showCustomEnvVarsDialog = async( - spec: ISpecModel | undefined - ) => { + const showCustomEnvVarsDialog = async (spec: ISpecModel | undefined, node: HTMLElement) => { let envConfiguration: PartialJSONObject = {}; let label = trans.__('Cancel'); const buttons = [ @@ -2003,35 +2001,41 @@ function activateNotebookHandler( }), Dialog.okButton({ label: trans.__('Setup'), - ariaLabel: trans.__('setup custom env variables') + ariaLabel: trans.__('Setup custom env variables') }) ]; - - let defaultEnvValues = {} + + let defaultEnvValues = {}; const dialog = new Dialog({ - title: trans.__('Setup custom environment variables'), - body: new CustomEnvWidget(envConfiguration, defaultEnvValues, formData => { - envConfiguration = formData as PartialJSONObject; - console.log('envConfiguration'); - console.dir(envConfiguration); - }, translator), + title: '', + body: new CustomEnvWidget( + envConfiguration, + defaultEnvValues, + formData => { + envConfiguration = formData as PartialJSONObject; + console.log('envConfiguration'); + console.dir(envConfiguration); + }, true, + translator + ), buttons }); const result = await dialog.launch(); - + if (!result.button.accept) { return; } console.log('result.value'); console.dir(result.value); - if (result.value) { + if (Object.keys(envConfiguration).length>0 && spec) { + node.setAttribute("custom-env-vars", JSON.stringify(envConfiguration)); //saveve for each kernel spec } }; - const LAUNCHER_LABEL = "jp-LauncherCard"; + const LAUNCHER_LABEL = 'jp-LauncherCard'; const isLauncherLabel = (node: HTMLElement) => node.classList.contains(LAUNCHER_LABEL); let selectedSpec: ISpecModel | undefined; @@ -2052,9 +2056,9 @@ function activateNotebookHandler( console.log('node'); console.dir(node); - let defaultName = node.getAttribute('titile'); - console.log('defaultName'); - console.dir(defaultName); + let defaultName = node.innerText; + console.log('defaultName'); + console.dir(defaultName); for (const name in specs.kernelspecs) { const spec = specs.kernelspecs[name]; if (spec && spec.display_name === defaultName) { @@ -2063,11 +2067,10 @@ function activateNotebookHandler( } console.log('selectedSpec'); console.dir(selectedSpec); - showCustomEnvVarsDialog(selectedSpec); + showCustomEnvVarsDialog(selectedSpec, node); } }); - // Add a launcher item if the launcher is available. if (launcher) { void services.ready.then(() => { @@ -2107,12 +2110,17 @@ function activateNotebookHandler( onSpecsChanged(); services.kernelspecs.specsChanged.connect(onSpecsChanged); }); - - app.contextMenu.addItem({ - command: CommandIDs.setupCustomEnv, - selector: '.jp-LauncherCard', - rank: 0 - }); + const allow_custom_env_variables = + PageConfig.getOption('allow_custom_env_variables') === 'true' + ? true + : false; + if (allow_custom_env_variables) { + app.contextMenu.addItem({ + command: CommandIDs.setupCustomEnv, + selector: '.jp-LauncherCard', + rank: 0 + }); + } } return tracker; diff --git a/packages/ui-components/src/components/customenvvars.tsx b/packages/ui-components/src/components/customenvvars.tsx index e88d656afd8a..67aa9eece64e 100644 --- a/packages/ui-components/src/components/customenvvars.tsx +++ b/packages/ui-components/src/components/customenvvars.tsx @@ -6,135 +6,183 @@ import { ITranslator, nullTranslator } from '@jupyterlab/translation'; import { ReactWidget } from './vdom'; import { PartialJSONObject } from '@lumino/coreutils'; -import React, { ChangeEvent, ChangeEventHandler, useEffect, useState } from 'react'; +import React, { + ChangeEvent, + ChangeEventHandler, + useEffect, + useState +} from 'react'; +import { Button } from './button'; interface IEnvProps { - updateFormData: (formData: PartialJSONObject)=>void; + updateFormData: (formData: PartialJSONObject) => void; defaultEnvValues: PartialJSONObject; + showBlock: boolean; translator?: ITranslator | undefined; } interface IEnvBlockProps { - handleChange:(envVars: PartialJSONObject)=>void; + handleChange: (envVars: PartialJSONObject) => void; id: string; defaultName: string; defaultEnvValue: string; translator: ITranslator | undefined; } -function EnvBlock({handleChange, id, defaultName,defaultEnvValue, translator }:IEnvBlockProps ){ +function EnvBlock({ + handleChange, + id, + defaultName, + defaultEnvValue, + translator +}: IEnvBlockProps) { const [newEnvName, setEnvName] = useState(defaultName); const [newEnvValue, setEnvValue] = useState(defaultEnvValue); translator = translator || nullTranslator; const trans = translator.load('jupyterlab'); - useEffect(()=>{ + useEffect(() => { let envVar = {} as PartialJSONObject; envVar[id] = { - name:newEnvName, - value:newEnvValue + name: newEnvName, + value: newEnvValue }; console.log('envVar'); console.dir(envVar); handleChange(envVar); - },[newEnvName, newEnvValue]); + }, [newEnvName, newEnvValue]); - const onChange: ChangeEventHandler = (event: ChangeEvent) => { + const onChange: ChangeEventHandler = ( + event: ChangeEvent + ) => { const { name, value } = event.target; console.log('name', name); console.log('value', value); - if (name === "env_name") { + if (name === 'env_name') { setEnvName(value); - } else if (name === "env_value") { + } else if (name === 'env_value') { setEnvValue(value); } }; - - -return ( - <> - -
- -
-) + return ( + <> + +
+ +
+ + ); } - -function CustomEnv({updateFormData, defaultEnvValues, translator }: IEnvProps) { +function CustomEnv({ + updateFormData, + defaultEnvValues, + showBlock, + translator +}: IEnvProps) { const [formData, setInputs] = useState(defaultEnvValues); - const [countEnvBlock, setCountEnvBlock] = useState(Object.keys(formData).length); + const [isShownBlock, setShowBlock] = useState(showBlock); + const [countEnvBlock, setCountEnvBlock] = useState( + Object.keys(formData).length + ); translator = translator || nullTranslator; const trans = translator.load('jupyterlab'); - useEffect(()=>{ + useEffect(() => { updateFormData(formData); - },[formData]); + }, [formData]); - useEffect(()=>{ - let count = defaultEnvValues && Object.keys(defaultEnvValues).length>0? Object.keys(defaultEnvValues).length : 1; + useEffect(() => { + let count = + defaultEnvValues && Object.keys(defaultEnvValues).length > 0 + ? Object.keys(defaultEnvValues).length + : 1; setCountEnvBlock(count); - },[defaultEnvValues]) + }, [defaultEnvValues]); - const addMoreEnvVariables = ()=>{ - let newCountEnvBlock = countEnvBlock +1; + const addMoreEnvVariables = () => { + let newCountEnvBlock = countEnvBlock + 1; setCountEnvBlock(newCountEnvBlock); - } + }; const handleChange = (envVars: PartialJSONObject) => { - setInputs({ ...formData, ...envVars }); }; - - - const handleSubmit = (e: { preventDefault: () => void; }) => { - e.preventDefault(); + const showCustomEnvBlock = () => { + setShowBlock(!isShownBlock); }; let envBlock = []; - for(let index=1; index<=countEnvBlock; index++) { + for (let index = 1; index <= countEnvBlock; index++) { let envData = formData[`${index}`] as PartialJSONObject | undefined; - let defaultName = envData && envData.name? envData.name: ''; - let defaultEnvValue = envData && envData.value? envData.value: ''; - - envBlock.push() + let defaultName = envData && envData.name ? envData.name : ''; + let defaultEnvValue = envData && envData.value ? envData.value : ''; + + envBlock.push( + + ); } - const header = `${trans.__('Setup custom env variables:')}`; - const addMoreVarLabel= trans.__('Add more'); - + const header = `${trans.__('Setup custom env variables')}`; + const addMoreVarLabel = trans.__('Add more'); + + const classes = 'jp-Dialog-button jp-mod-accept jp-mod-styled js-custom-env'; + return (
-
{header}
-
- {envBlock} -
- +
+ {header}{' '} + +
+ {isShownBlock && ( + <> +
{envBlock}
+ + + )}
); } @@ -142,27 +190,30 @@ function CustomEnv({updateFormData, defaultEnvValues, translator }: IEnvProps) { export default CustomEnv; /** - * A Dialog Widget that wraps a FormComponent. + * A Dialog Widget that wraps a form component for custom env variables. */ export class CustomEnvWidget extends ReactWidget { updateFormData: (formData: PartialJSONObject) => void; envConfiguration: PartialJSONObject; defaultEnvValues: PartialJSONObject; + showBlock: boolean; translator?: ITranslator | undefined; /** - * Constructs a new FormWidget. + * Constructs a new custom env variables widget. */ constructor( envConfiguration: PartialJSONObject, - defaultEnvValues:PartialJSONObject, + defaultEnvValues: PartialJSONObject, updateFormData: (formData: PartialJSONObject) => void, - translator?: ITranslator, + showBlock: boolean, + translator?: ITranslator ) { super(); this.envConfiguration = envConfiguration; this.updateFormData = updateFormData; this.translator = translator; this.defaultEnvValues = defaultEnvValues; + this.showBlock = showBlock; } getValue(): PartialJSONObject { @@ -175,15 +226,22 @@ export class CustomEnvWidget extends ReactWidget { for (let index in this.defaultEnvValues) { let envVarsIndex = `${k}`; tmp[envVarsIndex] = { - 'name': index, - 'value':this.defaultEnvValues[index] + name: index, + value: this.defaultEnvValues[index] }; - k+=1; + k += 1; + } + let showBlock = this.showBlock; + if (Object.keys(tmp).length > 0) { + showBlock = true; } return ( ); } -} \ No newline at end of file +}