Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(editor): Autocomplete info box: improve structure and add examples #9019

Merged
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
c381d89
Restyle info box + add args, examples
elsmr Apr 2, 2024
f6a6792
Add examples for String.includes
elsmr Apr 2, 2024
ac1e7b6
Disable closeOnBlur
elsmr Apr 2, 2024
e88f4b4
Infobox styling.
gandreini Apr 9, 2024
86575bb
Merge branch 'master' into node-1280-autocomplete-info-box-improve-st…
elsmr Apr 9, 2024
4bde4c8
Improve infobox DOM structure
elsmr Apr 9, 2024
56ae4e5
Add string extension docs
elsmr Apr 10, 2024
9e92b66
Extension methods tweaks
elsmr Apr 10, 2024
f9920d6
Infobox styling.
gandreini Apr 19, 2024
bea19e1
Merge branch 'master' into node-1280-autocomplete-info-box-improve-st…
elsmr Apr 19, 2024
a372082
Add all String examples/descriptions
elsmr Apr 19, 2024
e38663a
Re-enable closeOnBlur
elsmr Apr 19, 2024
7a64761
Add test for microseconds toDateTime
elsmr Apr 19, 2024
20332e0
Fix tests
elsmr Apr 22, 2024
181f2e3
Fix dollar completion info box layout
elsmr Apr 23, 2024
0704b0e
Styling improvements
elsmr Apr 23, 2024
c40ed94
Remove section from toDateTime
elsmr Apr 23, 2024
5ab4423
Review fixes
elsmr Apr 23, 2024
a8173e0
Replace unneeded innerHTML with textContent
elsmr Apr 25, 2024
3f1a834
Remove type annotations to improve typing
elsmr Apr 25, 2024
6efb364
Fix review remarks
elsmr Apr 25, 2024
1cc70ca
Merge branch 'master' into node-1280-autocomplete-info-box-improve-st…
elsmr Apr 26, 2024
93e98ed
Hide autocomplete in e2e test
elsmr Apr 26, 2024
9c80c4f
Fix code node autocomplete styling
elsmr Apr 26, 2024
baf0b17
Minor style tweaks.
gandreini Apr 29, 2024
d966bcd
Fix review feedback
elsmr May 2, 2024
fa58b9a
Infobox CSS improvements.
gandreini May 2, 2024
70e48f6
Merge branch 'node-1280-autocomplete-info-box-improve-structure-and-a…
gandreini May 2, 2024
04e72d5
Render examples section with 1 border
elsmr May 2, 2024
1329425
Hide docURL
elsmr May 3, 2024
d507efc
Merge branch 'master' into node-1280-autocomplete-info-box-improve-st…
elsmr May 3, 2024
e3d550a
Infobox color for dark mode.
gandreini May 6, 2024
e8fba7f
Review fixes
elsmr May 7, 2024
47bfb55
Fix variadic methods, improve links style, bring back docURL
elsmr May 8, 2024
9a63353
Restore object sections
elsmr May 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ watchDebounced(
<style lang="scss" module>
.tip {
display: flex;
align-items: flex-start;
align-items: center;
gap: var(--spacing-4xs);
line-height: var(--font-line-height-regular);
color: var(--color-text-base);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,10 @@ describe('Luxon method completions', () => {
vi.spyOn(workflowHelpers, 'resolveParameter').mockReturnValueOnce(DateTime.now());

expect(completions('{{ $now.| }}')).toHaveLength(
uniqBy(luxonInstanceOptions().concat(extensions('date')), (option) => option.label).length +
LUXON_RECOMMENDED_OPTIONS.length,
uniqBy(
luxonInstanceOptions().concat(extensions({ typeName: 'date' })),
(option) => option.label,
).length + LUXON_RECOMMENDED_OPTIONS.length,
);
});

Expand All @@ -140,8 +142,10 @@ describe('Luxon method completions', () => {
vi.spyOn(workflowHelpers, 'resolveParameter').mockReturnValueOnce(DateTime.now());

expect(completions('{{ $today.| }}')).toHaveLength(
uniqBy(luxonInstanceOptions().concat(extensions('date')), (option) => option.label).length +
LUXON_RECOMMENDED_OPTIONS.length,
uniqBy(
luxonInstanceOptions().concat(extensions({ typeName: 'date' })),
(option) => option.label,
).length + LUXON_RECOMMENDED_OPTIONS.length,
);
});
});
Expand All @@ -153,7 +157,9 @@ describe('Resolution-based completions', () => {
vi.spyOn(workflowHelpers, 'resolveParameter').mockReturnValueOnce('abc');

expect(completions('{{ "abc".| }}')).toHaveLength(
natives('string').length + extensions('string').length + STRING_RECOMMENDED_OPTIONS.length,
natives({ typeName: 'string' }).length +
extensions({ typeName: 'string' }).length +
STRING_RECOMMENDED_OPTIONS.length,
);
});

Expand All @@ -163,15 +169,19 @@ describe('Resolution-based completions', () => {

const result = completions('{{ "You \'owe\' me 200$".| }}');

expect(result).toHaveLength(natives('string').length + extensions('string').length + 1);
expect(result).toHaveLength(
natives({ typeName: 'string' }).length + extensions({ typeName: 'string' }).length + 1,
);
});

test('should return completions for number literal: {{ (123).| }}', () => {
// @ts-expect-error Spied function is mistyped
vi.spyOn(workflowHelpers, 'resolveParameter').mockReturnValueOnce(123);

expect(completions('{{ (123).| }}')).toHaveLength(
natives('number').length + extensions('number').length + ['isEven()', 'isOdd()'].length,
natives({ typeName: 'number' }).length +
extensions({ typeName: 'number' }).length +
['isEven()', 'isOdd()'].length,
);
});

Expand All @@ -180,7 +190,7 @@ describe('Resolution-based completions', () => {
vi.spyOn(workflowHelpers, 'resolveParameter').mockReturnValueOnce([1, 2, 3]);

expect(completions('{{ [1, 2, 3].| }}')).toHaveLength(
natives('array').length + extensions('array').length,
natives({ typeName: 'array' }).length + extensions({ typeName: 'array' }).length,
);
});

Expand All @@ -192,7 +202,9 @@ describe('Resolution-based completions', () => {

if (!found) throw new Error('Expected to find completion');

expect(found).toHaveLength(natives('array').length + extensions('array').length);
expect(found).toHaveLength(
natives({ typeName: 'array' }).length + extensions({ typeName: 'array' }).length,
);
});

test('should return completions for object literal', () => {
Expand All @@ -201,7 +213,7 @@ describe('Resolution-based completions', () => {
vi.spyOn(workflowHelpers, 'resolveParameter').mockReturnValueOnce(object);

expect(completions('{{ ({ a: 1 }).| }}')).toHaveLength(
Object.keys(object).length + extensions('object').length,
Object.keys(object).length + extensions({ typeName: 'object' }).length,
);
});
});
Expand All @@ -212,7 +224,9 @@ describe('Resolution-based completions', () => {
vi.spyOn(workflowHelpers, 'resolveParameter').mockReturnValueOnce('a');

expect(completions('{{ "abc"[0].| }}')).toHaveLength(
natives('string').length + extensions('string').length + STRING_RECOMMENDED_OPTIONS.length,
natives({ typeName: 'string' }).length +
extensions({ typeName: 'string' }).length +
STRING_RECOMMENDED_OPTIONS.length,
);
});
});
Expand All @@ -225,7 +239,9 @@ describe('Resolution-based completions', () => {
const found = completions('{{ Math.abs($input.item.json.num1).| }}');
if (!found) throw new Error('Expected to find completions');
expect(found).toHaveLength(
extensions('number').length + natives('number').length + ['isEven()', 'isOdd()'].length,
extensions({ typeName: 'number' }).length +
natives({ typeName: 'number' }).length +
['isEven()', 'isOdd()'].length,
);
});

Expand All @@ -240,8 +256,10 @@ describe('Resolution-based completions', () => {
test('should return completions for complex expression: {{ $now.diff($now.diff($now.|)) }}', () => {
vi.spyOn(workflowHelpers, 'resolveParameter').mockReturnValueOnce(DateTime.now());
expect(completions('{{ $now.diff($now.diff($now.|)) }}')).toHaveLength(
uniqBy(luxonInstanceOptions().concat(extensions('date')), (option) => option.label).length +
LUXON_RECOMMENDED_OPTIONS.length,
uniqBy(
luxonInstanceOptions().concat(extensions({ typeName: 'date' })),
(option) => option.label,
).length + LUXON_RECOMMENDED_OPTIONS.length,
);
});

Expand All @@ -251,7 +269,9 @@ describe('Resolution-based completions', () => {
const found = completions('{{ $execution.resumeUrl.includes($json.|) }}');

if (!found) throw new Error('Expected to find completions');
expect(found).toHaveLength(Object.keys($json).length + extensions('object').length);
expect(found).toHaveLength(
Object.keys($json).length + extensions({ typeName: 'object' }).length,
);
});

test('should return completions for operation expression: {{ $now.day + $json. }}', () => {
Expand All @@ -261,7 +281,9 @@ describe('Resolution-based completions', () => {

if (!found) throw new Error('Expected to find completions');

expect(found).toHaveLength(Object.keys($json).length + extensions('object').length);
expect(found).toHaveLength(
Object.keys($json).length + extensions({ typeName: 'object' }).length,
);
});

test('should return completions for operation expression: {{ Math.abs($now.day) >= 10 ? $now : Math.abs($json.). }}', () => {
Expand All @@ -271,7 +293,9 @@ describe('Resolution-based completions', () => {

if (!found) throw new Error('Expected to find completions');

expect(found).toHaveLength(Object.keys($json).length + extensions('object').length);
expect(found).toHaveLength(
Object.keys($json).length + extensions({ typeName: 'object' }).length,
);
});
});

Expand All @@ -286,7 +310,9 @@ describe('Resolution-based completions', () => {
if (!found) throw new Error('Expected to find completions');

expect(found).toHaveLength(
extensions('string').length + natives('string').length + STRING_RECOMMENDED_OPTIONS.length,
extensions({ typeName: 'string' }).length +
natives({ typeName: 'string' }).length +
STRING_RECOMMENDED_OPTIONS.length,
);
expect(found.map((c) => c.label).every((l) => !l.endsWith('()')));
});
Expand All @@ -299,7 +325,9 @@ describe('Resolution-based completions', () => {
if (!found) throw new Error('Expected to find completions');

expect(found).toHaveLength(
extensions('number').length + natives('number').length + ['isEven()', 'isOdd()'].length,
extensions({ typeName: 'number' }).length +
natives({ typeName: 'number' }).length +
['isEven()', 'isOdd()'].length,
);
expect(found.map((c) => c.label).every((l) => !l.endsWith('()')));
});
Expand All @@ -311,7 +339,9 @@ describe('Resolution-based completions', () => {

if (!found) throw new Error('Expected to find completions');

expect(found).toHaveLength(extensions('array').length + natives('array').length);
expect(found).toHaveLength(
extensions({ typeName: 'array' }).length + natives({ typeName: 'array' }).length,
);
expect(found.map((c) => c.label).every((l) => !l.endsWith('()')));
});
});
Expand Down Expand Up @@ -339,7 +369,6 @@ describe('Resolution-based completions', () => {
{
info: expect.any(Function),
label: provider,
type: 'keyword',
apply: expect.any(Function),
},
]);
Expand All @@ -363,13 +392,11 @@ describe('Resolution-based completions', () => {
{
info: expect.any(Function),
label: secrets[0],
type: 'keyword',
apply: expect.any(Function),
},
{
info: expect.any(Function),
label: secrets[1],
type: 'keyword',
apply: expect.any(Function),
},
]);
Expand Down Expand Up @@ -445,71 +472,77 @@ describe('Resolution-based completions', () => {
vi.spyOn(workflowHelpers, 'resolveParameter').mockReturnValue([$input.item]);

expect(completions('{{ $input.all().| }}')).toHaveLength(
extensions('array').length + natives('array').length - ARRAY_NUMBER_ONLY_METHODS.length,
extensions({ typeName: 'array' }).length +
natives({ typeName: 'array' }).length -
ARRAY_NUMBER_ONLY_METHODS.length,
);
});

test("should return completions for: '{{ $input.item.| }}'", () => {
vi.spyOn(workflowHelpers, 'resolveParameter').mockReturnValue($input.item.json);

expect(completions('{{ $input.item.| }}')).toHaveLength(
Object.keys($input.item.json).length + extensions('object').length,
Object.keys($input.item.json).length + extensions({ typeName: 'object' }).length,
);
});

test("should return completions for: '{{ $input.first().| }}'", () => {
vi.spyOn(workflowHelpers, 'resolveParameter').mockReturnValue($input.first().json);

expect(completions('{{ $input.first().| }}')).toHaveLength(
Object.keys($input.first().json).length + extensions('object').length,
Object.keys($input.first().json).length + extensions({ typeName: 'object' }).length,
);
});

test("should return completions for: '{{ $input.last().| }}'", () => {
vi.spyOn(workflowHelpers, 'resolveParameter').mockReturnValue($input.last().json);

expect(completions('{{ $input.last().| }}')).toHaveLength(
Object.keys($input.last().json).length + extensions('object').length,
Object.keys($input.last().json).length + extensions({ typeName: 'object' }).length,
);
});

test("should return completions for: '{{ $input.all()[0].| }}'", () => {
vi.spyOn(workflowHelpers, 'resolveParameter').mockReturnValue($input.all()[0].json);

expect(completions('{{ $input.all()[0].| }}')).toHaveLength(
Object.keys($input.all()[0].json).length + extensions('object').length,
Object.keys($input.all()[0].json).length + extensions({ typeName: 'object' }).length,
);
});

test('should return completions for: {{ $input.item.json.str.| }}', () => {
vi.spyOn(workflowHelpers, 'resolveParameter').mockReturnValue($input.item.json.str);

expect(completions('{{ $input.item.json.str.| }}')).toHaveLength(
extensions('string').length + natives('string').length + STRING_RECOMMENDED_OPTIONS.length,
extensions({ typeName: 'string' }).length +
natives({ typeName: 'string' }).length +
STRING_RECOMMENDED_OPTIONS.length,
);
});

test('should return completions for: {{ $input.item.json.num.| }}', () => {
vi.spyOn(workflowHelpers, 'resolveParameter').mockReturnValue($input.item.json.num);

expect(completions('{{ $input.item.json.num.| }}')).toHaveLength(
extensions('number').length + natives('number').length + ['isEven()', 'isOdd()'].length,
extensions({ typeName: 'number' }).length +
natives({ typeName: 'number' }).length +
['isEven()', 'isOdd()'].length,
);
});

test('should return completions for: {{ $input.item.json.arr.| }}', () => {
vi.spyOn(workflowHelpers, 'resolveParameter').mockReturnValue($input.item.json.arr);

expect(completions('{{ $input.item.json.arr.| }}')).toHaveLength(
extensions('array').length + natives('array').length,
extensions({ typeName: 'array' }).length + natives({ typeName: 'array' }).length,
);
});

test('should return completions for: {{ $input.item.json.obj.| }}', () => {
vi.spyOn(workflowHelpers, 'resolveParameter').mockReturnValue($input.item.json.obj);

expect(completions('{{ $input.item.json.obj.| }}')).toHaveLength(
Object.keys($input.item.json.obj).length + extensions('object').length,
Object.keys($input.item.json.obj).length + extensions({ typeName: 'object' }).length,
);
});
});
Expand Down Expand Up @@ -591,15 +624,12 @@ describe('Resolution-based completions', () => {
);
});

test('should recommend toInt(),toFloat() for: {{ "5.3".| }}', () => {
test('should recommend toNumber() for: {{ "5.3".| }}', () => {
// @ts-expect-error Spied function is mistyped
vi.spyOn(workflowHelpers, 'resolveParameter').mockReturnValueOnce('5.3');
const options = completions('{{ "5.3".| }}');
expect(options?.[0]).toEqual(
expect.objectContaining({ label: 'toInt()', section: RECOMMENDED_SECTION }),
);
expect(options?.[1]).toEqual(
expect.objectContaining({ label: 'toFloat()', section: RECOMMENDED_SECTION }),
expect.objectContaining({ label: 'toNumber()', section: RECOMMENDED_SECTION }),
);
});

Expand Down Expand Up @@ -659,25 +689,25 @@ describe('Resolution-based completions', () => {
);
});

test('should recommend toDateTime("s") for: {{ (1900062210).| }}', () => {
test("should recommend toDateTime('s') for: {{ (1900062210).| }}", () => {
vi.spyOn(workflowHelpers, 'resolveParameter').mockReturnValueOnce(
// @ts-expect-error Spied function is mistyped
1900062210,
);
const options = completions('{{ (1900062210).| }}');
expect(options?.[0]).toEqual(
expect.objectContaining({ label: 'toDateTime("s")', section: RECOMMENDED_SECTION }),
expect.objectContaining({ label: "toDateTime('s')", section: RECOMMENDED_SECTION }),
);
});

test('should recommend toDateTime("ms") for: {{ (1900062210000).| }}', () => {
test("should recommend toDateTime('ms') for: {{ (1900062210000).| }}", () => {
vi.spyOn(workflowHelpers, 'resolveParameter').mockReturnValueOnce(
// @ts-expect-error Spied function is mistyped
1900062210000,
);
const options = completions('{{ (1900062210000).| }}');
expect(options?.[0]).toEqual(
expect.objectContaining({ label: 'toDateTime("ms")', section: RECOMMENDED_SECTION }),
expect.objectContaining({ label: "toDateTime('ms')", section: RECOMMENDED_SECTION }),
);
});

Expand Down Expand Up @@ -714,7 +744,9 @@ describe('Resolution-based completions', () => {

const result = completions('{{ $json.foo| }}', true);
expect(result).toHaveLength(
extensions('string').length + natives('string').length + STRING_RECOMMENDED_OPTIONS.length,
extensions({ typeName: 'string' }).length +
natives({ typeName: 'string' }).length +
STRING_RECOMMENDED_OPTIONS.length,
);
});
});
Expand Down
Loading
Loading