mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-13 16:14:07 -08:00
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
This commit is contained in:
parent
8f5f1c3aa5
commit
96ec5bc880
|
@ -203,12 +203,12 @@ export const mouseSelect = mixins(deviceSupportHelpers).extend({
|
||||||
nodeDeselected(node: INodeUi) {
|
nodeDeselected(node: INodeUi) {
|
||||||
this.uiStore.removeNodeFromSelection(node);
|
this.uiStore.removeNodeFromSelection(node);
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
this.instance.removeFromDragSelection(this.$refs[`node-${node.id}`][0].$el);
|
this.instance.removeFromDragSelection(this.instance.getManagedElement(node?.id));
|
||||||
},
|
},
|
||||||
nodeSelected(node: INodeUi) {
|
nodeSelected(node: INodeUi) {
|
||||||
this.uiStore.addSelectedNode(node);
|
this.uiStore.addSelectedNode(node);
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
this.instance.addToDragSelection(this.$refs[`node-${node.id}`][0].$el);
|
this.instance.addToDragSelection(this.instance.getManagedElement(node?.id));
|
||||||
},
|
},
|
||||||
deselectAllNodes() {
|
deselectAllNodes() {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { useUIStore } from '@/stores/ui';
|
||||||
import { useHistoryStore } from '@/stores/history';
|
import { useHistoryStore } from '@/stores/history';
|
||||||
import { INodeUi, XYPosition } from '@/Interface';
|
import { INodeUi, XYPosition } from '@/Interface';
|
||||||
import { scaleBigger, scaleReset, scaleSmaller } from '@/utils';
|
import { scaleBigger, scaleReset, scaleSmaller } from '@/utils';
|
||||||
import { START_NODE_TYPE, STICKY_NODE_TYPE } from '@/constants';
|
import { START_NODE_TYPE } from '@/constants';
|
||||||
import type {
|
import type {
|
||||||
BeforeStartEventParams,
|
BeforeStartEventParams,
|
||||||
BrowserJsPlumbInstance,
|
BrowserJsPlumbInstance,
|
||||||
|
@ -37,7 +37,7 @@ export const useCanvasStore = defineStore('canvas', () => {
|
||||||
const uiStore = useUIStore();
|
const uiStore = useUIStore();
|
||||||
const historyStore = useHistoryStore();
|
const historyStore = useHistoryStore();
|
||||||
|
|
||||||
const jsPlumbInstance = ref<BrowserJsPlumbInstance>();
|
const jsPlumbInstanceRef = ref<BrowserJsPlumbInstance>();
|
||||||
const isDragging = ref<boolean>(false);
|
const isDragging = ref<boolean>(false);
|
||||||
|
|
||||||
const nodes = computed<INodeUi[]>(() => workflowStore.allNodes);
|
const nodes = computed<INodeUi[]>(() => workflowStore.allNodes);
|
||||||
|
@ -78,7 +78,7 @@ export const useCanvasStore = defineStore('canvas', () => {
|
||||||
|
|
||||||
const setZoomLevel = (zoomLevel: number, offset: XYPosition) => {
|
const setZoomLevel = (zoomLevel: number, offset: XYPosition) => {
|
||||||
nodeViewScale.value = zoomLevel;
|
nodeViewScale.value = zoomLevel;
|
||||||
jsPlumbInstance.value?.setZoom(zoomLevel);
|
jsPlumbInstanceRef.value?.setZoom(zoomLevel);
|
||||||
uiStore.nodeViewOffsetPosition = offset;
|
uiStore.nodeViewOffsetPosition = offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -143,13 +143,13 @@ export const useCanvasStore = defineStore('canvas', () => {
|
||||||
|
|
||||||
function initInstance(container: Element) {
|
function initInstance(container: Element) {
|
||||||
// Make sure to clean-up previous instance if it exists
|
// Make sure to clean-up previous instance if it exists
|
||||||
if (jsPlumbInstance.value) {
|
if (jsPlumbInstanceRef.value) {
|
||||||
jsPlumbInstance.value.destroy();
|
jsPlumbInstanceRef.value.destroy();
|
||||||
jsPlumbInstance.value.reset();
|
jsPlumbInstanceRef.value.reset();
|
||||||
jsPlumbInstance.value = undefined;
|
jsPlumbInstanceRef.value = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
jsPlumbInstance.value = newInstance({
|
jsPlumbInstanceRef.value = newInstance({
|
||||||
container,
|
container,
|
||||||
connector: CONNECTOR_FLOWCHART_TYPE,
|
connector: CONNECTOR_FLOWCHART_TYPE,
|
||||||
resizeObserver: false,
|
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
|
// 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
|
// undefined. So check if the currently dragged node is selected and if not clear
|
||||||
// the drag-selection.
|
// the drag-selection.
|
||||||
jsPlumbInstance.value?.clearDragSelection();
|
jsPlumbInstanceRef.value?.clearDragSelection();
|
||||||
uiStore.resetSelectedNodes();
|
uiStore.resetSelectedNodes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,7 +231,7 @@ export const useCanvasStore = defineStore('canvas', () => {
|
||||||
filter: '.node-description, .node-description .node-name, .node-description .node-subtitle',
|
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;
|
const isReadOnly = uiStore.isReadOnlyView;
|
||||||
if (isReadOnly) {
|
if (isReadOnly) {
|
||||||
// Do not allow to move nodes in readOnly mode
|
// Do not allow to move nodes in readOnly mode
|
||||||
|
@ -240,6 +240,8 @@ export const useCanvasStore = defineStore('canvas', () => {
|
||||||
return pos;
|
return pos;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const jsPlumbInstance = computed(() => jsPlumbInstanceRef.value as BrowserJsPlumbInstance);
|
||||||
return {
|
return {
|
||||||
isDemo,
|
isDemo,
|
||||||
nodeViewScale,
|
nodeViewScale,
|
||||||
|
|
|
@ -52,7 +52,6 @@
|
||||||
@runWorkflow="onRunNode"
|
@runWorkflow="onRunNode"
|
||||||
@moved="onNodeMoved"
|
@moved="onNodeMoved"
|
||||||
@run="onNodeRun"
|
@run="onNodeRun"
|
||||||
:ref="`node-${nodeData.id}`"
|
|
||||||
:key="`${nodeData.id}_node`"
|
:key="`${nodeData.id}_node`"
|
||||||
:name="nodeData.name"
|
:name="nodeData.name"
|
||||||
:isReadOnly="isReadOnly"
|
:isReadOnly="isReadOnly"
|
||||||
|
@ -76,7 +75,6 @@
|
||||||
@nodeSelected="nodeSelectedByName"
|
@nodeSelected="nodeSelectedByName"
|
||||||
@removeNode="(name) => removeNode(name, true)"
|
@removeNode="(name) => removeNode(name, true)"
|
||||||
:key="`${nodeData.id}_sticky`"
|
:key="`${nodeData.id}_sticky`"
|
||||||
:ref="`node-${nodeData.id}`"
|
|
||||||
:name="nodeData.name"
|
:name="nodeData.name"
|
||||||
:isReadOnly="isReadOnly"
|
:isReadOnly="isReadOnly"
|
||||||
:instance="instance"
|
:instance="instance"
|
||||||
|
@ -406,8 +404,6 @@ export default mixins(
|
||||||
next();
|
next();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Make sure workflow id is empty when leaving the editor
|
|
||||||
this.workflowsStore.setWorkflowId(PLACEHOLDER_EMPTY_WORKFLOW_ID);
|
|
||||||
if (this.uiStore.stateIsDirty) {
|
if (this.uiStore.stateIsDirty) {
|
||||||
const confirmModal = await this.confirmModal(
|
const confirmModal = await this.confirmModal(
|
||||||
this.$locale.baseText('generic.unsavedWork.confirmMessage.message'),
|
this.$locale.baseText('generic.unsavedWork.confirmMessage.message'),
|
||||||
|
@ -418,6 +414,8 @@ export default mixins(
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
if (confirmModal === MODAL_CONFIRMED) {
|
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);
|
const saved = await this.saveCurrentWorkflow({}, false);
|
||||||
if (saved) {
|
if (saved) {
|
||||||
await this.settingsStore.fetchPromptsData();
|
await this.settingsStore.fetchPromptsData();
|
||||||
|
@ -439,6 +437,7 @@ export default mixins(
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
} else if (confirmModal === MODAL_CANCEL) {
|
} else if (confirmModal === MODAL_CANCEL) {
|
||||||
|
this.workflowsStore.setWorkflowId(PLACEHOLDER_EMPTY_WORKFLOW_ID);
|
||||||
await this.resetWorkspace();
|
await this.resetWorkspace();
|
||||||
this.uiStore.stateIsDirty = false;
|
this.uiStore.stateIsDirty = false;
|
||||||
next();
|
next();
|
||||||
|
@ -2755,12 +2754,10 @@ export default mixins(
|
||||||
},
|
},
|
||||||
getJSPlumbEndpoints(nodeName: string): Endpoint[] {
|
getJSPlumbEndpoints(nodeName: string): Endpoint[] {
|
||||||
const node = this.workflowsStore.getNodeByName(nodeName);
|
const node = this.workflowsStore.getNodeByName(nodeName);
|
||||||
const nodeEls: Element = (this.$refs[`node-${node?.id}`] as ComponentInstance[])[0]
|
const nodeEl = this.instance.getManagedElement(node?.id);
|
||||||
.$el as Element;
|
|
||||||
|
|
||||||
const endpoints = this.instance?.getEndpoints(nodeEls);
|
const endpoints = this.instance?.getEndpoints(nodeEl);
|
||||||
|
return endpoints;
|
||||||
return endpoints as Endpoint[];
|
|
||||||
},
|
},
|
||||||
getPlusEndpoint(nodeName: string, outputIndex: number): Endpoint | undefined {
|
getPlusEndpoint(nodeName: string, outputIndex: number): Endpoint | undefined {
|
||||||
const endpoints = this.getJSPlumbEndpoints(nodeName);
|
const endpoints = this.getJSPlumbEndpoints(nodeName);
|
||||||
|
|
Loading…
Reference in a new issue