"use client"; import { useCallback } from "react"; import { toast } from "sonner"; import { api } from "~/lib/api/client"; import { useGraphStore } from "~/modules/diagram/stores/useGraphStore"; import { graphToFlow } from "~/modules/diagram/lib/graph-converter"; import type { DiagramType, GraphData } from "~/modules/diagram/types/graph"; interface GraphPatchData { meta: { diagramType: string; title: string; version?: string; layoutDirection?: "DOWN" | "RIGHT" | "LEFT" | "UP"; edgeRouting?: "ORTHOGONAL" | "SPLINES" | "POLYLINE"; }; nodes: GraphData["nodes"]; edges: GraphData["edges"]; pools?: GraphData["pools"]; groups?: GraphData["groups"]; } function patchToGraphData(patch: GraphPatchData, fallbackType: DiagramType): GraphData { const effectiveDiagramType = (patch.meta.diagramType as DiagramType) ?? fallbackType; return { meta: { version: patch.meta.version ?? "1", title: patch.meta.title, diagramType: effectiveDiagramType, layoutDirection: patch.meta.layoutDirection, edgeRouting: patch.meta.edgeRouting, }, nodes: patch.nodes, edges: patch.edges, pools: patch.pools, groups: patch.groups, }; } export function persistGraphData(diagramId: string, graphData: GraphData) { api.diagrams[":id"] .$patch({ param: { id: diagramId }, json: { graphData: graphData as unknown as Record }, }) .then((res) => { if (!res.ok) { toast.error("Failed to save diagram — changes may be lost on reload"); } }) .catch(() => { toast.error("Failed to save diagram — changes may be lost on reload"); }); } export function useGraphMutation(diagramId: string, diagramType: DiagramType) { const setNodes = useGraphStore((s) => s.setNodes); const setEdges = useGraphStore((s) => s.setEdges); const setLayoutDirection = useGraphStore((s) => s.setLayoutDirection); const setEdgeRouting = useGraphStore((s) => s.setEdgeRouting); const requestLayout = useGraphStore((s) => s.requestLayout); const applyGraphPatch = useCallback( (patch: GraphPatchData) => { const graphData = patchToGraphData(patch, diagramType); const { nodes, edges } = graphToFlow(graphData); setNodes(nodes); setEdges(edges); if (graphData.meta?.layoutDirection) { setLayoutDirection(graphData.meta.layoutDirection); } if (graphData.meta?.edgeRouting) { setEdgeRouting(graphData.meta.edgeRouting); } requestLayout(); persistGraphData(diagramId, graphData); }, [ diagramId, diagramType, setNodes, setEdges, setLayoutDirection, setEdgeRouting, requestLayout, ], ); const proposeGraphPatch = useCallback( (patch: GraphPatchData) => { const graphData = patchToGraphData(patch, diagramType); useGraphStore.getState().proposeChanges(graphData); }, [diagramType], ); return { applyGraphPatch, proposeGraphPatch }; }