diff --git a/packages/kbn-babel-preset/styled_components_files.js b/packages/kbn-babel-preset/styled_components_files.js index 6533573807d49..eb105084f426c 100644 --- a/packages/kbn-babel-preset/styled_components_files.js +++ b/packages/kbn-babel-preset/styled_components_files.js @@ -199,7 +199,6 @@ module.exports = { /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]common[\/\\]components[\/\\]charts[\/\\]chart_place_holder.tsx/, /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]common[\/\\]components[\/\\]charts[\/\\]common.tsx/, /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]common[\/\\]components[\/\\]charts[\/\\]donutchart.tsx/, - /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]common[\/\\]components[\/\\]charts[\/\\]donutchart_empty.tsx/, /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]common[\/\\]components[\/\\]charts[\/\\]draggable_legend.tsx/, /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]common[\/\\]components[\/\\]charts[\/\\]draggable_legend_item.tsx/, /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]common[\/\\]components[\/\\]charts[\/\\]legend_item.tsx/, diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/charts/barchart.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/common/components/charts/barchart.test.tsx index 7a5eb94d56249..ed94c2ce8933d 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/charts/barchart.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/charts/barchart.test.tsx @@ -353,8 +353,6 @@ describe.each(chartDataSets)('BarChart with stackByField', () => { }, ]; - const expectedColors = ['#1EA593', '#2B70F7', '#CE0060']; - const stackByField = 'process.name'; beforeAll(() => { @@ -369,12 +367,6 @@ describe.each(chartDataSets)('BarChart with stackByField', () => { expect(wrapper.find('[data-test-subj="draggable-legend"]').exists()).toBe(true); }); - expectedColors.forEach((color, i) => { - test(`it renders the expected legend color ${color} for legend item ${i}`, () => { - expect(wrapper.find(`div [color="${color}"]`).exists()).toBe(true); - }); - }); - data.forEach((datum) => { test(`it renders the expected draggable legend text for datum ${datum.key}`, () => { const dataProviderId = `draggableId.content.draggable-legend-item-uuid_v4()-${escapeDataProviderId( diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/charts/barchart.tsx b/x-pack/solutions/security/plugins/security_solution/public/common/components/charts/barchart.tsx index 9ccfd5124a635..526261d13bca6 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/charts/barchart.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/charts/barchart.tsx @@ -18,7 +18,6 @@ import deepEqual from 'fast-deep-equal'; import { escapeDataProviderId } from '../drag_and_drop/helpers'; import { useTimeZone } from '../../lib/kibana'; -import { defaultLegendColors } from '../matrix_histogram/utils'; import { useThrottledResizeObserver } from '../utils'; import { hasValueToDisplay } from '../../utils/validators'; import { EMPTY_VALUE_LABEL } from './translation'; @@ -192,8 +191,8 @@ export const BarChartComponent: React.FC = ({ const legendItems: LegendItem[] = useMemo( () => barChart != null && stackByField != null - ? barChart.map((d, i) => ({ - color: d.color ?? (i < defaultLegendColors.length ? defaultLegendColors[i] : undefined), + ? barChart.map((d) => ({ + color: d.color, dataProviderId: escapeDataProviderId( `draggable-legend-item-${uuidv4()}-${stackByField}-${d.key}` ), diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/charts/donutchart_empty.tsx b/x-pack/solutions/security/plugins/security_solution/public/common/components/charts/donutchart_empty.tsx index e59a685133ba5..a24c487d7d924 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/charts/donutchart_empty.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/charts/donutchart_empty.tsx @@ -4,42 +4,54 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import type { EuiThemeComputed } from '@elastic/eui'; +import { useEuiTheme } from '@elastic/eui'; +import { css } from '@emotion/react'; import React from 'react'; -import styled from 'styled-components'; -import { useEuiBackgroundColor } from '@elastic/eui'; interface DonutChartEmptyProps { size?: number; donutWidth?: number; } +/* + ** @deprecated use getEmptyDonutColor instead + */ export const emptyDonutColor = '#FAFBFD'; -const BigRing = styled.div` - border-radius: 50%; - ${({ size }) => - `height: ${size}px; - width: ${size}px; - background-color: ${emptyDonutColor}; - text-align: center; - line-height: ${size}px;`} -`; - -const SmallRing = styled.div` - border-radius: 50%; - ${({ size }) => ` - height: ${size}px; - width: ${size}px; - background-color: ${useEuiBackgroundColor('plain')}; - display: inline-block; - vertical-align: middle;`} -`; +export const getEmptyDonutColor = (euiTheme: EuiThemeComputed) => euiTheme.colors.textSubdued; -const EmptyDonutChartComponent: React.FC = ({ size = 90, donutWidth = 20 }) => - size - donutWidth > 0 ? ( - - - +const EmptyDonutChartComponent: React.FC = ({ + size = 90, + donutWidth = 20, +}) => { + const { euiTheme } = useEuiTheme(); + const middleSize = size - donutWidth; + return size - donutWidth > 0 ? ( +
+
+
) : null; +}; export const DonutChartEmpty = React.memo(EmptyDonutChartComponent); diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/matrix_histogram/utils.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/matrix_histogram/utils.ts deleted file mode 100644 index 7c5f01d26ebdb..0000000000000 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/matrix_histogram/utils.ts +++ /dev/null @@ -1,23 +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. - */ - -export const DEFAULT_CHART_HEIGHT = 174; -export const DEFAULT_Y_TICK_FORMATTER = (value: string | number): string => value.toLocaleString(); - -export const defaultLegendColors = [ - '#1EA593', - '#2B70F7', - '#CE0060', - '#38007E', - '#FCA5D3', - '#F37020', - '#E49E29', - '#B0916F', - '#7B000B', - '#34130C', - '#GGGGGG', -]; diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/__snapshots__/authentication.test.ts.snap b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/__snapshots__/authentication.test.ts.snap index 15ef132d3e3d5..4c5601ef3bdf7 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/__snapshots__/authentication.test.ts.snap +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/__snapshots__/authentication.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`authenticationLensAttributes should render 1`] = ` +exports[`getAuthenticationLensAttributes should render 1`] = ` Object { "description": "", "references": Array [ @@ -228,7 +228,7 @@ Object { "xAccessor": "b41a2958-650b-470a-84c4-c6fd8f0c6d37", "yConfig": Array [ Object { - "color": "#54b399", + "color": "#54B399", "forAccessor": "5417777d-d9d9-4268-9cdc-eb29b873bd65", }, ], @@ -243,7 +243,7 @@ Object { "xAccessor": "cded27f7-8ef8-458c-8d9b-70db48ae340d", "yConfig": Array [ Object { - "color": "#da8b45", + "color": "#DA8B45", "forAccessor": "a3bf9dc1-c8d2-42d6-9e60-31892a4c509e", }, ], diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/__snapshots__/rule_preview.test.ts.snap b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/__snapshots__/rule_preview.test.ts.snap index 0139cc872035e..ce83bd5c12c33 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/__snapshots__/rule_preview.test.ts.snap +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/__snapshots__/rule_preview.test.ts.snap @@ -23,12 +23,12 @@ Object { "layers": Object { "mockLayerId": Object { "columnOrder": Array [ - "e92c8920-0449-4564-81f4-8945517817a4", - "eba07b4d-766d-49d7-8435-d40367d3d055", - "9c89324b-0c59-4403-9698-d989a09dc5a8", + "mockColumnTopValuesId", + "mockColumnTimestampId", + "mockColumnCountOfRecordsId", ], "columns": Object { - "9c89324b-0c59-4403-9698-d989a09dc5a8": Object { + "mockColumnCountOfRecordsId": Object { "dataType": "number", "isBucketed": false, "label": "Count of records", @@ -39,7 +39,20 @@ Object { "scale": "ratio", "sourceField": "___records___", }, - "e92c8920-0449-4564-81f4-8945517817a4": Object { + "mockColumnTimestampId": Object { + "dataType": "date", + "isBucketed": true, + "label": "@timestamp", + "operationType": "date_histogram", + "params": Object { + "dropPartials": false, + "includeEmptyRows": true, + "interval": "auto", + }, + "scale": "interval", + "sourceField": "@timestamp", + }, + "mockColumnTopValuesId": Object { "dataType": "string", "isBucketed": true, "label": "Top 10 values of event.category", @@ -51,7 +64,7 @@ Object { "includeIsRegex": false, "missingBucket": false, "orderBy": Object { - "columnId": "9c89324b-0c59-4403-9698-d989a09dc5a8", + "columnId": "mockColumnCountOfRecordsId", "type": "column", }, "orderDirection": "desc", @@ -64,19 +77,6 @@ Object { "scale": "ordinal", "sourceField": "event.category", }, - "eba07b4d-766d-49d7-8435-d40367d3d055": Object { - "dataType": "date", - "isBucketed": true, - "label": "@timestamp", - "operationType": "date_histogram", - "params": Object { - "dropPartials": false, - "includeEmptyRows": true, - "interval": "auto", - }, - "scale": "interval", - "sourceField": "@timestamp", - }, }, "incompleteColumns": Object {}, "sampling": 1, @@ -145,15 +145,15 @@ Object { "layers": Array [ Object { "accessors": Array [ - "9c89324b-0c59-4403-9698-d989a09dc5a8", + "mockColumnCountOfRecordsId", ], "layerId": "mockLayerId", "layerType": "data", "position": "top", "seriesType": "bar_stacked", "showGridlines": false, - "splitAccessor": "e92c8920-0449-4564-81f4-8945517817a4", - "xAccessor": "eba07b4d-766d-49d7-8435-d40367d3d055", + "splitAccessor": "mockColumnTopValuesId", + "xAccessor": "mockColumnTimestampId", }, ], "legend": Object { diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/alerts_by_status_donut.test.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/alerts_by_status_donut.test.ts index ee6c7117093fa..ffd8a215c330d 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/alerts_by_status_donut.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/alerts_by_status_donut.test.ts @@ -13,7 +13,11 @@ import { useLensAttributes } from '../../../use_lens_attributes'; import { getAlertsByStatusAttributes } from './alerts_by_status_donut'; jest.mock('uuid', () => ({ - v4: jest.fn().mockReturnValue('b9b43606-7ff7-46ae-a47c-85bed80fab9a'), + v4: jest + .fn() + .mockReturnValueOnce('b9b43606-7ff7-46ae-a47c-85bed80fab9a') + .mockReturnValueOnce('a9b43606-7ff7-46ae-a47c-85bed80fab9a') + .mockReturnValueOnce('21cc4a49-3780-4b1a-be28-f02fa5303d24'), })); jest.mock('../../../../../../sourcerer/containers', () => ({ diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/alerts_by_status_donut.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/alerts_by_status_donut.ts index 33bc6827fa020..ca456292a0797 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/alerts_by_status_donut.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/alerts_by_status_donut.ts @@ -7,11 +7,13 @@ import { v4 as uuidv4 } from 'uuid'; import type { GetLensAttributes } from '../../../types'; const layerId = uuidv4(); +const columnSeverity = uuidv4(); +const columnRecord = uuidv4(); -export const getAlertsByStatusAttributes: GetLensAttributes = ( +export const getAlertsByStatusAttributes: GetLensAttributes = ({ stackByField = 'kibana.alert.workflow_status', - extraOptions -) => { + extraOptions, +}) => { return { title: 'Alerts', description: '', @@ -22,8 +24,8 @@ export const getAlertsByStatusAttributes: GetLensAttributes = ( layers: [ { layerId, - primaryGroups: ['a9b43606-7ff7-46ae-a47c-85bed80fab9a'], - metrics: ['21cc4a49-3780-4b1a-be28-f02fa5303d24'], + primaryGroups: [columnSeverity], + metrics: [columnRecord], numberDisplay: 'value', categoryDisplay: 'hide', legendDisplay: 'hide', @@ -69,7 +71,7 @@ export const getAlertsByStatusAttributes: GetLensAttributes = ( layers: { [layerId]: { columns: { - 'a9b43606-7ff7-46ae-a47c-85bed80fab9a': { + [columnSeverity]: { label: 'Filters', dataType: 'string', operationType: 'filters', @@ -108,7 +110,7 @@ export const getAlertsByStatusAttributes: GetLensAttributes = ( ], }, }, - '21cc4a49-3780-4b1a-be28-f02fa5303d24': { + [columnRecord]: { label: 'Count of records', dataType: 'number', operationType: 'count', @@ -124,10 +126,7 @@ export const getAlertsByStatusAttributes: GetLensAttributes = ( }, }, }, - columnOrder: [ - 'a9b43606-7ff7-46ae-a47c-85bed80fab9a', - '21cc4a49-3780-4b1a-be28-f02fa5303d24', - ], + columnOrder: [columnSeverity, columnRecord], sampling: 1, incompleteColumns: {}, }, diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/alerts_histogram.test.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/alerts_histogram.test.ts index e853ba80d01aa..fd6699ccbc599 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/alerts_histogram.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/alerts_histogram.test.ts @@ -13,7 +13,12 @@ import { useLensAttributes } from '../../../use_lens_attributes'; import { getAlertsHistogramLensAttributes } from './alerts_histogram'; jest.mock('uuid', () => ({ - v4: jest.fn().mockReturnValue('0039eb0c-9a1a-4687-ae54-0f4e239bec75'), + v4: jest + .fn() + .mockReturnValueOnce('0039eb0c-9a1a-4687-ae54-0f4e239bec75') + .mockReturnValueOnce('e09e0380-0740-4105-becc-0a4ca12e3944') + .mockReturnValueOnce('34919782-4546-43a5-b668-06ac934d3acd') + .mockReturnValueOnce('aac9d7d0-13a3-480a-892b-08207a787926'), })); jest.mock('../../../../../../sourcerer/containers', () => ({ diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/alerts_histogram.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/alerts_histogram.ts index a37ed21fd29ab..e0469a55bf565 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/alerts_histogram.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/alerts_histogram.ts @@ -7,11 +7,14 @@ import { v4 as uuidv4 } from 'uuid'; import type { GetLensAttributes } from '../../../types'; const layerId = uuidv4(); +const columnCountOfRecords = uuidv4(); +const columnTopValues = uuidv4(); +const columnTimestamp = uuidv4(); -export const getAlertsHistogramLensAttributes: GetLensAttributes = ( +export const getAlertsHistogramLensAttributes: GetLensAttributes = ({ stackByField = 'kibana.alert.rule.name', - extraOptions -) => { + extraOptions, +}) => { return { title: 'Alerts', description: '', @@ -30,13 +33,13 @@ export const getAlertsHistogramLensAttributes: GetLensAttributes = ( layers: [ { layerId, - accessors: ['e09e0380-0740-4105-becc-0a4ca12e3944'], + accessors: [columnCountOfRecords], position: 'top', seriesType: 'bar_stacked', showGridlines: false, layerType: 'data', - xAccessor: 'aac9d7d0-13a3-480a-892b-08207a787926', - splitAccessor: '34919782-4546-43a5-b668-06ac934d3acd', + xAccessor: columnTimestamp, + splitAccessor: columnTopValues, }, ], yRightExtent: { @@ -61,7 +64,7 @@ export const getAlertsHistogramLensAttributes: GetLensAttributes = ( layers: { [layerId]: { columns: { - 'aac9d7d0-13a3-480a-892b-08207a787926': { + [columnTimestamp]: { label: '@timestamp', dataType: 'date', operationType: 'date_histogram', @@ -73,7 +76,7 @@ export const getAlertsHistogramLensAttributes: GetLensAttributes = ( includeEmptyRows: true, }, }, - 'e09e0380-0740-4105-becc-0a4ca12e3944': { + [columnCountOfRecords]: { label: 'Count of records', dataType: 'number', operationType: 'count', @@ -82,7 +85,7 @@ export const getAlertsHistogramLensAttributes: GetLensAttributes = ( sourceField: '___records___', params: { emptyAsNull: true }, }, - '34919782-4546-43a5-b668-06ac934d3acd': { + [columnTopValues]: { label: `Top values of ${stackByField}`, dataType: 'string', operationType: 'terms', @@ -93,7 +96,7 @@ export const getAlertsHistogramLensAttributes: GetLensAttributes = ( size: 1000, orderBy: { type: 'column', - columnId: 'e09e0380-0740-4105-becc-0a4ca12e3944', + columnId: columnCountOfRecords, }, orderDirection: 'desc', otherBucket: true, @@ -105,11 +108,7 @@ export const getAlertsHistogramLensAttributes: GetLensAttributes = ( }, }, }, - columnOrder: [ - '34919782-4546-43a5-b668-06ac934d3acd', - 'aac9d7d0-13a3-480a-892b-08207a787926', - 'e09e0380-0740-4105-becc-0a4ca12e3944', - ], + columnOrder: [columnTopValues, columnTimestamp, columnCountOfRecords], incompleteColumns: {}, }, }, diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/alerts_table.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/alerts_table.ts index 9358bcc5db810..a1efd1674cadf 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/alerts_table.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/alerts_table.ts @@ -62,10 +62,10 @@ const getTopValuesOfBreakdownFieldColumnSettings = ( }, }); -export const getAlertsTableLensAttributes: GetLensAttributes = ( +export const getAlertsTableLensAttributes: GetLensAttributes = ({ stackByField = 'kibana.alert.rule.name', - extraOptions -) => { + extraOptions, +}) => { const breakdownFieldProvided = !isEmpty(extraOptions?.breakdownField); const countField = extraOptions?.breakdownField && breakdownFieldProvided diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/rule_preview.test.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/rule_preview.test.ts index 0d0eae638afeb..8164464a97731 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/rule_preview.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/rule_preview.test.ts @@ -15,7 +15,13 @@ const mockInternalReferenceId = 'mockInternalReferenceId'; const mockRuleId = 'mockRuleId'; jest.mock('uuid', () => ({ - v4: jest.fn().mockReturnValueOnce('mockLayerId').mockReturnValueOnce('mockInternalReferenceId'), + v4: jest + .fn() + .mockReturnValueOnce('mockLayerId') + .mockReturnValueOnce('mockInternalReferenceId') + .mockReturnValueOnce('mockColumnCountOfRecordsId') + .mockReturnValueOnce('mockColumnTimestampId') + .mockReturnValueOnce('mockColumnTopValuesId'), })); jest.mock('../../../../../../sourcerer/containers', () => ({ diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/rule_preview.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/rule_preview.ts index 9ec679629739a..8fbd5a19751e3 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/rule_preview.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/alerts/rule_preview.ts @@ -9,11 +9,14 @@ import type { GetLensAttributes } from '../../../types'; const layerId = uuidv4(); const internalReferenceId = uuidv4(); +const columnCountOfRecords = uuidv4(); +const columnTimestamp = uuidv4(); +const columnTopValues = uuidv4(); -export const getRulePreviewLensAttributes: GetLensAttributes = ( +export const getRulePreviewLensAttributes: GetLensAttributes = ({ stackByField = 'event.category', - extraOptions -) => { + extraOptions, +}) => { return { title: 'Rule preview', description: '', @@ -31,13 +34,13 @@ export const getRulePreviewLensAttributes: GetLensAttributes = ( layers: [ { layerId, - accessors: ['9c89324b-0c59-4403-9698-d989a09dc5a8'], + accessors: [columnCountOfRecords], position: 'top', seriesType: 'bar_stacked', showGridlines: false, layerType: 'data', - xAccessor: 'eba07b4d-766d-49d7-8435-d40367d3d055', - splitAccessor: 'e92c8920-0449-4564-81f4-8945517817a4', + xAccessor: columnTimestamp, + splitAccessor: columnTopValues, }, ], yTitle: '', @@ -77,7 +80,7 @@ export const getRulePreviewLensAttributes: GetLensAttributes = ( layers: { [layerId]: { columns: { - '9c89324b-0c59-4403-9698-d989a09dc5a8': { + [columnCountOfRecords]: { label: 'Count of records', dataType: 'number', operationType: 'count', @@ -88,7 +91,7 @@ export const getRulePreviewLensAttributes: GetLensAttributes = ( emptyAsNull: true, }, }, - 'eba07b4d-766d-49d7-8435-d40367d3d055': { + [columnTimestamp]: { label: '@timestamp', dataType: 'date', operationType: 'date_histogram', @@ -101,7 +104,7 @@ export const getRulePreviewLensAttributes: GetLensAttributes = ( dropPartials: false, }, }, - 'e92c8920-0449-4564-81f4-8945517817a4': { + [columnTopValues]: { label: `Top 10 values of ${stackByField}`, dataType: 'string', operationType: 'terms', @@ -112,7 +115,7 @@ export const getRulePreviewLensAttributes: GetLensAttributes = ( size: 10, orderBy: { type: 'column', - columnId: '9c89324b-0c59-4403-9698-d989a09dc5a8', + columnId: columnCountOfRecords, }, orderDirection: 'desc', otherBucket: true, @@ -127,11 +130,7 @@ export const getRulePreviewLensAttributes: GetLensAttributes = ( }, }, }, - columnOrder: [ - 'e92c8920-0449-4564-81f4-8945517817a4', - 'eba07b4d-766d-49d7-8435-d40367d3d055', - '9c89324b-0c59-4403-9698-d989a09dc5a8', - ], + columnOrder: [columnTopValues, columnTimestamp, columnCountOfRecords], sampling: 1, incompleteColumns: {}, }, diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/authentication.test.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/authentication.test.ts index 734390f6040b8..65438f0204dbd 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/authentication.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/authentication.test.ts @@ -10,7 +10,18 @@ import { wrapper } from '../../mocks'; import { useLensAttributes } from '../../use_lens_attributes'; -import { authenticationLensAttributes } from './authentication'; +import { getAuthenticationLensAttributes } from './authentication'; + +jest.mock('uuid', () => ({ + v4: jest + .fn() + .mockReturnValueOnce('3fd0c5d5-f762-4a27-8c56-14eee0223e13') + .mockReturnValueOnce('bef502be-e5ff-442f-9e3e-229f86ca2afa') + .mockReturnValueOnce('cded27f7-8ef8-458c-8d9b-70db48ae340d') + .mockReturnValueOnce('a3bf9dc1-c8d2-42d6-9e60-31892a4c509e') + .mockReturnValueOnce('b41a2958-650b-470a-84c4-c6fd8f0c6d37') + .mockReturnValueOnce('5417777d-d9d9-4268-9cdc-eb29b873bd65'), +})); jest.mock('../../../../../sourcerer/containers', () => ({ useSourcererDataView: jest.fn().mockReturnValue({ @@ -31,12 +42,12 @@ jest.mock('../../../../utils/route/use_route_spy', () => ({ ]), })); -describe('authenticationLensAttributes', () => { +describe('getAuthenticationLensAttributes', () => { it('should render', () => { const { result } = renderHook( () => useLensAttributes({ - lensAttributes: authenticationLensAttributes, + getLensAttributes: getAuthenticationLensAttributes, stackByField: 'event.dataset', }), { wrapper } diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/authentication.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/authentication.ts index 013a05c840fbf..cc07c8dfb1428 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/authentication.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/authentication.ts @@ -4,193 +4,195 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - +import { v4 as uuidv4 } from 'uuid'; import { AUTHENTICATION_FAILURE_CHART_LABEL, AUTHENTICATION_SUCCESS_CHART_LABEL, } from '../../translations'; -import type { LensAttributes } from '../../types'; +import type { LensAttributes, GetLensAttributes } from '../../types'; -export const authenticationLensAttributes: LensAttributes = { - title: 'Authentication', - description: '', - visualizationType: 'lnsXY', - state: { - visualization: { - title: 'Empty XY chart', - legend: { - isVisible: true, - position: 'right', - legendSize: 'xlarge', - }, - valueLabels: 'hide', - preferredSeriesType: 'bar_stacked', - layers: [ - { - layerId: '3fd0c5d5-f762-4a27-8c56-14eee0223e13', - accessors: ['5417777d-d9d9-4268-9cdc-eb29b873bd65'], - position: 'top', - seriesType: 'bar_stacked', - showGridlines: false, - layerType: 'data', - xAccessor: 'b41a2958-650b-470a-84c4-c6fd8f0c6d37', - yConfig: [ - { - forAccessor: '5417777d-d9d9-4268-9cdc-eb29b873bd65', - color: '#54b399', - }, - ], - }, - { - layerId: 'bef502be-e5ff-442f-9e3e-229f86ca2afa', - seriesType: 'bar_stacked', - accessors: ['a3bf9dc1-c8d2-42d6-9e60-31892a4c509e'], - layerType: 'data', - xAccessor: 'cded27f7-8ef8-458c-8d9b-70db48ae340d', - yConfig: [ - { - forAccessor: 'a3bf9dc1-c8d2-42d6-9e60-31892a4c509e', - color: '#da8b45', - }, - ], - }, - ], - yRightExtent: { - mode: 'full', - }, - yLeftExtent: { - mode: 'full', - }, - axisTitlesVisibilitySettings: { - x: false, - yLeft: false, - yRight: true, - }, - }, - query: { - query: '', - language: 'kuery', - }, - filters: [ - { - meta: { - index: '6f4dbdc7-35b6-4e20-ac53-1272167e3919', - type: 'custom', - disabled: false, - negate: false, - alias: null, - key: 'query', - value: '{"bool":{"must":[{"term":{"event.category":"authentication"}}]}}', - }, - $state: { - store: 'appState', +const layerAuthenticationSuccess = uuidv4(); +const layerAuthenticationFailure = uuidv4(); +const columnTimestampFailure = uuidv4(); +const columnEventOutcomeFailure = uuidv4(); +const columnTimestampSuccess = uuidv4(); +const columnEventOutcomeSuccess = uuidv4(); + +export const getAuthenticationLensAttributes: GetLensAttributes = ({ euiTheme }) => + ({ + title: 'Authentication', + description: '', + visualizationType: 'lnsXY', + state: { + visualization: { + title: 'Empty XY chart', + legend: { + isVisible: true, + position: 'right', + legendSize: 'xlarge', }, - query: { - bool: { - must: [ + valueLabels: 'hide', + preferredSeriesType: 'bar_stacked', + layers: [ + { + layerId: layerAuthenticationSuccess, + accessors: [columnEventOutcomeSuccess], + position: 'top', + seriesType: 'bar_stacked', + showGridlines: false, + layerType: 'data', + xAccessor: columnTimestampSuccess, + yConfig: [ { - term: { - 'event.category': 'authentication', - }, + forAccessor: columnEventOutcomeSuccess, + color: euiTheme.colors.vis.euiColorVis0, }, ], }, + { + layerId: layerAuthenticationFailure, + seriesType: 'bar_stacked', + accessors: [columnEventOutcomeFailure], + layerType: 'data', + xAccessor: columnTimestampFailure, + yConfig: [ + { + forAccessor: columnEventOutcomeFailure, + color: euiTheme.colors.vis.euiColorVis7, + }, + ], + }, + ], + yRightExtent: { + mode: 'full', + }, + yLeftExtent: { + mode: 'full', + }, + axisTitlesVisibilitySettings: { + x: false, + yLeft: false, + yRight: true, }, }, - ], - datasourceStates: { - formBased: { - layers: { - '3fd0c5d5-f762-4a27-8c56-14eee0223e13': { - columns: { - 'b41a2958-650b-470a-84c4-c6fd8f0c6d37': { - label: '@timestamp', - dataType: 'date', - operationType: 'date_histogram', - sourceField: '@timestamp', - isBucketed: true, - scale: 'interval', - params: { - interval: 'auto', - }, - }, - '5417777d-d9d9-4268-9cdc-eb29b873bd65': { - label: AUTHENTICATION_SUCCESS_CHART_LABEL, - dataType: 'number', - operationType: 'count', - isBucketed: false, - scale: 'ratio', - sourceField: '___records___', - filter: { - query: 'event.outcome : "success"', - language: 'kuery', + query: { + query: '', + language: 'kuery', + }, + filters: [ + { + meta: { + index: '6f4dbdc7-35b6-4e20-ac53-1272167e3919', + type: 'custom', + disabled: false, + negate: false, + alias: null, + key: 'query', + value: '{"bool":{"must":[{"term":{"event.category":"authentication"}}]}}', + }, + $state: { + store: 'appState', + }, + query: { + bool: { + must: [ + { + term: { + 'event.category': 'authentication', + }, }, - customLabel: true, - }, + ], }, - columnOrder: [ - 'b41a2958-650b-470a-84c4-c6fd8f0c6d37', - '5417777d-d9d9-4268-9cdc-eb29b873bd65', - ], - incompleteColumns: {}, }, - 'bef502be-e5ff-442f-9e3e-229f86ca2afa': { - columns: { - 'cded27f7-8ef8-458c-8d9b-70db48ae340d': { - label: '@timestamp', - dataType: 'date', - operationType: 'date_histogram', - sourceField: '@timestamp', - isBucketed: true, - scale: 'interval', - params: { - interval: 'auto', + }, + ], + datasourceStates: { + formBased: { + layers: { + [layerAuthenticationSuccess]: { + columns: { + [columnTimestampSuccess]: { + label: '@timestamp', + dataType: 'date', + operationType: 'date_histogram', + sourceField: '@timestamp', + isBucketed: true, + scale: 'interval', + params: { + interval: 'auto', + }, + }, + [columnEventOutcomeSuccess]: { + label: AUTHENTICATION_SUCCESS_CHART_LABEL, + dataType: 'number', + operationType: 'count', + isBucketed: false, + scale: 'ratio', + sourceField: '___records___', + filter: { + query: 'event.outcome : "success"', + language: 'kuery', + }, + customLabel: true, }, }, - 'a3bf9dc1-c8d2-42d6-9e60-31892a4c509e': { - label: AUTHENTICATION_FAILURE_CHART_LABEL, - dataType: 'number', - operationType: 'count', - isBucketed: false, - scale: 'ratio', - sourceField: '___records___', - filter: { - query: 'event.outcome : "failure"', - language: 'kuery', + columnOrder: [columnTimestampSuccess, columnEventOutcomeSuccess], + incompleteColumns: {}, + }, + [layerAuthenticationFailure]: { + columns: { + [columnTimestampFailure]: { + label: '@timestamp', + dataType: 'date', + operationType: 'date_histogram', + sourceField: '@timestamp', + isBucketed: true, + scale: 'interval', + params: { + interval: 'auto', + }, + }, + [columnEventOutcomeFailure]: { + label: AUTHENTICATION_FAILURE_CHART_LABEL, + dataType: 'number', + operationType: 'count', + isBucketed: false, + scale: 'ratio', + sourceField: '___records___', + filter: { + query: 'event.outcome : "failure"', + language: 'kuery', + }, + customLabel: true, }, - customLabel: true, }, + columnOrder: [columnTimestampFailure, columnEventOutcomeFailure], + incompleteColumns: {}, }, - columnOrder: [ - 'cded27f7-8ef8-458c-8d9b-70db48ae340d', - 'a3bf9dc1-c8d2-42d6-9e60-31892a4c509e', - ], - incompleteColumns: {}, }, }, }, }, - }, - references: [ - { - type: 'index-pattern', - id: '{dataViewId}', - name: 'indexpattern-datasource-current-indexpattern', - }, - { - type: 'index-pattern', - id: '{dataViewId}', - name: 'indexpattern-datasource-layer-3fd0c5d5-f762-4a27-8c56-14eee0223e13', - }, - { - type: 'index-pattern', - id: '{dataViewId}', - name: 'indexpattern-datasource-layer-bef502be-e5ff-442f-9e3e-229f86ca2afa', - }, - { - type: 'index-pattern', - name: '6f4dbdc7-35b6-4e20-ac53-1272167e3919', - id: '{dataViewId}', - }, - ], -} as LensAttributes; + references: [ + { + type: 'index-pattern', + id: '{dataViewId}', + name: 'indexpattern-datasource-current-indexpattern', + }, + { + type: 'index-pattern', + id: '{dataViewId}', + name: `indexpattern-datasource-layer-${layerAuthenticationSuccess}`, + }, + { + type: 'index-pattern', + id: '{dataViewId}', + name: `indexpattern-datasource-layer-${layerAuthenticationFailure}`, + }, + { + type: 'index-pattern', + name: '6f4dbdc7-35b6-4e20-ac53-1272167e3919', + id: '{dataViewId}', + }, + ], + } as LensAttributes); diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/event.test.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/event.test.ts index be87445ba2618..1f2d248697405 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/event.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/event.test.ts @@ -14,7 +14,12 @@ import { useLensAttributes } from '../../use_lens_attributes'; import { getEventsHistogramLensAttributes, stackByFieldAccessorId } from './events'; jest.mock('uuid', () => ({ - v4: jest.fn().mockReturnValue('0039eb0c-9a1a-4687-ae54-0f4e239bec75'), + v4: jest + .fn() + .mockReturnValue('0039eb0c-9a1a-4687-ae54-0f4e239bec75') + .mockReturnValue('34919782-4546-43a5-b668-06ac934d3acd') + .mockReturnValue('aac9d7d0-13a3-480a-892b-08207a787926') + .mockReturnValue('e09e0380-0740-4105-becc-0a4ca12e3944'), })); jest.mock('../../../../../sourcerer/containers', () => ({ diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/events.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/events.ts index 174abce6baf62..e036289d99562 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/events.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/events.ts @@ -6,15 +6,18 @@ */ import { v4 as uuidv4 } from 'uuid'; import type { GetLensAttributes } from '../../types'; +import { COUNT } from '../../translations'; const layerId = uuidv4(); // Exported for testing purposes -export const stackByFieldAccessorId = '34919782-4546-43a5-b668-06ac934d3acd'; +export const stackByFieldAccessorId = uuidv4(); +export const columnTimestampId = uuidv4(); +export const columnCountOfRecordsId = uuidv4(); -export const getEventsHistogramLensAttributes: GetLensAttributes = ( +export const getEventsHistogramLensAttributes: GetLensAttributes = ({ stackByField, - extraOptions = {} -) => { + extraOptions = {}, +}) => { return { title: 'Events', description: '', @@ -27,18 +30,19 @@ export const getEventsHistogramLensAttributes: GetLensAttributes = ( position: 'right', legendSize: 'xlarge', legendStats: ['currentAndLastValue'], + showSingleSeries: true, }, valueLabels: 'hide', preferredSeriesType: 'bar_stacked', layers: [ { layerId, - accessors: ['e09e0380-0740-4105-becc-0a4ca12e3944'], + accessors: [columnCountOfRecordsId], position: 'top', seriesType: 'bar_stacked', showGridlines: false, layerType: 'data', - xAccessor: 'aac9d7d0-13a3-480a-892b-08207a787926', + xAccessor: columnTimestampId, splitAccessor: stackByField ? stackByFieldAccessorId : undefined, }, ], @@ -64,7 +68,7 @@ export const getEventsHistogramLensAttributes: GetLensAttributes = ( layers: { [layerId]: { columns: { - 'aac9d7d0-13a3-480a-892b-08207a787926': { + [columnTimestampId]: { label: '@timestamp', dataType: 'date', operationType: 'date_histogram', @@ -76,8 +80,8 @@ export const getEventsHistogramLensAttributes: GetLensAttributes = ( includeEmptyRows: true, }, }, - 'e09e0380-0740-4105-becc-0a4ca12e3944': { - label: 'Count of records', + [columnCountOfRecordsId]: { + label: COUNT, dataType: 'number', operationType: 'count', isBucketed: false, @@ -97,7 +101,7 @@ export const getEventsHistogramLensAttributes: GetLensAttributes = ( size: 10, orderBy: { type: 'column', - columnId: 'e09e0380-0740-4105-becc-0a4ca12e3944', + columnId: columnCountOfRecordsId, }, orderDirection: 'desc', otherBucket: true, @@ -111,8 +115,8 @@ export const getEventsHistogramLensAttributes: GetLensAttributes = ( }, columnOrder: [ ...(stackByField ? [stackByFieldAccessorId] : []), - 'aac9d7d0-13a3-480a-892b-08207a787926', - 'e09e0380-0740-4105-becc-0a4ca12e3944', + columnTimestampId, + columnCountOfRecordsId, ], incompleteColumns: {}, }, diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/external_alert.test.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/external_alert.test.ts index 62a9fe3bd108c..4da1c760c6e2b 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/external_alert.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/external_alert.test.ts @@ -12,6 +12,15 @@ import { useLensAttributes } from '../../use_lens_attributes'; import { getExternalAlertLensAttributes } from './external_alert'; +jest.mock('uuid', () => ({ + v4: jest + .fn() + .mockReturnValueOnce('a3c54471-615f-4ff9-9fda-69b5b2ea3eef') + .mockReturnValueOnce('37bdf546-3c11-4b08-8c5d-e37debc44f1d') + .mockReturnValueOnce('0a923af2-c880-4aa3-aa93-a0b9c2801f6d') + .mockReturnValueOnce('42334c6e-98d9-47a2-b4cb-a445abb44c93'), +})); + jest.mock('../../../../../sourcerer/containers', () => ({ useSourcererDataView: jest.fn().mockReturnValue({ selectedPatterns: ['auditbeat-mytest-*'], diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/external_alert.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/external_alert.ts index 35a9f124a2993..726f55486ae74 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/external_alert.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/external_alert.ts @@ -4,13 +4,19 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import { v4 as uuidv4 } from 'uuid'; import { COUNT, TOP_VALUE } from '../../translations'; import type { GetLensAttributes, LensAttributes } from '../../types'; -export const getExternalAlertLensAttributes: GetLensAttributes = ( - stackByField = 'event.module' -) => { +const layerId = uuidv4(); +const columnTimestamp = uuidv4(); +const columnCount = uuidv4(); +const columnTopValue = uuidv4(); + +export const getExternalAlertLensAttributes: GetLensAttributes = ({ + stackByField = 'event.module', +}) => { return { title: 'External alerts', description: '', @@ -28,14 +34,14 @@ export const getExternalAlertLensAttributes: GetLensAttributes = ( preferredSeriesType: 'bar_stacked', layers: [ { - layerId: 'a3c54471-615f-4ff9-9fda-69b5b2ea3eef', - accessors: ['0a923af2-c880-4aa3-aa93-a0b9c2801f6d'], + layerId, + accessors: [columnCount], position: 'top', seriesType: 'bar_stacked', showGridlines: false, layerType: 'data', - xAccessor: '37bdf546-3c11-4b08-8c5d-e37debc44f1d', - splitAccessor: '42334c6e-98d9-47a2-b4cb-a445abb44c93', + xAccessor: columnTimestamp, + splitAccessor: columnTopValue, }, ], yRightExtent: { @@ -80,9 +86,9 @@ export const getExternalAlertLensAttributes: GetLensAttributes = ( datasourceStates: { formBased: { layers: { - 'a3c54471-615f-4ff9-9fda-69b5b2ea3eef': { + [layerId]: { columns: { - '37bdf546-3c11-4b08-8c5d-e37debc44f1d': { + [columnTimestamp]: { label: '@timestamp', dataType: 'date', operationType: 'date_histogram', @@ -94,7 +100,7 @@ export const getExternalAlertLensAttributes: GetLensAttributes = ( includeEmptyRows: true, }, }, - '0a923af2-c880-4aa3-aa93-a0b9c2801f6d': { + [columnCount]: { label: COUNT, dataType: 'number', operationType: 'count', @@ -103,18 +109,18 @@ export const getExternalAlertLensAttributes: GetLensAttributes = ( sourceField: '___records___', params: { emptyAsNull: true }, }, - '42334c6e-98d9-47a2-b4cb-a445abb44c93': { - label: TOP_VALUE(`${stackByField}`), // could be event.category + [columnTopValue]: { + label: TOP_VALUE(`${stackByField}`), dataType: 'string', operationType: 'terms', scale: 'ordinal', - sourceField: `${stackByField}`, // could be event.category + sourceField: `${stackByField}`, isBucketed: true, params: { size: 10, orderBy: { type: 'column', - columnId: '0a923af2-c880-4aa3-aa93-a0b9c2801f6d', + columnId: columnCount, }, orderDirection: 'desc', otherBucket: true, @@ -125,11 +131,7 @@ export const getExternalAlertLensAttributes: GetLensAttributes = ( }, }, }, - columnOrder: [ - '42334c6e-98d9-47a2-b4cb-a445abb44c93', - '37bdf546-3c11-4b08-8c5d-e37debc44f1d', - '0a923af2-c880-4aa3-aa93-a0b9c2801f6d', - ], + columnOrder: [columnTopValue, columnTimestamp, columnCount], incompleteColumns: {}, }, }, @@ -145,7 +147,7 @@ export const getExternalAlertLensAttributes: GetLensAttributes = ( { type: 'index-pattern', id: '{dataViewId}', - name: 'indexpattern-datasource-layer-a3c54471-615f-4ff9-9fda-69b5b2ea3eef', + name: `indexpattern-datasource-layer-${layerId}`, }, { type: 'index-pattern', @@ -158,5 +160,5 @@ export const getExternalAlertLensAttributes: GetLensAttributes = ( id: '{dataViewId}', }, ], - } as LensAttributes; + } as unknown as LensAttributes; }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_host_area.test.ts.snap b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_host_area.test.ts.snap index 1d98d79a0ec2e..afbc567ad3e83 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_host_area.test.ts.snap +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_host_area.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`kpiHostAreaLensAttributes should render 1`] = ` +exports[`getKpiHostAreaLensAttributes should render 1`] = ` Object { "description": "", "references": Array [ diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_unique_ips_area.test.ts.snap b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_unique_ips_area.test.ts.snap index f10087899d289..a829f18fd216c 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_unique_ips_area.test.ts.snap +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_unique_ips_area.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`kpiUniqueIpsAreaLensAttributes should render 1`] = ` +exports[`getKpiUniqueIpsAreaLensAttributes should render 1`] = ` Object { "description": "", "references": Array [ @@ -55,20 +55,11 @@ Object { }, "ca05ecdb-0fa4-49a8-9305-b23d91012a46": Object { "columnOrder": Array [ - "f95e74e6-99dd-4b11-8faf-439b4d959df9", + "95e74e6-99dd-4b11-8faf-439b4d959df9", "e7052671-fb9e-481f-8df3-7724c98cfc6f", ], "columns": Object { - "e7052671-fb9e-481f-8df3-7724c98cfc6f": Object { - "customLabel": true, - "dataType": "number", - "isBucketed": false, - "label": "Dest.", - "operationType": "unique_count", - "scale": "ratio", - "sourceField": "destination.ip", - }, - "f95e74e6-99dd-4b11-8faf-439b4d959df9": Object { + "95e74e6-99dd-4b11-8faf-439b4d959df9": Object { "dataType": "date", "isBucketed": true, "label": "@timestamp", @@ -79,6 +70,15 @@ Object { "scale": "interval", "sourceField": "@timestamp", }, + "e7052671-fb9e-481f-8df3-7724c98cfc6f": Object { + "customLabel": true, + "dataType": "number", + "isBucketed": false, + "label": "Dest.", + "operationType": "unique_count", + "scale": "ratio", + "sourceField": "destination.ip", + }, }, "incompleteColumns": Object {}, }, @@ -199,7 +199,7 @@ Object { "xAccessor": "a0cb6400-f708-46c3-ad96-24788f12dae4", "yConfig": Array [ Object { - "color": "#d36186", + "color": "#CA8EAE", "forAccessor": "d9a6eb6b-8b78-439e-98e7-a718f8ffbebe", }, ], @@ -211,10 +211,10 @@ Object { "layerId": "ca05ecdb-0fa4-49a8-9305-b23d91012a46", "layerType": "data", "seriesType": "area", - "xAccessor": "f95e74e6-99dd-4b11-8faf-439b4d959df9", + "xAccessor": "95e74e6-99dd-4b11-8faf-439b4d959df9", "yConfig": Array [ Object { - "color": "#9170b8", + "color": "#D36086", "forAccessor": "e7052671-fb9e-481f-8df3-7724c98cfc6f", }, ], diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_unique_ips_bar.test.ts.snap b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_unique_ips_bar.test.ts.snap index 94b51748ade1c..a6e3277032138 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_unique_ips_bar.test.ts.snap +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_unique_ips_bar.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`kpiUniqueIpsBarLensAttributes should render 1`] = ` +exports[`getKpiUniqueIpsBarLensAttributes should render 1`] = ` Object { "description": "", "references": Array [ @@ -212,7 +212,7 @@ Object { "xAccessor": "f8bfa719-5c1c-4bf2-896e-c318d77fc08e", "yConfig": Array [ Object { - "color": "#d36186", + "color": "#CA8EAE", "forAccessor": "32f66676-f4e1-48fd-b7f8-d4de38318601", }, ], @@ -227,7 +227,7 @@ Object { "xAccessor": "c72aad6a-fc9c-43dc-9194-e13ca3ee8aff", "yConfig": Array [ Object { - "color": "#9170b8", + "color": "#D36086", "forAccessor": "b7e59b08-96e6-40d1-84fd-e97b977d1c47", }, ], diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_host_area.test.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_host_area.test.ts index cffcf9f91b4ea..d0732ce14129a 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_host_area.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_host_area.test.ts @@ -10,7 +10,7 @@ import { wrapper } from '../../mocks'; import { useLensAttributes } from '../../use_lens_attributes'; -import { kpiHostAreaLensAttributes } from './kpi_host_area'; +import { getKpiHostAreaLensAttributes } from './kpi_host_area'; jest.mock('../../../../../sourcerer/containers', () => ({ useSourcererDataView: jest.fn().mockReturnValue({ @@ -31,12 +31,12 @@ jest.mock('../../../../utils/route/use_route_spy', () => ({ ]), })); -describe('kpiHostAreaLensAttributes', () => { +describe('getKpiHostAreaLensAttributes', () => { it('should render', () => { const { result } = renderHook( () => useLensAttributes({ - lensAttributes: kpiHostAreaLensAttributes, + getLensAttributes: getKpiHostAreaLensAttributes, stackByField: 'event.dataset', }), { wrapper } diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_host_area.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_host_area.ts index 561d8896f1b53..053e8f3497caf 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_host_area.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_host_area.ts @@ -6,80 +6,84 @@ */ import { UNIQUE_COUNT } from '../../translations'; -import type { LensAttributes } from '../../types'; +import type { LensAttributes, GetLensAttributes } from '../../types'; -export const kpiHostAreaLensAttributes: LensAttributes = { - description: '', - state: { - datasourceStates: { - formBased: { - layers: { - '416b6fad-1923-4f6a-a2df-b223bb287e30': { - columnOrder: [ - '5eea817b-67b7-4268-8ecb-7688d1094721', - 'b00c65ea-32be-4163-bfc8-f795b1ef9d06', - ], - columns: { - '5eea817b-67b7-4268-8ecb-7688d1094721': { - dataType: 'date', - isBucketed: true, - label: '@timestamp', - operationType: 'date_histogram', - params: { interval: 'auto' }, - scale: 'interval', - sourceField: '@timestamp', - }, - 'b00c65ea-32be-4163-bfc8-f795b1ef9d06': { - customLabel: true, - dataType: 'number', - isBucketed: false, - label: UNIQUE_COUNT('host.name'), - operationType: 'unique_count', - scale: 'ratio', - sourceField: 'host.name', +const columnTimestamp = '5eea817b-67b7-4268-8ecb-7688d1094721'; +const columnHostName = 'b00c65ea-32be-4163-bfc8-f795b1ef9d06'; + +const layerHostName = '416b6fad-1923-4f6a-a2df-b223bb287e30'; + +export const getKpiHostAreaLensAttributes: GetLensAttributes = () => { + return { + description: '', + state: { + datasourceStates: { + formBased: { + layers: { + [layerHostName]: { + columnOrder: [columnTimestamp, columnHostName], + columns: { + [columnTimestamp]: { + dataType: 'date', + isBucketed: true, + label: '@timestamp', + operationType: 'date_histogram', + params: { interval: 'auto' }, + scale: 'interval', + sourceField: '@timestamp', + }, + [columnHostName]: { + customLabel: true, + dataType: 'number', + isBucketed: false, + label: UNIQUE_COUNT('host.name'), + operationType: 'unique_count', + scale: 'ratio', + sourceField: 'host.name', + }, }, + incompleteColumns: {}, }, - incompleteColumns: {}, }, }, }, + filters: [], + query: { language: 'kuery', query: '' }, + visualization: { + axisTitlesVisibilitySettings: { x: false, yLeft: false, yRight: false }, + fittingFunction: 'None', + gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true }, + labelsOrientation: { x: 0, yLeft: 0, yRight: 0 }, + layers: [ + { + accessors: [columnHostName], + layerId: layerHostName, + layerType: 'data', + seriesType: 'area', + xAccessor: columnTimestamp, + }, + ], + legend: { isVisible: false, position: 'right' }, + preferredSeriesType: 'area', + tickLabelsVisibilitySettings: { x: true, yLeft: true, yRight: true }, + valueLabels: 'hide', + yLeftExtent: { mode: 'full' }, + yRightExtent: { mode: 'full' }, + }, }, - filters: [], - query: { language: 'kuery', query: '' }, - visualization: { - axisTitlesVisibilitySettings: { x: false, yLeft: false, yRight: false }, - fittingFunction: 'None', - gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true }, - labelsOrientation: { x: 0, yLeft: 0, yRight: 0 }, - layers: [ - { - accessors: ['b00c65ea-32be-4163-bfc8-f795b1ef9d06'], - layerId: '416b6fad-1923-4f6a-a2df-b223bb287e30', - layerType: 'data', - seriesType: 'area', - xAccessor: '5eea817b-67b7-4268-8ecb-7688d1094721', - }, - ], - legend: { isVisible: false, position: 'right' }, - preferredSeriesType: 'area', - tickLabelsVisibilitySettings: { x: true, yLeft: true, yRight: true }, - valueLabels: 'hide', - yLeftExtent: { mode: 'full' }, - yRightExtent: { mode: 'full' }, - }, - }, - title: '[Host] Hosts - area', - visualizationType: 'lnsXY', - references: [ - { - id: '{dataViewId}', - name: 'indexpattern-datasource-current-indexpattern', - type: 'index-pattern', - }, - { - id: '{dataViewId}', - name: 'indexpattern-datasource-layer-416b6fad-1923-4f6a-a2df-b223bb287e30', - type: 'index-pattern', - }, - ], -} as LensAttributes; + title: '[Host] Hosts - area', + visualizationType: 'lnsXY', + references: [ + { + id: '{dataViewId}', + name: 'indexpattern-datasource-current-indexpattern', + type: 'index-pattern', + }, + { + id: '{dataViewId}', + name: `indexpattern-datasource-layer-${layerHostName}`, + type: 'index-pattern', + }, + ], + } as LensAttributes; +}; diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_area.test.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_area.test.ts index cb4260c2d630a..ce3eedb6359b9 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_area.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_area.test.ts @@ -10,7 +10,7 @@ import { wrapper } from '../../mocks'; import { useLensAttributes } from '../../use_lens_attributes'; -import { kpiUniqueIpsAreaLensAttributes } from './kpi_unique_ips_area'; +import { getKpiUniqueIpsAreaLensAttributes } from './kpi_unique_ips_area'; jest.mock('../../../../../sourcerer/containers', () => ({ useSourcererDataView: jest.fn().mockReturnValue({ @@ -31,12 +31,12 @@ jest.mock('../../../../utils/route/use_route_spy', () => ({ ]), })); -describe('kpiUniqueIpsAreaLensAttributes', () => { +describe('getKpiUniqueIpsAreaLensAttributes', () => { it('should render', () => { const { result } = renderHook( () => useLensAttributes({ - lensAttributes: kpiUniqueIpsAreaLensAttributes, + getLensAttributes: getKpiUniqueIpsAreaLensAttributes, stackByField: 'event.dataset', }), { wrapper } diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_area.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_area.ts index 79539f40390af..133f7a51a5e1b 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_area.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_area.ts @@ -6,124 +6,133 @@ */ import { DESTINATION_CHART_LABEL, SOURCE_CHART_LABEL } from '../../translations'; -import type { LensAttributes } from '../../types'; +import type { GetLensAttributes, LensAttributes } from '../../types'; -export const kpiUniqueIpsAreaLensAttributes: LensAttributes = { - description: '', - state: { - datasourceStates: { - formBased: { - layers: { - '8be0156b-d423-4a39-adf1-f54d4c9f2e69': { - columnOrder: [ - 'a0cb6400-f708-46c3-ad96-24788f12dae4', - 'd9a6eb6b-8b78-439e-98e7-a718f8ffbebe', - ], - columns: { - 'a0cb6400-f708-46c3-ad96-24788f12dae4': { - dataType: 'date', - isBucketed: true, - label: '@timestamp', - operationType: 'date_histogram', - params: { interval: 'auto' }, - scale: 'interval', - sourceField: '@timestamp', - }, - 'd9a6eb6b-8b78-439e-98e7-a718f8ffbebe': { - customLabel: true, - dataType: 'number', - isBucketed: false, - label: SOURCE_CHART_LABEL, - operationType: 'unique_count', - scale: 'ratio', - sourceField: 'source.ip', +const columnSourceTimestamp = 'a0cb6400-f708-46c3-ad96-24788f12dae4'; +const columnSourceUniqueIp = 'd9a6eb6b-8b78-439e-98e7-a718f8ffbebe'; + +const columnDestinationIp = 'e7052671-fb9e-481f-8df3-7724c98cfc6f'; +const columnDestinationTimestamp = '95e74e6-99dd-4b11-8faf-439b4d959df9'; + +const layerDestinationIp = 'ca05ecdb-0fa4-49a8-9305-b23d91012a46'; +const layerSourceIp = '8be0156b-d423-4a39-adf1-f54d4c9f2e69'; + +export const getKpiUniqueIpsAreaLensAttributes: GetLensAttributes = ({ euiTheme }) => { + return { + description: '', + state: { + datasourceStates: { + formBased: { + layers: { + [layerSourceIp]: { + columnOrder: [columnSourceTimestamp, columnSourceUniqueIp], + columns: { + [columnSourceTimestamp]: { + dataType: 'date', + isBucketed: true, + label: '@timestamp', + operationType: 'date_histogram', + params: { interval: 'auto' }, + scale: 'interval', + sourceField: '@timestamp', + }, + [columnSourceUniqueIp]: { + customLabel: true, + dataType: 'number', + isBucketed: false, + label: SOURCE_CHART_LABEL, + operationType: 'unique_count', + scale: 'ratio', + sourceField: 'source.ip', + }, }, + incompleteColumns: {}, }, - incompleteColumns: {}, - }, - 'ca05ecdb-0fa4-49a8-9305-b23d91012a46': { - columnOrder: [ - 'f95e74e6-99dd-4b11-8faf-439b4d959df9', - 'e7052671-fb9e-481f-8df3-7724c98cfc6f', - ], - columns: { - 'e7052671-fb9e-481f-8df3-7724c98cfc6f': { - customLabel: true, - dataType: 'number', - isBucketed: false, - label: DESTINATION_CHART_LABEL, - operationType: 'unique_count', - scale: 'ratio', - sourceField: 'destination.ip', - }, - 'f95e74e6-99dd-4b11-8faf-439b4d959df9': { - dataType: 'date', - isBucketed: true, - label: '@timestamp', - operationType: 'date_histogram', - params: { interval: 'auto' }, - scale: 'interval', - sourceField: '@timestamp', + [layerDestinationIp]: { + columnOrder: [columnDestinationTimestamp, columnDestinationIp], + columns: { + [columnDestinationIp]: { + customLabel: true, + dataType: 'number', + isBucketed: false, + label: DESTINATION_CHART_LABEL, + operationType: 'unique_count', + scale: 'ratio', + sourceField: 'destination.ip', + }, + [columnDestinationTimestamp]: { + dataType: 'date', + isBucketed: true, + label: '@timestamp', + operationType: 'date_histogram', + params: { interval: 'auto' }, + scale: 'interval', + sourceField: '@timestamp', + }, }, + incompleteColumns: {}, }, - incompleteColumns: {}, }, }, }, + filters: [], + query: { language: 'kuery', query: '' }, + visualization: { + axisTitlesVisibilitySettings: { x: false, yLeft: false, yRight: true }, + fittingFunction: 'None', + gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true }, + labelsOrientation: { x: 0, yLeft: 0, yRight: 0 }, + layers: [ + { + accessors: [columnSourceUniqueIp], + layerId: layerSourceIp, + layerType: 'data', + seriesType: 'area', + xAccessor: columnSourceTimestamp, + yConfig: [ + { color: euiTheme.colors.vis.euiColorVis4, forAccessor: columnSourceUniqueIp }, + ], + }, + { + accessors: [columnDestinationIp], + layerId: layerDestinationIp, + layerType: 'data', + seriesType: 'area', + xAccessor: columnDestinationTimestamp, + yConfig: [ + { color: euiTheme.colors.vis.euiColorVis2, forAccessor: columnDestinationIp }, + ], + }, + ], + legend: { isVisible: false, position: 'right', showSingleSeries: false }, + preferredSeriesType: 'area', + tickLabelsVisibilitySettings: { x: true, yLeft: true, yRight: true }, + valueLabels: 'hide', + yLeftExtent: { mode: 'full' }, + yRightExtent: { mode: 'full' }, + }, }, - filters: [], - query: { language: 'kuery', query: '' }, - visualization: { - axisTitlesVisibilitySettings: { x: false, yLeft: false, yRight: true }, - fittingFunction: 'None', - gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true }, - labelsOrientation: { x: 0, yLeft: 0, yRight: 0 }, - layers: [ - { - accessors: ['d9a6eb6b-8b78-439e-98e7-a718f8ffbebe'], - layerId: '8be0156b-d423-4a39-adf1-f54d4c9f2e69', - layerType: 'data', - seriesType: 'area', - xAccessor: 'a0cb6400-f708-46c3-ad96-24788f12dae4', - yConfig: [{ color: '#d36186', forAccessor: 'd9a6eb6b-8b78-439e-98e7-a718f8ffbebe' }], - }, - { - accessors: ['e7052671-fb9e-481f-8df3-7724c98cfc6f'], - layerId: 'ca05ecdb-0fa4-49a8-9305-b23d91012a46', - layerType: 'data', - seriesType: 'area', - xAccessor: 'f95e74e6-99dd-4b11-8faf-439b4d959df9', - yConfig: [{ color: '#9170b8', forAccessor: 'e7052671-fb9e-481f-8df3-7724c98cfc6f' }], - }, - ], - legend: { isVisible: false, position: 'right', showSingleSeries: false }, - preferredSeriesType: 'area', - tickLabelsVisibilitySettings: { x: true, yLeft: true, yRight: true }, - valueLabels: 'hide', - yLeftExtent: { mode: 'full' }, - yRightExtent: { mode: 'full' }, - }, - }, - title: '[Host] Unique IPs - area', - visualizationType: 'lnsXY', - references: [ - { - id: '{dataViewId}', - name: 'indexpattern-datasource-current-indexpattern', - type: 'index-pattern', - }, - { - id: '{dataViewId}', - name: 'indexpattern-datasource-layer-8be0156b-d423-4a39-adf1-f54d4c9f2e69', - type: 'index-pattern', - }, - { - id: '{dataViewId}', - name: 'indexpattern-datasource-layer-ca05ecdb-0fa4-49a8-9305-b23d91012a46', - type: 'index-pattern', - }, - ], - type: 'lens', - updated_at: '2022-02-09T17:44:03.359Z', - version: 'WzI5MTI5OSwzXQ==', -} as LensAttributes; + title: '[Host] Unique IPs - area', + visualizationType: 'lnsXY', + references: [ + { + id: '{dataViewId}', + name: 'indexpattern-datasource-current-indexpattern', + type: 'index-pattern', + }, + { + id: '{dataViewId}', + name: `indexpattern-datasource-layer-${layerSourceIp}`, + type: 'index-pattern', + }, + { + id: '{dataViewId}', + name: `indexpattern-datasource-layer-${layerDestinationIp}`, + type: 'index-pattern', + }, + ], + type: 'lens', + updated_at: '2022-02-09T17:44:03.359Z', + version: 'WzI5MTI5OSwzXQ==', + } as LensAttributes; +}; diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_bar.test.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_bar.test.ts index 187cf18ddc88f..c611024df3064 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_bar.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_bar.test.ts @@ -10,7 +10,7 @@ import { wrapper } from '../../mocks'; import { useLensAttributes } from '../../use_lens_attributes'; -import { kpiUniqueIpsBarLensAttributes } from './kpi_unique_ips_bar'; +import { getKpiUniqueIpsBarLensAttributes } from './kpi_unique_ips_bar'; jest.mock('../../../../../sourcerer/containers', () => ({ useSourcererDataView: jest.fn().mockReturnValue({ @@ -31,12 +31,12 @@ jest.mock('../../../../utils/route/use_route_spy', () => ({ ]), })); -describe('kpiUniqueIpsBarLensAttributes', () => { +describe('getKpiUniqueIpsBarLensAttributes', () => { it('should render', () => { const { result } = renderHook( () => useLensAttributes({ - lensAttributes: kpiUniqueIpsBarLensAttributes, + getLensAttributes: getKpiUniqueIpsBarLensAttributes, stackByField: 'event.dataset', }), { wrapper } diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_bar.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_bar.ts index abee121d24585..0303c9abe9e12 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_bar.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_bar.ts @@ -5,130 +5,136 @@ * 2.0. */ -import type { LensAttributes } from '../../types'; +import type { GetLensAttributes, LensAttributes } from '../../types'; import { SOURCE_CHART_LABEL, DESTINATION_CHART_LABEL, UNIQUE_COUNT } from '../../translations'; +const columnSourceIp = '32f66676-f4e1-48fd-b7f8-d4de38318601'; +const columnSourceFilter = 'f8bfa719-5c1c-4bf2-896e-c318d77fc08e'; -export const kpiUniqueIpsBarLensAttributes: LensAttributes = { - description: '', - state: { - datasourceStates: { - formBased: { - layers: { - '8be0156b-d423-4a39-adf1-f54d4c9f2e69': { - columnOrder: [ - 'f8bfa719-5c1c-4bf2-896e-c318d77fc08e', - '32f66676-f4e1-48fd-b7f8-d4de38318601', - ], - columns: { - '32f66676-f4e1-48fd-b7f8-d4de38318601': { - dataType: 'number', - isBucketed: false, - label: UNIQUE_COUNT('source.ip'), - operationType: 'unique_count', - scale: 'ratio', - sourceField: 'source.ip', - }, - 'f8bfa719-5c1c-4bf2-896e-c318d77fc08e': { - dataType: 'string', - isBucketed: true, - label: 'Filters', - operationType: 'filters', - params: { - filters: [ - { - input: { language: 'kuery', query: 'source.ip: *' }, - label: SOURCE_CHART_LABEL, - }, - ], +const columnDestinationIp = 'b7e59b08-96e6-40d1-84fd-e97b977d1c47'; +const columnDestinationFilter = 'c72aad6a-fc9c-43dc-9194-e13ca3ee8aff'; + +const layerSourceIp = '8be0156b-d423-4a39-adf1-f54d4c9f2e69'; +const layerDestinationIp = 'ec84ba70-2adb-4647-8ef0-8ad91a0e6d4e'; + +export const getKpiUniqueIpsBarLensAttributes: GetLensAttributes = ({ euiTheme }) => { + return { + description: '', + state: { + datasourceStates: { + formBased: { + layers: { + [layerSourceIp]: { + columnOrder: [columnSourceFilter, columnSourceIp], + columns: { + [columnSourceIp]: { + dataType: 'number', + isBucketed: false, + label: UNIQUE_COUNT('source.ip'), + operationType: 'unique_count', + scale: 'ratio', + sourceField: 'source.ip', + }, + [columnSourceFilter]: { + dataType: 'string', + isBucketed: true, + label: 'Filters', + operationType: 'filters', + params: { + filters: [ + { + input: { language: 'kuery', query: 'source.ip: *' }, + label: SOURCE_CHART_LABEL, + }, + ], + }, + scale: 'ordinal', }, - scale: 'ordinal', }, + incompleteColumns: {}, }, - incompleteColumns: {}, - }, - 'ec84ba70-2adb-4647-8ef0-8ad91a0e6d4e': { - columnOrder: [ - 'c72aad6a-fc9c-43dc-9194-e13ca3ee8aff', - 'b7e59b08-96e6-40d1-84fd-e97b977d1c47', - ], - columns: { - 'b7e59b08-96e6-40d1-84fd-e97b977d1c47': { - dataType: 'number', - isBucketed: false, - label: UNIQUE_COUNT('destination.ip'), - operationType: 'unique_count', - scale: 'ratio', - sourceField: 'destination.ip', - }, - 'c72aad6a-fc9c-43dc-9194-e13ca3ee8aff': { - customLabel: true, - dataType: 'string', - isBucketed: true, - label: DESTINATION_CHART_LABEL, - operationType: 'filters', - params: { - filters: [ - { input: { language: 'kuery', query: 'destination.ip: *' }, label: 'Dest.' }, - ], + [layerDestinationIp]: { + columnOrder: [columnDestinationFilter, columnDestinationIp], + columns: { + [columnDestinationIp]: { + dataType: 'number', + isBucketed: false, + label: UNIQUE_COUNT('destination.ip'), + operationType: 'unique_count', + scale: 'ratio', + sourceField: 'destination.ip', + }, + [columnDestinationFilter]: { + customLabel: true, + dataType: 'string', + isBucketed: true, + label: DESTINATION_CHART_LABEL, + operationType: 'filters', + params: { + filters: [ + { input: { language: 'kuery', query: 'destination.ip: *' }, label: 'Dest.' }, + ], + }, + scale: 'ordinal', }, - scale: 'ordinal', }, + incompleteColumns: {}, }, - incompleteColumns: {}, }, }, }, + filters: [], + query: { language: 'kuery', query: '' }, + visualization: { + axisTitlesVisibilitySettings: { x: false, yLeft: false, yRight: true }, + fittingFunction: 'None', + gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true }, + labelsOrientation: { x: 0, yLeft: 0, yRight: 0 }, + layers: [ + { + accessors: [columnSourceIp], + layerId: layerSourceIp, + layerType: 'data', + seriesType: 'bar_horizontal_stacked', + xAccessor: columnSourceFilter, + yConfig: [{ color: euiTheme.colors.vis.euiColorVis4, forAccessor: columnSourceIp }], + }, + { + accessors: [columnDestinationIp], + layerId: layerDestinationIp, + layerType: 'data', + seriesType: 'bar_horizontal_stacked', + xAccessor: columnDestinationFilter, + yConfig: [ + { color: euiTheme.colors.vis.euiColorVis2, forAccessor: columnDestinationIp }, + ], + }, + ], + legend: { isVisible: false, position: 'right', showSingleSeries: false }, + preferredSeriesType: 'bar_horizontal_stacked', + tickLabelsVisibilitySettings: { x: true, yLeft: true, yRight: true }, + valueLabels: 'hide', + yLeftExtent: { mode: 'full' }, + yRightExtent: { mode: 'full' }, + }, }, - filters: [], - query: { language: 'kuery', query: '' }, - visualization: { - axisTitlesVisibilitySettings: { x: false, yLeft: false, yRight: true }, - fittingFunction: 'None', - gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true }, - labelsOrientation: { x: 0, yLeft: 0, yRight: 0 }, - layers: [ - { - accessors: ['32f66676-f4e1-48fd-b7f8-d4de38318601'], - layerId: '8be0156b-d423-4a39-adf1-f54d4c9f2e69', - layerType: 'data', - seriesType: 'bar_horizontal_stacked', - xAccessor: 'f8bfa719-5c1c-4bf2-896e-c318d77fc08e', - yConfig: [{ color: '#d36186', forAccessor: '32f66676-f4e1-48fd-b7f8-d4de38318601' }], - }, - { - accessors: ['b7e59b08-96e6-40d1-84fd-e97b977d1c47'], - layerId: 'ec84ba70-2adb-4647-8ef0-8ad91a0e6d4e', - layerType: 'data', - seriesType: 'bar_horizontal_stacked', - xAccessor: 'c72aad6a-fc9c-43dc-9194-e13ca3ee8aff', - yConfig: [{ color: '#9170b8', forAccessor: 'b7e59b08-96e6-40d1-84fd-e97b977d1c47' }], - }, - ], - legend: { isVisible: false, position: 'right', showSingleSeries: false }, - preferredSeriesType: 'bar_horizontal_stacked', - tickLabelsVisibilitySettings: { x: true, yLeft: true, yRight: true }, - valueLabels: 'hide', - yLeftExtent: { mode: 'full' }, - yRightExtent: { mode: 'full' }, - }, - }, - title: '[Host] Unique IPs - bar chart', - visualizationType: 'lnsXY', - references: [ - { - id: '{dataViewId}', - name: 'indexpattern-datasource-current-indexpattern', - type: 'index-pattern', - }, - { - id: '{dataViewId}', - name: 'indexpattern-datasource-layer-8be0156b-d423-4a39-adf1-f54d4c9f2e69', - type: 'index-pattern', - }, - { - id: '{dataViewId}', - name: 'indexpattern-datasource-layer-ec84ba70-2adb-4647-8ef0-8ad91a0e6d4e', - type: 'index-pattern', - }, - ], -} as LensAttributes; + title: '[Host] Unique IPs - bar chart', + visualizationType: 'lnsXY', + references: [ + { + id: '{dataViewId}', + name: 'indexpattern-datasource-current-indexpattern', + type: 'index-pattern', + }, + { + id: '{dataViewId}', + name: `indexpattern-datasource-layer-${layerSourceIp}`, + type: 'index-pattern', + }, + { + id: '{dataViewId}', + name: `indexpattern-datasource-layer-${layerDestinationIp}`, + type: 'index-pattern', + }, + ], + } as LensAttributes; +}; diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_private_ips_area.test.ts.snap b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_private_ips_area.test.ts.snap index 71722765d8314..3e46284421b4a 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_private_ips_area.test.ts.snap +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_private_ips_area.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`kpiUniquePrivateIpsAreaLensAttributes should render 1`] = ` +exports[`getKpiUniquePrivateIpsAreaLensAttributes should render 1`] = ` Object { "description": "", "references": Array [ @@ -223,7 +223,7 @@ Object { "xAccessor": "662cd5e5-82bf-4325-a703-273f84b97e09", "yConfig": Array [ Object { - "color": "#d36186", + "color": "#CA8EAE", "forAccessor": "5f317308-cfbb-4ee5-bfb9-07653184fabf", }, ], @@ -238,7 +238,7 @@ Object { "xAccessor": "36444b8c-7e10-4069-8298-6c1b46912be2", "yConfig": Array [ Object { - "color": "#9170b8", + "color": "#D36086", "forAccessor": "ac1eb80c-ddde-46c4-a90c-400261926762", }, ], diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_private_ips_bar.test.ts.snap b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_private_ips_bar.test.ts.snap index 17d65402506f1..443ddb2cfdfca 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_private_ips_bar.test.ts.snap +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_private_ips_bar.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`kpiUniquePrivateIpsBarLensAttributes should render 1`] = ` +exports[`getKpiUniquePrivateIpsBarLensAttributes should render 1`] = ` Object { "description": "", "references": Array [ @@ -238,7 +238,7 @@ Object { "xAccessor": "d9c438c5-f776-4436-9d20-d62dc8c03be8", "yConfig": Array [ Object { - "color": "#d36186", + "color": "#CA8EAE", "forAccessor": "5acd4c9d-dc3b-4b21-9632-e4407944c36d", }, ], @@ -253,7 +253,7 @@ Object { "xAccessor": "4607c585-3af3-43b9-804f-e49b27796d79", "yConfig": Array [ Object { - "color": "#9170b8", + "color": "#D36086", "forAccessor": "d27e0966-daf9-41f4-9033-230cf1e76dc9", }, ], diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/dns_top_domains.test.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/dns_top_domains.test.ts index 8446c7a71db86..e90dc72688236 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/dns_top_domains.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/dns_top_domains.test.ts @@ -14,6 +14,15 @@ import { useLensAttributes } from '../../use_lens_attributes'; import { getDnsTopDomainsLensAttributes } from './dns_top_domains'; +jest.mock('uuid', () => ({ + v4: jest + .fn() + .mockReturnValueOnce('b1c3efc6-c886-4fba-978f-3b6bb5e7948a') + .mockReturnValueOnce('e8842815-2a45-4c74-86de-c19a391e2424') + .mockReturnValueOnce('d1452b87-0e9e-4fc0-a725-3727a18e0b37') + .mockReturnValueOnce('2a4d5e20-f570-48e4-b9ab-ff3068919377'), +})); + jest.mock('../../../../../sourcerer/containers', () => ({ useSourcererDataView: jest.fn().mockReturnValue({ selectedPatterns: ['auditbeat-mytest-*'], diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/dns_top_domains.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/dns_top_domains.ts index ff04bf695fb83..3b3853a9f04e3 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/dns_top_domains.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/dns_top_domains.ts @@ -4,15 +4,20 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - +import { v4 as uuidv4 } from 'uuid'; import { TOP_VALUE, UNIQUE_COUNT } from '../../translations'; import type { LensAttributes, GetLensAttributes } from '../../types'; +const layerId = uuidv4(); +const columnTopValue = uuidv4(); +const columnTimestamp = uuidv4(); +const columnDNSQuestionName = uuidv4(); + /* Exported from Kibana Saved Object */ -export const getDnsTopDomainsLensAttributes: GetLensAttributes = ( +export const getDnsTopDomainsLensAttributes: GetLensAttributes = ({ stackByField = 'dns.question.registered_domain', - extraOptions -) => + extraOptions, +}) => ({ title: 'Top domains by dns.question.registered_domain', visualizationType: 'lnsXY', @@ -55,14 +60,14 @@ export const getDnsTopDomainsLensAttributes: GetLensAttributes = ( preferredSeriesType: 'bar_stacked', layers: [ { - layerId: 'b1c3efc6-c886-4fba-978f-3b6bb5e7948a', - accessors: ['2a4d5e20-f570-48e4-b9ab-ff3068919377'], + layerId, + accessors: [columnDNSQuestionName], position: 'top', seriesType: 'bar_stacked', showGridlines: false, layerType: 'data', - xAccessor: 'd1452b87-0e9e-4fc0-a725-3727a18e0b37', - splitAccessor: 'e8842815-2a45-4c74-86de-c19a391e2424', + xAccessor: columnTimestamp, + splitAccessor: columnTopValue, }, ], }, @@ -100,9 +105,9 @@ export const getDnsTopDomainsLensAttributes: GetLensAttributes = ( datasourceStates: { formBased: { layers: { - 'b1c3efc6-c886-4fba-978f-3b6bb5e7948a': { + [layerId]: { columns: { - 'e8842815-2a45-4c74-86de-c19a391e2424': { + [columnTopValue]: { label: TOP_VALUE(stackByField), dataType: 'string', operationType: 'terms', @@ -113,7 +118,7 @@ export const getDnsTopDomainsLensAttributes: GetLensAttributes = ( size: 10, orderBy: { type: 'column', - columnId: '2a4d5e20-f570-48e4-b9ab-ff3068919377', + columnId: columnDNSQuestionName, }, orderDirection: 'desc', otherBucket: true, @@ -125,7 +130,7 @@ export const getDnsTopDomainsLensAttributes: GetLensAttributes = ( accuracyMode: true, }, }, - 'd1452b87-0e9e-4fc0-a725-3727a18e0b37': { + [columnTimestamp]: { label: '@timestamp', dataType: 'date', operationType: 'date_histogram', @@ -137,7 +142,7 @@ export const getDnsTopDomainsLensAttributes: GetLensAttributes = ( includeEmptyRows: true, }, }, - '2a4d5e20-f570-48e4-b9ab-ff3068919377': { + [columnDNSQuestionName]: { label: UNIQUE_COUNT('dns.question.name'), dataType: 'number', operationType: 'unique_count', @@ -147,11 +152,7 @@ export const getDnsTopDomainsLensAttributes: GetLensAttributes = ( params: { emptyAsNull: true }, }, }, - columnOrder: [ - 'e8842815-2a45-4c74-86de-c19a391e2424', - 'd1452b87-0e9e-4fc0-a725-3727a18e0b37', - '2a4d5e20-f570-48e4-b9ab-ff3068919377', - ], + columnOrder: [columnTopValue, columnTimestamp, columnDNSQuestionName], incompleteColumns: {}, }, }, @@ -164,7 +165,7 @@ export const getDnsTopDomainsLensAttributes: GetLensAttributes = ( { type: 'index-pattern', id: '{dataViewId}', - name: 'indexpattern-datasource-layer-b1c3efc6-c886-4fba-978f-3b6bb5e7948a', + name: `indexpattern-datasource-layer-${layerId}`, }, ], } as LensAttributes); diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_area.test.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_area.test.ts index 4948d649f0740..d76cbc72b26d2 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_area.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_area.test.ts @@ -10,7 +10,7 @@ import { wrapper } from '../../mocks'; import { useLensAttributes } from '../../use_lens_attributes'; -import { kpiUniquePrivateIpsAreaLensAttributes } from './kpi_unique_private_ips_area'; +import { getKpiUniquePrivateIpsAreaLensAttributes } from './kpi_unique_private_ips_area'; jest.mock('../../../../../sourcerer/containers', () => ({ useSourcererDataView: jest.fn().mockReturnValue({ @@ -31,12 +31,12 @@ jest.mock('../../../../utils/route/use_route_spy', () => ({ ]), })); -describe('kpiUniquePrivateIpsAreaLensAttributes', () => { +describe('getKpiUniquePrivateIpsAreaLensAttributes', () => { it('should render', () => { const { result } = renderHook( () => useLensAttributes({ - lensAttributes: kpiUniquePrivateIpsAreaLensAttributes, + getLensAttributes: getKpiUniquePrivateIpsAreaLensAttributes, stackByField: 'event.dataset', }), { wrapper } diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_area.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_area.ts index 86e9f21d7ffef..a0a74af33cd68 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_area.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_area.ts @@ -5,171 +5,175 @@ * 2.0. */ import { DESTINATION_CHART_LABEL, SOURCE_CHART_LABEL } from '../../translations'; -import type { LensAttributes } from '../../types'; +import type { LensAttributes, GetLensAttributes } from '../../types'; -export const kpiUniquePrivateIpsAreaLensAttributes: LensAttributes = { - title: '[Network] Unique private IPs - area chart', - description: '', - visualizationType: 'lnsXY', - state: { - visualization: { - legend: { - isVisible: false, - position: 'right', - showSingleSeries: false, - }, - valueLabels: 'hide', - fittingFunction: 'None', - yLeftExtent: { - mode: 'full', - }, - yRightExtent: { - mode: 'full', - }, - axisTitlesVisibilitySettings: { - x: false, - yLeft: false, - yRight: true, - }, - tickLabelsVisibilitySettings: { - x: true, - yLeft: true, - yRight: true, - }, - labelsOrientation: { - x: 0, - yLeft: 0, - yRight: 0, - }, - gridlinesVisibilitySettings: { - x: true, - yLeft: true, - yRight: true, - }, - preferredSeriesType: 'area', - layers: [ - { - layerId: '38aa6532-6bf9-4c8f-b2a6-da8d32f7d0d7', - seriesType: 'area', - accessors: ['5f317308-cfbb-4ee5-bfb9-07653184fabf'], - layerType: 'data', - xAccessor: '662cd5e5-82bf-4325-a703-273f84b97e09', - yConfig: [ - { - forAccessor: '5f317308-cfbb-4ee5-bfb9-07653184fabf', - color: '#d36186', - }, - ], +const columnTimestamp = '662cd5e5-82bf-4325-a703-273f84b97e09'; +const columnSourceIp = '5f317308-cfbb-4ee5-bfb9-07653184fabf'; +const columnDestinationIpTimestamp = '36444b8c-7e10-4069-8298-6c1b46912be2'; +const columnDestinationIp = 'ac1eb80c-ddde-46c4-a90c-400261926762'; + +const layerSourceIp = '38aa6532-6bf9-4c8f-b2a6-da8d32f7d0d7'; +const layerDestinationIp = '72dc4b99-b07d-4dc9-958b-081d259e11fa'; + +export const getKpiUniquePrivateIpsAreaLensAttributes: GetLensAttributes = ({ euiTheme }) => { + return { + title: '[Network] Unique private IPs - area chart', + description: '', + visualizationType: 'lnsXY', + state: { + visualization: { + legend: { + isVisible: false, + position: 'right', + showSingleSeries: false, }, - { - layerId: '72dc4b99-b07d-4dc9-958b-081d259e11fa', - seriesType: 'area', - accessors: ['ac1eb80c-ddde-46c4-a90c-400261926762'], - layerType: 'data', - xAccessor: '36444b8c-7e10-4069-8298-6c1b46912be2', - yConfig: [ - { - forAccessor: 'ac1eb80c-ddde-46c4-a90c-400261926762', - color: '#9170b8', - }, - ], + valueLabels: 'hide', + fittingFunction: 'None', + yLeftExtent: { + mode: 'full', }, - ], - }, - query: { - query: '', - language: 'kuery', - }, - filters: [], - datasourceStates: { - formBased: { - layers: { - '38aa6532-6bf9-4c8f-b2a6-da8d32f7d0d7': { - columns: { - '662cd5e5-82bf-4325-a703-273f84b97e09': { - label: '@timestamp', - dataType: 'date', - operationType: 'date_histogram', - sourceField: '@timestamp', - isBucketed: true, - scale: 'interval', - params: { - interval: 'auto', - }, + yRightExtent: { + mode: 'full', + }, + axisTitlesVisibilitySettings: { + x: false, + yLeft: false, + yRight: true, + }, + tickLabelsVisibilitySettings: { + x: true, + yLeft: true, + yRight: true, + }, + labelsOrientation: { + x: 0, + yLeft: 0, + yRight: 0, + }, + gridlinesVisibilitySettings: { + x: true, + yLeft: true, + yRight: true, + }, + preferredSeriesType: 'area', + layers: [ + { + layerId: layerSourceIp, + seriesType: 'area', + accessors: [columnSourceIp], + layerType: 'data', + xAccessor: columnTimestamp, + yConfig: [ + { + forAccessor: columnSourceIp, + color: euiTheme.colors.vis.euiColorVis4, }, - '5f317308-cfbb-4ee5-bfb9-07653184fabf': { - label: SOURCE_CHART_LABEL, - dataType: 'number', - operationType: 'unique_count', - scale: 'ratio', - sourceField: 'source.ip', - isBucketed: false, - customLabel: true, - filter: { - query: - '"source.ip": "10.0.0.0/8" or "source.ip": "192.168.0.0/16" or "source.ip": "172.16.0.0/12" or "source.ip": "fd00::/8"', - language: 'kuery', - }, + ], + }, + { + layerId: layerDestinationIp, + seriesType: 'area', + accessors: [columnDestinationIp], + layerType: 'data', + xAccessor: columnDestinationIpTimestamp, + yConfig: [ + { + forAccessor: columnDestinationIp, + color: euiTheme.colors.vis.euiColorVis2, }, - }, - columnOrder: [ - '662cd5e5-82bf-4325-a703-273f84b97e09', - '5f317308-cfbb-4ee5-bfb9-07653184fabf', ], - incompleteColumns: {}, }, - '72dc4b99-b07d-4dc9-958b-081d259e11fa': { - columns: { - '36444b8c-7e10-4069-8298-6c1b46912be2': { - label: '@timestamp', - dataType: 'date', - operationType: 'date_histogram', - sourceField: '@timestamp', - isBucketed: true, - scale: 'interval', - params: { - interval: 'auto', + ], + }, + query: { + query: '', + language: 'kuery', + }, + filters: [], + datasourceStates: { + formBased: { + layers: { + [layerSourceIp]: { + columns: { + [columnTimestamp]: { + label: '@timestamp', + dataType: 'date', + operationType: 'date_histogram', + sourceField: '@timestamp', + isBucketed: true, + scale: 'interval', + params: { + interval: 'auto', + }, + }, + [columnSourceIp]: { + label: SOURCE_CHART_LABEL, + dataType: 'number', + operationType: 'unique_count', + scale: 'ratio', + sourceField: 'source.ip', + isBucketed: false, + customLabel: true, + filter: { + query: + '"source.ip": "10.0.0.0/8" or "source.ip": "192.168.0.0/16" or "source.ip": "172.16.0.0/12" or "source.ip": "fd00::/8"', + language: 'kuery', + }, }, }, - 'ac1eb80c-ddde-46c4-a90c-400261926762': { - label: DESTINATION_CHART_LABEL, - dataType: 'number', - operationType: 'unique_count', - scale: 'ratio', - sourceField: 'destination.ip', - isBucketed: false, - filter: { - query: - '"destination.ip": "10.0.0.0/8" or "destination.ip": "192.168.0.0/16" or "destination.ip": "172.16.0.0/12" or "destination.ip": "fd00::/8"', - language: 'kuery', + columnOrder: [columnTimestamp, columnSourceIp], + incompleteColumns: {}, + }, + [layerDestinationIp]: { + columns: { + [columnDestinationIpTimestamp]: { + label: '@timestamp', + dataType: 'date', + operationType: 'date_histogram', + sourceField: '@timestamp', + isBucketed: true, + scale: 'interval', + params: { + interval: 'auto', + }, + }, + [columnDestinationIp]: { + label: DESTINATION_CHART_LABEL, + dataType: 'number', + operationType: 'unique_count', + scale: 'ratio', + sourceField: 'destination.ip', + isBucketed: false, + filter: { + query: + '"destination.ip": "10.0.0.0/8" or "destination.ip": "192.168.0.0/16" or "destination.ip": "172.16.0.0/12" or "destination.ip": "fd00::/8"', + language: 'kuery', + }, }, }, + columnOrder: [columnDestinationIpTimestamp, columnDestinationIp], + incompleteColumns: {}, }, - columnOrder: [ - '36444b8c-7e10-4069-8298-6c1b46912be2', - 'ac1eb80c-ddde-46c4-a90c-400261926762', - ], - incompleteColumns: {}, }, }, }, }, - }, - references: [ - { - type: 'index-pattern', - id: '{dataViewId}', - name: 'indexpattern-datasource-current-indexpattern', - }, - { - type: 'index-pattern', - id: '{dataViewId}', - name: 'indexpattern-datasource-layer-38aa6532-6bf9-4c8f-b2a6-da8d32f7d0d7', - }, - { - type: 'index-pattern', - id: '{dataViewId}', - name: 'indexpattern-datasource-layer-72dc4b99-b07d-4dc9-958b-081d259e11fa', - }, - ], -} as LensAttributes; + references: [ + { + type: 'index-pattern', + id: '{dataViewId}', + name: 'indexpattern-datasource-current-indexpattern', + }, + { + type: 'index-pattern', + id: '{dataViewId}', + name: `indexpattern-datasource-layer-${layerSourceIp}`, + }, + { + type: 'index-pattern', + id: '{dataViewId}', + name: `indexpattern-datasource-layer-${layerDestinationIp}`, + }, + ], + } as LensAttributes; +}; diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_bar.test.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_bar.test.ts index e8bfdbad68dce..d268a925abbb7 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_bar.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_bar.test.ts @@ -10,7 +10,18 @@ import { wrapper } from '../../mocks'; import { useLensAttributes } from '../../use_lens_attributes'; -import { kpiUniquePrivateIpsBarLensAttributes } from './kpi_unique_private_ips_bar'; +import { getKpiUniquePrivateIpsBarLensAttributes } from './kpi_unique_private_ips_bar'; + +jest.mock('uuid', () => ({ + v4: jest + .fn() + .mockReturnValueOnce('5acd4c9d-dc3b-4b21-9632-e4407944c36d') + .mockReturnValueOnce('d9c438c5-f776-4436-9d20-d62dc8c03be8') + .mockReturnValueOnce('d27e0966-daf9-41f4-9033-230cf1e76dc9') + .mockReturnValueOnce('4607c585-3af3-43b9-804f-e49b27796d79') + .mockReturnValueOnce('e406bf4f-942b-41ac-b516-edb5cef06ec8') + .mockReturnValueOnce('38aa6532-6bf9-4c8f-b2a6-da8d32f7d0d7'), +})); jest.mock('../../../../../sourcerer/containers', () => ({ useSourcererDataView: jest.fn().mockReturnValue({ @@ -31,12 +42,12 @@ jest.mock('../../../../utils/route/use_route_spy', () => ({ ]), })); -describe('kpiUniquePrivateIpsBarLensAttributes', () => { +describe('getKpiUniquePrivateIpsBarLensAttributes', () => { it('should render', () => { const { result } = renderHook( () => useLensAttributes({ - lensAttributes: kpiUniquePrivateIpsBarLensAttributes, + getLensAttributes: getKpiUniquePrivateIpsBarLensAttributes, stackByField: 'event.dataset', }), { wrapper } diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_bar.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_bar.ts index 106c1c5e83124..7f4b444451a9f 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_bar.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_bar.ts @@ -4,182 +4,187 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - +import { v4 as uuidv4 } from 'uuid'; import { SOURCE_CHART_LABEL, DESTINATION_CHART_LABEL, UNIQUE_COUNT } from '../../translations'; -import type { LensAttributes } from '../../types'; +import type { LensAttributes, GetLensAttributes } from '../../types'; -export const kpiUniquePrivateIpsBarLensAttributes: LensAttributes = { - title: '[Network] Unique private IPs - bar chart', - description: '', - visualizationType: 'lnsXY', - state: { - visualization: { - legend: { - isVisible: false, - position: 'right', - showSingleSeries: false, - }, - valueLabels: 'hide', - fittingFunction: 'None', - yLeftExtent: { - mode: 'full', - }, - yRightExtent: { - mode: 'full', - }, - axisTitlesVisibilitySettings: { - x: false, - yLeft: false, - yRight: true, - }, - tickLabelsVisibilitySettings: { - x: true, - yLeft: true, - yRight: true, - }, - labelsOrientation: { - x: 0, - yLeft: 0, - yRight: 0, - }, - gridlinesVisibilitySettings: { - x: true, - yLeft: true, - yRight: true, - }, - preferredSeriesType: 'bar_horizontal_stacked', - layers: [ - { - layerId: 'e406bf4f-942b-41ac-b516-edb5cef06ec8', - accessors: ['5acd4c9d-dc3b-4b21-9632-e4407944c36d'], - position: 'top', - seriesType: 'bar_horizontal_stacked', - showGridlines: false, - layerType: 'data', - yConfig: [ - { - forAccessor: '5acd4c9d-dc3b-4b21-9632-e4407944c36d', - color: '#d36186', - }, - ], - xAccessor: 'd9c438c5-f776-4436-9d20-d62dc8c03be8', +const columnSourceIp = uuidv4(); +const columnSourceIpFilter = uuidv4(); + +const columnDestinationIp = uuidv4(); +const columnDestinationIpFilter = uuidv4(); + +const layerSourceIp = uuidv4(); +const layerDestinationIp = uuidv4(); + +export const getKpiUniquePrivateIpsBarLensAttributes: GetLensAttributes = ({ euiTheme }) => { + return { + title: '[Network] Unique private IPs - bar chart', + description: '', + visualizationType: 'lnsXY', + state: { + visualization: { + legend: { + isVisible: false, + position: 'right', + showSingleSeries: false, }, - { - layerId: '38aa6532-6bf9-4c8f-b2a6-da8d32f7d0d7', - seriesType: 'bar_horizontal_stacked', - accessors: ['d27e0966-daf9-41f4-9033-230cf1e76dc9'], - layerType: 'data', - yConfig: [ - { - forAccessor: 'd27e0966-daf9-41f4-9033-230cf1e76dc9', - color: '#9170b8', - }, - ], - xAccessor: '4607c585-3af3-43b9-804f-e49b27796d79', + valueLabels: 'hide', + fittingFunction: 'None', + yLeftExtent: { + mode: 'full', }, - ], - }, - query: { - query: '', - language: 'kuery', - }, - filters: [], - datasourceStates: { - formBased: { - layers: { - 'e406bf4f-942b-41ac-b516-edb5cef06ec8': { - columns: { - '5acd4c9d-dc3b-4b21-9632-e4407944c36d': { - label: UNIQUE_COUNT('source.ip'), - dataType: 'number', - isBucketed: false, - operationType: 'unique_count', - scale: 'ratio', - sourceField: 'source.ip', - filter: { - query: - 'source.ip: "10.0.0.0/8" or source.ip: "192.168.0.0/16" or source.ip: "172.16.0.0/12" or source.ip: "fd00::/8"', - language: 'kuery', - }, + yRightExtent: { + mode: 'full', + }, + axisTitlesVisibilitySettings: { + x: false, + yLeft: false, + yRight: true, + }, + tickLabelsVisibilitySettings: { + x: true, + yLeft: true, + yRight: true, + }, + labelsOrientation: { + x: 0, + yLeft: 0, + yRight: 0, + }, + gridlinesVisibilitySettings: { + x: true, + yLeft: true, + yRight: true, + }, + preferredSeriesType: 'bar_horizontal_stacked', + layers: [ + { + layerId: layerSourceIp, + accessors: [columnSourceIp], + position: 'top', + seriesType: 'bar_horizontal_stacked', + showGridlines: false, + layerType: 'data', + yConfig: [ + { + forAccessor: columnSourceIp, + color: euiTheme.colors.vis.euiColorVis4, }, - 'd9c438c5-f776-4436-9d20-d62dc8c03be8': { - label: 'Filters', - dataType: 'string', - operationType: 'filters', - scale: 'ordinal', - isBucketed: true, - params: { - filters: [ - { - input: { language: 'kuery', query: 'source.ip: *' }, - label: SOURCE_CHART_LABEL, - }, - ], - }, + ], + xAccessor: columnSourceIpFilter, + }, + { + layerId: layerDestinationIp, + seriesType: 'bar_horizontal_stacked', + accessors: [columnDestinationIp], + layerType: 'data', + yConfig: [ + { + forAccessor: columnDestinationIp, + color: euiTheme.colors.vis.euiColorVis2, }, - }, - columnOrder: [ - 'd9c438c5-f776-4436-9d20-d62dc8c03be8', - '5acd4c9d-dc3b-4b21-9632-e4407944c36d', ], - incompleteColumns: {}, + xAccessor: columnDestinationIpFilter, }, - '38aa6532-6bf9-4c8f-b2a6-da8d32f7d0d7': { - columns: { - 'd27e0966-daf9-41f4-9033-230cf1e76dc9': { - label: UNIQUE_COUNT('destination.ip'), - dataType: 'number', - isBucketed: false, - operationType: 'unique_count', - scale: 'ratio', - sourceField: 'destination.ip', - filter: { - query: - '"destination.ip": "10.0.0.0/8" or "destination.ip": "192.168.0.0/16" or "destination.ip": "172.16.0.0/12" or "destination.ip": "fd00::/8"', - language: 'kuery', + ], + }, + query: { + query: '', + language: 'kuery', + }, + filters: [], + datasourceStates: { + formBased: { + layers: { + [layerSourceIp]: { + columns: { + [columnSourceIp]: { + label: UNIQUE_COUNT('source.ip'), + dataType: 'number', + isBucketed: false, + operationType: 'unique_count', + scale: 'ratio', + sourceField: 'source.ip', + filter: { + query: + 'source.ip: "10.0.0.0/8" or source.ip: "192.168.0.0/16" or source.ip: "172.16.0.0/12" or source.ip: "fd00::/8"', + language: 'kuery', + }, + }, + [columnSourceIpFilter]: { + label: 'Filters', + dataType: 'string', + operationType: 'filters', + scale: 'ordinal', + isBucketed: true, + params: { + filters: [ + { + input: { language: 'kuery', query: 'source.ip: *' }, + label: SOURCE_CHART_LABEL, + }, + ], + }, }, }, - '4607c585-3af3-43b9-804f-e49b27796d79': { - label: 'Filters', - dataType: 'string', - operationType: 'filters', - scale: 'ordinal', - isBucketed: true, - params: { - filters: [ - { - input: { language: 'kuery', query: 'destination.ip: *' }, - label: DESTINATION_CHART_LABEL, - }, - ], + columnOrder: [columnSourceIpFilter, columnSourceIp], + incompleteColumns: {}, + }, + [layerDestinationIp]: { + columns: { + [columnDestinationIp]: { + label: UNIQUE_COUNT('destination.ip'), + dataType: 'number', + isBucketed: false, + operationType: 'unique_count', + scale: 'ratio', + sourceField: 'destination.ip', + filter: { + query: + '"destination.ip": "10.0.0.0/8" or "destination.ip": "192.168.0.0/16" or "destination.ip": "172.16.0.0/12" or "destination.ip": "fd00::/8"', + language: 'kuery', + }, + }, + [columnDestinationIpFilter]: { + label: 'Filters', + dataType: 'string', + operationType: 'filters', + scale: 'ordinal', + isBucketed: true, + params: { + filters: [ + { + input: { language: 'kuery', query: 'destination.ip: *' }, + label: DESTINATION_CHART_LABEL, + }, + ], + }, }, }, + columnOrder: [columnDestinationIpFilter, columnDestinationIp], + incompleteColumns: {}, }, - columnOrder: [ - '4607c585-3af3-43b9-804f-e49b27796d79', - 'd27e0966-daf9-41f4-9033-230cf1e76dc9', - ], - incompleteColumns: {}, }, }, }, }, - }, - references: [ - { - type: 'index-pattern', - id: '{dataViewId}', - name: 'indexpattern-datasource-current-indexpattern', - }, - { - type: 'index-pattern', - id: '{dataViewId}', - name: 'indexpattern-datasource-layer-e406bf4f-942b-41ac-b516-edb5cef06ec8', - }, - { - type: 'index-pattern', - id: '{dataViewId}', - name: 'indexpattern-datasource-layer-38aa6532-6bf9-4c8f-b2a6-da8d32f7d0d7', - }, - ], -} as LensAttributes; + references: [ + { + type: 'index-pattern', + id: '{dataViewId}', + name: 'indexpattern-datasource-current-indexpattern', + }, + { + type: 'index-pattern', + id: '{dataViewId}', + name: `indexpattern-datasource-layer-${layerSourceIp}`, + }, + { + type: 'index-pattern', + id: '{dataViewId}', + name: `indexpattern-datasource-layer-${layerDestinationIp}`, + }, + ], + } as LensAttributes; +}; diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_total_users_area.test.ts.snap b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_total_users_area.test.ts.snap index c1082249eaf09..2b0e38615bb20 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_total_users_area.test.ts.snap +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_total_users_area.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`kpiTotalUsersAreaLensAttributes should render 1`] = ` +exports[`getKpiTotalUsersAreaLensAttributes should render 1`] = ` Object { "description": "", "references": Array [ diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_user_authentications_area.test.ts.snap b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_user_authentications_area.test.ts.snap index 1aff234b94837..70fb96a186640 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_user_authentications_area.test.ts.snap +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_user_authentications_area.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`kpiUserAuthenticationsAreaLensAttributes should render 1`] = ` +exports[`getKpiUserAuthenticationsAreaLensAttributes should render 1`] = ` Object { "description": "", "references": Array [ @@ -232,7 +232,7 @@ Object { "xAccessor": "49a42fe6-ebe8-4adb-8eed-1966a5297b7e", "yConfig": Array [ Object { - "color": "#54b399", + "color": "#54B399", "forAccessor": "0eb97c09-a351-4280-97da-944e4bd30dd7", }, ], @@ -247,7 +247,7 @@ Object { "xAccessor": "33a6163d-0c0a-451d-aa38-8ca6010dd5bf", "yConfig": Array [ Object { - "color": "#e7664c", + "color": "#CA8EAE", "forAccessor": "2b27c80e-a20d-46f1-8fb2-79626ef4563c", }, ], diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_user_authentications_bar.test.ts.snap b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_user_authentications_bar.test.ts.snap index 719fa4f10c326..1fe0fc602ca1f 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_user_authentications_bar.test.ts.snap +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_user_authentications_bar.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`kpiUserAuthenticationsBarLensAttributes should render 1`] = ` +exports[`getKpiUserAuthenticationsBarLensAttributes should render 1`] = ` Object { "description": "", "references": Array [ @@ -235,7 +235,12 @@ Object { "layerType": "data", "seriesType": "bar_horizontal_stacked", "xAccessor": "430e690c-9992-414f-9bce-00812d99a5e7", - "yConfig": Array [], + "yConfig": Array [ + Object { + "color": "#54B399", + "forAccessor": "938b445a-a291-4bbc-84fe-4f47b69c20e4", + }, + ], }, Object { "accessors": Array [ @@ -247,7 +252,7 @@ Object { "xAccessor": "e959c351-a3a2-4525-b244-9623f215a8fd", "yConfig": Array [ Object { - "color": "#e7664c", + "color": "#CA8EAE", "forAccessor": "c8165fc3-7180-4f1b-8c87-bc3ea04c6df7", }, ], diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_total_users_area.test.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_total_users_area.test.ts index 6c4b5316cd69e..a6e623227dff2 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_total_users_area.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_total_users_area.test.ts @@ -10,7 +10,7 @@ import { wrapper } from '../../mocks'; import { useLensAttributes } from '../../use_lens_attributes'; -import { kpiTotalUsersAreaLensAttributes } from './kpi_total_users_area'; +import { getKpiTotalUsersAreaLensAttributes } from './kpi_total_users_area'; jest.mock('../../../../../sourcerer/containers', () => ({ useSourcererDataView: jest.fn().mockReturnValue({ @@ -31,12 +31,12 @@ jest.mock('../../../../utils/route/use_route_spy', () => ({ ]), })); -describe('kpiTotalUsersAreaLensAttributes', () => { +describe('getKpiTotalUsersAreaLensAttributes', () => { it('should render', () => { const { result } = renderHook( () => useLensAttributes({ - lensAttributes: kpiTotalUsersAreaLensAttributes, + getLensAttributes: getKpiTotalUsersAreaLensAttributes, stackByField: 'event.dataset', }), { wrapper } diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_total_users_area.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_total_users_area.ts index c241d03266cc3..786c738315db1 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_total_users_area.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_total_users_area.ts @@ -6,80 +6,83 @@ */ import { UNIQUE_COUNT } from '../../translations'; -import type { LensAttributes } from '../../types'; +import type { LensAttributes, GetLensAttributes } from '../../types'; -export const kpiTotalUsersAreaLensAttributes: LensAttributes = { - description: '', - state: { - datasourceStates: { - formBased: { - layers: { - '416b6fad-1923-4f6a-a2df-b223bb287e30': { - columnOrder: [ - '5eea817b-67b7-4268-8ecb-7688d1094721', - 'b00c65ea-32be-4163-bfc8-f795b1ef9d06', - ], - columns: { - '5eea817b-67b7-4268-8ecb-7688d1094721': { - dataType: 'date', - isBucketed: true, - label: '@timestamp', - operationType: 'date_histogram', - params: { interval: 'auto' }, - scale: 'interval', - sourceField: '@timestamp', - }, - 'b00c65ea-32be-4163-bfc8-f795b1ef9d06': { - customLabel: true, - dataType: 'number', - isBucketed: false, - label: UNIQUE_COUNT('user.name'), - operationType: 'unique_count', - scale: 'ratio', - sourceField: 'user.name', +const columnTimestamp = '5eea817b-67b7-4268-8ecb-7688d1094721'; +const columnUserName = 'b00c65ea-32be-4163-bfc8-f795b1ef9d06'; + +const layerUserName = '416b6fad-1923-4f6a-a2df-b223bb287e30'; + +export const getKpiTotalUsersAreaLensAttributes: GetLensAttributes = () => + ({ + description: '', + state: { + datasourceStates: { + formBased: { + layers: { + [layerUserName]: { + columnOrder: [columnTimestamp, columnUserName], + columns: { + [columnTimestamp]: { + dataType: 'date', + isBucketed: true, + label: '@timestamp', + operationType: 'date_histogram', + params: { interval: 'auto' }, + scale: 'interval', + sourceField: '@timestamp', + }, + [columnUserName]: { + customLabel: true, + dataType: 'number', + isBucketed: false, + label: UNIQUE_COUNT('user.name'), + operationType: 'unique_count', + scale: 'ratio', + sourceField: 'user.name', + }, }, + incompleteColumns: {}, }, - incompleteColumns: {}, }, }, }, + filters: [], + query: { language: 'kuery', query: '' }, + visualization: { + axisTitlesVisibilitySettings: { x: false, yLeft: false, yRight: false }, + fittingFunction: 'None', + gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true }, + labelsOrientation: { x: 0, yLeft: 0, yRight: 0 }, + layers: [ + { + accessors: [columnUserName], + layerId: layerUserName, + layerType: 'data', + seriesType: 'area', + xAccessor: columnTimestamp, + }, + ], + legend: { isVisible: true, position: 'right' }, + preferredSeriesType: 'area', + tickLabelsVisibilitySettings: { x: true, yLeft: true, yRight: true }, + valueLabels: 'hide', + yLeftExtent: { mode: 'full' }, + yRightExtent: { mode: 'full' }, + }, }, - filters: [], - query: { language: 'kuery', query: '' }, - visualization: { - axisTitlesVisibilitySettings: { x: false, yLeft: false, yRight: false }, - fittingFunction: 'None', - gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true }, - labelsOrientation: { x: 0, yLeft: 0, yRight: 0 }, - layers: [ - { - accessors: ['b00c65ea-32be-4163-bfc8-f795b1ef9d06'], - layerId: '416b6fad-1923-4f6a-a2df-b223bb287e30', - layerType: 'data', - seriesType: 'area', - xAccessor: '5eea817b-67b7-4268-8ecb-7688d1094721', - }, - ], - legend: { isVisible: true, position: 'right' }, - preferredSeriesType: 'area', - tickLabelsVisibilitySettings: { x: true, yLeft: true, yRight: true }, - valueLabels: 'hide', - yLeftExtent: { mode: 'full' }, - yRightExtent: { mode: 'full' }, - }, - }, - title: '[User] Users - area', - visualizationType: 'lnsXY', - references: [ - { - id: '{dataViewId}', - name: 'indexpattern-datasource-current-indexpattern', - type: 'index-pattern', - }, - { - id: '{dataViewId}', - name: 'indexpattern-datasource-layer-416b6fad-1923-4f6a-a2df-b223bb287e30', - type: 'index-pattern', - }, - ], -} as LensAttributes; + title: '[User] Users - area', + visualizationType: 'lnsXY', + references: [ + { + id: '{dataViewId}', + name: 'indexpattern-datasource-current-indexpattern', + type: 'index-pattern', + }, + { + id: '{dataViewId}', + name: `indexpattern-datasource-layer-${layerUserName}`, + type: 'index-pattern', + }, + ], + } as LensAttributes); diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_area.test.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_area.test.ts index c60a8682ea32c..98a973878a699 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_area.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_area.test.ts @@ -10,7 +10,18 @@ import { wrapper } from '../../mocks'; import { useLensAttributes } from '../../use_lens_attributes'; -import { kpiUserAuthenticationsAreaLensAttributes } from './kpi_user_authentications_area'; +import { getKpiUserAuthenticationsAreaLensAttributes } from './kpi_user_authentications_area'; + +jest.mock('uuid', () => ({ + v4: jest + .fn() + .mockReturnValueOnce('2b27c80e-a20d-46f1-8fb2-79626ef4563c') + .mockReturnValueOnce('33a6163d-0c0a-451d-aa38-8ca6010dd5bf') + .mockReturnValueOnce('0eb97c09-a351-4280-97da-944e4bd30dd7') + .mockReturnValueOnce('49a42fe6-ebe8-4adb-8eed-1966a5297b7e') + .mockReturnValueOnce('4590dafb-4ac7-45aa-8641-47a3ff0b817c') + .mockReturnValueOnce('31213ae3-905b-4e88-b987-0cccb1f3209f'), +})); jest.mock('../../../../../sourcerer/containers', () => ({ useSourcererDataView: jest.fn().mockReturnValue({ @@ -31,12 +42,12 @@ jest.mock('../../../../utils/route/use_route_spy', () => ({ ]), })); -describe('kpiUserAuthenticationsAreaLensAttributes', () => { +describe('getKpiUserAuthenticationsAreaLensAttributes', () => { it('should render', () => { const { result } = renderHook( () => useLensAttributes({ - lensAttributes: kpiUserAuthenticationsAreaLensAttributes, + getLensAttributes: getKpiUserAuthenticationsAreaLensAttributes, stackByField: 'event.dataset', }), { wrapper } diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_area.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_area.ts index a7efc44155eec..f9e9d7e62d701 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_area.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_area.ts @@ -4,199 +4,202 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - +import { v4 as uuidv4 } from 'uuid'; import { FAIL_CHART_LABEL, SUCCESS_CHART_LABEL } from '../../translations'; -import type { LensAttributes } from '../../types'; +import type { LensAttributes, GetLensAttributes } from '../../types'; -export const kpiUserAuthenticationsAreaLensAttributes: LensAttributes = { - title: '[Host] User authentications - area ', - description: '', - visualizationType: 'lnsXY', - state: { - visualization: { - axisTitlesVisibilitySettings: { - x: false, - yLeft: false, - yRight: true, - }, - fittingFunction: 'None', - gridlinesVisibilitySettings: { - x: true, - yLeft: true, - yRight: true, - }, - labelsOrientation: { - x: 0, - yLeft: 0, - yRight: 0, - }, - layers: [ - { - accessors: ['0eb97c09-a351-4280-97da-944e4bd30dd7'], - layerId: '4590dafb-4ac7-45aa-8641-47a3ff0b817c', - layerType: 'data', - seriesType: 'area', - xAccessor: '49a42fe6-ebe8-4adb-8eed-1966a5297b7e', - yConfig: [ - { - color: '#54b399', - forAccessor: '0eb97c09-a351-4280-97da-944e4bd30dd7', - }, - ], - }, - { - accessors: ['2b27c80e-a20d-46f1-8fb2-79626ef4563c'], - layerId: '31213ae3-905b-4e88-b987-0cccb1f3209f', - layerType: 'data', - seriesType: 'area', - xAccessor: '33a6163d-0c0a-451d-aa38-8ca6010dd5bf', - yConfig: [ - { - color: '#e7664c', - forAccessor: '2b27c80e-a20d-46f1-8fb2-79626ef4563c', - }, - ], +const columnEventOutcomeFailure = uuidv4(); +const columnEventOutcomeFailureTimestamp = uuidv4(); + +const columnEventOutcomeSuccess = uuidv4(); +const columnEventOutcomeSuccessTimestamp = uuidv4(); +const layoutEventOutcomeSuccess = uuidv4(); +const layoutEventOutcomeFailure = uuidv4(); + +export const getKpiUserAuthenticationsAreaLensAttributes: GetLensAttributes = ({ euiTheme }) => + ({ + title: '[Host] User authentications - area ', + description: '', + visualizationType: 'lnsXY', + state: { + visualization: { + axisTitlesVisibilitySettings: { + x: false, + yLeft: false, + yRight: true, }, - ], - legend: { - isVisible: false, - position: 'right', - showSingleSeries: false, - }, - preferredSeriesType: 'area', - tickLabelsVisibilitySettings: { - x: true, - yLeft: true, - yRight: true, - }, - valueLabels: 'hide', - yLeftExtent: { - mode: 'full', - }, - yRightExtent: { - mode: 'full', - }, - }, - query: { - language: 'kuery', - query: '', - }, - filters: [ - { - $state: { - store: 'appState', + fittingFunction: 'None', + gridlinesVisibilitySettings: { + x: true, + yLeft: true, + yRight: true, }, - meta: { - alias: null, - disabled: false, - // @ts-expect-error upgrade typescript v4.9.5 - indexRefName: 'filter-index-pattern-0', - key: 'query', - negate: false, - type: 'custom', - value: '{"bool":{"filter":[{"term":{"event.category":"authentication"}}]}}', + labelsOrientation: { + x: 0, + yLeft: 0, + yRight: 0, }, - query: { - bool: { - filter: [ + layers: [ + { + accessors: [columnEventOutcomeSuccess], + layerId: layoutEventOutcomeSuccess, + layerType: 'data', + seriesType: 'area', + xAccessor: columnEventOutcomeSuccessTimestamp, + yConfig: [ { - term: { - 'event.category': 'authentication', - }, + color: euiTheme.colors.vis.euiColorVis0, + forAccessor: columnEventOutcomeSuccess, }, ], }, + { + accessors: [columnEventOutcomeFailure], + layerId: layoutEventOutcomeFailure, + layerType: 'data', + seriesType: 'area', + xAccessor: columnEventOutcomeFailureTimestamp, + yConfig: [ + { + color: euiTheme.colors.vis.euiColorVis4, + forAccessor: columnEventOutcomeFailure, + }, + ], + }, + ], + legend: { + isVisible: false, + position: 'right', + showSingleSeries: false, + }, + preferredSeriesType: 'area', + tickLabelsVisibilitySettings: { + x: true, + yLeft: true, + yRight: true, + }, + valueLabels: 'hide', + yLeftExtent: { + mode: 'full', + }, + yRightExtent: { + mode: 'full', }, }, - ], - datasourceStates: { - formBased: { - layers: { - '31213ae3-905b-4e88-b987-0cccb1f3209f': { - columnOrder: [ - '33a6163d-0c0a-451d-aa38-8ca6010dd5bf', - '2b27c80e-a20d-46f1-8fb2-79626ef4563c', - ], - columns: { - '2b27c80e-a20d-46f1-8fb2-79626ef4563c': { - customLabel: true, - dataType: 'number', - filter: { - language: 'kuery', - query: 'event.outcome: "failure" ', - }, - isBucketed: false, - label: FAIL_CHART_LABEL, - operationType: 'count', - scale: 'ratio', - sourceField: '___records___', - }, - '33a6163d-0c0a-451d-aa38-8ca6010dd5bf': { - dataType: 'date', - isBucketed: true, - label: '@timestamp', - operationType: 'date_histogram', - params: { - interval: 'auto', + query: { + language: 'kuery', + query: '', + }, + filters: [ + { + $state: { + store: 'appState', + }, + meta: { + alias: null, + disabled: false, + // @ts-expect-error upgrade typescript v4.9.5 + indexRefName: 'filter-index-pattern-0', + key: 'query', + negate: false, + type: 'custom', + value: '{"bool":{"filter":[{"term":{"event.category":"authentication"}}]}}', + }, + query: { + bool: { + filter: [ + { + term: { + 'event.category': 'authentication', + }, }, - scale: 'interval', - sourceField: '@timestamp', - }, + ], }, - incompleteColumns: {}, }, - '4590dafb-4ac7-45aa-8641-47a3ff0b817c': { - columnOrder: [ - '49a42fe6-ebe8-4adb-8eed-1966a5297b7e', - '0eb97c09-a351-4280-97da-944e4bd30dd7', - ], - columns: { - '0eb97c09-a351-4280-97da-944e4bd30dd7': { - customLabel: true, - dataType: 'number', - filter: { - language: 'kuery', - query: 'event.outcome : "success" ', + }, + ], + datasourceStates: { + formBased: { + layers: { + [layoutEventOutcomeFailure]: { + columnOrder: [columnEventOutcomeFailureTimestamp, columnEventOutcomeFailure], + columns: { + [columnEventOutcomeFailure]: { + customLabel: true, + dataType: 'number', + filter: { + language: 'kuery', + query: 'event.outcome: "failure" ', + }, + isBucketed: false, + label: FAIL_CHART_LABEL, + operationType: 'count', + scale: 'ratio', + sourceField: '___records___', + }, + [columnEventOutcomeFailureTimestamp]: { + dataType: 'date', + isBucketed: true, + label: '@timestamp', + operationType: 'date_histogram', + params: { + interval: 'auto', + }, + scale: 'interval', + sourceField: '@timestamp', }, - isBucketed: false, - label: SUCCESS_CHART_LABEL, - operationType: 'count', - scale: 'ratio', - sourceField: '___records___', }, - '49a42fe6-ebe8-4adb-8eed-1966a5297b7e': { - dataType: 'date', - isBucketed: true, - label: '@timestamp', - operationType: 'date_histogram', - params: { - interval: 'auto', + incompleteColumns: {}, + }, + [layoutEventOutcomeSuccess]: { + columnOrder: [columnEventOutcomeSuccessTimestamp, columnEventOutcomeSuccess], + columns: { + [columnEventOutcomeSuccess]: { + customLabel: true, + dataType: 'number', + filter: { + language: 'kuery', + query: 'event.outcome : "success" ', + }, + isBucketed: false, + label: SUCCESS_CHART_LABEL, + operationType: 'count', + scale: 'ratio', + sourceField: '___records___', + }, + [columnEventOutcomeSuccessTimestamp]: { + dataType: 'date', + isBucketed: true, + label: '@timestamp', + operationType: 'date_histogram', + params: { + interval: 'auto', + }, + scale: 'interval', + sourceField: '@timestamp', }, - scale: 'interval', - sourceField: '@timestamp', }, + incompleteColumns: {}, }, - incompleteColumns: {}, }, }, }, }, - }, - references: [ - { - type: 'index-pattern', - id: '{dataViewId}', - name: 'indexpattern-datasource-current-indexpattern', - }, - { - type: 'index-pattern', - id: '{dataViewId}', - name: 'indexpattern-datasource-layer-31213ae3-905b-4e88-b987-0cccb1f3209f', - }, - { - type: 'index-pattern', - id: '{dataViewId}', - name: 'indexpattern-datasource-layer-4590dafb-4ac7-45aa-8641-47a3ff0b817c', - }, - ], -} as LensAttributes; + references: [ + { + type: 'index-pattern', + id: '{dataViewId}', + name: 'indexpattern-datasource-current-indexpattern', + }, + { + type: 'index-pattern', + id: '{dataViewId}', + name: `indexpattern-datasource-layer-${layoutEventOutcomeFailure}`, + }, + { + type: 'index-pattern', + id: '{dataViewId}', + name: `indexpattern-datasource-layer-${layoutEventOutcomeSuccess}`, + }, + ], + } as LensAttributes); diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_bar.test.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_bar.test.ts index 2d6f8992b27f2..5c370cdb20f15 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_bar.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_bar.test.ts @@ -10,7 +10,18 @@ import { wrapper } from '../../mocks'; import { useLensAttributes } from '../../use_lens_attributes'; -import { kpiUserAuthenticationsBarLensAttributes } from './kpi_user_authentications_bar'; +import { getKpiUserAuthenticationsBarLensAttributes } from './kpi_user_authentications_bar'; + +jest.mock('uuid', () => ({ + v4: jest + .fn() + .mockReturnValueOnce('c8165fc3-7180-4f1b-8c87-bc3ea04c6df7') + .mockReturnValueOnce('e959c351-a3a2-4525-b244-9623f215a8fd') + .mockReturnValueOnce('938b445a-a291-4bbc-84fe-4f47b69c20e4') + .mockReturnValueOnce('430e690c-9992-414f-9bce-00812d99a5e7') + .mockReturnValueOnce('b9acd453-f476-4467-ad38-203e37b73e55') + .mockReturnValueOnce('31213ae3-905b-4e88-b987-0cccb1f3209f'), +})); jest.mock('../../../../../sourcerer/containers', () => ({ useSourcererDataView: jest.fn().mockReturnValue({ @@ -31,12 +42,12 @@ jest.mock('../../../../utils/route/use_route_spy', () => ({ ]), })); -describe('kpiUserAuthenticationsBarLensAttributes', () => { +describe('getKpiUserAuthenticationsBarLensAttributes', () => { it('should render', () => { const { result } = renderHook( () => useLensAttributes({ - lensAttributes: kpiUserAuthenticationsBarLensAttributes, + getLensAttributes: getKpiUserAuthenticationsBarLensAttributes, stackByField: 'event.dataset', }), { wrapper } diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_bar.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_bar.ts index ff6937b1e43e4..6237b1827314d 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_bar.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_bar.ts @@ -4,199 +4,208 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - -import type { LensAttributes } from '../../types'; +import { v4 as uuidv4 } from 'uuid'; +import type { LensAttributes, GetLensAttributes } from '../../types'; import { FAIL_CHART_LABEL, SUCCESS_CHART_LABEL } from '../../translations'; -export const kpiUserAuthenticationsBarLensAttributes: LensAttributes = { - title: '[Host] User authentications - bar ', - description: '', - visualizationType: 'lnsXY', - state: { - visualization: { - axisTitlesVisibilitySettings: { - x: false, - yLeft: false, - yRight: true, - }, - fittingFunction: 'None', - gridlinesVisibilitySettings: { - x: true, - yLeft: true, - yRight: true, - }, - labelsOrientation: { - x: 0, - yLeft: 0, - yRight: 0, - }, - layers: [ - { - accessors: ['938b445a-a291-4bbc-84fe-4f47b69c20e4'], - layerId: '31213ae3-905b-4e88-b987-0cccb1f3209f', - layerType: 'data', - seriesType: 'bar_horizontal_stacked', - xAccessor: '430e690c-9992-414f-9bce-00812d99a5e7', - yConfig: [], +const columnEventOutcomeFailure = uuidv4(); +const columnEventOutcomeFailureFilter = uuidv4(); + +const columnEventOutcomeSuccess = uuidv4(); +const columnEventOutcomeSuccessFilter = uuidv4(); + +const layerEventOutcomeFailure = uuidv4(); +const layerEventOutcomeSuccess = uuidv4(); + +export const getKpiUserAuthenticationsBarLensAttributes: GetLensAttributes = ({ euiTheme }) => + ({ + title: '[Host] User authentications - bar ', + description: '', + visualizationType: 'lnsXY', + state: { + visualization: { + axisTitlesVisibilitySettings: { + x: false, + yLeft: false, + yRight: true, }, - { - accessors: ['c8165fc3-7180-4f1b-8c87-bc3ea04c6df7'], - layerId: 'b9acd453-f476-4467-ad38-203e37b73e55', - layerType: 'data', - seriesType: 'bar_horizontal_stacked', - xAccessor: 'e959c351-a3a2-4525-b244-9623f215a8fd', - yConfig: [ - { - color: '#e7664c', - forAccessor: 'c8165fc3-7180-4f1b-8c87-bc3ea04c6df7', - }, - ], + fittingFunction: 'None', + gridlinesVisibilitySettings: { + x: true, + yLeft: true, + yRight: true, }, - ], - legend: { - isVisible: false, - position: 'right', - showSingleSeries: false, - }, - preferredSeriesType: 'bar_horizontal_stacked', - tickLabelsVisibilitySettings: { - x: true, - yLeft: true, - yRight: true, - }, - valueLabels: 'hide', - yLeftExtent: { - mode: 'full', - }, - yRightExtent: { - mode: 'full', - }, - }, - query: { - language: 'kuery', - query: '', - }, - filters: [ - { - $state: { - store: 'appState', + labelsOrientation: { + x: 0, + yLeft: 0, + yRight: 0, }, - meta: { - alias: null, - disabled: false, - // @ts-expect-error upgrade typescript v4.9.5 - indexRefName: 'filter-index-pattern-0', - key: 'query', - negate: false, - type: 'custom', - value: '{"bool":{"filter":[{"term":{"event.category":"authentication"}}]}}', - }, - query: { - bool: { - filter: [ + layers: [ + { + accessors: [columnEventOutcomeSuccess], + layerId: layerEventOutcomeSuccess, + layerType: 'data', + seriesType: 'bar_horizontal_stacked', + xAccessor: columnEventOutcomeSuccessFilter, + yConfig: [ { - term: { - 'event.category': 'authentication', - }, + color: euiTheme.colors.vis.euiColorVis0, + forAccessor: columnEventOutcomeSuccess, }, ], }, + { + accessors: [columnEventOutcomeFailure], + layerId: layerEventOutcomeFailure, + layerType: 'data', + seriesType: 'bar_horizontal_stacked', + xAccessor: columnEventOutcomeFailureFilter, + yConfig: [ + { + color: euiTheme.colors.vis.euiColorVis4, + forAccessor: columnEventOutcomeFailure, + }, + ], + }, + ], + legend: { + isVisible: false, + position: 'right', + showSingleSeries: false, + }, + preferredSeriesType: 'bar_horizontal_stacked', + tickLabelsVisibilitySettings: { + x: true, + yLeft: true, + yRight: true, + }, + valueLabels: 'hide', + yLeftExtent: { + mode: 'full', + }, + yRightExtent: { + mode: 'full', }, }, - ], - datasourceStates: { - formBased: { - layers: { - '31213ae3-905b-4e88-b987-0cccb1f3209f': { - columnOrder: [ - '430e690c-9992-414f-9bce-00812d99a5e7', - '938b445a-a291-4bbc-84fe-4f47b69c20e4', - ], - columns: { - '430e690c-9992-414f-9bce-00812d99a5e7': { - dataType: 'string', - isBucketed: true, - label: 'Filters', - operationType: 'filters', - params: { - filters: [ - { - input: { - language: 'kuery', - query: 'event.outcome : "success" ', - }, - label: SUCCESS_CHART_LABEL, - }, - ], + query: { + language: 'kuery', + query: '', + }, + filters: [ + { + $state: { + store: 'appState', + }, + meta: { + alias: null, + disabled: false, + // @ts-expect-error upgrade typescript v4.9.5 + indexRefName: 'filter-index-pattern-0', + key: 'query', + negate: false, + type: 'custom', + value: '{"bool":{"filter":[{"term":{"event.category":"authentication"}}]}}', + }, + query: { + bool: { + filter: [ + { + term: { + 'event.category': 'authentication', + }, }, - scale: 'ordinal', - }, - '938b445a-a291-4bbc-84fe-4f47b69c20e4': { - dataType: 'number', - isBucketed: false, - label: SUCCESS_CHART_LABEL, - operationType: 'count', - scale: 'ratio', - sourceField: '___records___', - }, + ], }, - incompleteColumns: {}, }, - 'b9acd453-f476-4467-ad38-203e37b73e55': { - columnOrder: [ - 'e959c351-a3a2-4525-b244-9623f215a8fd', - 'c8165fc3-7180-4f1b-8c87-bc3ea04c6df7', - ], - columns: { - 'c8165fc3-7180-4f1b-8c87-bc3ea04c6df7': { - dataType: 'number', - isBucketed: false, - label: 'Fail', - operationType: 'count', - scale: 'ratio', - sourceField: '___records___', + }, + ], + datasourceStates: { + formBased: { + layers: { + [layerEventOutcomeSuccess]: { + columnOrder: [columnEventOutcomeSuccessFilter, columnEventOutcomeSuccess], + columns: { + [columnEventOutcomeSuccessFilter]: { + dataType: 'string', + isBucketed: true, + label: 'Filters', + operationType: 'filters', + params: { + filters: [ + { + input: { + language: 'kuery', + query: 'event.outcome : "success" ', + }, + label: SUCCESS_CHART_LABEL, + }, + ], + }, + scale: 'ordinal', + }, + [columnEventOutcomeSuccess]: { + dataType: 'number', + isBucketed: false, + label: SUCCESS_CHART_LABEL, + operationType: 'count', + scale: 'ratio', + sourceField: '___records___', + }, }, - 'e959c351-a3a2-4525-b244-9623f215a8fd': { - customLabel: true, - dataType: 'string', - isBucketed: true, - label: FAIL_CHART_LABEL, - operationType: 'filters', - params: { - filters: [ - { - input: { - language: 'kuery', - query: 'event.outcome:"failure" ', + incompleteColumns: {}, + }, + [layerEventOutcomeFailure]: { + columnOrder: [columnEventOutcomeFailureFilter, columnEventOutcomeFailure], + columns: { + [columnEventOutcomeFailure]: { + dataType: 'number', + isBucketed: false, + label: 'Fail', + operationType: 'count', + scale: 'ratio', + sourceField: '___records___', + }, + [columnEventOutcomeFailureFilter]: { + customLabel: true, + dataType: 'string', + isBucketed: true, + label: FAIL_CHART_LABEL, + operationType: 'filters', + params: { + filters: [ + { + input: { + language: 'kuery', + query: 'event.outcome:"failure" ', + }, + label: FAIL_CHART_LABEL, }, - label: FAIL_CHART_LABEL, - }, - ], + ], + }, + scale: 'ordinal', }, - scale: 'ordinal', }, + incompleteColumns: {}, }, - incompleteColumns: {}, }, }, }, }, - }, - references: [ - { - type: 'index-pattern', - id: '{dataViewId}', - name: 'indexpattern-datasource-current-indexpattern', - }, - { - type: 'index-pattern', - id: '{dataViewId}', - name: 'indexpattern-datasource-layer-31213ae3-905b-4e88-b987-0cccb1f3209f', - }, - { - type: 'index-pattern', - id: '{dataViewId}', - name: 'indexpattern-datasource-layer-b9acd453-f476-4467-ad38-203e37b73e55', - }, - ], -} as LensAttributes; + references: [ + { + type: 'index-pattern', + id: '{dataViewId}', + name: 'indexpattern-datasource-current-indexpattern', + }, + { + type: 'index-pattern', + id: '{dataViewId}', + name: `indexpattern-datasource-layer-${layerEventOutcomeSuccess}`, + }, + { + type: 'index-pattern', + id: '{dataViewId}', + name: `indexpattern-datasource-layer-${layerEventOutcomeFailure}`, + }, + ], + } as LensAttributes); diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/types.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/types.ts index f6a90ebfd479b..07fe2d96f2f77 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/types.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/types.ts @@ -17,15 +17,19 @@ import type { Action } from '@kbn/ui-actions-plugin/public'; import type { Filter, Query } from '@kbn/es-query'; import type { LensProps } from '@kbn/cases-plugin/public/types'; +import type { EuiThemeComputed } from '@elastic/eui'; import type { InputsModelId } from '../../store/inputs/constants'; import type { SourcererScopeName } from '../../../sourcerer/store/model'; import type { Status } from '../../../../common/api/detection_engine'; +export type ColorSchemas = Record; + export type LensAttributes = TypedLensByValueInput['attributes']; -export type GetLensAttributes = ( - stackByField?: string, - extraOptions?: ExtraOptions -) => LensAttributes; +export type GetLensAttributes = (params: { + stackByField?: string; + euiTheme: EuiThemeComputed; + extraOptions?: ExtraOptions; +}) => LensAttributes; export interface UseLensAttributesProps { applyGlobalQueriesAndFilters?: boolean; diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/use_lens_attributes.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/use_lens_attributes.test.tsx index 341fcab3c567d..300920c5de320 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/use_lens_attributes.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/use_lens_attributes.test.tsx @@ -24,12 +24,24 @@ import { useRouteSpy } from '../../utils/route/use_route_spy'; import { SecurityPageName } from '../../../app/types'; import type { Query } from '@kbn/es-query'; import { getEventsHistogramLensAttributes } from './lens_attributes/common/events'; +import type { EuiThemeComputed } from '@elastic/eui'; + +jest.mock('uuid', () => ({ + v4: jest + .fn() + .mockReturnValueOnce('a3c54471-615f-4ff9-9fda-69b5b2ea3eef') + .mockReturnValueOnce('37bdf546-3c11-4b08-8c5d-e37debc44f1d') + .mockReturnValueOnce('0a923af2-c880-4aa3-aa93-a0b9c2801f6d') + .mockReturnValueOnce('42334c6e-98d9-47a2-b4cb-a445abb44c93'), +})); jest.mock('../../../sourcerer/containers'); jest.mock('../../utils/route/use_route_spy', () => ({ useRouteSpy: jest.fn(), })); - +const params = { + euiTheme: {} as EuiThemeComputed, +}; describe('useLensAttributes', () => { beforeEach(() => { (useSourcererDataView as jest.Mock).mockReturnValue({ @@ -71,7 +83,7 @@ describe('useLensAttributes', () => { ); expect(result?.current?.state.filters).toEqual([ - ...getExternalAlertLensAttributes().state.filters, + ...getExternalAlertLensAttributes(params).state.filters, ...getDetailsPageFilter('hosts', 'mockHost'), ...fieldNameExistsFilter('hosts'), ...getIndexFilters(['auditbeat-*']), @@ -97,7 +109,7 @@ describe('useLensAttributes', () => { ); expect(result?.current?.state.filters).toEqual([ - ...getExternalAlertLensAttributes().state.filters, + ...getExternalAlertLensAttributes(params).state.filters, ...getNetworkDetailsPageFilter('192.168.1.1'), ...sourceOrDestinationIpExistsFilter, ...getIndexFilters(['auditbeat-*']), @@ -123,7 +135,7 @@ describe('useLensAttributes', () => { ); expect(result?.current?.state.filters).toEqual([ - ...getExternalAlertLensAttributes().state.filters, + ...getExternalAlertLensAttributes(params).state.filters, ...getDetailsPageFilter('user', 'elastic'), ...getIndexFilters(['auditbeat-*']), ...filterFromSearchBar, @@ -151,7 +163,7 @@ describe('useLensAttributes', () => { expect((result?.current?.state.query as Query).query).toEqual(''); expect(result?.current?.state.filters).toEqual([ - ...getExternalAlertLensAttributes().state.filters, + ...getExternalAlertLensAttributes(params).state.filters, ...getIndexFilters(['auditbeat-*']), ]); }); @@ -175,7 +187,7 @@ describe('useLensAttributes', () => { ); expect(result?.current?.state.filters).toEqual([ - ...getExternalAlertLensAttributes().state.filters, + ...getExternalAlertLensAttributes(params).state.filters, ...getIndexFilters(['auditbeat-*']), ...filterFromSearchBar, ]); diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/use_lens_attributes.tsx b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/use_lens_attributes.tsx index 6a227c84681b1..df52183c06845 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/use_lens_attributes.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/visualization_actions/use_lens_attributes.tsx @@ -6,6 +6,7 @@ */ import { useMemo } from 'react'; +import { useEuiTheme } from '@elastic/eui'; import { SecurityPageName } from '../../../../common/constants'; import { NetworkRouteType } from '../../../explore/network/pages/navigation/types'; import { useSourcererDataView } from '../../../sourcerer/containers'; @@ -32,6 +33,7 @@ export const useLensAttributes = ({ stackByField, title, }: UseLensAttributesProps): LensAttributes | null => { + const { euiTheme } = useEuiTheme(); const { selectedPatterns, dataViewId, indicesExist } = useSourcererDataView(scopeId); const getGlobalQuerySelector = useMemo(() => inputsSelectors.globalQuerySelector(), []); const getGlobalFiltersQuerySelector = useMemo( @@ -73,8 +75,8 @@ export const useLensAttributes = ({ lensAttributes ?? ((getLensAttributes && stackByField !== null && - getLensAttributes(stackByField, extraOptions)) as LensAttributes), - [extraOptions, getLensAttributes, lensAttributes, stackByField] + getLensAttributes({ stackByField, euiTheme, extraOptions })) as LensAttributes), + [euiTheme, extraOptions, getLensAttributes, lensAttributes, stackByField] ); const hasAdHocDataViews = Object.values(attrs?.state?.adHocDataViews ?? {}).length > 0; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/grouping_settings/group_panel_renderers.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/grouping_settings/group_panel_renderers.tsx index cd858b74399a2..d5696d3077a69 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/grouping_settings/group_panel_renderers.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/grouping_settings/group_panel_renderers.tsx @@ -15,6 +15,7 @@ import { EuiText, EuiTextColor, EuiTitle, + useEuiTheme, } from '@elastic/eui'; import { euiThemeVars } from '@kbn/ui-theme'; import { isArray } from 'lodash/fp'; @@ -94,40 +95,45 @@ const RuleNameGroupContent = React.memo<{ RuleNameGroupContent.displayName = 'RuleNameGroup'; const HostNameGroupContent = React.memo<{ hostName: string | string[]; nullGroupMessage?: string }>( - ({ hostName, nullGroupMessage }) => ( - - - - + ({ hostName, nullGroupMessage }) => { + const { euiTheme } = useEuiTheme(); + return ( + + + + - - -
{hostName}
-
-
- {nullGroupMessage && ( - + +
{hostName}
+
- )} -
- ) + {nullGroupMessage && ( + + + + )} +
+ ); + } ); HostNameGroupContent.displayName = 'HostNameGroupContent'; const UserNameGroupContent = React.memo<{ userName: string | string[]; nullGroupMessage?: string }>( ({ userName, nullGroupMessage }) => { const userNameValue = firstNonNullValue(userName) ?? '-'; + const { euiTheme } = useEuiTheme(); + return ( - + diff --git a/x-pack/solutions/security/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_donut.ts b/x-pack/solutions/security/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_donut.ts index ea06d4dcdb567..d15ebb32987bf 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_donut.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_donut.ts @@ -10,10 +10,10 @@ import type { GetLensAttributes } from '../../common/components/visualization_ac const internalReferenceIdMapping: Record = { host: uuidv4(), user: uuidv4() }; -export const getRiskScoreDonutAttributes: GetLensAttributes = ( +export const getRiskScoreDonutAttributes: GetLensAttributes = ({ stackByField = 'host', - extraOptions = { spaceId: 'default' } -) => { + extraOptions = { spaceId: 'default' }, +}) => { const layerId = uuidv4(); const internalReferenceId = internalReferenceIdMapping[stackByField]; return { diff --git a/x-pack/solutions/security/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_over_time_area.ts b/x-pack/solutions/security/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_over_time_area.ts index 06bebcb4e1339..19534279ee337 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_over_time_area.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_over_time_area.ts @@ -10,10 +10,10 @@ import type { GetLensAttributes } from '../../common/components/visualization_ac const internalReferenceIdMapping: Record = { host: uuidv4(), user: uuidv4() }; -export const getRiskScoreOverTimeAreaAttributes: GetLensAttributes = ( +export const getRiskScoreOverTimeAreaAttributes: GetLensAttributes = ({ stackByField = 'host', - extraOptions = { spaceId: 'default' } -) => { + extraOptions = { spaceId: 'default' }, +}) => { const layerIds = [uuidv4(), uuidv4()]; const layer2ColumnId = uuidv4(); const internalReferenceId = internalReferenceIdMapping[stackByField]; diff --git a/x-pack/solutions/security/plugins/security_solution/public/explore/components/authentication/helpers.tsx b/x-pack/solutions/security/plugins/security_solution/public/explore/components/authentication/helpers.tsx index 80b5924860ecb..f9dcc97a2976a 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/explore/components/authentication/helpers.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/explore/components/authentication/helpers.tsx @@ -24,8 +24,7 @@ import type { MatrixHistogramConfigs, MatrixHistogramOption, } from '../../../common/components/matrix_histogram/types'; -import type { LensAttributes } from '../../../common/components/visualization_actions/types'; -import { authenticationLensAttributes } from '../../../common/components/visualization_actions/lens_attributes/common/authentication'; +import { getAuthenticationLensAttributes } from '../../../common/components/visualization_actions/lens_attributes/common/authentication'; export const getHostDetailsAuthenticationColumns = (): AuthTableColumns => [ USER_COLUMN, @@ -199,5 +198,5 @@ export const histogramConfigs: MatrixHistogramConfigs = { authenticationsStackByOptions[0], stackByOptions: authenticationsStackByOptions, title: i18n.NAVIGATION_AUTHENTICATIONS_TITLE, - lensAttributes: authenticationLensAttributes as LensAttributes, + getLensAttributes: getAuthenticationLensAttributes, }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/explore/components/stat_items/stat_items.tsx b/x-pack/solutions/security/plugins/security_solution/public/explore/components/stat_items/stat_items.tsx index 570ffadca64e7..fe1a5b6764f05 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/explore/components/stat_items/stat_items.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/explore/components/stat_items/stat_items.tsx @@ -29,8 +29,8 @@ export const StatItemsComponent = React.memo(({ statItems, from, enableAreaChart, enableBarChart, fields, - barChartLensAttributes, - areaChartLensAttributes, + getBarChartLensAttributes, + getAreaChartLensAttributes, } = statItems; const { isToggleExpanded, onToggle } = useToggleStatus({ id }); @@ -59,7 +59,7 @@ export const StatItemsComponent = React.memo(({ statItems, from, (({ statItems, from, { render(, { wrapper: TestProviders, }); - expect(MockKpiBaseComponent.mock.calls[0][0].statItems).toEqual(hostsStatItems); expect(MockKpiBaseComponent.mock.calls[0][0].from).toEqual(from); expect(MockKpiBaseComponent.mock.calls[0][0].to).toEqual(to); }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/explore/hosts/components/kpi_hosts/hosts/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/explore/hosts/components/kpi_hosts/hosts/index.tsx index 04ceab7438059..1b4cfdf401843 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/explore/hosts/components/kpi_hosts/hosts/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/explore/hosts/components/kpi_hosts/hosts/index.tsx @@ -5,36 +5,43 @@ * 2.0. */ -import React from 'react'; +import React, { useMemo } from 'react'; +import { useEuiTheme } from '@elastic/eui'; import type { StatItems } from '../../../../components/stat_items'; -import { kpiHostAreaLensAttributes } from '../../../../../common/components/visualization_actions/lens_attributes/hosts/kpi_host_area'; +import { getKpiHostAreaLensAttributes } from '../../../../../common/components/visualization_actions/lens_attributes/hosts/kpi_host_area'; import { kpiHostMetricLensAttributes } from '../../../../../common/components/visualization_actions/lens_attributes/hosts/kpi_host_metric'; import { KpiBaseComponent } from '../../../../components/kpi'; import type { HostsKpiProps } from '../types'; -import { HostsKpiChartColors } from '../types'; import * as i18n from './translations'; export const ID = 'hostsKpiHostsQuery'; -export const hostsStatItems: Readonly = [ - { - key: 'hosts', - fields: [ +export const useGetHostsStatItems: () => Readonly = () => { + const { euiTheme } = useEuiTheme(); + return useMemo( + () => [ { key: 'hosts', - color: HostsKpiChartColors.hosts, - icon: 'storage', - lensAttributes: kpiHostMetricLensAttributes, + fields: [ + { + key: 'hosts', + color: euiTheme.colors.vis.euiColorVis1, + icon: 'storage', + lensAttributes: kpiHostMetricLensAttributes, + }, + ], + enableAreaChart: true, + description: i18n.HOSTS, + getAreaChartLensAttributes: getKpiHostAreaLensAttributes, }, ], - enableAreaChart: true, - description: i18n.HOSTS, - areaChartLensAttributes: kpiHostAreaLensAttributes, - }, -]; + [euiTheme.colors.vis.euiColorVis1] + ); +}; const HostsKpiHostsComponent: React.FC = ({ from, to }) => { + const hostsStatItems = useGetHostsStatItems(); return ; }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/explore/hosts/components/kpi_hosts/types.ts b/x-pack/solutions/security/plugins/security_solution/public/explore/hosts/components/kpi_hosts/types.ts index b58367832f850..1bd94d21c4607 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/explore/hosts/components/kpi_hosts/types.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/explore/hosts/components/kpi_hosts/types.ts @@ -9,9 +9,3 @@ export interface HostsKpiProps { from: string; to: string; } - -export enum HostsKpiChartColors { - uniqueSourceIps = '#D36086', - uniqueDestinationIps = '#9170B8', - hosts = '#6092C0', -} diff --git a/x-pack/solutions/security/plugins/security_solution/public/explore/hosts/components/kpi_hosts/unique_ips/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/explore/hosts/components/kpi_hosts/unique_ips/index.test.tsx index 2fbb35328286d..f86a8b88e863c 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/explore/hosts/components/kpi_hosts/unique_ips/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/explore/hosts/components/kpi_hosts/unique_ips/index.test.tsx @@ -8,7 +8,7 @@ import { render } from '@testing-library/react'; import { TestProviders } from '../../../../../common/mock'; import React from 'react'; -import { uniqueIpsStatItems, HostsKpiUniqueIps } from '.'; +import { HostsKpiUniqueIps } from '.'; import { KpiBaseComponent } from '../../../../components/kpi'; jest.mock('../../../../components/kpi'); @@ -26,7 +26,6 @@ describe('Hosts KPI', () => { render(, { wrapper: TestProviders, }); - expect(MockKpiBaseComponent.mock.calls[0][0].statItems).toEqual(uniqueIpsStatItems); expect(MockKpiBaseComponent.mock.calls[0][0].from).toEqual(from); expect(MockKpiBaseComponent.mock.calls[0][0].to).toEqual(to); }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/explore/hosts/components/kpi_hosts/unique_ips/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/explore/hosts/components/kpi_hosts/unique_ips/index.tsx index 41e7cb5c12413..4dc8e9fd62b66 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/explore/hosts/components/kpi_hosts/unique_ips/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/explore/hosts/components/kpi_hosts/unique_ips/index.tsx @@ -5,50 +5,57 @@ * 2.0. */ -import React from 'react'; +import React, { useMemo } from 'react'; +import { useEuiTheme } from '@elastic/eui'; import type { StatItems } from '../../../../components/stat_items'; -import { kpiUniqueIpsAreaLensAttributes } from '../../../../../common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_area'; -import { kpiUniqueIpsBarLensAttributes } from '../../../../../common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_bar'; +import { getKpiUniqueIpsAreaLensAttributes } from '../../../../../common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_area'; +import { getKpiUniqueIpsBarLensAttributes } from '../../../../../common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_bar'; import { kpiUniqueIpsDestinationMetricLensAttributes } from '../../../../../common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_destination_metric'; import { kpiUniqueIpsSourceMetricLensAttributes } from '../../../../../common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_source_metric'; import { KpiBaseComponent } from '../../../../components/kpi'; import type { HostsKpiProps } from '../types'; -import { HostsKpiChartColors } from '../types'; import * as i18n from './translations'; export const ID = 'hostsKpiUniqueIpsQuery'; -export const uniqueIpsStatItems: Readonly = [ - { - key: 'uniqueIps', - fields: [ +export const useGetUniqueIpsStatItems: () => Readonly = () => { + const { euiTheme } = useEuiTheme(); + return useMemo( + () => [ { - key: 'uniqueSourceIps', - name: i18n.SOURCE_CHART_LABEL, - description: i18n.SOURCE_UNIT_LABEL, - color: HostsKpiChartColors.uniqueSourceIps, - icon: 'visMapCoordinate', - lensAttributes: kpiUniqueIpsSourceMetricLensAttributes, - }, - { - key: 'uniqueDestinationIps', - name: i18n.DESTINATION_CHART_LABEL, - description: i18n.DESTINATION_UNIT_LABEL, - color: HostsKpiChartColors.uniqueDestinationIps, - icon: 'visMapCoordinate', - lensAttributes: kpiUniqueIpsDestinationMetricLensAttributes, + key: 'uniqueIps', + fields: [ + { + key: 'uniqueSourceIps', + name: i18n.SOURCE_CHART_LABEL, + description: i18n.SOURCE_UNIT_LABEL, + color: euiTheme.colors.vis.euiColorVis4, + icon: 'visMapCoordinate', + lensAttributes: kpiUniqueIpsSourceMetricLensAttributes, + }, + { + key: 'uniqueDestinationIps', + name: i18n.DESTINATION_CHART_LABEL, + description: i18n.DESTINATION_UNIT_LABEL, + color: euiTheme.colors.vis.euiColorVis2, + icon: 'visMapCoordinate', + lensAttributes: kpiUniqueIpsDestinationMetricLensAttributes, + }, + ], + enableAreaChart: true, + enableBarChart: true, + description: i18n.UNIQUE_IPS, + getAreaChartLensAttributes: getKpiUniqueIpsAreaLensAttributes, + getBarChartLensAttributes: getKpiUniqueIpsBarLensAttributes, }, ], - enableAreaChart: true, - enableBarChart: true, - description: i18n.UNIQUE_IPS, - areaChartLensAttributes: kpiUniqueIpsAreaLensAttributes, - barChartLensAttributes: kpiUniqueIpsBarLensAttributes, - }, -]; + [euiTheme.colors.vis.euiColorVis2, euiTheme.colors.vis.euiColorVis4] + ); +}; const HostsKpiUniqueIpsComponent: React.FC = ({ from, to }) => { + const uniqueIpsStatItems = useGetUniqueIpsStatItems(); return ; }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/explore/network/components/kpi_network/network_events/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/explore/network/components/kpi_network/network_events/index.test.tsx index f0757a7c07cc4..897bfb309b8c7 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/explore/network/components/kpi_network/network_events/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/explore/network/components/kpi_network/network_events/index.test.tsx @@ -8,7 +8,7 @@ import { render } from '@testing-library/react'; import { TestProviders } from '../../../../../common/mock'; import React from 'react'; -import { networkEventsStatsItems, NetworkKpiNetworkEvents } from '.'; +import { NetworkKpiNetworkEvents } from '.'; import { KpiBaseComponent } from '../../../../components/kpi'; jest.mock('../../../../components/kpi'); @@ -26,7 +26,6 @@ describe('Network events KPI', () => { render(, { wrapper: TestProviders, }); - expect(MockKpiBaseComponent.mock.calls[0][0].statItems).toEqual(networkEventsStatsItems); expect(MockKpiBaseComponent.mock.calls[0][0].from).toEqual(from); expect(MockKpiBaseComponent.mock.calls[0][0].to).toEqual(to); }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/explore/network/components/kpi_network/network_events/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/explore/network/components/kpi_network/network_events/index.tsx index 31b3396a567d3..88c275d2e56ec 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/explore/network/components/kpi_network/network_events/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/explore/network/components/kpi_network/network_events/index.tsx @@ -5,9 +5,9 @@ * 2.0. */ -import React from 'react'; -import { euiPaletteColorBlind } from '@elastic/eui'; +import React, { useMemo } from 'react'; +import { useEuiTheme } from '@elastic/eui'; import type { StatItems } from '../../../../components/stat_items'; import type { NetworkKpiProps } from '../types'; import * as i18n from './translations'; @@ -16,24 +16,28 @@ import { KpiBaseComponent } from '../../../../components/kpi'; export const ID = 'networkKpiNetworkEventsQuery'; -const euiVisColorPalette = euiPaletteColorBlind(); -const euiColorVis1 = euiVisColorPalette[1]; - -export const networkEventsStatsItems: Readonly = [ - { - key: 'networkEvents', - fields: [ +const useGetNetworkEventsStatsItems: () => Readonly = () => { + const { euiTheme } = useEuiTheme(); + return useMemo( + () => [ { key: 'networkEvents', - color: euiColorVis1, - lensAttributes: kpiNetworkEventsLensAttributes, + fields: [ + { + key: 'networkEvents', + color: euiTheme.colors.vis.euiColorVis1, + lensAttributes: kpiNetworkEventsLensAttributes, + }, + ], + description: i18n.NETWORK_EVENTS, }, ], - description: i18n.NETWORK_EVENTS, - }, -]; + [euiTheme.colors.vis.euiColorVis1] + ); +}; const NetworkKpiNetworkEventsComponent: React.FC = ({ from, to }) => { + const networkEventsStatsItems = useGetNetworkEventsStatsItems(); return ; }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/explore/network/components/kpi_network/unique_private_ips/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/explore/network/components/kpi_network/unique_private_ips/index.test.tsx index d19ae024fdaa4..3965db7356b01 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/explore/network/components/kpi_network/unique_private_ips/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/explore/network/components/kpi_network/unique_private_ips/index.test.tsx @@ -8,7 +8,7 @@ import { render } from '@testing-library/react'; import { TestProviders } from '../../../../../common/mock'; import React from 'react'; -import { uniquePrivateIpsStatItems, NetworkKpiUniquePrivateIps } from '.'; +import { NetworkKpiUniquePrivateIps } from '.'; import { KpiBaseComponent } from '../../../../components/kpi'; jest.mock('../../../../components/kpi'); @@ -26,7 +26,6 @@ describe('Network unique private ips KPI', () => { render(, { wrapper: TestProviders, }); - expect(MockKpiBaseComponent.mock.calls[0][0].statItems).toEqual(uniquePrivateIpsStatItems); expect(MockKpiBaseComponent.mock.calls[0][0].from).toEqual(from); expect(MockKpiBaseComponent.mock.calls[0][0].to).toEqual(to); }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/explore/network/components/kpi_network/unique_private_ips/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/explore/network/components/kpi_network/unique_private_ips/index.tsx index 2c84c27899084..b53804076b67c 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/explore/network/components/kpi_network/unique_private_ips/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/explore/network/components/kpi_network/unique_private_ips/index.tsx @@ -5,53 +5,57 @@ * 2.0. */ -import React from 'react'; -import { euiPaletteColorBlind } from '@elastic/eui'; +import React, { useMemo } from 'react'; +import { useEuiTheme } from '@elastic/eui'; import type { StatItems } from '../../../../components/stat_items'; import type { NetworkKpiProps } from '../types'; import * as i18n from './translations'; import { kpiUniquePrivateIpsSourceMetricLensAttributes } from '../../../../../common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_source_metric'; import { kpiUniquePrivateIpsDestinationMetricLensAttributes } from '../../../../../common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_destination_metric'; -import { kpiUniquePrivateIpsAreaLensAttributes } from '../../../../../common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_area'; -import { kpiUniquePrivateIpsBarLensAttributes } from '../../../../../common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_bar'; +import { getKpiUniquePrivateIpsAreaLensAttributes } from '../../../../../common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_area'; +import { getKpiUniquePrivateIpsBarLensAttributes } from '../../../../../common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_bar'; import { KpiBaseComponent } from '../../../../components/kpi'; -const euiVisColorPalette = euiPaletteColorBlind(); -const euiColorVis2 = euiVisColorPalette[2]; -const euiColorVis3 = euiVisColorPalette[3]; export const ID = 'networkKpiUniquePrivateIpsQuery'; -export const uniquePrivateIpsStatItems: Readonly = [ - { - key: 'uniqueIps', - fields: [ +export const useGetUniquePrivateIpsStatItems: () => Readonly = () => { + const { euiTheme } = useEuiTheme(); + return useMemo( + () => [ { - key: 'uniqueSourcePrivateIps', - name: i18n.SOURCE_CHART_LABEL, - description: i18n.SOURCE_UNIT_LABEL, - color: euiColorVis2, - icon: 'visMapCoordinate', - lensAttributes: kpiUniquePrivateIpsSourceMetricLensAttributes, - }, - { - key: 'uniqueDestinationPrivateIps', - name: i18n.DESTINATION_CHART_LABEL, - description: i18n.DESTINATION_UNIT_LABEL, - color: euiColorVis3, - icon: 'visMapCoordinate', - lensAttributes: kpiUniquePrivateIpsDestinationMetricLensAttributes, + key: 'uniqueIps', + fields: [ + { + key: 'uniqueSourcePrivateIps', + name: i18n.SOURCE_CHART_LABEL, + description: i18n.SOURCE_UNIT_LABEL, + color: euiTheme.colors.vis.euiColorVis4, + icon: 'visMapCoordinate', + lensAttributes: kpiUniquePrivateIpsSourceMetricLensAttributes, + }, + { + key: 'uniqueDestinationPrivateIps', + name: i18n.DESTINATION_CHART_LABEL, + description: i18n.DESTINATION_UNIT_LABEL, + color: euiTheme.colors.vis.euiColorVis2, + icon: 'visMapCoordinate', + lensAttributes: kpiUniquePrivateIpsDestinationMetricLensAttributes, + }, + ], + description: i18n.UNIQUE_PRIVATE_IPS, + enableAreaChart: true, + enableBarChart: true, + getAreaChartLensAttributes: getKpiUniquePrivateIpsAreaLensAttributes, + getBarChartLensAttributes: getKpiUniquePrivateIpsBarLensAttributes, }, ], - description: i18n.UNIQUE_PRIVATE_IPS, - enableAreaChart: true, - enableBarChart: true, - areaChartLensAttributes: kpiUniquePrivateIpsAreaLensAttributes, - barChartLensAttributes: kpiUniquePrivateIpsBarLensAttributes, - }, -]; + [euiTheme.colors.vis.euiColorVis2, euiTheme.colors.vis.euiColorVis4] + ); +}; const NetworkKpiUniquePrivateIpsComponent: React.FC = ({ from, to }) => { + const uniquePrivateIpsStatItems = useGetUniquePrivateIpsStatItems(); return ; }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/explore/users/components/kpi_users/authentications/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/explore/users/components/kpi_users/authentications/index.test.tsx index 2697e4675e4c3..c59a4f934c2f6 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/explore/users/components/kpi_users/authentications/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/explore/users/components/kpi_users/authentications/index.test.tsx @@ -8,7 +8,7 @@ import { render } from '@testing-library/react'; import { TestProviders } from '../../../../../common/mock'; import React from 'react'; -import { authenticationsStatItems, UsersKpiAuthentications } from '.'; +import { UsersKpiAuthentications } from '.'; import { KpiBaseComponent } from '../../../../components/kpi'; jest.mock('../../../../components/kpi'); @@ -26,7 +26,6 @@ describe('User authentications KPI', () => { render(, { wrapper: TestProviders, }); - expect(MockKpiBaseComponent.mock.calls[0][0].statItems).toEqual(authenticationsStatItems); expect(MockKpiBaseComponent.mock.calls[0][0].from).toEqual(from); expect(MockKpiBaseComponent.mock.calls[0][0].to).toEqual(to); }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/explore/users/components/kpi_users/authentications/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/explore/users/components/kpi_users/authentications/index.tsx index a1b9066a721ac..13dddc7de2bec 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/explore/users/components/kpi_users/authentications/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/explore/users/components/kpi_users/authentications/index.tsx @@ -5,11 +5,12 @@ * 2.0. */ -import React from 'react'; +import React, { useMemo } from 'react'; +import { useEuiTheme } from '@elastic/eui'; import type { StatItems } from '../../../../components/stat_items'; -import { kpiUserAuthenticationsAreaLensAttributes } from '../../../../../common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_area'; -import { kpiUserAuthenticationsBarLensAttributes } from '../../../../../common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_bar'; +import { getKpiUserAuthenticationsAreaLensAttributes } from '../../../../../common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_area'; +import { getKpiUserAuthenticationsBarLensAttributes } from '../../../../../common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_bar'; import { kpiUserAuthenticationsMetricSuccessLensAttributes } from '../../../../../common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_metric_success'; import { kpiUserAuthenticationsMetricFailureLensAttributes } from '../../../../../common/components/visualization_actions/lens_attributes/users/kpi_user_authentication_metric_failure'; import { KpiBaseComponent } from '../../../../components/kpi'; @@ -18,41 +19,43 @@ import type { UsersKpiProps } from '../types'; const ID = 'usersKpiAuthentications'; -enum ChartColors { - authenticationsSuccess = '#54B399', - authenticationsFailure = '#E7664C', -} - -export const authenticationsStatItems: Readonly = [ - { - key: 'authentication', - fields: [ - { - key: 'authenticationsSuccess', - name: i18n.SUCCESS_CHART_LABEL, - description: i18n.SUCCESS_UNIT_LABEL, - color: ChartColors.authenticationsSuccess, - icon: 'check', - lensAttributes: kpiUserAuthenticationsMetricSuccessLensAttributes, - }, +export const useGetAuthenticationsStatItems: () => Readonly = () => { + const { euiTheme } = useEuiTheme(); + return useMemo( + () => [ { - key: 'authenticationsFailure', - name: i18n.FAIL_CHART_LABEL, - description: i18n.FAIL_UNIT_LABEL, - color: ChartColors.authenticationsFailure, - icon: 'cross', - lensAttributes: kpiUserAuthenticationsMetricFailureLensAttributes, + key: 'authentication', + fields: [ + { + key: 'authenticationsSuccess', + name: i18n.SUCCESS_CHART_LABEL, + description: i18n.SUCCESS_UNIT_LABEL, + color: euiTheme.colors.vis.euiColorVis0, + icon: 'check', + lensAttributes: kpiUserAuthenticationsMetricSuccessLensAttributes, + }, + { + key: 'authenticationsFailure', + name: i18n.FAIL_CHART_LABEL, + description: i18n.FAIL_UNIT_LABEL, + color: euiTheme.colors.vis.euiColorVis4, + icon: 'cross', + lensAttributes: kpiUserAuthenticationsMetricFailureLensAttributes, + }, + ], + enableAreaChart: true, + enableBarChart: true, + description: i18n.USER_AUTHENTICATIONS, + getAreaChartLensAttributes: getKpiUserAuthenticationsAreaLensAttributes, + getBarChartLensAttributes: getKpiUserAuthenticationsBarLensAttributes, }, ], - enableAreaChart: true, - enableBarChart: true, - description: i18n.USER_AUTHENTICATIONS, - areaChartLensAttributes: kpiUserAuthenticationsAreaLensAttributes, - barChartLensAttributes: kpiUserAuthenticationsBarLensAttributes, - }, -]; + [euiTheme.colors.vis.euiColorVis0, euiTheme.colors.vis.euiColorVis4] + ); +}; const UsersKpiAuthenticationsComponent: React.FC = ({ from, to }) => { + const authenticationsStatItems = useGetAuthenticationsStatItems(); return ; }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/explore/users/components/kpi_users/total_users/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/explore/users/components/kpi_users/total_users/index.test.tsx index 30bb37782889f..0c8a278532be8 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/explore/users/components/kpi_users/total_users/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/explore/users/components/kpi_users/total_users/index.test.tsx @@ -8,7 +8,7 @@ import { render } from '@testing-library/react'; import { TestProviders } from '../../../../../common/mock'; import React from 'react'; -import { usersStatItems, TotalUsersKpi } from '.'; +import { TotalUsersKpi } from '.'; import { KpiBaseComponent } from '../../../../components/kpi'; jest.mock('../../../../components/kpi'); @@ -26,7 +26,6 @@ describe('Users KPI', () => { render(, { wrapper: TestProviders, }); - expect(MockKpiBaseComponent.mock.calls[0][0].statItems).toEqual(usersStatItems); expect(MockKpiBaseComponent.mock.calls[0][0].from).toEqual(from); expect(MockKpiBaseComponent.mock.calls[0][0].to).toEqual(to); }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/explore/users/components/kpi_users/total_users/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/explore/users/components/kpi_users/total_users/index.tsx index 195bc43337f9d..c9839d06fd8fb 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/explore/users/components/kpi_users/total_users/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/explore/users/components/kpi_users/total_users/index.tsx @@ -5,38 +5,42 @@ * 2.0. */ -import { euiPaletteColorBlind } from '@elastic/eui'; -import React from 'react'; +import React, { useMemo } from 'react'; +import { useEuiTheme } from '@elastic/eui'; import type { StatItems } from '../../../../components/stat_items'; import { KpiBaseComponent } from '../../../../components/kpi'; import { kpiTotalUsersMetricLensAttributes } from '../../../../../common/components/visualization_actions/lens_attributes/users/kpi_total_users_metric'; -import { kpiTotalUsersAreaLensAttributes } from '../../../../../common/components/visualization_actions/lens_attributes/users/kpi_total_users_area'; +import { getKpiTotalUsersAreaLensAttributes } from '../../../../../common/components/visualization_actions/lens_attributes/users/kpi_total_users_area'; import * as i18n from './translations'; import type { UsersKpiProps } from '../types'; -const euiVisColorPalette = euiPaletteColorBlind(); -const euiColorVis1 = euiVisColorPalette[1]; - -export const usersStatItems: Readonly = [ - { - key: 'users', - fields: [ +export const useGetUsersStatItems: () => Readonly = () => { + const { euiTheme } = useEuiTheme(); + return useMemo( + () => [ { key: 'users', - color: euiColorVis1, - icon: 'storage', - lensAttributes: kpiTotalUsersMetricLensAttributes, + fields: [ + { + key: 'users', + color: euiTheme.colors.vis.euiColorVis0, + icon: 'storage', + lensAttributes: kpiTotalUsersMetricLensAttributes, + }, + ], + enableAreaChart: true, + description: i18n.USERS, + getAreaChartLensAttributes: getKpiTotalUsersAreaLensAttributes, }, ], - enableAreaChart: true, - description: i18n.USERS, - areaChartLensAttributes: kpiTotalUsersAreaLensAttributes, - }, -]; + [euiTheme.colors.vis.euiColorVis0] + ); +}; const ID = 'TotalUsersKpiQuery'; const TotalUsersKpiComponent: React.FC = ({ from, to }) => { + const usersStatItems = useGetUsersStatItems(); return ; }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/overview/components/detection_response/cases_by_status/cases_by_status.tsx b/x-pack/solutions/security/plugins/security_solution/public/overview/components/detection_response/cases_by_status/cases_by_status.tsx index e702454d45ec5..a7fdca017b55d 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/overview/components/detection_response/cases_by_status/cases_by_status.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/overview/components/detection_response/cases_by_status/cases_by_status.tsx @@ -6,7 +6,7 @@ */ import React, { useCallback, useMemo } from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiText } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiText, useEuiTheme } from '@elastic/eui'; import type { AxisStyle, Rotation } from '@elastic/charts'; import { ScaleType } from '@elastic/charts'; import styled from 'styled-components'; @@ -80,13 +80,6 @@ export const barchartConfigs = { customHeight: 146, }; -const barColors = { - empty: 'rgba(105, 112, 125, 0.1)', - open: '#79aad9', - 'in-progress': '#f1d86f', - closed: '#d3dae6', -}; - const StyledEuiFlexItem = styled(EuiFlexItem)` align-items: center; width: 70%; @@ -97,6 +90,7 @@ const Wrapper = styled.div` `; const CasesByStatusComponent: React.FC = () => { + const { euiTheme } = useEuiTheme(); const { toggleStatus, setToggleStatus } = useQueryToggle(CASES_BY_STATUS_ID); const { getAppUrl, navigateTo } = useNavigation(); const { search } = useFormatUrl(SecurityPageName.case); @@ -113,6 +107,21 @@ const CasesByStatusComponent: React.FC = () => { skip: !toggleStatus, }); + const barColors = useMemo( + () => ({ + empty: euiTheme.colors.vis.euiColorVis8, + open: euiTheme.colors.primary, + 'in-progress': euiTheme.colors.warning, + closed: euiTheme.colors.borderBaseSubdued, + }), + [ + euiTheme.colors.vis.euiColorVis8, + euiTheme.colors.primary, + euiTheme.colors.warning, + euiTheme.colors.borderBaseSubdued, + ] + ); + const chartData = useMemo( () => [ { @@ -131,7 +140,7 @@ const CasesByStatusComponent: React.FC = () => { color: barColors.closed, }, ], - [closed, inProgress, open] + [barColors, closed, inProgress, open] ); return ( diff --git a/x-pack/solutions/security/plugins/security_solution/public/overview/components/detection_response/utils.tsx b/x-pack/solutions/security/plugins/security_solution/public/overview/components/detection_response/utils.tsx index b82108c50e0e2..61ed89aabf0f0 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/overview/components/detection_response/utils.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/overview/components/detection_response/utils.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - +// @deprecated export const SEVERITY_COLOR = { critical: '#E7664C', high: '#DA8B45',