diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx
index 833688ae57993..6f77d15913d07 100644
--- a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx
@@ -50,6 +50,10 @@ const utilityBar = (refetch: inputsModel.Refetch, totalCount: number) => (
);
+const exceptionsModal = (refetch: inputsModel.Refetch) => (
+
+);
+
const eventsViewerDefaultProps = {
browserFields: {},
columns: [],
@@ -460,4 +464,42 @@ describe('EventsViewer', () => {
});
});
});
+
+ describe('exceptions modal', () => {
+ test('it renders exception modal if "exceptionsModal" callback exists', async () => {
+ const wrapper = mount(
+
+
+
+
+
+ );
+
+ await waitFor(() => {
+ wrapper.update();
+
+ expect(wrapper.find(`[data-test-subj="mock-exceptions-modal"]`).exists()).toBeTruthy();
+ });
+ });
+
+ test('it does not render exception modal if "exceptionModal" callback does not exist', async () => {
+ const wrapper = mount(
+
+
+
+
+
+ );
+
+ await waitFor(() => {
+ wrapper.update();
+
+ expect(wrapper.find(`[data-test-subj="mock-exceptions-modal"]`).exists()).toBeFalsy();
+ });
+ });
+ });
});
diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx
index 436386077e725..ebda64efabf65 100644
--- a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx
@@ -109,6 +109,7 @@ interface Props {
utilityBar?: (refetch: inputsModel.Refetch, totalCount: number) => React.ReactNode;
// If truthy, the graph viewer (Resolver) is showing
graphEventId: string | undefined;
+ exceptionsModal?: (refetch: inputsModel.Refetch) => React.ReactNode;
}
const EventsViewerComponent: React.FC = ({
@@ -134,6 +135,7 @@ const EventsViewerComponent: React.FC = ({
toggleColumn,
utilityBar,
graphEventId,
+ exceptionsModal,
}) => {
const { globalFullScreen } = useFullScreen();
const columnsHeader = isEmpty(columns) ? defaultHeaders : columns;
@@ -259,6 +261,7 @@ const EventsViewerComponent: React.FC = ({
)}
+ {exceptionsModal && exceptionsModal(refetch)}
{utilityBar && !resolverIsShowing(graphEventId) && (
{utilityBar?.(refetch, totalCountMinusDeleted)}
)}
@@ -335,5 +338,6 @@ export const EventsViewer = React.memo(
prevProps.start === nextProps.start &&
prevProps.sort === nextProps.sort &&
prevProps.utilityBar === nextProps.utilityBar &&
- prevProps.graphEventId === nextProps.graphEventId
+ prevProps.graphEventId === nextProps.graphEventId &&
+ prevProps.exceptionsModal === nextProps.exceptionsModal
);
diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx
index 1563eab6039a6..ec56a3a1bd8d3 100644
--- a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx
@@ -43,6 +43,7 @@ export interface OwnProps {
headerFilterGroup?: React.ReactNode;
pageFilters?: Filter[];
utilityBar?: (refetch: inputsModel.Refetch, totalCount: number) => React.ReactNode;
+ exceptionsModal?: (refetch: inputsModel.Refetch) => React.ReactNode;
}
type Props = OwnProps & PropsFromRedux;
@@ -74,6 +75,7 @@ const StatefulEventsViewerComponent: React.FC = ({
utilityBar,
// If truthy, the graph viewer (Resolver) is showing
graphEventId,
+ exceptionsModal,
}) => {
const [
{ docValueFields, browserFields, indexPatterns, isLoading: isLoadingIndexPattern },
@@ -156,6 +158,7 @@ const StatefulEventsViewerComponent: React.FC = ({
toggleColumn={toggleColumn}
utilityBar={utilityBar}
graphEventId={graphEventId}
+ exceptionsModal={exceptionsModal}
/>
@@ -241,6 +244,7 @@ export const StatefulEventsViewer = connector(
prevProps.showCheckboxes === nextProps.showCheckboxes &&
prevProps.start === nextProps.start &&
prevProps.utilityBar === nextProps.utilityBar &&
- prevProps.graphEventId === nextProps.graphEventId
+ prevProps.graphEventId === nextProps.graphEventId &&
+ prevProps.exceptionsModal === nextProps.exceptionsModal
)
);
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 07e69d850f173..854565ace9b4b 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
@@ -228,7 +228,7 @@ export const AlertsTableComponent: React.FC = ({
exceptionListType,
alertData,
}: AddExceptionModalBaseProps) => {
- if (alertData !== null && alertData !== undefined) {
+ if (alertData != null) {
setShouldShowAddExceptionModal(true);
setAddExceptionModalState({
ruleName,
@@ -441,9 +441,43 @@ export const AlertsTableComponent: React.FC = ({
closeAddExceptionModal();
}, [closeAddExceptionModal]);
- const onAddExceptionConfirm = useCallback(() => closeAddExceptionModal(), [
- closeAddExceptionModal,
- ]);
+ const onAddExceptionConfirm = useCallback(
+ (refetch: inputsModel.Refetch) => (): void => {
+ refetch();
+ closeAddExceptionModal();
+ },
+ [closeAddExceptionModal]
+ );
+
+ // Callback for creating the AddExceptionModal and allowing it
+ // access to the refetchQuery to update the page
+ const exceptionModalCallback = useCallback(
+ (refetchQuery: inputsModel.Refetch) => {
+ if (shouldShowAddExceptionModal) {
+ return (
+
+ );
+ } else {
+ return <>>;
+ }
+ },
+ [
+ addExceptionModalState,
+ filterGroup,
+ onAddExceptionCancel,
+ onAddExceptionConfirm,
+ shouldShowAddExceptionModal,
+ ]
+ );
if (loading || indexPatternsLoading || isEmpty(signalsIndex)) {
return (
@@ -465,19 +499,8 @@ export const AlertsTableComponent: React.FC = ({
id={timelineId}
start={from}
utilityBar={utilityBarCallback}
+ exceptionsModal={exceptionModalCallback}
/>
- {shouldShowAddExceptionModal === true && addExceptionModalState.alertData !== null && (
-
- )}
>
);
};