'use client'; import { useEffect, useState } from 'react'; import { type Edge, MarkerType, type Node, useEdgesState, useNodesState } from 'reactflow'; import { TGEdgeTypes } from '@/features/rsform/components/term-graph/graph/tg-edge-types'; import { TGNodeTypes } from '@/features/rsform/components/term-graph/graph/tg-node-types'; import { SelectColoring } from '@/features/rsform/components/term-graph/select-coloring'; import { ToolbarFocusedCst } from '@/features/rsform/components/term-graph/toolbar-focused-cst'; import { applyLayout, produceFilteredGraph, type TGNodeData } from '@/features/rsform/models/graph-api'; import { type IConstituenta, type IRSForm } from '@/features/rsform/models/rsform'; import { flowOptions } from '@/features/rsform/pages/rsform-page/editor-term-graph/tg-flow'; import { useTermGraphStore } from '@/features/rsform/stores/term-graph'; import { DiagramFlow, useReactFlow } from '@/components/flow/diagram-flow'; import { PARAMETER } from '@/utils/constants'; import ToolbarGraphFilter from './toolbar-graph-filter'; export interface TGReadonlyFlowProps { schema: IRSForm; } export function TGReadonlyFlow({ schema }: TGReadonlyFlowProps) { const [focusCst, setFocusCst] = useState(null); const filter = useTermGraphStore(state => state.filter); const filteredGraph = produceFilteredGraph(schema, filter, focusCst); const [nodes, setNodes, onNodesChange] = useNodesState([]); const [edges, setEdges] = useEdgesState([]); const { fitView, viewportInitialized } = useReactFlow(); useEffect(() => { if (!viewportInitialized) { return; } const newNodes: Node[] = []; filteredGraph.nodes.forEach(node => { const cst = schema.cstByID.get(node.id); if (cst) { newNodes.push({ id: String(node.id), type: 'concept', position: { x: 0, y: 0 }, data: { cst: cst, focused: focusCst?.id === cst.id } }); } }); const newEdges: Edge[] = []; let edgeID = 1; filteredGraph.nodes.forEach(source => { source.outputs.forEach(target => { if (newNodes.find(node => node.id === String(target))) { newEdges.push({ id: String(edgeID), source: String(source.id), target: String(target), type: 'termEdge', focusable: false, markerEnd: { type: MarkerType.ArrowClosed, width: 20, height: 20 } }); edgeID += 1; } }); }); applyLayout(newNodes, newEdges, !filter.noText); setNodes(newNodes); setEdges(newEdges); setTimeout(() => fitView(flowOptions.fitViewOptions), PARAMETER.minimalTimeout); }, [schema, filteredGraph, setNodes, setEdges, filter.noText, fitView, viewportInitialized, focusCst]); function handleNodeContextMenu(event: React.MouseEvent, node: TGNodeData) { event.preventDefault(); event.stopPropagation(); setFocusCst(focusCst?.id === node.data.cst.id ? null : node.data.cst); } return (
setFocusCst(null)} />
event.preventDefault()} onNodeContextMenu={handleNodeContextMenu} />
); }