From 62df4331d448dfdabd51db33560a87dd5d805a13 Mon Sep 17 00:00:00 2001 From: Elias Meire Date: Wed, 22 May 2024 09:40:09 +0200 Subject: [PATCH] fix(editor): Emit change events from filter component on update (#9479) --- .../components/FilterConditions/Condition.vue | 10 ++- .../__tests__/FilterConditions.test.ts | 65 ++++++++++++++++++- 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/packages/editor-ui/src/components/FilterConditions/Condition.vue b/packages/editor-ui/src/components/FilterConditions/Condition.vue index 4a6671b89..5fb6568ea 100644 --- a/packages/editor-ui/src/components/FilterConditions/Condition.vue +++ b/packages/editor-ui/src/components/FilterConditions/Condition.vue @@ -21,6 +21,7 @@ import { operatorTypeToNodeProperty, resolveCondition, } from './utils'; +import { useDebounce } from '@/composables/useDebounce'; interface Props { path: string; @@ -47,6 +48,7 @@ const emit = defineEmits<{ }>(); const i18n = useI18n(); +const { debounce } = useDebounce(); const condition = ref(props.condition); @@ -101,12 +103,16 @@ const rightParameter = computed(() => { }; }); +const debouncedEmitUpdate = debounce(() => emit('update', condition.value), { debounceTime: 500 }); + const onLeftValueChange = (update: IUpdateInformation): void => { condition.value.leftValue = update.value; + debouncedEmitUpdate(); }; const onRightValueChange = (update: IUpdateInformation): void => { condition.value.rightValue = update.value; + debouncedEmitUpdate(); }; const onOperatorChange = (value: string): void => { @@ -117,7 +123,7 @@ const onOperatorChange = (value: string): void => { newOperator, }); - emit('update', condition.value); + debouncedEmitUpdate(); }; const onRemove = (): void => { @@ -125,7 +131,7 @@ const onRemove = (): void => { }; const onBlur = (): void => { - emit('update', condition.value); + debouncedEmitUpdate(); }; diff --git a/packages/editor-ui/src/components/FilterConditions/__tests__/FilterConditions.test.ts b/packages/editor-ui/src/components/FilterConditions/__tests__/FilterConditions.test.ts index 568d65c9b..a41a58759 100644 --- a/packages/editor-ui/src/components/FilterConditions/__tests__/FilterConditions.test.ts +++ b/packages/editor-ui/src/components/FilterConditions/__tests__/FilterConditions.test.ts @@ -5,8 +5,9 @@ import { STORES } from '@/constants'; import { useNDVStore } from '@/stores/ndv.store'; import { createTestingPinia } from '@pinia/testing'; import userEvent from '@testing-library/user-event'; -import { within } from '@testing-library/vue'; +import { within, waitFor } from '@testing-library/vue'; import { getFilterOperator } from '../utils'; +import { get } from 'lodash-es'; const DEFAULT_SETUP = { pinia: createTestingPinia({ @@ -274,6 +275,68 @@ describe('FilterConditions.vue', () => { expect(conditions[0].querySelector('[data-test-id="filter-remove-condition"]')).toBeNull(); }); + it('can edit conditions', async () => { + const { getByTestId, emitted } = renderComponent({ + ...DEFAULT_SETUP, + props: { + ...DEFAULT_SETUP.props, + value: { + options: { + caseSensitive: true, + leftValue: '', + }, + conditions: [ + { + leftValue: '={{ $json.name }}', + rightValue: 'John', + operator: getFilterOperator('string:equals'), + }, + ], + }, + }, + }); + + const condition = getByTestId('filter-condition'); + await waitFor(() => + expect(within(condition).getByTestId('filter-condition-left')).toHaveTextContent( + '{{ $json.name }}', + ), + ); + + expect(emitted('valueChanged')).toBeUndefined(); + + const expressionEditor = within(condition) + .getByTestId('filter-condition-left') + .querySelector('.cm-line'); + + if (expressionEditor) { + await userEvent.type(expressionEditor, 'test'); + } + + await waitFor(() => { + expect(get(emitted('valueChanged')[0], '0.value.conditions.0.leftValue')).toEqual( + expect.stringContaining('test'), + ); + }); + + const parameterInput = within(condition) + .getByTestId('filter-condition-right') + .querySelector('input'); + + if (parameterInput) { + await userEvent.type(parameterInput, 'test'); + } + + await waitFor(() => { + expect(get(emitted('valueChanged')[0], '0.value.conditions.0.leftValue')).toEqual( + expect.stringContaining('test'), + ); + expect(get(emitted('valueChanged')[0], '0.value.conditions.0.rightValue')).toEqual( + expect.stringContaining('test'), + ); + }); + }); + it('renders correctly in read only mode', async () => { const { findAllByTestId, queryByTestId } = renderComponent({ props: {