mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
fix(editor): Fix schema view in AI tools (#11089)
Some checks are pending
Test Master / install-and-build (push) Waiting to run
Test Master / Unit tests (18.x) (push) Blocked by required conditions
Test Master / Unit tests (20.x) (push) Blocked by required conditions
Test Master / Unit tests (22.4) (push) Blocked by required conditions
Test Master / Lint (push) Blocked by required conditions
Test Master / Notify Slack on failure (push) Blocked by required conditions
Some checks are pending
Test Master / install-and-build (push) Waiting to run
Test Master / Unit tests (18.x) (push) Blocked by required conditions
Test Master / Unit tests (20.x) (push) Blocked by required conditions
Test Master / Unit tests (22.4) (push) Blocked by required conditions
Test Master / Lint (push) Blocked by required conditions
Test Master / Notify Slack on failure (push) Blocked by required conditions
This commit is contained in:
parent
cc009559ee
commit
09cfdbd181
|
@ -246,8 +246,8 @@ export default defineComponent({
|
||||||
isSchemaView(): boolean {
|
isSchemaView(): boolean {
|
||||||
return this.displayMode === 'schema';
|
return this.displayMode === 'schema';
|
||||||
},
|
},
|
||||||
isInputSchemaView(): boolean {
|
displaysMultipleNodes(): boolean {
|
||||||
return this.isSchemaView && this.paneType === 'input';
|
return this.isSchemaView && this.paneType === 'input' && this.nodes.length > 0;
|
||||||
},
|
},
|
||||||
isTriggerNode(): boolean {
|
isTriggerNode(): boolean {
|
||||||
if (this.node === null) {
|
if (this.node === null) {
|
||||||
|
@ -1307,7 +1307,7 @@ export default defineComponent({
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="maxRunIndex > 0 && !isInputSchemaView"
|
v-if="maxRunIndex > 0 && !displaysMultipleNodes"
|
||||||
v-show="!editMode.enabled"
|
v-show="!editMode.enabled"
|
||||||
:class="$style.runSelector"
|
:class="$style.runSelector"
|
||||||
>
|
>
|
||||||
|
@ -1349,7 +1349,7 @@ export default defineComponent({
|
||||||
<slot name="run-info"></slot>
|
<slot name="run-info"></slot>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<slot v-if="!isInputSchemaView" name="before-data" />
|
<slot v-if="!displaysMultipleNodes" name="before-data" />
|
||||||
|
|
||||||
<n8n-callout
|
<n8n-callout
|
||||||
v-for="hint in getNodeHints()"
|
v-for="hint in getNodeHints()"
|
||||||
|
@ -1361,7 +1361,7 @@ export default defineComponent({
|
||||||
</n8n-callout>
|
</n8n-callout>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="maxOutputIndex > 0 && branches.length > 1 && !isInputSchemaView"
|
v-if="maxOutputIndex > 0 && branches.length > 1 && !displaysMultipleNodes"
|
||||||
:class="$style.outputs"
|
:class="$style.outputs"
|
||||||
data-test-id="branches"
|
data-test-id="branches"
|
||||||
>
|
>
|
||||||
|
@ -1382,7 +1382,7 @@ export default defineComponent({
|
||||||
hasNodeRun &&
|
hasNodeRun &&
|
||||||
((dataCount > 0 && maxRunIndex === 0) || search) &&
|
((dataCount > 0 && maxRunIndex === 0) || search) &&
|
||||||
!isArtificialRecoveredEventItem &&
|
!isArtificialRecoveredEventItem &&
|
||||||
!isInputSchemaView
|
!displaysMultipleNodes
|
||||||
"
|
"
|
||||||
v-show="!editMode.enabled && !hasRunError"
|
v-show="!editMode.enabled && !hasRunError"
|
||||||
:class="[$style.itemsCount, { [$style.muted]: paneType === 'input' && maxRunIndex === 0 }]"
|
:class="[$style.itemsCount, { [$style.muted]: paneType === 'input' && maxRunIndex === 0 }]"
|
||||||
|
@ -1443,12 +1443,15 @@ export default defineComponent({
|
||||||
<slot name="node-waiting">xxx</slot>
|
<slot name="node-waiting">xxx</slot>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-else-if="!hasNodeRun && !(isInputSchemaView && node?.disabled)" :class="$style.center">
|
<div
|
||||||
|
v-else-if="!hasNodeRun && !(displaysMultipleNodes && node?.disabled)"
|
||||||
|
:class="$style.center"
|
||||||
|
>
|
||||||
<slot name="node-not-run"></slot>
|
<slot name="node-not-run"></slot>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-else-if="paneType === 'input' && !isInputSchemaView && node?.disabled"
|
v-else-if="paneType === 'input' && !displaysMultipleNodes && node?.disabled"
|
||||||
:class="$style.center"
|
:class="$style.center"
|
||||||
>
|
>
|
||||||
<n8n-text>
|
<n8n-text>
|
||||||
|
|
|
@ -95,7 +95,7 @@ const nodes = computed(() => {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
node: fullNode,
|
node: fullNode,
|
||||||
connectedOutputIndexes: node.indicies,
|
connectedOutputIndexes: node.indicies.length > 0 ? node.indicies : [0],
|
||||||
depth: node.depth,
|
depth: node.depth,
|
||||||
itemsCount,
|
itemsCount,
|
||||||
nodeType,
|
nodeType,
|
||||||
|
@ -264,7 +264,10 @@ watch(
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-if="paneType === 'input'" :class="[$style.schemaWrapper, { highlightSchema: highlight }]">
|
<div
|
||||||
|
v-if="paneType === 'input' && nodes.length > 0"
|
||||||
|
:class="[$style.schemaWrapper, { highlightSchema: highlight }]"
|
||||||
|
>
|
||||||
<div v-if="search && nodes.length > 0 && filteredNodes.length === 0" :class="$style.noMatch">
|
<div v-if="search && nodes.length > 0 && filteredNodes.length === 0" :class="$style.noMatch">
|
||||||
<n8n-text tag="h3" size="large">{{
|
<n8n-text tag="h3" size="large">{{
|
||||||
$locale.baseText('ndv.search.noNodeMatch.title')
|
$locale.baseText('ndv.search.noNodeMatch.title')
|
||||||
|
|
|
@ -44,13 +44,20 @@ const ifNode = createTestNode({
|
||||||
disabled: false,
|
disabled: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const aiTool = createTestNode({
|
||||||
|
name: 'AI Tool',
|
||||||
|
type: '@n8n/n8n-nodes-langchain.memoryBufferWindow',
|
||||||
|
typeVersion: 1,
|
||||||
|
disabled: false,
|
||||||
|
});
|
||||||
|
|
||||||
async function setupStore() {
|
async function setupStore() {
|
||||||
const workflow = mock<IWorkflowDb>({
|
const workflow = mock<IWorkflowDb>({
|
||||||
id: '123',
|
id: '123',
|
||||||
name: 'Test Workflow',
|
name: 'Test Workflow',
|
||||||
connections: {},
|
connections: {},
|
||||||
active: true,
|
active: true,
|
||||||
nodes: [mockNode1, mockNode2, disabledNode, ifNode],
|
nodes: [mockNode1, mockNode2, disabledNode, ifNode, aiTool],
|
||||||
});
|
});
|
||||||
|
|
||||||
const pinia = createPinia();
|
const pinia = createPinia();
|
||||||
|
@ -239,6 +246,49 @@ describe('RunDataSchema.vue', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('renders previous nodes schema for AI tools', async () => {
|
||||||
|
mockNodeOutputData(
|
||||||
|
'If',
|
||||||
|
[
|
||||||
|
{ id: 1, name: 'John' },
|
||||||
|
{ id: 2, name: 'Jane' },
|
||||||
|
],
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
const { getByTestId } = renderComponent({
|
||||||
|
props: {
|
||||||
|
nodes: [
|
||||||
|
{
|
||||||
|
name: 'If',
|
||||||
|
indicies: [], // indicies are not set for AI tools
|
||||||
|
depth: 2,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
node: aiTool,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(getByTestId('run-data-schema-node-name')).toHaveTextContent('If');
|
||||||
|
expect(getByTestId('run-data-schema-node-item-count')).toHaveTextContent('2 items');
|
||||||
|
expect(getByTestId('run-data-schema-node-schema')).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders its own data for AI tools in debug mode', async () => {
|
||||||
|
const { getByTestId } = renderComponent({
|
||||||
|
props: {
|
||||||
|
nodes: [], // in debug mode nodes are empty
|
||||||
|
node: aiTool,
|
||||||
|
data: [{ output: 'AI tool output' }],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(getByTestId('run-data-schema-node-schema')).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test.each([[[{ tx: false }, { tx: false }]], [[{ tx: '' }, { tx: '' }]], [[{ tx: [] }]]])(
|
test.each([[[{ tx: false }, { tx: false }]], [[{ tx: '' }, { tx: '' }]], [[{ tx: [] }]]])(
|
||||||
'renders schema instead of showing no data for %o',
|
'renders schema instead of showing no data for %o',
|
||||||
(data) => {
|
(data) => {
|
||||||
|
|
|
@ -1,5 +1,295 @@
|
||||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||||
|
|
||||||
|
exports[`RunDataSchema.vue > renders its own data for AI tools in debug mode 1`] = `
|
||||||
|
<div
|
||||||
|
class="schema"
|
||||||
|
data-test-id="run-data-schema-node-schema"
|
||||||
|
data-v-46dade00=""
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="item"
|
||||||
|
data-test-id="run-data-schema-item"
|
||||||
|
data-v-46dade00=""
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="itemContent"
|
||||||
|
>
|
||||||
|
<!--v-if-->
|
||||||
|
<!--v-if-->
|
||||||
|
</div>
|
||||||
|
<!--v-if-->
|
||||||
|
<!--v-if-->
|
||||||
|
<div
|
||||||
|
class="sub"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="innerSub"
|
||||||
|
>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="item"
|
||||||
|
data-test-id="run-data-schema-item"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="itemContent"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="pill mappable"
|
||||||
|
title="string"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="label"
|
||||||
|
data-depth="1"
|
||||||
|
data-name="output"
|
||||||
|
data-path=".output"
|
||||||
|
data-target="mappable"
|
||||||
|
data-value="{{ $json.output }}"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="svg-inline--fa fa-font fa-w-14 fa-sm"
|
||||||
|
data-icon="font"
|
||||||
|
data-prefix="fas"
|
||||||
|
focusable="false"
|
||||||
|
role="img"
|
||||||
|
viewBox="0 0 448 512"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
class=""
|
||||||
|
d="M432 416h-23.41L277.88 53.69A32 32 0 0 0 247.58 32h-47.16a32 32 0 0 0-30.3 21.69L39.41 416H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h128a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16h-19.58l23.3-64h152.56l23.3 64H304a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h128a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM176.85 272L224 142.51 271.15 272z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<!--v-if-->
|
||||||
|
<span
|
||||||
|
class="content"
|
||||||
|
>
|
||||||
|
|
||||||
|
<span>
|
||||||
|
<!--v-if-->
|
||||||
|
output
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
class="text"
|
||||||
|
data-test-id="run-data-schema-item-value"
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
<!--v-if-->
|
||||||
|
<span
|
||||||
|
class="content"
|
||||||
|
>
|
||||||
|
|
||||||
|
<span>
|
||||||
|
<!--v-if-->
|
||||||
|
AI tool output
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
|
||||||
|
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<!--v-if-->
|
||||||
|
<!--v-if-->
|
||||||
|
<!--v-if-->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`RunDataSchema.vue > renders previous nodes schema for AI tools 1`] = `
|
||||||
|
<div
|
||||||
|
class="schema animated"
|
||||||
|
data-test-id="run-data-schema-node-schema"
|
||||||
|
data-v-46dade00=""
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="innerSchema"
|
||||||
|
data-v-46dade00=""
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="item"
|
||||||
|
data-test-id="run-data-schema-item"
|
||||||
|
data-v-46dade00=""
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="itemContent"
|
||||||
|
>
|
||||||
|
<!--v-if-->
|
||||||
|
<!--v-if-->
|
||||||
|
</div>
|
||||||
|
<!--v-if-->
|
||||||
|
<!--v-if-->
|
||||||
|
<div
|
||||||
|
class="sub"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="innerSub"
|
||||||
|
>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="item"
|
||||||
|
data-test-id="run-data-schema-item"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="itemContent"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="pill mappable"
|
||||||
|
title="number"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="label"
|
||||||
|
data-depth="1"
|
||||||
|
data-name="id"
|
||||||
|
data-path=".id"
|
||||||
|
data-target="mappable"
|
||||||
|
data-value="{{ $('If').item.json.id }}"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="svg-inline--fa fa-hashtag fa-w-14 fa-sm"
|
||||||
|
data-icon="hashtag"
|
||||||
|
data-prefix="fas"
|
||||||
|
focusable="false"
|
||||||
|
role="img"
|
||||||
|
viewBox="0 0 448 512"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
class=""
|
||||||
|
d="M440.667 182.109l7.143-40c1.313-7.355-4.342-14.109-11.813-14.109h-74.81l14.623-81.891C377.123 38.754 371.468 32 363.997 32h-40.632a12 12 0 0 0-11.813 9.891L296.175 128H197.54l14.623-81.891C213.477 38.754 207.822 32 200.35 32h-40.632a12 12 0 0 0-11.813 9.891L132.528 128H53.432a12 12 0 0 0-11.813 9.891l-7.143 40C33.163 185.246 38.818 192 46.289 192h74.81L98.242 320H19.146a12 12 0 0 0-11.813 9.891l-7.143 40C-1.123 377.246 4.532 384 12.003 384h74.81L72.19 465.891C70.877 473.246 76.532 480 84.003 480h40.632a12 12 0 0 0 11.813-9.891L151.826 384h98.634l-14.623 81.891C234.523 473.246 240.178 480 247.65 480h40.632a12 12 0 0 0 11.813-9.891L315.472 384h79.096a12 12 0 0 0 11.813-9.891l7.143-40c1.313-7.355-4.342-14.109-11.813-14.109h-74.81l22.857-128h79.096a12 12 0 0 0 11.813-9.891zM261.889 320h-98.634l22.857-128h98.634l-22.857 128z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<!--v-if-->
|
||||||
|
<span
|
||||||
|
class="content"
|
||||||
|
>
|
||||||
|
|
||||||
|
<span>
|
||||||
|
<!--v-if-->
|
||||||
|
id
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
class="text"
|
||||||
|
data-test-id="run-data-schema-item-value"
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
<!--v-if-->
|
||||||
|
<span
|
||||||
|
class="content"
|
||||||
|
>
|
||||||
|
|
||||||
|
<span>
|
||||||
|
<!--v-if-->
|
||||||
|
1
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
|
||||||
|
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<!--v-if-->
|
||||||
|
<!--v-if-->
|
||||||
|
<!--v-if-->
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="item"
|
||||||
|
data-test-id="run-data-schema-item"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="itemContent"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="pill mappable"
|
||||||
|
title="string"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="label"
|
||||||
|
data-depth="1"
|
||||||
|
data-name="name"
|
||||||
|
data-path=".name"
|
||||||
|
data-target="mappable"
|
||||||
|
data-value="{{ $('If').item.json.name }}"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="svg-inline--fa fa-font fa-w-14 fa-sm"
|
||||||
|
data-icon="font"
|
||||||
|
data-prefix="fas"
|
||||||
|
focusable="false"
|
||||||
|
role="img"
|
||||||
|
viewBox="0 0 448 512"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
class=""
|
||||||
|
d="M432 416h-23.41L277.88 53.69A32 32 0 0 0 247.58 32h-47.16a32 32 0 0 0-30.3 21.69L39.41 416H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h128a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16h-19.58l23.3-64h152.56l23.3 64H304a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h128a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM176.85 272L224 142.51 271.15 272z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<!--v-if-->
|
||||||
|
<span
|
||||||
|
class="content"
|
||||||
|
>
|
||||||
|
|
||||||
|
<span>
|
||||||
|
<!--v-if-->
|
||||||
|
name
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
class="text"
|
||||||
|
data-test-id="run-data-schema-item-value"
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
<!--v-if-->
|
||||||
|
<span
|
||||||
|
class="content"
|
||||||
|
>
|
||||||
|
|
||||||
|
<span>
|
||||||
|
<!--v-if-->
|
||||||
|
John
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
|
||||||
|
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<!--v-if-->
|
||||||
|
<!--v-if-->
|
||||||
|
<!--v-if-->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`RunDataSchema.vue > renders schema for correct output branch 1`] = `
|
exports[`RunDataSchema.vue > renders schema for correct output branch 1`] = `
|
||||||
<div
|
<div
|
||||||
class="schema animated"
|
class="schema animated"
|
||||||
|
|
Loading…
Reference in a new issue