* ⚡ Adjust `format` script * 🔥 Remove exemption for `editor-ui` * 🎨 Prettify * 👕 Fix lint
140 lines
3.9 KiB
TypeScript
140 lines
3.9 KiB
TypeScript
import { computed, ref } from 'vue';
|
|
import { defineStore } from 'pinia';
|
|
import { jsPlumb } from 'jsplumb';
|
|
import { v4 as uuid } from 'uuid';
|
|
import normalizeWheel from 'normalize-wheel';
|
|
import { useWorkflowsStore } from '@/stores/workflows';
|
|
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
|
import { useUIStore } from '@/stores/ui';
|
|
import { INodeUi, XYPosition } from '@/Interface';
|
|
import { scaleBigger, scaleReset, scaleSmaller } from '@/utils';
|
|
import { START_NODE_TYPE } from '@/constants';
|
|
import '@/plugins/N8nCustomConnectorType';
|
|
import '@/plugins/PlusEndpointType';
|
|
import {
|
|
DEFAULT_PLACEHOLDER_TRIGGER_BUTTON,
|
|
getMidCanvasPosition,
|
|
getNewNodePosition,
|
|
getZoomToFit,
|
|
PLACEHOLDER_TRIGGER_NODE_SIZE,
|
|
} from '@/utils/nodeViewUtils';
|
|
|
|
export const useCanvasStore = defineStore('canvas', () => {
|
|
const workflowStore = useWorkflowsStore();
|
|
const nodeTypesStore = useNodeTypesStore();
|
|
const uiStore = useUIStore();
|
|
const jsPlumbInstance = jsPlumb.getInstance();
|
|
|
|
const nodes = computed<INodeUi[]>(() => workflowStore.allNodes);
|
|
const triggerNodes = computed<INodeUi[]>(() =>
|
|
nodes.value.filter(
|
|
(node) => node.type === START_NODE_TYPE || nodeTypesStore.isTriggerNode(node.type),
|
|
),
|
|
);
|
|
const isDemo = ref<boolean>(false);
|
|
const nodeViewScale = ref<number>(1);
|
|
const canvasAddButtonPosition = ref<XYPosition>([1, 1]);
|
|
|
|
const setRecenteredCanvasAddButtonPosition = (offset?: XYPosition) => {
|
|
const position = getMidCanvasPosition(nodeViewScale.value, offset || [0, 0]);
|
|
|
|
position[0] -= PLACEHOLDER_TRIGGER_NODE_SIZE / 2;
|
|
position[1] -= PLACEHOLDER_TRIGGER_NODE_SIZE / 2;
|
|
|
|
canvasAddButtonPosition.value = getNewNodePosition(nodes.value, position);
|
|
};
|
|
|
|
const getPlaceholderTriggerNodeUI = (): INodeUi => {
|
|
setRecenteredCanvasAddButtonPosition();
|
|
|
|
return {
|
|
id: uuid(),
|
|
...DEFAULT_PLACEHOLDER_TRIGGER_BUTTON,
|
|
position: canvasAddButtonPosition.value,
|
|
};
|
|
};
|
|
|
|
const getNodesWithPlaceholderNode = (): INodeUi[] =>
|
|
triggerNodes.value.length > 0 ? nodes.value : [getPlaceholderTriggerNodeUI(), ...nodes.value];
|
|
|
|
const setZoomLevel = (zoomLevel: number, offset: XYPosition) => {
|
|
nodeViewScale.value = zoomLevel;
|
|
jsPlumbInstance.setZoom(zoomLevel);
|
|
uiStore.nodeViewOffsetPosition = offset;
|
|
};
|
|
|
|
const resetZoom = () => {
|
|
const { scale, offset } = scaleReset({
|
|
scale: nodeViewScale.value,
|
|
offset: uiStore.nodeViewOffsetPosition,
|
|
});
|
|
setZoomLevel(scale, offset);
|
|
};
|
|
|
|
const zoomIn = () => {
|
|
const { scale, offset } = scaleBigger({
|
|
scale: nodeViewScale.value,
|
|
offset: uiStore.nodeViewOffsetPosition,
|
|
});
|
|
setZoomLevel(scale, offset);
|
|
};
|
|
|
|
const zoomOut = () => {
|
|
const { scale, offset } = scaleSmaller({
|
|
scale: nodeViewScale.value,
|
|
offset: uiStore.nodeViewOffsetPosition,
|
|
});
|
|
setZoomLevel(scale, offset);
|
|
};
|
|
|
|
const zoomToFit = () => {
|
|
const nodes = getNodesWithPlaceholderNode();
|
|
if (!nodes.length) {
|
|
// some unknown workflow executions
|
|
return;
|
|
}
|
|
const { zoomLevel, offset } = getZoomToFit(nodes, !isDemo.value);
|
|
setZoomLevel(zoomLevel, offset);
|
|
};
|
|
|
|
const wheelMoveWorkflow = (e: WheelEvent) => {
|
|
const normalized = normalizeWheel(e);
|
|
const offsetPosition = uiStore.nodeViewOffsetPosition;
|
|
const nodeViewOffsetPositionX =
|
|
offsetPosition[0] - (e.shiftKey ? normalized.pixelY : normalized.pixelX);
|
|
const nodeViewOffsetPositionY =
|
|
offsetPosition[1] - (e.shiftKey ? normalized.pixelX : normalized.pixelY);
|
|
uiStore.nodeViewOffsetPosition = [nodeViewOffsetPositionX, nodeViewOffsetPositionY];
|
|
};
|
|
|
|
const wheelScroll = (e: WheelEvent) => {
|
|
//* Control + scroll zoom
|
|
if (e.ctrlKey) {
|
|
if (e.deltaY > 0) {
|
|
zoomOut();
|
|
} else {
|
|
zoomIn();
|
|
}
|
|
|
|
e.preventDefault();
|
|
return;
|
|
}
|
|
wheelMoveWorkflow(e);
|
|
};
|
|
|
|
return {
|
|
jsPlumbInstance,
|
|
isDemo,
|
|
nodeViewScale,
|
|
canvasAddButtonPosition,
|
|
setRecenteredCanvasAddButtonPosition,
|
|
getNodesWithPlaceholderNode,
|
|
setZoomLevel,
|
|
resetZoom,
|
|
zoomIn,
|
|
zoomOut,
|
|
zoomToFit,
|
|
wheelScroll,
|
|
};
|
|
});
|