@jupyterlab/apputils
Version:
JupyterLab - Application Utilities
310 lines • 10.2 kB
JavaScript
/*
* Copyright (c) Jupyter Development Team.
* Distributed under the terms of the Modified BSD License.
*/
import { UUID } from '@lumino/coreutils';
import { Signal } from '@lumino/signaling';
/**
* Notification manager
*/
export class NotificationManager {
constructor() {
this._isDisposed = false;
this._queue = [];
this._changed = new Signal(this);
}
/**
* Signal emitted whenever a notification changes.
*/
get changed() {
return this._changed;
}
/**
* Total number of notifications.
*/
get count() {
return this._queue.length;
}
/**
* Whether the manager is disposed or not.
*/
get isDisposed() {
return this._isDisposed;
}
/**
* The list of notifications.
*/
get notifications() {
return this._queue.slice();
}
/**
* Dismiss one notification (specified by its id) or all if no id provided.
*
* @param id Notification id
*/
dismiss(id) {
if (typeof id === 'undefined') {
const q = this._queue.slice();
this._queue.length = 0;
for (const notification of q) {
this._changed.emit({
type: 'removed',
notification
});
}
}
else {
const notificationIndex = this._queue.findIndex(n => n.id === id);
if (notificationIndex > -1) {
const notification = this._queue.splice(notificationIndex, 1)[0];
this._changed.emit({
type: 'removed',
notification
});
}
}
}
/**
* Dispose the manager.
*/
dispose() {
if (this._isDisposed) {
return;
}
this._isDisposed = true;
Signal.clearData(this);
}
/**
* Test whether a notification exists or not.
*
* @param id Notification id
* @returns Notification status
*/
has(id) {
return this._queue.findIndex(n => n.id === id) > -1;
}
/**
* Add a new notification.
*
* This will trigger the `changed` signal with an `added` event.
*
* @param message Notification message
* @param type Notification type
* @param options Notification option
* @returns Notification unique id
*/
notify(message, type, options) {
const now = Date.now();
const { progress, ...othersOptions } = options;
const notification = Object.freeze({
id: UUID.uuid4(),
createdAt: now,
modifiedAt: now,
message,
type,
options: {
// By default notification will be silent
autoClose: 0,
progress: typeof progress === 'number'
? Math.min(Math.max(0, progress), 1)
: progress,
...othersOptions
}
});
this._queue.unshift(notification);
this._changed.emit({
type: 'added',
notification
});
return notification.id;
}
/**
* Update an existing notification.
*
* If the notification does not exists this won't do anything.
*
* Once updated the notification will be moved at the begin
* of the notification stack.
*
* @param args Update options
* @returns Whether the update was successful or not.
*/
update(args) {
const { id, message, actions, autoClose, data, progress, type } = args;
const newProgress = typeof progress === 'number'
? Math.min(Math.max(0, progress), 1)
: progress;
const notificationIndex = this._queue.findIndex(n => n.id === id);
if (notificationIndex > -1) {
const oldNotification = this._queue[notificationIndex];
// We need to create a new object as notification are frozen; i.e. cannot be edited
const notification = Object.freeze({
...oldNotification,
message: message !== null && message !== void 0 ? message : oldNotification.message,
type: type !== null && type !== void 0 ? type : oldNotification.type,
options: {
actions: actions !== null && actions !== void 0 ? actions : oldNotification.options.actions,
autoClose: autoClose !== null && autoClose !== void 0 ? autoClose : oldNotification.options.autoClose,
data: data !== null && data !== void 0 ? data : oldNotification.options.data,
progress: newProgress !== null && newProgress !== void 0 ? newProgress : oldNotification.options.progress
},
modifiedAt: Date.now()
});
this._queue.splice(notificationIndex, 1);
this._queue.unshift(notification);
this._changed.emit({
type: 'updated',
notification
});
return true;
}
return false;
}
}
/**
* Notification namespace
*/
export var Notification;
(function (Notification) {
/**
* The global notification manager.
*/
Notification.manager = new NotificationManager();
/**
* Dismiss one notification (specified by its id) or all if no id provided
*
* @param id notification id
*/
function dismiss(id) {
Notification.manager.dismiss(id);
}
Notification.dismiss = dismiss;
/**
* Helper function to emit a notification.
*
* #### Notes
* The message will be truncated if longer than 140 characters.
*
* @param message Notification message
* @param type Notification type
* @param options Options for the error notification
* @returns Notification unique id
*/
function emit(message, type = 'default', options = {}) {
return Notification.manager.notify(message, type, options);
}
Notification.emit = emit;
/**
* Helper function to emit an error notification.
*
* #### Notes
* The message will be truncated if longer than 140 characters.
*
* @param message Notification message
* @param options Options for the error notification
* @returns Notification unique id
*/
function error(message, options = {}) {
return Notification.manager.notify(message, 'error', options);
}
Notification.error = error;
/**
* Helper function to emit an info notification.
*
* #### Notes
* The message will be truncated if longer than 140 characters.
*
* @param message Notification message
* @param options Options for the info notification
* @returns Notification unique id
*/
function info(message, options = {}) {
return Notification.manager.notify(message, 'info', options);
}
Notification.info = info;
/**
* Helper function to show an in-progress notification.
*
* #### Notes
* The message will be truncated if longer than 140 characters.
*
* @param promise Promise to wait for
* @param options Options for the in-progress notification
* @returns Notification unique id
*/
function promise(promise, options) {
var _a;
const { pending, error, success } = options;
const id = Notification.manager.notify(pending.message, 'in-progress', (_a = pending.options) !== null && _a !== void 0 ? _a : {});
promise
.then(result => {
var _a, _b, _c;
Notification.manager.update({
id,
message: success.message(result, (_a = success.options) === null || _a === void 0 ? void 0 : _a.data),
type: 'success',
...success.options,
data: (_c = (_b = success.options) === null || _b === void 0 ? void 0 : _b.data) !== null && _c !== void 0 ? _c : result
});
})
.catch(reason => {
var _a, _b, _c;
Notification.manager.update({
id,
message: error.message(reason, (_a = error.options) === null || _a === void 0 ? void 0 : _a.data),
type: 'error',
...error.options,
data: (_c = (_b = error.options) === null || _b === void 0 ? void 0 : _b.data) !== null && _c !== void 0 ? _c : reason
});
});
return id;
}
Notification.promise = promise;
/**
* Helper function to emit a success notification.
*
* #### Notes
* The message will be truncated if longer than 140 characters.
*
* @param message Notification message
* @param options Options for the success notification
* @returns Notification unique id
*/
function success(message, options = {}) {
return Notification.manager.notify(message, 'success', options);
}
Notification.success = success;
/**
* Helper function to update a notification.
*
* If the notification does not exists, nothing will happen.
*
* Once updated the notification will be moved at the begin
* of the notification stack.
*
* #### Notes
* The message will be truncated if longer than 140 characters.
*
* @param args Update options
* @returns Whether the update was successful or not.
*/
function update(args) {
return Notification.manager.update(args);
}
Notification.update = update;
/**
* Helper function to emit a warning notification.
*
* #### Notes
* The message will be truncated if longer than 140 characters.
*
* @param message Notification message
* @param options Options for the warning notification
* @returns Notification unique id
*/
function warning(message, options = {}) {
return Notification.manager.notify(message, 'warning', options);
}
Notification.warning = warning;
})(Notification || (Notification = {}));
//# sourceMappingURL=notification.js.map