From 2c72047d0b260db5a4b1fd0d7448ab19378e908f Mon Sep 17 00:00:00 2001 From: Shireen Missi <94372015+ShireenMissi@users.noreply.github.com> Date: Wed, 8 Jan 2025 09:30:35 +0000 Subject: [PATCH] fix(editor): Render empty string instead of [empty] (#12448) --- .../composables/useExpressionEditor.test.ts | 103 ++++++++++++++++++ .../src/composables/useExpressionEditor.ts | 20 ++-- 2 files changed, 110 insertions(+), 13 deletions(-) diff --git a/packages/editor-ui/src/composables/useExpressionEditor.test.ts b/packages/editor-ui/src/composables/useExpressionEditor.test.ts index d6ed9338c5..4512e7654a 100644 --- a/packages/editor-ui/src/composables/useExpressionEditor.test.ts +++ b/packages/editor-ui/src/composables/useExpressionEditor.test.ts @@ -132,6 +132,109 @@ describe('useExpressionEditor', () => { }); }); + test('render [empty] when expression evaluates to an empty string', async () => { + mockResolveExpression().mockReturnValueOnce(''); + + const { + expressionEditor: { segments }, + } = await renderExpressionEditor({ + editorValue: "{{ '' }}", + extensions: [n8nLang()], + }); + + await waitFor(() => { + expect(toValue(segments.all)).toEqual([ + { + error: null, + from: 0, + kind: 'resolvable', + resolvable: "{{ '' }}", + resolved: '[empty]', + state: 'valid', + to: 8, + }, + ]); + + expect(toValue(segments.resolvable)).toEqual([ + { + error: null, + from: 0, + kind: 'resolvable', + resolvable: "{{ '' }}", + resolved: '[empty]', + state: 'valid', + to: 8, + }, + ]); + + expect(toValue(segments.plaintext)).toEqual([]); + }); + }); + + test('does not render [empty] when expression evaluates to an empty string within a string', async () => { + mockResolveExpression().mockReturnValueOnce(''); + + const { + expressionEditor: { segments }, + } = await renderExpressionEditor({ + editorValue: "before {{ '' }} after", + extensions: [n8nLang()], + }); + + await waitFor(() => { + expect(toValue(segments.all)).toEqual([ + { + from: 0, + kind: 'plaintext', + plaintext: 'before ', + to: 7, + }, + { + error: null, + from: 7, + kind: 'resolvable', + resolvable: "{{ '' }}", + resolved: '', + state: 'valid', + to: 15, + }, + { + from: 15, + kind: 'plaintext', + plaintext: ' after', + to: 21, + }, + ]); + + expect(toValue(segments.resolvable)).toEqual([ + { + error: null, + from: 7, + kind: 'resolvable', + resolvable: "{{ '' }}", + resolved: '', + state: 'valid', + to: 15, + }, + ]); + + expect(toValue(segments.plaintext)).toEqual([ + { + from: 0, + kind: 'plaintext', + plaintext: 'before ', + to: 7, + }, + { + from: 15, + kind: 'plaintext', + plaintext: ' after', + to: 21, + }, + ]); + }); + }); + describe('readEditorValue()', () => { test('should return the full editor value (unresolved)', async () => { mockResolveExpression().mockReturnValueOnce(15); diff --git a/packages/editor-ui/src/composables/useExpressionEditor.ts b/packages/editor-ui/src/composables/useExpressionEditor.ts index 0911621be3..6cee456249 100644 --- a/packages/editor-ui/src/composables/useExpressionEditor.ts +++ b/packages/editor-ui/src/composables/useExpressionEditor.ts @@ -22,11 +22,7 @@ import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers'; import { highlighter } from '@/plugins/codemirror/resolvableHighlighter'; import { closeCursorInfoBox } from '@/plugins/codemirror/tooltips/InfoBoxTooltip'; import type { Html, Plaintext, RawSegment, Resolvable, Segment } from '@/types/expressions'; -import { - getExpressionErrorMessage, - getResolvableState, - isEmptyExpression, -} from '@/utils/expressions'; +import { getExpressionErrorMessage, getResolvableState } from '@/utils/expressions'; import { closeCompletion, completionStatus } from '@codemirror/autocomplete'; import { Compartment, @@ -129,6 +125,12 @@ export const useExpressionEditor = ({ return acc; }, []); + if ( + segments.value.length === 1 && + segments.value[0]?.kind === 'resolvable' && + segments.value[0]?.resolved === '' + ) + segments.value[0].resolved = i18n.baseText('expressionModalInput.empty'); }; function readEditorValue(): string { @@ -314,14 +316,6 @@ export const useExpressionEditor = ({ result.fullError = error; } - if (result.resolved === '') { - result.resolved = i18n.baseText('expressionModalInput.empty'); - } - - if (result.resolved === undefined && isEmptyExpression(resolvable)) { - result.resolved = i18n.baseText('expressionModalInput.empty'); - } - if (result.resolved === undefined) { result.resolved = isUncalledExpressionExtension(resolvable) ? i18n.baseText('expressionEditor.uncalledFunction')