[Security Solution][Exceptions] - Fix bug of alerts not updating after closure from exceptions modal (#76145)
## Summary Fixes bug found in 7.9. **Current behavior:** - Go to alerts page - Select action to add exception item - Select checkbox to close all alerts matching exception - Click `Add exception` - Note that the alerts table does not update until after you refresh or toggle between `Closed` and `Open` **New behavior:** - Go to alerts page - Select action to add exception item - Select checkbox to close all alerts matching exception - Click `Add exception` - Note that the alerts table updates
This commit is contained in:
parent
64311d306f
commit
69599e0b49
|
@ -50,6 +50,10 @@ const utilityBar = (refetch: inputsModel.Refetch, totalCount: number) => (
|
||||||
<div data-test-subj="mock-utility-bar" />
|
<div data-test-subj="mock-utility-bar" />
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const exceptionsModal = (refetch: inputsModel.Refetch) => (
|
||||||
|
<div data-test-subj="mock-exceptions-modal" />
|
||||||
|
);
|
||||||
|
|
||||||
const eventsViewerDefaultProps = {
|
const eventsViewerDefaultProps = {
|
||||||
browserFields: {},
|
browserFields: {},
|
||||||
columns: [],
|
columns: [],
|
||||||
|
@ -460,4 +464,42 @@ describe('EventsViewer', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('exceptions modal', () => {
|
||||||
|
test('it renders exception modal if "exceptionsModal" callback exists', async () => {
|
||||||
|
const wrapper = mount(
|
||||||
|
<TestProviders>
|
||||||
|
<MockedProvider mocks={mockEventViewerResponse} addTypename={false}>
|
||||||
|
<EventsViewer
|
||||||
|
{...eventsViewerDefaultProps}
|
||||||
|
exceptionsModal={exceptionsModal}
|
||||||
|
graphEventId=""
|
||||||
|
/>
|
||||||
|
</MockedProvider>
|
||||||
|
</TestProviders>
|
||||||
|
);
|
||||||
|
|
||||||
|
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(
|
||||||
|
<TestProviders>
|
||||||
|
<MockedProvider mocks={mockEventViewerResponse} addTypename={false}>
|
||||||
|
<EventsViewer {...eventsViewerDefaultProps} graphEventId="" />
|
||||||
|
</MockedProvider>
|
||||||
|
</TestProviders>
|
||||||
|
);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
wrapper.update();
|
||||||
|
|
||||||
|
expect(wrapper.find(`[data-test-subj="mock-exceptions-modal"]`).exists()).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -109,6 +109,7 @@ interface Props {
|
||||||
utilityBar?: (refetch: inputsModel.Refetch, totalCount: number) => React.ReactNode;
|
utilityBar?: (refetch: inputsModel.Refetch, totalCount: number) => React.ReactNode;
|
||||||
// If truthy, the graph viewer (Resolver) is showing
|
// If truthy, the graph viewer (Resolver) is showing
|
||||||
graphEventId: string | undefined;
|
graphEventId: string | undefined;
|
||||||
|
exceptionsModal?: (refetch: inputsModel.Refetch) => React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
const EventsViewerComponent: React.FC<Props> = ({
|
const EventsViewerComponent: React.FC<Props> = ({
|
||||||
|
@ -134,6 +135,7 @@ const EventsViewerComponent: React.FC<Props> = ({
|
||||||
toggleColumn,
|
toggleColumn,
|
||||||
utilityBar,
|
utilityBar,
|
||||||
graphEventId,
|
graphEventId,
|
||||||
|
exceptionsModal,
|
||||||
}) => {
|
}) => {
|
||||||
const { globalFullScreen } = useFullScreen();
|
const { globalFullScreen } = useFullScreen();
|
||||||
const columnsHeader = isEmpty(columns) ? defaultHeaders : columns;
|
const columnsHeader = isEmpty(columns) ? defaultHeaders : columns;
|
||||||
|
@ -259,6 +261,7 @@ const EventsViewerComponent: React.FC<Props> = ({
|
||||||
</HeaderFilterGroupWrapper>
|
</HeaderFilterGroupWrapper>
|
||||||
)}
|
)}
|
||||||
</HeaderSection>
|
</HeaderSection>
|
||||||
|
{exceptionsModal && exceptionsModal(refetch)}
|
||||||
{utilityBar && !resolverIsShowing(graphEventId) && (
|
{utilityBar && !resolverIsShowing(graphEventId) && (
|
||||||
<UtilityBar>{utilityBar?.(refetch, totalCountMinusDeleted)}</UtilityBar>
|
<UtilityBar>{utilityBar?.(refetch, totalCountMinusDeleted)}</UtilityBar>
|
||||||
)}
|
)}
|
||||||
|
@ -335,5 +338,6 @@ export const EventsViewer = React.memo(
|
||||||
prevProps.start === nextProps.start &&
|
prevProps.start === nextProps.start &&
|
||||||
prevProps.sort === nextProps.sort &&
|
prevProps.sort === nextProps.sort &&
|
||||||
prevProps.utilityBar === nextProps.utilityBar &&
|
prevProps.utilityBar === nextProps.utilityBar &&
|
||||||
prevProps.graphEventId === nextProps.graphEventId
|
prevProps.graphEventId === nextProps.graphEventId &&
|
||||||
|
prevProps.exceptionsModal === nextProps.exceptionsModal
|
||||||
);
|
);
|
||||||
|
|
|
@ -43,6 +43,7 @@ export interface OwnProps {
|
||||||
headerFilterGroup?: React.ReactNode;
|
headerFilterGroup?: React.ReactNode;
|
||||||
pageFilters?: Filter[];
|
pageFilters?: Filter[];
|
||||||
utilityBar?: (refetch: inputsModel.Refetch, totalCount: number) => React.ReactNode;
|
utilityBar?: (refetch: inputsModel.Refetch, totalCount: number) => React.ReactNode;
|
||||||
|
exceptionsModal?: (refetch: inputsModel.Refetch) => React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
type Props = OwnProps & PropsFromRedux;
|
type Props = OwnProps & PropsFromRedux;
|
||||||
|
@ -74,6 +75,7 @@ const StatefulEventsViewerComponent: React.FC<Props> = ({
|
||||||
utilityBar,
|
utilityBar,
|
||||||
// If truthy, the graph viewer (Resolver) is showing
|
// If truthy, the graph viewer (Resolver) is showing
|
||||||
graphEventId,
|
graphEventId,
|
||||||
|
exceptionsModal,
|
||||||
}) => {
|
}) => {
|
||||||
const [
|
const [
|
||||||
{ docValueFields, browserFields, indexPatterns, isLoading: isLoadingIndexPattern },
|
{ docValueFields, browserFields, indexPatterns, isLoading: isLoadingIndexPattern },
|
||||||
|
@ -156,6 +158,7 @@ const StatefulEventsViewerComponent: React.FC<Props> = ({
|
||||||
toggleColumn={toggleColumn}
|
toggleColumn={toggleColumn}
|
||||||
utilityBar={utilityBar}
|
utilityBar={utilityBar}
|
||||||
graphEventId={graphEventId}
|
graphEventId={graphEventId}
|
||||||
|
exceptionsModal={exceptionsModal}
|
||||||
/>
|
/>
|
||||||
</InspectButtonContainer>
|
</InspectButtonContainer>
|
||||||
</FullScreenContainer>
|
</FullScreenContainer>
|
||||||
|
@ -220,6 +223,7 @@ type PropsFromRedux = ConnectedProps<typeof connector>;
|
||||||
export const StatefulEventsViewer = connector(
|
export const StatefulEventsViewer = connector(
|
||||||
React.memo(
|
React.memo(
|
||||||
StatefulEventsViewerComponent,
|
StatefulEventsViewerComponent,
|
||||||
|
// eslint-disable-next-line complexity
|
||||||
(prevProps, nextProps) =>
|
(prevProps, nextProps) =>
|
||||||
prevProps.id === nextProps.id &&
|
prevProps.id === nextProps.id &&
|
||||||
deepEqual(prevProps.columns, nextProps.columns) &&
|
deepEqual(prevProps.columns, nextProps.columns) &&
|
||||||
|
@ -240,6 +244,7 @@ export const StatefulEventsViewer = connector(
|
||||||
prevProps.showCheckboxes === nextProps.showCheckboxes &&
|
prevProps.showCheckboxes === nextProps.showCheckboxes &&
|
||||||
prevProps.start === nextProps.start &&
|
prevProps.start === nextProps.start &&
|
||||||
prevProps.utilityBar === nextProps.utilityBar &&
|
prevProps.utilityBar === nextProps.utilityBar &&
|
||||||
prevProps.graphEventId === nextProps.graphEventId
|
prevProps.graphEventId === nextProps.graphEventId &&
|
||||||
|
prevProps.exceptionsModal === nextProps.exceptionsModal
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -228,7 +228,7 @@ export const AlertsTableComponent: React.FC<AlertsTableComponentProps> = ({
|
||||||
exceptionListType,
|
exceptionListType,
|
||||||
alertData,
|
alertData,
|
||||||
}: AddExceptionModalBaseProps) => {
|
}: AddExceptionModalBaseProps) => {
|
||||||
if (alertData !== null && alertData !== undefined) {
|
if (alertData != null) {
|
||||||
setShouldShowAddExceptionModal(true);
|
setShouldShowAddExceptionModal(true);
|
||||||
setAddExceptionModalState({
|
setAddExceptionModalState({
|
||||||
ruleName,
|
ruleName,
|
||||||
|
@ -441,9 +441,43 @@ export const AlertsTableComponent: React.FC<AlertsTableComponentProps> = ({
|
||||||
closeAddExceptionModal();
|
closeAddExceptionModal();
|
||||||
}, [closeAddExceptionModal]);
|
}, [closeAddExceptionModal]);
|
||||||
|
|
||||||
const onAddExceptionConfirm = useCallback(() => closeAddExceptionModal(), [
|
const onAddExceptionConfirm = useCallback(
|
||||||
closeAddExceptionModal,
|
(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 (
|
||||||
|
<AddExceptionModal
|
||||||
|
ruleName={addExceptionModalState.ruleName}
|
||||||
|
ruleId={addExceptionModalState.ruleId}
|
||||||
|
ruleIndices={addExceptionModalState.ruleIndices}
|
||||||
|
exceptionListType={addExceptionModalState.exceptionListType}
|
||||||
|
alertData={addExceptionModalState.alertData}
|
||||||
|
onCancel={onAddExceptionCancel}
|
||||||
|
onConfirm={onAddExceptionConfirm(refetchQuery)}
|
||||||
|
alertStatus={filterGroup}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return <></>;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[
|
||||||
|
addExceptionModalState,
|
||||||
|
filterGroup,
|
||||||
|
onAddExceptionCancel,
|
||||||
|
onAddExceptionConfirm,
|
||||||
|
shouldShowAddExceptionModal,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
if (loading || indexPatternsLoading || isEmpty(signalsIndex)) {
|
if (loading || indexPatternsLoading || isEmpty(signalsIndex)) {
|
||||||
return (
|
return (
|
||||||
|
@ -465,19 +499,8 @@ export const AlertsTableComponent: React.FC<AlertsTableComponentProps> = ({
|
||||||
id={timelineId}
|
id={timelineId}
|
||||||
start={from}
|
start={from}
|
||||||
utilityBar={utilityBarCallback}
|
utilityBar={utilityBarCallback}
|
||||||
|
exceptionsModal={exceptionModalCallback}
|
||||||
/>
|
/>
|
||||||
{shouldShowAddExceptionModal === true && addExceptionModalState.alertData !== null && (
|
|
||||||
<AddExceptionModal
|
|
||||||
ruleName={addExceptionModalState.ruleName}
|
|
||||||
ruleId={addExceptionModalState.ruleId}
|
|
||||||
ruleIndices={addExceptionModalState.ruleIndices}
|
|
||||||
exceptionListType={addExceptionModalState.exceptionListType}
|
|
||||||
alertData={addExceptionModalState.alertData}
|
|
||||||
onCancel={onAddExceptionCancel}
|
|
||||||
onConfirm={onAddExceptionConfirm}
|
|
||||||
alertStatus={filterGroup}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue