src/vs/platform/notification/common/notification.ts

491 LOC · 477 covered · 14 uncovered · 5 ranges · 2573 concepts · 3 introducers · 1289 tests

File neighbourhood

The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the related-file, concept, and source links on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.

1 > /*--------------------------------------------------------------------------------------------- notification.ts ×3
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 { localize } from '../../../nls.js';
7 > import { IAction } from '../../../base/common/actions.js';
8 > import { Event } from '../../../base/common/event.js';
9 > import BaseSeverity from '../../../base/common/severity.js';
10 > import { createDecorator } from '../../instantiation/common/instantiation.js';
11 >
12 > export import Severity = BaseSeverity;
13 >
14 > export const INotificationService = createDecorator<INotificationService>('notificationService');
15 >
16 > export type NotificationMessage = string | Error;
17 >
18 > export enum NotificationPriority {
19 >
20 > /**
21 > * Default priority: notification will be visible unless do not disturb mode is enabled.
22 > */
23 > DEFAULT,
24 >
25 > /**
26 > * Optional priority: notification might only be visible from the notifications center.
27 > */
28 > OPTIONAL,
29 >
30 > /**
31 > * Silent priority: notification will only be visible from the notifications center.
32 > */
33 > SILENT,
34 >
35 > /**
36 > * Urgent priority: notification will be visible even when do not disturb mode is enabled.
37 > */
38 > URGENT
39 > }
40 >
41 > export interface INotificationProperties {
42 >
43 > /**
44 > * Sticky notifications are not automatically removed after a certain timeout.
45 > *
46 > * Currently, only 2 kinds of notifications are sticky:
47 > * - Error notifications with primary actions
48 > * - Notifications that show progress
49 > */
50 > readonly sticky?: boolean;
51 >
52 > /**
53 > * Allows to override the priority of the notification based on needs.
54 > */
55 > readonly priority?: NotificationPriority;
56 >
57 > /**
58 > * Adds an action to never show the notification again. The choice will be persisted
59 > * such as future requests will not cause the notification to show again.
60 > */
61 > readonly neverShowAgain?: INeverShowAgainOptions;
62 > }
63 >
64 > export enum NeverShowAgainScope {
65 >
66 > /**
67 > * Will never show this notification on the current workspace again.
68 > */
69 > WORKSPACE,
70 >
71 > /**
72 > * Will never show this notification on any workspace of the same
73 > * profile again.
74 > */
75 > PROFILE,
76 >
77 > /**
78 > * Will never show this notification on any workspace across all
79 > * profiles again.
80 > */
81 > APPLICATION
82 > }
83 >
84 > export interface INeverShowAgainOptions {
85 >
86 > /**
87 > * The id is used to persist the selection of not showing the notification again.
88 > */
89 > readonly id: string;
90 >
91 > /**
92 > * By default the action will show up as primary action. Setting this to true will
93 > * make it a secondary action instead.
94 > */
95 > readonly isSecondary?: boolean;
96 >
97 > /**
98 > * Whether to persist the choice in the current workspace or for all workspaces. By
99 > * default it will be persisted for all workspaces across all profiles
100 > * (= `NeverShowAgainScope.APPLICATION`).
101 > */
102 > readonly scope?: NeverShowAgainScope;
103 > }
104 >
105 > export interface INotificationSource {
106 >
107 > /**
108 > * The id of the source.
109 > */
110 > readonly id: string;
111 >
112 > /**
113 > * The label of the source.
114 > */
115 > readonly label: string;
116 > }
117 >
118 > export function isNotificationSource(thing: unknown): thing is INotificationSource {
119 > if (thing) { notifications.ts ×25
120 > const candidate = thing as INotificationSource;
121 >
122 > return typeof candidate.id === 'string' && typeof candidate.label === 'string';
123 > }
124 >
125 > return false;
126 > }
128 > export interface INotification extends INotificationProperties {
129 >
130 > /**
131 > * The id of the notification. If provided, will be used to compare
132 > * notifications with others to decide whether a notification is
133 > * duplicate or not.
134 > */
135 > readonly id?: string;
136 >
137 > /**
138 > * The severity of the notification. Either `Info`, `Warning` or `Error`.
139 > */
140 > readonly severity: Severity;
141 >
142 > /**
143 > * The message of the notification. This can either be a `string` or `Error`. Messages
144 > * can optionally include links in the format: `[text](link)`
145 > */
146 > readonly message: NotificationMessage;
147 >
148 > /**
149 > * The source of the notification appears as additional information.
150 > */
151 > readonly source?: string | INotificationSource;
152 >
153 > /**
154 > * Actions to show as part of the notification. Primary actions show up as
155 > * buttons as part of the message and will close the notification once clicked.
156 > *
157 > * Secondary actions are meant to provide additional configuration or context
158 > * for the notification and will show up less prominent. A notification does not
159 > * close automatically when invoking a secondary action.
160 > *
161 > * **Note:** If your intent is to show a message with actions to the user, consider
162 > * the `INotificationService.prompt()` method instead which are optimized for
163 > * this usecase and much easier to use!
164 > */
165 > actions?: INotificationActions;
166 >
167 > /**
168 > * The initial set of progress properties for the notification. To update progress
169 > * later on, access the `INotificationHandle.progress` property.
170 > */
171 > readonly progress?: INotificationProgressProperties;
172 > }
173 >
174 > export interface INotificationActions {
175 >
176 > /**
177 > * Primary actions show up as buttons as part of the message and will close
178 > * the notification once clicked.
179 > *
180 > * Pass `ActionWithMenuAction` for an action that has additional menu actions.
181 > */
182 > readonly primary?: readonly IAction[];
183 >
184 > /**
185 > * Secondary actions are meant to provide additional configuration or context
186 > * for the notification and will show up less prominent. A notification does not
187 > * close automatically when invoking a secondary action.
188 > */
189 > readonly secondary?: readonly IAction[];
190 > }
191 >
192 > export interface INotificationProgressProperties {
193 >
194 > /**
195 > * Causes the progress bar to spin infinitley.
196 > */
197 > readonly infinite?: boolean;
198 >
199 > /**
200 > * Indicate the total amount of work.
201 > */
202 > readonly total?: number;
203 >
204 > /**
205 > * Indicate that a specific chunk of work is done.
206 > */
207 > readonly worked?: number;
208 > }
209 >
210 > export interface INotificationProgress {
211 >
212 > /**
213 > * Causes the progress bar to spin infinitley.
214 > */
215 > infinite(): void;
216 >
217 > /**
218 > * Indicate the total amount of work.
219 > */
220 > total(value: number): void;
221 >
222 > /**
223 > * Indicate that a specific chunk of work is done.
224 > */
225 > worked(value: number): void;
226 >
227 > /**
228 > * Indicate that the long running operation is done.
229 > */
230 > done(): void;
231 > }
232 >
233 > export interface INotificationHandle {
234 >
235 > /**
236 > * Will be fired once the notification is closed.
237 > */
238 > readonly onDidClose: Event<void>;
239 >
240 > /**
241 > * Will be fired whenever the visibility of the notification changes.
242 > * A notification can either be visible as toast or inside the notification
243 > * center if it is visible.
244 > */
245 > readonly onDidChangeVisibility: Event<boolean>;
246 >
247 > /**
248 > * Allows to indicate progress on the notification even after the
249 > * notification is already visible.
250 > */
251 > readonly progress: INotificationProgress;
252 >
253 > /**
254 > * Allows to update the severity of the notification.
255 > */
256 > updateSeverity(severity: Severity): void;
257 >
258 > /**
259 > * Allows to update the message of the notification even after the
260 > * notification is already visible.
261 > */
262 > updateMessage(message: NotificationMessage): void;
263 >
264 > /**
265 > * Allows to update the actions of the notification even after the
266 > * notification is already visible.
267 > */
268 > updateActions(actions?: INotificationActions): void;
269 >
270 > /**
271 > * Hide the notification and remove it from the notification center.
272 > */
273 > close(): void;
274 > }
275 >
276 > export interface IStatusHandle {
277 >
278 > /**
279 > * Hide the status message.
280 > */
281 > close(): void;
282 > }
283 >
284 > interface IBasePromptChoice {
285 >
286 > /**
287 > * Label to show for the choice to the user.
288 > */
289 > readonly label: string;
290 >
291 > /**
292 > * Whether to keep the notification open after the choice was selected
293 > * by the user. By default, will close the notification upon click.
294 > */
295 > readonly keepOpen?: boolean;
296 >
297 > /**
298 > * Triggered when the user selects the choice.
299 > */
300 > run: () => void;
301 > }
302 >
303 > export interface IPromptChoice extends IBasePromptChoice {
304 >
305 > /**
306 > * Primary choices show up as buttons in the notification below the message.
307 > * Secondary choices show up under the gear icon in the header of the notification.
308 > */
309 > readonly isSecondary?: boolean;
310 > }
311 >
312 > export interface IPromptChoiceWithMenu extends IPromptChoice {
313 >
314 > /**
315 > * Additional choices those will be shown in the dropdown menu for this choice.
316 > */
317 > readonly menu: IBasePromptChoice[];
318 >
319 > /**
320 > * Menu is not supported on secondary choices
321 > */
322 > readonly isSecondary: false | undefined;
323 > }
324 >
325 > export interface IPromptOptions extends INotificationProperties {
326 >
327 > /**
328 > * Will be called if the user closed the notification without picking
329 > * any of the provided choices.
330 > */
331 > onCancel?: () => void;
332 > }
333 >
334 > export interface IStatusMessageOptions {
335 >
336 > /**
337 > * An optional timeout after which the status message should show. By default
338 > * the status message will show immediately.
339 > */
340 > readonly showAfter?: number;
341 >
342 > /**
343 > * An optional timeout after which the status message is to be hidden. By default
344 > * the status message will not hide until another status message is displayed.
345 > */
346 > readonly hideAfter?: number;
347 > }
348 >
349 > export enum NotificationsFilter {
350 >
351 > /**
352 > * No filter is enabled.
353 > */
354 > OFF,
355 >
356 > /**
357 > * All notifications are silent except error notifications.
358 > */
359 > ERROR
360 > }
361 >
362 > export interface INotificationSourceFilter extends INotificationSource {
363 > readonly filter: NotificationsFilter;
364 > }
365 >
366 > /**
367 > * A service to bring up notifications and non-modal prompts.
368 > *
369 > * Note: use the `IDialogService` for a modal way to ask the user for input.
370 > */
371 > export interface INotificationService {
372 >
373 > readonly _serviceBrand: undefined;
374 >
375 > /**
376 > * Emitted when the notifications filter changed.
377 > */
378 > readonly onDidChangeFilter: Event<void>;
379 >
380 > /**
381 > * Sets a notification filter either for all notifications
382 > * or for a specific source.
383 > */
384 > setFilter(filter: NotificationsFilter | INotificationSourceFilter): void;
385 >
386 > /**
387 > * Gets the notification filter either for all notifications
388 > * or for a specific source.
389 > */
390 > getFilter(source?: INotificationSource): NotificationsFilter;
391 >
392 > /**
393 > * Returns all filters with their sources.
394 > */
395 > getFilters(): INotificationSourceFilter[];
396 >
397 > /**
398 > * Removes a filter for a specific source.
399 > */
400 > removeFilter(sourceId: string): void;
401 >
402 > /**
403 > * Show the provided notification to the user. The returned `INotificationHandle`
404 > * can be used to control the notification afterwards.
405 > *
406 > * **Note:** If your intent is to show a message with actions to the user, consider
407 > * the `INotificationService.prompt()` method instead which are optimized for
408 > * this usecase and much easier to use!
409 > *
410 > * @returns a handle on the notification to e.g. hide it or update message, buttons, etc.
411 > */
412 > notify(notification: INotification): INotificationHandle;
413 >
414 > /**
415 > * A convenient way of reporting infos. Use the `INotificationService.notify`
416 > * method if you need more control over the notification.
417 > */
418 > info(message: NotificationMessage | NotificationMessage[]): void;
419 >
420 > /**
421 > * A convenient way of reporting warnings. Use the `INotificationService.notify`
422 > * method if you need more control over the notification.
423 > */
424 > warn(message: NotificationMessage | NotificationMessage[]): void;
425 >
426 > /**
427 > * A convenient way of reporting errors. Use the `INotificationService.notify`
428 > * method if you need more control over the notification.
429 > */
430 > error(message: NotificationMessage | NotificationMessage[]): void;
431 >
432 > /**
433 > * Shows a prompt in the notification area with the provided choices. The prompt
434 > * is non-modal. If you want to show a modal dialog instead, use `IDialogService`.
435 > *
436 > * @param severity the severity of the notification. Either `Info`, `Warning` or `Error`.
437 > * @param message the message to show as status.
438 > * @param choices options to be chosen from.
439 > * @param options provides some optional configuration options.
440 > *
441 > * @returns a handle on the notification to e.g. hide it or update message, buttons, etc.
442 > */
443 > prompt(severity: Severity, message: string, choices: (IPromptChoice | IPromptChoiceWithMenu)[], options?: IPromptOptions): INotificationHandle;
444 >
445 > /**
446 > * Shows a status message in the status area with the provided text.
447 > *
448 > * @param message the message to show as status
449 > * @param options provides some optional configuration options
450 > *
451 > * @returns a handle to hide the status message
452 > */
453 > status(message: NotificationMessage, options?: IStatusMessageOptions): IStatusHandle;
454 > }
455 >
456 > export class NoOpNotification implements INotificationHandle {
458 > readonly progress = new NoOpProgress();
459 >
460 > readonly onDidClose = Event.None;
461 > readonly onDidChangeVisibility = Event.None;
463 > updateSeverity(severity: Severity): void { }
464 > updateMessage(message: NotificationMessage): void { }
465 > updateActions(actions?: INotificationActions): void { }
466 >
467 > close(): void { }
468 > }
469 >
470 > export class NoOpProgress implements INotificationProgress {
471 > infinite(): void { }
472 > done(): void { }
473 > total(value: number): void { }
474 > worked(value: number): void { }
475 > }
476 >
477 > export function withSeverityPrefix(label: string, severity: Severity): string {
478
479 // Add severity prefix to match WCAG 4.1.3 Status
480 // Messages requirements.
481
482 if (severity === Severity.Error) {
483 return localize('severityPrefix.error', "Error: {0}", label);
484 }
485
486 if (severity === Severity.Warning) {
487 return localize('severityPrefix.warning', "Warning: {0}", label);
488 }
489
490 return localize('severityPrefix.info', "Info: {0}", label);
491 }