Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[7.x] refactor action filter creation utils (#62969) #64143

Merged
merged 1 commit into from
Apr 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

```typescript
actions: {
createFiltersFromEvent: typeof createFiltersFromEvent;
createFiltersFromValueClickAction: typeof createFiltersFromValueClickAction;
createFiltersFromRangeSelectAction: typeof createFiltersFromRangeSelectAction;
};
```
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export interface DataPublicPluginStart

| Property | Type | Description |
| --- | --- | --- |
| [actions](./kibana-plugin-plugins-data-public.datapublicpluginstart.actions.md) | <code>{</code><br/><code> createFiltersFromEvent: typeof createFiltersFromEvent;</code><br/><code> }</code> | |
| [actions](./kibana-plugin-plugins-data-public.datapublicpluginstart.actions.md) | <code>{</code><br/><code> createFiltersFromValueClickAction: typeof createFiltersFromValueClickAction;</code><br/><code> createFiltersFromRangeSelectAction: typeof createFiltersFromRangeSelectAction;</code><br/><code> }</code> | |
| [autocomplete](./kibana-plugin-plugins-data-public.datapublicpluginstart.autocomplete.md) | <code>AutocompleteStart</code> | |
| [fieldFormats](./kibana-plugin-plugins-data-public.datapublicpluginstart.fieldformats.md) | <code>FieldFormatsStart</code> | |
| [indexPatterns](./kibana-plugin-plugins-data-public.datapublicpluginstart.indexpatterns.md) | <code>IndexPatternsContract</code> | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
fieldFormats: {
FieldFormat: typeof FieldFormat;
FieldFormatsRegistry: typeof FieldFormatsRegistry;
serialize: (agg: import("./search").AggConfig) => import("../../expressions/common").SerializedFieldFormat<object>;
serialize: (agg: import("./search").AggConfig) => import("../../expressions").SerializedFieldFormat<object>;
DEFAULT_CONVERTER_COLOR: {
range: string;
regex: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
fieldFormats: {
FieldFormatsRegistry: typeof FieldFormatsRegistry;
FieldFormat: typeof FieldFormat;
serializeFieldFormat: (agg: import("../public/search").AggConfig) => import("../../expressions/common").SerializedFieldFormat<object>;
serializeFieldFormat: (agg: import("../public/search").AggConfig) => import("../../expressions").SerializedFieldFormat<object>;
BoolFormat: typeof BoolFormat;
BytesFormat: typeof BytesFormat;
ColorFormat: typeof ColorFormat;
Expand Down
2 changes: 1 addition & 1 deletion src/legacy/core_plugins/vis_type_vislib/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,6 @@ export class VisTypeVislibPlugin implements Plugin<void, void> {

public start(core: CoreStart, { data }: VisTypeVislibPluginStartDependencies) {
setFormatService(data.fieldFormats);
setDataActions({ createFiltersFromEvent: data.actions.createFiltersFromEvent });
setDataActions(data.actions);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ jest.mock('../../../legacy_imports', () => ({
}));

jest.mock('../../../services', () => ({
getDataActions: () => ({ createFiltersFromEvent: jest.fn().mockResolvedValue(['yes']) }),
getDataActions: () => ({
createFiltersFromValueClickAction: jest.fn().mockResolvedValue(['yes']),
}),
}));

const vis = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export class VisLegend extends PureComponent<VisLegendProps, VisLegendState> {
return false;
}

const filters = await getDataActions().createFiltersFromEvent(item.values);
const filters = await getDataActions().createFiltersFromValueClickAction({ data: item.values });
return Boolean(filters.length);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,21 @@ export class Handler {

// memoize so that the same function is returned every time,
// allowing us to remove/re-add the same function
this.getProxyHandler = _.memoize(function(event) {
this.getProxyHandler = _.memoize(function(eventType) {
const self = this;
return function(e) {
self.vis.emit(event, e);
return function(eventPayload) {
switch (eventType) {
case 'brush':
const xRaw = _.get(eventPayload.data, 'series[0].values[0].xRaw');
if (!xRaw) return; // not sure if this is possible?
return self.vis.emit(eventType, {
table: xRaw.table,
range: eventPayload.range,
column: xRaw.column,
});
case 'click':
return self.vis.emit(eventType, eventPayload);
}
};
});

Expand Down
3 changes: 2 additions & 1 deletion src/legacy/ui/public/new_platform/new_platform.karma_mock.js
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,8 @@ export const npStart = {
},
data: {
actions: {
createFiltersFromEvent: Promise.resolve(['yes']),
createFiltersFromValueClickAction: Promise.resolve(['yes']),
createFiltersFromRangeSelectAction: sinon.fake(),
},
autocomplete: {
getProvider: sinon.fake(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,87 +19,72 @@

import moment from 'moment';

import { onBrushEvent, BrushEvent } from './brush_event';
import { createFiltersFromRangeSelectAction } from './create_filters_from_range_select';

import { IndexPatternsContract } from '../../../public';
import { IndexPatternsContract, RangeFilter } from '../../../public';
import { dataPluginMock } from '../../../public/mocks';
import { setIndexPatterns } from '../../../public/services';
import { mockDataServices } from '../../../public/search/aggs/test_helpers';
import { TriggerContextMapping } from '../../../../ui_actions/public';

describe('brushEvent', () => {
const DAY_IN_MS = 24 * 60 * 60 * 1000;
const JAN_01_2014 = 1388559600000;
let baseEvent: BrushEvent;
let baseEvent: TriggerContextMapping['SELECT_RANGE_TRIGGER']['data'];

const indexPattern = {
id: 'indexPatternId',
timeFieldName: 'time',
fields: {
getByName: () => undefined,
filter: () => [],
},
};

const aggConfigs = [
{
params: {
field: {},
},
getIndexPattern: () => ({
timeFieldName: 'time',
fields: {
getByName: () => undefined,
filter: () => [],
},
}),
getIndexPattern: () => indexPattern,
},
];

beforeEach(() => {
mockDataServices();
setIndexPatterns(({
...dataPluginMock.createStartContract().indexPatterns,
get: async () => ({
id: 'indexPatternId',
timeFieldName: 'time',
fields: {
getByName: () => undefined,
filter: () => [],
},
}),
get: async () => indexPattern,
} as unknown) as IndexPatternsContract);

baseEvent = {
data: {
ordered: {
date: false,
},
series: [
column: 0,
table: {
type: 'kibana_datatable',
columns: [
{
values: [
{
xRaw: {
column: 0,
table: {
columns: [
{
id: '1',
meta: {
type: 'histogram',
indexPatternId: 'indexPatternId',
aggConfigParams: aggConfigs[0].params,
},
},
],
},
},
},
],
id: '1',
name: '1',
meta: {
type: 'histogram',
indexPatternId: 'indexPatternId',
aggConfigParams: aggConfigs[0].params,
},
},
],
rows: [],
},
range: [],
};
});

test('should be a function', () => {
expect(typeof onBrushEvent).toBe('function');
expect(typeof createFiltersFromRangeSelectAction).toBe('function');
});

test('ignores event when data.xAxisField not provided', async () => {
const filter = await onBrushEvent(baseEvent);
expect(filter).toBeUndefined();
const filter = await createFiltersFromRangeSelectAction(baseEvent);
expect(filter).toEqual([]);
});

describe('handles an event when the x-axis field is a date field', () => {
Expand All @@ -109,29 +94,29 @@ describe('brushEvent', () => {
name: 'time',
type: 'date',
};
baseEvent.data.ordered = { date: true };
});

afterAll(() => {
baseEvent.range = [];
baseEvent.data.ordered = { date: false };
aggConfigs[0].params.field = {};
});

test('by ignoring the event when range spans zero time', async () => {
baseEvent.range = [JAN_01_2014, JAN_01_2014];
const filter = await onBrushEvent(baseEvent);
expect(filter).toBeUndefined();
const filter = await createFiltersFromRangeSelectAction(baseEvent);
expect(filter).toEqual([]);
});

test('by updating the timefilter', async () => {
baseEvent.range = [JAN_01_2014, JAN_01_2014 + DAY_IN_MS];
const filter = await onBrushEvent(baseEvent);
const filter = await createFiltersFromRangeSelectAction(baseEvent);
expect(filter).toBeDefined();

if (filter) {
expect(filter.range.time.gte).toBe(new Date(JAN_01_2014).toISOString());
if (filter.length) {
const rangeFilter = filter[0] as RangeFilter;
expect(rangeFilter.range.time.gte).toBe(new Date(JAN_01_2014).toISOString());
// Set to a baseline timezone for comparison.
expect(filter.range.time.lt).toBe(new Date(JAN_01_2014 + DAY_IN_MS).toISOString());
expect(rangeFilter.range.time.lt).toBe(new Date(JAN_01_2014 + DAY_IN_MS).toISOString());
}
});
});
Expand All @@ -142,26 +127,26 @@ describe('brushEvent', () => {
name: 'anotherTimeField',
type: 'date',
};
baseEvent.data.ordered = { date: true };
});

afterAll(() => {
baseEvent.range = [];
baseEvent.data.ordered = { date: false };
aggConfigs[0].params.field = {};
});

test('creates a new range filter', async () => {
const rangeBegin = JAN_01_2014;
const rangeEnd = rangeBegin + DAY_IN_MS;
baseEvent.range = [rangeBegin, rangeEnd];
const filter = await onBrushEvent(baseEvent);
const filter = await createFiltersFromRangeSelectAction(baseEvent);

expect(filter).toBeDefined();

if (filter) {
expect(filter.range.anotherTimeField.gte).toBe(moment(rangeBegin).toISOString());
expect(filter.range.anotherTimeField.lt).toBe(moment(rangeEnd).toISOString());
expect(filter.range.anotherTimeField).toHaveProperty(
if (filter.length) {
const rangeFilter = filter[0] as RangeFilter;
expect(rangeFilter.range.anotherTimeField.gte).toBe(moment(rangeBegin).toISOString());
expect(rangeFilter.range.anotherTimeField.lt).toBe(moment(rangeEnd).toISOString());
expect(rangeFilter.range.anotherTimeField).toHaveProperty(
'format',
'strict_date_optional_time'
);
Expand All @@ -184,20 +169,21 @@ describe('brushEvent', () => {

test('by ignoring the event when range does not span at least 2 values', async () => {
baseEvent.range = [1];
const filter = await onBrushEvent(baseEvent);
expect(filter).toBeUndefined();
const filter = await createFiltersFromRangeSelectAction(baseEvent);
expect(filter).toEqual([]);
});

test('by creating a new filter', async () => {
baseEvent.range = [1, 2, 3, 4];
const filter = await onBrushEvent(baseEvent);
const filter = await createFiltersFromRangeSelectAction(baseEvent);

expect(filter).toBeDefined();

if (filter) {
expect(filter.range.numberField.gte).toBe(1);
expect(filter.range.numberField.lt).toBe(4);
expect(filter.range.numberField).not.toHaveProperty('format');
if (filter.length) {
const rangeFilter = filter[0] as RangeFilter;
expect(rangeFilter.range.numberField.gte).toBe(1);
expect(rangeFilter.range.numberField.lt).toBe(4);
expect(rangeFilter.range.numberField).not.toHaveProperty('format');
}
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,18 @@
* under the License.
*/

import { get, last } from 'lodash';
import { last } from 'lodash';
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';

export interface BrushEvent {
data: {
ordered: {
date: boolean;
};
series: Array<Record<string, any>>;
};
range: number[];
}

export async function onBrushEvent(event: BrushEvent) {
const isDate = get(event.data, 'ordered.date');
const xRaw: Record<string, any> = get(event.data, 'series[0].values[0].xRaw');

if (!xRaw) {
return;
}

const column: Record<string, any> = xRaw.table.columns[xRaw.column];
export async function createFiltersFromRangeSelectAction(event: RangeSelectTriggerContext['data']) {
const column: Record<string, any> = event.table.columns[event.column];

if (!column || !column.meta) {
return;
return [];
}

const indexPattern = await getIndexPatterns().get(column.meta.indexPatternId);
Expand All @@ -55,16 +39,18 @@ export async function onBrushEvent(event: BrushEvent) {
const field: IFieldType = aggConfig.params.field;

if (!field || event.range.length <= 1) {
return;
return [];
}

const min = event.range[0];
const max = last(event.range);

if (min === max) {
return;
return [];
}

const isDate = field.type === 'date';

const range: RangeFilterParams = {
gte: isDate ? moment(min).toISOString() : min,
lt: isDate ? moment(max).toISOString() : max,
Expand All @@ -74,5 +60,5 @@ export async function onBrushEvent(event: BrushEvent) {
range.format = 'strict_date_optional_time';
}

return esFilters.buildRangeFilter(field, range, indexPattern);
return esFilters.mapAndFlattenFilters([esFilters.buildRangeFilter(field, range, indexPattern)]);
}
Loading