用户界面助手#

JupyterLab 提供了帮助程序来显示或向用户请求简单信息。 这些功能加快了开发速度并确保了一致的外观和感觉。

对话框#

通用对话框#

要显示一个通用对话框,请使用showDialog函数,该函数来自@jupyterlab/apputils

可用的选项有:

showDialog({
  title: 'Dialog title', // Can be text or a react element
  body: 'Dialog body', // Can be text, a widget or a react element
  host: document.body, // Parent element for rendering the dialog
  buttons: [ // List of buttons
   {
     label: 'my button', // Button label
     caption: 'my button title', // Button title
     className: 'my-button', // Additional button CSS class
     accept: true, // Whether this button will discard or accept the dialog
     displayType: 'default' // applies 'default' or 'warn' styles
   }
  ],
  checkbox: { // Optional checkbox in the dialog footer
    label: 'check me', // Checkbox label
    caption: 'check me I\'magic', // Checkbox title
    className: 'my-checkbox', // Additional checkbox CSS class
    checked: true, // Default checkbox state
  },
  defaultButton: 0, // Index of the default button
  focusNodeSelector: '.my-input', // Selector for focussing an input element when dialog opens
  hasClose: false, // Whether to display a close button or not
  renderer: undefined // To define customized dialog structure
})

注意

如果没有指定选项,对话框将只包含确定取消按钮。

消息对话框#

apputils包中提供了向用户显示消息的辅助函数。 这些对话框在用户关闭对话框时返回一个Promise

有一个助手:

  • showErrorMessage : 显示一个错误消息对话框。

输入对话框#

apputils包中的InputDialog命名空间内,提供了用于请求用户输入单个输入的辅助函数。共有四个辅助函数:

  • getBoolean : 通过复选框请求一个布尔值。

  • getItem : 从列表中请求一个项目;该列表可能是可编辑的。

  • getNumber : 请求一个数字;如果用户输入的不是有效的数字,则返回NaN。

  • getText : 请求一个简短的文本。

  • getPassword : 请求一个短密码。

所有对话框都基于标准的Dialog构建。因此,每个辅助函数都返回一个解析为Dialog.IResult对象的Promise

// Request a boolean
InputDialog.getBoolean({ title: 'Check or not?' }).then(value => {
  console.log('boolean ' + value.value);
});

// Request a choice from a list
InputDialog.getItem({
  title: 'Pick a choice',
  items: ['1', '2']
}).then(value => {
  console.log('item ' + value.value);
});

// Request a choice from a list or specify your own choice
InputDialog.getItem({
  title: 'Pick a choice or write your own',
  items: ['1', '2'],
  editable: true
}).then(value => {
  console.log('editable item ' + value.value);
});

// Request a number
InputDialog.getNumber({ title: 'How much?' }).then(value => {
  console.log('number ' + value.value);
});

// Request a text
InputDialog.getText({ title: 'Provide a text' }).then(value => {
  console.log('text ' + value.value);
});

// Request a text
InputDialog.getPassword({ title: 'Input password' }).then(value => {
  console.log('A password was input');
});

文件对话框#

filebrowser包中的FileDialog命名空间下,有两个辅助函数可用于请求用户打开文件或文件夹。

这是一个请求文件的示例。

const dialog = FileDialog.getOpenFiles({
  manager, // IDocumentManager
  filter: model => model.type == 'notebook' // optional (model: Contents.IModel) => boolean
});

const result = await dialog;

if(result.button.accept){
  let files = result.value;
}

对于一个文件夹。

const dialog = FileDialog.getExistingDirectory({
  manager // IDocumentManager
});

const result = await dialog;

if(result.button.accept){
  let folders = result.value;
}

注意

文档管理器可以通过请求IFileBrowserFactory令牌在插件中获取。管理器将通过factory.defaultBrowser.model.manager访问。

通知#

JupyterLab 有一个通知管理器,可以添加、更新或关闭通知。该功能由 @jupyterlab/apputils 包提供。

警告

为了尊重用户的注意力,限制发送的通知数量是一个良好的做法。 因此,默认情况下,通知不会显示给用户。但状态栏会 指示有新通知到达。因此,用户可以点击指示器查看所有 通知。

尝试为重复通知添加一个按钮不再显示,以允许用户快速筛选对他们重要的通知。

通知由以下元素描述:

{
  /**
   * Notification message
   *
   * ### Notes
   * Message can only be plain text with a maximum length of 140 characters.
   */
  message: string;
  /**
   * Notification type
   */
  type?:  'info' | 'in-progress' | 'success' | 'warning' | 'error' | 'default';
  /**
   * Notification options
   */
  options?: {
    /**
     * Autoclosing behavior - false (not closing automatically)
     * or number (time in milliseconds before hiding the notification)
     *
     * Set to zero if you want the notification to be retained in the notification
     * center but not displayed as toast. This is the default behavior.
     */
    autoClose?: number | false;
    /**
     * List of associated actions
     */
    actions?: Array<IAction>;
    /**
     * Data associated with a notification
     */
    data?: T;
  };
}

在创建时,通知将收到一个唯一的标识符。

操作可以链接到通知,但界面取决于通知的处理方式。

与通知交互有两种方式:通过API或通过命令。唯一的区别是,当使用API时,与通知相关的操作可以有一个任意的回调。但是,当使用命令调用来创建通知时,只能将命令设置为操作。

使用API#

要创建通知,您需要提供一条消息,并且可以使用以下助手自动设置类型(或使用notify手动设置类型):

/**
 * Helper function to emit an error notification.
 */
Notification.error(message: string, options?: IOptions): string;

/**
 * Helper function to emit an info notification.
 */
Notification.info(message: string, options?: IOptions): string;

/**
 * Helper function to emit a success notification.
 */
Notification.success(message: string, options?: IOptions): string;

/**
 * Helper function to emit a warning notification.
 */
Notification.warning(message: string, options?: IOptions): string;

/**
 * Helper function to emit a in-progress notification. Then
 * it will update it with a error or success notification
 * depending on the promise resolution.
 */
Notification.promise(
  promise: Promise,
  {
    pending: { message: string, options?: IOptions },
    /**
     * If not set `options.data` will be set to the promise result.
     */
    success: { message: (result, data) => string, options?: IOptions },
    /**
     * If not set `options.data` will be set to the promise rejection error.
     */
    error: { message: (reason, data) => string, options?: IOptions }
  }
): string;

/**
 * Helper function to emit a notification.
 */
Notification.emit(
  message: string,
  type: 'info' | 'in-progress' | 'success' | 'warning' | 'error' | 'default' = 'default',
  options?: IOptions
): string;

使用API时,一个动作由以下定义:

{
  /**
   * The action label.
   *
   * This should be a short description.
   */
  label: string;
  /**
   * Callback function to trigger
   *
   * ### Notes
   * By default execution of the callback will close the toast
   * and dismiss the notification. You can prevent this by calling
   * `event.preventDefault()` in the callback.
   */
  callback: (event: MouseEvent) => void;
  /**
   * The action caption.
   *
   * This can be a longer description of the action.
   */
  caption?: string;
  /**
   * The action display type.
   *
   * This will be used to modify the action button style.
   */
  displayType?: 'default' | 'accent' | 'warn' | 'link';
}

您可以使用以下方式更新通知:

Notification.update({
  id: string;
  message: string;
  type?:  'info' | 'in-progress' | 'success' | 'warning' | 'error' | 'default';
  autoClose?: number | false;
  actions?: Array<IAction>;
  data?: ReadonlyJsonValue;
}): boolean;

注意

一旦更新,通知将被移动到通知堆栈的开头。

你可以通过以下方式关闭一个通知(如果你提供了一个id)或所有通知:

Notification.dismiss(id?: string): void;

注意

关闭通知会将其从通知列表中移除,而不知道用户是否已经看到它。因此,建议不要关闭通知。

使用命令#

有三个可用的命令。

'apputils:notify' 用于创建通知:

commands.execute('apputils:notify', {
   message: string;
   type?: 'info' | 'in-progress' | 'success' | 'warning' | 'error' | 'default';
   options?: {
     autoClose?: number | false;
     actions?: Array<IAction>;
     data?: T;
   };
});

结果是通知的唯一标识符。

一个动作由以下定义:

{
  /**
   * The action label.
   *
   * This should be a short description.
   */
  label: string;
  /**
   * Callback command id to trigger
   */
  commandId: string;
  /**
   * Command arguments
   */
  args?: ReadonlyJsonObject;
  /**
   * The action caption.
   *
   * This can be a longer description of the action.
   */
  caption?: string;
  /**
   * The action display type.
   *
   * This will be used to modify the action button style.
   */
  displayType?: 'default' | 'accent' | 'warn' | 'link';
}

'apputils:update-notification' 用于更新通知:

commands.execute('apputils:update-notification', {
  id: string;
  message: string;
  type?: 'info' | 'in-progress' | 'success' | 'warning' | 'error' | 'default';
  autoClose?: number | false;
  actions?: Array<IAction>;
  data?: T;
});

结果是一个布尔值,表示更新是否成功。特别是,更新一个不存在的通知将会失败。

'apputils:dismiss-notification' 用于关闭通知:

commands.execute('apputils:dismiss-notification', {
  id: string;
});

注意

关闭通知会将其从通知列表中移除,而不知道用户是否已经看到它。因此,建议不要关闭通知。