Skip to content

Commit

Permalink
fix(editor): UI enhancements and fixes for expression inputs (#8996)
Browse files Browse the repository at this point in the history
  • Loading branch information
elsmr committed Mar 29, 2024
1 parent 1cbd044 commit 8788e2a
Show file tree
Hide file tree
Showing 12 changed files with 41 additions and 86 deletions.
7 changes: 7 additions & 0 deletions packages/editor-ui/src/__tests__/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,10 @@ window.ResizeObserver =
}));

Element.prototype.scrollIntoView = vi.fn();

Range.prototype.getBoundingClientRect = vi.fn();
Range.prototype.getClientRects = vi.fn(() => ({
item: vi.fn(),
length: 0,
[Symbol.iterator]: vi.fn(),
}));
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@ const onBlur = (): void => {
display-options
hide-label
hide-hint
:rows="3"
:is-read-only="isReadOnly"
:parameter="nameParameter"
:value="assignment.name"
Expand All @@ -196,7 +195,6 @@ const onBlur = (): void => {
hide-label
hide-issues
hide-hint
:rows="3"
is-assignment
:is-read-only="isReadOnly"
:options-position="breakpoint === 'default' ? 'top' : 'bottom'"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,6 @@ const onBlur = (): void => {
hide-label
hide-hint
hide-issues
:rows="3"
:is-read-only="readOnly"
:parameter="leftParameter"
:value="condition.leftValue"
Expand All @@ -181,7 +180,6 @@ const onBlur = (): void => {
hide-label
hide-hint
hide-issues
:rows="3"
:is-read-only="readOnly"
:options-position="breakpoint === 'default' ? 'top' : 'bottom'"
:parameter="rightParameter"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,24 @@ const resolvedExpression = computed(() => {
});
const plaintextSegments = computed<Plaintext[]>(() => {
if (props.segments.length === 0) {
return [
{
from: 0,
to: resolvedExpression.value.length - 1,
plaintext: resolvedExpression.value,
kind: 'plaintext',
},
];
}
return props.segments.filter((s): s is Plaintext => s.kind === 'plaintext');
});
const resolvedSegments = computed<Resolved[]>(() => {
if (props.segments.length === 0) {
const emptyExpression = resolvedExpression.value;
const emptySegment: Resolved = {
from: 0,
to: emptyExpression.length,
kind: 'resolvable',
error: null,
resolvable: '',
resolved: emptyExpression,
state: 'pending',
};
return [emptySegment];
}
let cursor = 0;
return props.segments
Expand Down
7 changes: 6 additions & 1 deletion packages/editor-ui/src/components/ParameterInputFull.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<n8n-input-label
:class="$style.wrapper"
:class="[$style.wrapper, { [$style.tipVisible]: showDragnDropTip }]"
:label="hideLabel ? '' : i18n.nodeText().inputLabelDisplayName(parameter, path)"
:tooltip-text="hideLabel ? '' : i18n.nodeText().inputLabelDescription(parameter, path)"
:show-tooltip="focused"
Expand Down Expand Up @@ -357,6 +357,11 @@ export default defineComponent({
}
}
.tipVisible {
--input-border-bottom-left-radius: 0;
--input-border-bottom-right-radius: 0;
}
.tip {
position: absolute;
z-index: 2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import { setActivePinia } from 'pinia';
import { waitFor } from '@testing-library/vue';

describe('ExpressionParameterInput', () => {
const originalRangeGetBoundingClientRect = Range.prototype.getBoundingClientRect;
const originalRangeGetClientRects = Range.prototype.getClientRects;
const renderComponent = createComponentRenderer(ExpressionEditorModalInput);
let pinia: TestingPinia;

Expand All @@ -16,19 +14,6 @@ describe('ExpressionParameterInput', () => {
setActivePinia(pinia);
});

beforeAll(() => {
Range.prototype.getBoundingClientRect = vi.fn();
Range.prototype.getClientRects = () => ({
item: vi.fn(),
length: 0,
[Symbol.iterator]: vi.fn(),
});
});

afterAll(() => {
Range.prototype.getBoundingClientRect = originalRangeGetBoundingClientRect;
Range.prototype.getClientRects = originalRangeGetClientRects;
});
test.each([
['not be editable', 'readonly', true, ''],
['be editable', 'not readonly', false, 'test'],
Expand Down
17 changes: 0 additions & 17 deletions packages/editor-ui/src/components/__tests__/HtmlEditor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ const DEFAULT_SETUP = {
};

describe('HtmlEditor.vue', () => {
const originalRangeGetBoundingClientRect = Range.prototype.getBoundingClientRect;
const originalRangeGetClientRects = Range.prototype.getClientRects;

const pinia = createTestingPinia({
initialState: {
[STORES.SETTINGS]: {
Expand All @@ -29,20 +26,6 @@ describe('HtmlEditor.vue', () => {
});
setActivePinia(pinia);

beforeAll(() => {
Range.prototype.getBoundingClientRect = vi.fn();
Range.prototype.getClientRects = () => ({
item: vi.fn(),
length: 0,
[Symbol.iterator]: vi.fn(),
});
});

afterAll(() => {
Range.prototype.getBoundingClientRect = originalRangeGetBoundingClientRect;
Range.prototype.getClientRects = originalRangeGetClientRects;
});

afterAll(() => {
vi.clearAllMocks();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ vi.mock('@/stores/n8nRoot.store', () => ({
}));

describe('useAutocompleteTelemetry', () => {
const originalRangeGetBoundingClientRect = Range.prototype.getBoundingClientRect;
const originalRangeGetClientRects = Range.prototype.getClientRects;

beforeEach(() => {
setActivePinia(createTestingPinia());
});
Expand All @@ -39,20 +36,6 @@ describe('useAutocompleteTelemetry', () => {
vi.clearAllMocks();
});

beforeAll(() => {
Range.prototype.getBoundingClientRect = vi.fn();
Range.prototype.getClientRects = () => ({
item: vi.fn(),
length: 0,
[Symbol.iterator]: vi.fn(),
});
});

afterAll(() => {
Range.prototype.getBoundingClientRect = originalRangeGetBoundingClientRect;
Range.prototype.getClientRects = originalRangeGetClientRects;
});

const getEditor = (defaultDoc = '') => {
const extensionCompartment = new Compartment();
const state = EditorState.create({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ vi.mock('@/stores/ndv.store', () => ({
}));

describe('useExpressionEditor', () => {
const originalRangeGetBoundingClientRect = Range.prototype.getBoundingClientRect;
const originalRangeGetClientRects = Range.prototype.getClientRects;

const mockResolveExpression = () => {
const mock = vi.fn();
vi.spyOn(workflowHelpers, 'useWorkflowHelpers').mockReturnValueOnce({
Expand All @@ -42,20 +39,6 @@ describe('useExpressionEditor', () => {
vi.clearAllMocks();
});

beforeAll(() => {
Range.prototype.getBoundingClientRect = vi.fn();
Range.prototype.getClientRects = () => ({
item: vi.fn(),
length: 0,
[Symbol.iterator]: vi.fn(),
});
});

afterAll(() => {
Range.prototype.getBoundingClientRect = originalRangeGetBoundingClientRect;
Range.prototype.getClientRects = originalRangeGetClientRects;
});

test('should create an editor', async () => {
const root = ref<HTMLElement>();
const { editor } = useExpressionEditor({
Expand Down
5 changes: 3 additions & 2 deletions packages/editor-ui/src/composables/useExpressionEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ export const useExpressionEditor = ({
if (editor.value) {
editor.value.destroy();
}
editor.value = new EditorView({ parent, state });
editor.value = new EditorView({ parent, state, scrollTo: EditorView.scrollIntoView(0) });
debouncedUpdateSegments();
});

Expand Down Expand Up @@ -385,7 +385,8 @@ export const useExpressionEditor = ({
function setCursorPosition(pos: number | 'lastExpression' | 'end'): void {
if (pos === 'lastExpression') {
const END_OF_EXPRESSION = ' }}';
pos = Math.max(readEditorValue().lastIndexOf(END_OF_EXPRESSION), 0);
const endOfLastExpression = readEditorValue().lastIndexOf(END_OF_EXPRESSION);
pos = endOfLastExpression !== -1 ? endOfLastExpression : editor.value?.state.doc.length ?? 0;
} else if (pos === 'end') {
pos = editor.value?.state.doc.length ?? 0;
}
Expand Down
5 changes: 4 additions & 1 deletion packages/workflow/src/Extensions/StringExtensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,10 @@ function parseJson(value: string): unknown {
try {
return JSON.parse(value);
} catch (error) {
return undefined;
if (value.includes("'")) {
throw new ExpressionExtensionError("Parsing failed. Check you're using double quotes");
}
throw new ExpressionExtensionError('Parsing failed');
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,13 @@ describe('Data Transformation Functions', () => {
test1: 1,
test2: '2',
});
expect(evaluate('={{ "hi".parseJson() }}')).toBeUndefined();
});

test('.parseJson should throw on invalid JSON', () => {
expect(() => evaluate("={{ \"{'test1':1,'test2':'2'}\".parseJson() }}")).toThrowError(
"Parsing failed. Check you're using double quotes",
);
expect(() => evaluate('={{ "No JSON here".parseJson() }}')).toThrowError('Parsing failed');
});

test('.toBoolean should work on a string', () => {
Expand Down

0 comments on commit 8788e2a

Please sign in to comment.