fix: Disable autocomplete expression for specialized editor types (#14344)

This commit is contained in:
Michael Kret
2025-04-02 12:23:16 +03:00
committed by GitHub
parent 1e4541603f
commit 0450542170
3 changed files with 29 additions and 13 deletions

View File

@@ -68,7 +68,7 @@ import { createEventBus } from '@n8n/utils/event-bus';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { useElementSize } from '@vueuse/core'; import { useElementSize } from '@vueuse/core';
import { captureMessage } from '@sentry/vue'; import { captureMessage } from '@sentry/vue';
import { completeExpressionSyntax, isStringWithExpressionSyntax } from '@/utils/expressions'; import { completeExpressionSyntax, shouldConvertToExpression } from '@/utils/expressions';
import { isPresent } from '@/utils/typesUtils'; import { isPresent } from '@/utils/typesUtils';
import CssEditor from './CssEditor/CssEditor.vue'; import CssEditor from './CssEditor/CssEditor.vue';
@@ -853,7 +853,13 @@ function valueChanged(value: NodeParameterValueType | {} | Date) {
return; return;
} }
if (!oldValue && oldValue !== undefined && isStringWithExpressionSyntax(value)) { const isSpecializedEditor = props.parameter.typeOptions?.editor !== undefined;
if (
!oldValue &&
oldValue !== undefined &&
shouldConvertToExpression(value, isSpecializedEditor)
) {
// if empty old value and updated value has an expression, add '=' prefix to switch to expression mode // if empty old value and updated value has an expression, add '=' prefix to switch to expression mode
value = '=' + value; value = '=' + value;
} }
@@ -862,7 +868,7 @@ function valueChanged(value: NodeParameterValueType | {} | Date) {
activeCredentialType.value = value as string; activeCredentialType.value = value as string;
} }
value = completeExpressionSyntax(value); value = completeExpressionSyntax(value, isSpecializedEditor);
if (value instanceof Date) { if (value instanceof Date) {
value = value.toISOString(); value = value.toISOString();

View File

@@ -1,7 +1,7 @@
import { ExpressionError } from 'n8n-workflow'; import { ExpressionError } from 'n8n-workflow';
import { import {
completeExpressionSyntax, completeExpressionSyntax,
isStringWithExpressionSyntax, shouldConvertToExpression,
removeExpressionPrefix, removeExpressionPrefix,
stringifyExpressionResult, stringifyExpressionResult,
unwrapExpression, unwrapExpression,
@@ -79,25 +79,33 @@ describe('Utils: Expressions', () => {
expect(completeExpressionSyntax(true)).toBe(true); expect(completeExpressionSyntax(true)).toBe(true);
expect(completeExpressionSyntax(null)).toBe(null); expect(completeExpressionSyntax(null)).toBe(null);
}); });
it('should return unchanged value if special editor type', () => {
expect(completeExpressionSyntax('test {{ ', true)).toBe('test {{ ');
});
}); });
describe('isStringWithExpressionSyntax', () => { describe('shouldConvertToExpression', () => {
it('should return true for strings with expression syntax', () => { it('should return true for strings with expression syntax', () => {
expect(isStringWithExpressionSyntax('test {{ value }}')).toBe(true); expect(shouldConvertToExpression('test {{ value }}')).toBe(true);
}); });
it('should return false for strings without expression syntax', () => { it('should return false for strings without expression syntax', () => {
expect(isStringWithExpressionSyntax('just a string')).toBe(false); expect(shouldConvertToExpression('just a string')).toBe(false);
}); });
it('should return false for strings starting with "="', () => { it('should return false for strings starting with "="', () => {
expect(isStringWithExpressionSyntax('=expression {{ value }}')).toBe(false); expect(shouldConvertToExpression('=expression {{ value }}')).toBe(false);
}); });
it('should return false for non-string values', () => { it('should return false for non-string values', () => {
expect(isStringWithExpressionSyntax(123)).toBe(false); expect(shouldConvertToExpression(123)).toBe(false);
expect(isStringWithExpressionSyntax(true)).toBe(false); expect(shouldConvertToExpression(true)).toBe(false);
expect(isStringWithExpressionSyntax(null)).toBe(false); expect(shouldConvertToExpression(null)).toBe(false);
});
it('should return false if special editor type', () => {
expect(shouldConvertToExpression('test {{ value }}', true)).toBe(false);
}); });
}); });
}); });

View File

@@ -140,7 +140,8 @@ export const stringifyExpressionResult = (
return typeof result.result === 'string' ? result.result : String(result.result); return typeof result.result === 'string' ? result.result : String(result.result);
}; };
export const completeExpressionSyntax = <T>(value: T) => { export const completeExpressionSyntax = <T>(value: T, isSpecializedEditor = false) => {
if (isSpecializedEditor) return value;
if (typeof value === 'string' && !value.startsWith('=')) { if (typeof value === 'string' && !value.startsWith('=')) {
if (value.endsWith('{{ ')) return '=' + value + ' }}'; if (value.endsWith('{{ ')) return '=' + value + ' }}';
if (value.endsWith('{{$')) return '=' + value.slice(0, -1) + ' $ }}'; if (value.endsWith('{{$')) return '=' + value.slice(0, -1) + ' $ }}';
@@ -149,7 +150,8 @@ export const completeExpressionSyntax = <T>(value: T) => {
return value; return value;
}; };
export const isStringWithExpressionSyntax = <T>(value: T): boolean => { export const shouldConvertToExpression = <T>(value: T, isSpecializedEditor = false): boolean => {
if (isSpecializedEditor) return false;
return ( return (
typeof value === 'string' && typeof value === 'string' &&
!value.startsWith('=') && !value.startsWith('=') &&