From eec325127c075a0a0db429d5b41db5c2851fc187 Mon Sep 17 00:00:00 2001 From: Elias Meire Date: Fri, 14 Mar 2025 15:09:36 +0100 Subject: [PATCH] fix(editor): Fix options parameters that have extra displayName field (#13928) --- .../src/components/ParameterInput.test.ts | 46 +++++++++++++++++++ .../src/components/ParameterInput.vue | 4 +- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/packages/frontend/editor-ui/src/components/ParameterInput.test.ts b/packages/frontend/editor-ui/src/components/ParameterInput.test.ts index 4d19250f01..38dda6e214 100644 --- a/packages/frontend/editor-ui/src/components/ParameterInput.test.ts +++ b/packages/frontend/editor-ui/src/components/ParameterInput.test.ts @@ -143,6 +143,52 @@ describe('ParameterInput.vue', () => { expect(emitted('update')).toContainEqual([expect.objectContaining({ value: 'append' })]); }); + test('should render an options parameter even if it has invalid fields (like displayName)', async () => { + // Test case based on the Schedule node + // type=options parameters shouldn't have a displayName field, but some do + const { container, baseElement, emitted } = renderComponent(ParameterInput, { + pinia: createTestingPinia(), + props: { + path: 'operation', + parameter: { + displayName: 'Trigger at Hour', + name: 'triggerAtHour', + type: 'options', + default: 0, + options: [ + { + name: 'Midnight', + displayName: 'Midnight', + value: 0, + }, + { + name: '1am', + displayName: '1am', + value: 1, + }, + ], + description: 'The hour of the day to trigger', + }, + modelValue: 0, + }, + }); + const select = container.querySelector('input') as HTMLInputElement; + const selectTrigger = container.querySelector('.select-trigger') as HTMLElement; + + await waitFor(() => expect(select).toHaveValue('Midnight')); + + await userEvent.click(selectTrigger); + + const options = baseElement.querySelectorAll('.list-option'); + expect(options.length).toEqual(2); + expect(options[0].querySelector('.option-headline')).toHaveTextContent('Midnight'); + expect(options[1].querySelector('.option-headline')).toHaveTextContent('1am'); + + await userEvent.click(options[1]); + + expect(emitted('update')).toContainEqual([expect.objectContaining({ value: 1 })]); + }); + test('should render a string parameter', async () => { const { container, emitted } = renderComponent(ParameterInput, { pinia: createTestingPinia(), diff --git a/packages/frontend/editor-ui/src/components/ParameterInput.vue b/packages/frontend/editor-ui/src/components/ParameterInput.vue index eed224dee0..d5fb016a01 100644 --- a/packages/frontend/editor-ui/src/components/ParameterInput.vue +++ b/packages/frontend/editor-ui/src/components/ParameterInput.vue @@ -23,7 +23,7 @@ import type { IParameterLabel, NodeParameterValueType, } from 'n8n-workflow'; -import { CREDENTIAL_EMPTY_VALUE, isINodePropertyOptions, NodeHelpers } from 'n8n-workflow'; +import { CREDENTIAL_EMPTY_VALUE, NodeHelpers } from 'n8n-workflow'; import CodeNodeEditor from '@/components/CodeNodeEditor/CodeNodeEditor.vue'; import CredentialsSelect from '@/components/CredentialsSelect.vue'; @@ -574,7 +574,7 @@ const shouldCaptureForPosthog = computed(() => { function isValidParameterOption( option: INodePropertyOptions | INodeProperties | INodePropertyCollection, ): option is INodePropertyOptions { - return isINodePropertyOptions(option) && isPresent(option.value) && isPresent(option.name); + return 'value' in option && isPresent(option.value) && isPresent(option.name); } function isRemoteParameterOption(option: INodePropertyOptions) {