From 28ebfd010fc8b40876458ac1e86302f0bb7d1319 Mon Sep 17 00:00:00 2001 From: patrykkopycinski Date: Tue, 7 Jan 2020 19:15:56 +0100 Subject: [PATCH] [SIEM] Fix doubled drag handles in Timeline (#52679) (#54130) --- .../drag_and_drop/draggable_wrapper.tsx | 147 +-------------- .../drag_and_drop/provider_container.tsx | 154 +++++++++++++++ .../components/event_details/columns.tsx | 32 +--- .../event_details/event_fields_browser.tsx | 43 +++-- .../public/components/skeleton_row/index.tsx | 25 ++- .../__snapshots__/index.test.tsx.snap | 156 +++++----------- .../formatted_field.test.tsx.snap | 5 +- .../get_column_renderer.test.tsx.snap | 26 +-- .../plain_column_renderer.test.tsx.snap | 26 +-- .../body/renderers/formatted_field.test.tsx | 175 ++++++++++-------- .../body/renderers/formatted_field.tsx | 92 +++++---- .../body/renderers/plain_column_renderer.tsx | 109 ++--------- 12 files changed, 453 insertions(+), 537 deletions(-) create mode 100644 x-pack/legacy/plugins/siem/public/components/drag_and_drop/provider_container.tsx diff --git a/x-pack/legacy/plugins/siem/public/components/drag_and_drop/draggable_wrapper.tsx b/x-pack/legacy/plugins/siem/public/components/drag_and_drop/draggable_wrapper.tsx index 4faf02ead3fe1..9672097713a9b 100644 --- a/x-pack/legacy/plugins/siem/public/components/drag_and_drop/draggable_wrapper.tsx +++ b/x-pack/legacy/plugins/siem/public/components/drag_and_drop/draggable_wrapper.tsx @@ -13,15 +13,15 @@ import { Droppable, } from 'react-beautiful-dnd'; import { connect } from 'react-redux'; -import styled, { css } from 'styled-components'; +import styled from 'styled-components'; import { ActionCreator } from 'typescript-fsa'; import { EuiPortal } from '@elastic/eui'; import { dragAndDropActions } from '../../store/drag_and_drop'; import { DataProvider } from '../timeline/data_providers/data_provider'; -import { STATEFUL_EVENT_CSS_CLASS_NAME } from '../timeline/helpers'; import { TruncatableText } from '../truncatable_text'; import { getDraggableId, getDroppableId } from './helpers'; +import { ProviderContainer } from './provider_container'; // As right now, we do not know what we want there, we will keep it as a placeholder export const DragEffects = styled.div``; @@ -42,143 +42,12 @@ const Wrapper = styled.div` Wrapper.displayName = 'Wrapper'; -const ProviderContainer = styled.div<{ isDragging: boolean }>` - &, - &::before, - &::after { - transition: background ${({ theme }) => theme.eui.euiAnimSpeedFast} ease, - color ${({ theme }) => theme.eui.euiAnimSpeedFast} ease; +const ProviderContentWrapper = styled.span` + > span.euiToolTipAnchor { + display: block; /* allow EuiTooltip content to be truncatable */ } - - ${({ isDragging }) => - !isDragging && - css` - & { - border-radius: 2px; - padding: 0 4px 0 8px; - position: relative; - z-index: ${({ theme }) => theme.eui.euiZLevel0} !important; - - &::before { - background-image: linear-gradient( - 135deg, - ${({ theme }) => theme.eui.euiColorMediumShade} 25%, - transparent 25% - ), - linear-gradient( - -135deg, - ${({ theme }) => theme.eui.euiColorMediumShade} 25%, - transparent 25% - ), - linear-gradient( - 135deg, - transparent 75%, - ${({ theme }) => theme.eui.euiColorMediumShade} 75% - ), - linear-gradient( - -135deg, - transparent 75%, - ${({ theme }) => theme.eui.euiColorMediumShade} 75% - ); - background-position: 0 0, 1px 0, 1px -1px, 0px 1px; - background-size: 2px 2px; - bottom: 2px; - content: ''; - display: block; - left: 2px; - position: absolute; - top: 2px; - width: 4px; - } - } - - &:hover { - &, - & .euiBadge, - & .euiBadge__text { - cursor: move; /* Fallback for IE11 */ - cursor: grab; - } - } - - .${STATEFUL_EVENT_CSS_CLASS_NAME}:hover &, - tr:hover & { - background-color: ${({ theme }) => theme.eui.euiColorLightShade}; - - &::before { - background-image: linear-gradient( - 135deg, - ${({ theme }) => theme.eui.euiColorDarkShade} 25%, - transparent 25% - ), - linear-gradient( - -135deg, - ${({ theme }) => theme.eui.euiColorDarkShade} 25%, - transparent 25% - ), - linear-gradient( - 135deg, - transparent 75%, - ${({ theme }) => theme.eui.euiColorDarkShade} 75% - ), - linear-gradient( - -135deg, - transparent 75%, - ${({ theme }) => theme.eui.euiColorDarkShade} 75% - ); - } - } - - &:hover, - &:focus, - .${STATEFUL_EVENT_CSS_CLASS_NAME}:hover &:hover, - .${STATEFUL_EVENT_CSS_CLASS_NAME}:focus &:focus, - tr:hover &:hover, - tr:hover &:focus { - background-color: ${({ theme }) => theme.eui.euiColorPrimary}; - - &, - & a, - & a:hover { - color: ${({ theme }) => theme.eui.euiColorEmptyShade}; - } - - &::before { - background-image: linear-gradient( - 135deg, - ${({ theme }) => theme.eui.euiColorEmptyShade} 25%, - transparent 25% - ), - linear-gradient( - -135deg, - ${({ theme }) => theme.eui.euiColorEmptyShade} 25%, - transparent 25% - ), - linear-gradient( - 135deg, - transparent 75%, - ${({ theme }) => theme.eui.euiColorEmptyShade} 75% - ), - linear-gradient( - -135deg, - transparent 75%, - ${({ theme }) => theme.eui.euiColorEmptyShade} 75% - ); - } - } - `} - - ${({ isDragging }) => - isDragging && - css` - & { - z-index: 9999 !important; - } - `} `; -ProviderContainer.displayName = 'ProviderContainer'; - interface OwnProps { dataProvider: DataProvider; inline?: boolean; @@ -244,9 +113,11 @@ const DraggableWrapperComponent = React.memo( {render(dataProvider, provided, snapshot)} ) : ( - + {render(dataProvider, provided, snapshot)} - + )} diff --git a/x-pack/legacy/plugins/siem/public/components/drag_and_drop/provider_container.tsx b/x-pack/legacy/plugins/siem/public/components/drag_and_drop/provider_container.tsx new file mode 100644 index 0000000000000..c1f029086aa35 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/drag_and_drop/provider_container.tsx @@ -0,0 +1,154 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import styled, { css } from 'styled-components'; +import { STATEFUL_EVENT_CSS_CLASS_NAME } from '../timeline/helpers'; + +interface ProviderContainerProps { + isDragging: boolean; +} + +const ProviderContainerComponent = styled.div` + &, + &::before, + &::after { + transition: background ${({ theme }) => theme.eui.euiAnimSpeedFast} ease, + color ${({ theme }) => theme.eui.euiAnimSpeedFast} ease; + } + + ${({ isDragging }) => + !isDragging && + css` + & { + border-radius: 2px; + padding: 0 4px 0 8px; + position: relative; + z-index: ${({ theme }) => theme.eui.euiZLevel0} !important; + + &::before { + background-image: linear-gradient( + 135deg, + ${({ theme }) => theme.eui.euiColorMediumShade} 25%, + transparent 25% + ), + linear-gradient( + -135deg, + ${({ theme }) => theme.eui.euiColorMediumShade} 25%, + transparent 25% + ), + linear-gradient( + 135deg, + transparent 75%, + ${({ theme }) => theme.eui.euiColorMediumShade} 75% + ), + linear-gradient( + -135deg, + transparent 75%, + ${({ theme }) => theme.eui.euiColorMediumShade} 75% + ); + background-position: 0 0, 1px 0, 1px -1px, 0px 1px; + background-size: 2px 2px; + bottom: 2px; + content: ''; + display: block; + left: 2px; + position: absolute; + top: 2px; + width: 4px; + } + } + + &:hover { + &, + & .euiBadge, + & .euiBadge__text { + cursor: move; /* Fallback for IE11 */ + cursor: grab; + } + } + + .${STATEFUL_EVENT_CSS_CLASS_NAME}:hover &, + tr:hover & { + background-color: ${({ theme }) => theme.eui.euiColorLightShade}; + + &::before { + background-image: linear-gradient( + 135deg, + ${({ theme }) => theme.eui.euiColorDarkShade} 25%, + transparent 25% + ), + linear-gradient( + -135deg, + ${({ theme }) => theme.eui.euiColorDarkShade} 25%, + transparent 25% + ), + linear-gradient( + 135deg, + transparent 75%, + ${({ theme }) => theme.eui.euiColorDarkShade} 75% + ), + linear-gradient( + -135deg, + transparent 75%, + ${({ theme }) => theme.eui.euiColorDarkShade} 75% + ); + } + } + + &:hover, + &:focus, + .${STATEFUL_EVENT_CSS_CLASS_NAME}:hover &:hover, + .${STATEFUL_EVENT_CSS_CLASS_NAME}:focus &:focus, + tr:hover &:hover, + tr:hover &:focus { + background-color: ${({ theme }) => theme.eui.euiColorPrimary}; + + &, + & a, + & a:hover { + color: ${({ theme }) => theme.eui.euiColorEmptyShade}; + } + + &::before { + background-image: linear-gradient( + 135deg, + ${({ theme }) => theme.eui.euiColorEmptyShade} 25%, + transparent 25% + ), + linear-gradient( + -135deg, + ${({ theme }) => theme.eui.euiColorEmptyShade} 25%, + transparent 25% + ), + linear-gradient( + 135deg, + transparent 75%, + ${({ theme }) => theme.eui.euiColorEmptyShade} 75% + ), + linear-gradient( + -135deg, + transparent 75%, + ${({ theme }) => theme.eui.euiColorEmptyShade} 75% + ); + } + } + `} + + ${({ isDragging }) => + isDragging && + css` + & { + z-index: 9999 !important; + } + `} +`; + +ProviderContainerComponent.displayName = 'ProviderContainerComponent'; + +export const ProviderContainer = React.memo(ProviderContainerComponent); + +ProviderContainer.displayName = 'ProviderContainer'; diff --git a/x-pack/legacy/plugins/siem/public/components/event_details/columns.tsx b/x-pack/legacy/plugins/siem/public/components/event_details/columns.tsx index d835d2c621931..77f03f0555454 100644 --- a/x-pack/legacy/plugins/siem/public/components/event_details/columns.tsx +++ b/x-pack/legacy/plugins/siem/public/components/event_details/columns.tsx @@ -23,16 +23,14 @@ import { WithCopyToClipboard } from '../../lib/clipboard/with_copy_to_clipboard' import { DragEffects } from '../drag_and_drop/draggable_wrapper'; import { DroppableWrapper } from '../drag_and_drop/droppable_wrapper'; import { getDroppableId, getDraggableFieldId, DRAG_TYPE_FIELD } from '../drag_and_drop/helpers'; -import { DefaultDraggable } from '../draggables'; import { DraggableFieldBadge } from '../draggables/field_badge'; -import { EVENT_DURATION_FIELD_NAME } from '../duration'; import { FieldName } from '../fields_browser/field_name'; import { SelectableText } from '../selectable_text'; import { OverflowField } from '../tables/helpers'; import { ColumnHeader } from '../timeline/body/column_headers/column_header'; import { defaultColumnHeaderType } from '../timeline/body/column_headers/default_headers'; import { DEFAULT_COLUMN_MIN_WIDTH } from '../timeline/body/helpers'; -import { DATE_FIELD_TYPE, MESSAGE_FIELD_NAME } from '../timeline/body/renderers/constants'; +import { MESSAGE_FIELD_NAME } from '../timeline/body/renderers/constants'; import { FormattedFieldValue } from '../timeline/body/renderers/formatted_field'; import { OnUpdateColumns } from '../timeline/events'; import { WithHoverActions } from '../with_hover_actions'; @@ -180,28 +178,14 @@ export const getColumns = ({ data.field === MESSAGE_FIELD_NAME ? ( ) : ( - - - - - + /> ) } /> diff --git a/x-pack/legacy/plugins/siem/public/components/event_details/event_fields_browser.tsx b/x-pack/legacy/plugins/siem/public/components/event_details/event_fields_browser.tsx index cec8ddff1a7c9..f4e9a2b789d71 100644 --- a/x-pack/legacy/plugins/siem/public/components/event_details/event_fields_browser.tsx +++ b/x-pack/legacy/plugins/siem/public/components/event_details/event_fields_browser.tsx @@ -6,7 +6,7 @@ import { sortBy } from 'lodash'; import { EuiInMemoryTable } from '@elastic/eui'; -import * as React from 'react'; +import React, { useMemo } from 'react'; import { ColumnHeader } from '../timeline/body/column_headers/column_header'; import { BrowserFields, getAllFieldsByName } from '../../containers/source'; @@ -29,26 +29,35 @@ interface Props { /** Renders a table view or JSON view of the `ECS` `data` */ export const EventFieldsBrowser = React.memo( ({ browserFields, columnHeaders, data, eventId, onUpdateColumns, timelineId, toggleColumn }) => { - const fieldsByName = getAllFieldsByName(browserFields); + const fieldsByName = useMemo(() => getAllFieldsByName(browserFields), [browserFields]); + const items = useMemo( + () => + sortBy(data, ['field']).map(item => ({ + ...item, + ...fieldsByName[item.field], + valuesConcatenated: item.values != null ? item.values.join() : '', + })), + [data, fieldsByName] + ); + const columns = useMemo( + () => + getColumns({ + browserFields, + columnHeaders, + eventId, + onUpdateColumns, + contextId: timelineId, + toggleColumn, + }), + [browserFields, columnHeaders, eventId, onUpdateColumns, timelineId, toggleColumn] + ); + return (
, column `render` callbacks expect complete BrowserField - items={sortBy(data, ['field']).map(item => { - return { - ...item, - ...fieldsByName[item.field], - valuesConcatenated: item.values != null ? item.values.join() : '', - }; - })} - columns={getColumns({ - browserFields, - columnHeaders, - eventId, - onUpdateColumns, - contextId: timelineId, - toggleColumn, - })} + items={items} + columns={columns} pagination={false} search={search} sorting={true} diff --git a/x-pack/legacy/plugins/siem/public/components/skeleton_row/index.tsx b/x-pack/legacy/plugins/siem/public/components/skeleton_row/index.tsx index 20aea3251d838..dce360877130e 100644 --- a/x-pack/legacy/plugins/siem/public/components/skeleton_row/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/skeleton_row/index.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; +import React, { useMemo } from 'react'; import styled from 'styled-components'; interface RowProps { @@ -12,7 +12,7 @@ interface RowProps { rowPadding?: string; } -const Row = styled.div.attrs(({ rowHeight, rowPadding, theme }) => ({ +const RowComponent = styled.div.attrs(({ rowHeight, rowPadding, theme }) => ({ className: 'siemSkeletonRow', rowHeight: rowHeight || theme.eui.euiSizeXL, rowPadding: rowPadding || `${theme.eui.paddingSizes.s} ${theme.eui.paddingSizes.xs}`, @@ -22,6 +22,10 @@ const Row = styled.div.attrs(({ rowHeight, rowPadding, theme }) => ({ height: ${({ rowHeight }) => rowHeight}; padding: ${({ rowPadding }) => rowPadding}; `; +RowComponent.displayName = 'RowComponent'; + +const Row = React.memo(RowComponent); + Row.displayName = 'Row'; interface CellProps { @@ -29,7 +33,7 @@ interface CellProps { cellMargin?: string; } -const Cell = styled.div.attrs(({ cellColor, cellMargin, theme }) => ({ +const CellComponent = styled.div.attrs(({ cellColor, cellMargin, theme }) => ({ className: 'siemSkeletonRow__cell', cellColor: cellColor || theme.eui.euiColorLightestShade, cellMargin: cellMargin || theme.eui.gutterTypes.gutterSmall, @@ -42,6 +46,10 @@ const Cell = styled.div.attrs(({ cellColor, cellMargin, theme }) => ( margin-left: ${({ cellMargin }) => cellMargin}; } `; +CellComponent.displayName = 'CellComponent'; + +const Cell = React.memo(CellComponent); + Cell.displayName = 'Cell'; export interface SkeletonRowProps extends CellProps, RowProps { @@ -51,9 +59,14 @@ export interface SkeletonRowProps extends CellProps, RowProps { export const SkeletonRow = React.memo( ({ cellColor, cellCount = 4, cellMargin, rowHeight, rowPadding, style }) => { - const cells = [...Array(cellCount)].map((_, i) => ( - - )); + const cells = useMemo( + () => + [...Array(cellCount)].map( + (_, i) => , + [cellCount] + ), + [cellCount, cellColor, cellMargin] + ); return ( diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/body/data_driven_columns/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/timeline/body/data_driven_columns/__snapshots__/index.test.tsx.snap index d370a24cc1d4d..a168f8d48fa33 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/body/data_driven_columns/__snapshots__/index.test.tsx.snap +++ b/x-pack/legacy/plugins/siem/public/components/timeline/body/data_driven_columns/__snapshots__/index.test.tsx.snap @@ -49,25 +49,15 @@ exports[`Columns it renders the expected columns 1`] = ` - @@ -82,25 +72,15 @@ exports[`Columns it renders the expected columns 1`] = ` - @@ -115,25 +95,15 @@ exports[`Columns it renders the expected columns 1`] = ` - @@ -148,25 +118,15 @@ exports[`Columns it renders the expected columns 1`] = ` - @@ -181,25 +141,15 @@ exports[`Columns it renders the expected columns 1`] = ` - @@ -214,25 +164,15 @@ exports[`Columns it renders the expected columns 1`] = ` - diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/__snapshots__/formatted_field.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/__snapshots__/formatted_field.test.tsx.snap index 1fe02f6f35d06..83a241b628edb 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/__snapshots__/formatted_field.test.tsx.snap +++ b/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/__snapshots__/formatted_field.test.tsx.snap @@ -1,8 +1,11 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Events renders correctly against snapshot 1`] = ` - `; diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/__snapshots__/get_column_renderer.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/__snapshots__/get_column_renderer.test.tsx.snap index b867e0a788449..a79a7ed23e3d1 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/__snapshots__/get_column_renderer.test.tsx.snap +++ b/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/__snapshots__/get_column_renderer.test.tsx.snap @@ -2,24 +2,14 @@ exports[`get_column_renderer renders correctly against snapshot 1`] = ` - `; diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/__snapshots__/plain_column_renderer.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/__snapshots__/plain_column_renderer.test.tsx.snap index e2eaf1d872b26..563e356a689c8 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/__snapshots__/plain_column_renderer.test.tsx.snap +++ b/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/__snapshots__/plain_column_renderer.test.tsx.snap @@ -2,24 +2,14 @@ exports[`plain_column_renderer rendering renders correctly against snapshot 1`] = ` - `; diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/formatted_field.test.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/formatted_field.test.tsx index 5c54e5be3374c..1e7c3bfedc9b9 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/formatted_field.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/formatted_field.test.tsx @@ -4,12 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json'; import { shallow } from 'enzyme'; import toJson from 'enzyme-to-json'; import { get } from 'lodash/fp'; -import * as React from 'react'; -import { ThemeProvider } from 'styled-components'; +import React from 'react'; import { mockTimelineData, TestProviders } from '../../../../mock'; import { getEmptyValue } from '../../../empty_value'; @@ -21,31 +19,34 @@ import { HOST_NAME_FIELD_NAME } from './constants'; jest.mock('../../../../lib/kibana'); describe('Events', () => { - const theme = () => ({ eui: euiDarkVars, darkMode: true }); const mount = useMountAppended(); test('renders correctly against snapshot', () => { const wrapper = shallow( - + + + ); - expect(toJson(wrapper)).toMatchSnapshot(); + expect(toJson(wrapper.find('FormattedFieldValue'))).toMatchSnapshot(); }); test('it renders a localized date tooltip for a field type of date that has a valid timestamp', () => { const wrapper = mount( - + + + ); expect(wrapper.find('[data-test-subj="localized-date-tool-tip"]').exists()).toEqual(true); @@ -53,13 +54,15 @@ describe('Events', () => { test('it does NOT render a localized date tooltip when field type is NOT date, even if it contains valid timestamp', () => { const wrapper = mount( - + + + ); expect(wrapper.find('[data-test-subj="localized-date-tool-tip"]').exists()).toEqual(false); @@ -72,13 +75,15 @@ describe('Events', () => { }; const wrapper = mount( - + + + ); expect(wrapper.find('[data-test-subj="localized-date-tool-tip"]').exists()).toEqual(false); @@ -86,13 +91,15 @@ describe('Events', () => { test('it renders the value for a non-date field when the field is populated', () => { const wrapper = mount( - + + + ); expect(wrapper.text()).toEqual('nginx'); @@ -100,7 +107,7 @@ describe('Events', () => { test('it renders placeholder text for a non-date field when the field is NOT populated', () => { const wrapper = mount( - + { fieldType="text" value={get('fake.field', mockTimelineData[0].ecs)} /> - + ); expect(wrapper.text()).toEqual(getEmptyValue()); @@ -116,14 +123,16 @@ describe('Events', () => { test('it renders tooltip for truncatable message when it exists', () => { const wrapper = mount( - + + + ); expect(wrapper.find('[data-test-subj="message-tool-tip"]').exists()).toEqual(true); @@ -179,53 +188,61 @@ describe('Events', () => { test('it renders a message text string', () => { const wrapper = mount( - + + + ); expect(wrapper.text()).toEqual('some message'); }); test('it renders truncatable message text when fieldName is message with truncate prop', () => { const wrapper = mount( - + + + ); expect(wrapper.find('[data-test-subj="truncatable-message"]').exists()).toEqual(true); }); test('it does NOT render the truncatable message style when fieldName is NOT message', () => { const wrapper = mount( - + + + ); expect(wrapper.find('[data-test-subj="truncatable-message"]').exists()).toEqual(false); }); test('it renders a hyperlink to the hosts details page when fieldName is host.name, and a hostname is provided', () => { const wrapper = mount( - + + + ); expect(wrapper.find('[data-test-subj="host-details-link"]').exists()).toEqual(true); }); diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/formatted_field.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/formatted_field.tsx index 7529c0623ef47..280de3683a11f 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/formatted_field.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/formatted_field.tsx @@ -5,9 +5,10 @@ */ import { EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui'; -import { isNumber, isString } from 'lodash/fp'; -import * as React from 'react'; +import { isNumber, isString, isEmpty } from 'lodash/fp'; +import React from 'react'; +import { DefaultDraggable } from '../../../draggables'; import { Bytes, BYTES_FORMAT } from '../../../bytes'; import { Duration, EVENT_DURATION_FIELD_NAME } from '../../../duration'; import { getOrEmptyTagFromValue, getEmptyTagValue } from '../../../empty_value'; @@ -23,6 +24,9 @@ import { MESSAGE_FIELD_NAME, } from './constants'; +// simple black-list to prevent dragging and dropping fields such as message name +const columnNamesNotDraggable = [MESSAGE_FIELD_NAME]; + export const FormattedFieldValue = React.memo<{ contextId: string; eventId: string; @@ -42,7 +46,16 @@ export const FormattedFieldValue = React.memo<{ /> ); } else if (fieldType === DATE_FIELD_TYPE) { - return ; + return ( + + + + ); } else if (PORT_NAMES.some(portName => fieldName === portName)) { return ( @@ -55,11 +68,16 @@ export const FormattedFieldValue = React.memo<{ const hostname = `${value}`; return isString(value) && hostname.length > 0 ? ( - + - {value} + {value} - + ) : ( getEmptyTagValue() ); @@ -67,34 +85,46 @@ export const FormattedFieldValue = React.memo<{ return ( ); - } else if (fieldName === MESSAGE_FIELD_NAME && value != null && value !== '') { - return ( - <> - {truncate ? ( - - - - {fieldName} - - - {value} - - - } - > - <>{value} - - - ) : ( + } else if (columnNamesNotDraggable.includes(fieldName)) { + return truncate && !isEmpty(value) ? ( + + + + {fieldName} + + + {value} + + + } + > <>{value} - )} - + + + ) : ( + <>{value} ); } else { - return getOrEmptyTagFromValue(value); + const contentValue = getOrEmptyTagFromValue(value); + const content = truncate ? {contentValue} : contentValue; + + return ( + + {content} + + ); } }); diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/plain_column_renderer.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/plain_column_renderer.tsx index 25a70502e3e45..70485c41f3b88 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/plain_column_renderer.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/body/renderers/plain_column_renderer.tsx @@ -4,29 +4,18 @@ * you may not use this file except in compliance with the Elastic License. */ -import { isNumber } from 'lodash/fp'; import React from 'react'; import { TimelineNonEcsData } from '../../../../graphql/types'; -import { DragEffects, DraggableWrapper } from '../../../drag_and_drop/draggable_wrapper'; -import { escapeDataProviderId } from '../../../drag_and_drop/helpers'; import { getEmptyTagValue } from '../../../empty_value'; -import { FormattedIp } from '../../../formatted_ip'; -import { IS_OPERATOR, DataProvider } from '../../data_providers/data_provider'; -import { Provider } from '../../data_providers/provider'; import { ColumnHeader } from '../column_headers/column_header'; import { ColumnRenderer } from './column_renderer'; -import { IP_FIELD_TYPE, MESSAGE_FIELD_NAME } from './constants'; import { FormattedFieldValue } from './formatted_field'; -import { parseQueryValue } from './parse_query_value'; import { parseValue } from './parse_value'; export const dataExistsAtColumn = (columnName: string, data: TimelineNonEcsData[]): boolean => data.findIndex(item => item.field === columnName) !== -1; -// simple black-list to prevent dragging and dropping fields such as message name -const columnNamesNotDraggable = [MESSAGE_FIELD_NAME]; - export const plainColumnRenderer: ColumnRenderer = { isInstance: (columnName: string, data: TimelineNonEcsData[]) => dataExistsAtColumn(columnName, data), @@ -47,91 +36,17 @@ export const plainColumnRenderer: ColumnRenderer = { values: string[] | undefined | null; }) => values != null - ? values.map(value => { - const itemDataProvider: DataProvider = { - enabled: true, - id: escapeDataProviderId( - `plain-column-renderer-data-provider-${timelineId}-${columnName}-${eventId}-${field.id}-${value}` - ), - name: `${columnName}: ${parseQueryValue(value)}`, - queryMatch: { - field: field.id, - value: parseQueryValue(value), - operator: IS_OPERATOR, - }, - excluded: false, - kqlQuery: '', - and: [], - }; - if (field.type === IP_FIELD_TYPE) { - // since ip fields may contain multiple IP addresses, return a FormattedIp here to avoid a "draggable of draggables" - return ( - - ); - } - - if (columnNamesNotDraggable.includes(columnName)) { - if (truncate) { - return ( - - ); - } else { - return ( - - ); - } - } - // note: we use a raw DraggableWrapper here instead of a DefaultDraggable, - // because we pass a width to enable text truncation, and we will show empty values - return ( - - snapshot.isDragging ? ( - - - - ) : ( - - ) - } - truncate={truncate} - /> - ); - }) + ? values.map(value => ( + + )) : getEmptyTagValue(), };