Skip to content

Commit

Permalink
[Security Solution] Exceptions flyout refreshes when it regains focus…
Browse files Browse the repository at this point in the history
…, causing configured fields to get cleared (elastic#166550) (elastic#172666)

## Summary

Addresses elastic#166550

These changes fix the issue where user can experience data loss while
adding rule exceptions.

The main issue is that we keep conditions state inside the child
component `ExceptionsConditions` which is rendered conditionally based
on `isLoading` flag. This flag changes when `useQuery` data gets stale
and refetching is triggered. In this case we would remove
`ExceptionsConditions` component while loading data and re-create it
after. Since conditions state stored inside `ExceptionsConditions` we
will lose it.

This is a quick fix to make sure our users are not frustrated. The state
refactoring will come separately in the next release when we are going
to address the main issue
elastic/security-team#8197

To reproduce:
1. Open "add rule exception" flyout
2. Add exception conditions
3. Wait for 5 minutes (to avoid waiting this long you can use [this
approach](elastic#166550 (comment)))
4. Remove focus from the page (by switching to another app or navigating
to a different tab in a browser)
5. Focus on the page again

When you are back to the page all exception conditions should still be
there.

---------

Co-authored-by: Vitalii Dmyterko <[email protected]>
  • Loading branch information
e40pud and vitaliidm authored Dec 12, 2023
1 parent 778edc2 commit a0631cf
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -500,106 +500,112 @@ export const AddExceptionFlyout = memo(function AddExceptionFlyout({
</EuiTitle>
<EuiSpacer size="m" />
</FlyoutHeader>

<FlyoutBodySection className="builder-section">
<EuiSkeletonText data-test-subj="loadingAddExceptionFlyout" lines={4} isLoading={isLoading}>
{errorSubmitting != null && (
<>
<EuiCallOut
data-test-subj="addExceptionErrorCallOut"
title={i18n.SUBMIT_ERROR_TITLE}
{
// TODO: This is a quick fix to make sure that we do not lose conditions state on refetching index patterns via `useFetchIndexPatterns`
// which happens due to data being stale after 5 minutes (in `useFetchJobsSummaryQuery`, `useFetchModulesQuery` and `useFetchRecognizerQuery`)
// which makes useQuery triggering data refetch.
// To fix the issue properly, we will need to do refactoring and store conditions state in the parent component (`AddExceptionFlyout`)
// instead of keeping it in `ExceptionsConditions` which can be removed and recreated due to fetching steps described above.
// Refactoring ticket: https://github.com/elastic/security-team/issues/8197
}
{isLoading && <EuiSkeletonText data-test-subj="loadingAddExceptionFlyout" lines={4} />}
{errorSubmitting != null && (
<>
<EuiCallOut
data-test-subj="addExceptionErrorCallOut"
title={i18n.SUBMIT_ERROR_TITLE}
color="danger"
iconType="warning"
>
<EuiText>{i18n.SUBMIT_ERROR_DISMISS_MESSAGE}</EuiText>
<EuiSpacer size="s" />
<EuiButton
data-test-subj="addExceptionErrorDismissButton"
color="danger"
iconType="warning"
onClick={handleDismissError}
>
<EuiText>{i18n.SUBMIT_ERROR_DISMISS_MESSAGE}</EuiText>
<EuiSpacer size="s" />
<EuiButton
data-test-subj="addExceptionErrorDismissButton"
color="danger"
onClick={handleDismissError}
>
{i18n.SUBMIT_ERROR_DISMISS_BUTTON}
</EuiButton>
</EuiCallOut>
<EuiSpacer size="s" />
</>
)}
<ExceptionsFlyoutMeta
exceptionItemName={exceptionItemName}
onChange={setExceptionItemMeta}
/>
<EuiHorizontalRule />
<ExceptionsConditions
exceptionItemName={exceptionItemName}
allowLargeValueLists={allowLargeValueLists}
exceptionListItems={initialItems}
exceptionListType={listType}
indexPatterns={indexPatterns}
rules={rules}
selectedOs={selectedOs}
showOsTypeOptions={listType === ExceptionListTypeEnum.ENDPOINT && !hasAlertData}
isEdit={false}
onOsChange={setSelectedOs}
onExceptionItemAdd={setExceptionItemsToAdd}
onSetErrorExists={setConditionsValidationError}
getExtendedFields={getExtendedFields}
/>

{listType !== ExceptionListTypeEnum.ENDPOINT && !sharedListToAddTo?.length && (
<>
<EuiHorizontalRule />
<ExceptionsAddToRulesOrLists
rules={rules}
isBulkAction={isBulkAction}
selectedRadioOption={addExceptionToRadioSelection}
onListSelectionChange={setListsToAddExceptionTo}
onRuleSelectionChange={setSelectedRules}
onRadioChange={setRadioOption}
/>
</>
)}
<EuiHorizontalRule />
<ExceptionItemComments
accordionTitle={
<SectionHeader size="xs">
<h3>{i18n.COMMENTS_SECTION_TITLE(newComment ? 1 : 0)}</h3>
</SectionHeader>
}
initialIsOpen={!!newComment}
newCommentValue={newComment}
newCommentOnChange={setComment}
setCommentError={setCommentError}
/>
{listType !== ExceptionListTypeEnum.ENDPOINT && (
<>
<EuiHorizontalRule />
<ExceptionsExpireTime
expireTime={expireTime}
setExpireTime={setExpireTime}
setExpireError={setExpireError}
/>
</>
)}
{showAlertCloseOptions && (
<>
<EuiHorizontalRule />
<ExceptionItemsFlyoutAlertsActions
exceptionListType={listType}
shouldCloseSingleAlert={closeSingleAlert}
shouldBulkCloseAlert={bulkCloseAlerts}
disableBulkClose={disableBulkClose}
exceptionListItems={exceptionItems}
alertData={alertData}
alertStatus={alertStatus}
isAlertDataLoading={isAlertDataLoading ?? false}
onDisableBulkClose={setDisableBulkCloseAlerts}
onUpdateBulkCloseIndex={setBulkCloseIndex}
onBulkCloseCheckboxChange={setBulkCloseAlerts}
onSingleAlertCloseCheckboxChange={setCloseSingleAlert}
/>
</>
)}
</EuiSkeletonText>
{i18n.SUBMIT_ERROR_DISMISS_BUTTON}
</EuiButton>
</EuiCallOut>
<EuiSpacer size="s" />
</>
)}
<ExceptionsFlyoutMeta
exceptionItemName={exceptionItemName}
onChange={setExceptionItemMeta}
/>
<EuiHorizontalRule />
<ExceptionsConditions
exceptionItemName={exceptionItemName}
allowLargeValueLists={allowLargeValueLists}
exceptionListItems={initialItems}
exceptionListType={listType}
indexPatterns={indexPatterns}
rules={rules}
selectedOs={selectedOs}
showOsTypeOptions={listType === ExceptionListTypeEnum.ENDPOINT && !hasAlertData}
isEdit={false}
onOsChange={setSelectedOs}
onExceptionItemAdd={setExceptionItemsToAdd}
onSetErrorExists={setConditionsValidationError}
getExtendedFields={getExtendedFields}
/>

{listType !== ExceptionListTypeEnum.ENDPOINT && !sharedListToAddTo?.length && (
<>
<EuiHorizontalRule />
<ExceptionsAddToRulesOrLists
rules={rules}
isBulkAction={isBulkAction}
selectedRadioOption={addExceptionToRadioSelection}
onListSelectionChange={setListsToAddExceptionTo}
onRuleSelectionChange={setSelectedRules}
onRadioChange={setRadioOption}
/>
</>
)}
<EuiHorizontalRule />
<ExceptionItemComments
accordionTitle={
<SectionHeader size="xs">
<h3>{i18n.COMMENTS_SECTION_TITLE(newComment ? 1 : 0)}</h3>
</SectionHeader>
}
initialIsOpen={!!newComment}
newCommentValue={newComment}
newCommentOnChange={setComment}
setCommentError={setCommentError}
/>
{listType !== ExceptionListTypeEnum.ENDPOINT && (
<>
<EuiHorizontalRule />
<ExceptionsExpireTime
expireTime={expireTime}
setExpireTime={setExpireTime}
setExpireError={setExpireError}
/>
</>
)}
{showAlertCloseOptions && (
<>
<EuiHorizontalRule />
<ExceptionItemsFlyoutAlertsActions
exceptionListType={listType}
shouldCloseSingleAlert={closeSingleAlert}
shouldBulkCloseAlert={bulkCloseAlerts}
disableBulkClose={disableBulkClose}
exceptionListItems={exceptionItems}
alertData={alertData}
alertStatus={alertStatus}
isAlertDataLoading={isAlertDataLoading ?? false}
onDisableBulkClose={setDisableBulkCloseAlerts}
onUpdateBulkCloseIndex={setBulkCloseIndex}
onBulkCloseCheckboxChange={setBulkCloseAlerts}
onSingleAlertCloseCheckboxChange={setCloseSingleAlert}
/>
</>
)}
</FlyoutBodySection>
<EuiFlyoutFooter>
<FlyoutFooterGroup justifyContent="spaceBetween">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -370,8 +370,8 @@ const EditExceptionFlyoutComponent: React.FC<EditExceptionFlyoutProps> = ({
</EuiTitle>
<EuiSpacer size="m" />
</FlyoutHeader>
{isLoading && <EuiSkeletonText data-test-subj="loadingEditExceptionFlyout" lines={4} />}
<FlyoutBodySection className="builder-section">
{isLoading && <EuiSkeletonText data-test-subj="loadingEditExceptionFlyout" lines={4} />}
<ExceptionsFlyoutMeta
exceptionItemName={exceptionItemName}
onChange={setExceptionItemMeta}
Expand Down

0 comments on commit a0631cf

Please sign in to comment.