diff --git a/src/sql/workbench/contrib/notebook/browser/notebookActions.ts b/src/sql/workbench/contrib/notebook/browser/notebookActions.ts index c85d0a37ca..e6c64290d0 100644 --- a/src/sql/workbench/contrib/notebook/browser/notebookActions.ts +++ b/src/sql/workbench/contrib/notebook/browser/notebookActions.ts @@ -37,6 +37,7 @@ import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry'; import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { KernelsLanguage } from 'sql/workbench/services/notebook/common/notebookConstants'; import { INotebookViews } from 'sql/workbench/services/notebook/browser/notebookViews/notebookViews'; +import { Schemas } from 'vs/base/common/network'; const msgLoading = localize('loading', "Loading kernels..."); export const msgChanging = localize('changing', "Changing kernel..."); @@ -53,6 +54,7 @@ const maskedIconClass = 'masked-icon'; export const kernelNotSupported: string = localize('kernelNotSupported', "This notebook cannot run with parameters as the kernel is not supported. Please use the supported kernels and format. [Learn more](https://docs.microsoft.com/sql/azure-data-studio/notebooks/notebooks-parameterization)."); export const noParameterCell: string = localize('noParametersCell', "This notebook cannot run with parameters until a parameter cell is added. [Learn more](https://docs.microsoft.com/sql/azure-data-studio/notebooks/notebooks-parameterization)."); export const noParametersInCell: string = localize('noParametersInCell', "This notebook cannot run with parameters until there are parameters added to the parameter cell. [Learn more](https://docs.microsoft.com/sql/azure-data-studio/notebooks/notebooks-parameterization)."); +export const untitledNotSupported: string = localize('untitledNotSupported', "Run with parameters is not supported for Untitled notebooks. Please save the notebook before continuing. [Learn more](https://docs.microsoft.com/sql/azure-data-studio/notebooks/notebooks-parameterization)."); // Action to add a cell to notebook based on cell type(code/markdown). export class AddCellAction extends Action { @@ -448,6 +450,14 @@ export class RunParametersAction extends TooltipFromLabelAction { * with injected parameters value from the QuickInput */ public override async run(context: URI): Promise { + if (context.scheme === Schemas.untitled) { + // Run with parameters is not supported for untitled notebooks + this.notificationService.notify({ + severity: Severity.Info, + message: untitledNotSupported, + }); + return; + } const editor = this._notebookService.findNotebookEditor(context); // Only run action for kernels that are supported (Python, PySpark, PowerShell) let supportedKernels: string[] = [KernelsLanguage.Python, KernelsLanguage.PowerShell]; diff --git a/src/sql/workbench/contrib/notebook/test/browser/notebookActions.test.ts b/src/sql/workbench/contrib/notebook/test/browser/notebookActions.test.ts index 3492de4cfe..82726a8b34 100644 --- a/src/sql/workbench/contrib/notebook/test/browser/notebookActions.test.ts +++ b/src/sql/workbench/contrib/notebook/test/browser/notebookActions.test.ts @@ -7,7 +7,7 @@ import * as assert from 'assert'; import * as azdata from 'azdata'; import * as sinon from 'sinon'; import { TestConfigurationService } from 'sql/platform/connection/test/common/testConfigurationService'; -import { AddCellAction, ClearAllOutputsAction, CollapseCellsAction, CreateNotebookViewAction, DashboardViewAction, kernelNotSupported, KernelsDropdown, msgChanging, NewNotebookAction, noKernelName, noParameterCell, noParametersInCell, NotebookViewAction, NotebookViewsActionProvider, RunAllCellsAction, RunParametersAction, TrustedAction } from 'sql/workbench/contrib/notebook/browser/notebookActions'; +import { AddCellAction, ClearAllOutputsAction, CollapseCellsAction, CreateNotebookViewAction, DashboardViewAction, kernelNotSupported, KernelsDropdown, msgChanging, NewNotebookAction, noKernelName, noParameterCell, noParametersInCell, NotebookViewAction, NotebookViewsActionProvider, RunAllCellsAction, RunParametersAction, TrustedAction, untitledNotSupported } from 'sql/workbench/contrib/notebook/browser/notebookActions'; import { ClientSessionStub, ContextViewProviderStub, NotebookComponentStub, NotebookModelStub, NotebookServiceStub, NotebookViewsStub, NotebookViewStub } from 'sql/workbench/contrib/notebook/test/stubs'; import { NotebookEditorStub } from 'sql/workbench/contrib/notebook/test/testCommon'; import { ICellModel, INotebookModel, ViewMode } from 'sql/workbench/services/notebook/browser/models/modelInterfaces'; @@ -120,7 +120,7 @@ suite('Notebook Actions', function (): void { let mockNotebookEditor: TypeMoq.Mock; let mockNotebookService: TypeMoq.Mock; - const testUri = URI.parse('untitled'); + const testUri = URI.parse('file://a/b/c/test.ipynb'); let testNotebookModel = new TestNotebookModel(); suiteSetup(function (): void { @@ -536,6 +536,51 @@ suite('Notebook Actions', function (): void { assert.strictEqual(actualMsg, expectedMsg); }); + test('Should inform user that run with parameters is not supported for untitled notebooks', async function (): Promise { + // Kernels that are supported (Python, PySpark, PowerShell) + const untitledUri = URI.parse('untitled:Notebook-0'); + const testContents: azdata.nb.INotebookContents = { + cells: [{ + cell_type: CellTypes.Code, + source: ['x=2.0\n', 'y=5.0'], + metadata: { language: 'python' }, + execution_count: 1 + }], + metadata: { + kernelspec: { + name: 'python', + language: 'python', + display_name: 'Python 3' + } + }, + nbformat: NBFORMAT, + nbformat_minor: NBFORMAT_MINOR + }; + let expectedMsg: string = untitledNotSupported; + + let actualMsg: string; + let mockNotification = TypeMoq.Mock.ofType(TestNotificationService); + mockNotification.setup(n => n.notify(TypeMoq.It.isAny())).returns(notification => { + actualMsg = notification.message; + return undefined; + }); + + let quickInputService = new MockQuickInputService; + let testLanguageInfo: azdata.nb.ILanguageInfo = { + name: 'python', + }; + let mockNotebookModel = new NotebookModelStub(testLanguageInfo, undefined, testContents); + + let action = new RunParametersAction('TestId', true, untitledUri, quickInputService, mockNotebookService.object, mockNotification.object); + + mockNotebookEditor.setup(x => x.model).returns(() => mockNotebookModel); + + // Run Parameters Action + await action.run(untitledUri); + + assert.strictEqual(actualMsg, expectedMsg); + }); + test('notebookViewsActionProvider', async () => { const testGuid = '1'; const testName = 'Notebook-0';