From 62cc5db284a518f28ca6e378a644365febf2a562 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Kopyci=C5=84ski?= Date: Wed, 14 Oct 2020 20:21:35 +0200 Subject: [PATCH] [Security Solution] Fix timeline querybar filters persistance (#80320) --- .../timeline/query_bar/index.test.tsx | 43 +++++++++++++++++-- .../components/timeline/query_bar/index.tsx | 25 +++++------ 2 files changed, 53 insertions(+), 15 deletions(-) diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.test.tsx index 87956647c11f1..36116de8d33d9 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.test.tsx @@ -13,11 +13,16 @@ import { mockBrowserFields } from '../../../../common/containers/source/mock'; import { convertKueryToElasticSearchQuery } from '../../../../common/lib/keury'; import { mockIndexPattern, TestProviders } from '../../../../common/mock'; import { QueryBar } from '../../../../common/components/query_bar'; -import { FilterManager } from '../../../../../../../../src/plugins/data/public'; +import { esFilters, FilterManager } from '../../../../../../../../src/plugins/data/public'; import { mockDataProviders } from '../data_providers/mock/mock_data_providers'; import { buildGlobalQuery } from '../helpers'; -import { QueryBarTimeline, QueryBarTimelineComponentProps, getDataProviderFilter } from './index'; +import { + QueryBarTimeline, + QueryBarTimelineComponentProps, + getDataProviderFilter, + TIMELINE_FILTER_DROP_AREA, +} from './index'; const mockUiSettingsForFilterManager = coreMock.createStart().uiSettings; @@ -39,13 +44,43 @@ describe('Timeline QueryBar ', () => { }); test('check if we format the appropriate props to QueryBar', () => { + const filters = [ + { + $state: { store: esFilters.FilterStateStore.APP_STATE }, + meta: { + alias: null, + controlledBy: TIMELINE_FILTER_DROP_AREA, + disabled: false, + index: undefined, + key: 'event.category', + negate: true, + params: { query: 'file' }, + type: 'phrase', + }, + query: { match: { 'event.category': { query: 'file', type: 'phrase' } } }, + }, + { + $state: { store: esFilters.FilterStateStore.APP_STATE }, + meta: { + alias: null, + controlledBy: undefined, + disabled: false, + index: undefined, + key: 'event.category', + negate: true, + params: { query: 'process' }, + type: 'phrase', + }, + query: { match: { 'event.category': { query: 'process', type: 'phrase' } } }, + }, + ]; const wrapper = mount( { expect(queryBarProps.dateRangeTo).toEqual('now'); expect(queryBarProps.filterQuery).toEqual({ query: 'here: query', language: 'kuery' }); expect(queryBarProps.savedQuery).toEqual(null); + expect(queryBarProps.filters).toHaveLength(1); + expect(queryBarProps.filters[0].query).toEqual(filters[1].query); }); describe('#onChangeQuery', () => { diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.tsx index 74f21fecd0fda..3b882c1e1bd14 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.tsx @@ -53,7 +53,10 @@ export interface QueryBarTimelineComponentProps { updateReduxTime: DispatchUpdateReduxTime; } -const timelineFilterDropArea = 'timeline-filter-drop-area'; +export const TIMELINE_FILTER_DROP_AREA = 'timeline-filter-drop-area'; + +const getNonDropAreaFilters = (filters: Filter[] = []) => + filters.filter((f: Filter) => f.meta.controlledBy !== TIMELINE_FILTER_DROP_AREA); export const QueryBarTimeline = memo( ({ @@ -91,7 +94,9 @@ export const QueryBarTimeline = memo( query: filterQuery != null ? filterQuery.expression : '', language: filterQuery != null ? filterQuery.kind : 'kuery', }); - const [queryBarFilters, setQueryBarFilters] = useState([]); + const [queryBarFilters, setQueryBarFilters] = useState( + getNonDropAreaFilters(filters) + ); const [dataProvidersDsl, setDataProvidersDsl] = useState( convertKueryToElasticSearchQuery(buildGlobalQuery(dataProviders, browserFields), indexPattern) ); @@ -106,9 +111,7 @@ export const QueryBarTimeline = memo( filterManager.getUpdates$().subscribe({ next: () => { if (isSubscribed) { - const filterWithoutDropArea = filterManager - .getFilters() - .filter((f: Filter) => f.meta.controlledBy !== timelineFilterDropArea); + const filterWithoutDropArea = getNonDropAreaFilters(filterManager.getFilters()); setFilters(filterWithoutDropArea); setQueryBarFilters(filterWithoutDropArea); } @@ -124,9 +127,7 @@ export const QueryBarTimeline = memo( }, []); useEffect(() => { - const filterWithoutDropArea = filterManager - .getFilters() - .filter((f: Filter) => f.meta.controlledBy !== timelineFilterDropArea); + const filterWithoutDropArea = getNonDropAreaFilters(filterManager.getFilters()); if (!deepEqual(filters, filterWithoutDropArea)) { filterManager.setFilters(filters); } @@ -175,7 +176,7 @@ export const QueryBarTimeline = memo( ...mySavedQuery, attributes: { ...mySavedQuery.attributes, - filters: filters.filter((f) => f.meta.controlledBy !== timelineFilterDropArea), + filters: getNonDropAreaFilters(filters), }, }); } @@ -250,7 +251,7 @@ export const QueryBarTimeline = memo( const dataProviderFilterExists = newSavedQuery.attributes.filters != null ? newSavedQuery.attributes.filters.findIndex( - (f) => f.meta.controlledBy === timelineFilterDropArea + (f) => f.meta.controlledBy === TIMELINE_FILTER_DROP_AREA ) : -1; savedQueryServices.saveQuery( @@ -311,8 +312,8 @@ export const getDataProviderFilter = (dataProviderDsl: string): Filter => { return { ...dslObject, meta: { - alias: timelineFilterDropArea, - controlledBy: timelineFilterDropArea, + alias: TIMELINE_FILTER_DROP_AREA, + controlledBy: TIMELINE_FILTER_DROP_AREA, negate: false, disabled: false, type: 'custom',