From 04176cf7b766c031b25a351c198d21fb1ac1a240 Mon Sep 17 00:00:00 2001 From: Anastasiia Sliusar Date: Tue, 30 Apr 2024 22:32:45 +0200 Subject: [PATCH 01/29] Add dialog for kernel custom specs --- packages/notebook-extension/package.json | 2 + .../src/customKernelWidget.tsx | 82 ++++++++++++++++ packages/notebook-extension/src/index.ts | 94 ++++++++++++++----- 3 files changed, 155 insertions(+), 23 deletions(-) create mode 100644 packages/notebook-extension/src/customKernelWidget.tsx diff --git a/packages/notebook-extension/package.json b/packages/notebook-extension/package.json index 9b58ce30cd0b..08b83708bb1e 100644 --- a/packages/notebook-extension/package.json +++ b/packages/notebook-extension/package.json @@ -74,7 +74,9 @@ "@lumino/messaging": "^2.0.1", "@lumino/polling": "^2.1.2", "@lumino/widgets": "^2.3.2", + "@rjsf/core": "^5.13.4", "@rjsf/utils": "^5.13.4", + "@rjsf/validator-ajv8": "^5.13.4", "react": "^18.2.0" }, "devDependencies": { diff --git a/packages/notebook-extension/src/customKernelWidget.tsx b/packages/notebook-extension/src/customKernelWidget.tsx new file mode 100644 index 000000000000..0124f8f43bb1 --- /dev/null +++ b/packages/notebook-extension/src/customKernelWidget.tsx @@ -0,0 +1,82 @@ +import { ReactWidget } from '@jupyterlab/ui-components'; +import React, { useEffect, useState } from 'react'; + +import Form, { IChangeEvent } from '@rjsf/core'; +import { RJSFSchema, UiSchema } from '@rjsf/utils'; +import validator from '@rjsf/validator-ajv8'; + +/** + * Form to select custom properties of kernel + * + * @returns The React component + */ + +const FormComponent = (props: { + schema: RJSFSchema; + getFormData: ( + formData: IChangeEvent | undefined + ) => void; +}): JSX.Element => { + const [data, setFormData] = useState< + IChangeEvent | undefined + >(undefined); + + useEffect(() => { + props.getFormData(data); + }, [data]); + + const uiSchema: UiSchema = { + 'ui:options': { + submitButtonOptions: { + props: { + disabled: true + }, + norender: true + } + } + }; + + const onChange = ({ formData }: IChangeEvent) => { + setFormData(formData); + }; + + return ( +
+ ); +}; + +/** + * A Button Lumino Widget that wraps a FormComponent. + */ +export class DialogWidget extends ReactWidget { + schema: RJSFSchema; + formData: IChangeEvent | undefined; + /** + * Constructs a new FormWidget. + */ + constructor(schema: RJSFSchema) { + super(); + this.schema = schema; + this.formData = undefined; + } + + getValue(): IChangeEvent | undefined { + return this.formData; + } + + getFormData(formData: IChangeEvent | undefined): void { + console.log(`formData-->${formData}`); + this.formData = formData; + } + + render(): JSX.Element { + return ( + + ); + } +} diff --git a/packages/notebook-extension/src/index.ts b/packages/notebook-extension/src/index.ts index b64f4ab2528c..09b7c7405b9a 100644 --- a/packages/notebook-extension/src/index.ts +++ b/packages/notebook-extension/src/index.ts @@ -5,7 +5,7 @@ * @module notebook-extension */ -import type { FieldProps } from '@rjsf/utils'; +import type { FieldProps, RJSFSchema } from '@rjsf/utils'; import { ILabShell, @@ -121,6 +121,7 @@ import { CommandRegistry } from '@lumino/commands'; import { JSONExt, JSONObject, + ReadonlyJSONObject, ReadonlyJSONValue, ReadonlyPartialJSONObject, UUID @@ -135,6 +136,7 @@ import { CellMetadataField, NotebookMetadataField } from './tool-widgets/metadataEditorFields'; +import { DialogWidget } from './customKernelWidget'; /** * The command IDs used by the notebook plugin. @@ -1955,11 +1957,45 @@ function activateNotebookHandler( } }; + const showDialog = async (parameters: RJSFSchema, cwd:string, kernelId: string, kernelName:string)=>{ + + let label = trans.__('Cancel'); + const buttons = [ + Dialog.cancelButton({ + label + }), + Dialog.okButton({ + label: trans.__('Select'), + ariaLabel: trans.__('Select Kernel') + }) + ]; + + // const autoStartDefault = sessionContext.kernelPreference.autoStartDefault; + + const dialog = new Dialog({ + title: trans.__('Select Kernel'), + body: new DialogWidget(parameters), + buttons, + }); + + const result = await dialog.launch(); + + if (!result.button.accept) { + return; + } + console.log(`result.value`); + console.dir(result.value); + + } + + + // Add a command for creating a new notebook. commands.addCommand(CommandIDs.createNew, { label: args => { const kernelName = (args['kernelName'] as string) || ''; if (args['isLauncher'] && args['kernelName'] && services.kernelspecs) { + // return ( services.kernelspecs.specs?.kernelspecs[kernelName]?.display_name ?? '' @@ -1973,12 +2009,21 @@ function activateNotebookHandler( caption: trans.__('Create a new notebook'), icon: args => (args['isPalette'] ? undefined : notebookIcon), execute: args => { - const currentBrowser = - filebrowserFactory?.tracker.currentWidget ?? defaultBrowser; + const currentBrowser = + filebrowserFactory?.tracker.currentWidget ?? defaultBrowser; + console.log(`args-->${args}`); + console.dir(args); + //if has enum then calll const cwd = (args['cwd'] as string) || (currentBrowser?.model.path ?? ''); const kernelId = (args['kernelId'] as string) || ''; const kernelName = (args['kernelName'] as string) || ''; + const metadata = args['metadata'] as ReadonlyJSONObject; + if (metadata?.parameters) { + let schema = metadata.parameters as RJSFSchema; + showDialog(schema, cwd, kernelId, kernelName); + } else { return createNew(cwd, kernelId, kernelName); + } } }); @@ -1996,26 +2041,29 @@ function activateNotebookHandler( return; } disposables = new DisposableSet(); - - for (const name in specs.kernelspecs) { - const rank = name === specs.default ? 0 : Infinity; - const spec = specs.kernelspecs[name]!; - const kernelIconUrl = - spec.resources['logo-svg'] || spec.resources['logo-64x64']; - disposables.add( - launcher.add({ - command: CommandIDs.createNew, - args: { isLauncher: true, kernelName: name }, - category: trans.__('Notebook'), - rank, - kernelIconUrl, - metadata: { - kernel: JSONExt.deepCopy( - spec.metadata || {} - ) as ReadonlyJSONValue - } - }) - ); + + for (const name in specs.kernelspecs) { + const rank = name === specs.default ? 0 : Infinity; + const spec = specs.kernelspecs[name]!; + const kernelIconUrl = + spec.resources['logo-svg'] || spec.resources['logo-64x64']; + //if has enum then add one icon + + disposables.add( + launcher.add({ + command: CommandIDs.createNew, + args: { isLauncher: true, kernelName: name, metadata: spec.metadata as ReadonlyJSONObject }, + category: trans.__('Notebook'), + rank, + kernelIconUrl, + metadata: { + kernel: JSONExt.deepCopy( + spec.metadata || {} + ) as ReadonlyJSONValue + } + }) + ); + } }; onSpecsChanged(); From f21e44b4a9253b7301326f234331d94ec7a3d638 Mon Sep 17 00:00:00 2001 From: Anastasiia Sliusar Date: Fri, 3 May 2024 16:19:52 +0200 Subject: [PATCH 02/29] Fix dialog, pass custom kernel spec to backend --- packages/apputils/src/sessioncontext.tsx | 42 +++++++-- packages/docmanager/src/manager.ts | 6 ++ packages/docregistry/src/registry.ts | 4 +- .../src/customKernelWidget.tsx | 43 +++++----- packages/notebook-extension/src/index.ts | 86 ++++++++++++------- packages/services/src/kernel/restapi.ts | 7 ++ packages/services/src/session/default.ts | 2 + packages/services/src/session/restapi.ts | 9 ++ 8 files changed, 140 insertions(+), 59 deletions(-) diff --git a/packages/apputils/src/sessioncontext.tsx b/packages/apputils/src/sessioncontext.tsx index 1121f67c4dff..695510772703 100644 --- a/packages/apputils/src/sessioncontext.tsx +++ b/packages/apputils/src/sessioncontext.tsx @@ -15,7 +15,7 @@ import { TranslationBundle } from '@jupyterlab/translation'; import { find } from '@lumino/algorithm'; -import { JSONExt, PromiseDelegate, UUID } from '@lumino/coreutils'; +import { JSONExt, PartialJSONObject, PromiseDelegate, UUID } from '@lumino/coreutils'; import { IDisposable, IObservableDisposable } from '@lumino/disposable'; import { ISignal, Signal } from '@lumino/signaling'; import { Widget } from '@lumino/widgets'; @@ -287,6 +287,13 @@ export namespace ISessionContext { * found (default `false`). */ readonly autoStartDefault?: boolean; + + /** + * Kernel custom specs defined by kernel name + */ + customKernelSpecs?: { + [key:string]: undefined | PartialJSONObject | {}; + } | undefined } export type KernelDisplayStatus = @@ -670,7 +677,9 @@ export class SessionContext implements ISessionContext { */ async startKernel(): Promise { const preference = this.kernelPreference; - + const specs = this.specsManager.specs; +// +console.log('startKernel - options'); if (!preference.autoStartDefault && preference.shouldStart === false) { return true; } @@ -679,16 +688,28 @@ export class SessionContext implements ISessionContext { if (preference.id) { options = { id: preference.id }; } else { + console.log('getDefaultKernel'); const name = Private.getDefaultKernel({ - specs: this.specsManager.specs, + specs, sessions: this.sessionManager.running(), preference }); if (name) { - options = { name }; + if (preference.customKernelSpecs) { + options = { + name, + custom_kernel_specs: preference.customKernelSpecs + } + } else { + options = { name }; + } } } + console.dir(options); + console.dir(preference); + console.log('end startKernel - options'); + if (options) { try { await this._changeKernel(options); @@ -887,6 +908,9 @@ export class SessionContext implements ISessionContext { this._pendingKernelName = model.name; } + console.log('_changeKernel'); + console.dir(model); + if (!this._session) { this._kernelChanged.emit({ name: 'kernel', @@ -1369,18 +1393,26 @@ export class SessionContextDialogs implements ISessionContext.IDialogs { if (sessionContext.isDisposed || !result.button.accept) { return; } +// + const model = result.value; if (hasCheckbox && result.isChecked !== null) { + // if there is a new kernel than kernel custom specs should be deleted + if (model && sessionContext.kernelPreference?.customKernelSpecs && !sessionContext.kernelPreference?.customKernelSpecs[model.name]) { + sessionContext.kernelPreference.customKernelSpecs = undefined; + } sessionContext.kernelPreference = { ...sessionContext.kernelPreference, autoStartDefault: result.isChecked }; } - const model = result.value; + if (model === null && !sessionContext.hasNoKernel) { return sessionContext.shutdown(); } + console.log('model'); + console.dir(model); if (model) { await sessionContext.changeKernel(model); } diff --git a/packages/docmanager/src/manager.ts b/packages/docmanager/src/manager.ts index d41247f6617c..ff0431181878 100644 --- a/packages/docmanager/src/manager.ts +++ b/packages/docmanager/src/manager.ts @@ -651,6 +651,12 @@ export class DocumentManager implements IDocumentManager { kernel ); + console.log('_createOrOpenDocument--preference'); + console.dir(preference); + + console.log('_createOrOpenDocument-kernel'); + console.dir(kernel); + let context: Private.IContext | null; let ready: Promise = Promise.resolve(undefined); diff --git a/packages/docregistry/src/registry.ts b/packages/docregistry/src/registry.ts index 046e38fb7b43..b746f56bb52b 100644 --- a/packages/docregistry/src/registry.ts +++ b/packages/docregistry/src/registry.ts @@ -643,6 +643,7 @@ export class DocumentRegistry implements IDisposable { const language = modelFactory.preferredLanguage(PathExt.basename(path)); const name = kernel && kernel.name; const id = kernel && kernel.id; + const customKernelSpecs = kernel && kernel.custom_kernel_specs; return { id, name, @@ -650,7 +651,8 @@ export class DocumentRegistry implements IDisposable { shouldStart: widgetFactory.preferKernel, canStart: widgetFactory.canStartKernel, shutdownOnDispose: widgetFactory.shutdownOnClose, - autoStartDefault: widgetFactory.autoStartDefault + autoStartDefault: widgetFactory.autoStartDefault, + customKernelSpecs: customKernelSpecs ? customKernelSpecs : undefined }; } diff --git a/packages/notebook-extension/src/customKernelWidget.tsx b/packages/notebook-extension/src/customKernelWidget.tsx index 0124f8f43bb1..e4db6bfdca6a 100644 --- a/packages/notebook-extension/src/customKernelWidget.tsx +++ b/packages/notebook-extension/src/customKernelWidget.tsx @@ -1,9 +1,12 @@ import { ReactWidget } from '@jupyterlab/ui-components'; -import React, { useEffect, useState } from 'react'; +import React from 'react'; import Form, { IChangeEvent } from '@rjsf/core'; import { RJSFSchema, UiSchema } from '@rjsf/utils'; import validator from '@rjsf/validator-ajv8'; +import { PartialJSONObject } from '@lumino/coreutils'; + +type FormDataProps = IChangeEvent | undefined | PartialJSONObject | {}; /** * Form to select custom properties of kernel @@ -12,18 +15,13 @@ import validator from '@rjsf/validator-ajv8'; */ const FormComponent = (props: { - schema: RJSFSchema; - getFormData: ( - formData: IChangeEvent | undefined + schema: RJSFSchema, + kernelConfigurarion: FormDataProps, + updateFormData: ( + formData: FormDataProps ) => void; }): JSX.Element => { - const [data, setFormData] = useState< - IChangeEvent | undefined - >(undefined); - useEffect(() => { - props.getFormData(data); - }, [data]); const uiSchema: UiSchema = { 'ui:options': { @@ -37,7 +35,8 @@ const FormComponent = (props: { }; const onChange = ({ formData }: IChangeEvent) => { - setFormData(formData); + console.log('+++'); + props.updateFormData(formData); }; return ( @@ -55,28 +54,32 @@ const FormComponent = (props: { */ export class DialogWidget extends ReactWidget { schema: RJSFSchema; - formData: IChangeEvent | undefined; + formData: FormDataProps | {}; + updateFormData: (formData: FormDataProps) => void; + kernelConfigurarion: FormDataProps; /** * Constructs a new FormWidget. */ - constructor(schema: RJSFSchema) { + constructor(schema: RJSFSchema, kernelConfigurarion: FormDataProps, updateFormData: ( + formData: FormDataProps + ) => void) { super(); this.schema = schema; this.formData = undefined; + this.kernelConfigurarion = kernelConfigurarion; + this.updateFormData = updateFormData; } - getValue(): IChangeEvent | undefined { - return this.formData; + getValue(): FormDataProps | {} { + console.log(`kernelConfigurarion`); + console.dir(this.kernelConfigurarion); + return this.kernelConfigurarion; } - getFormData(formData: IChangeEvent | undefined): void { - console.log(`formData-->${formData}`); - this.formData = formData; - } render(): JSX.Element { return ( - + ); } } diff --git a/packages/notebook-extension/src/index.ts b/packages/notebook-extension/src/index.ts index 09b7c7405b9a..849eac79238c 100644 --- a/packages/notebook-extension/src/index.ts +++ b/packages/notebook-extension/src/index.ts @@ -121,6 +121,7 @@ import { CommandRegistry } from '@lumino/commands'; import { JSONExt, JSONObject, + PartialJSONObject, ReadonlyJSONObject, ReadonlyJSONValue, ReadonlyPartialJSONObject, @@ -1845,6 +1846,53 @@ function activateNotebookHandler( }); } } + + const showKernelSpecDialog = async (parameters: RJSFSchema, cwd:string, kernelId: string, kernelName:string)=>{ + let kernelConfigurarion: PartialJSONObject = {}; + let label = trans.__('Cancel'); + const buttons = [ + Dialog.cancelButton({ + label + }), + Dialog.okButton({ + label: trans.__('Select'), + ariaLabel: trans.__('Select Kernel') + }) + ]; + + // const autoStartDefault = sessionContext.kernelPreference.autoStartDefault; + + const dialog = new Dialog({ + title: trans.__('Select Kernel'), + body: new DialogWidget(parameters, kernelConfigurarion, (formData)=>{ + kernelConfigurarion = formData as PartialJSONObject; + }), + buttons, + }); + + const result = await dialog.launch(); + + if (!result.button.accept) { + return; + } + console.log(`result.value`); + console.dir(result.value); + if (result.value) { + console.log(`value--kernelConfigurarion`); + console.dir(kernelConfigurarion); + let customKernelSpecs = undefined; + // let customKernelName = kernelConfigurarion ? kernelConfigurarion?.cpp_version : kernelName; + if(kernelConfigurarion) { + customKernelSpecs = kernelConfigurarion; + if (customKernelSpecs.kernelName) { + kernelName = customKernelSpecs.kernelName as string; + } + } + + createNew(cwd, kernelId, kernelName, customKernelSpecs); + } +} + /** * Update the setting values. @@ -1940,7 +1988,8 @@ function activateNotebookHandler( const createNew = async ( cwd: string, kernelId: string, - kernelName: string + kernelName: string, + customKernelSpecs?: undefined | PartialJSONObject | {} ) => { const model = await commands.execute('docmanager:new-untitled', { path: cwd, @@ -1950,43 +1999,14 @@ function activateNotebookHandler( const widget = (await commands.execute('docmanager:open', { path: model.path, factory: FACTORY, - kernel: { id: kernelId, name: kernelName } + kernel: { id: kernelId, name: kernelName, custom_kernel_specs: customKernelSpecs } })) as unknown as IDocumentWidget; widget.isUntitled = true; return widget; } }; - const showDialog = async (parameters: RJSFSchema, cwd:string, kernelId: string, kernelName:string)=>{ - - let label = trans.__('Cancel'); - const buttons = [ - Dialog.cancelButton({ - label - }), - Dialog.okButton({ - label: trans.__('Select'), - ariaLabel: trans.__('Select Kernel') - }) - ]; - - // const autoStartDefault = sessionContext.kernelPreference.autoStartDefault; - const dialog = new Dialog({ - title: trans.__('Select Kernel'), - body: new DialogWidget(parameters), - buttons, - }); - - const result = await dialog.launch(); - - if (!result.button.accept) { - return; - } - console.log(`result.value`); - console.dir(result.value); - - } @@ -2019,8 +2039,8 @@ function activateNotebookHandler( const kernelName = (args['kernelName'] as string) || ''; const metadata = args['metadata'] as ReadonlyJSONObject; if (metadata?.parameters) { - let schema = metadata.parameters as RJSFSchema; - showDialog(schema, cwd, kernelId, kernelName); + let schema = metadata.parameters as RJSFSchema; + showKernelSpecDialog(schema, cwd, kernelId, kernelName); } else { return createNew(cwd, kernelId, kernelName); } diff --git a/packages/services/src/kernel/restapi.ts b/packages/services/src/kernel/restapi.ts index f2399cc1f3d8..d57441620dfb 100644 --- a/packages/services/src/kernel/restapi.ts +++ b/packages/services/src/kernel/restapi.ts @@ -4,6 +4,7 @@ import { ServerConnection } from '../serverconnection'; import { URLExt } from '@jupyterlab/coreutils'; import { validateModel, validateModels } from './validate'; +import { PartialJSONObject } from '@lumino/coreutils'; /** * The kernel model provided by the server. @@ -47,6 +48,11 @@ export interface IModel { * The traceback for a dead kernel, if applicable. */ readonly traceback?: string; + + /** + * Custom kernel specifications for running a kernel + */ + custom_kernel_specs?: undefined | PartialJSONObject | {}; } /** @@ -101,6 +107,7 @@ export async function startNew( method: 'POST', body: JSON.stringify(options) }; + // const response = await ServerConnection.makeRequest(url, init, settings); if (response.status !== 201) { const err = await ServerConnection.ResponseError.create(response); diff --git a/packages/services/src/session/default.ts b/packages/services/src/session/default.ts index 05ffeb314043..2d67573a62ef 100644 --- a/packages/services/src/session/default.ts +++ b/packages/services/src/session/default.ts @@ -391,6 +391,8 @@ export class SessionConnection implements Session.ISessionConnection { private async _patch( body: DeepPartial ): Promise { + console.log('_patch-body'); + console.dir(body); const model = await updateSession( { ...body, id: this._id }, this.serverSettings diff --git a/packages/services/src/session/restapi.ts b/packages/services/src/session/restapi.ts index 6198c2829620..49464cd274cc 100644 --- a/packages/services/src/session/restapi.ts +++ b/packages/services/src/session/restapi.ts @@ -104,11 +104,17 @@ export async function startSession( options: Session.ISessionOptions, settings: ServerConnection.ISettings = ServerConnection.makeSettings() ): Promise { + const url = URLExt.join(settings.baseUrl, SESSION_SERVICE_URL); const init = { method: 'POST', body: JSON.stringify(options) }; + + console.log(`url-->${url}`); + console.log(`options`); + console.dir(options); + const response = await ServerConnection.makeRequest(url, init, settings); if (response.status !== 201) { const err = await ServerConnection.ResponseError.create(response); @@ -128,6 +134,9 @@ export async function updateSession( settings: ServerConnection.ISettings = ServerConnection.makeSettings() ): Promise { const url = getSessionUrl(settings.baseUrl, model.id); + + console.log('updaye session - model'); + console.dir(model); const init = { method: 'PATCH', body: JSON.stringify(model) From f45d64eb37ac093bcdfb6e55b04eb9114c2acb2b Mon Sep 17 00:00:00 2001 From: Anastasiia Sliusar Date: Tue, 14 May 2024 13:15:45 +0200 Subject: [PATCH 03/29] Updte forms for seting custom kernel specs --- package.json | 2 + packages/apputils/src/sessioncontext.tsx | 139 ++++++++++++++---- packages/notebook-extension/src/index.ts | 5 +- packages/ui-components/package.json | 1 + .../src/components/customform.tsx | 85 +++++++++++ .../ui-components/src/components/index.ts | 1 + 6 files changed, 206 insertions(+), 27 deletions(-) create mode 100644 packages/ui-components/src/components/customform.tsx diff --git a/package.json b/package.json index ad092e93cfb4..38a71b58f91c 100644 --- a/package.json +++ b/package.json @@ -110,6 +110,8 @@ "yjs": "^13.5.40" }, "dependencies": { + "@jupyterlab/application": "workspace:^", + "@jupyterlab/apputils": "workspace:^", "@typescript-eslint/eslint-plugin": "~6.13.2", "@typescript-eslint/parser": "~6.13.2", "eslint": "~8.55.0", diff --git a/packages/apputils/src/sessioncontext.tsx b/packages/apputils/src/sessioncontext.tsx index 695510772703..0b0f059bbe2f 100644 --- a/packages/apputils/src/sessioncontext.tsx +++ b/packages/apputils/src/sessioncontext.tsx @@ -15,12 +15,19 @@ import { TranslationBundle } from '@jupyterlab/translation'; import { find } from '@lumino/algorithm'; -import { JSONExt, PartialJSONObject, PromiseDelegate, UUID } from '@lumino/coreutils'; +import { + JSONExt, + PartialJSONObject, + PromiseDelegate, + UUID +} from '@lumino/coreutils'; import { IDisposable, IObservableDisposable } from '@lumino/disposable'; import { ISignal, Signal } from '@lumino/signaling'; import { Widget } from '@lumino/widgets'; import * as React from 'react'; import { Dialog, showDialog } from './dialog'; +import { DialogWidget, ReactWidget } from '@jupyterlab/ui-components'; +import { IRenderMime } from '@jupyterlab/rendermime-interfaces'; /** * A context object to manage a widget's kernel session connection. @@ -288,7 +295,7 @@ export namespace ISessionContext { */ readonly autoStartDefault?: boolean; - /** + /** * Kernel custom specs defined by kernel name */ customKernelSpecs?: { @@ -678,8 +685,8 @@ export class SessionContext implements ISessionContext { async startKernel(): Promise { const preference = this.kernelPreference; const specs = this.specsManager.specs; -// -console.log('startKernel - options'); + // + console.log('startKernel - options'); if (!preference.autoStartDefault && preference.shouldStart === false) { return true; } @@ -699,7 +706,7 @@ console.log('startKernel - options'); options = { name, custom_kernel_specs: preference.customKernelSpecs - } + }; } else { options = { name }; } @@ -1379,12 +1386,12 @@ export class SessionContextDialogs implements ISessionContext.IDialogs { buttons, checkbox: hasCheckbox ? { - label: trans.__('Always start the preferred kernel'), - caption: trans.__( - 'Remember my choice and always start the preferred kernel' - ), - checked: autoStartDefault - } + label: trans.__('Always start the preferred kernel'), + caption: trans.__( + 'Remember my choice and always start the preferred kernel' + ), + checked: autoStartDefault + } : null }); @@ -1393,12 +1400,16 @@ export class SessionContextDialogs implements ISessionContext.IDialogs { if (sessionContext.isDisposed || !result.button.accept) { return; } -// + // const model = result.value; if (hasCheckbox && result.isChecked !== null) { // if there is a new kernel than kernel custom specs should be deleted - if (model && sessionContext.kernelPreference?.customKernelSpecs && !sessionContext.kernelPreference?.customKernelSpecs[model.name]) { + if ( + model && + sessionContext.kernelPreference?.customKernelSpecs && + !sessionContext.kernelPreference?.customKernelSpecs[model.name] + ) { sessionContext.kernelPreference.customKernelSpecs = undefined; } sessionContext.kernelPreference = { @@ -1407,7 +1418,6 @@ export class SessionContextDialogs implements ISessionContext.IDialogs { }; } - if (model === null && !sessionContext.hasNoKernel) { return sessionContext.shutdown(); } @@ -1512,24 +1522,103 @@ namespace Private { const trans = translator.load('jupyterlab'); const body = document.createElement('div'); + const container = document.createElement('div'); + container.setAttribute('id', 'js-kernel-selector-container'); const text = document.createElement('label'); - text.textContent = `${trans.__('Select kernel for:')} "${ - sessionContext.name - }"`; - body.appendChild(text); + text.textContent = `${trans.__('Select kernel for:')} "${sessionContext.name + }"`; + container.appendChild(text); const options = getKernelSearch(sessionContext); const selector = document.createElement('select'); + selector.setAttribute('id', 'js-kernel-selector'); + selector.onchange = () => { + checkCustomKernelSpecs(sessionContext, body, trans); + }; + populateKernelSelect( selector, options, translator, !sessionContext.hasNoKernel ? sessionContext.kernelDisplayName : null ); - body.appendChild(selector); + container.append(selector); + body.append(container); return body; } + function checkCustomKernelSpecs( + sessionContext: ISessionContext, + body: HTMLDivElement, + trans: IRenderMime.TranslationBundle + ) { + let selectedKernel = "javascript";//body.querySelector("selector#js-kernel-selector");// + + //clear + body.querySelector("#js-kernel-custom-kernel-selector-container")?.remove(); + + const kernelSelectorContainer = body.querySelector( + '#js-kernel-selector-container' + ); + + console.log(`kernelSelectorContainer`); + console.dir(kernelSelectorContainer); + + // let test; + + let kernel = sessionContext.specsManager.specs?.kernelspecs[selectedKernel]; + if (kernel?.metadata && kernel?.metadata?.parameters) { + console.log(`sessioncontext parameters`); + + let kernelParameters = kernel?.metadata?.parameters as PartialJSONObject; + if (kernelParameters) { + console.log(`kernelParameters`); + console.dir(kernelParameters) + //clean preavious a custom kernel specs selector + + + + //hide selector for kernels + if (kernelSelectorContainer) { + kernelSelectorContainer.setAttribute('style', '{display: none}'); + } + + const customContainer = document.createElement('div'); + customContainer.setAttribute("id","#js-kernel-custom-kernel-selector-container"); + let kernelConfigurarion: PartialJSONObject = {}; + let test = new DialogWidget(kernelParameters, kernelConfigurarion, (formData) => { + kernelConfigurarion = formData as PartialJSONObject; + }) + + if ((test as ReactWidget).renderPromise) { + console.log('yes'); + } else { + console.log('no'); + } + //set hidden div + if ( + test instanceof ReactWidget && + (test as ReactWidget).renderPromise !== undefined + ) { + (this.test as ReactWidget) + .renderPromise!.then(() => { + console.log('CustomKernelSpecForm'); + //setFocus(); + }) + .catch(() => { + console.error("Error while loading Dialog's body"); + }); + } else { + customContainer.append(test.node); + } + body.append(customContainer); + } + } + + } + + + /** * Get the default kernel name given select options. */ @@ -1574,12 +1663,12 @@ namespace Private { const specName = matches[0]; console.warn( 'No exact match found for ' + - specName + - ', using kernel ' + - specName + - ' that matches ' + - 'language=' + - language + specName + + ', using kernel ' + + specName + + ' that matches ' + + 'language=' + + language ); return specName; } diff --git a/packages/notebook-extension/src/index.ts b/packages/notebook-extension/src/index.ts index 55cd3beeaeb7..510fd447676d 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, + DialogWidget } from '@jupyterlab/ui-components'; import { ArrayExt } from '@lumino/algorithm'; import { CommandRegistry } from '@lumino/commands'; @@ -137,7 +138,7 @@ import { CellMetadataField, NotebookMetadataField } from './tool-widgets/metadataEditorFields'; -import { DialogWidget } from './customKernelWidget'; +//import { CustomKernelSpecForm } from '@jupyterlab/services/src/kernelspec/kernelspec'; /** * The command IDs used by the notebook plugin. diff --git a/packages/ui-components/package.json b/packages/ui-components/package.json index 73158c696420..6eccd88b0d28 100644 --- a/packages/ui-components/package.json +++ b/packages/ui-components/package.json @@ -58,6 +58,7 @@ "@lumino/widgets": "^2.3.2", "@rjsf/core": "^5.13.4", "@rjsf/utils": "^5.13.4", + "@rjsf/validator-ajv8": "^5.13.4", "react": "^18.2.0", "react-dom": "^18.2.0", "typestyle": "^2.0.4" diff --git a/packages/ui-components/src/components/customform.tsx b/packages/ui-components/src/components/customform.tsx new file mode 100644 index 000000000000..1e592255391c --- /dev/null +++ b/packages/ui-components/src/components/customform.tsx @@ -0,0 +1,85 @@ +import React from 'react'; + +import Form, { IChangeEvent } from '@rjsf/core'; +import { RJSFSchema, UiSchema } from '@rjsf/utils'; +import validator from '@rjsf/validator-ajv8'; +import { PartialJSONObject } from '@lumino/coreutils'; +import { ReactWidget } from './vdom'; + +type FormDataProps = IChangeEvent | undefined | PartialJSONObject | {}; + +/** + * Form to select custom properties of kernel + * + * @returns The React component + */ + +const FormComponent = (props: { + schema: RJSFSchema, + kernelConfigurarion: FormDataProps, + updateFormData: ( + formData: FormDataProps + ) => void; +}): JSX.Element => { + + + const uiSchema: UiSchema = { + 'ui:options': { + submitButtonOptions: { + props: { + disabled: true + }, + norender: true + } + } + }; + + const onChange = ({ formData }: IChangeEvent) => { + console.log('+++'); + props.updateFormData(formData); + }; + + return ( + + ); +}; + +/** + * A Button Lumino Widget that wraps a FormComponent. + */ +export class DialogWidget extends ReactWidget { + schema: RJSFSchema; + formData: FormDataProps | {}; + updateFormData: (formData: FormDataProps) => void; + kernelConfigurarion: FormDataProps; + /** + * Constructs a new FormWidget. + */ + constructor(schema: RJSFSchema, kernelConfigurarion: FormDataProps, updateFormData: ( + formData: FormDataProps + ) => void) { + super(); + this.schema = schema; + this.formData = undefined; + this.kernelConfigurarion = kernelConfigurarion; + this.updateFormData = updateFormData; + } + + getValue(): FormDataProps | {} { + console.log(`kernelConfigurarion`); + console.dir(this.kernelConfigurarion); + return this.kernelConfigurarion; + } + + + render(): JSX.Element { + return ( + + ); + } +} diff --git a/packages/ui-components/src/components/index.ts b/packages/ui-components/src/components/index.ts index b4b3cd986b26..9da0a0336a1e 100644 --- a/packages/ui-components/src/components/index.ts +++ b/packages/ui-components/src/components/index.ts @@ -19,3 +19,4 @@ export * from './table'; export * from './toolbar'; export * from './vdom'; export * from './windowedlist'; +export * from './customform'; From 53d6ba96a8bfa89d7e561b967f4543944bf97fab Mon Sep 17 00:00:00 2001 From: Anastasiia Sliusar Date: Tue, 14 May 2024 23:47:12 +0200 Subject: [PATCH 04/29] Add validation --- packages/apputils/src/sessioncontext.tsx | 8 +- packages/notebook-extension/src/index.ts | 2 +- .../src/components/customform.tsx | 125 ++++++++++++------ 3 files changed, 89 insertions(+), 46 deletions(-) diff --git a/packages/apputils/src/sessioncontext.tsx b/packages/apputils/src/sessioncontext.tsx index 0b0f059bbe2f..3389c67e53bc 100644 --- a/packages/apputils/src/sessioncontext.tsx +++ b/packages/apputils/src/sessioncontext.tsx @@ -26,7 +26,7 @@ import { ISignal, Signal } from '@lumino/signaling'; import { Widget } from '@lumino/widgets'; import * as React from 'react'; import { Dialog, showDialog } from './dialog'; -import { DialogWidget, ReactWidget } from '@jupyterlab/ui-components'; +//import { DialogWidget, ReactWidget } from '@jupyterlab/ui-components'; import { IRenderMime } from '@jupyterlab/rendermime-interfaces'; /** @@ -1585,8 +1585,8 @@ namespace Private { const customContainer = document.createElement('div'); customContainer.setAttribute("id","#js-kernel-custom-kernel-selector-container"); - let kernelConfigurarion: PartialJSONObject = {}; - let test = new DialogWidget(kernelParameters, kernelConfigurarion, (formData) => { + // let kernelConfigurarion: PartialJSONObject = {}; + /*let test = new DialogWidget(kernelParameters, kernelConfigurarion, (formData) => { kernelConfigurarion = formData as PartialJSONObject; }) @@ -1611,7 +1611,7 @@ namespace Private { } else { customContainer.append(test.node); } - body.append(customContainer); + body.append(customContainer);*/ } } diff --git a/packages/notebook-extension/src/index.ts b/packages/notebook-extension/src/index.ts index 510fd447676d..0b397f2d0c04 100644 --- a/packages/notebook-extension/src/index.ts +++ b/packages/notebook-extension/src/index.ts @@ -1867,7 +1867,7 @@ function activateNotebookHandler( title: trans.__('Select Kernel'), body: new DialogWidget(parameters, kernelConfigurarion, (formData)=>{ kernelConfigurarion = formData as PartialJSONObject; - }), + }, trans), buttons, }); diff --git a/packages/ui-components/src/components/customform.tsx b/packages/ui-components/src/components/customform.tsx index 1e592255391c..5289b999c257 100644 --- a/packages/ui-components/src/components/customform.tsx +++ b/packages/ui-components/src/components/customform.tsx @@ -1,53 +1,29 @@ import React from 'react'; -import Form, { IChangeEvent } from '@rjsf/core'; +import { IChangeEvent } from '@rjsf/core'; import { RJSFSchema, UiSchema } from '@rjsf/utils'; import validator from '@rjsf/validator-ajv8'; -import { PartialJSONObject } from '@lumino/coreutils'; +import { PartialJSONObject, ReadonlyPartialJSONObject } from '@lumino/coreutils'; +//import { ReactWidget } from '@jupyterlab/apputils'; +//import { FormComponent, ReactWidget } from '@jupyterlab/ui-components'; +import { JSONSchema7 } from 'json-schema'; +import { IRenderMime } from '@jupyterlab/rendermime-interfaces'; import { ReactWidget } from './vdom'; +import { FormComponent } from './form'; -type FormDataProps = IChangeEvent | undefined | PartialJSONObject | {}; + +type FormDataProps = + | IChangeEvent + | undefined + | PartialJSONObject + | {}; /** * Form to select custom properties of kernel * * @returns The React component - */ - -const FormComponent = (props: { - schema: RJSFSchema, - kernelConfigurarion: FormDataProps, - updateFormData: ( - formData: FormDataProps - ) => void; -}): JSX.Element => { - const uiSchema: UiSchema = { - 'ui:options': { - submitButtonOptions: { - props: { - disabled: true - }, - norender: true - } - } - }; - - const onChange = ({ formData }: IChangeEvent) => { - console.log('+++'); - props.updateFormData(formData); - }; - - return ( - - ); -}; /** * A Button Lumino Widget that wraps a FormComponent. @@ -57,17 +33,33 @@ export class DialogWidget extends ReactWidget { formData: FormDataProps | {}; updateFormData: (formData: FormDataProps) => void; kernelConfigurarion: FormDataProps; + uiSchema: UiSchema; + trans: IRenderMime.TranslationBundle; /** * Constructs a new FormWidget. */ - constructor(schema: RJSFSchema, kernelConfigurarion: FormDataProps, updateFormData: ( - formData: FormDataProps - ) => void) { + constructor( + schema: RJSFSchema, + kernelConfigurarion: FormDataProps, + updateFormData: (formData: FormDataProps) => void, + trans: IRenderMime.TranslationBundle + ) { super(); this.schema = schema; this.formData = undefined; this.kernelConfigurarion = kernelConfigurarion; this.updateFormData = updateFormData; + this.uiSchema = { + 'ui:options': { + submitButtonOptions: { + props: { + disabled: true + }, + norender: true + } + } + }; + this.trans = trans; } getValue(): FormDataProps | {} { @@ -76,10 +68,61 @@ export class DialogWidget extends ReactWidget { return this.kernelConfigurarion; } + #checkFormData(formData: FormDataProps) { + console.log('validate'); + console.log('formData'); + console.dir(formData); + //let proba: FormDataProps= {}; + if (formData && Object.keys(formData).length) { + let formDataArr = Object.entries(formData); + console.log() + for (const [key, value] of formDataArr) { + console.log(`key--->${key}`); + let isValid = this.#validate(value); + if (isValid) { + console.log('yes. valid'); + } + } + } + return formData; + } + + #validate(value: string) { + const regexp = /^[a-zA-Z0-9]+$/; + let isValid = false; + value = value + .replace(/.*?<\/script>/gi, '') + .replace(/<.*?javascript:.*?>/gi, '') + .replace(/<.*? on\w+=.*?>/gi, ''); + if (regexp.test(value)) { + isValid = true; + } + return isValid; + } render(): JSX.Element { + let formData: Record = {}; + for (let kernel_custom_variable in this.schema.properties){ + console.log('kernel_custom_variable new'); + console.log(kernel_custom_variable); + // formData[kernel_custom_variable] = this.schema.properties[kernel_custom_variable].default || ''; + } return ( - + ) => { + let formData = this.#checkFormData(e.formData || {}); + console.log('checkFormData') + this.updateFormData(formData); + }} + showModifiedFromDefault={false} + /> + ); } } + From 39eddd1bf7718bb3f1e689cf06d418b89f92e370 Mon Sep 17 00:00:00 2001 From: Anastasiia Sliusar Date: Thu, 16 May 2024 16:53:39 +0200 Subject: [PATCH 05/29] Update a form and update data if there is no error --- .../src/components/customform.tsx | 140 +++++++----------- .../ui-components/src/components/form.tsx | 9 +- 2 files changed, 58 insertions(+), 91 deletions(-) diff --git a/packages/ui-components/src/components/customform.tsx b/packages/ui-components/src/components/customform.tsx index 5289b999c257..f67417b792bd 100644 --- a/packages/ui-components/src/components/customform.tsx +++ b/packages/ui-components/src/components/customform.tsx @@ -1,128 +1,94 @@ -import React from 'react'; - -import { IChangeEvent } from '@rjsf/core'; +import React, { RefObject, createRef } from 'react'; +import Form, { IChangeEvent } from '@rjsf/core'; import { RJSFSchema, UiSchema } from '@rjsf/utils'; import validator from '@rjsf/validator-ajv8'; -import { PartialJSONObject, ReadonlyPartialJSONObject } from '@lumino/coreutils'; -//import { ReactWidget } from '@jupyterlab/apputils'; -//import { FormComponent, ReactWidget } from '@jupyterlab/ui-components'; -import { JSONSchema7 } from 'json-schema'; +import { PartialJSONObject} from '@lumino/coreutils'; import { IRenderMime } from '@jupyterlab/rendermime-interfaces'; import { ReactWidget } from './vdom'; import { FormComponent } from './form'; -type FormDataProps = - | IChangeEvent - | undefined - | PartialJSONObject - | {}; +type FormDataProps = IChangeEvent | undefined | PartialJSONObject | {}; /** * Form to select custom properties of kernel * * @returns The React component + */ +const FormComponentWrapper = (props: { + schema: RJSFSchema, + kernelConfigurarion: FormDataProps, + updateFormData: ( + formData: FormDataProps + ) => void; +}): JSX.Element => { + const formRef = createRef() as RefObject>; + const onError = (errors: any) => alert(errors); + const uiSchema: UiSchema = { + 'ui:options': { + submitButtonOptions: { + props: { + disabled: true + }, + norender: true + } + } + }; + + const onChange = ({ formData }: IChangeEvent) => { + if (formRef.current && formRef.current.validateForm()) { + props.updateFormData(formData); + } + }; + + const formData: Record = {}; + + return ( + + ); +}; /** - * A Button Lumino Widget that wraps a FormComponent. + * A Dialog Widget that wraps a FormComponent. */ export class DialogWidget extends ReactWidget { schema: RJSFSchema; formData: FormDataProps | {}; updateFormData: (formData: FormDataProps) => void; kernelConfigurarion: FormDataProps; - uiSchema: UiSchema; - trans: IRenderMime.TranslationBundle; /** * Constructs a new FormWidget. */ - constructor( - schema: RJSFSchema, - kernelConfigurarion: FormDataProps, - updateFormData: (formData: FormDataProps) => void, - trans: IRenderMime.TranslationBundle - ) { + constructor(schema: RJSFSchema, kernelConfigurarion: FormDataProps, updateFormData: ( + formData: FormDataProps + ) => void, trans:IRenderMime.TranslationBundle) { super(); this.schema = schema; this.formData = undefined; this.kernelConfigurarion = kernelConfigurarion; this.updateFormData = updateFormData; - this.uiSchema = { - 'ui:options': { - submitButtonOptions: { - props: { - disabled: true - }, - norender: true - } - } - }; - this.trans = trans; } getValue(): FormDataProps | {} { - console.log(`kernelConfigurarion`); - console.dir(this.kernelConfigurarion); return this.kernelConfigurarion; } - #checkFormData(formData: FormDataProps) { - console.log('validate'); - console.log('formData'); - console.dir(formData); - //let proba: FormDataProps= {}; - if (formData && Object.keys(formData).length) { - let formDataArr = Object.entries(formData); - console.log() - for (const [key, value] of formDataArr) { - console.log(`key--->${key}`); - let isValid = this.#validate(value); - if (isValid) { - console.log('yes. valid'); - } - } - } - return formData; - } - - #validate(value: string) { - const regexp = /^[a-zA-Z0-9]+$/; - let isValid = false; - value = value - .replace(/.*?<\/script>/gi, '') - .replace(/<.*?javascript:.*?>/gi, '') - .replace(/<.*? on\w+=.*?>/gi, ''); - if (regexp.test(value)) { - isValid = true; - } - return isValid; - } render(): JSX.Element { - let formData: Record = {}; - for (let kernel_custom_variable in this.schema.properties){ - console.log('kernel_custom_variable new'); - console.log(kernel_custom_variable); - // formData[kernel_custom_variable] = this.schema.properties[kernel_custom_variable].default || ''; - } return ( - ) => { - let formData = this.#checkFormData(e.formData || {}); - console.log('checkFormData') - this.updateFormData(formData); - }} - showModifiedFromDefault={false} - /> - + ); } -} - +} \ No newline at end of file diff --git a/packages/ui-components/src/components/form.tsx b/packages/ui-components/src/components/form.tsx index 997c207eb2d9..1ce6f338e2a2 100644 --- a/packages/ui-components/src/components/form.tsx +++ b/packages/ui-components/src/components/form.tsx @@ -16,10 +16,11 @@ import { getTemplate, ObjectFieldTemplateProps, Registry, + RJSFSchema, UiSchema } from '@rjsf/utils'; -import React from 'react'; +import React, { forwardRef } from 'react'; import { addIcon, caretDownIcon, @@ -617,7 +618,7 @@ export interface IFormComponentProps /** * Generic rjsf form component for JupyterLab UI. */ -export function FormComponent(props: IFormComponentProps): JSX.Element { +export const FormComponent = forwardRef(function FormComponent(props: IFormComponentProps, ref:React.RefObject> | null): JSX.Element { const { buttonStyle, compact, @@ -677,6 +678,6 @@ export function FormComponent(props: IFormComponentProps): JSX.Element { }; return ( - + ); -} +}) From 68742222958ae8a46be975616697b6c085573d82 Mon Sep 17 00:00:00 2001 From: Anastasiia Sliusar Date: Fri, 17 May 2024 16:04:12 +0200 Subject: [PATCH 06/29] fix form and validation --- packages/apputils/src/sessioncontext.tsx | 131 ++++++++++-------- .../src/components/customform.tsx | 19 ++- 2 files changed, 90 insertions(+), 60 deletions(-) diff --git a/packages/apputils/src/sessioncontext.tsx b/packages/apputils/src/sessioncontext.tsx index 3389c67e53bc..b9866f656744 100644 --- a/packages/apputils/src/sessioncontext.tsx +++ b/packages/apputils/src/sessioncontext.tsx @@ -26,7 +26,7 @@ import { ISignal, Signal } from '@lumino/signaling'; import { Widget } from '@lumino/widgets'; import * as React from 'react'; import { Dialog, showDialog } from './dialog'; -//import { DialogWidget, ReactWidget } from '@jupyterlab/ui-components'; +import { DialogWidget, ReactWidget } from '@jupyterlab/ui-components'; import { IRenderMime } from '@jupyterlab/rendermime-interfaces'; /** @@ -298,9 +298,11 @@ export namespace ISessionContext { /** * Kernel custom specs defined by kernel name */ - customKernelSpecs?: { - [key:string]: undefined | PartialJSONObject | {}; - } | undefined + customKernelSpecs?: + | { + [key: string]: undefined | PartialJSONObject | {}; + } + | undefined; } export type KernelDisplayStatus = @@ -1386,12 +1388,12 @@ export class SessionContextDialogs implements ISessionContext.IDialogs { buttons, checkbox: hasCheckbox ? { - label: trans.__('Always start the preferred kernel'), - caption: trans.__( - 'Remember my choice and always start the preferred kernel' - ), - checked: autoStartDefault - } + label: trans.__('Always start the preferred kernel'), + caption: trans.__( + 'Remember my choice and always start the preferred kernel' + ), + checked: autoStartDefault + } : null }); @@ -1494,11 +1496,13 @@ namespace Private { * A widget that provides a kernel selection. */ export class KernelSelector extends Widget { + kernelSpecWidget: Widget; /** * Create a new kernel selector widget. */ constructor(sessionContext: ISessionContext, translator?: ITranslator) { super({ node: createSelectorNode(sessionContext, translator) }); + this.kernelSpecWidget; } /** @@ -1522,11 +1526,23 @@ namespace Private { const trans = translator.load('jupyterlab'); const body = document.createElement('div'); + const container = document.createElement('div'); + + const kernelSpecsContainer = document.createElement('div'); + container.setAttribute('id', 'js-kernel-selector-container'); + + kernelSpecsContainer.setAttribute( + 'id', + 'js-kernel-specs-selector-container' + ); + const text = document.createElement('label'); - text.textContent = `${trans.__('Select kernel for:')} "${sessionContext.name - }"`; + text.textContent = `${trans.__('Select kernel for:')} "${ + sessionContext.name + }"`; + container.appendChild(text); const options = getKernelSearch(sessionContext); @@ -1544,6 +1560,7 @@ namespace Private { ); container.append(selector); body.append(container); + body.append(kernelSpecsContainer); return body; } @@ -1552,12 +1569,21 @@ namespace Private { body: HTMLDivElement, trans: IRenderMime.TranslationBundle ) { - let selectedKernel = "javascript";//body.querySelector("selector#js-kernel-selector");// + let kernelSelect = document.querySelector( + 'selector#js-kernel-selector' + ) as HTMLSelectElement; + + console.log(`kernelSelect`); + console.dir(kernelSelect); + + let selectedKernel = kernelSelect.value; + + console.log(`selectedKernel-->${selectedKernel}`); //clear - body.querySelector("#js-kernel-custom-kernel-selector-container")?.remove(); + // body.querySelector("#js-kernel-custom-kernel-selector-container")?.remove(); - const kernelSelectorContainer = body.querySelector( + const kernelSelectorContainer = document.querySelector( '#js-kernel-selector-container' ); @@ -1565,60 +1591,51 @@ namespace Private { console.dir(kernelSelectorContainer); // let test; - - let kernel = sessionContext.specsManager.specs?.kernelspecs[selectedKernel]; - if (kernel?.metadata && kernel?.metadata?.parameters) { + const kernelSpecsContainer = document.querySelector( + '#js-kernel-specs-selector-container' + ) as HTMLElement; + console.log(`kernelSpecsContainer`); + console.dir(kernelSpecsContainer); + + let kernel = + selectedKernel && + sessionContext.specsManager.specs?.kernelspecs[selectedKernel]; + if (kernel && kernel?.metadata && kernel?.metadata?.parameters) { console.log(`sessioncontext parameters`); let kernelParameters = kernel?.metadata?.parameters as PartialJSONObject; if (kernelParameters) { console.log(`kernelParameters`); - console.dir(kernelParameters) + console.dir(kernelParameters); //clean preavious a custom kernel specs selector - + if (this.kernelSpecsContainer) { + Widget.detach(this.kernelSpecWidget); + } //hide selector for kernels if (kernelSelectorContainer) { - kernelSelectorContainer.setAttribute('style', '{display: none}'); + kernelSelectorContainer.setAttribute('style', 'display: none;'); } - const customContainer = document.createElement('div'); - customContainer.setAttribute("id","#js-kernel-custom-kernel-selector-container"); - // let kernelConfigurarion: PartialJSONObject = {}; - /*let test = new DialogWidget(kernelParameters, kernelConfigurarion, (formData) => { - kernelConfigurarion = formData as PartialJSONObject; - }) + let kernelConfigurarion: PartialJSONObject = {}; + this.kernelSpecWidget = new DialogWidget( + kernelParameters, + kernelConfigurarion, + formData => { + kernelConfigurarion = formData as PartialJSONObject; + }, + trans + ); - if ((test as ReactWidget).renderPromise) { - console.log('yes'); - } else { - console.log('no'); + //Update widget + if (kernelSpecsContainer) { + Widget.attach(this.kernelSpecWidget, kernelSpecsContainer); } - //set hidden div - if ( - test instanceof ReactWidget && - (test as ReactWidget).renderPromise !== undefined - ) { - (this.test as ReactWidget) - .renderPromise!.then(() => { - console.log('CustomKernelSpecForm'); - //setFocus(); - }) - .catch(() => { - console.error("Error while loading Dialog's body"); - }); - } else { - customContainer.append(test.node); - } - body.append(customContainer);*/ } } - } - - /** * Get the default kernel name given select options. */ @@ -1663,12 +1680,12 @@ namespace Private { const specName = matches[0]; console.warn( 'No exact match found for ' + - specName + - ', using kernel ' + - specName + - ' that matches ' + - 'language=' + - language + specName + + ', using kernel ' + + specName + + ' that matches ' + + 'language=' + + language ); return specName; } diff --git a/packages/ui-components/src/components/customform.tsx b/packages/ui-components/src/components/customform.tsx index f67417b792bd..5c8d7f0535cf 100644 --- a/packages/ui-components/src/components/customform.tsx +++ b/packages/ui-components/src/components/customform.tsx @@ -1,4 +1,4 @@ -import React, { RefObject, createRef } from 'react'; +import React, { RefObject, createRef, useState } from 'react'; import Form, { IChangeEvent } from '@rjsf/core'; import { RJSFSchema, UiSchema } from '@rjsf/utils'; import validator from '@rjsf/validator-ajv8'; @@ -24,8 +24,15 @@ const FormComponentWrapper = (props: { ) => void; }): JSX.Element => { + const [errorList, setErrors] = useState(); + const formRef = createRef() as RefObject>; - const onError = (errors: any) => alert(errors); + const onError = (errors: any) => + { + setErrors(errors) + console.log('errors'); + console.log("errors"); + }; const uiSchema: UiSchema = { 'ui:options': { submitButtonOptions: { @@ -38,9 +45,14 @@ const FormComponentWrapper = (props: { }; const onChange = ({ formData }: IChangeEvent) => { - if (formRef.current && formRef.current.validateForm()) { + // if (formRef.current && formRef.current.validateForm()) { + console.log('onChange and errorList'); + console.dir(errorList); + if (!errorList) { + console.log('update data'); props.updateFormData(formData); } + // } }; const formData: Record = {}; @@ -52,6 +64,7 @@ const FormComponentWrapper = (props: { uiSchema={uiSchema} validator={validator} onChange={onChange} + liveValidate ref={formRef} onError={onError} idPrefix={`jp-CustomKernel-test`} From 6961eb5204e93fba1f51de81c8c015b3e103076c Mon Sep 17 00:00:00 2001 From: Anastasiia Sliusar Date: Mon, 20 May 2024 23:31:11 +0200 Subject: [PATCH 07/29] Fix starting kernels --- packages/apputils/src/sessioncontext.tsx | 89 +++++++++---------- .../src/components/customform.tsx | 15 ++-- 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/packages/apputils/src/sessioncontext.tsx b/packages/apputils/src/sessioncontext.tsx index b9866f656744..315a245c1228 100644 --- a/packages/apputils/src/sessioncontext.tsx +++ b/packages/apputils/src/sessioncontext.tsx @@ -26,7 +26,7 @@ import { ISignal, Signal } from '@lumino/signaling'; import { Widget } from '@lumino/widgets'; import * as React from 'react'; import { Dialog, showDialog } from './dialog'; -import { DialogWidget, ReactWidget } from '@jupyterlab/ui-components'; +import { DialogWidget } from '@jupyterlab/ui-components'; import { IRenderMime } from '@jupyterlab/rendermime-interfaces'; /** @@ -298,11 +298,7 @@ export namespace ISessionContext { /** * Kernel custom specs defined by kernel name */ - customKernelSpecs?: - | { - [key: string]: undefined | PartialJSONObject | {}; - } - | undefined; + customKernelSpecs?: undefined | PartialJSONObject | {}; } export type KernelDisplayStatus = @@ -739,6 +735,9 @@ export class SessionContext implements ISessionContext { */ async restartKernel(): Promise { const kernel = this.session?.kernel || null; + + console.log('restrating kernel'); + console.dir(kernel); if (this._isRestarting) { return; } @@ -1398,22 +1397,31 @@ export class SessionContextDialogs implements ISessionContext.IDialogs { }); const result = await dialog.launch(); + if (sessionContext.isDisposed || !result.button.accept) { return; } - // - const model = result.value; + + const dialogResult = result.value as Kernel.IModel; + + if (dialogResult) { + const model = { + 'name': dialogResult.name + } if (hasCheckbox && result.isChecked !== null) { - // if there is a new kernel than kernel custom specs should be deleted if ( model && - sessionContext.kernelPreference?.customKernelSpecs && - !sessionContext.kernelPreference?.customKernelSpecs[model.name] + sessionContext.kernelPreference?.customKernelSpecs ) { sessionContext.kernelPreference.customKernelSpecs = undefined; } + + if(model && dialogResult.custom_kernel_specs){ + sessionContext.kernelPreference.customKernelSpecs = dialogResult.custom_kernel_specs; + } + sessionContext.kernelPreference = { ...sessionContext.kernelPreference, autoStartDefault: result.isChecked @@ -1423,12 +1431,11 @@ export class SessionContextDialogs implements ISessionContext.IDialogs { if (model === null && !sessionContext.hasNoKernel) { return sessionContext.shutdown(); } - console.log('model'); - console.dir(model); if (model) { await sessionContext.changeKernel(model); } } + } /** * Restart the session. @@ -1496,21 +1503,24 @@ namespace Private { * A widget that provides a kernel selection. */ export class KernelSelector extends Widget { - kernelSpecWidget: Widget; /** * Create a new kernel selector widget. */ constructor(sessionContext: ISessionContext, translator?: ITranslator) { super({ node: createSelectorNode(sessionContext, translator) }); - this.kernelSpecWidget; } /** * Get the value of the kernel selector widget. */ getValue(): Kernel.IModel { - const selector = this.node.querySelector('select') as HTMLSelectElement; - return JSON.parse(selector.value) as Kernel.IModel; + const selector = this.node.querySelector('select#js-kernel-selector') as HTMLSelectElement; + const selectorKernelSpecs = selector.getAttribute('data-kernel-spec'); + let kernelData = JSON.parse(selector.value) as Kernel.IModel; + if(selectorKernelSpecs){ + kernelData['custom_kernel_specs'] = JSON.parse(selectorKernelSpecs) ; + } + return kernelData; } } @@ -1569,68 +1579,53 @@ namespace Private { body: HTMLDivElement, trans: IRenderMime.TranslationBundle ) { + let kernelConfiguration: PartialJSONObject = {}; let kernelSelect = document.querySelector( - 'selector#js-kernel-selector' + 'select#js-kernel-selector' ) as HTMLSelectElement; - console.log(`kernelSelect`); - console.dir(kernelSelect); - - let selectedKernel = kernelSelect.value; - - console.log(`selectedKernel-->${selectedKernel}`); - - //clear - // body.querySelector("#js-kernel-custom-kernel-selector-container")?.remove(); - + let selectedKernel =JSON.parse(kernelSelect.value) as Kernel.IModel; const kernelSelectorContainer = document.querySelector( '#js-kernel-selector-container' ); - console.log(`kernelSelectorContainer`); - console.dir(kernelSelectorContainer); - - // let test; const kernelSpecsContainer = document.querySelector( '#js-kernel-specs-selector-container' ) as HTMLElement; - console.log(`kernelSpecsContainer`); - console.dir(kernelSpecsContainer); + let kernelName = selectedKernel && selectedKernel.name ? selectedKernel.name : '' let kernel = - selectedKernel && - sessionContext.specsManager.specs?.kernelspecs[selectedKernel]; + kernelName && + sessionContext.specsManager.specs?.kernelspecs[kernelName]; if (kernel && kernel?.metadata && kernel?.metadata?.parameters) { - console.log(`sessioncontext parameters`); let kernelParameters = kernel?.metadata?.parameters as PartialJSONObject; if (kernelParameters) { - console.log(`kernelParameters`); - console.dir(kernelParameters); //clean preavious a custom kernel specs selector - if (this.kernelSpecsContainer) { - Widget.detach(this.kernelSpecWidget); - } + // if (this.kernelSpecWidget) { + // Widget.detach(this.kernelSpecWidget); + // } //hide selector for kernels if (kernelSelectorContainer) { kernelSelectorContainer.setAttribute('style', 'display: none;'); } - let kernelConfigurarion: PartialJSONObject = {}; - this.kernelSpecWidget = new DialogWidget( + + let kernelSpecWidget = new DialogWidget( kernelParameters, - kernelConfigurarion, + kernelConfiguration, formData => { - kernelConfigurarion = formData as PartialJSONObject; + kernelConfiguration = formData as PartialJSONObject; + kernelSelect.setAttribute('data-kernel-spec', JSON.stringify(kernelConfiguration)); }, trans ); //Update widget if (kernelSpecsContainer) { - Widget.attach(this.kernelSpecWidget, kernelSpecsContainer); + Widget.attach(kernelSpecWidget, kernelSpecsContainer); } } } diff --git a/packages/ui-components/src/components/customform.tsx b/packages/ui-components/src/components/customform.tsx index 5c8d7f0535cf..17e494f8feba 100644 --- a/packages/ui-components/src/components/customform.tsx +++ b/packages/ui-components/src/components/customform.tsx @@ -25,13 +25,14 @@ const FormComponentWrapper = (props: { }): JSX.Element => { const [errorList, setErrors] = useState(); + const [isUpdate, setUpdate] = useState(0); const formRef = createRef() as RefObject>; const onError = (errors: any) => { - setErrors(errors) console.log('errors'); - console.log("errors"); + console.log(errors); + setErrors(errors); }; const uiSchema: UiSchema = { 'ui:options': { @@ -48,10 +49,15 @@ const FormComponentWrapper = (props: { // if (formRef.current && formRef.current.validateForm()) { console.log('onChange and errorList'); console.dir(errorList); - if (!errorList) { - console.log('update data'); + if(!isUpdate) { props.updateFormData(formData); } + if (formRef.current && formRef?.current.validateForm()) { + console.log('update datallll'); + props.updateFormData(formData); + } + let update = isUpdate+1; + setUpdate(update); // } }; @@ -64,7 +70,6 @@ const FormComponentWrapper = (props: { uiSchema={uiSchema} validator={validator} onChange={onChange} - liveValidate ref={formRef} onError={onError} idPrefix={`jp-CustomKernel-test`} From 4fe58f60e13814c45df12bc5930b7627df1fa109 Mon Sep 17 00:00:00 2001 From: Anastasiia Sliusar Date: Fri, 24 May 2024 17:23:45 +0200 Subject: [PATCH 08/29] Set custom kernel variables into metadata --- packages/notebook/src/panel.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/notebook/src/panel.ts b/packages/notebook/src/panel.ts index 9e8f08766ddd..8263cb090381 100644 --- a/packages/notebook/src/panel.ts +++ b/packages/notebook/src/panel.ts @@ -253,10 +253,12 @@ export class NotebookPanel extends DocumentWidget { if (this.isDisposed) { return; } + let customKernelSpecs = this.context.sessionContext.kernelPreference?.customKernelSpecs; this.model!.setMetadata('kernelspec', { name: kernel.name, display_name: spec?.display_name, - language: spec?.language + language: spec?.language, + ...customKernelSpecs ? { customKernelSpecs: customKernelSpecs}: {} }); } From 6a27c011b062d3c5396f5f16858e2567a6e3f074 Mon Sep 17 00:00:00 2001 From: Anastasiia Sliusar Date: Tue, 28 May 2024 10:58:32 +0200 Subject: [PATCH 09/29] Fix running a kernel by using metadata with custom kernel specs --- packages/docregistry/src/context.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/packages/docregistry/src/context.ts b/packages/docregistry/src/context.ts index bb2556ab72b8..aa121bc9cdd5 100644 --- a/packages/docregistry/src/context.ts +++ b/packages/docregistry/src/context.ts @@ -23,7 +23,7 @@ import { TranslationBundle } from '@jupyterlab/translation'; -import { PartialJSONValue, PromiseDelegate } from '@lumino/coreutils'; +import { PartialJSONObject, PartialJSONValue, PromiseDelegate } from '@lumino/coreutils'; import { DisposableDelegate, IDisposable } from '@lumino/disposable'; import { ISignal, Signal } from '@lumino/signaling'; import { Widget } from '@lumino/widgets'; @@ -528,7 +528,7 @@ export class Context< /** * Handle an initial population. */ - private async _populate(): Promise { + private async _populate(customKernelSpecs?:undefined | PartialJSONObject | {}): Promise { this._isPopulated = true; this._isReady = true; this._populatedPromise.resolve(void 0); @@ -538,6 +538,11 @@ export class Context< if (this.isDisposed) { return; } + + if ((!customKernelSpecs || Object.keys(customKernelSpecs).length === 0) && this.sessionContext.kernelPreference.customKernelSpecs) { + customKernelSpecs = this.sessionContext.kernelPreference.customKernelSpecs; + } + // Update the kernel preference. const name = this._model.defaultKernelName || @@ -545,7 +550,8 @@ export class Context< this.sessionContext.kernelPreference = { ...this.sessionContext.kernelPreference, name, - language: this._model.defaultKernelLanguage + language: this._model.defaultKernelLanguage, + customKernelSpecs: customKernelSpecs }; // Note: we don't wait on the session to initialize // so that the user can be shown the content before @@ -642,10 +648,14 @@ export class Context< return this._manager.contents.get(path, opts); }) .then(contents => { + let customKernelSpecs = {}; if (this.isDisposed) { return; } if (contents.content) { + if (contents.content.metadata && contents.content.metadata.kernelspec && contents.content.metadata.kernelspec.customKernelSpecs) { + customKernelSpecs = contents.content.metadata.kernelspec.customKernelSpecs; + } if (contents.format === 'json') { model.fromJSON(contents.content); } else { @@ -668,7 +678,7 @@ export class Context< this._updateContentsModel(contents); model.dirty = false; if (!this._isPopulated) { - return this._populate(); + return this._populate(customKernelSpecs); } }) .catch(async err => { From 0272d695f4d1e00332a4689ebab779cab46bcbd2 Mon Sep 17 00:00:00 2001 From: Anastasiia Sliusar Date: Fri, 31 May 2024 11:52:47 +0200 Subject: [PATCH 10/29] Fix saving custom kernel params into metadata --- packages/notebook/src/panel.ts | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/packages/notebook/src/panel.ts b/packages/notebook/src/panel.ts index 8263cb090381..76ad0f3622bf 100644 --- a/packages/notebook/src/panel.ts +++ b/packages/notebook/src/panel.ts @@ -12,7 +12,7 @@ import { PageConfig } from '@jupyterlab/coreutils'; import { DocumentRegistry, DocumentWidget } from '@jupyterlab/docregistry'; import { Kernel, KernelMessage, Session } from '@jupyterlab/services'; import { ITranslator } from '@jupyterlab/translation'; -import { Token } from '@lumino/coreutils'; +import { PartialJSONObject, Token } from '@lumino/coreutils'; import { INotebookModel } from './model'; import { Notebook, StaticNotebook } from './widget'; import { Message } from '@lumino/messaging'; @@ -253,12 +253,36 @@ export class NotebookPanel extends DocumentWidget { if (this.isDisposed) { return; } - let customKernelSpecs = this.context.sessionContext.kernelPreference?.customKernelSpecs; + + let customKernelSpecs = this.context.sessionContext.kernelPreference + ?.customKernelSpecs as PartialJSONObject; + let data = {} as PartialJSONObject; + + if ( + customKernelSpecs && + spec && + spec?.metadata && + spec?.metadata?.parameters + ) { + let kernelParameters = spec?.metadata?.parameters as PartialJSONObject; + for (let key in customKernelSpecs) { + let properties = kernelParameters.properties as PartialJSONObject; + let kernelParameter = properties[key] as PartialJSONObject; + + if (kernelParameter && kernelParameter?.save) { + + let item = customKernelSpecs[key] as PartialJSONObject | {}; + + data[key] = item; + } + } + } + this.model!.setMetadata('kernelspec', { name: kernel.name, display_name: spec?.display_name, language: spec?.language, - ...customKernelSpecs ? { customKernelSpecs: customKernelSpecs}: {} + ...Object.keys(data).length ? { customKernelSpecs: data}: {} }); } From 493f05d8b17f70c7fb5b356f7e973a52146d4a9d Mon Sep 17 00:00:00 2001 From: Anastasiia Sliusar Date: Tue, 4 Jun 2024 17:33:11 +0200 Subject: [PATCH 11/29] Setup a dialog window to a Console panel on Launcher --- packages/apputils/src/sessioncontext.tsx | 8 --- packages/console-extension/package.json | 3 +- packages/console-extension/src/index.ts | 67 +++++++++++++++++++++++- packages/console/src/panel.ts | 8 +-- 4 files changed, 72 insertions(+), 14 deletions(-) diff --git a/packages/apputils/src/sessioncontext.tsx b/packages/apputils/src/sessioncontext.tsx index 315a245c1228..c88b9aa8066f 100644 --- a/packages/apputils/src/sessioncontext.tsx +++ b/packages/apputils/src/sessioncontext.tsx @@ -1603,14 +1603,6 @@ namespace Private { if (kernelParameters) { //clean preavious a custom kernel specs selector - // if (this.kernelSpecWidget) { - // Widget.detach(this.kernelSpecWidget); - // } - - //hide selector for kernels - if (kernelSelectorContainer) { - kernelSelectorContainer.setAttribute('style', 'display: none;'); - } let kernelSpecWidget = new DialogWidget( diff --git a/packages/console-extension/package.json b/packages/console-extension/package.json index 85c47a9e4125..218561fa4bfc 100644 --- a/packages/console-extension/package.json +++ b/packages/console-extension/package.json @@ -53,7 +53,8 @@ "@lumino/coreutils": "^2.1.2", "@lumino/disposable": "^2.1.2", "@lumino/properties": "^2.0.1", - "@lumino/widgets": "^2.3.2" + "@lumino/widgets": "^2.3.2", + "@rjsf/utils": "^5.13.4" }, "devDependencies": { "rimraf": "~5.0.5", diff --git a/packages/console-extension/src/index.ts b/packages/console-extension/src/index.ts index cb98a2e93c8b..58981d14a520 100644 --- a/packages/console-extension/src/index.ts +++ b/packages/console-extension/src/index.ts @@ -42,6 +42,7 @@ import { ISettingRegistry } from '@jupyterlab/settingregistry'; import { ITranslator, nullTranslator } from '@jupyterlab/translation'; import { consoleIcon, + DialogWidget, IFormRendererRegistry, redoIcon, undoIcon @@ -50,6 +51,8 @@ import { find } from '@lumino/algorithm'; import { JSONExt, JSONObject, + PartialJSONObject, + ReadonlyJSONObject, ReadonlyJSONValue, ReadonlyPartialJSONObject, UUID @@ -58,6 +61,7 @@ import { DisposableSet } from '@lumino/disposable'; import { DockLayout, Widget } from '@lumino/widgets'; import foreign from './foreign'; import { cellExecutor } from './cellexecutor'; +import type { RJSFSchema } from '@rjsf/utils'; /** * The command IDs used by the console plugin. @@ -276,6 +280,51 @@ async function activateConsole( const sessionDialogs = sessionDialogs_ ?? new SessionContextDialogs({ translator }); + const showKernelSpecDialog = async ( + parameters: RJSFSchema, + basePath: string, + args: ReadonlyPartialJSONObject + ) => { + let newArgs = { ...args }; + let kernelConfigurarion: PartialJSONObject = {}; + let label = trans.__('Cancel'); + const buttons = [ + Dialog.cancelButton({ + label + }), + Dialog.okButton({ + label: trans.__('Select'), + ariaLabel: trans.__('Select Kernel') + }) + ]; + + const dialog = new Dialog({ + title: trans.__('Select Kernel'), + body: new DialogWidget( + parameters, + kernelConfigurarion, + formData => { + kernelConfigurarion = formData as PartialJSONObject; + }, + trans + ), + buttons + }); + + const result = await dialog.launch(); + + if (!result.button.accept) { + return; + } + if (result.value) { + if (kernelConfigurarion) { + let customKernelSpecs = { customKernelSpecs: kernelConfigurarion } + newArgs['kernelPreference'] = customKernelSpecs; + } + return createConsole({ basePath, ...newArgs }); + } + }; + // Create a widget tracker for all console panels. const tracker = new WidgetTracker({ namespace: 'console' @@ -320,7 +369,11 @@ async function activateConsole( disposables.add( launcher.add({ command: CommandIDs.create, - args: { isLauncher: true, kernelPreference: { name } }, + args: { + isLauncher: true, + kernelPreference: { name }, + metadata: spec.metadata as ReadonlyJSONObject + }, category: trans.__('Console'), rank, kernelIconUrl, @@ -517,6 +570,9 @@ async function activateConsole( return item.path === path; }); if (model) { + // + //console.log('open console args'); + //console.dir(args); return createConsole(args); } return Promise.reject(`No running kernel session for path: ${path}`); @@ -548,7 +604,14 @@ async function activateConsole( (args['cwd'] as string) || filebrowser?.model.path) ?? ''; - return createConsole({ basePath, ...args }); + // + const metadata = args['metadata'] as ReadonlyJSONObject; + if (metadata?.parameters) { + let schema = metadata.parameters as RJSFSchema; + return showKernelSpecDialog(schema, basePath, args); + } else { + return createConsole({ basePath, ...args }); + } } }); diff --git a/packages/console/src/panel.ts b/packages/console/src/panel.ts index 795d3dea09f5..c1195899ad75 100644 --- a/packages/console/src/panel.ts +++ b/packages/console/src/panel.ts @@ -87,12 +87,14 @@ export class ConsolePanel extends MainAreaWidget { translator }); this.content.addWidget(this.console); - void sessionContext.initialize().then(async value => { if (value) { - await ( + let dialog = await ( options.sessionDialogs ?? new SessionContextDialogs({ translator }) - ).selectKernel(sessionContext!); + ); + if (options.kernelPreference && !options.kernelPreference.customKernelSpecs ) { + dialog.selectKernel(sessionContext!); + } } this._connected = new Date(); this._updateTitlePanel(); From 5fa63a6aceb4de59023cc5849435ce1587ccca70 Mon Sep 17 00:00:00 2001 From: Anastasiia Sliusar Date: Thu, 6 Jun 2024 20:13:07 +0200 Subject: [PATCH 12/29] Running a console with a kernel, fix a dialog window --- packages/apputils/src/sessioncontext.tsx | 13 ++++--------- packages/console-extension/src/index.ts | 11 ++++++++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/apputils/src/sessioncontext.tsx b/packages/apputils/src/sessioncontext.tsx index c88b9aa8066f..9c7457d1cdbf 100644 --- a/packages/apputils/src/sessioncontext.tsx +++ b/packages/apputils/src/sessioncontext.tsx @@ -701,7 +701,7 @@ export class SessionContext implements ISessionContext { }); if (name) { if (preference.customKernelSpecs) { - options = { + options = { name, custom_kernel_specs: preference.customKernelSpecs }; @@ -1585,25 +1585,20 @@ namespace Private { ) as HTMLSelectElement; let selectedKernel =JSON.parse(kernelSelect.value) as Kernel.IModel; - const kernelSelectorContainer = document.querySelector( - '#js-kernel-selector-container' - ); const kernelSpecsContainer = document.querySelector( '#js-kernel-specs-selector-container' ) as HTMLElement; + kernelSpecsContainer.innerHTML = ''; let kernelName = selectedKernel && selectedKernel.name ? selectedKernel.name : '' let kernel = kernelName && sessionContext.specsManager.specs?.kernelspecs[kernelName]; if (kernel && kernel?.metadata && kernel?.metadata?.parameters) { - let kernelParameters = kernel?.metadata?.parameters as PartialJSONObject; + if (kernelParameters) { - //clean preavious a custom kernel specs selector - - let kernelSpecWidget = new DialogWidget( kernelParameters, @@ -1630,7 +1625,7 @@ namespace Private { options: SessionContext.IKernelSearch ): string | null { const { specs, preference } = options; - const { name, language, canStart, autoStartDefault } = preference; + const { name, language, canStart, autoStartDefault } = preference; if (!specs || canStart === false) { return null; diff --git a/packages/console-extension/src/index.ts b/packages/console-extension/src/index.ts index 58981d14a520..280e21723ba6 100644 --- a/packages/console-extension/src/index.ts +++ b/packages/console-extension/src/index.ts @@ -318,10 +318,15 @@ async function activateConsole( } if (result.value) { if (kernelConfigurarion) { - let customKernelSpecs = { customKernelSpecs: kernelConfigurarion } - newArgs['kernelPreference'] = customKernelSpecs; + if (args.kernelPreference) { + let kernelPreference = args.kernelPreference as ReadonlyPartialJSONObject; + newArgs['kernelPreference'] = { + ...kernelPreference, + customKernelSpecs: kernelConfigurarion + }; + } } - return createConsole({ basePath, ...newArgs }); + return createConsole({ basePath, ...newArgs }); } }; From 939d34b3786f8e6ef8be2d4d6109dfff9a68a162 Mon Sep 17 00:00:00 2001 From: Anastasiia Sliusar Date: Mon, 10 Jun 2024 14:38:56 +0200 Subject: [PATCH 13/29] Fix showing part of a dialog when a kernel is selected by default --- packages/apputils/src/sessioncontext.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/apputils/src/sessioncontext.tsx b/packages/apputils/src/sessioncontext.tsx index 9c7457d1cdbf..c82f4e6c51e0 100644 --- a/packages/apputils/src/sessioncontext.tsx +++ b/packages/apputils/src/sessioncontext.tsx @@ -1571,6 +1571,7 @@ namespace Private { container.append(selector); body.append(container); body.append(kernelSpecsContainer); + checkCustomKernelSpecs(sessionContext, body, trans); return body; } From 42f54bd701255ea0740a505213e1691c0ae5903d Mon Sep 17 00:00:00 2001 From: Anastasiia Sliusar Date: Mon, 10 Jun 2024 20:33:27 +0200 Subject: [PATCH 14/29] Add fixes to a dialog --- packages/apputils/src/sessioncontext.tsx | 58 +++++++++++++++++++----- 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/packages/apputils/src/sessioncontext.tsx b/packages/apputils/src/sessioncontext.tsx index c82f4e6c51e0..764df050da32 100644 --- a/packages/apputils/src/sessioncontext.tsx +++ b/packages/apputils/src/sessioncontext.tsx @@ -1503,11 +1503,25 @@ namespace Private { * A widget that provides a kernel selection. */ export class KernelSelector extends Widget { + sessionContext: ISessionContext; /** * Create a new kernel selector widget. */ constructor(sessionContext: ISessionContext, translator?: ITranslator) { super({ node: createSelectorNode(sessionContext, translator) }); + this.setupDefaultKernelSpecs(translator); + this.sessionContext = sessionContext; + + } + + setupDefaultKernelSpecs(translator: ITranslator | undefined) { + translator = translator || nullTranslator; + const trans = translator.load('jupyterlab'); + if (this.node) { + const selector = this.node.querySelector('select#js-kernel-selector') as HTMLSelectElement; + const kernelSpeccSelectorContainer = this.node.querySelector('div#js-kernel-specs-selector-container') as HTMLDivElement; + checkCustomKernelSpecs(this.sessionContext, selector, trans, kernelSpeccSelectorContainer); + } } /** @@ -1559,7 +1573,7 @@ namespace Private { const selector = document.createElement('select'); selector.setAttribute('id', 'js-kernel-selector'); selector.onchange = () => { - checkCustomKernelSpecs(sessionContext, body, trans); + checkCustomKernelSpecs(sessionContext, selector, trans); }; populateKernelSelect( @@ -1571,25 +1585,45 @@ namespace Private { container.append(selector); body.append(container); body.append(kernelSpecsContainer); - checkCustomKernelSpecs(sessionContext, body, trans); return body; } function checkCustomKernelSpecs( sessionContext: ISessionContext, - body: HTMLDivElement, - trans: IRenderMime.TranslationBundle + selector: HTMLSelectElement, + trans: IRenderMime.TranslationBundle, + kernelSpeccSelectorContainer?: HTMLDivElement ) { let kernelConfiguration: PartialJSONObject = {}; - let kernelSelect = document.querySelector( - 'select#js-kernel-selector' - ) as HTMLSelectElement; + // let kernelSelect = document.querySelector( + // 'select#js-kernel-selector' + // ) as HTMLSelectElement; + let selectedKernel =JSON.parse(selector.value) as Kernel.IModel; - let selectedKernel =JSON.parse(kernelSelect.value) as Kernel.IModel; + console.log('selectedKernel-->'); + console.dir(selectedKernel); - const kernelSpecsContainer = document.querySelector( + // const kernelSpecsContainer = body.querySelector( + // '#js-kernel-specs-selector-container' + // ) as HTMLElement; + + let kernelSpecsContainer = document.querySelector( '#js-kernel-specs-selector-container' - ) as HTMLElement; + ) as HTMLElement; + + console.log('kernelSpecsContainer-->before'); + console.dir(kernelSpecsContainer); + + if (!kernelSpecsContainer && kernelSpeccSelectorContainer) { + kernelSpecsContainer = kernelSpeccSelectorContainer; + } + + console.log('kernelSpecsContainer-->after'); + console.dir(kernelSpecsContainer); + + //console.log('kernelSpecsContainer1-->'); + //console.dir(kernelSpecsContainer1); + kernelSpecsContainer.innerHTML = ''; let kernelName = selectedKernel && selectedKernel.name ? selectedKernel.name : '' @@ -1598,6 +1632,8 @@ namespace Private { sessionContext.specsManager.specs?.kernelspecs[kernelName]; if (kernel && kernel?.metadata && kernel?.metadata?.parameters) { let kernelParameters = kernel?.metadata?.parameters as PartialJSONObject; + console.log('kernelParameters'); + console.dir(kernelParameters); if (kernelParameters) { @@ -1606,7 +1642,7 @@ namespace Private { kernelConfiguration, formData => { kernelConfiguration = formData as PartialJSONObject; - kernelSelect.setAttribute('data-kernel-spec', JSON.stringify(kernelConfiguration)); + selector.setAttribute('data-kernel-spec', JSON.stringify(kernelConfiguration)); }, trans ); From df6e8f474d0f543d887d555d566ad5fcdf17806c Mon Sep 17 00:00:00 2001 From: Anastasiia Sliusar Date: Tue, 11 Jun 2024 13:52:01 +0200 Subject: [PATCH 15/29] Fix a dialog window for selecting a kernel --- packages/apputils/src/sessioncontext.tsx | 30 ++++++++---------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/packages/apputils/src/sessioncontext.tsx b/packages/apputils/src/sessioncontext.tsx index 764df050da32..4e7b78646dc3 100644 --- a/packages/apputils/src/sessioncontext.tsx +++ b/packages/apputils/src/sessioncontext.tsx @@ -28,6 +28,7 @@ import * as React from 'react'; import { Dialog, showDialog } from './dialog'; import { DialogWidget } from '@jupyterlab/ui-components'; import { IRenderMime } from '@jupyterlab/rendermime-interfaces'; +import { Message } from '@lumino/messaging'; /** * A context object to manage a widget's kernel session connection. @@ -1504,23 +1505,28 @@ namespace Private { */ export class KernelSelector extends Widget { sessionContext: ISessionContext; + translator: ITranslator | undefined; /** * Create a new kernel selector widget. */ constructor(sessionContext: ISessionContext, translator?: ITranslator) { super({ node: createSelectorNode(sessionContext, translator) }); - this.setupDefaultKernelSpecs(translator); - this.sessionContext = sessionContext; + this.sessionContext = sessionContext; + this.translator = translator; + } + protected onAfterAttach(msg: Message): void { + super.onAfterAttach(msg); + this.setupDefaultKernelSpecs(this.sessionContext, this.translator); } - setupDefaultKernelSpecs(translator: ITranslator | undefined) { + setupDefaultKernelSpecs(sessionContext: ISessionContext, translator: ITranslator | undefined) { translator = translator || nullTranslator; const trans = translator.load('jupyterlab'); if (this.node) { const selector = this.node.querySelector('select#js-kernel-selector') as HTMLSelectElement; const kernelSpeccSelectorContainer = this.node.querySelector('div#js-kernel-specs-selector-container') as HTMLDivElement; - checkCustomKernelSpecs(this.sessionContext, selector, trans, kernelSpeccSelectorContainer); + checkCustomKernelSpecs(sessionContext, selector, trans, kernelSpeccSelectorContainer); } } @@ -1595,18 +1601,8 @@ namespace Private { kernelSpeccSelectorContainer?: HTMLDivElement ) { let kernelConfiguration: PartialJSONObject = {}; - // let kernelSelect = document.querySelector( - // 'select#js-kernel-selector' - // ) as HTMLSelectElement; let selectedKernel =JSON.parse(selector.value) as Kernel.IModel; - console.log('selectedKernel-->'); - console.dir(selectedKernel); - - // const kernelSpecsContainer = body.querySelector( - // '#js-kernel-specs-selector-container' - // ) as HTMLElement; - let kernelSpecsContainer = document.querySelector( '#js-kernel-specs-selector-container' ) as HTMLElement; @@ -1618,12 +1614,6 @@ namespace Private { kernelSpecsContainer = kernelSpeccSelectorContainer; } - console.log('kernelSpecsContainer-->after'); - console.dir(kernelSpecsContainer); - - //console.log('kernelSpecsContainer1-->'); - //console.dir(kernelSpecsContainer1); - kernelSpecsContainer.innerHTML = ''; let kernelName = selectedKernel && selectedKernel.name ? selectedKernel.name : '' From 434718f222840c4321530fa9d620afb1a9d2727b Mon Sep 17 00:00:00 2001 From: Anastasiia Sliusar Date: Fri, 14 Jun 2024 19:27:26 +0200 Subject: [PATCH 16/29] Fix selecting parameterized kernels --- packages/apputils/src/sessioncontext.tsx | 54 +++++++++++++++++++++--- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/packages/apputils/src/sessioncontext.tsx b/packages/apputils/src/sessioncontext.tsx index 4e7b78646dc3..4409dbf20990 100644 --- a/packages/apputils/src/sessioncontext.tsx +++ b/packages/apputils/src/sessioncontext.tsx @@ -18,6 +18,7 @@ import { find } from '@lumino/algorithm'; import { JSONExt, PartialJSONObject, + PartialJSONValue, PromiseDelegate, UUID } from '@lumino/coreutils'; @@ -1407,8 +1408,9 @@ export class SessionContextDialogs implements ISessionContext.IDialogs { const dialogResult = result.value as Kernel.IModel; if (dialogResult) { - const model = { - 'name': dialogResult.name + let model = { + 'name': dialogResult.name, + 'custom_kernel_specs': {} } if (hasCheckbox && result.isChecked !== null) { @@ -1421,6 +1423,7 @@ export class SessionContextDialogs implements ISessionContext.IDialogs { if(model && dialogResult.custom_kernel_specs){ sessionContext.kernelPreference.customKernelSpecs = dialogResult.custom_kernel_specs; + model['custom_kernel_specs'] = dialogResult.custom_kernel_specs; } sessionContext.kernelPreference = { @@ -1525,6 +1528,9 @@ namespace Private { const trans = translator.load('jupyterlab'); if (this.node) { const selector = this.node.querySelector('select#js-kernel-selector') as HTMLSelectElement; + selector.setAttribute( + 'data-kernel-spec', '' + ); const kernelSpeccSelectorContainer = this.node.querySelector('div#js-kernel-specs-selector-container') as HTMLDivElement; checkCustomKernelSpecs(sessionContext, selector, trans, kernelSpeccSelectorContainer); } @@ -1536,6 +1542,8 @@ namespace Private { getValue(): Kernel.IModel { const selector = this.node.querySelector('select#js-kernel-selector') as HTMLSelectElement; const selectorKernelSpecs = selector.getAttribute('data-kernel-spec'); + console.log("selectorKernelSpecs"); + console.dir(selectorKernelSpecs); let kernelData = JSON.parse(selector.value) as Kernel.IModel; if(selectorKernelSpecs){ kernelData['custom_kernel_specs'] = JSON.parse(selectorKernelSpecs) ; @@ -1622,17 +1630,53 @@ namespace Private { sessionContext.specsManager.specs?.kernelspecs[kernelName]; if (kernel && kernel?.metadata && kernel?.metadata?.parameters) { let kernelParameters = kernel?.metadata?.parameters as PartialJSONObject; - console.log('kernelParameters'); + console.log('kernelParameters before'); console.dir(kernelParameters); if (kernelParameters) { - + if (sessionContext.kernelPreference?.customKernelSpecs) { + console.log('sessionContext.kernelPreference?.customKernelSpecs yes'); + let customKernelSpecs = sessionContext.kernelPreference + ?.customKernelSpecs as PartialJSONObject; + console.log('customKernelSpecs'); + console.dir(customKernelSpecs); + for (let key in customKernelSpecs) { + console.log('key'); + console.dir(key); + let selectedValue = customKernelSpecs[key] as PartialJSONValue | undefined; + console.log('selectedValue'); + console.dir(selectedValue); + if (kernelParameters.properties) { + let properties = kernelParameters.properties as PartialJSONObject; + console.log('properties'); + console.dir(properties); + let kernelParameter = properties[key] as PartialJSONObject; + console.log('kernelParameter'); + console.dir(kernelParameter); + if (kernelParameter) { + console.log('in if'); + console.log('selectedValue'); + console.dir(selectedValue); + let kernelParametersTmp = (kernelParameters.properties as PartialJSONObject)[key] as PartialJSONObject; + (kernelParameters.properties as PartialJSONObject)[key] = {... kernelParametersTmp, default: selectedValue } + } + } + } + } + console.log('kernelParameters after'); + console.dir(kernelParameters); + let kernelSpecWidget = new DialogWidget( kernelParameters, kernelConfiguration, formData => { + console.log('formData'); + console.dir(formData); kernelConfiguration = formData as PartialJSONObject; - selector.setAttribute('data-kernel-spec', JSON.stringify(kernelConfiguration)); + selector.setAttribute( + 'data-kernel-spec', + JSON.stringify(kernelConfiguration) + ); }, trans ); From fcfc13d2356d4711ca2c3fc72fc58d3a55f82110 Mon Sep 17 00:00:00 2001 From: Anastasiia Sliusar Date: Fri, 14 Jun 2024 22:49:26 +0200 Subject: [PATCH 17/29] Clean console.log and console.dir --- packages/apputils/src/sessioncontext.tsx | 38 ++----------------- packages/docmanager/src/manager.ts | 5 --- .../src/customKernelWidget.tsx | 2 - packages/notebook-extension/src/index.ts | 10 ----- packages/services/src/session/default.ts | 2 - packages/services/src/session/restapi.ts | 6 --- .../src/components/customform.tsx | 4 -- 7 files changed, 3 insertions(+), 64 deletions(-) diff --git a/packages/apputils/src/sessioncontext.tsx b/packages/apputils/src/sessioncontext.tsx index 4409dbf20990..04fc528172a3 100644 --- a/packages/apputils/src/sessioncontext.tsx +++ b/packages/apputils/src/sessioncontext.tsx @@ -686,7 +686,6 @@ export class SessionContext implements ISessionContext { const preference = this.kernelPreference; const specs = this.specsManager.specs; // - console.log('startKernel - options'); if (!preference.autoStartDefault && preference.shouldStart === false) { return true; } @@ -695,7 +694,6 @@ export class SessionContext implements ISessionContext { if (preference.id) { options = { id: preference.id }; } else { - console.log('getDefaultKernel'); const name = Private.getDefaultKernel({ specs, sessions: this.sessionManager.running(), @@ -713,9 +711,6 @@ export class SessionContext implements ISessionContext { } } - console.dir(options); - console.dir(preference); - console.log('end startKernel - options'); if (options) { try { @@ -738,8 +733,6 @@ export class SessionContext implements ISessionContext { async restartKernel(): Promise { const kernel = this.session?.kernel || null; - console.log('restrating kernel'); - console.dir(kernel); if (this._isRestarting) { return; } @@ -918,9 +911,6 @@ export class SessionContext implements ISessionContext { this._pendingKernelName = model.name; } - console.log('_changeKernel'); - console.dir(model); - if (!this._session) { this._kernelChanged.emit({ name: 'kernel', @@ -1542,8 +1532,6 @@ namespace Private { getValue(): Kernel.IModel { const selector = this.node.querySelector('select#js-kernel-selector') as HTMLSelectElement; const selectorKernelSpecs = selector.getAttribute('data-kernel-spec'); - console.log("selectorKernelSpecs"); - console.dir(selectorKernelSpecs); let kernelData = JSON.parse(selector.value) as Kernel.IModel; if(selectorKernelSpecs){ kernelData['custom_kernel_specs'] = JSON.parse(selectorKernelSpecs) ; @@ -1615,9 +1603,6 @@ namespace Private { '#js-kernel-specs-selector-container' ) as HTMLElement; - console.log('kernelSpecsContainer-->before'); - console.dir(kernelSpecsContainer); - if (!kernelSpecsContainer && kernelSpeccSelectorContainer) { kernelSpecsContainer = kernelSpeccSelectorContainer; } @@ -1630,48 +1615,31 @@ namespace Private { sessionContext.specsManager.specs?.kernelspecs[kernelName]; if (kernel && kernel?.metadata && kernel?.metadata?.parameters) { let kernelParameters = kernel?.metadata?.parameters as PartialJSONObject; - console.log('kernelParameters before'); - console.dir(kernelParameters); if (kernelParameters) { if (sessionContext.kernelPreference?.customKernelSpecs) { - console.log('sessionContext.kernelPreference?.customKernelSpecs yes'); let customKernelSpecs = sessionContext.kernelPreference ?.customKernelSpecs as PartialJSONObject; - console.log('customKernelSpecs'); - console.dir(customKernelSpecs); for (let key in customKernelSpecs) { - console.log('key'); - console.dir(key); let selectedValue = customKernelSpecs[key] as PartialJSONValue | undefined; - console.log('selectedValue'); - console.dir(selectedValue); + if (kernelParameters.properties) { let properties = kernelParameters.properties as PartialJSONObject; - console.log('properties'); - console.dir(properties); + let kernelParameter = properties[key] as PartialJSONObject; - console.log('kernelParameter'); - console.dir(kernelParameter); + if (kernelParameter) { - console.log('in if'); - console.log('selectedValue'); - console.dir(selectedValue); let kernelParametersTmp = (kernelParameters.properties as PartialJSONObject)[key] as PartialJSONObject; (kernelParameters.properties as PartialJSONObject)[key] = {... kernelParametersTmp, default: selectedValue } } } } } - console.log('kernelParameters after'); - console.dir(kernelParameters); let kernelSpecWidget = new DialogWidget( kernelParameters, kernelConfiguration, formData => { - console.log('formData'); - console.dir(formData); kernelConfiguration = formData as PartialJSONObject; selector.setAttribute( 'data-kernel-spec', diff --git a/packages/docmanager/src/manager.ts b/packages/docmanager/src/manager.ts index ff0431181878..b02045a3f356 100644 --- a/packages/docmanager/src/manager.ts +++ b/packages/docmanager/src/manager.ts @@ -651,11 +651,6 @@ export class DocumentManager implements IDocumentManager { kernel ); - console.log('_createOrOpenDocument--preference'); - console.dir(preference); - - console.log('_createOrOpenDocument-kernel'); - console.dir(kernel); let context: Private.IContext | null; let ready: Promise = Promise.resolve(undefined); diff --git a/packages/notebook-extension/src/customKernelWidget.tsx b/packages/notebook-extension/src/customKernelWidget.tsx index e4db6bfdca6a..4086dea75410 100644 --- a/packages/notebook-extension/src/customKernelWidget.tsx +++ b/packages/notebook-extension/src/customKernelWidget.tsx @@ -71,8 +71,6 @@ export class DialogWidget extends ReactWidget { } getValue(): FormDataProps | {} { - console.log(`kernelConfigurarion`); - console.dir(this.kernelConfigurarion); return this.kernelConfigurarion; } diff --git a/packages/notebook-extension/src/index.ts b/packages/notebook-extension/src/index.ts index fd236427a92b..5a6d1e27ffb7 100644 --- a/packages/notebook-extension/src/index.ts +++ b/packages/notebook-extension/src/index.ts @@ -1876,18 +1876,10 @@ function activateNotebookHandler( if (!result.button.accept) { return; } - console.log(`result.value`); - console.dir(result.value); if (result.value) { - console.log(`value--kernelConfigurarion`); - console.dir(kernelConfigurarion); let customKernelSpecs = undefined; - // let customKernelName = kernelConfigurarion ? kernelConfigurarion?.cpp_version : kernelName; if(kernelConfigurarion) { customKernelSpecs = kernelConfigurarion; - if (customKernelSpecs.kernelName) { - kernelName = customKernelSpecs.kernelName as string; - } } createNew(cwd, kernelId, kernelName, customKernelSpecs); @@ -2032,8 +2024,6 @@ function activateNotebookHandler( execute: args => { const currentBrowser = filebrowserFactory?.tracker.currentWidget ?? defaultBrowser; - console.log(`args-->${args}`); - console.dir(args); //if has enum then calll const cwd = (args['cwd'] as string) || (currentBrowser?.model.path ?? ''); const kernelId = (args['kernelId'] as string) || ''; diff --git a/packages/services/src/session/default.ts b/packages/services/src/session/default.ts index 2d67573a62ef..05ffeb314043 100644 --- a/packages/services/src/session/default.ts +++ b/packages/services/src/session/default.ts @@ -391,8 +391,6 @@ export class SessionConnection implements Session.ISessionConnection { private async _patch( body: DeepPartial ): Promise { - console.log('_patch-body'); - console.dir(body); const model = await updateSession( { ...body, id: this._id }, this.serverSettings diff --git a/packages/services/src/session/restapi.ts b/packages/services/src/session/restapi.ts index 49464cd274cc..8ff78779477f 100644 --- a/packages/services/src/session/restapi.ts +++ b/packages/services/src/session/restapi.ts @@ -111,10 +111,6 @@ export async function startSession( body: JSON.stringify(options) }; - console.log(`url-->${url}`); - console.log(`options`); - console.dir(options); - const response = await ServerConnection.makeRequest(url, init, settings); if (response.status !== 201) { const err = await ServerConnection.ResponseError.create(response); @@ -135,8 +131,6 @@ export async function updateSession( ): Promise { const url = getSessionUrl(settings.baseUrl, model.id); - console.log('updaye session - model'); - console.dir(model); const init = { method: 'PATCH', body: JSON.stringify(model) diff --git a/packages/ui-components/src/components/customform.tsx b/packages/ui-components/src/components/customform.tsx index 17e494f8feba..6196c8b5ef19 100644 --- a/packages/ui-components/src/components/customform.tsx +++ b/packages/ui-components/src/components/customform.tsx @@ -46,14 +46,10 @@ const FormComponentWrapper = (props: { }; const onChange = ({ formData }: IChangeEvent) => { - // if (formRef.current && formRef.current.validateForm()) { - console.log('onChange and errorList'); - console.dir(errorList); if(!isUpdate) { props.updateFormData(formData); } if (formRef.current && formRef?.current.validateForm()) { - console.log('update datallll'); props.updateFormData(formData); } let update = isUpdate+1; From 2356748836eba3dfe218d640b1d456682501c4c8 Mon Sep 17 00:00:00 2001 From: Anastasiia Sliusar Date: Fri, 14 Jun 2024 23:32:26 +0200 Subject: [PATCH 18/29] minor fix --- packages/ui-components/src/components/customform.tsx | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/packages/ui-components/src/components/customform.tsx b/packages/ui-components/src/components/customform.tsx index 6196c8b5ef19..233672402213 100644 --- a/packages/ui-components/src/components/customform.tsx +++ b/packages/ui-components/src/components/customform.tsx @@ -24,16 +24,10 @@ const FormComponentWrapper = (props: { ) => void; }): JSX.Element => { - const [errorList, setErrors] = useState(); const [isUpdate, setUpdate] = useState(0); const formRef = createRef() as RefObject>; - const onError = (errors: any) => - { - console.log('errors'); - console.log(errors); - setErrors(errors); - }; + const uiSchema: UiSchema = { 'ui:options': { submitButtonOptions: { @@ -67,7 +61,6 @@ const FormComponentWrapper = (props: { validator={validator} onChange={onChange} ref={formRef} - onError={onError} idPrefix={`jp-CustomKernel-test`} showModifiedFromDefault={false} /> From 05c32ca45179a05b71844328cea329d2514599e4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 14 Jun 2024 21:38:57 +0000 Subject: [PATCH 19/29] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- packages/apputils/src/sessioncontext.tsx | 16 ++++++++-------- packages/notebook-extension/src/index.ts | 14 +++++++------- packages/notebook/src/panel.ts | 6 +++--- .../ui-components/src/components/customform.tsx | 4 ++-- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/packages/apputils/src/sessioncontext.tsx b/packages/apputils/src/sessioncontext.tsx index 04fc528172a3..b9d07252201b 100644 --- a/packages/apputils/src/sessioncontext.tsx +++ b/packages/apputils/src/sessioncontext.tsx @@ -1389,19 +1389,19 @@ export class SessionContextDialogs implements ISessionContext.IDialogs { }); const result = await dialog.launch(); - + if (sessionContext.isDisposed || !result.button.accept) { return; } - + const dialogResult = result.value as Kernel.IModel; - + if (dialogResult) { let model = { 'name': dialogResult.name, 'custom_kernel_specs': {} - } + } if (hasCheckbox && result.isChecked !== null) { if ( @@ -1410,7 +1410,7 @@ export class SessionContextDialogs implements ISessionContext.IDialogs { ) { sessionContext.kernelPreference.customKernelSpecs = undefined; } - + if(model && dialogResult.custom_kernel_specs){ sessionContext.kernelPreference.customKernelSpecs = dialogResult.custom_kernel_specs; model['custom_kernel_specs'] = dialogResult.custom_kernel_specs; @@ -1523,7 +1523,7 @@ namespace Private { ); const kernelSpeccSelectorContainer = this.node.querySelector('div#js-kernel-specs-selector-container') as HTMLDivElement; checkCustomKernelSpecs(sessionContext, selector, trans, kernelSpeccSelectorContainer); - } + } } /** @@ -1615,14 +1615,14 @@ namespace Private { sessionContext.specsManager.specs?.kernelspecs[kernelName]; if (kernel && kernel?.metadata && kernel?.metadata?.parameters) { let kernelParameters = kernel?.metadata?.parameters as PartialJSONObject; - + if (kernelParameters) { if (sessionContext.kernelPreference?.customKernelSpecs) { let customKernelSpecs = sessionContext.kernelPreference ?.customKernelSpecs as PartialJSONObject; for (let key in customKernelSpecs) { let selectedValue = customKernelSpecs[key] as PartialJSONValue | undefined; - + if (kernelParameters.properties) { let properties = kernelParameters.properties as PartialJSONObject; diff --git a/packages/notebook-extension/src/index.ts b/packages/notebook-extension/src/index.ts index 5a6d1e27ffb7..f80790149bec 100644 --- a/packages/notebook-extension/src/index.ts +++ b/packages/notebook-extension/src/index.ts @@ -1847,7 +1847,7 @@ function activateNotebookHandler( }); } } - + const showKernelSpecDialog = async (parameters: RJSFSchema, cwd:string, kernelId: string, kernelName:string)=>{ let kernelConfigurarion: PartialJSONObject = {}; let label = trans.__('Cancel'); @@ -1881,7 +1881,7 @@ function activateNotebookHandler( if(kernelConfigurarion) { customKernelSpecs = kernelConfigurarion; } - + createNew(cwd, kernelId, kernelName, customKernelSpecs); } } @@ -2002,7 +2002,7 @@ function activateNotebookHandler( - + // Add a command for creating a new notebook. commands.addCommand(CommandIDs.createNew, { label: args => { @@ -2024,7 +2024,7 @@ function activateNotebookHandler( execute: args => { const currentBrowser = filebrowserFactory?.tracker.currentWidget ?? defaultBrowser; - //if has enum then calll + //if has enum then calll const cwd = (args['cwd'] as string) || (currentBrowser?.model.path ?? ''); const kernelId = (args['kernelId'] as string) || ''; const kernelName = (args['kernelName'] as string) || ''; @@ -2052,14 +2052,14 @@ function activateNotebookHandler( return; } disposables = new DisposableSet(); - + for (const name in specs.kernelspecs) { const rank = name === specs.default ? 0 : Infinity; const spec = specs.kernelspecs[name]!; const kernelIconUrl = spec.resources['logo-svg'] || spec.resources['logo-64x64']; //if has enum then add one icon - + disposables.add( launcher.add({ command: CommandIDs.createNew, @@ -2074,7 +2074,7 @@ function activateNotebookHandler( } }) ); - + } }; onSpecsChanged(); diff --git a/packages/notebook/src/panel.ts b/packages/notebook/src/panel.ts index 76ad0f3622bf..8e703cf2c203 100644 --- a/packages/notebook/src/panel.ts +++ b/packages/notebook/src/panel.ts @@ -268,11 +268,11 @@ export class NotebookPanel extends DocumentWidget { for (let key in customKernelSpecs) { let properties = kernelParameters.properties as PartialJSONObject; let kernelParameter = properties[key] as PartialJSONObject; - + if (kernelParameter && kernelParameter?.save) { - + let item = customKernelSpecs[key] as PartialJSONObject | {}; - + data[key] = item; } } diff --git a/packages/ui-components/src/components/customform.tsx b/packages/ui-components/src/components/customform.tsx index 233672402213..da87f1bb247e 100644 --- a/packages/ui-components/src/components/customform.tsx +++ b/packages/ui-components/src/components/customform.tsx @@ -50,7 +50,7 @@ const FormComponentWrapper = (props: { setUpdate(update); // } }; - + const formData: Record = {}; return ( @@ -98,4 +98,4 @@ export class DialogWidget extends ReactWidget { ); } -} \ No newline at end of file +} From 398b819730adbf2b7ff24317179690202251cacd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 14 Jun 2024 21:40:15 +0000 Subject: [PATCH 20/29] Automatic application of license header --- packages/notebook-extension/src/customKernelWidget.tsx | 5 +++++ packages/ui-components/src/components/customform.tsx | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/packages/notebook-extension/src/customKernelWidget.tsx b/packages/notebook-extension/src/customKernelWidget.tsx index 4086dea75410..6fead99d7c50 100644 --- a/packages/notebook-extension/src/customKernelWidget.tsx +++ b/packages/notebook-extension/src/customKernelWidget.tsx @@ -1,3 +1,8 @@ +/* + * Copyright (c) Jupyter Development Team. + * Distributed under the terms of the Modified BSD License. + */ + import { ReactWidget } from '@jupyterlab/ui-components'; import React from 'react'; diff --git a/packages/ui-components/src/components/customform.tsx b/packages/ui-components/src/components/customform.tsx index da87f1bb247e..3c5212590cbe 100644 --- a/packages/ui-components/src/components/customform.tsx +++ b/packages/ui-components/src/components/customform.tsx @@ -1,3 +1,8 @@ +/* + * Copyright (c) Jupyter Development Team. + * Distributed under the terms of the Modified BSD License. + */ + import React, { RefObject, createRef, useState } from 'react'; import Form, { IChangeEvent } from '@rjsf/core'; import { RJSFSchema, UiSchema } from '@rjsf/utils'; From 1501b2b9188e7f9f7f6ad71dd6c06906975cb2b6 Mon Sep 17 00:00:00 2001 From: Anastasiia Sliusar Date: Mon, 17 Jun 2024 14:54:04 +0200 Subject: [PATCH 21/29] Fix pre-commit errors --- packages/apputils/src/sessioncontext.tsx | 128 ++++++++++-------- packages/console-extension/src/index.ts | 3 +- packages/console/src/panel.ts | 10 +- packages/docmanager/src/manager.ts | 1 - packages/docregistry/src/context.ts | 27 +++- .../src/customKernelWidget.tsx | 31 +++-- packages/notebook-extension/src/index.ts | 116 +++++++++------- packages/notebook/src/panel.ts | 5 +- packages/services/src/kernel/restapi.ts | 2 +- packages/services/src/session/restapi.ts | 1 - .../src/components/customform.tsx | 45 +++--- .../ui-components/src/components/form.tsx | 14 +- 12 files changed, 221 insertions(+), 162 deletions(-) diff --git a/packages/apputils/src/sessioncontext.tsx b/packages/apputils/src/sessioncontext.tsx index b9d07252201b..c32d7837ed7b 100644 --- a/packages/apputils/src/sessioncontext.tsx +++ b/packages/apputils/src/sessioncontext.tsx @@ -300,7 +300,7 @@ export namespace ISessionContext { /** * Kernel custom specs defined by kernel name */ - customKernelSpecs?: undefined | PartialJSONObject | {}; + customKernelSpecs?: undefined | PartialJSONObject; } export type KernelDisplayStatus = @@ -701,7 +701,7 @@ export class SessionContext implements ISessionContext { }); if (name) { if (preference.customKernelSpecs) { - options = { + options = { name, custom_kernel_specs: preference.customKernelSpecs }; @@ -711,7 +711,6 @@ export class SessionContext implements ISessionContext { } } - if (options) { try { await this._changeKernel(options); @@ -1390,7 +1389,6 @@ export class SessionContextDialogs implements ISessionContext.IDialogs { const result = await dialog.launch(); - if (sessionContext.isDisposed || !result.button.accept) { return; } @@ -1398,38 +1396,36 @@ export class SessionContextDialogs implements ISessionContext.IDialogs { const dialogResult = result.value as Kernel.IModel; if (dialogResult) { - let model = { - 'name': dialogResult.name, - 'custom_kernel_specs': {} - } + let model = { + name: dialogResult.name, + custom_kernel_specs: {} + }; - if (hasCheckbox && result.isChecked !== null) { - if ( - model && - sessionContext.kernelPreference?.customKernelSpecs - ) { - sessionContext.kernelPreference.customKernelSpecs = undefined; - } + if (hasCheckbox && result.isChecked !== null) { + if (model && sessionContext.kernelPreference?.customKernelSpecs) { + sessionContext.kernelPreference.customKernelSpecs = undefined; + } - if(model && dialogResult.custom_kernel_specs){ - sessionContext.kernelPreference.customKernelSpecs = dialogResult.custom_kernel_specs; - model['custom_kernel_specs'] = dialogResult.custom_kernel_specs; - } + if (model && dialogResult.custom_kernel_specs) { + sessionContext.kernelPreference.customKernelSpecs = + dialogResult.custom_kernel_specs; + model['custom_kernel_specs'] = dialogResult.custom_kernel_specs; + } - sessionContext.kernelPreference = { - ...sessionContext.kernelPreference, - autoStartDefault: result.isChecked - }; - } + sessionContext.kernelPreference = { + ...sessionContext.kernelPreference, + autoStartDefault: result.isChecked + }; + } - if (model === null && !sessionContext.hasNoKernel) { - return sessionContext.shutdown(); - } - if (model) { - await sessionContext.changeKernel(model); + if (model === null && !sessionContext.hasNoKernel) { + return sessionContext.shutdown(); + } + if (model) { + await sessionContext.changeKernel(model); + } } } - } /** * Restart the session. @@ -1504,8 +1500,8 @@ namespace Private { */ constructor(sessionContext: ISessionContext, translator?: ITranslator) { super({ node: createSelectorNode(sessionContext, translator) }); - this.sessionContext = sessionContext; - this.translator = translator; + this.sessionContext = sessionContext; + this.translator = translator; } protected onAfterAttach(msg: Message): void { @@ -1513,16 +1509,26 @@ namespace Private { this.setupDefaultKernelSpecs(this.sessionContext, this.translator); } - setupDefaultKernelSpecs(sessionContext: ISessionContext, translator: ITranslator | undefined) { + setupDefaultKernelSpecs( + sessionContext: ISessionContext, + translator: ITranslator | undefined + ) { translator = translator || nullTranslator; const trans = translator.load('jupyterlab'); if (this.node) { - const selector = this.node.querySelector('select#js-kernel-selector') as HTMLSelectElement; - selector.setAttribute( - 'data-kernel-spec', '' + const selector = this.node.querySelector( + 'select#js-kernel-selector' + ) as HTMLSelectElement; + selector.setAttribute('data-kernel-spec', ''); + const kernelSpeccSelectorContainer = this.node.querySelector( + 'div#js-kernel-specs-selector-container' + ) as HTMLDivElement; + checkCustomKernelSpecs( + sessionContext, + selector, + trans, + kernelSpeccSelectorContainer ); - const kernelSpeccSelectorContainer = this.node.querySelector('div#js-kernel-specs-selector-container') as HTMLDivElement; - checkCustomKernelSpecs(sessionContext, selector, trans, kernelSpeccSelectorContainer); } } @@ -1530,11 +1536,13 @@ namespace Private { * Get the value of the kernel selector widget. */ getValue(): Kernel.IModel { - const selector = this.node.querySelector('select#js-kernel-selector') as HTMLSelectElement; + const selector = this.node.querySelector( + 'select#js-kernel-selector' + ) as HTMLSelectElement; const selectorKernelSpecs = selector.getAttribute('data-kernel-spec'); let kernelData = JSON.parse(selector.value) as Kernel.IModel; - if(selectorKernelSpecs){ - kernelData['custom_kernel_specs'] = JSON.parse(selectorKernelSpecs) ; + if (selectorKernelSpecs) { + kernelData['custom_kernel_specs'] = JSON.parse(selectorKernelSpecs); } return kernelData; } @@ -1597,22 +1605,21 @@ namespace Private { kernelSpeccSelectorContainer?: HTMLDivElement ) { let kernelConfiguration: PartialJSONObject = {}; - let selectedKernel =JSON.parse(selector.value) as Kernel.IModel; + let selectedKernel = JSON.parse(selector.value) as Kernel.IModel; let kernelSpecsContainer = document.querySelector( '#js-kernel-specs-selector-container' - ) as HTMLElement; + ) as HTMLElement; if (!kernelSpecsContainer && kernelSpeccSelectorContainer) { kernelSpecsContainer = kernelSpeccSelectorContainer; } - kernelSpecsContainer.innerHTML = ''; - let kernelName = selectedKernel && selectedKernel.name ? selectedKernel.name : '' + let kernelName = + selectedKernel && selectedKernel.name ? selectedKernel.name : ''; let kernel = - kernelName && - sessionContext.specsManager.specs?.kernelspecs[kernelName]; + kernelName && sessionContext.specsManager.specs?.kernelspecs[kernelName]; if (kernel && kernel?.metadata && kernel?.metadata?.parameters) { let kernelParameters = kernel?.metadata?.parameters as PartialJSONObject; @@ -1621,19 +1628,26 @@ namespace Private { let customKernelSpecs = sessionContext.kernelPreference ?.customKernelSpecs as PartialJSONObject; for (let key in customKernelSpecs) { - let selectedValue = customKernelSpecs[key] as PartialJSONValue | undefined; + let selectedValue = customKernelSpecs[key] as + | PartialJSONValue + | undefined; if (kernelParameters.properties) { - let properties = kernelParameters.properties as PartialJSONObject; - - let kernelParameter = properties[key] as PartialJSONObject; - - if (kernelParameter) { - let kernelParametersTmp = (kernelParameters.properties as PartialJSONObject)[key] as PartialJSONObject; - (kernelParameters.properties as PartialJSONObject)[key] = {... kernelParametersTmp, default: selectedValue } + let properties = kernelParameters.properties as PartialJSONObject; + + let kernelParameter = properties[key] as PartialJSONObject; + + if (kernelParameter) { + let kernelParametersTmp = ( + kernelParameters.properties as PartialJSONObject + )[key] as PartialJSONObject; + (kernelParameters.properties as PartialJSONObject)[key] = { + ...kernelParametersTmp, + default: selectedValue + }; + } } } - } } let kernelSpecWidget = new DialogWidget( @@ -1664,7 +1678,7 @@ namespace Private { options: SessionContext.IKernelSearch ): string | null { const { specs, preference } = options; - const { name, language, canStart, autoStartDefault } = preference; + const { name, language, canStart, autoStartDefault } = preference; if (!specs || canStart === false) { return null; diff --git a/packages/console-extension/src/index.ts b/packages/console-extension/src/index.ts index 280e21723ba6..f0378901863a 100644 --- a/packages/console-extension/src/index.ts +++ b/packages/console-extension/src/index.ts @@ -319,7 +319,8 @@ async function activateConsole( if (result.value) { if (kernelConfigurarion) { if (args.kernelPreference) { - let kernelPreference = args.kernelPreference as ReadonlyPartialJSONObject; + let kernelPreference = + args.kernelPreference as ReadonlyPartialJSONObject; newArgs['kernelPreference'] = { ...kernelPreference, customKernelSpecs: kernelConfigurarion diff --git a/packages/console/src/panel.ts b/packages/console/src/panel.ts index c1195899ad75..0e13e3a8ae9d 100644 --- a/packages/console/src/panel.ts +++ b/packages/console/src/panel.ts @@ -89,10 +89,12 @@ export class ConsolePanel extends MainAreaWidget { this.content.addWidget(this.console); void sessionContext.initialize().then(async value => { if (value) { - let dialog = await ( - options.sessionDialogs ?? new SessionContextDialogs({ translator }) - ); - if (options.kernelPreference && !options.kernelPreference.customKernelSpecs ) { + let dialog = await (options.sessionDialogs ?? + new SessionContextDialogs({ translator })); + if ( + options.kernelPreference && + !options.kernelPreference.customKernelSpecs + ) { dialog.selectKernel(sessionContext!); } } diff --git a/packages/docmanager/src/manager.ts b/packages/docmanager/src/manager.ts index b02045a3f356..d41247f6617c 100644 --- a/packages/docmanager/src/manager.ts +++ b/packages/docmanager/src/manager.ts @@ -651,7 +651,6 @@ export class DocumentManager implements IDocumentManager { kernel ); - let context: Private.IContext | null; let ready: Promise = Promise.resolve(undefined); diff --git a/packages/docregistry/src/context.ts b/packages/docregistry/src/context.ts index aa121bc9cdd5..cba76dde95f6 100644 --- a/packages/docregistry/src/context.ts +++ b/packages/docregistry/src/context.ts @@ -23,7 +23,11 @@ import { TranslationBundle } from '@jupyterlab/translation'; -import { PartialJSONObject, PartialJSONValue, PromiseDelegate } from '@lumino/coreutils'; +import { + PartialJSONObject, + PartialJSONValue, + PromiseDelegate +} from '@lumino/coreutils'; import { DisposableDelegate, IDisposable } from '@lumino/disposable'; import { ISignal, Signal } from '@lumino/signaling'; import { Widget } from '@lumino/widgets'; @@ -528,7 +532,9 @@ export class Context< /** * Handle an initial population. */ - private async _populate(customKernelSpecs?:undefined | PartialJSONObject | {}): Promise { + private async _populate( + customKernelSpecs?: undefined | PartialJSONObject + ): Promise { this._isPopulated = true; this._isReady = true; this._populatedPromise.resolve(void 0); @@ -539,8 +545,12 @@ export class Context< return; } - if ((!customKernelSpecs || Object.keys(customKernelSpecs).length === 0) && this.sessionContext.kernelPreference.customKernelSpecs) { - customKernelSpecs = this.sessionContext.kernelPreference.customKernelSpecs; + if ( + (!customKernelSpecs || Object.keys(customKernelSpecs).length === 0) && + this.sessionContext.kernelPreference.customKernelSpecs + ) { + customKernelSpecs = + this.sessionContext.kernelPreference.customKernelSpecs; } // Update the kernel preference. @@ -653,8 +663,13 @@ export class Context< return; } if (contents.content) { - if (contents.content.metadata && contents.content.metadata.kernelspec && contents.content.metadata.kernelspec.customKernelSpecs) { - customKernelSpecs = contents.content.metadata.kernelspec.customKernelSpecs; + if ( + contents.content.metadata && + contents.content.metadata.kernelspec && + contents.content.metadata.kernelspec.customKernelSpecs + ) { + customKernelSpecs = + contents.content.metadata.kernelspec.customKernelSpecs; } if (contents.format === 'json') { model.fromJSON(contents.content); diff --git a/packages/notebook-extension/src/customKernelWidget.tsx b/packages/notebook-extension/src/customKernelWidget.tsx index 6fead99d7c50..884b6a1a79d1 100644 --- a/packages/notebook-extension/src/customKernelWidget.tsx +++ b/packages/notebook-extension/src/customKernelWidget.tsx @@ -11,7 +11,11 @@ import { RJSFSchema, UiSchema } from '@rjsf/utils'; import validator from '@rjsf/validator-ajv8'; import { PartialJSONObject } from '@lumino/coreutils'; -type FormDataProps = IChangeEvent | undefined | PartialJSONObject | {}; +type FormDataProps = + | IChangeEvent + | undefined + | PartialJSONObject + | {}; /** * Form to select custom properties of kernel @@ -20,14 +24,10 @@ type FormDataProps = IChangeEvent | undefined | PartialJSO */ const FormComponent = (props: { - schema: RJSFSchema, - kernelConfigurarion: FormDataProps, - updateFormData: ( - formData: FormDataProps - ) => void; + schema: RJSFSchema; + kernelConfigurarion: FormDataProps; + updateFormData: (formData: FormDataProps) => void; }): JSX.Element => { - - const uiSchema: UiSchema = { 'ui:options': { submitButtonOptions: { @@ -65,9 +65,11 @@ export class DialogWidget extends ReactWidget { /** * Constructs a new FormWidget. */ - constructor(schema: RJSFSchema, kernelConfigurarion: FormDataProps, updateFormData: ( - formData: FormDataProps - ) => void) { + constructor( + schema: RJSFSchema, + kernelConfigurarion: FormDataProps, + updateFormData: (formData: FormDataProps) => void + ) { super(); this.schema = schema; this.formData = undefined; @@ -79,10 +81,13 @@ export class DialogWidget extends ReactWidget { return this.kernelConfigurarion; } - render(): JSX.Element { return ( - + ); } } diff --git a/packages/notebook-extension/src/index.ts b/packages/notebook-extension/src/index.ts index f80790149bec..f9dedc0794fe 100644 --- a/packages/notebook-extension/src/index.ts +++ b/packages/notebook-extension/src/index.ts @@ -103,6 +103,7 @@ import { buildIcon, copyIcon, cutIcon, + DialogWidget, duplicateIcon, fastForwardIcon, IFormRenderer, @@ -114,8 +115,7 @@ import { refreshIcon, runIcon, stopIcon, - tableRowsIcon, - DialogWidget + tableRowsIcon } from '@jupyterlab/ui-components'; import { ArrayExt } from '@lumino/algorithm'; import { CommandRegistry } from '@lumino/commands'; @@ -1848,7 +1848,12 @@ function activateNotebookHandler( } } - const showKernelSpecDialog = async (parameters: RJSFSchema, cwd:string, kernelId: string, kernelName:string)=>{ + const showKernelSpecDialog = async ( + parameters: RJSFSchema, + cwd: string, + kernelId: string, + kernelName: string + ) => { let kernelConfigurarion: PartialJSONObject = {}; let label = trans.__('Cancel'); const buttons = [ @@ -1861,31 +1866,35 @@ function activateNotebookHandler( }) ]; - // const autoStartDefault = sessionContext.kernelPreference.autoStartDefault; + // const autoStartDefault = sessionContext.kernelPreference.autoStartDefault; const dialog = new Dialog({ title: trans.__('Select Kernel'), - body: new DialogWidget(parameters, kernelConfigurarion, (formData)=>{ - kernelConfigurarion = formData as PartialJSONObject; - }, trans), - buttons, + body: new DialogWidget( + parameters, + kernelConfigurarion, + formData => { + kernelConfigurarion = formData as PartialJSONObject; + }, + trans + ), + buttons }); const result = await dialog.launch(); - if (!result.button.accept) { + if (!result.button.accept) { return; - } - if (result.value) { - let customKernelSpecs = undefined; - if(kernelConfigurarion) { - customKernelSpecs = kernelConfigurarion; } + if (result.value) { + let customKernelSpecs = undefined; + if (kernelConfigurarion) { + customKernelSpecs = kernelConfigurarion; + } - createNew(cwd, kernelId, kernelName, customKernelSpecs); - } -} - + createNew(cwd, kernelId, kernelName, customKernelSpecs); + } + }; /** * Update the setting values. @@ -1982,7 +1991,7 @@ function activateNotebookHandler( cwd: string, kernelId: string, kernelName: string, - customKernelSpecs?: undefined | PartialJSONObject | {} + customKernelSpecs?: undefined | PartialJSONObject ) => { const model = await commands.execute('docmanager:new-untitled', { path: cwd, @@ -1992,17 +2001,17 @@ function activateNotebookHandler( const widget = (await commands.execute('docmanager:open', { path: model.path, factory: FACTORY, - kernel: { id: kernelId, name: kernelName, custom_kernel_specs: customKernelSpecs } + kernel: { + id: kernelId, + name: kernelName, + custom_kernel_specs: customKernelSpecs + } })) as unknown as IDocumentWidget; widget.isUntitled = true; return widget; } }; - - - - // Add a command for creating a new notebook. commands.addCommand(CommandIDs.createNew, { label: args => { @@ -2022,18 +2031,18 @@ function activateNotebookHandler( caption: trans.__('Create a new notebook'), icon: args => (args['isPalette'] ? undefined : notebookIcon), execute: args => { - const currentBrowser = - filebrowserFactory?.tracker.currentWidget ?? defaultBrowser; - //if has enum then calll + const currentBrowser = + filebrowserFactory?.tracker.currentWidget ?? defaultBrowser; + //if has enum then calll const cwd = (args['cwd'] as string) || (currentBrowser?.model.path ?? ''); const kernelId = (args['kernelId'] as string) || ''; const kernelName = (args['kernelName'] as string) || ''; const metadata = args['metadata'] as ReadonlyJSONObject; if (metadata?.parameters) { - let schema = metadata.parameters as RJSFSchema; - showKernelSpecDialog(schema, cwd, kernelId, kernelName); + let schema = metadata.parameters as RJSFSchema; + showKernelSpecDialog(schema, cwd, kernelId, kernelName); } else { - return createNew(cwd, kernelId, kernelName); + return createNew(cwd, kernelId, kernelName); } } }); @@ -2053,28 +2062,31 @@ function activateNotebookHandler( } disposables = new DisposableSet(); - for (const name in specs.kernelspecs) { - const rank = name === specs.default ? 0 : Infinity; - const spec = specs.kernelspecs[name]!; - const kernelIconUrl = - spec.resources['logo-svg'] || spec.resources['logo-64x64']; - //if has enum then add one icon - - disposables.add( - launcher.add({ - command: CommandIDs.createNew, - args: { isLauncher: true, kernelName: name, metadata: spec.metadata as ReadonlyJSONObject }, - category: trans.__('Notebook'), - rank, - kernelIconUrl, - metadata: { - kernel: JSONExt.deepCopy( - spec.metadata || {} - ) as ReadonlyJSONValue - } - }) - ); - + for (const name in specs.kernelspecs) { + const rank = name === specs.default ? 0 : Infinity; + const spec = specs.kernelspecs[name]!; + const kernelIconUrl = + spec.resources['logo-svg'] || spec.resources['logo-64x64']; + //if has enum then add one icon + + disposables.add( + launcher.add({ + command: CommandIDs.createNew, + args: { + isLauncher: true, + kernelName: name, + metadata: spec.metadata as ReadonlyJSONObject + }, + category: trans.__('Notebook'), + rank, + kernelIconUrl, + metadata: { + kernel: JSONExt.deepCopy( + spec.metadata || {} + ) as ReadonlyJSONValue + } + }) + ); } }; onSpecsChanged(); diff --git a/packages/notebook/src/panel.ts b/packages/notebook/src/panel.ts index 8e703cf2c203..eb5143b28b63 100644 --- a/packages/notebook/src/panel.ts +++ b/packages/notebook/src/panel.ts @@ -270,8 +270,7 @@ export class NotebookPanel extends DocumentWidget { let kernelParameter = properties[key] as PartialJSONObject; if (kernelParameter && kernelParameter?.save) { - - let item = customKernelSpecs[key] as PartialJSONObject | {}; + let item = customKernelSpecs[key] as PartialJSONObject; data[key] = item; } @@ -282,7 +281,7 @@ export class NotebookPanel extends DocumentWidget { name: kernel.name, display_name: spec?.display_name, language: spec?.language, - ...Object.keys(data).length ? { customKernelSpecs: data}: {} + ...(Object.keys(data).length ? { customKernelSpecs: data } : {}) }); } diff --git a/packages/services/src/kernel/restapi.ts b/packages/services/src/kernel/restapi.ts index d57441620dfb..e84410c8a17a 100644 --- a/packages/services/src/kernel/restapi.ts +++ b/packages/services/src/kernel/restapi.ts @@ -52,7 +52,7 @@ export interface IModel { /** * Custom kernel specifications for running a kernel */ - custom_kernel_specs?: undefined | PartialJSONObject | {}; + custom_kernel_specs?: undefined | PartialJSONObject; } /** diff --git a/packages/services/src/session/restapi.ts b/packages/services/src/session/restapi.ts index 8ff78779477f..5b73df20921c 100644 --- a/packages/services/src/session/restapi.ts +++ b/packages/services/src/session/restapi.ts @@ -104,7 +104,6 @@ export async function startSession( options: Session.ISessionOptions, settings: ServerConnection.ISettings = ServerConnection.makeSettings() ): Promise { - const url = URLExt.join(settings.baseUrl, SESSION_SERVICE_URL); const init = { method: 'POST', diff --git a/packages/ui-components/src/components/customform.tsx b/packages/ui-components/src/components/customform.tsx index 3c5212590cbe..c35df8d16e58 100644 --- a/packages/ui-components/src/components/customform.tsx +++ b/packages/ui-components/src/components/customform.tsx @@ -3,17 +3,19 @@ * Distributed under the terms of the Modified BSD License. */ -import React, { RefObject, createRef, useState } from 'react'; +import React, { createRef, RefObject, useState } from 'react'; import Form, { IChangeEvent } from '@rjsf/core'; import { RJSFSchema, UiSchema } from '@rjsf/utils'; import validator from '@rjsf/validator-ajv8'; -import { PartialJSONObject} from '@lumino/coreutils'; +import { PartialJSONObject } from '@lumino/coreutils'; import { IRenderMime } from '@jupyterlab/rendermime-interfaces'; import { ReactWidget } from './vdom'; import { FormComponent } from './form'; - -type FormDataProps = IChangeEvent | undefined | PartialJSONObject | {}; +type FormDataProps = + | IChangeEvent + | undefined + | PartialJSONObject; /** * Form to select custom properties of kernel @@ -22,13 +24,10 @@ type FormDataProps = IChangeEvent | undefined | PartialJSO */ const FormComponentWrapper = (props: { - schema: RJSFSchema, - kernelConfigurarion: FormDataProps, - updateFormData: ( - formData: FormDataProps - ) => void; + schema: RJSFSchema; + kernelConfigurarion: FormDataProps; + updateFormData: (formData: FormDataProps) => void; }): JSX.Element => { - const [isUpdate, setUpdate] = useState(0); const formRef = createRef() as RefObject>; @@ -45,15 +44,15 @@ const FormComponentWrapper = (props: { }; const onChange = ({ formData }: IChangeEvent) => { - if(!isUpdate) { + if (!isUpdate) { props.updateFormData(formData); } if (formRef.current && formRef?.current.validateForm()) { props.updateFormData(formData); } - let update = isUpdate+1; + let update = isUpdate + 1; setUpdate(update); - // } + // } }; const formData: Record = {}; @@ -77,15 +76,18 @@ const FormComponentWrapper = (props: { */ export class DialogWidget extends ReactWidget { schema: RJSFSchema; - formData: FormDataProps | {}; + formData: FormDataProps; updateFormData: (formData: FormDataProps) => void; kernelConfigurarion: FormDataProps; /** * Constructs a new FormWidget. */ - constructor(schema: RJSFSchema, kernelConfigurarion: FormDataProps, updateFormData: ( - formData: FormDataProps - ) => void, trans:IRenderMime.TranslationBundle) { + constructor( + schema: RJSFSchema, + kernelConfigurarion: FormDataProps, + updateFormData: (formData: FormDataProps) => void, + trans: IRenderMime.TranslationBundle + ) { super(); this.schema = schema; this.formData = undefined; @@ -93,14 +95,17 @@ export class DialogWidget extends ReactWidget { this.updateFormData = updateFormData; } - getValue(): FormDataProps | {} { + getValue(): FormDataProps { return this.kernelConfigurarion; } - render(): JSX.Element { return ( - + ); } } diff --git a/packages/ui-components/src/components/form.tsx b/packages/ui-components/src/components/form.tsx index 1ce6f338e2a2..0b1aec6b292b 100644 --- a/packages/ui-components/src/components/form.tsx +++ b/packages/ui-components/src/components/form.tsx @@ -618,7 +618,10 @@ export interface IFormComponentProps /** * Generic rjsf form component for JupyterLab UI. */ -export const FormComponent = forwardRef(function FormComponent(props: IFormComponentProps, ref:React.RefObject> | null): JSX.Element { +export const FormComponent = forwardRef(function FormComponent( + props: IFormComponentProps, + ref: React.RefObject> | null +): JSX.Element { const { buttonStyle, compact, @@ -678,6 +681,11 @@ export const FormComponent = forwardRef(function FormComponent(props: IFormCompo }; return ( - + ); -}) +}); From 3de9803bb8f07cdd71ad94fa9b8f949ea7f9849d Mon Sep 17 00:00:00 2001 From: Anastasiia Sliusar Date: Fri, 21 Jun 2024 14:48:06 +0200 Subject: [PATCH 22/29] Fix updating launch parameters when a new kernel is selected --- packages/apputils/src/sessioncontext.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/apputils/src/sessioncontext.tsx b/packages/apputils/src/sessioncontext.tsx index c32d7837ed7b..57488238151d 100644 --- a/packages/apputils/src/sessioncontext.tsx +++ b/packages/apputils/src/sessioncontext.tsx @@ -1583,6 +1583,8 @@ namespace Private { const selector = document.createElement('select'); selector.setAttribute('id', 'js-kernel-selector'); selector.onchange = () => { + selector.setAttribute( + 'data-kernel-spec',''); checkCustomKernelSpecs(sessionContext, selector, trans); }; From 9cbb5e1dcee44a9c20612a9620e3a9d7daf0697c Mon Sep 17 00:00:00 2001 From: Anastasiia Sliusar Date: Fri, 21 Jun 2024 17:24:56 +0200 Subject: [PATCH 23/29] Remove saving a user kernel custom selection into notebook metadata --- packages/docregistry/src/context.ts | 11 +---------- packages/notebook/src/panel.ts | 28 ++-------------------------- 2 files changed, 3 insertions(+), 36 deletions(-) diff --git a/packages/docregistry/src/context.ts b/packages/docregistry/src/context.ts index cba76dde95f6..a10d6f783e97 100644 --- a/packages/docregistry/src/context.ts +++ b/packages/docregistry/src/context.ts @@ -658,19 +658,10 @@ export class Context< return this._manager.contents.get(path, opts); }) .then(contents => { - let customKernelSpecs = {}; if (this.isDisposed) { return; } if (contents.content) { - if ( - contents.content.metadata && - contents.content.metadata.kernelspec && - contents.content.metadata.kernelspec.customKernelSpecs - ) { - customKernelSpecs = - contents.content.metadata.kernelspec.customKernelSpecs; - } if (contents.format === 'json') { model.fromJSON(contents.content); } else { @@ -693,7 +684,7 @@ export class Context< this._updateContentsModel(contents); model.dirty = false; if (!this._isPopulated) { - return this._populate(customKernelSpecs); + return this._populate(); } }) .catch(async err => { diff --git a/packages/notebook/src/panel.ts b/packages/notebook/src/panel.ts index eb5143b28b63..27b9e26a3b79 100644 --- a/packages/notebook/src/panel.ts +++ b/packages/notebook/src/panel.ts @@ -11,8 +11,8 @@ import { isMarkdownCellModel } from '@jupyterlab/cells'; import { PageConfig } from '@jupyterlab/coreutils'; import { DocumentRegistry, DocumentWidget } from '@jupyterlab/docregistry'; import { Kernel, KernelMessage, Session } from '@jupyterlab/services'; +import { Token } from '@lumino/coreutils'; import { ITranslator } from '@jupyterlab/translation'; -import { PartialJSONObject, Token } from '@lumino/coreutils'; import { INotebookModel } from './model'; import { Notebook, StaticNotebook } from './widget'; import { Message } from '@lumino/messaging'; @@ -253,35 +253,11 @@ export class NotebookPanel extends DocumentWidget { if (this.isDisposed) { return; } - - let customKernelSpecs = this.context.sessionContext.kernelPreference - ?.customKernelSpecs as PartialJSONObject; - let data = {} as PartialJSONObject; - - if ( - customKernelSpecs && - spec && - spec?.metadata && - spec?.metadata?.parameters - ) { - let kernelParameters = spec?.metadata?.parameters as PartialJSONObject; - for (let key in customKernelSpecs) { - let properties = kernelParameters.properties as PartialJSONObject; - let kernelParameter = properties[key] as PartialJSONObject; - - if (kernelParameter && kernelParameter?.save) { - let item = customKernelSpecs[key] as PartialJSONObject; - - data[key] = item; - } - } - } - + this.model!.setMetadata('kernelspec', { name: kernel.name, display_name: spec?.display_name, language: spec?.language, - ...(Object.keys(data).length ? { customKernelSpecs: data } : {}) }); } From 2cd96b591bef5ba3e7fc280abcbdf34e02e06033 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 21 Jun 2024 15:25:13 +0000 Subject: [PATCH 24/29] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- packages/notebook/src/panel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/notebook/src/panel.ts b/packages/notebook/src/panel.ts index 27b9e26a3b79..d437613fdfaf 100644 --- a/packages/notebook/src/panel.ts +++ b/packages/notebook/src/panel.ts @@ -253,7 +253,7 @@ export class NotebookPanel extends DocumentWidget { if (this.isDisposed) { return; } - + this.model!.setMetadata('kernelspec', { name: kernel.name, display_name: spec?.display_name, From e852ee908924fb7f4fb64ad9a8e63f7484dfa2f3 Mon Sep 17 00:00:00 2001 From: Anastasiia Sliusar Date: Wed, 26 Jun 2024 16:36:28 +0200 Subject: [PATCH 25/29] Add condition when a dialog should be shown --- packages/notebook-extension/src/index.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/notebook-extension/src/index.ts b/packages/notebook-extension/src/index.ts index f9dedc0794fe..ca0a67bde2f4 100644 --- a/packages/notebook-extension/src/index.ts +++ b/packages/notebook-extension/src/index.ts @@ -2038,7 +2038,12 @@ function activateNotebookHandler( const kernelId = (args['kernelId'] as string) || ''; const kernelName = (args['kernelName'] as string) || ''; const metadata = args['metadata'] as ReadonlyJSONObject; - if (metadata?.parameters) { + console.log('PageConfig'); + console.dir(PageConfig); + const allow_insecure_kernel_specs = PageConfig.getOption('allow_insecure_kernel_specs'); + console.log('allow_insecure_kernel_specs'); + console.log(allow_insecure_kernel_specs); + if (metadata?.parameters && allow_insecure_kernel_specs) { let schema = metadata.parameters as RJSFSchema; showKernelSpecDialog(schema, cwd, kernelId, kernelName); } else { From c48f438acc284efb68ad85cdbaaf3af4cc591489 Mon Sep 17 00:00:00 2001 From: Anastasiia Sliusar Date: Thu, 4 Jul 2024 17:58:45 +0200 Subject: [PATCH 26/29] fix showing a dialog when a kernel spec file are secure and insecure --- packages/apputils/src/sessioncontext.tsx | 103 +++++++++++++---------- packages/notebook-extension/src/index.ts | 23 +++-- 2 files changed, 72 insertions(+), 54 deletions(-) diff --git a/packages/apputils/src/sessioncontext.tsx b/packages/apputils/src/sessioncontext.tsx index 57488238151d..fa1fb9227572 100644 --- a/packages/apputils/src/sessioncontext.tsx +++ b/packages/apputils/src/sessioncontext.tsx @@ -1,7 +1,7 @@ // Copyright (c) Jupyter Development Team. // Distributed under the terms of the Modified BSD License. -import { IChangedArgs, PathExt } from '@jupyterlab/coreutils'; +import { IChangedArgs, PageConfig, PathExt } from '@jupyterlab/coreutils'; import { Kernel, KernelMessage, @@ -1583,8 +1583,7 @@ namespace Private { const selector = document.createElement('select'); selector.setAttribute('id', 'js-kernel-selector'); selector.onchange = () => { - selector.setAttribute( - 'data-kernel-spec',''); + selector.setAttribute('data-kernel-spec', ''); checkCustomKernelSpecs(sessionContext, selector, trans); }; @@ -1622,52 +1621,66 @@ namespace Private { selectedKernel && selectedKernel.name ? selectedKernel.name : ''; let kernel = kernelName && sessionContext.specsManager.specs?.kernelspecs[kernelName]; - if (kernel && kernel?.metadata && kernel?.metadata?.parameters) { - let kernelParameters = kernel?.metadata?.parameters as PartialJSONObject; - - if (kernelParameters) { - if (sessionContext.kernelPreference?.customKernelSpecs) { - let customKernelSpecs = sessionContext.kernelPreference - ?.customKernelSpecs as PartialJSONObject; - for (let key in customKernelSpecs) { - let selectedValue = customKernelSpecs[key] as - | PartialJSONValue - | undefined; - - if (kernelParameters.properties) { - let properties = kernelParameters.properties as PartialJSONObject; - - let kernelParameter = properties[key] as PartialJSONObject; - - if (kernelParameter) { - let kernelParametersTmp = ( - kernelParameters.properties as PartialJSONObject - )[key] as PartialJSONObject; - (kernelParameters.properties as PartialJSONObject)[key] = { - ...kernelParametersTmp, - default: selectedValue - }; + const allow_insecure_kernelspec_params = + PageConfig.getOption('allow_insecure_kernelspec_params') === 'true' + ? true + : false; + if ( + (kernel && + kernel?.metadata && + kernel?.metadata?.is_secure && + kernel?.metadata?.parameters) || + allow_insecure_kernelspec_params + ) { + if (kernel && kernel?.metadata && kernel?.metadata?.parameters) { + let kernelParameters = kernel?.metadata + ?.parameters as PartialJSONObject; + + if (kernelParameters) { + if (sessionContext.kernelPreference?.customKernelSpecs) { + let customKernelSpecs = sessionContext.kernelPreference + ?.customKernelSpecs as PartialJSONObject; + for (let key in customKernelSpecs) { + let selectedValue = customKernelSpecs[key] as + | PartialJSONValue + | undefined; + + if (kernelParameters.properties) { + let properties = + kernelParameters.properties as PartialJSONObject; + + let kernelParameter = properties[key] as PartialJSONObject; + + if (kernelParameter) { + let kernelParametersTmp = ( + kernelParameters.properties as PartialJSONObject + )[key] as PartialJSONObject; + (kernelParameters.properties as PartialJSONObject)[key] = { + ...kernelParametersTmp, + default: selectedValue + }; + } } } } - } - let kernelSpecWidget = new DialogWidget( - kernelParameters, - kernelConfiguration, - formData => { - kernelConfiguration = formData as PartialJSONObject; - selector.setAttribute( - 'data-kernel-spec', - JSON.stringify(kernelConfiguration) - ); - }, - trans - ); - - //Update widget - if (kernelSpecsContainer) { - Widget.attach(kernelSpecWidget, kernelSpecsContainer); + let kernelSpecWidget = new DialogWidget( + kernelParameters, + kernelConfiguration, + formData => { + kernelConfiguration = formData as PartialJSONObject; + selector.setAttribute( + 'data-kernel-spec', + JSON.stringify(kernelConfiguration) + ); + }, + trans + ); + + //Update widget + if (kernelSpecsContainer) { + Widget.attach(kernelSpecWidget, kernelSpecsContainer); + } } } } diff --git a/packages/notebook-extension/src/index.ts b/packages/notebook-extension/src/index.ts index ca0a67bde2f4..3df2b45d477a 100644 --- a/packages/notebook-extension/src/index.ts +++ b/packages/notebook-extension/src/index.ts @@ -2038,16 +2038,21 @@ function activateNotebookHandler( const kernelId = (args['kernelId'] as string) || ''; const kernelName = (args['kernelName'] as string) || ''; const metadata = args['metadata'] as ReadonlyJSONObject; - console.log('PageConfig'); - console.dir(PageConfig); - const allow_insecure_kernel_specs = PageConfig.getOption('allow_insecure_kernel_specs'); - console.log('allow_insecure_kernel_specs'); - console.log(allow_insecure_kernel_specs); - if (metadata?.parameters && allow_insecure_kernel_specs) { - let schema = metadata.parameters as RJSFSchema; - showKernelSpecDialog(schema, cwd, kernelId, kernelName); + const allow_insecure_kernelspec_params = PageConfig.getOption('allow_insecure_kernelspec_params') === 'true' ? true: false; + if(metadata?.is_secure) { + if (!metadata?.parameters) { + return createNew(cwd, kernelId, kernelName); + } else { + let schema = metadata.parameters as RJSFSchema; + showKernelSpecDialog(schema, cwd, kernelId, kernelName); + } } else { - return createNew(cwd, kernelId, kernelName); + if (allow_insecure_kernelspec_params) { + let schema = metadata.parameters as RJSFSchema; + showKernelSpecDialog(schema, cwd, kernelId, kernelName); + } else { + return createNew(cwd, kernelId, kernelName); + } } } }); From 7f07a5d71daa6cf741fdc343feae75343b585553 Mon Sep 17 00:00:00 2001 From: Anastasiia Sliusar Date: Fri, 5 Jul 2024 17:05:07 +0200 Subject: [PATCH 27/29] Fix showing a dialog from console when kernel spec files are filtered --- packages/apputils/src/sessioncontext.tsx | 4 ++-- packages/console-extension/src/index.ts | 20 ++++++++++++++++---- packages/notebook-extension/src/index.ts | 6 ++++-- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/packages/apputils/src/sessioncontext.tsx b/packages/apputils/src/sessioncontext.tsx index fa1fb9227572..f095a415b6b7 100644 --- a/packages/apputils/src/sessioncontext.tsx +++ b/packages/apputils/src/sessioncontext.tsx @@ -1621,7 +1621,7 @@ namespace Private { selectedKernel && selectedKernel.name ? selectedKernel.name : ''; let kernel = kernelName && sessionContext.specsManager.specs?.kernelspecs[kernelName]; - const allow_insecure_kernelspec_params = + const allowInsecureKernelspecParams = PageConfig.getOption('allow_insecure_kernelspec_params') === 'true' ? true : false; @@ -1630,7 +1630,7 @@ namespace Private { kernel?.metadata && kernel?.metadata?.is_secure && kernel?.metadata?.parameters) || - allow_insecure_kernelspec_params + allowInsecureKernelspecParams ) { if (kernel && kernel?.metadata && kernel?.metadata?.parameters) { let kernelParameters = kernel?.metadata diff --git a/packages/console-extension/src/index.ts b/packages/console-extension/src/index.ts index f0378901863a..16fd51e6ee1a 100644 --- a/packages/console-extension/src/index.ts +++ b/packages/console-extension/src/index.ts @@ -62,6 +62,7 @@ import { DockLayout, Widget } from '@lumino/widgets'; import foreign from './foreign'; import { cellExecutor } from './cellexecutor'; import type { RJSFSchema } from '@rjsf/utils'; +import { PageConfig } from '@jupyterlab/coreutils'; /** * The command IDs used by the console plugin. @@ -612,11 +613,22 @@ async function activateConsole( ''; // const metadata = args['metadata'] as ReadonlyJSONObject; - if (metadata?.parameters) { - let schema = metadata.parameters as RJSFSchema; - return showKernelSpecDialog(schema, basePath, args); + const allowInsecureKernelspecParams = PageConfig.getOption('allow_insecure_kernelspec_params') === 'true' ? true: false; + + if(metadata?.is_secure) { + if (!metadata?.parameters) { + return createConsole({ basePath, ...args }); + } else { + let schema = metadata.parameters as RJSFSchema; + return showKernelSpecDialog(schema, basePath, args); + } } else { - return createConsole({ basePath, ...args }); + if (allowInsecureKernelspecParams) { + let schema = metadata.parameters as RJSFSchema; + return showKernelSpecDialog(schema, basePath, args); + } else { + return createConsole({ basePath, ...args }); + } } } }); diff --git a/packages/notebook-extension/src/index.ts b/packages/notebook-extension/src/index.ts index 3df2b45d477a..fb777e03d025 100644 --- a/packages/notebook-extension/src/index.ts +++ b/packages/notebook-extension/src/index.ts @@ -2038,7 +2038,7 @@ function activateNotebookHandler( const kernelId = (args['kernelId'] as string) || ''; const kernelName = (args['kernelName'] as string) || ''; const metadata = args['metadata'] as ReadonlyJSONObject; - const allow_insecure_kernelspec_params = PageConfig.getOption('allow_insecure_kernelspec_params') === 'true' ? true: false; + const allowInsecureKernelspecParams = PageConfig.getOption('allow_insecure_kernelspec_params') === 'true' ? true: false; if(metadata?.is_secure) { if (!metadata?.parameters) { return createNew(cwd, kernelId, kernelName); @@ -2047,7 +2047,7 @@ function activateNotebookHandler( showKernelSpecDialog(schema, cwd, kernelId, kernelName); } } else { - if (allow_insecure_kernelspec_params) { + if (allowInsecureKernelspecParams) { let schema = metadata.parameters as RJSFSchema; showKernelSpecDialog(schema, cwd, kernelId, kernelName); } else { @@ -2075,6 +2075,8 @@ function activateNotebookHandler( for (const name in specs.kernelspecs) { const rank = name === specs.default ? 0 : Infinity; const spec = specs.kernelspecs[name]!; + console.log('spec'); + console.dir(spec); const kernelIconUrl = spec.resources['logo-svg'] || spec.resources['logo-64x64']; //if has enum then add one icon From 6579197abb6c49e84e234f8d94dc50ae3c19e338 Mon Sep 17 00:00:00 2001 From: Anastasiia Sliusar Date: Tue, 13 Aug 2024 14:09:06 +0200 Subject: [PATCH 28/29] Fix showing the dialog part for setuping kernel custom params --- packages/apputils/src/sessioncontext.tsx | 52 ++++++++---------------- 1 file changed, 16 insertions(+), 36 deletions(-) diff --git a/packages/apputils/src/sessioncontext.tsx b/packages/apputils/src/sessioncontext.tsx index bc844ce0e57d..8a8b9d0a08a5 100644 --- a/packages/apputils/src/sessioncontext.tsx +++ b/packages/apputils/src/sessioncontext.tsx @@ -30,7 +30,6 @@ import * as React from 'react'; import { Dialog, showDialog } from './dialog'; import { DialogWidget } from '@jupyterlab/ui-components'; import { IRenderMime } from '@jupyterlab/rendermime-interfaces'; -import { Message } from '@lumino/messaging'; /** * A context object to manage a widget's kernel session connection. @@ -1870,34 +1869,6 @@ namespace Private { this.translator = translator; } - protected onAfterAttach(msg: Message): void { - super.onAfterAttach(msg); - this.setupDefaultKernelSpecs(this.sessionContext, this.translator); - } - - setupDefaultKernelSpecs( - sessionContext: ISessionContext, - translator: ITranslator | undefined - ) { - translator = translator || nullTranslator; - const trans = translator.load('jupyterlab'); - if (this.node) { - const selector = this.node.querySelector( - 'select#js-kernel-selector' - ) as HTMLSelectElement; - selector.setAttribute('data-kernel-spec', ''); - const kernelSpeccSelectorContainer = this.node.querySelector( - 'div#js-kernel-specs-selector-container' - ) as HTMLDivElement; - checkCustomKernelSpecs( - sessionContext, - selector, - trans, - kernelSpeccSelectorContainer - ); - } - } - /** * Get the value of the kernel selector widget. */ @@ -1931,11 +1902,11 @@ namespace Private { const kernelSpecsContainer = document.createElement('div'); - container.setAttribute('id', 'js-kernel-selector-container'); + container.setAttribute('id', 'js-kernel-select-container'); kernelSpecsContainer.setAttribute( 'id', - 'js-kernel-specs-selector-container' + 'js-kernel-specs-select-container' ); const text = document.createElement('label'); @@ -1957,7 +1928,15 @@ namespace Private { optgroup.label = label; for (const { selected, text, title, value } of options) { const option = document.createElement('option'); - if (selected) option.selected = true; + if (selected) { + option.selected = true; + let val = JSON.parse(value); + let id = val && val.id ? val.id : ''; + if (!id) { + select.setAttribute('data-kernel-spec', ''); + checkCustomKernelSpecs(sessionContext, select, trans); + } + } if (title) option.title = title; option.text = text; option.value = value; @@ -1972,20 +1951,21 @@ namespace Private { }; body.appendChild(select); + body.appendChild(kernelSpecsContainer); return body; } function checkCustomKernelSpecs( sessionContext: ISessionContext, - selector: HTMLSelectElement, + select: HTMLSelectElement, trans: IRenderMime.TranslationBundle, kernelSpeccSelectorContainer?: HTMLDivElement ) { let kernelConfiguration: PartialJSONObject = {}; - let selectedKernel = JSON.parse(selector.value) as Kernel.IModel; + let selectedKernel = JSON.parse(select.value) as Kernel.IModel; let kernelSpecsContainer = document.querySelector( - '#js-kernel-specs-selector-container' + '#js-kernel-specs-select-container' ) as HTMLElement; if (!kernelSpecsContainer && kernelSpeccSelectorContainer) { @@ -2045,7 +2025,7 @@ namespace Private { kernelConfiguration, formData => { kernelConfiguration = formData as PartialJSONObject; - selector.setAttribute( + select.setAttribute( 'data-kernel-spec', JSON.stringify(kernelConfiguration) ); From 8baa65c62c59466d0c7e540028f218eb044d89f6 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 13 Aug 2024 12:10:05 +0000 Subject: [PATCH 29/29] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- packages/console-extension/src/index.ts | 2 +- packages/notebook-extension/src/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/console-extension/src/index.ts b/packages/console-extension/src/index.ts index 16fd51e6ee1a..10dfc7284b60 100644 --- a/packages/console-extension/src/index.ts +++ b/packages/console-extension/src/index.ts @@ -627,7 +627,7 @@ async function activateConsole( let schema = metadata.parameters as RJSFSchema; return showKernelSpecDialog(schema, basePath, args); } else { - return createConsole({ basePath, ...args }); + return createConsole({ basePath, ...args }); } } } diff --git a/packages/notebook-extension/src/index.ts b/packages/notebook-extension/src/index.ts index fb777e03d025..d2ad716a63da 100644 --- a/packages/notebook-extension/src/index.ts +++ b/packages/notebook-extension/src/index.ts @@ -2051,7 +2051,7 @@ function activateNotebookHandler( let schema = metadata.parameters as RJSFSchema; showKernelSpecDialog(schema, cwd, kernelId, kernelName); } else { - return createNew(cwd, kernelId, kernelName); + return createNew(cwd, kernelId, kernelName); } } }