File size: 2,702 Bytes
dcce454
 
 
 
 
 
5365cac
dcce454
 
 
 
 
 
 
 
 
5365cac
 
 
e3322d7
 
 
 
 
 
 
dcce454
 
 
 
5365cac
 
 
 
 
e3322d7
 
 
 
 
5365cac
 
 
dcce454
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5365cac
 
 
 
 
dcce454
e3322d7
 
dcce454
 
 
 
 
 
5365cac
dcce454
5365cac
dcce454
 
5365cac
dcce454
 
5365cac
dcce454
 
5365cac
 
 
 
 
e3322d7
dcce454
 
 
5365cac
 
 
dcce454
5365cac
dcce454
 
 
 
 
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import { useCallback, useEffect, useState } from 'react';
import ReactFlow, {
  Background,
  Controls,
  Edge,
  Node,
  NodeMouseHandler,
  OnConnect,
  OnEdgesChange,
  OnNodesChange,
  addEdge,
  applyEdgeChanges,
  applyNodeChanges,
} from 'reactflow';
import 'reactflow/dist/style.css';

import { NodeContextMenu, useHandleNodeContextMenu } from './context-menu';

import FlowDrawer from '../flow-drawer';
import {
  useHandleDrop,
  useHandleKeyUp,
  useHandleSelectionChange,
  useShowDrawer,
} from '../hooks';
import { dsl } from '../mock';
import { TextUpdaterNode } from './node';

const nodeTypes = { textUpdater: TextUpdaterNode };

interface IProps {
  sideWidth: number;
}

function FlowCanvas({ sideWidth }: IProps) {
  const [nodes, setNodes] = useState<Node[]>(dsl.graph.nodes);
  const [edges, setEdges] = useState<Edge[]>(dsl.graph.edges);

  const { selectedEdges, selectedNodes } = useHandleSelectionChange();

  const { ref, menu, onNodeContextMenu, onPaneClick } =
    useHandleNodeContextMenu(sideWidth);
  const { drawerVisible, hideDrawer, showDrawer } = useShowDrawer();

  const onNodesChange: OnNodesChange = useCallback(
    (changes) => setNodes((nds) => applyNodeChanges(changes, nds)),
    [],
  );
  const onEdgesChange: OnEdgesChange = useCallback(
    (changes) => setEdges((eds) => applyEdgeChanges(changes, eds)),
    [],
  );

  const onConnect: OnConnect = useCallback(
    (params) => setEdges((eds) => addEdge(params, eds)),
    [],
  );

  const onNodeClick: NodeMouseHandler = useCallback(() => {
    showDrawer();
  }, [showDrawer]);

  const { onDrop, onDragOver, setReactFlowInstance } = useHandleDrop(setNodes);

  const { handleKeyUp } = useHandleKeyUp(selectedEdges, selectedNodes);

  useEffect(() => {
    console.info('nodes:', nodes);
    console.info('edges:', edges);
  }, [nodes, edges]);

  return (
    <div style={{ height: '100%', width: '100%' }}>
      <ReactFlow
        ref={ref}
        nodes={nodes}
        onNodesChange={onNodesChange}
        onNodeContextMenu={onNodeContextMenu}
        edges={edges}
        onEdgesChange={onEdgesChange}
        fitView
        onConnect={onConnect}
        nodeTypes={nodeTypes}
        onPaneClick={onPaneClick}
        onDrop={onDrop}
        onDragOver={onDragOver}
        onNodeClick={onNodeClick}
        onInit={setReactFlowInstance}
        onKeyUp={handleKeyUp}
      >
        <Background />
        <Controls />
        {Object.keys(menu).length > 0 && (
          <NodeContextMenu onClick={onPaneClick} {...(menu as any)} />
        )}
      </ReactFlow>
      <FlowDrawer visible={drawerVisible} hideModal={hideDrawer}></FlowDrawer>
    </div>
  );
}

export default FlowCanvas;