diff --git a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper_hover_content.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper_hover_content.tsx index 71c3114015a03..19740ecf4deef 100644 --- a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper_hover_content.tsx +++ b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper_hover_content.tsx @@ -34,6 +34,7 @@ import { useSourcererScope } from '../../containers/sourcerer'; import { timelineSelectors } from '../../../timelines/store/timeline'; import { stopPropagationAndPreventDefault } from '../../../../../timelines/public'; import { TooltipWithKeyboardShortcut } from '../accessibility'; +import { FilterManager } from '../../../../../../../src/plugins/data/public'; export const AdditionalContent = styled.div` padding: 2px; @@ -104,7 +105,7 @@ const DraggableWrapperHoverContentComponent: React.FC = ({ value, }) => { const kibana = useKibana(); - const { timelines } = kibana.services; + const { timelines, uiSettings } = kibana.services; const { startDragToTimeline } = timelines.getUseAddToTimeline()({ draggableId, fieldName: field, @@ -120,8 +121,11 @@ const DraggableWrapperHoverContentComponent: React.FC = ({ const panelRef = useRef(null); const filterManager = useMemo( - () => (timelineId === TimelineId.active ? activeFilterMananager : filterManagerBackup), - [timelineId, activeFilterMananager, filterManagerBackup] + () => + timelineId === TimelineId.active + ? activeFilterMananager ?? new FilterManager(uiSettings) + : filterManagerBackup, + [uiSettings, timelineId, activeFilterMananager, filterManagerBackup] ); // Regarding data from useManageTimeline: diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.tsx index 768d5f3c80751..c150f1a44f196 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.tsx @@ -14,7 +14,7 @@ import { EuiBadge, } from '@elastic/eui'; import { isEmpty } from 'lodash/fp'; -import React, { useState, useMemo, useEffect, useCallback } from 'react'; +import React, { useMemo, useEffect, useCallback } from 'react'; import styled from 'styled-components'; import { Dispatch } from 'redux'; import { connect, ConnectedProps, useDispatch } from 'react-redux'; @@ -60,6 +60,7 @@ import { activeTimeline } from '../../../containers/active_timeline_context'; import { DetailsPanel } from '../../side_panel'; import { ExitFullScreen } from '../../../../common/components/exit_full_screen'; import { defaultControlColumn } from '../body/control_columns'; +import { useDeepEqualSelector } from '../../../../common/hooks/use_selector'; const TimelineHeaderContainer = styled.div` margin-top: 6px; @@ -193,7 +194,17 @@ export const QueryTabContentComponent: React.FC = ({ } = useSourcererScope(SourcererScopeName.timeline); const { uiSettings } = useKibana().services; - const [filterManager] = useState(new FilterManager(uiSettings)); + + const getManageTimeline = useMemo(() => timelineSelectors.getManageTimelineById(), []); + const { filterManager: activeFilterManager } = useDeepEqualSelector((state) => + getManageTimeline(state, timelineId ?? '') + ); + + const filterManager = useMemo(() => activeFilterManager ?? new FilterManager(uiSettings), [ + activeFilterManager, + uiSettings, + ]); + const esQueryConfig = useMemo(() => esQuery.getEsQueryConfig(uiSettings), [uiSettings]); const kqlQuery: { query: string; @@ -258,7 +269,7 @@ export const QueryTabContentComponent: React.FC = ({ id: timelineId, }) ); - }, [filterManager, timelineId, dispatch]); + }, [activeFilterManager, dispatch, filterManager, timelineId, uiSettings]); const [ isQueryLoading, diff --git a/x-pack/plugins/security_solution/public/timelines/store/timeline/helpers.ts b/x-pack/plugins/security_solution/public/timelines/store/timeline/helpers.ts index 7c07410a2789a..6ee844958aeed 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/timeline/helpers.ts +++ b/x-pack/plugins/security_solution/public/timelines/store/timeline/helpers.ts @@ -156,6 +156,7 @@ export const addTimelineToStore = ({ ...timelineById, [id]: { ...timeline, + filterManager: timelineById[id].filterManager, isLoading: timelineById[id].isLoading, initialized: timelineById[id].initialized, dateRange: diff --git a/x-pack/plugins/security_solution/public/timelines/store/timeline/reducer.test.ts b/x-pack/plugins/security_solution/public/timelines/store/timeline/reducer.test.ts index 8a5c8546d3834..c221961f9a21b 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/timeline/reducer.test.ts +++ b/x-pack/plugins/security_solution/public/timelines/store/timeline/reducer.test.ts @@ -52,6 +52,7 @@ import { TimelineModel } from './model'; import { timelineDefaults } from './defaults'; import { TimelineById } from './types'; import { Direction } from '../../../../common/search_strategy'; +import { FilterManager } from '../../../../../../../src/plugins/data/public'; jest.mock('../../../common/components/url_state/normalize_time_range.ts'); jest.mock('../../../common/utils/default_date_settings', () => { @@ -63,6 +64,8 @@ jest.mock('../../../common/utils/default_date_settings', () => { }; }); +const mockFilterManager = {} as FilterManager; + const basicDataProvider: DataProvider = { and: [], id: '123', @@ -95,6 +98,7 @@ const basicTimeline: TimelineModel = { eventIdToNoteIds: {}, excludedRowRendererIds: [], expandedDetail: {}, + filterManager: mockFilterManager, highlightedDropAndProviderId: '', historyIds: [], id: 'foo', @@ -190,6 +194,20 @@ describe('Timeline', () => { }, }); }); + + test('should contain existing filterManager', () => { + const update = addTimelineToStore({ + id: 'foo', + timeline: { + ...basicTimeline, + status: TimelineStatus.immutable, + timelineType: TimelineType.template, + }, + timelineById: timelineByIdMock, + }); + + expect(update.foo.filterManager).toEqual(mockFilterManager); + }); }); describe('#addNewTimeline', () => {