fix: Add factor to prevent overlap (#5426)
* fix: add random factor to prevent overlap * update package.lock * feat: Add positionDictionary and related functions to FlowStoreType * feat: Add buildPositionDictionary function to reactflowUtils.ts * feat: Add buildPositionDictionary function to reactflowUtils.ts This commit adds the buildPositionDictionary function to reactflowUtils.ts. This function is used to build a dictionary of positions for nodes in the flow. It is necessary for managing the positions of nodes and preventing overlap. * fix: Remove random factor from paste function in PageComponent * [autofix.ci] apply automated fixes * feat: Add setPositionDictionary function to PageComponent This commit adds the setPositionDictionary function to the PageComponent in order to set the position dictionary for the flow. This function is used to update the position dictionary when the canvas is moved or resized. Co-authored-by: [Author Name] * [autofix.ci] apply automated fixes * Refactor position calculation in useFlowStore * [autofix.ci] apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
f8ca6d4980
commit
1f614ccca6
4 changed files with 52 additions and 1 deletions
|
|
@ -86,6 +86,9 @@ export default function Page({ view }: { view?: boolean }): JSX.Element {
|
|||
const templates = useTypesStore((state) => state.templates);
|
||||
const setFilterEdge = useFlowStore((state) => state.setFilterEdge);
|
||||
const reactFlowWrapper = useRef<HTMLDivElement>(null);
|
||||
const setPositionDictionary = useFlowStore(
|
||||
(state) => state.setPositionDictionary,
|
||||
);
|
||||
|
||||
const reactFlowInstance = useFlowStore((state) => state.reactFlowInstance);
|
||||
const setReactFlowInstance = useFlowStore(
|
||||
|
|
@ -338,7 +341,15 @@ export default function Page({ view }: { view?: boolean }): JSX.Element {
|
|||
// 👇 make moving the canvas undoable
|
||||
autoSaveFlow();
|
||||
updateCurrentFlow({ nodes });
|
||||
}, [takeSnapshot, autoSaveFlow, nodes, edges, reactFlowInstance]);
|
||||
setPositionDictionary({});
|
||||
}, [
|
||||
takeSnapshot,
|
||||
autoSaveFlow,
|
||||
nodes,
|
||||
edges,
|
||||
reactFlowInstance,
|
||||
setPositionDictionary,
|
||||
]);
|
||||
|
||||
const onSelectionDragStart: SelectionDragHandler = useCallback(() => {
|
||||
// 👇 make dragging a selection undoable
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import {
|
|||
import { FlowStoreType, VertexLayerElementType } from "../types/zustand/flow";
|
||||
import { buildFlowVerticesWithFallback } from "../utils/buildUtils";
|
||||
import {
|
||||
buildPositionDictionary,
|
||||
checkChatInput,
|
||||
cleanEdges,
|
||||
detectBrokenEdgesEdges,
|
||||
|
|
@ -52,6 +53,19 @@ import { useTypesStore } from "./typesStore";
|
|||
|
||||
// this is our useStore hook that we can use in our components to get parts of the store and call actions
|
||||
const useFlowStore = create<FlowStoreType>((set, get) => ({
|
||||
positionDictionary: {},
|
||||
setPositionDictionary: (positionDictionary) => {
|
||||
set({ positionDictionary });
|
||||
},
|
||||
isPositionAvailable: (position: { x: number; y: number }) => {
|
||||
if (
|
||||
get().positionDictionary[position.x] &&
|
||||
get().positionDictionary[position.x] === position.y
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
fitViewNode: (nodeId) => {
|
||||
if (get().reactFlowInstance && get().nodes.find((n) => n.id === nodeId)) {
|
||||
get().reactFlowInstance?.fitView({ nodes: [{ id: nodeId }] });
|
||||
|
|
@ -211,6 +225,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
|
|||
hasIO: inputs.length > 0 || outputs.length > 0,
|
||||
flowPool: {},
|
||||
currentFlow: flow,
|
||||
positionDictionary: {},
|
||||
});
|
||||
},
|
||||
setIsBuilding: (isBuilding) => {
|
||||
|
|
@ -386,6 +401,17 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
|
|||
y: position.y,
|
||||
});
|
||||
|
||||
let internalPostionDictionary = get().positionDictionary;
|
||||
if (Object.keys(internalPostionDictionary).length === 0) {
|
||||
internalPostionDictionary = buildPositionDictionary(get().nodes);
|
||||
}
|
||||
while (!get().isPositionAvailable(insidePosition)) {
|
||||
insidePosition.x += 10;
|
||||
insidePosition.y += 10;
|
||||
}
|
||||
internalPostionDictionary[insidePosition.x] = insidePosition.y;
|
||||
get().setPositionDictionary(internalPostionDictionary);
|
||||
|
||||
selection.nodes.forEach((node: AllNodeType) => {
|
||||
// Generate a unique node ID
|
||||
let newId = getNodeId(node.data.type);
|
||||
|
|
|
|||
|
|
@ -53,6 +53,12 @@ export type FlowPoolType = {
|
|||
};
|
||||
|
||||
export type FlowStoreType = {
|
||||
//key x, y
|
||||
positionDictionary: { [key: number]: number };
|
||||
isPositionAvailable: (position: { x: number; y: number }) => boolean;
|
||||
setPositionDictionary: (positionDictionary: {
|
||||
[key: number]: number;
|
||||
}) => void;
|
||||
fitViewNode: (nodeId: string) => void;
|
||||
autoSaveFlow: (() => void) | undefined;
|
||||
componentsToUpdate: string[];
|
||||
|
|
|
|||
|
|
@ -1746,3 +1746,11 @@ export function someFlowTemplateFields(
|
|||
export function checkHasToolMode(template: APITemplateType) {
|
||||
return template && Object.values(template).some((field) => field.tool_mode);
|
||||
}
|
||||
|
||||
export function buildPositionDictionary(nodes: AllNodeType[]) {
|
||||
const positionDictionary = {};
|
||||
nodes.forEach((node) => {
|
||||
positionDictionary[node.position.x] = node.position.y;
|
||||
});
|
||||
return positionDictionary;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue