Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

utils: Add implementation for showWorkspaceFolderPick #1734

Merged
merged 6 commits into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions utils/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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`
Expand Down Expand Up @@ -959,6 +959,15 @@ export interface IAzureUserInput {
* @returns A promise that resolves to the selected resources.
*/
showOpenDialog(options: AzExtOpenDialogOptions): Promise<Uri[]>;

/**
* 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<WorkspaceFolder>;
Copy link
Member

@alexweininger alexweininger Jun 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make more sense to name it showWorkspaceFolderPicker? Is it a pick or a picker? This is a nit, I'm mostly asking and not asking for a change.

Copy link
Contributor Author

@MicroFish91 MicroFish91 Jun 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Picker is potentially a better name, but I was thinking to just keep the name mirrored with its VS Code analogue => vscode.window.showWorkspaceFolderPick

}

/**
Expand Down Expand Up @@ -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.
Expand All @@ -1107,6 +1121,7 @@ export declare class AzExtUserInputWithInputQueue implements IAzureUserInput {
showWarningMessage<T extends MessageItem>(message: string, ...items: T[]): Promise<T>;
showWarningMessage<T extends MessageItem>(message: string, options: IAzureMessageOptions, ...items: T[]): Promise<T>;
showOpenDialog(options: AzExtOpenDialogOptions): Promise<Uri[]>;
showWorkspaceFolderPick(options: AzExtWorkspaceFolderPickOptions): Promise<WorkspaceFolder>;
}

export interface IWizardOptions<T extends IActionContext> {
Expand Down Expand Up @@ -2231,6 +2246,7 @@ export interface IAzureAgentInput {
showWarningMessage<T extends MessageItem>(message: string, ...items: T[]): Promise<T>;
showWarningMessage<T extends MessageItem>(message: string, options: IAzureMessageOptions, ...items: T[]): Promise<T>;
showOpenDialog(options: AzExtOpenDialogOptions): Promise<Uri[]>;
showWorkspaceFolderPick(options: AzExtWorkspaceFolderPickOptions): Promise<WorkspaceFolder>;
}

// #endregion
Expand Down
8 changes: 4 additions & 4 deletions utils/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
},
"devDependencies": {
"@microsoft/eslint-config-azuretools": "^0.2.1",
"@microsoft/vscode-azext-dev": "^2.0.0",
"@microsoft/vscode-azext-dev": "^2.0.4",
"@types/html-to-text": "^8.1.0",
"@types/mocha": "^7.0.2",
"@types/node": "^16.0.0",
Expand Down
18 changes: 17 additions & 1 deletion utils/src/userInput/AzExtUserInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
* 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';
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;
Expand Down Expand Up @@ -79,6 +80,21 @@ export class AzExtUserInput implements types.IAzureUserInput {
}
}

public async showWorkspaceFolderPick(options: types.AzExtWorkspaceFolderPickOptions): Promise<WorkspaceFolder> {
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<T extends MessageItem>(message: string, ...items: T[]): Promise<T>;
public async showWarningMessage<T extends MessageItem>(message: string, options: types.IAzureMessageOptions, ...items: T[]): Promise<T>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down
22 changes: 21 additions & 1 deletion utils/src/userInput/AzExtUserInputWithInputQueue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -100,6 +100,26 @@ export class AzExtUserInputWithInputQueue implements AzExtUserInputWithInputQueu
return result;
}

public async showWorkspaceFolderPick(options: AzExtWorkspaceFolderPickOptions): Promise<vscode.WorkspaceFolder> {
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<T extends vscode.MessageItem>(message: string, ...items: T[]): Promise<T>;
public async showWarningMessage<T extends vscode.MessageItem>(message: string, options: IAzureMessageOptions, ...items: T[]): Promise<T>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down
20 changes: 20 additions & 0 deletions utils/src/userInput/showWorkspaceFolderPick.ts
Original file line number Diff line number Diff line change
@@ -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<WorkspaceFolder> {
const folder: WorkspaceFolder | undefined = await window.showWorkspaceFolderPick({
...options,
placeHolder: options?.placeHolder ?? l10n.t('Select a workspace folder')
});

if (!folder) {
throw new UserCancelledError('selectWorkspaceFolder');
}

return folder;
}
10 changes: 8 additions & 2 deletions utils/test/AzureAgentInputTypeCheck.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<PromptResult>;
Expand All @@ -25,6 +25,9 @@ class MockAzureUserInput implements IAzureUserInput {
showOpenDialog(_options: AzExtOpenDialogOptions): Promise<Uri[]> {
throw new Error("Method not implemented.");
}
showWorkspaceFolderPick(_options: AzExtWorkspaceFolderPickOptions): Promise<WorkspaceFolder> {
throw new Error("Method not implemented.");
}
}

class MockAzureAgentInput implements IAzureAgentInput {
Expand All @@ -45,6 +48,9 @@ class MockAzureAgentInput implements IAzureAgentInput {
showOpenDialog(_options: AzExtOpenDialogOptions): Promise<Uri[]> {
throw new Error("Method not implemented.");
}
showWorkspaceFolderPick(_options: AzExtWorkspaceFolderPickOptions): Promise<WorkspaceFolder> {
throw new Error("Method not implemented.");
}
}

const mockAzureUserInput: IAzureUserInput = new MockAzureUserInput();
Expand Down
Loading