Skip to content

Commit 06bc389

Browse files
authored
[Security Solution] [Timeline] Bugfix for timeline row actions disappear sometimes (#70958)
1 parent 465ed21 commit 06bc389

File tree

11 files changed

+37
-49
lines changed

11 files changed

+37
-49
lines changed

x-pack/plugins/security_solution/public/alerts/components/alerts_table/index.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import {
4848
displaySuccessToast,
4949
displayErrorToast,
5050
} from '../../../common/components/toasters';
51+
import { getInvestigateInResolverAction } from '../../../timelines/components/timeline/body/helpers';
5152

5253
interface OwnProps {
5354
timelineId: TimelineIdLiteral;
@@ -331,13 +332,14 @@ export const AlertsTableComponent: React.FC<AlertsTableComponentProps> = ({
331332

332333
useEffect(() => {
333334
initializeTimeline({
334-
id: timelineId,
335-
documentType: i18n.ALERTS_DOCUMENT_TYPE,
336335
defaultModel: alertsDefaultModel,
336+
documentType: i18n.ALERTS_DOCUMENT_TYPE,
337337
footerText: i18n.TOTAL_COUNT_OF_ALERTS,
338+
id: timelineId,
338339
loadingText: i18n.LOADING_ALERTS,
339-
title: i18n.ALERTS_TABLE_TITLE,
340340
selectAll: canUserCRUD ? selectAll : false,
341+
timelineRowActions: [getInvestigateInResolverAction({ dispatch, timelineId })],
342+
title: i18n.ALERTS_TABLE_TITLE,
341343
});
342344
// eslint-disable-next-line react-hooks/exhaustive-deps
343345
}, []);

x-pack/plugins/security_solution/public/common/components/alerts_viewer/alerts_table.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,21 +69,18 @@ const AlertsTableComponent: React.FC<Props> = ({
6969
}) => {
7070
const dispatch = useDispatch();
7171
const alertsFilter = useMemo(() => [...defaultAlertsFilters, ...pageFilters], [pageFilters]);
72-
const { initializeTimeline, setTimelineRowActions } = useManageTimeline();
72+
const { initializeTimeline } = useManageTimeline();
7373

7474
useEffect(() => {
7575
initializeTimeline({
7676
id: timelineId,
7777
documentType: i18n.ALERTS_DOCUMENT_TYPE,
7878
defaultModel: alertsDefaultModel,
7979
footerText: i18n.TOTAL_COUNT_OF_ALERTS,
80+
timelineRowActions: [getInvestigateInResolverAction({ dispatch, timelineId })],
8081
title: i18n.ALERTS_TABLE_TITLE,
8182
unit: i18n.UNIT,
8283
});
83-
setTimelineRowActions({
84-
id: timelineId,
85-
timelineRowActions: [getInvestigateInResolverAction({ dispatch, timelineId })],
86-
});
8784
// eslint-disable-next-line react-hooks/exhaustive-deps
8885
}, []);
8986
return (

x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper_hover_content.test.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { useAddToTimeline } from '../../hooks/use_add_to_timeline';
1818
import { DraggableWrapperHoverContent } from './draggable_wrapper_hover_content';
1919
import {
2020
ManageGlobalTimeline,
21-
timelineDefaults,
21+
getTimelineDefaults,
2222
} from '../../../timelines/components/manage_timeline';
2323
import { TimelineId } from '../../../../common/types/timeline';
2424

@@ -152,10 +152,7 @@ describe('DraggableWrapperHoverContent', () => {
152152
beforeEach(() => {
153153
onFilterAdded = jest.fn();
154154
const manageTimelineForTesting = {
155-
[timelineId]: {
156-
...timelineDefaults,
157-
id: timelineId,
158-
},
155+
[timelineId]: getTimelineDefaults(timelineId),
159156
};
160157

161158
wrapper = mount(
@@ -249,8 +246,7 @@ describe('DraggableWrapperHoverContent', () => {
249246

250247
const manageTimelineForTesting = {
251248
[timelineId]: {
252-
...timelineDefaults,
253-
id: timelineId,
249+
...getTimelineDefaults(timelineId),
254250
filterManager,
255251
},
256252
};

x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import { EuiPanel } from '@elastic/eui';
88
import { getOr, isEmpty, union } from 'lodash/fp';
99
import React, { useEffect, useMemo, useState } from 'react';
10-
import { useDispatch } from 'react-redux';
1110
import styled from 'styled-components';
1211
import deepEqual from 'fast-deep-equal';
1312

@@ -35,7 +34,6 @@ import {
3534
} from '../../../../../../../src/plugins/data/public';
3635
import { inputsModel } from '../../store';
3736
import { useManageTimeline } from '../../../timelines/components/manage_timeline';
38-
import { getInvestigateInResolverAction } from '../../../timelines/components/timeline/body/helpers';
3937

4038
const DEFAULT_EVENTS_VIEWER_HEIGHT = 500;
4139

@@ -93,7 +91,6 @@ const EventsViewerComponent: React.FC<Props> = ({
9391
toggleColumn,
9492
utilityBar,
9593
}) => {
96-
const dispatch = useDispatch();
9794
const columnsHeader = isEmpty(columns) ? defaultHeaders : columns;
9895
const kibana = useKibana();
9996
const { filterManager } = useKibana().services.data.query;
@@ -103,16 +100,8 @@ const EventsViewerComponent: React.FC<Props> = ({
103100
getManageTimelineById,
104101
setIsTimelineLoading,
105102
setTimelineFilterManager,
106-
setTimelineRowActions,
107103
} = useManageTimeline();
108104

109-
useEffect(() => {
110-
setTimelineRowActions({
111-
id,
112-
timelineRowActions: [getInvestigateInResolverAction({ dispatch, timelineId: id })],
113-
});
114-
}, [setTimelineRowActions, id, dispatch]);
115-
116105
useEffect(() => {
117106
setIsTimelineLoading({ id, isLoading: isQueryLoading });
118107
// eslint-disable-next-line react-hooks/exhaustive-deps

x-pack/plugins/security_solution/public/common/components/top_n/index.test.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import { Props } from './top_n';
2525
import { StatefulTopN } from '.';
2626
import {
2727
ManageGlobalTimeline,
28-
timelineDefaults,
28+
getTimelineDefaults,
2929
} from '../../../timelines/components/manage_timeline';
3030
import { TimelineId } from '../../../../common/types/timeline';
3131

@@ -272,8 +272,7 @@ describe('StatefulTopN', () => {
272272
filterManager = new FilterManager(mockUiSettingsForFilterManager);
273273
const manageTimelineForTesting = {
274274
[TimelineId.active]: {
275-
...timelineDefaults,
276-
id: TimelineId.active,
275+
...getTimelineDefaults(TimelineId.active),
277276
filterManager,
278277
},
279278
};
@@ -351,8 +350,7 @@ describe('StatefulTopN', () => {
351350

352351
const manageTimelineForTesting = {
353352
[TimelineId.active]: {
354-
...timelineDefaults,
355-
id: TimelineId.active,
353+
...getTimelineDefaults(TimelineId.active),
356354
filterManager,
357355
documentType: 'alerts',
358356
},

x-pack/plugins/security_solution/public/hosts/pages/navigation/events_query_tab_body.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
import React, { useEffect } from 'react';
8+
import { useDispatch } from 'react-redux';
89
import { TimelineId } from '../../../../common/types/timeline';
910
import { StatefulEventsViewer } from '../../../common/components/events_viewer';
1011
import { HostsComponentsQueryProps } from './types';
@@ -18,6 +19,7 @@ import { MatrixHistogramContainer } from '../../../common/components/matrix_hist
1819
import * as i18n from '../translations';
1920
import { HistogramType } from '../../../graphql/types';
2021
import { useManageTimeline } from '../../../timelines/components/manage_timeline';
22+
import { getInvestigateInResolverAction } from '../../../timelines/components/timeline/body/helpers';
2123

2224
const EVENTS_HISTOGRAM_ID = 'eventsOverTimeQuery';
2325

@@ -57,13 +59,17 @@ export const EventsQueryTabBody = ({
5759
startDate,
5860
}: HostsComponentsQueryProps) => {
5961
const { initializeTimeline } = useManageTimeline();
62+
const dispatch = useDispatch();
6063

6164
useEffect(() => {
6265
initializeTimeline({
6366
id: TimelineId.hostsPageEvents,
6467
defaultModel: eventsDefaultModel,
68+
timelineRowActions: [
69+
getInvestigateInResolverAction({ dispatch, timelineId: TimelineId.hostsPageEvents }),
70+
],
6571
});
66-
}, [initializeTimeline]);
72+
}, [dispatch, initializeTimeline]);
6773

6874
useEffect(() => {
6975
return () => {

x-pack/plugins/security_solution/public/timelines/components/manage_timeline/index.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import React, { createContext, useCallback, useContext, useReducer } from 'react';
88
import { noop } from 'lodash/fp';
9+
910
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
1011
import { FilterManager } from '../../../../../../../src/plugins/data/public/query/filter_manager';
1112
import { TimelineRowAction } from '../timeline/body/actions';
@@ -22,6 +23,7 @@ interface ManageTimelineInit {
2223
indexToAdd?: string[] | null;
2324
loadingText?: string;
2425
selectAll?: boolean;
26+
timelineRowActions: TimelineRowAction[];
2527
title?: string;
2628
unit?: (totalCount: number) => string;
2729
}
@@ -73,19 +75,20 @@ type ActionManageTimeline =
7375
payload: { filterManager: FilterManager };
7476
};
7577

76-
export const timelineDefaults = {
78+
export const getTimelineDefaults = (id: string) => ({
7779
indexToAdd: null,
7880
defaultModel: timelineDefaultModel,
7981
loadingText: i18n.LOADING_EVENTS,
8082
footerText: i18nF.TOTAL_COUNT_OF_EVENTS,
8183
documentType: i18nF.TOTAL_COUNT_OF_EVENTS,
8284
selectAll: false,
85+
id,
8386
isLoading: false,
8487
queryFields: [],
8588
timelineRowActions: [],
8689
title: i18n.EVENTS,
8790
unit: (n: number) => i18n.UNIT(n),
88-
};
91+
});
8992
const reducerManageTimeline = (
9093
state: ManageTimelineById,
9194
action: ActionManageTimeline
@@ -95,7 +98,7 @@ const reducerManageTimeline = (
9598
return {
9699
...state,
97100
[action.id]: {
98-
...timelineDefaults,
101+
...getTimelineDefaults(action.id),
99102
...state[action.id],
100103
...action.payload,
101104
},
@@ -216,8 +219,8 @@ const useTimelineManager = (manageTimelineForTesting?: ManageTimelineById): UseT
216219
if (state[id] != null) {
217220
return state[id];
218221
}
219-
initializeTimeline({ id });
220-
return { ...timelineDefaults, id };
222+
initializeTimeline({ id, timelineRowActions: [] });
223+
return getTimelineDefaults(id);
221224
},
222225
[initializeTimeline, state]
223226
);
@@ -236,7 +239,7 @@ const useTimelineManager = (manageTimelineForTesting?: ManageTimelineById): UseT
236239
};
237240

238241
const init = {
239-
getManageTimelineById: (id: string) => ({ ...timelineDefaults, id }),
242+
getManageTimelineById: (id: string) => getTimelineDefaults(id),
240243
getTimelineFilterManager: () => undefined,
241244
setIndexToAdd: () => undefined,
242245
isManagedTimeline: () => false,
@@ -245,6 +248,7 @@ const init = {
245248
setTimelineRowActions: () => noop,
246249
setTimelineFilterManager: () => noop,
247250
};
251+
248252
const ManageTimelineContext = createContext<UseTimelineManager>(init);
249253

250254
export const useManageTimeline = () => useContext(ManageTimelineContext);

x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/event_column_view.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,7 @@ export const EventColumnView = React.memo<Props>(
194194
</EventsTdContent>,
195195
]
196196
: grouped.icon;
197-
// eslint-disable-next-line react-hooks/exhaustive-deps
198-
}, [button, ecsData, timelineActions, isPopoverOpen]); // , isPopoverOpen, closePopover, onButtonClick]);
197+
}, [button, closePopover, id, onClickCb, ecsData, timelineActions, isPopoverOpen]);
199198

200199
return (
201200
<EventsTrData data-test-subj="event-column-view">

x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/data_providers.test.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { useMountAppended } from '../../../../common/utils/use_mount_appended';
1313
import { DataProviders } from '.';
1414
import { DataProvider } from './data_provider';
1515
import { mockDataProviders } from './mock/mock_data_providers';
16-
import { ManageGlobalTimeline, timelineDefaults } from '../../manage_timeline';
16+
import { ManageGlobalTimeline, getTimelineDefaults } from '../../manage_timeline';
1717
import { FilterManager } from '../../../../../../../../src/plugins/data/public/query/filter_manager';
1818
import { createKibanaCoreStartMock } from '../../../../common/mock/kibana_core';
1919
const mockUiSettingsForFilterManager = createKibanaCoreStartMock().uiSettings;
@@ -28,8 +28,7 @@ describe('DataProviders', () => {
2828
test('renders correctly against snapshot', () => {
2929
const manageTimelineForTesting = {
3030
foo: {
31-
...timelineDefaults,
32-
id: 'foo',
31+
...getTimelineDefaults('foo'),
3332
filterManager,
3433
},
3534
};

x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/providers.test.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { mockDataProviders } from './mock/mock_data_providers';
1616
import { Providers } from './providers';
1717
import { DELETE_CLASS_NAME, ENABLE_CLASS_NAME, EXCLUDE_CLASS_NAME } from './provider_item_actions';
1818
import { useMountAppended } from '../../../../common/utils/use_mount_appended';
19-
import { ManageGlobalTimeline, timelineDefaults } from '../../manage_timeline';
19+
import { ManageGlobalTimeline, getTimelineDefaults } from '../../manage_timeline';
2020

2121
const mockUiSettingsForFilterManager = createKibanaCoreStartMock().uiSettings;
2222

@@ -27,8 +27,7 @@ describe('Providers', () => {
2727

2828
const manageTimelineForTesting = {
2929
foo: {
30-
...timelineDefaults,
31-
id: 'foo',
30+
...getTimelineDefaults('foo'),
3231
filterManager,
3332
isLoading,
3433
},

0 commit comments

Comments
 (0)