UNPKG

jupyterlab_toastify

Version:
244 lines (243 loc) 10.4 kB
/* eslint-disable no-inner-declarations */ /* eslint-disable react/jsx-key */ /* eslint-disable react/prop-types */ import { faBell } from '@fortawesome/free-solid-svg-icons/faBell'; import { faCheck } from '@fortawesome/free-solid-svg-icons/faCheck'; import { faExclamationCircle } from '@fortawesome/free-solid-svg-icons/faExclamationCircle'; import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons/faExclamationTriangle'; import { faSpinner } from '@fortawesome/free-solid-svg-icons/faSpinner'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import * as React from 'react'; // import { closeIcon } from "@jupyterlab/ui-components"; // Not available on JLab 1.x #8 const closeIcon = (React.createElement("svg", { "element-position": "center", height: "16px", viewBox: "0 0 24 24", width: "16px", xmlns: "http://www.w3.org/2000/svg" }, React.createElement("g", { className: "jp-icon-none jp-icon-selectable-inverse jp-icon3-hover", fill: "none" }, React.createElement("circle", { cx: "12", cy: "12", r: "11" })), React.createElement("g", { className: "jp-icon3 jp-icon-selectable jp-icon-accent2-hover", fill: "#616161" }, React.createElement("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" })), React.createElement("g", { className: "jp-icon-none jp-icon-busy", fill: "none" }, React.createElement("circle", { cx: "12", cy: "12", r: "7" })))); export var INotification; (function (INotification) { /** Create a button with customized callback in a toast */ const ToastButton = ({ button, closeToast, }) => { const fullClassName = button.className === undefined ? 'jp-toast-button' : 'jp-toast-button ' + button.className; const clickHandler = () => { closeToast(); button.callback(); }; return (React.createElement("button", { className: fullClassName, onClick: clickHandler }, button.label)); }; /** * Helper function to construct the notification content * * @param message Message to print in the notification * @param closeHandler Function closing the notification * @param buttons Toast buttons */ function createContent(message, closeHandler, buttons, icon) { const hasButtons = buttons && buttons.length > 0; return (React.createElement(React.Fragment, null, icon ? icon : null, message, hasButtons && (React.createElement("div", { className: "jp-toast-buttonBar" }, React.createElement("div", { className: "jp-toast-spacer" }), buttons.map((button, idx) => { return (React.createElement(ToastButton, { key: 'button-' + idx, button: button, closeToast: closeHandler })); }))))); } async function createToast(message, buttons, options) { let _resolve; const toast = await Private.toast(); const promise = new Promise((resolve) => { _resolve = resolve; }); const theOptions = Object.assign({}, options); const toastId = toast(({ closeToast }) => createContent(message, closeToast, buttons, Private.type2Icon.get(theOptions.type || 'in-progress')), Object.assign(Object.assign({}, options), { className: `jp-toast-${theOptions.type || 'in-progress'}`, onOpen: () => _resolve(toastId) })); return promise; } /** * Helper function to show an error notification. Those * notifications need an user action to close. * * @param message Message to be printed in the notification * @param options Options for the error notification * @returns ToastId */ INotification.error = async (message, options) => { return createToast(message, options && options.buttons, { type: 'error', autoClose: (options && options.autoClose) || false, }); }; /** * Helper function to show a warning notification. Those * notifications need an user action to close. * * @param message Message to be printed in the notification * @param options Options for the warning notification * @returns ToastId */ INotification.warning = async (message, options) => { return createToast(message, options && options.buttons, { type: 'warning', autoClose: (options && options.autoClose) || false, }); }; /** * Helper function to show an informative notification. Those * notifications close automatically. * * @param message Message to be printed in the notification * @param options Options for the error notification * @returns ToastId */ INotification.info = async (message, options) => { const theOptions = Object.assign({}, options); const buttons = theOptions.buttons; const autoClose = theOptions.autoClose || (buttons && buttons.length > 0 ? false : undefined); return createToast(message, buttons, { type: 'info', autoClose: autoClose, }); }; /** * Helper function to show a success notification. Those * notifications close automatically. * * @param message Message to be printed in the notification * @param options Options for the error notification * @returns ToastId */ INotification.success = async (message, options) => { const theOptions = Object.assign({}, options); const buttons = theOptions.buttons; const autoClose = theOptions.autoClose || (buttons && buttons.length > 0 ? false : undefined); return createToast(message, buttons, { type: 'success', autoClose: autoClose, }); }; /** * Helper function to show a in progress notification. Those * notifications do not close automatically. * * @param message Message to be printed in the notification * @param options Options for the error notification * @returns ToastId */ INotification.inProgress = async (message, options) => { return createToast(message, options && options.buttons, { autoClose: (options && options.autoClose) || false, }); }; /** * Update an existing toast. * * If the toast is inactive (i.e. closed), a new one with the provided id * will be created with the new content. * * @param args Update options */ INotification.update = async (args) => { const toast = await Private.toast(); const buttons = args.buttons; const options = {}; if (args.type) { options.type = args.type; } const autoClose = args.autoClose || (buttons && buttons.length > 0 ? false : undefined); if (autoClose) { options.autoClose = autoClose; } if (toast.isActive(args.toastId)) { // Update existing toast const closeToast = () => { toast.dismiss(args.toastId); }; toast.update(args.toastId, Object.assign(Object.assign({}, options), { render: createContent(args.message, closeToast, args.buttons, // If not type specified, assumes it is `in progress` Private.type2Icon.get(options.type || 'in-progress')) })); } else { // Needs to recreate a closed toast // If not type specified, assumes it is `in progress` const newOptions = Object.assign({ autoClose: false, toastId: args.toastId }, options); await createToast(args.message, args.buttons, newOptions); } }; /** * Dismiss one toast (specified by its id) or all if no id provided * * @param toastId Toast id * @returns False or void */ INotification.dismiss = async (toastId) => { const toast = await Private.toast(); return toast.dismiss(toastId); }; /** * Proxy to `toast` function from `react-toastify` module * * The Promise is due to the asynchronous import of the dependency * * @param content Toast content * @param options Toast creation option * @returns ToastId */ INotification.notify = async (content, options) => { const toast = await Private.toast(); return toast(content, options); }; })(INotification || (INotification = {})); var Private; (function (Private) { Private.type2Icon = new Map([ ['default', null], [ 'in-progress', React.createElement(FontAwesomeIcon, { icon: faSpinner, pull: "left", spin: true, style: { color: 'var(--jp-inverse-layout-color3)' } }), ], [ 'error', React.createElement(FontAwesomeIcon, { icon: faExclamationCircle, pull: "left", style: { color: 'var(--jp-error-color1)' } }), ], [ 'warning', React.createElement(FontAwesomeIcon, { icon: faExclamationTriangle, pull: "left", style: { color: 'var(--jp-warn-color1)' } }), ], [ 'info', React.createElement(FontAwesomeIcon, { icon: faBell, pull: "left", style: { color: 'var(--jp-info-color1)' } }), ], [ 'success', React.createElement(FontAwesomeIcon, { icon: faCheck, pull: "left", style: { color: 'var(--jp-success-color1)' } }), ], ]); let toastify = null; const CloseButton = ({ closeToast, }) => (React.createElement("i", { onClick: closeToast }, React.createElement("span", { className: "jp-icon-hover" }, closeIcon))); async function toast() { if (toastify === null) { toastify = await import('react-toastify'); toastify.toast.configure({ draggable: false, closeOnClick: false, hideProgressBar: true, newestOnTop: true, pauseOnFocusLoss: true, pauseOnHover: true, position: 'bottom-right', className: 'jp-toastContainer', transition: toastify.Slide, closeButton: CloseButton, }); } return toastify.toast; } Private.toast = toast; })(Private || (Private = {}));