From 03d7f245a1bb3c9301b921ec473d70d6aab9f1a6 Mon Sep 17 00:00:00 2001 From: Oleksii Orel Date: Mon, 7 May 2018 18:19:55 +0300 Subject: [PATCH] Add notification manager API (#2) Signed-off-by: Oleksii Orel --- packages/plugin-ext/src/api/plugin-api.ts | 15 +- .../src/hosted/browser/worker/worker-main.ts | 6 +- .../src/hosted/node/hosted-plugin.ts | 6 +- .../browser/dialogs/modal-notification.ts | 81 +++++++ .../dialogs/style/modal-notification.css | 16 ++ .../src/main/browser/main-context.ts | 4 + .../src/main/browser/message-registry-main.ts | 104 +++++++++ .../browser/plugin-ext-frontend-module.ts | 3 + .../plugin-ext/src/plugin/message-registry.ts | 38 ++++ .../plugin-ext/src/plugin/plugin-context.ts | 17 ++ packages/plugin/API.md | 19 ++ packages/plugin/src/theia.d.ts | 200 +++++++++++++++--- 12 files changed, 473 insertions(+), 36 deletions(-) create mode 100644 packages/plugin-ext/src/main/browser/dialogs/modal-notification.ts create mode 100644 packages/plugin-ext/src/main/browser/dialogs/style/modal-notification.css create mode 100644 packages/plugin-ext/src/main/browser/message-registry-main.ts create mode 100644 packages/plugin-ext/src/plugin/message-registry.ts diff --git a/packages/plugin-ext/src/api/plugin-api.ts b/packages/plugin-ext/src/api/plugin-api.ts index 7acf087ec76dc..e22bbe2bdb967 100644 --- a/packages/plugin-ext/src/api/plugin-api.ts +++ b/packages/plugin-ext/src/api/plugin-api.ts @@ -56,6 +56,18 @@ export interface PickOpenItem { detail?: string; picked?: boolean; } + +export interface MessageRegistryMain { + $showInformationMessage (message: string, + optionsOrFirstItem: theia.MessageOptions | string | theia.MessageItem, + items: string[] | theia.MessageItem[]): PromiseLike; + $showWarningMessage (message: string, + optionsOrFirstItem: theia.MessageOptions | string | theia.MessageItem, + items: string[] | theia.MessageItem[]): PromiseLike; + $showErrorMessage (message: string, + optionsOrFirstItem: theia.MessageOptions | string | theia.MessageItem, + items: string[] | theia.MessageItem[]): PromiseLike; +} export interface QuickOpenExt { $onItemSelected(handle: number): void; $validateInput(input: string): PromiseLike | undefined; @@ -70,7 +82,8 @@ export interface QuickOpenMain { export const PLUGIN_RPC_CONTEXT = { COMMAND_REGISTRY_MAIN: >createProxyIdentifier('CommandRegistryMain'), - QUICK_OPEN_MAIN: createProxyIdentifier('QuickOpenMain') + QUICK_OPEN_MAIN: createProxyIdentifier('QuickOpenMain'), + MESSAGE_REGISTRY_MAIN: >createProxyIdentifier('MessageRegistryMain') }; export const MAIN_RPC_CONTEXT = { diff --git a/packages/plugin-ext/src/hosted/browser/worker/worker-main.ts b/packages/plugin-ext/src/hosted/browser/worker/worker-main.ts index aff0b5e8583ae..2f91d5f642622 100644 --- a/packages/plugin-ext/src/hosted/browser/worker/worker-main.ts +++ b/packages/plugin-ext/src/hosted/browser/worker/worker-main.ts @@ -14,15 +14,15 @@ import { createAPI, startPlugin } from '../../../plugin/plugin-context'; const ctx = self as any; const plugins = new Map void>(); -const emmitter = new Emitter(); +const emitter = new Emitter(); const rpc = new RPCProtocolImpl({ - onMessage: emmitter.event, + onMessage: emitter.event, send: (m: {}) => { ctx.postMessage(m); } }); addEventListener('message', (message: any) => { - emmitter.fire(message.data); + emitter.fire(message.data); }); const theia = createAPI(rpc); diff --git a/packages/plugin-ext/src/hosted/node/hosted-plugin.ts b/packages/plugin-ext/src/hosted/node/hosted-plugin.ts index be77ed9bcefe4..513ac0f147245 100644 --- a/packages/plugin-ext/src/hosted/node/hosted-plugin.ts +++ b/packages/plugin-ext/src/hosted/node/hosted-plugin.ts @@ -57,12 +57,12 @@ export class HostedPluginSupport { } private terminatePluginServer(cp: cp.ChildProcess) { - const emmitter = new Emitter(); + const emitter = new Emitter(); cp.on('message', message => { - emmitter.fire(JSON.parse(message)); + emitter.fire(JSON.parse(message)); }); const rpc = new RPCProtocolImpl({ - onMessage: emmitter.event, + onMessage: emitter.event, send: (m: {}) => { if (cp.send) { cp.send(JSON.stringify(m)); diff --git a/packages/plugin-ext/src/main/browser/dialogs/modal-notification.ts b/packages/plugin-ext/src/main/browser/dialogs/modal-notification.ts new file mode 100644 index 0000000000000..fad18ecdaeb5d --- /dev/null +++ b/packages/plugin-ext/src/main/browser/dialogs/modal-notification.ts @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2018 Red Hat, Inc. and others. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + */ +import {injectable} from 'inversify'; +import {Message} from '@phosphor/messaging'; +import {Key} from '@theia/core/lib/browser'; +import {MessageType} from '../message-registry-main'; +import {AbstractDialog} from '@theia/core/lib/browser/dialogs'; +import '../../../../src/main/browser/dialogs/style/modal-notification.css'; + +const NOTIFICATION = 'theia-Notification'; +const ICON = 'icon'; +const TEXT = 'text'; + +@injectable() +export class ModalNotification extends AbstractDialog { + + protected actionTitle: string | undefined; + + constructor() { + super({title: 'Theia'}); + } + + protected onCloseRequest(msg: Message): void { + this.actionTitle = undefined; + this.accept(); + } + + get value(): string | undefined { + return this.actionTitle; + } + + showDialog(messageType: MessageType, text: string, actions: string[]): Promise { + this.contentNode.appendChild(this.createMessageNode(messageType, text, actions)); + return this.open(); + } + + protected createMessageNode(messageType: MessageType, text: string, actions: string[]): HTMLElement { + const messageNode = document.createElement('div'); + messageNode.classList.add(NOTIFICATION); + + const iconContainer = messageNode.appendChild(document.createElement('div')); + iconContainer.classList.add(ICON); + const iconElement = iconContainer.appendChild(document.createElement('i')); + iconElement.classList.add('fa', this.toIconClass(messageType), 'fa-fw', messageType); + + const textContainer = messageNode.appendChild(document.createElement('div')); + textContainer.classList.add(TEXT); + const textElement = textContainer.appendChild(document.createElement('span')); + textElement.textContent = text; + + actions.forEach((action: string) => { + const button = this.createButton(action); + button.classList.add('main'); + this.controlPanel.appendChild(button); + this.addKeyListener(button, + Key.ENTER, + () => { + this.actionTitle = action; + this.accept(); + }, + 'click'); + }); + this.appendCloseButton('close'); + + return messageNode; + } + + protected toIconClass(icon: string): string { + if (icon === MessageType.Error) { + return 'fa-times-circle'; + } + if (icon === MessageType.Warning) { + return 'fa-warning'; + } + return 'fa-info-circle'; + } +} diff --git a/packages/plugin-ext/src/main/browser/dialogs/style/modal-notification.css b/packages/plugin-ext/src/main/browser/dialogs/style/modal-notification.css new file mode 100644 index 0000000000000..c25e614c727ea --- /dev/null +++ b/packages/plugin-ext/src/main/browser/dialogs/style/modal-notification.css @@ -0,0 +1,16 @@ +/* +* Copyright (C) 2018 Red Hat, Inc. and others. +* +* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. +* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +*/ +.dialogContent .theia-Notification { + min-width: inherit; + box-shadow: none; + animation: none; +} + +.dialogContent .theia-Notification .icon { + font-size: 20px; + padding: 5px 0; +} diff --git a/packages/plugin-ext/src/main/browser/main-context.ts b/packages/plugin-ext/src/main/browser/main-context.ts index bb28fc36e3de4..3015028629684 100644 --- a/packages/plugin-ext/src/main/browser/main-context.ts +++ b/packages/plugin-ext/src/main/browser/main-context.ts @@ -9,6 +9,7 @@ import { CommandRegistryMainImpl } from './command-registry-main'; import { QuickOpenMainImpl } from './quick-open-main'; import { RPCProtocol } from '../../api/rpc-protocol'; import { PLUGIN_RPC_CONTEXT } from '../../api/plugin-api'; +import { MessageRegistryMainImpl } from './message-registry-main'; export function setUpPluginApi(rpc: RPCProtocol, container: interfaces.Container): void { const commandRegistryMain = new CommandRegistryMainImpl(rpc, container); @@ -16,4 +17,7 @@ export function setUpPluginApi(rpc: RPCProtocol, container: interfaces.Container const quickOpenMain = new QuickOpenMainImpl(rpc, container); rpc.set(PLUGIN_RPC_CONTEXT.QUICK_OPEN_MAIN, quickOpenMain); + + const messageRegistryMain = new MessageRegistryMainImpl(container); + rpc.set(PLUGIN_RPC_CONTEXT.MESSAGE_REGISTRY_MAIN, messageRegistryMain); } diff --git a/packages/plugin-ext/src/main/browser/message-registry-main.ts b/packages/plugin-ext/src/main/browser/message-registry-main.ts new file mode 100644 index 0000000000000..f8fdbc5fc9e82 --- /dev/null +++ b/packages/plugin-ext/src/main/browser/message-registry-main.ts @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2018 Red Hat, Inc. and others. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + */ +import {interfaces} from 'inversify'; +import * as theia from '@theia/plugin'; +import {MessageService} from '@theia/core/lib/common/message-service'; +import {MessageRegistryMain} from '../../api/plugin-api'; +import {ModalNotification} from './dialogs/modal-notification'; + +export enum MessageType { + Error = 'error', + Warning = 'warning', + Info = 'info' +} + +export class MessageRegistryMainImpl implements MessageRegistryMain { + private messageService: MessageService; + + constructor(container: interfaces.Container) { + this.messageService = container.get(MessageService); + } + + $showInformationMessage(message: string, + optionsOrFirstItem: theia.MessageOptions | string | theia.MessageItem, + items: string[] | theia.MessageItem[]): PromiseLike { + return this.showMessage(MessageType.Info, message, optionsOrFirstItem, ...items); + } + + $showWarningMessage(message: string, + optionsOrFirstItem: theia.MessageOptions | string | theia.MessageItem, + items: string[] | theia.MessageItem[]): PromiseLike { + return this.showMessage(MessageType.Warning, message, optionsOrFirstItem, ...items); + } + + $showErrorMessage(message: string, + optionsOrFirstItem: theia.MessageOptions | string | theia.MessageItem, + items: string[] | theia.MessageItem[]): PromiseLike { + return this.showMessage(MessageType.Error, message, optionsOrFirstItem, ...items); + } + + protected showMessage(type: MessageType, message: string, ...args: any[]): PromiseLike { + const actionsMap = new Map(); + const actionTitles: string[] = []; + const options: theia.MessageOptions = {modal: false}; + + let onCloseAction: string; + if (!!args && args.length > 0) { + const first = args[0]; + if (first && first.modal) { + options.modal = true; + } + args.forEach(arg => { + if (!arg) { + return; + } + let actionTitle: string; + if (typeof arg === 'string') { + actionTitle = arg; + } else if (arg.title) { + actionTitle = arg.title; + actionsMap.set(actionTitle, arg); + if (arg.isCloseAffordance) { + onCloseAction = arg.title; + } + } else { + return; + } + actionTitles.push(actionTitle); + }); + } + + let promise: Promise; + + try { + if (options.modal) { + const modalNotification = new ModalNotification(); + promise = modalNotification.showDialog(type, message, actionTitles).then(result => { + return result !== undefined ? result : onCloseAction; + }); + } else { + switch (type) { + case MessageType.Info: + promise = this.messageService.info(message, ...actionTitles); + break; + case MessageType.Warning: + promise = this.messageService.warn(message, ...actionTitles); + break; + case MessageType.Error: + promise = this.messageService.error(message, ...actionTitles); + break; + default: + return Promise.reject(new Error(`Message type '${type}' is not supported yet!`)); + } + } + } catch (e) { + return Promise.reject(e); + } + + return Promise.resolve(promise.then(result => !!result && actionsMap.has(result) ? actionsMap.get(result) : result)); + } +} diff --git a/packages/plugin-ext/src/main/browser/plugin-ext-frontend-module.ts b/packages/plugin-ext/src/main/browser/plugin-ext-frontend-module.ts index f6ce78c873fab..ac550a7d14ed0 100644 --- a/packages/plugin-ext/src/main/browser/plugin-ext-frontend-module.ts +++ b/packages/plugin-ext/src/main/browser/plugin-ext-frontend-module.ts @@ -15,8 +15,11 @@ import { HostedPluginManagerClient } from "./plugin-manager-client"; import { PluginApiFrontendContribution } from "./plugin-frontend-contribution"; import { setUpPluginApi } from "./main-context"; import { HostedPluginServer, hostedServicePath } from "../../common/plugin-protocol"; +import { ModalNotification } from './dialogs/modal-notification'; export default new ContainerModule(bind => { + bind(ModalNotification).toSelf().inSingletonScope(); + bind(PluginWorker).toSelf().inSingletonScope(); bind(HostedPluginSupport).toSelf().inSingletonScope(); bind(HostedPluginWatcher).toSelf().inSingletonScope(); diff --git a/packages/plugin-ext/src/plugin/message-registry.ts b/packages/plugin-ext/src/plugin/message-registry.ts new file mode 100644 index 0000000000000..5bdfded43535b --- /dev/null +++ b/packages/plugin-ext/src/plugin/message-registry.ts @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2018 Red Hat, Inc. and others. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + */ +import { + PLUGIN_RPC_CONTEXT as Ext, MessageRegistryMain +} from '../api/plugin-api'; +import {RPCProtocol} from '../api/rpc-protocol'; +import {MessageItem, MessageOptions} from "@theia/plugin"; + +export class MessageRegistryExt { + + private proxy: MessageRegistryMain; + + constructor(rpc: RPCProtocol) { + this.proxy = rpc.getProxy(Ext.MESSAGE_REGISTRY_MAIN); + } + + showInformationMessage(message: string, + optionsOrFirstItem: MessageOptions | string | MessageItem, + items: string[] | MessageItem[]): PromiseLike { + return this.proxy.$showInformationMessage(message, optionsOrFirstItem, items); + } + + showWarningMessage(message: string, + optionsOrFirstItem: MessageOptions | string | MessageItem, + items: string[] | MessageItem[]): PromiseLike { + return this.proxy.$showWarningMessage(message, optionsOrFirstItem, items); + } + + showErrorMessage(message: string, + optionsOrFirstItem: MessageOptions | string | MessageItem, + items: string[] | MessageItem[]): PromiseLike { + return this.proxy.$showErrorMessage(message, optionsOrFirstItem, items); + } +} diff --git a/packages/plugin-ext/src/plugin/plugin-context.ts b/packages/plugin-ext/src/plugin/plugin-context.ts index c3be7ca57821c..b391abafd1ab3 100644 --- a/packages/plugin-ext/src/plugin/plugin-context.ts +++ b/packages/plugin-ext/src/plugin/plugin-context.ts @@ -13,10 +13,12 @@ import { MAIN_RPC_CONTEXT, Plugin } from '../api/plugin-api'; import { RPCProtocol } from '../api/rpc-protocol'; import { getPluginId } from '../common/plugin-protocol'; import { Disposable } from './types-impl'; +import { MessageRegistryExt } from './message-registry'; export function createAPI(rpc: RPCProtocol): typeof theia { const commandRegistryExt = rpc.set(MAIN_RPC_CONTEXT.COMMAND_REGISTRY_EXT, new CommandRegistryImpl(rpc)); const quickOpenExt = rpc.set(MAIN_RPC_CONTEXT.QUICK_OPEN_EXT, new QuickOpenExtImpl(rpc)); + const messageRegistryExt = new MessageRegistryExt(rpc); const commands: typeof theia.commands = { registerCommand(command: theia.Command, handler?: (...args: any[]) => T | Thenable): Disposable { @@ -36,6 +38,21 @@ export function createAPI(rpc: RPCProtocol): typeof theia { const window: typeof theia.window = { showQuickPick(items: any, options: theia.QuickPickOptions, token?: theia.CancellationToken): any { return quickOpenExt.showQuickPick(items, options, token); + }, + showInformationMessage(message: string, + optionsOrFirstItem: theia.MessageOptions | string | theia.MessageItem, + ...items: any[]): PromiseLike { + return messageRegistryExt.showInformationMessage(message, optionsOrFirstItem, items); + }, + showWarningMessage(message: string, + optionsOrFirstItem: theia.MessageOptions | string | theia.MessageItem, + ...items: any[]): PromiseLike { + return messageRegistryExt.showWarningMessage(message, optionsOrFirstItem, items); + }, + showErrorMessage(message: string, + optionsOrFirstItem: theia.MessageOptions | string | theia.MessageItem, + ...items: any[]): PromiseLike { + return messageRegistryExt.showErrorMessage(message, optionsOrFirstItem, items); } }; diff --git a/packages/plugin/API.md b/packages/plugin/API.md index f1a43348a6cb1..bb60397ba34f7 100644 --- a/packages/plugin/API.md +++ b/packages/plugin/API.md @@ -51,3 +51,22 @@ theia.window.showQuickPick(["foo", "bar", "foobar"], option).then((val: string[] console.log(`Quick Pick Selected: ${val}`); }); ``` +#### Notification API + A notification shows an information message to users. + Optionally provide an array of items which will be presented as clickable buttons. + + Notifications can be shown using the [showInformationMessage](#window.showInformationMessage), + [showWarningMessage](#window.showWarningMessage) and [showErrorMessage](#window.showErrorMessage) functions. + + +Simple example that show an information message: +```javascript +theia.window.showInformationMessage('Information message'); +``` + +Simple example that show an information message with buttons: +```javascript +theia.window.showInformationMessage('Information message', 'Btn1', 'Btn2').then(result => { + console.log("Click button", result); +}); +``` diff --git a/packages/plugin/src/theia.d.ts b/packages/plugin/src/theia.d.ts index 19fb008d3068f..4ac6b235537d7 100644 --- a/packages/plugin/src/theia.d.ts +++ b/packages/plugin/src/theia.d.ts @@ -47,7 +47,7 @@ declare module '@theia/plugin' { } /** - * + * */ export interface TextEditorEdit { // TODO implement TextEditorEdit @@ -79,7 +79,7 @@ declare module '@theia/plugin' { /** * Fire the event and pass data object - * @param data + * @param data */ fire(data?: T): void; @@ -90,7 +90,7 @@ declare module '@theia/plugin' { } /** - * A cancellation token used to request cancellation on long running + * A cancellation token used to request cancellation on long running * or asynchronous task. */ export interface CancellationToken { @@ -153,7 +153,7 @@ declare module '@theia/plugin' { machOnDetail?: boolean; /** - * The place holder in input box + * The place holder in input box */ placeHolder?: string; @@ -186,60 +186,90 @@ declare module '@theia/plugin' { } /** - * Namespace for dealing with commands. In short, a command is a function with a - * unique identifier. The function is sometimes also called _command handler_. - * + * Namespace for dealing with commands. In short, a command is a function with a + * unique identifier. The function is sometimes also called _command handler_. + * * Commands can be added using the [registerCommand](#commands.registerCommand) and * [registerTextEditorCommand](#commands.registerTextEditorCommand) functions. - * Registration can be split in two step: first register command without handler, + * Registration can be split in two step: first register command without handler, * second register handler by command id. - * - * Any contributed command are available to any plugin, command can be invoked + * + * Any contributed command are available to any plugin, command can be invoked * by [executeCommand](#commands.executeCommand) function. - * + * * Simple example that register command: * ```javascript * theia.commands.registerCommand({id:'say.hello.command'}, ()=>{ * console.log("Hello World!"); * }); * ``` - * + * * Simple example that invoke command: - * + * * ```javascript * theia.commands.executeCommand('core.about'); * ``` - */ + */ export namespace commands { /** * Register the given command and handler if present. * * Throw if a command is already registered for the given command identifier. */ - export function registerCommand(command: Command, handler?: (...args: any[]) => any): Disposable + export function registerCommand(command: Command, handler?: (...args: any[]) => any): Disposable; /** * Register the given handler for the given command identifier. - * + * * @param commandId a given command id * @param handler a command handler */ - export function registerHandler(commandId: string, handler: (...args: any[]) => any): Disposable + export function registerHandler(commandId: string, handler: (...args: any[]) => any): Disposable; /** - * Register a text editor command which can execute only if active editor present and command has access to the active editor - * - * @param command a command description - * @param handler a command handler with access to text editor + * Register a text editor command which can execute only if active editor present and command has access to the active editor + * + * @param command a command description + * @param handler a command handler with access to text editor */ - export function registerTextEditorCommand(command: Command, handler: (textEditor: TextEditor, edit: TextEditorEdit, ...arg: any[]) => void): Disposable + export function registerTextEditorCommand(command: Command, handler: (textEditor: TextEditor, edit: TextEditorEdit, ...arg: any[]) => void): Disposable; /** * Execute the active handler for the given command and arguments. * * Reject if a command cannot be executed. */ - export function executeCommand(commandId: string, ...args: any[]): PromiseLike + export function executeCommand(commandId: string, ...args: any[]): PromiseLike; + } + + /** + * Represents an action that is shown with a message. + */ + export interface MessageItem { + + /** + * A message title. + */ + title: string; + + /** + * Indicates that the item should be triggered + * when the user cancels the dialog. + * + * Note: this option is ignored for non-modal messages. + */ + isCloseAffordance?: boolean; + } + + /** + * Options to configure the message behavior. + */ + export interface MessageOptions { + + /** + * Indicates that this message should be modal. + */ + modal?: boolean; } /** @@ -249,9 +279,9 @@ declare module '@theia/plugin' { /** * Shows a selection list. - * @param items - * @param options - * @param token + * @param items + * @param options + * @param token */ export function showQuickPick(items: string[] | PromiseLike, options: QuickPickOptions, token?: CancellationToken): PromiseLike; @@ -262,9 +292,9 @@ declare module '@theia/plugin' { /** * Shows a selection list. - * @param items - * @param options - * @param token + * @param items + * @param options + * @param token */ export function showQuickPick(items: T[] | PromiseLike, options: QuickPickOptions, token?: CancellationToken): PromiseLike; @@ -273,6 +303,118 @@ declare module '@theia/plugin' { */ export function showQuickPick(items: T[] | PromiseLike, options: QuickPickOptions & { canPickMany: true }, token?: CancellationToken): PromiseLike; + /** + * Show an information message. + * + * @param message a message to show. + * @param items A set of items that will be rendered as actions in the message. + * @return A promise that resolves to the selected item or `undefined` when being dismissed. + */ + export function showInformationMessage(message: string, ...items: string[]): PromiseLike; + /** + * Show an information message. + * + * @param message a message to show. + * @param options Configures the behaviour of the message. + * @param items A set of items that will be rendered as actions in the message. + * @return A promise that resolves to the selected item or `undefined` when being dismissed. + */ + export function showInformationMessage(message: string, options: MessageOptions, ...items: string[]): PromiseLike; + + /** + * Show an information message. + * + * @param message a message to show. + * @param items A set of items that will be rendered as actions in the message. + * @return A promise that resolves to the selected item or `undefined` when being dismissed. + */ + export function showInformationMessage(message: string, options: MessageOptions, ...items: T[]): PromiseLike + + /** + * Show an information message. + * + * @param message a message to show. + * @param options Configures the behaviour of the message. + * @param items A set of items that will be rendered as actions in the message. + * @return A promise that resolves to the selected item or `undefined` when being dismissed. + */ + export function showInformationMessage(message: string, options: MessageOptions, ...items: T[]): PromiseLike; + + /** + * Show a warning message. + * + * @param message a message to show. + * @param items A set of items that will be rendered as actions in the message. + * @return A promise that resolves to the selected item or `undefined` when being dismissed. + */ + export function showWarningMessage(message: string, options: MessageOptions, ...items: T[]): PromiseLike + + /** + * Show a warning message. + * + * @param message a message to show. + * @param options Configures the behaviour of the message. + * @param items A set of items that will be rendered as actions in the message. + * @return A promise that resolves to the selected item or `undefined` when being dismissed. + */ + export function showWarningMessage(message: string, options: MessageOptions, ...items: string[]): PromiseLike; + + /** + * Show a warning message. + * + * @param message a message to show. + * @param items A set of items that will be rendered as actions in the message. + * @return A promise that resolves to the selected item or `undefined` when being dismissed. + */ + export function showWarningMessage(message: string, ...items: T[]): PromiseLike; + + /** + * Show a warning message. + * + * @param message a message to show. + * @param options Configures the behaviour of the message. + * @param items A set of items that will be rendered as actions in the message. + * @return A promise that resolves to the selected item or `undefined` when being dismissed. + */ + export function showWarningMessage(message: string, options: MessageOptions, ...items: T[]): PromiseLike; + + /** + * Show an error message. + * + * @param message a message to show. + * @param items A set of items that will be rendered as actions in the message. + * @return A promise that resolves to the selected item or `undefined` when being dismissed. + */ + export function showErrorMessage(message: string, options: MessageOptions, ...items: T[]): PromiseLike + + /** + * Show an error message. + * + * @param message a message to show. + * @param options Configures the behaviour of the message. + * @param items A set of items that will be rendered as actions in the message. + * @return A promise that resolves to the selected item or `undefined` when being dismissed. + */ + export function showErrorMessage(message: string, options: MessageOptions, ...items: string[]): PromiseLike; + + /** + * Show an error message. + * + * @param message a message to show. + * @param items A set of items that will be rendered as actions in the message. + * @return A promise that resolves to the selected item or `undefined` when being dismissed. + */ + export function showErrorMessage(message: string, ...items: T[]): PromiseLike; + + /** + * Show an error message. + * + * @param message a message to show. + * @param options Configures the behaviour of the message. + * @param items A set of items that will be rendered as actions in the message. + * @return A promise that resolves to the selected item or `undefined` when being dismissed. + */ + export function showErrorMessage(message: string, options: MessageOptions, ...items: T[]): PromiseLike; } }