[Alerting UI] Fixing bug when switching between threshold comparators (#85844) (#86187)

* Fixing bug when switching between comparators with different number of inputs

* Triggering onThresholdChange call on next render cycle
This commit is contained in:
ymao1 2020-12-16 17:54:19 -05:00 committed by GitHub
parent 9735f90991
commit 9bc45d5955
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 18 deletions

View file

@ -108,4 +108,34 @@ describe('threshold expression', () => {
expect(onChangeSelectedThreshold).toHaveBeenCalled();
expect(onChangeSelectedThresholdComparator).toHaveBeenCalled();
});
it('renders the correct number of threshold inputs', async () => {
const wrapper = mountWithIntl(
<ThresholdExpression
thresholdComparator={'>'}
threshold={[10]}
errors={{ threshold0: [], threshold1: [] }}
onChangeSelectedThreshold={jest.fn()}
onChangeSelectedThresholdComparator={jest.fn()}
/>
);
wrapper.find('[data-test-subj="thresholdPopover"]').first().simulate('click');
expect(wrapper.find('[data-test-subj="comparatorOptionsComboBox"]').exists()).toBeTruthy();
expect(wrapper.find('input[data-test-subj="alertThresholdInput"]').length).toEqual(1);
wrapper
.find('[data-test-subj="comparatorOptionsComboBox"]')
.last()
.simulate('change', { target: { value: 'between' } });
wrapper.update();
expect(wrapper.find('input[data-test-subj="alertThresholdInput"]').length).toEqual(2);
wrapper
.find('[data-test-subj="comparatorOptionsComboBox"]')
.last()
.simulate('change', { target: { value: '<' } });
wrapper.update();
expect(wrapper.find('input[data-test-subj="alertThresholdInput"]').length).toEqual(1);
});
});

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import React, { useState, Fragment } from 'react';
import React, { useEffect, useState, Fragment } from 'react';
import { i18n } from '@kbn/i18n';
import {
EuiExpression,
@ -58,6 +58,10 @@ export const ThresholdExpression = ({
}: ThresholdExpressionProps) => {
const comparators = customComparators ?? builtInComparators;
const [alertThresholdPopoverOpen, setAlertThresholdPopoverOpen] = useState(false);
const [comparator, setComparator] = useState<string>(thresholdComparator);
const [numRequiredThresholds, setNumRequiredThresholds] = useState<number>(
comparators[thresholdComparator].requiredValues
);
const andThresholdText = i18n.translate(
'xpack.triggersActionsUI.common.expressionItems.threshold.andLabel',
@ -66,15 +70,23 @@ export const ThresholdExpression = ({
}
);
useEffect(() => {
const updateThresholdValue = comparators[comparator].requiredValues !== numRequiredThresholds;
if (updateThresholdValue) {
const thresholdValues = threshold.slice(0, comparators[comparator].requiredValues);
onChangeSelectedThreshold(thresholdValues);
setNumRequiredThresholds(comparators[comparator].requiredValues);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [comparator]);
return (
<EuiPopover
button={
<EuiExpression
data-test-subj="thresholdPopover"
description={comparators[thresholdComparator].text}
value={(threshold || [])
.slice(0, comparators[thresholdComparator].requiredValues)
.join(` ${andThresholdText} `)}
description={comparators[comparator].text}
value={(threshold || []).slice(0, numRequiredThresholds).join(` ${andThresholdText} `)}
isActive={Boolean(
alertThresholdPopoverOpen ||
(errors.threshold0 && errors.threshold0.length) ||
@ -102,32 +114,23 @@ export const ThresholdExpression = ({
>
<div>
<ClosablePopoverTitle onClose={() => setAlertThresholdPopoverOpen(false)}>
<>{comparators[thresholdComparator].text}</>
<>{comparators[comparator].text}</>
</ClosablePopoverTitle>
<EuiFlexGroup>
<EuiFlexItem grow={false}>
<EuiSelect
data-test-subj="comparatorOptionsComboBox"
value={thresholdComparator}
value={comparator}
onChange={(e) => {
const updateThresholdValue =
comparators[thresholdComparator].requiredValues !==
comparators[e.target.value].requiredValues;
setComparator(e.target.value);
onChangeSelectedThresholdComparator(e.target.value);
if (updateThresholdValue) {
const thresholdValues = threshold.slice(
0,
comparators[e.target.value].requiredValues
);
onChangeSelectedThreshold(thresholdValues);
}
}}
options={Object.values(comparators).map(({ text, value }) => {
return { text, value };
})}
/>
</EuiFlexItem>
{Array.from(Array(comparators[thresholdComparator].requiredValues)).map((_notUsed, i) => {
{Array.from(Array(numRequiredThresholds)).map((_notUsed, i) => {
return (
<Fragment key={`threshold${i}`}>
{i > 0 ? (