import { useEffect, useMemo } from "react";
import ReactFlow, {
Background,
BackgroundVariant,
Controls,
MiniMap,
useReactFlow,
ReactFlowProvider,
type Node,
type NodeMouseHandler,
} from "reactflow";
import "reactflow/dist/style.css";
import "./graph-overrides.css";
import { layoutGraph } from "../lib/layout";
import type { IRGraph, IRNode } from "../types";
import { nodeTypes } from "./CustomNodes";
interface Props {
ir: IRGraph;
onSelectNode: (node: IRNode | null) => void;
}
function GraphViewInner({ ir, onSelectNode }: Props) {
const { nodes, edges } = useMemo(() => layoutGraph(ir), [ir]);
const { fitView } = useReactFlow();
// Re-fit the camera every time the underlying graph topology changes
// (e.g. a new model loaded, or the granularity slider collapsed clusters).
// Without this, the viewport stays where the previous graph was and the
// user can end up staring at an empty panel.
useEffect(() => {
const id = window.setTimeout(() => {
fitView({ duration: 200, padding: 0.15 });
}, 50);
return () => window.clearTimeout(id);
}, [nodes.length, edges.length, fitView]);
const handleNodeClick: NodeMouseHandler = (_e, node) => {
const irNode = (node.data as { irNode?: IRNode }).irNode ?? null;
onSelectNode(irNode);
};
const handlePaneClick = () => onSelectNode(null);
const nodeColor = (n: Node) =>
(n.data as { color?: string }).color ?? "#6477a8";
return (
);
}
export function GraphView(props: Props) {
return (
);
}