From 56c6463fd4f27aa14fc5a7024503f31077c4bd5c Mon Sep 17 00:00:00 2001 From: Angela Chuang Date: Fri, 10 Jan 2025 12:57:04 +0000 Subject: [PATCH 01/19] update severity colors --- .../components/alerts/alerts_preview.tsx | 2 +- .../alerts_findings_details_table.tsx | 13 +- .../components/charts/donutchart_empty.tsx | 8 - .../components/severity_badge/index.tsx | 15 +- .../public/common/constants.ts | 7 - .../common/utils/risk_color_palette.tsx | 37 ++ .../step_rule_actions/index.test.tsx | 5 +- .../components/rule_preview/index.test.tsx | 5 +- .../severity_mapping/default_severity.tsx | 5 +- .../components/step_about_rule/data.tsx | 47 +-- .../step_about_rule/default_value.ts | 13 +- .../components/step_about_rule/index.test.tsx | 24 +- .../step_schedule_rule/index.test.tsx | 5 +- .../pages/rule_creation/index.tsx | 8 +- .../pages/rule_editing/index.tsx | 3 + .../pages/rule_details/index.tsx | 5 +- .../alerts_treemap/index.tsx | 5 +- .../lib/chart_palette/index.test.ts | 40 ++- .../alerts_treemap/lib/chart_palette/index.ts | 20 +- .../alerts_treemap/lib/layers/index.test.ts | 14 +- .../legend/get_flattened_legend_items.test.ts | 39 ++- .../alerts_treemap/lib/legend/index.test.ts | 20 +- .../chart_panels/chart_collapse/index.tsx | 13 +- .../severity_level_panel/columns.tsx | 78 +++-- .../severity_level_panel/helpers.tsx | 9 +- .../severity_level_chart.tsx | 20 +- .../detection_engine/rules/helpers.test.tsx | 21 +- .../pages/detection_engine/rules/helpers.tsx | 22 +- .../pages/detection_engine/rules/utils.ts | 13 +- .../components/alert_count_insight.test.tsx | 27 +- .../shared/components/alert_count_insight.tsx | 13 +- .../flyout/rule_details/right/content.tsx | 10 +- .../alerts_by_status/alerts_by_status.tsx | 45 +-- .../host_alerts_table/host_alerts_table.tsx | 322 +++++++++--------- .../rule_alerts_table/rule_alerts_table.tsx | 155 ++++----- .../user_alerts_table/user_alerts_table.tsx | 317 ++++++++--------- .../components/detection_response/utils.tsx | 4 +- 37 files changed, 791 insertions(+), 618 deletions(-) create mode 100644 x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.tsx diff --git a/x-pack/solutions/security/plugins/security_solution/public/cloud_security_posture/components/alerts/alerts_preview.tsx b/x-pack/solutions/security/plugins/security_solution/public/cloud_security_posture/components/alerts/alerts_preview.tsx index cd5fcc93495a1..407e85e67cc57 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/cloud_security_posture/components/alerts/alerts_preview.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/cloud_security_posture/components/alerts/alerts_preview.tsx @@ -86,7 +86,7 @@ export const AlertsPreview = ({ const alertStats = Array.from(severityMap, ([key, count]) => ({ key: capitalize(key), count, - color: getSeverityColor(key), + color: getSeverityColor(key, euiTheme), })); const totalAlertsCount = alertStats.reduce((total, item) => total + item.count, 0); diff --git a/x-pack/solutions/security/plugins/security_solution/public/cloud_security_posture/components/csp_details/alerts_findings_details_table.tsx b/x-pack/solutions/security/plugins/security_solution/public/cloud_security_posture/components/csp_details/alerts_findings_details_table.tsx index e9aab1d922a72..448d38c9f4062 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/cloud_security_posture/components/csp_details/alerts_findings_details_table.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/cloud_security_posture/components/csp_details/alerts_findings_details_table.tsx @@ -9,7 +9,15 @@ import React, { memo, useCallback, useEffect, useState } from 'react'; import { encode } from '@kbn/rison'; import { capitalize } from 'lodash'; import type { Criteria, EuiBasicTableColumn, EuiTableSortingType } from '@elastic/eui'; -import { EuiSpacer, EuiPanel, EuiText, EuiBasicTable, EuiIcon, EuiLink } from '@elastic/eui'; +import { + EuiSpacer, + EuiPanel, + EuiText, + EuiBasicTable, + EuiIcon, + EuiLink, + useEuiTheme, +} from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { DistributionBar } from '@kbn/security-solution-distribution-bar'; import { @@ -77,6 +85,7 @@ interface AlertsDetailsFields { export const AlertsDetailsTable = memo( ({ field, value }: { field: 'host.name' | 'user.name'; value: string }) => { + const { euiTheme } = useEuiTheme(); useEffect(() => { uiMetricService.trackUiMetric( METRIC_TYPE.COUNT, @@ -163,7 +172,7 @@ export const AlertsDetailsTable = memo( const alertStats = Array.from(severityMap, ([key, count]) => ({ key: capitalize(key), count, - color: getSeverityColor(key), + color: getSeverityColor(key, euiTheme), filter: () => { setCurrentFilter(key); setQuery( 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 a24c487d7d924..6b9191880345c 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,7 +4,6 @@ * 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'; @@ -14,13 +13,6 @@ interface DonutChartEmptyProps { donutWidth?: number; } -/* - ** @deprecated use getEmptyDonutColor instead - */ -export const emptyDonutColor = '#FAFBFD'; - -export const getEmptyDonutColor = (euiTheme: EuiThemeComputed) => euiTheme.colors.textSubdued; - const EmptyDonutChartComponent: React.FC = ({ size = 90, donutWidth = 20, diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/severity_badge/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/common/components/severity_badge/index.tsx index 4c6312761666f..4651afb19ea0a 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/severity_badge/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/severity_badge/index.tsx @@ -7,18 +7,11 @@ import React from 'react'; import { upperFirst } from 'lodash/fp'; -import { euiLightVars } from '@kbn/ui-theme'; import type { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; +import { useEuiTheme } from '@elastic/eui'; import { HealthTruncateText } from '../health_truncate_text'; - -const { euiColorVis0, euiColorVis5, euiColorVis7, euiColorVis9 } = euiLightVars; -const severityToColorMap: Record = { - low: euiColorVis0, - medium: euiColorVis5, - high: euiColorVis7, - critical: euiColorVis9, -}; +import { useRiskSeverityColors } from '../../utils/risk_color_palette'; interface Props { value: Severity; @@ -29,8 +22,10 @@ const SeverityBadgeComponent: React.FC = ({ value, 'data-test-subj': dataTestSubj = 'severity', }) => { + const { euiTheme } = useEuiTheme(); const displayValue = upperFirst(value); - const color = severityToColorMap[value] ?? 'subdued'; + const severityToColorMap = useRiskSeverityColors(); + const color = severityToColorMap[value] ?? euiTheme.colors.textSubdued; return ( { + if (euiTheme.flags.hasVisColorAdjustment) { + // Amsterdam + return { + low: euiTheme.colors.vis.euiColorVis0, + medium: euiTheme.colors.vis.euiColorVis5, + high: euiTheme.colors.vis.euiColorVis7, + critical: euiTheme.colors.vis.euiColorVis9, + }; + } + + // Borealis + return { + low: euiTheme.colors.vis.euiColorVisSuccess0, + medium: euiTheme.colors.vis.euiColorSeverity7, + high: euiTheme.colors.vis.euiColorSeverity10, + critical: euiTheme.colors.vis.euiColorSeverity14, + }; +}; + +export const useRiskSeverityColors = (): Record => { + const { euiTheme } = useEuiTheme(); + + return useMemo(() => getRiskSeverityColors(euiTheme), [euiTheme]); +}; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/step_rule_actions/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/step_rule_actions/index.test.tsx index 583769069157d..de104d63c6168 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/step_rule_actions/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/step_rule_actions/index.test.tsx @@ -14,13 +14,14 @@ import { TestProviders } from '../../../../common/mock'; import { StepRuleActions, stepActionsDefaultValue } from '.'; import { defaultSchedule, - stepAboutDefaultValue, + getStepAboutDefaultValue, stepDefineDefaultValue, } from '../../../../detections/pages/detection_engine/rules/utils'; import { useRuleForms } from '../../../rule_creation_ui/pages/form'; import type { FormHook } from '../../../../shared_imports'; import type { ActionsStepRule } from '../../../../detections/pages/detection_engine/rules/types'; import { FrequencyDescription } from './notification_action'; +import type { EuiThemeComputed } from '@elastic/eui'; jest.mock('../../../../common/lib/kibana', () => ({ useKibana: jest.fn().mockReturnValue({ @@ -61,7 +62,7 @@ describe('StepRuleActions', () => { }) => { const { actionsStepForm } = useRuleForms({ defineStepDefault: stepDefineDefaultValue, - aboutStepDefault: stepAboutDefaultValue, + aboutStepDefault: getStepAboutDefaultValue({} as unknown as EuiThemeComputed), scheduleStepDefault: defaultSchedule, actionsStepDefault: stepActionsDefaultValue, }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/rule_preview/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/rule_preview/index.test.tsx index 25d5b90d5408a..102bb06b61196 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/rule_preview/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/rule_preview/index.test.tsx @@ -19,10 +19,11 @@ import { usePreviewRoute } from './use_preview_route'; import { DataSourceType } from '../../../../detections/pages/detection_engine/rules/types'; import { getStepScheduleDefaultValue, - stepAboutDefaultValue, + getStepAboutDefaultValue, stepDefineDefaultValue, } from '../../../../detections/pages/detection_engine/rules/utils'; import { usePreviewInvocationCount } from './use_preview_invocation_count'; +import type { EuiThemeComputed } from '@elastic/eui'; jest.mock('../../../../common/lib/kibana'); jest.mock('./use_preview_route'); @@ -95,7 +96,7 @@ const defaultProps: RulePreviewProps = { newTermsFields: ['host.ip'], historyWindowSize: '7d', }, - aboutRuleData: stepAboutDefaultValue, + aboutRuleData: getStepAboutDefaultValue({} as unknown as EuiThemeComputed), scheduleRuleData: getStepScheduleDefaultValue('threat_match'), }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/default_severity.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/default_severity.tsx index 477b4bcd0f519..352563ceea2cb 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/default_severity.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/default_severity.tsx @@ -12,10 +12,11 @@ import { EuiFlexItem, EuiSpacer, EuiSuperSelect, + useEuiTheme, } from '@elastic/eui'; import React from 'react'; import type { Severity } from '../../../../../common/api/detection_engine/model/rule_schema/common_attributes.gen'; -import { severityOptions } from '../step_about_rule/data'; +import { getSeverityOptions } from '../step_about_rule/data'; import * as i18n from './translations'; const describedByIds = ['detectionEngineStepAboutRuleSeverity']; @@ -26,6 +27,8 @@ interface DefaultSeverityProps { } export function DefaultSeverity({ value, onChange }: DefaultSeverityProps) { + const { euiTheme } = useEuiTheme(); + const severityOptions = getSeverityOptions(euiTheme); return ( {I18n.LOW}, - }, - { - value: 'medium', - inputDisplay: {I18n.MEDIUM}, - }, - { - value: 'high', - inputDisplay: {I18n.HIGH}, - }, - { - value: 'critical', - inputDisplay: {I18n.CRITICAL}, - }, -]; +export const getSeverityOptions: (euiTheme: EuiThemeComputed) => SeverityOptionItem[] = ( + euiTheme +) => { + const palette = getRiskSeverityColors(euiTheme); + return [ + { + value: 'low', + inputDisplay: {I18n.LOW}, + }, + { + value: 'medium', + inputDisplay: {I18n.MEDIUM}, + }, + { + value: 'high', + inputDisplay: {I18n.HIGH}, + }, + { + value: 'critical', + inputDisplay: {I18n.CRITICAL}, + }, + ]; +}; export const defaultRiskScoreBySeverity: Record = { low: RISK_SCORE_LOW, diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/default_value.ts b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/default_value.ts index 9d1fff5b8a9ef..3a333698c778a 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/default_value.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/default_value.ts @@ -5,6 +5,7 @@ * 2.0. */ +import type { EuiThemeComputed } from '@elastic/eui'; import { DEFAULT_MAX_SIGNALS } from '../../../../../common/constants'; import type { AboutStepRule } from '../../../../detections/pages/detection_engine/rules/types'; import { fillEmptySeverityMappings } from '../../../../detections/pages/detection_engine/rules/helpers'; @@ -17,13 +18,19 @@ export const threatDefault = [ }, ]; -export const stepAboutDefaultValue: AboutStepRule = { +export const getStepAboutDefaultValue: (euiTheme: EuiThemeComputed) => AboutStepRule = ( + euiTheme +) => ({ author: [], name: '', description: '', isAssociatedToEndpointList: false, isBuildingBlock: false, - severity: { value: 'low', mapping: fillEmptySeverityMappings([]), isMappingChecked: false }, + severity: { + value: 'low', + mapping: fillEmptySeverityMappings([], euiTheme), + isMappingChecked: false, + }, riskScore: { value: 21, mapping: [], isMappingChecked: false }, references: [''], falsePositives: [''], @@ -36,4 +43,4 @@ export const stepAboutDefaultValue: AboutStepRule = { note: '', maxSignals: DEFAULT_MAX_SIGNALS, setup: '', -}; +}); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/index.test.tsx index 94e230c59569c..7fc9236386087 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/index.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { mount, shallow, type ComponentType as EnzymeComponentType } from 'enzyme'; -import { act } from '@testing-library/react'; +import { act, renderHook } from '@testing-library/react'; import { stubIndexPattern } from '@kbn/data-plugin/common/stubs'; import { StepAboutRule, StepAboutRuleReadOnly } from '.'; @@ -16,7 +16,7 @@ import { useGetInstalledJob } from '../../../../common/components/ml/hooks/use_g import { useSecurityJobs } from '../../../../common/components/ml_popover/hooks/use_security_jobs'; import { mockAboutStepRule } from '../../../rule_management_ui/components/rules_table/__mocks__/mock'; import { StepRuleDescription } from '../description_step'; -import { stepAboutDefaultValue } from './default_value'; +import { getStepAboutDefaultValue } from './default_value'; import type { AboutStepRule, DefineStepRule, @@ -46,6 +46,7 @@ import { } from '../../../rule_creation/components/alert_suppression_edit'; import { THRESHOLD_ALERT_SUPPRESSION_ENABLED } from '../../../rule_creation/components/threshold_alert_suppression_edit'; import { AlertSuppressionMissingFieldsStrategyEnum } from '../../../../../common/api/detection_engine'; +import { useEuiTheme } from '@elastic/eui'; jest.mock('../../../../common/lib/kibana'); jest.mock('../../../../common/containers/source'); @@ -95,6 +96,8 @@ export const stepDefineStepMLRule: DefineStepRule = { describe('StepAboutRuleComponent', () => { let useGetInstalledJobMock: jest.Mock; let useSecurityJobsMock: jest.Mock; + const { result: euiThemeResult } = renderHook(() => useEuiTheme()); + const euiTheme = euiThemeResult.current.euiTheme; const TestComp = ({ setFormRef, defineStepDefaultOverride, @@ -103,9 +106,10 @@ describe('StepAboutRuleComponent', () => { defineStepDefaultOverride?: DefineStepRule; }) => { const defineStepDefault = defineStepDefaultOverride ?? stepDefineDefaultValue; + const aboutStepDefault = getStepAboutDefaultValue(euiTheme); const { aboutStepForm } = useRuleForms({ defineStepDefault, - aboutStepDefault: stepAboutDefaultValue, + aboutStepDefault, scheduleStepDefault: defaultSchedule, actionsStepDefault: stepActionsDefaultValue, }); @@ -118,7 +122,7 @@ describe('StepAboutRuleComponent', () => { machineLearningJobId={defineStepDefault.machineLearningJobId} index={defineStepDefault.index} dataViewId={defineStepDefault.dataViewId} - timestampOverride={stepAboutDefaultValue.timestampOverride} + timestampOverride={aboutStepDefault.timestampOverride} isLoading={false} form={aboutStepForm} /> @@ -287,7 +291,11 @@ describe('StepAboutRuleComponent', () => { setup: '', references: [''], riskScore: { value: 21, mapping: [], isMappingChecked: false }, - severity: { value: 'low', mapping: fillEmptySeverityMappings([]), isMappingChecked: false }, + severity: { + value: 'low', + mapping: fillEmptySeverityMappings([], euiTheme), + isMappingChecked: false, + }, tags: [], threat: [ { @@ -349,7 +357,11 @@ describe('StepAboutRuleComponent', () => { setup: '', references: [''], riskScore: { value: 80, mapping: [], isMappingChecked: false }, - severity: { value: 'low', mapping: fillEmptySeverityMappings([]), isMappingChecked: false }, + severity: { + value: 'low', + mapping: fillEmptySeverityMappings([], euiTheme), + isMappingChecked: false, + }, tags: [], threat: [ { diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_schedule_rule/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_schedule_rule/index.test.tsx index 7e85334527d55..1bb8ae7494837 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_schedule_rule/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_schedule_rule/index.test.tsx @@ -13,13 +13,14 @@ import { StepScheduleRule, StepScheduleRuleReadOnly } from '.'; import { getStepScheduleDefaultValue, defaultSchedule, - stepAboutDefaultValue, + getStepAboutDefaultValue, stepDefineDefaultValue, } from '../../../../detections/pages/detection_engine/rules/utils'; import { useRuleForms } from '../../pages/form'; import { stepActionsDefaultValue } from '../../../rule_creation/components/step_rule_actions'; import type { FormHook } from '../../../../shared_imports'; import type { ScheduleStepRule } from '../../../../detections/pages/detection_engine/rules/types'; +import type { EuiThemeComputed } from '@elastic/eui'; describe('StepScheduleRule', () => { const TestComp = ({ @@ -29,7 +30,7 @@ describe('StepScheduleRule', () => { }) => { const { scheduleStepForm } = useRuleForms({ defineStepDefault: stepDefineDefaultValue, - aboutStepDefault: stepAboutDefaultValue, + aboutStepDefault: getStepAboutDefaultValue({} as unknown as EuiThemeComputed), scheduleStepDefault: defaultSchedule, actionsStepDefault: stepActionsDefaultValue, }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/index.tsx index e145edd29c9e0..f00837f83b534 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/index.tsx @@ -15,6 +15,7 @@ import { EuiFlexGroup, EuiResizableContainer, EuiFlexItem, + useEuiTheme, } from '@elastic/eui'; import React, { memo, useCallback, useRef, useState, useMemo, useEffect } from 'react'; import styled from 'styled-components'; @@ -66,7 +67,7 @@ import { defaultSchedule, defaultThreatMatchSchedule, ruleStepsOrder, - stepAboutDefaultValue, + getStepAboutDefaultValue, stepDefineDefaultValue, } from '../../../../detections/pages/detection_engine/rules/utils'; import { @@ -111,6 +112,7 @@ const MyEuiPanel = styled(EuiPanel)<{ MyEuiPanel.displayName = 'MyEuiPanel'; const CreateRulePageComponent: React.FC = () => { + const { euiTheme } = useEuiTheme(); const [ { loading: userInfoLoading, @@ -164,6 +166,8 @@ const CreateRulePageComponent: React.FC = () => { [kibanaAbsoluteUrl] ); + const aboutStepDefault = useMemo(() => getStepAboutDefaultValue(euiTheme), [euiTheme]); + const { defineStepForm, defineStepData, @@ -175,7 +179,7 @@ const CreateRulePageComponent: React.FC = () => { actionsStepData, } = useRuleForms({ defineStepDefault, - aboutStepDefault: stepAboutDefaultValue, + aboutStepDefault, scheduleStepDefault: defaultSchedule, actionsStepDefault, }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx index 601eb852d010e..cf81577224361 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx @@ -15,6 +15,7 @@ import { EuiSpacer, EuiTab, EuiTabs, + useEuiTheme, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import type { FC } from 'react'; @@ -73,6 +74,7 @@ import { useIsPrebuiltRulesCustomizationEnabled } from '../../../rule_management import { ALERT_SUPPRESSION_FIELDS_FIELD_NAME } from '../../../rule_creation/components/alert_suppression_edit'; const EditRulePageComponent: FC<{ rule: RuleResponse }> = ({ rule }) => { + const { euiTheme } = useEuiTheme(); const { addSuccess } = useAppToasts(); const [ { @@ -115,6 +117,7 @@ const EditRulePageComponent: FC<{ rule: RuleResponse }> = ({ rule }) => { const { aboutRuleData, defineRuleData, scheduleRuleData, ruleActionsData } = getStepsData({ rule, + euiTheme, }); const { diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx index 851d219ad43d3..a8e8a62ba3a58 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx @@ -17,6 +17,7 @@ import { EuiSpacer, EuiToolTip, EuiWindowEvent, + useEuiTheme, } from '@elastic/eui'; import type { Filter } from '@kbn/es-query'; import { Route, Routes } from '@kbn/shared-ux-router'; @@ -194,7 +195,7 @@ const RuleDetailsPageComponent: React.FC = ({ timelines: timelinesUi, spaces: spacesApi, } = useKibana().services; - + const { euiTheme } = useEuiTheme(); const dispatch = useDispatch(); const containerElement = useRef(null); const getTable = useMemo(() => dataTableSelectors.getTableByIdSelector(), []); @@ -273,7 +274,7 @@ const RuleDetailsPageComponent: React.FC = ({ const { aboutRuleData, modifiedAboutRuleDetailsData, ruleActionsData } = rule != null - ? getStepsData({ rule, detailsView: true }) + ? getStepsData({ rule, detailsView: true, euiTheme }) : { aboutRuleData: null, modifiedAboutRuleDetailsData: null, diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/index.tsx index ef7000f5037b3..5cdf30f4a6e0d 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/index.tsx @@ -7,7 +7,7 @@ import type { Datum, ElementClickListener, PartialTheme } from '@elastic/charts'; import { Chart, Partition, PartitionLayout, Settings } from '@elastic/charts'; -import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, useEuiTheme } from '@elastic/eui'; import { isEmpty } from 'lodash/fp'; import React, { useCallback, useMemo } from 'react'; import styled from 'styled-components'; @@ -60,6 +60,7 @@ const AlertsTreemapComponent: React.FC = ({ stackByField0, stackByField1, }: Props) => { + const { euiTheme } = useEuiTheme(); const { theme, baseTheme } = useThemes(); const fillColor = useMemo( () => theme?.background?.color ?? baseTheme.background.color, @@ -101,7 +102,7 @@ const AlertsTreemapComponent: React.FC = ({ [buckets, maxRiskSubAggregations, stackByField0] ); - const colorPalette = useMemo(() => getRiskScorePalette(RISK_SCORE_STEPS), []); + const colorPalette = useMemo(() => getRiskScorePalette(RISK_SCORE_STEPS, euiTheme), [euiTheme]); const legendItems: LegendItem[] = useMemo( () => diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/chart_palette/index.test.ts b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/chart_palette/index.test.ts index 64bd8911ddcd6..ec607d659eb63 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/chart_palette/index.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/chart_palette/index.test.ts @@ -5,79 +5,83 @@ * 2.0. */ -import { euiPaletteWarm } from '@elastic/eui'; +import { euiPaletteWarm, useEuiTheme } from '@elastic/eui'; import { - RISK_COLOR_LOW, - RISK_COLOR_MEDIUM, - RISK_COLOR_HIGH, - RISK_COLOR_CRITICAL, RISK_SCORE_MEDIUM, RISK_SCORE_HIGH, RISK_SCORE_CRITICAL, } from '../../../../../../../common/constants'; import { getFillColor, getRiskScorePalette, RISK_SCORE_STEPS } from '.'; +import { renderHook } from '@testing-library/react'; +import { getRiskSeverityColors } from '../../../../../../../common/utils/risk_color_palette'; describe('getFillColor', () => { + const { result } = renderHook(() => useEuiTheme()); + const euiTheme = result.current.euiTheme; + describe('when using the Risk Score palette', () => { - const colorPalette = getRiskScorePalette(RISK_SCORE_STEPS); + const colorPalette = getRiskScorePalette(RISK_SCORE_STEPS, euiTheme); + const expectedColorPalette = getRiskSeverityColors(euiTheme); it('returns the expected fill color', () => { - expect(getFillColor({ riskScore: 50, colorPalette })).toEqual('#d6bf57'); + expect(getFillColor({ riskScore: 50, colorPalette })).toEqual('#D6BF57'); }); it('returns the expected fill color when risk score is zero', () => { - expect(getFillColor({ riskScore: 0, colorPalette })).toEqual('#54b399'); + expect(getFillColor({ riskScore: 0, colorPalette })).toEqual('#54B399'); }); it('returns the expected fill color when risk score is less than zero', () => { - expect(getFillColor({ riskScore: -1, colorPalette })).toEqual('#54b399'); + expect(getFillColor({ riskScore: -1, colorPalette })).toEqual('#54B399'); }); it('returns the expected fill color when risk score is 100', () => { - expect(getFillColor({ riskScore: 100, colorPalette })).toEqual('#e7664c'); + expect(getFillColor({ riskScore: 100, colorPalette })).toEqual('#E7664C'); }); it('returns the expected fill color when risk score is greater than 100', () => { - expect(getFillColor({ riskScore: 101, colorPalette })).toEqual('#e7664c'); + expect(getFillColor({ riskScore: 101, colorPalette })).toEqual('#E7664C'); }); it('returns the expected fill color when risk score is greater than RISK_SCORE_CRITICAL', () => { expect(getFillColor({ riskScore: RISK_SCORE_CRITICAL + 1, colorPalette })).toEqual( - RISK_COLOR_CRITICAL + expectedColorPalette.critical ); }); it('returns the expected fill color when risk score is equal to RISK_SCORE_CRITICAL', () => { expect(getFillColor({ riskScore: RISK_SCORE_CRITICAL, colorPalette })).toEqual( - RISK_COLOR_CRITICAL + expectedColorPalette.critical ); }); it('returns the expected fill color when risk score is greater than RISK_SCORE_HIGH', () => { expect(getFillColor({ riskScore: RISK_SCORE_HIGH + 1, colorPalette })).toEqual( - RISK_COLOR_HIGH + expectedColorPalette.high ); }); it('returns the expected fill color when risk score is equal to RISK_SCORE_HIGH', () => { - expect(getFillColor({ riskScore: RISK_SCORE_HIGH, colorPalette })).toEqual(RISK_COLOR_HIGH); + expect(getFillColor({ riskScore: RISK_SCORE_HIGH, colorPalette })).toEqual( + expectedColorPalette.high + ); }); it('returns the expected fill color when risk score is greater than RISK_SCORE_MEDIUM', () => { expect(getFillColor({ riskScore: RISK_SCORE_MEDIUM + 1, colorPalette })).toEqual( - RISK_COLOR_MEDIUM + expectedColorPalette.medium ); }); it('returns the expected fill color when risk score is equal to RISK_SCORE_MEDIUM', () => { expect(getFillColor({ riskScore: RISK_SCORE_MEDIUM, colorPalette })).toEqual( - RISK_COLOR_MEDIUM + expectedColorPalette.medium ); }); it('returns the expected fill color when risk score is less than RISK_SCORE_MEDIUM', () => { expect(getFillColor({ riskScore: RISK_SCORE_MEDIUM - 1, colorPalette })).toEqual( - RISK_COLOR_LOW + expectedColorPalette.low ); }); }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/chart_palette/index.ts b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/chart_palette/index.ts index 7cc31c76b112e..fdbeb989632e3 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/chart_palette/index.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/chart_palette/index.ts @@ -7,15 +7,13 @@ import { clamp } from 'lodash/fp'; +import type { EuiThemeComputed } from '@elastic/eui'; import { - RISK_COLOR_LOW, - RISK_COLOR_MEDIUM, - RISK_COLOR_HIGH, - RISK_COLOR_CRITICAL, RISK_SCORE_MEDIUM, RISK_SCORE_HIGH, RISK_SCORE_CRITICAL, } from '../../../../../../../common/constants'; +import { getRiskSeverityColors } from '../../../../../../../common/utils/risk_color_palette'; /** * The detection engine creates risk scores in the range 1 - 100. @@ -34,20 +32,22 @@ export const RISK_SCORE_STEPS = 101; * This pallet has the same type as `EuiPalette`, which is not exported by * EUI at the time of this writing. */ -export const getRiskScorePalette = (steps: number): string[] => - Array(steps) +export const getRiskScorePalette = (steps: number, euiTheme: EuiThemeComputed): string[] => { + const palette = getRiskSeverityColors(euiTheme); + return Array(steps) .fill(0) .map((_, i) => { if (i >= RISK_SCORE_CRITICAL) { - return RISK_COLOR_CRITICAL; + return palette.critical; } else if (i >= RISK_SCORE_HIGH) { - return RISK_COLOR_HIGH; + return palette.high; } else if (i >= RISK_SCORE_MEDIUM) { - return RISK_COLOR_MEDIUM; + return palette.medium; } else { - return RISK_COLOR_LOW; + return palette.low; } }); +}; /** Returns a fill color based on the index of the risk score in the color palette */ export const getFillColor = ({ diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/layers/index.test.ts b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/layers/index.test.ts index f8404cc7d33ed..c3b675b6d1bc1 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/layers/index.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/layers/index.test.ts @@ -9,9 +9,13 @@ import { getRiskScorePalette, RISK_SCORE_STEPS } from '../chart_palette'; import { maxRiskSubAggregations } from '../flatten/mocks/mock_buckets'; import { getGroupFromPath, getLayersOneDimension, getLayersMultiDimensional } from '.'; import type { Key, ArrayNode } from '@elastic/charts'; +import { useEuiTheme } from '@elastic/eui'; +import { renderHook } from '@testing-library/react'; describe('layers', () => { - const colorPalette = getRiskScorePalette(RISK_SCORE_STEPS); + const { result } = renderHook(() => useEuiTheme()); + const euiTheme = result.current.euiTheme; + const colorPalette = getRiskScorePalette(RISK_SCORE_STEPS, euiTheme); describe('getGroupFromPath', () => { it('returns the expected group from the path', () => { @@ -69,14 +73,14 @@ describe('layers', () => { const dataName = 'mimikatz process started'; expect( getLayersOneDimension({ colorPalette, maxRiskSubAggregations })[0].shape.fillColor(dataName) - ).toEqual('#e7664c'); + ).toEqual('#E7664C'); }); it('return the default fill color when dataName is not found in the maxRiskSubAggregations', () => { const dataName = 'this does not exist'; expect( getLayersOneDimension({ colorPalette, maxRiskSubAggregations })[0].shape.fillColor(dataName) - ).toEqual('#54b399'); + ).toEqual('#54B399'); }); }); @@ -165,7 +169,7 @@ describe('layers', () => { { index: 0, value: 'Host-k8iyfzraq9' }, ], }) - ).toEqual('#e7664c'); + ).toEqual('#E7664C'); }); it('returns the default fillColor for layer 1 when the group from path is not found', () => { @@ -188,7 +192,7 @@ describe('layers', () => { { index: 0, value: 'nope' }, ], }) - ).toEqual('#54b399'); + ).toEqual('#54B399'); }); }); }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/legend/get_flattened_legend_items.test.ts b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/legend/get_flattened_legend_items.test.ts index c0fb3383a2556..4db6d61a63123 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/legend/get_flattened_legend_items.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/legend/get_flattened_legend_items.test.ts @@ -13,6 +13,8 @@ import { getFlattenedLegendItems } from './get_flattened_legend_items'; import { bucketsWithStackByField1, maxRiskSubAggregations } from '../flatten/mocks/mock_buckets'; import { flattenedBuckets } from '../flatten/mocks/mock_flattened_buckets'; import { TableId } from '@kbn/securitysolution-data-table'; +import { renderHook } from '@testing-library/react'; +import { useEuiTheme } from '@elastic/eui'; describe('getFlattenedLegendItems', () => { it('returns the expected legend items', () => { @@ -23,25 +25,25 @@ describe('getFlattenedLegendItems', () => { value: 'matches everything', }, { - color: '#54b399', + color: '#54B399', count: 12, field: 'host.name', value: 'Host-k8iyfzraq9', }, { - color: '#54b399', + color: '#54B399', count: 10, field: 'host.name', value: 'Host-ao1a4wu7vn', }, { - color: '#54b399', + color: '#54B399', count: 7, field: 'host.name', value: 'Host-3fbljiq8rj', }, { - color: '#54b399', + color: '#54B399', count: 5, field: 'host.name', value: 'Host-r4y6xi92ob', @@ -52,25 +54,25 @@ describe('getFlattenedLegendItems', () => { value: 'EQL process sequence', }, { - color: '#da8b45', + color: '#DA8B45', count: 10, field: 'host.name', value: 'Host-k8iyfzraq9', }, { - color: '#da8b45', + color: '#DA8B45', count: 7, field: 'host.name', value: 'Host-ao1a4wu7vn', }, { - color: '#da8b45', + color: '#DA8B45', count: 5, field: 'host.name', value: 'Host-3fbljiq8rj', }, { - color: '#da8b45', + color: '#DA8B45', count: 3, field: 'host.name', value: 'Host-r4y6xi92ob', @@ -81,25 +83,25 @@ describe('getFlattenedLegendItems', () => { value: 'Endpoint Security', }, { - color: '#d6bf57', + color: '#D6BF57', count: 11, field: 'host.name', value: 'Host-ao1a4wu7vn', }, { - color: '#d6bf57', + color: '#D6BF57', count: 6, field: 'host.name', value: 'Host-3fbljiq8rj', }, { - color: '#d6bf57', + color: '#D6BF57', count: 1, field: 'host.name', value: 'Host-k8iyfzraq9', }, { - color: '#d6bf57', + color: '#D6BF57', count: 1, field: 'host.name', value: 'Host-r4y6xi92ob', @@ -110,19 +112,19 @@ describe('getFlattenedLegendItems', () => { value: 'mimikatz process started', }, { - color: '#e7664c', + color: '#E7664C', count: 3, field: 'host.name', value: 'Host-k8iyfzraq9', }, { - color: '#e7664c', + color: '#E7664C', count: 1, field: 'host.name', value: 'Host-3fbljiq8rj', }, { - color: '#e7664c', + color: '#E7664C', count: 1, field: 'host.name', value: 'Host-r4y6xi92ob', @@ -133,16 +135,17 @@ describe('getFlattenedLegendItems', () => { value: 'Threshold rule', }, { - color: '#e7664c', + color: '#E7664C', count: 1, field: 'host.name', value: 'Host-r4y6xi92ob', }, ].map((legend) => ({ ...legend, scopeId: TableId.alertsOnAlertsPage })); - + const { result: euiThemeResult } = renderHook(() => useEuiTheme()); + const euiTheme = euiThemeResult.current.euiTheme; const legendItems = getFlattenedLegendItems({ buckets: bucketsWithStackByField1, - colorPalette: getRiskScorePalette(RISK_SCORE_STEPS), + colorPalette: getRiskScorePalette(RISK_SCORE_STEPS, euiTheme), flattenedBuckets, maxRiskSubAggregations, stackByField0: 'kibana.alert.rule.name', diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/legend/index.test.ts b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/legend/index.test.ts index fe136924576a8..d7f0276afab6f 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/legend/index.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/legend/index.test.ts @@ -18,9 +18,13 @@ import { } from '.'; import type { FlattenedBucket, RawBucket } from '../../types'; import { TableId } from '@kbn/securitysolution-data-table'; +import { renderHook } from '@testing-library/react'; +import { useEuiTheme } from '@elastic/eui'; describe('legend', () => { - const colorPalette = getRiskScorePalette(RISK_SCORE_STEPS); + const { result } = renderHook(() => useEuiTheme()); + const euiTheme = result.current.euiTheme; + const colorPalette = getRiskScorePalette(RISK_SCORE_STEPS, euiTheme); describe('getLegendItemFromRawBucket', () => { const bucket: RawBucket = { @@ -56,7 +60,7 @@ describe('legend', () => { showColor: true, stackByField0: 'kibana.alert.rule.name', }).color - ).toEqual('#54b399'); + ).toEqual('#54B399'); }); it('returns the expected count', () => { @@ -166,7 +170,7 @@ describe('legend', () => { }) ) ).toEqual({ - color: '#54b399', + color: '#54B399', count: 12, field: 'host.name', value: 'Host-k8iyfzraq9', @@ -212,35 +216,35 @@ describe('legend', () => { }).map((x) => omit(['render', 'dataProviderId'], x)) ).toEqual([ { - color: '#54b399', + color: '#54B399', count: 34, field: 'kibana.alert.rule.name', value: 'matches everything', scopeId: TableId.alertsOnAlertsPage, }, { - color: '#da8b45', + color: '#DA8B45', count: 28, field: 'kibana.alert.rule.name', value: 'EQL process sequence', scopeId: TableId.alertsOnAlertsPage, }, { - color: '#d6bf57', + color: '#D6BF57', count: 19, field: 'kibana.alert.rule.name', value: 'Endpoint Security', scopeId: TableId.alertsOnAlertsPage, }, { - color: '#e7664c', + color: '#E7664C', count: 5, field: 'kibana.alert.rule.name', value: 'mimikatz process started', scopeId: TableId.alertsOnAlertsPage, }, { - color: '#e7664c', + color: '#E7664C', count: 1, field: 'kibana.alert.rule.name', value: 'Threshold rule', diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/chart_panels/chart_collapse/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/chart_panels/chart_collapse/index.tsx index 0539b7f7615d6..54853d6402e86 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/chart_panels/chart_collapse/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/chart_panels/chart_collapse/index.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { EuiFlexGroup, EuiFlexItem, EuiHealth, EuiText } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiHealth, EuiText, useEuiTheme } from '@elastic/eui'; import { ALERT_SEVERITY, ALERT_RULE_NAME } from '@kbn/rule-data-utils'; import type { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/types'; import type { Filter, Query } from '@kbn/es-query'; @@ -20,8 +20,7 @@ import { getSeverityColor } from '../../severity_level_panel/helpers'; import { FormattedCount } from '../../../../../common/components/formatted_number'; import { getIsChartCollapseData } from './helpers'; import * as i18n from './translations'; - -import { SEVERITY_COLOR } from '../../../../../overview/components/detection_response/utils'; +import { useRiskSeverityColors } from '../../../../../common/utils/risk_color_palette'; const DETECTIONS_ALERTS_COLLAPSED_CHART_ID = 'detectioin-alerts-collapsed-chart'; @@ -79,6 +78,7 @@ export const ChartCollapse: React.FC = ({ signalIndexName, runtimeMappings, }: Props) => { + const { euiTheme } = useEuiTheme(); const uniqueQueryId = useMemo(() => `${DETECTIONS_ALERTS_COLLAPSED_CHART_ID}-${uuid()}`, []); const aggregations = useMemo(() => combinedAggregations(groupBySelection), [groupBySelection]); @@ -94,9 +94,10 @@ export const ChartCollapse: React.FC = ({ const topRule = useMemo(() => data.at(0)?.rule ?? i18n.NO_RESULT_MESSAGE, [data]); const topGroup = useMemo(() => data.at(0)?.group ?? i18n.NO_RESULT_MESSAGE, [data]); + const severityColors = useRiskSeverityColors(); const severities = useMemo(() => { const severityData = data.at(0)?.severities ?? []; - return Object.keys(SEVERITY_COLOR).map((severity) => { + return Object.keys(severityColors).map((severity) => { const obj = severityData.find((s) => s.key === severity); if (obj) { return { key: obj.key, label: obj.label, value: obj.value }; @@ -104,7 +105,7 @@ export const ChartCollapse: React.FC = ({ return { key: severity, label: capitalize(severity), value: 0 }; } }); - }, [data]); + }, [data, severityColors]); const groupBy = useMemo(() => getGroupByLabel(groupBySelection), [groupBySelection]); return ( @@ -115,7 +116,7 @@ export const ChartCollapse: React.FC = ({ {severities.map((severity) => ( - + {`${severity.label}: `} diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/columns.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/columns.tsx index 3e9f7eea4fbf8..866633b630512 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/columns.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/columns.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React from 'react'; +import React, { useMemo } from 'react'; import { EuiHealth, EuiText } from '@elastic/eui'; import { capitalize } from 'lodash'; import { ALERT_SEVERITY } from '@kbn/rule-data-utils'; @@ -13,42 +13,48 @@ import type { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; import { TableId } from '@kbn/securitysolution-data-table'; import type { SeverityBuckets as SeverityData } from '../../../../overview/components/detection_response/alerts_by_status/types'; import { DefaultDraggable } from '../../../../common/components/draggables'; -import { SEVERITY_COLOR } from '../../../../overview/components/detection_response/utils'; import { FormattedCount } from '../../../../common/components/formatted_number'; import { COUNT_TABLE_TITLE } from '../alerts_count_panel/translations'; import * as i18n from './translations'; +import { useRiskSeverityColors } from '../../../../common/utils/risk_color_palette'; -export const getSeverityTableColumns = (): Array> => [ - { - field: 'key', - name: i18n.SEVERITY_LEVEL_COLUMN_TITLE, - 'data-test-subj': 'severityTable-severity', - render: (severity: Severity) => ( - - - - ), - }, - { - field: 'value', - name: COUNT_TABLE_TITLE, - sortable: true, - dataType: 'number', - 'data-test-subj': 'severityTable-alertCount', - width: '45%', - render: (alertCount: number) => ( - - - - ), - }, -]; +export const useGetSeverityTableColumns = (): Array> => { + const severityColors = useRiskSeverityColors(); + return useMemo( + () => [ + { + field: 'key', + name: i18n.SEVERITY_LEVEL_COLUMN_TITLE, + 'data-test-subj': 'severityTable-severity', + render: (severity: Severity) => ( + + + + ), + }, + { + field: 'value', + name: COUNT_TABLE_TITLE, + sortable: true, + dataType: 'number', + 'data-test-subj': 'severityTable-alertCount', + width: '45%', + render: (alertCount: number) => ( + + + + ), + }, + ], + [severityColors] + ); +}; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/helpers.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/helpers.tsx index 86b4a5f0eae28..03cc4e2284701 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/helpers.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/helpers.tsx @@ -6,17 +6,18 @@ */ import type { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; import { has } from 'lodash'; +import type { EuiThemeComputed } from '@elastic/eui'; import type { AlertsBySeverityAgg } from './types'; import type { AlertSearchResponse } from '../../../containers/detection_engine/alerts/types'; import type { SeverityBuckets as SeverityData } from '../../../../overview/components/detection_response/alerts_by_status/types'; import type { SummaryChartsData, SummaryChartsAgg } from '../alerts_summary_charts_panel/types'; import { severityLabels } from '../../../../overview/components/detection_response/alerts_by_status/use_alerts_by_status'; -import { emptyDonutColor } from '../../../../common/components/charts/donutchart_empty'; -import { SEVERITY_COLOR } from '../../../../overview/components/detection_response/utils'; import * as i18n from './translations'; +import { getRiskSeverityColors } from '../../../../common/utils/risk_color_palette'; -export const getSeverityColor = (severity: string) => { - return SEVERITY_COLOR[severity.toLocaleLowerCase() as Severity] ?? emptyDonutColor; +export const getSeverityColor = (severity: string, euiTheme: EuiThemeComputed) => { + const palette = getRiskSeverityColors(euiTheme); + return palette[severity.toLocaleLowerCase() as Severity] ?? euiTheme.colors.textSubdued; }; export const parseSeverityData = ( diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/severity_level_chart.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/severity_level_chart.tsx index bad0b55c0cebb..0bc8030b188c5 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/severity_level_chart.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/severity_level_chart.tsx @@ -7,13 +7,19 @@ import React, { useCallback, useMemo } from 'react'; import { ALERT_SEVERITY } from '@kbn/rule-data-utils'; import styled from 'styled-components'; -import { EuiFlexGroup, EuiFlexItem, EuiInMemoryTable, EuiLoadingSpinner } from '@elastic/eui'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiInMemoryTable, + EuiLoadingSpinner, + useEuiTheme, +} from '@elastic/eui'; import type { SortOrder } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { SeverityBuckets as SeverityData } from '../../../../overview/components/detection_response/alerts_by_status/types'; import type { FillColor } from '../../../../common/components/charts/donutchart'; import { DonutChart } from '../../../../common/components/charts/donutchart'; import { ChartLabel } from '../../../../overview/components/detection_response/alerts_by_status/chart_label'; -import { getSeverityTableColumns } from './columns'; +import { useGetSeverityTableColumns } from './columns'; import { getSeverityColor } from './helpers'; import { TOTAL_COUNT_OF_ALERTS } from '../../alerts_table/translations'; @@ -33,7 +39,8 @@ export const SeverityLevelChart: React.FC = ({ isLoading, addFilter, }) => { - const columns = useMemo(() => getSeverityTableColumns(), []); + const { euiTheme } = useEuiTheme(); + const columns = useGetSeverityTableColumns(); const count = useMemo(() => { return data @@ -43,9 +50,10 @@ export const SeverityLevelChart: React.FC = ({ : 0; }, [data]); - const fillColor: FillColor = useCallback((dataName: string) => { - return getSeverityColor(dataName); - }, []); + const fillColor: FillColor = useCallback( + (dataName: string) => getSeverityColor(dataName, euiTheme), + [euiTheme] + ); const sorting: { sort: { field: keyof SeverityData; direction: SortOrder } } = { sort: { diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx index 210884f9754a1..476051b5782d1 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx @@ -45,9 +45,13 @@ import { ALERT_SUPPRESSION_MISSING_FIELDS_FIELD_NAME, } from '../../../../detection_engine/rule_creation/components/alert_suppression_edit'; import { THRESHOLD_ALERT_SUPPRESSION_ENABLED } from '../../../../detection_engine/rule_creation/components/threshold_alert_suppression_edit'; +import { renderHook } from '@testing-library/react'; +import { useEuiTheme } from '@elastic/eui'; describe('rule helpers', () => { moment.suppressDeprecationWarnings = true; + const { result: euiThemeResult } = renderHook(() => useEuiTheme()); + const euiTheme = euiThemeResult.current.euiTheme; describe('getStepsData', () => { test('returns object with about, define, schedule and actions step properties formatted', () => { const { @@ -58,6 +62,7 @@ describe('rule helpers', () => { ruleActionsData, }: GetStepsData = getStepsData({ rule: mockRuleWithEverything('test-id'), + euiTheme, }); const defineRuleStepData = { ruleType: 'saved_query', @@ -149,7 +154,11 @@ describe('rule helpers', () => { references: ['www.test.co'], riskScore: { value: 21, mapping: [], isMappingChecked: false }, ruleNameOverride: 'message', - severity: { value: 'low', mapping: fillEmptySeverityMappings([]), isMappingChecked: false }, + severity: { + value: 'low', + mapping: fillEmptySeverityMappings([], euiTheme), + isMappingChecked: false, + }, tags: ['tag1', 'tag2'], threat: getThreatMock(), timestampOverride: 'event.ingested', @@ -180,7 +189,11 @@ describe('rule helpers', () => { describe('getAboutStepsData', () => { test('returns name, description, and note as empty string if detailsView is true', () => { - const result: AboutStepRule = getAboutStepsData(mockRuleWithEverything('test-id'), true); + const result: AboutStepRule = getAboutStepsData( + mockRuleWithEverything('test-id'), + true, + euiTheme + ); expect(result.name).toEqual(''); expect(result.description).toEqual(''); @@ -190,7 +203,7 @@ describe('rule helpers', () => { test('returns note as empty string if property does not exist on rule', () => { const mockedRule = mockRuleWithEverything('test-id'); delete mockedRule.note; - const result: AboutStepRule = getAboutStepsData(mockedRule, false); + const result: AboutStepRule = getAboutStepsData(mockedRule, false, euiTheme); expect(result.note).toEqual(''); }); @@ -198,7 +211,7 @@ describe('rule helpers', () => { test('returns customHighlightedField as empty array if property does not exist on rule', () => { const mockedRule = mockRuleWithEverything('test-id'); delete mockedRule.investigation_fields; - const result: AboutStepRule = getAboutStepsData(mockedRule, false); + const result: AboutStepRule = getAboutStepsData(mockedRule, false, euiTheme); expect(result.investigationFields).toEqual([]); }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx index 4136b21e96106..4376e754acc43 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx @@ -11,6 +11,7 @@ import memoizeOne from 'memoize-one'; import { useLocation } from 'react-router-dom'; import styled from 'styled-components'; +import type { EuiThemeComputed } from '@elastic/eui'; import { EuiFlexItem } from '@elastic/eui'; import type { Severity, @@ -44,7 +45,7 @@ import type { ActionsStepRule, } from './types'; import { DataSourceType, AlertSuppressionDurationType } from './types'; -import { severityOptions } from '../../../../detection_engine/rule_creation_ui/components/step_about_rule/data'; +import { getSeverityOptions } from '../../../../detection_engine/rule_creation_ui/components/step_about_rule/data'; import { DEFAULT_SUPPRESSION_MISSING_FIELDS_STRATEGY } from '../../../../../common/detection_engine/constants'; import type { RuleAction, RuleResponse } from '../../../../../common/api/detection_engine'; import { normalizeMachineLearningJobId } from '../../../../common/utils/normalize_machine_learning_job_id'; @@ -62,12 +63,14 @@ export interface GetStepsData { export const getStepsData = ({ rule, detailsView = false, + euiTheme, }: { rule: RuleResponse; detailsView?: boolean; + euiTheme: EuiThemeComputed; }): GetStepsData => { const defineRuleData: DefineStepRule = getDefineStepsData(rule); - const aboutRuleData: AboutStepRule = getAboutStepsData(rule, detailsView); + const aboutRuleData: AboutStepRule = getAboutStepsData(rule, detailsView, euiTheme); const modifiedAboutRuleDetailsData: AboutStepRuleDetails = getModifiedAboutDetailsData(rule); const scheduleRuleData: ScheduleStepRule = getScheduleStepsData(rule); const ruleActionsData: ActionsStepRule = getActionsStepsData(rule); @@ -230,7 +233,11 @@ export const getHumanizedDuration = (from: string, interval: string): string => return secondsToDurationString(intervalDuration); }; -export const getAboutStepsData = (rule: RuleResponse, detailsView: boolean): AboutStepRule => { +export const getAboutStepsData = ( + rule: RuleResponse, + detailsView: boolean, + euiTheme: EuiThemeComputed +): AboutStepRule => { const { name, description, note, setup } = determineDetailsValue(rule, detailsView); const { author, @@ -269,7 +276,7 @@ export const getAboutStepsData = (rule: RuleResponse, detailsView: boolean): Abo references, severity: { value: severity as Severity, - mapping: fillEmptySeverityMappings(severityMapping), + mapping: fillEmptySeverityMappings(severityMapping, euiTheme), isMappingChecked: severityMapping.length > 0, }, tags, @@ -294,8 +301,11 @@ const severitySortMapping = { critical: 3, }; -export const fillEmptySeverityMappings = (mappings: SeverityMapping): SeverityMapping => { - const missingMappings: SeverityMapping = severityOptions.flatMap((so) => +export const fillEmptySeverityMappings = ( + mappings: SeverityMapping, + euiTheme: EuiThemeComputed +): SeverityMapping => { + const missingMappings: SeverityMapping = getSeverityOptions(euiTheme).flatMap((so) => mappings.find((mapping) => mapping.severity === so.value) == null ? [{ field: '', value: '', operator: 'equals', severity: so.value }] : [] diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts index f0529e22114a7..e0a5fcf8b9bf6 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts @@ -6,6 +6,7 @@ */ import type { Type } from '@kbn/securitysolution-io-ts-alerting-types'; +import type { EuiThemeComputed } from '@elastic/eui'; import { DEFAULT_THREAT_MAPPING_VALUE } from '../../../../detection_engine/rule_creation/components/threat_match_mapping_edit'; import { ALERT_SUPPRESSION_DURATION_FIELD_NAME, @@ -79,13 +80,19 @@ export const stepDefineDefaultValue: DefineStepRule = { [THRESHOLD_ALERT_SUPPRESSION_ENABLED]: false, }; -export const stepAboutDefaultValue: AboutStepRule = { +export const getStepAboutDefaultValue: (euiTheme: EuiThemeComputed) => AboutStepRule = ( + euiTheme +) => ({ author: [], name: '', description: '', isAssociatedToEndpointList: false, isBuildingBlock: false, - severity: { value: 'low', mapping: fillEmptySeverityMappings([]), isMappingChecked: false }, + severity: { + value: 'low', + mapping: fillEmptySeverityMappings([], euiTheme), + isMappingChecked: false, + }, riskScore: { value: 21, mapping: [], isMappingChecked: false }, investigationFields: [], references: [''], @@ -100,7 +107,7 @@ export const stepAboutDefaultValue: AboutStepRule = { threatIndicatorPath: undefined, timestampOverrideFallbackDisabled: undefined, maxSignals: DEFAULT_MAX_SIGNALS, -}; +}); const DEFAULT_INTERVAL = '5m'; const DEFAULT_FROM = '1m'; diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/alert_count_insight.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/alert_count_insight.test.tsx index d9ae4673b1749..c4451c8cce1ce 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/alert_count_insight.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/alert_count_insight.test.tsx @@ -6,12 +6,13 @@ */ import React from 'react'; -import { render } from '@testing-library/react'; +import { render, renderHook } from '@testing-library/react'; import { TestProviders } from '../../../../common/mock'; import { AlertCountInsight, getFormattedAlertStats } from './alert_count_insight'; import { useAlertsByStatus } from '../../../../overview/components/detection_response/alerts_by_status/use_alerts_by_status'; import type { ParsedAlertsData } from '../../../../overview/components/detection_response/alerts_by_status/types'; import { SEVERITY_COLOR } from '../../../../overview/components/detection_response/utils'; +import { useEuiTheme } from '@elastic/eui'; jest.mock('../../../../common/lib/kibana'); @@ -110,8 +111,11 @@ describe('AlertCountInsight', () => { }); describe('getFormattedAlertStats', () => { + const { result } = renderHook(() => useEuiTheme()); + const euiTheme = result.current.euiTheme; + it('should return alert stats', () => { - const alertStats = getFormattedAlertStats(mockAlertData); + const alertStats = getFormattedAlertStats(mockAlertData, euiTheme); expect(alertStats).toEqual([ { key: 'High', count: 2, color: SEVERITY_COLOR.high }, { key: 'Low', count: 2, color: SEVERITY_COLOR.low }, @@ -121,15 +125,18 @@ describe('getFormattedAlertStats', () => { }); it('should return empty array if no active alerts are available', () => { - const alertStats = getFormattedAlertStats({ - closed: { - total: 2, - severities: [ - { key: 'high', value: 1, label: 'High' }, - { key: 'low', value: 1, label: 'Low' }, - ], + const alertStats = getFormattedAlertStats( + { + closed: { + total: 2, + severities: [ + { key: 'high', value: 1, label: 'High' }, + { key: 'low', value: 1, label: 'Low' }, + ], + }, }, - }); + euiTheme + ); expect(alertStats).toEqual([]); }); }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/alert_count_insight.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/alert_count_insight.tsx index 9b5b056311354..73f7271851429 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/alert_count_insight.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/alert_count_insight.tsx @@ -7,7 +7,8 @@ import React, { useMemo } from 'react'; import { capitalize } from 'lodash'; -import { EuiLoadingSpinner, EuiFlexItem, type EuiFlexGroupProps } from '@elastic/eui'; +import type { EuiThemeComputed } from '@elastic/eui'; +import { EuiLoadingSpinner, EuiFlexItem, type EuiFlexGroupProps, useEuiTheme } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { InsightDistributionBar } from './insight_distribution_bar'; import { getSeverityColor } from '../../../../detections/components/alerts_kpis/severity_level_panel/helpers'; @@ -49,7 +50,10 @@ interface AlertCountInsightProps { /** * Filters closed alerts and format the alert stats for the distribution bar */ -export const getFormattedAlertStats = (alertsData: ParsedAlertsData) => { +export const getFormattedAlertStats = ( + alertsData: ParsedAlertsData, + euiTheme: EuiThemeComputed +) => { const severityMap = new Map(); const filteredAlertsData: ParsedAlertsData = alertsData @@ -68,7 +72,7 @@ export const getFormattedAlertStats = (alertsData: ParsedAlertsData) => { const alertStats = Array.from(severityMap, ([key, count]) => ({ key: capitalize(key), count, - color: getSeverityColor(key), + color: getSeverityColor(key, euiTheme), })); return alertStats; }; @@ -82,6 +86,7 @@ export const AlertCountInsight: React.FC = ({ direction, 'data-test-subj': dataTestSubj, }) => { + const { euiTheme } = useEuiTheme(); const entityFilter = useMemo(() => ({ field: fieldName, value: name }), [fieldName, name]); const { to, from } = useGlobalTime(); const { signalIndexName } = useSignalIndex(); @@ -94,7 +99,7 @@ export const AlertCountInsight: React.FC = ({ from, }); - const alertStats = useMemo(() => getFormattedAlertStats(items), [items]); + const alertStats = useMemo(() => getFormattedAlertStats(items, euiTheme), [items, euiTheme]); const totalAlertCount = useMemo( () => alertStats.reduce((acc, item) => acc + item.count, 0), diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/content.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/content.tsx index 54e6824ce5052..2346a2c1150d2 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/content.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/content.tsx @@ -5,7 +5,7 @@ * 2.0. */ import React, { memo, useMemo } from 'react'; -import { EuiText, EuiHorizontalRule, EuiSpacer, EuiPanel } from '@elastic/eui'; +import { EuiText, EuiHorizontalRule, EuiSpacer, EuiPanel, useEuiTheme } from '@elastic/eui'; import { css } from '@emotion/css'; import { FormattedMessage } from '@kbn/i18n-react'; import { ExpandableSection } from '../../document_details/right/components/expandable_section'; @@ -50,9 +50,13 @@ export interface RuleDetailsProps { * Rule details content on the right section of expandable flyout */ export const PanelContent = memo(({ rule }: RuleDetailsProps) => { + const { euiTheme } = useEuiTheme(); const { ruleActionsData } = useMemo( - () => (rule != null ? getStepsData({ rule, detailsView: true }) : { ruleActionsData: null }), - [rule] + () => + rule != null + ? getStepsData({ rule, detailsView: true, euiTheme }) + : { ruleActionsData: null }, + [rule, euiTheme] ); const hasNotificationActions = useMemo( diff --git a/x-pack/solutions/security/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.tsx b/x-pack/solutions/security/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.tsx index 60dcceb894119..fd5daa04fd894 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import type { EuiThemeComputed } from '@elastic/eui'; import { EuiFlexGroup, EuiFlexItem, @@ -12,11 +13,11 @@ import { EuiProgress, EuiSpacer, EuiText, + useEuiTheme, useIsWithinMaxBreakpoint, useIsWithinMinBreakpoint, } from '@elastic/eui'; import React, { useCallback, useMemo } from 'react'; -import type { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; import styled from 'styled-components'; import { ALERT_WORKFLOW_STATUS, ALERT_SEVERITY } from '@kbn/rule-data-utils'; @@ -49,11 +50,9 @@ import { } from '../translations'; import { useQueryToggle } from '../../../../common/containers/query_toggle'; import { VIEW_ALERTS } from '../../../pages/translations'; -import { SEVERITY_COLOR } from '../utils'; import { FormattedCount } from '../../../../common/components/formatted_number'; import { ChartLabel } from './chart_label'; import { Legend } from '../../../../common/components/charts/legend'; -import { emptyDonutColor } from '../../../../common/components/charts/donutchart_empty'; import { LastUpdatedAt } from '../../../../common/components/last_updated_at'; import { LinkButton, useGetSecuritySolutionLinkProps } from '../../../../common/components/links'; import { useNavigateToTimeline } from '../hooks/use_navigate_to_timeline'; @@ -65,6 +64,7 @@ import { SourcererScopeName } from '../../../../sourcerer/store/model'; import { VisualizationEmbeddable } from '../../../../common/components/visualization_actions/visualization_embeddable'; import type { Status } from '../../../../../common/api/detection_engine'; import { getAlertsByStatusAttributes } from '../../../../common/components/visualization_actions/lens_attributes/common/alerts/alerts_by_status_donut'; +import { getRiskSeverityColors } from '../../../../common/utils/risk_color_palette'; const StyledFlexItem = styled(EuiFlexItem)` padding: 0 4px; @@ -84,12 +84,20 @@ interface AlertsByStatusProps { signalIndexName: string | null; } -const chartConfigs: Array<{ key: Severity; label: string; color: string }> = [ - { key: 'critical', label: STATUS_CRITICAL_LABEL, color: SEVERITY_COLOR.critical }, - { key: 'high', label: STATUS_HIGH_LABEL, color: SEVERITY_COLOR.high }, - { key: 'medium', label: STATUS_MEDIUM_LABEL, color: SEVERITY_COLOR.medium }, - { key: 'low', label: STATUS_LOW_LABEL, color: SEVERITY_COLOR.low }, -]; +const getChartConfigs = (euiTheme: EuiThemeComputed) => { + const palette = getRiskSeverityColors(euiTheme); + + return [ + { key: 'critical', label: STATUS_CRITICAL_LABEL, color: palette.critical }, + { key: 'high', label: STATUS_HIGH_LABEL, color: palette.high }, + { key: 'medium', label: STATUS_MEDIUM_LABEL, color: palette.medium }, + { key: 'low', label: STATUS_LOW_LABEL, color: palette.low }, + ].map((config) => ({ + ...config, + field: ALERT_SEVERITY, + value: config.label, + })); +}; const eventKindSignalFilter: EntityFilter = { field: 'event.kind', @@ -106,6 +114,7 @@ export const AlertsByStatus = ({ signalIndexName, entityFilter, }: AlertsByStatusProps) => { + const { euiTheme } = useEuiTheme(); const { toggleStatus, setToggleStatus } = useQueryToggle(DETECTION_RESPONSE_ALERTS_BY_STATUS_ID); const { openTimelineWithFilters } = useNavigateToTimeline(); const navigateToAlerts = useNavigateToAlertsPageWithFilters(); @@ -149,15 +158,7 @@ export const AlertsByStatus = ({ to, from, }); - const legendItems: LegendItem[] = useMemo( - () => - chartConfigs.map((d) => ({ - color: d.color, - field: ALERT_SEVERITY, - value: d.label, - })), - [] - ); + const legendItems: LegendItem[] = useMemo(() => getChartConfigs(euiTheme), [euiTheme]); const navigateToAlertsWithStatus = useCallback( (status: Status, level?: string) => @@ -214,9 +215,11 @@ export const AlertsByStatus = ({ const totalAlertsCount = isDonutChartEmbeddablesEnabled ? visualizationTotalAlerts : totalAlerts; - const fillColor: FillColor = useCallback((dataName: string) => { - return chartConfigs.find((cfg) => cfg.label === dataName)?.color ?? emptyDonutColor; - }, []); + const fillColor: FillColor = useCallback( + (dataName: string) => + legendItems.find(({ value }) => value === dataName)?.color ?? euiTheme.colors.textSubdued, + [euiTheme.colors.textSubdued, legendItems] + ); return ( <> diff --git a/x-pack/solutions/security/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/host_alerts_table.tsx b/x-pack/solutions/security/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/host_alerts_table.tsx index 3d4070d4cd8e3..b4e3bf1072eb2 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/host_alerts_table.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/overview/components/detection_response/host_alerts_table/host_alerts_table.tsx @@ -30,7 +30,7 @@ import { HostDetailsLink } from '../../../../common/components/links'; import { useQueryToggle } from '../../../../common/containers/query_toggle'; import * as i18n from '../translations'; -import { ITEMS_PER_PAGE, SEVERITY_COLOR } from '../utils'; +import { ITEMS_PER_PAGE } from '../utils'; import type { HostAlertsItem } from './use_host_alerts_items'; import { useHostAlertsItems } from './use_host_alerts_items'; import { @@ -40,6 +40,7 @@ import { } from '../../../../common/components/cell_actions'; import { useGlobalFilterQuery } from '../../../../common/hooks/use_global_filter_query'; import { SourcererScopeName } from '../../../../sourcerer/store/model'; +import { useRiskSeverityColors } from '../../../../common/utils/risk_color_palette'; interface HostAlertsTableProps { signalIndexName: string | null; @@ -87,7 +88,7 @@ export const HostAlertsTable = React.memo(({ signalIndexName }: HostAlertsTableP filterQuery, }); - const columns = useMemo(() => getTableColumns(openHostInAlerts), [openHostInAlerts]); + const columns = useGetTableColumns(openHostInAlerts); return ( @@ -132,54 +133,29 @@ export const HostAlertsTable = React.memo(({ signalIndexName }: HostAlertsTableP HostAlertsTable.displayName = 'HostAlertsTable'; -const getTableColumns: GetTableColumns = (handleClick) => [ - { - field: 'hostName', - name: i18n.HOST_ALERTS_HOSTNAME_COLUMN, - 'data-test-subj': 'hostSeverityAlertsTable-hostName', - render: (hostName: string) => ( - - - - ), - }, - { - field: 'totalAlerts', - name: i18n.ALERTS_TEXT, - 'data-test-subj': 'hostSeverityAlertsTable-totalAlerts', - render: (totalAlerts: number, { hostName }) => ( - - handleClick({ hostName })} - > - - - - ), - }, - { - field: 'critical', - name: i18n.STATUS_CRITICAL_LABEL, - render: (count: number, { hostName }) => ( - - {count > 0 ? ( +const useGetTableColumns: GetTableColumns = (handleClick) => { + const severityColors = useRiskSeverityColors(); + return useMemo( + () => [ + { + field: 'hostName', + name: i18n.HOST_ALERTS_HOSTNAME_COLUMN, + 'data-test-subj': 'hostSeverityAlertsTable-hostName', + render: (hostName: string) => ( + + + + ), + }, + { + field: 'totalAlerts', + name: i18n.ALERTS_TEXT, + 'data-test-subj': 'hostSeverityAlertsTable-totalAlerts', + render: (totalAlerts: number, { hostName }) => ( [ triggerId={SecurityCellActionsTrigger.ALERTS_COUNT} sourcererScopeId={SourcererScopeName.detections} metadata={{ - andFilters: [ - { field: 'kibana.alert.severity', value: 'critical' }, - { field: 'kibana.alert.workflow_status', value: 'open' }, - ], + andFilters: [{ field: 'kibana.alert.workflow_status', value: 'open' }], }} > handleClick({ hostName, severity: 'critical' })} + data-test-subj="hostSeverityAlertsTable-totalAlertsLink" + disabled={totalAlerts === 0} + onClick={() => handleClick({ hostName })} > - + - ) : ( - - )} - - ), - }, - { - field: 'high', - name: i18n.STATUS_HIGH_LABEL, - render: (count: number, { hostName }) => ( - - {count > 0 ? ( - ( + - handleClick({ hostName, severity: 'high' })}> + {count > 0 ? ( + + handleClick({ hostName, severity: 'critical' })} + > + + + + ) : ( - - - ) : ( - - )} - - ), - }, - { - field: 'medium', - name: i18n.STATUS_MEDIUM_LABEL, - render: (count: number, { hostName }) => ( - - {count > 0 ? ( - - handleClick({ hostName, severity: 'medium' })}> + )} + + ), + }, + { + field: 'high', + name: i18n.STATUS_HIGH_LABEL, + render: (count: number, { hostName }) => ( + + {count > 0 ? ( + + handleClick({ hostName, severity: 'high' })}> + + + + ) : ( - - - ) : ( - - )} - - ), - }, - { - field: 'low', - name: i18n.STATUS_LOW_LABEL, - render: (count: number, { hostName }) => ( - - {count > 0 ? ( - - handleClick({ hostName, severity: 'low' })}> + )} + + ), + }, + { + field: 'medium', + name: i18n.STATUS_MEDIUM_LABEL, + render: (count: number, { hostName }) => ( + + {count > 0 ? ( + + handleClick({ hostName, severity: 'medium' })}> + + + + ) : ( - - - ) : ( - - )} - - ), - }, -]; + )} + + ), + }, + { + field: 'low', + name: i18n.STATUS_LOW_LABEL, + render: (count: number, { hostName }) => ( + + {count > 0 ? ( + + handleClick({ hostName, severity: 'low' })}> + + + + ) : ( + + )} + + ), + }, + ], + [ + handleClick, + severityColors.critical, + severityColors.high, + severityColors.low, + severityColors.medium, + ] + ); +}; diff --git a/x-pack/solutions/security/plugins/security_solution/public/overview/components/detection_response/rule_alerts_table/rule_alerts_table.tsx b/x-pack/solutions/security/plugins/security_solution/public/overview/components/detection_response/rule_alerts_table/rule_alerts_table.tsx index 6c88a6e903ed7..6938c389d4744 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/overview/components/detection_response/rule_alerts_table/rule_alerts_table.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/overview/components/detection_response/rule_alerts_table/rule_alerts_table.tsx @@ -25,7 +25,6 @@ import { SecurityCellActionsTrigger } from '../../../../app/actions/constants'; import { useNavigateToAlertsPageWithFilters } from '../../../../common/hooks/use_navigate_to_alerts_page_with_filters'; import { HeaderSection } from '../../../../common/components/header_section'; -import { SEVERITY_COLOR } from '../utils'; import * as i18n from '../translations'; import type { RuleAlertsItem } from './use_rule_alerts_items'; import { useRuleAlertsItems } from './use_rule_alerts_items'; @@ -40,6 +39,7 @@ import { FormattedCount } from '../../../../common/components/formatted_number'; import { SecurityCellActions, CellActionsMode } from '../../../../common/components/cell_actions'; import { useGlobalFilterQuery } from '../../../../common/hooks/use_global_filter_query'; import { SourcererScopeName } from '../../../../sourcerer/store/model'; +import { useRiskSeverityColors } from '../../../../common/utils/risk_color_palette'; export interface RuleAlertsTableProps { signalIndexName: string | null; @@ -54,82 +54,88 @@ export type GetTableColumns = (params: { const DETECTION_RESPONSE_RULE_ALERTS_QUERY_ID = 'detection-response-rule-alerts-severity-table' as const; -export const getTableColumns: GetTableColumns = ({ +export const useGetTableColumns: GetTableColumns = ({ getAppUrl, navigateTo, openRuleInAlertsPage, -}) => [ - { - field: 'name', - name: i18n.RULE_ALERTS_COLUMN_RULE_NAME, - render: (name: string, { id }) => { - const url = getAppUrl({ deepLinkId: SecurityPageName.rules, path: `id/${id}` }); - return ( - - {/* eslint-disable-next-line @elastic/eui/href-or-on-click */} - { - if (ev) { - ev.preventDefault(); - } - navigateTo({ url }); +}) => { + const severityColors = useRiskSeverityColors(); + return useMemo( + () => [ + { + field: 'name', + name: i18n.RULE_ALERTS_COLUMN_RULE_NAME, + render: (name: string, { id }) => { + const url = getAppUrl({ deepLinkId: SecurityPageName.rules, path: `id/${id}` }); + return ( + + {/* eslint-disable-next-line @elastic/eui/href-or-on-click */} + { + if (ev) { + ev.preventDefault(); + } + navigateTo({ url }); + }} + > + {name} + + + ); + }, + }, + { + field: 'last_alert_at', + name: i18n.RULE_ALERTS_COLUMN_LAST_ALERT, + 'data-test-subj': 'severityRuleAlertsTable-lastAlertAt', + render: (lastAlertAt: string) => , + }, + { + field: 'alert_count', + name: i18n.RULE_ALERTS_COLUMN_ALERT_COUNT, + 'data-test-subj': 'severityRuleAlertsTable-alertCount', + render: (alertCount: number, { name }) => ( + - {name} - - - ); - }, - }, - { - field: 'last_alert_at', - name: i18n.RULE_ALERTS_COLUMN_LAST_ALERT, - 'data-test-subj': 'severityRuleAlertsTable-lastAlertAt', - render: (lastAlertAt: string) => , - }, - { - field: 'alert_count', - name: i18n.RULE_ALERTS_COLUMN_ALERT_COUNT, - 'data-test-subj': 'severityRuleAlertsTable-alertCount', - render: (alertCount: number, { name }) => ( - - openRuleInAlertsPage(name)} - > - - - - ), - }, - { - field: 'severity', - name: i18n.RULE_ALERTS_COLUMN_SEVERITY, - 'data-test-subj': 'severityRuleAlertsTable-severity', - render: (severity: Severity) => ( - {capitalize(severity)} - ), - }, -]; + openRuleInAlertsPage(name)} + > + + + + ), + }, + { + field: 'severity', + name: i18n.RULE_ALERTS_COLUMN_SEVERITY, + 'data-test-subj': 'severityRuleAlertsTable-severity', + render: (severity: Severity) => ( + {capitalize(severity)} + ), + }, + ], + [getAppUrl, navigateTo, openRuleInAlertsPage, severityColors] + ); +}; export const RuleAlertsTable = React.memo(({ signalIndexName }) => { const { getAppUrl, navigateTo } = useNavigation(); @@ -163,10 +169,7 @@ export const RuleAlertsTable = React.memo(({ signalIndexNa }); }, [openAlertsPageWithFilter]); - const columns = useMemo( - () => getTableColumns({ getAppUrl, navigateTo, openRuleInAlertsPage }), - [getAppUrl, navigateTo, openRuleInAlertsPage] - ); + const columns = useGetTableColumns({ getAppUrl, navigateTo, openRuleInAlertsPage }); return ( diff --git a/x-pack/solutions/security/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/user_alerts_table.tsx b/x-pack/solutions/security/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/user_alerts_table.tsx index d2ec3efe63aa5..c4d4d0bd710e3 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/user_alerts_table.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/overview/components/detection_response/user_alerts_table/user_alerts_table.tsx @@ -30,12 +30,13 @@ import { LastUpdatedAt } from '../../../../common/components/last_updated_at'; import { UserDetailsLink } from '../../../../common/components/links'; import { useQueryToggle } from '../../../../common/containers/query_toggle'; import * as i18n from '../translations'; -import { ITEMS_PER_PAGE, SEVERITY_COLOR } from '../utils'; +import { ITEMS_PER_PAGE } from '../utils'; import type { UserAlertsItem } from './use_user_alerts_items'; import { useUserAlertsItems } from './use_user_alerts_items'; import { SecurityCellActions, CellActionsMode } from '../../../../common/components/cell_actions'; import { useGlobalFilterQuery } from '../../../../common/hooks/use_global_filter_query'; import { SourcererScopeName } from '../../../../sourcerer/store/model'; +import { useRiskSeverityColors } from '../../../../common/utils/risk_color_palette'; interface UserAlertsTableProps { signalIndexName: string | null; @@ -82,8 +83,7 @@ export const UserAlertsTable = React.memo(({ signalIndexName }: UserAlertsTableP signalIndexName, filterQuery, }); - - const columns = useMemo(() => getTableColumns(openUserInAlerts), [openUserInAlerts]); + const columns = useGetTableColumns(openUserInAlerts); return ( @@ -128,54 +128,29 @@ export const UserAlertsTable = React.memo(({ signalIndexName }: UserAlertsTableP UserAlertsTable.displayName = 'UserAlertsTable'; -const getTableColumns: GetTableColumns = (handleClick) => [ - { - field: 'userName', - name: i18n.USER_ALERTS_USERNAME_COLUMN, - 'data-test-subj': 'userSeverityAlertsTable-userName', - render: (userName: string) => ( - - - - ), - }, - { - field: 'totalAlerts', - name: i18n.ALERTS_TEXT, - 'data-test-subj': 'userSeverityAlertsTable-totalAlerts', - render: (totalAlerts: number, { userName }) => ( - - handleClick({ userName })} - > - - - - ), - }, - { - field: 'critical', - name: i18n.STATUS_CRITICAL_LABEL, - render: (count: number, { userName }) => ( - - {count > 0 ? ( +const useGetTableColumns: GetTableColumns = (handleClick) => { + const severityColors = useRiskSeverityColors(); + return useMemo( + () => [ + { + field: 'userName', + name: i18n.USER_ALERTS_USERNAME_COLUMN, + 'data-test-subj': 'userSeverityAlertsTable-userName', + render: (userName: string) => ( + + + + ), + }, + { + field: 'totalAlerts', + name: i18n.ALERTS_TEXT, + 'data-test-subj': 'userSeverityAlertsTable-totalAlerts', + render: (totalAlerts: number, { userName }) => ( [ triggerId={SecurityCellActionsTrigger.ALERTS_COUNT} sourcererScopeId={SourcererScopeName.detections} metadata={{ - andFilters: [ - { field: 'kibana.alert.severity', value: 'critical' }, - { field: 'kibana.alert.workflow_status', value: 'open' }, - ], + andFilters: [{ field: 'kibana.alert.workflow_status', value: 'open' }], }} > handleClick({ userName, severity: 'critical' })} + data-test-subj="userSeverityAlertsTable-totalAlertsLink" + disabled={totalAlerts === 0} + onClick={() => handleClick({ userName })} > - + - ) : ( - - )} - - ), - }, - { - field: 'high', - name: i18n.STATUS_HIGH_LABEL, - render: (count: number, { userName }) => ( - - {count > 0 ? ( - ( + - handleClick({ userName, severity: 'high' })}> + {count > 0 ? ( + + handleClick({ userName, severity: 'critical' })} + > + + + + ) : ( - - - ) : ( - - )} - - ), - }, - { - field: 'medium', - name: i18n.STATUS_MEDIUM_LABEL, - render: (count: number, { userName }) => ( - - {count > 0 ? ( - - handleClick({ userName, severity: 'medium' })}> + )} + + ), + }, + { + field: 'high', + name: i18n.STATUS_HIGH_LABEL, + render: (count: number, { userName }) => ( + + {count > 0 ? ( + + handleClick({ userName, severity: 'high' })}> + + + + ) : ( - - - ) : ( - - )} - - ), - }, - { - field: 'low', - name: i18n.STATUS_LOW_LABEL, - render: (count: number, { userName }) => ( - - {count > 0 ? ( - - handleClick({ userName, severity: 'low' })}> + )} + + ), + }, + { + field: 'medium', + name: i18n.STATUS_MEDIUM_LABEL, + render: (count: number, { userName }) => ( + + {count > 0 ? ( + + handleClick({ userName, severity: 'medium' })}> + + + + ) : ( - - - ) : ( - - )} - - ), - }, -]; + )} + + ), + }, + { + field: 'low', + name: i18n.STATUS_LOW_LABEL, + render: (count: number, { userName }) => ( + + {count > 0 ? ( + + handleClick({ userName, severity: 'low' })}> + + + + ) : ( + + )} + + ), + }, + ], + [handleClick, severityColors] + ); +}; 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 61ed89aabf0f0..9163cc1edd2de 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,9 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -// @deprecated +/** + * deprecated, use getRiskSeverityColors or useRiskSeverityColors from /common/utils/risk_color_palette.tsx instead + */ export const SEVERITY_COLOR = { critical: '#E7664C', high: '#DA8B45', From 0a4b2022c7915d109544ca92e09634fe9ef9e088 Mon Sep 17 00:00:00 2001 From: Angela Chuang Date: Fri, 10 Jan 2025 13:50:09 +0000 Subject: [PATCH 02/19] update unit tests --- .../common/components/charts/donutchart_empty.tsx | 5 +++++ .../components/step_about_rule_details/index.test.tsx | 7 +++++-- .../components/description_step/index.test.tsx | 7 +++++-- .../components/severity_mapping/severity_override.tsx | 6 +++++- .../components/step_about_rule/index.test.tsx | 2 +- .../components/rules_table/__mocks__/mock.ts | 9 +++++++-- .../public/flyout/rule_details/right/content.test.tsx | 10 +++++++--- .../public/flyout/rule_details/right/index.test.tsx | 8 ++++++-- 8 files changed, 41 insertions(+), 13 deletions(-) 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 6b9191880345c..b70460e81aa92 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 @@ -13,6 +13,11 @@ interface DonutChartEmptyProps { donutWidth?: number; } +/* + ** @deprecated + */ +export const emptyDonutColor = '#FAFBFD'; + const EmptyDonutChartComponent: React.FC = ({ size = 90, donutWidth = 20, diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/step_about_rule_details/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/step_about_rule_details/index.test.tsx index ec39abb61465a..1f19a141d5169 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/step_about_rule_details/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/step_about_rule_details/index.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { mount, shallow } from 'enzyme'; -import { EuiProgress, EuiButtonGroup } from '@elastic/eui'; +import { EuiProgress, EuiButtonGroup, useEuiTheme } from '@elastic/eui'; import { ThemeProvider } from 'styled-components'; import { StepAboutRuleToggleDetails } from '.'; @@ -19,6 +19,7 @@ import { HeaderSection } from '../../../../common/components/header_section'; import { StepAboutRule } from '../../../rule_creation_ui/components/step_about_rule'; import type { AboutStepRule } from '../../../../detections/pages/detection_engine/rules/types'; import { getMockTheme } from '../../../../common/lib/kibana/kibana_react.mock'; +import { renderHook } from '@testing-library/react'; jest.mock('../../../../common/lib/kibana'); @@ -30,7 +31,9 @@ describe('StepAboutRuleToggleDetails', () => { let stepDataMock: AboutStepRule; beforeEach(() => { - stepDataMock = mockAboutStepRule(); + const { result } = renderHook(() => useEuiTheme()); + const euiTheme = result.current.euiTheme; + stepDataMock = mockAboutStepRule(euiTheme); }); test('it renders loading component when "loading" is true', () => { diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/description_step/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/description_step/index.test.tsx index bfcd8368d9675..a8890087280b7 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/description_step/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/description_step/index.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { shallow, mount } from 'enzyme'; -import { render } from '@testing-library/react'; +import { render, renderHook } from '@testing-library/react'; import { StepRuleDescription, @@ -40,6 +40,7 @@ import { ALERT_SUPPRESSION_MISSING_FIELDS_FIELD_NAME, } from '../../../rule_creation/components/alert_suppression_edit'; import { THRESHOLD_ALERT_SUPPRESSION_ENABLED } from '../../../rule_creation/components/threshold_alert_suppression_edit'; +import { useEuiTheme } from '@elastic/eui'; jest.mock('../../../../common/lib/kibana'); @@ -60,7 +61,9 @@ describe('description_step', () => { beforeEach(() => { setupMock.uiSettings.get.mockImplementation(uiSettingsMock(true)); mockFilterManager = new FilterManager(setupMock.uiSettings); - mockAboutStep = mockAboutStepRule(); + const { result } = renderHook(() => useEuiTheme()); + const euiTheme = result.current.euiTheme; + mockAboutStep = mockAboutStepRule(euiTheme); }); describe('StepRuleDescription', () => { diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/severity_override.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/severity_override.tsx index 046f360c3af4d..5ec04ae73dc41 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/severity_override.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/severity_override.tsx @@ -14,6 +14,7 @@ import { EuiFormLabel, EuiIcon, EuiSpacer, + useEuiTheme, } from '@elastic/eui'; import React, { useCallback, useMemo } from 'react'; import type { DataViewBase, DataViewFieldBase } from '@kbn/es-query'; @@ -22,7 +23,7 @@ import { AutocompleteFieldMatchComponent, } from '@kbn/securitysolution-autocomplete'; import type { Severity, SeverityMappingItem } from '@kbn/securitysolution-io-ts-alerting-types'; -import { severityOptions } from '../step_about_rule/data'; +import { getSeverityOptions } from '../step_about_rule/data'; import { useKibana } from '../../../../common/lib/kibana'; import * as styles from './styles'; import * as i18n from './translations'; @@ -158,6 +159,9 @@ function SeverityMappingRow({ [index, severityMappingItem.severity, onFieldMatchValueChange] ); + const { euiTheme } = useEuiTheme(); + const severityOptions = useMemo(() => getSeverityOptions(euiTheme), [euiTheme]); + return ( diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/index.test.tsx index 7fc9236386087..2a9c0ad784d50 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/index.test.tsx @@ -147,7 +147,7 @@ describe('StepAboutRuleComponent', () => { const wrapper = shallow( ); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/__mocks__/mock.ts b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/__mocks__/mock.ts index 25b2d88c6dddd..eba17d026e540 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/__mocks__/mock.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/__mocks__/mock.ts @@ -33,6 +33,7 @@ import { ALERT_SUPPRESSION_MISSING_FIELDS_FIELD_NAME, } from '../../../../rule_creation/components/alert_suppression_edit'; import { THRESHOLD_ALERT_SUPPRESSION_ENABLED } from '../../../../rule_creation/components/threshold_alert_suppression_edit'; +import type { EuiThemeComputed } from '@elastic/eui'; export const mockQueryBar: FieldValueQueryBar = { query: { @@ -195,7 +196,7 @@ export const mockRuleWithEverything = (id: string): RuleResponse => ({ }); // TODO: update types mapping -export const mockAboutStepRule = (): AboutStepRule => ({ +export const mockAboutStepRule = (euiTheme: EuiThemeComputed): AboutStepRule => ({ author: ['Elastic'], isAssociatedToEndpointList: false, isBuildingBlock: false, @@ -205,7 +206,11 @@ export const mockAboutStepRule = (): AboutStepRule => ({ name: 'Query with rule-id', description: '24/7', riskScore: { value: 21, mapping: [], isMappingChecked: false }, - severity: { value: 'low', mapping: fillEmptySeverityMappings([]), isMappingChecked: false }, + severity: { + value: 'low', + mapping: fillEmptySeverityMappings([], euiTheme), + isMappingChecked: false, + }, references: ['www.test.co'], falsePositives: ['test'], tags: ['tag1', 'tag2'], diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/content.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/content.test.tsx index 1a65f91273589..633cd80019801 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/content.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/content.test.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; -import { render } from '@testing-library/react'; +import { render, renderHook } from '@testing-library/react'; import { PanelContent } from './content'; import { ThemeProvider } from 'styled-components'; import { getMockTheme } from '../../../common/lib/kibana/kibana_react.mock'; @@ -30,6 +30,7 @@ import { ACTIONS_HEADER_TEST_ID, ACTIONS_CONTENT_TEST_ID, } from './test_ids'; +import { useEuiTheme } from '@elastic/eui'; const mockUseRuleDetails = useRuleDetails as jest.Mock; jest.mock('../hooks/use_rule_details'); @@ -50,6 +51,9 @@ const renderRulePreview = () => ); describe('', () => { + const { result } = renderHook(() => useEuiTheme()); + const euiTheme = result.current.euiTheme; + afterEach(() => { jest.clearAllMocks(); mockUseRuleDetails.mockReturnValue({ @@ -61,7 +65,7 @@ describe('', () => { it('should render rule preview and its sub sections', () => { mockGetStepsData.mockReturnValue({ - aboutRuleData: mockAboutStepRule(), + aboutRuleData: mockAboutStepRule(euiTheme), defineRuleData: mockDefineStepRule(), scheduleRuleData: mockScheduleStepRule(), ruleActionsData: { actions: ['action'] }, @@ -86,7 +90,7 @@ describe('', () => { it('should not render actions if action is not available', () => { mockGetStepsData.mockReturnValue({ - aboutRuleData: mockAboutStepRule(), + aboutRuleData: mockAboutStepRule(euiTheme), defineRuleData: mockDefineStepRule(), scheduleRuleData: mockScheduleStepRule(), }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/index.test.tsx index c1a629f881710..eda4178fdea13 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/index.test.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; -import { render } from '@testing-library/react'; +import { render, renderHook } from '@testing-library/react'; import { ThemeProvider } from 'styled-components'; import { getMockTheme } from '../../../common/lib/kibana/kibana_react.mock'; import { TestProviders } from '../../../common/mock'; @@ -32,6 +32,7 @@ import { useExpandableFlyoutState, useExpandableFlyoutHistory, } from '@kbn/expandable-flyout'; +import { useEuiTheme } from '@elastic/eui'; jest.mock('../../document_details/shared/hooks/use_rule_details_link'); @@ -67,6 +68,9 @@ const renderRulePanel = (isPreviewMode = false) => ); describe('', () => { + const { result } = renderHook(() => useEuiTheme()); + const euiTheme = result.current.euiTheme; + beforeEach(() => { jest.mocked(useExpandableFlyoutHistory).mockReturnValue(flyoutHistory); jest.mocked(useExpandableFlyoutState).mockReturnValue({} as unknown as ExpandableFlyoutState); @@ -80,7 +84,7 @@ describe('', () => { isExistingRule: true, }); mockGetStepsData.mockReturnValue({ - aboutRuleData: mockAboutStepRule(), + aboutRuleData: mockAboutStepRule(euiTheme), defineRuleData: mockDefineStepRule(), scheduleRuleData: mockScheduleStepRule(), ruleActionsData: { actions: ['action'] }, From 9fc992aa47f3a30d8465e4b39fc1c3d89572b01d Mon Sep 17 00:00:00 2001 From: Angela Chuang Date: Fri, 10 Jan 2025 17:29:26 +0000 Subject: [PATCH 03/19] fix types and code review --- .../components/step_about_rule/data.tsx | 15 ++++++++---- .../step_about_rule/default_value.ts | 9 +++----- .../components/step_about_rule/index.test.tsx | 15 +++++------- .../pages/rule_creation/helpers.test.ts | 6 ++--- .../pages/rule_creation/index.tsx | 8 ++----- .../components/rules_table/__mocks__/mock.ts | 7 +++--- .../detection_engine/rules/helpers.test.tsx | 2 +- .../pages/detection_engine/rules/helpers.tsx | 23 +++++++++---------- .../pages/detection_engine/rules/utils.ts | 9 +++----- 9 files changed, 43 insertions(+), 51 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/data.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/data.tsx index aa096df90790a..a987549846e19 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/data.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/data.tsx @@ -29,25 +29,32 @@ const StyledEuiHealth = styled(EuiHealth)` line-height: inherit; `; +export enum SeverityLevel { + low = 'low', + medium = 'medium', + high = 'high', + critical = 'critical', +} + export const getSeverityOptions: (euiTheme: EuiThemeComputed) => SeverityOptionItem[] = ( euiTheme ) => { const palette = getRiskSeverityColors(euiTheme); return [ { - value: 'low', + value: SeverityLevel.low, inputDisplay: {I18n.LOW}, }, { - value: 'medium', + value: SeverityLevel.medium, inputDisplay: {I18n.MEDIUM}, }, { - value: 'high', + value: SeverityLevel.high, inputDisplay: {I18n.HIGH}, }, { - value: 'critical', + value: SeverityLevel.critical, inputDisplay: {I18n.CRITICAL}, }, ]; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/default_value.ts b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/default_value.ts index 3a333698c778a..e397281b684bc 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/default_value.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/default_value.ts @@ -5,7 +5,6 @@ * 2.0. */ -import type { EuiThemeComputed } from '@elastic/eui'; import { DEFAULT_MAX_SIGNALS } from '../../../../../common/constants'; import type { AboutStepRule } from '../../../../detections/pages/detection_engine/rules/types'; import { fillEmptySeverityMappings } from '../../../../detections/pages/detection_engine/rules/helpers'; @@ -18,9 +17,7 @@ export const threatDefault = [ }, ]; -export const getStepAboutDefaultValue: (euiTheme: EuiThemeComputed) => AboutStepRule = ( - euiTheme -) => ({ +export const stepAboutDefaultValue: AboutStepRule = { author: [], name: '', description: '', @@ -28,7 +25,7 @@ export const getStepAboutDefaultValue: (euiTheme: EuiThemeComputed) => AboutStep isBuildingBlock: false, severity: { value: 'low', - mapping: fillEmptySeverityMappings([], euiTheme), + mapping: fillEmptySeverityMappings([]), isMappingChecked: false, }, riskScore: { value: 21, mapping: [], isMappingChecked: false }, @@ -43,4 +40,4 @@ export const getStepAboutDefaultValue: (euiTheme: EuiThemeComputed) => AboutStep note: '', maxSignals: DEFAULT_MAX_SIGNALS, setup: '', -}); +}; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/index.test.tsx index 2a9c0ad784d50..3a095915ddde2 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/index.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { mount, shallow, type ComponentType as EnzymeComponentType } from 'enzyme'; -import { act, renderHook } from '@testing-library/react'; +import { act } from '@testing-library/react'; import { stubIndexPattern } from '@kbn/data-plugin/common/stubs'; import { StepAboutRule, StepAboutRuleReadOnly } from '.'; @@ -16,7 +16,7 @@ import { useGetInstalledJob } from '../../../../common/components/ml/hooks/use_g import { useSecurityJobs } from '../../../../common/components/ml_popover/hooks/use_security_jobs'; import { mockAboutStepRule } from '../../../rule_management_ui/components/rules_table/__mocks__/mock'; import { StepRuleDescription } from '../description_step'; -import { getStepAboutDefaultValue } from './default_value'; +import { stepAboutDefaultValue } from './default_value'; import type { AboutStepRule, DefineStepRule, @@ -46,7 +46,6 @@ import { } from '../../../rule_creation/components/alert_suppression_edit'; import { THRESHOLD_ALERT_SUPPRESSION_ENABLED } from '../../../rule_creation/components/threshold_alert_suppression_edit'; import { AlertSuppressionMissingFieldsStrategyEnum } from '../../../../../common/api/detection_engine'; -import { useEuiTheme } from '@elastic/eui'; jest.mock('../../../../common/lib/kibana'); jest.mock('../../../../common/containers/source'); @@ -96,8 +95,6 @@ export const stepDefineStepMLRule: DefineStepRule = { describe('StepAboutRuleComponent', () => { let useGetInstalledJobMock: jest.Mock; let useSecurityJobsMock: jest.Mock; - const { result: euiThemeResult } = renderHook(() => useEuiTheme()); - const euiTheme = euiThemeResult.current.euiTheme; const TestComp = ({ setFormRef, defineStepDefaultOverride, @@ -106,7 +103,7 @@ describe('StepAboutRuleComponent', () => { defineStepDefaultOverride?: DefineStepRule; }) => { const defineStepDefault = defineStepDefaultOverride ?? stepDefineDefaultValue; - const aboutStepDefault = getStepAboutDefaultValue(euiTheme); + const aboutStepDefault = stepAboutDefaultValue; const { aboutStepForm } = useRuleForms({ defineStepDefault, aboutStepDefault, @@ -147,7 +144,7 @@ describe('StepAboutRuleComponent', () => { const wrapper = shallow( ); @@ -293,7 +290,7 @@ describe('StepAboutRuleComponent', () => { riskScore: { value: 21, mapping: [], isMappingChecked: false }, severity: { value: 'low', - mapping: fillEmptySeverityMappings([], euiTheme), + mapping: fillEmptySeverityMappings([]), isMappingChecked: false, }, tags: [], @@ -359,7 +356,7 @@ describe('StepAboutRuleComponent', () => { riskScore: { value: 80, mapping: [], isMappingChecked: false }, severity: { value: 'low', - mapping: fillEmptySeverityMappings([], euiTheme), + mapping: fillEmptySeverityMappings([]), isMappingChecked: false, }, tags: [], diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/helpers.test.ts b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/helpers.test.ts index d28634fb6691a..f7aadb9708f3b 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/helpers.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/helpers.test.ts @@ -108,7 +108,7 @@ describe('helpers', () => { let mockThreat: Threat; beforeEach(() => { - mockThreat = mockAboutStepRule().threat[0]; + mockThreat = mockAboutStepRule.threat[0]; }); test('filters out fields with empty tactics', () => { @@ -727,7 +727,7 @@ describe('helpers', () => { let mockData: AboutStepRule; beforeEach(() => { - mockData = mockAboutStepRule(); + mockData = mockAboutStepRule; }); test('returns formatted object as AboutStepRuleJson', () => { @@ -1182,7 +1182,7 @@ describe('helpers', () => { const actionTypeRegistry = actionTypeRegistryMock.create(); beforeEach(() => { - mockAbout = mockAboutStepRule(); + mockAbout = mockAboutStepRule; mockDefine = mockDefineStepRule(); mockSchedule = mockScheduleStepRule(); mockActions = mockActionsStepRule(); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/index.tsx index f00837f83b534..e145edd29c9e0 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/index.tsx @@ -15,7 +15,6 @@ import { EuiFlexGroup, EuiResizableContainer, EuiFlexItem, - useEuiTheme, } from '@elastic/eui'; import React, { memo, useCallback, useRef, useState, useMemo, useEffect } from 'react'; import styled from 'styled-components'; @@ -67,7 +66,7 @@ import { defaultSchedule, defaultThreatMatchSchedule, ruleStepsOrder, - getStepAboutDefaultValue, + stepAboutDefaultValue, stepDefineDefaultValue, } from '../../../../detections/pages/detection_engine/rules/utils'; import { @@ -112,7 +111,6 @@ const MyEuiPanel = styled(EuiPanel)<{ MyEuiPanel.displayName = 'MyEuiPanel'; const CreateRulePageComponent: React.FC = () => { - const { euiTheme } = useEuiTheme(); const [ { loading: userInfoLoading, @@ -166,8 +164,6 @@ const CreateRulePageComponent: React.FC = () => { [kibanaAbsoluteUrl] ); - const aboutStepDefault = useMemo(() => getStepAboutDefaultValue(euiTheme), [euiTheme]); - const { defineStepForm, defineStepData, @@ -179,7 +175,7 @@ const CreateRulePageComponent: React.FC = () => { actionsStepData, } = useRuleForms({ defineStepDefault, - aboutStepDefault, + aboutStepDefault: stepAboutDefaultValue, scheduleStepDefault: defaultSchedule, actionsStepDefault, }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/__mocks__/mock.ts b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/__mocks__/mock.ts index eba17d026e540..9ef07b137c674 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/__mocks__/mock.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/__mocks__/mock.ts @@ -33,7 +33,6 @@ import { ALERT_SUPPRESSION_MISSING_FIELDS_FIELD_NAME, } from '../../../../rule_creation/components/alert_suppression_edit'; import { THRESHOLD_ALERT_SUPPRESSION_ENABLED } from '../../../../rule_creation/components/threshold_alert_suppression_edit'; -import type { EuiThemeComputed } from '@elastic/eui'; export const mockQueryBar: FieldValueQueryBar = { query: { @@ -196,7 +195,7 @@ export const mockRuleWithEverything = (id: string): RuleResponse => ({ }); // TODO: update types mapping -export const mockAboutStepRule = (euiTheme: EuiThemeComputed): AboutStepRule => ({ +export const mockAboutStepRule: AboutStepRule = { author: ['Elastic'], isAssociatedToEndpointList: false, isBuildingBlock: false, @@ -208,7 +207,7 @@ export const mockAboutStepRule = (euiTheme: EuiThemeComputed): AboutStepRule => riskScore: { value: 21, mapping: [], isMappingChecked: false }, severity: { value: 'low', - mapping: fillEmptySeverityMappings([], euiTheme), + mapping: fillEmptySeverityMappings([]), isMappingChecked: false, }, references: ['www.test.co'], @@ -219,7 +218,7 @@ export const mockAboutStepRule = (euiTheme: EuiThemeComputed): AboutStepRule => setup: '# this is some setup documentation', investigationFields: ['foo', 'bar'], maxSignals: 100, -}); +}; export const mockActionsStepRule = (enabled = false): ActionsStepRule => ({ actions: [], diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx index 476051b5782d1..71ca5a03801a3 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx @@ -156,7 +156,7 @@ describe('rule helpers', () => { ruleNameOverride: 'message', severity: { value: 'low', - mapping: fillEmptySeverityMappings([], euiTheme), + mapping: fillEmptySeverityMappings([]), isMappingChecked: false, }, tags: ['tag1', 'tag2'], diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx index 4376e754acc43..ebf03233e6be9 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx @@ -45,7 +45,7 @@ import type { ActionsStepRule, } from './types'; import { DataSourceType, AlertSuppressionDurationType } from './types'; -import { getSeverityOptions } from '../../../../detection_engine/rule_creation_ui/components/step_about_rule/data'; +import { SeverityLevel } from '../../../../detection_engine/rule_creation_ui/components/step_about_rule/data'; import { DEFAULT_SUPPRESSION_MISSING_FIELDS_STRATEGY } from '../../../../../common/detection_engine/constants'; import type { RuleAction, RuleResponse } from '../../../../../common/api/detection_engine'; import { normalizeMachineLearningJobId } from '../../../../common/utils/normalize_machine_learning_job_id'; @@ -276,7 +276,7 @@ export const getAboutStepsData = ( references, severity: { value: severity as Severity, - mapping: fillEmptySeverityMappings(severityMapping, euiTheme), + mapping: fillEmptySeverityMappings(severityMapping), isMappingChecked: severityMapping.length > 0, }, tags, @@ -301,15 +301,15 @@ const severitySortMapping = { critical: 3, }; -export const fillEmptySeverityMappings = ( - mappings: SeverityMapping, - euiTheme: EuiThemeComputed -): SeverityMapping => { - const missingMappings: SeverityMapping = getSeverityOptions(euiTheme).flatMap((so) => - mappings.find((mapping) => mapping.severity === so.value) == null - ? [{ field: '', value: '', operator: 'equals', severity: so.value }] - : [] - ); +export const fillEmptySeverityMappings = (mappings: SeverityMapping): SeverityMapping => { + const missingMappings: SeverityMapping = Object.values(SeverityLevel).flatMap((severityLevel) => { + const isSeverityLevelInMappings = mappings.some( + (mapping) => mapping.severity === severityLevel + ); + return isSeverityLevelInMappings + ? [] + : [{ field: '', value: '', operator: 'equals', severity: severityLevel }]; + }); return [...mappings, ...missingMappings].sort( (a, b) => severitySortMapping[a.severity] - severitySortMapping[b.severity] ); @@ -449,7 +449,6 @@ const getRuleSpecificRuleParamKeys = (ruleType: Type) => { case 'eql': return queryRuleParams; } - assertUnreachable(ruleType); }; export const getActionMessageRuleParams = (ruleType: Type): string[] => { diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts index e0a5fcf8b9bf6..1a8bbeef18fc6 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts @@ -6,7 +6,6 @@ */ import type { Type } from '@kbn/securitysolution-io-ts-alerting-types'; -import type { EuiThemeComputed } from '@elastic/eui'; import { DEFAULT_THREAT_MAPPING_VALUE } from '../../../../detection_engine/rule_creation/components/threat_match_mapping_edit'; import { ALERT_SUPPRESSION_DURATION_FIELD_NAME, @@ -80,9 +79,7 @@ export const stepDefineDefaultValue: DefineStepRule = { [THRESHOLD_ALERT_SUPPRESSION_ENABLED]: false, }; -export const getStepAboutDefaultValue: (euiTheme: EuiThemeComputed) => AboutStepRule = ( - euiTheme -) => ({ +export const stepAboutDefaultValue: AboutStepRule = { author: [], name: '', description: '', @@ -90,7 +87,7 @@ export const getStepAboutDefaultValue: (euiTheme: EuiThemeComputed) => AboutStep isBuildingBlock: false, severity: { value: 'low', - mapping: fillEmptySeverityMappings([], euiTheme), + mapping: fillEmptySeverityMappings([]), isMappingChecked: false, }, riskScore: { value: 21, mapping: [], isMappingChecked: false }, @@ -107,7 +104,7 @@ export const getStepAboutDefaultValue: (euiTheme: EuiThemeComputed) => AboutStep threatIndicatorPath: undefined, timestampOverrideFallbackDisabled: undefined, maxSignals: DEFAULT_MAX_SIGNALS, -}); +}; const DEFAULT_INTERVAL = '5m'; const DEFAULT_FROM = '1m'; From b2e083afa6f6693b6b9e15630200fc9ea36bd7df Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Fri, 10 Jan 2025 17:55:17 +0000 Subject: [PATCH 04/19] [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' --- .../public/detections/pages/detection_engine/rules/helpers.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx index ebf03233e6be9..8fee07b725e15 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx @@ -32,7 +32,6 @@ import { import { THRESHOLD_ALERT_SUPPRESSION_ENABLED } from '../../../../detection_engine/rule_creation/components/threshold_alert_suppression_edit'; import type { ResponseAction } from '../../../../../common/api/detection_engine/model/rule_response_actions'; import { normalizeThresholdField } from '../../../../../common/detection_engine/utils'; -import { assertUnreachable } from '../../../../../common/utility_types'; import { transformRuleToAlertAction, transformRuleToAlertResponseAction, From 4c4655cc5c5d159f397fb01cc570978a6c0366d9 Mon Sep 17 00:00:00 2001 From: Angela Chuang Date: Fri, 10 Jan 2025 18:16:13 +0000 Subject: [PATCH 05/19] fix types --- .../components/step_about_rule_details/index.test.tsx | 7 ++----- .../components/step_rule_actions/index.test.tsx | 5 ++--- .../components/description_step/index.test.tsx | 7 ++----- .../components/rule_preview/index.test.tsx | 4 ++-- .../components/step_schedule_rule/index.test.tsx | 5 ++--- .../pages/detection_engine/rules/helpers.tsx | 1 + .../public/flyout/rule_details/right/content.test.tsx | 10 +++------- .../public/flyout/rule_details/right/index.test.tsx | 2 +- 8 files changed, 15 insertions(+), 26 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/step_about_rule_details/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/step_about_rule_details/index.test.tsx index 1f19a141d5169..8e7a77ae57eb6 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/step_about_rule_details/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/step_about_rule_details/index.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { mount, shallow } from 'enzyme'; -import { EuiProgress, EuiButtonGroup, useEuiTheme } from '@elastic/eui'; +import { EuiProgress, EuiButtonGroup } from '@elastic/eui'; import { ThemeProvider } from 'styled-components'; import { StepAboutRuleToggleDetails } from '.'; @@ -19,7 +19,6 @@ import { HeaderSection } from '../../../../common/components/header_section'; import { StepAboutRule } from '../../../rule_creation_ui/components/step_about_rule'; import type { AboutStepRule } from '../../../../detections/pages/detection_engine/rules/types'; import { getMockTheme } from '../../../../common/lib/kibana/kibana_react.mock'; -import { renderHook } from '@testing-library/react'; jest.mock('../../../../common/lib/kibana'); @@ -31,9 +30,7 @@ describe('StepAboutRuleToggleDetails', () => { let stepDataMock: AboutStepRule; beforeEach(() => { - const { result } = renderHook(() => useEuiTheme()); - const euiTheme = result.current.euiTheme; - stepDataMock = mockAboutStepRule(euiTheme); + stepDataMock = mockAboutStepRule; }); test('it renders loading component when "loading" is true', () => { diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/step_rule_actions/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/step_rule_actions/index.test.tsx index de104d63c6168..583769069157d 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/step_rule_actions/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/step_rule_actions/index.test.tsx @@ -14,14 +14,13 @@ import { TestProviders } from '../../../../common/mock'; import { StepRuleActions, stepActionsDefaultValue } from '.'; import { defaultSchedule, - getStepAboutDefaultValue, + stepAboutDefaultValue, stepDefineDefaultValue, } from '../../../../detections/pages/detection_engine/rules/utils'; import { useRuleForms } from '../../../rule_creation_ui/pages/form'; import type { FormHook } from '../../../../shared_imports'; import type { ActionsStepRule } from '../../../../detections/pages/detection_engine/rules/types'; import { FrequencyDescription } from './notification_action'; -import type { EuiThemeComputed } from '@elastic/eui'; jest.mock('../../../../common/lib/kibana', () => ({ useKibana: jest.fn().mockReturnValue({ @@ -62,7 +61,7 @@ describe('StepRuleActions', () => { }) => { const { actionsStepForm } = useRuleForms({ defineStepDefault: stepDefineDefaultValue, - aboutStepDefault: getStepAboutDefaultValue({} as unknown as EuiThemeComputed), + aboutStepDefault: stepAboutDefaultValue, scheduleStepDefault: defaultSchedule, actionsStepDefault: stepActionsDefaultValue, }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/description_step/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/description_step/index.test.tsx index a8890087280b7..de5985c5432a0 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/description_step/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/description_step/index.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { shallow, mount } from 'enzyme'; -import { render, renderHook } from '@testing-library/react'; +import { render } from '@testing-library/react'; import { StepRuleDescription, @@ -40,7 +40,6 @@ import { ALERT_SUPPRESSION_MISSING_FIELDS_FIELD_NAME, } from '../../../rule_creation/components/alert_suppression_edit'; import { THRESHOLD_ALERT_SUPPRESSION_ENABLED } from '../../../rule_creation/components/threshold_alert_suppression_edit'; -import { useEuiTheme } from '@elastic/eui'; jest.mock('../../../../common/lib/kibana'); @@ -61,9 +60,7 @@ describe('description_step', () => { beforeEach(() => { setupMock.uiSettings.get.mockImplementation(uiSettingsMock(true)); mockFilterManager = new FilterManager(setupMock.uiSettings); - const { result } = renderHook(() => useEuiTheme()); - const euiTheme = result.current.euiTheme; - mockAboutStep = mockAboutStepRule(euiTheme); + mockAboutStep = mockAboutStepRule; }); describe('StepRuleDescription', () => { diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/rule_preview/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/rule_preview/index.test.tsx index 102bb06b61196..690599c8ce732 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/rule_preview/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/rule_preview/index.test.tsx @@ -19,7 +19,7 @@ import { usePreviewRoute } from './use_preview_route'; import { DataSourceType } from '../../../../detections/pages/detection_engine/rules/types'; import { getStepScheduleDefaultValue, - getStepAboutDefaultValue, + stepAboutDefaultValue, stepDefineDefaultValue, } from '../../../../detections/pages/detection_engine/rules/utils'; import { usePreviewInvocationCount } from './use_preview_invocation_count'; @@ -96,7 +96,7 @@ const defaultProps: RulePreviewProps = { newTermsFields: ['host.ip'], historyWindowSize: '7d', }, - aboutRuleData: getStepAboutDefaultValue({} as unknown as EuiThemeComputed), + aboutRuleData: stepAboutDefaultValue, scheduleRuleData: getStepScheduleDefaultValue('threat_match'), }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_schedule_rule/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_schedule_rule/index.test.tsx index 1bb8ae7494837..7e85334527d55 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_schedule_rule/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_schedule_rule/index.test.tsx @@ -13,14 +13,13 @@ import { StepScheduleRule, StepScheduleRuleReadOnly } from '.'; import { getStepScheduleDefaultValue, defaultSchedule, - getStepAboutDefaultValue, + stepAboutDefaultValue, stepDefineDefaultValue, } from '../../../../detections/pages/detection_engine/rules/utils'; import { useRuleForms } from '../../pages/form'; import { stepActionsDefaultValue } from '../../../rule_creation/components/step_rule_actions'; import type { FormHook } from '../../../../shared_imports'; import type { ScheduleStepRule } from '../../../../detections/pages/detection_engine/rules/types'; -import type { EuiThemeComputed } from '@elastic/eui'; describe('StepScheduleRule', () => { const TestComp = ({ @@ -30,7 +29,7 @@ describe('StepScheduleRule', () => { }) => { const { scheduleStepForm } = useRuleForms({ defineStepDefault: stepDefineDefaultValue, - aboutStepDefault: getStepAboutDefaultValue({} as unknown as EuiThemeComputed), + aboutStepDefault: stepAboutDefaultValue, scheduleStepDefault: defaultSchedule, actionsStepDefault: stepActionsDefaultValue, }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx index ebf03233e6be9..354d1db9320a1 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx @@ -449,6 +449,7 @@ const getRuleSpecificRuleParamKeys = (ruleType: Type) => { case 'eql': return queryRuleParams; } + assertUnreachable(ruleType); }; export const getActionMessageRuleParams = (ruleType: Type): string[] => { diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/content.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/content.test.tsx index 633cd80019801..5db587d0fcc32 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/content.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/content.test.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; -import { render, renderHook } from '@testing-library/react'; +import { render } from '@testing-library/react'; import { PanelContent } from './content'; import { ThemeProvider } from 'styled-components'; import { getMockTheme } from '../../../common/lib/kibana/kibana_react.mock'; @@ -30,7 +30,6 @@ import { ACTIONS_HEADER_TEST_ID, ACTIONS_CONTENT_TEST_ID, } from './test_ids'; -import { useEuiTheme } from '@elastic/eui'; const mockUseRuleDetails = useRuleDetails as jest.Mock; jest.mock('../hooks/use_rule_details'); @@ -51,9 +50,6 @@ const renderRulePreview = () => ); describe('', () => { - const { result } = renderHook(() => useEuiTheme()); - const euiTheme = result.current.euiTheme; - afterEach(() => { jest.clearAllMocks(); mockUseRuleDetails.mockReturnValue({ @@ -65,7 +61,7 @@ describe('', () => { it('should render rule preview and its sub sections', () => { mockGetStepsData.mockReturnValue({ - aboutRuleData: mockAboutStepRule(euiTheme), + aboutRuleData: mockAboutStepRule, defineRuleData: mockDefineStepRule(), scheduleRuleData: mockScheduleStepRule(), ruleActionsData: { actions: ['action'] }, @@ -90,7 +86,7 @@ describe('', () => { it('should not render actions if action is not available', () => { mockGetStepsData.mockReturnValue({ - aboutRuleData: mockAboutStepRule(euiTheme), + aboutRuleData: mockAboutStepRule, defineRuleData: mockDefineStepRule(), scheduleRuleData: mockScheduleStepRule(), }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/index.test.tsx index eda4178fdea13..8611fbcab2f90 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/index.test.tsx @@ -84,7 +84,7 @@ describe('', () => { isExistingRule: true, }); mockGetStepsData.mockReturnValue({ - aboutRuleData: mockAboutStepRule(euiTheme), + aboutRuleData: mockAboutStepRule, defineRuleData: mockDefineStepRule(), scheduleRuleData: mockScheduleStepRule(), ruleActionsData: { actions: ['action'] }, From 724abfada9df968a04ccec1ba519309ad2d488ec Mon Sep 17 00:00:00 2001 From: Angela Chuang Date: Fri, 10 Jan 2025 18:17:05 +0000 Subject: [PATCH 06/19] fix types --- .../rule_creation_ui/components/rule_preview/index.test.tsx | 1 - .../public/flyout/rule_details/right/index.test.tsx | 6 +----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/rule_preview/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/rule_preview/index.test.tsx index 690599c8ce732..25d5b90d5408a 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/rule_preview/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/rule_preview/index.test.tsx @@ -23,7 +23,6 @@ import { stepDefineDefaultValue, } from '../../../../detections/pages/detection_engine/rules/utils'; import { usePreviewInvocationCount } from './use_preview_invocation_count'; -import type { EuiThemeComputed } from '@elastic/eui'; jest.mock('../../../../common/lib/kibana'); jest.mock('./use_preview_route'); diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/index.test.tsx index 8611fbcab2f90..3086e646b0a76 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/index.test.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; -import { render, renderHook } from '@testing-library/react'; +import { render } from '@testing-library/react'; import { ThemeProvider } from 'styled-components'; import { getMockTheme } from '../../../common/lib/kibana/kibana_react.mock'; import { TestProviders } from '../../../common/mock'; @@ -32,7 +32,6 @@ import { useExpandableFlyoutState, useExpandableFlyoutHistory, } from '@kbn/expandable-flyout'; -import { useEuiTheme } from '@elastic/eui'; jest.mock('../../document_details/shared/hooks/use_rule_details_link'); @@ -68,9 +67,6 @@ const renderRulePanel = (isPreviewMode = false) => ); describe('', () => { - const { result } = renderHook(() => useEuiTheme()); - const euiTheme = result.current.euiTheme; - beforeEach(() => { jest.mocked(useExpandableFlyoutHistory).mockReturnValue(flyoutHistory); jest.mocked(useExpandableFlyoutState).mockReturnValue({} as unknown as ExpandableFlyoutState); From fef4abc4366b3d551a0f37f0ad4da22e64c0542a Mon Sep 17 00:00:00 2001 From: Angela Chuang Date: Mon, 13 Jan 2025 13:13:00 +0000 Subject: [PATCH 07/19] review --- .../severity_mapping/default_severity.tsx | 6 ++---- .../severity_mapping/severity_override.tsx | 6 ++---- .../components/step_about_rule/data.tsx | 15 ++++++++++----- .../rule_creation_ui/pages/rule_editing/index.tsx | 3 --- .../rule_details_ui/pages/rule_details/index.tsx | 4 +--- .../pages/detection_engine/rules/helpers.test.tsx | 15 +++------------ .../pages/detection_engine/rules/helpers.tsx | 11 ++--------- 7 files changed, 20 insertions(+), 40 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/default_severity.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/default_severity.tsx index 352563ceea2cb..b33bd1c737a5a 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/default_severity.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/default_severity.tsx @@ -12,11 +12,10 @@ import { EuiFlexItem, EuiSpacer, EuiSuperSelect, - useEuiTheme, } from '@elastic/eui'; import React from 'react'; import type { Severity } from '../../../../../common/api/detection_engine/model/rule_schema/common_attributes.gen'; -import { getSeverityOptions } from '../step_about_rule/data'; +import { useSeverityOptions } from '../step_about_rule/data'; import * as i18n from './translations'; const describedByIds = ['detectionEngineStepAboutRuleSeverity']; @@ -27,8 +26,7 @@ interface DefaultSeverityProps { } export function DefaultSeverity({ value, onChange }: DefaultSeverityProps) { - const { euiTheme } = useEuiTheme(); - const severityOptions = getSeverityOptions(euiTheme); + const severityOptions = useSeverityOptions(); return ( getSeverityOptions(euiTheme), [euiTheme]); + const severityOptions = useSeverityOptions(); return ( diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/data.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/data.tsx index a987549846e19..57e824d7d400d 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/data.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/data.tsx @@ -5,10 +5,10 @@ * 2.0. */ -import React from 'react'; +import React, { useMemo } from 'react'; import styled from 'styled-components'; import type { EuiThemeComputed } from '@elastic/eui'; -import { EuiHealth } from '@elastic/eui'; +import { EuiHealth, useEuiTheme } from '@elastic/eui'; import type { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; import * as I18n from './translations'; @@ -36,9 +36,7 @@ export enum SeverityLevel { critical = 'critical', } -export const getSeverityOptions: (euiTheme: EuiThemeComputed) => SeverityOptionItem[] = ( - euiTheme -) => { +const getSeverityOptions: (euiTheme: EuiThemeComputed) => SeverityOptionItem[] = (euiTheme) => { const palette = getRiskSeverityColors(euiTheme); return [ { @@ -60,6 +58,13 @@ export const getSeverityOptions: (euiTheme: EuiThemeComputed) => SeverityOptionI ]; }; +export const useSeverityOptions = () => { + const { euiTheme } = useEuiTheme(); + const severityOptions = useMemo(() => getSeverityOptions(euiTheme), [euiTheme]); + + return severityOptions; +}; + export const defaultRiskScoreBySeverity: Record = { low: RISK_SCORE_LOW, medium: RISK_SCORE_MEDIUM, diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx index cf81577224361..601eb852d010e 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx @@ -15,7 +15,6 @@ import { EuiSpacer, EuiTab, EuiTabs, - useEuiTheme, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import type { FC } from 'react'; @@ -74,7 +73,6 @@ import { useIsPrebuiltRulesCustomizationEnabled } from '../../../rule_management import { ALERT_SUPPRESSION_FIELDS_FIELD_NAME } from '../../../rule_creation/components/alert_suppression_edit'; const EditRulePageComponent: FC<{ rule: RuleResponse }> = ({ rule }) => { - const { euiTheme } = useEuiTheme(); const { addSuccess } = useAppToasts(); const [ { @@ -117,7 +115,6 @@ const EditRulePageComponent: FC<{ rule: RuleResponse }> = ({ rule }) => { const { aboutRuleData, defineRuleData, scheduleRuleData, ruleActionsData } = getStepsData({ rule, - euiTheme, }); const { diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx index a8e8a62ba3a58..ecc6d424d520c 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx @@ -17,7 +17,6 @@ import { EuiSpacer, EuiToolTip, EuiWindowEvent, - useEuiTheme, } from '@elastic/eui'; import type { Filter } from '@kbn/es-query'; import { Route, Routes } from '@kbn/shared-ux-router'; @@ -195,7 +194,6 @@ const RuleDetailsPageComponent: React.FC = ({ timelines: timelinesUi, spaces: spacesApi, } = useKibana().services; - const { euiTheme } = useEuiTheme(); const dispatch = useDispatch(); const containerElement = useRef(null); const getTable = useMemo(() => dataTableSelectors.getTableByIdSelector(), []); @@ -274,7 +272,7 @@ const RuleDetailsPageComponent: React.FC = ({ const { aboutRuleData, modifiedAboutRuleDetailsData, ruleActionsData } = rule != null - ? getStepsData({ rule, detailsView: true, euiTheme }) + ? getStepsData({ rule, detailsView: true }) : { aboutRuleData: null, modifiedAboutRuleDetailsData: null, diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx index 71ca5a03801a3..ddfd863bb8dc7 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx @@ -45,13 +45,9 @@ import { ALERT_SUPPRESSION_MISSING_FIELDS_FIELD_NAME, } from '../../../../detection_engine/rule_creation/components/alert_suppression_edit'; import { THRESHOLD_ALERT_SUPPRESSION_ENABLED } from '../../../../detection_engine/rule_creation/components/threshold_alert_suppression_edit'; -import { renderHook } from '@testing-library/react'; -import { useEuiTheme } from '@elastic/eui'; describe('rule helpers', () => { moment.suppressDeprecationWarnings = true; - const { result: euiThemeResult } = renderHook(() => useEuiTheme()); - const euiTheme = euiThemeResult.current.euiTheme; describe('getStepsData', () => { test('returns object with about, define, schedule and actions step properties formatted', () => { const { @@ -62,7 +58,6 @@ describe('rule helpers', () => { ruleActionsData, }: GetStepsData = getStepsData({ rule: mockRuleWithEverything('test-id'), - euiTheme, }); const defineRuleStepData = { ruleType: 'saved_query', @@ -189,11 +184,7 @@ describe('rule helpers', () => { describe('getAboutStepsData', () => { test('returns name, description, and note as empty string if detailsView is true', () => { - const result: AboutStepRule = getAboutStepsData( - mockRuleWithEverything('test-id'), - true, - euiTheme - ); + const result: AboutStepRule = getAboutStepsData(mockRuleWithEverything('test-id'), true); expect(result.name).toEqual(''); expect(result.description).toEqual(''); @@ -203,7 +194,7 @@ describe('rule helpers', () => { test('returns note as empty string if property does not exist on rule', () => { const mockedRule = mockRuleWithEverything('test-id'); delete mockedRule.note; - const result: AboutStepRule = getAboutStepsData(mockedRule, false, euiTheme); + const result: AboutStepRule = getAboutStepsData(mockedRule, false); expect(result.note).toEqual(''); }); @@ -211,7 +202,7 @@ describe('rule helpers', () => { test('returns customHighlightedField as empty array if property does not exist on rule', () => { const mockedRule = mockRuleWithEverything('test-id'); delete mockedRule.investigation_fields; - const result: AboutStepRule = getAboutStepsData(mockedRule, false, euiTheme); + const result: AboutStepRule = getAboutStepsData(mockedRule, false); expect(result.investigationFields).toEqual([]); }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx index 17d0bd355df5b..213380446cd2a 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx @@ -11,7 +11,6 @@ import memoizeOne from 'memoize-one'; import { useLocation } from 'react-router-dom'; import styled from 'styled-components'; -import type { EuiThemeComputed } from '@elastic/eui'; import { EuiFlexItem } from '@elastic/eui'; import type { Severity, @@ -62,14 +61,12 @@ export interface GetStepsData { export const getStepsData = ({ rule, detailsView = false, - euiTheme, }: { rule: RuleResponse; detailsView?: boolean; - euiTheme: EuiThemeComputed; }): GetStepsData => { const defineRuleData: DefineStepRule = getDefineStepsData(rule); - const aboutRuleData: AboutStepRule = getAboutStepsData(rule, detailsView, euiTheme); + const aboutRuleData: AboutStepRule = getAboutStepsData(rule, detailsView); const modifiedAboutRuleDetailsData: AboutStepRuleDetails = getModifiedAboutDetailsData(rule); const scheduleRuleData: ScheduleStepRule = getScheduleStepsData(rule); const ruleActionsData: ActionsStepRule = getActionsStepsData(rule); @@ -232,11 +229,7 @@ export const getHumanizedDuration = (from: string, interval: string): string => return secondsToDurationString(intervalDuration); }; -export const getAboutStepsData = ( - rule: RuleResponse, - detailsView: boolean, - euiTheme: EuiThemeComputed -): AboutStepRule => { +export const getAboutStepsData = (rule: RuleResponse, detailsView: boolean): AboutStepRule => { const { name, description, note, setup } = determineDetailsValue(rule, detailsView); const { author, From c3c6bf94e1317347f5ede94302f1abb3666b7113 Mon Sep 17 00:00:00 2001 From: Angela Chuang Date: Mon, 13 Jan 2025 13:19:51 +0000 Subject: [PATCH 08/19] check theme with euiTheme.themeName --- .../public/common/utils/risk_color_palette.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.tsx b/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.tsx index f3fe19e31b472..9d6dbfdc5a017 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.tsx @@ -11,8 +11,7 @@ import type { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; import { useMemo } from 'react'; export const getRiskSeverityColors = (euiTheme: EuiThemeComputed) => { - if (euiTheme.flags.hasVisColorAdjustment) { - // Amsterdam + if (euiTheme.themeName === 'EUI_THEME_AMSTERDAM') { return { low: euiTheme.colors.vis.euiColorVis0, medium: euiTheme.colors.vis.euiColorVis5, From d0074e9af7b60585debd630ebd6d844f2e9f0555 Mon Sep 17 00:00:00 2001 From: Angela Chuang Date: Mon, 13 Jan 2025 13:25:40 +0000 Subject: [PATCH 09/19] revert unnecessary changes --- .../components/step_about_rule_details/index.test.tsx | 2 +- .../components/description_step/index.test.tsx | 2 +- .../components/step_about_rule/index.test.tsx | 2 +- .../rule_creation_ui/pages/rule_creation/helpers.test.ts | 6 +++--- .../components/rules_table/__mocks__/mock.ts | 4 ++-- .../public/flyout/rule_details/right/content.test.tsx | 4 ++-- .../public/flyout/rule_details/right/index.test.tsx | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/step_about_rule_details/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/step_about_rule_details/index.test.tsx index 8e7a77ae57eb6..ec39abb61465a 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/step_about_rule_details/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/step_about_rule_details/index.test.tsx @@ -30,7 +30,7 @@ describe('StepAboutRuleToggleDetails', () => { let stepDataMock: AboutStepRule; beforeEach(() => { - stepDataMock = mockAboutStepRule; + stepDataMock = mockAboutStepRule(); }); test('it renders loading component when "loading" is true', () => { diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/description_step/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/description_step/index.test.tsx index de5985c5432a0..bfcd8368d9675 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/description_step/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/description_step/index.test.tsx @@ -60,7 +60,7 @@ describe('description_step', () => { beforeEach(() => { setupMock.uiSettings.get.mockImplementation(uiSettingsMock(true)); mockFilterManager = new FilterManager(setupMock.uiSettings); - mockAboutStep = mockAboutStepRule; + mockAboutStep = mockAboutStepRule(); }); describe('StepRuleDescription', () => { diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/index.test.tsx index 3a095915ddde2..d101b771e9fe1 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/index.test.tsx @@ -144,7 +144,7 @@ describe('StepAboutRuleComponent', () => { const wrapper = shallow( ); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/helpers.test.ts b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/helpers.test.ts index f7aadb9708f3b..d28634fb6691a 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/helpers.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/helpers.test.ts @@ -108,7 +108,7 @@ describe('helpers', () => { let mockThreat: Threat; beforeEach(() => { - mockThreat = mockAboutStepRule.threat[0]; + mockThreat = mockAboutStepRule().threat[0]; }); test('filters out fields with empty tactics', () => { @@ -727,7 +727,7 @@ describe('helpers', () => { let mockData: AboutStepRule; beforeEach(() => { - mockData = mockAboutStepRule; + mockData = mockAboutStepRule(); }); test('returns formatted object as AboutStepRuleJson', () => { @@ -1182,7 +1182,7 @@ describe('helpers', () => { const actionTypeRegistry = actionTypeRegistryMock.create(); beforeEach(() => { - mockAbout = mockAboutStepRule; + mockAbout = mockAboutStepRule(); mockDefine = mockDefineStepRule(); mockSchedule = mockScheduleStepRule(); mockActions = mockActionsStepRule(); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/__mocks__/mock.ts b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/__mocks__/mock.ts index 9ef07b137c674..9fc852882c792 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/__mocks__/mock.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/__mocks__/mock.ts @@ -195,7 +195,7 @@ export const mockRuleWithEverything = (id: string): RuleResponse => ({ }); // TODO: update types mapping -export const mockAboutStepRule: AboutStepRule = { +export const mockAboutStepRule = (): AboutStepRule => ({ author: ['Elastic'], isAssociatedToEndpointList: false, isBuildingBlock: false, @@ -218,7 +218,7 @@ export const mockAboutStepRule: AboutStepRule = { setup: '# this is some setup documentation', investigationFields: ['foo', 'bar'], maxSignals: 100, -}; +}); export const mockActionsStepRule = (enabled = false): ActionsStepRule => ({ actions: [], diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/content.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/content.test.tsx index 5db587d0fcc32..1a65f91273589 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/content.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/content.test.tsx @@ -61,7 +61,7 @@ describe('', () => { it('should render rule preview and its sub sections', () => { mockGetStepsData.mockReturnValue({ - aboutRuleData: mockAboutStepRule, + aboutRuleData: mockAboutStepRule(), defineRuleData: mockDefineStepRule(), scheduleRuleData: mockScheduleStepRule(), ruleActionsData: { actions: ['action'] }, @@ -86,7 +86,7 @@ describe('', () => { it('should not render actions if action is not available', () => { mockGetStepsData.mockReturnValue({ - aboutRuleData: mockAboutStepRule, + aboutRuleData: mockAboutStepRule(), defineRuleData: mockDefineStepRule(), scheduleRuleData: mockScheduleStepRule(), }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/index.test.tsx index 3086e646b0a76..c1a629f881710 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/index.test.tsx @@ -80,7 +80,7 @@ describe('', () => { isExistingRule: true, }); mockGetStepsData.mockReturnValue({ - aboutRuleData: mockAboutStepRule, + aboutRuleData: mockAboutStepRule(), defineRuleData: mockDefineStepRule(), scheduleRuleData: mockScheduleStepRule(), ruleActionsData: { actions: ['action'] }, From 230dd46da6d595017bbd027a1012cd1eb09975c2 Mon Sep 17 00:00:00 2001 From: Angela Chuang Date: Mon, 13 Jan 2025 13:28:22 +0000 Subject: [PATCH 10/19] revert unnecessary changes --- .../rule_details_ui/pages/rule_details/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx index ecc6d424d520c..851d219ad43d3 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx @@ -194,6 +194,7 @@ const RuleDetailsPageComponent: React.FC = ({ timelines: timelinesUi, spaces: spacesApi, } = useKibana().services; + const dispatch = useDispatch(); const containerElement = useRef(null); const getTable = useMemo(() => dataTableSelectors.getTableByIdSelector(), []); From d5add99e87c2ec01569b1158e7cb0ca7113bc4f3 Mon Sep 17 00:00:00 2001 From: Angela Chuang Date: Mon, 13 Jan 2025 14:03:34 +0000 Subject: [PATCH 11/19] type error --- .../pages/detection_engine/rules/helpers.tsx | 1 + .../public/flyout/rule_details/right/content.tsx | 10 +++------- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx index 213380446cd2a..eb6836ed0b259 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx @@ -31,6 +31,7 @@ import { import { THRESHOLD_ALERT_SUPPRESSION_ENABLED } from '../../../../detection_engine/rule_creation/components/threshold_alert_suppression_edit'; import type { ResponseAction } from '../../../../../common/api/detection_engine/model/rule_response_actions'; import { normalizeThresholdField } from '../../../../../common/detection_engine/utils'; +import { assertUnreachable } from '../../../../../common/utility_types'; import { transformRuleToAlertAction, transformRuleToAlertResponseAction, diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/content.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/content.tsx index 2346a2c1150d2..54e6824ce5052 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/content.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/rule_details/right/content.tsx @@ -5,7 +5,7 @@ * 2.0. */ import React, { memo, useMemo } from 'react'; -import { EuiText, EuiHorizontalRule, EuiSpacer, EuiPanel, useEuiTheme } from '@elastic/eui'; +import { EuiText, EuiHorizontalRule, EuiSpacer, EuiPanel } from '@elastic/eui'; import { css } from '@emotion/css'; import { FormattedMessage } from '@kbn/i18n-react'; import { ExpandableSection } from '../../document_details/right/components/expandable_section'; @@ -50,13 +50,9 @@ export interface RuleDetailsProps { * Rule details content on the right section of expandable flyout */ export const PanelContent = memo(({ rule }: RuleDetailsProps) => { - const { euiTheme } = useEuiTheme(); const { ruleActionsData } = useMemo( - () => - rule != null - ? getStepsData({ rule, detailsView: true, euiTheme }) - : { ruleActionsData: null }, - [rule, euiTheme] + () => (rule != null ? getStepsData({ rule, detailsView: true }) : { ruleActionsData: null }), + [rule] ); const hasNotificationActions = useMemo( From 7678e74faae3294a6cc0a03bb713dabc1448dc97 Mon Sep 17 00:00:00 2001 From: Angela Chuang Date: Wed, 15 Jan 2025 16:28:08 +0000 Subject: [PATCH 12/19] tests --- .../common/utils/__mocks__/severity_colors.ts | 38 +++++++++++ .../common/utils/risk_color_palette.test.tsx | 63 +++++++++++++++++++ .../severity_level_panel/helpers.test.tsx | 24 ++++++- 3 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 x-pack/solutions/security/plugins/security_solution/public/common/utils/__mocks__/severity_colors.ts create mode 100644 x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.test.tsx diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/utils/__mocks__/severity_colors.ts b/x-pack/solutions/security/plugins/security_solution/public/common/utils/__mocks__/severity_colors.ts new file mode 100644 index 0000000000000..cf621306d4988 --- /dev/null +++ b/x-pack/solutions/security/plugins/security_solution/public/common/utils/__mocks__/severity_colors.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { EuiThemeComputed } from '@elastic/eui'; + +const mockAmsterdamColors = { + vis: { + euiColorVis0: 'euiColorVis0', + euiColorVis5: 'euiColorVis5', + euiColorVis7: 'euiColorVis7', + euiColorVis9: 'euiColorVis9', + }, +}; + +const mockBorealisColors = { + vis: { + euiColorVisSuccess0: 'euiColorVisSuccess0', + euiColorSeverity7: 'euiColorSeverity7', + euiColorSeverity10: 'euiColorSeverity10', + euiColorSeverity14: 'euiColorSeverity14', + }, +}; + +export const getMockEuiAmsterdamTheme = () => + ({ + themeName: 'EUI_THEME_AMSTERDAM', + colors: mockAmsterdamColors, + } as EuiThemeComputed); + +export const getMockEuiBorealisTheme = () => + ({ + themeName: 'EUI_THEME_BOREALIS', + colors: mockBorealisColors, + } as EuiThemeComputed); diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.test.tsx new file mode 100644 index 0000000000000..d58803659fe42 --- /dev/null +++ b/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.test.tsx @@ -0,0 +1,63 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { renderHook } from '@testing-library/react'; +import { getRiskSeverityColors, useRiskSeverityColors } from './risk_color_palette'; +import { useEuiTheme } from '@elastic/eui'; +import { getMockEuiAmsterdamTheme, getMockEuiBorealisTheme } from './__mocks__/severity_colors'; + +jest.mock('@elastic/eui', () => ({ + useEuiTheme: jest.fn(), +})); + +describe('risk_color_palette', () => { + const scenarios = [ + { + mockEuiTheme: getMockEuiAmsterdamTheme(), + themeName: 'Amsterdam', + expected: { + low: 'euiColorVis0', + medium: 'euiColorVis5', + high: 'euiColorVis7', + critical: 'euiColorVis9', + }, + }, + { + mockEuiTheme: getMockEuiBorealisTheme(), + themeName: 'Borealis', + expected: { + low: 'euiColorVisSuccess0', + medium: 'euiColorSeverity7', + high: 'euiColorSeverity10', + critical: 'euiColorSeverity14', + }, + }, + ]; + + describe.each(scenarios)( + '$themeName: getRiskSeverityColors', + ({ mockEuiTheme, themeName, expected }) => { + it(`returns the correct colors for ${themeName} theme`, () => { + expect(getRiskSeverityColors(mockEuiTheme)).toEqual(expected); + }); + } + ); + + describe.each(scenarios)( + '$themeName: useRiskSeverityColors', + ({ mockEuiTheme, themeName, expected }) => { + const useEuiThemeMock = useEuiTheme as jest.Mock; + + it(`returns the correct colors for ${themeName} theme`, () => { + useEuiThemeMock.mockReturnValue({ + euiTheme: mockEuiTheme, + }); + const { result } = renderHook(() => useRiskSeverityColors()); + expect(result.current).toEqual(expected); + }); + } + ); +}); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/helpers.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/helpers.test.tsx index 9e493ba8fe48f..85e87c2e5d564 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/helpers.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/helpers.test.tsx @@ -4,10 +4,14 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { parseSeverityData } from './helpers'; +import { getSeverityColor, parseSeverityData } from './helpers'; import * as mock from './mock_data'; import type { AlertsBySeverityAgg } from './types'; import type { AlertSearchResponse } from '../../../containers/detection_engine/alerts/types'; +import { + getMockEuiAmsterdamTheme, + getMockEuiBorealisTheme, +} from '../../../../common/utils/__mocks__/severity_colors'; describe('parse severity data', () => { test('parse alerts with data', () => { @@ -24,3 +28,21 @@ describe('parse severity data', () => { expect(res).toEqual([]); }); }); + +describe.each([ + { severity: 'critical', colorToken: 'euiColorVis9', themeName: 'Amsterdam' }, + { severity: 'high', colorToken: 'euiColorVis7', themeName: 'Amsterdam' }, + { severity: 'medium', colorToken: 'euiColorVis5', themeName: 'Amsterdam' }, + { severity: 'low', colorToken: 'euiColorVis0', themeName: 'Amsterdam' }, + { severity: 'critical', colorToken: 'euiColorSeverity14', themeName: 'Borealis' }, + { severity: 'high', colorToken: 'euiColorSeverity10', themeName: 'Borealis' }, + { severity: 'medium', colorToken: 'euiColorSeverity7', themeName: 'Borealis' }, + { severity: 'low', colorToken: 'euiColorVisSuccess0', themeName: 'Borealis' }, +])('$themeName: getSeverityColor', ({ severity, colorToken, themeName }) => { + const mockEuiTheme = + themeName === 'Amsterdam' ? getMockEuiAmsterdamTheme() : getMockEuiBorealisTheme(); + + test(`returns color for given severity: ${severity}`, () => { + expect(getSeverityColor(severity, mockEuiTheme)).toEqual(colorToken); + }); +}); From c2b39f129a2f1a272dfe3241032574897fa8b3fe Mon Sep 17 00:00:00 2001 From: Angela Chuang Date: Fri, 24 Jan 2025 00:06:14 +0800 Subject: [PATCH 13/19] use hard coded serverity colors --- .../common/utils/risk_color_palette.tsx | 24 ++++++------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.tsx b/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.tsx index 9d6dbfdc5a017..7cd44e23e5e92 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.tsx @@ -10,24 +10,14 @@ import { useEuiTheme } from '@elastic/eui'; import type { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; import { useMemo } from 'react'; -export const getRiskSeverityColors = (euiTheme: EuiThemeComputed) => { - if (euiTheme.themeName === 'EUI_THEME_AMSTERDAM') { - return { - low: euiTheme.colors.vis.euiColorVis0, - medium: euiTheme.colors.vis.euiColorVis5, - high: euiTheme.colors.vis.euiColorVis7, - critical: euiTheme.colors.vis.euiColorVis9, - }; - } +export const SEVERITY_COLOR = { + low: '#54B399', + medium: '#D6BF57', + high: '#DA8B45', + critical: '#E7664C', +} as const; - // Borealis - return { - low: euiTheme.colors.vis.euiColorVisSuccess0, - medium: euiTheme.colors.vis.euiColorSeverity7, - high: euiTheme.colors.vis.euiColorSeverity10, - critical: euiTheme.colors.vis.euiColorSeverity14, - }; -}; +export const getRiskSeverityColors = (_: EuiThemeComputed) => SEVERITY_COLOR; export const useRiskSeverityColors = (): Record => { const { euiTheme } = useEuiTheme(); From b275cf51525111242359999812684e7ecc996cba Mon Sep 17 00:00:00 2001 From: Angela Chuang Date: Fri, 24 Jan 2025 00:16:40 +0800 Subject: [PATCH 14/19] unit tests --- .../common/utils/risk_color_palette.test.tsx | 21 ++++++++----------- .../common/utils/risk_color_palette.tsx | 1 + 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.test.tsx index d58803659fe42..8ca6ba8740b1d 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.test.tsx @@ -13,27 +13,24 @@ jest.mock('@elastic/eui', () => ({ useEuiTheme: jest.fn(), })); +const EXPECTED_SEVERITY_COLOR = { + low: '#54B399', + medium: '#D6BF57', + high: '#DA8B45', + critical: '#E7664C', +} as const; + describe('risk_color_palette', () => { const scenarios = [ { mockEuiTheme: getMockEuiAmsterdamTheme(), themeName: 'Amsterdam', - expected: { - low: 'euiColorVis0', - medium: 'euiColorVis5', - high: 'euiColorVis7', - critical: 'euiColorVis9', - }, + expected: EXPECTED_SEVERITY_COLOR, }, { mockEuiTheme: getMockEuiBorealisTheme(), themeName: 'Borealis', - expected: { - low: 'euiColorVisSuccess0', - medium: 'euiColorSeverity7', - high: 'euiColorSeverity10', - critical: 'euiColorSeverity14', - }, + expected: EXPECTED_SEVERITY_COLOR, }, ]; diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.tsx b/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.tsx index 7cd44e23e5e92..ba0deacd9de4d 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.tsx @@ -10,6 +10,7 @@ import { useEuiTheme } from '@elastic/eui'; import type { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; import { useMemo } from 'react'; +// Temporary solution until we have a decision for color palette export const SEVERITY_COLOR = { low: '#54B399', medium: '#D6BF57', From 3ae15b1e6c2276a9fab058fcb915c3fc2027aa64 Mon Sep 17 00:00:00 2001 From: Angela Chuang Date: Fri, 24 Jan 2025 16:20:59 +0800 Subject: [PATCH 15/19] unit tests --- .../severity_level_panel/helpers.test.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/helpers.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/helpers.test.tsx index 85e87c2e5d564..db8fde9552163 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/helpers.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/helpers.test.tsx @@ -30,14 +30,14 @@ describe('parse severity data', () => { }); describe.each([ - { severity: 'critical', colorToken: 'euiColorVis9', themeName: 'Amsterdam' }, - { severity: 'high', colorToken: 'euiColorVis7', themeName: 'Amsterdam' }, - { severity: 'medium', colorToken: 'euiColorVis5', themeName: 'Amsterdam' }, - { severity: 'low', colorToken: 'euiColorVis0', themeName: 'Amsterdam' }, - { severity: 'critical', colorToken: 'euiColorSeverity14', themeName: 'Borealis' }, - { severity: 'high', colorToken: 'euiColorSeverity10', themeName: 'Borealis' }, - { severity: 'medium', colorToken: 'euiColorSeverity7', themeName: 'Borealis' }, - { severity: 'low', colorToken: 'euiColorVisSuccess0', themeName: 'Borealis' }, + { severity: 'critical', colorToken: '#E7664C', themeName: 'Amsterdam' }, + { severity: 'high', colorToken: '#DA8B45', themeName: 'Amsterdam' }, + { severity: 'medium', colorToken: '#D6BF57', themeName: 'Amsterdam' }, + { severity: 'low', colorToken: '#54B399', themeName: 'Amsterdam' }, + { severity: 'critical', colorToken: '#E7664C', themeName: 'Borealis' }, + { severity: 'high', colorToken: '#DA8B45', themeName: 'Borealis' }, + { severity: 'medium', colorToken: '#D6BF57', themeName: 'Borealis' }, + { severity: 'low', colorToken: '#54B399', themeName: 'Borealis' }, ])('$themeName: getSeverityColor', ({ severity, colorToken, themeName }) => { const mockEuiTheme = themeName === 'Amsterdam' ? getMockEuiAmsterdamTheme() : getMockEuiBorealisTheme(); From 8fa94c3826b7244192d0020710e964f9f8f28055 Mon Sep 17 00:00:00 2001 From: Angela Chuang Date: Fri, 24 Jan 2025 21:44:51 +0800 Subject: [PATCH 16/19] update severity colors --- .../public/common/constants.ts | 17 +++++++++++++ .../common/utils/__mocks__/severity_colors.ts | 20 --------------- .../common/utils/risk_color_palette.test.tsx | 13 +++++++--- .../common/utils/risk_color_palette.tsx | 25 +++++++++++++++++-- .../lib/chart_palette/index.test.ts | 10 ++++---- 5 files changed, 55 insertions(+), 30 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/constants.ts b/x-pack/solutions/security/plugins/security_solution/public/common/constants.ts index 67915eca4ecfd..3b5cd00f25a0c 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/constants.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/constants.ts @@ -4,6 +4,23 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import { euiThemeVars } from '@kbn/ui-theme'; +/** + * @deprecated Use getRiskSeverityColors instead + */ +export const RISK_COLOR_LOW = euiThemeVars.euiColorVis0; +/** + * @deprecated Use getRiskSeverityColors instead + */ +export const RISK_COLOR_MEDIUM = euiThemeVars.euiColorVis5_behindText; +/** + * @deprecated Use getRiskSeverityColors instead + */ +export const RISK_COLOR_HIGH = euiThemeVars.euiColorVis9_behindText; +/** + * @deprecated Use getRiskSeverityColors instead + */ +export const RISK_COLOR_CRITICAL = euiThemeVars.euiColorDanger; export const RISK_SCORE_LOW = 21; export const RISK_SCORE_MEDIUM = 47; diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/utils/__mocks__/severity_colors.ts b/x-pack/solutions/security/plugins/security_solution/public/common/utils/__mocks__/severity_colors.ts index cf621306d4988..027827b314ebd 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/utils/__mocks__/severity_colors.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/utils/__mocks__/severity_colors.ts @@ -7,32 +7,12 @@ import type { EuiThemeComputed } from '@elastic/eui'; -const mockAmsterdamColors = { - vis: { - euiColorVis0: 'euiColorVis0', - euiColorVis5: 'euiColorVis5', - euiColorVis7: 'euiColorVis7', - euiColorVis9: 'euiColorVis9', - }, -}; - -const mockBorealisColors = { - vis: { - euiColorVisSuccess0: 'euiColorVisSuccess0', - euiColorSeverity7: 'euiColorSeverity7', - euiColorSeverity10: 'euiColorSeverity10', - euiColorSeverity14: 'euiColorSeverity14', - }, -}; - export const getMockEuiAmsterdamTheme = () => ({ themeName: 'EUI_THEME_AMSTERDAM', - colors: mockAmsterdamColors, } as EuiThemeComputed); export const getMockEuiBorealisTheme = () => ({ themeName: 'EUI_THEME_BOREALIS', - colors: mockBorealisColors, } as EuiThemeComputed); diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.test.tsx index 8ca6ba8740b1d..136153d2a760c 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.test.tsx @@ -13,7 +13,14 @@ jest.mock('@elastic/eui', () => ({ useEuiTheme: jest.fn(), })); -const EXPECTED_SEVERITY_COLOR = { +const EXPECTED_SEVERITY_COLOR_AMSTERDAM = { + low: '#54b399', + medium: '#f1d86f', + high: '#ff7e62', + critical: '#bd271e', +}; + +const EXPECTED_SEVERITY_COLOR_BOREALIS = { low: '#54B399', medium: '#D6BF57', high: '#DA8B45', @@ -25,12 +32,12 @@ describe('risk_color_palette', () => { { mockEuiTheme: getMockEuiAmsterdamTheme(), themeName: 'Amsterdam', - expected: EXPECTED_SEVERITY_COLOR, + expected: EXPECTED_SEVERITY_COLOR_AMSTERDAM, }, { mockEuiTheme: getMockEuiBorealisTheme(), themeName: 'Borealis', - expected: EXPECTED_SEVERITY_COLOR, + expected: EXPECTED_SEVERITY_COLOR_BOREALIS, }, ]; diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.tsx b/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.tsx index ba0deacd9de4d..10c175ce8cf26 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.tsx @@ -9,8 +9,15 @@ import type { EuiThemeComputed } from '@elastic/eui'; import { useEuiTheme } from '@elastic/eui'; import type { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; import { useMemo } from 'react'; +import { + RISK_COLOR_CRITICAL, + RISK_COLOR_HIGH, + RISK_COLOR_LOW, + RISK_COLOR_MEDIUM, +} from '../constants'; -// Temporary solution until we have a decision for color palette +// Temporary solution until we have a decision for color palette https://github.com/elastic/kibana/issues/203387 +// TODO: Borealis migration - move from hardcoded values to severity palette https://github.com/elastic/security-team/issues/11606 export const SEVERITY_COLOR = { low: '#54B399', medium: '#D6BF57', @@ -18,7 +25,21 @@ export const SEVERITY_COLOR = { critical: '#E7664C', } as const; -export const getRiskSeverityColors = (_: EuiThemeComputed) => SEVERITY_COLOR; +const isAmsterdam = (euiThemeName: string) => { + return euiThemeName?.toLowerCase().includes('amsterdam'); +}; + +export const getRiskSeverityColors = (euiTheme: EuiThemeComputed) => { + if (euiTheme && isAmsterdam(euiTheme.themeName)) { + return { + low: RISK_COLOR_LOW, + medium: RISK_COLOR_MEDIUM, + high: RISK_COLOR_HIGH, + critical: RISK_COLOR_CRITICAL, + }; + } + return SEVERITY_COLOR; +}; export const useRiskSeverityColors = (): Record => { const { euiTheme } = useEuiTheme(); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/chart_palette/index.test.ts b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/chart_palette/index.test.ts index ec607d659eb63..d7974ac8f4a51 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/chart_palette/index.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/chart_palette/index.test.ts @@ -24,23 +24,23 @@ describe('getFillColor', () => { const expectedColorPalette = getRiskSeverityColors(euiTheme); it('returns the expected fill color', () => { - expect(getFillColor({ riskScore: 50, colorPalette })).toEqual('#D6BF57'); + expect(getFillColor({ riskScore: 50, colorPalette })).toEqual('#f1d86f'); }); it('returns the expected fill color when risk score is zero', () => { - expect(getFillColor({ riskScore: 0, colorPalette })).toEqual('#54B399'); + expect(getFillColor({ riskScore: 0, colorPalette })).toEqual('#54b399'); }); it('returns the expected fill color when risk score is less than zero', () => { - expect(getFillColor({ riskScore: -1, colorPalette })).toEqual('#54B399'); + expect(getFillColor({ riskScore: -1, colorPalette })).toEqual('#54b399'); }); it('returns the expected fill color when risk score is 100', () => { - expect(getFillColor({ riskScore: 100, colorPalette })).toEqual('#E7664C'); + expect(getFillColor({ riskScore: 100, colorPalette })).toEqual('#bd271e'); }); it('returns the expected fill color when risk score is greater than 100', () => { - expect(getFillColor({ riskScore: 101, colorPalette })).toEqual('#E7664C'); + expect(getFillColor({ riskScore: 101, colorPalette })).toEqual('#bd271e'); }); it('returns the expected fill color when risk score is greater than RISK_SCORE_CRITICAL', () => { From 0b6a6450ff323019a37da9f89ad0b88d2f17eae9 Mon Sep 17 00:00:00 2001 From: Angela Chuang Date: Fri, 24 Jan 2025 21:57:08 +0800 Subject: [PATCH 17/19] update comments --- .../security_solution/public/common/utils/risk_color_palette.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.tsx b/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.tsx index 10c175ce8cf26..e0eac26c7fe04 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/common/utils/risk_color_palette.tsx @@ -17,7 +17,6 @@ import { } from '../constants'; // Temporary solution until we have a decision for color palette https://github.com/elastic/kibana/issues/203387 -// TODO: Borealis migration - move from hardcoded values to severity palette https://github.com/elastic/security-team/issues/11606 export const SEVERITY_COLOR = { low: '#54B399', medium: '#D6BF57', From 4341caf1318a7bfeb285b45b721ca1862c80e64b Mon Sep 17 00:00:00 2001 From: Angela Chuang Date: Fri, 24 Jan 2025 23:58:10 +0800 Subject: [PATCH 18/19] unit tests --- .../alerts_treemap/lib/layers/index.test.ts | 8 ++--- .../legend/get_flattened_legend_items.test.ts | 32 +++++++++---------- .../alerts_treemap/lib/legend/index.test.ts | 14 ++++---- .../severity_level_panel/helpers.test.tsx | 8 ++--- .../components/alert_count_insight.test.tsx | 8 ++--- .../components/detection_response/utils.tsx | 2 +- 6 files changed, 36 insertions(+), 36 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/layers/index.test.ts b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/layers/index.test.ts index c3b675b6d1bc1..24f40ee94067f 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/layers/index.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/layers/index.test.ts @@ -73,14 +73,14 @@ describe('layers', () => { const dataName = 'mimikatz process started'; expect( getLayersOneDimension({ colorPalette, maxRiskSubAggregations })[0].shape.fillColor(dataName) - ).toEqual('#E7664C'); + ).toEqual('#bd271e'); }); it('return the default fill color when dataName is not found in the maxRiskSubAggregations', () => { const dataName = 'this does not exist'; expect( getLayersOneDimension({ colorPalette, maxRiskSubAggregations })[0].shape.fillColor(dataName) - ).toEqual('#54B399'); + ).toEqual('#54b399'); }); }); @@ -169,7 +169,7 @@ describe('layers', () => { { index: 0, value: 'Host-k8iyfzraq9' }, ], }) - ).toEqual('#E7664C'); + ).toEqual('#bd271e'); }); it('returns the default fillColor for layer 1 when the group from path is not found', () => { @@ -192,7 +192,7 @@ describe('layers', () => { { index: 0, value: 'nope' }, ], }) - ).toEqual('#54B399'); + ).toEqual('#54b399'); }); }); }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/legend/get_flattened_legend_items.test.ts b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/legend/get_flattened_legend_items.test.ts index 4db6d61a63123..0702b3b98b738 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/legend/get_flattened_legend_items.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/legend/get_flattened_legend_items.test.ts @@ -25,25 +25,25 @@ describe('getFlattenedLegendItems', () => { value: 'matches everything', }, { - color: '#54B399', + color: '#54b399', count: 12, field: 'host.name', value: 'Host-k8iyfzraq9', }, { - color: '#54B399', + color: '#54b399', count: 10, field: 'host.name', value: 'Host-ao1a4wu7vn', }, { - color: '#54B399', + color: '#54b399', count: 7, field: 'host.name', value: 'Host-3fbljiq8rj', }, { - color: '#54B399', + color: '#54b399', count: 5, field: 'host.name', value: 'Host-r4y6xi92ob', @@ -54,25 +54,25 @@ describe('getFlattenedLegendItems', () => { value: 'EQL process sequence', }, { - color: '#DA8B45', + color: '#ff7e62', count: 10, field: 'host.name', value: 'Host-k8iyfzraq9', }, { - color: '#DA8B45', + color: '#ff7e62', count: 7, field: 'host.name', value: 'Host-ao1a4wu7vn', }, { - color: '#DA8B45', + color: '#ff7e62', count: 5, field: 'host.name', value: 'Host-3fbljiq8rj', }, { - color: '#DA8B45', + color: '#ff7e62', count: 3, field: 'host.name', value: 'Host-r4y6xi92ob', @@ -83,25 +83,25 @@ describe('getFlattenedLegendItems', () => { value: 'Endpoint Security', }, { - color: '#D6BF57', + color: '#f1d86f', count: 11, field: 'host.name', value: 'Host-ao1a4wu7vn', }, { - color: '#D6BF57', + color: '#f1d86f', count: 6, field: 'host.name', value: 'Host-3fbljiq8rj', }, { - color: '#D6BF57', + color: '#f1d86f', count: 1, field: 'host.name', value: 'Host-k8iyfzraq9', }, { - color: '#D6BF57', + color: '#f1d86f', count: 1, field: 'host.name', value: 'Host-r4y6xi92ob', @@ -112,19 +112,19 @@ describe('getFlattenedLegendItems', () => { value: 'mimikatz process started', }, { - color: '#E7664C', + color: '#bd271e', count: 3, field: 'host.name', value: 'Host-k8iyfzraq9', }, { - color: '#E7664C', + color: '#bd271e', count: 1, field: 'host.name', value: 'Host-3fbljiq8rj', }, { - color: '#E7664C', + color: '#bd271e', count: 1, field: 'host.name', value: 'Host-r4y6xi92ob', @@ -135,7 +135,7 @@ describe('getFlattenedLegendItems', () => { value: 'Threshold rule', }, { - color: '#E7664C', + color: '#bd271e', count: 1, field: 'host.name', value: 'Host-r4y6xi92ob', diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/legend/index.test.ts b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/legend/index.test.ts index d7f0276afab6f..deeff81b97d2a 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/legend/index.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/alerts_treemap_panel/alerts_treemap/lib/legend/index.test.ts @@ -60,7 +60,7 @@ describe('legend', () => { showColor: true, stackByField0: 'kibana.alert.rule.name', }).color - ).toEqual('#54B399'); + ).toEqual('#54b399'); }); it('returns the expected count', () => { @@ -170,7 +170,7 @@ describe('legend', () => { }) ) ).toEqual({ - color: '#54B399', + color: '#54b399', count: 12, field: 'host.name', value: 'Host-k8iyfzraq9', @@ -216,35 +216,35 @@ describe('legend', () => { }).map((x) => omit(['render', 'dataProviderId'], x)) ).toEqual([ { - color: '#54B399', + color: '#54b399', count: 34, field: 'kibana.alert.rule.name', value: 'matches everything', scopeId: TableId.alertsOnAlertsPage, }, { - color: '#DA8B45', + color: '#ff7e62', count: 28, field: 'kibana.alert.rule.name', value: 'EQL process sequence', scopeId: TableId.alertsOnAlertsPage, }, { - color: '#D6BF57', + color: '#f1d86f', count: 19, field: 'kibana.alert.rule.name', value: 'Endpoint Security', scopeId: TableId.alertsOnAlertsPage, }, { - color: '#E7664C', + color: '#bd271e', count: 5, field: 'kibana.alert.rule.name', value: 'mimikatz process started', scopeId: TableId.alertsOnAlertsPage, }, { - color: '#E7664C', + color: '#bd271e', count: 1, field: 'kibana.alert.rule.name', value: 'Threshold rule', diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/helpers.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/helpers.test.tsx index db8fde9552163..f0ed436159ec0 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/helpers.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/helpers.test.tsx @@ -30,10 +30,10 @@ describe('parse severity data', () => { }); describe.each([ - { severity: 'critical', colorToken: '#E7664C', themeName: 'Amsterdam' }, - { severity: 'high', colorToken: '#DA8B45', themeName: 'Amsterdam' }, - { severity: 'medium', colorToken: '#D6BF57', themeName: 'Amsterdam' }, - { severity: 'low', colorToken: '#54B399', themeName: 'Amsterdam' }, + { severity: 'critical', colorToken: '#bd271e', themeName: 'Amsterdam' }, + { severity: 'high', colorToken: '#ff7e62', themeName: 'Amsterdam' }, + { severity: 'medium', colorToken: '#f1d86f', themeName: 'Amsterdam' }, + { severity: 'low', colorToken: '#54b399', themeName: 'Amsterdam' }, { severity: 'critical', colorToken: '#E7664C', themeName: 'Borealis' }, { severity: 'high', colorToken: '#DA8B45', themeName: 'Borealis' }, { severity: 'medium', colorToken: '#D6BF57', themeName: 'Borealis' }, diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/alert_count_insight.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/alert_count_insight.test.tsx index 260a49c56c340..8c648d5f3c302 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/alert_count_insight.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/alert_count_insight.test.tsx @@ -152,10 +152,10 @@ describe('getFormattedAlertStats', () => { it('should return alert stats', () => { const alertStats = getFormattedAlertStats(mockAlertData, euiTheme); expect(alertStats).toEqual([ - { key: 'High', count: 2, color: SEVERITY_COLOR.high }, - { key: 'Low', count: 2, color: SEVERITY_COLOR.low }, - { key: 'Medium', count: 2, color: SEVERITY_COLOR.medium }, - { key: 'Critical', count: 2, color: SEVERITY_COLOR.critical }, + { key: 'High', count: 2, color: '#ff7e62' }, + { key: 'Low', count: 2, color: '#54b399' }, + { key: 'Medium', count: 2, color: '#f1d86f' }, + { key: 'Critical', count: 2, color: '#bd271e' }, ]); }); 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 9163cc1edd2de..e272ca6530053 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 @@ -5,7 +5,7 @@ * 2.0. */ /** - * deprecated, use getRiskSeverityColors or useRiskSeverityColors from /common/utils/risk_color_palette.tsx instead + * @deprecated, use getRiskSeverityColors or useRiskSeverityColors from /common/utils/risk_color_palette.tsx instead */ export const SEVERITY_COLOR = { critical: '#E7664C', From 500c7a5f2fb86b2d779927eac64872241f1ca4a2 Mon Sep 17 00:00:00 2001 From: Angela Chuang Date: Sat, 25 Jan 2025 00:28:33 +0800 Subject: [PATCH 19/19] lint --- .../shared/components/alert_count_insight.test.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/alert_count_insight.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/alert_count_insight.test.tsx index 8c648d5f3c302..7fa3cbe7a2dd6 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/alert_count_insight.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/alert_count_insight.test.tsx @@ -11,7 +11,6 @@ import { TestProviders } from '../../../../common/mock'; import { AlertCountInsight, getFormattedAlertStats } from './alert_count_insight'; import { useAlertsByStatus } from '../../../../overview/components/detection_response/alerts_by_status/use_alerts_by_status'; import type { ParsedAlertsData } from '../../../../overview/components/detection_response/alerts_by_status/types'; -import { SEVERITY_COLOR } from '../../../../overview/components/detection_response/utils'; import { useEuiTheme } from '@elastic/eui'; import { INSIGHTS_ALERTS_COUNT_INVESTIGATE_IN_TIMELINE_BUTTON_TEST_ID,