diff --git a/x-pack/packages/kbn-cloud-security-posture/public/src/hooks/use_has_misconfigurations.ts b/x-pack/packages/kbn-cloud-security-posture/public/src/hooks/use_has_misconfigurations.ts
new file mode 100644
index 0000000000000..9b126332b567b
--- /dev/null
+++ b/x-pack/packages/kbn-cloud-security-posture/public/src/hooks/use_has_misconfigurations.ts
@@ -0,0 +1,29 @@
+/*
+ * 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 { buildEntityFlyoutPreviewQuery } from '@kbn/cloud-security-posture-common';
+import { useMisconfigurationPreview } from './use_misconfiguration_preview';
+
+export const useHasMisconfigurations = (field: 'host.name' | 'user.name', value: string) => {
+ const { data } = useMisconfigurationPreview({
+ query: buildEntityFlyoutPreviewQuery(field, value),
+ sort: [],
+ enabled: true,
+ pageSize: 1,
+ });
+
+ const passedFindings = data?.count.passed || 0;
+ const failedFindings = data?.count.failed || 0;
+
+ const hasMisconfigurationFindings = passedFindings > 0 || failedFindings > 0;
+
+ return {
+ passedFindings,
+ failedFindings,
+ hasMisconfigurationFindings,
+ };
+};
diff --git a/x-pack/packages/kbn-cloud-security-posture/public/src/hooks/use_has_vulnerabilities.ts b/x-pack/packages/kbn-cloud-security-posture/public/src/hooks/use_has_vulnerabilities.ts
new file mode 100644
index 0000000000000..336892ee888af
--- /dev/null
+++ b/x-pack/packages/kbn-cloud-security-posture/public/src/hooks/use_has_vulnerabilities.ts
@@ -0,0 +1,39 @@
+/*
+ * 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 { buildEntityFlyoutPreviewQuery } from '@kbn/cloud-security-posture-common';
+import { useVulnerabilitiesPreview } from './use_vulnerabilities_preview';
+import { hasVulnerabilitiesData } from '../utils/vulnerability_helpers';
+
+export const useHasVulnerabilities = (field: 'host.name' | 'user.name', value: string) => {
+ const { data: vulnerabilitiesData } = useVulnerabilitiesPreview({
+ query: buildEntityFlyoutPreviewQuery(field, value),
+ sort: [],
+ enabled: true,
+ pageSize: 1,
+ });
+
+ const {
+ CRITICAL = 0,
+ HIGH = 0,
+ MEDIUM = 0,
+ LOW = 0,
+ NONE = 0,
+ } = vulnerabilitiesData?.count || {};
+
+ const counts = {
+ critical: CRITICAL,
+ high: HIGH,
+ medium: MEDIUM,
+ low: LOW,
+ none: NONE,
+ };
+
+ const hasVulnerabilitiesFindings = hasVulnerabilitiesData(counts);
+
+ return { counts, hasVulnerabilitiesFindings };
+};
diff --git a/x-pack/plugins/security_solution/public/cloud_security_posture/components/alerts/alerts_preview.test.tsx b/x-pack/plugins/security_solution/public/cloud_security_posture/components/alerts/alerts_preview.test.tsx
index fff9450b6a1cb..594629e9f9e27 100644
--- a/x-pack/plugins/security_solution/public/cloud_security_posture/components/alerts/alerts_preview.test.tsx
+++ b/x-pack/plugins/security_solution/public/cloud_security_posture/components/alerts/alerts_preview.test.tsx
@@ -58,7 +58,7 @@ describe('AlertsPreview', () => {
it('renders', () => {
const { getByTestId } = render(
-
+
);
@@ -68,7 +68,7 @@ describe('AlertsPreview', () => {
it('renders correct alerts number', () => {
const { getByTestId } = render(
-
+
);
@@ -78,7 +78,7 @@ describe('AlertsPreview', () => {
it('should render the correct number of distribution bar section based on the number of severities', () => {
const { queryAllByTestId } = render(
-
+
);
diff --git a/x-pack/plugins/security_solution/public/cloud_security_posture/components/alerts/alerts_preview.tsx b/x-pack/plugins/security_solution/public/cloud_security_posture/components/alerts/alerts_preview.tsx
index a5f08527cdc77..8edd0b7981936 100644
--- a/x-pack/plugins/security_solution/public/cloud_security_posture/components/alerts/alerts_preview.tsx
+++ b/x-pack/plugins/security_solution/public/cloud_security_posture/components/alerts/alerts_preview.tsx
@@ -5,40 +5,21 @@
* 2.0.
*/
-import React, { useCallback, useMemo } from 'react';
+import React, { useMemo } 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 {
- buildEntityFlyoutPreviewQuery,
- getAbbreviatedNumber,
-} from '@kbn/cloud-security-posture-common';
-import { hasVulnerabilitiesData } from '@kbn/cloud-security-posture';
-import { useMisconfigurationPreview } from '@kbn/cloud-security-posture/src/hooks/use_misconfiguration_preview';
-import { useVulnerabilitiesPreview } from '@kbn/cloud-security-posture/src/hooks/use_vulnerabilities_preview';
-import { useExpandableFlyoutApi } from '@kbn/expandable-flyout';
+import { getAbbreviatedNumber } from '@kbn/cloud-security-posture-common';
import type {
AlertsByStatus,
ParsedAlertsData,
} from '../../../overview/components/detection_response/alerts_by_status/types';
import { ExpandablePanel } from '../../../flyout/shared/components/expandable_panel';
import { getSeverityColor } from '../../../detections/components/alerts_kpis/severity_level_panel/helpers';
-import type { HostRiskScore, UserRiskScore } from '../../../../common/search_strategy';
-import {
- buildHostNamesFilter,
- buildUserNamesFilter,
- RiskScoreEntity,
-} from '../../../../common/search_strategy';
-import { useRiskScore } from '../../../entity_analytics/api/hooks/use_risk_score';
-import { FIRST_RECORD_PAGINATION } from '../../../entity_analytics/common';
-import { HostDetailsPanelKey } from '../../../flyout/entity_details/host_details_left';
-import {
- EntityDetailsLeftPanelTab,
- CspInsightLeftPanelSubTab,
-} from '../../../flyout/entity_details/shared/components/left_panel/left_panel_header';
-import { UserDetailsPanelKey } from '../../../flyout/entity_details/user_details_left';
+import { CspInsightLeftPanelSubTab } from '../../../flyout/entity_details/shared/components/left_panel/left_panel_header';
+import { useNavigateEntityInsight } from '../../hooks/use_entity_insight';
const AlertsCount = ({
alertsTotal,
@@ -77,13 +58,13 @@ const AlertsCount = ({
export const AlertsPreview = ({
alertsData,
- fieldName,
- name,
+ field,
+ value,
isPreviewMode,
}: {
alertsData: ParsedAlertsData;
- fieldName: string;
- name: string;
+ field: 'host.name' | 'user.name';
+ value: string;
isPreviewMode?: boolean;
}) => {
const { euiTheme } = useEuiTheme();
@@ -107,101 +88,14 @@ export const AlertsPreview = ({
const totalAlertsCount = alertStats.reduce((total, item) => total + item.count, 0);
- const { data } = useMisconfigurationPreview({
- query: buildEntityFlyoutPreviewQuery(fieldName, name),
- sort: [],
- enabled: true,
- pageSize: 1,
- ignore_unavailable: true,
- });
- const isUsingHostName = fieldName === 'host.name';
- const passedFindings = data?.count.passed || 0;
- const failedFindings = data?.count.failed || 0;
-
- const hasMisconfigurationFindings = passedFindings > 0 || failedFindings > 0;
-
- const { data: vulnerabilitiesData } = useVulnerabilitiesPreview({
- query: buildEntityFlyoutPreviewQuery('host.name', name),
- sort: [],
- enabled: true,
- pageSize: 1,
- });
-
- const {
- CRITICAL = 0,
- HIGH = 0,
- MEDIUM = 0,
- LOW = 0,
- NONE = 0,
- } = vulnerabilitiesData?.count || {};
-
- const hasVulnerabilitiesFindings = hasVulnerabilitiesData({
- critical: CRITICAL,
- high: HIGH,
- medium: MEDIUM,
- low: LOW,
- none: NONE,
- });
-
- const buildFilterQuery = useMemo(
- () => (isUsingHostName ? buildHostNamesFilter([name]) : buildUserNamesFilter([name])),
- [isUsingHostName, name]
- );
-
- const riskScoreState = useRiskScore({
- riskEntity: isUsingHostName ? RiskScoreEntity.host : RiskScoreEntity.user,
- filterQuery: buildFilterQuery,
- onlyLatest: false,
- pagination: FIRST_RECORD_PAGINATION,
- });
-
- const { data: hostRisk } = riskScoreState;
-
- const riskData = hostRisk?.[0];
-
- const isRiskScoreExist = isUsingHostName
- ? !!(riskData as HostRiskScore)?.host.risk
- : !!(riskData as UserRiskScore)?.user.risk;
-
const hasNonClosedAlerts = totalAlertsCount > 0;
- const { openLeftPanel } = useExpandableFlyoutApi();
-
- const goToEntityInsightTab = useCallback(() => {
- openLeftPanel({
- id: isUsingHostName ? HostDetailsPanelKey : UserDetailsPanelKey,
- params: isUsingHostName
- ? {
- name,
- isRiskScoreExist,
- hasMisconfigurationFindings,
- hasVulnerabilitiesFindings,
- hasNonClosedAlerts,
- path: {
- tab: EntityDetailsLeftPanelTab.CSP_INSIGHTS,
- subTab: CspInsightLeftPanelSubTab.ALERTS,
- },
- }
- : {
- user: { name },
- isRiskScoreExist,
- hasMisconfigurationFindings,
- hasNonClosedAlerts,
- path: {
- tab: EntityDetailsLeftPanelTab.CSP_INSIGHTS,
- subTab: CspInsightLeftPanelSubTab.ALERTS,
- },
- },
- });
- }, [
- hasMisconfigurationFindings,
- hasNonClosedAlerts,
- hasVulnerabilitiesFindings,
- isRiskScoreExist,
- isUsingHostName,
- name,
- openLeftPanel,
- ]);
+ const { goToEntityInsightTab } = useNavigateEntityInsight({
+ field,
+ value,
+ queryIdExtension: 'ALERTS_PREVIEW',
+ subTab: CspInsightLeftPanelSubTab.ALERTS,
+ });
const link = useMemo(
() =>
!isPreviewMode
diff --git a/x-pack/plugins/security_solution/public/cloud_security_posture/components/csp_details/alerts_findings_details_table.tsx b/x-pack/plugins/security_solution/public/cloud_security_posture/components/csp_details/alerts_findings_details_table.tsx
index 966de68e3497f..6567fb41a93f4 100644
--- a/x-pack/plugins/security_solution/public/cloud_security_posture/components/csp_details/alerts_findings_details_table.tsx
+++ b/x-pack/plugins/security_solution/public/cloud_security_posture/components/csp_details/alerts_findings_details_table.tsx
@@ -60,7 +60,7 @@ interface AlertsDetailsFields {
}
export const AlertsDetailsTable = memo(
- ({ fieldName, queryName }: { fieldName: 'host.name' | 'user.name'; queryName: string }) => {
+ ({ field, value }: { field: 'host.name' | 'user.name'; value: string }) => {
useEffect(() => {
uiMetricService.trackUiMetric(
METRIC_TYPE.COUNT,
@@ -90,7 +90,7 @@ export const AlertsDetailsTable = memo(
const { to, from } = useGlobalTime();
const { signalIndexName } = useSignalIndex();
const { data } = useQueryAlerts({
- query: buildEntityAlertsQuery(fieldName, to, from, queryName, 500),
+ query: buildEntityAlertsQuery(field, to, from, value, 500),
queryName: ALERTS_QUERY_NAMES.BY_RULE_BY_STATUS,
indexName: signalIndexName,
});
@@ -216,11 +216,11 @@ export const AlertsDetailsTable = memo(
[
{
title:
- fieldName === 'host.name'
+ field === 'host.name'
? OPEN_IN_ALERTS_TITLE_HOSTNAME
: OPEN_IN_ALERTS_TITLE_USERNAME,
- selectedOptions: [queryName],
- fieldName,
+ selectedOptions: [value],
+ fieldName: field,
},
{
title: OPEN_IN_ALERTS_TITLE_STATUS,
@@ -230,7 +230,7 @@ export const AlertsDetailsTable = memo(
],
true
),
- [fieldName, openAlertsPageWithFilters, queryName]
+ [field, openAlertsPageWithFilters, value]
);
return (
diff --git a/x-pack/plugins/security_solution/public/cloud_security_posture/components/csp_details/insights_tab_csp.tsx b/x-pack/plugins/security_solution/public/cloud_security_posture/components/csp_details/insights_tab_csp.tsx
index 2e7b4171fd023..84e3ee4faee99 100644
--- a/x-pack/plugins/security_solution/public/cloud_security_posture/components/csp_details/insights_tab_csp.tsx
+++ b/x-pack/plugins/security_solution/public/cloud_security_posture/components/csp_details/insights_tab_csp.tsx
@@ -42,7 +42,7 @@ function isCspFlyoutPanelProps(
}
export const InsightsTabCsp = memo(
- ({ name, fieldName }: { name: string; fieldName: 'host.name' | 'user.name' }) => {
+ ({ value, field }: { value: string; field: 'host.name' | 'user.name' }) => {
const panels = useExpandableFlyoutState();
let hasMisconfigurationFindings = false;
@@ -150,11 +150,11 @@ export const InsightsTabCsp = memo(
/>
{activeInsightsId === CspInsightLeftPanelSubTab.MISCONFIGURATIONS ? (
-
+
) : activeInsightsId === CspInsightLeftPanelSubTab.VULNERABILITIES ? (
-
+
) : (
-
+
)}
>
);
diff --git a/x-pack/plugins/security_solution/public/cloud_security_posture/components/csp_details/misconfiguration_findings_details_table.tsx b/x-pack/plugins/security_solution/public/cloud_security_posture/components/csp_details/misconfiguration_findings_details_table.tsx
index 69912c58e4e15..00430c2b87262 100644
--- a/x-pack/plugins/security_solution/public/cloud_security_posture/components/csp_details/misconfiguration_findings_details_table.tsx
+++ b/x-pack/plugins/security_solution/public/cloud_security_posture/components/csp_details/misconfiguration_findings_details_table.tsx
@@ -59,7 +59,7 @@ const getFindingsStats = (passedFindingsStats: number, failedFindingsStats: numb
* Insights view displayed in the document details expandable flyout left section
*/
export const MisconfigurationFindingsDetailsTable = memo(
- ({ fieldName, queryName }: { fieldName: 'host.name' | 'user.name'; queryName: string }) => {
+ ({ field, value }: { field: 'host.name' | 'user.name'; value: string }) => {
useEffect(() => {
uiMetricService.trackUiMetric(
METRIC_TYPE.COUNT,
@@ -68,7 +68,7 @@ export const MisconfigurationFindingsDetailsTable = memo(
}, []);
const { data } = useMisconfigurationFindings({
- query: buildEntityFlyoutPreviewQuery(fieldName, queryName),
+ query: buildEntityFlyoutPreviewQuery(field, value),
sort: [],
enabled: true,
pageSize: 1,
@@ -183,7 +183,7 @@ export const MisconfigurationFindingsDetailsTable = memo(
{
diff --git a/x-pack/plugins/security_solution/public/cloud_security_posture/components/csp_details/vulnerabilities_findings_details_table.tsx b/x-pack/plugins/security_solution/public/cloud_security_posture/components/csp_details/vulnerabilities_findings_details_table.tsx
index 82c5f91bf4250..155946a791f79 100644
--- a/x-pack/plugins/security_solution/public/cloud_security_posture/components/csp_details/vulnerabilities_findings_details_table.tsx
+++ b/x-pack/plugins/security_solution/public/cloud_security_posture/components/csp_details/vulnerabilities_findings_details_table.tsx
@@ -44,7 +44,7 @@ interface VulnerabilitiesPackage extends Vulnerability {
};
}
-export const VulnerabilitiesFindingsDetailsTable = memo(({ queryName }: { queryName: string }) => {
+export const VulnerabilitiesFindingsDetailsTable = memo(({ value }: { value: string }) => {
useEffect(() => {
uiMetricService.trackUiMetric(
METRIC_TYPE.COUNT,
@@ -53,7 +53,7 @@ export const VulnerabilitiesFindingsDetailsTable = memo(({ queryName }: { queryN
}, []);
const { data } = useVulnerabilitiesFindings({
- query: buildEntityFlyoutPreviewQuery('host.name', queryName),
+ query: buildEntityFlyoutPreviewQuery('host.name', value),
sort: [],
enabled: true,
pageSize: 1,
@@ -204,7 +204,7 @@ export const VulnerabilitiesFindingsDetailsTable = memo(({ queryName }: { queryN
{
diff --git a/x-pack/plugins/security_solution/public/cloud_security_posture/components/entity_insight.tsx b/x-pack/plugins/security_solution/public/cloud_security_posture/components/entity_insight.tsx
index 7139994f7e972..eec66e765371b 100644
--- a/x-pack/plugins/security_solution/public/cloud_security_posture/components/entity_insight.tsx
+++ b/x-pack/plugins/security_solution/public/cloud_security_posture/components/entity_insight.tsx
@@ -7,97 +7,56 @@
import { EuiAccordion, EuiHorizontalRule, EuiSpacer, EuiTitle, useEuiTheme } from '@elastic/eui';
-import React, { useMemo } from 'react';
+import React from 'react';
import { css } from '@emotion/react';
import { FormattedMessage } from '@kbn/i18n-react';
-import { useMisconfigurationPreview } from '@kbn/cloud-security-posture/src/hooks/use_misconfiguration_preview';
-import { buildEntityFlyoutPreviewQuery } from '@kbn/cloud-security-posture-common';
-import { useVulnerabilitiesPreview } from '@kbn/cloud-security-posture/src/hooks/use_vulnerabilities_preview';
-import { hasVulnerabilitiesData } from '@kbn/cloud-security-posture';
-import { FILTER_CLOSED } from '../../../common/types';
+import { useHasVulnerabilities } from '@kbn/cloud-security-posture/src/hooks/use_has_vulnerabilities';
+import { useHasMisconfigurations } from '@kbn/cloud-security-posture/src/hooks/use_has_misconfigurations';
import { MisconfigurationsPreview } from './misconfiguration/misconfiguration_preview';
import { VulnerabilitiesPreview } from './vulnerabilities/vulnerabilities_preview';
import { AlertsPreview } from './alerts/alerts_preview';
import { useGlobalTime } from '../../common/containers/use_global_time';
-import type { ParsedAlertsData } from '../../overview/components/detection_response/alerts_by_status/types';
import { DETECTION_RESPONSE_ALERTS_BY_STATUS_ID } from '../../overview/components/detection_response/alerts_by_status/types';
-import { useAlertsByStatus } from '../../overview/components/detection_response/alerts_by_status/use_alerts_by_status';
-import { useSignalIndex } from '../../detections/containers/detection_engine/alerts/use_signal_index';
+import { useNonClosedAlerts } from '../hooks/use_non_closed_alerts';
export const EntityInsight = ({
- name,
- fieldName,
+ value,
+ field,
isPreviewMode,
}: {
- name: string;
- fieldName: 'host.name' | 'user.name';
+ value: string;
+ field: 'host.name' | 'user.name';
isPreviewMode?: boolean;
}) => {
const { euiTheme } = useEuiTheme();
const insightContent: React.ReactElement[] = [];
- const { data: dataMisconfiguration } = useMisconfigurationPreview({
- query: buildEntityFlyoutPreviewQuery(fieldName, name),
- sort: [],
- enabled: true,
- pageSize: 1,
- });
-
- const passedFindings = dataMisconfiguration?.count.passed || 0;
- const failedFindings = dataMisconfiguration?.count.failed || 0;
-
- const hasMisconfigurationFindings = passedFindings > 0 || failedFindings > 0;
-
- const { data } = useVulnerabilitiesPreview({
- query: buildEntityFlyoutPreviewQuery(fieldName, name),
- sort: [],
- enabled: true,
- pageSize: 1,
- });
-
- const { CRITICAL = 0, HIGH = 0, MEDIUM = 0, LOW = 0, NONE = 0 } = data?.count || {};
-
- const hasVulnerabilitiesFindings = hasVulnerabilitiesData({
- critical: CRITICAL,
- high: HIGH,
- medium: MEDIUM,
- low: LOW,
- none: NONE,
- });
-
- const isVulnerabilitiesFindingForHost = hasVulnerabilitiesFindings && fieldName === 'host.name';
+ const { hasMisconfigurationFindings: showMisconfigurationsPreview } = useHasMisconfigurations(
+ field,
+ value
+ );
- const { signalIndexName } = useSignalIndex();
+ const { hasVulnerabilitiesFindings } = useHasVulnerabilities(field, value);
- const entityFilter = useMemo(() => ({ field: fieldName, value: name }), [fieldName, name]);
+ const showVulnerabilitiesPreview = hasVulnerabilitiesFindings && field === 'host.name';
const { to, from } = useGlobalTime();
- const { items: alertsData } = useAlertsByStatus({
- entityFilter,
- signalIndexName,
- queryId: DETECTION_RESPONSE_ALERTS_BY_STATUS_ID,
+ const { hasNonClosedAlerts: showAlertsPreview, filteredAlertsData } = useNonClosedAlerts({
+ field,
+ value,
to,
from,
+ queryId: DETECTION_RESPONSE_ALERTS_BY_STATUS_ID,
});
- const filteredAlertsData: ParsedAlertsData = alertsData
- ? Object.fromEntries(Object.entries(alertsData).filter(([key]) => key !== FILTER_CLOSED))
- : {};
-
- const alertsOpenCount = filteredAlertsData?.open?.total || 0;
-
- const alertsAcknowledgedCount = filteredAlertsData?.acknowledged?.total || 0;
-
- const alertsCount = alertsOpenCount + alertsAcknowledgedCount;
-
- if (alertsCount > 0) {
+ if (showAlertsPreview) {
insightContent.push(
<>
@@ -105,34 +64,23 @@ export const EntityInsight = ({
);
}
- if (hasMisconfigurationFindings)
+ if (showMisconfigurationsPreview)
insightContent.push(
<>
- 0}
- isPreviewMode={isPreviewMode}
- />
+
>
);
- if (isVulnerabilitiesFindingForHost && hasVulnerabilitiesFindings)
+ if (showVulnerabilitiesPreview)
insightContent.push(
<>
- 0}
- />
+
>
);
return (
<>
- {(insightContent.length > 0 ||
- hasMisconfigurationFindings ||
- (isVulnerabilitiesFindingForHost && hasVulnerabilitiesFindings)) && (
+ {insightContent.length > 0 && (
<>
{
it('renders', () => {
const { getByTestId } = render(
-
+
);
diff --git a/x-pack/plugins/security_solution/public/cloud_security_posture/components/misconfiguration/misconfiguration_preview.tsx b/x-pack/plugins/security_solution/public/cloud_security_posture/components/misconfiguration/misconfiguration_preview.tsx
index 42a5906ce4e36..c7c1889a5838b 100644
--- a/x-pack/plugins/security_solution/public/cloud_security_posture/components/misconfiguration/misconfiguration_preview.tsx
+++ b/x-pack/plugins/security_solution/public/cloud_security_posture/components/misconfiguration/misconfiguration_preview.tsx
@@ -5,39 +5,23 @@
* 2.0.
*/
-import React, { useCallback, useEffect, useMemo } from 'react';
+import React, { useEffect, useMemo } from 'react';
import { css } from '@emotion/react';
import type { EuiThemeComputed } from '@elastic/eui';
import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText, useEuiTheme, EuiTitle } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { DistributionBar } from '@kbn/security-solution-distribution-bar';
-import { useMisconfigurationPreview } from '@kbn/cloud-security-posture/src/hooks/use_misconfiguration_preview';
+import { useHasMisconfigurations } from '@kbn/cloud-security-posture/src/hooks/use_has_misconfigurations';
import { i18n } from '@kbn/i18n';
-import { buildEntityFlyoutPreviewQuery } from '@kbn/cloud-security-posture-common';
-import { useExpandableFlyoutApi } from '@kbn/expandable-flyout';
-import { useVulnerabilitiesPreview } from '@kbn/cloud-security-posture/src/hooks/use_vulnerabilities_preview';
-import { hasVulnerabilitiesData, statusColors } from '@kbn/cloud-security-posture';
+import { statusColors } from '@kbn/cloud-security-posture';
import { METRIC_TYPE } from '@kbn/analytics';
import {
ENTITY_FLYOUT_WITH_MISCONFIGURATION_VISIT,
uiMetricService,
} from '@kbn/cloud-security-posture-common/utils/ui_metrics';
import { ExpandablePanel } from '../../../flyout/shared/components/expandable_panel';
-import {
- CspInsightLeftPanelSubTab,
- EntityDetailsLeftPanelTab,
-} from '../../../flyout/entity_details/shared/components/left_panel/left_panel_header';
-import { UserDetailsPanelKey } from '../../../flyout/entity_details/user_details_left';
-import { HostDetailsPanelKey } from '../../../flyout/entity_details/host_details_left';
-import { useRiskScore } from '../../../entity_analytics/api/hooks/use_risk_score';
-import { RiskScoreEntity } from '../../../../common/entity_analytics/risk_engine';
-import type { HostRiskScore, UserRiskScore } from '../../../../common/search_strategy';
-import { buildHostNamesFilter, buildUserNamesFilter } from '../../../../common/search_strategy';
-
-const FIRST_RECORD_PAGINATION = {
- cursorStart: 0,
- querySize: 1,
-};
+import { CspInsightLeftPanelSubTab } from '../../../flyout/entity_details/shared/components/left_panel/left_panel_header';
+import { useNavigateEntityInsight } from '../../hooks/use_entity_insight';
export const getFindingsStats = (passedFindingsStats: number, failedFindingsStats: number) => {
if (passedFindingsStats === 0 && failedFindingsStats === 0) return [];
@@ -101,113 +85,30 @@ const MisconfigurationPreviewScore = ({
};
export const MisconfigurationsPreview = ({
- name,
- fieldName,
- hasNonClosedAlerts = false,
+ value,
+ field,
isPreviewMode,
}: {
- name: string;
- fieldName: 'host.name' | 'user.name';
- hasNonClosedAlerts?: boolean;
+ value: string;
+ field: 'host.name' | 'user.name';
isPreviewMode?: boolean;
}) => {
- const { data } = useMisconfigurationPreview({
- query: buildEntityFlyoutPreviewQuery(fieldName, name),
- sort: [],
- enabled: true,
- pageSize: 1,
- ignore_unavailable: true,
- });
- const isUsingHostName = fieldName === 'host.name';
- const passedFindings = data?.count.passed || 0;
- const failedFindings = data?.count.failed || 0;
+ const { hasMisconfigurationFindings, passedFindings, failedFindings } = useHasMisconfigurations(
+ field,
+ value
+ );
useEffect(() => {
uiMetricService.trackUiMetric(METRIC_TYPE.CLICK, ENTITY_FLYOUT_WITH_MISCONFIGURATION_VISIT);
}, []);
const { euiTheme } = useEuiTheme();
- const hasMisconfigurationFindings = passedFindings > 0 || failedFindings > 0;
- const { data: vulnerabilitiesData } = useVulnerabilitiesPreview({
- query: buildEntityFlyoutPreviewQuery('host.name', name),
- sort: [],
- enabled: true,
- pageSize: 1,
+ const { goToEntityInsightTab } = useNavigateEntityInsight({
+ field,
+ value,
+ queryIdExtension: 'MISCONFIGURATION_PREVIEW',
+ subTab: CspInsightLeftPanelSubTab.MISCONFIGURATIONS,
});
-
- const {
- CRITICAL = 0,
- HIGH = 0,
- MEDIUM = 0,
- LOW = 0,
- NONE = 0,
- } = vulnerabilitiesData?.count || {};
-
- const hasVulnerabilitiesFindings = hasVulnerabilitiesData({
- critical: CRITICAL,
- high: HIGH,
- medium: MEDIUM,
- low: LOW,
- none: NONE,
- });
-
- const buildFilterQuery = useMemo(
- () => (isUsingHostName ? buildHostNamesFilter([name]) : buildUserNamesFilter([name])),
- [isUsingHostName, name]
- );
-
- const riskScoreState = useRiskScore({
- riskEntity: isUsingHostName ? RiskScoreEntity.host : RiskScoreEntity.user,
- filterQuery: buildFilterQuery,
- onlyLatest: false,
- pagination: FIRST_RECORD_PAGINATION,
- });
-
- const { data: hostRisk } = riskScoreState;
-
- const riskData = hostRisk?.[0];
-
- const isRiskScoreExist = isUsingHostName
- ? !!(riskData as HostRiskScore)?.host.risk
- : !!(riskData as UserRiskScore)?.user.risk;
-
- const { openLeftPanel } = useExpandableFlyoutApi();
-
- const goToEntityInsightTab = useCallback(() => {
- openLeftPanel({
- id: isUsingHostName ? HostDetailsPanelKey : UserDetailsPanelKey,
- params: isUsingHostName
- ? {
- name,
- isRiskScoreExist,
- hasMisconfigurationFindings,
- hasVulnerabilitiesFindings,
- hasNonClosedAlerts,
- path: {
- tab: EntityDetailsLeftPanelTab.CSP_INSIGHTS,
- subTab: CspInsightLeftPanelSubTab.MISCONFIGURATIONS,
- },
- }
- : {
- user: { name },
- isRiskScoreExist,
- hasMisconfigurationFindings,
- hasNonClosedAlerts,
- path: {
- tab: EntityDetailsLeftPanelTab.CSP_INSIGHTS,
- subTab: CspInsightLeftPanelSubTab.MISCONFIGURATIONS,
- },
- },
- });
- }, [
- hasMisconfigurationFindings,
- hasNonClosedAlerts,
- hasVulnerabilitiesFindings,
- isRiskScoreExist,
- isUsingHostName,
- name,
- openLeftPanel,
- ]);
const link = useMemo(
() =>
!isPreviewMode
diff --git a/x-pack/plugins/security_solution/public/cloud_security_posture/components/vulnerabilities/vulnerabilities_preview.test.tsx b/x-pack/plugins/security_solution/public/cloud_security_posture/components/vulnerabilities/vulnerabilities_preview.test.tsx
index cc71d1be2158d..14a6366fd4baa 100644
--- a/x-pack/plugins/security_solution/public/cloud_security_posture/components/vulnerabilities/vulnerabilities_preview.test.tsx
+++ b/x-pack/plugins/security_solution/public/cloud_security_posture/components/vulnerabilities/vulnerabilities_preview.test.tsx
@@ -37,7 +37,7 @@ describe('VulnerabilitiesPreview', () => {
it('renders', () => {
const { getByTestId } = render(
-
+
);
diff --git a/x-pack/plugins/security_solution/public/cloud_security_posture/components/vulnerabilities/vulnerabilities_preview.tsx b/x-pack/plugins/security_solution/public/cloud_security_posture/components/vulnerabilities/vulnerabilities_preview.tsx
index c4335d921e371..5a5b638abafa3 100644
--- a/x-pack/plugins/security_solution/public/cloud_security_posture/components/vulnerabilities/vulnerabilities_preview.tsx
+++ b/x-pack/plugins/security_solution/public/cloud_security_posture/components/vulnerabilities/vulnerabilities_preview.tsx
@@ -5,7 +5,7 @@
* 2.0.
*/
-import React, { useCallback, useEffect, useMemo } from 'react';
+import React, { useEffect, useMemo } from 'react';
import { css } from '@emotion/react';
import type { EuiThemeComputed } from '@elastic/eui';
import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText, useEuiTheme, EuiTitle } from '@elastic/eui';
@@ -17,24 +17,14 @@ import {
getAbbreviatedNumber,
} from '@kbn/cloud-security-posture-common';
import { getVulnerabilityStats, hasVulnerabilitiesData } from '@kbn/cloud-security-posture';
-import { useExpandableFlyoutApi } from '@kbn/expandable-flyout';
-import { useMisconfigurationPreview } from '@kbn/cloud-security-posture/src/hooks/use_misconfiguration_preview';
import {
ENTITY_FLYOUT_WITH_VULNERABILITY_PREVIEW,
uiMetricService,
} from '@kbn/cloud-security-posture-common/utils/ui_metrics';
import { METRIC_TYPE } from '@kbn/analytics';
import { ExpandablePanel } from '../../../flyout/shared/components/expandable_panel';
-import { EntityDetailsLeftPanelTab } from '../../../flyout/entity_details/shared/components/left_panel/left_panel_header';
-import { HostDetailsPanelKey } from '../../../flyout/entity_details/host_details_left';
-import { useRiskScore } from '../../../entity_analytics/api/hooks/use_risk_score';
-import { RiskScoreEntity } from '../../../../common/entity_analytics/risk_engine';
-import { buildHostNamesFilter } from '../../../../common/search_strategy';
-
-const FIRST_RECORD_PAGINATION = {
- cursorStart: 0,
- querySize: 1,
-};
+import { CspInsightLeftPanelSubTab } from '../../../flyout/entity_details/shared/components/left_panel/left_panel_header';
+import { useNavigateEntityInsight } from '../../hooks/use_entity_insight';
const VulnerabilitiesCount = ({
vulnerabilitiesTotal,
@@ -70,20 +60,20 @@ const VulnerabilitiesCount = ({
};
export const VulnerabilitiesPreview = ({
- name,
+ value,
+ field,
isPreviewMode,
- hasNonClosedAlerts = false,
}: {
- name: string;
+ value: string;
+ field: 'host.name' | 'user.name';
isPreviewMode?: boolean;
- hasNonClosedAlerts?: boolean;
}) => {
useEffect(() => {
uiMetricService.trackUiMetric(METRIC_TYPE.CLICK, ENTITY_FLYOUT_WITH_VULNERABILITY_PREVIEW);
}, []);
const { data } = useVulnerabilitiesPreview({
- query: buildEntityFlyoutPreviewQuery('host.name', name),
+ query: buildEntityFlyoutPreviewQuery(field, value),
sort: [],
enabled: true,
pageSize: 1,
@@ -103,49 +93,12 @@ export const VulnerabilitiesPreview = ({
const { euiTheme } = useEuiTheme();
- const { data: dataMisconfiguration } = useMisconfigurationPreview({
- query: buildEntityFlyoutPreviewQuery('host.name', name),
- sort: [],
- enabled: true,
- pageSize: 1,
- });
-
- const passedFindings = dataMisconfiguration?.count.passed || 0;
- const failedFindings = dataMisconfiguration?.count.failed || 0;
-
- const hasMisconfigurationFindings = passedFindings > 0 || failedFindings > 0;
-
- const buildFilterQuery = useMemo(() => buildHostNamesFilter([name]), [name]);
- const riskScoreState = useRiskScore({
- riskEntity: RiskScoreEntity.host,
- filterQuery: buildFilterQuery,
- onlyLatest: false,
- pagination: FIRST_RECORD_PAGINATION,
+ const { goToEntityInsightTab } = useNavigateEntityInsight({
+ field,
+ value,
+ queryIdExtension: 'VULNERABILITIES_PREVIEW',
+ subTab: CspInsightLeftPanelSubTab.VULNERABILITIES,
});
- const { data: hostRisk } = riskScoreState;
- const riskData = hostRisk?.[0];
- const isRiskScoreExist = riskData?.host.risk;
- const { openLeftPanel } = useExpandableFlyoutApi();
- const goToEntityInsightTab = useCallback(() => {
- openLeftPanel({
- id: HostDetailsPanelKey,
- params: {
- name,
- isRiskScoreExist,
- hasMisconfigurationFindings,
- hasVulnerabilitiesFindings,
- hasNonClosedAlerts,
- path: { tab: EntityDetailsLeftPanelTab.CSP_INSIGHTS, subTab: 'vulnerabilitiesTabId' },
- },
- });
- }, [
- hasMisconfigurationFindings,
- hasNonClosedAlerts,
- hasVulnerabilitiesFindings,
- isRiskScoreExist,
- name,
- openLeftPanel,
- ]);
const link = useMemo(
() =>
!isPreviewMode
diff --git a/x-pack/plugins/security_solution/public/cloud_security_posture/hooks/use_entity_insight.ts b/x-pack/plugins/security_solution/public/cloud_security_posture/hooks/use_entity_insight.ts
new file mode 100644
index 0000000000000..fc35474ffdef0
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/cloud_security_posture/hooks/use_entity_insight.ts
@@ -0,0 +1,89 @@
+/*
+ * 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 { useExpandableFlyoutApi } from '@kbn/expandable-flyout';
+import { useCallback } from 'react';
+import { useHasVulnerabilities } from '@kbn/cloud-security-posture/src/hooks/use_has_vulnerabilities';
+import { useHasMisconfigurations } from '@kbn/cloud-security-posture/src/hooks/use_has_misconfigurations';
+import { UserDetailsPanelKey } from '../../flyout/entity_details/user_details_left';
+import { HostDetailsPanelKey } from '../../flyout/entity_details/host_details_left';
+import { EntityDetailsLeftPanelTab } from '../../flyout/entity_details/shared/components/left_panel/left_panel_header';
+import { useGlobalTime } from '../../common/containers/use_global_time';
+import { DETECTION_RESPONSE_ALERTS_BY_STATUS_ID } from '../../overview/components/detection_response/alerts_by_status/types';
+import { useNonClosedAlerts } from './use_non_closed_alerts';
+import { useHasRiskScore } from './use_risk_score_data';
+
+export const useNavigateEntityInsight = ({
+ field,
+ value,
+ subTab,
+ queryIdExtension,
+}: {
+ field: 'host.name' | 'user.name';
+ value: string;
+ subTab: string;
+ queryIdExtension: string;
+}) => {
+ const isHostNameField = field === 'host.name';
+ const { to, from } = useGlobalTime();
+
+ const { hasNonClosedAlerts } = useNonClosedAlerts({
+ field,
+ value,
+ to,
+ from,
+ queryId: `${DETECTION_RESPONSE_ALERTS_BY_STATUS_ID}${queryIdExtension}`,
+ });
+
+ const { hasVulnerabilitiesFindings } = useHasVulnerabilities(field, value);
+
+ const { hasRiskScore } = useHasRiskScore({
+ field,
+ value,
+ });
+ const { hasMisconfigurationFindings } = useHasMisconfigurations(field, value);
+ const { openLeftPanel } = useExpandableFlyoutApi();
+
+ const goToEntityInsightTab = useCallback(() => {
+ openLeftPanel({
+ id: isHostNameField ? HostDetailsPanelKey : UserDetailsPanelKey,
+ params: isHostNameField
+ ? {
+ name: value,
+ isRiskScoreExist: hasRiskScore,
+ hasMisconfigurationFindings,
+ hasVulnerabilitiesFindings,
+ hasNonClosedAlerts,
+ path: {
+ tab: EntityDetailsLeftPanelTab.CSP_INSIGHTS,
+ subTab,
+ },
+ }
+ : {
+ user: { name: value },
+ isRiskScoreExist: hasRiskScore,
+ hasMisconfigurationFindings,
+ hasNonClosedAlerts,
+ path: {
+ tab: EntityDetailsLeftPanelTab.CSP_INSIGHTS,
+ subTab,
+ },
+ },
+ });
+ }, [
+ openLeftPanel,
+ isHostNameField,
+ value,
+ hasRiskScore,
+ hasMisconfigurationFindings,
+ hasVulnerabilitiesFindings,
+ hasNonClosedAlerts,
+ subTab,
+ ]);
+
+ return { goToEntityInsightTab };
+};
diff --git a/x-pack/plugins/security_solution/public/cloud_security_posture/hooks/use_non_closed_alerts.ts b/x-pack/plugins/security_solution/public/cloud_security_posture/hooks/use_non_closed_alerts.ts
new file mode 100644
index 0000000000000..598f78cd68402
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/cloud_security_posture/hooks/use_non_closed_alerts.ts
@@ -0,0 +1,47 @@
+/*
+ * 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 { useMemo } from 'react';
+import { FILTER_CLOSED } from '@kbn/securitysolution-data-table/common/types';
+import { useSignalIndex } from '../../detections/containers/detection_engine/alerts/use_signal_index';
+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';
+
+export const useNonClosedAlerts = ({
+ field,
+ value,
+ to,
+ from,
+ queryId,
+}: {
+ field: 'host.name' | 'user.name';
+ value: string;
+ to: string;
+ from: string;
+ queryId: string;
+}) => {
+ const { signalIndexName } = useSignalIndex();
+
+ const entityFilter = useMemo(() => ({ field, value }), [field, value]);
+
+ const { items: alertsData } = useAlertsByStatus({
+ entityFilter,
+ signalIndexName,
+ queryId,
+ to,
+ from,
+ });
+
+ const filteredAlertsData: ParsedAlertsData = alertsData
+ ? Object.fromEntries(Object.entries(alertsData).filter(([key]) => key !== FILTER_CLOSED))
+ : {};
+
+ const hasNonClosedAlerts =
+ (filteredAlertsData?.acknowledged?.total || 0) + (filteredAlertsData?.open?.total || 0) > 0;
+
+ return { hasNonClosedAlerts, filteredAlertsData };
+};
diff --git a/x-pack/plugins/security_solution/public/cloud_security_posture/hooks/use_risk_score_data.ts b/x-pack/plugins/security_solution/public/cloud_security_posture/hooks/use_risk_score_data.ts
new file mode 100644
index 0000000000000..b100fe30b105b
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/cloud_security_posture/hooks/use_risk_score_data.ts
@@ -0,0 +1,45 @@
+/*
+ * 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 { useMemo } from 'react';
+import {
+ RiskScoreEntity,
+ type HostRiskScore,
+ type UserRiskScore,
+ buildHostNamesFilter,
+ buildUserNamesFilter,
+} from '../../../common/search_strategy';
+import { useRiskScore } from '../../entity_analytics/api/hooks/use_risk_score';
+import { FIRST_RECORD_PAGINATION } from '../../entity_analytics/common';
+
+export const useHasRiskScore = ({
+ field,
+ value,
+}: {
+ field: 'host.name' | 'user.name';
+ value: string;
+}) => {
+ const isHostNameField = field === 'host.name';
+ const buildFilterQuery = useMemo(
+ () => (isHostNameField ? buildHostNamesFilter([value]) : buildUserNamesFilter([value])),
+ [isHostNameField, value]
+ );
+ const { data } = useRiskScore({
+ riskEntity: isHostNameField ? RiskScoreEntity.host : RiskScoreEntity.user,
+ filterQuery: buildFilterQuery,
+ onlyLatest: false,
+ pagination: FIRST_RECORD_PAGINATION,
+ });
+
+ const riskData = data?.[0];
+
+ const hasRiskScore = isHostNameField
+ ? !!(riskData as HostRiskScore)?.host.risk
+ : !!(riskData as UserRiskScore)?.user.risk;
+
+ return { hasRiskScore };
+};
diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/index.tsx
index 6f728d7653783..1073be375b093 100644
--- a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/index.tsx
+++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/index.tsx
@@ -44,6 +44,6 @@ export const getInsightsInputTab = ({
defaultMessage="Insights"
/>
),
- content: ,
+ content: ,
};
};
diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/host_right/content.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/host_right/content.tsx
index 2e7c14fc38027..9c2ce61dea7fc 100644
--- a/x-pack/plugins/security_solution/public/flyout/entity_details/host_right/content.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/entity_details/host_right/content.tsx
@@ -64,7 +64,7 @@ export const HostPanelContent = ({
entity={{ name: hostName, type: 'host' }}
onChange={onAssetCriticalityChange}
/>
-
+
{
@@ -101,43 +98,18 @@ export const HostPanel = ({
{ onSuccess: refetchRiskScore }
);
- const { data } = useMisconfigurationPreview({
- query: buildEntityFlyoutPreviewQuery('host.name', hostName),
- sort: [],
- enabled: true,
- pageSize: 1,
- ignore_unavailable: true,
- });
-
- const passedFindings = data?.count.passed || 0;
- const failedFindings = data?.count.failed || 0;
-
- const hasMisconfigurationFindings = passedFindings > 0 || failedFindings > 0;
-
- const { data: vulnerabilitiesData } = useVulnerabilitiesPreview({
- query: buildEntityFlyoutPreviewQuery('host.name', hostName),
- sort: [],
- enabled: true,
- pageSize: 1,
- });
+ const { hasMisconfigurationFindings } = useHasMisconfigurations('host.name', hostName);
- const hasVulnerabilitiesFindings = sum(Object.values(vulnerabilitiesData?.count || {})) > 0;
+ const { hasVulnerabilitiesFindings } = useHasVulnerabilities('host.name', hostName);
- const { signalIndexName } = useSignalIndex();
-
- const entityFilter = useMemo(() => ({ field: 'host.name', value: hostName }), [hostName]);
-
- const { items: alertsData } = useAlertsByStatus({
- entityFilter,
- signalIndexName,
- queryId: `${DETECTION_RESPONSE_ALERTS_BY_STATUS_ID}HOST_NAME_RIGHT`,
+ const { hasNonClosedAlerts } = useNonClosedAlerts({
+ field: 'host.name',
+ value: hostName,
to,
from,
+ queryId: `${DETECTION_RESPONSE_ALERTS_BY_STATUS_ID}HOST_NAME_RIGHT`,
});
- const hasNonClosedAlerts =
- (alertsData?.acknowledged?.total || 0) + (alertsData?.open?.total || 0) > 0;
-
useQueryInspector({
deleteQuery,
inspect: inspectRiskScore,
diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.tsx
index 0dbc1faa5cb42..08295038a1bd8 100644
--- a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.tsx
@@ -73,7 +73,7 @@ export const UserPanelContent = ({
entity={{ name: userName, type: 'user' }}
onChange={onAssetCriticalityChange}
/>
-
+
0 || failedFindings > 0;
-
- const { signalIndexName } = useSignalIndex();
+ const { hasMisconfigurationFindings } = useHasMisconfigurations('user.name', userName);
- const entityFilter = useMemo(() => ({ field: 'user.name', value: userName }), [userName]);
-
- const { items: alertsData } = useAlertsByStatus({
- entityFilter,
- signalIndexName,
- queryId: `${DETECTION_RESPONSE_ALERTS_BY_STATUS_ID}USER_NAME_RIGHT`,
+ const { hasNonClosedAlerts } = useNonClosedAlerts({
+ field: 'user.name',
+ value: userName,
to,
from,
+ queryId: `${DETECTION_RESPONSE_ALERTS_BY_STATUS_ID}USER_NAME_RIGHT`,
});
- const hasNonClosedAlerts =
- (alertsData?.acknowledged?.total || 0) + (alertsData?.open?.total || 0) > 0;
-
useQueryInspector({
deleteQuery,
inspect,