mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
This reverts commit d1dd97f4fe
.
This commit is contained in:
parent
d1dd97f4fe
commit
667a3d5c99
4 changed files with 33 additions and 520 deletions
|
@ -5,155 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { Filter } from '@kbn/es-query';
|
||||
|
||||
import { TimelineId } from '../../../../common/types/timeline';
|
||||
import {
|
||||
alertEvents,
|
||||
allEvents,
|
||||
defaultOptions,
|
||||
getOptions,
|
||||
getSourcererScopeName,
|
||||
isDetectionsAlertsTable,
|
||||
rawEvents,
|
||||
removeIgnoredAlertFilters,
|
||||
shouldIgnoreAlertFilters,
|
||||
} from './helpers';
|
||||
import { SourcererScopeName } from '../../store/sourcerer/model';
|
||||
|
||||
/** the following `TimelineId`s are detection alert tables */
|
||||
const detectionAlertsTimelines = [TimelineId.detectionsPage, TimelineId.detectionsRulesDetailsPage];
|
||||
|
||||
/** the following `TimelineId`s are NOT detection alert tables */
|
||||
const otherTimelines = [
|
||||
TimelineId.hostsPageEvents,
|
||||
TimelineId.hostsPageExternalAlerts,
|
||||
TimelineId.networkPageExternalAlerts,
|
||||
TimelineId.uebaPageExternalAlerts,
|
||||
TimelineId.active,
|
||||
TimelineId.casePage,
|
||||
TimelineId.test,
|
||||
TimelineId.alternateTest,
|
||||
];
|
||||
|
||||
const othersWithoutActive = otherTimelines.filter((x) => x !== TimelineId.active);
|
||||
|
||||
const hostNameFilter: Filter = {
|
||||
meta: {
|
||||
alias: null,
|
||||
negate: false,
|
||||
disabled: false,
|
||||
type: 'phrase',
|
||||
key: 'host.name',
|
||||
params: {
|
||||
query: 'Host-abcd',
|
||||
},
|
||||
},
|
||||
query: {
|
||||
match_phrase: {
|
||||
'host.name': {
|
||||
query: 'Host-abcd',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const buildingBlockTypeFilter: Filter = {
|
||||
meta: {
|
||||
alias: null,
|
||||
negate: true,
|
||||
disabled: false,
|
||||
type: 'exists',
|
||||
key: 'kibana.alert.building_block_type',
|
||||
value: 'exists',
|
||||
},
|
||||
query: {
|
||||
exists: {
|
||||
field: 'kibana.alert.building_block_type',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const ruleIdFilter: Filter = {
|
||||
meta: {
|
||||
alias: null,
|
||||
negate: false,
|
||||
disabled: false,
|
||||
type: 'phrase',
|
||||
key: 'kibana.alert.rule.rule_id',
|
||||
params: {
|
||||
query: '32a4aefa-80fb-4716-bc0f-3f7bb1f14929',
|
||||
},
|
||||
},
|
||||
query: {
|
||||
match_phrase: {
|
||||
'kibana.alert.rule.rule_id': '32a4aefa-80fb-4716-bc0f-3f7bb1f14929',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const ruleNameFilter: Filter = {
|
||||
meta: {
|
||||
alias: null,
|
||||
negate: false,
|
||||
disabled: false,
|
||||
type: 'phrase',
|
||||
key: 'kibana.alert.rule.name',
|
||||
params: {
|
||||
query: 'baz',
|
||||
},
|
||||
},
|
||||
query: {
|
||||
match_phrase: {
|
||||
'kibana.alert.rule.name': {
|
||||
query: 'baz',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const threatMappingFilter: Filter = {
|
||||
meta: {
|
||||
alias: null,
|
||||
negate: true,
|
||||
disabled: false,
|
||||
type: 'exists',
|
||||
key: 'kibana.alert.rule.threat_mapping',
|
||||
value: 'exists',
|
||||
},
|
||||
query: {
|
||||
exists: {
|
||||
field: 'kibana.alert.rule.threat_mapping',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const workflowStatusFilter: Filter = {
|
||||
meta: {
|
||||
alias: null,
|
||||
negate: false,
|
||||
disabled: false,
|
||||
type: 'phrase',
|
||||
key: 'kibana.alert.workflow_status',
|
||||
params: {
|
||||
query: 'open',
|
||||
},
|
||||
},
|
||||
query: {
|
||||
term: {
|
||||
'kibana.alert.workflow_status': 'open',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const allFilters = [
|
||||
hostNameFilter,
|
||||
buildingBlockTypeFilter,
|
||||
ruleIdFilter,
|
||||
ruleNameFilter,
|
||||
threatMappingFilter,
|
||||
workflowStatusFilter,
|
||||
];
|
||||
import { allEvents, defaultOptions, getOptions, rawEvents, alertEvents } from './helpers';
|
||||
|
||||
describe('getOptions', () => {
|
||||
test(`it returns the default options when 'activeTimelineEventType' is undefined`, () => {
|
||||
|
@ -172,123 +24,3 @@ describe('getOptions', () => {
|
|||
expect(getOptions('alert')).toEqual(alertEvents);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isDetectionsAlertsTable', () => {
|
||||
detectionAlertsTimelines.forEach((timelineId) =>
|
||||
test(`it returns true for detections alerts table '${timelineId}'`, () => {
|
||||
expect(isDetectionsAlertsTable(timelineId)).toEqual(true);
|
||||
})
|
||||
);
|
||||
|
||||
otherTimelines.forEach((timelineId) =>
|
||||
test(`it returns false for (NON alert table) timeline '${timelineId}'`, () => {
|
||||
expect(isDetectionsAlertsTable(timelineId)).toEqual(false);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
describe('shouldIgnoreAlertFilters', () => {
|
||||
detectionAlertsTimelines.forEach((timelineId) => {
|
||||
test(`it returns true when the view is 'raw' for detections alerts table '${timelineId}'`, () => {
|
||||
const view = 'raw';
|
||||
expect(shouldIgnoreAlertFilters({ timelineId, view })).toEqual(true);
|
||||
});
|
||||
|
||||
test(`it returns false when the view is NOT 'raw' for detections alerts table '${timelineId}'`, () => {
|
||||
const view = 'alert'; // the default selection for detection alert tables
|
||||
expect(shouldIgnoreAlertFilters({ timelineId, view })).toEqual(false);
|
||||
});
|
||||
});
|
||||
|
||||
otherTimelines.forEach((timelineId) => {
|
||||
test(`it returns false when the view is 'raw' for (NON alert table) timeline'${timelineId}'`, () => {
|
||||
const view = 'raw';
|
||||
expect(shouldIgnoreAlertFilters({ timelineId, view })).toEqual(false);
|
||||
});
|
||||
|
||||
test(`it returns false when the view is NOT 'raw' for (NON alert table) timeline '${timelineId}'`, () => {
|
||||
const view = 'alert';
|
||||
expect(shouldIgnoreAlertFilters({ timelineId, view })).toEqual(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('removeIgnoredAlertFilters', () => {
|
||||
detectionAlertsTimelines.forEach((timelineId) => {
|
||||
test(`it removes the ignored alert filters when the view is 'raw' for detections alerts table '${timelineId}'`, () => {
|
||||
const view = 'raw';
|
||||
expect(removeIgnoredAlertFilters({ filters: allFilters, timelineId, view })).toEqual([
|
||||
hostNameFilter,
|
||||
]);
|
||||
});
|
||||
|
||||
test(`it does NOT remove any filters when the view is NOT 'raw' for detections alerts table '${timelineId}'`, () => {
|
||||
const view = 'alert';
|
||||
expect(removeIgnoredAlertFilters({ filters: allFilters, timelineId, view })).toEqual(
|
||||
allFilters
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
otherTimelines.forEach((timelineId) => {
|
||||
test(`it does NOT remove any filters when the view is 'raw' for (NON alert table) '${timelineId}'`, () => {
|
||||
const view = 'alert';
|
||||
expect(removeIgnoredAlertFilters({ filters: allFilters, timelineId, view })).toEqual(
|
||||
allFilters
|
||||
);
|
||||
});
|
||||
|
||||
test(`it does NOT remove any filters when the view is NOT 'raw' for (NON alert table '${timelineId}'`, () => {
|
||||
const view = 'alert';
|
||||
expect(removeIgnoredAlertFilters({ filters: allFilters, timelineId, view })).toEqual(
|
||||
allFilters
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSourcererScopeName', () => {
|
||||
detectionAlertsTimelines.forEach((timelineId) => {
|
||||
test(`it returns the 'default' SourcererScopeName when the view is 'raw' for detections alerts table '${timelineId}'`, () => {
|
||||
const view = 'raw';
|
||||
expect(getSourcererScopeName({ timelineId, view })).toEqual(SourcererScopeName.default);
|
||||
});
|
||||
|
||||
test(`it returns the 'detections' SourcererScopeName when the view is NOT 'raw' for detections alerts table '${timelineId}'`, () => {
|
||||
const view = 'alert';
|
||||
expect(getSourcererScopeName({ timelineId, view })).toEqual(SourcererScopeName.detections);
|
||||
});
|
||||
});
|
||||
|
||||
test(`it returns the 'default' SourcererScopeName when timelineId is undefined'`, () => {
|
||||
const timelineId = undefined;
|
||||
const view = 'raw';
|
||||
expect(getSourcererScopeName({ timelineId, view })).toEqual(SourcererScopeName.default);
|
||||
});
|
||||
|
||||
test(`it returns the 'timeline' SourcererScopeName when the view is 'raw' for the active timeline '${TimelineId.active}'`, () => {
|
||||
const view = 'raw';
|
||||
expect(getSourcererScopeName({ timelineId: TimelineId.active, view })).toEqual(
|
||||
SourcererScopeName.timeline
|
||||
);
|
||||
});
|
||||
|
||||
test(`it returns the 'timeline' SourcererScopeName when the view is NOT 'raw' for the active timeline '${TimelineId.active}'`, () => {
|
||||
const view = 'all';
|
||||
expect(getSourcererScopeName({ timelineId: TimelineId.active, view })).toEqual(
|
||||
SourcererScopeName.timeline
|
||||
);
|
||||
});
|
||||
|
||||
othersWithoutActive.forEach((timelineId) => {
|
||||
test(`it returns the 'default' SourcererScopeName when the view is 'raw' for (NON alert table) timeline '${timelineId}'`, () => {
|
||||
const view = 'raw';
|
||||
expect(getSourcererScopeName({ timelineId, view })).toEqual(SourcererScopeName.default);
|
||||
});
|
||||
|
||||
test(`it returns the 'default' SourcererScopeName when the view is NOT 'raw' for detections alerts table '${timelineId}'`, () => {
|
||||
const view = 'alert';
|
||||
expect(getSourcererScopeName({ timelineId, view })).toEqual(SourcererScopeName.default);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,60 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { Filter } from '@kbn/es-query';
|
||||
import {
|
||||
ALERT_ACTION_GROUP,
|
||||
ALERT_BUILDING_BLOCK_TYPE,
|
||||
ALERT_DURATION,
|
||||
ALERT_END,
|
||||
ALERT_EVALUATION_THRESHOLD,
|
||||
ALERT_EVALUATION_VALUE,
|
||||
ALERT_INSTANCE_ID,
|
||||
ALERT_NAMESPACE,
|
||||
ALERT_REASON,
|
||||
ALERT_RISK_SCORE,
|
||||
ALERT_RULE_AUTHOR,
|
||||
ALERT_RULE_CATEGORY,
|
||||
ALERT_RULE_CONSUMER,
|
||||
ALERT_RULE_CREATED_AT,
|
||||
ALERT_RULE_CREATED_BY,
|
||||
ALERT_RULE_DESCRIPTION,
|
||||
ALERT_RULE_ENABLED,
|
||||
ALERT_RULE_FROM,
|
||||
ALERT_RULE_INTERVAL,
|
||||
ALERT_RULE_LICENSE,
|
||||
ALERT_RULE_NAME,
|
||||
ALERT_RULE_NAMESPACE,
|
||||
ALERT_RULE_NOTE,
|
||||
ALERT_RULE_PARAMETERS,
|
||||
ALERT_RULE_PRODUCER,
|
||||
ALERT_RULE_REFERENCES,
|
||||
ALERT_RULE_RISK_SCORE,
|
||||
ALERT_RULE_RISK_SCORE_MAPPING,
|
||||
ALERT_RULE_RULE_ID,
|
||||
ALERT_RULE_RULE_NAME_OVERRIDE,
|
||||
ALERT_RULE_SEVERITY,
|
||||
ALERT_RULE_SEVERITY_MAPPING,
|
||||
ALERT_RULE_TAGS,
|
||||
ALERT_RULE_TO,
|
||||
ALERT_RULE_TYPE,
|
||||
ALERT_RULE_TYPE_ID,
|
||||
ALERT_RULE_UPDATED_AT,
|
||||
ALERT_RULE_UPDATED_BY,
|
||||
ALERT_RULE_UUID,
|
||||
ALERT_RULE_VERSION,
|
||||
ALERT_SEVERITY,
|
||||
ALERT_START,
|
||||
ALERT_STATUS,
|
||||
ALERT_SYSTEM_STATUS,
|
||||
ALERT_UUID,
|
||||
ALERT_WORKFLOW_REASON,
|
||||
ALERT_WORKFLOW_STATUS,
|
||||
ALERT_WORKFLOW_USER,
|
||||
} from '@kbn/rule-data-utils';
|
||||
|
||||
import { TimelineEventsType, TimelineId } from '../../../../common/types/timeline';
|
||||
import { SourcererScopeName } from '../../store/sourcerer/model';
|
||||
import { TimelineEventsType } from '../../../../common/types/timeline';
|
||||
|
||||
import * as i18n from './translations';
|
||||
|
||||
|
@ -118,126 +65,3 @@ export const getOptions = (activeTimelineEventsType?: TimelineEventsType): TopNO
|
|||
return defaultOptions;
|
||||
}
|
||||
};
|
||||
|
||||
/** returns true if the specified timelineId is a detections alert table */
|
||||
export const isDetectionsAlertsTable = (timelineId: string | undefined): boolean =>
|
||||
timelineId === TimelineId.detectionsPage || timelineId === TimelineId.detectionsRulesDetailsPage;
|
||||
|
||||
/**
|
||||
* The following fields are used to filter alerts tables, (i.e. tables in the
|
||||
* `Security > Alert` and `Security > Rule > Details` pages). These fields,
|
||||
* MUST be ignored when showing Top N alerts for `raw` documents, because
|
||||
* the raw documents don't include them.
|
||||
*/
|
||||
export const IGNORED_ALERT_FILTERS = [
|
||||
ALERT_ACTION_GROUP,
|
||||
ALERT_BUILDING_BLOCK_TYPE, // an "Additional filters" option on the alerts table
|
||||
ALERT_DURATION,
|
||||
ALERT_END,
|
||||
ALERT_EVALUATION_THRESHOLD,
|
||||
ALERT_EVALUATION_VALUE,
|
||||
ALERT_INSTANCE_ID,
|
||||
ALERT_NAMESPACE,
|
||||
ALERT_RULE_NAMESPACE,
|
||||
ALERT_RULE_CONSUMER,
|
||||
ALERT_RULE_PRODUCER,
|
||||
ALERT_REASON,
|
||||
ALERT_RISK_SCORE,
|
||||
ALERT_STATUS,
|
||||
ALERT_WORKFLOW_REASON,
|
||||
ALERT_WORKFLOW_STATUS, // open | acknowledged | closed filter
|
||||
ALERT_WORKFLOW_USER,
|
||||
ALERT_RULE_AUTHOR,
|
||||
ALERT_RULE_CREATED_AT,
|
||||
ALERT_RULE_CREATED_BY,
|
||||
ALERT_RULE_DESCRIPTION,
|
||||
ALERT_RULE_ENABLED,
|
||||
ALERT_RULE_FROM,
|
||||
ALERT_RULE_INTERVAL,
|
||||
ALERT_RULE_LICENSE,
|
||||
ALERT_RULE_NAME, // not a built-in view filter, but frequently applied via the `Filter In` and `Filter Out` actions
|
||||
ALERT_RULE_NOTE,
|
||||
ALERT_RULE_PARAMETERS,
|
||||
ALERT_RULE_REFERENCES,
|
||||
ALERT_RULE_RISK_SCORE,
|
||||
ALERT_RULE_RISK_SCORE_MAPPING,
|
||||
ALERT_RULE_RULE_ID, // filters alerts to a single rule on the Security > Rules > details pages
|
||||
ALERT_RULE_RULE_NAME_OVERRIDE,
|
||||
ALERT_RULE_SEVERITY_MAPPING,
|
||||
ALERT_RULE_TAGS,
|
||||
'kibana.alert.rule.threat_mapping', // an "Additional filters" option on the alerts table
|
||||
ALERT_RULE_TO,
|
||||
ALERT_RULE_TYPE,
|
||||
ALERT_RULE_TYPE_ID,
|
||||
ALERT_RULE_UPDATED_AT,
|
||||
ALERT_RULE_UPDATED_BY,
|
||||
ALERT_RULE_UUID,
|
||||
ALERT_RULE_CATEGORY,
|
||||
ALERT_RULE_VERSION,
|
||||
ALERT_RULE_SEVERITY,
|
||||
ALERT_SEVERITY,
|
||||
ALERT_START,
|
||||
ALERT_SYSTEM_STATUS,
|
||||
ALERT_UUID,
|
||||
];
|
||||
|
||||
/**
|
||||
* returns true if the Top N query should ignore filters specific to alerts
|
||||
* when querying raw documents
|
||||
*
|
||||
* @see IGNORED_ALERT_FILTERS
|
||||
*/
|
||||
export const shouldIgnoreAlertFilters = ({
|
||||
timelineId,
|
||||
view,
|
||||
}: {
|
||||
timelineId: string | undefined;
|
||||
view: TimelineEventsType;
|
||||
}): boolean => view === 'raw' && isDetectionsAlertsTable(timelineId);
|
||||
|
||||
/**
|
||||
* returns a new set of `filters` that don't contain the fields specified in
|
||||
* `IGNORED_ALERT_FILTERS` when they should be ignored
|
||||
*
|
||||
* @see IGNORED_ALERT_FILTERS
|
||||
*/
|
||||
export const removeIgnoredAlertFilters = ({
|
||||
filters,
|
||||
timelineId,
|
||||
view,
|
||||
}: {
|
||||
filters: Filter[];
|
||||
timelineId: string | undefined;
|
||||
view: TimelineEventsType;
|
||||
}): Filter[] => {
|
||||
if (!shouldIgnoreAlertFilters({ timelineId, view })) {
|
||||
return filters; // unmodified filters
|
||||
}
|
||||
|
||||
return filters.filter((x) => !IGNORED_ALERT_FILTERS.includes(`${x.meta.key}`));
|
||||
};
|
||||
|
||||
/** returns the SourcererScopeName applicable to the specified timelineId and view */
|
||||
export const getSourcererScopeName = ({
|
||||
timelineId,
|
||||
view,
|
||||
}: {
|
||||
timelineId: string | undefined;
|
||||
view: TimelineEventsType;
|
||||
}): SourcererScopeName => {
|
||||
// When alerts should be ignored, use the `default` Sourcerer scope,
|
||||
// because it does NOT include alert indexes:
|
||||
if (shouldIgnoreAlertFilters({ timelineId, view })) {
|
||||
return SourcererScopeName.default; // no alerts in this scope
|
||||
}
|
||||
|
||||
if (isDetectionsAlertsTable(timelineId)) {
|
||||
return SourcererScopeName.detections;
|
||||
}
|
||||
|
||||
if (timelineId === TimelineId.active) {
|
||||
return SourcererScopeName.timeline;
|
||||
}
|
||||
|
||||
return SourcererScopeName.default;
|
||||
};
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
import { mount, ReactWrapper } from 'enzyme';
|
||||
import React from 'react';
|
||||
import { waitFor } from '@testing-library/react';
|
||||
|
||||
import { TimelineId } from '../../../../common/types';
|
||||
import '../../mock/match_media';
|
||||
import { TestProviders, mockIndexPattern } from '../../mock';
|
||||
|
||||
|
@ -128,59 +126,9 @@ describe('TopN', () => {
|
|||
|
||||
expect(toggleTopN).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('view selection', () => {
|
||||
const detectionAlertsTimelines = [
|
||||
TimelineId.detectionsPage,
|
||||
TimelineId.detectionsRulesDetailsPage,
|
||||
];
|
||||
|
||||
const nonDetectionAlertTables = [
|
||||
TimelineId.hostsPageEvents,
|
||||
TimelineId.hostsPageExternalAlerts,
|
||||
TimelineId.networkPageExternalAlerts,
|
||||
TimelineId.casePage,
|
||||
];
|
||||
|
||||
test('it disables view selection when timelineId is undefined', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<TopN {...testProps} timelineId={undefined} />
|
||||
</TestProviders>
|
||||
);
|
||||
expect(wrapper.find('[data-test-subj="view-select"]').first().props().disabled).toBe(true);
|
||||
});
|
||||
|
||||
test('it disables view selection when timelineId is `active`', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<TopN {...testProps} timelineId={TimelineId.active} />
|
||||
</TestProviders>
|
||||
);
|
||||
expect(wrapper.find('[data-test-subj="view-select"]').first().props().disabled).toBe(true);
|
||||
});
|
||||
|
||||
detectionAlertsTimelines.forEach((timelineId) => {
|
||||
test(`it enables view selection for detection alert table '${timelineId}'`, () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<TopN {...testProps} timelineId={timelineId} />
|
||||
</TestProviders>
|
||||
);
|
||||
expect(wrapper.find('[data-test-subj="view-select"]').first().props().disabled).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
nonDetectionAlertTables.forEach((timelineId) => {
|
||||
test(`it disables view selection for NON detection alert table '${timelineId}'`, () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<TopN {...testProps} timelineId={timelineId} />
|
||||
</TestProviders>
|
||||
);
|
||||
expect(wrapper.find('[data-test-subj="view-select"]').first().props().disabled).toBe(true);
|
||||
});
|
||||
test('it enables the view select by default', () => {
|
||||
expect(wrapper.find('[data-test-subj="view-select"]').first().props().disabled).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -255,6 +203,10 @@ describe('TopN', () => {
|
|||
);
|
||||
});
|
||||
|
||||
test(`it disables the view select when 'options' contains only one entry`, () => {
|
||||
expect(wrapper.find('[data-test-subj="view-select"]').first().props().disabled).toBe(true);
|
||||
});
|
||||
|
||||
test(`it renders EventsByDataset when defaultView is 'all'`, () => {
|
||||
expect(
|
||||
wrapper.find('[data-test-subj="eventsByDatasetOverview-uuid.v4()Panel"]').exists()
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
*/
|
||||
|
||||
import { EuiButtonIcon, EuiSuperSelect } from '@elastic/eui';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import type { DataViewBase, Filter, Query } from '@kbn/es-query';
|
||||
|
@ -15,15 +17,13 @@ import { EventsByDataset } from '../../../overview/components/events_by_dataset'
|
|||
import { SignalsByCategory } from '../../../overview/components/signals_by_category';
|
||||
import { InputsModelId } from '../../store/inputs/constants';
|
||||
import { TimelineEventsType } from '../../../../common/types/timeline';
|
||||
import { useSourcererDataView } from '../../containers/sourcerer';
|
||||
import {
|
||||
isDetectionsAlertsTable,
|
||||
getSourcererScopeName,
|
||||
removeIgnoredAlertFilters,
|
||||
TopNOption,
|
||||
} from './helpers';
|
||||
|
||||
import { TopNOption } from './helpers';
|
||||
import * as i18n from './translations';
|
||||
import { getIndicesSelector, IndicesSelector } from './selectors';
|
||||
import { State } from '../../store';
|
||||
import { AlertsStackByField } from '../../../detections/components/alerts_kpis/common/types';
|
||||
import { SourcererScopeName } from '../../store/sourcerer/model';
|
||||
|
||||
const TopNContainer = styled.div`
|
||||
min-width: 600px;
|
||||
|
@ -89,7 +89,19 @@ const TopNComponent: React.FC<Props> = ({
|
|||
(value: string) => setView(value as TimelineEventsType),
|
||||
[setView]
|
||||
);
|
||||
const { selectedPatterns } = useSourcererDataView(getSourcererScopeName({ timelineId, view }));
|
||||
const indicesSelector = useMemo(getIndicesSelector, []);
|
||||
const { all: allIndices, raw: rawIndices } = useSelector<State, IndicesSelector>(
|
||||
(state) =>
|
||||
indicesSelector(
|
||||
state,
|
||||
timelineId != null
|
||||
? defaultView === 'alert'
|
||||
? SourcererScopeName.detections
|
||||
: SourcererScopeName.timeline
|
||||
: SourcererScopeName.default
|
||||
),
|
||||
deepEqual
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setView(defaultView);
|
||||
|
@ -99,20 +111,13 @@ const TopNComponent: React.FC<Props> = ({
|
|||
() => (
|
||||
<ViewSelect
|
||||
data-test-subj="view-select"
|
||||
disabled={!isDetectionsAlertsTable(timelineId)}
|
||||
disabled={options.length === 1}
|
||||
onChange={onViewSelected}
|
||||
options={options}
|
||||
valueOfSelected={view}
|
||||
/>
|
||||
),
|
||||
[onViewSelected, options, timelineId, view]
|
||||
);
|
||||
|
||||
// alert workflow statuses (e.g. open | closed) and other alert-specific
|
||||
// filters must be ignored when viewing raw alerts
|
||||
const applicableFilters = useMemo(
|
||||
() => removeIgnoredAlertFilters({ filters, timelineId, view }),
|
||||
[filters, timelineId, view]
|
||||
[onViewSelected, options, view]
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -129,11 +134,11 @@ const TopNComponent: React.FC<Props> = ({
|
|||
<EventsByDataset
|
||||
combinedQueries={combinedQueries}
|
||||
deleteQuery={deleteQuery}
|
||||
filters={applicableFilters}
|
||||
filters={filters}
|
||||
from={from}
|
||||
headerChildren={headerChildren}
|
||||
indexPattern={indexPattern}
|
||||
indexNames={selectedPatterns}
|
||||
indexNames={view === 'raw' ? rawIndices : allIndices}
|
||||
onlyField={field}
|
||||
paddingSize={paddingSize}
|
||||
query={query}
|
||||
|
@ -148,7 +153,7 @@ const TopNComponent: React.FC<Props> = ({
|
|||
) : (
|
||||
<SignalsByCategory
|
||||
combinedQueries={combinedQueries}
|
||||
filters={applicableFilters}
|
||||
filters={filters}
|
||||
headerChildren={headerChildren}
|
||||
onlyField={field}
|
||||
paddingSize={paddingSize}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue