From 585232118fb5d8f607bf23bfaa8a7fc143307e20 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Wed, 29 May 2024 14:57:54 -0700 Subject: [PATCH] Add showWorkspaceFolderPick to AzExtUserInput --- utils/index.d.ts | 20 +++++++++++++++-- utils/src/userInput/AzExtUserInput.ts | 18 ++++++++++++++- .../userInput/AzExtUserInputWithInputQueue.ts | 22 ++++++++++++++++++- .../src/userInput/showWorkspaceFolderPick.ts | 20 +++++++++++++++++ utils/test/AzureAgentInputTypeCheck.test.ts | 10 +++++++-- 5 files changed, 84 insertions(+), 6 deletions(-) create mode 100644 utils/src/userInput/showWorkspaceFolderPick.ts diff --git a/utils/index.d.ts b/utils/index.d.ts index ff019f78a2..8d7e7a3780 100644 --- a/utils/index.d.ts +++ b/utils/index.d.ts @@ -7,7 +7,7 @@ import type { Environment } from '@azure/ms-rest-azure-env'; import type { AzExtResourceType, AzureResource, AzureSubscription, ResourceModelBase } from '@microsoft/vscode-azureresources-api'; -import { AuthenticationSession, CancellationToken, CancellationTokenSource, Disposable, Event, ExtensionContext, FileChangeEvent, FileChangeType, FileStat, FileSystemProvider, FileType, InputBoxOptions, LogOutputChannel, MarkdownString, MessageItem, MessageOptions, OpenDialogOptions, OutputChannel, Progress, ProviderResult, QuickPickItem, TextDocumentShowOptions, ThemeIcon, TreeDataProvider, TreeItem, TreeItemCollapsibleState, TreeView, Uri, QuickPickOptions as VSCodeQuickPickOptions } from 'vscode'; +import { AuthenticationSession, CancellationToken, CancellationTokenSource, Disposable, Event, ExtensionContext, FileChangeEvent, FileChangeType, FileStat, FileSystemProvider, FileType, InputBoxOptions, LogOutputChannel, MarkdownString, MessageItem, MessageOptions, OpenDialogOptions, OutputChannel, Progress, ProviderResult, QuickPickItem, TextDocumentShowOptions, ThemeIcon, TreeDataProvider, TreeItem, TreeItemCollapsibleState, TreeView, Uri, QuickPickOptions as VSCodeQuickPickOptions, WorkspaceFolder, WorkspaceFolderPickOptions } from 'vscode'; import { TargetPopulation } from 'vscode-tas-client'; import type { Activity, ActivityTreeItemOptions, AppResource, OnErrorActivityData, OnProgressActivityData, OnStartActivityData, OnSuccessActivityData } from './hostapi'; // This must remain `import type` or else a circular reference will result @@ -884,7 +884,7 @@ export interface IParsedError { } export type PromptResult = { - value: string | QuickPickItem | QuickPickItem[] | MessageItem | Uri[]; + value: string | QuickPickItem | QuickPickItem[] | MessageItem | Uri[] | WorkspaceFolder; /** * True if the user did not change from the default value, currently only supported for `showInputBox` @@ -959,6 +959,15 @@ export interface IAzureUserInput { * @returns A promise that resolves to the selected resources. */ showOpenDialog(options: AzExtOpenDialogOptions): Promise; + + /** + * Shows a selection list of existing workspace folders to choose from. + * + * @param options Configures the behavior of the workspace folder list. + * @throws `UserCancelledError` if the user cancels. + * @returns A promise that resolves to the selected `WorkspaceFolder`. + */ + showWorkspaceFolderPick(options: AzExtWorkspaceFolderPickOptions): Promise; } /** @@ -1086,6 +1095,11 @@ export interface AzExtInputBoxOptions extends InputBoxOptions, AzExtUserInputOpt */ export interface AzExtOpenDialogOptions extends OpenDialogOptions, AzExtUserInputOptions { } +/** +* Provides additional options for workspace folder picks used in Azure Extensions +*/ +export type AzExtWorkspaceFolderPickOptions = WorkspaceFolderPickOptions & AzExtUserInputOptions; + /** * A queue of inputs that should be used by an {@link IAzureUserInput} implementation to answer prompts instead of showing prompts to the user. * If the head of the queue is undefined or null, then the {@link IAzureUserInput} implementation should show a prompt to the user. @@ -1107,6 +1121,7 @@ export declare class AzExtUserInputWithInputQueue implements IAzureUserInput { showWarningMessage(message: string, ...items: T[]): Promise; showWarningMessage(message: string, options: IAzureMessageOptions, ...items: T[]): Promise; showOpenDialog(options: AzExtOpenDialogOptions): Promise; + showWorkspaceFolderPick(options: AzExtWorkspaceFolderPickOptions): Promise; } export interface IWizardOptions { @@ -2231,6 +2246,7 @@ export interface IAzureAgentInput { showWarningMessage(message: string, ...items: T[]): Promise; showWarningMessage(message: string, options: IAzureMessageOptions, ...items: T[]): Promise; showOpenDialog(options: AzExtOpenDialogOptions): Promise; + showWorkspaceFolderPick(options: AzExtWorkspaceFolderPickOptions): Promise; } // #endregion diff --git a/utils/src/userInput/AzExtUserInput.ts b/utils/src/userInput/AzExtUserInput.ts index cb50a9fddc..d690d9c639 100644 --- a/utils/src/userInput/AzExtUserInput.ts +++ b/utils/src/userInput/AzExtUserInput.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Event, EventEmitter, MessageItem, Uri } from 'vscode'; +import { Event, EventEmitter, MessageItem, Uri, WorkspaceFolder } from 'vscode'; import * as types from '../../index'; import { UserCancelledError } from '../errors'; import { IInternalActionContext, IInternalAzureWizard } from './IInternalActionContext'; @@ -11,6 +11,7 @@ import { showInputBox } from './showInputBox'; import { showOpenDialog } from './showOpenDialog'; import { showQuickPick } from './showQuickPick'; import { showWarningMessage } from './showWarningMessage'; +import { showWorkspaceFolderPick } from './showWorkspaceFolderPick'; export class AzExtUserInput implements types.IAzureUserInput { public wizard?: IInternalAzureWizard; @@ -79,6 +80,21 @@ export class AzExtUserInput implements types.IAzureUserInput { } } + public async showWorkspaceFolderPick(options: types.AzExtWorkspaceFolderPickOptions): Promise { + addStepTelemetry(this._context, options.stepName, 'WorkspaceFolderPick', options.placeHolder); + if (this._context.ui.wizard?.cancellationToken.isCancellationRequested) { + throw new UserCancelledError(); + } + try { + this._isPrompting = true; + const result = await showWorkspaceFolderPick(options); + this._onDidFinishPromptEmitter.fire({ value: result }); + return result; + } finally { + this._isPrompting = false; + } + } + public async showWarningMessage(message: string, ...items: T[]): Promise; public async showWarningMessage(message: string, options: types.IAzureMessageOptions, ...items: T[]): Promise; // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/utils/src/userInput/AzExtUserInputWithInputQueue.ts b/utils/src/userInput/AzExtUserInputWithInputQueue.ts index 8f1c5830ce..feeb37abd6 100644 --- a/utils/src/userInput/AzExtUserInputWithInputQueue.ts +++ b/utils/src/userInput/AzExtUserInputWithInputQueue.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from "vscode"; -import { AzExtInputBoxOptions, AzExtOpenDialogOptions, AzureUserInputQueue, IAzureMessageOptions, IAzureQuickPickItem, IAzureQuickPickOptions, IAzureUserInput, PromptResult, type AzExtUserInputWithInputQueue as AzExtUserInputWithInputQueueType } from "../../"; +import { AzExtInputBoxOptions, AzExtOpenDialogOptions, AzExtWorkspaceFolderPickOptions, AzureUserInputQueue, IAzureMessageOptions, IAzureQuickPickItem, IAzureQuickPickOptions, IAzureUserInput, PromptResult, type AzExtUserInputWithInputQueue as AzExtUserInputWithInputQueueType } from "../../"; import { UserCancelledError } from "../errors"; import { AzExtUserInput, addStepTelemetry } from "./AzExtUserInput"; import { IInternalActionContext } from "./IInternalActionContext"; @@ -100,6 +100,26 @@ export class AzExtUserInputWithInputQueue implements AzExtUserInputWithInputQueu return result; } + public async showWorkspaceFolderPick(options: AzExtWorkspaceFolderPickOptions): Promise { + addStepTelemetry(this._context, options.stepName, 'WorkspaceFolderPick', options.placeHolder); + if (this._context.ui.wizard?.cancellationToken.isCancellationRequested) { + throw new UserCancelledError(); + } + this._isPrompting = true; + + let result: vscode.WorkspaceFolder; + const nextItemInQueue = (this._inputsQueue.shift() as vscode.WorkspaceFolder | null | undefined); + if (!nextItemInQueue) { + result = await this._realAzureUserInput.showWorkspaceFolderPick(options); + } else { + result = nextItemInQueue; + this._onDidFinishPromptEmitter.fire({ value: result }); + } + + this._isPrompting = false; + return result; + } + public async showWarningMessage(message: string, ...items: T[]): Promise; public async showWarningMessage(message: string, options: IAzureMessageOptions, ...items: T[]): Promise; // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/utils/src/userInput/showWorkspaceFolderPick.ts b/utils/src/userInput/showWorkspaceFolderPick.ts new file mode 100644 index 0000000000..39275c62e7 --- /dev/null +++ b/utils/src/userInput/showWorkspaceFolderPick.ts @@ -0,0 +1,20 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { WorkspaceFolder, WorkspaceFolderPickOptions, l10n, window } from "vscode"; +import { UserCancelledError } from "../errors"; + +export async function showWorkspaceFolderPick(options?: WorkspaceFolderPickOptions): Promise { + const folder: WorkspaceFolder | undefined = await window.showWorkspaceFolderPick({ + ...options, + placeHolder: options?.placeHolder ?? l10n.t('Select a root workspace folder') + }); + + if (!folder) { + throw new UserCancelledError('selectRootWorkspaceFolder'); + } + + return folder; +} diff --git a/utils/test/AzureAgentInputTypeCheck.test.ts b/utils/test/AzureAgentInputTypeCheck.test.ts index 5421e9f925..c76af8e49d 100644 --- a/utils/test/AzureAgentInputTypeCheck.test.ts +++ b/utils/test/AzureAgentInputTypeCheck.test.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from "assert"; -import { Event, MessageItem, QuickPickItem, Uri } from "vscode"; -import { AgentInputBoxOptions, AgentQuickPickItem, AgentQuickPickOptions, AzExtInputBoxOptions, AzExtOpenDialogOptions, IAzureAgentInput, IAzureMessageOptions, IAzureQuickPickOptions, IAzureUserInput, PromptResult } from ".."; +import { Event, MessageItem, QuickPickItem, Uri, WorkspaceFolder } from "vscode"; +import { AgentInputBoxOptions, AgentQuickPickItem, AgentQuickPickOptions, AzExtInputBoxOptions, AzExtOpenDialogOptions, AzExtWorkspaceFolderPickOptions, IAzureAgentInput, IAzureMessageOptions, IAzureQuickPickOptions, IAzureUserInput, PromptResult } from ".."; class MockAzureUserInput implements IAzureUserInput { onDidFinishPrompt: Event; @@ -25,6 +25,9 @@ class MockAzureUserInput implements IAzureUserInput { showOpenDialog(_options: AzExtOpenDialogOptions): Promise { throw new Error("Method not implemented."); } + showWorkspaceFolderPick(_options: AzExtWorkspaceFolderPickOptions): Promise { + throw new Error("Method not implemented."); + } } class MockAzureAgentInput implements IAzureAgentInput { @@ -45,6 +48,9 @@ class MockAzureAgentInput implements IAzureAgentInput { showOpenDialog(_options: AzExtOpenDialogOptions): Promise { throw new Error("Method not implemented."); } + showWorkspaceFolderPick(_options: AzExtWorkspaceFolderPickOptions): Promise { + throw new Error("Method not implemented."); + } } const mockAzureUserInput: IAzureUserInput = new MockAzureUserInput();