1
>
/*---------------------------------------------------------------------------------------------
dialogs.ts
2
>
* Copyright (c) Microsoft Corporation. All rights reserved.
3
>
* Licensed under the MIT License. See License.txt in the project root for license information.
4
>
*--------------------------------------------------------------------------------------------*/
5
>
6
>
import { CancellationToken } from '../../../base/common/cancellation.js';
7
>
import { Event } from '../../../base/common/event.js';
8
>
import { ThemeIcon } from '../../../base/common/themables.js';
9
>
import { IMarkdownString } from '../../../base/common/htmlContent.js';
10
>
import { basename } from '../../../base/common/resources.js';
11
>
import Severity from '../../../base/common/severity.js';
12
>
import { URI } from '../../../base/common/uri.js';
13
>
import { localize } from '../../../nls.js';
14
>
import { createDecorator } from '../../instantiation/common/instantiation.js';
15
>
import { ITelemetryData } from '../../telemetry/common/telemetry.js';
16
>
17
>
export interface IDialogArgs {
18
>
readonly confirmArgs?: IConfirmDialogArgs;
19
>
readonly inputArgs?: IInputDialogArgs;
20
>
readonly promptArgs?: IPromptDialogArgs;
21
>
}
22
>
23
>
export interface IBaseDialogOptions {
24
>
readonly type?: Severity | DialogType;
25
>
26
>
readonly title?: string;
27
>
readonly message: string;
28
>
readonly detail?: string;
29
>
30
>
readonly checkbox?: ICheckbox;
31
>
32
>
/**
33
>
* Allows to enforce use of custom dialog even in native environments.
34
>
*/
35
>
readonly custom?: boolean | ICustomDialogOptions;
36
>
37
>
/**
38
>
* An optional cancellation token that can be used to dismiss the dialog
39
>
* programmatically for custom dialog implementations.
40
>
*
41
>
* When cancelled, the custom dialog resolves as if the cancel button was
42
>
* pressed. Native dialog handlers cannot currently be dismissed
43
>
* programmatically and ignore this option unless a custom dialog is
44
>
* explicitly enforced via the {@link custom} option.
45
>
*/
46
>
readonly token?: CancellationToken;
47
>
}
48
>
49
>
export interface IConfirmDialogArgs {
50
>
readonly confirmation: IConfirmation;
51
>
}
52
>
53
>
export interface IConfirmation extends IBaseDialogOptions {
54
>
55
>
/**
56
>
* If not provided, defaults to `Yes`.
57
>
*/
58
>
readonly primaryButton?: string;
59
>
60
>
/**
61
>
* If not provided, defaults to `Cancel`.
62
>
*/
63
>
readonly cancelButton?: string;
64
>
}
65
>
66
>
export interface IConfirmationResult extends ICheckboxResult {
67
>
68
>
/**
69
>
* Will be true if the dialog was confirmed with the primary button pressed.
70
>
*/
71
>
readonly confirmed: boolean;
72
>
}
73
>
74
>
export interface IInputDialogArgs {
75
>
readonly input: IInput;
76
>
}
77
>
78
>
export interface IInput extends IConfirmation {
79
>
readonly inputs: IInputElement[];
80
>
81
>
/**
82
>
* If not provided, defaults to `Ok`.
83
>
*/
84
>
readonly primaryButton?: string;
85
>
}
86
>
87
>
export interface IInputElement {
88
>
readonly type?: 'text' | 'password';
89
>
readonly value?: string;
90
>
readonly placeholder?: string;
91
>
}
92
>
93
>
export interface IInputResult extends IConfirmationResult {
94
>
95
>
/**
96
>
* Values for the input fields as provided by the user or `undefined` if none.
97
>
*/
98
>
readonly values?: string[];
99
>
}
100
>
101
>
export interface IPromptDialogArgs {
102
>
readonly prompt: IPrompt<unknown>;
103
>
}
104
>
105
>
export interface IPromptBaseButton<T> {
106
>
107
>
/**
108
>
* @returns the result of the prompt button will be returned
109
>
* as result from the `prompt()` call.
110
>
*/
111
>
run(checkbox: ICheckboxResult): T | Promise<T>;
112
>
}
113
>
114
>
export interface IPromptButton<T> extends IPromptBaseButton<T> {
115
>
readonly label: string;
116
>
}
117
>
118
>
export interface IPromptCancelButton<T> extends IPromptBaseButton<T> {
119
>
120
>
/**
121
>
* The cancel button to show in the prompt. Defaults to
122
>
* `Cancel` if not provided.
123
>
*/
124
>
readonly label?: string;
125
>
}
126
>
127
>
export interface IPrompt<T> extends IBaseDialogOptions {
128
>
129
>
/**
130
>
* The buttons to show in the prompt. Defaults to `OK`
131
>
* if no buttons or cancel button is provided.
132
>
*/
133
>
readonly buttons?: IPromptButton<T>[];
134
>
135
>
/**
136
>
* The cancel button to show in the prompt. Defaults to
137
>
* `Cancel` if set to `true`.
138
>
*/
139
>
readonly cancelButton?: IPromptCancelButton<T> | true | string;
140
>
}
141
>
142
>
export interface IPromptWithCustomCancel<T> extends IPrompt<T> {
143
>
readonly cancelButton: IPromptCancelButton<T>;
144
>
}
145
>
146
>
export interface IPromptWithDefaultCancel<T> extends IPrompt<T> {
147
>
readonly cancelButton: true | string;
148
>
}
149
>
150
>
export interface IPromptResult<T> extends ICheckboxResult {
151
>
152
>
/**
153
>
* The result of the `IPromptButton` that was pressed or `undefined` if none.
154
>
*/
155
>
readonly result?: T;
156
>
}
157
>
158
>
export interface IPromptResultWithCancel<T> extends IPromptResult<T> {
159
>
readonly result: T;
160
>
}
161
>
162
>
export interface IAsyncPromptResult<T> extends ICheckboxResult {
163
>
164
>
/**
165
>
* The result of the `IPromptButton` that was pressed or `undefined` if none.
166
>
*/
167
>
readonly result?: Promise<T>;
168
>
}
169
>
170
>
export interface IAsyncPromptResultWithCancel<T> extends IAsyncPromptResult<T> {
171
>
readonly result: Promise<T>;
172
>
}
173
>
174
>
export type IDialogResult = IConfirmationResult | IInputResult | IAsyncPromptResult<unknown>;
175
>
176
>
export type DialogType = 'none' | 'info' | 'error' | 'question' | 'warning';
177
>
178
>
export interface ICheckbox {
179
>
readonly label: string;
180
>
readonly checked?: boolean;
181
>
}
182
>
183
>
export interface ICheckboxResult {
184
>
185
>
/**
186
>
* This will only be defined if the confirmation was created
187
>
* with the checkbox option defined.
188
>
*/
189
>
readonly checkboxChecked?: boolean;
190
>
}
191
>
192
>
export interface IPickAndOpenOptions {
193
>
readonly forceNewWindow?: boolean;
194
>
defaultUri?: URI;
195
>
readonly telemetryExtraData?: ITelemetryData;
196
>
availableFileSystems?: string[];
197
>
remoteAuthority?: string | null;
198
>
}
199
>
200
>
export interface FileFilter {
201
>
readonly extensions: string[];
202
>
readonly name: string;
203
>
}
204
>
205
>
export interface ISaveDialogOptions {
206
>
207
>
/**
208
>
* A human-readable string for the dialog title
209
>
*/
210
>
title?: string;
211
>
212
>
/**
213
>
* The resource the dialog shows when opened.
214
>
*/
215
>
defaultUri?: URI;
216
>
217
>
/**
218
>
* A set of file filters that are used by the dialog. Each entry is a human readable label,
219
>
* like "TypeScript", and an array of extensions.
220
>
*/
221
>
filters?: FileFilter[];
222
>
223
>
/**
224
>
* A human-readable string for the ok button
225
>
*/
226
>
readonly saveLabel?: { readonly withMnemonic: string; readonly withoutMnemonic: string } | string;
227
>
228
>
/**
229
>
* Specifies a list of schemas for the file systems the user can save to. If not specified, uses the schema of the defaultURI or, if also not specified,
230
>
* the schema of the current window.
231
>
*/
232
>
availableFileSystems?: readonly string[];
233
>
}
234
>
235
>
export interface IOpenDialogOptions {
236
>
237
>
/**
238
>
* A human-readable string for the dialog title
239
>
*/
240
>
readonly title?: string;
241
>
242
>
/**
243
>
* The resource the dialog shows when opened.
244
>
*/
245
>
defaultUri?: URI;
246
>
247
>
/**
248
>
* A human-readable string for the open button.
249
>
*/
250
>
readonly openLabel?: { readonly withMnemonic: string; readonly withoutMnemonic: string } | string;
251
>
252
>
/**
253
>
* Allow to select files, defaults to `true`.
254
>
*/
255
>
canSelectFiles?: boolean;
256
>
257
>
/**
258
>
* Allow to select folders, defaults to `false`.
259
>
*/
260
>
canSelectFolders?: boolean;
261
>
262
>
/**
263
>
* Allow to select many files or folders.
264
>
*/
265
>
readonly canSelectMany?: boolean;
266
>
267
>
/**
268
>
* A set of file filters that are used by the dialog. Each entry is a human readable label,
269
>
* like "TypeScript", and an array of extensions.
270
>
*/
271
>
filters?: FileFilter[];
272
>
273
>
/**
274
>
* Specifies a list of schemas for the file systems the user can load from. If not specified, uses the schema of the defaultURI or, if also not available,
275
>
* the schema of the current window.
276
>
*/
277
>
availableFileSystems?: readonly string[];
278
>
}
279
>
280
>
export const IDialogService = createDecorator<IDialogService>('dialogService');
281
>
282
>
export interface ICustomDialogOptions {
283
>
readonly buttonDetails?: string[];
284
>
readonly markdownDetails?: ICustomDialogMarkdown[];
285
>
readonly classes?: string[];
286
>
readonly icon?: ThemeIcon;
287
>
readonly disableCloseAction?: boolean;
288
>
}
289
>
290
>
export interface ICustomDialogMarkdown {
291
>
readonly markdown: IMarkdownString;
292
>
readonly classes?: string[];
293
>
/** Custom link handler for markdown content, see {@link IContentActionHandler}. Defaults to {@link openLinkFromMarkdown}. */
294
>
actionHandler?(link: string): Promise<boolean>;
295
>
}
296
>
297
>
/**
298
>
* A handler to bring up modal dialogs.
299
>
*/
300
>
export interface IDialogHandler {
301
>
302
>
/**
303
>
* Ask the user for confirmation with a modal dialog.
304
>
*/
305
>
confirm(confirmation: IConfirmation): Promise<IConfirmationResult>;
306
>
307
>
/**
308
>
* Prompt the user with a modal dialog.
309
>
*/
310
>
prompt<T>(prompt: IPrompt<T>): Promise<IAsyncPromptResult<T>>;
311
>
312
>
/**
313
>
* Present a modal dialog to the user asking for input.
314
>
*/
315
>
input(input: IInput): Promise<IInputResult>;
316
>
317
>
/**
318
>
* Present the about dialog to the user.
319
>
*/
320
>
about(title: string, details: string, detailsToCopy: string): Promise<void>;
321
>
}
322
>
323
>
enum DialogKind {
324
>
Confirmation = 1,
325
>
Prompt,
326
>
Input
327
>
}
328
>
329
>
export abstract class AbstractDialogHandler implements IDialogHandler {
330
>
331
>
protected getConfirmationButtons(dialog: IConfirmation): string[] {
332
return this.getButtons(dialog, DialogKind.Confirmation);
333
}
335
>
protected getPromptButtons(dialog: IPrompt<unknown>): string[] {
336
return this.getButtons(dialog, DialogKind.Prompt);
337
}
339
>
protected getInputButtons(dialog: IInput): string[] {
340
return this.getButtons(dialog, DialogKind.Input);
341
}
343
>
private getButtons(dialog: IConfirmation, kind: DialogKind.Confirmation): string[];
344
>
private getButtons(dialog: IPrompt<unknown>, kind: DialogKind.Prompt): string[];
345
>
private getButtons(dialog: IInput, kind: DialogKind.Input): string[];
346
>
private getButtons(dialog: IConfirmation | IInput | IPrompt<unknown>, kind: DialogKind): string[] {
347
348
// We put buttons in the order of "default" button first and "cancel"