From e0409a2fed41716262be2428250f63f811e3eb7c Mon Sep 17 00:00:00 2001 From: Aditya Choudhari Date: Mon, 23 Dec 2024 17:17:17 -0500 Subject: [PATCH] fix: React flow diagrams don't shift when dragging node --- .../ResourceVisualizationDiagram.tsx | 2 +- .../(app)/_components/reactflow/layout.ts | 2 +- .../releases/[versionId]/FlowDiagram.tsx | 32 +++++-------------- .../environments/EnvFlowBuilder.tsx | 30 ++++------------- 4 files changed, 16 insertions(+), 50 deletions(-) diff --git a/apps/webservice/src/app/[workspaceSlug]/(app)/(resources)/resources/[resourceId]/visualize/ResourceVisualizationDiagram.tsx b/apps/webservice/src/app/[workspaceSlug]/(app)/(resources)/resources/[resourceId]/visualize/ResourceVisualizationDiagram.tsx index d59947b7..02dcb771 100644 --- a/apps/webservice/src/app/[workspaceSlug]/(app)/(resources)/resources/[resourceId]/visualize/ResourceVisualizationDiagram.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/(app)/(resources)/resources/[resourceId]/visualize/ResourceVisualizationDiagram.tsx @@ -29,7 +29,7 @@ export const ResourceVisualizationDiagram: React.FC< const [edges, __, onEdgesChange] = useEdgesState(getEdges(relationships)); - const setReactFlowInstance = useLayoutAndFitView(nodes, { + const { setReactFlowInstance } = useLayoutAndFitView(nodes, { direction: "LR", extraEdgeLength: 50, focusedNodeId: relationships.resource.id, diff --git a/apps/webservice/src/app/[workspaceSlug]/(app)/_components/reactflow/layout.ts b/apps/webservice/src/app/[workspaceSlug]/(app)/_components/reactflow/layout.ts index 31eb641e..bcf875d9 100644 --- a/apps/webservice/src/app/[workspaceSlug]/(app)/_components/reactflow/layout.ts +++ b/apps/webservice/src/app/[workspaceSlug]/(app)/_components/reactflow/layout.ts @@ -146,5 +146,5 @@ export const useLayoutAndFitView = (nodes: Node[], config?: LayoutConfig) => { setDefaultView, ]); - return setReactFlowInstance; + return { setReactFlowInstance, onLayout }; }; diff --git a/apps/webservice/src/app/[workspaceSlug]/(app)/systems/[systemSlug]/deployments/[deploymentSlug]/releases/[versionId]/FlowDiagram.tsx b/apps/webservice/src/app/[workspaceSlug]/(app)/systems/[systemSlug]/deployments/[deploymentSlug]/releases/[versionId]/FlowDiagram.tsx index 270a23e1..c7f7d5c1 100644 --- a/apps/webservice/src/app/[workspaceSlug]/(app)/systems/[systemSlug]/deployments/[deploymentSlug]/releases/[versionId]/FlowDiagram.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/(app)/systems/[systemSlug]/deployments/[deploymentSlug]/releases/[versionId]/FlowDiagram.tsx @@ -7,8 +7,7 @@ import type { Release, Workspace, } from "@ctrlplane/db/schema"; -import type { NodeTypes, ReactFlowInstance } from "reactflow"; -import { useCallback, useEffect, useState } from "react"; +import type { NodeTypes } from "reactflow"; import ReactFlow, { useEdgesState, useNodesState } from "reactflow"; import { ArrowEdge } from "~/app/[workspaceSlug]/(app)/_components/reactflow/ArrowEdge"; @@ -18,7 +17,7 @@ import { createEdgesFromReleaseSequencingToEnvironment, createEdgesWherePolicyHasNoEnvironment, } from "~/app/[workspaceSlug]/(app)/_components/reactflow/edges"; -import { getLayoutedElementsDagre } from "~/app/[workspaceSlug]/(app)/_components/reactflow/layout"; +import { useLayoutAndFitView } from "~/app/[workspaceSlug]/(app)/_components/reactflow/layout"; import { EnvironmentNode } from "./FlowNode"; import { PolicyNode } from "./FlowPolicyNode"; import { ReleaseSequencingNode } from "./ReleaseSequencingNode"; @@ -38,10 +37,7 @@ export const FlowDiagram: React.FC<{ policies: Array; policyDeployments: Array; }> = ({ workspace, release, envs, policies, policyDeployments }) => { - const [reactFlowInstance, setReactFlowInstance] = - useState(null); - - const [nodes, setNodes, onNodesChange] = useNodesState<{ label: string }>([ + const [nodes, _, onNodesChange] = useNodesState<{ label: string }>([ { id: "trigger", type: "trigger", @@ -86,29 +82,17 @@ export const FlowDiagram: React.FC<{ }), ]); - const [edges, setEdges, onEdgesChange] = useEdgesState([ + const [edges, __, onEdgesChange] = useEdgesState([ ...createEdgesFromPolicyToReleaseSequencing(envs), ...createEdgesFromReleaseSequencingToEnvironment(envs), ...createEdgesWherePolicyHasNoEnvironment(policies, policyDeployments), ...createEdgesFromPolicyDeployment(policyDeployments), ]); - const onLayout = useCallback(() => { - const layouted = getLayoutedElementsDagre(nodes, edges, "LR"); - - setNodes([...layouted.nodes]); - setEdges([...layouted.edges]); - }, [nodes, edges, setNodes, setEdges]); - - useEffect(() => { - if (reactFlowInstance && nodes.length) - reactFlowInstance.fitView({ padding: 0.16, maxZoom: 1 }); - }, [reactFlowInstance, nodes, edges]); - - useEffect(() => { - if (reactFlowInstance != null) onLayout(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [reactFlowInstance]); + const { setReactFlowInstance } = useLayoutAndFitView(nodes, { + direction: "LR", + padding: 0.16, + }); return ( ; policyDeployments: Array; }> = ({ systemId, envs, policies, policyDeployments }) => { - const [nodes, setNodes, onNodesChange] = useNodesState([ + const [nodes, _, onNodesChange] = useNodesState([ triggerNode, ...envs.map((env) => ({ id: env.id, @@ -203,7 +203,7 @@ export const EnvFlowBuilder: React.FC<{ if (selected != null) setSelectedNodeId(selected); }); - const [edges, setEdges, onEdgesChange] = useEdgesState([ + const [edges, __, onEdgesChange] = useEdgesState([ ...createEdgesWhereEnvironmentHasNoPolicy(envs), ...createEdgesWherePolicyHasNoEnvironment(policies, policyDeployments), ...createEdgesFromPolicyDeployment(policyDeployments), @@ -213,25 +213,7 @@ export const EnvFlowBuilder: React.FC<{ const onConnect = useOnConnect(); - const [reactFlowInstance, setReactFlowInstance] = - useState(null); - - const onLayout = useCallback(() => { - const layouted = getLayoutedElementsDagre(nodes, edges, "TB"); - - setNodes([...layouted.nodes]); - setEdges([...layouted.edges]); - }, [nodes, edges, setNodes, setEdges]); - - useEffect(() => { - if (reactFlowInstance && nodes.length) - reactFlowInstance.fitView({ padding: 0.12, maxZoom: 1 }); - }, [reactFlowInstance, nodes]); - - useEffect(() => { - if (reactFlowInstance != null) onLayout(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [reactFlowInstance]); + const { setReactFlowInstance, onLayout } = useLayoutAndFitView(nodes); const onEdgeClick = useOnEdgeClick();