From b655160366d887007ecc182280a74cf70848d236 Mon Sep 17 00:00:00 2001 From: streamich Date: Mon, 6 Apr 2020 14:21:35 +0200 Subject: [PATCH 1/7] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20set=20up=20sample=20?= =?UTF-8?q?action=20factory=20provider?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/embeddable/public/index.ts | 9 ++-- .../dashboard_enhanced/public/plugin.ts | 45 +++++++++++++++++-- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/plugins/embeddable/public/index.ts b/src/plugins/embeddable/public/index.ts index 23275fbe8e8f0..3f671b520fb2e 100644 --- a/src/plugins/embeddable/public/index.ts +++ b/src/plugins/embeddable/public/index.ts @@ -23,23 +23,24 @@ import { PluginInitializerContext } from 'src/core/public'; import { EmbeddablePublicPlugin } from './plugin'; export { - Adapters, ACTION_ADD_PANEL, - AddPanelAction, ACTION_APPLY_FILTER, + ACTION_EDIT_PANEL, + Adapters, + AddPanelAction, Container, ContainerInput, ContainerOutput, CONTEXT_MENU_TRIGGER, contextMenuTrigger, - ACTION_EDIT_PANEL, + defaultEmbeddableFactoryProvider, EditPanelAction, Embeddable, EmbeddableChildPanel, EmbeddableChildPanelProps, EmbeddableContext, - EmbeddableFactoryDefinition, EmbeddableFactory, + EmbeddableFactoryDefinition, EmbeddableFactoryNotFoundError, EmbeddableFactoryRenderer, EmbeddableInput, diff --git a/x-pack/plugins/dashboard_enhanced/public/plugin.ts b/x-pack/plugins/dashboard_enhanced/public/plugin.ts index 30b3f3c080f49..f6103daa9acda 100644 --- a/x-pack/plugins/dashboard_enhanced/public/plugin.ts +++ b/x-pack/plugins/dashboard_enhanced/public/plugin.ts @@ -5,18 +5,31 @@ */ import { CoreStart, CoreSetup, Plugin, PluginInitializerContext } from 'src/core/public'; +import { SavedObjectAttributes } from 'kibana/public'; import { UiActionsSetup, UiActionsStart } from '../../../../src/plugins/ui_actions/public'; +import { + EmbeddableFactory, + EmbeddableFactoryDefinition, + EmbeddableInput, + EmbeddableOutput, + EmbeddableSetup, + EmbeddableStart, + IEmbeddable, + defaultEmbeddableFactoryProvider, +} from '../../../../src/plugins/embeddable/public'; import { DashboardDrilldownsService } from './services'; import { DrilldownsSetup, DrilldownsStart } from '../../drilldowns/public'; export interface SetupDependencies { - uiActions: UiActionsSetup; drilldowns: DrilldownsSetup; + embeddable: EmbeddableSetup; + uiActions: UiActionsSetup; } export interface StartDependencies { - uiActions: UiActionsStart; drilldowns: DrilldownsStart; + embeddable: EmbeddableStart; + uiActions: UiActionsStart; } // eslint-disable-next-line @@ -35,8 +48,34 @@ export class DashboardEnhancedPlugin } public setup(core: CoreSetup, plugins: SetupDependencies): SetupContract { + plugins.embeddable.setCustomEmbeddableFactoryProvider( + < + I extends EmbeddableInput = EmbeddableInput, + O extends EmbeddableOutput = EmbeddableOutput, + E extends IEmbeddable = IEmbeddable, + T extends SavedObjectAttributes = SavedObjectAttributes + >( + def: EmbeddableFactoryDefinition + ): EmbeddableFactory => { + const factory: EmbeddableFactory = defaultEmbeddableFactoryProvider( + def + ); + return { + ...factory, + create: async (...args) => { + const embeddable = await factory.create(...args); + return embeddable; + }, + createFromSavedObject: async (...args) => { + const embeddable = await factory.createFromSavedObject(...args); + return embeddable; + }, + }; + } + ); + this.drilldowns.bootstrap(core, plugins, { - enableDrilldowns: this.config.drilldowns.enabled, + enableDrilldowns: true, }); return {}; From bd60130b63b3f50a95cc39b3e0df7ae944f30915 Mon Sep 17 00:00:00 2001 From: streamich Date: Mon, 6 Apr 2020 15:00:08 +0200 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20create=20dashboard?= =?UTF-8?q?=5Fenhanced=20plugin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dashboard_enhanced/public/plugin.ts | 38 +--------- x-pack/plugins/embeddable_enhanced/README.md | 1 + .../plugins/embeddable_enhanced/kibana.json | 7 ++ .../embeddable_enhanced/public/index.ts | 19 +++++ .../embeddable_enhanced/public/mocks.ts | 27 +++++++ .../embeddable_enhanced/public/plugin.ts | 76 +++++++++++++++++++ 6 files changed, 131 insertions(+), 37 deletions(-) create mode 100644 x-pack/plugins/embeddable_enhanced/README.md create mode 100644 x-pack/plugins/embeddable_enhanced/kibana.json create mode 100644 x-pack/plugins/embeddable_enhanced/public/index.ts create mode 100644 x-pack/plugins/embeddable_enhanced/public/mocks.ts create mode 100644 x-pack/plugins/embeddable_enhanced/public/plugin.ts diff --git a/x-pack/plugins/dashboard_enhanced/public/plugin.ts b/x-pack/plugins/dashboard_enhanced/public/plugin.ts index f6103daa9acda..fff0f67e14f90 100644 --- a/x-pack/plugins/dashboard_enhanced/public/plugin.ts +++ b/x-pack/plugins/dashboard_enhanced/public/plugin.ts @@ -5,18 +5,8 @@ */ import { CoreStart, CoreSetup, Plugin, PluginInitializerContext } from 'src/core/public'; -import { SavedObjectAttributes } from 'kibana/public'; import { UiActionsSetup, UiActionsStart } from '../../../../src/plugins/ui_actions/public'; -import { - EmbeddableFactory, - EmbeddableFactoryDefinition, - EmbeddableInput, - EmbeddableOutput, - EmbeddableSetup, - EmbeddableStart, - IEmbeddable, - defaultEmbeddableFactoryProvider, -} from '../../../../src/plugins/embeddable/public'; +import { EmbeddableSetup, EmbeddableStart } from '../../../../src/plugins/embeddable/public'; import { DashboardDrilldownsService } from './services'; import { DrilldownsSetup, DrilldownsStart } from '../../drilldowns/public'; @@ -48,32 +38,6 @@ export class DashboardEnhancedPlugin } public setup(core: CoreSetup, plugins: SetupDependencies): SetupContract { - plugins.embeddable.setCustomEmbeddableFactoryProvider( - < - I extends EmbeddableInput = EmbeddableInput, - O extends EmbeddableOutput = EmbeddableOutput, - E extends IEmbeddable = IEmbeddable, - T extends SavedObjectAttributes = SavedObjectAttributes - >( - def: EmbeddableFactoryDefinition - ): EmbeddableFactory => { - const factory: EmbeddableFactory = defaultEmbeddableFactoryProvider( - def - ); - return { - ...factory, - create: async (...args) => { - const embeddable = await factory.create(...args); - return embeddable; - }, - createFromSavedObject: async (...args) => { - const embeddable = await factory.createFromSavedObject(...args); - return embeddable; - }, - }; - } - ); - this.drilldowns.bootstrap(core, plugins, { enableDrilldowns: true, }); diff --git a/x-pack/plugins/embeddable_enhanced/README.md b/x-pack/plugins/embeddable_enhanced/README.md new file mode 100644 index 0000000000000..a0be90731fdb0 --- /dev/null +++ b/x-pack/plugins/embeddable_enhanced/README.md @@ -0,0 +1 @@ +# X-Pack part of `embeddable` plugin diff --git a/x-pack/plugins/embeddable_enhanced/kibana.json b/x-pack/plugins/embeddable_enhanced/kibana.json new file mode 100644 index 0000000000000..9f63a55d5731d --- /dev/null +++ b/x-pack/plugins/embeddable_enhanced/kibana.json @@ -0,0 +1,7 @@ +{ + "id": "embeddableEnhanced", + "version": "kibana", + "server": false, + "ui": true, + "requiredPlugins": ["uiActions", "embeddable"] +} diff --git a/x-pack/plugins/embeddable_enhanced/public/index.ts b/x-pack/plugins/embeddable_enhanced/public/index.ts new file mode 100644 index 0000000000000..7e282e934ab82 --- /dev/null +++ b/x-pack/plugins/embeddable_enhanced/public/index.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { PluginInitializerContext } from 'src/core/public'; +import { EmbeddableEnhancedPlugin } from './plugin'; + +export { + SetupContract as EmbeddableEnhancedSetupContract, + SetupDependencies as EmbeddableEnhancedSetupDependencies, + StartContract as EmbeddableEnhancedStartContract, + StartDependencies as EmbeddableEnhancedStartDependencies, +} from './plugin'; + +export function plugin(context: PluginInitializerContext) { + return new EmbeddableEnhancedPlugin(context); +} diff --git a/x-pack/plugins/embeddable_enhanced/public/mocks.ts b/x-pack/plugins/embeddable_enhanced/public/mocks.ts new file mode 100644 index 0000000000000..d048d1248b6ff --- /dev/null +++ b/x-pack/plugins/embeddable_enhanced/public/mocks.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EmbeddableEnhancedSetupContract, EmbeddableEnhancedStartContract } from '.'; + +export type Setup = jest.Mocked; +export type Start = jest.Mocked; + +const createSetupContract = (): Setup => { + const setupContract: Setup = {}; + + return setupContract; +}; + +const createStartContract = (): Start => { + const startContract: Start = {}; + + return startContract; +}; + +export const embeddableEnhancedPluginMock = { + createSetupContract, + createStartContract, +}; diff --git a/x-pack/plugins/embeddable_enhanced/public/plugin.ts b/x-pack/plugins/embeddable_enhanced/public/plugin.ts new file mode 100644 index 0000000000000..b3938b10f89f9 --- /dev/null +++ b/x-pack/plugins/embeddable_enhanced/public/plugin.ts @@ -0,0 +1,76 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { CoreStart, CoreSetup, Plugin, PluginInitializerContext } from 'src/core/public'; +import { SavedObjectAttributes } from 'kibana/public'; +import { UiActionsSetup, UiActionsStart } from '../../../../src/plugins/ui_actions/public'; +import { + EmbeddableFactory, + EmbeddableFactoryDefinition, + EmbeddableInput, + EmbeddableOutput, + EmbeddableSetup, + EmbeddableStart, + IEmbeddable, + defaultEmbeddableFactoryProvider, +} from '../../../../src/plugins/embeddable/public'; + +export interface SetupDependencies { + embeddable: EmbeddableSetup; + uiActions: UiActionsSetup; +} + +export interface StartDependencies { + embeddable: EmbeddableStart; + uiActions: UiActionsStart; +} + +// eslint-disable-next-line +export interface SetupContract {} + +// eslint-disable-next-line +export interface StartContract {} + +export class EmbeddableEnhancedPlugin + implements Plugin { + constructor(protected readonly context: PluginInitializerContext) {} + + public setup(core: CoreSetup, plugins: SetupDependencies): SetupContract { + plugins.embeddable.setCustomEmbeddableFactoryProvider( + < + I extends EmbeddableInput = EmbeddableInput, + O extends EmbeddableOutput = EmbeddableOutput, + E extends IEmbeddable = IEmbeddable, + T extends SavedObjectAttributes = SavedObjectAttributes + >( + def: EmbeddableFactoryDefinition + ): EmbeddableFactory => { + const factory: EmbeddableFactory = defaultEmbeddableFactoryProvider( + def + ); + return { + ...factory, + create: async (...args) => { + const embeddable = await factory.create(...args); + return embeddable; + }, + createFromSavedObject: async (...args) => { + const embeddable = await factory.createFromSavedObject(...args); + return embeddable; + }, + }; + } + ); + + return {}; + } + + public start(core: CoreStart, plugins: StartDependencies): StartContract { + return {}; + } + + public stop() {} +} From 6a6caf5a80404a835bcbf7f1d480bdcc822b69d9 Mon Sep 17 00:00:00 2001 From: streamich Date: Mon, 6 Apr 2020 18:40:29 +0200 Subject: [PATCH 3/7] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20add=20EnhancedEmbedd?= =?UTF-8?q?able=20interface?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../public/lib/embeddables/i_embeddable.ts | 5 +++ .../embeddable_enhanced/public/plugin.ts | 36 ++++++++++++++----- .../embeddable_enhanced/public/types.ts | 17 +++++++++ 3 files changed, 50 insertions(+), 8 deletions(-) create mode 100644 x-pack/plugins/embeddable_enhanced/public/types.ts diff --git a/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts b/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts index 9a4452aceba00..b1b904d215cf2 100644 --- a/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts +++ b/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts @@ -91,6 +91,11 @@ export interface IEmbeddable< */ readonly runtimeId?: number; + /** + * Extra abilities added to Embeddable by `*_enhanced` plugins. + */ + enhancements?: object; + /** * Default implementation of dynamic action API for embeddables. */ diff --git a/x-pack/plugins/embeddable_enhanced/public/plugin.ts b/x-pack/plugins/embeddable_enhanced/public/plugin.ts index b3938b10f89f9..60f67905af95f 100644 --- a/x-pack/plugins/embeddable_enhanced/public/plugin.ts +++ b/x-pack/plugins/embeddable_enhanced/public/plugin.ts @@ -17,6 +17,7 @@ import { IEmbeddable, defaultEmbeddableFactoryProvider, } from '../../../../src/plugins/embeddable/public'; +import { EnhancedEmbeddable } from './types'; export interface SetupDependencies { embeddable: EmbeddableSetup; @@ -39,6 +40,18 @@ export class EmbeddableEnhancedPlugin constructor(protected readonly context: PluginInitializerContext) {} public setup(core: CoreSetup, plugins: SetupDependencies): SetupContract { + this.setCustomEmbeddableFactoryProvider(plugins); + + return {}; + } + + public start(core: CoreStart, plugins: StartDependencies): StartContract { + return {}; + } + + public stop() {} + + private setCustomEmbeddableFactoryProvider(plugins: SetupDependencies) { plugins.embeddable.setCustomEmbeddableFactoryProvider( < I extends EmbeddableInput = EmbeddableInput, @@ -55,22 +68,29 @@ export class EmbeddableEnhancedPlugin ...factory, create: async (...args) => { const embeddable = await factory.create(...args); - return embeddable; + if (!embeddable) return embeddable; + return this.enhanceEmbeddableWithDynamicActions(embeddable); }, createFromSavedObject: async (...args) => { const embeddable = await factory.createFromSavedObject(...args); - return embeddable; + if (!embeddable) return embeddable; + return this.enhanceEmbeddableWithDynamicActions(embeddable); }, }; } ); - - return {}; } - public start(core: CoreStart, plugins: StartDependencies): StartContract { - return {}; - } + private enhanceEmbeddableWithDynamicActions( + embeddable: E + ): EnhancedEmbeddable { + const enhancedEmbeddable = embeddable as EnhancedEmbeddable; - public stop() {} + enhancedEmbeddable.enhancements = { + ...enhancedEmbeddable.enhancements, + dynamicActions: {} as any, + }; + + return enhancedEmbeddable; + } } diff --git a/x-pack/plugins/embeddable_enhanced/public/types.ts b/x-pack/plugins/embeddable_enhanced/public/types.ts new file mode 100644 index 0000000000000..54d49e06e9d93 --- /dev/null +++ b/x-pack/plugins/embeddable_enhanced/public/types.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { IEmbeddable } from '../../../../src/plugins/embeddable/public'; +import { UiActionsDynamicActionManager } from '../../../../src/plugins/ui_actions/public'; + +export type EnhancedEmbeddable = E & { + enhancements: { + /** + * Default implementation of dynamic action manager for embeddables. + */ + dynamicActions: UiActionsDynamicActionManager; + }; +}; From 4aaf17eb154197cdcd01038e7398bc08872390de Mon Sep 17 00:00:00 2001 From: streamich Date: Tue, 7 Apr 2020 14:18:37 +0200 Subject: [PATCH 4/7] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20move=20DynamicAc?= =?UTF-8?q?tionManager=20to=20x-pack?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../public/lib/embeddables/embeddable.tsx | 51 +------------------ .../public/lib/embeddables/i_embeddable.ts | 6 --- .../public/lib/panel/embeddable_panel.tsx | 12 +++-- .../ui_actions/public/actions/index.ts | 2 - .../ui_actions/public/actions/types.ts | 6 +++ src/plugins/ui_actions/public/index.ts | 6 +-- .../dynamic_action_manager.test.ts | 33 ++++-------- .../dynamic_action_manager.ts | 31 ++++------- .../dynamic_action_manager_state.ts | 19 ++----- .../dynamic_action_storage.ts | 21 ++------ .../public/dynamic_actions/index.ts | 9 ++++ .../advanced_ui_actions/public/index.ts | 7 +++ .../flyout_create_drilldown.tsx | 13 +++-- .../flyout_edit_drilldown.tsx | 16 +++--- .../flyout_edit_drilldown/menu_item.test.tsx | 10 ++-- .../flyout_edit_drilldown/menu_item.tsx | 11 ++-- .../dashboard_drilldowns_services.ts | 10 ++-- .../connected_flyout_manage_drilldowns.tsx | 2 +- .../test_data.ts | 6 ++- .../embeddable_action_storage.test.ts | 31 ++++------- .../embeddables/embeddable_action_storage.ts | 49 +++++++----------- .../public/embeddables/index.ts | 8 +++ .../embeddables/is_enhanced_embeddable.ts | 14 +++++ .../embeddable_enhanced/public/index.ts | 3 ++ .../embeddable_enhanced/public/plugin.ts | 17 ++++++- .../embeddable_enhanced/public/types.ts | 8 ++- 26 files changed, 170 insertions(+), 231 deletions(-) rename {src/plugins/ui_actions/public/actions => x-pack/plugins/advanced_ui_actions/public/dynamic_actions}/dynamic_action_manager.test.ts (94%) rename {src/plugins/ui_actions/public/actions => x-pack/plugins/advanced_ui_actions/public/dynamic_actions}/dynamic_action_manager.ts (88%) rename {src/plugins/ui_actions/public/actions => x-pack/plugins/advanced_ui_actions/public/dynamic_actions}/dynamic_action_manager_state.ts (75%) rename {src/plugins/ui_actions/public/actions => x-pack/plugins/advanced_ui_actions/public/dynamic_actions}/dynamic_action_storage.ts (77%) create mode 100644 x-pack/plugins/advanced_ui_actions/public/dynamic_actions/index.ts rename {src/plugins/embeddable/public/lib => x-pack/plugins/embeddable_enhanced/public}/embeddables/embeddable_action_storage.test.ts (93%) rename {src/plugins/embeddable/public/lib => x-pack/plugins/embeddable_enhanced/public}/embeddables/embeddable_action_storage.ts (54%) create mode 100644 x-pack/plugins/embeddable_enhanced/public/embeddables/index.ts create mode 100644 x-pack/plugins/embeddable_enhanced/public/embeddables/is_enhanced_embeddable.ts diff --git a/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx b/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx index e3a6a3359132c..3c5374d6c124c 100644 --- a/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx +++ b/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx @@ -22,12 +22,7 @@ import { Adapters, ViewMode } from '../types'; import { IContainer } from '../containers'; import { EmbeddableInput, EmbeddableOutput, IEmbeddable } from './i_embeddable'; import { TriggerContextMapping } from '../ui_actions'; -import { EmbeddableActionStorage } from './embeddable_action_storage'; -import { - UiActionsDynamicActionManager, - UiActionsStart, -} from '../../../../../plugins/ui_actions/public'; -import { EmbeddableContext } from '../triggers'; +import { UiActionsStart } from '../../../../../plugins/ui_actions/public'; function getPanelTitle(input: EmbeddableInput, output: EmbeddableOutput) { return input.hidePanelTitles ? '' : input.title === undefined ? output.defaultTitle : input.title; @@ -60,28 +55,9 @@ export abstract class Embeddable< // to update input when the parent changes. private parentSubscription?: Rx.Subscription; - private storageSubscription?: Rx.Subscription; - // TODO: Rename to destroyed. private destoyed: boolean = false; - private storage = new EmbeddableActionStorage((this as unknown) as Embeddable); - - private cachedDynamicActions?: UiActionsDynamicActionManager; - public get dynamicActions(): UiActionsDynamicActionManager | undefined { - if (!this.params.uiActions) return undefined; - if (!this.cachedDynamicActions) { - this.cachedDynamicActions = new UiActionsDynamicActionManager({ - isCompatible: async (context: unknown) => - (context as EmbeddableContext).embeddable.runtimeId === this.runtimeId, - storage: this.storage, - uiActions: this.params.uiActions, - }); - } - - return this.cachedDynamicActions; - } - constructor( input: TEmbeddableInput, output: TEmbeddableOutput, @@ -111,18 +87,6 @@ export abstract class Embeddable< this.onResetInput(newInput); }); } - - if (this.dynamicActions) { - this.dynamicActions.start().catch(error => { - /* eslint-disable */ - console.log('Failed to start embeddable dynamic actions', this); - console.error(error); - /* eslint-enable */ - }); - this.storageSubscription = this.input$.subscribe(() => { - this.storage.reload$.next(); - }); - } } public getIsContainer(): this is IContainer { @@ -202,19 +166,6 @@ export abstract class Embeddable< public destroy(): void { this.destoyed = true; - if (this.dynamicActions) { - this.dynamicActions.stop().catch(error => { - /* eslint-disable */ - console.log('Failed to stop embeddable dynamic actions', this); - console.error(error); - /* eslint-enable */ - }); - } - - if (this.storageSubscription) { - this.storageSubscription.unsubscribe(); - } - this.input$.complete(); this.output$.complete(); diff --git a/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts b/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts index b1b904d215cf2..e5d8e6e1b7de9 100644 --- a/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts +++ b/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts @@ -18,7 +18,6 @@ */ import { Observable } from 'rxjs'; -import { UiActionsDynamicActionManager } from '../../../../../plugins/ui_actions/public'; import { Adapters } from '../types'; import { IContainer } from '../containers/i_container'; import { ViewMode } from '../types'; @@ -96,11 +95,6 @@ export interface IEmbeddable< */ enhancements?: object; - /** - * Default implementation of dynamic action API for embeddables. - */ - dynamicActions?: UiActionsDynamicActionManager; - /** * A functional representation of the isContainer variable, but helpful for typescript to * know the shape if this returns true diff --git a/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx b/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx index c6537f2d94994..d4d23874cfb19 100644 --- a/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx +++ b/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx @@ -203,13 +203,15 @@ export class EmbeddablePanel extends React.Component { this.props.embeddable.render(this.embeddableRoot.current); } - const dynamicActions = this.props.embeddable.dynamicActions; + const dynamicActions = (this.props.embeddable.enhancements as any)?.dynamicActions; if (dynamicActions) { this.setState({ eventCount: dynamicActions.state.get().events.length }); - this.eventCountSubscription = dynamicActions.state.state$.subscribe(({ events }) => { - if (!this.mounted) return; - this.setState({ eventCount: events.length }); - }); + this.eventCountSubscription = dynamicActions.state.state$.subscribe( + ({ events }: { events: unknown[] }) => { + if (!this.mounted) return; + this.setState({ eventCount: events.length }); + } + ); } } diff --git a/src/plugins/ui_actions/public/actions/index.ts b/src/plugins/ui_actions/public/actions/index.ts index 0ddba197aced6..0b0e60b3cf75c 100644 --- a/src/plugins/ui_actions/public/actions/index.ts +++ b/src/plugins/ui_actions/public/actions/index.ts @@ -23,6 +23,4 @@ export * from './action_factory_definition'; export * from './action_factory'; export * from './create_action'; export * from './incompatible_action_error'; -export * from './dynamic_action_storage'; -export * from './dynamic_action_manager'; export * from './types'; diff --git a/src/plugins/ui_actions/public/actions/types.ts b/src/plugins/ui_actions/public/actions/types.ts index 465f091e45ef1..d29e97eea532f 100644 --- a/src/plugins/ui_actions/public/actions/types.ts +++ b/src/plugins/ui_actions/public/actions/types.ts @@ -22,3 +22,9 @@ export interface SerializedAction { readonly name: string; readonly config: Config; } + +export interface SerializedEvent { + eventId: string; + triggers: string[]; + action: SerializedAction; +} diff --git a/src/plugins/ui_actions/public/index.ts b/src/plugins/ui_actions/public/index.ts index 9265d35bad9a9..4f00ac4a26fc3 100644 --- a/src/plugins/ui_actions/public/index.ts +++ b/src/plugins/ui_actions/public/index.ts @@ -31,11 +31,7 @@ export { ActionDefinition as UiActionsActionDefinition, ActionFactoryDefinition as UiActionsActionFactoryDefinition, ActionInternal as UiActionsActionInternal, - ActionStorage as UiActionsActionStorage, - AbstractActionStorage as UiActionsAbstractActionStorage, createAction, - DynamicActionManager, - DynamicActionManagerState, IncompatibleActionError, SerializedAction as UiActionsSerializedAction, SerializedEvent as UiActionsSerializedEvent, @@ -57,4 +53,4 @@ export { applyFilterTrigger, } from './triggers'; export { TriggerContextMapping, TriggerId, ActionContextMapping, ActionType } from './types'; -export { ActionByType, DynamicActionManager as UiActionsDynamicActionManager } from './actions'; +export { ActionByType } from './actions'; diff --git a/src/plugins/ui_actions/public/actions/dynamic_action_manager.test.ts b/x-pack/plugins/advanced_ui_actions/public/dynamic_actions/dynamic_action_manager.test.ts similarity index 94% rename from src/plugins/ui_actions/public/actions/dynamic_action_manager.test.ts rename to x-pack/plugins/advanced_ui_actions/public/dynamic_actions/dynamic_action_manager.test.ts index 2574a9e529ebf..e4bd73558b357 100644 --- a/src/plugins/ui_actions/public/actions/dynamic_action_manager.test.ts +++ b/x-pack/plugins/advanced_ui_actions/public/dynamic_actions/dynamic_action_manager.test.ts @@ -1,29 +1,18 @@ /* - * 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. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. */ import { DynamicActionManager } from './dynamic_action_manager'; import { ActionStorage, MemoryActionStorage, SerializedEvent } from './dynamic_action_storage'; -import { UiActionsService } from '../service'; -import { ActionFactoryDefinition } from './action_factory_definition'; -import { ActionRegistry } from '../types'; -import { SerializedAction } from './types'; -import { of } from '../../../kibana_utils'; +import { + UiActionsService, + UiActionsActionFactoryDefinition as ActionFactoryDefinition, + UiActionsSerializedAction as SerializedAction, + UiActionsActionInternal as ActionInternal, +} from '../../../../../src/plugins/ui_actions/public'; +import { of } from '../../../../../src/plugins/kibana_utils'; const actionFactoryDefinition1: ActionFactoryDefinition = { id: 'ACTION_FACTORY_1', @@ -82,7 +71,7 @@ const event3: SerializedEvent = { const setup = (events: readonly SerializedEvent[] = []) => { const isCompatible = async () => true; const storage: ActionStorage = new MemoryActionStorage(events); - const actions: ActionRegistry = new Map(); + const actions = new Map(); const uiActions = new UiActionsService({ actions, }); diff --git a/src/plugins/ui_actions/public/actions/dynamic_action_manager.ts b/x-pack/plugins/advanced_ui_actions/public/dynamic_actions/dynamic_action_manager.ts similarity index 88% rename from src/plugins/ui_actions/public/actions/dynamic_action_manager.ts rename to x-pack/plugins/advanced_ui_actions/public/dynamic_actions/dynamic_action_manager.ts index 97eb5b05fbbc2..73aff70332fc3 100644 --- a/src/plugins/ui_actions/public/actions/dynamic_action_manager.ts +++ b/x-pack/plugins/advanced_ui_actions/public/dynamic_actions/dynamic_action_manager.ts @@ -1,31 +1,20 @@ /* - * 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. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. */ import { v4 as uuidv4 } from 'uuid'; import { Subscription } from 'rxjs'; import { ActionStorage, SerializedEvent } from './dynamic_action_storage'; -import { UiActionsService } from '../service'; -import { SerializedAction } from './types'; -import { TriggerContextMapping } from '../types'; -import { ActionDefinition } from './action'; +import { + UiActionsService, + UiActionsSerializedAction as SerializedAction, + TriggerContextMapping, + UiActionsActionDefinition as ActionDefinition, +} from '../../../../../src/plugins/ui_actions/public'; import { defaultState, transitions, selectors, State } from './dynamic_action_manager_state'; -import { StateContainer, createStateContainer } from '../../../kibana_utils'; +import { StateContainer, createStateContainer } from '../../../../../src/plugins/kibana_utils'; const compareEvents = ( a: ReadonlyArray<{ eventId: string }>, diff --git a/src/plugins/ui_actions/public/actions/dynamic_action_manager_state.ts b/x-pack/plugins/advanced_ui_actions/public/dynamic_actions/dynamic_action_manager_state.ts similarity index 75% rename from src/plugins/ui_actions/public/actions/dynamic_action_manager_state.ts rename to x-pack/plugins/advanced_ui_actions/public/dynamic_actions/dynamic_action_manager_state.ts index 636af076ea39f..9f10eced43a65 100644 --- a/src/plugins/ui_actions/public/actions/dynamic_action_manager_state.ts +++ b/x-pack/plugins/advanced_ui_actions/public/dynamic_actions/dynamic_action_manager_state.ts @@ -1,20 +1,7 @@ /* - * 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. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. */ import { SerializedEvent } from './dynamic_action_storage'; diff --git a/src/plugins/ui_actions/public/actions/dynamic_action_storage.ts b/x-pack/plugins/advanced_ui_actions/public/dynamic_actions/dynamic_action_storage.ts similarity index 77% rename from src/plugins/ui_actions/public/actions/dynamic_action_storage.ts rename to x-pack/plugins/advanced_ui_actions/public/dynamic_actions/dynamic_action_storage.ts index 28550a671782e..92d2e8f0c3da7 100644 --- a/src/plugins/ui_actions/public/actions/dynamic_action_storage.ts +++ b/x-pack/plugins/advanced_ui_actions/public/dynamic_actions/dynamic_action_storage.ts @@ -1,26 +1,13 @@ /* - * 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. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. */ /* eslint-disable max-classes-per-file */ import { Observable, Subject } from 'rxjs'; -import { SerializedAction } from './types'; +import { UiActionsSerializedAction as SerializedAction } from '../../../../../src/plugins/ui_actions/public'; /** * Serialized representation of event-action pair, used to persist in storage. diff --git a/x-pack/plugins/advanced_ui_actions/public/dynamic_actions/index.ts b/x-pack/plugins/advanced_ui_actions/public/dynamic_actions/index.ts new file mode 100644 index 0000000000000..a2f2818d29731 --- /dev/null +++ b/x-pack/plugins/advanced_ui_actions/public/dynamic_actions/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export * from './dynamic_action_storage'; +export * from './dynamic_action_manager_state'; +export * from './dynamic_action_manager'; diff --git a/x-pack/plugins/advanced_ui_actions/public/index.ts b/x-pack/plugins/advanced_ui_actions/public/index.ts index 55361105dcb0f..4f31229a4e532 100644 --- a/x-pack/plugins/advanced_ui_actions/public/index.ts +++ b/x-pack/plugins/advanced_ui_actions/public/index.ts @@ -26,3 +26,10 @@ export { Configurable as AdvancedUiActionsConfigurable, CollectConfigProps as AdvancedUiActionsCollectConfigProps, } from './util'; + +export { + AbstractActionStorage as UiActionsEnhancedAbstractActionStorage, + DynamicActionManager as UiActionsEnhancedDynamicActionManager, + DynamicActionManagerParams as UiActionsEnhancedDynamicActionManagerParams, + DynamicActionManagerState as UiActionsEnhancedDynamicActionManagerState, +} from './dynamic_actions'; diff --git a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_create_drilldown/flyout_create_drilldown.tsx b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_create_drilldown/flyout_create_drilldown.tsx index 00e74ea570a11..d901bb8cf4e47 100644 --- a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_create_drilldown/flyout_create_drilldown.tsx +++ b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_create_drilldown/flyout_create_drilldown.tsx @@ -10,6 +10,7 @@ import { CoreStart } from 'src/core/public'; import { ActionByType } from '../../../../../../../../src/plugins/ui_actions/public'; import { toMountPoint } from '../../../../../../../../src/plugins/kibana_react/public'; import { DrilldownsStart } from '../../../../../../drilldowns/public'; +import { isEnhancedEmbeddable } from '../../../../../../embeddable_enhanced/public'; import { EmbeddableContext } from '../../../../../../../../src/plugins/embeddable/public'; export const OPEN_FLYOUT_ADD_DRILLDOWN = 'OPEN_FLYOUT_ADD_DRILLDOWN'; @@ -37,7 +38,7 @@ export class FlyoutCreateDrilldownAction implements ActionByType -1; @@ -51,10 +52,12 @@ export class FlyoutCreateDrilldownAction implements ActionByType handle.close()} placeContext={context} viewMode={'create'} - dynamicActionManager={dynamicActionManager} + dynamicActionManager={embeddable.enhancements.dynamicActions} /> ), { diff --git a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.tsx b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.tsx index 816b757592a72..23a6689bd8d9d 100644 --- a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.tsx +++ b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.tsx @@ -15,6 +15,7 @@ import { EmbeddableContext, ViewMode } from '../../../../../../../../src/plugins import { DrilldownsStart } from '../../../../../../drilldowns/public'; import { txtDisplayName } from './i18n'; import { MenuItem } from './menu_item'; +import { isEnhancedEmbeddable } from '../../../../../../embeddable_enhanced/public'; export const OPEN_FLYOUT_EDIT_DRILLDOWN = 'OPEN_FLYOUT_EDIT_DRILLDOWN'; @@ -42,16 +43,19 @@ export class FlyoutEditDrilldownAction implements ActionByType 0; + if (!isEnhancedEmbeddable(embeddable)) return false; + return embeddable.enhancements.dynamicActions.state.get().events.length > 0; } public async execute(context: EmbeddableContext) { const overlays = await this.params.overlays(); const drilldowns = await this.params.drilldowns(); - const dynamicActionManager = context.embeddable.dynamicActions; - if (!dynamicActionManager) { - throw new Error(`Can't execute FlyoutEditDrilldownAction without dynamicActionsManager`); + const { embeddable } = context; + + if (!isEnhancedEmbeddable(embeddable)) { + throw new Error( + 'Need embeddable to be EnhancedEmbeddable to execute FlyoutEditDrilldownAction.' + ); } const handle = overlays.openFlyout( @@ -60,7 +64,7 @@ export class FlyoutEditDrilldownAction implements ActionByType handle.close()} placeContext={context} viewMode={'manage'} - dynamicActionManager={dynamicActionManager} + dynamicActionManager={embeddable.enhancements.dynamicActions} /> ), { diff --git a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/menu_item.test.tsx b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/menu_item.test.tsx index be693fadf9282..c57bafc88e978 100644 --- a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/menu_item.test.tsx +++ b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/menu_item.test.tsx @@ -8,8 +8,8 @@ import React from 'react'; import { render, cleanup, act } from '@testing-library/react/pure'; import { MenuItem } from './menu_item'; import { createStateContainer } from '../../../../../../../../src/plugins/kibana_utils/common'; -import { DynamicActionManager } from '../../../../../../../../src/plugins/ui_actions/public'; -import { IEmbeddable } from '../../../../../../../../src/plugins/embeddable/public/lib/embeddables'; +import { UiActionsEnhancedDynamicActionManager as DynamicActionManager } from '../../../../../../advanced_ui_actions/public'; +import { EnhancedEmbeddable } from '../../../../../../embeddable_enhanced/public'; import '@testing-library/jest-dom'; afterEach(cleanup); @@ -20,8 +20,10 @@ test('', () => { ); diff --git a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/menu_item.tsx b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/menu_item.tsx index 4f99fca511b07..ddcea0028409c 100644 --- a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/menu_item.tsx +++ b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/menu_item.tsx @@ -6,15 +6,12 @@ import React from 'react'; import { EuiNotificationBadge, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import { EmbeddableContext } from '../../../../../../../../src/plugins/embeddable/public'; -import { txtDisplayName } from './i18n'; import { useContainerState } from '../../../../../../../../src/plugins/kibana_utils/common'; +import { EnhancedEmbeddableContext } from '../../../../../../embeddable_enhanced/public'; +import { txtDisplayName } from './i18n'; -export const MenuItem: React.FC<{ context: EmbeddableContext }> = ({ context }) => { - if (!context.embeddable.dynamicActions) - throw new Error('Flyout edit drillldown context menu item requires `dynamicActions`'); - - const { events } = useContainerState(context.embeddable.dynamicActions.state); +export const MenuItem: React.FC<{ context: EnhancedEmbeddableContext }> = ({ context }) => { + const { events } = useContainerState(context.embeddable.enhancements.dynamicActions.state); const count = events.length; return ( diff --git a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_drilldowns_services.ts b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_drilldowns_services.ts index 4bdf03dff3531..3c7089937488b 100644 --- a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_drilldowns_services.ts +++ b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_drilldowns_services.ts @@ -6,10 +6,8 @@ import { CoreSetup } from 'src/core/public'; import { SetupDependencies } from '../../plugin'; -import { - CONTEXT_MENU_TRIGGER, - EmbeddableContext, -} from '../../../../../../src/plugins/embeddable/public'; +import { CONTEXT_MENU_TRIGGER } from '../../../../../../src/plugins/embeddable/public'; +import { EnhancedEmbeddableContext } from '../../../../embeddable_enhanced/public'; import { FlyoutCreateDrilldownAction, FlyoutEditDrilldownAction, @@ -21,8 +19,8 @@ import { DashboardToDashboardDrilldown } from './dashboard_to_dashboard_drilldow declare module '../../../../../../src/plugins/ui_actions/public' { export interface ActionContextMapping { - [OPEN_FLYOUT_ADD_DRILLDOWN]: EmbeddableContext; - [OPEN_FLYOUT_EDIT_DRILLDOWN]: EmbeddableContext; + [OPEN_FLYOUT_ADD_DRILLDOWN]: EnhancedEmbeddableContext; + [OPEN_FLYOUT_EDIT_DRILLDOWN]: EnhancedEmbeddableContext; } } diff --git a/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.tsx b/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.tsx index f22ccc2f26f02..f4dcbf64d895e 100644 --- a/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.tsx +++ b/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.tsx @@ -9,13 +9,13 @@ import useMountedState from 'react-use/lib/useMountedState'; import { AdvancedUiActionsActionFactory as ActionFactory, AdvancedUiActionsStart, + UiActionsEnhancedDynamicActionManager as DynamicActionManager, } from '../../../../advanced_ui_actions/public'; import { NotificationsStart } from '../../../../../../src/core/public'; import { DrilldownWizardConfig, FlyoutDrilldownWizard } from '../flyout_drilldown_wizard'; import { FlyoutListManageDrilldowns } from '../flyout_list_manage_drilldowns'; import { IStorageWrapper } from '../../../../../../src/plugins/kibana_utils/public'; import { - DynamicActionManager, UiActionsSerializedEvent, UiActionsSerializedAction, VALUE_CLICK_TRIGGER, diff --git a/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/test_data.ts b/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/test_data.ts index b8deaa8b842bc..780c91eee56c3 100644 --- a/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/test_data.ts +++ b/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/test_data.ts @@ -6,8 +6,10 @@ import uuid from 'uuid'; import { - DynamicActionManager, - DynamicActionManagerState, + UiActionsEnhancedDynamicActionManager as DynamicActionManager, + UiActionsEnhancedDynamicActionManagerState as DynamicActionManagerState, +} from '../../../../advanced_ui_actions/public'; +import { UiActionsSerializedAction, TriggerContextMapping, } from '../../../../../../src/plugins/ui_actions/public'; diff --git a/src/plugins/embeddable/public/lib/embeddables/embeddable_action_storage.test.ts b/x-pack/plugins/embeddable_enhanced/public/embeddables/embeddable_action_storage.test.ts similarity index 93% rename from src/plugins/embeddable/public/lib/embeddables/embeddable_action_storage.test.ts rename to x-pack/plugins/embeddable_enhanced/public/embeddables/embeddable_action_storage.test.ts index 83fd3f184e098..1f779e92edc6e 100644 --- a/src/plugins/embeddable/public/lib/embeddables/embeddable_action_storage.test.ts +++ b/x-pack/plugins/embeddable_enhanced/public/embeddables/embeddable_action_storage.test.ts @@ -1,28 +1,17 @@ /* - * 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. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. */ -import { Embeddable } from './embeddable'; -import { EmbeddableInput } from './i_embeddable'; -import { ViewMode } from '../types'; +import { + Embeddable, + EmbeddableInput, + ViewMode, +} from '../../../../../src/plugins/embeddable/public'; import { EmbeddableActionStorage } from './embeddable_action_storage'; -import { UiActionsSerializedEvent } from '../../../../ui_actions/public'; -import { of } from '../../../../kibana_utils/common'; +import { UiActionsSerializedEvent } from '../../../../../src/plugins/ui_actions/public'; +import { of } from '../../../../../src/plugins/kibana_utils/common'; class TestEmbeddable extends Embeddable { public readonly type = 'test'; diff --git a/src/plugins/embeddable/public/lib/embeddables/embeddable_action_storage.ts b/x-pack/plugins/embeddable_enhanced/public/embeddables/embeddable_action_storage.ts similarity index 54% rename from src/plugins/embeddable/public/lib/embeddables/embeddable_action_storage.ts rename to x-pack/plugins/embeddable_enhanced/public/embeddables/embeddable_action_storage.ts index fad5b4d535d6c..ad4f82cc529b5 100644 --- a/src/plugins/embeddable/public/lib/embeddables/embeddable_action_storage.ts +++ b/x-pack/plugins/embeddable_enhanced/public/embeddables/embeddable_action_storage.ts @@ -1,36 +1,21 @@ /* - * 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. + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. */ -import { - UiActionsAbstractActionStorage, - UiActionsSerializedEvent, -} from '../../../../ui_actions/public'; -import { Embeddable } from '..'; +import { UiActionsSerializedEvent as SerializedEvent } from '../../../../../src/plugins/ui_actions/public'; +import { UiActionsEnhancedAbstractActionStorage as AbstractActionStorage } from '../../../advanced_ui_actions/public'; +import { IEmbeddable } from '../../../../../src/plugins/embeddable/public'; -export class EmbeddableActionStorage extends UiActionsAbstractActionStorage { - constructor(private readonly embbeddable: Embeddable) { +export class EmbeddableActionStorage extends AbstractActionStorage { + constructor(private readonly embbeddable: IEmbeddable) { super(); } - async create(event: UiActionsSerializedEvent) { + async create(event: SerializedEvent) { const input = this.embbeddable.getInput(); - const events = (input.events || []) as UiActionsSerializedEvent[]; + const events = (input.events || []) as SerializedEvent[]; const exists = !!events.find(({ eventId }) => eventId === event.eventId); if (exists) { @@ -45,9 +30,9 @@ export class EmbeddableActionStorage extends UiActionsAbstractActionStorage { }); } - async update(event: UiActionsSerializedEvent) { + async update(event: SerializedEvent) { const input = this.embbeddable.getInput(); - const events = (input.events || []) as UiActionsSerializedEvent[]; + const events = (input.events || []) as SerializedEvent[]; const index = events.findIndex(({ eventId }) => eventId === event.eventId); if (index === -1) { @@ -65,7 +50,7 @@ export class EmbeddableActionStorage extends UiActionsAbstractActionStorage { async remove(eventId: string) { const input = this.embbeddable.getInput(); - const events = (input.events || []) as UiActionsSerializedEvent[]; + const events = (input.events || []) as SerializedEvent[]; const index = events.findIndex(event => eventId === event.eventId); if (index === -1) { @@ -81,9 +66,9 @@ export class EmbeddableActionStorage extends UiActionsAbstractActionStorage { }); } - async read(eventId: string): Promise { + async read(eventId: string): Promise { const input = this.embbeddable.getInput(); - const events = (input.events || []) as UiActionsSerializedEvent[]; + const events = (input.events || []) as SerializedEvent[]; const event = events.find(ev => eventId === ev.eventId); if (!event) { @@ -98,10 +83,10 @@ export class EmbeddableActionStorage extends UiActionsAbstractActionStorage { private __list() { const input = this.embbeddable.getInput(); - return (input.events || []) as UiActionsSerializedEvent[]; + return (input.events || []) as SerializedEvent[]; } - async list(): Promise { + async list(): Promise { return this.__list(); } } diff --git a/x-pack/plugins/embeddable_enhanced/public/embeddables/index.ts b/x-pack/plugins/embeddable_enhanced/public/embeddables/index.ts new file mode 100644 index 0000000000000..fabbc60a13f67 --- /dev/null +++ b/x-pack/plugins/embeddable_enhanced/public/embeddables/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export * from './is_enhanced_embeddable'; +export * from './embeddable_action_storage'; diff --git a/x-pack/plugins/embeddable_enhanced/public/embeddables/is_enhanced_embeddable.ts b/x-pack/plugins/embeddable_enhanced/public/embeddables/is_enhanced_embeddable.ts new file mode 100644 index 0000000000000..f29430dc6a3de --- /dev/null +++ b/x-pack/plugins/embeddable_enhanced/public/embeddables/is_enhanced_embeddable.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { IEmbeddable } from '../../../../../src/plugins/embeddable/public'; +import { EnhancedEmbeddable } from '../types'; + +export const isEnhancedEmbeddable = ( + maybeEnhancedEmbeddable: E +): maybeEnhancedEmbeddable is EnhancedEmbeddable => + typeof (maybeEnhancedEmbeddable as EnhancedEmbeddable) + ?.enhancements?.dynamicActions === 'object'; diff --git a/x-pack/plugins/embeddable_enhanced/public/index.ts b/x-pack/plugins/embeddable_enhanced/public/index.ts index 7e282e934ab82..059acf9644820 100644 --- a/x-pack/plugins/embeddable_enhanced/public/index.ts +++ b/x-pack/plugins/embeddable_enhanced/public/index.ts @@ -17,3 +17,6 @@ export { export function plugin(context: PluginInitializerContext) { return new EmbeddableEnhancedPlugin(context); } + +export { EnhancedEmbeddable, EnhancedEmbeddableContext } from './types'; +export { isEnhancedEmbeddable } from './embeddables'; diff --git a/x-pack/plugins/embeddable_enhanced/public/plugin.ts b/x-pack/plugins/embeddable_enhanced/public/plugin.ts index 60f67905af95f..7d62c21dfa62b 100644 --- a/x-pack/plugins/embeddable_enhanced/public/plugin.ts +++ b/x-pack/plugins/embeddable_enhanced/public/plugin.ts @@ -16,8 +16,11 @@ import { EmbeddableStart, IEmbeddable, defaultEmbeddableFactoryProvider, + EmbeddableContext, } from '../../../../src/plugins/embeddable/public'; import { EnhancedEmbeddable } from './types'; +import { EmbeddableActionStorage } from './embeddables/embeddable_action_storage'; +import { UiActionsEnhancedDynamicActionManager as DynamicActionManager } from '../../advanced_ui_actions/public'; export interface SetupDependencies { embeddable: EmbeddableSetup; @@ -39,6 +42,8 @@ export class EmbeddableEnhancedPlugin implements Plugin { constructor(protected readonly context: PluginInitializerContext) {} + private uiActions?: StartDependencies['uiActions']; + public setup(core: CoreSetup, plugins: SetupDependencies): SetupContract { this.setCustomEmbeddableFactoryProvider(plugins); @@ -46,6 +51,8 @@ export class EmbeddableEnhancedPlugin } public start(core: CoreStart, plugins: StartDependencies): StartContract { + this.uiActions = plugins.uiActions; + return {}; } @@ -86,9 +93,17 @@ export class EmbeddableEnhancedPlugin ): EnhancedEmbeddable { const enhancedEmbeddable = embeddable as EnhancedEmbeddable; + const storage = new EmbeddableActionStorage(embeddable); + const dynamicActions = new DynamicActionManager({ + isCompatible: async (context: unknown) => + (context as EmbeddableContext).embeddable.runtimeId === embeddable.runtimeId, + storage, + uiActions: this.uiActions!, + }); + enhancedEmbeddable.enhancements = { ...enhancedEmbeddable.enhancements, - dynamicActions: {} as any, + dynamicActions, }; return enhancedEmbeddable; diff --git a/x-pack/plugins/embeddable_enhanced/public/types.ts b/x-pack/plugins/embeddable_enhanced/public/types.ts index 54d49e06e9d93..924605be332b2 100644 --- a/x-pack/plugins/embeddable_enhanced/public/types.ts +++ b/x-pack/plugins/embeddable_enhanced/public/types.ts @@ -5,13 +5,17 @@ */ import { IEmbeddable } from '../../../../src/plugins/embeddable/public'; -import { UiActionsDynamicActionManager } from '../../../../src/plugins/ui_actions/public'; +import { UiActionsEnhancedDynamicActionManager as DynamicActionManager } from '../../advanced_ui_actions/public'; export type EnhancedEmbeddable = E & { enhancements: { /** * Default implementation of dynamic action manager for embeddables. */ - dynamicActions: UiActionsDynamicActionManager; + dynamicActions: DynamicActionManager; }; }; + +export interface EnhancedEmbeddableContext { + embeddable: EnhancedEmbeddable; +} From 5fea25d2b11ad2ffaf91c5dfa8261b41bc8a9254 Mon Sep 17 00:00:00 2001 From: streamich Date: Tue, 7 Apr 2020 14:48:43 +0200 Subject: [PATCH 5/7] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20connect=20dynamic=20?= =?UTF-8?q?action=20manager=20to=20embeddable=20life-cycle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../embeddable_enhanced/public/plugin.ts | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/x-pack/plugins/embeddable_enhanced/public/plugin.ts b/x-pack/plugins/embeddable_enhanced/public/plugin.ts index 7d62c21dfa62b..5a1f07a480937 100644 --- a/x-pack/plugins/embeddable_enhanced/public/plugin.ts +++ b/x-pack/plugins/embeddable_enhanced/public/plugin.ts @@ -101,6 +101,30 @@ export class EmbeddableEnhancedPlugin uiActions: this.uiActions!, }); + dynamicActions.start().catch(error => { + /* eslint-disable */ + console.log('Failed to start embeddable dynamic actions', embeddable); + console.error(error); + /* eslint-enable */ + }); + + const stop = () => { + dynamicActions.stop().catch(error => { + /* eslint-disable */ + console.log('Failed to stop embeddable dynamic actions', embeddable); + console.error(error); + /* eslint-enable */ + }); + }; + + embeddable.getInput$().subscribe({ + next: () => { + storage.reload$.next(); + }, + error: stop, + complete: stop, + }); + enhancedEmbeddable.enhancements = { ...enhancedEmbeddable.enhancements, dynamicActions, From 45821c713dd6e3cb6d1c0160a76e16501690dc07 Mon Sep 17 00:00:00 2001 From: streamich Date: Wed, 8 Apr 2020 11:59:09 +0200 Subject: [PATCH 6/7] =?UTF-8?q?test:=20=F0=9F=92=8D=20fix=20Jest=20tests?= =?UTF-8?q?=20after=20refactor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../advanced_ui_actions/public/index.ts | 1 + .../flyout_create_drilldown.test.tsx | 100 ++++++++-------- .../flyout_edit_drilldown.test.tsx | 113 ++++++++++++------ .../drilldowns/actions/test_helpers.ts | 22 +++- 4 files changed, 153 insertions(+), 83 deletions(-) diff --git a/x-pack/plugins/advanced_ui_actions/public/index.ts b/x-pack/plugins/advanced_ui_actions/public/index.ts index 4f31229a4e532..9672fb10f9e16 100644 --- a/x-pack/plugins/advanced_ui_actions/public/index.ts +++ b/x-pack/plugins/advanced_ui_actions/public/index.ts @@ -32,4 +32,5 @@ export { DynamicActionManager as UiActionsEnhancedDynamicActionManager, DynamicActionManagerParams as UiActionsEnhancedDynamicActionManagerParams, DynamicActionManagerState as UiActionsEnhancedDynamicActionManagerState, + MemoryActionStorage as UiActionsEnhancedMemoryActionStorage, } from './dynamic_actions'; diff --git a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_create_drilldown/flyout_create_drilldown.test.tsx b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_create_drilldown/flyout_create_drilldown.test.tsx index 31ee9e29938cb..dcdefba04d882 100644 --- a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_create_drilldown/flyout_create_drilldown.test.tsx +++ b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_create_drilldown/flyout_create_drilldown.test.tsx @@ -13,7 +13,7 @@ import { drilldownsPluginMock } from '../../../../../../drilldowns/public/mocks' import { ViewMode } from '../../../../../../../../src/plugins/embeddable/public'; import { uiActionsPluginMock } from '../../../../../../../../src/plugins/ui_actions/public/mocks'; import { TriggerContextMapping } from '../../../../../../../../src/plugins/ui_actions/public'; -import { MockEmbeddable } from '../test_helpers'; +import { MockEmbeddable, enhanceEmbeddable } from '../test_helpers'; const overlays = coreMock.createStart().overlays; const drilldowns = drilldownsPluginMock.createStartContract(); @@ -40,85 +40,91 @@ test('icon exists', () => { ); }); +interface CompatibilityParams { + isEdit?: boolean; + isValueClickTriggerSupported?: boolean; + isEmbeddableEnhanced?: boolean; +} + describe('isCompatible', () => { const drilldownAction = new FlyoutCreateDrilldownAction(actionParams); - function checkCompatibility(params: { - isEdit: boolean; - withUiActions: boolean; - isValueClickTriggerSupported: boolean; - }): Promise { - return drilldownAction.isCompatible({ - embeddable: new MockEmbeddable( - { id: '', viewMode: params.isEdit ? ViewMode.EDIT : ViewMode.VIEW }, - { - supportedTriggers: (params.isValueClickTriggerSupported - ? ['VALUE_CLICK_TRIGGER'] - : []) as Array, - uiActions: params.withUiActions ? uiActions : undefined, // dynamic actions support - } - ), + async function assertCompatibility( + { + isEdit = true, + isValueClickTriggerSupported = true, + isEmbeddableEnhanced = true, + }: CompatibilityParams, + expectedResult: boolean = true + ): Promise { + let embeddable = new MockEmbeddable( + { id: '', viewMode: isEdit ? ViewMode.EDIT : ViewMode.VIEW }, + { + supportedTriggers: (isValueClickTriggerSupported ? ['VALUE_CLICK_TRIGGER'] : []) as Array< + keyof TriggerContextMapping + >, + uiActions, + } + ); + + if (isEmbeddableEnhanced) { + embeddable = enhanceEmbeddable(embeddable); + } + + const result = await drilldownAction.isCompatible({ + embeddable, }); + + expect(result).toBe(expectedResult); } + const assertNonCompatibility = (params: CompatibilityParams) => + assertCompatibility(params, false); + test("compatible if dynamicUiActions enabled, 'VALUE_CLICK_TRIGGER' is supported, in edit mode", async () => { - expect( - await checkCompatibility({ - withUiActions: true, - isEdit: true, - isValueClickTriggerSupported: true, - }) - ).toBe(true); + await assertCompatibility({}); }); - test('not compatible if dynamicUiActions disabled', async () => { - expect( - await checkCompatibility({ - withUiActions: false, - isEdit: true, - isValueClickTriggerSupported: true, - }) - ).toBe(false); + test('not compatible if embeddable is not enhanced', async () => { + await assertNonCompatibility({ + isEmbeddableEnhanced: false, + }); }); test("not compatible if 'VALUE_CLICK_TRIGGER' is not supported", async () => { - expect( - await checkCompatibility({ - withUiActions: true, - isEdit: true, - isValueClickTriggerSupported: false, - }) - ).toBe(false); + await assertNonCompatibility({ + isValueClickTriggerSupported: false, + }); }); test('not compatible if in view mode', async () => { - expect( - await checkCompatibility({ - withUiActions: true, - isEdit: false, - isValueClickTriggerSupported: true, - }) - ).toBe(false); + await assertNonCompatibility({ + isEdit: false, + }); }); }); describe('execute', () => { const drilldownAction = new FlyoutCreateDrilldownAction(actionParams); + test('throws error if no dynamicUiActions', async () => { await expect( drilldownAction.execute({ embeddable: new MockEmbeddable({ id: '' }, {}), }) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Can't execute FlyoutCreateDrilldownAction without dynamicActionsManager"` + `"Need embeddable to be EnhancedEmbeddable to execute FlyoutCreateDrilldownAction."` ); }); test('should open flyout', async () => { const spy = jest.spyOn(overlays, 'openFlyout'); + const embeddable = enhanceEmbeddable(new MockEmbeddable({ id: '' }, { uiActions })); + await drilldownAction.execute({ - embeddable: new MockEmbeddable({ id: '' }, { uiActions }), + embeddable, }); + expect(spy).toBeCalled(); }); }); diff --git a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.test.tsx b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.test.tsx index a3f11eb976f90..06a3654258291 100644 --- a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.test.tsx +++ b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.test.tsx @@ -9,11 +9,24 @@ import { coreMock } from '../../../../../../../../src/core/public/mocks'; import { drilldownsPluginMock } from '../../../../../../drilldowns/public/mocks'; import { ViewMode } from '../../../../../../../../src/plugins/embeddable/public'; import { uiActionsPluginMock } from '../../../../../../../../src/plugins/ui_actions/public/mocks'; -import { MockEmbeddable } from '../test_helpers'; +import { EnhancedEmbeddable } from '../../../../../../embeddable_enhanced/public'; +import { MockEmbeddable, enhanceEmbeddable } from '../test_helpers'; const overlays = coreMock.createStart().overlays; const drilldowns = drilldownsPluginMock.createStartContract(); -const uiActions = uiActionsPluginMock.createStartContract(); +const uiActionsPlugin = uiActionsPluginMock.createPlugin(); +const uiActions = uiActionsPlugin.doStart(); + +uiActionsPlugin.setup.registerActionFactory({ + id: 'foo', + CollectConfig: {} as any, + createConfig: () => ({}), + isConfigValid: () => true, + create: () => ({ + id: 'test', + execute: async () => {}, + }), +}); const actionParams: FlyoutEditDrilldownParams = { drilldowns: () => Promise.resolve(drilldowns), @@ -39,63 +52,93 @@ test('MenuItem exists', () => { }); describe('isCompatible', () => { - const drilldownAction = new FlyoutEditDrilldownAction(actionParams); + function setupIsCompatible({ + isEdit = true, + isEmbeddableEnhanced = true, + }: { + isEdit?: boolean; + isEmbeddableEnhanced?: boolean; + } = {}) { + const action = new FlyoutEditDrilldownAction(actionParams); + const input = { + id: '', + viewMode: isEdit ? ViewMode.EDIT : ViewMode.VIEW, + }; + const embeddable = new MockEmbeddable(input, { + uiActions, + }); + const context = { + embeddable: (isEmbeddableEnhanced + ? enhanceEmbeddable(embeddable, uiActions) + : embeddable) as EnhancedEmbeddable, + }; + + return { + action, + context, + }; + } + + test('not compatible if no drilldowns', async () => { + const { action, context } = setupIsCompatible(); + expect(await action.isCompatible(context)).toBe(false); + }); + + test('not compatible if embeddable is not enhanced', async () => { + const { action, context } = setupIsCompatible({ isEmbeddableEnhanced: false }); + expect(await action.isCompatible(context)).toBe(false); + }); + + describe('when has at least one drilldown', () => { + test('is compatible in edit mode', async () => { + const { action, context } = setupIsCompatible(); - function checkCompatibility(params: { - isEdit: boolean; - withUiActions: boolean; - }): Promise { - return drilldownAction.isCompatible({ - embeddable: new MockEmbeddable( + await context.embeddable.enhancements.dynamicActions.createEvent( { - id: '', - viewMode: params.isEdit ? ViewMode.EDIT : ViewMode.VIEW, + config: {}, + factoryId: 'foo', + name: '', }, - { - uiActions: params.withUiActions ? uiActions : undefined, // dynamic actions support - } - ), + ['VALUE_CLICK_TRIGGER'] + ); + + expect(await action.isCompatible(context)).toBe(true); }); - } - // TODO: need proper DynamicActionsMock and ActionFactory mock - test.todo('compatible if dynamicUiActions enabled, in edit view, and have at least 1 drilldown'); + test('not compatible in view mode', async () => { + const { action, context } = setupIsCompatible({ isEdit: false }); - test('not compatible if dynamicUiActions disabled', async () => { - expect( - await checkCompatibility({ - withUiActions: false, - isEdit: true, - }) - ).toBe(false); - }); + await context.embeddable.enhancements.dynamicActions.createEvent( + { + config: {}, + factoryId: 'foo', + name: '', + }, + ['VALUE_CLICK_TRIGGER'] + ); - test('not compatible if no drilldowns', async () => { - expect( - await checkCompatibility({ - withUiActions: true, - isEdit: true, - }) - ).toBe(false); + expect(await action.isCompatible(context)).toBe(false); + }); }); }); describe('execute', () => { const drilldownAction = new FlyoutEditDrilldownAction(actionParams); + test('throws error if no dynamicUiActions', async () => { await expect( drilldownAction.execute({ embeddable: new MockEmbeddable({ id: '' }, {}), }) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Can't execute FlyoutEditDrilldownAction without dynamicActionsManager"` + `"Need embeddable to be EnhancedEmbeddable to execute FlyoutEditDrilldownAction."` ); }); test('should open flyout', async () => { const spy = jest.spyOn(overlays, 'openFlyout'); await drilldownAction.execute({ - embeddable: new MockEmbeddable({ id: '' }, { uiActions }), + embeddable: enhanceEmbeddable(new MockEmbeddable({ id: '' }, { uiActions })), }); expect(spy).toBeCalled(); }); diff --git a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/test_helpers.ts b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/test_helpers.ts index 9b156b0ba85b4..07751f383fe15 100644 --- a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/test_helpers.ts +++ b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/test_helpers.ts @@ -4,11 +4,17 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Embeddable, EmbeddableInput } from '../../../../../../../src/plugins/embeddable/public/'; +import { Embeddable, EmbeddableInput } from '../../../../../../../src/plugins/embeddable/public'; +import { EnhancedEmbeddable } from '../../../../../embeddable_enhanced/public'; +import { + UiActionsEnhancedMemoryActionStorage as MemoryActionStorage, + UiActionsEnhancedDynamicActionManager as DynamicActionManager, +} from '../../../../../advanced_ui_actions/public'; import { TriggerContextMapping, UiActionsStart, } from '../../../../../../../src/plugins/ui_actions/public'; +import { uiActionsPluginMock } from '../../../../../../../src/plugins/ui_actions/public/mocks'; export class MockEmbeddable extends Embeddable { public readonly type = 'mock'; @@ -26,3 +32,17 @@ export class MockEmbeddable extends Embeddable { return this.triggers; } } + +export const enhanceEmbeddable = ( + embeddable: E, + uiActions: UiActionsStart = uiActionsPluginMock.createStartContract() +): EnhancedEmbeddable => { + (embeddable as EnhancedEmbeddable).enhancements = { + dynamicActions: new DynamicActionManager({ + storage: new MemoryActionStorage(), + isCompatible: async () => true, + uiActions, + }), + }; + return embeddable as EnhancedEmbeddable; +}; From 3ce0958e8c23515588a2f90da206a3c2c13835d0 Mon Sep 17 00:00:00 2001 From: streamich Date: Thu, 9 Apr 2020 11:07:46 +0200 Subject: [PATCH 7/7] =?UTF-8?q?fix:=20=F0=9F=90=9B=20fix=20type=20error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- x-pack/legacy/plugins/canvas/public/application.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/legacy/plugins/canvas/public/application.tsx b/x-pack/legacy/plugins/canvas/public/application.tsx index 79b3918fef99b..670583e6542ee 100644 --- a/x-pack/legacy/plugins/canvas/public/application.tsx +++ b/x-pack/legacy/plugins/canvas/public/application.tsx @@ -117,7 +117,7 @@ export const initializeCanvas = async ( restoreAction = action; startPlugins.uiActions.detachAction(VALUE_CLICK_TRIGGER, action.id); - startPlugins.uiActions.attachAction(VALUE_CLICK_TRIGGER, emptyAction); + startPlugins.uiActions.addTriggerAction(VALUE_CLICK_TRIGGER, emptyAction); } return canvasStore; @@ -129,7 +129,7 @@ export const teardownCanvas = (coreStart: CoreStart, startPlugins: CanvasStartDe startPlugins.uiActions.detachAction(VALUE_CLICK_TRIGGER, emptyAction.id); if (restoreAction) { - startPlugins.uiActions.attachAction(VALUE_CLICK_TRIGGER, restoreAction); + startPlugins.uiActions.addTriggerAction(VALUE_CLICK_TRIGGER, restoreAction); restoreAction = undefined; }