import { CircularPlant, CircularProduct, CircularCenter } from "./CircularData"; import { Node, Edge } from "@xyflow/react"; import styles from "./PipelineBlock.module.css"; import { ReactFlow, Background, Controls, MarkerType } from '@xyflow/react'; import Section from '../Common/Section'; import Card from '../Common/Card'; import { useEffect, useCallback } from "react"; import { Connection } from '@xyflow/react'; import CustomNode, { CustomNodeData }from "./NodesAndEdges"; interface PipelineBlockProps { onAddPlant: () => void; onAddProduct: () => void; onAddCenter: () => void; onMovePlant: (name: string , x: number, y: number) => void; onMoveProduct: (name: string, x: number, y: number) => void; onMoveCenter: (name: string, x: number, y: number) => void; onSetPlantInput: (plantName:string, productName: string) => void; onAddPlantOutput: (plantName: string, productName: string) => void; onAddCenterInput: (plantName: string, productName: string) => void; onAddCenterOutput: (plantName: string, productName: string) => void; onRemovePlant: (id:string) => void; onRemoveProduct: (id: string) => void; onRemoveCenter: (id: string) => void; products: Record; plants: Record; centers: Record; } const onNodeDoubleClick = () => {}; const handleNodesDelete = () => {}; const handleEdgesDelete = () => {}; const onLayout = () => {}; const PipelineBlock: React.FC = (props) => { const nodes: Node[] = []; const edges: Edge[] = []; let mapNameToType: Record = {}; let hasNullPositions: boolean = false; const onConnect = (params: Connection) => { const { source, target } = params; if (!source || ! target) return; const sourceType = mapNameToType[source]; const targetType = mapNameToType[target]; if (sourceType === "product" && targetType === "plant") { props.onSetPlantInput(target,source); } else if (sourceType === "plant" && targetType === "product") { props.onAddPlantOutput(source, target); } else if (sourceType === "product" && targetType === "center") { props.onAddCenterInput(target, source); } else if (sourceType === "center" && targetType === "product") { props.onAddCenterOutput(source, target); } }; const onNodeDragStop =(_:any, node: Node) => { const { id, position, data} = node; if (data.type === "plant") { props.onMovePlant(id, position.x, position.y); } if (data.type === "product") { props.onMoveProduct(id, position.x, position.y); } if (data.type === "center") { props.onMoveCenter(id, position.x, position.y); } }; const handleNodesDelete = useCallback((deleted: Node[]) => { deleted.forEach((n) => { const type = mapNameToType[n.id]; if (type === "plant") { props.onRemovePlant(n.id); } else if (type === "product") { props.onRemoveProduct(n.id); } else if (type === "center") { props.onRemoveCenter!(n.id); } }); }, [props, mapNameToType]); for (const [productName, product] of Object.entries(props.products) as [string, CircularProduct][]) { if(!product.x || !product.y) hasNullPositions = true; mapNameToType[productName] = "product"; nodes.push({ id: productName, type: "default", data: {label: productName, type: 'product'}, position: { x:product.x, y:product.y}, className: 'ProductNode' }); } for (const [plantName, plant] of Object.entries(props.plants) as [string, CircularPlant][]) { if(!plant.x || !plant.y) hasNullPositions = true; mapNameToType[plantName] = "plant"; nodes.push({ id: plantName, type: "default", data: {label: plantName, type: 'plant'}, position: { x:plant.x, y:plant.y}, className: 'PlantNode' }); if (plant) { for (const inputProduct of plant.inputs){ edges.push({ id: `${inputProduct}-${plantName}`, source: inputProduct, target: plantName, animated: true, style: { stroke: "black" }, markerEnd: { type: MarkerType.ArrowClosed, }, }); } for (const outputProduct of plant.outputs ?? []) { edges.push({ id: `${plantName}-${outputProduct}`, source: plantName, target: outputProduct, animated: true, style: { stroke: 'black' }, markerEnd: { type: MarkerType.ArrowClosed }, }); } } } for (const [centerName, center] of Object.entries(props.centers)) { mapNameToType[centerName] = "center"; nodes.push({ id: centerName, type: "default", data: { label: centerName, type: "center"}, position: {x: center.x, y: center.y}, className: 'CenterNode' }); if (center.input) { edges.push({ id: `${center.input}-${centerName}`, source: center.input, target:centerName, animated: true, style: { stroke: "black"}, markerEnd: { type: MarkerType.ArrowClosed}, }); } for (const out of center.output) { edges.push({ id: `${centerName}-${out}`, source: centerName, target:out, animated: true, style: { stroke: "black"}, markerEnd: { type: MarkerType.ArrowClosed}, }); } } useEffect(() => { if (hasNullPositions) onLayout(); }, [hasNullPositions]); return ( <>
); }; export default PipelineBlock;