From 7749ba523cbfd784982ba3043fb8a0c99dd61ec9 Mon Sep 17 00:00:00 2001 From: Jatin Kathuria Date: Fri, 11 Oct 2024 17:52:42 +0200 Subject: [PATCH 1/7] start: remove unifiedComponentsInTimelineDisabled flag --- .../common/experimental_features.ts | 4 - .../header_actions/header_actions.test.tsx | 59 ++----- .../header_actions/header_actions.tsx | 81 +--------- .../timeline/use_init_timeline_url_param.ts | 7 +- .../use_query_timeline_by_id_on_url_change.ts | 16 +- .../utils/timeline/use_timeline_click.tsx | 8 +- .../use_investigate_in_timeline.tsx | 20 +-- .../rules/use_rule_from_timeline.tsx | 8 +- .../components/open_timeline_button.test.tsx | 7 - .../notes/components/open_timeline_button.tsx | 8 +- .../components/recent_timelines/index.tsx | 8 +- .../components/open_timeline/helpers.test.ts | 28 +--- .../components/open_timeline/helpers.ts | 35 +--- .../components/open_timeline/index.tsx | 23 +-- .../timelines/components/timeline/index.tsx | 12 +- .../timeline/tabs/eql/index.test.tsx | 3 - .../components/timeline/tabs/eql/index.tsx | 151 ++++-------------- .../timeline/tabs/pinned/index.test.tsx | 3 - .../components/timeline/tabs/pinned/index.tsx | 117 +++----------- .../timeline/tabs/query/header/index.tsx | 17 -- .../timeline/tabs/query/index.test.tsx | 3 - .../components/timeline/tabs/query/index.tsx | 142 +++------------- .../query_tab_unified_components.test.tsx | 9 -- .../tabs/shared/use_timeline_columns.tsx | 17 +- .../shared/use_timeline_control_columns.tsx | 150 ++++++++--------- .../unified_components/index.test.tsx | 3 - .../timelines/hooks/use_create_timeline.tsx | 10 +- .../timelines/fields_browser.cy.ts | 108 ------------- .../investigations/timelines/pagination.cy.ts | 83 ---------- .../investigations/timelines/query_tab.cy.ts | 85 ---------- .../timelines/table_row_actions.cy.ts | 57 ------- 31 files changed, 196 insertions(+), 1086 deletions(-) delete mode 100644 x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/fields_browser.cy.ts delete mode 100644 x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/pagination.cy.ts delete mode 100644 x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/query_tab.cy.ts delete mode 100644 x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/table_row_actions.cy.ts diff --git a/x-pack/plugins/security_solution/common/experimental_features.ts b/x-pack/plugins/security_solution/common/experimental_features.ts index 1e5ffee50afc7..81dd264853034 100644 --- a/x-pack/plugins/security_solution/common/experimental_features.ts +++ b/x-pack/plugins/security_solution/common/experimental_features.ts @@ -188,10 +188,6 @@ export const allowedExperimentalValues = Object.freeze({ * */ timelineEsqlTabDisabled: false, - /* - * Disables experimental Discover components, UnifiedFieldList and UnifiedDataTable in Timeline. - */ - unifiedComponentsInTimelineDisabled: false, /* * Disables date pickers and sourcerer in analyzer if needed. diff --git a/x-pack/plugins/security_solution/public/common/components/header_actions/header_actions.test.tsx b/x-pack/plugins/security_solution/public/common/components/header_actions/header_actions.test.tsx index 5b48b4286fe63..22320b2a9a3db 100644 --- a/x-pack/plugins/security_solution/public/common/components/header_actions/header_actions.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/header_actions/header_actions.test.tsx @@ -14,7 +14,6 @@ import { TimelineTabs } from '../../../../common/types'; import { HeaderActions } from './header_actions'; import { timelineActions } from '../../../timelines/store'; import { getColumnHeader } from '../../../timelines/components/timeline/body/column_headers/helpers'; -import { useIsExperimentalFeatureEnabled } from '../../hooks/use_experimental_features'; jest.mock('../../hooks/use_experimental_features', () => ({ useIsExperimentalFeatureEnabled: jest.fn(), @@ -141,51 +140,23 @@ describe('HeaderActions', () => { }); }); - describe('conditional components based on unifiedComponentsInTimelineDisabled', () => { - describe('when unifiedComponentsInTimelineDisabled is false', () => { - beforeEach(() => { - (useIsExperimentalFeatureEnabled as jest.Mock).mockReturnValue(false); - }); - it('should not show the event renderer settings', () => { - const result = render( - - - - ); - expect(result.queryByTestId('show-row-renderers-gear')).toBeNull(); - }); - - it('should not show the sorting settings', () => { - const result = render( - - - - ); - expect(result.queryByTestId('timeline-sorting-fields')).toBeNull(); - }); + describe('Controls', () => { + it('should not show the event renderer settings', () => { + const result = render( + + + + ); + expect(result.queryByTestId('show-row-renderers-gear')).toBeNull(); }); - describe('when unifiedComponentsInTimelineDisabled is true', () => { - beforeEach(() => { - (useIsExperimentalFeatureEnabled as jest.Mock).mockReturnValue(true); - }); - it('should show the event renderer settings', () => { - const result = render( - - - - ); - result.getByTestId('show-row-renderers-gear'); - }); - - it('should show the sorting settings', () => { - const result = render( - - - - ); - result.getByTestId('timeline-sorting-fields'); - }); + it('should not show the sorting settings', () => { + const result = render( + + + + ); + expect(result.queryByTestId('timeline-sorting-fields')).toBeNull(); }); }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/header_actions/header_actions.tsx b/x-pack/plugins/security_solution/public/common/components/header_actions/header_actions.tsx index 7dabf3014da95..034f454abaef1 100644 --- a/x-pack/plugins/security_solution/public/common/components/header_actions/header_actions.tsx +++ b/x-pack/plugins/security_solution/public/common/components/header_actions/header_actions.tsx @@ -6,13 +6,13 @@ */ import React, { useMemo, useCallback, memo } from 'react'; -import type { EuiDataGridSorting, EuiDataGridSchemaDetector } from '@elastic/eui'; -import { EuiButtonIcon, EuiToolTip, useDataGridColumnSorting, EuiCheckbox } from '@elastic/eui'; +import type { EuiDataGridSorting } from '@elastic/eui'; +import { EuiButtonIcon, EuiToolTip, EuiCheckbox } from '@elastic/eui'; import { useDispatch } from 'react-redux'; import styled from 'styled-components'; import type { HeaderActionProps, SortDirection } from '../../../../common/types'; -import { TimelineTabs, TimelineId } from '../../../../common/types'; +import { TimelineId } from '../../../../common/types'; import { isFullScreen } from '../../../timelines/components/timeline/body/column_headers'; import { isActiveTimeline } from '../../../helpers'; import { getColumnHeader } from '../../../timelines/components/timeline/body/column_headers/helpers'; @@ -21,28 +21,12 @@ import { useGlobalFullScreen, useTimelineFullScreen } from '../../containers/use import { useKibana } from '../../lib/kibana'; import { DEFAULT_ACTION_BUTTON_WIDTH } from '.'; import { EventsTh, EventsThContent } from '../../../timelines/components/timeline/styles'; -import { StatefulRowRenderersBrowser } from '../../../timelines/components/row_renderers_browser'; import { EXIT_FULL_SCREEN } from '../exit_full_screen/translations'; import { EventsSelect } from '../../../timelines/components/timeline/body/column_headers/events_select'; import * as i18n from './translations'; -import { useIsExperimentalFeatureEnabled } from '../../hooks/use_experimental_features'; import { useDeepEqualSelector } from '../../hooks/use_selector'; import { selectTimelineById } from '../../../timelines/store/selectors'; -const SortingColumnsContainer = styled.div` - button { - color: ${({ theme }) => theme.eui.euiColorPrimary}; - } - - .euiPopover .euiButtonEmpty { - padding: 0; - - .euiButtonEmpty__text { - display: none; - } - } -`; - const FieldBrowserContainer = styled.div` .euiToolTipAnchor { .euiButtonContent { @@ -66,10 +50,6 @@ const ActionsContainer = styled.div` display: flex; `; -// Defined statically to reduce rerenders -const emptySchema = {}; -const emptySchemaDetectors: EuiDataGridSchemaDetector[] = []; - const HeaderActionsComponent: React.FC = memo( ({ width, @@ -91,10 +71,6 @@ const HeaderActionsComponent: React.FC = memo( const { timelineFullScreen, setTimelineFullScreen } = useTimelineFullScreen(); const dispatch = useDispatch(); - const unifiedComponentsInTimelineDisabled = useIsExperimentalFeatureEnabled( - 'unifiedComponentsInTimelineDisabled' - ); - const { defaultColumns } = useDeepEqualSelector((state) => selectTimelineById(state, timelineId) ); @@ -151,35 +127,6 @@ const HeaderActionsComponent: React.FC = memo( [columnHeaders, dispatch, timelineId] ); - const sortedColumns = useMemo( - () => ({ - onSort: onSortColumns, - columns: - sort?.map<{ id: string; direction: 'asc' | 'desc' }>(({ columnId, sortDirection }) => ({ - id: columnId, - direction: sortDirection as 'asc' | 'desc', - })) ?? [], - }), - [onSortColumns, sort] - ); - const displayValues = useMemo( - () => - columnHeaders?.reduce((acc, ch) => ({ ...acc, [ch.id]: ch.displayAsText ?? ch.id }), {}) ?? - {}, - [columnHeaders] - ); - - const myColumns = useMemo( - () => - columnHeaders?.map(({ aggregatable, displayAsText, id, type }) => ({ - id, - isSortable: aggregatable, - displayAsText, - schema: type, - })) ?? [], - [columnHeaders] - ); - const onResetColumns = useCallback(() => { dispatch(timelineActions.updateColumns({ id: timelineId, columns: defaultColumns })); }, [defaultColumns, dispatch, timelineId]); @@ -206,14 +153,6 @@ const HeaderActionsComponent: React.FC = memo( [columnHeaders, dispatch, timelineId, defaultColumns] ); - const ColumnSorting = useDataGridColumnSorting({ - columns: myColumns, - sorting: sortedColumns, - schema: emptySchema, - schemaDetectors: emptySchemaDetectors, - displayValues, - }); - return ( {showSelectAllCheckbox && ( @@ -242,11 +181,6 @@ const HeaderActionsComponent: React.FC = memo( )} - {unifiedComponentsInTimelineDisabled && ( - - - - )} {showFullScreenToggle && ( @@ -275,15 +209,6 @@ const HeaderActionsComponent: React.FC = memo( )} - {tabType !== TimelineTabs.eql && unifiedComponentsInTimelineDisabled && ( - - - - {ColumnSorting} - - - - )} {showEventsSelect && ( diff --git a/x-pack/plugins/security_solution/public/common/hooks/timeline/use_init_timeline_url_param.ts b/x-pack/plugins/security_solution/public/common/hooks/timeline/use_init_timeline_url_param.ts index d885787c14b12..5e032a9a97d07 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/timeline/use_init_timeline_url_param.ts +++ b/x-pack/plugins/security_solution/public/common/hooks/timeline/use_init_timeline_url_param.ts @@ -19,10 +19,6 @@ import { URL_PARAM_KEY } from '../use_url_state'; import { useIsExperimentalFeatureEnabled } from '../use_experimental_features'; export const useInitTimelineFromUrlParam = () => { - const unifiedComponentsInTimelineDisabled = useIsExperimentalFeatureEnabled( - 'unifiedComponentsInTimelineDisabled' - ); - const isEsqlTabDisabled = useIsExperimentalFeatureEnabled('timelineEsqlTabDisabled'); const queryTimelineById = useQueryTimelineById(); @@ -43,11 +39,10 @@ export const useInitTimelineFromUrlParam = () => { timelineId: initialState.id, openTimeline: initialState.isOpen, savedSearchId: initialState.savedSearchId, - unifiedComponentsInTimelineDisabled, }); } }, - [isEsqlTabDisabled, queryTimelineById, unifiedComponentsInTimelineDisabled] + [isEsqlTabDisabled, queryTimelineById] ); useEffect(() => { diff --git a/x-pack/plugins/security_solution/public/common/hooks/timeline/use_query_timeline_by_id_on_url_change.ts b/x-pack/plugins/security_solution/public/common/hooks/timeline/use_query_timeline_by_id_on_url_change.ts index d4df6d67504d6..60d4ff10b8de1 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/timeline/use_query_timeline_by_id_on_url_change.ts +++ b/x-pack/plugins/security_solution/public/common/hooks/timeline/use_query_timeline_by_id_on_url_change.ts @@ -21,7 +21,6 @@ import { getQueryStringFromLocation, } from '../../utils/global_query_string/helpers'; import { URL_PARAM_KEY } from '../use_url_state'; -import { useIsExperimentalFeatureEnabled } from '../use_experimental_features'; /** * After the initial load of the security solution, timeline is not updated when the timeline URL search value is changed @@ -42,10 +41,6 @@ export const useQueryTimelineByIdOnUrlChange = () => { const oldSearch = usePrevious(search); const timelineIdFromReduxStore = flyoutTimeline?.savedObjectId ?? ''; - const unifiedComponentsInTimelineDisabled = useIsExperimentalFeatureEnabled( - 'unifiedComponentsInTimelineDisabled' - ); - const [previousTimeline, currentTimeline] = useMemo(() => { const oldUrlStateString = getQueryStringKeyValue({ urlKey: URL_PARAM_KEY.timeline, @@ -74,18 +69,9 @@ export const useQueryTimelineByIdOnUrlChange = () => { graphEventId, timelineId: newId, openTimeline: true, - unifiedComponentsInTimelineDisabled, }); } - }, [ - timelineIdFromReduxStore, - oldId, - newId, - activeTab, - graphEventId, - queryTimelineById, - unifiedComponentsInTimelineDisabled, - ]); + }, [timelineIdFromReduxStore, oldId, newId, activeTab, graphEventId, queryTimelineById]); }; export const getQueryStringKeyValue = ({ search, urlKey }: { search: string; urlKey: string }) => diff --git a/x-pack/plugins/security_solution/public/common/utils/timeline/use_timeline_click.tsx b/x-pack/plugins/security_solution/public/common/utils/timeline/use_timeline_click.tsx index db42ca9b774bd..f5e866f240e16 100644 --- a/x-pack/plugins/security_solution/public/common/utils/timeline/use_timeline_click.tsx +++ b/x-pack/plugins/security_solution/public/common/utils/timeline/use_timeline_click.tsx @@ -8,25 +8,19 @@ import { useCallback } from 'react'; import { useQueryTimelineById } from '../../../timelines/components/open_timeline/helpers'; import type { TimelineErrorCallback } from '../../../timelines/components/open_timeline/types'; -import { useIsExperimentalFeatureEnabled } from '../../hooks/use_experimental_features'; export const useTimelineClick = () => { const queryTimelineById = useQueryTimelineById(); - const unifiedComponentsInTimelineDisabled = useIsExperimentalFeatureEnabled( - 'unifiedComponentsInTimelineDisabled' - ); - const handleTimelineClick = useCallback( (timelineId: string, onError: TimelineErrorCallback, graphEventId?: string) => { queryTimelineById({ graphEventId, timelineId, onError, - unifiedComponentsInTimelineDisabled, }); }, - [queryTimelineById, unifiedComponentsInTimelineDisabled] + [queryTimelineById] ); return handleTimelineClick; 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 a68d773468e75..a67eb08496dd0 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 @@ -19,7 +19,6 @@ import { useApi } from '@kbn/securitysolution-list-hooks'; import type { Filter } from '@kbn/es-query'; import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs'; import { isEmpty } from 'lodash'; -import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; import { createHistoryEntry } from '../../../../common/utils/global_query_string/helpers'; import { useKibana } from '../../../../common/lib/kibana'; import { TimelineId } from '../../../../../common/types/timeline'; @@ -35,7 +34,6 @@ import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; import { useStartTransaction } from '../../../../common/lib/apm/use_start_transaction'; import { ALERTS_ACTIONS } from '../../../../common/lib/apm/user_actions'; import { defaultUdtHeaders } from '../../../../timelines/components/timeline/unified_components/default_headers'; -import { defaultHeaders } from '../../../../timelines/components/timeline/body/column_headers/default_headers'; interface UseInvestigateInTimelineActionProps { ecsRowData?: Ecs | Ecs[] | null; @@ -146,21 +144,13 @@ export const useInvestigateInTimeline = ({ timelineType: TimelineTypeEnum.default, }); - const unifiedComponentsInTimelineDisabled = useIsExperimentalFeatureEnabled( - 'unifiedComponentsInTimelineDisabled' - ); - const updateTimeline = useUpdateTimeline(); const createTimeline = useCallback( async ({ from: fromTimeline, timeline, to: toTimeline, ruleNote }: CreateTimelineProps) => { const newColumns = timeline.columns; const newColumnsOverride = - !newColumns || isEmpty(newColumns) - ? !unifiedComponentsInTimelineDisabled - ? defaultUdtHeaders - : defaultHeaders - : newColumns; + !newColumns || isEmpty(newColumns) ? defaultUdtHeaders : newColumns; await clearActiveTimeline(); updateTimelineIsLoading({ id: TimelineId.active, isLoading: false }); @@ -175,7 +165,6 @@ export const useInvestigateInTimeline = ({ indexNames: timeline.indexNames ?? [], show: true, excludedRowRendererIds: - !unifiedComponentsInTimelineDisabled && timeline.timelineType !== TimelineTypeEnum.template ? timeline.excludedRowRendererIds : [], @@ -184,12 +173,7 @@ export const useInvestigateInTimeline = ({ ruleNote, }); }, - [ - updateTimeline, - updateTimelineIsLoading, - clearActiveTimeline, - unifiedComponentsInTimelineDisabled, - ] + [updateTimeline, updateTimelineIsLoading, clearActiveTimeline] ); const investigateInTimelineAlertClick = useCallback(async () => { diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_from_timeline.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_from_timeline.tsx index a8eec62f2d58a..27c2699cdf195 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_from_timeline.tsx +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_from_timeline.tsx @@ -10,7 +10,6 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useDispatch } from 'react-redux'; import { i18n } from '@kbn/i18n'; import type { EqlOptionsSelected } from '@kbn/timelines-plugin/common'; -import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; import { convertKueryToElasticSearchQuery } from '../../../../common/lib/kuery'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; import { useSourcererDataView } from '../../../../sourcerer/containers'; @@ -48,10 +47,6 @@ export const useRuleFromTimeline = (setRuleQuery: SetRuleQuery): RuleFromTimelin SourcererScopeName.timeline ); - const unifiedComponentsInTimelineDisabled = useIsExperimentalFeatureEnabled( - 'unifiedComponentsInTimelineDisabled' - ); - const isEql = useRef(false); // selectedTimeline = timeline to set rule from @@ -200,11 +195,10 @@ export const useRuleFromTimeline = (setRuleQuery: SetRuleQuery): RuleFromTimelin queryTimelineById({ timelineId, onOpenTimeline, - unifiedComponentsInTimelineDisabled, }); } }, - [onOpenTimeline, queryTimelineById, selectedTimeline, unifiedComponentsInTimelineDisabled] + [onOpenTimeline, queryTimelineById, selectedTimeline] ); const [urlStateInitialized, setUrlStateInitialized] = useState(false); diff --git a/x-pack/plugins/security_solution/public/notes/components/open_timeline_button.test.tsx b/x-pack/plugins/security_solution/public/notes/components/open_timeline_button.test.tsx index 85ecfce68e5d9..c6a2629494758 100644 --- a/x-pack/plugins/security_solution/public/notes/components/open_timeline_button.test.tsx +++ b/x-pack/plugins/security_solution/public/notes/components/open_timeline_button.test.tsx @@ -10,7 +10,6 @@ import React from 'react'; import { OpenTimelineButtonIcon } from './open_timeline_button'; import type { Note } from '../../../common/api/timeline'; import { OPEN_TIMELINE_BUTTON_TEST_ID } from './test_ids'; -import { useIsExperimentalFeatureEnabled } from '../../common/hooks/use_experimental_features'; import { useQueryTimelineById } from '../../timelines/components/open_timeline/helpers'; jest.mock('../../common/hooks/use_experimental_features'); @@ -40,11 +39,6 @@ describe('OpenTimelineButtonIcon', () => { const openTimeline = jest.fn(); (useQueryTimelineById as jest.Mock).mockReturnValue(openTimeline); - const unifiedComponentsInTimelineDisabled = false; - (useIsExperimentalFeatureEnabled as jest.Mock).mockReturnValue( - unifiedComponentsInTimelineDisabled - ); - const { getByTestId } = render(); const button = getByTestId(`${OPEN_TIMELINE_BUTTON_TEST_ID}-${index}`); @@ -55,7 +49,6 @@ describe('OpenTimelineButtonIcon', () => { onOpenTimeline: undefined, timelineId: note.timelineId, timelineType: undefined, - unifiedComponentsInTimelineDisabled, }); }); }); diff --git a/x-pack/plugins/security_solution/public/notes/components/open_timeline_button.tsx b/x-pack/plugins/security_solution/public/notes/components/open_timeline_button.tsx index b44ffd55a767a..91f3a722ebeeb 100644 --- a/x-pack/plugins/security_solution/public/notes/components/open_timeline_button.tsx +++ b/x-pack/plugins/security_solution/public/notes/components/open_timeline_button.tsx @@ -8,7 +8,6 @@ import React, { memo, useCallback } from 'react'; import { EuiButtonIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { useIsExperimentalFeatureEnabled } from '../../common/hooks/use_experimental_features'; import { useQueryTimelineById } from '../../timelines/components/open_timeline/helpers'; import { OPEN_TIMELINE_BUTTON_TEST_ID } from './test_ids'; import type { Note } from '../../../common/api/timeline'; @@ -32,10 +31,6 @@ export interface OpenTimelineButtonIconProps { * Renders a button to open the timeline associated with a note */ export const OpenTimelineButtonIcon = memo(({ note, index }: OpenTimelineButtonIconProps) => { - const unifiedComponentsInTimelineDisabled = useIsExperimentalFeatureEnabled( - 'unifiedComponentsInTimelineDisabled' - ); - const queryTimelineById = useQueryTimelineById(); const openTimeline = useCallback( ({ timelineId }: { timelineId: string }) => @@ -44,9 +39,8 @@ export const OpenTimelineButtonIcon = memo(({ note, index }: OpenTimelineButtonI onOpenTimeline: undefined, timelineId, timelineType: undefined, - unifiedComponentsInTimelineDisabled, }), - [queryTimelineById, unifiedComponentsInTimelineDisabled] + [queryTimelineById] ); return ( diff --git a/x-pack/plugins/security_solution/public/overview/components/recent_timelines/index.tsx b/x-pack/plugins/security_solution/public/overview/components/recent_timelines/index.tsx index a167791a7b06c..97310f8a90f23 100644 --- a/x-pack/plugins/security_solution/public/overview/components/recent_timelines/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/recent_timelines/index.tsx @@ -8,7 +8,6 @@ import { EuiHorizontalRule, EuiText } from '@elastic/eui'; import React, { useCallback, useMemo, useEffect } from 'react'; -import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features'; import { SortFieldTimelineEnum, TimelineTypeEnum } from '../../../../common/api/timeline'; import { useGetAllTimeline } from '../../../timelines/containers/all'; import { useQueryTimelineById } from '../../../timelines/components/open_timeline/helpers'; @@ -33,10 +32,6 @@ interface Props { const PAGE_SIZE = 3; const StatefulRecentTimelinesComponent: React.FC = ({ filterBy }) => { - const unifiedComponentsInTimelineDisabled = useIsExperimentalFeatureEnabled( - 'unifiedComponentsInTimelineDisabled' - ); - const { formatUrl } = useFormatUrl(SecurityPageName.timelines); const { navigateToApp } = useKibana().services.application; @@ -47,10 +42,9 @@ const StatefulRecentTimelinesComponent: React.FC = ({ filterBy }) => { queryTimelineById({ duplicate, timelineId, - unifiedComponentsInTimelineDisabled, }); }, - [queryTimelineById, unifiedComponentsInTimelineDisabled] + [queryTimelineById] ); const goToTimelines = useCallback( 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 a3428ae6f2e1d..8c8be30b22d5a 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 @@ -37,8 +37,6 @@ import { import { resolveTimeline } from '../../containers/api'; import { defaultUdtHeaders } from '../timeline/unified_components/default_headers'; import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features'; -import type { ExperimentalFeatures } from '../../../../common'; -import { allowedExperimentalValues } from '../../../../common'; jest.mock('../../../common/hooks/use_experimental_features'); const useIsExperimentalFeatureEnabledMock = useIsExperimentalFeatureEnabled as jest.Mock; @@ -146,14 +144,6 @@ describe('helpers', () => { beforeEach(() => { mockResults = cloneDeep(mockTimelineResults); - - (useIsExperimentalFeatureEnabledMock as jest.Mock).mockImplementation( - (featureFlag: keyof ExperimentalFeatures) => { - return featureFlag === 'unifiedComponentsInTimelineDisabled' - ? false - : allowedExperimentalValues[featureFlag]; - } - ); }); describe('#getPinnedEventCount', () => { @@ -538,7 +528,7 @@ describe('helpers', () => { }); }); - test('should produce correct model if unifiedComponentsInTimelineDisabled is false', () => { + test('should produce correct model', () => { const timeline = { savedObjectId: 'savedObject-1', title: 'Awesome Timeline', @@ -564,7 +554,7 @@ describe('helpers', () => { }); }); - test('should produce correct model if unifiedComponentsInTimelineDisabled == false and custom set of columns is passed', () => { + test('should produce correct model if custom set of columns is passed', () => { const customColumns = defaultUdtHeaders.slice(0, 2); const timeline = { savedObjectId: 'savedObject-1', @@ -592,7 +582,7 @@ describe('helpers', () => { }); }); - test('should produce correct model if unifiedComponentsInTimelineDisabled == false and custom set of excludedRowRendererIds is passed', () => { + test('should produce correct model if custom set of excludedRowRendererIds is passed', () => { const excludedRowRendererIds: RowRendererId[] = ['zeek']; const timeline = { savedObjectId: 'savedObject-1', @@ -649,7 +639,7 @@ describe('helpers', () => { }); }); - describe('open a timeline', () => { + describe('open a timeline 1', () => { const selectedTimeline = { ...mockSelectedTimeline, }; @@ -843,7 +833,8 @@ describe('helpers', () => { }); }); }); - describe('open a timeline when unifiedComponentsInTimelineDisabled is false', () => { + + describe('open a timeline', () => { const untitledTimeline = { ...mockSelectedTimeline, title: '' }; const onOpenTimeline = jest.fn(); afterEach(() => { @@ -858,7 +849,6 @@ describe('helpers', () => { timelineType: TimelineTypeEnum.default, onOpenTimeline, openTimeline: true, - unifiedComponentsInTimelineDisabled: false, }; (resolveTimeline as jest.Mock).mockResolvedValue(untitledTimeline); renderHook(async () => { @@ -894,7 +884,6 @@ describe('helpers', () => { timelineType: TimelineTypeEnum.default, onOpenTimeline: undefined, openTimeline: true, - unifiedComponentsInTimelineDisabled: false, }; (resolveTimeline as jest.Mock).mockResolvedValue(mockSelectedTimeline); @@ -933,7 +922,6 @@ describe('helpers', () => { timelineType: TimelineTypeEnum.default, onOpenTimeline, openTimeline: true, - unifiedComponentsInTimelineDisabled: false, }; (resolveTimeline as jest.Mock).mockResolvedValue(mockSelectedTimeline); @@ -959,13 +947,13 @@ describe('helpers', () => { }); describe('omitTypenameInTimeline', () => { - test('it does not modify the passed in timeline if no __typename exists', () => { + test('should not modify the passed in timeline if no __typename exists', () => { const result = omitTypenameInTimeline(mockGetOneTimelineResult); expect(result).toEqual(mockGetOneTimelineResult); }); - test('it returns timeline with __typename removed when it exists', () => { + test('should return timeline with __typename removed when it exists', () => { const mockTimeline = { ...mockGetOneTimelineResult, __typename: 'something, something', 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 000a7b226561e..b3f84a82d4ed0 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 @@ -35,10 +35,7 @@ import { useUpdateTimeline } from './use_update_timeline'; import type { TimelineModel } from '../../store/model'; import { timelineDefaults } from '../../store/defaults'; -import { - defaultColumnHeaderType, - defaultHeaders, -} from '../timeline/body/column_headers/default_headers'; +import { defaultColumnHeaderType } from '../timeline/body/column_headers/default_headers'; import type { OpenTimelineResult, TimelineErrorCallback } from './types'; import { IS_OPERATOR } from '../timeline/data_providers/data_provider'; @@ -238,13 +235,10 @@ export const getTimelineStatus = ( export const defaultTimelineToTimelineModel = ( timeline: TimelineResponse, duplicate: boolean, - timelineType?: TimelineType, - unifiedComponentsInTimelineDisabled?: boolean + timelineType?: TimelineType ): TimelineModel => { const isTemplate = timeline.timelineType === TimelineTypeEnum.template; - const defaultHeadersValue = !unifiedComponentsInTimelineDisabled - ? defaultUdtHeaders - : defaultHeaders; + const defaultHeadersValue = defaultUdtHeaders; const timelineEntries = { ...timeline, @@ -294,18 +288,12 @@ export const defaultTimelineToTimelineModel = ( export const formatTimelineResponseToModel = ( timelineToOpen: TimelineResponse, duplicate: boolean = false, - timelineType?: TimelineType, - unifiedComponentsInTimelineDisabled?: boolean + timelineType?: TimelineType ): { notes: Note[] | null | undefined; timeline: TimelineModel } => { const { notes, ...timelineModel } = timelineToOpen; return { notes, - timeline: defaultTimelineToTimelineModel( - timelineModel, - duplicate, - timelineType, - unifiedComponentsInTimelineDisabled - ), + timeline: defaultTimelineToTimelineModel(timelineModel, duplicate, timelineType), }; }; @@ -319,11 +307,6 @@ export interface QueryTimelineById { onOpenTimeline?: (timeline: TimelineModel) => void; openTimeline?: boolean; savedSearchId?: string; - /* - * Below feature flag will be removed once - * unified components have been fully migrated - * */ - unifiedComponentsInTimelineDisabled?: boolean; } export const useQueryTimelineById = () => { @@ -347,7 +330,6 @@ export const useQueryTimelineById = () => { onOpenTimeline, openTimeline = true, savedSearchId, - unifiedComponentsInTimelineDisabled = false, }: QueryTimelineById) => { updateIsLoading({ id: TimelineId.active, isLoading: true }); if (timelineId == null) { @@ -359,14 +341,14 @@ export const useQueryTimelineById = () => { to: DEFAULT_TO_MOMENT.toISOString(), timeline: { ...timelineDefaults, - columns: !unifiedComponentsInTimelineDisabled ? defaultUdtHeaders : defaultHeaders, + columns: defaultUdtHeaders, id: TimelineId.active, activeTab: activeTimelineTab, show: openTimeline, initialized: true, savedSearchId: savedSearchId ?? null, excludedRowRendererIds: - !unifiedComponentsInTimelineDisabled && timelineType !== TimelineTypeEnum.template + timelineType !== TimelineTypeEnum.template ? timelineDefaults.excludedRowRendererIds : [], }, @@ -384,8 +366,7 @@ export const useQueryTimelineById = () => { const { timeline, notes } = formatTimelineResponseToModel( timelineToOpen, duplicate, - timelineType, - unifiedComponentsInTimelineDisabled + timelineType ); if (onOpenTimeline != null) { diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/index.tsx index cdb61ecf61f6e..6afd900185af7 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/index.tsx @@ -9,7 +9,6 @@ import React, { useEffect, useState, useCallback, useMemo } from 'react'; import { useDispatch } from 'react-redux'; import { encode } from '@kbn/rison'; -import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features'; import { RULE_FROM_EQL_URL_PARAM, RULE_FROM_TIMELINE_URL_PARAM, @@ -25,8 +24,6 @@ import { createTimeline as dispatchCreateNewTimeline } from '../../store/actions import { useGetAllTimeline } from '../../containers/all'; -import { defaultHeaders } from '../timeline/body/column_headers/default_headers'; - import { OpenTimeline } from './open_timeline'; import { OPEN_TIMELINE_CLASS_NAME, useQueryTimelineById } from './helpers'; import { OpenTimelineModalBody } from './open_timeline_modal/open_timeline_modal_body'; @@ -160,9 +157,6 @@ export const StatefulOpenTimelineComponent = React.memo( ); const { dataViewId, selectedPatterns } = useSourcererDataView(SourcererScopeName.timeline); - const unifiedComponentsInTimelineDisabled = useIsExperimentalFeatureEnabled( - 'unifiedComponentsInTimelineDisabled' - ); const { customTemplateTimelineCount, @@ -251,13 +245,11 @@ export const StatefulOpenTimelineComponent = React.memo( dispatch( dispatchCreateNewTimeline({ id: TimelineId.active, - columns: !unifiedComponentsInTimelineDisabled ? defaultUdtHeaders : defaultHeaders, + columns: defaultUdtHeaders, dataViewId, indexNames: selectedPatterns, show: false, - excludedRowRendererIds: !unifiedComponentsInTimelineDisabled - ? timelineDefaults.excludedRowRendererIds - : [], + excludedRowRendererIds: timelineDefaults.excludedRowRendererIds, }) ); } @@ -265,15 +257,7 @@ export const StatefulOpenTimelineComponent = React.memo( await deleteTimelinesByIds(timelineIds, searchIds); refetch(); }, - [ - startTransaction, - timelineSavedObjectId, - refetch, - dispatch, - dataViewId, - selectedPatterns, - unifiedComponentsInTimelineDisabled, - ] + [startTransaction, timelineSavedObjectId, refetch, dispatch, dataViewId, selectedPatterns] ); const onDeleteOneTimeline: OnDeleteOneTimeline = useCallback( @@ -374,7 +358,6 @@ export const StatefulOpenTimelineComponent = React.memo( onOpenTimeline, timelineId, timelineType: timelineTypeToOpen, - unifiedComponentsInTimelineDisabled, }); }, // eslint-disable-next-line react-hooks/exhaustive-deps 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 f502c1b8884aa..991355b1177bb 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 @@ -12,11 +12,9 @@ import { useDispatch, useSelector } from 'react-redux'; import styled from 'styled-components'; import { isTab } from '@kbn/timelines-plugin/public'; -import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features'; import { useUserPrivileges } from '../../../common/components/user_privileges'; import { timelineActions, timelineSelectors } from '../../store'; import { timelineDefaults } from '../../store/defaults'; -import { defaultHeaders } from './body/column_headers/default_headers'; import type { CellValueElementProps } from './cell_rendering'; import { SourcererScopeName } from '../../../sourcerer/store/model'; import { TimelineModalHeader } from '../modal/header'; @@ -75,10 +73,6 @@ const StatefulTimelineComponent: React.FC = ({ }) => { const dispatch = useDispatch(); - const unifiedComponentsInTimelineDisabled = useIsExperimentalFeatureEnabled( - 'unifiedComponentsInTimelineDisabled' - ); - const containerElement = useRef(null); const getTimeline = useMemo(() => timelineSelectors.getTimelineByIdSelector(), []); const selectedPatternsSourcerer = useSelector((state: State) => { @@ -129,13 +123,11 @@ const StatefulTimelineComponent: React.FC = ({ dispatch( timelineActions.createTimeline({ id: timelineId, - columns: !unifiedComponentsInTimelineDisabled ? defaultUdtHeaders : defaultHeaders, + columns: defaultUdtHeaders, dataViewId: selectedDataViewIdSourcerer, indexNames: selectedPatternsSourcerer, show: false, - excludedRowRendererIds: !unifiedComponentsInTimelineDisabled - ? timelineDefaults.excludedRowRendererIds - : [], + excludedRowRendererIds: timelineDefaults.excludedRowRendererIds, }) ); } diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/eql/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/eql/index.test.tsx index 034f812373ec2..25f89dab3e332 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/eql/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs/eql/index.test.tsx @@ -78,9 +78,6 @@ describe('Timeline', () => { (useIsExperimentalFeatureEnabledMock as jest.Mock).mockImplementation( (feature: keyof ExperimentalFeatures) => { - if (feature === 'unifiedComponentsInTimelineDisabled') { - return true; - } return allowedExperimentalValues[feature]; } ); 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 e2881c8c24458..ca69532c681b6 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 @@ -22,18 +22,11 @@ import { DocumentDetailsLeftPanelKey, DocumentDetailsRightPanelKey, } from '../../../../../flyout/document_details/shared/constants/panel_keys'; -import { InputsModelId } from '../../../../../common/store/inputs/constants'; -import type { ControlColumnProps } from '../../../../../../common/types'; import { useDeepEqualSelector } from '../../../../../common/hooks/use_selector'; import { useIsExperimentalFeatureEnabled } from '../../../../../common/hooks/use_experimental_features'; import { timelineActions, timelineSelectors } from '../../../../store'; import { useTimelineEvents } from '../../../../containers'; -import { StatefulBody } from '../../body'; -import { Footer, footerHeight } from '../../footer'; -import { calculateTotalPages } from '../../helpers'; -import { TimelineRefetch } from '../../refetch_timeline'; import { TimelineId, TimelineTabs } from '../../../../../../common/types/timeline'; -import { EventDetailsWidthProvider } from '../../../../../common/components/events_viewer/event_details_width_context'; import type { inputsModel, State } from '../../../../../common/store'; import { inputsSelectors } from '../../../../../common/store'; import { SourcererScopeName } from '../../../../../sourcerer/store/model'; @@ -42,19 +35,8 @@ import { useSourcererDataView } from '../../../../../sourcerer/containers'; import { useEqlEventsCountPortal } from '../../../../../common/hooks/use_timeline_events_count'; import type { TimelineModel } from '../../../../store/model'; import { useTimelineFullScreen } from '../../../../../common/containers/use_full_screen'; -import { - EventsCountBadge, - FullWidthFlexGroup, - ScrollableFlexItem, - StyledEuiFlyoutBody, - StyledEuiFlyoutFooter, -} from '../shared/layout'; -import { - TIMELINE_EMPTY_EVENTS, - isTimerangeSame, - timelineEmptyTrailingControlColumns, - TIMELINE_NO_SORTING, -} from '../shared/utils'; +import { EventsCountBadge, FullWidthFlexGroup } from '../shared/layout'; +import { isTimerangeSame, TIMELINE_NO_SORTING } from '../shared/utils'; import type { TimelineTabCommonProps } from '../shared/types'; import { UnifiedTimelineBody } from '../../body/unified_timeline_body'; import { EqlTabHeader } from './header'; @@ -96,10 +78,6 @@ export const EqlTabContentComponent: React.FC = ({ } = useSourcererDataView(SourcererScopeName.timeline); const { augmentedColumnHeaders, timelineQueryFieldsFromColumns } = useTimelineColumns(columns); - const unifiedComponentsInTimelineDisabled = useIsExperimentalFeatureEnabled( - 'unifiedComponentsInTimelineDisabled' - ); - const getManageTimeline = useMemo(() => timelineSelectors.getTimelineByIdSelector(), []); const currentTimeline = useDeepEqualSelector((state) => @@ -132,7 +110,7 @@ export const EqlTabContentComponent: React.FC = ({ id: timelineId, indexNames: selectedPatterns, language: 'eql', - limit: !unifiedComponentsInTimelineDisabled ? sampleSize : itemsPerPage, + limit: sampleSize, runtimeMappings: sourcererDataView?.runtimeFieldMap as RunTimeMappings, skip: !canQueryTimeline(), startDate: start, @@ -267,103 +245,36 @@ export const EqlTabContentComponent: React.FC = ({ return ( <> - {!unifiedComponentsInTimelineDisabled ? ( - <> - - {totalCount >= 0 ? ( - {totalCount} - ) : null} - - {NotesFlyoutMemo} - - - - - ) : ( - <> - - {totalCount >= 0 ? {totalCount} : null} - - {NotesFlyoutMemo} - + + {totalCount >= 0 ? ( + {totalCount} + ) : null} + + {NotesFlyoutMemo} + + - - {unifiedHeader} - - - - - - - - {!isBlankTimeline && ( -