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 {
|
||||
return this.displayMode === 'schema';
|
||||
},
|
||||
isInputSchemaView(): boolean {
|
||||
return this.isSchemaView && this.paneType === 'input';
|
||||
displaysMultipleNodes(): boolean {
|
||||
return this.isSchemaView && this.paneType === 'input' && this.nodes.length > 0;
|
||||
},
|
||||
isTriggerNode(): boolean {
|
||||
if (this.node === null) {
|
||||
|
@ -1307,7 +1307,7 @@ export default defineComponent({
|
|||
</div>
|
||||
|
||||
<div
|
||||
v-if="maxRunIndex > 0 && !isInputSchemaView"
|
||||
v-if="maxRunIndex > 0 && !displaysMultipleNodes"
|
||||
v-show="!editMode.enabled"
|
||||
:class="$style.runSelector"
|
||||
>
|
||||
|
@ -1349,7 +1349,7 @@ export default defineComponent({
|
|||
<slot name="run-info"></slot>
|
||||
</div>
|
||||
|
||||
<slot v-if="!isInputSchemaView" name="before-data" />
|
||||
<slot v-if="!displaysMultipleNodes" name="before-data" />
|
||||
|
||||
<n8n-callout
|
||||
v-for="hint in getNodeHints()"
|
||||
|
@ -1361,7 +1361,7 @@ export default defineComponent({
|
|||
</n8n-callout>
|
||||
|
||||
<div
|
||||
v-if="maxOutputIndex > 0 && branches.length > 1 && !isInputSchemaView"
|
||||
v-if="maxOutputIndex > 0 && branches.length > 1 && !displaysMultipleNodes"
|
||||
:class="$style.outputs"
|
||||
data-test-id="branches"
|
||||
>
|
||||
|
@ -1382,7 +1382,7 @@ export default defineComponent({
|
|||
hasNodeRun &&
|
||||
((dataCount > 0 && maxRunIndex === 0) || search) &&
|
||||
!isArtificialRecoveredEventItem &&
|
||||
!isInputSchemaView
|
||||
!displaysMultipleNodes
|
||||
"
|
||||
v-show="!editMode.enabled && !hasRunError"
|
||||
:class="[$style.itemsCount, { [$style.muted]: paneType === 'input' && maxRunIndex === 0 }]"
|
||||
|
@ -1443,12 +1443,15 @@ export default defineComponent({
|
|||
<slot name="node-waiting">xxx</slot>
|
||||
</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>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-else-if="paneType === 'input' && !isInputSchemaView && node?.disabled"
|
||||
v-else-if="paneType === 'input' && !displaysMultipleNodes && node?.disabled"
|
||||
:class="$style.center"
|
||||
>
|
||||
<n8n-text>
|
||||
|
|
|
@ -95,7 +95,7 @@ const nodes = computed(() => {
|
|||
|
||||
return {
|
||||
node: fullNode,
|
||||
connectedOutputIndexes: node.indicies,
|
||||
connectedOutputIndexes: node.indicies.length > 0 ? node.indicies : [0],
|
||||
depth: node.depth,
|
||||
itemsCount,
|
||||
nodeType,
|
||||
|
@ -264,7 +264,10 @@ watch(
|
|||
</script>
|
||||
|
||||
<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">
|
||||
<n8n-text tag="h3" size="large">{{
|
||||
$locale.baseText('ndv.search.noNodeMatch.title')
|
||||
|
|
|
@ -44,13 +44,20 @@ const ifNode = createTestNode({
|
|||
disabled: false,
|
||||
});
|
||||
|
||||
const aiTool = createTestNode({
|
||||
name: 'AI Tool',
|
||||
type: '@n8n/n8n-nodes-langchain.memoryBufferWindow',
|
||||
typeVersion: 1,
|
||||
disabled: false,
|
||||
});
|
||||
|
||||
async function setupStore() {
|
||||
const workflow = mock<IWorkflowDb>({
|
||||
id: '123',
|
||||
name: 'Test Workflow',
|
||||
connections: {},
|
||||
active: true,
|
||||
nodes: [mockNode1, mockNode2, disabledNode, ifNode],
|
||||
nodes: [mockNode1, mockNode2, disabledNode, ifNode, aiTool],
|
||||
});
|
||||
|
||||
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: [] }]]])(
|
||||
'renders schema instead of showing no data for %o',
|
||||
(data) => {
|
||||
|
|
|
@ -1,5 +1,295 @@
|
|||
// 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`] = `
|
||||
<div
|
||||
class="schema animated"
|
||||
|
|
Loading…
Reference in a new issue