Skip to content

Commit

Permalink
query pers state
Browse files Browse the repository at this point in the history
  • Loading branch information
Dosant committed May 20, 2022
1 parent f0cb40a commit 8ec1b06
Show file tree
Hide file tree
Showing 19 changed files with 334 additions and 100 deletions.
1 change: 1 addition & 0 deletions src/plugins/data/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export {
getTime,
isQuery,
isTimeRange,
QueryState,
} from './query';
export * from './search';
export type {
Expand Down
40 changes: 40 additions & 0 deletions src/plugins/data/common/query/filters/persistable_state.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { extract, inject } from './persistable_state';
import { Filter } from '@kbn/es-query';
import { DATA_VIEW_SAVED_OBJECT_TYPE } from '@kbn/data-views-plugin/common';

describe('filter manager persistable state tests', () => {
const filters: Filter[] = [
{ meta: { alias: 'test', disabled: false, negate: false, index: 'test' } },
];
describe('reference injection', () => {
test('correctly inserts reference to filter', () => {
const updatedFilters = inject(filters, [
{ type: DATA_VIEW_SAVED_OBJECT_TYPE, name: 'test', id: '123' },
]);
expect(updatedFilters[0]).toHaveProperty('meta.index', '123');
});

test('drops index setting if reference is missing', () => {
const updatedFilters = inject(filters, [
{ type: DATA_VIEW_SAVED_OBJECT_TYPE, name: 'test123', id: '123' },
]);
expect(updatedFilters[0]).toHaveProperty('meta.index', undefined);
});
});

describe('reference extraction', () => {
test('correctly extracts references', () => {
const { state, references } = extract(filters);
expect(state[0]).toHaveProperty('meta.index');
expect(references[0]).toHaveProperty('id', 'test');
});
});
});
65 changes: 65 additions & 0 deletions src/plugins/data/common/query/filters/persistable_state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import uuid from 'uuid';
import { Filter } from '@kbn/es-query';
import { SavedObjectReference } from '@kbn/core/types';
import { MigrateFunctionsObject, VersionedState } from '@kbn/kibana-utils-plugin/common';
import { DATA_VIEW_SAVED_OBJECT_TYPE } from '@kbn/data-views-plugin/common';

export const extract = (filters: Filter[]) => {
const references: SavedObjectReference[] = [];
const updatedFilters = filters.map((filter) => {
if (filter.meta?.index) {
const id = uuid();
references.push({
type: DATA_VIEW_SAVED_OBJECT_TYPE,
name: id,
id: filter.meta.index,
});

return {
...filter,
meta: {
...filter.meta,
index: id,
},
};
}
return filter;
});
return { state: updatedFilters, references };
};

export const inject = (filters: Filter[], references: SavedObjectReference[]) => {
return filters.map((filter) => {
if (!filter.meta.index) {
return filter;
}
const reference = references.find((ref) => ref.name === filter.meta.index);
return {
...filter,
meta: {
...filter.meta,
index: reference && reference.id,
},
};
});
};

export const telemetry = (filters: Filter[], collector: unknown) => {
return {};
};

export const migrateToLatest = (filters: VersionedState<Filter[]>) => {
return filters.state;
};

export const getAllMigrations = (): MigrateFunctionsObject => {
return {};
};
1 change: 1 addition & 0 deletions src/plugins/data/common/query/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@
export * from './timefilter';
export * from './types';
export * from './is_query';
export * from './query_state';
37 changes: 28 additions & 9 deletions src/plugins/data/common/query/persistable_state.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,52 @@

import { extract, inject } from './persistable_state';
import { Filter } from '@kbn/es-query';
import { DATA_VIEW_SAVED_OBJECT_TYPE } from '..';
import { DATA_VIEW_SAVED_OBJECT_TYPE } from '@kbn/data-views-plugin/common';
import { QueryState } from './query_state';

describe('filter manager persistable state tests', () => {
describe('query service persistable state tests', () => {
const filters: Filter[] = [
{ meta: { alias: 'test', disabled: false, negate: false, index: 'test' } },
];
const query = { language: 'kql', query: 'query' };
const time = { from: new Date().toISOString(), to: new Date().toISOString() };
const refreshInterval = { pause: false, value: 10 };

const queryState: QueryState = {
filters,
query,
time,
refreshInterval,
};

describe('reference injection', () => {
test('correctly inserts reference to filter', () => {
const updatedFilters = inject(filters, [
const updatedQueryState = inject(queryState, [
{ type: DATA_VIEW_SAVED_OBJECT_TYPE, name: 'test', id: '123' },
]);
expect(updatedFilters[0]).toHaveProperty('meta.index', '123');
expect(updatedQueryState.filters[0]).toHaveProperty('meta.index', '123');
expect(updatedQueryState.query).toEqual(queryState.query);
expect(updatedQueryState.time).toEqual(queryState.time);
expect(updatedQueryState.refreshInterval).toEqual(queryState.refreshInterval);
});

test('drops index setting if reference is missing', () => {
const updatedFilters = inject(filters, [
test('drops index setting from filter if reference is missing', () => {
const updatedQueryState = inject(queryState, [
{ type: DATA_VIEW_SAVED_OBJECT_TYPE, name: 'test123', id: '123' },
]);
expect(updatedFilters[0]).toHaveProperty('meta.index', undefined);
expect(updatedQueryState.filters[0]).toHaveProperty('meta.index', undefined);
});
});

describe('reference extraction', () => {
test('correctly extracts references', () => {
const { state, references } = extract(filters);
expect(state[0]).toHaveProperty('meta.index');
const { state, references } = extract(queryState);
expect(state.filters[0]).toHaveProperty('meta.index');
expect(references[0]).toHaveProperty('id', 'test');

expect(state.query).toEqual(queryState.query);
expect(state.time).toEqual(queryState.time);
expect(state.refreshInterval).toEqual(queryState.refreshInterval);
});
});
});
79 changes: 37 additions & 42 deletions src/plugins/data/common/query/persistable_state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,58 +6,53 @@
* Side Public License, v 1.
*/

import uuid from 'uuid';
import { Filter } from '@kbn/es-query';
import { SavedObjectReference } from '@kbn/core/types';
import { MigrateFunctionsObject } from '@kbn/kibana-utils-plugin/common';
import { DATA_VIEW_SAVED_OBJECT_TYPE } from '..';
import { MigrateFunctionsObject, VersionedState } from '@kbn/kibana-utils-plugin/common';
import type { QueryState } from './query_state';
import * as filtersPersistableState from './filters/persistable_state';

export const extract = (filters: Filter[]) => {
export const extract = (queryState: QueryState) => {
const references: SavedObjectReference[] = [];
const updatedFilters = filters.map((filter) => {
if (filter.meta?.index) {
const id = uuid();
references.push({
type: DATA_VIEW_SAVED_OBJECT_TYPE,
name: id,
id: filter.meta.index,
});

return {
...filter,
meta: {
...filter.meta,
index: id,
},
};
}
return filter;
});
return { state: updatedFilters, references };
const { state: updatedFilters, references: referencesFromFilters } =
filtersPersistableState.extract(queryState.filters ?? []);
references.push(...referencesFromFilters);

return {
state: {
...queryState,
filters: updatedFilters,
},
references,
};
};

export const inject = (filters: Filter[], references: SavedObjectReference[]) => {
return filters.map((filter) => {
if (!filter.meta.index) {
return filter;
}
const reference = references.find((ref) => ref.name === filter.meta.index);
return {
...filter,
meta: {
...filter.meta,
index: reference && reference.id,
},
};
});
export const inject = (queryState: QueryState, references: SavedObjectReference[]) => {
const updatedFilters = filtersPersistableState.inject(queryState.filters ?? [], references);

return {
...queryState,
filters: updatedFilters,
};
};

export const telemetry = (filters: Filter[], collector: unknown) => {
return {};
export const telemetry = (queryState: QueryState, collector: unknown) => {
const filtersTelemetry = filtersPersistableState.telemetry(queryState.filters ?? [], collector);
return {
...filtersTelemetry,
};
};

export const migrateToLatest = (filters: Filter[], version: string) => {
return filters;
export const migrateToLatest = ({ state, version }: VersionedState<QueryState>) => {
const migratedFilters = filtersPersistableState.migrateToLatest({
state: state.filters ?? [],
version,
});

return {
...state,
filters: migratedFilters,
};
};

export const getAllMigrations = (): MigrateFunctionsObject => {
Expand Down
26 changes: 26 additions & 0 deletions src/plugins/data/common/query/query_state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import type { Filter } from '@kbn/es-query';
import type { TimeRange, RefreshInterval } from './timefilter/types';
import type { Query } from './types';

/**
* All query state service state
*
* @remark
* `type` instead of `interface` to make it compatible with PersistableState utils
*
*/
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
export type QueryState = {
time?: TimeRange;
refreshInterval?: RefreshInterval;
filters?: Filter[];
query?: Query;
};
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
SerializedSearchSourceFields,
} from '.';
import { IndexPatternsContract } from '../..';
import { getAllMigrations as filtersGetAllMigrations } from '../../query/persistable_state';
import { getAllMigrations as filtersGetAllMigrations } from '../../query/filters/persistable_state';

const getAllMigrations = (): MigrateFunctionsObject => {
const searchSourceMigrations = {};
Expand Down
1 change: 1 addition & 0 deletions src/plugins/data/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ export {
getQueryLog,
mapAndFlattenFilters,
QueryService,
QueryState$,
} from './query';

export { NowProvider } from './now_provider';
Expand Down
19 changes: 10 additions & 9 deletions src/plugins/data/public/query/filter_manager/filter_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,25 @@ import { Subject } from 'rxjs';

import { IUiSettingsClient } from '@kbn/core/public';

import { isFilterPinned, onlyDisabledFiltersChanged, Filter } from '@kbn/es-query';
import { PersistableStateService } from '@kbn/kibana-utils-plugin/common/persistable_state';
import { sortFilters } from './lib/sort_filters';
import { mapAndFlattenFilters } from './lib/map_and_flatten_filters';

import {
FilterStateStore,
isFilterPinned,
onlyDisabledFiltersChanged,
Filter,
uniqFilters,
compareFilters,
COMPARE_ALL_OPTIONS,
UI_SETTINGS,
} from '../../../common';
} from '@kbn/es-query';
import { PersistableStateService } from '@kbn/kibana-utils-plugin/common/persistable_state';
import { sortFilters } from './lib/sort_filters';
import { mapAndFlattenFilters } from './lib/map_and_flatten_filters';

import { FilterStateStore, UI_SETTINGS } from '../../../common';
import {
getAllMigrations,
inject,
extract,
telemetry,
} from '../../../common/query/persistable_state';
} from '../../../common/query/filters/persistable_state';

interface PartitionedFilters {
globalFilters: Filter[];
Expand Down
17 changes: 17 additions & 0 deletions src/plugins/data/public/query/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ const createSetupContractMock = () => {
queryString: queryStringManagerMock.createSetupContract(),
state$: new Observable(),
getState: jest.fn(),

inject: jest.fn(),
extract: jest.fn(),
telemetry: jest.fn(),
migrateToLatest: jest.fn(),
getAllMigrations: jest.fn(),
};

return setupContract;
Expand All @@ -37,6 +43,11 @@ const createStartContractMock = () => {
getState: jest.fn(),
timefilter: timefilterServiceMock.createStartContract(),
getEsQuery: jest.fn(),
inject: jest.fn(),
extract: jest.fn(),
telemetry: jest.fn(),
migrateToLatest: jest.fn(),
getAllMigrations: jest.fn(),
};

return startContract;
Expand All @@ -47,6 +58,12 @@ const createMock = () => {
setup: jest.fn(),
start: jest.fn(),
stop: jest.fn(),

inject: jest.fn(),
extract: jest.fn(),
telemetry: jest.fn(),
migrateToLatest: jest.fn(),
getAllMigrations: jest.fn(),
};

mocked.setup.mockReturnValue(createSetupContractMock());
Expand Down
Loading

0 comments on commit 8ec1b06

Please sign in to comment.