-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Cloud Security] Alerts Preview for Host Name (#197102)
## Summary <img width="1447" alt="Screenshot 2024-10-21 at 10 38 49 PM" src="https://github.com/user-attachments/assets/e7d011dd-8245-4bf8-ad96-a4fd634e82c1"> This PR is for Alerts preview component in Contextual Flyout (Host Name)
- Loading branch information
Showing
4 changed files
with
242 additions
and
4 deletions.
There are no files selected for viewing
76 changes: 76 additions & 0 deletions
76
...security_solution/public/cloud_security_posture/components/alerts/alerts_preview.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* | ||
* 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 React from 'react'; | ||
import { render } from '@testing-library/react'; | ||
import { AlertsPreview } from './alerts_preview'; | ||
import { TestProviders } from '../../../common/mock/test_providers'; | ||
import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; | ||
import type { ParsedAlertsData } from '../../../overview/components/detection_response/alerts_by_status/types'; | ||
|
||
const mockAlertsData: ParsedAlertsData = { | ||
open: { | ||
total: 3, | ||
severities: [ | ||
{ key: 'low', value: 2, label: 'Low' }, | ||
{ key: 'medium', value: 1, label: 'Medium' }, | ||
], | ||
}, | ||
acknowledged: { | ||
total: 2, | ||
severities: [ | ||
{ key: 'low', value: 1, label: 'Low' }, | ||
{ key: 'high', value: 1, label: 'High' }, | ||
], | ||
}, | ||
}; | ||
|
||
jest.mock( | ||
'../../../detections/components/alerts_kpis/alerts_summary_charts_panel/use_summary_chart_data' | ||
); | ||
jest.mock('@kbn/expandable-flyout'); | ||
|
||
describe('AlertsPreview', () => { | ||
const mockOpenLeftPanel = jest.fn(); | ||
|
||
beforeEach(() => { | ||
(useExpandableFlyoutApi as jest.Mock).mockReturnValue({ openLeftPanel: mockOpenLeftPanel }); | ||
}); | ||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('renders', () => { | ||
const { getByTestId } = render( | ||
<TestProviders> | ||
<AlertsPreview alertsData={mockAlertsData} /> | ||
</TestProviders> | ||
); | ||
|
||
expect(getByTestId('securitySolutionFlyoutInsightsAlertsTitleText')).toBeInTheDocument(); | ||
}); | ||
|
||
it('renders correct alerts number', () => { | ||
const { getByTestId } = render( | ||
<TestProviders> | ||
<AlertsPreview alertsData={mockAlertsData} /> | ||
</TestProviders> | ||
); | ||
|
||
expect(getByTestId('securitySolutionFlyoutInsightsAlertsCount').textContent).toEqual('5'); | ||
}); | ||
|
||
it('should render the correct number of distribution bar section based on the number of severities', () => { | ||
const { queryAllByTestId } = render( | ||
<TestProviders> | ||
<AlertsPreview alertsData={mockAlertsData} /> | ||
</TestProviders> | ||
); | ||
|
||
expect(queryAllByTestId('AlertsPreviewDistributionBarTestId__part').length).toEqual(3); | ||
}); | ||
}); |
121 changes: 121 additions & 0 deletions
121
...gins/security_solution/public/cloud_security_posture/components/alerts/alerts_preview.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
/* | ||
* 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 React from 'react'; | ||
import { capitalize } from 'lodash'; | ||
import type { EuiThemeComputed } from '@elastic/eui'; | ||
import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText, EuiTitle, useEuiTheme } from '@elastic/eui'; | ||
import { FormattedMessage } from '@kbn/i18n-react'; | ||
import { DistributionBar } from '@kbn/security-solution-distribution-bar'; | ||
import { getAbbreviatedNumber } from '@kbn/cloud-security-posture-common'; | ||
import { ExpandablePanel } from '../../../flyout/shared/components/expandable_panel'; | ||
import { getSeverityColor } from '../../../detections/components/alerts_kpis/severity_level_panel/helpers'; | ||
import type { | ||
AlertsByStatus, | ||
ParsedAlertsData, | ||
} from '../../../overview/components/detection_response/alerts_by_status/types'; | ||
|
||
const AlertsCount = ({ | ||
alertsTotal, | ||
euiTheme, | ||
}: { | ||
alertsTotal: number; | ||
euiTheme: EuiThemeComputed<{}>; | ||
}) => { | ||
return ( | ||
<EuiFlexItem> | ||
<EuiFlexGroup direction="column" gutterSize="none"> | ||
<EuiFlexItem> | ||
<EuiTitle size="s"> | ||
<h1 data-test-subj={'securitySolutionFlyoutInsightsAlertsCount'}> | ||
{getAbbreviatedNumber(alertsTotal)} | ||
</h1> | ||
</EuiTitle> | ||
</EuiFlexItem> | ||
<EuiFlexItem> | ||
<EuiText | ||
size="m" | ||
css={{ | ||
fontWeight: euiTheme.font.weight.semiBold, | ||
}} | ||
> | ||
<FormattedMessage | ||
id="xpack.securitySolution.flyout.right.insights.alerts.alertsCountDescription" | ||
defaultMessage="Alerts" | ||
/> | ||
</EuiText> | ||
</EuiFlexItem> | ||
</EuiFlexGroup> | ||
</EuiFlexItem> | ||
); | ||
}; | ||
|
||
export const AlertsPreview = ({ | ||
alertsData, | ||
isPreviewMode, | ||
}: { | ||
alertsData: ParsedAlertsData; | ||
isPreviewMode?: boolean; | ||
}) => { | ||
const { euiTheme } = useEuiTheme(); | ||
|
||
const severityMap = new Map<string, number>(); | ||
|
||
(Object.keys(alertsData || {}) as AlertsByStatus[]).forEach((status) => { | ||
if (alertsData?.[status]?.severities) { | ||
alertsData?.[status]?.severities.forEach((severity) => { | ||
const currentSeverity = severityMap.get(severity.key) || 0; | ||
severityMap.set(severity.key, currentSeverity + severity.value); | ||
}); | ||
} | ||
}); | ||
|
||
const alertStats = Array.from(severityMap, ([key, count]) => ({ | ||
key: capitalize(key), | ||
count, | ||
color: getSeverityColor(key), | ||
})); | ||
|
||
const totalAlertsCount = alertStats.reduce((total, item) => total + item.count, 0); | ||
|
||
return ( | ||
<ExpandablePanel | ||
header={{ | ||
title: ( | ||
<EuiText | ||
size="xs" | ||
css={{ | ||
fontWeight: euiTheme.font.weight.semiBold, | ||
}} | ||
> | ||
<FormattedMessage | ||
id="xpack.securitySolution.flyout.right.insights.alerts.alertsTitle" | ||
defaultMessage="Alerts" | ||
/> | ||
</EuiText> | ||
), | ||
}} | ||
data-test-subj={'securitySolutionFlyoutInsightsAlerts'} | ||
> | ||
<EuiFlexGroup gutterSize="none"> | ||
<AlertsCount alertsTotal={totalAlertsCount} euiTheme={euiTheme} /> | ||
<EuiFlexItem grow={2}> | ||
<EuiFlexGroup direction="column" gutterSize="none"> | ||
<EuiFlexItem /> | ||
<EuiFlexItem> | ||
<EuiSpacer /> | ||
<DistributionBar | ||
stats={alertStats.reverse()} | ||
data-test-subj="AlertsPreviewDistributionBarTestId" | ||
/> | ||
</EuiFlexItem> | ||
</EuiFlexGroup> | ||
</EuiFlexItem> | ||
</EuiFlexGroup> | ||
</ExpandablePanel> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters