From 4e180aa19301de9e4d13e3f2ad905c3c5b9568a4 Mon Sep 17 00:00:00 2001 From: streamich Date: Thu, 18 Jun 2020 11:11:45 +0200 Subject: [PATCH 01/25] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20rename=20folde?= =?UTF-8?q?r=20to=20"explore=5Fdata"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../explore_data_context_menu_action.test.ts | 0 .../explore_data_context_menu_action.ts | 0 .../public/actions/{view_in_discover => explore_data}/index.ts | 0 x-pack/plugins/discover_enhanced/public/actions/index.ts | 2 +- 4 files changed, 1 insertion(+), 1 deletion(-) rename x-pack/plugins/discover_enhanced/public/actions/{view_in_discover => explore_data}/explore_data_context_menu_action.test.ts (100%) rename x-pack/plugins/discover_enhanced/public/actions/{view_in_discover => explore_data}/explore_data_context_menu_action.ts (100%) rename x-pack/plugins/discover_enhanced/public/actions/{view_in_discover => explore_data}/index.ts (100%) diff --git a/x-pack/plugins/discover_enhanced/public/actions/view_in_discover/explore_data_context_menu_action.test.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts similarity index 100% rename from x-pack/plugins/discover_enhanced/public/actions/view_in_discover/explore_data_context_menu_action.test.ts rename to x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts diff --git a/x-pack/plugins/discover_enhanced/public/actions/view_in_discover/explore_data_context_menu_action.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.ts similarity index 100% rename from x-pack/plugins/discover_enhanced/public/actions/view_in_discover/explore_data_context_menu_action.ts rename to x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.ts diff --git a/x-pack/plugins/discover_enhanced/public/actions/view_in_discover/index.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/index.ts similarity index 100% rename from x-pack/plugins/discover_enhanced/public/actions/view_in_discover/index.ts rename to x-pack/plugins/discover_enhanced/public/actions/explore_data/index.ts diff --git a/x-pack/plugins/discover_enhanced/public/actions/index.ts b/x-pack/plugins/discover_enhanced/public/actions/index.ts index cbb955fa46340a..209ae6bee09b50 100644 --- a/x-pack/plugins/discover_enhanced/public/actions/index.ts +++ b/x-pack/plugins/discover_enhanced/public/actions/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export * from './view_in_discover'; +export * from './explore_data'; From 428bbab202974e8d6557aa9aa7d2a3abcebcd04f Mon Sep 17 00:00:00 2001 From: streamich Date: Thu, 18 Jun 2020 11:12:58 +0200 Subject: [PATCH 02/25] =?UTF-8?q?style:=20=F0=9F=92=84=20check=20for=20"sh?= =?UTF-8?q?are"=20plugin=20in=20more=20semantic=20way?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "explore data" actions use Discover URL generator, which is registered in "share" plugin, which is optional plugin, so we check for its existance, because otherwise URL generator is not available. --- x-pack/plugins/discover_enhanced/public/plugin.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/discover_enhanced/public/plugin.ts b/x-pack/plugins/discover_enhanced/public/plugin.ts index f55c5dab3449ba..e68c16042cf32b 100644 --- a/x-pack/plugins/discover_enhanced/public/plugin.ts +++ b/x-pack/plugins/discover_enhanced/public/plugin.ts @@ -48,8 +48,9 @@ export class DiscoverEnhancedPlugin { uiActions, share }: DiscoverEnhancedSetupDependencies ) { const start = createStartServicesGetter(core.getStartServices); + const isSharePluginInstalled = !!share; - if (!!share) { + if (isSharePluginInstalled) { const exploreDataAction = new ExploreDataContextMenuAction({ start }); uiActions.addTriggerAction(CONTEXT_MENU_TRIGGER, exploreDataAction); } From 11c6b644267e848e03c0f795c137cbb15c706737 Mon Sep 17 00:00:00 2001 From: streamich Date: Thu, 18 Jun 2020 11:17:03 +0200 Subject: [PATCH 03/25] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20move=20KibanaU?= =?UTF-8?q?RL=20to=20a=20separate=20file?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../explore_data_context_menu_action.ts | 29 +---------------- .../public/actions/explore_data/kibana_url.ts | 31 +++++++++++++++++++ 2 files changed, 32 insertions(+), 28 deletions(-) create mode 100644 x-pack/plugins/discover_enhanced/public/actions/explore_data/kibana_url.ts diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.ts index d66ca129934a88..7e0576e4fca90f 100644 --- a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.ts +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable max-classes-per-file */ - import { i18n } from '@kbn/i18n'; import { Action } from '../../../../../../src/plugins/ui_actions/public'; import { DiscoverStart } from '../../../../../../src/plugins/discover/public'; @@ -20,32 +18,7 @@ import { VisualizeEmbeddableContract, VISUALIZE_EMBEDDABLE_TYPE, } from '../../../../../../src/plugins/visualizations/public'; - -// TODO: Replace this logic with KibanaURL once it is available. -// https://github.com/elastic/kibana/issues/64497 -class KibanaURL { - public readonly path: string; - public readonly appName: string; - public readonly appPath: string; - - constructor(path: string) { - const match = path.match(/^.*\/app\/([^\/#]+)(.+)$/); - - if (!match) { - throw new Error('Unexpected Discover URL path.'); - } - - const [, appName, appPath] = match; - - if (!appName || !appPath) { - throw new Error('Could not parse Discover URL path.'); - } - - this.path = path; - this.appName = appName; - this.appPath = appPath; - } -} +import { KibanaURL } from './kibana_url'; export const ACTION_EXPLORE_DATA = 'ACTION_EXPLORE_DATA'; diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/kibana_url.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/kibana_url.ts new file mode 100644 index 00000000000000..3c25fc2b3c3d15 --- /dev/null +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/kibana_url.ts @@ -0,0 +1,31 @@ +/* + * 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. + */ + +// TODO: Replace this logic with KibanaURL once it is available. +// https://github.com/elastic/kibana/issues/64497 +export class KibanaURL { + public readonly path: string; + public readonly appName: string; + public readonly appPath: string; + + constructor(path: string) { + const match = path.match(/^.*\/app\/([^\/#]+)(.+)$/); + + if (!match) { + throw new Error('Unexpected Discover URL path.'); + } + + const [, appName, appPath] = match; + + if (!appName || !appPath) { + throw new Error('Could not parse Discover URL path.'); + } + + this.path = path; + this.appName = appName; + this.appPath = appPath; + } +} From 795bfbb54c59c9b5c1d9125e8745fd5a10eb1bfc Mon Sep 17 00:00:00 2001 From: streamich Date: Thu, 18 Jun 2020 12:30:52 +0200 Subject: [PATCH 04/25] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20add=20"Explore=20u?= =?UTF-8?q?nderlying=20data"=20in-chart=20action?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../abstract_explore_data_action.ts | 73 ++++++++++++ .../explore_data/explore_data_chart_action.ts | 55 +++++++++ .../explore_data_context_menu_action.test.ts | 11 +- .../explore_data_context_menu_action.ts | 105 ++---------------- .../public/actions/explore_data/index.ts | 1 + .../public/actions/explore_data/shared.ts | 36 ++++++ .../discover_enhanced/public/plugin.ts | 24 +++- 7 files changed, 204 insertions(+), 101 deletions(-) create mode 100644 x-pack/plugins/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts create mode 100644 x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.ts create mode 100644 x-pack/plugins/discover_enhanced/public/actions/explore_data/shared.ts diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts new file mode 100644 index 00000000000000..3c722d214b4ac0 --- /dev/null +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts @@ -0,0 +1,73 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { DiscoverStart } from '../../../../../../src/plugins/discover/public'; +import { ViewMode, IEmbeddable } from '../../../../../../src/plugins/embeddable/public'; +import { StartServicesGetter } from '../../../../../../src/plugins/kibana_utils/public'; +import { CoreStart } from '../../../../../../src/core/public'; +import { VisualizeEmbeddableContract } from '../../../../../../src/plugins/visualizations/public'; +import { KibanaURL } from './kibana_url'; +import * as shared from './shared'; + +export const ACTION_EXPLORE_DATA = 'ACTION_EXPLORE_DATA'; + +interface PluginDeps { + discover: Pick; +} + +interface CoreDeps { + application: Pick; +} + +interface Params { + start: StartServicesGetter; +} + +export abstract class AbstractExploreDataAction { + public readonly getIconType = (context: Context): string => 'discoverApp'; + + public readonly getDisplayName = (context: Context): string => + i18n.translate('xpack.discover.FlyoutCreateDrilldownAction.displayName', { + defaultMessage: 'Explore underlying data', + }); + + constructor(protected readonly params: Params) {} + + protected abstract async getUrl(embeddable: VisualizeEmbeddableContract): Promise; + + public async isCompatible({ embeddable }: Context): Promise { + if (!embeddable) return false; + if (!this.params.start().plugins.discover.urlGenerator) return false; + if (!shared.isVisualizeEmbeddable(embeddable)) return false; + if (!shared.getIndexPattern(embeddable)) return false; + if (embeddable.getInput().viewMode !== ViewMode.VIEW) return false; + return true; + } + + public async execute({ embeddable }: Context): Promise { + if (!shared.isVisualizeEmbeddable(embeddable)) return; + + const { core } = this.params.start(); + const { appName, appPath } = await this.getUrl(embeddable); + + await core.application.navigateToApp(appName, { + path: appPath, + }); + } + + public async getHref(context: Context): Promise { + const { embeddable } = context; + + if (!shared.isVisualizeEmbeddable(embeddable)) { + throw new Error(`Embeddable not supported for "${this.getDisplayName(context)}" action.`); + } + + const { path } = await this.getUrl(embeddable); + + return path; + } +} diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.ts new file mode 100644 index 00000000000000..37c2dfadd078f7 --- /dev/null +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.ts @@ -0,0 +1,55 @@ +/* + * 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 { Action } from '../../../../../../src/plugins/ui_actions/public'; +import { + ValueClickTriggerContext, + RangeSelectTriggerContext, +} from '../../../../../../src/plugins/embeddable/public'; +import { VisualizeEmbeddableContract } from '../../../../../../src/plugins/visualizations/public'; +import { KibanaURL } from './kibana_url'; +import * as shared from './shared'; +import { AbstractExploreDataAction } from './abstract_explore_data_action'; + +export type ExploreDataChartActionContext = ValueClickTriggerContext | RangeSelectTriggerContext; + +export const ACTION_EXPLORE_DATA_CHART = 'ACTION_EXPLORE_DATA_CHART'; + +/** + * This is "Explore underlying data" action which appears in popup context + * menu when user clicks a value in visualization or brushes a time range. + */ +export class ExploreDataChartAction extends AbstractExploreDataAction + implements Action { + public readonly id = ACTION_EXPLORE_DATA_CHART; + + public readonly type = ACTION_EXPLORE_DATA_CHART; + + public readonly order = 200; + + protected readonly getUrl = async ( + embeddable: VisualizeEmbeddableContract + ): Promise => { + const { plugins } = this.params.start(); + const { urlGenerator } = plugins.discover; + + if (!urlGenerator) { + throw new Error('Discover URL generator not available.'); + } + + const { timeRange, query, filters } = embeddable.getInput(); + const indexPatternId = shared.getIndexPattern(embeddable); + + const path = await urlGenerator.createUrl({ + indexPatternId, + filters, + query, + timeRange, + }); + + return new KibanaURL(path); + }; +} diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts index a7167d2e2e6911..8f84ca1133eaa7 100644 --- a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts @@ -83,19 +83,20 @@ const setup = () => { describe('"Explore underlying data" panel action', () => { test('action has Discover icon', () => { - const { action } = setup(); - expect(action.getIconType()).toBe('discoverApp'); + const { action, context } = setup(); + expect(action.getIconType(context)).toBe('discoverApp'); }); test('title is "Explore underlying data"', () => { - const { action } = setup(); - expect(action.getDisplayName()).toBe('Explore underlying data'); + const { action, context } = setup(); + expect(action.getDisplayName(context)).toBe('Explore underlying data'); }); test('translates title', () => { expect(i18nTranslateSpy).toHaveBeenCalledTimes(0); - setup().action.getDisplayName(); + const { action, context } = setup(); + action.getDisplayName(context); expect(i18nTranslateSpy).toHaveBeenCalledTimes(1); expect(i18nTranslateSpy.mock.calls[0][0]).toBe( diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.ts index 7e0576e4fca90f..61555c149127b9 100644 --- a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.ts +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.ts @@ -4,96 +4,28 @@ * you may not use this file except in compliance with the Elastic License. */ -import { i18n } from '@kbn/i18n'; import { Action } from '../../../../../../src/plugins/ui_actions/public'; -import { DiscoverStart } from '../../../../../../src/plugins/discover/public'; -import { - EmbeddableContext, - IEmbeddable, - ViewMode, -} from '../../../../../../src/plugins/embeddable/public'; -import { StartServicesGetter } from '../../../../../../src/plugins/kibana_utils/public'; -import { CoreStart } from '../../../../../../src/core/public'; -import { - VisualizeEmbeddableContract, - VISUALIZE_EMBEDDABLE_TYPE, -} from '../../../../../../src/plugins/visualizations/public'; +import { EmbeddableContext } from '../../../../../../src/plugins/embeddable/public'; +import { VisualizeEmbeddableContract } from '../../../../../../src/plugins/visualizations/public'; import { KibanaURL } from './kibana_url'; +import * as shared from './shared'; +import { AbstractExploreDataAction } from './abstract_explore_data_action'; export const ACTION_EXPLORE_DATA = 'ACTION_EXPLORE_DATA'; -const isOutputWithIndexPatterns = ( - output: unknown -): output is { indexPatterns: Array<{ id: string }> } => { - if (!output || typeof output !== 'object') return false; - return Array.isArray((output as any).indexPatterns); -}; - -const isVisualizeEmbeddable = ( - embeddable: IEmbeddable -): embeddable is VisualizeEmbeddableContract => embeddable?.type === VISUALIZE_EMBEDDABLE_TYPE; - -export interface PluginDeps { - discover: Pick; -} - -export interface CoreDeps { - application: Pick; -} - -export interface Params { - start: StartServicesGetter; -} - -export class ExploreDataContextMenuAction implements Action { +/** + * This is "Explore underlying data" action which appears in the context + * menu of a dashboard panel. + */ +export class ExploreDataContextMenuAction extends AbstractExploreDataAction + implements Action { public readonly id = ACTION_EXPLORE_DATA; public readonly type = ACTION_EXPLORE_DATA; public readonly order = 200; - constructor(private readonly params: Params) {} - - public getDisplayName() { - return i18n.translate('xpack.discover.FlyoutCreateDrilldownAction.displayName', { - defaultMessage: 'Explore underlying data', - }); - } - - public getIconType() { - return 'discoverApp'; - } - - public async isCompatible({ embeddable }: EmbeddableContext) { - if (!this.params.start().plugins.discover.urlGenerator) return false; - if (!isVisualizeEmbeddable(embeddable)) return false; - if (!this.getIndexPattern(embeddable)) return false; - if (embeddable.getInput().viewMode !== ViewMode.VIEW) return false; - return true; - } - - public async execute({ embeddable }: EmbeddableContext) { - if (!isVisualizeEmbeddable(embeddable)) return; - - const { core } = this.params.start(); - const { appName, appPath } = await this.getUrl(embeddable); - - await core.application.navigateToApp(appName, { - path: appPath, - }); - } - - public async getHref({ embeddable }: EmbeddableContext): Promise { - if (!isVisualizeEmbeddable(embeddable)) { - throw new Error(`Embeddable not supported for "${this.getDisplayName()}" action.`); - } - - const { path } = await this.getUrl(embeddable); - - return path; - } - - private async getUrl(embeddable: VisualizeEmbeddableContract): Promise { + protected async getUrl(embeddable: VisualizeEmbeddableContract): Promise { const { plugins } = this.params.start(); const { urlGenerator } = plugins.discover; @@ -102,7 +34,7 @@ export class ExploreDataContextMenuAction implements Action { } const { timeRange, query, filters } = embeddable.getInput(); - const indexPatternId = this.getIndexPattern(embeddable); + const indexPatternId = shared.getIndexPattern(embeddable); const path = await urlGenerator.createUrl({ indexPatternId, @@ -113,17 +45,4 @@ export class ExploreDataContextMenuAction implements Action { return new KibanaURL(path); } - - /** - * @returns Returns empty string if no index pattern ID found. - */ - private getIndexPattern(embeddable: VisualizeEmbeddableContract): string { - const output = embeddable!.getOutput(); - - if (isOutputWithIndexPatterns(output) && output.indexPatterns.length > 0) { - return output.indexPatterns[0].id; - } - - return ''; - } } diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/index.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/index.ts index 8788621365385a..e6d7d4b59149e3 100644 --- a/x-pack/plugins/discover_enhanced/public/actions/explore_data/index.ts +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/index.ts @@ -5,3 +5,4 @@ */ export * from './explore_data_context_menu_action'; +export * from './explore_data_chart_action'; diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/shared.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/shared.ts new file mode 100644 index 00000000000000..80ec2b11757862 --- /dev/null +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/shared.ts @@ -0,0 +1,36 @@ +/* + * 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 { + VISUALIZE_EMBEDDABLE_TYPE, + VisualizeEmbeddableContract, +} from '../../../../../../src/plugins/visualizations/public'; + +export const isOutputWithIndexPatterns = ( + output: unknown +): output is { indexPatterns: Array<{ id: string }> } => { + if (!output || typeof output !== 'object') return false; + return Array.isArray((output as any).indexPatterns); +}; + +export const isVisualizeEmbeddable = ( + embeddable?: IEmbeddable +): embeddable is VisualizeEmbeddableContract => + embeddable && embeddable?.type === VISUALIZE_EMBEDDABLE_TYPE ? true : false; + +/** + * @returns Returns empty string if no index pattern ID found. + */ +export const getIndexPattern = (embeddable: VisualizeEmbeddableContract): string => { + const output = embeddable!.getOutput(); + + if (isOutputWithIndexPatterns(output) && output.indexPatterns.length > 0) { + return output.indexPatterns[0].id; + } + + return ''; +}; diff --git a/x-pack/plugins/discover_enhanced/public/plugin.ts b/x-pack/plugins/discover_enhanced/public/plugin.ts index e68c16042cf32b..ea3c1222eb369d 100644 --- a/x-pack/plugins/discover_enhanced/public/plugin.ts +++ b/x-pack/plugins/discover_enhanced/public/plugin.ts @@ -6,7 +6,12 @@ import { CoreSetup, CoreStart, Plugin } from 'kibana/public'; import { PluginInitializerContext } from 'kibana/public'; -import { UiActionsSetup, UiActionsStart } from '../../../../src/plugins/ui_actions/public'; +import { + UiActionsSetup, + UiActionsStart, + SELECT_RANGE_TRIGGER, + VALUE_CLICK_TRIGGER, +} from '../../../../src/plugins/ui_actions/public'; import { createStartServicesGetter } from '../../../../src/plugins/kibana_utils/public'; import { DiscoverSetup, DiscoverStart } from '../../../../src/plugins/discover/public'; import { SharePluginSetup, SharePluginStart } from '../../../../src/plugins/share/public'; @@ -16,11 +21,18 @@ import { EmbeddableContext, CONTEXT_MENU_TRIGGER, } from '../../../../src/plugins/embeddable/public'; -import { ExploreDataContextMenuAction, ACTION_EXPLORE_DATA } from './actions'; +import { + ExploreDataContextMenuAction, + ExploreDataChartAction, + ACTION_EXPLORE_DATA, + ACTION_EXPLORE_DATA_CHART, + ExploreDataChartActionContext, +} from './actions'; declare module '../../../../src/plugins/ui_actions/public' { export interface ActionContextMapping { [ACTION_EXPLORE_DATA]: EmbeddableContext; + [ACTION_EXPLORE_DATA_CHART]: ExploreDataChartActionContext; } } @@ -51,8 +63,14 @@ export class DiscoverEnhancedPlugin const isSharePluginInstalled = !!share; if (isSharePluginInstalled) { - const exploreDataAction = new ExploreDataContextMenuAction({ start }); + const params = { start }; + + const exploreDataAction = new ExploreDataContextMenuAction(params); uiActions.addTriggerAction(CONTEXT_MENU_TRIGGER, exploreDataAction); + + const exploreDataChartAction = new ExploreDataChartAction(params); + uiActions.addTriggerAction(SELECT_RANGE_TRIGGER, exploreDataChartAction); + uiActions.addTriggerAction(VALUE_CLICK_TRIGGER, exploreDataChartAction); } } From 64ce4c4564d2cea36a44237f1aba97285c15876c Mon Sep 17 00:00:00 2001 From: streamich Date: Thu, 18 Jun 2020 12:33:55 +0200 Subject: [PATCH 05/25] =?UTF-8?q?fix:=20=F0=9F=90=9B=20fix=20imports=20aft?= =?UTF-8?q?er=20refactor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../actions/explore_data/abstract_explore_data_action.ts | 6 +++--- .../explore_data/explore_data_context_menu_action.test.ts | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts index 3c722d214b4ac0..60f20cf9ce9160 100644 --- a/x-pack/plugins/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts @@ -15,15 +15,15 @@ import * as shared from './shared'; export const ACTION_EXPLORE_DATA = 'ACTION_EXPLORE_DATA'; -interface PluginDeps { +export interface PluginDeps { discover: Pick; } -interface CoreDeps { +export interface CoreDeps { application: Pick; } -interface Params { +export interface Params { start: StartServicesGetter; } diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts index 8f84ca1133eaa7..1d606fce647468 100644 --- a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts @@ -7,9 +7,8 @@ import { ExploreDataContextMenuAction, ACTION_EXPLORE_DATA, - Params, - PluginDeps, } from './explore_data_context_menu_action'; +import { Params, PluginDeps } from './abstract_explore_data_action'; import { coreMock } from '../../../../../../src/core/public/mocks'; import { UrlGeneratorContract } from '../../../../../../src/plugins/share/public'; import { i18n } from '@kbn/i18n'; From 55992da7b97b02d875cc72287211ea4a9dc8b75d Mon Sep 17 00:00:00 2001 From: streamich Date: Thu, 18 Jun 2020 13:47:56 +0200 Subject: [PATCH 06/25] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20add=20start.filter?= =?UTF-8?q?sFromContext=20to=20embeddable=20plugin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/embeddable/kibana.json | 1 + src/plugins/embeddable/public/index.ts | 1 + .../public/lib/triggers/triggers.ts | 14 +++++++---- src/plugins/embeddable/public/plugin.tsx | 24 ++++++++++++++++++- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/plugins/embeddable/kibana.json b/src/plugins/embeddable/kibana.json index 06b0e88da334fa..332237d19e2187 100644 --- a/src/plugins/embeddable/kibana.json +++ b/src/plugins/embeddable/kibana.json @@ -4,6 +4,7 @@ "server": false, "ui": true, "requiredPlugins": [ + "data", "inspector", "uiActions" ], diff --git a/src/plugins/embeddable/public/index.ts b/src/plugins/embeddable/public/index.ts index d595197373a21d..24e75f2614100d 100644 --- a/src/plugins/embeddable/public/index.ts +++ b/src/plugins/embeddable/public/index.ts @@ -29,6 +29,7 @@ export { ACTION_EDIT_PANEL, Adapters, AddPanelAction, + ChartActionContext, Container, ContainerInput, ContainerOutput, diff --git a/src/plugins/embeddable/public/lib/triggers/triggers.ts b/src/plugins/embeddable/public/lib/triggers/triggers.ts index 2b447c89e28501..5bb96a708b7ac1 100644 --- a/src/plugins/embeddable/public/lib/triggers/triggers.ts +++ b/src/plugins/embeddable/public/lib/triggers/triggers.ts @@ -39,10 +39,6 @@ export interface ValueClickTriggerContext { }; } -export const isValueClickTriggerContext = ( - context: ValueClickTriggerContext | RangeSelectTriggerContext -): context is ValueClickTriggerContext => context.data && 'data' in context.data; - export interface RangeSelectTriggerContext { embeddable?: T; data: { @@ -53,8 +49,16 @@ export interface RangeSelectTriggerContext }; } +export type ChartActionContext = + | ValueClickTriggerContext + | RangeSelectTriggerContext; + +export const isValueClickTriggerContext = ( + context: ChartActionContext +): context is ValueClickTriggerContext => context.data && 'data' in context.data; + export const isRangeSelectTriggerContext = ( - context: ValueClickTriggerContext | RangeSelectTriggerContext + context: ChartActionContext ): context is RangeSelectTriggerContext => context.data && 'range' in context.data; export const CONTEXT_MENU_TRIGGER = 'CONTEXT_MENU_TRIGGER'; diff --git a/src/plugins/embeddable/public/plugin.tsx b/src/plugins/embeddable/public/plugin.tsx index 269b1ffed829b1..958eacf3c844ee 100644 --- a/src/plugins/embeddable/public/plugin.tsx +++ b/src/plugins/embeddable/public/plugin.tsx @@ -17,6 +17,7 @@ * under the License. */ import React from 'react'; +import { DataPublicPluginSetup, DataPublicPluginStart, Filter } from '../../data/public'; import { getSavedObjectFinder } from '../../saved_objects/public'; import { UiActionsSetup, UiActionsStart } from '../../ui_actions/public'; import { Start as InspectorStart } from '../../inspector/public'; @@ -30,14 +31,19 @@ import { defaultEmbeddableFactoryProvider, IEmbeddable, EmbeddablePanel, + ChartActionContext, + isRangeSelectTriggerContext, + isValueClickTriggerContext, } from './lib'; import { EmbeddableFactoryDefinition } from './lib/embeddables/embeddable_factory_definition'; export interface EmbeddableSetupDependencies { + data: DataPublicPluginSetup; uiActions: UiActionsSetup; } export interface EmbeddableStartDependencies { + data: DataPublicPluginStart; uiActions: UiActionsStart; inspector: InspectorStart; } @@ -64,6 +70,7 @@ export interface EmbeddableStart { ) => EmbeddableFactory | undefined; getEmbeddableFactories: () => IterableIterator; EmbeddablePanel: React.FC<{ embeddable: IEmbeddable; hideHeader?: boolean }>; + filtersFromContext: (context: ChartActionContext) => Promise; } export class EmbeddablePublicPlugin implements Plugin { @@ -95,7 +102,7 @@ export class EmbeddablePublicPlugin implements Plugin { this.embeddableFactories.set( @@ -130,6 +137,21 @@ export class EmbeddablePublicPlugin implements Plugin ), + + filtersFromContext: async (context) => { + try { + if (isRangeSelectTriggerContext(context)) + return await data.actions.createFiltersFromRangeSelectAction(context.data); + if (isValueClickTriggerContext(context)) + return await data.actions.createFiltersFromValueClickAction(context.data); + // eslint-disable-next-line no-console + console.warn("Can't extract filters from action.", context); + } catch (error) { + // eslint-disable-next-line no-console + console.warn('Error extracting filters from action. Returning empty filter list.', error); + } + return []; + }, }; } From a730c55fdaff9e13529949171686d76525252f81 Mon Sep 17 00:00:00 2001 From: streamich Date: Thu, 18 Jun 2020 15:09:19 +0200 Subject: [PATCH 07/25] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20add=20type=20check?= =?UTF-8?q?ers=20to=20data=20plugin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/es_query/filters/meta_filter.ts | 10 +++++++ src/plugins/data/common/index.ts | 3 ++- src/plugins/data/common/query/index.ts | 1 + src/plugins/data/common/query/is_query.ts | 27 +++++++++++++++++++ src/plugins/data/common/timefilter/index.ts | 20 ++++++++++++++ .../data/common/timefilter/is_time_range.ts | 26 ++++++++++++++++++ src/plugins/data/public/index.ts | 2 ++ 7 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 src/plugins/data/common/query/is_query.ts create mode 100644 src/plugins/data/common/timefilter/index.ts create mode 100644 src/plugins/data/common/timefilter/is_time_range.ts diff --git a/src/plugins/data/common/es_query/filters/meta_filter.ts b/src/plugins/data/common/es_query/filters/meta_filter.ts index ff6dff9d8b7490..e3099ae6a40264 100644 --- a/src/plugins/data/common/es_query/filters/meta_filter.ts +++ b/src/plugins/data/common/es_query/filters/meta_filter.ts @@ -107,3 +107,13 @@ export const pinFilter = (filter: Filter) => export const unpinFilter = (filter: Filter) => !isFilterPinned(filter) ? filter : toggleFilterPinned(filter); + +export const isFilter = (x: unknown): x is Filter => + !!x && + typeof x === 'object' && + !!(x as Filter).meta && + typeof (x as Filter).meta === 'object' && + typeof (x as Filter).meta.disabled === 'boolean'; + +export const isFilters = (x: unknown): x is Filter[] => + Array.isArray(x) && !x.find((y) => !isFilter(y)); diff --git a/src/plugins/data/common/index.ts b/src/plugins/data/common/index.ts index adbd93d518fc7d..b40e02b709d301 100644 --- a/src/plugins/data/common/index.ts +++ b/src/plugins/data/common/index.ts @@ -20,11 +20,12 @@ export * from './constants'; export * from './es_query'; export * from './field_formats'; +export * from './field_mapping'; export * from './index_patterns'; export * from './kbn_field_types'; export * from './query'; export * from './search'; export * from './search/aggs'; +export * from './timefilter'; export * from './types'; export * from './utils'; -export * from './field_mapping'; diff --git a/src/plugins/data/common/query/index.ts b/src/plugins/data/common/query/index.ts index 421cc4f63e4efb..4e90f6f8bb83ec 100644 --- a/src/plugins/data/common/query/index.ts +++ b/src/plugins/data/common/query/index.ts @@ -19,3 +19,4 @@ export * from './filter_manager'; export * from './types'; +export * from './is_query'; diff --git a/src/plugins/data/common/query/is_query.ts b/src/plugins/data/common/query/is_query.ts new file mode 100644 index 00000000000000..08a99a39b1ac19 --- /dev/null +++ b/src/plugins/data/common/query/is_query.ts @@ -0,0 +1,27 @@ +/* + * 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 { Query } from './types'; + +export const isQuery = (x: unknown): x is Query => + !!x && + typeof x === 'object' && + typeof (x as Query).language === 'string' && + (typeof (x as Query).query === 'string' || + (typeof (x as Query).query === 'object' && !!(x as Query).query)); diff --git a/src/plugins/data/common/timefilter/index.ts b/src/plugins/data/common/timefilter/index.ts new file mode 100644 index 00000000000000..e0c509e119fda1 --- /dev/null +++ b/src/plugins/data/common/timefilter/index.ts @@ -0,0 +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. + */ + +export { isTimeRange } from './is_time_range'; diff --git a/src/plugins/data/common/timefilter/is_time_range.ts b/src/plugins/data/common/timefilter/is_time_range.ts new file mode 100644 index 00000000000000..f206cd04dde316 --- /dev/null +++ b/src/plugins/data/common/timefilter/is_time_range.ts @@ -0,0 +1,26 @@ +/* + * 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 { TimeRange } from './types'; + +export const isTimeRange = (x: unknown): x is TimeRange => + !!x && + typeof x === 'object' && + typeof (x as TimeRange).from === 'string' && + typeof (x as TimeRange).to === 'string'; diff --git a/src/plugins/data/public/index.ts b/src/plugins/data/public/index.ts index 1554ac71f8c552..0762fea7847375 100644 --- a/src/plugins/data/public/index.ts +++ b/src/plugins/data/public/index.ts @@ -443,6 +443,8 @@ export { getKbnTypeNames, } from '../common'; +export { isTimeRange, isQuery, isFilter, isFilters } from '../common'; + export * from '../common/field_mapping'; /* From 00a7aa3c2f414e8b169690695f0a887d257bd0ba Mon Sep 17 00:00:00 2001 From: streamich Date: Thu, 18 Jun 2020 15:11:10 +0200 Subject: [PATCH 08/25] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20better=20handle=20?= =?UTF-8?q?empty=20filters=20in=20Discover=20URL=20generator?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/discover/public/index.ts | 2 +- src/plugins/discover/public/url_generator.ts | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/plugins/discover/public/index.ts b/src/plugins/discover/public/index.ts index 4154fdfeb3ff48..6ac8f674b61531 100644 --- a/src/plugins/discover/public/index.ts +++ b/src/plugins/discover/public/index.ts @@ -27,4 +27,4 @@ export function plugin(initializerContext: PluginInitializerContext) { export { SavedSearch, SavedSearchLoader, createSavedSearchesLoader } from './saved_searches'; export { ISearchEmbeddable, SEARCH_EMBEDDABLE_TYPE, SearchInput } from './application/embeddable'; -export { DISCOVER_APP_URL_GENERATOR } from './url_generator'; +export { DISCOVER_APP_URL_GENERATOR, DiscoverUrlGeneratorState } from './url_generator'; diff --git a/src/plugins/discover/public/url_generator.ts b/src/plugins/discover/public/url_generator.ts index 42d689050d5ad4..c7f2e2147e819c 100644 --- a/src/plugins/discover/public/url_generator.ts +++ b/src/plugins/discover/public/url_generator.ts @@ -98,11 +98,13 @@ export class DiscoverUrlGenerator const queryState: QueryState = {}; if (query) appState.query = query; - if (filters) appState.filters = filters?.filter((f) => !esFilters.isFilterPinned(f)); + if (filters && filters.length) + appState.filters = filters?.filter((f) => !esFilters.isFilterPinned(f)); if (indexPatternId) appState.index = indexPatternId; if (timeRange) queryState.time = timeRange; - if (filters) queryState.filters = filters?.filter((f) => esFilters.isFilterPinned(f)); + if (filters && filters.length) + queryState.filters = filters?.filter((f) => esFilters.isFilterPinned(f)); if (refreshInterval) queryState.refreshInterval = refreshInterval; let url = `${this.params.appBasePath}#/${savedSearchPath}`; From 088feb14ab1a8cacaaa6badff0607601d6c757c8 Mon Sep 17 00:00:00 2001 From: streamich Date: Thu, 18 Jun 2020 15:13:01 +0200 Subject: [PATCH 09/25] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20implement=20.getUr?= =?UTF-8?q?l()=20method=20of=20explore=20data=20in-chart=20act?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../abstract_explore_data_action.ts | 13 +++++---- .../explore_data/explore_data_chart_action.ts | 28 +++++++++++++------ .../public/actions/explore_data/shared.ts | 5 ++-- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts index 60f20cf9ce9160..620cabe6527784 100644 --- a/x-pack/plugins/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts @@ -6,10 +6,10 @@ import { i18n } from '@kbn/i18n'; import { DiscoverStart } from '../../../../../../src/plugins/discover/public'; +import { EmbeddableStart } from '../../../../../../src/plugins/embeddable/public'; import { ViewMode, IEmbeddable } from '../../../../../../src/plugins/embeddable/public'; import { StartServicesGetter } from '../../../../../../src/plugins/kibana_utils/public'; import { CoreStart } from '../../../../../../src/core/public'; -import { VisualizeEmbeddableContract } from '../../../../../../src/plugins/visualizations/public'; import { KibanaURL } from './kibana_url'; import * as shared from './shared'; @@ -17,6 +17,7 @@ export const ACTION_EXPLORE_DATA = 'ACTION_EXPLORE_DATA'; export interface PluginDeps { discover: Pick; + embeddable: Pick; } export interface CoreDeps { @@ -37,7 +38,7 @@ export abstract class AbstractExploreDataAction; + protected abstract async getUrl(context: Context): Promise; public async isCompatible({ embeddable }: Context): Promise { if (!embeddable) return false; @@ -48,11 +49,11 @@ export abstract class AbstractExploreDataAction { - if (!shared.isVisualizeEmbeddable(embeddable)) return; + public async execute(context: Context): Promise { + if (!shared.isVisualizeEmbeddable(context.embeddable)) return; const { core } = this.params.start(); - const { appName, appPath } = await this.getUrl(embeddable); + const { appName, appPath } = await this.getUrl(context); await core.application.navigateToApp(appName, { path: appPath, @@ -66,7 +67,7 @@ export abstract class AbstractExploreDataAction => { const { plugins } = this.params.start(); const { urlGenerator } = plugins.discover; @@ -40,15 +41,24 @@ export class ExploreDataChartAction extends AbstractExploreDataAction { - const output = embeddable!.getOutput(); +export const getIndexPattern = (embeddable?: IEmbeddable): string => { + if (!embeddable) return ''; + const output = embeddable.getOutput(); if (isOutputWithIndexPatterns(output) && output.indexPatterns.length > 0) { return output.indexPatterns[0].id; From 302702f6a745698267adfa636dc72fe11fa0e14e Mon Sep 17 00:00:00 2001 From: streamich Date: Thu, 18 Jun 2020 15:15:28 +0200 Subject: [PATCH 10/25] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20add=20embeddable.f?= =?UTF-8?q?iltersAndTimeRangeFromContext()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/embeddable/public/plugin.tsx | 71 ++++++++++++++++++------ 1 file changed, 55 insertions(+), 16 deletions(-) diff --git a/src/plugins/embeddable/public/plugin.tsx b/src/plugins/embeddable/public/plugin.tsx index 958eacf3c844ee..fcf52c0f564602 100644 --- a/src/plugins/embeddable/public/plugin.tsx +++ b/src/plugins/embeddable/public/plugin.tsx @@ -17,7 +17,13 @@ * under the License. */ import React from 'react'; -import { DataPublicPluginSetup, DataPublicPluginStart, Filter } from '../../data/public'; +import { + DataPublicPluginSetup, + DataPublicPluginStart, + Filter, + TimeRange, + esFilters, +} from '../../data/public'; import { getSavedObjectFinder } from '../../saved_objects/public'; import { UiActionsSetup, UiActionsStart } from '../../ui_actions/public'; import { Start as InspectorStart } from '../../inspector/public'; @@ -70,7 +76,18 @@ export interface EmbeddableStart { ) => EmbeddableFactory | undefined; getEmbeddableFactories: () => IterableIterator; EmbeddablePanel: React.FC<{ embeddable: IEmbeddable; hideHeader?: boolean }>; + + /** + * Given {@link ChartActionContext} returns a list of `data` plugin {@link Filter} entries. + */ filtersFromContext: (context: ChartActionContext) => Promise; + + /** + * Returns possible time range and filters that can be constructed from {@link ChartActionContext} object. + */ + filtersAndTimeRangeFromContext: ( + context: ChartActionContext + ) => Promise<{ filters: Filter[]; timeRange?: TimeRange }>; } export class EmbeddablePublicPlugin implements Plugin { @@ -114,6 +131,41 @@ export class EmbeddablePublicPlugin implements Plugin { + try { + if (isRangeSelectTriggerContext(context)) + return await data.actions.createFiltersFromRangeSelectAction(context.data); + if (isValueClickTriggerContext(context)) + return await data.actions.createFiltersFromValueClickAction(context.data); + // eslint-disable-next-line no-console + console.warn("Can't extract filters from action.", context); + } catch (error) { + // eslint-disable-next-line no-console + console.warn('Error extracting filters from action. Returning empty filter list.', error); + } + return []; + }; + + const filtersAndTimeRangeFromContext: EmbeddableStart['filtersAndTimeRangeFromContext'] = async ( + context + ) => { + const filters = await filtersFromContext(context); + + if (!context.data.timeFieldName) return { filters }; + + const { timeRangeFilter, restOfFilters } = esFilters.extractTimeFilter( + context.data.timeFieldName, + filters + ); + + return { + filters: restOfFilters, + timeRange: timeRangeFilter + ? esFilters.convertRangeFilterToTimeRangeString(timeRangeFilter) + : undefined, + }; + }; + return { getEmbeddableFactory: this.getEmbeddableFactory, getEmbeddableFactories: this.getEmbeddableFactories, @@ -137,21 +189,8 @@ export class EmbeddablePublicPlugin implements Plugin ), - - filtersFromContext: async (context) => { - try { - if (isRangeSelectTriggerContext(context)) - return await data.actions.createFiltersFromRangeSelectAction(context.data); - if (isValueClickTriggerContext(context)) - return await data.actions.createFiltersFromValueClickAction(context.data); - // eslint-disable-next-line no-console - console.warn("Can't extract filters from action.", context); - } catch (error) { - // eslint-disable-next-line no-console - console.warn('Error extracting filters from action. Returning empty filter list.', error); - } - return []; - }, + filtersFromContext, + filtersAndTimeRangeFromContext, }; } From 5217996f6cc6be2623f676925700e443c219145f Mon Sep 17 00:00:00 2001 From: streamich Date: Thu, 18 Jun 2020 15:17:10 +0200 Subject: [PATCH 11/25] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20improve=20getUrl()?= =?UTF-8?q?=20method=20of=20explore=20data=20action?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../explore_data_context_menu_action.ts | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.ts index 61555c149127b9..6691089f875d86 100644 --- a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.ts +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.ts @@ -6,7 +6,8 @@ import { Action } from '../../../../../../src/plugins/ui_actions/public'; import { EmbeddableContext } from '../../../../../../src/plugins/embeddable/public'; -import { VisualizeEmbeddableContract } from '../../../../../../src/plugins/visualizations/public'; +import { DiscoverUrlGeneratorState } from '../../../../../../src/plugins/discover/public'; +import { isTimeRange, isQuery, isFilters } from '../../../../../../src/plugins/data/public'; import { KibanaURL } from './kibana_url'; import * as shared from './shared'; import { AbstractExploreDataAction } from './abstract_explore_data_action'; @@ -25,7 +26,7 @@ export class ExploreDataContextMenuAction extends AbstractExploreDataAction { + protected readonly getUrl = async (context: EmbeddableContext): Promise => { const { plugins } = this.params.start(); const { urlGenerator } = plugins.discover; @@ -33,16 +34,21 @@ export class ExploreDataContextMenuAction extends AbstractExploreDataAction Date: Thu, 18 Jun 2020 15:20:26 +0200 Subject: [PATCH 12/25] =?UTF-8?q?test:=20=F0=9F=92=8D=20update=20test=20mo?= =?UTF-8?q?ck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../explore_data/explore_data_context_menu_action.test.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts index 1d606fce647468..e945802a6c95ef 100644 --- a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts @@ -11,6 +11,7 @@ import { import { Params, PluginDeps } from './abstract_explore_data_action'; import { coreMock } from '../../../../../../src/core/public/mocks'; import { UrlGeneratorContract } from '../../../../../../src/plugins/share/public'; +import { EmbeddableStart } from '../../../../../../src/plugins/embeddable/public'; import { i18n } from '@kbn/i18n'; import { VisualizeEmbeddableContract, @@ -40,10 +41,17 @@ const setup = () => { createUrl: jest.fn(() => Promise.resolve('/xyz/app/discover/foo#bar')), } as unknown) as UrlGenerator; + const filtersAndTimeRangeFromContext = jest.fn((async () => ({ + filters: [], + })) as EmbeddableStart['filtersAndTimeRangeFromContext']); + const plugins: PluginDeps = { discover: { urlGenerator, }, + embeddable: { + filtersAndTimeRangeFromContext, + }, }; const params: Params = { From 9b5739a886488f3c07c8bafb3456d3d250315250 Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Wed, 24 Jun 2020 17:53:02 +0200 Subject: [PATCH 13/25] fix possible stale hashHistory.location in discover --- src/plugins/discover/public/kibana_services.ts | 16 +++++++++++++++- src/plugins/discover/public/plugin.ts | 2 ++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/plugins/discover/public/kibana_services.ts b/src/plugins/discover/public/kibana_services.ts index bbd0357f41ed4e..b8d3129878970e 100644 --- a/src/plugins/discover/public/kibana_services.ts +++ b/src/plugins/discover/public/kibana_services.ts @@ -59,10 +59,24 @@ export const [getDocViewsRegistry, setDocViewsRegistry] = createGetterSetter createHashHistory()); +/** + * Discover & context are using same hash history instance, + * When getting back to discover internal history.location could get out of sync with window.location + * This helper function syncs window.location state to internal hash history + * + * Using this on discover mount also workarounds possible issues with async hash event: https://github.com/elastic/kibana/pull/65163 + * This helper is temp until: https://github.com/elastic/kibana/issues/65161 resolved + */ +export const ensureHashHistoryLocation = () => { + const h = getHistory(); + Object.assign(h.location, createHashHistory().location); + return h; +}; + export const [getScopedHistory, setScopedHistory] = createGetterSetter( 'scopedHistory' ); diff --git a/src/plugins/discover/public/plugin.ts b/src/plugins/discover/public/plugin.ts index 091288e3e65aa4..5416462147b31e 100644 --- a/src/plugins/discover/public/plugin.ts +++ b/src/plugins/discover/public/plugin.ts @@ -55,6 +55,7 @@ import { setServices, setScopedHistory, getScopedHistory, + ensureHashHistoryLocation, } from './kibana_services'; import { createSavedSearchesLoader } from './saved_searches'; import { registerFeature } from './register_feature'; @@ -242,6 +243,7 @@ export class DiscoverPlugin throw Error('Discover plugin method initializeInnerAngular is undefined'); } setScopedHistory(params.history); + ensureHashHistoryLocation(); appMounted(); const { plugins: { data: dataStart }, From eb6145227c9a1ca75275e9174bcd6dc294def3e4 Mon Sep 17 00:00:00 2001 From: streamich Date: Thu, 25 Jun 2020 11:33:30 +0200 Subject: [PATCH 14/25] =?UTF-8?q?style:=20=F0=9F=92=84=20ensureHashHistory?= =?UTF-8?q?Location=20->=20syncHistoryLocations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/discover/public/kibana_services.ts | 11 +++++------ src/plugins/discover/public/plugin.ts | 4 ++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/plugins/discover/public/kibana_services.ts b/src/plugins/discover/public/kibana_services.ts index 993e9b81a97f62..2c6bbcc3ecce12 100644 --- a/src/plugins/discover/public/kibana_services.ts +++ b/src/plugins/discover/public/kibana_services.ts @@ -65,14 +65,13 @@ export const [getDocViewsRegistry, setDocViewsRegistry] = createGetterSetter createHashHistory()); /** - * Discover & context are using same hash history instance, - * When getting back to discover internal history.location could get out of sync with window.location - * This helper function syncs window.location state to internal hash history + * Discover currently uses two `history` instances: one from Kibana Platform and + * another from `history` package. Below function is used every time Discover + * app is loaded to synchronize both instances. * - * Using this on discover mount also workarounds possible issues with async hash event: https://github.com/elastic/kibana/pull/65163 - * This helper is temp until: https://github.com/elastic/kibana/issues/65161 resolved + * This helper is temporary until https://github.com/elastic/kibana/issues/65161 is resolved. */ -export const ensureHashHistoryLocation = () => { +export const syncHistoryLocations = () => { const h = getHistory(); Object.assign(h.location, createHashHistory().location); return h; diff --git a/src/plugins/discover/public/plugin.ts b/src/plugins/discover/public/plugin.ts index 16694dd030d8df..e97ac783c616f0 100644 --- a/src/plugins/discover/public/plugin.ts +++ b/src/plugins/discover/public/plugin.ts @@ -55,7 +55,7 @@ import { setServices, setScopedHistory, getScopedHistory, - ensureHashHistoryLocation, + syncHistoryLocations, getServices, } from './kibana_services'; import { createSavedSearchesLoader } from './saved_searches'; @@ -246,7 +246,7 @@ export class DiscoverPlugin throw Error('Discover plugin method initializeInnerAngular is undefined'); } setScopedHistory(params.history); - ensureHashHistoryLocation(); + syncHistoryLocations(); appMounted(); const { plugins: { data: dataStart }, From 406e02d3628c734e409a1c6e99008d806a0abb91 Mon Sep 17 00:00:00 2001 From: streamich Date: Thu, 25 Jun 2020 12:14:43 +0200 Subject: [PATCH 15/25] =?UTF-8?q?docs:=20=E2=9C=8F=EF=B8=8F=20update=20aut?= =?UTF-8?q?ogenerated=20docs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ana-plugin-plugins-data-public.isfilter.md | 11 ++++++++++ ...na-plugin-plugins-data-public.isfilters.md | 11 ++++++++++ ...bana-plugin-plugins-data-public.isquery.md | 11 ++++++++++ ...-plugin-plugins-data-public.istimerange.md | 11 ++++++++++ .../kibana-plugin-plugins-data-public.md | 4 ++++ src/plugins/data/public/public.api.md | 20 +++++++++++++++++++ 6 files changed, 68 insertions(+) create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isfilter.md create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isfilters.md create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isquery.md create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.istimerange.md diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isfilter.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isfilter.md new file mode 100644 index 00000000000000..f1916e89c2c98e --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isfilter.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [isFilter](./kibana-plugin-plugins-data-public.isfilter.md) + +## isFilter variable + +Signature: + +```typescript +isFilter: (x: unknown) => x is Filter +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isfilters.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isfilters.md new file mode 100644 index 00000000000000..558da72cc26bb4 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isfilters.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [isFilters](./kibana-plugin-plugins-data-public.isfilters.md) + +## isFilters variable + +Signature: + +```typescript +isFilters: (x: unknown) => x is Filter[] +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isquery.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isquery.md new file mode 100644 index 00000000000000..0884566333aa87 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isquery.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [isQuery](./kibana-plugin-plugins-data-public.isquery.md) + +## isQuery variable + +Signature: + +```typescript +isQuery: (x: unknown) => x is Query +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.istimerange.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.istimerange.md new file mode 100644 index 00000000000000..e9420493c82fba --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.istimerange.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [isTimeRange](./kibana-plugin-plugins-data-public.istimerange.md) + +## isTimeRange variable + +Signature: + +```typescript +isTimeRange: (x: unknown) => x is TimeRange +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md index f62479f02926e5..feeb686a1f5ede 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md @@ -110,6 +110,10 @@ | [getKbnTypeNames](./kibana-plugin-plugins-data-public.getkbntypenames.md) | Get the esTypes known by all kbnFieldTypes {Array} | | [indexPatterns](./kibana-plugin-plugins-data-public.indexpatterns.md) | | | [injectSearchSourceReferences](./kibana-plugin-plugins-data-public.injectsearchsourcereferences.md) | | +| [isFilter](./kibana-plugin-plugins-data-public.isfilter.md) | | +| [isFilters](./kibana-plugin-plugins-data-public.isfilters.md) | | +| [isQuery](./kibana-plugin-plugins-data-public.isquery.md) | | +| [isTimeRange](./kibana-plugin-plugins-data-public.istimerange.md) | | | [parseSearchSourceJSON](./kibana-plugin-plugins-data-public.parsesearchsourcejson.md) | | | [QueryStringInput](./kibana-plugin-plugins-data-public.querystringinput.md) | | | [search](./kibana-plugin-plugins-data-public.search.md) | | diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index 31dc5b51a06f56..45781035dad6df 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -1278,6 +1278,26 @@ export interface ISearchStrategy { search: ISearch; } +// Warning: (ae-missing-release-tag) "isFilter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const isFilter: (x: unknown) => x is Filter; + +// Warning: (ae-missing-release-tag) "isFilters" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const isFilters: (x: unknown) => x is Filter[]; + +// Warning: (ae-missing-release-tag) "isQuery" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const isQuery: (x: unknown) => x is Query; + +// Warning: (ae-missing-release-tag) "isTimeRange" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const isTimeRange: (x: unknown) => x is TimeRange; + // Warning: (ae-missing-release-tag) "ISyncSearchRequest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) From 599382ba329580ab62385bdb94e8e03f07ec15f6 Mon Sep 17 00:00:00 2001 From: streamich Date: Thu, 25 Jun 2020 12:15:38 +0200 Subject: [PATCH 16/25] =?UTF-8?q?test:=20=F0=9F=92=8D=20add=20in-chart=20"?= =?UTF-8?q?Explore=20underlying=20data"=20unit=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../explore_data_chart_action.test.ts | 274 ++++++++++++++++++ .../explore_data_context_menu_action.test.ts | 6 +- 2 files changed, 275 insertions(+), 5 deletions(-) create mode 100644 x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.test.ts diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.test.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.test.ts new file mode 100644 index 00000000000000..a273f0d50e45e8 --- /dev/null +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.test.ts @@ -0,0 +1,274 @@ +/* + * 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 { ExploreDataChartAction } from './explore_data_chart_action'; +import { Params, PluginDeps } from './abstract_explore_data_action'; +import { coreMock } from '../../../../../../src/core/public/mocks'; +import { UrlGeneratorContract } from '../../../../../../src/plugins/share/public'; +import { + EmbeddableStart, + RangeSelectTriggerContext, + ValueClickTriggerContext, + ChartActionContext, +} from '../../../../../../src/plugins/embeddable/public'; +import { i18n } from '@kbn/i18n'; +import { + VisualizeEmbeddableContract, + VISUALIZE_EMBEDDABLE_TYPE, +} from '../../../../../../src/plugins/visualizations/public'; +import { ViewMode } from '../../../../../../src/plugins/embeddable/public'; +import { Filter, TimeRange } from '../../../../../../src/plugins/data/public'; + +const i18nTranslateSpy = (i18n.translate as unknown) as jest.SpyInstance; + +jest.mock('@kbn/i18n', () => ({ + i18n: { + translate: jest.fn((key, options) => options.defaultMessage), + }, +})); + +afterEach(() => { + i18nTranslateSpy.mockClear(); +}); + +const setup = ({ useRangeEvent = false }: { useRangeEvent?: boolean } = {}) => { + type UrlGenerator = UrlGeneratorContract<'DISCOVER_APP_URL_GENERATOR'>; + + const core = coreMock.createStart(); + + const urlGenerator: UrlGenerator = ({ + createUrl: jest.fn(() => Promise.resolve('/xyz/app/discover/foo#bar')), + } as unknown) as UrlGenerator; + + const filtersAndTimeRangeFromContext = jest.fn((async () => ({ + filters: [], + })) as EmbeddableStart['filtersAndTimeRangeFromContext']); + + const plugins: PluginDeps = { + discover: { + urlGenerator, + }, + embeddable: { + filtersAndTimeRangeFromContext, + }, + }; + + const params: Params = { + start: () => ({ + plugins, + self: {}, + core, + }), + }; + const action = new ExploreDataChartAction(params); + + const input = { + viewMode: ViewMode.VIEW, + }; + + const output = { + indexPatterns: [ + { + id: 'index-ptr-foo', + }, + ], + }; + + const embeddable: VisualizeEmbeddableContract = ({ + type: VISUALIZE_EMBEDDABLE_TYPE, + getInput: () => input, + getOutput: () => output, + } as unknown) as VisualizeEmbeddableContract; + + const data: ChartActionContext['data'] = { + ...(useRangeEvent + ? ({ range: {} } as RangeSelectTriggerContext['data']) + : ({ data: [] } as ValueClickTriggerContext['data'])), + timeFieldName: 'order_date', + }; + + const context = { + embeddable, + data, + } as ChartActionContext; + + return { core, plugins, urlGenerator, params, action, input, output, embeddable, data, context }; +}; + +describe('"Explore underlying data" panel action', () => { + test('action has Discover icon', () => { + const { action, context } = setup(); + expect(action.getIconType(context)).toBe('discoverApp'); + }); + + test('title is "Explore underlying data"', () => { + const { action, context } = setup(); + expect(action.getDisplayName(context)).toBe('Explore underlying data'); + }); + + test('translates title', () => { + expect(i18nTranslateSpy).toHaveBeenCalledTimes(0); + + const { action, context } = setup(); + action.getDisplayName(context); + + expect(i18nTranslateSpy).toHaveBeenCalledTimes(1); + expect(i18nTranslateSpy.mock.calls[0][0]).toBe( + 'xpack.discover.FlyoutCreateDrilldownAction.displayName' + ); + }); + + describe('isCompatible()', () => { + test('returns true when all conditions are met', async () => { + const { action, context } = setup(); + + const isCompatible = await action.isCompatible(context); + + expect(isCompatible).toBe(true); + }); + + test('returns false when URL generator is not present', async () => { + const { action, plugins, context } = setup(); + (plugins.discover as any).urlGenerator = undefined; + + const isCompatible = await action.isCompatible(context); + + expect(isCompatible).toBe(false); + }); + + test('returns false if embeddable is not Visualize embeddable', async () => { + const { action, embeddable, context } = setup(); + (embeddable as any).type = 'NOT_VISUALIZE_EMBEDDABLE'; + + const isCompatible = await action.isCompatible(context); + + expect(isCompatible).toBe(false); + }); + + test('returns false if embeddable does not have index patterns', async () => { + const { action, output, context } = setup(); + delete output.indexPatterns; + + const isCompatible = await action.isCompatible(context); + + expect(isCompatible).toBe(false); + }); + + test('returns false if embeddable index patterns are empty', async () => { + const { action, output, context } = setup(); + output.indexPatterns = []; + + const isCompatible = await action.isCompatible(context); + + expect(isCompatible).toBe(false); + }); + + test('returns false if dashboard is in edit mode', async () => { + const { action, input, context } = setup(); + input.viewMode = ViewMode.EDIT; + + const isCompatible = await action.isCompatible(context); + + expect(isCompatible).toBe(false); + }); + }); + + describe('getHref()', () => { + test('returns URL path generated by URL generator', async () => { + const { action, context } = setup(); + + const href = await action.getHref(context); + + expect(href).toBe('/xyz/app/discover/foo#bar'); + }); + + test('calls URL generator with right arguments', async () => { + const { action, urlGenerator, context } = setup(); + + expect(urlGenerator.createUrl).toHaveBeenCalledTimes(0); + + await action.getHref(context); + + expect(urlGenerator.createUrl).toHaveBeenCalledTimes(1); + expect(urlGenerator.createUrl).toHaveBeenCalledWith({ + filters: [], + indexPatternId: 'index-ptr-foo', + timeRange: undefined, + }); + }); + + test('applies chart event filters', async () => { + const { action, context, urlGenerator, plugins } = setup(); + + ((plugins.embeddable + .filtersAndTimeRangeFromContext as unknown) as jest.SpyInstance).mockImplementation(() => { + const filters: Filter[] = [ + { + meta: { + alias: 'alias', + disabled: false, + negate: false, + }, + }, + ]; + const timeRange: TimeRange = { + from: 'from', + to: 'to', + }; + return { filters, timeRange }; + }); + + expect(plugins.embeddable.filtersAndTimeRangeFromContext).toHaveBeenCalledTimes(0); + + await action.getHref(context); + + expect(plugins.embeddable.filtersAndTimeRangeFromContext).toHaveBeenCalledTimes(1); + expect(plugins.embeddable.filtersAndTimeRangeFromContext).toHaveBeenCalledWith(context); + expect(urlGenerator.createUrl).toHaveBeenCalledWith({ + filters: [ + { + meta: { + alias: 'alias', + disabled: false, + negate: false, + }, + }, + ], + indexPatternId: 'index-ptr-foo', + timeRange: { + from: 'from', + to: 'to', + }, + }); + }); + }); + + describe('execute()', () => { + test('calls platform SPA navigation method', async () => { + const { action, context, core } = setup(); + + expect(core.application.navigateToApp).toHaveBeenCalledTimes(0); + + await action.execute(context); + + expect(core.application.navigateToApp).toHaveBeenCalledTimes(1); + }); + + test('calls platform SPA navigation method with right arguments', async () => { + const { action, context, core } = setup(); + + await action.execute(context); + + expect(core.application.navigateToApp).toHaveBeenCalledTimes(1); + expect(core.application.navigateToApp.mock.calls[0]).toEqual([ + 'discover', + { + path: '/foo#bar', + }, + ]); + }); + }); +}); diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts index e945802a6c95ef..e742b693809731 100644 --- a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts @@ -4,10 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - ExploreDataContextMenuAction, - ACTION_EXPLORE_DATA, -} from './explore_data_context_menu_action'; +import { ExploreDataContextMenuAction } from './explore_data_context_menu_action'; import { Params, PluginDeps } from './abstract_explore_data_action'; import { coreMock } from '../../../../../../src/core/public/mocks'; import { UrlGeneratorContract } from '../../../../../../src/plugins/share/public'; @@ -37,7 +34,6 @@ const setup = () => { const core = coreMock.createStart(); const urlGenerator: UrlGenerator = ({ - id: ACTION_EXPLORE_DATA, createUrl: jest.fn(() => Promise.resolve('/xyz/app/discover/foo#bar')), } as unknown) as UrlGenerator; From 4ceefdd9343b363d9bd31ec0691fe3fe68bafea4 Mon Sep 17 00:00:00 2001 From: streamich Date: Thu, 25 Jun 2020 13:17:54 +0200 Subject: [PATCH 17/25] =?UTF-8?q?test:=20=F0=9F=92=8D=20add=20in-chart=20"?= =?UTF-8?q?Explore=20underlying=20data"=20functional=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../drilldowns/explore_data_chart_action.ts | 98 +++++++++++++++++++ .../drilldowns/explore_data_panel_action.ts | 10 +- .../apps/dashboard/drilldowns/index.ts | 1 + 3 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 x-pack/test/functional/apps/dashboard/drilldowns/explore_data_chart_action.ts diff --git a/x-pack/test/functional/apps/dashboard/drilldowns/explore_data_chart_action.ts b/x-pack/test/functional/apps/dashboard/drilldowns/explore_data_chart_action.ts new file mode 100644 index 00000000000000..d9103f08ce36c8 --- /dev/null +++ b/x-pack/test/functional/apps/dashboard/drilldowns/explore_data_chart_action.ts @@ -0,0 +1,98 @@ +/* + * 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 expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../ftr_provider_context'; + +const ACTION_ID = 'ACTION_EXPLORE_DATA_CHART'; +const ACTION_TEST_SUBJ = `embeddablePanelAction-${ACTION_ID}`; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const drilldowns = getService('dashboardDrilldownsManage'); + const { dashboard, discover, common, timePicker } = getPageObjects([ + 'dashboard', + 'discover', + 'common', + 'timePicker', + ]); + const testSubjects = getService('testSubjects'); + const pieChart = getService('pieChart'); + const dashboardDrilldownPanelActions = getService('dashboardDrilldownPanelActions'); + const filterBar = getService('filterBar'); + const browser = getService('browser'); + + describe('Explore underlying data - chart action', () => { + describe('value click action', () => { + it('action exists in chart click popup menu', async () => { + await common.navigateToApp('dashboard'); + await dashboard.preserveCrossAppState(); + await dashboard.loadSavedDashboard(drilldowns.DASHBOARD_WITH_PIE_CHART_NAME); + await pieChart.filterOnPieSlice('160,000'); + await dashboardDrilldownPanelActions.expectMultipleActionsMenuOpened(); + await testSubjects.existOrFail(ACTION_TEST_SUBJ); + }); + + it('action is a link element', async () => { + const actionElement = await testSubjects.find(ACTION_TEST_SUBJ); + const tag = await actionElement.getTagName(); + const href = await actionElement.getAttribute('href'); + + expect(tag.toLowerCase()).to.be('a'); + expect(typeof href).to.be('string'); + expect(href.length > 5).to.be(true); + }); + + it('navigates to Discover app on action click carrying over pie slice filter', async () => { + await testSubjects.clickWhenNotDisabled(ACTION_TEST_SUBJ); + await discover.waitForDiscoverAppOnScreen(); + await filterBar.hasFilter('memory', '160,000 to 200,000'); + const filterCount = await filterBar.getFilterCount(); + + expect(filterCount).to.be(1); + }); + }); + + describe('brush action', () => { + let originalTimeRangeDurationHours: number | undefined; + + it('action exists in chart brush popup menu', async () => { + await common.navigateToApp('dashboard'); + await dashboard.preserveCrossAppState(); + await dashboard.loadSavedDashboard(drilldowns.DASHBOARD_WITH_AREA_CHART_NAME); + + originalTimeRangeDurationHours = await timePicker.getTimeDurationInHours(); + const areaChart = await testSubjects.find('visualizationLoader'); + await browser.dragAndDrop( + { + location: areaChart, + offset: { + x: -100, + y: 0, + }, + }, + { + location: areaChart, + offset: { + x: 100, + y: 0, + }, + } + ); + + await dashboardDrilldownPanelActions.expectMultipleActionsMenuOpened(); + await testSubjects.existOrFail(ACTION_TEST_SUBJ); + }); + + it('navigates to Discover on click carrying over brushed time range', async () => { + await testSubjects.clickWhenNotDisabled(ACTION_TEST_SUBJ); + await discover.waitForDiscoverAppOnScreen(); + const newTimeRangeDurationHours = await timePicker.getTimeDurationInHours(); + + expect(newTimeRangeDurationHours).to.be.lessThan(originalTimeRangeDurationHours as number); + }); + }); + }); +} diff --git a/x-pack/test/functional/apps/dashboard/drilldowns/explore_data_panel_action.ts b/x-pack/test/functional/apps/dashboard/drilldowns/explore_data_panel_action.ts index 24d6e820ac0ebd..d165a41ecbdf4d 100644 --- a/x-pack/test/functional/apps/dashboard/drilldowns/explore_data_panel_action.ts +++ b/x-pack/test/functional/apps/dashboard/drilldowns/explore_data_panel_action.ts @@ -8,7 +8,7 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../ftr_provider_context'; const ACTION_ID = 'ACTION_EXPLORE_DATA'; -const EXPLORE_RAW_DATA_ACTION_TEST_SUBJ = `embeddablePanelAction-${ACTION_ID}`; +const ACTION_TEST_SUBJ = `embeddablePanelAction-${ACTION_ID}`; export default function ({ getService, getPageObjects }: FtrProviderContext) { const drilldowns = getService('dashboardDrilldownsManage'); @@ -37,18 +37,18 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('action exists in panel context menu', async () => { await dashboard.loadSavedDashboard(drilldowns.DASHBOARD_WITH_PIE_CHART_NAME); await panelActions.openContextMenu(); - await testSubjects.existOrFail(EXPLORE_RAW_DATA_ACTION_TEST_SUBJ); + await testSubjects.existOrFail(ACTION_TEST_SUBJ); }); it('is a link element', async () => { - const actionElement = await testSubjects.find(EXPLORE_RAW_DATA_ACTION_TEST_SUBJ); + const actionElement = await testSubjects.find(ACTION_TEST_SUBJ); const tag = await actionElement.getTagName(); expect(tag.toLowerCase()).to.be('a'); }); it('navigates to Discover app to index pattern of the panel on action click', async () => { - await testSubjects.clickWhenNotDisabled(EXPLORE_RAW_DATA_ACTION_TEST_SUBJ); + await testSubjects.clickWhenNotDisabled(ACTION_TEST_SUBJ); await discover.waitForDiscoverAppOnScreen(); const el = await testSubjects.find('indexPattern-switch-link'); @@ -71,7 +71,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await dashboard.saveDashboard('Dashboard with Pie Chart'); await panelActions.openContextMenu(); - await testSubjects.clickWhenNotDisabled(EXPLORE_RAW_DATA_ACTION_TEST_SUBJ); + await testSubjects.clickWhenNotDisabled(ACTION_TEST_SUBJ); await discover.waitForDiscoverAppOnScreen(); const text = await timePicker.getShowDatesButtonText(); diff --git a/x-pack/test/functional/apps/dashboard/drilldowns/index.ts b/x-pack/test/functional/apps/dashboard/drilldowns/index.ts index 19d85ad0e448f7..4cdb33c06947fe 100644 --- a/x-pack/test/functional/apps/dashboard/drilldowns/index.ts +++ b/x-pack/test/functional/apps/dashboard/drilldowns/index.ts @@ -24,5 +24,6 @@ export default function ({ loadTestFile, getService }: FtrProviderContext) { loadTestFile(require.resolve('./dashboard_drilldowns')); loadTestFile(require.resolve('./explore_data_panel_action')); + loadTestFile(require.resolve('./explore_data_chart_action')); }); } From 0e29de3eef4bf65f23f04f3d6be23ee5073e3c0a Mon Sep 17 00:00:00 2001 From: streamich Date: Thu, 25 Jun 2020 13:27:11 +0200 Subject: [PATCH 18/25] =?UTF-8?q?test:=20=F0=9F=92=8D=20clean-up=20custom?= =?UTF-8?q?=20time=20range=20after=20panel=20action=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dashboard/drilldowns/explore_data_panel_action.ts | 8 ++++++++ .../functional/services/dashboard/panel_time_range.ts | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/x-pack/test/functional/apps/dashboard/drilldowns/explore_data_panel_action.ts b/x-pack/test/functional/apps/dashboard/drilldowns/explore_data_panel_action.ts index d165a41ecbdf4d..244cc831e06e19 100644 --- a/x-pack/test/functional/apps/dashboard/drilldowns/explore_data_panel_action.ts +++ b/x-pack/test/functional/apps/dashboard/drilldowns/explore_data_panel_action.ts @@ -32,6 +32,14 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { after(async () => { await kibanaServer.uiSettings.replace({ defaultIndex: 'logstash-*' }); + + // Clean-up custom time range on panel + await common.navigateToApp('dashboard'); + await dashboard.gotoDashboardEditMode(drilldowns.DASHBOARD_WITH_PIE_CHART_NAME); + await panelActions.openContextMenu(); + await panelActionsTimeRange.clickTimeRangeActionInContextMenu(); + await panelActionsTimeRange.clickRemovePerPanelTimeRangeButton(); + await dashboard.saveDashboard('Dashboard with Pie Chart'); }); it('action exists in panel context menu', async () => { diff --git a/x-pack/test/functional/services/dashboard/panel_time_range.ts b/x-pack/test/functional/services/dashboard/panel_time_range.ts index 6a91a6ff0584b4..f71e8284c30d94 100644 --- a/x-pack/test/functional/services/dashboard/panel_time_range.ts +++ b/x-pack/test/functional/services/dashboard/panel_time_range.ts @@ -52,5 +52,11 @@ export function DashboardPanelTimeRangeProvider({ getService }: FtrProviderConte const button = await this.findModalTestSubject('addPerPanelTimeRangeButton'); await button.click(); } + + public async clickRemovePerPanelTimeRangeButton() { + log.debug('clickRemovePerPanelTimeRangeButton'); + const button = await this.findModalTestSubject('removePerPanelTimeRangeButton'); + await button.click(); + } })(); } From 424414f3f45c309eec70cd421a80c0c1ba8fc924 Mon Sep 17 00:00:00 2001 From: streamich Date: Thu, 25 Jun 2020 13:34:19 +0200 Subject: [PATCH 19/25] =?UTF-8?q?chore:=20=F0=9F=A4=96=20fix=20embeddable?= =?UTF-8?q?=20plugin=20mocks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/embeddable/public/mocks.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/plugins/embeddable/public/mocks.tsx b/src/plugins/embeddable/public/mocks.tsx index 49910525c7ab18..c98416cb3e8c7e 100644 --- a/src/plugins/embeddable/public/mocks.tsx +++ b/src/plugins/embeddable/public/mocks.tsx @@ -31,6 +31,7 @@ import { coreMock } from '../../../core/public/mocks'; import { UiActionsService } from './lib/ui_actions'; import { CoreStart } from '../../../core/public'; import { Start as InspectorStart } from '../../inspector/public'; +import { dataPluginMock } from '../../data/public/mocks'; // eslint-disable-next-line import { inspectorPluginMock } from '../../inspector/public/mocks'; @@ -100,6 +101,8 @@ const createStartContract = (): Start => { EmbeddablePanel: jest.fn(), getEmbeddablePanel: jest.fn(), getStateTransfer: jest.fn(() => createEmbeddableStateTransferMock() as EmbeddableStateTransfer), + filtersAndTimeRangeFromContext: jest.fn(), + filtersFromContext: jest.fn(), }; return startContract; }; @@ -108,11 +111,13 @@ const createInstance = (setupPlugins: Partial = {}) const plugin = new EmbeddablePublicPlugin({} as any); const setup = plugin.setup(coreMock.createSetup(), { uiActions: setupPlugins.uiActions || uiActionsPluginMock.createSetupContract(), + data: dataPluginMock.createSetupContract(), }); const doStart = (startPlugins: Partial = {}) => plugin.start(coreMock.createStart(), { uiActions: startPlugins.uiActions || uiActionsPluginMock.createStartContract(), inspector: inspectorPluginMock.createStartContract(), + data: dataPluginMock.createStartContract(), }); return { plugin, From dcef452f59ed317c3aaaa358fd2394f9ffed5dfe Mon Sep 17 00:00:00 2001 From: streamich Date: Thu, 25 Jun 2020 13:40:43 +0200 Subject: [PATCH 20/25] =?UTF-8?q?chore:=20=F0=9F=A4=96=20fix=20another=20m?= =?UTF-8?q?ock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/embeddable/public/tests/test_plugin.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/plugins/embeddable/public/tests/test_plugin.ts b/src/plugins/embeddable/public/tests/test_plugin.ts index e13a906e30338f..bb12e3d7b90116 100644 --- a/src/plugins/embeddable/public/tests/test_plugin.ts +++ b/src/plugins/embeddable/public/tests/test_plugin.ts @@ -23,6 +23,7 @@ import { UiActionsStart } from '../../../ui_actions/public'; import { uiActionsPluginMock } from '../../../ui_actions/public/mocks'; // eslint-disable-next-line import { inspectorPluginMock } from '../../../inspector/public/mocks'; +import { dataPluginMock } from '../../../data/public/mocks'; import { coreMock } from '../../../../core/public/mocks'; import { EmbeddablePublicPlugin, EmbeddableSetup, EmbeddableStart } from '../plugin'; @@ -42,7 +43,10 @@ export const testPlugin = ( const uiActions = uiActionsPluginMock.createPlugin(coreSetup, coreStart); const initializerContext = {} as any; const plugin = new EmbeddablePublicPlugin(initializerContext); - const setup = plugin.setup(coreSetup, { uiActions: uiActions.setup }); + const setup = plugin.setup(coreSetup, { + data: dataPluginMock.createSetupContract(), + uiActions: uiActions.setup, + }); return { plugin, @@ -51,8 +55,9 @@ export const testPlugin = ( setup, doStart: (anotherCoreStart: CoreStart = coreStart) => { const start = plugin.start(anotherCoreStart, { - uiActions: uiActionsPluginMock.createStartContract(), + data: dataPluginMock.createStartContract(), inspector: inspectorPluginMock.createStartContract(), + uiActions: uiActionsPluginMock.createStartContract(), }); return start; }, From 905f0bc5b9861205673da5cbfb340160bcd940ff Mon Sep 17 00:00:00 2001 From: streamich Date: Thu, 25 Jun 2020 14:23:28 +0200 Subject: [PATCH 21/25] =?UTF-8?q?test:=20=F0=9F=92=8D=20add=20support=20fo?= =?UTF-8?q?r=20new=20action=20to=20pie=20chart=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../services/dashboard/panel_actions.ts | 14 ++++++++++++++ .../services/visualizations/pie_chart.ts | 17 +++++++++++++++-- .../drilldowns/dashboard_drilldowns.ts | 2 +- .../drilldowns/explore_data_chart_action.ts | 2 +- .../drilldowns/explore_data_panel_action.ts | 15 +++++++++++---- 5 files changed, 42 insertions(+), 8 deletions(-) diff --git a/test/functional/services/dashboard/panel_actions.ts b/test/functional/services/dashboard/panel_actions.ts index c9a5dcfba32b11..0f5d6ea74a6b66 100644 --- a/test/functional/services/dashboard/panel_actions.ts +++ b/test/functional/services/dashboard/panel_actions.ts @@ -213,5 +213,19 @@ export function DashboardPanelActionsProvider({ getService, getPageObjects }: Ft await testSubjects.click('saveNewTitleButton'); await this.toggleContextMenu(panel); } + + async getActionWebElementByText(text: string): Promise { + log.debug(`getActionWebElement: "${text}"`); + const menu = await testSubjects.find('multipleActionsContextMenu'); + const items = await menu.findAllByCssSelector('[data-test-subj*="embeddablePanelAction-"]'); + for (const item of items) { + const currentText = await item.getVisibleText(); + if (currentText === text) { + return item; + } + } + + throw new Error(`No action matching text "${text}"`); + } })(); } diff --git a/test/functional/services/visualizations/pie_chart.ts b/test/functional/services/visualizations/pie_chart.ts index 66f32d246b31f4..a25695a5bfcb70 100644 --- a/test/functional/services/visualizations/pie_chart.ts +++ b/test/functional/services/visualizations/pie_chart.ts @@ -28,10 +28,13 @@ export function PieChartProvider({ getService }: FtrProviderContext) { const testSubjects = getService('testSubjects'); const find = getService('find'); const defaultFindTimeout = config.get('timeouts.find'); + const panelActions = getService('dashboardPanelActions'); return new (class PieChart { - async filterOnPieSlice(name?: string) { - log.debug(`PieChart.filterOnPieSlice(${name})`); + private readonly filterActionText = 'Apply filter to current view'; + + async clickOnPieSlice(name?: string) { + log.debug(`PieChart.clickOnPieSlice(${name})`); if (name) { await testSubjects.click(`pieSlice-${name.split(' ').join('-')}`); } else { @@ -44,6 +47,16 @@ export function PieChartProvider({ getService }: FtrProviderContext) { } } + async filterOnPieSlice(name?: string) { + log.debug(`PieChart.filterOnPieSlice(${name})`); + await this.clickOnPieSlice(name); + const hasUiActionsPopup = await testSubjects.exists('multipleActionsContextMenu'); + if (hasUiActionsPopup) { + const actionElement = await panelActions.getActionWebElementByText(this.filterActionText); + await actionElement.click(); + } + } + async filterByLegendItem(label: string) { log.debug(`PieChart.filterByLegendItem(${label})`); await testSubjects.click(`legend-${label}`); diff --git a/x-pack/test/functional/apps/dashboard/drilldowns/dashboard_drilldowns.ts b/x-pack/test/functional/apps/dashboard/drilldowns/dashboard_drilldowns.ts index bcdd3d1f82e7dc..29ead0db1c6349 100644 --- a/x-pack/test/functional/apps/dashboard/drilldowns/dashboard_drilldowns.ts +++ b/x-pack/test/functional/apps/dashboard/drilldowns/dashboard_drilldowns.ts @@ -59,7 +59,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ); // trigger drilldown action by clicking on a pie and picking drilldown action by it's name - await pieChart.filterOnPieSlice('40,000'); + await pieChart.clickOnPieSlice('40,000'); await dashboardDrilldownPanelActions.expectMultipleActionsMenuOpened(); const href = await dashboardDrilldownPanelActions.getActionHrefByText( diff --git a/x-pack/test/functional/apps/dashboard/drilldowns/explore_data_chart_action.ts b/x-pack/test/functional/apps/dashboard/drilldowns/explore_data_chart_action.ts index d9103f08ce36c8..12363f8800c28c 100644 --- a/x-pack/test/functional/apps/dashboard/drilldowns/explore_data_chart_action.ts +++ b/x-pack/test/functional/apps/dashboard/drilldowns/explore_data_chart_action.ts @@ -30,7 +30,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await common.navigateToApp('dashboard'); await dashboard.preserveCrossAppState(); await dashboard.loadSavedDashboard(drilldowns.DASHBOARD_WITH_PIE_CHART_NAME); - await pieChart.filterOnPieSlice('160,000'); + await pieChart.clickOnPieSlice('160,000'); await dashboardDrilldownPanelActions.expectMultipleActionsMenuOpened(); await testSubjects.existOrFail(ACTION_TEST_SUBJ); }); diff --git a/x-pack/test/functional/apps/dashboard/drilldowns/explore_data_panel_action.ts b/x-pack/test/functional/apps/dashboard/drilldowns/explore_data_panel_action.ts index 244cc831e06e19..fedc83a2f81c7e 100644 --- a/x-pack/test/functional/apps/dashboard/drilldowns/explore_data_panel_action.ts +++ b/x-pack/test/functional/apps/dashboard/drilldowns/explore_data_panel_action.ts @@ -24,16 +24,23 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const kibanaServer = getService('kibanaServer'); describe('Explore underlying data - panel action', function () { - before(async () => { - await kibanaServer.uiSettings.replace({ defaultIndex: 'logstash*' }); + before( + 'change default index pattern to verify action navigates to correct index pattern', + async () => { + await kibanaServer.uiSettings.replace({ defaultIndex: 'logstash*' }); + } + ); + + before('start on Dashboard landing page', async () => { await common.navigateToApp('dashboard'); await dashboard.preserveCrossAppState(); }); - after(async () => { + after('set back default index pattern', async () => { await kibanaServer.uiSettings.replace({ defaultIndex: 'logstash-*' }); + }); - // Clean-up custom time range on panel + after('clean-up custom time range on panel', async () => { await common.navigateToApp('dashboard'); await dashboard.gotoDashboardEditMode(drilldowns.DASHBOARD_WITH_PIE_CHART_NAME); await panelActions.openContextMenu(); From 8c2e4e31ff7064d311eb6cc3a2f3113eb4aa8436 Mon Sep 17 00:00:00 2001 From: streamich Date: Fri, 26 Jun 2020 10:37:48 +0200 Subject: [PATCH 22/25] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20enable=20"Explore?= =?UTF-8?q?=20underlying=20data"=20action=20for=20Lens=20vis?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../abstract_explore_data_action.ts | 7 +++-- .../explore_data/explore_data_chart_action.ts | 2 +- .../explore_data_context_menu_action.ts | 2 +- .../public/actions/explore_data/shared.ts | 27 +++++-------------- 4 files changed, 12 insertions(+), 26 deletions(-) diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts index 620cabe6527784..59359fb35f544b 100644 --- a/x-pack/plugins/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts @@ -43,14 +43,13 @@ export abstract class AbstractExploreDataAction { if (!embeddable) return false; if (!this.params.start().plugins.discover.urlGenerator) return false; - if (!shared.isVisualizeEmbeddable(embeddable)) return false; - if (!shared.getIndexPattern(embeddable)) return false; + if (!shared.hasExactlyOneIndexPattern(embeddable)) return false; if (embeddable.getInput().viewMode !== ViewMode.VIEW) return false; return true; } public async execute(context: Context): Promise { - if (!shared.isVisualizeEmbeddable(context.embeddable)) return; + if (!shared.hasExactlyOneIndexPattern(context.embeddable)) return; const { core } = this.params.start(); const { appName, appPath } = await this.getUrl(context); @@ -63,7 +62,7 @@ export abstract class AbstractExploreDataAction { const { embeddable } = context; - if (!shared.isVisualizeEmbeddable(embeddable)) { + if (!shared.hasExactlyOneIndexPattern(embeddable)) { throw new Error(`Embeddable not supported for "${this.getDisplayName(context)}" action.`); } diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.ts index 359f14959c6a6a..5e7ae39c797373 100644 --- a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.ts +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.ts @@ -49,7 +49,7 @@ export class ExploreDataChartAction extends AbstractExploreDataAction } => { if (!output || typeof output !== 'object') return false; return Array.isArray((output as any).indexPatterns); }; -export const isVisualizeEmbeddable = ( - embeddable?: IEmbeddable -): embeddable is VisualizeEmbeddableContract => - embeddable && embeddable?.type === VISUALIZE_EMBEDDABLE_TYPE ? true : false; - -/** - * @returns Returns empty string if no index pattern ID found. - */ -export const getIndexPattern = (embeddable?: IEmbeddable): string => { - if (!embeddable) return ''; +export const getIndexPatterns = (embeddable?: IEmbeddable): string[] => { + if (!embeddable) return []; const output = embeddable.getOutput(); - if (isOutputWithIndexPatterns(output) && output.indexPatterns.length > 0) { - return output.indexPatterns[0].id; - } - - return ''; + return isOutputWithIndexPatterns(output) ? output.indexPatterns.map(({ id }) => id) : []; }; + +export const hasExactlyOneIndexPattern = (embeddable?: IEmbeddable): string[] => + getIndexPatterns(embeddable).length === 1; From 06b7743912000c6dd98b6aa5e52d94f8d8a2b78c Mon Sep 17 00:00:00 2001 From: streamich Date: Fri, 26 Jun 2020 10:46:00 +0200 Subject: [PATCH 23/25] =?UTF-8?q?test:=20=F0=9F=92=8D=20make=20tests=20gre?= =?UTF-8?q?en=20again?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../explore_data/explore_data_chart_action.test.ts | 13 ++++++++++--- .../explore_data_context_menu_action.test.ts | 13 ++++++++++--- .../public/actions/explore_data/shared.ts | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.test.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.test.ts index a273f0d50e45e8..a5a82112ac91d2 100644 --- a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.test.ts +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.test.ts @@ -139,9 +139,16 @@ describe('"Explore underlying data" panel action', () => { expect(isCompatible).toBe(false); }); - test('returns false if embeddable is not Visualize embeddable', async () => { - const { action, embeddable, context } = setup(); - (embeddable as any).type = 'NOT_VISUALIZE_EMBEDDABLE'; + test('returns false if embeddable has more than one index pattern', async () => { + const { action, output, context } = setup(); + output.indexPatterns = [ + { + id: 'index-ptr-foo', + }, + { + id: 'index-ptr-bar', + }, + ]; const isCompatible = await action.isCompatible(context); diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts index e742b693809731..c362e554e96c04 100644 --- a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts @@ -125,9 +125,16 @@ describe('"Explore underlying data" panel action', () => { expect(isCompatible).toBe(false); }); - test('returns false if embeddable is not Visualize embeddable', async () => { - const { action, embeddable, context } = setup(); - (embeddable as any).type = 'NOT_VISUALIZE_EMBEDDABLE'; + test('returns false if embeddable has more than one index pattern', async () => { + const { action, output, context } = setup(); + output.indexPatterns = [ + { + id: 'index-ptr-foo', + }, + { + id: 'index-ptr-bar', + }, + ]; const isCompatible = await action.isCompatible(context); diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/shared.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/shared.ts index a1587a7b215034..c7051413e8f250 100644 --- a/x-pack/plugins/discover_enhanced/public/actions/explore_data/shared.ts +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/shared.ts @@ -20,5 +20,5 @@ export const getIndexPatterns = (embeddable?: IEmbeddable): string[] => { return isOutputWithIndexPatterns(output) ? output.indexPatterns.map(({ id }) => id) : []; }; -export const hasExactlyOneIndexPattern = (embeddable?: IEmbeddable): string[] => +export const hasExactlyOneIndexPattern = (embeddable?: IEmbeddable): boolean => getIndexPatterns(embeddable).length === 1; From eb08d0eb23867273e0e49ba375b07c4baf682a33 Mon Sep 17 00:00:00 2001 From: streamich Date: Fri, 26 Jun 2020 15:23:17 +0200 Subject: [PATCH 24/25] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20rename=20trigg?= =?UTF-8?q?er=20contexts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../filters/create_filters_from_range_select.ts | 4 ++-- .../filters/create_filters_from_value_click.test.ts | 4 ++-- .../filters/create_filters_from_value_click.ts | 4 ++-- .../data/public/actions/select_range_action.ts | 4 ++-- .../data/public/actions/value_click_action.ts | 4 ++-- src/plugins/embeddable/public/index.ts | 4 ++-- .../embeddable/public/lib/triggers/triggers.ts | 12 ++++++------ src/plugins/ui_actions/public/types.ts | 6 +++--- .../drilldown.test.tsx | 8 ++++---- .../dashboard_to_dashboard_drilldown/types.ts | 8 ++++---- .../explore_data/explore_data_chart_action.test.ts | 8 ++++---- .../explore_data/explore_data_chart_action.ts | 6 +++--- 12 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/plugins/data/public/actions/filters/create_filters_from_range_select.ts b/src/plugins/data/public/actions/filters/create_filters_from_range_select.ts index 409614ca9c3802..a0eb49d773f3d5 100644 --- a/src/plugins/data/public/actions/filters/create_filters_from_range_select.ts +++ b/src/plugins/data/public/actions/filters/create_filters_from_range_select.ts @@ -22,9 +22,9 @@ import moment from 'moment'; import { esFilters, IFieldType, RangeFilterParams } from '../../../public'; import { getIndexPatterns } from '../../../public/services'; import { deserializeAggConfig } from '../../search/expressions/utils'; -import { RangeSelectTriggerContext } from '../../../../embeddable/public'; +import { RangeSelectContext } from '../../../../embeddable/public'; -export async function createFiltersFromRangeSelectAction(event: RangeSelectTriggerContext['data']) { +export async function createFiltersFromRangeSelectAction(event: RangeSelectContext['data']) { const column: Record = event.table.columns[event.column]; if (!column || !column.meta) { diff --git a/src/plugins/data/public/actions/filters/create_filters_from_value_click.test.ts b/src/plugins/data/public/actions/filters/create_filters_from_value_click.test.ts index a0e285c20d776a..3e38477a908b8d 100644 --- a/src/plugins/data/public/actions/filters/create_filters_from_value_click.test.ts +++ b/src/plugins/data/public/actions/filters/create_filters_from_value_click.test.ts @@ -27,7 +27,7 @@ import { dataPluginMock } from '../../../public/mocks'; import { setIndexPatterns } from '../../../public/services'; import { mockDataServices } from '../../../public/search/aggs/test_helpers'; import { createFiltersFromValueClickAction } from './create_filters_from_value_click'; -import { ValueClickTriggerContext } from '../../../../embeddable/public'; +import { ValueClickContext } from '../../../../embeddable/public'; const mockField = { name: 'bytes', @@ -39,7 +39,7 @@ const mockField = { }; describe('createFiltersFromValueClick', () => { - let dataPoints: ValueClickTriggerContext['data']['data']; + let dataPoints: ValueClickContext['data']['data']; beforeEach(() => { dataPoints = [ diff --git a/src/plugins/data/public/actions/filters/create_filters_from_value_click.ts b/src/plugins/data/public/actions/filters/create_filters_from_value_click.ts index 2fdd7465355191..1974b9f776748b 100644 --- a/src/plugins/data/public/actions/filters/create_filters_from_value_click.ts +++ b/src/plugins/data/public/actions/filters/create_filters_from_value_click.ts @@ -21,7 +21,7 @@ import { KibanaDatatable } from '../../../../../plugins/expressions/public'; import { deserializeAggConfig } from '../../search/expressions'; import { esFilters, Filter } from '../../../public'; import { getIndexPatterns } from '../../../public/services'; -import { ValueClickTriggerContext } from '../../../../embeddable/public'; +import { ValueClickContext } from '../../../../embeddable/public'; /** * For terms aggregations on `__other__` buckets, this assembles a list of applicable filter @@ -114,7 +114,7 @@ const createFilter = async ( export const createFiltersFromValueClickAction = async ({ data, negate, -}: ValueClickTriggerContext['data']) => { +}: ValueClickContext['data']) => { const filters: Filter[] = []; await Promise.all( diff --git a/src/plugins/data/public/actions/select_range_action.ts b/src/plugins/data/public/actions/select_range_action.ts index 18853f7e292f68..49766143b5588e 100644 --- a/src/plugins/data/public/actions/select_range_action.ts +++ b/src/plugins/data/public/actions/select_range_action.ts @@ -24,12 +24,12 @@ import { ActionByType, } from '../../../../plugins/ui_actions/public'; import { createFiltersFromRangeSelectAction } from './filters/create_filters_from_range_select'; -import { RangeSelectTriggerContext } from '../../../embeddable/public'; +import { RangeSelectContext } from '../../../embeddable/public'; import { FilterManager, TimefilterContract, esFilters } from '..'; export const ACTION_SELECT_RANGE = 'ACTION_SELECT_RANGE'; -export type SelectRangeActionContext = RangeSelectTriggerContext; +export type SelectRangeActionContext = RangeSelectContext; async function isCompatible(context: SelectRangeActionContext) { try { diff --git a/src/plugins/data/public/actions/value_click_action.ts b/src/plugins/data/public/actions/value_click_action.ts index 5d4f1f5f1d6dbb..dd74a7ee507f37 100644 --- a/src/plugins/data/public/actions/value_click_action.ts +++ b/src/plugins/data/public/actions/value_click_action.ts @@ -27,12 +27,12 @@ import { import { getOverlays, getIndexPatterns } from '../services'; import { applyFiltersPopover } from '../ui/apply_filters'; import { createFiltersFromValueClickAction } from './filters/create_filters_from_value_click'; -import { ValueClickTriggerContext } from '../../../embeddable/public'; +import { ValueClickContext } from '../../../embeddable/public'; import { Filter, FilterManager, TimefilterContract, esFilters } from '..'; export const ACTION_VALUE_CLICK = 'ACTION_VALUE_CLICK'; -export type ValueClickActionContext = ValueClickTriggerContext; +export type ValueClickActionContext = ValueClickContext; async function isCompatible(context: ValueClickActionContext) { try { diff --git a/src/plugins/embeddable/public/index.ts b/src/plugins/embeddable/public/index.ts index f19974942c43d1..6960550b59d1c7 100644 --- a/src/plugins/embeddable/public/index.ts +++ b/src/plugins/embeddable/public/index.ts @@ -48,8 +48,8 @@ export { EmbeddableOutput, EmbeddablePanel, EmbeddableRoot, - ValueClickTriggerContext, - RangeSelectTriggerContext, + ValueClickContext, + RangeSelectContext, ErrorEmbeddable, IContainer, IEmbeddable, diff --git a/src/plugins/embeddable/public/lib/triggers/triggers.ts b/src/plugins/embeddable/public/lib/triggers/triggers.ts index 5bb96a708b7ac1..ccba5cf7710886 100644 --- a/src/plugins/embeddable/public/lib/triggers/triggers.ts +++ b/src/plugins/embeddable/public/lib/triggers/triggers.ts @@ -25,7 +25,7 @@ export interface EmbeddableContext { embeddable: IEmbeddable; } -export interface ValueClickTriggerContext { +export interface ValueClickContext { embeddable?: T; data: { data: Array<{ @@ -39,7 +39,7 @@ export interface ValueClickTriggerContext { }; } -export interface RangeSelectTriggerContext { +export interface RangeSelectContext { embeddable?: T; data: { table: KibanaDatatable; @@ -50,16 +50,16 @@ export interface RangeSelectTriggerContext } export type ChartActionContext = - | ValueClickTriggerContext - | RangeSelectTriggerContext; + | ValueClickContext + | RangeSelectContext; export const isValueClickTriggerContext = ( context: ChartActionContext -): context is ValueClickTriggerContext => context.data && 'data' in context.data; +): context is ValueClickContext => context.data && 'data' in context.data; export const isRangeSelectTriggerContext = ( context: ChartActionContext -): context is RangeSelectTriggerContext => context.data && 'range' in context.data; +): context is RangeSelectContext => context.data && 'range' in context.data; export const CONTEXT_MENU_TRIGGER = 'CONTEXT_MENU_TRIGGER'; export const contextMenuTrigger: Trigger<'CONTEXT_MENU_TRIGGER'> = { diff --git a/src/plugins/ui_actions/public/types.ts b/src/plugins/ui_actions/public/types.ts index 85c87306cc4f94..9fcd8a32881df3 100644 --- a/src/plugins/ui_actions/public/types.ts +++ b/src/plugins/ui_actions/public/types.ts @@ -22,7 +22,7 @@ import { TriggerInternal } from './triggers/trigger_internal'; import { Filter } from '../../data/public'; import { SELECT_RANGE_TRIGGER, VALUE_CLICK_TRIGGER, APPLY_FILTER_TRIGGER } from './triggers'; import { IEmbeddable } from '../../embeddable/public'; -import { RangeSelectTriggerContext, ValueClickTriggerContext } from '../../embeddable/public'; +import { RangeSelectContext, ValueClickContext } from '../../embeddable/public'; export type TriggerRegistry = Map>; export type ActionRegistry = Map; @@ -37,8 +37,8 @@ export type TriggerContext = BaseContext; export interface TriggerContextMapping { [DEFAULT_TRIGGER]: TriggerContext; - [SELECT_RANGE_TRIGGER]: RangeSelectTriggerContext; - [VALUE_CLICK_TRIGGER]: ValueClickTriggerContext; + [SELECT_RANGE_TRIGGER]: RangeSelectContext; + [VALUE_CLICK_TRIGGER]: ValueClickContext; [APPLY_FILTER_TRIGGER]: { embeddable: IEmbeddable; filters: Filter[]; diff --git a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/drilldown.test.tsx b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/drilldown.test.tsx index 6ce7dccd3a3ec8..52b232afa9410f 100644 --- a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/drilldown.test.tsx +++ b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/drilldown.test.tsx @@ -22,8 +22,8 @@ import { createDashboardUrlGenerator } from '../../../../../../../src/plugins/da import { UrlGeneratorsService } from '../../../../../../../src/plugins/share/public/url_generators'; import { VisualizeEmbeddableContract } from '../../../../../../../src/plugins/visualizations/public'; import { - RangeSelectTriggerContext, - ValueClickTriggerContext, + RangeSelectContext, + ValueClickContext, } from '../../../../../../../src/plugins/embeddable/public'; import { StartDependencies } from '../../../plugin'; import { SavedObjectLoader } from '../../../../../../../src/plugins/saved_objects/public'; @@ -136,8 +136,8 @@ describe('.execute() & getHref', () => { const context = ({ data: { ...(useRangeEvent - ? ({ range: {} } as RangeSelectTriggerContext['data']) - : ({ data: [] } as ValueClickTriggerContext['data'])), + ? ({ range: {} } as RangeSelectContext['data']) + : ({ data: [] } as ValueClickContext['data'])), timeFieldName: 'order_date', }, embeddable: { diff --git a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/types.ts b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/types.ts index 1fbff0a7269e26..6be2e2a77269fc 100644 --- a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/types.ts +++ b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/types.ts @@ -5,14 +5,14 @@ */ import { - ValueClickTriggerContext, - RangeSelectTriggerContext, + ValueClickContext, + RangeSelectContext, IEmbeddable, } from '../../../../../../../src/plugins/embeddable/public'; export type ActionContext = - | ValueClickTriggerContext - | RangeSelectTriggerContext; + | ValueClickContext + | RangeSelectContext; export interface Config { dashboardId?: string; diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.test.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.test.ts index a5a82112ac91d2..0d22f0a36d418b 100644 --- a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.test.ts +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.test.ts @@ -10,8 +10,8 @@ import { coreMock } from '../../../../../../src/core/public/mocks'; import { UrlGeneratorContract } from '../../../../../../src/plugins/share/public'; import { EmbeddableStart, - RangeSelectTriggerContext, - ValueClickTriggerContext, + RangeSelectContext, + ValueClickContext, ChartActionContext, } from '../../../../../../src/plugins/embeddable/public'; import { i18n } from '@kbn/i18n'; @@ -85,8 +85,8 @@ const setup = ({ useRangeEvent = false }: { useRangeEvent?: boolean } = {}) => { const data: ChartActionContext['data'] = { ...(useRangeEvent - ? ({ range: {} } as RangeSelectTriggerContext['data']) - : ({ data: [] } as ValueClickTriggerContext['data'])), + ? ({ range: {} } as RangeSelectContext['data']) + : ({ data: [] } as ValueClickContext['data'])), timeFieldName: 'order_date', }; diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.ts index 5e7ae39c797373..658a6bcb3cf4d5 100644 --- a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.ts +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.ts @@ -6,8 +6,8 @@ import { Action } from '../../../../../../src/plugins/ui_actions/public'; import { - ValueClickTriggerContext, - RangeSelectTriggerContext, + ValueClickContext, + RangeSelectContext, } from '../../../../../../src/plugins/embeddable/public'; import { DiscoverUrlGeneratorState } from '../../../../../../src/plugins/discover/public'; import { isTimeRange, isQuery, isFilters } from '../../../../../../src/plugins/data/public'; @@ -15,7 +15,7 @@ import { KibanaURL } from './kibana_url'; import * as shared from './shared'; import { AbstractExploreDataAction } from './abstract_explore_data_action'; -export type ExploreDataChartActionContext = ValueClickTriggerContext | RangeSelectTriggerContext; +export type ExploreDataChartActionContext = ValueClickContext | RangeSelectContext; export const ACTION_EXPLORE_DATA_CHART = 'ACTION_EXPLORE_DATA_CHART'; From 54f84b5e0abd0bc83d46041cb3f9e607a56db78d Mon Sep 17 00:00:00 2001 From: streamich Date: Fri, 26 Jun 2020 16:28:31 +0200 Subject: [PATCH 25/25] =?UTF-8?q?chore:=20=F0=9F=A4=96=20fix=20TypeScript?= =?UTF-8?q?=20errors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../public/dashboard_hello_world_drilldown/index.tsx | 7 ++----- .../public/dashboard_to_discover_drilldown/types.ts | 7 ++----- .../public/dashboard_to_url_drilldown/index.tsx | 7 ++----- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_hello_world_drilldown/index.tsx b/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_hello_world_drilldown/index.tsx index bfe853241ae1dc..2598d66c4976f1 100644 --- a/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_hello_world_drilldown/index.tsx +++ b/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_hello_world_drilldown/index.tsx @@ -8,13 +8,10 @@ import React from 'react'; import { EuiFormRow, EuiFieldText } from '@elastic/eui'; import { reactToUiComponent } from '../../../../../src/plugins/kibana_react/public'; import { UiActionsEnhancedDrilldownDefinition as Drilldown } from '../../../../plugins/ui_actions_enhanced/public'; -import { - RangeSelectTriggerContext, - ValueClickTriggerContext, -} from '../../../../../src/plugins/embeddable/public'; +import { ChartActionContext } from '../../../../../src/plugins/embeddable/public'; import { CollectConfigProps } from '../../../../../src/plugins/kibana_utils/public'; -export type ActionContext = RangeSelectTriggerContext | ValueClickTriggerContext; +export type ActionContext = ChartActionContext; export interface Config { name: string; diff --git a/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_to_discover_drilldown/types.ts b/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_to_discover_drilldown/types.ts index 5dfc250a56d288..d8147827ed473f 100644 --- a/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_to_discover_drilldown/types.ts +++ b/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_to_discover_drilldown/types.ts @@ -4,13 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - RangeSelectTriggerContext, - ValueClickTriggerContext, -} from '../../../../../src/plugins/embeddable/public'; +import { ChartActionContext } from '../../../../../src/plugins/embeddable/public'; import { CollectConfigProps as CollectConfigPropsBase } from '../../../../../src/plugins/kibana_utils/public'; -export type ActionContext = RangeSelectTriggerContext | ValueClickTriggerContext; +export type ActionContext = ChartActionContext; export interface Config { /** diff --git a/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_to_url_drilldown/index.tsx b/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_to_url_drilldown/index.tsx index 4810fb2d6ad8da..005421ec8c50e1 100644 --- a/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_to_url_drilldown/index.tsx +++ b/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_to_url_drilldown/index.tsx @@ -8,10 +8,7 @@ import React from 'react'; import { EuiFormRow, EuiSwitch, EuiFieldText, EuiCallOut, EuiSpacer } from '@elastic/eui'; import { reactToUiComponent } from '../../../../../src/plugins/kibana_react/public'; import { UiActionsEnhancedDrilldownDefinition as Drilldown } from '../../../../plugins/ui_actions_enhanced/public'; -import { - RangeSelectTriggerContext, - ValueClickTriggerContext, -} from '../../../../../src/plugins/embeddable/public'; +import { ChartActionContext } from '../../../../../src/plugins/embeddable/public'; import { CollectConfigProps as CollectConfigPropsBase } from '../../../../../src/plugins/kibana_utils/public'; function isValidUrl(url: string) { @@ -23,7 +20,7 @@ function isValidUrl(url: string) { } } -export type ActionContext = RangeSelectTriggerContext | ValueClickTriggerContext; +export type ActionContext = ChartActionContext; export interface Config { url: string;