Skip to content

Commit

Permalink
Lens drilldowns (#65675)
Browse files Browse the repository at this point in the history
  • Loading branch information
flash1293 authored May 15, 2020
1 parent f7a8960 commit 5207009
Show file tree
Hide file tree
Showing 34 changed files with 521 additions and 298 deletions.
8 changes: 4 additions & 4 deletions src/plugins/data/public/actions/select_range_action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,16 @@ export function selectRangeAction(
});
},
isCompatible,
execute: async ({ timeFieldName, data }: SelectRangeActionContext) => {
if (!(await isCompatible({ timeFieldName, data }))) {
execute: async ({ data }: SelectRangeActionContext) => {
if (!(await isCompatible({ data }))) {
throw new IncompatibleActionError();
}

const selectedFilters = await createFiltersFromRangeSelectAction(data);

if (timeFieldName) {
if (data.timeFieldName) {
const { timeRangeFilter, restOfFilters } = esFilters.extractTimeFilter(
timeFieldName,
data.timeFieldName,
selectedFilters
);
filterManager.addFilters(restOfFilters);
Expand Down
10 changes: 5 additions & 5 deletions src/plugins/data/public/actions/value_click_action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ export function valueClickAction(
});
},
isCompatible,
execute: async (context: ValueClickActionContext) => {
if (!(await isCompatible(context))) {
execute: async ({ data }: ValueClickActionContext) => {
if (!(await isCompatible({ data }))) {
throw new IncompatibleActionError();
}

const filters: Filter[] = await createFiltersFromValueClickAction(context.data);
const filters: Filter[] = await createFiltersFromValueClickAction(data);

let selectedFilters = filters;

Expand Down Expand Up @@ -98,9 +98,9 @@ export function valueClickAction(
selectedFilters = await filterSelectionPromise;
}

if (context.timeFieldName) {
if (data.timeFieldName) {
const { timeRangeFilter, restOfFilters } = esFilters.extractTimeFilter(
context.timeFieldName,
data.timeFieldName,
selectedFilters
);
filterManager.addFilters(restOfFilters);
Expand Down
4 changes: 2 additions & 2 deletions src/plugins/embeddable/public/lib/triggers/triggers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ export interface EmbeddableContext {

export interface ValueClickTriggerContext<T extends IEmbeddable = IEmbeddable> {
embeddable?: T;
timeFieldName?: string;
data: {
data: Array<{
table: Pick<KibanaDatatable, 'rows' | 'columns'>;
column: number;
row: number;
value: any;
}>;
timeFieldName?: string;
negate?: boolean;
};
}
Expand All @@ -45,11 +45,11 @@ export const isValueClickTriggerContext = (

export interface RangeSelectTriggerContext<T extends IEmbeddable = IEmbeddable> {
embeddable?: T;
timeFieldName?: string;
data: {
table: KibanaDatatable;
column: number;
range: number[];
timeFieldName?: string;
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,8 +264,7 @@ export class VisualizeEmbeddable extends Embeddable<VisualizeInput, VisualizeOut
event.name === 'brush' ? VIS_EVENT_TO_TRIGGER.brush : VIS_EVENT_TO_TRIGGER.filter;
const context = {
embeddable: this,
timeFieldName: this.vis.data.indexPattern!.timeFieldName!,
data: event.data,
data: { timeFieldName: this.vis.data.indexPattern?.timeFieldName!, ...event.data },
};

getUiActions()
Expand Down
30 changes: 0 additions & 30 deletions x-pack/plugins/canvas/public/application.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ import { getDocumentationLinks } from './lib/documentation_links';
import { HelpMenu } from './components/help_menu/help_menu';
import { createStore, destroyStore } from './store';

import { VALUE_CLICK_TRIGGER, ActionByType } from '../../../../src/plugins/ui_actions/public';
/* eslint-disable */
import { ACTION_VALUE_CLICK } from '../../../../src/plugins/data/public/actions/value_click_action';
/* eslint-enable */
import { init as initStatsReporter } from './lib/ui_metric';

Expand All @@ -45,16 +42,6 @@ import './style/index.scss';

const { ReadOnlyBadge: strings } = CapabilitiesStrings;

let restoreAction: ActionByType<any> | undefined;
const emptyAction = {
id: 'empty-action',
type: '',
getDisplayName: () => 'empty action',
getIconType: () => undefined,
isCompatible: async () => true,
execute: async () => undefined,
} as ActionByType<any>;

export const renderApp = (
coreStart: CoreStart,
plugins: CanvasStartDeps,
Expand Down Expand Up @@ -134,17 +121,6 @@ export const initializeCanvas = async (
},
});

// TODO: We need this to disable the filtering modal from popping up in lens embeds until
// they honor the disableTriggers parameter
const action = startPlugins.uiActions.getAction(ACTION_VALUE_CLICK);

if (action) {
restoreAction = action;

startPlugins.uiActions.detachAction(VALUE_CLICK_TRIGGER, action.id);
startPlugins.uiActions.addTriggerAction(VALUE_CLICK_TRIGGER, emptyAction);
}

if (setupPlugins.usageCollection) {
initStatsReporter(setupPlugins.usageCollection.reportUiStats);
}
Expand All @@ -158,12 +134,6 @@ export const teardownCanvas = (coreStart: CoreStart, startPlugins: CanvasStartDe
resetInterpreter();
destroyStore();

startPlugins.uiActions.detachAction(VALUE_CLICK_TRIGGER, emptyAction.id);
if (restoreAction) {
startPlugins.uiActions.addTriggerAction(VALUE_CLICK_TRIGGER, restoreAction);
restoreAction = undefined;
}

coreStart.chrome.setBadge(undefined);
coreStart.chrome.setHelpExtension(undefined);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,6 @@ export class FlyoutCreateDrilldownAction implements ActionByType<typeof OPEN_FLY
if (!supportedTriggers || !supportedTriggers.length) return false;
if (context.embeddable.getRoot().type !== 'dashboard') return false;

/**
* Temporarily disable drilldowns for Lens as Lens embeddable does not have
* `.embeddable` field on VALUE_CLICK_TRIGGER context.
*
* @todo Remove this condition once Lens adds `.embeddable` to field to context.
*/
if (context.embeddable.type === 'lens') return false;

return supportedTriggers.indexOf('VALUE_CLICK_TRIGGER') > -1;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,12 @@ describe('.execute() & getHref', () => {
};

const context = ({
data: useRangeEvent
? ({ range: {} } as RangeSelectTriggerContext['data'])
: ({ data: [] } as ValueClickTriggerContext['data']),
timeFieldName: 'order_date',
data: {
...(useRangeEvent
? ({ range: {} } as RangeSelectTriggerContext['data'])
: ({ data: [] } as ValueClickTriggerContext['data'])),
timeFieldName: 'order_date',
},
embeddable: {
getInput: () => ({
filters: [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,9 @@ export class DashboardToDashboardDrilldown
}
})();

if (context.timeFieldName) {
if (context.data.timeFieldName) {
const { timeRangeFilter, restOfFilters } = esFilters.extractTimeFilter(
context.timeFieldName,
context.data.timeFieldName,
filtersFromEvent
);
filtersFromEvent = restOfFilters;
Expand Down
3 changes: 1 addition & 2 deletions x-pack/plugins/lens/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@
"expressions",
"navigation",
"kibanaLegacy",
"uiActions",
"visualizations",
"dashboard"
],
"optionalPlugins": ["embeddable", "usageCollection", "taskManager"],
"optionalPlugins": ["embeddable", "usageCollection", "taskManager", "uiActions"],
"configPath": ["xpack", "lens"]
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { DatatableProps } from './expression';
import { createMockExecutionContext } from '../../../../../src/plugins/expressions/common/mocks';
import { IFieldFormat } from '../../../../../src/plugins/data/public';
import { IAggType } from 'src/plugins/data/public';
const executeTriggerActions = jest.fn();
const onClickValue = jest.fn();

function sampleArgs() {
const data: LensMultiTable = {
Expand Down Expand Up @@ -66,7 +66,7 @@ describe('datatable_expression', () => {
data={data}
args={args}
formatFactory={x => x as IFieldFormat}
executeTriggerActions={executeTriggerActions}
onClickValue={onClickValue}
getType={jest.fn()}
/>
)
Expand All @@ -87,7 +87,7 @@ describe('datatable_expression', () => {
}}
args={args}
formatFactory={x => x as IFieldFormat}
executeTriggerActions={executeTriggerActions}
onClickValue={onClickValue}
getType={jest.fn(() => ({ type: 'buckets' } as IAggType))}
/>
);
Expand All @@ -97,18 +97,16 @@ describe('datatable_expression', () => {
.first()
.simulate('click');

expect(executeTriggerActions).toHaveBeenCalledWith('VALUE_CLICK_TRIGGER', {
data: {
data: [
{
column: 0,
row: 0,
table: data.tables.l1,
value: 10110,
},
],
negate: true,
},
expect(onClickValue).toHaveBeenCalledWith({
data: [
{
column: 0,
row: 0,
table: data.tables.l1,
value: 10110,
},
],
negate: true,
timeFieldName: undefined,
});
});
Expand All @@ -127,7 +125,7 @@ describe('datatable_expression', () => {
}}
args={args}
formatFactory={x => x as IFieldFormat}
executeTriggerActions={executeTriggerActions}
onClickValue={onClickValue}
getType={jest.fn(() => ({ type: 'buckets' } as IAggType))}
/>
);
Expand All @@ -137,18 +135,16 @@ describe('datatable_expression', () => {
.at(3)
.simulate('click');

expect(executeTriggerActions).toHaveBeenCalledWith('VALUE_CLICK_TRIGGER', {
data: {
data: [
{
column: 1,
row: 0,
table: data.tables.l1,
value: 1588024800000,
},
],
negate: false,
},
expect(onClickValue).toHaveBeenCalledWith({
data: [
{
column: 1,
row: 0,
table: data.tables.l1,
value: 1588024800000,
},
],
negate: false,
timeFieldName: 'b',
});
});
Expand Down
46 changes: 23 additions & 23 deletions x-pack/plugins/lens/public/datatable_visualization/expression.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ import { i18n } from '@kbn/i18n';
import { I18nProvider } from '@kbn/i18n/react';
import { EuiBasicTable, EuiFlexGroup, EuiButtonIcon, EuiFlexItem, EuiToolTip } from '@elastic/eui';
import { IAggType } from 'src/plugins/data/public';
import { FormatFactory, LensMultiTable } from '../types';
import {
FormatFactory,
ILensInterpreterRenderHandlers,
LensFilterEvent,
LensMultiTable,
} from '../types';
import {
ExpressionFunctionDefinition,
ExpressionRenderDefinition,
IInterpreterRenderHandlers,
} from '../../../../../src/plugins/expressions/public';
import { VisualizationContainer } from '../visualization_container';
import { ValueClickTriggerContext } from '../../../../../src/plugins/embeddable/public';
import { VIS_EVENT_TO_TRIGGER } from '../../../../../src/plugins/visualizations/public';
import { UiActionsStart } from '../../../../../src/plugins/ui_actions/public';
import { getExecuteTriggerActions } from '../services';
export interface DatatableColumns {
columnIds: string[];
}
Expand All @@ -37,7 +37,7 @@ export interface DatatableProps {

type DatatableRenderProps = DatatableProps & {
formatFactory: FormatFactory;
executeTriggerActions: UiActionsStart['executeTriggerActions'];
onClickValue: (data: LensFilterEvent['data']) => void;
getType: (name: string) => IAggType;
};

Expand Down Expand Up @@ -125,17 +125,19 @@ export const getDatatableRenderer = (dependencies: {
render: async (
domNode: Element,
config: DatatableProps,
handlers: IInterpreterRenderHandlers
handlers: ILensInterpreterRenderHandlers
) => {
const resolvedFormatFactory = await dependencies.formatFactory;
const executeTriggerActions = getExecuteTriggerActions();
const resolvedGetType = await dependencies.getType;
const onClickValue = (data: LensFilterEvent['data']) => {
handlers.event({ name: 'filter', data });
};
ReactDOM.render(
<I18nProvider>
<DatatableComponent
{...config}
formatFactory={resolvedFormatFactory}
executeTriggerActions={executeTriggerActions}
onClickValue={onClickValue}
getType={resolvedGetType}
/>
</I18nProvider>,
Expand All @@ -162,21 +164,19 @@ export function DatatableComponent(props: DatatableRenderProps) {
const timeFieldName = negate && isDateHistogram ? undefined : col?.meta?.aggConfigParams?.field;
const rowIndex = firstTable.rows.findIndex(row => row[field] === value);

const context: ValueClickTriggerContext = {
data: {
negate,
data: [
{
row: rowIndex,
column: colIndex,
value,
table: firstTable,
},
],
},
const data: LensFilterEvent['data'] = {
negate,
data: [
{
row: rowIndex,
column: colIndex,
value,
table: firstTable,
},
],
timeFieldName,
};
props.executeTriggerActions(VIS_EVENT_TO_TRIGGER.filter, context);
props.onClickValue(data);
};

return (
Expand Down
Loading

0 comments on commit 5207009

Please sign in to comment.