diff --git a/packages/frontend/editor-ui/src/__tests__/data/canvas.ts b/packages/frontend/editor-ui/src/__tests__/data/canvas.ts index 7e72041c52..ebd99c9c15 100644 --- a/packages/frontend/editor-ui/src/__tests__/data/canvas.ts +++ b/packages/frontend/editor-ui/src/__tests__/data/canvas.ts @@ -142,6 +142,7 @@ export function createCanvasProvide({ connectingHandle: ref(connectingHandle), viewport: ref(viewport), isExperimentalNdvActive: computed(() => false), + isPaneMoving: ref(false), } satisfies CanvasInjectionData, }; } diff --git a/packages/frontend/editor-ui/src/components/canvas/Canvas.vue b/packages/frontend/editor-ui/src/components/canvas/Canvas.vue index ddc6f5de7c..a4ac0e244c 100644 --- a/packages/frontend/editor-ui/src/components/canvas/Canvas.vue +++ b/packages/frontend/editor-ui/src/components/canvas/Canvas.vue @@ -196,15 +196,18 @@ const classes = computed(() => ({ const panningKeyCode = ref(isMobileDevice ? true : [' ', controlKeyCode]); const panningMouseButton = ref(isMobileDevice ? true : [1]); const selectionKeyCode = ref(isMobileDevice ? 'Shift' : true); +const isInPanningMode = ref(false); function switchToPanningMode() { selectionKeyCode.value = null; panningMouseButton.value = [0, 1]; + isInPanningMode.value = true; } function switchToSelectionMode() { selectionKeyCode.value = true; panningMouseButton.value = [1]; + isInPanningMode.value = false; } onKeyDown(panningKeyCode.value, switchToPanningMode, { @@ -651,8 +654,13 @@ function setReadonly(value: boolean) { elementsSelectable.value = true; } -function onPaneMoveStart() { - isPaneMoving.value = true; +function onPaneMove({ event }: { event: unknown }) { + // The event object is either D3ZoomEvent or WheelEvent. + // Here I'm ignoring D3ZoomEvent because it's not necessarily followed by a moveEnd event. + // This can be simplified once https://github.com/bcakmakoglu/vue-flow/issues/1908 is resolved + if (isInPanningMode.value || event instanceof WheelEvent) { + isPaneMoving.value = true; + } } function onPaneMoveEnd() { @@ -894,6 +902,7 @@ provide(CanvasKey, { initialized, viewport, isExperimentalNdvActive, + isPaneMoving, }); @@ -923,7 +932,7 @@ provide(CanvasKey, { @connect-end="onConnectEnd" @pane-click="onClickPane" @pane-context-menu="onOpenContextMenu" - @move-start="onPaneMoveStart" + @move="onPaneMove" @move-end="onPaneMoveEnd" @node-drag-stop="onNodeDragStop" @node-click="onNodeClick" diff --git a/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalEmbeddedNdvMapper.vue b/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalEmbeddedNdvMapper.vue index 86fc389802..497481aa06 100644 --- a/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalEmbeddedNdvMapper.vue +++ b/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalEmbeddedNdvMapper.vue @@ -1,5 +1,6 @@ diff --git a/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalEmbeddedNodeDetails.vue b/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalEmbeddedNodeDetails.vue index f83c87b8c0..41bbb902e2 100644 --- a/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalEmbeddedNodeDetails.vue +++ b/packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalEmbeddedNodeDetails.vue @@ -8,13 +8,14 @@ import type { ExpressionLocalResolveContext } from '@/types/expressions'; import { N8nText } from '@n8n/design-system'; import { useVueFlow } from '@vue-flow/core'; import { watchOnce } from '@vueuse/core'; -import { computed, onBeforeUnmount, provide, ref, useTemplateRef } from 'vue'; +import { computed, provide, ref, useTemplateRef } from 'vue'; import { useExperimentalNdvStore } from '../experimentalNdv.store'; import ExperimentalCanvasNodeSettings from './ExperimentalCanvasNodeSettings.vue'; import { useI18n } from '@n8n/i18n'; import NodeIcon from '@/components/NodeIcon.vue'; import { getNodeSubTitleText } from '@/components/canvas/experimental/experimentalNdv.utils'; import ExperimentalEmbeddedNdvActions from '@/components/canvas/experimental/components/ExperimentalEmbeddedNdvActions.vue'; +import { useCanvas } from '@/composables/useCanvas'; const { nodeId, isReadOnly, isConfigurable } = defineProps<{ nodeId: string; @@ -36,22 +37,7 @@ const nodeType = computed(() => { return null; }); const vf = useVueFlow(); - -const isMoving = ref(false); - -const moveStartListener = vf.onMoveStart(() => { - isMoving.value = true; -}); - -const moveEndListener = vf.onMoveEnd(() => { - isMoving.value = false; -}); - -onBeforeUnmount(() => { - moveStartListener.off(); - moveEndListener.off(); -}); - +const { isPaneMoving } = useCanvas(); const isVisible = computed(() => vf.isNodeIntersecting( { id: nodeId }, @@ -150,7 +136,7 @@ watchOnce(isVisible, (visible) => { '--zoom': `${1 / experimentalNdvStore.maxCanvasZoom}`, '--node-width-scaler': isConfigurable ? 1 : 1.5, '--max-height-on-focus': `${(vf.dimensions.value.height * 0.8) / experimentalNdvStore.maxCanvasZoom}px`, - pointerEvents: isMoving ? 'none' : 'auto', // Don't interrupt canvas panning + pointerEvents: isPaneMoving ? 'none' : 'auto', // Don't interrupt canvas panning }" >