'use client'; import { useCallback, useMemo } from 'react'; import { Edge, EdgeChange, Node, NodeChange, NodeTypes, ProOptions, ReactFlow, useEdgesState, useNodesState, useViewport } from 'reactflow'; import Overlay from '@/components/ui/Overlay'; import AnimateFade from '@/components/wrap/AnimateFade'; import { useConceptOptions } from '@/context/ConceptOptionsContext'; import { useOSS } from '@/context/OssContext'; import { useOssEdit } from '../OssEditContext'; import InputNode from './InputNode'; import OperationNode from './OperationNode'; import ToolbarOssGraph from './ToolbarOssGraph'; function OssFlow() { const { calculateHeight } = useConceptOptions(); const model = useOSS(); const controller = useOssEdit(); const viewport = useViewport(); const initialNodes: Node[] = useMemo( () => !model.schema ? [] : model.schema.items.map(operation => ({ id: String(operation.id), data: { label: operation.alias }, position: { x: operation.position_x, y: operation.position_y }, type: operation.operation_type.toString() })), [model.schema] ); // const initialNodes = [ // { id: '1', data: { label: '-' }, position: { x: 100, y: 100 } }, // { id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 200 } } // ]; const initialEdges: Edge[] = useMemo( () => !model.schema ? [] : model.schema.arguments.map((argument, index) => ({ id: String(index), source: String(argument.argument), target: String(argument.operation) })), [model.schema] ); // const initialEdges = [{ id: 'e1-2', source: '1', target: '2' }]; const [nodes, onNodesChange] = useNodesState(initialNodes); const [edges, onEdgesChange] = useEdgesState(initialEdges); const getPositions = useCallback( () => nodes.map(node => ({ id: Number(node.id), position_x: node.position.x, position_y: node.position.y })), [nodes] ); const handleNodesChange = useCallback( (changes: NodeChange[]) => { // @ts-expect-error TODO: Figure out internal type errors in ReactFlow onNodesChange(changes); }, [onNodesChange] ); const handleEdgesChange = useCallback( (changes: EdgeChange[]) => { // @ts-expect-error TODO: Figure out internal type errors in ReactFlow onEdgesChange(changes); }, [onEdgesChange] ); const handleCreateOperation = useCallback(() => { // TODO: calculate insert location controller.promptCreateOperation(viewport.x, viewport.y, getPositions()); }, [controller, viewport, getPositions]); const proOptions: ProOptions = useMemo(() => ({ hideAttribution: true }), []); const canvasWidth = useMemo(() => 'calc(100vw - 1rem)', []); const canvasHeight = useMemo(() => calculateHeight('1.75rem + 4px'), [calculateHeight]); const OssNodeTypes: NodeTypes = useMemo( () => ({ synthesis: OperationNode, input: InputNode }), [] ); const graph = useMemo( () => ( ), [nodes, edges, proOptions, handleNodesChange, handleEdgesChange, OssNodeTypes] ); return (
{graph}
); } export default OssFlow;