Skip to content

Commit

Permalink
fix(editor): Use correct output for connected nodes in schema view (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
elsmr authored Sep 24, 2024
1 parent a81256a commit ad60d49
Show file tree
Hide file tree
Showing 3 changed files with 1,571 additions and 23 deletions.
29 changes: 15 additions & 14 deletions packages/editor-ui/src/components/RunDataSchema.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type SchemaNode = {
depth: number;
loading: boolean;
open: boolean;
connectedOutputIndexes: number[];
itemsCount: number | null;
schema: Schema | null;
};
Expand Down Expand Up @@ -94,6 +95,7 @@ const nodes = computed(() => {
return {
node: fullNode,
connectedOutputIndexes: node.indicies,
depth: node.depth,
itemsCount,
nodeType,
Expand Down Expand Up @@ -141,27 +143,26 @@ const highlight = computed(() => ndvStore.highlightDraggables);
const allNodesOpen = computed(() => nodes.value.every((node) => node.open));
const noNodesOpen = computed(() => nodes.value.every((node) => !node.open));
const loadNodeData = async (node: INodeUi) => {
const loadNodeData = async ({ node, connectedOutputIndexes }: SchemaNode) => {
const pinData = workflowsStore.pinDataByNodeName(node.name);
const data =
pinData ??
executionDataToJson(
getNodeInputData(
node,
props.runIndex,
props.outputIndex,
props.paneType,
props.connectionType,
) ?? [],
);
connectedOutputIndexes
.map((outputIndex) =>
executionDataToJson(
getNodeInputData(node, props.runIndex, outputIndex, props.paneType, props.connectionType),
),
)
.flat();
nodesData.value[node.name] = {
schema: getSchemaForExecutionData(data),
itemsCount: data.length,
};
};
const toggleOpenNode = async ({ node, schema, open }: SchemaNode, exclusive = false) => {
const toggleOpenNode = async (schemaNode: SchemaNode, exclusive = false) => {
const { node, schema, open } = schemaNode;
disableScrollInView.value = false;
if (open) {
nodesOpen.value[node.name] = false;
Expand All @@ -170,7 +171,7 @@ const toggleOpenNode = async ({ node, schema, open }: SchemaNode, exclusive = fa
if (!schema) {
nodesLoading.value[node.name] = true;
await loadNodeData(node);
await loadNodeData(schemaNode);
nodesLoading.value[node.name] = false;
}
Expand All @@ -182,8 +183,8 @@ const toggleOpenNode = async ({ node, schema, open }: SchemaNode, exclusive = fa
};
const openAllNodes = async () => {
const nodesToLoad = nodes.value.filter((node) => !node.schema).map(({ node }) => node);
await Promise.all(nodesToLoad.map(async (node) => await loadNodeData(node)));
const nodesToLoad = nodes.value.filter((node) => !node.schema);
await Promise.all(nodesToLoad.map(loadNodeData));
nodesOpen.value = Object.fromEntries(nodes.value.map(({ node }) => [node.name, true]));
};
Expand Down
68 changes: 62 additions & 6 deletions packages/editor-ui/src/components/__tests__/RunDataSchema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@ import { createComponentRenderer } from '@/__tests__/render';
import RunDataJsonSchema from '@/components/RunDataSchema.vue';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { userEvent } from '@testing-library/user-event';
import { cleanup, within } from '@testing-library/vue';
import { cleanup, within, waitFor } from '@testing-library/vue';
import { createPinia, setActivePinia } from 'pinia';
import { createTestNode, defaultNodeDescriptions } from '@/__tests__/mocks';
import { SET_NODE_TYPE } from '@/constants';
import {
createTestNode,
defaultNodeDescriptions,
mockNodeTypeDescription,
} from '@/__tests__/mocks';
import { IF_NODE_TYPE, SET_NODE_TYPE } from '@/constants';
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
import { mock } from 'vitest-mock-extended';
import type { IWorkflowDb } from '@/Interface';
import { NodeConnectionType, type IDataObject } from 'n8n-workflow';
import * as nodeHelpers from '@/composables/useNodeHelpers';

const mockNode1 = createTestNode({
name: 'Set1',
Expand All @@ -31,13 +37,20 @@ const disabledNode = createTestNode({
disabled: true,
});

const ifNode = createTestNode({
name: 'If',
type: IF_NODE_TYPE,
typeVersion: 1,
disabled: false,
});

async function setupStore() {
const workflow = mock<IWorkflowDb>({
id: '123',
name: 'Test Workflow',
connections: {},
active: true,
nodes: [mockNode1, mockNode2, disabledNode],
nodes: [mockNode1, mockNode2, disabledNode, ifNode],
});

const pinia = createPinia();
Expand All @@ -46,12 +59,33 @@ async function setupStore() {
const workflowsStore = useWorkflowsStore();
const nodeTypesStore = useNodeTypesStore();

nodeTypesStore.setNodeTypes(defaultNodeDescriptions);
nodeTypesStore.setNodeTypes([
...defaultNodeDescriptions,
mockNodeTypeDescription({
name: IF_NODE_TYPE,
outputs: [NodeConnectionType.Main, NodeConnectionType.Main],
}),
]);
workflowsStore.workflow = workflow;

return pinia;
}

function mockNodeOutputData(nodeName: string, data: IDataObject[], outputIndex = 0) {
const originalNodeHelpers = nodeHelpers.useNodeHelpers();
vi.spyOn(nodeHelpers, 'useNodeHelpers').mockImplementation(() => {
return {
...originalNodeHelpers,
getNodeInputData: vi.fn((node, _, output) => {
if (node.name === nodeName && output === outputIndex) {
return data.map((json) => ({ json }));
}
return [];
}),
};
});
}

describe('RunDataSchema.vue', () => {
let renderComponent: ReturnType<typeof createComponentRenderer>;

Expand Down Expand Up @@ -122,7 +156,7 @@ describe('RunDataSchema.vue', () => {
expect(within(nodes[1]).getByTestId('run-data-schema-node-schema')).toMatchSnapshot();
});

it('renders schema for in output pane', async () => {
it('renders schema in output pane', async () => {
const { container } = renderComponent({
props: {
nodes: [],
Expand Down Expand Up @@ -183,6 +217,28 @@ describe('RunDataSchema.vue', () => {
);
});

it('renders schema for correct output branch', async () => {
mockNodeOutputData(
'If',
[
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' },
],
1,
);
const { getByTestId } = renderComponent({
props: {
nodes: [{ name: 'If', indicies: [1], depth: 2 }],
},
});

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();
});
});

test.each([[[{ tx: false }, { tx: false }]], [[{ tx: '' }, { tx: '' }]], [[{ tx: [] }]]])(
'renders schema instead of showing no data for %o',
(data) => {
Expand Down
Loading

0 comments on commit ad60d49

Please sign in to comment.