Skip to content

Commit

Permalink
[Security Solution] Remove unifiedComponentsInTimelineDisabled flag (
Browse files Browse the repository at this point in the history
…elastic#195959)

## Summary

Handles elastic/security-team#9645

Follow Up PR for removal of Old timeline Code :
elastic#196243

- This PR removes `unifiedComponentsInTimelineDisabled` flag. What this
means that that unified components in Timeline are now enabled by
default.

- Consequently, the old timeline table code becomes obsolete and is also
removed. ( elastic#196243)

## Changes

1. Converted all cypress and jest tests that were testing old Timeline
table to test new unified components in Timeline. If the test for new
timeline already existed, old tests are also removed.
  • Loading branch information
logeekal authored Oct 24, 2024
1 parent 1821093 commit c41178d
Show file tree
Hide file tree
Showing 40 changed files with 1,440 additions and 6,518 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down Expand Up @@ -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(
<TestProviders>
<HeaderActions {...defaultProps} />
</TestProviders>
);
expect(result.queryByTestId('show-row-renderers-gear')).toBeNull();
});

it('should not show the sorting settings', () => {
const result = render(
<TestProviders>
<HeaderActions {...defaultProps} />
</TestProviders>
);
expect(result.queryByTestId('timeline-sorting-fields')).toBeNull();
});
describe('Controls', () => {
it('should not show the event renderer settings', () => {
const result = render(
<TestProviders>
<HeaderActions {...defaultProps} />
</TestProviders>
);
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(
<TestProviders>
<HeaderActions {...defaultProps} />
</TestProviders>
);
result.getByTestId('show-row-renderers-gear');
});

it('should show the sorting settings', () => {
const result = render(
<TestProviders>
<HeaderActions {...defaultProps} />
</TestProviders>
);
result.getByTestId('timeline-sorting-fields');
});
it('should not show the sorting settings', () => {
const result = render(
<TestProviders>
<HeaderActions {...defaultProps} />
</TestProviders>
);
expect(result.queryByTestId('timeline-sorting-fields')).toBeNull();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@
*/

import React, { useMemo, useCallback, memo } from 'react';
import type { EuiDataGridSorting, EuiDataGridSchemaDetector } from '@elastic/eui';
import { EuiButtonIcon, EuiToolTip, useDataGridColumnSorting, EuiCheckbox } 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 type { HeaderActionProps } 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';
Expand All @@ -21,28 +20,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 {
Expand All @@ -66,23 +49,15 @@ const ActionsContainer = styled.div`
display: flex;
`;

// Defined statically to reduce rerenders
const emptySchema = {};
const emptySchemaDetectors: EuiDataGridSchemaDetector[] = [];

const HeaderActionsComponent: React.FC<HeaderActionProps> = memo(
({
width,
browserFields,
columnHeaders,
isEventViewer = false,
isSelectAllChecked,
onSelectAll,
showEventsSelect,
showSelectAllCheckbox,
showFullScreenToggle = true,
sort,
tabType,
timelineId,
fieldBrowserOptions,
}) => {
Expand All @@ -91,10 +66,6 @@ const HeaderActionsComponent: React.FC<HeaderActionProps> = memo(
const { timelineFullScreen, setTimelineFullScreen } = useTimelineFullScreen();
const dispatch = useDispatch();

const unifiedComponentsInTimelineDisabled = useIsExperimentalFeatureEnabled(
'unifiedComponentsInTimelineDisabled'
);

const { defaultColumns } = useDeepEqualSelector((state) =>
selectTimelineById(state, timelineId)
);
Expand Down Expand Up @@ -129,57 +100,6 @@ const HeaderActionsComponent: React.FC<HeaderActionProps> = memo(
[onSelectAll]
);

const onSortColumns = useCallback(
(cols: EuiDataGridSorting['columns']) =>
dispatch(
timelineActions.updateSort({
id: timelineId,
sort: cols.map(({ id, direction }) => {
const columnHeader = columnHeaders.find((ch) => ch.id === id);
const columnType = columnHeader?.type ?? '';
const esTypes = columnHeader?.esTypes ?? [];

return {
columnId: id,
columnType,
esTypes,
sortDirection: direction as SortDirection,
};
}),
})
),
[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]);
Expand All @@ -206,14 +126,6 @@ const HeaderActionsComponent: React.FC<HeaderActionProps> = memo(
[columnHeaders, dispatch, timelineId, defaultColumns]
);

const ColumnSorting = useDataGridColumnSorting({
columns: myColumns,
sorting: sortedColumns,
schema: emptySchema,
schemaDetectors: emptySchemaDetectors,
displayValues,
});

return (
<ActionsContainer data-test-subj="header-actions-container">
{showSelectAllCheckbox && (
Expand Down Expand Up @@ -242,11 +154,6 @@ const HeaderActionsComponent: React.FC<HeaderActionProps> = memo(
</EventsTh>
)}

{unifiedComponentsInTimelineDisabled && (
<EventsTh role="button">
<StatefulRowRenderersBrowser timelineId={timelineId} />
</EventsTh>
)}
{showFullScreenToggle && (
<EventsTh role="button">
<EventsThContent textAlign="center" width={DEFAULT_ACTION_BUTTON_WIDTH}>
Expand Down Expand Up @@ -275,15 +182,6 @@ const HeaderActionsComponent: React.FC<HeaderActionProps> = memo(
</EventsThContent>
</EventsTh>
)}
{tabType !== TimelineTabs.eql && unifiedComponentsInTimelineDisabled && (
<EventsTh role="button" data-test-subj="timeline-sorting-fields">
<EventsThContent textAlign="center" width={DEFAULT_ACTION_BUTTON_WIDTH}>
<EuiToolTip content={i18n.SORT_FIELDS}>
<SortingColumnsContainer>{ColumnSorting}</SortingColumnsContainer>
</EuiToolTip>
</EventsThContent>
</EventsTh>
)}

{showEventsSelect && (
<EventsTh role="button">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -43,11 +39,10 @@ export const useInitTimelineFromUrlParam = () => {
timelineId: initialState.id,
openTimeline: initialState.isOpen,
savedSearchId: initialState.savedSearchId,
unifiedComponentsInTimelineDisabled,
});
}
},
[isEsqlTabDisabled, queryTimelineById, unifiedComponentsInTimelineDisabled]
[isEsqlTabDisabled, queryTimelineById]
);

useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand Down Expand Up @@ -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 }) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading

0 comments on commit c41178d

Please sign in to comment.