Skip to content

Commit

Permalink
[Security Solution] Fix hanging rule creation page (elastic#201629)
Browse files Browse the repository at this point in the history
**Closes:** elastic#201606

## Summary

This PR fixes a bug introduced in elastic@06986e4 leading to hanging rule creation page after manipulation with EQL rule's query and alert suppression fields.

## Details

elastic@06986e4 add `usePersistentAlertSuppressionState()` hook to persist alert suppression state upon rule type change. It didn't take into account rule type change is a tricky process leading to multiple re-renders. In that case it easily can lead to a hanging page due to repeating updating form values leading to re-rendering.

The fix checks for the current and previous rule types to reset alert suppression form data only once upon rule type change.
  • Loading branch information
maximpn authored Nov 26, 2024
1 parent 04c3289 commit 9ddb459
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,9 @@ export const AlertSuppressionEdit = memo(function AlertSuppressionEdit({
</>
);

return disabled && disabledText ? (
<EuiToolTip position="right" content={disabledText}>
return (
<EuiToolTip position="right" content={disabled && disabledText}>
{content}
</EuiToolTip>
) : (
content
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
* 2.0.
*/

import React, { useMemo } from 'react';
import React, { useEffect, useMemo, useRef } from 'react';
import type { DataViewFieldBase } from '@kbn/es-query';
import type { EuiComboBox } from '@elastic/eui';
import { ComboBoxField } from '@kbn/es-ui-shared-plugin/static/forms/components';
import type { FieldHook } from '../../../../shared_imports';
import { FIELD_PLACEHOLDER } from './translations';
Expand All @@ -30,6 +31,7 @@ export const MultiSelectAutocompleteComponent: React.FC<MultiSelectAutocompleteP
fullWidth = false,
dataTestSubj,
}: MultiSelectAutocompleteProps) => {
const comboBoxRef = useRef<EuiComboBox<unknown>>();
const fieldEuiFieldProps = useMemo(
() => ({
fullWidth: true,
Expand All @@ -39,10 +41,24 @@ export const MultiSelectAutocompleteComponent: React.FC<MultiSelectAutocompleteP
onCreateOption: undefined,
...(fullWidth ? {} : { style: { width: `${FIELD_COMBO_BOX_WIDTH}px` } }),
isDisabled,
ref: comboBoxRef,
}),
[browserFields, isDisabled, fullWidth]
[browserFields, isDisabled, fullWidth, comboBoxRef]
);

/**
* ComboBox's options list might stay open after disabling the control.
*
* It happens for example when disabled state condition depends on the number of selected items.
* When removing the last item the control switches to disabled state but doesn't close the
* options lits.
*/
useEffect(() => {
if (isDisabled) {
comboBoxRef.current?.closeList();
}
}, [isDisabled]);

return (
<ComboBoxField
field={field}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

import { useEffect } from 'react';
import usePrevious from 'react-use/lib/usePrevious';
import { isThresholdRule } from '../../../../../common/detection_engine/utils';
import type { FormHook } from '../../../../shared_imports';
import { useFormData } from '../../../../shared_imports';
Expand Down Expand Up @@ -51,8 +52,13 @@ export function usePersistentAlertSuppressionState({
ALERT_SUPPRESSION_MISSING_FIELDS_FIELD_NAME,
],
});
const previousRuleType = usePrevious(ruleType);

useEffect(() => {
if (!ruleType || ruleType === previousRuleType) {
return;
}

form.updateFieldValues({
[THRESHOLD_ALERT_SUPPRESSION_ENABLED]: thresholdAlertSuppressionEnabled,
[ALERT_SUPPRESSION_FIELDS_FIELD_NAME]: suppressionFields,
Expand All @@ -68,6 +74,7 @@ export function usePersistentAlertSuppressionState({
}, [
form,
ruleType,
previousRuleType,
thresholdAlertSuppressionEnabled,
suppressionFields,
suppressionDurationType,
Expand Down

0 comments on commit 9ddb459

Please sign in to comment.