diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.test.tsx
index 6f83c075f0a9a..4ca2980dc74e5 100644
--- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.test.tsx
+++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.test.tsx
@@ -17,17 +17,19 @@ describe('AlertsUtilityBar', () => {
test('renders correctly', () => {
const wrapper = shallow(
);
@@ -41,17 +43,19 @@ describe('AlertsUtilityBar', () => {
const wrapper = mount(
@@ -72,22 +76,61 @@ describe('AlertsUtilityBar', () => {
).toEqual(false);
});
+ test('does not show the showOnlyThreatIndicatorAlerts checked if the showThreatMatchOnly is false', () => {
+ const wrapper = mount(
+
+
+
+ );
+ // click the filters button to popup the checkbox to make it visible
+ wrapper
+ .find('[data-test-subj="additionalFilters"] button')
+ .first()
+ .simulate('click')
+ .update();
+
+ // The check box should be false
+ expect(
+ wrapper
+ .find('[data-test-subj="showOnlyThreatIndicatorAlertsCheckbox"] input')
+ .first()
+ .prop('checked')
+ ).toEqual(false);
+ });
+
test('does show the showBuildingBlockAlerts checked if the showBuildingBlockAlerts is true', () => {
const onShowBuildingBlockAlertsChanged = jest.fn();
const wrapper = mount(
@@ -108,22 +151,61 @@ describe('AlertsUtilityBar', () => {
).toEqual(true);
});
+ test('does show the showOnlyThreatIndicatorAlerts checked if the showOnlyThreatIndicatorAlerts is true', () => {
+ const wrapper = mount(
+
+
+
+ );
+ // click the filters button to popup the checkbox to make it visible
+ wrapper
+ .find('[data-test-subj="additionalFilters"] button')
+ .first()
+ .simulate('click')
+ .update();
+
+ // The check box should be true
+ expect(
+ wrapper
+ .find('[data-test-subj="showOnlyThreatIndicatorAlertsCheckbox"] input')
+ .first()
+ .prop('checked')
+ ).toEqual(true);
+ });
+
test('calls the onShowBuildingBlockAlertsChanged when the check box is clicked', () => {
const onShowBuildingBlockAlertsChanged = jest.fn();
const wrapper = mount(
@@ -145,21 +227,62 @@ describe('AlertsUtilityBar', () => {
expect(onShowBuildingBlockAlertsChanged).toHaveBeenCalled();
});
+ test('calls the onShowOnlyThreatIndicatorAlertsChanged when the check box is clicked', () => {
+ const onShowOnlyThreatIndicatorAlertsChanged = jest.fn();
+ const wrapper = mount(
+
+
+
+ );
+ // click the filters button to popup the checkbox to make it visible
+ wrapper
+ .find('[data-test-subj="additionalFilters"] button')
+ .first()
+ .simulate('click')
+ .update();
+
+ // check the box
+ wrapper
+ .find('[data-test-subj="showOnlyThreatIndicatorAlertsCheckbox"] input')
+ .first()
+ .simulate('change', { target: { checked: true } });
+
+ // Make sure our callback is called
+ expect(onShowOnlyThreatIndicatorAlertsChanged).toHaveBeenCalled();
+ });
+
test('can update showBuildingBlockAlerts from false to true', () => {
const Proxy = (props: AlertsUtilityBarProps) => (
@@ -167,17 +290,19 @@ describe('AlertsUtilityBar', () => {
const wrapper = mount(
);
@@ -214,5 +339,79 @@ describe('AlertsUtilityBar', () => {
.prop('checked')
).toEqual(true);
});
+
+ test('can update showOnlyThreatIndicatorAlerts from false to true', () => {
+ const Proxy = (props: AlertsUtilityBarProps) => (
+
+
+
+ );
+
+ const wrapper = mount(
+
+ );
+ // click the filters button to popup the checkbox to make it visible
+ wrapper
+ .find('[data-test-subj="additionalFilters"] button')
+ .first()
+ .simulate('click')
+ .update();
+
+ // The check box should false now since we initially set the showBuildingBlockAlerts to false
+ expect(
+ wrapper
+ .find('[data-test-subj="showOnlyThreatIndicatorAlertsCheckbox"] input')
+ .first()
+ .prop('checked')
+ ).toEqual(false);
+
+ wrapper.setProps({ showOnlyThreatIndicatorAlerts: true });
+ wrapper.update();
+
+ // click the filters button to popup the checkbox to make it visible
+ wrapper
+ .find('[data-test-subj="additionalFilters"] button')
+ .first()
+ .simulate('click')
+ .update();
+
+ // The check box should be true now since we changed the showBuildingBlockAlerts from false to true
+ expect(
+ wrapper
+ .find('[data-test-subj="showOnlyThreatIndicatorAlertsCheckbox"] input')
+ .first()
+ .prop('checked')
+ ).toEqual(true);
+ });
});
});
diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.tsx
index ec2f84ba3e12d..bda8c85ddb315 100644
--- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.tsx
+++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.tsx
@@ -30,16 +30,18 @@ import { UpdateAlertsStatus } from '../types';
import { FILTER_CLOSED, FILTER_IN_PROGRESS, FILTER_OPEN } from '../alerts_filter_group';
export interface AlertsUtilityBarProps {
- hasIndexWrite: boolean;
- hasIndexMaintenance: boolean;
areEventsLoading: boolean;
clearSelection: () => void;
currentFilter: Status;
+ hasIndexMaintenance: boolean;
+ hasIndexWrite: boolean;
+ onShowBuildingBlockAlertsChanged: (showBuildingBlockAlerts: boolean) => void;
+ onShowOnlyThreatIndicatorAlertsChanged: (showOnlyThreatIndicatorAlerts: boolean) => void;
selectAll: () => void;
selectedEventIds: Readonly>;
showBuildingBlockAlerts: boolean;
- onShowBuildingBlockAlertsChanged: (showBuildingBlockAlerts: boolean) => void;
showClearSelection: boolean;
+ showOnlyThreatIndicatorAlerts: boolean;
totalCount: number;
updateAlertsStatus: UpdateAlertsStatus;
}
@@ -56,21 +58,22 @@ const BuildingBlockContainer = styled(EuiFlexItem)`
rgba(245, 167, 0, 0.05) 2px,
rgba(245, 167, 0, 0.05) 10px
);
- padding: ${({ theme }) => `${theme.eui.paddingSizes.xs}`};
`;
const AlertsUtilityBarComponent: React.FC = ({
- hasIndexWrite,
- hasIndexMaintenance,
areEventsLoading,
clearSelection,
- totalCount,
- selectedEventIds,
currentFilter,
+ hasIndexMaintenance,
+ hasIndexWrite,
+ onShowBuildingBlockAlertsChanged,
+ onShowOnlyThreatIndicatorAlertsChanged,
selectAll,
+ selectedEventIds,
showBuildingBlockAlerts,
- onShowBuildingBlockAlertsChanged,
showClearSelection,
+ showOnlyThreatIndicatorAlerts,
+ totalCount,
updateAlertsStatus,
}) => {
const [defaultNumberFormat] = useUiSetting$(DEFAULT_NUMBER_FORMAT);
@@ -144,7 +147,7 @@ const AlertsUtilityBarComponent: React.FC = ({
);
const UtilityBarAdditionalFiltersContent = (closePopover: () => void) => (
-
+
= ({
label={i18n.ADDITIONAL_FILTERS_ACTIONS_SHOW_BUILDING_BLOCK}
/>
+
+ ) => {
+ closePopover();
+ onShowOnlyThreatIndicatorAlertsChanged(e.target.checked);
+ }}
+ checked={showOnlyThreatIndicatorAlerts}
+ color="text"
+ data-test-subj="showOnlyThreatIndicatorAlertsCheckbox"
+ label={i18n.ADDITIONAL_FILTERS_ACTIONS_SHOW_ONLY_THREAT_INDICATOR_ALERTS}
+ />
+
);
@@ -240,5 +257,7 @@ export const AlertsUtilityBar = React.memo(
prevProps.selectedEventIds === nextProps.selectedEventIds &&
prevProps.totalCount === nextProps.totalCount &&
prevProps.showClearSelection === nextProps.showClearSelection &&
- prevProps.showBuildingBlockAlerts === nextProps.showBuildingBlockAlerts
+ prevProps.showBuildingBlockAlerts === nextProps.showBuildingBlockAlerts &&
+ prevProps.onShowOnlyThreatIndicatorAlertsChanged ===
+ nextProps.onShowOnlyThreatIndicatorAlertsChanged
);
diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/translations.ts b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/translations.ts
index 9307e8b1cd5f7..c52e443c50753 100644
--- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/translations.ts
+++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/translations.ts
@@ -42,6 +42,13 @@ export const ADDITIONAL_FILTERS_ACTIONS_SHOW_BUILDING_BLOCK = i18n.translate(
}
);
+export const ADDITIONAL_FILTERS_ACTIONS_SHOW_ONLY_THREAT_INDICATOR_ALERTS = i18n.translate(
+ 'xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersActions.showOnlyThreatIndicatorAlerts',
+ {
+ defaultMessage: 'Show only threat indicator alerts',
+ }
+);
+
export const CLEAR_SELECTION = i18n.translate(
'xpack.securitySolution.detectionEngine.alerts.utilityBar.clearSelectionTitle',
{
diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.test.tsx
index 26bc8f213ca46..79c2a45273c33 100644
--- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.test.tsx
+++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.test.tsx
@@ -6,7 +6,7 @@
*/
import { Filter } from '../../../../../../../src/plugins/data/common/es_query';
-import { buildAlertsRuleIdFilter } from './default_config';
+import { buildAlertsRuleIdFilter, buildThreatMatchFilter } from './default_config';
jest.mock('./actions');
@@ -34,7 +34,34 @@ describe('alerts default_config', () => {
expect(filters).toHaveLength(1);
expect(filters[0]).toEqual(expectedFilter);
});
+
+ describe('buildThreatMatchFilter', () => {
+ test('given a showOnlyThreatIndicatorAlerts=true this will return an array with a single filter', () => {
+ const filters: Filter[] = buildThreatMatchFilter(true);
+ const expectedFilter: Filter = {
+ meta: {
+ alias: null,
+ disabled: false,
+ negate: false,
+ key: 'signal.rule.threat_mapping',
+ type: 'exists',
+ value: 'exists',
+ },
+ // @ts-expect-error TODO: Rework parent typings to support ExistsFilter[]
+ exists: {
+ field: 'signal.rule.threat_mapping',
+ },
+ };
+ expect(filters).toHaveLength(1);
+ expect(filters[0]).toEqual(expectedFilter);
+ });
+ test('given a showOnlyThreatIndicatorAlerts=false this will return an empty filter', () => {
+ const filters: Filter[] = buildThreatMatchFilter(false);
+ expect(filters).toHaveLength(0);
+ });
+ });
});
+
// TODO: move these tests to ../timelines/components/timeline/body/events/event_column_view.tsx
// describe.skip('getAlertActions', () => {
// let setEventsLoading: ({ eventIds, isLoading }: SetEventsLoadingProps) => void;
diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.tsx
index 4fae2e69ac1f6..6a83039bf1ec8 100644
--- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.tsx
+++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.tsx
@@ -39,28 +39,31 @@ export const buildAlertStatusFilter = (status: Status): Filter[] => [
},
];
-export const buildAlertsRuleIdFilter = (ruleId: string): Filter[] => [
- {
- meta: {
- alias: null,
- negate: false,
- disabled: false,
- type: 'phrase',
- key: 'signal.rule.id',
- params: {
- query: ruleId,
- },
- },
- query: {
- match_phrase: {
- 'signal.rule.id': ruleId,
- },
- },
- },
-];
+export const buildAlertsRuleIdFilter = (ruleId: string | null): Filter[] =>
+ ruleId
+ ? [
+ {
+ meta: {
+ alias: null,
+ negate: false,
+ disabled: false,
+ type: 'phrase',
+ key: 'signal.rule.id',
+ params: {
+ query: ruleId,
+ },
+ },
+ query: {
+ match_phrase: {
+ 'signal.rule.id': ruleId,
+ },
+ },
+ },
+ ]
+ : [];
-export const buildShowBuildingBlockFilter = (showBuildingBlockAlerts: boolean): Filter[] => [
- ...(showBuildingBlockAlerts
+export const buildShowBuildingBlockFilter = (showBuildingBlockAlerts: boolean): Filter[] =>
+ showBuildingBlockAlerts
? []
: [
{
@@ -75,8 +78,25 @@ export const buildShowBuildingBlockFilter = (showBuildingBlockAlerts: boolean):
// @ts-expect-error TODO: Rework parent typings to support ExistsFilter[]
exists: { field: 'signal.rule.building_block_type' },
},
- ]),
-];
+ ];
+
+export const buildThreatMatchFilter = (showOnlyThreatIndicatorAlerts: boolean): Filter[] =>
+ showOnlyThreatIndicatorAlerts
+ ? [
+ {
+ meta: {
+ alias: null,
+ disabled: false,
+ negate: false,
+ key: 'signal.rule.threat_mapping',
+ type: 'exists',
+ value: 'exists',
+ },
+ // @ts-expect-error TODO: Rework parent typings to support ExistsFilter[]
+ exists: { field: 'signal.rule.threat_mapping' },
+ },
+ ]
+ : [];
export const alertsHeaders: ColumnHeaderOptions[] = [
{
diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.test.tsx
index 5c659b7554ec2..be11aecfe47dd 100644
--- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.test.tsx
+++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.test.tsx
@@ -40,6 +40,8 @@ describe('AlertsTableComponent', () => {
clearEventsDeleted={jest.fn()}
showBuildingBlockAlerts={false}
onShowBuildingBlockAlertsChanged={jest.fn()}
+ showOnlyThreatIndicatorAlerts={false}
+ onShowOnlyThreatIndicatorAlertsChanged={jest.fn()}
/>
);
diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx
index cf6db52d0cece..2890eb912b84c 100644
--- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx
+++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx
@@ -52,22 +52,23 @@ import { DefaultCellRenderer } from '../../../timelines/components/timeline/cell
import { defaultRowRenderers } from '../../../timelines/components/timeline/body/renderers';
interface OwnProps {
- timelineId: TimelineIdLiteral;
defaultFilters?: Filter[];
- hasIndexWrite: boolean;
- hasIndexMaintenance: boolean;
from: string;
+ hasIndexMaintenance: boolean;
+ hasIndexWrite: boolean;
loading: boolean;
onRuleChange?: () => void;
- showBuildingBlockAlerts: boolean;
onShowBuildingBlockAlertsChanged: (showBuildingBlockAlerts: boolean) => void;
+ onShowOnlyThreatIndicatorAlertsChanged: (showOnlyThreatIndicatorAlerts: boolean) => void;
+ showBuildingBlockAlerts: boolean;
+ showOnlyThreatIndicatorAlerts: boolean;
+ timelineId: TimelineIdLiteral;
to: string;
}
type AlertsTableComponentProps = OwnProps & PropsFromRedux;
export const AlertsTableComponent: React.FC = ({
- timelineId,
clearEventsDeleted,
clearEventsLoading,
clearSelected,
@@ -75,17 +76,20 @@ export const AlertsTableComponent: React.FC = ({
from,
globalFilters,
globalQuery,
- hasIndexWrite,
hasIndexMaintenance,
+ hasIndexWrite,
isSelectAllChecked,
loading,
loadingEventIds,
onRuleChange,
+ onShowBuildingBlockAlertsChanged,
+ onShowOnlyThreatIndicatorAlertsChanged,
selectedEventIds,
setEventsDeleted,
setEventsLoading,
showBuildingBlockAlerts,
- onShowBuildingBlockAlertsChanged,
+ showOnlyThreatIndicatorAlerts,
+ timelineId,
to,
}) => {
const [showClearSelectionAction, setShowClearSelectionAction] = useState(false);
@@ -264,30 +268,34 @@ export const AlertsTableComponent: React.FC = ({
0}
clearSelection={clearSelectionCallback}
- hasIndexWrite={hasIndexWrite}
- hasIndexMaintenance={hasIndexMaintenance}
currentFilter={filterGroup}
+ hasIndexMaintenance={hasIndexMaintenance}
+ hasIndexWrite={hasIndexWrite}
+ onShowBuildingBlockAlertsChanged={onShowBuildingBlockAlertsChanged}
+ onShowOnlyThreatIndicatorAlertsChanged={onShowOnlyThreatIndicatorAlertsChanged}
selectAll={selectAllOnAllPagesCallback}
selectedEventIds={selectedEventIds}
showBuildingBlockAlerts={showBuildingBlockAlerts}
- onShowBuildingBlockAlertsChanged={onShowBuildingBlockAlertsChanged}
showClearSelection={showClearSelectionAction}
+ showOnlyThreatIndicatorAlerts={showOnlyThreatIndicatorAlerts}
totalCount={totalCount}
updateAlertsStatus={updateAlertsStatusCallback.bind(null, refetchQuery)}
/>
);
},
[
- hasIndexWrite,
- hasIndexMaintenance,
clearSelectionCallback,
filterGroup,
- showBuildingBlockAlerts,
- onShowBuildingBlockAlertsChanged,
+ hasIndexMaintenance,
+ hasIndexWrite,
loadingEventIds.length,
+ onShowBuildingBlockAlertsChanged,
+ onShowOnlyThreatIndicatorAlertsChanged,
selectAllOnAllPagesCallback,
selectedEventIds,
+ showBuildingBlockAlerts,
showClearSelectionAction,
+ showOnlyThreatIndicatorAlerts,
updateAlertsStatusCallback,
]
);
diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx
index 8d2f07e19b36a..02e18d09710d7 100644
--- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx
+++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx
@@ -50,7 +50,10 @@ import {
} from '../../../timelines/components/timeline/helpers';
import { timelineSelectors } from '../../../timelines/store/timeline';
import { timelineDefaults } from '../../../timelines/store/timeline/defaults';
-import { buildShowBuildingBlockFilter } from '../../components/alerts_table/default_config';
+import {
+ buildShowBuildingBlockFilter,
+ buildThreatMatchFilter,
+} from '../../components/alerts_table/default_config';
import { useSourcererScope } from '../../../common/containers/sourcerer';
import { SourcererScopeName } from '../../../common/store/sourcerer/model';
import { NeedAdminForUpdateRulesCallOut } from '../../components/callouts/need_admin_for_update_callout';
@@ -100,6 +103,7 @@ const DetectionEnginePageComponent = () => {
const [lastAlerts] = useAlertInfo({});
const { formatUrl } = useFormatUrl(SecurityPageName.detections);
const [showBuildingBlockAlerts, setShowBuildingBlockAlerts] = useState(false);
+ const [showOnlyThreatIndicatorAlerts, setShowOnlyThreatIndicatorAlerts] = useState(false);
const loading = userInfoLoading || listsConfigLoading;
const updateDateRangeCallback = useCallback(
@@ -128,14 +132,21 @@ const DetectionEnginePageComponent = () => {
);
const alertsHistogramDefaultFilters = useMemo(
- () => [...filters, ...buildShowBuildingBlockFilter(showBuildingBlockAlerts)],
- [filters, showBuildingBlockAlerts]
+ () => [
+ ...filters,
+ ...buildShowBuildingBlockFilter(showBuildingBlockAlerts),
+ ...buildThreatMatchFilter(showOnlyThreatIndicatorAlerts),
+ ],
+ [filters, showBuildingBlockAlerts, showOnlyThreatIndicatorAlerts]
);
// AlertsTable manages global filters itself, so not including `filters`
const alertsTableDefaultFilters = useMemo(
- () => buildShowBuildingBlockFilter(showBuildingBlockAlerts),
- [showBuildingBlockAlerts]
+ () => [
+ ...buildShowBuildingBlockFilter(showBuildingBlockAlerts),
+ ...buildThreatMatchFilter(showOnlyThreatIndicatorAlerts),
+ ],
+ [showBuildingBlockAlerts, showOnlyThreatIndicatorAlerts]
);
const onShowBuildingBlockAlertsChangedCallback = useCallback(
@@ -145,6 +156,13 @@ const DetectionEnginePageComponent = () => {
[setShowBuildingBlockAlerts]
);
+ const onShowOnlyThreatIndicatorAlertsCallback = useCallback(
+ (newShowOnlyThreatIndicatorAlerts: boolean) => {
+ setShowOnlyThreatIndicatorAlerts(newShowOnlyThreatIndicatorAlerts);
+ },
+ [setShowOnlyThreatIndicatorAlerts]
+ );
+
const { indicesExist, indexPattern } = useSourcererScope(SourcererScopeName.detections);
const onSkipFocusBeforeEventsTable = useCallback(() => {
@@ -250,6 +268,8 @@ const DetectionEnginePageComponent = () => {
defaultFilters={alertsTableDefaultFilters}
showBuildingBlockAlerts={showBuildingBlockAlerts}
onShowBuildingBlockAlertsChanged={onShowBuildingBlockAlertsChangedCallback}
+ showOnlyThreatIndicatorAlerts={showOnlyThreatIndicatorAlerts}
+ onShowOnlyThreatIndicatorAlertsChanged={onShowOnlyThreatIndicatorAlertsCallback}
to={to}
/>
diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx
index dddf8ac1bb839..a8d3742bfd600 100644
--- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx
+++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx
@@ -59,6 +59,7 @@ import { StepScheduleRule } from '../../../../components/rules/step_schedule_rul
import {
buildAlertsRuleIdFilter,
buildShowBuildingBlockFilter,
+ buildThreatMatchFilter,
} from '../../../../components/alerts_table/default_config';
import { ReadOnlyAlertsCallOut } from '../../../../components/callouts/read_only_alerts_callout';
import { ReadOnlyRulesCallOut } from '../../../../components/callouts/read_only_rules_callout';
@@ -208,6 +209,7 @@ const RuleDetailsPageComponent = () => {
};
const [lastAlerts] = useAlertInfo({ ruleId });
const [showBuildingBlockAlerts, setShowBuildingBlockAlerts] = useState(false);
+ const [showOnlyThreatIndicatorAlerts, setShowOnlyThreatIndicatorAlerts] = useState(false);
const mlCapabilities = useMlCapabilities();
const history = useHistory();
const { formatUrl } = useFormatUrl(SecurityPageName.detections);
@@ -286,10 +288,11 @@ const RuleDetailsPageComponent = () => {
const alertDefaultFilters = useMemo(
() => [
- ...(ruleId != null ? buildAlertsRuleIdFilter(ruleId) : []),
+ ...buildAlertsRuleIdFilter(ruleId),
...buildShowBuildingBlockFilter(showBuildingBlockAlerts),
+ ...buildThreatMatchFilter(showOnlyThreatIndicatorAlerts),
],
- [ruleId, showBuildingBlockAlerts]
+ [ruleId, showBuildingBlockAlerts, showOnlyThreatIndicatorAlerts]
);
const alertMergedFilters = useMemo(() => [...alertDefaultFilters, ...filters], [
@@ -446,6 +449,13 @@ const RuleDetailsPageComponent = () => {
[setShowBuildingBlockAlerts]
);
+ const onShowOnlyThreatIndicatorAlertsCallback = useCallback(
+ (newShowOnlyThreatIndicatorAlerts: boolean) => {
+ setShowOnlyThreatIndicatorAlerts(newShowOnlyThreatIndicatorAlerts);
+ },
+ [setShowOnlyThreatIndicatorAlerts]
+ );
+
const { indicesExist, indexPattern } = useSourcererScope(SourcererScopeName.detections);
const exceptionLists = useMemo((): {
@@ -670,7 +680,9 @@ const RuleDetailsPageComponent = () => {
from={from}
loading={loading}
showBuildingBlockAlerts={showBuildingBlockAlerts}
+ showOnlyThreatIndicatorAlerts={showOnlyThreatIndicatorAlerts}
onShowBuildingBlockAlertsChanged={onShowBuildingBlockAlertsChangedCallback}
+ onShowOnlyThreatIndicatorAlertsChanged={onShowOnlyThreatIndicatorAlertsCallback}
onRuleChange={refreshRule}
to={to}
/>