diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.test.tsx index bc260da6c4046..b14e007f36754 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.test.tsx @@ -100,6 +100,7 @@ const getExpectedcreateTimelineParam = ( notes: null, timeline: { ...timelineDefaults, + excludedRowRendererIds: [], dataProviders, id: TimelineId.active, indexNames: [], @@ -379,7 +380,7 @@ describe('alert actions', () => { }, eventIdToNoteIds: {}, eventType: 'all', - excludedRowRendererIds: defaultTimelineProps.timeline.excludedRowRendererIds, + excludedRowRendererIds: [], expandedDetail: {}, filters: [ { @@ -549,10 +550,13 @@ describe('alert actions', () => { getExceptionFilter: mockGetExceptionFilter, }); + const expectedTimelineProps = structuredClone(defaultTimelineProps); + expectedTimelineProps.timeline.excludedRowRendererIds = []; + expect(updateTimelineIsLoading).not.toHaveBeenCalled(); expect(mockGetExceptionFilter).not.toHaveBeenCalled(); expect(createTimeline).toHaveBeenCalledTimes(1); - expect(createTimeline).toHaveBeenCalledWith(defaultTimelineProps); + expect(createTimeline).toHaveBeenCalledWith(expectedTimelineProps); }); }); @@ -576,10 +580,13 @@ describe('alert actions', () => { getExceptionFilter: mockGetExceptionFilter, }); + const expectedTimelineProps = structuredClone(defaultTimelineProps); + expectedTimelineProps.timeline.excludedRowRendererIds = []; + expect(updateTimelineIsLoading).not.toHaveBeenCalled(); expect(mockGetExceptionFilter).not.toHaveBeenCalled(); expect(createTimeline).toHaveBeenCalledTimes(1); - expect(createTimeline).toHaveBeenCalledWith(defaultTimelineProps); + expect(createTimeline).toHaveBeenCalledWith(expectedTimelineProps); }); }); @@ -614,6 +621,7 @@ describe('alert actions', () => { ...defaultTimelineProps, timeline: { ...defaultTimelineProps.timeline, + excludedRowRendererIds: [], resolveTimelineConfig: undefined, dataProviders: [ { @@ -642,6 +650,9 @@ describe('alert actions', () => { }, }; + const expectedTimelineProps = structuredClone(defaultTimelineProps); + expectedTimelineProps.timeline.excludedRowRendererIds = []; + await sendAlertToTimelineAction({ createTimeline, ecsData: ecsDataMock, @@ -653,7 +664,7 @@ describe('alert actions', () => { expect(updateTimelineIsLoading).not.toHaveBeenCalled(); expect(mockGetExceptionFilter).not.toHaveBeenCalled(); expect(createTimeline).toHaveBeenCalledTimes(1); - expect(createTimeline).toHaveBeenCalledWith(defaultTimelineProps); + expect(createTimeline).toHaveBeenCalledWith(expectedTimelineProps); }); }); @@ -737,6 +748,7 @@ describe('alert actions', () => { ...defaultTimelineProps, timeline: { ...defaultTimelineProps.timeline, + excludedRowRendererIds: [], dataProviders: [ { and: [], @@ -890,6 +902,7 @@ describe('alert actions', () => { ...defaultTimelineProps, timeline: { ...defaultTimelineProps.timeline, + excludedRowRendererIds: [], columns: mockGetOneTimelineResult.columns, defaultColumns: defaultUdtHeaders, dataProviders: [], @@ -1043,6 +1056,7 @@ describe('alert actions', () => { ...defaultTimelineProps, timeline: { ...defaultTimelineProps.timeline, + excludedRowRendererIds: [], filters: [ { meta: { 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 b88ca5ff6ab83..8e5a25638788e 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 @@ -499,6 +499,7 @@ const createThresholdTimeline = async ( notes: null, timeline: { ...timelineDefaults, + excludedRowRendererIds: [], columns: templateValues.columns ?? timelineDefaults.columns, description: `_id: ${alertDoc._id}`, filters: allFilters, @@ -655,6 +656,7 @@ const createNewTermsTimeline = async ( timeline: { ...timelineDefaults, columns: templateValues.columns ?? timelineDefaults.columns, + excludedRowRendererIds: [], description: `_id: ${alertDoc._id}`, filters: allFilters, dataProviders: templateValues.dataProviders ?? dataProviders, @@ -824,6 +826,7 @@ const createSuppressedTimeline = async ( notes: null, timeline: { ...timelineDefaults, + excludedRowRendererIds: [], columns: templateValues.columns ?? timelineDefaults.columns, description: `_id: ${alertDoc._id}`, filters: allFilters, @@ -906,6 +909,7 @@ export const sendBulkEventsToTimelineAction = async ( notes: null, timeline: { ...timelineDefaults, + excludedRowRendererIds: [], dataProviders, id: TimelineId.active, indexNames: [], @@ -1050,6 +1054,7 @@ export const sendAlertToTimelineAction = async ({ from, timeline: { ...timeline, + excludedRowRendererIds: [], title: '', timelineType: TimelineType.default, templateTimelineId: null, @@ -1126,6 +1131,7 @@ export const sendAlertToTimelineAction = async ({ notes: null, timeline: { ...timelineDefaults, + excludedRowRendererIds: [], dataProviders, id: TimelineId.active, indexNames: [], 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 aa94c0f076f46..786708263fa74 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 @@ -163,9 +163,10 @@ export const useInvestigateInTimeline = ({ columns: !unifiedComponentsInTimelineDisabled ? defaultUdtHeaders : defaultHeaders, indexNames: timeline.indexNames ?? [], show: true, - excludedRowRendererIds: !unifiedComponentsInTimelineDisabled - ? timeline.excludedRowRendererIds - : [], + excludedRowRendererIds: + !unifiedComponentsInTimelineDisabled && timeline.timelineType !== TimelineType.template + ? timeline.excludedRowRendererIds + : [], }, to: toTimeline, ruleNote, diff --git a/x-pack/plugins/security_solution/public/timelines/components/new_timeline/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/new_timeline/index.test.tsx index d745e4abaa645..d343bb1371742 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/new_timeline/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/new_timeline/index.test.tsx @@ -94,7 +94,7 @@ describe('NewTimelineButton', () => { show: true, timelineType: TimelineType.template, updated: undefined, - excludedRowRendererIds: [...Object.values(RowRendererId)], + excludedRowRendererIds: [], }); }); }); 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 b31c7ba471bcf..a647c0ed44535 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 @@ -350,6 +350,7 @@ describe('helpers', () => { expect(newTimeline).toEqual({ ...defaultTimeline, columns: defaultUdtHeaders, + excludedRowRendererIds: [], }); }); @@ -500,6 +501,7 @@ describe('helpers', () => { timelineType: TimelineType.template, title: 'Awesome Timeline', columns: defaultUdtHeaders, + excludedRowRendererIds: [], }); }); 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 d31ad321b28c1..ec90e8477c72e 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 @@ -22,8 +22,13 @@ import type { PinnedEvent, Note, } from '../../../../common/api/timeline'; +import { + RowRendererId, + DataProviderType, + TimelineStatus, + TimelineType, +} from '../../../../common/api/timeline'; import { TimelineId, TimelineTabs } from '../../../../common/types/timeline'; -import { DataProviderType, TimelineStatus, TimelineType } from '../../../../common/api/timeline'; import { useUpdateTimeline } from './use_update_timeline'; import type { TimelineModel } from '../../store/model'; @@ -256,6 +261,7 @@ export const defaultTimelineToTimelineModel = ( } : timeline.dateRange, dataProviders: getDataProviders(duplicate, timeline.dataProviders, timelineType), + excludedRowRendererIds: isTemplate ? [] : Object.keys(RowRendererId), eventIdToNoteIds: setEventIdToNoteIds(duplicate, timeline.eventIdToNoteIds), filters: timeline.filters != null ? timeline.filters.map(setTimelineFilters) : [], isFavorite: duplicate @@ -358,9 +364,10 @@ export const useQueryTimelineById = () => { show: openTimeline, initialized: true, savedSearchId: savedSearchId ?? null, - excludedRowRendererIds: !unifiedComponentsInTimelineDisabled - ? timelineDefaults.excludedRowRendererIds - : [], + excludedRowRendererIds: + !unifiedComponentsInTimelineDisabled && timelineType !== TimelineType.template + ? timelineDefaults.excludedRowRendererIds + : [], }, }); resetDiscoverAppState(); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/custom_timeline_data_grid_body.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/custom_timeline_data_grid_body.tsx index 284452074a82a..fc98c72587e2e 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/custom_timeline_data_grid_body.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/custom_timeline_data_grid_body.tsx @@ -15,7 +15,7 @@ import styled from 'styled-components'; import type { RowRenderer } from '../../../../../../common/types'; import { TIMELINE_EVENT_DETAIL_ROW_ID } from '../../body/constants'; import { useStatefulRowRenderer } from '../../body/events/stateful_row_renderer/use_stateful_row_renderer'; -import { useGetEventTypeRowClassName } from './use_get_event_type_row_classname'; +import { getEventTypeRowClassName } from './get_event_type_row_classname'; export type CustomTimelineDataGridBodyProps = EuiDataGridCustomBodyProps & { rows: Array | undefined; @@ -181,7 +181,7 @@ const CustomDataGridSingleRow = memo(function CustomDataGridSingleRow( : {}, [canShowRowRenderer] ); - const eventTypeRowClassName = useGetEventTypeRowClassName(rowData.ecs); + const eventTypeRowClassName = useMemo(() => getEventTypeRowClassName(rowData.ecs), [rowData.ecs]); return ( { +describe('getEventTypeRowClassName', () => { it('should return rawEvent', () => { - const { result } = renderHook(() => useGetEventTypeRowClassName(mockEvent)); - expect(result.current).toEqual('rawEvent'); + const result = getEventTypeRowClassName(mockEvent); + expect(result).toEqual('rawEvent'); }); it('should contain eqlSequence', () => { - const { result } = renderHook(() => useGetEventTypeRowClassName(mockBuildingBlockAlert)); - expect(result.current).toContain('eqlSequence'); + const result = getEventTypeRowClassName(mockBuildingBlockAlert); + expect(result).toContain('eqlSequence'); }); it('should contain buildingBlockType', () => { - const { result } = renderHook(() => useGetEventTypeRowClassName(mockBuildingBlockAlert)); - expect(result.current).toContain('buildingBlockType'); + const result = getEventTypeRowClassName(mockBuildingBlockAlert); + expect(result).toContain('buildingBlockType'); }); it('should return eqlNonSequence', () => { - const { result } = renderHook(() => useGetEventTypeRowClassName(mockOddEqlEvent)); - expect(result.current).toEqual('eqlNonSequence'); + const result = getEventTypeRowClassName(mockOddEqlEvent); + expect(result).toEqual('eqlNonSequence'); }); it('should return nonRawEvent', () => { - const { result } = renderHook(() => useGetEventTypeRowClassName(mockAlert)); - expect(result.current).toEqual('nonRawEvent'); + const result = getEventTypeRowClassName(mockAlert); + expect(result).toEqual('nonRawEvent'); }); }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/get_event_type_row_classname.ts b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/get_event_type_row_classname.ts new file mode 100644 index 0000000000000..b6058af189c9d --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/get_event_type_row_classname.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { TimelineItem } from '@kbn/timelines-plugin/common'; +import { getEventType, isEvenEqlSequence, isEventBuildingBlockType } from '../../body/helpers'; + +export const getEventTypeRowClassName = (ecsData: TimelineItem['ecs']) => { + const eventType = getEventType(ecsData); + const eventTypeClassName = + eventType === 'raw' + ? 'rawEvent' + : eventType === 'eql' + ? isEvenEqlSequence(ecsData) + ? 'eqlSequence' + : 'eqlNonSequence' + : 'nonRawEvent'; + + const buildingBlockTypeClassName = isEventBuildingBlockType(ecsData) ? 'buildingBlockType' : ''; + + return `${eventTypeClassName} ${buildingBlockTypeClassName}`.trim(); +}; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/index.tsx index b1467a4afdf4d..a530a70c46379 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/data_table/index.tsx @@ -161,7 +161,7 @@ export const TimelineDataTableComponent: React.FC = memo( selectTimelineById(state, timelineId) ); - const tableRows = useMemo( + const { tableRows, tableStylesOverride } = useMemo( () => transformTimelineItemToUnifiedRows({ events, dataView }), [events, dataView] ); @@ -424,9 +424,10 @@ export const TimelineDataTableComponent: React.FC = memo( { - const eventType = useMemo(() => getEventType(ecsData), [ecsData]); - const eventTypeClassName = useMemo( - () => - eventType === 'raw' - ? 'rawEvent' - : eventType === 'eql' - ? isEvenEqlSequence(ecsData) - ? 'eqlSequence' - : 'eqlNonSequence' - : 'nonRawEvent', - [ecsData, eventType] - ); - const buildingBlockTypeClassName = useMemo( - () => (isEventBuildingBlockType(ecsData) ? 'buildingBlockType' : ''), - [ecsData] - ); - - return useMemo( - () => `${eventTypeClassName} ${buildingBlockTypeClassName}`.trim(), - [eventTypeClassName, buildingBlockTypeClassName] - ); -}; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/styles.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/styles.tsx index 2d32767ea19c0..6c9ca63cb4e68 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/styles.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/styles.tsx @@ -100,7 +100,8 @@ export const StyledTimelineUnifiedDataTable = styled.div.attrs(({ className = '' border-radius: 8px; } - .udtTimeline .euiDataGridRow:has(.buildingBlockType) { + .udtTimeline .euiDataGridRow:has(.buildingBlockType), + .udtTimeline .euiDataGridRow.buildingBlockType { background: repeating-linear-gradient( 127deg, rgba(245, 167, 0, 0.2), @@ -109,9 +110,10 @@ export const StyledTimelineUnifiedDataTable = styled.div.attrs(({ className = '' rgba(245, 167, 0, 0.05) 10px ); } - .udtTimeline .euiDataGridRow:has(.eqlSequence) { + .udtTimeline .euiDataGridRow:has(.eqlSequence), + .udtTimeline .euiDataGridRow.eqlSequence { .euiDataGridRowCell--firstColumn, - .euiDataGridRowCell--lastColumn, + .euiDataGridRowCell--controlColumn.euiDataGridRowCell--lastColumn, .udt--customRow { ${({ theme }) => `border-left: 4px solid ${theme.eui.euiColorPrimary}`}; } @@ -123,9 +125,10 @@ export const StyledTimelineUnifiedDataTable = styled.div.attrs(({ className = '' rgba(0, 107, 180, 0.05) 10px ); } - .udtTimeline .euiDataGridRow:has(.eqlNonSequence) { + .udtTimeline .euiDataGridRow:has(.eqlNonSequence), + .udtTimeline .euiDataGridRow.eqlNonSequence { .euiDataGridRowCell--firstColumn, - .euiDataGridRowCell--lastColumn, + .euiDataGridRowCell--controlColumn.euiDataGridRowCell--lastColumn, .udt--customRow { ${({ theme }) => `border-left: 4px solid ${theme.eui.euiColorAccent};`} } @@ -137,16 +140,18 @@ export const StyledTimelineUnifiedDataTable = styled.div.attrs(({ className = '' rgba(221, 10, 115, 0.05) 10px ); } - .udtTimeline .euiDataGridRow:has(.nonRawEvent) { + .udtTimeline .euiDataGridRow:has(.nonRawEvent), + .udtTimeline .euiDataGridRow.nonRawEvent { .euiDataGridRowCell--firstColumn, - .euiDataGridRowCell--lastColumn, + .euiDataGridRowCell--controlColumn.euiDataGridRowCell--lastColumn, .udt--customRow { ${({ theme }) => `border-left: 4px solid ${theme.eui.euiColorWarning};`} } } - .udtTimeline .euiDataGridRow:has(.rawEvent) { + .udtTimeline .euiDataGridRow:has(.rawEvent), + .udtTimeline .euiDataGridRow.rawEvent { .euiDataGridRowCell--firstColumn, - .euiDataGridRowCell--lastColumn, + .euiDataGridRowCell--controlColumn.euiDataGridRowCell--lastColumn, .udt--customRow { ${({ theme }) => `border-left: 4px solid ${theme.eui.euiColorLightShade};`} } diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/utils.test.ts b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/utils.test.ts index ae336d6bf4b79..af346e9addabd 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/utils.test.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/utils.test.ts @@ -10,22 +10,27 @@ import { fieldFormatsMock } from '@kbn/field-formats-plugin/common/mocks'; import { mockSourcererScope } from '../../../../sourcerer/containers/mocks'; import { mockTimelineData } from '../../../../common/mock'; +import type { TransformTimelineItemToUnifiedRowsReturn } from './utils'; import { transformTimelineItemToUnifiedRows } from './utils'; const testTimelineData = mockTimelineData; describe('utils', () => { describe('transformTimelineItemToUnifiedRows', () => { - it('should return correct result', () => { - const result = transformTimelineItemToUnifiedRows({ + let result: TransformTimelineItemToUnifiedRowsReturn; + beforeAll(() => { + result = transformTimelineItemToUnifiedRows({ events: testTimelineData, dataView: new DataView({ spec: mockSourcererScope.sourcererDataView, fieldFormats: fieldFormatsMock, }), }); + }); - expect(result[0]).toEqual({ + it('should return correct result', () => { + const { tableRows } = result; + expect(tableRows[0]).toEqual({ _id: testTimelineData[0]._id, id: testTimelineData[0]._id, data: testTimelineData[0].data, @@ -57,5 +62,53 @@ describe('utils', () => { }, }); }); + + it('should return correct table styles', () => { + const { tableStylesOverride } = result; + expect(tableStylesOverride).toMatchInlineSnapshot(` + Object { + "border": "horizontal", + "cellPadding": "l", + "fontSize": "s", + "header": "underline", + "rowClasses": Object { + "0": "rawEvent", + "1": "rawEvent", + "10": "rawEvent", + "11": "rawEvent", + "12": "rawEvent", + "13": "rawEvent", + "14": "rawEvent", + "15": "rawEvent", + "16": "rawEvent", + "17": "rawEvent", + "18": "rawEvent", + "19": "rawEvent", + "2": "rawEvent", + "20": "rawEvent", + "21": "rawEvent", + "22": "rawEvent", + "23": "rawEvent", + "24": "rawEvent", + "25": "rawEvent", + "26": "rawEvent", + "27": "rawEvent", + "28": "rawEvent", + "29": "rawEvent", + "3": "rawEvent", + "30": "rawEvent", + "31": "rawEvent", + "4": "rawEvent", + "5": "rawEvent", + "6": "rawEvent", + "7": "rawEvent", + "8": "rawEvent", + "9": "rawEvent", + }, + "rowHover": "highlight", + "stripes": true, + } + `); + }); }); }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/utils.ts b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/utils.ts index 20b769455d3ea..f76b3c45c303e 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/utils.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/unified_components/utils.ts @@ -5,23 +5,39 @@ * 2.0. */ +import type { EuiDataGridStyle } from '@elastic/eui'; import { flattenHit } from '@kbn/data-service'; import type { DataView } from '@kbn/data-views-plugin/public'; import type { DataTableRecord } from '@kbn/discover-utils/types'; +import { GRID_STYLE } from '@kbn/unified-data-table/src/constants'; import type { TimelineItem } from '../../../../../common/search_strategy'; +import { getEventTypeRowClassName } from './data_table/get_event_type_row_classname'; interface TransformTimelineItemToUnifiedRows { events: TimelineItem[]; dataView: DataView; } +export interface TransformTimelineItemToUnifiedRowsReturn { + tableRows: Array; + tableStylesOverride: EuiDataGridStyle; +} + export function transformTimelineItemToUnifiedRows( args: TransformTimelineItemToUnifiedRows -): Array { +): TransformTimelineItemToUnifiedRowsReturn { const { events, dataView } = args; - const unifiedDataTableRows = events.map(({ _id, _index, ecs, data }) => { + const rowClasses: EuiDataGridStyle['rowClasses'] = {}; + const unifiedDataTableRows = events.map(({ _id, _index, ecs, data }, index) => { const _source = ecs as unknown as Record; const hit = { _id, _index: String(_index), _source }; + + /** + * Side effect + * We need to add a custom className for each row based on the event type. Rather than looping twice + * we take advantage of this map to set the styles for each row + */ + rowClasses[index] = getEventTypeRowClassName(ecs); /* * Ideally for unified data table we only need raw and flattened keys * but we use this transformed data within other parts of security solution @@ -40,5 +56,5 @@ export function transformTimelineItemToUnifiedRows( }; }); - return unifiedDataTableRows; + return { tableRows: unifiedDataTableRows, tableStylesOverride: { ...GRID_STYLE, rowClasses } }; } diff --git a/x-pack/plugins/security_solution/public/timelines/hooks/use_create_timeline.test.tsx b/x-pack/plugins/security_solution/public/timelines/hooks/use_create_timeline.test.tsx index a45bd4e040d4e..49e16b927c0ca 100644 --- a/x-pack/plugins/security_solution/public/timelines/hooks/use_create_timeline.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/hooks/use_create_timeline.test.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { renderHook } from '@testing-library/react-hooks'; import { useCreateTimeline } from './use_create_timeline'; import type { TimeRange } from '../../common/store/inputs/model'; -import { TimelineType } from '../../../common/api/timeline'; +import { RowRendererCount, TimelineType } from '../../../common/api/timeline'; import { TimelineId } from '../../../common/types'; import { useDiscoverInTimelineContext } from '../../common/components/discover_in_timeline/use_discover_in_timeline_context'; import { timelineActions } from '../store'; @@ -79,6 +79,7 @@ describe('useCreateTimeline', () => { ); expect(createTimeline.mock.calls[0][0].show).toEqual(true); expect(createTimeline.mock.calls[0][0].updated).toEqual(undefined); + expect(createTimeline.mock.calls[0][0].excludedRowRendererIds).toHaveLength(RowRendererCount); expect(setSelectedDataView.mock.calls[0][0].id).toEqual(SourcererScopeName.timeline); expect(setSelectedDataView.mock.calls[0][0].selectedDataViewId).toEqual( mockGlobalState.sourcerer.defaultDataView.id diff --git a/x-pack/plugins/security_solution/public/timelines/hooks/use_create_timeline.tsx b/x-pack/plugins/security_solution/public/timelines/hooks/use_create_timeline.tsx index 1212e78b49305..31404b54957f7 100644 --- a/x-pack/plugins/security_solution/public/timelines/hooks/use_create_timeline.tsx +++ b/x-pack/plugins/security_solution/public/timelines/hooks/use_create_timeline.tsx @@ -13,6 +13,7 @@ import { timelineActions } from '../store'; import { useTimelineFullScreen } from '../../common/containers/use_full_screen'; import { TimelineId } from '../../../common/types/timeline'; import type { TimelineTypeLiteral } from '../../../common/api/timeline'; +import { TimelineType } from '../../../common/api/timeline'; import { useDeepEqualSelector } from '../../common/hooks/use_selector'; import { inputsActions, inputsSelectors } from '../../common/store/inputs'; import { sourcererActions, sourcererSelectors } from '../../sourcerer/store'; @@ -86,9 +87,10 @@ export const useCreateTimeline = ({ show, timelineType, updated: undefined, - excludedRowRendererIds: !unifiedComponentsInTimelineDisabled - ? timelineDefaults.excludedRowRendererIds - : [], + excludedRowRendererIds: + !unifiedComponentsInTimelineDisabled && timelineType !== TimelineType.template + ? timelineDefaults.excludedRowRendererIds + : [], }) );