File size: 3,090 Bytes
dcce454
 
 
 
 
 
5365cac
dcce454
 
 
78dc980
dcce454
 
 
 
 
 
5365cac
 
 
 
dcce454
 
 
 
 
 
78dc980
 
dcce454
 
78dc980
 
dcce454
 
78dc980
 
dcce454
 
78dc980
dcce454
 
 
78dc980
 
dcce454
 
78dc980
dcce454
 
 
 
 
 
 
5365cac
 
 
 
 
dcce454
 
5365cac
 
 
dcce454
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5365cac
 
 
 
 
dcce454
 
 
 
 
 
 
5365cac
dcce454
5365cac
dcce454
 
5365cac
dcce454
 
5365cac
dcce454
 
5365cac
 
 
 
 
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import { useCallback, useEffect, useState } from 'react';
import ReactFlow, {
  Background,
  Controls,
  Edge,
  Node,
  NodeMouseHandler,
  OnConnect,
  OnEdgesChange,
  OnNodesChange,
  Position,
  addEdge,
  applyEdgeChanges,
  applyNodeChanges,
} from 'reactflow';
import 'reactflow/dist/style.css';

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

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

const nodeTypes = { textUpdater: TextUpdaterNode };

const initialNodes = [
  {
    sourcePosition: Position.Left,
    targetPosition: Position.Right,
    id: 'node-1',
    type: 'textUpdater',
    position: { x: 400, y: 100 },
    data: { label: 123 },
  },
  {
    sourcePosition: Position.Right,
    targetPosition: Position.Left,
    id: '1',
    data: { label: 'Hello' },
    position: { x: 0, y: 50 },
    type: 'input',
  },
  {
    sourcePosition: Position.Right,
    targetPosition: Position.Left,
    id: '2',
    data: { label: 'World' },
    position: { x: 200, y: 50 },
  },
];

const initialEdges = [
  { id: '1-2', source: '1', target: '2', label: 'to the', type: 'step' },
];

interface IProps {
  sideWidth: number;
}

function FlowCanvas({ sideWidth }: IProps) {
  const [nodes, setNodes] = useState<Node[]>(initialNodes);
  const [edges, setEdges] = useState<Edge[]>(initialEdges);
  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);

  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}
      >
        <Background />
        <Controls />
        {Object.keys(menu).length > 0 && (
          <NodeContextMenu onClick={onPaneClick} {...(menu as any)} />
        )}
      </ReactFlow>
      <FlowDrawer visible={drawerVisible} hideModal={hideDrawer}></FlowDrawer>
    </div>
  );
}

export default FlowCanvas;