Skip to content

Commit ddc4c0b

Browse files
authored
fix(editor): Fix canvas moving check (#17856)
1 parent 34991d6 commit ddc4c0b

File tree

5 files changed

+27
-38
lines changed

5 files changed

+27
-38
lines changed

packages/frontend/editor-ui/src/__tests__/data/canvas.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ export function createCanvasProvide({
142142
connectingHandle: ref(connectingHandle),
143143
viewport: ref(viewport),
144144
isExperimentalNdvActive: computed(() => false),
145+
isPaneMoving: ref(false),
145146
} satisfies CanvasInjectionData,
146147
};
147148
}

packages/frontend/editor-ui/src/components/canvas/Canvas.vue

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,15 +196,18 @@ const classes = computed(() => ({
196196
const panningKeyCode = ref<string[] | true>(isMobileDevice ? true : [' ', controlKeyCode]);
197197
const panningMouseButton = ref<number[] | true>(isMobileDevice ? true : [1]);
198198
const selectionKeyCode = ref<string | true | null>(isMobileDevice ? 'Shift' : true);
199+
const isInPanningMode = ref(false);
199200
200201
function switchToPanningMode() {
201202
selectionKeyCode.value = null;
202203
panningMouseButton.value = [0, 1];
204+
isInPanningMode.value = true;
203205
}
204206
205207
function switchToSelectionMode() {
206208
selectionKeyCode.value = true;
207209
panningMouseButton.value = [1];
210+
isInPanningMode.value = false;
208211
}
209212
210213
onKeyDown(panningKeyCode.value, switchToPanningMode, {
@@ -651,8 +654,13 @@ function setReadonly(value: boolean) {
651654
elementsSelectable.value = true;
652655
}
653656
654-
function onPaneMoveStart() {
655-
isPaneMoving.value = true;
657+
function onPaneMove({ event }: { event: unknown }) {
658+
// The event object is either D3ZoomEvent or WheelEvent.
659+
// Here I'm ignoring D3ZoomEvent because it's not necessarily followed by a moveEnd event.
660+
// This can be simplified once https://github.com/bcakmakoglu/vue-flow/issues/1908 is resolved
661+
if (isInPanningMode.value || event instanceof WheelEvent) {
662+
isPaneMoving.value = true;
663+
}
656664
}
657665
658666
function onPaneMoveEnd() {
@@ -894,6 +902,7 @@ provide(CanvasKey, {
894902
initialized,
895903
viewport,
896904
isExperimentalNdvActive,
905+
isPaneMoving,
897906
});
898907
</script>
899908

@@ -923,7 +932,7 @@ provide(CanvasKey, {
923932
@connect-end="onConnectEnd"
924933
@pane-click="onClickPane"
925934
@pane-context-menu="onOpenContextMenu"
926-
@move-start="onPaneMoveStart"
935+
@move="onPaneMove"
927936
@move-end="onPaneMoveEnd"
928937
@node-drag-stop="onNodeDragStop"
929938
@node-click="onNodeClick"

packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalEmbeddedNdvMapper.vue

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
<script setup lang="ts">
22
import InputPanel from '@/components/InputPanel.vue';
3+
import { useCanvas } from '@/composables/useCanvas';
34
import type { INodeUi } from '@/Interface';
45
import { useNDVStore } from '@/stores/ndv.store';
56
import { N8nText } from '@n8n/design-system';
67
import { useVueFlow } from '@vue-flow/core';
78
import { useActiveElement } from '@vueuse/core';
89
import { ElPopover } from 'element-plus';
910
import type { Workflow } from 'n8n-workflow';
10-
import { onBeforeUnmount, ref, useTemplateRef, watch } from 'vue';
11+
import { ref, useTemplateRef, watch } from 'vue';
1112
1213
const { node, container } = defineProps<{
1314
workflow: Workflow;
@@ -18,23 +19,12 @@ const { node, container } = defineProps<{
1819
1920
const ndvStore = useNDVStore();
2021
const vf = useVueFlow();
22+
const { isPaneMoving, viewport } = useCanvas();
2123
const activeElement = useActiveElement();
2224
2325
const inputPanelRef = useTemplateRef('inputPanel');
2426
const shouldShowInputPanel = ref(false);
2527
26-
const moveStartListener = vf.onMoveStart(() => {
27-
shouldShowInputPanel.value = false;
28-
});
29-
30-
const moveEndListener = vf.onMoveEnd(() => {
31-
shouldShowInputPanel.value = getShouldShowInputPanel();
32-
});
33-
34-
const viewportChangeListener = vf.onViewportChange(() => {
35-
shouldShowInputPanel.value = false;
36-
});
37-
3828
function getShouldShowInputPanel() {
3929
const active = activeElement.value;
4030
@@ -59,10 +49,12 @@ watch([activeElement, vf.getSelectedNodes], ([active, selected]) => {
5949
}
6050
});
6151
62-
onBeforeUnmount(() => {
63-
moveStartListener.off();
64-
moveEndListener.off();
65-
viewportChangeListener.off();
52+
watch(isPaneMoving, (moving) => {
53+
shouldShowInputPanel.value = !moving && getShouldShowInputPanel();
54+
});
55+
56+
watch(viewport, () => {
57+
shouldShowInputPanel.value = false;
6658
});
6759
</script>
6860

packages/frontend/editor-ui/src/components/canvas/experimental/components/ExperimentalEmbeddedNodeDetails.vue

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ import type { ExpressionLocalResolveContext } from '@/types/expressions';
88
import { N8nText } from '@n8n/design-system';
99
import { useVueFlow } from '@vue-flow/core';
1010
import { watchOnce } from '@vueuse/core';
11-
import { computed, onBeforeUnmount, provide, ref, useTemplateRef } from 'vue';
11+
import { computed, provide, ref, useTemplateRef } from 'vue';
1212
import { useExperimentalNdvStore } from '../experimentalNdv.store';
1313
import ExperimentalCanvasNodeSettings from './ExperimentalCanvasNodeSettings.vue';
1414
import { useI18n } from '@n8n/i18n';
1515
import NodeIcon from '@/components/NodeIcon.vue';
1616
import { getNodeSubTitleText } from '@/components/canvas/experimental/experimentalNdv.utils';
1717
import ExperimentalEmbeddedNdvActions from '@/components/canvas/experimental/components/ExperimentalEmbeddedNdvActions.vue';
18+
import { useCanvas } from '@/composables/useCanvas';
1819
1920
const { nodeId, isReadOnly, isConfigurable } = defineProps<{
2021
nodeId: string;
@@ -36,22 +37,7 @@ const nodeType = computed(() => {
3637
return null;
3738
});
3839
const vf = useVueFlow();
39-
40-
const isMoving = ref(false);
41-
42-
const moveStartListener = vf.onMoveStart(() => {
43-
isMoving.value = true;
44-
});
45-
46-
const moveEndListener = vf.onMoveEnd(() => {
47-
isMoving.value = false;
48-
});
49-
50-
onBeforeUnmount(() => {
51-
moveStartListener.off();
52-
moveEndListener.off();
53-
});
54-
40+
const { isPaneMoving } = useCanvas();
5541
const isVisible = computed(() =>
5642
vf.isNodeIntersecting(
5743
{ id: nodeId },
@@ -150,7 +136,7 @@ watchOnce(isVisible, (visible) => {
150136
'--zoom': `${1 / experimentalNdvStore.maxCanvasZoom}`,
151137
'--node-width-scaler': isConfigurable ? 1 : 1.5,
152138
'--max-height-on-focus': `${(vf.dimensions.value.height * 0.8) / experimentalNdvStore.maxCanvasZoom}px`,
153-
pointerEvents: isMoving ? 'none' : 'auto', // Don't interrupt canvas panning
139+
pointerEvents: isPaneMoving ? 'none' : 'auto', // Don't interrupt canvas panning
154140
}"
155141
>
156142
<template v-if="!node || !isOnceVisible" />

packages/frontend/editor-ui/src/types/canvas.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ export interface CanvasInjectionData {
164164
connectingHandle: Ref<ConnectStartEvent | undefined>;
165165
viewport: Ref<ViewportTransform>;
166166
isExperimentalNdvActive: ComputedRef<boolean>;
167+
isPaneMoving: Ref<boolean>;
167168
}
168169

169170
export type CanvasNodeEventBusEvents = {

0 commit comments

Comments
 (0)