From 179034c387c2a920ffc381485221ec8ba419f74f Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Thu, 9 Feb 2023 15:45:46 -0500 Subject: [PATCH] [8.7] [Security Solution][Bug] Alerts type discrepancy and ui improvements (#150504) (#150649) # Backport This will backport the following commits from `main` to `8.7`: - [[Security Solution][Bug] Alerts type discrepancy and ui improvements (#150504)](https://github.com/elastic/kibana/pull/150504) ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) Co-authored-by: christineweng <18648970+christineweng@users.noreply.github.com> --- .../components/charts/donutchart_empty.tsx | 3 +- .../alerts_by_type_panel/columns.tsx | 4 +- .../alerts_by_type_panel/helpers.tsx | 49 +++++++++++-------- .../alerts_by_type_panel/translations.ts | 14 ++++++ .../helpers.test.tsx | 2 +- .../alerts_progress_bar_panel/helpers.tsx | 14 +++--- .../alerts_progress_bar_panel/mock_data.ts | 1 - .../severity_level_chart.tsx | 18 +++---- 8 files changed, 63 insertions(+), 42 deletions(-) diff --git a/x-pack/plugins/security_solution/public/common/components/charts/donutchart_empty.tsx b/x-pack/plugins/security_solution/public/common/components/charts/donutchart_empty.tsx index a378f94bfbe1ec..e59a685133ba56 100644 --- a/x-pack/plugins/security_solution/public/common/components/charts/donutchart_empty.tsx +++ b/x-pack/plugins/security_solution/public/common/components/charts/donutchart_empty.tsx @@ -6,6 +6,7 @@ */ import React from 'react'; import styled from 'styled-components'; +import { useEuiBackgroundColor } from '@elastic/eui'; interface DonutChartEmptyProps { size?: number; @@ -29,7 +30,7 @@ const SmallRing = styled.div` ${({ size }) => ` height: ${size}px; width: ${size}px; - background-color: white; + background-color: ${useEuiBackgroundColor('plain')}; display: inline-block; vertical-align: middle;`} `; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_by_type_panel/columns.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_by_type_panel/columns.tsx index f1479ae58f9453..6b23f82ad917ac 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_by_type_panel/columns.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_by_type_panel/columns.tsx @@ -12,7 +12,7 @@ import type { AlertsTypeData, AlertType } from './types'; import { DefaultDraggable } from '../../../../common/components/draggables'; import { FormattedCount } from '../../../../common/components/formatted_number'; import { ALERTS_HEADERS_RULE_NAME } from '../../alerts_table/translations'; -import { ALERT_TYPE_COLOR } from './helpers'; +import { ALERT_TYPE_COLOR, ALERT_TYPE_LABEL } from './helpers'; import { COUNT_TABLE_TITLE } from '../alerts_count_panel/translations'; import * as i18n from './translations'; @@ -46,7 +46,7 @@ export const getAlertsTypeTableColumns = (): Array - {type} + {ALERT_TYPE_LABEL[type as AlertType]} ); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_by_type_panel/helpers.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_by_type_panel/helpers.tsx index 94246f6932178a..55cc705cf78bbb 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_by_type_panel/helpers.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_by_type_panel/helpers.tsx @@ -8,11 +8,16 @@ import { has } from 'lodash'; import type { AlertType, AlertsByTypeAgg, AlertsTypeData } from './types'; import type { AlertSearchResponse } from '../../../containers/detection_engine/alerts/types'; import type { SummaryChartsData, SummaryChartsAgg } from '../alerts_summary_charts_panel/types'; +import { DETECTION, PREVENTION } from './translations'; export const ALERT_TYPE_COLOR = { Detection: '#D36086', Prevention: '#54B399', }; +export const ALERT_TYPE_LABEL = { + Detection: DETECTION, + Prevention: PREVENTION, +}; export const parseAlertsTypeData = ( response: AlertSearchResponse<{}, AlertsByTypeAgg> @@ -22,40 +27,44 @@ export const parseAlertsTypeData = ( ? [] : rulesBuckets.flatMap((rule) => { const events = rule.ruleByEventType?.buckets ?? []; - return getAggregateAlerts(rule.key, events); + return getAlertType(rule.key, rule.doc_count, events); }); }; -const getAggregateAlerts = ( +const getAlertType = ( ruleName: string, + ruleCount: number, ruleEvents: Array<{ key: string; doc_count: number }> ): AlertsTypeData[] => { - let preventions = 0; - let detections = 0; - - ruleEvents.map((eventBucket) => { - return eventBucket.key === 'denied' - ? (preventions += eventBucket.doc_count) - : (detections += eventBucket.doc_count); - }); + const preventions = ruleEvents.find((bucket) => bucket.key === 'denied'); + if (!preventions) { + return [ + { + rule: ruleName, + type: 'Detection' as AlertType, + value: ruleCount, + color: ALERT_TYPE_COLOR.Detection, + }, + ]; + } const ret = []; - if (detections > 0) { + if (preventions.doc_count < ruleCount) { ret.push({ rule: ruleName, type: 'Detection' as AlertType, - value: detections, + value: ruleCount - preventions.doc_count, color: ALERT_TYPE_COLOR.Detection, }); } - if (preventions > 0) { - ret.push({ - rule: ruleName, - type: 'Prevention' as AlertType, - value: preventions, - color: ALERT_TYPE_COLOR.Prevention, - }); - } + + ret.push({ + rule: ruleName, + type: 'Prevention' as AlertType, + value: preventions.doc_count, + color: ALERT_TYPE_COLOR.Prevention, + }); + return ret; }; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_by_type_panel/translations.ts b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_by_type_panel/translations.ts index 462ff3ea2774be..5f1c6c4ada6426 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_by_type_panel/translations.ts +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_by_type_panel/translations.ts @@ -33,3 +33,17 @@ export const DETECTIONS = i18n.translate( defaultMessage: 'Detections', } ); + +export const PREVENTION = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.alertsByType.prevention', + { + defaultMessage: 'Prevention', + } +); + +export const DETECTION = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.alertsByType.detection', + { + defaultMessage: 'Detection', + } +); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_progress_bar_panel/helpers.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_progress_bar_panel/helpers.test.tsx index 06c7cc0ce7e164..cea8c44d0be60c 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_progress_bar_panel/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_progress_bar_panel/helpers.test.tsx @@ -17,7 +17,7 @@ describe('parse progress bar data', () => { expect(res).toEqual(mock.parsedAlerts); }); - test('parse severity without data', () => { + test('parse alerts without data', () => { const res = parseAlertsGroupingData( mock.mockAlertsEmptyData as AlertSearchResponse<{}, AlertsByGroupingAgg> ); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_progress_bar_panel/helpers.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_progress_bar_panel/helpers.tsx index a441f41094c5d6..a05fe64a80837c 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_progress_bar_panel/helpers.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_progress_bar_panel/helpers.tsx @@ -33,12 +33,14 @@ export const parseAlertsGroupingData = ( }; }); - topAlerts.push({ - key: 'Other', - value: other, - percentage: Math.round((other / total) * 1000) / 10, - label: i18n.OTHER, - }); + if (other > 0) { + topAlerts.push({ + key: 'Other', + value: other, + percentage: Math.round((other / total) * 1000) / 10, + label: i18n.OTHER, + }); + } return topAlerts; }; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_progress_bar_panel/mock_data.ts b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_progress_bar_panel/mock_data.ts index 6eed4866333bc7..1965ef1cfe162f 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_progress_bar_panel/mock_data.ts +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_progress_bar_panel/mock_data.ts @@ -97,5 +97,4 @@ export const parsedAlerts = [ { key: 'Host-v5biklvcy8', value: 234, label: 'Host-v5biklvcy8', percentage: 41.1 }, { key: 'Host-5y1uprxfv2', value: 186, label: 'Host-5y1uprxfv2', percentage: 32.6 }, { key: 'Host-ssf1mhgy5c', value: 150, label: 'Host-ssf1mhgy5c', percentage: 26.3 }, - { key: 'Other', value: 0, label: 'Other', percentage: 0 }, ]; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/severity_level_chart.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/severity_level_chart.tsx index 1ef5a9dd53f28c..395357ff7b1b06 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/severity_level_chart.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/severity_level_panel/severity_level_chart.tsx @@ -4,9 +4,10 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React, { useCallback, useMemo, useEffect, useState } from 'react'; +import React, { useCallback, useMemo } from 'react'; import { isEmpty } from 'lodash/fp'; import { ALERT_SEVERITY } from '@kbn/rule-data-utils'; +import styled from 'styled-components'; import { EuiFlexGroup, EuiFlexItem, EuiInMemoryTable, EuiLoadingSpinner } from '@elastic/eui'; import type { SortOrder } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { ShapeTreeNode, ElementClickListener } from '@elastic/charts'; @@ -17,10 +18,12 @@ import { ChartLabel } from '../../../../overview/components/detection_response/a import { getSeverityTableColumns } from './columns'; import { getSeverityColor } from './helpers'; import { TOTAL_COUNT_OF_ALERTS } from '../../alerts_table/translations'; -import { showInitialLoadingSpinner } from '../alerts_histogram_panel/helpers'; const DONUT_HEIGHT = 150; +const StyledEuiLoadingSpinner = styled(EuiLoadingSpinner)` + margin: auto; +`; export interface SeverityLevelProps { data: SeverityData[]; isLoading: boolean; @@ -32,7 +35,6 @@ export const SeverityLevelChart: React.FC = ({ isLoading, addFilter, }) => { - const [isInitialLoading, setIsInitialLoading] = useState(true); const columns = useMemo(() => getSeverityTableColumns(), []); const count = useMemo(() => { @@ -71,12 +73,6 @@ export const SeverityLevelChart: React.FC = ({ [addFilter] ); - useEffect(() => { - if (!showInitialLoadingSpinner({ isInitialLoading, isLoadingAlerts: isLoading })) { - setIsInitialLoading(false); - } - }, [isInitialLoading, isLoading, setIsInitialLoading]); - return ( @@ -89,8 +85,8 @@ export const SeverityLevelChart: React.FC = ({ /> - {isInitialLoading ? ( - + {isLoading ? ( + ) : (