From 47100291a8cdb0ff42184b667d61eab383c6eb4c Mon Sep 17 00:00:00 2001 From: Jan Monschke Date: Mon, 18 Nov 2024 13:17:57 +0100 Subject: [PATCH] [SecuritySolution][Timeline] Remove timeline.isLoading (#198616) ## Summary Trying to answer the question of: "Do we still need `timeline.isLoading`?" `timeline.isSaving` should be the only indicator for "loading" states of timeline itself. All other pieces of state that are associated with timeline that could have a loading state, have their own loading indicators (e.g. data providers, alert list etc). Therefore, this PR removes all references to `timeline.isLoading` and parts of the UI that depended on it. Places that `timeline.isLoading` was used ([context](https://github.com/elastic/kibana/pull/38185)): - Blocking drag/drop on data providers - This is not necessary anymore. Drag/drop works while the underlying query is being executed. - Showing a loading state for the alerts table & data provider changes - Both components have their own loading state, so no extra loading state is necessary ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: Elastic Machine --- .../drag_and_drop/droppable_wrapper.tsx | 12 +- .../public/common/mock/global_state.ts | 1 - .../public/common/mock/timeline_results.ts | 2 - .../components/alerts_table/actions.test.tsx | 48 +--- .../components/alerts_table/actions.tsx | 3 - .../use_add_bulk_to_timeline.tsx | 10 +- .../use_investigate_in_timeline.tsx | 15 +- .../components/alerts_table/types.ts | 3 - .../rules/use_rule_from_timeline.test.ts | 20 +- .../use_investigate_in_timeline.ts | 12 +- .../components/open_timeline/helpers.test.ts | 53 ----- .../components/open_timeline/helpers.ts | 15 -- .../timeline/data_providers/index.tsx | 5 +- .../data_providers/provider_item_actions.tsx | 12 +- .../data_providers/provider_item_badge.tsx | 15 +- .../data_providers/providers.test.tsx | 214 +----------------- .../timelines/components/timeline/index.tsx | 1 - .../components/timeline/tabs/eql/index.tsx | 16 +- .../components/timeline/tabs/query/index.tsx | 9 - .../public/timelines/store/actions.ts | 5 - .../public/timelines/store/defaults.ts | 1 - .../public/timelines/store/helpers.test.ts | 1 - .../public/timelines/store/helpers.ts | 2 - .../store/middlewares/timeline_save.test.ts | 1 - .../public/timelines/store/model.ts | 2 - .../public/timelines/store/reducer.ts | 11 - .../cypress/screens/timeline.ts | 2 - .../cypress/tasks/alerts.ts | 4 - 28 files changed, 15 insertions(+), 480 deletions(-) diff --git a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/droppable_wrapper.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/droppable_wrapper.tsx index 586165893408c..d14a651a027a9 100644 --- a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/droppable_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/droppable_wrapper.tsx @@ -15,7 +15,6 @@ interface Props { children?: React.ReactNode; droppableId: string; height?: string; - isDropDisabled?: boolean; type?: string; render?: ({ isDraggingOver }: { isDraggingOver: boolean }) => React.ReactNode; renderClone?: DraggableChildrenFn; @@ -90,15 +89,7 @@ const ReactDndDropTarget = styled.div<{ isDraggingOver: boolean; height: string ReactDndDropTarget.displayName = 'ReactDndDropTarget'; export const DroppableWrapper = React.memo( - ({ - children = null, - droppableId, - height = '100%', - isDropDisabled = false, - type, - render = null, - renderClone, - }) => { + ({ children = null, droppableId, height = '100%', type, render = null, renderClone }) => { const DroppableContent = useCallback( (provided, snapshot) => ( ( return ( { const anchor = '2020-03-01T17:59:46.349Z'; const unix = moment(anchor).valueOf(); let createTimeline: CreateTimeline; - let updateTimelineIsLoading: UpdateTimelineLoading; let searchStrategyClient: jest.Mocked; let clock: sinon.SinonFakeTimers; let mockKibanaServices: jest.Mock; @@ -270,7 +269,6 @@ describe('alert actions', () => { mockGetExceptionFilter = jest.fn().mockResolvedValue(undefined); createTimeline = jest.fn() as jest.Mocked; - updateTimelineIsLoading = jest.fn() as jest.Mocked; mockKibanaServices = KibanaServices.get as jest.Mock; fetchMock = jest.fn(); @@ -296,28 +294,10 @@ describe('alert actions', () => { describe('sendAlertToTimelineAction', () => { describe('timeline id is NOT empty string and apollo client exists', () => { - test('it invokes updateTimelineIsLoading to set to true', async () => { - await sendAlertToTimelineAction({ - createTimeline, - ecsData: mockEcsDataWithAlert, - updateTimelineIsLoading, - searchStrategyClient, - getExceptionFilter: mockGetExceptionFilter, - }); - - expect(mockGetExceptionFilter).not.toHaveBeenCalled(); - expect(updateTimelineIsLoading).toHaveBeenCalledTimes(1); - expect(updateTimelineIsLoading).toHaveBeenCalledWith({ - id: TimelineId.active, - isLoading: true, - }); - }); - test('it invokes createTimeline with designated timeline template if "timelineTemplate" exists', async () => { await sendAlertToTimelineAction({ createTimeline, ecsData: mockEcsDataWithAlert, - updateTimelineIsLoading, searchStrategyClient, getExceptionFilter: mockGetExceptionFilter, }); @@ -407,7 +387,6 @@ describe('alert actions', () => { indexNames: [], isFavorite: false, isLive: false, - isLoading: false, isSaving: false, isSelectAllChecked: false, itemsPerPage: 25, @@ -477,7 +456,6 @@ describe('alert actions', () => { await sendAlertToTimelineAction({ createTimeline, ecsData: mockEcsDataWithAlert, - updateTimelineIsLoading, searchStrategyClient, getExceptionFilter: mockGetExceptionFilter, }); @@ -496,7 +474,6 @@ describe('alert actions', () => { await sendAlertToTimelineAction({ createTimeline, ecsData: mockEcsDataWithAlert, - updateTimelineIsLoading, searchStrategyClient, getExceptionFilter: mockGetExceptionFilter, }); @@ -505,14 +482,6 @@ describe('alert actions', () => { delete defaultTimelinePropsWithoutNote.ruleNote; delete defaultTimelinePropsWithoutNote.ruleAuthor; - expect(updateTimelineIsLoading).toHaveBeenCalledWith({ - id: TimelineId.active, - isLoading: true, - }); - expect(updateTimelineIsLoading).toHaveBeenCalledWith({ - id: TimelineId.active, - isLoading: false, - }); expect(mockGetExceptionFilter).not.toHaveBeenCalled(); expect(createTimeline).toHaveBeenCalledTimes(1); expect(createTimeline).toHaveBeenCalledWith({ @@ -544,7 +513,6 @@ describe('alert actions', () => { await sendAlertToTimelineAction({ createTimeline, ecsData: ecsDataMock, - updateTimelineIsLoading, searchStrategyClient, getExceptionFilter: mockGetExceptionFilter, }); @@ -552,7 +520,6 @@ describe('alert actions', () => { const expectedTimelineProps = structuredClone(defaultTimelineProps); expectedTimelineProps.timeline.excludedRowRendererIds = []; - expect(updateTimelineIsLoading).not.toHaveBeenCalled(); expect(mockGetExceptionFilter).not.toHaveBeenCalled(); expect(createTimeline).toHaveBeenCalledTimes(1); expect(createTimeline).toHaveBeenCalledWith(expectedTimelineProps); @@ -574,7 +541,6 @@ describe('alert actions', () => { await sendAlertToTimelineAction({ createTimeline, ecsData: ecsDataMock, - updateTimelineIsLoading, searchStrategyClient, getExceptionFilter: mockGetExceptionFilter, }); @@ -582,7 +548,6 @@ describe('alert actions', () => { const expectedTimelineProps = structuredClone(defaultTimelineProps); expectedTimelineProps.timeline.excludedRowRendererIds = []; - expect(updateTimelineIsLoading).not.toHaveBeenCalled(); expect(mockGetExceptionFilter).not.toHaveBeenCalled(); expect(createTimeline).toHaveBeenCalledTimes(1); expect(createTimeline).toHaveBeenCalledWith(expectedTimelineProps); @@ -608,12 +573,10 @@ describe('alert actions', () => { await sendAlertToTimelineAction({ createTimeline, ecsData: ecsDataMock, - updateTimelineIsLoading, searchStrategyClient, getExceptionFilter: mockGetExceptionFilter, }); - expect(updateTimelineIsLoading).not.toHaveBeenCalled(); expect(mockGetExceptionFilter).not.toHaveBeenCalled(); expect(createTimeline).toHaveBeenCalledTimes(1); expect(createTimeline).toHaveBeenCalledWith({ @@ -655,12 +618,10 @@ describe('alert actions', () => { await sendAlertToTimelineAction({ createTimeline, ecsData: ecsDataMock, - updateTimelineIsLoading, searchStrategyClient, getExceptionFilter: mockGetExceptionFilter, }); - expect(updateTimelineIsLoading).not.toHaveBeenCalled(); expect(mockGetExceptionFilter).not.toHaveBeenCalled(); expect(createTimeline).toHaveBeenCalledTimes(1); expect(createTimeline).toHaveBeenCalledWith(expectedTimelineProps); @@ -732,7 +693,6 @@ describe('alert actions', () => { await sendAlertToTimelineAction({ createTimeline, ecsData: ecsDataMockWithNoTemplateTimeline, - updateTimelineIsLoading, searchStrategyClient, getExceptionFilter: mockGetExceptionFilter, }); @@ -740,7 +700,6 @@ describe('alert actions', () => { const expectedFrom = '2021-01-10T21:11:45.839Z'; const expectedTo = '2021-01-10T21:12:45.839Z'; - expect(updateTimelineIsLoading).not.toHaveBeenCalled(); expect(mockGetExceptionFilter).toHaveBeenCalled(); expect(createTimeline).toHaveBeenCalledTimes(1); expect(createTimeline).toHaveBeenCalledWith({ @@ -861,7 +820,6 @@ describe('alert actions', () => { await sendAlertToTimelineAction({ createTimeline, ecsData: ecsDataMockWithNoTemplateTimelineAndNoFilters, - updateTimelineIsLoading, searchStrategyClient, getExceptionFilter: mockGetExceptionFilter, }); @@ -886,7 +844,6 @@ describe('alert actions', () => { await sendAlertToTimelineAction({ createTimeline, ecsData: ecsDataMockWithTemplateTimeline, - updateTimelineIsLoading, searchStrategyClient, getExceptionFilter: mockGetExceptionFilter, }); @@ -894,7 +851,6 @@ describe('alert actions', () => { const expectedFrom = '2021-01-10T21:11:45.839Z'; const expectedTo = '2021-01-10T21:12:45.839Z'; - expect(updateTimelineIsLoading).toHaveBeenCalled(); expect(mockGetExceptionFilter).toHaveBeenCalled(); expect(createTimeline).toHaveBeenCalledTimes(1); expect(createTimeline).toHaveBeenCalledWith({ @@ -1046,7 +1002,6 @@ describe('alert actions', () => { await sendAlertToTimelineAction({ createTimeline, ecsData: ecsDataMockWithNoTemplateTimeline, - updateTimelineIsLoading, searchStrategyClient, getExceptionFilter: mockGetExceptionFilter, }); @@ -1141,7 +1096,6 @@ describe('alert actions', () => { await sendAlertToTimelineAction({ createTimeline, ecsData: ecsDataMockWithNoTemplateTimeline, - updateTimelineIsLoading, searchStrategyClient, getExceptionFilter: mockGetExceptionFilter, }); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx index a2dfef2c43e9f..3a3e0d0255531 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx @@ -936,7 +936,6 @@ export const sendBulkEventsToTimelineAction = async ( export const sendAlertToTimelineAction = async ({ createTimeline, ecsData: ecs, - updateTimelineIsLoading, searchStrategyClient, getExceptionFilter, }: SendAlertToTimelineActionProps) => { @@ -962,7 +961,6 @@ export const sendAlertToTimelineAction = async ({ // For now we do not want to populate the template timeline if we have alertIds if (!isEmpty(timelineId)) { try { - updateTimelineIsLoading({ id: TimelineId.active, isLoading: true }); const [responseTimeline, eventDataResp] = await Promise.all([ getTimelineTemplate(timelineId), lastValueFrom( @@ -1092,7 +1090,6 @@ export const sendAlertToTimelineAction = async ({ } catch (error) { /* eslint-disable-next-line no-console */ console.error(error); - updateTimelineIsLoading({ id: TimelineId.active, isLoading: false }); return createTimeline({ from, notes: null, diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_bulk_to_timeline.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_bulk_to_timeline.tsx index 0086f40ffa44b..e402dfe2488fa 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_bulk_to_timeline.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_bulk_to_timeline.tsx @@ -23,7 +23,6 @@ import { useTimelineEventsHandler } from '../../../../timelines/containers'; import { eventsViewerSelector } from '../../../../common/components/events_viewer/selectors'; import type { State } from '../../../../common/store/types'; import { useUpdateTimeline } from '../../../../timelines/components/open_timeline/use_update_timeline'; -import { timelineActions } from '../../../../timelines/store'; import { useCreateTimeline } from '../../../../timelines/hooks/use_create_timeline'; import { INVESTIGATE_BULK_IN_TIMELINE } from '../translations'; import { TimelineId } from '../../../../../common/types/timeline'; @@ -141,18 +140,11 @@ export const useAddBulkToTimelineAction = ({ timelineType: TimelineTypeEnum.default, }); - const updateTimelineIsLoading = useCallback( - (payload: Parameters[0]) => - dispatch(timelineActions.updateIsLoading(payload)), - [dispatch] - ); - const updateTimeline = useUpdateTimeline(); const createTimeline = useCallback( async ({ timeline, ruleNote, timeline: { filters: eventIdFilters } }: CreateTimelineProps) => { await clearActiveTimeline(); - updateTimelineIsLoading({ id: TimelineId.active, isLoading: false }); updateTimeline({ duplicate: true, from, @@ -168,7 +160,7 @@ export const useAddBulkToTimelineAction = ({ ruleNote, }); }, - [updateTimeline, updateTimelineIsLoading, clearActiveTimeline, from, to] + [updateTimeline, clearActiveTimeline, from, to] ); const sendBulkEventsToTimelineHandler = useCallback( diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_investigate_in_timeline.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_investigate_in_timeline.tsx index d7df06616f221..3b36452f9315d 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_investigate_in_timeline.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_investigate_in_timeline.tsx @@ -5,7 +5,6 @@ * 2.0. */ import { useCallback, useMemo } from 'react'; -import { useDispatch } from 'react-redux'; import { i18n } from '@kbn/i18n'; import { ALERT_RULE_EXCEPTIONS_LIST, ALERT_RULE_PARAMETERS } from '@kbn/rule-data-utils'; @@ -23,7 +22,6 @@ import { createHistoryEntry } from '../../../../common/utils/global_query_string import { useKibana } from '../../../../common/lib/kibana'; import { TimelineId } from '../../../../../common/types/timeline'; import { TimelineTypeEnum } from '../../../../../common/api/timeline'; -import { timelineActions } from '../../../../timelines/store'; import { sendAlertToTimelineAction } from '../actions'; import { useUpdateTimeline } from '../../../../timelines/components/open_timeline/use_update_timeline'; import { useCreateTimeline } from '../../../../timelines/hooks/use_create_timeline'; @@ -98,7 +96,6 @@ export const useInvestigateInTimeline = ({ const { data: { search: searchStrategyClient }, } = useKibana().services; - const dispatch = useDispatch(); const { startTransaction } = useStartTransaction(); const { services } = useKibana(); @@ -133,12 +130,6 @@ export const useInvestigateInTimeline = ({ [addError, getExceptionFilterFromIds] ); - const updateTimelineIsLoading = useCallback( - (payload: Parameters[0]) => - dispatch(timelineActions.updateIsLoading(payload)), - [dispatch] - ); - const clearActiveTimeline = useCreateTimeline({ timelineId: TimelineId.active, timelineType: TimelineTypeEnum.default, @@ -153,7 +144,6 @@ export const useInvestigateInTimeline = ({ !newColumns || isEmpty(newColumns) ? defaultUdtHeaders : newColumns; await clearActiveTimeline(); - updateTimelineIsLoading({ id: TimelineId.active, isLoading: false }); updateTimeline({ duplicate: true, from: fromTimeline, @@ -173,12 +163,11 @@ export const useInvestigateInTimeline = ({ ruleNote, }); }, - [updateTimeline, updateTimelineIsLoading, clearActiveTimeline] + [updateTimeline, clearActiveTimeline] ); const investigateInTimelineAlertClick = useCallback(async () => { createHistoryEntry(); - startTransaction({ name: ALERTS_ACTIONS.INVESTIGATE_IN_TIMELINE }); if (onInvestigateInTimelineAlertClick) { onInvestigateInTimelineAlertClick(); @@ -188,7 +177,6 @@ export const useInvestigateInTimeline = ({ createTimeline, ecsData: ecsRowData, searchStrategyClient, - updateTimelineIsLoading, getExceptionFilter, }); } @@ -198,7 +186,6 @@ export const useInvestigateInTimeline = ({ ecsRowData, onInvestigateInTimelineAlertClick, searchStrategyClient, - updateTimelineIsLoading, getExceptionFilter, ]); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/types.ts b/x-pack/plugins/security_solution/public/detections/components/alerts_table/types.ts index 167601871ae2a..53deaf4145310 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/types.ts +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/types.ts @@ -55,13 +55,10 @@ export interface UpdateAlertStatusActionProps { export interface SendAlertToTimelineActionProps { createTimeline: CreateTimeline; ecsData: Ecs | Ecs[]; - updateTimelineIsLoading: UpdateTimelineLoading; searchStrategyClient: ISearchStart; getExceptionFilter: GetExceptionFilter; } -export type UpdateTimelineLoading = ({ id, isLoading }: { id: string; isLoading: boolean }) => void; - export interface CreateTimelineProps { from: string; timeline: TimelineModel; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_from_timeline.test.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_from_timeline.test.ts index ce653c82d7831..57a0aa43cdde6 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_from_timeline.test.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_from_timeline.test.ts @@ -121,7 +121,6 @@ describe('useRuleFromTimeline', () => { expect(result.current.loading).toEqual(true); await waitForNextUpdate(); expect(setRuleQuery).toHaveBeenCalled(); - expect(mockDispatch).toHaveBeenCalledTimes(2); }); }); @@ -153,16 +152,8 @@ describe('useRuleFromTimeline', () => { await waitForNextUpdate(); expect(setRuleQuery).toHaveBeenCalled(); - expect(mockDispatch).toHaveBeenCalledTimes(4); + expect(mockDispatch).toHaveBeenCalledTimes(2); expect(mockDispatch).toHaveBeenNthCalledWith(1, { - type: 'x-pack/security_solution/local/timeline/UPDATE_LOADING', - payload: { - id: 'timeline-1', - isLoading: true, - }, - }); - - expect(mockDispatch).toHaveBeenNthCalledWith(2, { type: 'x-pack/security_solution/local/sourcerer/SET_SELECTED_DATA_VIEW', payload: { id: 'timeline', @@ -170,13 +161,6 @@ describe('useRuleFromTimeline', () => { selectedPatterns: selectedTimeline.data.timeline.indexNames, }, }); - expect(mockDispatch).toHaveBeenNthCalledWith(3, { - type: 'x-pack/security_solution/local/timeline/UPDATE_LOADING', - payload: { - id: 'timeline-1', - isLoading: false, - }, - }); }); it('when from timeline data view id === selected data view id and browser fields is not empty, set rule data to match from timeline query', async () => { @@ -347,7 +331,7 @@ describe('useRuleFromTimeline', () => { const { waitForNextUpdate } = renderHook(() => useRuleFromTimeline(setRuleQuery)); await waitForNextUpdate(); expect(setRuleQuery).toHaveBeenCalled(); - expect(mockDispatch).toHaveBeenNthCalledWith(4, { + expect(mockDispatch).toHaveBeenNthCalledWith(2, { type: 'x-pack/security_solution/local/sourcerer/SET_SELECTED_DATA_VIEW', payload: { id: 'timeline', diff --git a/x-pack/plugins/security_solution/public/threat_intelligence/use_investigate_in_timeline.ts b/x-pack/plugins/security_solution/public/threat_intelligence/use_investigate_in_timeline.ts index 85ced6d6e153d..f840e65497cc4 100644 --- a/x-pack/plugins/security_solution/public/threat_intelligence/use_investigate_in_timeline.ts +++ b/x-pack/plugins/security_solution/public/threat_intelligence/use_investigate_in_timeline.ts @@ -6,14 +6,12 @@ */ import { useCallback } from 'react'; -import { useDispatch } from 'react-redux'; import { timelineDefaults } from '../timelines/store/defaults'; import { APP_UI_ID } from '../../common/constants'; import type { DataProvider } from '../../common/types'; import { TimelineId } from '../../common/types/timeline'; import { TimelineTypeEnum } from '../../common/api/timeline'; import { useStartTransaction } from '../common/lib/apm/use_start_transaction'; -import { timelineActions } from '../timelines/store'; import { useCreateTimeline } from '../timelines/hooks/use_create_timeline'; import type { CreateTimelineProps } from '../detections/components/alerts_table/types'; import { useUpdateTimeline } from '../timelines/components/open_timeline/use_update_timeline'; @@ -46,15 +44,8 @@ export const useInvestigateInTimeline = ({ from, to, }: UseInvestigateInTimelineActionProps) => { - const dispatch = useDispatch(); const { startTransaction } = useStartTransaction(); - const updateTimelineIsLoading = useCallback( - (payload: Parameters[0]) => - dispatch(timelineActions.updateIsLoading(payload)), - [dispatch] - ); - const clearActiveTimeline = useCreateTimeline({ timelineId: TimelineId.active, timelineType: TimelineTypeEnum.default, @@ -65,7 +56,6 @@ export const useInvestigateInTimeline = ({ const createTimeline = useCallback( async ({ from: fromTimeline, timeline, to: toTimeline, ruleNote }: CreateTimelineProps) => { await clearActiveTimeline(); - updateTimelineIsLoading({ id: TimelineId.active, isLoading: false }); updateTimeline({ duplicate: true, from: fromTimeline, @@ -80,7 +70,7 @@ export const useInvestigateInTimeline = ({ ruleNote, }); }, - [updateTimeline, updateTimelineIsLoading, clearActiveTimeline] + [updateTimeline, clearActiveTimeline] ); const investigateInTimelineClick = useCallback(async () => { diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.test.ts b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.test.ts index 917f1d1bc29db..525d8bba3d909 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.test.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.test.ts @@ -11,7 +11,6 @@ import { waitFor } from '@testing-library/react'; import { mockTimelineResults, mockGetOneTimelineResult } from '../../../common/mock'; import { timelineDefaults } from '../../store/defaults'; -import { updateIsLoading as dispatchUpdateIsLoading } from '../../store/actions'; import type { QueryTimelineById } from './helpers'; import { defaultTimelineToTimelineModel, @@ -646,13 +645,6 @@ describe('helpers', () => { jest.clearAllMocks(); }); - test('dispatch updateIsLoading to true', () => { - expect(dispatchUpdateIsLoading).toBeCalledWith({ - id: TimelineId.active, - isLoading: true, - }); - }); - test('get timeline by Id', () => { expect(resolveTimeline).toHaveBeenCalled(); }); @@ -671,13 +663,6 @@ describe('helpers', () => { ...timeline, }); }); - - test('dispatch updateIsLoading to false', () => { - expect(dispatchUpdateIsLoading).toBeCalledWith({ - id: TimelineId.active, - isLoading: false, - }); - }); }); describe('update a timeline', () => { @@ -706,11 +691,6 @@ describe('helpers', () => { await queryTimelineById(args); }); - expect(dispatchUpdateIsLoading).toBeCalledWith({ - id: TimelineId.active, - isLoading: true, - }); - // expect(resolveTimeline).toHaveBeenCalled(); const { timeline } = formatTimelineResponseToModel( omitTypenameInTimeline(getOr({}, 'data.timeline', selectedTimeline)), @@ -741,11 +721,6 @@ describe('helpers', () => { }, }); }); - - expect(dispatchUpdateIsLoading).toBeCalledWith({ - id: TimelineId.active, - isLoading: false, - }); }); test('should update timeline correctly when timeline is untitled', async () => { @@ -764,11 +739,6 @@ describe('helpers', () => { queryTimelineById(newArgs); }); - expect(dispatchUpdateIsLoading).toHaveBeenCalledWith({ - id: TimelineId.active, - isLoading: true, - }); - expect(mockUpdateTimeline).toHaveBeenNthCalledWith( 1, expect.objectContaining({ @@ -778,10 +748,6 @@ describe('helpers', () => { }), }) ); - expect(dispatchUpdateIsLoading).toHaveBeenCalledWith({ - id: TimelineId.active, - isLoading: false, - }); }); test('should update timeline correctly when timeline is already saved and onOpenTimeline is not provided', async () => { @@ -791,11 +757,6 @@ describe('helpers', () => { queryTimelineById(args); }); - expect(dispatchUpdateIsLoading).toHaveBeenCalledWith({ - id: TimelineId.active, - isLoading: true, - }); - await waitFor(() => { expect(mockUpdateTimeline).toHaveBeenNthCalledWith( 1, @@ -860,13 +821,6 @@ describe('helpers', () => { jest.clearAllMocks(); }); - test('dispatch updateIsLoading to true', () => { - expect(dispatchUpdateIsLoading).toBeCalledWith({ - id: TimelineId.active, - isLoading: true, - }); - }); - test('get timeline by Id', () => { expect(resolveTimeline).toHaveBeenCalled(); }); @@ -885,13 +839,6 @@ describe('helpers', () => { }, }); }); - - test('dispatch updateIsLoading to false', () => { - expect(dispatchUpdateIsLoading).toBeCalledWith({ - id: TimelineId.active, - isLoading: false, - }); - }); }); }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.ts b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.ts index e9c1d85b9049e..d3ca6c4654ff3 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.ts @@ -9,8 +9,6 @@ import { set } from '@kbn/safer-lodash-set/fp'; import { getOr } from 'lodash/fp'; import { v4 as uuidv4 } from 'uuid'; import deepMerge from 'deepmerge'; -import { useDispatch } from 'react-redux'; -import { useCallback } from 'react'; import { useDiscoverInTimelineContext } from '../../../common/components/discover_in_timeline/use_discover_in_timeline_context'; import type { ColumnHeaderOptions } from '../../../../common/types/timeline'; import type { @@ -49,7 +47,6 @@ import { DEFAULT_TO_MOMENT, } from '../../../common/utils/default_date_settings'; import { resolveTimeline } from '../../containers/api'; -import { timelineActions } from '../../store'; export const OPEN_TIMELINE_CLASS_NAME = 'open-timeline'; @@ -314,13 +311,6 @@ export interface QueryTimelineById { export const useQueryTimelineById = () => { const { resetDiscoverAppState } = useDiscoverInTimelineContext(); const updateTimeline = useUpdateTimeline(); - const dispatch = useDispatch(); - - const updateIsLoading = useCallback( - (status: { id: string; isLoading: boolean }) => - dispatch(timelineActions.updateIsLoading(status)), - [dispatch] - ); return ({ activeTimelineTab = TimelineTabs.query, @@ -333,7 +323,6 @@ export const useQueryTimelineById = () => { openTimeline = true, savedSearchId, }: QueryTimelineById) => { - updateIsLoading({ id: TimelineId.active, isLoading: true }); if (timelineId == null) { updateTimeline({ id: TimelineId.active, @@ -356,7 +345,6 @@ export const useQueryTimelineById = () => { }, }); resetDiscoverAppState(); - updateIsLoading({ id: TimelineId.active, isLoading: false }); } else { return Promise.resolve(resolveTimeline(timelineId)) .then((result) => { @@ -409,9 +397,6 @@ export const useQueryTimelineById = () => { if (onError != null) { onError(error, timelineId); } - }) - .finally(() => { - updateIsLoading({ id: TimelineId.active, isLoading: false }); }); } }; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/index.tsx index bcdf750d114f0..7a90b5254e445 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/index.tsx @@ -109,9 +109,6 @@ export const DataProviders = React.memo(({ timelineId }) => { const { browserFields } = useSourcererDataView(SourcererScopeName.timeline); const getTimeline = useMemo(() => timelineSelectors.getTimelineByIdSelector(), []); - const isLoading = useDeepEqualSelector( - (state) => (getTimeline(state, timelineId) ?? timelineDefaults).isLoading - ); const dataProviders = useDeepEqualSelector( (state) => (getTimeline(state, timelineId) ?? timelineDefaults).dataProviders ); @@ -167,7 +164,7 @@ export const DataProviders = React.memo(({ timelineId }) => { dataProviders={dataProviders} /> ) : ( - + )} diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_item_actions.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_item_actions.tsx index a5bef9b83551b..39d765fdd1f61 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_item_actions.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_item_actions.tsx @@ -44,7 +44,6 @@ interface OwnProps { kqlQuery: string; // eslint-disable-line react/no-unused-prop-types isEnabled: boolean; isExcluded: boolean; - isLoading: boolean; isOpen: boolean; onDataProviderEdited?: OnDataProviderEdited; operator: QueryOperator; @@ -77,7 +76,6 @@ interface GetProviderActionsProps { field: string; isEnabled: boolean; isExcluded: boolean; - isLoading: boolean; onDataProviderEdited?: OnDataProviderEdited; onFilterForFieldPresent: () => void; operator: QueryOperator; @@ -98,7 +96,6 @@ export const getProviderActions = ({ field, isEnabled, isExcluded, - isLoading, operator, onDataProviderEdited, onFilterForFieldPresent, @@ -116,28 +113,24 @@ export const getProviderActions = ({ items: [ { className: EDIT_CLASS_NAME, - disabled: isLoading, icon: 'pencil', name: i18n.EDIT_MENU_ITEM, panel: 1, }, { className: EXCLUDE_CLASS_NAME, - disabled: isLoading, icon: `${isExcluded ? 'plusInCircle' : 'minusInCircle'}`, name: isExcluded ? i18n.INCLUDE_DATA_PROVIDER : i18n.EXCLUDE_DATA_PROVIDER, onClick: toggleExcluded, }, { className: ENABLE_CLASS_NAME, - disabled: isLoading, icon: `${isEnabled ? 'eyeClosed' : 'eye'}`, name: isEnabled ? i18n.TEMPORARILY_DISABLE_DATA_PROVIDER : i18n.RE_ENABLE_DATA_PROVIDER, onClick: toggleEnabled, }, { className: FILTER_FOR_FIELD_PRESENT_CLASS_NAME, - disabled: isLoading, icon: 'logstashFilter', name: i18n.FILTER_FOR_FIELD_PRESENT, onClick: onFilterForFieldPresent, @@ -145,7 +138,7 @@ export const getProviderActions = ({ timelineType === TimelineTypeEnum.template ? { className: CONVERT_TO_FIELD_CLASS_NAME, - disabled: isLoading || operator === IS_ONE_OF_OPERATOR, + disabled: operator === IS_ONE_OF_OPERATOR, icon: 'visText', name: type === DataProviderTypeEnum.template @@ -156,7 +149,6 @@ export const getProviderActions = ({ : { name: null }, { className: DELETE_CLASS_NAME, - disabled: isLoading, icon: 'trash', name: i18n.DELETE_DATA_PROVIDER, onClick: deleteItem, @@ -196,7 +188,6 @@ export class ProviderItemActions extends React.PureComponent { field, isEnabled, isExcluded, - isLoading, isOpen, operator, providerId, @@ -216,7 +207,6 @@ export class ProviderItemActions extends React.PureComponent { field, isEnabled, isExcluded, - isLoading, onDataProviderEdited: this.onDataProviderEdited, onFilterForFieldPresent: this.onFilterForFieldPresent, operator, diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_item_badge.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_item_badge.tsx index 5f6f567bf32c7..53d43689a2706 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_item_badge.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/provider_item_badge.tsx @@ -5,7 +5,6 @@ * 2.0. */ -import { noop } from 'lodash/fp'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useDispatch } from 'react-redux'; @@ -15,10 +14,7 @@ import { TimelineTypeEnum, } from '../../../../../common/api/timeline'; import type { BrowserFields } from '../../../../common/containers/source'; -import { - useDeepEqualSelector, - useShallowEqualSelector, -} from '../../../../common/hooks/use_selector'; +import { useShallowEqualSelector } from '../../../../common/hooks/use_selector'; import { timelineSelectors } from '../../../store'; import type { PrimitiveOrArrayOfPrimitives } from '../../../../common/lib/kuery'; @@ -27,7 +23,6 @@ import { ProviderBadge } from './provider_badge'; import { ProviderItemActions } from './provider_item_actions'; import type { DataProvidersAnd, QueryOperator } from './data_provider'; import { dragAndDropActions } from '../../../../common/store/drag_and_drop'; -import { timelineDefaults } from '../../../store/defaults'; interface ProviderItemBadgeProps { andProviderId?: string; @@ -86,10 +81,6 @@ export const ProviderItemBadge = React.memo( return getTimeline(state, timelineId)?.timelineType ?? TimelineTypeEnum.default; }); - const { isLoading } = useDeepEqualSelector( - (state) => getTimeline(state, timelineId ?? '') ?? timelineDefaults - ); - const togglePopover = useCallback(() => { setIsPopoverOpen(!isPopoverOpen); }, [isPopoverOpen, setIsPopoverOpen]); @@ -142,7 +133,7 @@ export const ProviderItemBadge = React.memo( const button = useMemo( () => ( ( field, isEnabled, isExcluded, - isLoading, kqlQuery, onToggleTypeProvider, operator, @@ -186,7 +176,6 @@ export const ProviderItemBadge = React.memo( kqlQuery={kqlQuery} isEnabled={isEnabled} isExcluded={isExcluded} - isLoading={isLoading} isOpen={isPopoverOpen} onDataProviderEdited={onDataProviderEdited} operator={operator} diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/providers.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/providers.test.tsx index d6492c0d864b0..dbb073ddecc80 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/providers.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/providers.test.tsx @@ -32,7 +32,7 @@ describe('Providers', () => { beforeEach(() => { jest.clearAllMocks(); - (useDeepEqualSelector as jest.Mock).mockReturnValue({ isLoading: false }); + (useDeepEqualSelector as jest.Mock).mockReturnValue({}); }); describe('rendering', () => { @@ -88,28 +88,6 @@ describe('Providers', () => { expect(mockOnDataProviderRemoved.mock.calls[0][0].providerId).toEqual('id-Provider 1'); }); - test('while loading data, it does NOT invoke the onDataProviderRemoved callback when the close button is clicked', () => { - (useDeepEqualSelector as jest.Mock).mockReturnValue({ isLoading: true }); - const wrapper = mount( - - - - - - ); - - wrapper - .find('[data-test-subj="providerBadge"] [data-euiicon-type]') - .first() - .simulate('click'); - - expect(mockOnDataProviderRemoved).not.toBeCalled(); - }); - test('it invokes the onDataProviderRemoved callback when you click on the option "Delete" in the provider menu', () => { const wrapper = mount( @@ -132,31 +110,6 @@ describe('Providers', () => { .simulate('click'); expect(mockOnDataProviderRemoved.mock.calls[0][0].providerId).toEqual('id-Provider 1'); }); - - test('while loading data, it does NOT invoke the onDataProviderRemoved callback when you click on the option "Delete" in the provider menu', () => { - (useDeepEqualSelector as jest.Mock).mockReturnValue({ isLoading: true }); - const wrapper = mount( - - - - - - ); - wrapper.find('button[data-test-subj="providerBadge"]').first().simulate('click'); - - wrapper.update(); - - wrapper - .find(`[data-test-subj="providerActions"] .${DELETE_CLASS_NAME}`) - .first() - .simulate('click'); - - expect(mockOnDataProviderRemoved).not.toBeCalled(); - }); }); describe('#onToggleDataProviderEnabled', () => { @@ -191,35 +144,6 @@ describe('Providers', () => { providerId: 'id-Provider 1', }); }); - - test('while loading data, it does NOT invoke the onToggleDataProviderEnabled callback when you click on the option "Temporary disable" in the provider menu', () => { - (useDeepEqualSelector as jest.Mock).mockReturnValue({ isLoading: true }); - const mockOnToggleDataProviderEnabled = jest.spyOn( - timelineActions, - 'updateDataProviderEnabled' - ); - const wrapper = mount( - - - - - - ); - - wrapper.find('button[data-test-subj="providerBadge"]').first().simulate('click'); - wrapper.update(); - - wrapper - .find(`[data-test-subj="providerActions"] .${ENABLE_CLASS_NAME}`) - .first() - .simulate('click'); - - expect(mockOnToggleDataProviderEnabled).not.toBeCalled(); - }); }); describe('#onToggleDataProviderExcluded', () => { @@ -257,37 +181,6 @@ describe('Providers', () => { providerId: 'id-Provider 1', }); }); - - test('while loading data, it does NOT invoke the onToggleDataProviderExcluded callback when you click on the option "Exclude results" in the provider menu', () => { - (useDeepEqualSelector as jest.Mock).mockReturnValue({ isLoading: true }); - const mockOnToggleDataProviderExcluded = jest.spyOn( - timelineActions, - 'updateDataProviderExcluded' - ); - - const wrapper = mount( - - - - - - ); - - wrapper.find('button[data-test-subj="providerBadge"]').first().simulate('click'); - - wrapper.update(); - - wrapper - .find(`[data-test-subj="providerActions"] .${EXCLUDE_CLASS_NAME}`) - .first() - .simulate('click'); - - expect(mockOnToggleDataProviderExcluded).not.toBeCalled(); - }); }); describe('#ProviderWithAndProvider', () => { @@ -349,35 +242,6 @@ describe('Providers', () => { }); }); - test('while loading data, it does NOT invoke the onDataProviderRemoved callback when you click on the close button is clicked', () => { - (useDeepEqualSelector as jest.Mock).mockReturnValue({ isLoading: true }); - const dataProviders = mockDataProviders.slice(0, 1); - dataProviders[0].and = mockDataProviders.slice(1, 3); - - const wrapper = mount( - - - - - - ); - - wrapper - .find('[data-test-subj="providerBadge"]') - .at(4) - .find('[data-euiicon-type]') - .first() - .simulate('click'); - - wrapper.update(); - - expect(mockOnDataProviderRemoved).not.toBeCalled(); - }); - test('it invokes the onToggleDataProviderEnabled callback when you click on the option "Temporary disable" in the provider menu', () => { const dataProviders = mockDataProviders.slice(0, 1); dataProviders[0].and = mockDataProviders.slice(1, 3); @@ -420,44 +284,6 @@ describe('Providers', () => { }); }); - test('while loading data, it does NOT invoke the onToggleDataProviderEnabled callback when you click on the option "Temporary disable" in the provider menu', () => { - (useDeepEqualSelector as jest.Mock).mockReturnValue({ isLoading: true }); - const dataProviders = mockDataProviders.slice(0, 1); - dataProviders[0].and = mockDataProviders.slice(1, 3); - const mockOnToggleDataProviderEnabled = jest.spyOn( - timelineActions, - 'updateDataProviderEnabled' - ); - - const wrapper = mount( - - - - - - ); - - wrapper - .find('[data-test-subj="providerBadge"]') - .at(4) - .find('button') - .first() - .simulate('click'); - - wrapper.update(); - - wrapper - .find(`[data-test-subj="providerActions"] .${ENABLE_CLASS_NAME}`) - .first() - .simulate('click'); - - expect(mockOnToggleDataProviderEnabled).not.toBeCalled(); - }); - test('it invokes the onToggleDataProviderExcluded callback when you click on the option "Exclude results" in the provider menu', () => { const dataProviders = mockDataProviders.slice(0, 1); dataProviders[0].and = mockDataProviders.slice(1, 3); @@ -499,43 +325,5 @@ describe('Providers', () => { providerId: 'id-Provider 1', }); }); - - test('while loading data, it does NOT invoke the onToggleDataProviderExcluded callback when you click on the option "Exclude results" in the provider menu', () => { - (useDeepEqualSelector as jest.Mock).mockReturnValue({ isLoading: true }); - const dataProviders = mockDataProviders.slice(0, 1); - dataProviders[0].and = mockDataProviders.slice(1, 3); - const mockOnToggleDataProviderExcluded = jest.spyOn( - timelineActions, - 'updateDataProviderExcluded' - ); - - const wrapper = mount( - - - - - - ); - - wrapper - .find('[data-test-subj="providerBadge"]') - .at(4) - .find('button') - .first() - .simulate('click'); - - wrapper.update(); - - wrapper - .find(`[data-test-subj="providerActions"] .${EXCLUDE_CLASS_NAME}`) - .first() - .simulate('click'); - - expect(mockOnToggleDataProviderExcluded).not.toBeCalled(); - }); }); }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/index.tsx index 05d15f076f569..e54bfc82399f9 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/index.tsx @@ -100,7 +100,6 @@ const StatefulTimelineComponent: React.FC = ({ 'sessionViewConfig', 'initialized', 'show', - 'isLoading', 'activeTab', ], getTimeline(state, timelineId) ?? timelineDefaults diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/eql/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/eql/index.tsx index 5c4a592d99a7d..22289d090ab39 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/eql/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/eql/index.tsx @@ -7,9 +7,9 @@ import { EuiFlexGroup } from '@elastic/eui'; import { isEmpty } from 'lodash/fp'; -import React, { useCallback, useEffect, useMemo } from 'react'; +import React, { useCallback, useMemo } from 'react'; import type { ConnectedProps } from 'react-redux'; -import { connect, useDispatch } from 'react-redux'; +import { connect } from 'react-redux'; import deepEqual from 'fast-deep-equal'; import { InPortal } from 'react-reverse-portal'; import type { EuiDataGridControlColumn } from '@elastic/eui'; @@ -25,7 +25,7 @@ import { } from '../../../../../flyout/document_details/shared/constants/panel_keys'; import { useDeepEqualSelector } from '../../../../../common/hooks/use_selector'; import { useIsExperimentalFeatureEnabled } from '../../../../../common/hooks/use_experimental_features'; -import { timelineActions, timelineSelectors } from '../../../../store'; +import { timelineSelectors } from '../../../../store'; import { useTimelineEvents } from '../../../../containers'; import { TimelineId, TimelineTabs } from '../../../../../../common/types/timeline'; import type { inputsModel, State } from '../../../../../common/store'; @@ -66,7 +66,6 @@ export const EqlTabContentComponent: React.FC = ({ eventIdToNoteIds, }) => { const { telemetry } = useKibana().services; - const dispatch = useDispatch(); const { query: eqlQuery = '', ...restEqlOption } = eqlOptions; const { portalNode: eqlEventsCountPortalNode } = useEqlEventsCountPortal(); const { setTimelineFullScreen, timelineFullScreen } = useTimelineFullScreen(); @@ -206,15 +205,6 @@ export const EqlTabContentComponent: React.FC = ({ [dataLoadingState] ); - useEffect(() => { - dispatch( - timelineActions.updateIsLoading({ - id: timelineId, - isLoading: isQueryLoading || loadingSourcerer, - }) - ); - }, [loadingSourcerer, timelineId, isQueryLoading, dispatch]); - const unifiedHeader = useMemo( () => ( diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/query/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/query/index.tsx index ec61c67a3954a..967253a34a71a 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/query/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/query/index.tsx @@ -280,15 +280,6 @@ export const QueryTabContentComponent: React.FC = ({ [dataLoadingState] ); - useEffect(() => { - dispatch( - timelineActions.updateIsLoading({ - id: timelineId, - isLoading: isQueryLoading || loadingSourcerer, - }) - ); - }, [loadingSourcerer, timelineId, isQueryLoading, dispatch]); - // NOTE: The timeline is blank after browser FORWARD navigation (after using back button to navigate to // the previous page from the timeline), yet we still see total count. This is because the timeline // is not getting refreshed when using browser navigation. diff --git a/x-pack/plugins/security_solution/public/timelines/store/actions.ts b/x-pack/plugins/security_solution/public/timelines/store/actions.ts index e65b7273b5de7..976d35c030651 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/actions.ts +++ b/x-pack/plugins/security_solution/public/timelines/store/actions.ts @@ -191,11 +191,6 @@ export const updateEqlOptions = actionCreator<{ value: string | undefined; }>('UPDATE_EQL_OPTIONS_TIMELINE'); -export const updateIsLoading = actionCreator<{ - id: string; - isLoading: boolean; -}>('UPDATE_LOADING'); - export const setEventsLoading = actionCreator<{ id: string; eventIds: string[]; diff --git a/x-pack/plugins/security_solution/public/timelines/store/defaults.ts b/x-pack/plugins/security_solution/public/timelines/store/defaults.ts index e4fd97cd50534..5dbe2d1b9c1e8 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/defaults.ts +++ b/x-pack/plugins/security_solution/public/timelines/store/defaults.ts @@ -64,7 +64,6 @@ export const timelineDefaults: SubsetTimelineModel & indexNames: [], isFavorite: false, isLive: false, - isLoading: false, isSaving: false, itemsPerPage: 25, itemsPerPageOptions: [10, 25, 50, 100], diff --git a/x-pack/plugins/security_solution/public/timelines/store/helpers.test.ts b/x-pack/plugins/security_solution/public/timelines/store/helpers.test.ts index b0067d6d0d9f4..328c62fb08e20 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/helpers.test.ts +++ b/x-pack/plugins/security_solution/public/timelines/store/helpers.test.ts @@ -104,7 +104,6 @@ const basicTimeline: TimelineModel = { indexNames: [], isFavorite: false, isLive: false, - isLoading: false, isSaving: false, isSelectAllChecked: false, itemsPerPage: 25, diff --git a/x-pack/plugins/security_solution/public/timelines/store/helpers.ts b/x-pack/plugins/security_solution/public/timelines/store/helpers.ts index a9566c22a814a..6aa4262b26310 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/helpers.ts +++ b/x-pack/plugins/security_solution/public/timelines/store/helpers.ts @@ -131,7 +131,6 @@ export const addTimelineToStore = ({ ...timelineById, [id]: { ...timeline, - isLoading: timelineById[id].isLoading, initialized: timeline.initialized ?? timelineById[id].initialized, resolveTimelineConfig, dateRange: @@ -180,7 +179,6 @@ export const addNewTimeline = ({ savedObjectId: null, version: null, isSaving: false, - isLoading: false, timelineType, ...templateTimelineInfo, }, diff --git a/x-pack/plugins/security_solution/public/timelines/store/middlewares/timeline_save.test.ts b/x-pack/plugins/security_solution/public/timelines/store/middlewares/timeline_save.test.ts index 3c8bcf4b55f58..c3d7a26d7b027 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/middlewares/timeline_save.test.ts +++ b/x-pack/plugins/security_solution/public/timelines/store/middlewares/timeline_save.test.ts @@ -295,7 +295,6 @@ describe('Timeline save middleware', () => { isFavorite: false, isLive: false, isSelectAllChecked: false, - isLoading: false, isSaving: false, itemsPerPage: 25, itemsPerPageOptions: [10, 25, 50, 100], diff --git a/x-pack/plugins/security_solution/public/timelines/store/model.ts b/x-pack/plugins/security_solution/public/timelines/store/model.ts index 4061276204668..92c435f93cb43 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/model.ts +++ b/x-pack/plugins/security_solution/public/timelines/store/model.ts @@ -129,7 +129,6 @@ export interface TimelineModel { selectedEventIds: Record; /** If selectAll checkbox in header is checked **/ isSelectAllChecked: boolean; - isLoading: boolean; selectAll: boolean; /* discover saved search Id */ savedSearchId: string | null; @@ -190,7 +189,6 @@ export type SubsetTimelineModel = Readonly< | 'show' | 'sort' | 'isSaving' - | 'isLoading' | 'savedObjectId' | 'version' | 'status' diff --git a/x-pack/plugins/security_solution/public/timelines/store/reducer.ts b/x-pack/plugins/security_solution/public/timelines/store/reducer.ts index ba93b512136c8..546e60e47d10b 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/reducer.ts +++ b/x-pack/plugins/security_solution/public/timelines/store/reducer.ts @@ -45,7 +45,6 @@ import { removeColumn, upsertColumn, updateColumns, - updateIsLoading, updateSort, clearSelected, setSelected, @@ -409,16 +408,6 @@ export const timelineReducer = reducerWithInitialState(initialTimelineState) timelineById: state.timelineById, }), })) - .case(updateIsLoading, (state, { id, isLoading }) => ({ - ...state, - timelineById: { - ...state.timelineById, - [id]: { - ...state.timelineById[id], - isLoading, - }, - }, - })) .case(updateSort, (state, { id, sort }) => ({ ...state, timelineById: updateTableSort({ id, sort, timelineById: state.timelineById }), diff --git a/x-pack/test/security_solution_cypress/cypress/screens/timeline.ts b/x-pack/test/security_solution_cypress/cypress/screens/timeline.ts index df81ad54ecd48..c25bd1b9b115f 100644 --- a/x-pack/test/security_solution_cypress/cypress/screens/timeline.ts +++ b/x-pack/test/security_solution_cypress/cypress/screens/timeline.ts @@ -117,8 +117,6 @@ export const ALERTS_TABLE_COUNT = `[data-test-subj="toolbar-alerts-count"]`; export const STAR_ICON = '[data-test-subj="timeline-favorite-empty-star"]'; -export const TIMELINE_COLUMN_SPINNER = '[data-test-subj="timeline-loading-spinner"]'; - export const TIMELINE_COLLAPSED_ITEMS_BTN = '[data-test-subj="euiCollapsedItemActionsButton"]'; export const TIMELINE_CREATE_TEMPLATE_FROM_TIMELINE_BTN = diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/alerts.ts b/x-pack/test/security_solution_cypress/cypress/tasks/alerts.ts index e8541a529add0..b70adbefa1850 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/alerts.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/alerts.ts @@ -57,7 +57,6 @@ import { TOOLTIP, } from '../screens/alerts'; import { LOADING_INDICATOR, REFRESH_BUTTON } from '../screens/security_header'; -import { TIMELINE_COLUMN_SPINNER } from '../screens/timeline'; import { UPDATE_ENRICHMENT_RANGE_BUTTON, ENRICHMENT_QUERY_END_INPUT, @@ -216,7 +215,6 @@ export const goToClosedAlertsOnRuleDetailsPage = () => { cy.get(CLOSED_ALERTS_FILTER_BTN).click(); cy.get(REFRESH_BUTTON).should('not.have.attr', 'aria-label', 'Needs updating'); cy.get(REFRESH_BUTTON).should('have.attr', 'aria-label', 'Refresh query'); - cy.get(TIMELINE_COLUMN_SPINNER).should('not.exist'); }; export const goToClosedAlerts = () => { @@ -233,7 +231,6 @@ export const goToClosedAlerts = () => { selectPageFilterValue(0, 'closed'); cy.get(REFRESH_BUTTON).should('not.have.attr', 'aria-label', 'Needs updating'); cy.get(REFRESH_BUTTON).should('have.attr', 'aria-label', 'Refresh query'); - cy.get(TIMELINE_COLUMN_SPINNER).should('not.exist'); }; export const goToOpenedAlertsOnRuleDetailsPage = () => { @@ -297,7 +294,6 @@ export const goToAcknowledgedAlerts = () => { selectPageFilterValue(0, 'acknowledged'); cy.get(REFRESH_BUTTON).should('not.have.attr', 'aria-label', 'Needs updating'); cy.get(REFRESH_BUTTON).should('have.attr', 'aria-label', 'Refresh query'); - cy.get(TIMELINE_COLUMN_SPINNER).should('not.exist'); }; export const markAlertsAcknowledged = () => {