From 42effdde84942c8ae50ac227ea63c36929090bda Mon Sep 17 00:00:00 2001 From: Vadim Dalecky Date: Wed, 1 Jul 2020 03:16:23 -0700 Subject: [PATCH] Enable "Explore underlying data" actions for Lens visualizations (#70047) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: 💡 rename folder to "explore_data" * style: 💄 check for "share" plugin in more semantic way "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. * refactor: 💡 move KibanaURL to a separate file * feat: 🎸 add "Explore underlying data" in-chart action * fix: 🐛 fix imports after refactor * feat: 🎸 add start.filtersFromContext to embeddable plugin * feat: 🎸 add type checkers to data plugin * feat: 🎸 better handle empty filters in Discover URL generator * feat: 🎸 implement .getUrl() method of explore data in-chart act * feat: 🎸 add embeddable.filtersAndTimeRangeFromContext() * feat: 🎸 improve getUrl() method of explore data action * test: 💍 update test mock * fix possible stale hashHistory.location in discover * style: 💄 ensureHashHistoryLocation -> syncHistoryLocations * docs: ✏️ update autogenerated docs * test: 💍 add in-chart "Explore underlying data" unit tests * test: 💍 add in-chart "Explore underlying data" functional tests * test: 💍 clean-up custom time range after panel action tests * chore: 🤖 fix embeddable plugin mocks * chore: 🤖 fix another mock * test: 💍 add support for new action to pie chart service * feat: 🎸 enable "Explore underlying data" action for Lens vis * test: 💍 make tests green again * refactor: 💡 rename trigger contexts * chore: 🤖 fix TypeScript errors Co-authored-by: Anton Dosov Co-authored-by: Elastic Machine --- .../create_filters_from_range_select.ts | 4 +-- .../create_filters_from_value_click.test.ts | 4 +-- .../create_filters_from_value_click.ts | 4 +-- .../public/actions/select_range_action.ts | 4 +-- .../data/public/actions/value_click_action.ts | 4 +-- src/plugins/embeddable/public/index.ts | 4 +-- .../public/lib/triggers/triggers.ts | 12 ++++----- src/plugins/ui_actions/public/types.ts | 6 ++--- .../dashboard_hello_world_drilldown/index.tsx | 7 ++--- .../dashboard_to_discover_drilldown/types.ts | 7 ++--- .../dashboard_to_url_drilldown/index.tsx | 7 ++--- .../drilldown.test.tsx | 8 +++--- .../dashboard_to_dashboard_drilldown/types.ts | 8 +++--- .../abstract_explore_data_action.ts | 7 +++-- .../explore_data_chart_action.test.ts | 21 ++++++++++----- .../explore_data/explore_data_chart_action.ts | 8 +++--- .../explore_data_context_menu_action.test.ts | 13 ++++++--- .../explore_data_context_menu_action.ts | 2 +- .../public/actions/explore_data/shared.ts | 27 +++++-------------- 19 files changed, 74 insertions(+), 83 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/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 5e4ba54864461b..037e017097e533 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; 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/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.test.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.test.ts index a273f0d50e45e8..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', }; @@ -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_chart_action.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.ts index 359f14959c6a6a..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'; @@ -49,7 +49,7 @@ export class ExploreDataChartAction extends AbstractExploreDataAction { 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.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.ts index 6691089f875d86..8b79211a914cc3 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 @@ -38,7 +38,7 @@ export class ExploreDataContextMenuAction 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): boolean => + getIndexPatterns(embeddable).length === 1;