From b6a0cd3767abab526820e43fd48a0f367924a39e Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Mon, 11 May 2020 12:36:30 +0200 Subject: [PATCH] 7.9 --- .../public/hello_world_action.tsx | 28 ----------- .../public/hello_world_action_lazy.tsx | 47 +++++++++++++++++++ examples/ui_action_examples/public/plugin.ts | 14 +++--- examples/ui_actions_explorer/public/app.tsx | 6 ++- .../public/service/ui_actions_service.ts | 44 +++++++++-------- src/plugins/ui_actions/public/types.ts | 2 +- 6 files changed, 85 insertions(+), 56 deletions(-) create mode 100644 examples/ui_action_examples/public/hello_world_action_lazy.tsx diff --git a/examples/ui_action_examples/public/hello_world_action.tsx b/examples/ui_action_examples/public/hello_world_action.tsx index da20f40464516..96098fe977044 100644 --- a/examples/ui_action_examples/public/hello_world_action.tsx +++ b/examples/ui_action_examples/public/hello_world_action.tsx @@ -16,33 +16,5 @@ * specific language governing permissions and limitations * under the License. */ -import React from 'react'; -import { EuiText, EuiModalBody, EuiButton } from '@elastic/eui'; -import { OverlayStart } from '../../../src/core/public'; -import { createAction } from '../../../src/plugins/ui_actions/public'; -import { toMountPoint } from '../../../src/plugins/kibana_react/public'; export const ACTION_HELLO_WORLD = 'ACTION_HELLO_WORLD'; - -interface StartServices { - openModal: OverlayStart['openModal']; -} - -export const createHelloWorldAction = (getStartServices: () => Promise) => - createAction({ - type: ACTION_HELLO_WORLD, - getDisplayName: () => 'Hello World!', - execute: async () => { - const { openModal } = await getStartServices(); - const overlay = openModal( - toMountPoint( - - Hello world! - overlay.close()}> - Close - - - ) - ); - }, - }); diff --git a/examples/ui_action_examples/public/hello_world_action_lazy.tsx b/examples/ui_action_examples/public/hello_world_action_lazy.tsx new file mode 100644 index 0000000000000..15dd24f5d8763 --- /dev/null +++ b/examples/ui_action_examples/public/hello_world_action_lazy.tsx @@ -0,0 +1,47 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you 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 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { EuiText, EuiModalBody, EuiButton } from '@elastic/eui'; +import { OverlayStart } from '../../../src/core/public'; +import { createAction } from '../../../src/plugins/ui_actions/public'; +import { toMountPoint } from '../../../src/plugins/kibana_react/public'; +import { ACTION_HELLO_WORLD } from './hello_world_action'; + +interface StartServices { + openModal: OverlayStart['openModal']; +} + +export const createHelloWorldAction = (getStartServices: () => Promise) => + createAction({ + type: ACTION_HELLO_WORLD, + getDisplayName: () => 'Hello World!', + execute: async () => { + const { openModal } = await getStartServices(); + const overlay = openModal( + toMountPoint( + + Hello world! + overlay.close()}> + Close + + + ) + ); + }, + }); diff --git a/examples/ui_action_examples/public/plugin.ts b/examples/ui_action_examples/public/plugin.ts index 3a9f673261e33..b9d5962df1e20 100644 --- a/examples/ui_action_examples/public/plugin.ts +++ b/examples/ui_action_examples/public/plugin.ts @@ -19,7 +19,7 @@ import { Plugin, CoreSetup, CoreStart } from '../../../src/core/public'; import { UiActionsSetup, UiActionsStart } from '../../../src/plugins/ui_actions/public'; -import { createHelloWorldAction, ACTION_HELLO_WORLD } from './hello_world_action'; +import { ACTION_HELLO_WORLD } from './hello_world_action'; import { helloWorldTrigger, HELLO_WORLD_TRIGGER_ID } from './hello_world_trigger'; export interface UiActionExamplesSetupDependencies { @@ -49,12 +49,12 @@ export class UiActionExamplesPlugin ) { uiActions.registerTrigger(helloWorldTrigger); - const helloWorldAction = createHelloWorldAction(async () => ({ - openModal: (await core.getStartServices())[0].overlays.openModal, - })); - - uiActions.registerAction(helloWorldAction); - uiActions.addTriggerAction(helloWorldTrigger.id, helloWorldAction); + uiActions.registerAction('ACTION_HELLO_WORLD', async () => + (await import('./hello_world_action_lazy')).createHelloWorldAction(async () => ({ + openModal: (await core.getStartServices())[0].overlays.openModal, + })) + ); + uiActions.addTriggerAction(helloWorldTrigger.id, 'ACTION_HELLO_WORLD'); } public start(core: CoreStart, plugins: UiActionExamplesStartDependencies) {} diff --git a/examples/ui_actions_explorer/public/app.tsx b/examples/ui_actions_explorer/public/app.tsx index f08b8bb29bdd3..4e06fe3f791b7 100644 --- a/examples/ui_actions_explorer/public/app.tsx +++ b/examples/ui_actions_explorer/public/app.tsx @@ -95,7 +95,11 @@ const ActionsExplorer = ({ uiActionsApi, openModal }: Props) => { ); }, }); - uiActionsApi.addTriggerAction(HELLO_WORLD_TRIGGER_ID, dynamicAction); + + uiActionsApi.registerAction(dynamicAction.id, () => + Promise.resolve(dynamicAction) + ); + uiActionsApi.addTriggerAction(HELLO_WORLD_TRIGGER_ID, dynamicAction.id); setConfirmationText( `You've successfully added a new action: ${dynamicAction.getDisplayName( {} diff --git a/src/plugins/ui_actions/public/service/ui_actions_service.ts b/src/plugins/ui_actions/public/service/ui_actions_service.ts index 9a08aeabb00f3..92a0e8bb1bf2c 100644 --- a/src/plugins/ui_actions/public/service/ui_actions_service.ts +++ b/src/plugins/ui_actions/public/service/ui_actions_service.ts @@ -76,15 +76,15 @@ export class UiActionsService { }; public readonly registerAction = ( - definition: A - ): Action> => { - if (this.actions.has(definition.id)) { - throw new Error(`Action [action.id = ${definition.id}] already registered.`); + actionId: string, + definition: () => Promise + ): (() => Promise>>) => { + if (this.actions.has(actionId)) { + throw new Error(`Action [action.id = ${actionId}] already registered.`); } - const action = new ActionInternal(definition); - - this.actions.set(action.id, action); + const action = async () => new ActionInternal(await definition()); + this.actions.set(actionId, action); return action; }; @@ -140,33 +140,39 @@ export class UiActionsService { triggerId: T, // The action can accept partial or no context, but if it needs context not provided // by this type of trigger, typescript will complain. yay! - action: Action + actionId: string ): void => { - if (!this.actions.has(action.id)) this.registerAction(action); - this.attachAction(triggerId, action.id); + // if (!this.actions.has(action.id)) this.registerAction(action.id, action.definition); + this.attachAction(triggerId, actionId); }; - public readonly getAction = ( + public readonly getAction = async ( id: string - ): Action> => { + ): Promise>> => { if (!this.actions.has(id)) { throw new Error(`Action [action.id = ${id}] not registered.`); } - return this.actions.get(id) as ActionInternal; + const actionGetter = this.actions.get(id); + const action = await actionGetter!(); + + return action as ActionInternal; }; - public readonly getTriggerActions = ( + public readonly getTriggerActions = async ( triggerId: T - ): Array> => { + ): Promise>> => { // This line checks if trigger exists, otherwise throws. this.getTrigger!(triggerId); const actionIds = this.triggerToActions.get(triggerId); - const actions = actionIds! - .map(actionId => this.actions.get(actionId) as ActionInternal) - .filter(Boolean); + const actions = await Promise.all( + actionIds! + .map(actionId => this.actions.get(actionId)) + .filter(Boolean) + .map(actionGetter => actionGetter!()) + ); return actions as Array>>; }; @@ -175,7 +181,7 @@ export class UiActionsService { triggerId: T, context: TriggerContextMapping[T] ): Promise>> => { - const actions = this.getTriggerActions!(triggerId); + const actions = await this.getTriggerActions!(triggerId); const isCompatibles = await Promise.all(actions.map(action => action.isCompatible(context))); return actions.reduce( (acc: Array>, action, i) => diff --git a/src/plugins/ui_actions/public/types.ts b/src/plugins/ui_actions/public/types.ts index 85c87306cc4f9..9ac2b26f1e05b 100644 --- a/src/plugins/ui_actions/public/types.ts +++ b/src/plugins/ui_actions/public/types.ts @@ -25,7 +25,7 @@ import { IEmbeddable } from '../../embeddable/public'; import { RangeSelectTriggerContext, ValueClickTriggerContext } from '../../embeddable/public'; export type TriggerRegistry = Map>; -export type ActionRegistry = Map; +export type ActionRegistry = Map Promise>; export type TriggerToActionsRegistry = Map; const DEFAULT_TRIGGER = '';