mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 01:56:46 +00:00
113 lines
3.2 KiB
TypeScript
113 lines
3.2 KiB
TypeScript
import { MAIN_HEADER_TABS, VIEWS } from '@/constants';
|
|
import type { IZoomConfig } from '@/Interface';
|
|
import { useWorkflowsStore } from '@/stores/workflows.store';
|
|
import type { ConnectionDetachedParams } from '@jsplumb/core';
|
|
import type { IConnection } from 'n8n-workflow';
|
|
import type { RouteLocation } from 'vue-router';
|
|
|
|
/*
|
|
Constants and utility functions mainly used by canvas store
|
|
and components used to display workflow in node view.
|
|
These are general-purpose functions that are exported
|
|
with this module and should be used by importing from
|
|
'@/utils/canvasUtils'.
|
|
*/
|
|
|
|
const SCALE_CHANGE_FACTOR = 1.25;
|
|
const MIN_SCALE = 0.2;
|
|
const MAX_SCALE = 5;
|
|
const SCROLL_ZOOM_SPEED = 0.01;
|
|
const MAX_WHEEL_DELTA = 32;
|
|
|
|
const clamp = (min: number, max: number) => (num: number) => {
|
|
return Math.max(min, Math.min(max, num));
|
|
};
|
|
|
|
const clampScale = clamp(MIN_SCALE, MAX_SCALE);
|
|
|
|
export const applyScale =
|
|
(scale: number) =>
|
|
({ scale: initialScale, offset: [xOffset, yOffset], origin }: IZoomConfig): IZoomConfig => {
|
|
const newScale = clampScale(initialScale * scale);
|
|
const scaleChange = newScale / initialScale;
|
|
|
|
const xOrigin = origin?.[0] ?? window.innerWidth / 2;
|
|
const yOrigin = origin?.[1] ?? window.innerHeight / 2;
|
|
|
|
// Calculate the new offsets based on the zoom origin
|
|
xOffset = xOrigin - scaleChange * (xOrigin - xOffset);
|
|
yOffset = yOrigin - scaleChange * (yOrigin - yOffset);
|
|
|
|
return {
|
|
scale: newScale,
|
|
offset: [xOffset, yOffset],
|
|
};
|
|
};
|
|
|
|
export const scaleBigger = applyScale(SCALE_CHANGE_FACTOR);
|
|
|
|
export const scaleSmaller = applyScale(1 / SCALE_CHANGE_FACTOR);
|
|
|
|
export const scaleReset = (config: IZoomConfig): IZoomConfig => {
|
|
return applyScale(1 / config.scale)(config);
|
|
};
|
|
|
|
export const getNodeViewTab = (route: RouteLocation): string | null => {
|
|
if (route.meta?.nodeView) {
|
|
return MAIN_HEADER_TABS.WORKFLOW;
|
|
} else if (
|
|
[VIEWS.WORKFLOW_EXECUTIONS, VIEWS.EXECUTION_PREVIEW, VIEWS.EXECUTION_HOME]
|
|
.map(String)
|
|
.includes(String(route.name))
|
|
) {
|
|
return MAIN_HEADER_TABS.EXECUTIONS;
|
|
}
|
|
return null;
|
|
};
|
|
|
|
export const getConnectionInfo = (
|
|
connection: ConnectionDetachedParams,
|
|
): [IConnection, IConnection] | null => {
|
|
const sourceInfo = connection.sourceEndpoint.parameters;
|
|
const targetInfo = connection.targetEndpoint.parameters;
|
|
const sourceNode = useWorkflowsStore().getNodeById(sourceInfo.nodeId);
|
|
const targetNode = useWorkflowsStore().getNodeById(targetInfo.nodeId);
|
|
|
|
if (sourceNode && targetNode) {
|
|
return [
|
|
{
|
|
node: sourceNode.name,
|
|
type: sourceInfo.type,
|
|
index: sourceInfo.index,
|
|
},
|
|
{
|
|
node: targetNode.name,
|
|
type: targetInfo.type,
|
|
index: targetInfo.index,
|
|
},
|
|
];
|
|
}
|
|
return null;
|
|
};
|
|
|
|
const clampWheelDelta = clamp(-MAX_WHEEL_DELTA, MAX_WHEEL_DELTA);
|
|
|
|
export const normalizeWheelEventDelta = (event: WheelEvent): { deltaX: number; deltaY: number } => {
|
|
const factorByMode: Record<number, number> = {
|
|
[WheelEvent.DOM_DELTA_PIXEL]: 1,
|
|
[WheelEvent.DOM_DELTA_LINE]: 8,
|
|
[WheelEvent.DOM_DELTA_PAGE]: 24,
|
|
};
|
|
|
|
const factor = factorByMode[event.deltaMode] ?? 1;
|
|
|
|
return {
|
|
deltaX: clampWheelDelta(event.deltaX * factor),
|
|
deltaY: clampWheelDelta(event.deltaY * factor),
|
|
};
|
|
};
|
|
|
|
export const getScaleFromWheelEventDelta = (delta: number): number => {
|
|
return Math.pow(2, -delta * SCROLL_ZOOM_SPEED);
|
|
};
|