From 96ec5bc880e23c1916322d68e8aeaaa8176db2aa Mon Sep 17 00:00:00 2001 From: OlegIvaniv Date: Thu, 2 Feb 2023 09:05:14 +0100 Subject: [PATCH] refactor(editor): Fix duplicate NodeView keys when navigating between routes (no-changelog) (#5325) * refactor(editor): Fix duplicate NodeView keys when navigating between routes (no-changelog) * Prettier fixes * Use computed to export jsPlumb instance from canvas * Force jsPlumb computed instance type --- packages/editor-ui/src/mixins/mouseSelect.ts | 4 ++-- packages/editor-ui/src/stores/canvas.ts | 22 +++++++++++--------- packages/editor-ui/src/views/NodeView.vue | 15 ++++++------- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/packages/editor-ui/src/mixins/mouseSelect.ts b/packages/editor-ui/src/mixins/mouseSelect.ts index 89b0d6a54c510..ef062c699a821 100644 --- a/packages/editor-ui/src/mixins/mouseSelect.ts +++ b/packages/editor-ui/src/mixins/mouseSelect.ts @@ -203,12 +203,12 @@ export const mouseSelect = mixins(deviceSupportHelpers).extend({ nodeDeselected(node: INodeUi) { this.uiStore.removeNodeFromSelection(node); // @ts-ignore - this.instance.removeFromDragSelection(this.$refs[`node-${node.id}`][0].$el); + this.instance.removeFromDragSelection(this.instance.getManagedElement(node?.id)); }, nodeSelected(node: INodeUi) { this.uiStore.addSelectedNode(node); // @ts-ignore - this.instance.addToDragSelection(this.$refs[`node-${node.id}`][0].$el); + this.instance.addToDragSelection(this.instance.getManagedElement(node?.id)); }, deselectAllNodes() { // @ts-ignore diff --git a/packages/editor-ui/src/stores/canvas.ts b/packages/editor-ui/src/stores/canvas.ts index 53d4ea2e9700d..d4bb7333fdbf9 100644 --- a/packages/editor-ui/src/stores/canvas.ts +++ b/packages/editor-ui/src/stores/canvas.ts @@ -8,7 +8,7 @@ import { useUIStore } from '@/stores/ui'; import { useHistoryStore } from '@/stores/history'; import { INodeUi, XYPosition } from '@/Interface'; import { scaleBigger, scaleReset, scaleSmaller } from '@/utils'; -import { START_NODE_TYPE, STICKY_NODE_TYPE } from '@/constants'; +import { START_NODE_TYPE } from '@/constants'; import type { BeforeStartEventParams, BrowserJsPlumbInstance, @@ -37,7 +37,7 @@ export const useCanvasStore = defineStore('canvas', () => { const uiStore = useUIStore(); const historyStore = useHistoryStore(); - const jsPlumbInstance = ref(); + const jsPlumbInstanceRef = ref(); const isDragging = ref(false); const nodes = computed(() => workflowStore.allNodes); @@ -78,7 +78,7 @@ export const useCanvasStore = defineStore('canvas', () => { const setZoomLevel = (zoomLevel: number, offset: XYPosition) => { nodeViewScale.value = zoomLevel; - jsPlumbInstance.value?.setZoom(zoomLevel); + jsPlumbInstanceRef.value?.setZoom(zoomLevel); uiStore.nodeViewOffsetPosition = offset; }; @@ -143,13 +143,13 @@ export const useCanvasStore = defineStore('canvas', () => { function initInstance(container: Element) { // Make sure to clean-up previous instance if it exists - if (jsPlumbInstance.value) { - jsPlumbInstance.value.destroy(); - jsPlumbInstance.value.reset(); - jsPlumbInstance.value = undefined; + if (jsPlumbInstanceRef.value) { + jsPlumbInstanceRef.value.destroy(); + jsPlumbInstanceRef.value.reset(); + jsPlumbInstanceRef.value = undefined; } - jsPlumbInstance.value = newInstance({ + jsPlumbInstanceRef.value = newInstance({ container, connector: CONNECTOR_FLOWCHART_TYPE, resizeObserver: false, @@ -168,7 +168,7 @@ export const useCanvasStore = defineStore('canvas', () => { // Only the node which gets dragged directly gets an event, for all others it is // undefined. So check if the currently dragged node is selected and if not clear // the drag-selection. - jsPlumbInstance.value?.clearDragSelection(); + jsPlumbInstanceRef.value?.clearDragSelection(); uiStore.resetSelectedNodes(); } @@ -231,7 +231,7 @@ export const useCanvasStore = defineStore('canvas', () => { filter: '.node-description, .node-description .node-name, .node-description .node-subtitle', }, }); - jsPlumbInstance.value?.setDragConstrainFunction((pos: PointXY) => { + jsPlumbInstanceRef.value?.setDragConstrainFunction((pos: PointXY) => { const isReadOnly = uiStore.isReadOnlyView; if (isReadOnly) { // Do not allow to move nodes in readOnly mode @@ -240,6 +240,8 @@ export const useCanvasStore = defineStore('canvas', () => { return pos; }); } + + const jsPlumbInstance = computed(() => jsPlumbInstanceRef.value as BrowserJsPlumbInstance); return { isDemo, nodeViewScale, diff --git a/packages/editor-ui/src/views/NodeView.vue b/packages/editor-ui/src/views/NodeView.vue index 302ad710f0a34..9021a13f00f97 100644 --- a/packages/editor-ui/src/views/NodeView.vue +++ b/packages/editor-ui/src/views/NodeView.vue @@ -52,7 +52,6 @@ @runWorkflow="onRunNode" @moved="onNodeMoved" @run="onNodeRun" - :ref="`node-${nodeData.id}`" :key="`${nodeData.id}_node`" :name="nodeData.name" :isReadOnly="isReadOnly" @@ -76,7 +75,6 @@ @nodeSelected="nodeSelectedByName" @removeNode="(name) => removeNode(name, true)" :key="`${nodeData.id}_sticky`" - :ref="`node-${nodeData.id}`" :name="nodeData.name" :isReadOnly="isReadOnly" :instance="instance" @@ -406,8 +404,6 @@ export default mixins( next(); return; } - // Make sure workflow id is empty when leaving the editor - this.workflowsStore.setWorkflowId(PLACEHOLDER_EMPTY_WORKFLOW_ID); if (this.uiStore.stateIsDirty) { const confirmModal = await this.confirmModal( this.$locale.baseText('generic.unsavedWork.confirmMessage.message'), @@ -418,6 +414,8 @@ export default mixins( true, ); if (confirmModal === MODAL_CONFIRMED) { + // Make sure workflow id is empty when leaving the editor + this.workflowsStore.setWorkflowId(PLACEHOLDER_EMPTY_WORKFLOW_ID); const saved = await this.saveCurrentWorkflow({}, false); if (saved) { await this.settingsStore.fetchPromptsData(); @@ -439,6 +437,7 @@ export default mixins( next(); } } else if (confirmModal === MODAL_CANCEL) { + this.workflowsStore.setWorkflowId(PLACEHOLDER_EMPTY_WORKFLOW_ID); await this.resetWorkspace(); this.uiStore.stateIsDirty = false; next(); @@ -2755,12 +2754,10 @@ export default mixins( }, getJSPlumbEndpoints(nodeName: string): Endpoint[] { const node = this.workflowsStore.getNodeByName(nodeName); - const nodeEls: Element = (this.$refs[`node-${node?.id}`] as ComponentInstance[])[0] - .$el as Element; - - const endpoints = this.instance?.getEndpoints(nodeEls); + const nodeEl = this.instance.getManagedElement(node?.id); - return endpoints as Endpoint[]; + const endpoints = this.instance?.getEndpoints(nodeEl); + return endpoints; }, getPlusEndpoint(nodeName: string, outputIndex: number): Endpoint | undefined { const endpoints = this.getJSPlumbEndpoints(nodeName);