mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 17:46:45 +00:00
fix(editor): Fix canvas moving check (#17856)
This commit is contained in:
@@ -142,6 +142,7 @@ export function createCanvasProvide({
|
||||
connectingHandle: ref(connectingHandle),
|
||||
viewport: ref(viewport),
|
||||
isExperimentalNdvActive: computed(() => false),
|
||||
isPaneMoving: ref(false),
|
||||
} satisfies CanvasInjectionData,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -196,15 +196,18 @@ const classes = computed(() => ({
|
||||
const panningKeyCode = ref<string[] | true>(isMobileDevice ? true : [' ', controlKeyCode]);
|
||||
const panningMouseButton = ref<number[] | true>(isMobileDevice ? true : [1]);
|
||||
const selectionKeyCode = ref<string | true | null>(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,
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import InputPanel from '@/components/InputPanel.vue';
|
||||
import { useCanvas } from '@/composables/useCanvas';
|
||||
import type { INodeUi } from '@/Interface';
|
||||
import { useNDVStore } from '@/stores/ndv.store';
|
||||
import { N8nText } from '@n8n/design-system';
|
||||
@@ -7,7 +8,7 @@ import { useVueFlow } from '@vue-flow/core';
|
||||
import { useActiveElement } from '@vueuse/core';
|
||||
import { ElPopover } from 'element-plus';
|
||||
import type { Workflow } from 'n8n-workflow';
|
||||
import { onBeforeUnmount, ref, useTemplateRef, watch } from 'vue';
|
||||
import { ref, useTemplateRef, watch } from 'vue';
|
||||
|
||||
const { node, container } = defineProps<{
|
||||
workflow: Workflow;
|
||||
@@ -18,23 +19,12 @@ const { node, container } = defineProps<{
|
||||
|
||||
const ndvStore = useNDVStore();
|
||||
const vf = useVueFlow();
|
||||
const { isPaneMoving, viewport } = useCanvas();
|
||||
const activeElement = useActiveElement();
|
||||
|
||||
const inputPanelRef = useTemplateRef('inputPanel');
|
||||
const shouldShowInputPanel = ref(false);
|
||||
|
||||
const moveStartListener = vf.onMoveStart(() => {
|
||||
shouldShowInputPanel.value = false;
|
||||
});
|
||||
|
||||
const moveEndListener = vf.onMoveEnd(() => {
|
||||
shouldShowInputPanel.value = getShouldShowInputPanel();
|
||||
});
|
||||
|
||||
const viewportChangeListener = vf.onViewportChange(() => {
|
||||
shouldShowInputPanel.value = false;
|
||||
});
|
||||
|
||||
function getShouldShowInputPanel() {
|
||||
const active = activeElement.value;
|
||||
|
||||
@@ -59,10 +49,12 @@ watch([activeElement, vf.getSelectedNodes], ([active, selected]) => {
|
||||
}
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
moveStartListener.off();
|
||||
moveEndListener.off();
|
||||
viewportChangeListener.off();
|
||||
watch(isPaneMoving, (moving) => {
|
||||
shouldShowInputPanel.value = !moving && getShouldShowInputPanel();
|
||||
});
|
||||
|
||||
watch(viewport, () => {
|
||||
shouldShowInputPanel.value = false;
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -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
|
||||
}"
|
||||
>
|
||||
<template v-if="!node || !isOnceVisible" />
|
||||
|
||||
@@ -164,6 +164,7 @@ export interface CanvasInjectionData {
|
||||
connectingHandle: Ref<ConnectStartEvent | undefined>;
|
||||
viewport: Ref<ViewportTransform>;
|
||||
isExperimentalNdvActive: ComputedRef<boolean>;
|
||||
isPaneMoving: Ref<boolean>;
|
||||
}
|
||||
|
||||
export type CanvasNodeEventBusEvents = {
|
||||
|
||||
Reference in New Issue
Block a user