1
1
mirror of https://github.com/n8n-io/n8n.git synced 2024-09-11 13:15:28 +03:00

fix(editor): Update Filter component state when value is updated (#8684)

This commit is contained in:
Elias Meire 2024-02-23 13:45:42 +01:00 committed by कारतोफ्फेलस्क्रिप्ट™
parent f9edf26a47
commit a54e0d31d6
2 changed files with 99 additions and 10 deletions

View File

@ -1,5 +1,5 @@
<script setup lang="ts">
import { isEqual } from 'lodash-es';
import { isEmpty, isEqual } from 'lodash-es';
import {
type FilterConditionValue,
@ -40,7 +40,7 @@ const emit = defineEmits<{
const i18n = useI18n();
const ndvStore = useNDVStore();
const { callDebounced } = useDebounce();
const { debounce } = useDebounce();
function createCondition(): FilterConditionValue {
return { id: uuid(), leftValue: '', rightValue: '', operator: DEFAULT_OPERATOR_VALUE };
@ -92,34 +92,51 @@ watch(
if (!isEqual(state.paramValue.options, newOptions)) {
state.paramValue.options = newOptions;
debouncedEmitChange();
}
},
{ immediate: true },
);
watch(state.paramValue, (value) => {
void callDebounced(
() => {
emit('valueChanged', { name: props.path, value, node: props.node?.name as string });
},
{ debounceTime: 1000 },
);
});
watch(
() => props.value,
(value) => {
if (isEmpty(value) || isEqual(state.paramValue, value)) return;
state.paramValue.conditions = value.conditions;
state.paramValue.combinator = value.combinator;
state.paramValue.options = value.options;
},
);
function emitChange() {
emit('valueChanged', {
name: props.path,
value: state.paramValue,
node: props.node?.name as string,
});
}
const debouncedEmitChange = debounce(emitChange, { debounceTime: 1000 });
function addCondition(): void {
state.paramValue.conditions.push(createCondition());
debouncedEmitChange();
}
function onConditionUpdate(index: number, value: FilterConditionValue): void {
state.paramValue.conditions[index] = value;
debouncedEmitChange();
}
function onCombinatorChange(combinator: FilterTypeCombinator): void {
state.paramValue.combinator = combinator;
debouncedEmitChange();
}
function onConditionRemove(index: number): void {
state.paramValue.conditions.splice(index, 1);
debouncedEmitChange();
}
function getIssues(index: number): string[] {

View File

@ -304,4 +304,76 @@ describe('FilterConditions.vue', () => {
expect(operatorSelect.querySelector('input')).toBeDisabled();
}
});
it('re-renders when value prop changes', async () => {
const { findAllByTestId, rerender } = renderComponent({
...DEFAULT_SETUP,
props: {
...DEFAULT_SETUP.props,
value: {
conditions: [
{
id: '1',
leftValue: 'foo',
rightValue: 'bar',
operator: {
type: 'string',
operation: 'equals',
},
},
],
combinator: 'and',
},
},
});
// Rerender with different conditions
await rerender({
value: {
conditions: [
{
id: '2',
leftValue: 'quz',
rightValue: 'qux',
operator: {
type: 'string',
operation: 'notEquals',
},
},
{
id: '3',
leftValue: 5,
rightValue: 6,
operator: {
type: 'number',
operation: 'gt',
},
},
],
combinator: 'and',
},
});
const conditions = await findAllByTestId('filter-condition');
expect(conditions).toHaveLength(2);
expect(
within(conditions[0]).getByTestId('filter-condition-left').querySelector('input'),
).toHaveValue('quz');
expect(
within(conditions[0]).getByTestId('filter-operator-select').querySelector('input'),
).toHaveValue('is not equal to');
expect(
within(conditions[0]).getByTestId('filter-condition-right').querySelector('input'),
).toHaveValue('qux');
expect(
within(conditions[1]).getByTestId('filter-condition-left').querySelector('input'),
).toHaveValue(5);
expect(
within(conditions[1]).getByTestId('filter-operator-select').querySelector('input'),
).toHaveValue('is greater than');
expect(
within(conditions[1]).getByTestId('filter-condition-right').querySelector('input'),
).toHaveValue(6);
});
});