From eb5538ae6fa52e1acbe0ae4f6145d89c64383145 Mon Sep 17 00:00:00 2001 From: PhilippeOberti Date: Mon, 19 Sep 2022 07:57:10 -0500 Subject: [PATCH] [TIP] Fix many small UI issues - add EuiTooltip for all EuiButtonIcon - add missing translations - replace css with EuiFlexGroup where possible - extract fieldValueValid logic --- .../indicator_barchart_legend_action.tsx | 22 +++-- .../indicator_value_actions.tsx | 11 ++- .../components/block/indicator_block.tsx | 2 +- .../indicators_table/actions_row_cell.tsx | 8 +- .../indicators_table/cell_actions.tsx | 6 +- .../components/indicators_table/styles.ts | 18 ---- .../open_indicator_flyout_button.tsx | 18 ++-- .../indicators/lib/field_value.test.ts | 83 +++++++++++++----- .../modules/indicators/lib/field_value.ts | 10 +++ .../__snapshots__/filter_in.test.tsx.snap | 84 +++++++++++-------- .../components/filter_in/filter_in.tsx | 37 ++++---- .../__snapshots__/filter_out.test.tsx.snap | 84 +++++++++++-------- .../components/filter_out/filter_out.tsx | 37 ++++---- .../add_to_timeline.test.tsx.snap | 68 +++++++++------ .../add_to_timeline/add_to_timeline.tsx | 26 ++++-- .../components/add_to_timeline/styles.ts | 5 -- .../investigate_in_timeline_button.tsx | 6 +- ...gate_in_timeline_button_icon.test.tsx.snap | 12 +-- .../investigate_in_timeline_button_icon.tsx | 23 +++-- .../styles.ts | 18 ---- .../hooks/use_investigate_in_timeline.ts | 8 +- 21 files changed, 329 insertions(+), 257 deletions(-) delete mode 100644 x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/styles.ts delete mode 100644 x-pack/plugins/threat_intelligence/public/modules/timeline/components/investigate_in_timeline_button_icon/styles.ts diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicator_barchart_legend_action/indicator_barchart_legend_action.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicator_barchart_legend_action/indicator_barchart_legend_action.tsx index e015e409ec227..c87f812da76fb 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicator_barchart_legend_action/indicator_barchart_legend_action.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicator_barchart_legend_action/indicator_barchart_legend_action.tsx @@ -6,7 +6,8 @@ */ import React, { useState, VFC } from 'react'; -import { EuiButtonIcon, EuiContextMenuPanel, EuiPopover } from '@elastic/eui'; +import { EuiButtonIcon, EuiContextMenuPanel, EuiPopover, EuiToolTip } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; import { ComponentType } from '../../../../../common/types/component_type'; import { FilterIn } from '../../../query_bar/components/filter_in'; import { FilterOut } from '../../../query_bar/components/filter_out'; @@ -17,6 +18,10 @@ export const TIMELINE_BUTTON_TEST_ID = 'tiBarchartTimelineButton'; export const FILTER_IN_BUTTON_TEST_ID = 'tiBarchartFilterInButton'; export const FILTER_OUT_BUTTON_TEST_ID = 'tiBarchartFilterOutButton'; +const BUTTON_LABEL = i18n.translate('xpack.threatIntelligence.indicator.barChart.popover', { + defaultMessage: 'More actions', +}); + export interface IndicatorBarchartLegendActionProps { /** * Indicator @@ -59,12 +64,15 @@ export const IndicatorBarchartLegendAction: VFC setPopover(!isPopoverOpen)} - /> + + setPopover(!isPopoverOpen)} + /> + } isOpen={isPopoverOpen} closePopover={() => setPopover(false)} diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicator_value_actions/indicator_value_actions.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicator_value_actions/indicator_value_actions.tsx index 1fdc58f85cfcf..f3c5fd7c2e7d8 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicator_value_actions/indicator_value_actions.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicator_value_actions/indicator_value_actions.tsx @@ -7,12 +7,12 @@ import type { EuiButtonEmpty, EuiButtonIcon } from '@elastic/eui'; import React, { VFC } from 'react'; -import { EMPTY_VALUE } from '../../../../../common/constants'; +import { EuiFlexGroup } from '@elastic/eui'; import { Indicator } from '../../../../../common/types/indicator'; import { FilterIn } from '../../../query_bar/components/filter_in'; import { FilterOut } from '../../../query_bar/components/filter_out'; import { AddToTimeline } from '../../../timeline/components/add_to_timeline'; -import { getIndicatorFieldAndValue } from '../../lib/field_value'; +import { fieldAndValueValid, getIndicatorFieldAndValue } from '../../lib/field_value'; export const TIMELINE_BUTTON_TEST_ID = 'TimelineButton'; export const FILTER_IN_BUTTON_TEST_ID = 'FilterInButton'; @@ -44,8 +44,7 @@ export const IndicatorValueActions: VFC = ({ ...props }) => { const { key, value } = getIndicatorFieldAndValue(indicator, field); - - if (!key || value === EMPTY_VALUE || !key) { + if (!fieldAndValueValid(key, value)) { return null; } @@ -54,7 +53,7 @@ export const IndicatorValueActions: VFC = ({ const timelineTestId = `${props['data-test-subj']}${TIMELINE_BUTTON_TEST_ID}`; return ( - <> + = ({ field={field} data-test-subj={timelineTestId} /> - + ); }; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_flyout/tabs/indicators_flyout_overview/components/block/indicator_block.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_flyout/tabs/indicators_flyout_overview/components/block/indicator_block.tsx index 3fbd7d7365d50..9537131a574a3 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_flyout/tabs/indicators_flyout_overview/components/block/indicator_block.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_flyout/tabs/indicators_flyout_overview/components/block/indicator_block.tsx @@ -25,7 +25,7 @@ const VisibleOnHover = euiStyled.div` & .actionsWrapper { visibility: hidden; display: inline-block; - margin-inline-start: ${theme.eui.euiSizeXS}; + margin-inline-start: ${theme.eui.euiSizeS}; } &:hover .actionsWrapper { diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/actions_row_cell.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/actions_row_cell.tsx index 277b64fcacc3d..1744bf8ac06ce 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/actions_row_cell.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/actions_row_cell.tsx @@ -6,17 +6,15 @@ */ import React, { useContext, VFC } from 'react'; +import { EuiFlexGroup } from '@elastic/eui'; import { InvestigateInTimelineButtonIcon } from '../../../timeline/components/investigate_in_timeline_button_icon'; import { Indicator } from '../../../../../common/types/indicator'; import { OpenIndicatorFlyoutButton } from '../open_indicator_flyout_button/open_indicator_flyout_button'; import { IndicatorsTableContext } from './context'; -import { useStyles } from './styles'; const INVESTIGATE_TEST_ID = 'tiIndicatorTableInvestigateInTimelineButtonIcon'; export const ActionsRowCell: VFC<{ indicator: Indicator }> = ({ indicator }) => { - const styles = useStyles(); - const indicatorTableContext = useContext(IndicatorsTableContext); if (!indicatorTableContext) { @@ -26,13 +24,13 @@ export const ActionsRowCell: VFC<{ indicator: Indicator }> = ({ indicator }) => const { setExpanded, expanded } = indicatorTableContext; return ( -
+ -
+ ); }; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/cell_actions.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/cell_actions.tsx index fa255f053ab67..0f111f96c4c25 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/cell_actions.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/cell_actions.tsx @@ -8,11 +8,10 @@ import React, { VFC } from 'react'; import { EuiDataGridColumnCellActionProps } from '@elastic/eui/src/components/datagrid/data_grid_types'; import { ComponentType } from '../../../../../common/types/component_type'; -import { EMPTY_VALUE } from '../../../../../common/constants'; import { Indicator } from '../../../../../common/types/indicator'; import { Pagination } from '../../hooks/use_indicators'; import { AddToTimeline } from '../../../timeline/components/add_to_timeline'; -import { getIndicatorFieldAndValue } from '../../lib/field_value'; +import { fieldAndValueValid, getIndicatorFieldAndValue } from '../../lib/field_value'; import { FilterIn } from '../../../query_bar/components/filter_in'; import { FilterOut } from '../../../query_bar/components/filter_out'; @@ -47,8 +46,7 @@ export const CellActions: VFC = ({ }) => { const indicator = indicators[rowIndex % pagination.pageSize]; const { key, value } = getIndicatorFieldAndValue(indicator, columnId); - - if (!value || value === EMPTY_VALUE || !key) { + if (!fieldAndValueValid(key, value)) { return <>; } diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/styles.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/styles.ts deleted file mode 100644 index 3ae7bf4ef16d9..0000000000000 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/styles.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * 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 { CSSObject } from '@emotion/react'; - -export const useStyles = () => { - const rowActionsDiv: CSSObject = { - display: 'flex', - }; - - return { - rowActionsDiv, - }; -}; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/open_indicator_flyout_button/open_indicator_flyout_button.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/open_indicator_flyout_button/open_indicator_flyout_button.tsx index 48900019265c7..08a27381ce9a7 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/open_indicator_flyout_button/open_indicator_flyout_button.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/open_indicator_flyout_button/open_indicator_flyout_button.tsx @@ -12,6 +12,13 @@ import { Indicator } from '../../../../../common/types/indicator'; export const BUTTON_TEST_ID = 'tiToggleIndicatorFlyoutButton'; +const BUTTON_LABEL: string = i18n.translate( + 'xpack.threatIntelligence.indicator.table.viewDetailsButton', + { + defaultMessage: 'View details', + } +); + export interface OpenIndicatorFlyoutButtonProps { /** * {@link Indicator} passed to the flyout component. @@ -35,22 +42,15 @@ export const OpenIndicatorFlyoutButton: VFC = ({ onOpen, isOpen, }) => { - const buttonLabel: string = i18n.translate( - 'xpack.threatIntelligence.indicator.table.viewDetailsButton', - { - defaultMessage: 'View details', - } - ); - return ( - + onOpen(indicator)} /> diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/lib/field_value.test.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/lib/field_value.test.ts index fa9746e80cc21..bd6a36aaf2d50 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/lib/field_value.test.ts +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/lib/field_value.test.ts @@ -5,39 +5,76 @@ * 2.0. */ -import { getIndicatorFieldAndValue } from './field_value'; +import { fieldAndValueValid, getIndicatorFieldAndValue } from './field_value'; import { generateMockFileIndicator, generateMockUrlIndicator, } from '../../../../common/types/indicator'; +import { EMPTY_VALUE } from '../../../../common/constants'; -describe('getIndicatorFieldAndValue()', () => { - it('should return field/value pair for an indicator', () => { - const mockData = generateMockUrlIndicator(); - const mockKey = 'threat.feed.name'; +describe('field_value', () => { + describe('getIndicatorFieldAndValue()', () => { + it('should return field/value pair for an indicator', () => { + const mockData = generateMockUrlIndicator(); + const mockKey = 'threat.feed.name'; - const result = getIndicatorFieldAndValue(mockData, mockKey); - expect(result.key).toEqual(mockKey); - expect(result.value).toEqual((mockData.fields[mockKey] as unknown as string[])[0]); - }); + const result = getIndicatorFieldAndValue(mockData, mockKey); + expect(result.key).toEqual(mockKey); + expect(result.value).toEqual((mockData.fields[mockKey] as unknown as string[])[0]); + }); + + it('should return a null value for an incorrect field', () => { + const mockData = generateMockUrlIndicator(); + const mockKey = 'abc'; + + const result = getIndicatorFieldAndValue(mockData, mockKey); + expect(result.key).toEqual(mockKey); + expect(result.value).toBeNull(); + }); - it('should return a null value for an incorrect field', () => { - const mockData = generateMockUrlIndicator(); - const mockKey = 'abc'; + it('should return field/value pair for an indicator and DisplayName field', () => { + const mockData = generateMockFileIndicator(); + const mockKey = 'threat.indicator.name'; - const result = getIndicatorFieldAndValue(mockData, mockKey); - expect(result.key).toEqual(mockKey); - expect(result.value).toBeNull(); + const result = getIndicatorFieldAndValue(mockData, mockKey); + expect(result.key).toEqual( + (mockData.fields['threat.indicator.name_origin'] as unknown as string[])[0] + ); + expect(result.value).toEqual((mockData.fields[mockKey] as unknown as string[])[0]); + }); }); - it('should return field/value pair for an indicator and DisplayName field', () => { - const mockData = generateMockFileIndicator(); - const mockKey = 'threat.indicator.name'; + describe('fieldAndValueValid()', () => { + it('should return false for null value', () => { + const mockField = 'abc'; + const mockValue = null; + + const result = fieldAndValueValid(mockField, mockValue); + expect(result).toEqual(false); + }); + + it(`should return false for ${EMPTY_VALUE} value`, () => { + const mockField = 'abc'; + const mockValue = EMPTY_VALUE; + + const result = fieldAndValueValid(mockField, mockValue); + expect(result).toEqual(false); + }); + + it('should return false for empty field', () => { + const mockField = ''; + const mockValue = 'abc'; + + const result = fieldAndValueValid(mockField, mockValue); + expect(result).toEqual(false); + }); + + it('should return true if field and value are correct', () => { + const mockField = 'abc'; + const mockValue = 'abc'; - const result = getIndicatorFieldAndValue(mockData, mockKey); - expect(result.key).toEqual( - (mockData.fields['threat.indicator.name_origin'] as unknown as string[])[0] - ); - expect(result.value).toEqual((mockData.fields[mockKey] as unknown as string[])[0]); + const result = fieldAndValueValid(mockField, mockValue); + expect(result).toEqual(true); + }); }); }); diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/lib/field_value.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/lib/field_value.ts index f463537b120c4..958b33e6a6347 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/lib/field_value.ts +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/lib/field_value.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { EMPTY_VALUE } from '../../../../common/constants'; import { unwrapValue } from './unwrap_value'; import { Indicator, RawIndicatorFieldId } from '../../../../common/types/indicator'; @@ -29,3 +30,12 @@ export const getIndicatorFieldAndValue = ( value, }; }; + +/** + * Checks if field and value are correct + * @param field Indicator string field + * @param value Indicator string|null value for the field + * @returns true if correct, false if not + */ +export const fieldAndValueValid = (field: string | null, value: string | null): boolean => + value != null && value !== '' && value !== EMPTY_VALUE && field != null && field !== ''; diff --git a/x-pack/plugins/threat_intelligence/public/modules/query_bar/components/filter_in/__snapshots__/filter_in.test.tsx.snap b/x-pack/plugins/threat_intelligence/public/modules/query_bar/components/filter_in/__snapshots__/filter_in.test.tsx.snap index 1ceba15da5ad6..34e37aaf1dd40 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/query_bar/components/filter_in/__snapshots__/filter_in.test.tsx.snap +++ b/x-pack/plugins/threat_intelligence/public/modules/query_bar/components/filter_in/__snapshots__/filter_in.test.tsx.snap @@ -127,6 +127,31 @@ Object { "asFragment": [Function], "baseElement":
+ +
+ +
+
+
+ , + "container":
+
@@ -142,24 +167,7 @@ Object { />
-
- , - "container":
-
- -
+
, "debug": [Function], "findAllByAltText": [Function], @@ -220,6 +228,29 @@ Object { "asFragment": [Function], "baseElement":
+ + + +
+ , + "container":
+ -
- , - "container":
- +
, "debug": [Function], "findAllByAltText": [Function], diff --git a/x-pack/plugins/threat_intelligence/public/modules/query_bar/components/filter_in/filter_in.tsx b/x-pack/plugins/threat_intelligence/public/modules/query_bar/components/filter_in/filter_in.tsx index 44893c02c685e..d801f46915921 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/query_bar/components/filter_in/filter_in.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/query_bar/components/filter_in/filter_in.tsx @@ -7,13 +7,12 @@ import React, { useCallback, VFC } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiButtonEmpty, EuiButtonIcon, EuiContextMenuItem } from '@elastic/eui'; +import { EuiButtonEmpty, EuiButtonIcon, EuiContextMenuItem, EuiToolTip } from '@elastic/eui'; import { Filter } from '@kbn/es-query'; import { ComponentType } from '../../../../../common/types/component_type'; import { useIndicatorsFiltersContext } from '../../../indicators/hooks/use_indicators_filters_context'; -import { getIndicatorFieldAndValue } from '../../../indicators/lib/field_value'; +import { fieldAndValueValid, getIndicatorFieldAndValue } from '../../../indicators/lib/field_value'; import { FilterIn as FilterInConst, updateFiltersArray } from '../../lib/filter'; -import { EMPTY_VALUE } from '../../../../../common/constants'; import { Indicator } from '../../../../../common/types/indicator'; import { useStyles } from './styles'; @@ -66,16 +65,18 @@ export const FilterIn: VFC = ({ data, field, type, as: Component, filterManager.setFilters(newFilters); }, [filterManager, key, value]); - if (!value || value === EMPTY_VALUE || !key) { + if (!fieldAndValueValid(key, value)) { return <>; } if (type === ComponentType.EuiDataGrid) { return ( -
- {/* @ts-ignore*/} - -
+ +
+ {/* @ts-ignore*/} + +
+
); } @@ -94,14 +95,16 @@ export const FilterIn: VFC = ({ data, field, type, as: Component, } return ( - + + + ); }; diff --git a/x-pack/plugins/threat_intelligence/public/modules/query_bar/components/filter_out/__snapshots__/filter_out.test.tsx.snap b/x-pack/plugins/threat_intelligence/public/modules/query_bar/components/filter_out/__snapshots__/filter_out.test.tsx.snap index 5ace1d59f4bd8..bfee4c6363ba7 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/query_bar/components/filter_out/__snapshots__/filter_out.test.tsx.snap +++ b/x-pack/plugins/threat_intelligence/public/modules/query_bar/components/filter_out/__snapshots__/filter_out.test.tsx.snap @@ -127,6 +127,31 @@ Object { "asFragment": [Function], "baseElement":
+ +
+ +
+
+
+ , + "container":
+
@@ -142,24 +167,7 @@ Object { />
-
- , - "container":
-
- -
+
, "debug": [Function], "findAllByAltText": [Function], @@ -220,6 +228,29 @@ Object { "asFragment": [Function], "baseElement":
+ + + +
+ , + "container":
+ -
- , - "container":
- +
, "debug": [Function], "findAllByAltText": [Function], diff --git a/x-pack/plugins/threat_intelligence/public/modules/query_bar/components/filter_out/filter_out.tsx b/x-pack/plugins/threat_intelligence/public/modules/query_bar/components/filter_out/filter_out.tsx index dd7a644d43fe2..67f28a66b486e 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/query_bar/components/filter_out/filter_out.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/query_bar/components/filter_out/filter_out.tsx @@ -7,13 +7,12 @@ import React, { useCallback, VFC } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiButtonEmpty, EuiButtonIcon, EuiContextMenuItem } from '@elastic/eui'; +import { EuiButtonEmpty, EuiButtonIcon, EuiContextMenuItem, EuiToolTip } from '@elastic/eui'; import { Filter } from '@kbn/es-query'; import { ComponentType } from '../../../../../common/types/component_type'; import { useIndicatorsFiltersContext } from '../../../indicators/hooks/use_indicators_filters_context'; -import { getIndicatorFieldAndValue } from '../../../indicators/lib/field_value'; +import { fieldAndValueValid, getIndicatorFieldAndValue } from '../../../indicators/lib/field_value'; import { FilterOut as FilterOutConst, updateFiltersArray } from '../../lib/filter'; -import { EMPTY_VALUE } from '../../../../../common/constants'; import { Indicator } from '../../../../../common/types/indicator'; import { useStyles } from './styles'; @@ -66,16 +65,18 @@ export const FilterOut: VFC = ({ data, field, type, as: Componen filterManager.setFilters(newFilters); }, [filterManager, key, value]); - if (!value || value === EMPTY_VALUE || !key) { + if (!fieldAndValueValid(key, value)) { return <>; } if (type === ComponentType.EuiDataGrid) { return ( -
- {/* @ts-ignore*/} - -
+ +
+ {/* @ts-ignore*/} + +
+
); } @@ -94,14 +95,16 @@ export const FilterOut: VFC = ({ data, field, type, as: Componen } return ( - + + + ); }; diff --git a/x-pack/plugins/threat_intelligence/public/modules/timeline/components/add_to_timeline/__snapshots__/add_to_timeline.test.tsx.snap b/x-pack/plugins/threat_intelligence/public/modules/timeline/components/add_to_timeline/__snapshots__/add_to_timeline.test.tsx.snap index c56f657d1d905..c7373eb2f1645 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/timeline/components/add_to_timeline/__snapshots__/add_to_timeline.test.tsx.snap +++ b/x-pack/plugins/threat_intelligence/public/modules/timeline/components/add_to_timeline/__snapshots__/add_to_timeline.test.tsx.snap @@ -249,8 +249,27 @@ Object { "asFragment": [Function], "baseElement":
+ +
+ + Add To Timeline + +
+
+
+ , + "container":
+
-
- , - "container":
-
- - Add To Timeline - -
+
, "debug": [Function], "findAllByAltText": [Function], @@ -330,8 +338,27 @@ Object { "asFragment": [Function], "baseElement":
+ +
+ + Add To Timeline + +
+
+
+ , + "container":
+
-
- , - "container":
-
- - Add To Timeline - -
+
, "debug": [Function], "findAllByAltText": [Function], diff --git a/x-pack/plugins/threat_intelligence/public/modules/timeline/components/add_to_timeline/add_to_timeline.tsx b/x-pack/plugins/threat_intelligence/public/modules/timeline/components/add_to_timeline/add_to_timeline.tsx index 4ca644307eb55..2c0d2ec6c5f37 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/timeline/components/add_to_timeline/add_to_timeline.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/timeline/components/add_to_timeline/add_to_timeline.tsx @@ -9,11 +9,12 @@ import React, { useRef, VFC } from 'react'; import { DataProvider } from '@kbn/timelines-plugin/common'; import { AddToTimelineButtonProps } from '@kbn/timelines-plugin/public'; import { EuiButtonEmpty, EuiButtonIcon } from '@elastic/eui/src/components/button'; -import { EuiContextMenuItem } from '@elastic/eui'; +import { EuiContextMenuItem, EuiFlexItem, EuiToolTip } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; import { generateDataProvider } from '../../lib/data_provider'; import { ComponentType } from '../../../../../common/types/component_type'; -import { getIndicatorFieldAndValue } from '../../../indicators/lib/field_value'; -import { EMPTY_VALUE } from '../../../../../common/constants'; +import { fieldAndValueValid, getIndicatorFieldAndValue } from '../../../indicators/lib/field_value'; import { useKibana } from '../../../../hooks/use_kibana'; import { Indicator } from '../../../../../common/types/indicator'; import { useStyles } from './styles'; @@ -62,11 +63,11 @@ export const AddToTimeline: VFC = ({ data, field, type, as, const { key, value } = typeof data === 'string' ? { key: field, value: data } : getIndicatorFieldAndValue(data, field); - if (!value || value === EMPTY_VALUE || !key) { + if (!fieldAndValueValid(key, value)) { return <>; } - const dataProvider: DataProvider[] = [generateDataProvider(key, value)]; + const dataProvider: DataProvider[] = [generateDataProvider(key, value as string)]; const addToTimelineProps: AddToTimelineButtonProps = { dataProvider, @@ -90,7 +91,10 @@ export const AddToTimeline: VFC = ({ data, field, type, as, onClick={() => contextMenuRef.current?.click()} {...props} > - Add to Timeline + ); @@ -99,8 +103,12 @@ export const AddToTimeline: VFC = ({ data, field, type, as, if (as) addToTimelineProps.Component = as; return ( -
- {addToTimelineButton(addToTimelineProps)} -
+ + {addToTimelineButton(addToTimelineProps)} + ); }; diff --git a/x-pack/plugins/threat_intelligence/public/modules/timeline/components/add_to_timeline/styles.ts b/x-pack/plugins/threat_intelligence/public/modules/timeline/components/add_to_timeline/styles.ts index d4f13c215a7a7..8faebdf600953 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/timeline/components/add_to_timeline/styles.ts +++ b/x-pack/plugins/threat_intelligence/public/modules/timeline/components/add_to_timeline/styles.ts @@ -8,16 +8,11 @@ import { CSSObject } from '@emotion/react'; export const useStyles = () => { - const inlineFlex: CSSObject = { - display: 'inline-flex', - }; - const displayNone: CSSObject = { display: 'none', }; return { - inlineFlex, displayNone, }; }; diff --git a/x-pack/plugins/threat_intelligence/public/modules/timeline/components/investigate_in_timeline_button/investigate_in_timeline_button.tsx b/x-pack/plugins/threat_intelligence/public/modules/timeline/components/investigate_in_timeline_button/investigate_in_timeline_button.tsx index 4791b507700f8..479f175275625 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/timeline/components/investigate_in_timeline_button/investigate_in_timeline_button.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/timeline/components/investigate_in_timeline_button/investigate_in_timeline_button.tsx @@ -7,6 +7,7 @@ import React, { VFC } from 'react'; import { EuiButton } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; import { useInvestigateInTimeline } from '../../hooks/use_investigate_in_timeline'; import { Indicator } from '../../../../../common/types/indicator'; @@ -40,7 +41,10 @@ export const InvestigateInTimelineButton: VFC return ( - Investigate in Timeline + ); }; diff --git a/x-pack/plugins/threat_intelligence/public/modules/timeline/components/investigate_in_timeline_button_icon/__snapshots__/investigate_in_timeline_button_icon.test.tsx.snap b/x-pack/plugins/threat_intelligence/public/modules/timeline/components/investigate_in_timeline_button_icon/__snapshots__/investigate_in_timeline_button_icon.test.tsx.snap index a17cb9d47bb57..263e893f3f8b6 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/timeline/components/investigate_in_timeline_button_icon/__snapshots__/investigate_in_timeline_button_icon.test.tsx.snap +++ b/x-pack/plugins/threat_intelligence/public/modules/timeline/components/investigate_in_timeline_button_icon/__snapshots__/investigate_in_timeline_button_icon.test.tsx.snap @@ -5,8 +5,8 @@ Object { "asFragment": [Function], "baseElement":
-
-
+
, "container":
-
-
+
, "debug": [Function], "findAllByAltText": [Function], diff --git a/x-pack/plugins/threat_intelligence/public/modules/timeline/components/investigate_in_timeline_button_icon/investigate_in_timeline_button_icon.tsx b/x-pack/plugins/threat_intelligence/public/modules/timeline/components/investigate_in_timeline_button_icon/investigate_in_timeline_button_icon.tsx index 3585d0d2e62e6..888f420a3cac7 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/timeline/components/investigate_in_timeline_button_icon/investigate_in_timeline_button_icon.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/timeline/components/investigate_in_timeline_button_icon/investigate_in_timeline_button_icon.tsx @@ -6,11 +6,17 @@ */ import React, { VFC } from 'react'; -import { EuiButtonIcon } from '@elastic/eui'; +import { EuiButtonIcon, EuiToolTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { useInvestigateInTimeline } from '../../hooks/use_investigate_in_timeline'; import { Indicator } from '../../../../../common/types/indicator'; -import { useStyles } from './styles'; + +const BUTTON_LABEL: string = i18n.translate( + 'xpack.threatIntelligence.investigateInTimelineButtonIcon', + { + defaultMessage: 'Investigate in Timeline', + } +); export interface InvestigateInTimelineButtonIconProps { /** @@ -34,8 +40,6 @@ export const InvestigateInTimelineButtonIcon: VFC { - const styles = useStyles(); - const { onClick } = useInvestigateInTimeline({ indicator: data }); if (!onClick) { @@ -43,14 +47,9 @@ export const InvestigateInTimelineButtonIcon: VFC + - + ); }; diff --git a/x-pack/plugins/threat_intelligence/public/modules/timeline/components/investigate_in_timeline_button_icon/styles.ts b/x-pack/plugins/threat_intelligence/public/modules/timeline/components/investigate_in_timeline_button_icon/styles.ts deleted file mode 100644 index cc1b166edbc76..0000000000000 --- a/x-pack/plugins/threat_intelligence/public/modules/timeline/components/investigate_in_timeline_button_icon/styles.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * 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 { CSSObject } from '@emotion/react'; - -export const useStyles = () => { - const inlineFlex: CSSObject = { - display: 'inline-flex', - }; - - return { - inlineFlex, - }; -}; diff --git a/x-pack/plugins/threat_intelligence/public/modules/timeline/hooks/use_investigate_in_timeline.ts b/x-pack/plugins/threat_intelligence/public/modules/timeline/hooks/use_investigate_in_timeline.ts index 095960fbe484f..904a0afc4fd93 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/timeline/hooks/use_investigate_in_timeline.ts +++ b/x-pack/plugins/threat_intelligence/public/modules/timeline/hooks/use_investigate_in_timeline.ts @@ -10,9 +10,8 @@ import moment from 'moment'; import { DataProvider } from '@kbn/timelines-plugin/common'; import { generateDataProvider } from '../lib/data_provider'; import { SecuritySolutionContext } from '../../../containers/security_solution_context'; -import { getIndicatorFieldAndValue } from '../../indicators/lib/field_value'; +import { fieldAndValueValid, getIndicatorFieldAndValue } from '../../indicators/lib/field_value'; import { unwrapValue } from '../../indicators/lib/unwrap_value'; -import { EMPTY_VALUE } from '../../../../common/constants'; import { Indicator, IndicatorFieldEventEnrichmentMap, @@ -41,13 +40,12 @@ export const useInvestigateInTimeline = ({ const securitySolutionContext = useContext(SecuritySolutionContext); const { key, value } = getIndicatorFieldAndValue(indicator, RawIndicatorFieldId.Name); - - if (!value || value === EMPTY_VALUE || !key) { + if (!fieldAndValueValid(key, value)) { return {} as unknown as UseInvestigateInTimelineValue; } const dataProviders: DataProvider[] = [...IndicatorFieldEventEnrichmentMap[key], key].map( - (e: string) => generateDataProvider(e, value) + (e: string) => generateDataProvider(e, value as string) ); const to = unwrapValue(indicator, RawIndicatorFieldId.TimeStamp) as string;