File size: 3,311 Bytes
c4929ba
c132e32
 
 
 
 
 
 
c4929ba
86be414
 
c132e32
 
 
 
86be414
67a483e
7f30a93
c132e32
 
 
 
67a483e
 
c132e32
 
 
 
 
 
 
 
 
 
 
 
 
 
67a483e
 
7f30a93
c132e32
 
 
 
 
 
a53f3f6
c132e32
 
 
 
 
 
 
 
 
 
 
a53f3f6
c132e32
 
a53f3f6
c132e32
 
 
 
 
 
86be414
68b8ffb
c4929ba
86be414
c4929ba
7f30a93
86be414
 
67a483e
86be414
 
 
 
 
 
c132e32
1228d79
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import CustomNodeIframe from "../Nodes/Custom.js";
import '../../css/dist/output.css'
import ReactFlow, { Background,
                    applyNodeChanges,
                    applyEdgeChanges,
                    ReactFlowProvider,
                    } from 'react-flow-renderer';
import React ,{ useState, useCallback, useRef } from 'react';
import Navbar from '../Navagation/navbar';
import { useThemeDetector } from '../../helper/visual'
 
const types = {
    custom : CustomNodeIframe,
  }

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 onNodesChange = useCallback(
      (changes) => setNodes((nds) => applyNodeChanges(changes, nds)),
      [setNodes]
    );
  
    const onEdgesChange = useCallback(
      (changes) => setEdges((eds) => applyEdgeChanges(changes, eds)),
      [setEdges]
    );
  
    const onDragOver = useCallback((event) => {
      event.preventDefault();
      event.dataTransfer.dropEffect = 'move';
    }, []);

    const deleteNode = (id) =>{setNodes((nds) => nds.filter(n => n.id !== id ))}
    const deleteNodeContains = (id) =>{setNodes((nds) => nds.filter(n => !n.id.includes(`${id}-`) ))}
    const onDrop = useCallback(
      (event) => {
        event.preventDefault();
  
        const reactFlowBounds = reactFlowWrapper.current.getBoundingClientRect();
        const type = event.dataTransfer.getData('application/reactflow');
        const item  = JSON.parse(event.dataTransfer.getData('application/item'));
        const colour = event.dataTransfer.getData('application/colour');
        // check if the dropped element is valid
        if (typeof type === 'undefined' || !type) {
          return;
        }
  
        const position = reactFlowInstance.project({
          x: event.clientX - reactFlowBounds.left,
          y: event.clientY - reactFlowBounds.top,
        });
        const newNode = {
          id: `${item.name}-${nodes.length}`,
          type,
          position,
          data: { label: `${item.name}`, host : `${item.host}`, colour : `${colour}`, delete : deleteNode },
        };
        setNodes((nds) => nds.concat(newNode));
      },
      [reactFlowInstance, nodes]);

    return (
      <>          
        <div className=' absolute top-4 right-5 z-50' onClick={()=> setTheme(!theme)}>
          <h1 className='text-4xl select-none' >{theme  ? '🌙' : '☀️'}</h1>  
        </div>
        <div className={`flex h-screen w-screen ${theme ? "dark" : ""} transition-all`}>
          <Navbar onDelete={deleteNodeContains}/>
          <ReactFlowProvider>
            <div className="h-screen w-screen" ref={reactFlowWrapper}>
              <ReactFlow nodes={nodes} edges={edges} nodeTypes={types} onNodesChange={onNodesChange} onEdgesChange={onEdgesChange} onNodesDelete={deleteNode} onDragOver={onDragOver} onDrop={onDrop} onInit={setReactFlowInstance}  fitView>
              <Background variant='dots' size={1} className=" bg-white dark:bg-neutral-800"/>
            </ReactFlow>
            </div>
          </ReactFlowProvider>
        </div>
      </>
    );
  }