diff --git a/packages/frontend/editor-ui/src/features/ai/instanceAi/__tests__/instanceAiWorkflowSetup.utils.test.ts b/packages/frontend/editor-ui/src/features/ai/instanceAi/__tests__/instanceAiWorkflowSetup.utils.test.ts index c74e49691a2..3ed9261cfcb 100644 --- a/packages/frontend/editor-ui/src/features/ai/instanceAi/__tests__/instanceAiWorkflowSetup.utils.test.ts +++ b/packages/frontend/editor-ui/src/features/ai/instanceAi/__tests__/instanceAiWorkflowSetup.utils.test.ts @@ -142,6 +142,20 @@ describe('isParamValueSet', () => { test('returns true for non-empty resource locator', () => { expect(isParamValueSet({ __rl: true, value: 'some-id', mode: 'list' })).toBe(true); }); + + test('returns false for placeholder sentinel string', () => { + expect(isParamValueSet('<__PLACEHOLDER_VALUE__your_email__>')).toBe(false); + }); + + test('returns false for resource locator with placeholder sentinel value', () => { + expect( + isParamValueSet({ + __rl: true, + value: '<__PLACEHOLDER_VALUE__channel_name__>', + mode: 'list', + }), + ).toBe(false); + }); }); // --------------------------------------------------------------------------- diff --git a/packages/frontend/editor-ui/src/features/ndv/parameters/components/ParameterInput.test.ts b/packages/frontend/editor-ui/src/features/ndv/parameters/components/ParameterInput.test.ts index 2092d81ed60..43826b28165 100644 --- a/packages/frontend/editor-ui/src/features/ndv/parameters/components/ParameterInput.test.ts +++ b/packages/frontend/editor-ui/src/features/ndv/parameters/components/ParameterInput.test.ts @@ -64,7 +64,8 @@ beforeEach(() => { mockNodeTypesState = getNodeTypesStateMock(); mockCompletionResult = {}; mockBuilderState.trackWorkflowBuilderJourney.mockClear(); - mockIsPlaceholderValue.mockClear(); + mockIsPlaceholderValue.mockReset(); + mockExtractPlaceholderLabels.mockReset().mockReturnValue([]); mockBuilderState.isAIBuilderEnabled = true; }); @@ -112,10 +113,12 @@ vi.mock('@/features/ai/assistant/builder.store', () => { }); const mockIsPlaceholderValue = vi.fn(); +const mockExtractPlaceholderLabels = vi.fn().mockReturnValue([]); vi.mock('@/features/ai/assistant/composables/useBuilderTodos', () => { return { isPlaceholderValue: (value: unknown) => mockIsPlaceholderValue(value), + extractPlaceholderLabels: (value: unknown) => mockExtractPlaceholderLabels(value), }; }); diff --git a/packages/frontend/editor-ui/src/features/ndv/parameters/components/ParameterInput.vue b/packages/frontend/editor-ui/src/features/ndv/parameters/components/ParameterInput.vue index 89f3ac4ccd6..8aac8221dd5 100644 --- a/packages/frontend/editor-ui/src/features/ndv/parameters/components/ParameterInput.vue +++ b/packages/frontend/editor-ui/src/features/ndv/parameters/components/ParameterInput.vue @@ -112,7 +112,10 @@ import { } from '@n8n/design-system'; import { useCollectionOverhaul } from '@/app/composables/useCollectionOverhaul'; import { injectWorkflowDocumentStore } from '@/app/stores/workflowDocument.store'; -import { isPlaceholderValue } from '@/features/ai/assistant/composables/useBuilderTodos'; +import { + isPlaceholderValue, + extractPlaceholderLabels, +} from '@/features/ai/assistant/composables/useBuilderTodos'; type Picker = { $emit: (arg0: string, arg1: Date) => void }; @@ -455,6 +458,10 @@ const displayValue = computed(() => { returnValue = 'rgba(' + h.join() + ')'; } + if (typeof returnValue === 'string' && isPlaceholderValue(returnValue)) { + return ''; + } + return returnValue as string; }); @@ -760,6 +767,14 @@ function credentialSelected(updateInformation: INodeUpdatePropertiesInformation) } function getPlaceholder(): string { + const rawValue = isResourceLocatorValue(props.modelValue) + ? props.modelValue.value + : props.modelValue; + if (typeof rawValue === 'string') { + const labels = extractPlaceholderLabels(rawValue); + if (labels.length > 0) return labels[0]; + } + return props.isForCredential ? i18n.credText(uiStore.activeCredentialType).placeholder(props.parameter) : i18n.nodeText(ndvStore.activeNode?.type).placeholder(props.parameter, props.path);