mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
Remove 'missing fields' from alerts trend graph and count table (#108843)
This commit is contained in:
parent
348f040591
commit
ab637303e7
12 changed files with 31 additions and 178 deletions
|
@ -290,11 +290,6 @@ if (ENABLE_CASE_CONNECTOR) {
|
|||
export const NOTIFICATION_THROTTLE_NO_ACTIONS = 'no_actions';
|
||||
export const NOTIFICATION_THROTTLE_RULE = 'rule';
|
||||
|
||||
/**
|
||||
* Histograms for fields named in this list should be displayed with an
|
||||
* "All others" bucket, to count events that don't specify a value for
|
||||
* the field being counted
|
||||
*/
|
||||
export const showAllOthersBucket: string[] = [
|
||||
'destination.ip',
|
||||
'event.action',
|
||||
|
|
|
@ -26,9 +26,6 @@ jest.mock('@elastic/eui', () => {
|
|||
};
|
||||
});
|
||||
|
||||
const allOthersDataProviderId =
|
||||
'draggable-legend-item-527adabe-8e1c-4a1f-965c-2f3d65dda9e1-event_dataset-All others';
|
||||
|
||||
const legendItems: LegendItem[] = [
|
||||
{
|
||||
color: '#1EA593',
|
||||
|
@ -57,12 +54,6 @@ const legendItems: LegendItem[] = [
|
|||
field: 'event.dataset',
|
||||
value: 'esensor',
|
||||
},
|
||||
{
|
||||
color: '#F37020',
|
||||
dataProviderId: allOthersDataProviderId,
|
||||
field: 'event.dataset',
|
||||
value: 'All others',
|
||||
},
|
||||
];
|
||||
|
||||
describe('DraggableLegend', () => {
|
||||
|
@ -95,14 +86,7 @@ describe('DraggableLegend', () => {
|
|||
it('renders the legend items', () => {
|
||||
legendItems.forEach((item) =>
|
||||
expect(
|
||||
wrapper
|
||||
.find(
|
||||
item.dataProviderId !== allOthersDataProviderId
|
||||
? `[data-test-subj="legend-item-${item.dataProviderId}"]`
|
||||
: '[data-test-subj="all-others-legend-item"]'
|
||||
)
|
||||
.first()
|
||||
.text()
|
||||
wrapper.find(`[data-test-subj="legend-item-${item.dataProviderId}"]`).first().text()
|
||||
).toEqual(item.value)
|
||||
);
|
||||
});
|
||||
|
|
|
@ -26,97 +26,32 @@ jest.mock('@elastic/eui', () => {
|
|||
});
|
||||
|
||||
describe('DraggableLegendItem', () => {
|
||||
describe('rendering a regular (non "All others") legend item', () => {
|
||||
const legendItem: LegendItem = {
|
||||
color: '#1EA593',
|
||||
dataProviderId:
|
||||
'draggable-legend-item-3207fda7-d008-402a-86a0-8ad632081bad-event_dataset-flow',
|
||||
field: 'event.dataset',
|
||||
value: 'flow',
|
||||
};
|
||||
const legendItem: LegendItem = {
|
||||
color: '#1EA593',
|
||||
dataProviderId: 'draggable-legend-item-3207fda7-d008-402a-86a0-8ad632081bad-event_dataset-flow',
|
||||
field: 'event.dataset',
|
||||
value: 'flow',
|
||||
};
|
||||
|
||||
let wrapper: ReactWrapper;
|
||||
let wrapper: ReactWrapper;
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = mount(
|
||||
<TestProviders>
|
||||
<DraggableLegendItem legendItem={legendItem} />
|
||||
</TestProviders>
|
||||
);
|
||||
});
|
||||
|
||||
it('renders a colored circle with the expected legend item color', () => {
|
||||
expect(wrapper.find('[data-test-subj="legend-color"]').first().props().color).toEqual(
|
||||
legendItem.color
|
||||
);
|
||||
});
|
||||
|
||||
it('renders draggable legend item text', () => {
|
||||
expect(
|
||||
wrapper.find(`[data-test-subj="legend-item-${legendItem.dataProviderId}"]`).first().text()
|
||||
).toEqual(legendItem.value);
|
||||
});
|
||||
|
||||
it('does NOT render a non-draggable "All others" legend item', () => {
|
||||
expect(wrapper.find(`[data-test-subj="all-others-legend-item"]`).exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('rendering an "All others" legend item', () => {
|
||||
const allOthersLegendItem: LegendItem = {
|
||||
color: '#F37020',
|
||||
dataProviderId:
|
||||
'draggable-legend-item-527adabe-8e1c-4a1f-965c-2f3d65dda9e1-event_dataset-All others',
|
||||
field: 'event.dataset',
|
||||
value: 'All others',
|
||||
};
|
||||
|
||||
let wrapper: ReactWrapper;
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = mount(
|
||||
<TestProviders>
|
||||
<DraggableLegendItem legendItem={allOthersLegendItem} />
|
||||
</TestProviders>
|
||||
);
|
||||
});
|
||||
|
||||
it('renders a colored circle with the expected legend item color', () => {
|
||||
expect(wrapper.find('[data-test-subj="legend-color"]').first().props().color).toEqual(
|
||||
allOthersLegendItem.color
|
||||
);
|
||||
});
|
||||
|
||||
it('does NOT render a draggable legend item', () => {
|
||||
expect(
|
||||
wrapper
|
||||
.find(`[data-test-subj="legend-item-${allOthersLegendItem.dataProviderId}"]`)
|
||||
.exists()
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it('renders NON-draggable `All others` legend item text', () => {
|
||||
expect(wrapper.find(`[data-test-subj="all-others-legend-item"]`).first().text()).toEqual(
|
||||
allOthersLegendItem.value
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('does NOT render a colored circle when the legend item has no color', () => {
|
||||
const noColorLegendItem: LegendItem = {
|
||||
// no `color` attribute for this `LegendItem`!
|
||||
dataProviderId:
|
||||
'draggable-legend-item-3207fda7-d008-402a-86a0-8ad632081bad-event_dataset-flow',
|
||||
field: 'event.dataset',
|
||||
value: 'flow',
|
||||
};
|
||||
|
||||
const wrapper = mount(
|
||||
beforeEach(() => {
|
||||
wrapper = mount(
|
||||
<TestProviders>
|
||||
<DraggableLegendItem legendItem={noColorLegendItem} />
|
||||
<DraggableLegendItem legendItem={legendItem} />
|
||||
</TestProviders>
|
||||
);
|
||||
});
|
||||
|
||||
expect(wrapper.find('[data-test-subj="legend-color"]').exists()).toBe(false);
|
||||
it('renders a colored circle with the expected legend item color', () => {
|
||||
expect(wrapper.find('[data-test-subj="legend-color"]').first().props().color).toEqual(
|
||||
legendItem.color
|
||||
);
|
||||
});
|
||||
|
||||
it('renders draggable legend item text', () => {
|
||||
expect(
|
||||
wrapper.find(`[data-test-subj="legend-item-${legendItem.dataProviderId}"]`).first().text()
|
||||
).toEqual(legendItem.value);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,17 +7,9 @@
|
|||
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiHealth, EuiText } from '@elastic/eui';
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { DefaultDraggable } from '../draggables';
|
||||
|
||||
import * as i18n from './translation';
|
||||
|
||||
// The "All others" legend item is not draggable
|
||||
const AllOthers = styled.span`
|
||||
padding-left: 7px;
|
||||
`;
|
||||
|
||||
export interface LegendItem {
|
||||
color?: string;
|
||||
dataProviderId: string;
|
||||
|
@ -41,20 +33,14 @@ const DraggableLegendItemComponent: React.FC<{
|
|||
)}
|
||||
|
||||
<EuiFlexItem grow={false}>
|
||||
{value !== i18n.ALL_OTHERS ? (
|
||||
<DefaultDraggable
|
||||
data-test-subj={`legend-item-${dataProviderId}`}
|
||||
field={field}
|
||||
id={dataProviderId}
|
||||
isDraggable={false}
|
||||
timelineId={timelineId}
|
||||
value={value}
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
<AllOthers data-test-subj="all-others-legend-item">{value}</AllOthers>
|
||||
</>
|
||||
)}
|
||||
<DefaultDraggable
|
||||
data-test-subj={`legend-item-${dataProviderId}`}
|
||||
field={field}
|
||||
id={dataProviderId}
|
||||
isDraggable={false}
|
||||
timelineId={timelineId}
|
||||
value={value}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiText>
|
||||
|
|
|
@ -20,7 +20,3 @@ export const DATA_NOT_AVAILABLE_TITLE = i18n.translate(
|
|||
defaultMessage: 'Chart Data Not Available',
|
||||
}
|
||||
);
|
||||
|
||||
export const ALL_OTHERS = i18n.translate('xpack.securitySolution.chart.allOthersGroupingLabel', {
|
||||
defaultMessage: 'All others',
|
||||
});
|
||||
|
|
|
@ -16,7 +16,6 @@ import { DefaultDraggable } from '../../../../common/components/draggables';
|
|||
import type { GenericBuckets } from '../../../../../common';
|
||||
import type { AlertSearchResponse } from '../../../containers/detection_engine/alerts/types';
|
||||
import type { AlertsCountAggregation } from './types';
|
||||
import { MISSING_IP } from '../common/helpers';
|
||||
|
||||
interface AlertsCountProps {
|
||||
loading: boolean;
|
||||
|
@ -29,10 +28,6 @@ const Wrapper = styled.div`
|
|||
margin-top: -8px;
|
||||
`;
|
||||
|
||||
const StyledSpan = styled.span`
|
||||
padding-left: 8px;
|
||||
`;
|
||||
|
||||
const getAlertsCountTableColumns = (
|
||||
selectedStackByOption: string,
|
||||
defaultNumberFormat: string
|
||||
|
@ -43,9 +38,7 @@ const getAlertsCountTableColumns = (
|
|||
name: selectedStackByOption,
|
||||
truncateText: true,
|
||||
render: function DraggableStackOptionField(value: string) {
|
||||
return value === i18n.ALL_OTHERS || value === MISSING_IP ? (
|
||||
<StyledSpan>{value}</StyledSpan>
|
||||
) : (
|
||||
return (
|
||||
<DefaultDraggable
|
||||
field={selectedStackByOption}
|
||||
id={`alert-count-draggable-${selectedStackByOption}-${value}`}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
|
||||
import { DEFAULT_MAX_TABLE_QUERY_SIZE } from '../../../../../common/constants';
|
||||
import { getMissingFields } from '../common/helpers';
|
||||
import type { AlertsStackByField } from '../common/types';
|
||||
|
||||
export const getAlertsCountQuery = (
|
||||
|
@ -17,15 +16,12 @@ export const getAlertsCountQuery = (
|
|||
bool: { filter: unknown[]; should: unknown[]; must_not: unknown[]; must: unknown[] };
|
||||
}> = []
|
||||
) => {
|
||||
const missing = getMissingFields(stackByField);
|
||||
|
||||
return {
|
||||
size: 0,
|
||||
aggs: {
|
||||
alertsByGroupingCount: {
|
||||
terms: {
|
||||
field: stackByField,
|
||||
...missing,
|
||||
order: {
|
||||
_count: 'desc',
|
||||
},
|
||||
|
|
|
@ -10,7 +10,6 @@ import moment from 'moment';
|
|||
import { isEmpty } from 'lodash/fp';
|
||||
import type { HistogramData, AlertsAggregation, AlertsBucket, AlertsGroupBucket } from './types';
|
||||
import type { AlertSearchResponse } from '../../../containers/detection_engine/alerts/types';
|
||||
import { getMissingFields } from '../common/helpers';
|
||||
import type { AlertsStackByField } from '../common/types';
|
||||
|
||||
const EMPTY_ALERTS_DATA: HistogramData[] = [];
|
||||
|
@ -41,14 +40,11 @@ export const getAlertsHistogramQuery = (
|
|||
bool: { filter: unknown[]; should: unknown[]; must_not: unknown[]; must: unknown[] };
|
||||
}>
|
||||
) => {
|
||||
const missing = getMissingFields(stackByField);
|
||||
|
||||
return {
|
||||
aggs: {
|
||||
alertsByGrouping: {
|
||||
terms: {
|
||||
field: stackByField,
|
||||
...missing,
|
||||
order: {
|
||||
_count: 'desc',
|
||||
},
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { showAllOthersBucket } from '../../../../../common/constants';
|
||||
import type { AlertsStackByField } from './types';
|
||||
import * as i18n from './translations';
|
||||
|
||||
export const MISSING_IP = '0.0.0.0';
|
||||
|
||||
export const getMissingFields = (stackByField: AlertsStackByField) =>
|
||||
showAllOthersBucket.includes(stackByField)
|
||||
? {
|
||||
missing: stackByField.endsWith('.ip') ? MISSING_IP : i18n.ALL_OTHERS,
|
||||
}
|
||||
: {};
|
|
@ -13,10 +13,3 @@ export const STACK_BY_LABEL = i18n.translate(
|
|||
defaultMessage: 'Stack by',
|
||||
}
|
||||
);
|
||||
|
||||
export const ALL_OTHERS = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.alerts.histogram.allOthersGroupingLabel',
|
||||
{
|
||||
defaultMessage: 'All others',
|
||||
}
|
||||
);
|
||||
|
|
|
@ -20108,7 +20108,6 @@
|
|||
"xpack.securitySolution.cases.pageTitle": "ケース",
|
||||
"xpack.securitySolution.certificate.fingerprint.clientCertLabel": "クライアント証明書",
|
||||
"xpack.securitySolution.certificate.fingerprint.serverCertLabel": "サーバー証明書",
|
||||
"xpack.securitySolution.chart.allOthersGroupingLabel": "その他すべて",
|
||||
"xpack.securitySolution.chart.dataAllValuesZerosTitle": "すべての値はゼロを返します",
|
||||
"xpack.securitySolution.chart.dataNotAvailableTitle": "チャートデータが利用できません",
|
||||
"xpack.securitySolution.chrome.help.appName": "セキュリティ",
|
||||
|
|
|
@ -20552,7 +20552,6 @@
|
|||
"xpack.securitySolution.cases.pageTitle": "案例",
|
||||
"xpack.securitySolution.certificate.fingerprint.clientCertLabel": "客户端证书",
|
||||
"xpack.securitySolution.certificate.fingerprint.serverCertLabel": "服务器证书",
|
||||
"xpack.securitySolution.chart.allOthersGroupingLabel": "所有其他",
|
||||
"xpack.securitySolution.chart.dataAllValuesZerosTitle": "所有值返回了零",
|
||||
"xpack.securitySolution.chart.dataNotAvailableTitle": "图表数据不可用",
|
||||
"xpack.securitySolution.chrome.help.appName": "安全",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue