Skip to content

Commit 30a8e98

Browse files
Fix: Return to quick pick when cancelling file picker dialog (#1037)
1 parent 842793f commit 30a8e98

File tree

2 files changed

+51
-16
lines changed

2 files changed

+51
-16
lines changed

src/commands/image/imageSource/buildImageInAzure/SourcePathStep.ts

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,28 @@ import { AzureWizardPromptStep, type IAzureQuickPickItem } from '@microsoft/vsco
77
import * as path from 'path';
88
import { browseItem } from '../../../../constants';
99
import { localize } from '../../../../utils/localize';
10+
import { quickPickWithBrowse } from '../../../../utils/workspaceUtils';
1011
import { type BuildImageInAzureImageSourceContext } from './BuildImageInAzureImageSourceContext';
1112

1213
export class SourcePathStep extends AzureWizardPromptStep<BuildImageInAzureImageSourceContext> {
1314
public async prompt(context: BuildImageInAzureImageSourceContext): Promise<void> {
14-
const srcPath: string | undefined = (await context.ui.showQuickPick(this.getPicks(context), {
15-
placeHolder: localize('sourceDirectoryPick', 'Choose your source code directory'),
16-
suppressPersistence: true
17-
})).data;
18-
19-
context.srcPath = srcPath ?? (await context.ui.showOpenDialog({
20-
defaultUri: context.rootFolder?.uri,
21-
canSelectFiles: false,
22-
canSelectFolders: true
23-
}))[0].fsPath;
15+
const srcPath = await quickPickWithBrowse(
16+
context,
17+
this.getPicks(context),
18+
{
19+
placeHolder: localize('sourceDirectoryPick', 'Choose your source code directory'),
20+
suppressPersistence: true,
21+
},
22+
{
23+
defaultUri: context.rootFolder?.uri,
24+
canSelectFiles: false,
25+
canSelectFolders: true,
26+
},
27+
);
28+
29+
if (srcPath) {
30+
context.srcPath = srcPath;
31+
}
2432
}
2533

2634
public async configureBeforePrompt(context: BuildImageInAzureImageSourceContext): Promise<void> {

src/utils/workspaceUtils.ts

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { nonNullValue, type IActionContext, type IAzureQuickPickItem } from "@microsoft/vscode-azext-utils";
6+
import { UserCancelledError, nonNullValue, type IActionContext, type IAzureQuickPickItem, type IAzureQuickPickOptions } from "@microsoft/vscode-azext-utils";
77
import { basename, relative } from "path";
88
import { RelativePattern, Uri, workspace, type OpenDialogOptions, type WorkspaceFolder } from "vscode";
99
import { browseItem, dockerfileGlobPattern, envFileGlobPattern } from "../constants";
@@ -80,11 +80,38 @@ export async function selectWorkspaceFile(
8080
});
8181
}
8282

83-
const input: string | undefined = (await context.ui.showQuickPick(quickPicks, { placeHolder })).data;
84-
if (input === skipForNow) {
85-
return undefined;
86-
} else {
87-
return input || (await context.ui.showOpenDialog(options))[0].fsPath;
83+
return await quickPickWithBrowse(context, quickPicks, { placeHolder }, options, skipForNow);
84+
}
85+
86+
/**
87+
* Shows a quick pick that includes a "Browse..." option. If the user selects "Browse..." and then
88+
* cancels the native file picker dialog, re-prompts the quick pick instead of exiting the wizard.
89+
*
90+
* @param skipValue - If the selected item's data matches this value, returns `undefined` (used for "Skip for now")
91+
*/
92+
export async function quickPickWithBrowse(
93+
context: IActionContext,
94+
picks: IAzureQuickPickItem<string | undefined>[],
95+
quickPickOptions: IAzureQuickPickOptions,
96+
openDialogOptions: OpenDialogOptions,
97+
skipValue?: string,
98+
): Promise<string | undefined> {
99+
while (true) {
100+
const input: string | undefined = (await context.ui.showQuickPick(picks, quickPickOptions)).data;
101+
if (input === skipValue) {
102+
return undefined;
103+
} else if (input) {
104+
return input;
105+
} else {
106+
try {
107+
return (await context.ui.showOpenDialog(openDialogOptions))[0].fsPath;
108+
} catch (e) {
109+
if (e instanceof UserCancelledError) {
110+
continue;
111+
}
112+
throw e;
113+
}
114+
}
88115
}
89116
}
90117

0 commit comments

Comments
 (0)