From 57dfefd0f6d9c9612bb77aab02c4b00e7c96a7dc Mon Sep 17 00:00:00 2001 From: Alex Grozav Date: Thu, 11 Jul 2024 13:03:46 +0300 Subject: [PATCH] feat(editor): Add support for fallback nodes and new addNodes node render type in new canvas (no-changelog) (#10004) --- .../editor-ui/src/__tests__/data/canvas.ts | 19 +- .../src/components/canvas/Canvas.spec.ts | 18 +- .../src/components/canvas/Canvas.vue | 18 +- .../src/components/canvas/WorkflowCanvas.vue | 37 +++- ...pec.ts => CanvasRunWorkflowButton.spec.ts} | 6 +- ...Button.vue => CanvasRunWorkflowButton.vue} | 6 + .../CanvasRunWorkflowButton.spec.ts.snap | 7 + .../canvas/elements/nodes/CanvasNode.vue | 20 ++- .../elements/nodes/CanvasNodeRenderer.spec.ts | 5 +- .../elements/nodes/CanvasNodeRenderer.vue | 5 + .../elements/nodes/CanvasNodeToolbar.spec.ts | 3 +- .../nodes/render-types/CanvasNodeAddNodes.vue | 96 +++++++++++ .../render-types/CanvasNodeDefault.spec.ts | 11 +- .../__tests__/useCanvasOperations.spec.ts | 4 +- .../__tests__/useNodeConnections.spec.ts | 34 ++-- .../src/composables/useCanvasMapping.spec.ts | 163 ++++++++++-------- .../src/composables/useCanvasMapping.ts | 115 ++++++------ .../src/composables/useCanvasNode.spec.ts | 3 +- .../src/composables/useCanvasNode.ts | 7 +- .../src/composables/useCanvasOperations.ts | 4 +- .../src/composables/useNodeConnections.ts | 8 +- .../editor-ui/src/stores/nodeCreator.store.ts | 12 ++ packages/editor-ui/src/types/canvas.ts | 32 +++- packages/editor-ui/src/views/NodeView.v2.vue | 100 ++++++++++- 24 files changed, 509 insertions(+), 224 deletions(-) rename packages/editor-ui/src/components/canvas/elements/buttons/{CanvasExecuteWorkflowButton.spec.ts => CanvasRunWorkflowButton.spec.ts} (77%) rename packages/editor-ui/src/components/canvas/elements/buttons/{CanvasExecuteWorkflowButton.vue => CanvasRunWorkflowButton.vue} (83%) create mode 100644 packages/editor-ui/src/components/canvas/elements/buttons/__snapshots__/CanvasRunWorkflowButton.spec.ts.snap create mode 100644 packages/editor-ui/src/components/canvas/elements/nodes/render-types/CanvasNodeAddNodes.vue diff --git a/packages/editor-ui/src/__tests__/data/canvas.ts b/packages/editor-ui/src/__tests__/data/canvas.ts index e5ccb071a5..b7ac64fedc 100644 --- a/packages/editor-ui/src/__tests__/data/canvas.ts +++ b/packages/editor-ui/src/__tests__/data/canvas.ts @@ -1,6 +1,7 @@ import { CanvasNodeKey } from '@/constants'; import { ref } from 'vue'; -import type { CanvasElement, CanvasElementData } from '@/types'; +import type { CanvasNode, CanvasNodeData } from '@/types'; +import { CanvasNodeRenderType } from '@/types'; export function createCanvasNodeData({ id = 'node', @@ -15,10 +16,10 @@ export function createCanvasNodeData({ pinnedData = { count: 0, visible: false }, runData = { count: 0, visible: false }, render = { - type: 'default', + type: CanvasNodeRenderType.Default, options: { configurable: false, configuration: false, trigger: false }, }, -}: Partial = {}): CanvasElementData { +}: Partial = {}): CanvasNodeData { return { execution, issues, @@ -41,9 +42,7 @@ export function createCanvasNodeElement({ label = 'Node', position = { x: 100, y: 100 }, data, -}: Partial< - Omit & { data: Partial } -> = {}): CanvasElement { +}: Partial & { data: Partial }> = {}): CanvasNode { return { id, type, @@ -58,7 +57,7 @@ export function createCanvasNodeProps({ label = 'Test Node', selected = false, data = {}, -}: { id?: string; label?: string; selected?: boolean; data?: Partial } = {}) { +}: { id?: string; label?: string; selected?: boolean; data?: Partial } = {}) { return { id, label, @@ -72,7 +71,7 @@ export function createCanvasNodeProvide({ label = 'Test Node', selected = false, data = {}, -}: { id?: string; label?: string; selected?: boolean; data?: Partial } = {}) { +}: { id?: string; label?: string; selected?: boolean; data?: Partial } = {}) { const props = createCanvasNodeProps({ id, label, selected, data }); return { [`${CanvasNodeKey}`]: { @@ -85,8 +84,8 @@ export function createCanvasNodeProvide({ } export function createCanvasConnection( - nodeA: CanvasElement, - nodeB: CanvasElement, + nodeA: CanvasNode, + nodeB: CanvasNode, { sourceIndex = 0, targetIndex = 0 } = {}, ) { const nodeAOutput = nodeA.data?.outputs[sourceIndex]; diff --git a/packages/editor-ui/src/components/canvas/Canvas.spec.ts b/packages/editor-ui/src/components/canvas/Canvas.spec.ts index 5b99630fdf..d23e46cbfe 100644 --- a/packages/editor-ui/src/components/canvas/Canvas.spec.ts +++ b/packages/editor-ui/src/components/canvas/Canvas.spec.ts @@ -4,7 +4,7 @@ import { fireEvent, waitFor } from '@testing-library/vue'; import { createComponentRenderer } from '@/__tests__/render'; import Canvas from '@/components/canvas/Canvas.vue'; import { createPinia, setActivePinia } from 'pinia'; -import type { CanvasConnection, CanvasElement } from '@/types'; +import type { CanvasConnection, CanvasNode } from '@/types'; import { createCanvasConnection, createCanvasNodeElement } from '@/__tests__/data'; import { NodeConnectionType } from 'n8n-workflow'; @@ -44,7 +44,7 @@ describe('Canvas', () => { }); it('should render nodes and edges', async () => { - const elements: CanvasElement[] = [ + const nodes: CanvasNode[] = [ createCanvasNodeElement({ id: '1', label: 'Node 1', @@ -72,33 +72,33 @@ describe('Canvas', () => { }), ]; - const connections: CanvasConnection[] = [createCanvasConnection(elements[0], elements[1])]; + const connections: CanvasConnection[] = [createCanvasConnection(nodes[0], nodes[1])]; const { container } = renderComponent({ props: { - elements, + nodes, connections, }, }); await waitFor(() => expect(container.querySelectorAll('.vue-flow__node')).toHaveLength(2)); - expect(container.querySelector(`[data-id="${elements[0].id}"]`)).toBeInTheDocument(); - expect(container.querySelector(`[data-id="${elements[1].id}"]`)).toBeInTheDocument(); + expect(container.querySelector(`[data-id="${nodes[0].id}"]`)).toBeInTheDocument(); + expect(container.querySelector(`[data-id="${nodes[1].id}"]`)).toBeInTheDocument(); expect(container.querySelector(`[data-id="${connections[0].id}"]`)).toBeInTheDocument(); }); it('should handle node drag stop event', async () => { - const elements = [createCanvasNodeElement()]; + const nodes = [createCanvasNodeElement()]; const { container, emitted } = renderComponent({ props: { - elements, + nodes, }, }); await waitFor(() => expect(container.querySelectorAll('.vue-flow__node')).toHaveLength(1)); - const node = container.querySelector(`[data-id="${elements[0].id}"]`) as Element; + const node = container.querySelector(`[data-id="${nodes[0].id}"]`) as Element; await fireEvent.mouseDown(node, { view: window }); await fireEvent.mouseMove(node, { view: window, diff --git a/packages/editor-ui/src/components/canvas/Canvas.vue b/packages/editor-ui/src/components/canvas/Canvas.vue index c6ba71ad17..3fa90ea296 100644 --- a/packages/editor-ui/src/components/canvas/Canvas.vue +++ b/packages/editor-ui/src/components/canvas/Canvas.vue @@ -1,18 +1,18 @@