Skip to content

Commit

Permalink
Use "Apply_filter_trigger" in "explore underlying data" action (#71445)
Browse files Browse the repository at this point in the history
* use apply filter trigger for “expore underlying data”
* disable for maps for now

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
  • Loading branch information
Dosant and elasticmachine authored Aug 1, 2020
1 parent 01e6a4f commit 56e51bd
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 134 deletions.
1 change: 0 additions & 1 deletion src/plugins/embeddable/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"server": false,
"ui": true,
"requiredPlugins": [
"data",
"inspector",
"uiActions"
],
Expand Down
2 changes: 0 additions & 2 deletions src/plugins/embeddable/public/mocks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,6 @@ const createStartContract = (): Start => {
getAttributeService: jest.fn(),
getEmbeddablePanel: jest.fn(),
getStateTransfer: jest.fn(() => createEmbeddableStateTransferMock() as EmbeddableStateTransfer),
filtersAndTimeRangeFromContext: jest.fn(),
filtersFromContext: jest.fn(),
};
return startContract;
};
Expand Down
60 changes: 1 addition & 59 deletions src/plugins/embeddable/public/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,7 @@
* under the License.
*/
import React from 'react';
import {
DataPublicPluginSetup,
DataPublicPluginStart,
Filter,
TimeRange,
esFilters,
} from '../../data/public';
import { DataPublicPluginSetup, DataPublicPluginStart } from '../../data/public';
import { getSavedObjectFinder } from '../../saved_objects/public';
import { UiActionsSetup, UiActionsStart } from '../../ui_actions/public';
import { Start as InspectorStart } from '../../inspector/public';
Expand All @@ -44,9 +38,6 @@ import {
IEmbeddable,
EmbeddablePanel,
SavedObjectEmbeddableInput,
ChartActionContext,
isRangeSelectTriggerContext,
isValueClickTriggerContext,
} from './lib';
import { EmbeddableFactoryDefinition } from './lib/embeddables/embeddable_factory_definition';
import { AttributeService } from './lib/embeddables/attribute_service';
Expand Down Expand Up @@ -92,18 +83,6 @@ export interface EmbeddableStart {
type: string
) => AttributeService<A, V, R>;

/**
* Given {@link ChartActionContext} returns a list of `data` plugin {@link Filter} entries.
*/
filtersFromContext: (context: ChartActionContext) => Promise<Filter[]>;

/**
* Returns possible time range and filters that can be constructed from {@link ChartActionContext} object.
*/
filtersAndTimeRangeFromContext: (
context: ChartActionContext
) => Promise<{ filters: Filter[]; timeRange?: TimeRange }>;

EmbeddablePanel: EmbeddablePanelHOC;
getEmbeddablePanel: (stateTransfer?: EmbeddableStateTransfer) => EmbeddablePanelHOC;
getStateTransfer: (history?: ScopedHistory) => EmbeddableStateTransfer;
Expand Down Expand Up @@ -155,41 +134,6 @@ export class EmbeddablePublicPlugin implements Plugin<EmbeddableSetup, Embeddabl
this.outgoingOnlyStateTransfer = new EmbeddableStateTransfer(core.application.navigateToApp);
this.isRegistryReady = true;

const filtersFromContext: EmbeddableStart['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 [];
};

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,
};
};

const getEmbeddablePanelHoc = (stateTransfer?: EmbeddableStateTransfer) => ({
embeddable,
hideHeader,
Expand All @@ -216,8 +160,6 @@ export class EmbeddablePublicPlugin implements Plugin<EmbeddableSetup, Embeddabl
getEmbeddableFactory: this.getEmbeddableFactory,
getEmbeddableFactories: this.getEmbeddableFactories,
getAttributeService: (type: string) => new AttributeService(type, core.savedObjects.client),
filtersFromContext,
filtersAndTimeRangeFromContext,
getStateTransfer: (history?: ScopedHistory) => {
return history
? new EmbeddableStateTransfer(core.application.navigateToApp, history)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ import { Trigger } from '.';
export const APPLY_FILTER_TRIGGER = 'FILTER_TRIGGER';
export const applyFilterTrigger: Trigger<'FILTER_TRIGGER'> = {
id: APPLY_FILTER_TRIGGER,
title: 'Filter click',
title: 'Apply filter',
description: 'Triggered when user applies filter to an embeddable.',
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

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 { KibanaLegacyStart } from '../../../../../../src/plugins/kibana_legacy/public';
Expand All @@ -18,7 +17,6 @@ export const ACTION_EXPLORE_DATA = 'ACTION_EXPLORE_DATA';

export interface PluginDeps {
discover: Pick<DiscoverStart, 'urlGenerator'>;
embeddable: Pick<EmbeddableStart, 'filtersAndTimeRangeFromContext'>;
kibanaLegacy?: {
dashboardConfig: {
getHideWriteControls: KibanaLegacyStart['dashboardConfig']['getHideWriteControls'];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,14 @@ 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,
RangeSelectContext,
ValueClickContext,
ChartActionContext,
} from '../../../../../../src/plugins/embeddable/public';
import { ExploreDataChartActionContext } from './explore_data_chart_action';
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';
import { Filter, RangeFilter } from '../../../../../../src/plugins/data/public';

const i18nTranslateSpy = (i18n.translate as unknown) as jest.SpyInstance;

Expand All @@ -34,10 +29,19 @@ afterEach(() => {
i18nTranslateSpy.mockClear();
});

const setup = ({
useRangeEvent = false,
dashboardOnlyMode = false,
}: { useRangeEvent?: boolean; dashboardOnlyMode?: boolean } = {}) => {
const setup = (
{
useRangeEvent = false,
timeFieldName,
filters = [],
dashboardOnlyMode = false,
}: {
useRangeEvent?: boolean;
filters?: Filter[];
timeFieldName?: string;
dashboardOnlyMode?: boolean;
} = { filters: [] }
) => {
type UrlGenerator = UrlGeneratorContract<'DISCOVER_APP_URL_GENERATOR'>;

const core = coreMock.createStart();
Expand All @@ -46,17 +50,10 @@ 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,
},
kibanaLegacy: {
dashboardConfig: {
getHideWriteControls: () => dashboardOnlyMode,
Expand Down Expand Up @@ -91,19 +88,13 @@ const setup = ({
getOutput: () => output,
} as unknown) as VisualizeEmbeddableContract;

const data: ChartActionContext<typeof embeddable>['data'] = {
...(useRangeEvent
? ({ range: {} } as RangeSelectContext['data'])
: ({ data: [] } as ValueClickContext['data'])),
timeFieldName: 'order_date',
};

const context = {
filters,
timeFieldName,
embeddable,
data,
} as ChartActionContext<typeof embeddable>;
} as ExploreDataChartActionContext;

return { core, plugins, urlGenerator, params, action, input, output, embeddable, data, context };
return { core, plugins, urlGenerator, params, action, input, output, embeddable, context };
};

describe('"Explore underlying data" panel action', () => {
Expand Down Expand Up @@ -236,32 +227,41 @@ describe('"Explore underlying data" panel action', () => {
});

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 timeFieldName = 'timeField';
const from = '2020-07-13T13:40:43.583Z';
const to = '2020-07-13T13:44:43.583Z';
const filters: Array<Filter | RangeFilter> = [
{
meta: {
alias: 'alias',
disabled: false,
negate: false,
},
},
{
meta: {
alias: 'alias',
disabled: false,
negate: false,
field: timeFieldName,
params: {
gte: from,
lte: to,
},
},
];
const timeRange: TimeRange = {
from: 'from',
to: 'to',
};
return { filters, timeRange };
});
range: {
[timeFieldName]: {
gte: from,
lte: to,
},
},
},
];

expect(plugins.embeddable.filtersAndTimeRangeFromContext).toHaveBeenCalledTimes(0);
const { action, context, urlGenerator } = setup({ filters, timeFieldName });

await action.getHref(context);

expect(plugins.embeddable.filtersAndTimeRangeFromContext).toHaveBeenCalledTimes(1);
expect(plugins.embeddable.filtersAndTimeRangeFromContext).toHaveBeenCalledWith(context);
expect(urlGenerator.createUrl).toHaveBeenCalledWith({
filters: [
{
Expand All @@ -274,8 +274,8 @@ describe('"Explore underlying data" panel action', () => {
],
indexPatternId: 'index-ptr-foo',
timeRange: {
from: 'from',
to: 'to',
from,
to,
},
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@
*/

import { Action } from '../../../../../../src/plugins/ui_actions/public';
import {
ValueClickContext,
RangeSelectContext,
} from '../../../../../../src/plugins/embeddable/public';
import { DiscoverUrlGeneratorState } from '../../../../../../src/plugins/discover/public';
import { isTimeRange, isQuery, isFilters } from '../../../../../../src/plugins/data/public';
import {
isTimeRange,
isQuery,
isFilters,
ApplyGlobalFilterActionContext,
esFilters,
} from '../../../../../../src/plugins/data/public';
import { KibanaURL } from './kibana_url';
import * as shared from './shared';
import { AbstractExploreDataAction } from './abstract_explore_data_action';

export type ExploreDataChartActionContext = ValueClickContext | RangeSelectContext;
export type ExploreDataChartActionContext = ApplyGlobalFilterActionContext;

export const ACTION_EXPLORE_DATA_CHART = 'ACTION_EXPLORE_DATA_CHART';

Expand All @@ -31,6 +33,11 @@ export class ExploreDataChartAction extends AbstractExploreDataAction<ExploreDat

public readonly order = 200;

public async isCompatible(context: ExploreDataChartActionContext): Promise<boolean> {
if (context.embeddable?.type === 'map') return false; // TODO: https://github.com/elastic/kibana/issues/73043
return super.isCompatible(context);
}

protected readonly getUrl = async (
context: ExploreDataChartActionContext
): Promise<KibanaURL> => {
Expand All @@ -42,7 +49,11 @@ export class ExploreDataChartAction extends AbstractExploreDataAction<ExploreDat
}

const { embeddable } = context;
const { filters, timeRange } = await plugins.embeddable.filtersAndTimeRangeFromContext(context);
const { restOfFilters: filters, timeRange } = esFilters.extractTimeRange(
context.filters,
context.timeFieldName
);

const state: DiscoverUrlGeneratorState = {
filters,
timeRange,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ 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';
import { EmbeddableStart } from '../../../../../../src/plugins/embeddable/public';
import { i18n } from '@kbn/i18n';
import {
VisualizeEmbeddableContract,
Expand Down Expand Up @@ -37,17 +36,10 @@ const setup = ({ dashboardOnlyMode = false }: { dashboardOnlyMode?: boolean } =
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,
},
kibanaLegacy: {
dashboardConfig: {
getHideWriteControls: () => dashboardOnlyMode,
Expand Down
6 changes: 2 additions & 4 deletions x-pack/plugins/discover_enhanced/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import { PluginInitializerContext } from 'kibana/public';
import {
UiActionsSetup,
UiActionsStart,
SELECT_RANGE_TRIGGER,
VALUE_CLICK_TRIGGER,
APPLY_FILTER_TRIGGER,
} from '../../../../src/plugins/ui_actions/public';
import { createStartServicesGetter } from '../../../../src/plugins/kibana_utils/public';
import { DiscoverSetup, DiscoverStart } from '../../../../src/plugins/discover/public';
Expand Down Expand Up @@ -77,8 +76,7 @@ export class DiscoverEnhancedPlugin

if (this.config.actions.exploreDataInChart.enabled) {
const exploreDataChartAction = new ExploreDataChartAction(params);
uiActions.addTriggerAction(SELECT_RANGE_TRIGGER, exploreDataChartAction);
uiActions.addTriggerAction(VALUE_CLICK_TRIGGER, exploreDataChartAction);
uiActions.addTriggerAction(APPLY_FILTER_TRIGGER, exploreDataChartAction);
}
}
}
Expand Down

0 comments on commit 56e51bd

Please sign in to comment.