import Custom from "../Nodes/Custom.js"; import CustomNodeIframe from "../Nodes/Custom.js"; import '../../css/dist/output.css' import ReactFlow, { Background, applyNodeChanges, ReactFlowProvider, addEdge, updateEdge, applyEdgeChanges, Controls, MarkerType } from 'react-flow-renderer'; import React ,{ useState, useCallback, useRef, useEffect } from 'react'; import Navbar from '../Navagation/navbar'; import CustomEdge from '../Edges/Custom' import CustomLine from "../Edges/CustomLine.js"; import { useThemeDetector } from '../../helper/visual' import {CgMoreVerticalAlt} from 'react-icons/cg' import {BsFillEraserFill} from 'react-icons/bs' import {FaRegSave} from 'react-icons/fa' const NODE = { custom : CustomNodeIframe, embed: Custom, } const EDGE = { custom : CustomEdge } export default function ReactEnviorment() { const [theme, setTheme] = useState(useThemeDetector) const [nodes, setNodes] = useState([]); const [edges, setEdges] = useState([]) const [reactFlowInstance, setReactFlowInstance] = useState(null); const reactFlowWrapper = useRef(null); const [tool, setTool] = useState(false) const [showProxmoxForm, setShowProxmoxForm] = useState(false); const deleteNodeContains = useCallback((id) => setNodes((nds) => nds.filter(n => !n.id.includes(`${id}-`))), [setNodes]); const deleteEdge = useCallback((id) => setEdges((eds) => eds.filter(e => e.id !== id)), [setEdges]); const deleteNode = useCallback((id) => setNodes((nds) => nds.filter(n => n.id !== id)), [setNodes]); useEffect(() => { const restore = () => { const flow = JSON.parse(localStorage.getItem('flowkey')); if(flow){ const updatedNodes = flow.nodes.map((nds) => ({ ...nds, data: { ...nds.data, delete: deleteNode }})); const updatedEdges = flow.edges.map((eds) => ({ ...eds, data: { ...eds.data, delete: deleteEdge }})); setNodes(updatedNodes || []); setEdges(updatedEdges || []); } } restore(); },[deleteNode, deleteEdge]); // const handleAddProxmoxVnc = async ({ vmid, node }) => { // const response = await fetch('http://localhost:5000/api/proxmox/vnc', { // method: 'POST', // headers: { 'Content-Type': 'application/json' }, // body: JSON.stringify({ vmid, node }), // }); // const data = await response.json(); // // Use data.iframe_src to create a new node in React Flow // const newNode = { // id: `proxmox-vnc-${nodes.length + 1}`, // type: 'custom', // position: reactFlowInstance.project({ x: 0, y: 0 }), // data: { label: `Proxmox VM ${vmid}`, url: data.iframe_src }, // }; // setNodes((nds) => nds.concat(newNode)); // }; // const handleAddEmbed = useCallback((embedData) => { // const newNode = { // id: `embed-${nodes.length + 1}`, // type: 'embed', // position: reactFlowInstance.project({ x: 0, y: 0 }), // Adjust position as needed // data: { url: embedData.url, width: embedData.width || '100%', height: embedData.height || '400px' }, // }; // setNodes((nds) => nds.concat(newNode)); // console.log(`Adding embed with URL: ${embedData.url} and Label: ${embedData.label}`); // }, [nodes, reactFlowInstance]); const onNodesChange = useCallback( (changes) => setNodes((nds) => applyNodeChanges(changes, nds)), [setNodes] ); const onEdgesChange = useCallback( (changes) => setEdges((eds) => applyEdgeChanges(changes, eds)), [setEdges] ); const onEdgeUpdate = useCallback( (oldEdge, newConnection) => setEdges((els) => updateEdge(oldEdge, newConnection, els)), [setEdges] ); const onConnect = useCallback( (params) => { setEdges((els) => addEdge({...params, type: "custom", animated : true, style : {stroke : "#00FF4A", strokeWidth : "6"}, markerEnd: {type: MarkerType.ArrowClosed, color : "#00FF4A"}, data : { delete : deleteEdge}}, els)) fetch("http://localhost:2000/api/append/connection", {method : "POST", mode : 'cors', headers : { 'Content-Type' : 'application/json' }, body: JSON.stringify({"source": params.source, "target" : params.target})}).then( res => { console.log(res) }).catch(error => { console.log(error) }) }, [setEdges, deleteEdge] ); const onDragOver = useCallback((event) => { event.preventDefault(); event.dataTransfer.dropEffect = 'move'; }, []); const onSave = useCallback(() => { if (reactFlowInstance) { const flow = reactFlowInstance.toObject(); alert("The current nodes have been saved into the localstorage 💾") localStorage.setItem('flowkey', JSON.stringify(flow)); var labels = []; var colour = []; var emoji = []; flow.nodes.forEach((node) => { if (!labels.includes(node.data.label)) { colour.push(node.data.colour); emoji.push(node.data.emoji); labels.push(node.data.label); } }); localStorage.setItem('colour', JSON.stringify(colour)); localStorage.setItem('emoji', JSON.stringify(emoji)); } }, [reactFlowInstance]); const onErase = useCallback(() => { const flow = localStorage.getItem("flowkey") if (reactFlowInstance && flow){ alert("The current nodes have been erased from the localstorage") localStorage.removeItem("flowkey") localStorage.removeItem('colour') localStorage.removeItem('emoji') } },[reactFlowInstance]); const onDrop = useCallback( (event) => { event.preventDefault(); if(event.dataTransfer.getData('application/reactflow') !== ""){ const reactFlowBounds = reactFlowWrapper.current.getBoundingClientRect(); const type = event.dataTransfer.getData('application/reactflow'); const item = JSON.parse(event.dataTransfer.getData('application/item')); const style = JSON.parse(event.dataTransfer.getData('application/style')); if (typeof type === 'undefined' || !type) { return; } const position = reactFlowInstance.project({ x: event.clientX - reactFlowBounds.left, y: event.clientY - reactFlowBounds.top, }); let newNode; if (type === 'embed') { newNode = { id: `embed-${nodes.length + 1}`, type: 'embed', position, data: { url: item.url, width: item.width, height: item.height }, }; } else if (type === 'customProxmox') { newNode = { id: `proxmox-vm-${nodes.length + 1}`, type: 'customProxmox', position, data: { vmAddress: item.vmAddress }, }; } else { newNode = { id: `${item.name}-${nodes.length+1}`, type, position, dragHandle : `#draggable`, data: { label: `${item.name}`, host : `${item.host}`, colour : `${style.colour}`, emoji : `${style.emoji}`, delete : deleteNode }, }; } if (newNode) { setNodes((nds) => nds.concat(newNode)); } } }, [reactFlowInstance, nodes, deleteNode]); // const addProxmoxVMNode = (vmAddress) => { // const newNode = { // id: `proxmox-vm-${nodes.length + 1}`, // type: 'proxmoxVM', // position: { x: Math.random() * window.innerWidth, y: Math.random() * window.innerHeight }, // data: { vmAddress }, // }; // setNodes((nds) => nds.concat(newNode)); // setShowProxmoxForm(false); // }; return (
setTool(!tool)}/>

setTheme(!theme)} >{theme ? '🌙' : '☀️'}

onSave()}/> onErase()}/>
); }