File size: 3,156 Bytes
2bdad3e
b1ea792
 
 
 
2bdad3e
b1ea792
2bdad3e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b1ea792
 
 
 
 
2bdad3e
 
 
 
 
 
 
 
 
 
 
 
 
b1ea792
2bdad3e
 
 
 
 
 
 
b1ea792
2bdad3e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b1ea792
2bdad3e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
aaea411
2bdad3e
 
 
 
 
 
 
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
123
124
125
126
127
128
import { useTheme } from '@/components/theme-provider';
import {
  IIterationNode,
  IIterationStartNode,
} from '@/interfaces/database/flow';
import { cn } from '@/lib/utils';
import { Handle, NodeProps, NodeResizeControl, Position } from '@xyflow/react';
import { ListRestart } from 'lucide-react';
import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
import styles from './index.less';
import NodeHeader from './node-header';

function ResizeIcon() {
  return (
    <svg
      xmlns="http://www.w3.org/2000/svg"
      width="20"
      height="20"
      viewBox="0 0 24 24"
      strokeWidth="2"
      stroke="#5025f9"
      fill="none"
      strokeLinecap="round"
      strokeLinejoin="round"
      style={{
        position: 'absolute',
        right: 5,
        bottom: 5,
      }}
    >
      <path stroke="none" d="M0 0h24v24H0z" fill="none" />
      <polyline points="16 20 20 20 20 16" />
      <line x1="14" y1="14" x2="20" y2="20" />
      <polyline points="8 4 4 4 4 8" />
      <line x1="4" y1="4" x2="10" y2="10" />
    </svg>
  );
}

const controlStyle = {
  background: 'transparent',
  border: 'none',
  cursor: 'nwse-resize',
};

export function IterationNode({
  id,
  data,
  isConnectable = true,
  selected,
}: NodeProps<IIterationNode>) {
  const { theme } = useTheme();

  return (
    <section
      className={cn(
        'w-full h-full bg-zinc-200 opacity-70',
        styles.iterationNode,
        {
          ['bg-gray-800']: theme === 'dark',
          [styles.selectedIterationNode]: selected,
        },
      )}
    >
      <NodeResizeControl style={controlStyle} minWidth={100} minHeight={50}>
        <ResizeIcon />
      </NodeResizeControl>
      <Handle
        id="c"
        type="source"
        position={Position.Left}
        isConnectable={isConnectable}
        className={styles.handle}
        style={LeftHandleStyle}
      ></Handle>
      <Handle
        type="source"
        position={Position.Right}
        isConnectable={isConnectable}
        className={styles.handle}
        id="b"
        style={RightHandleStyle}
      ></Handle>
      <NodeHeader
        id={id}
        name={data.name}
        label={data.label}
        wrapperClassName={cn(
          'p-2 bg-white rounded-t-[10px] absolute w-full top-[-60px] left-[-0.3px]',
          styles.iterationHeader,
          {
            [`${styles.dark} text-white`]: theme === 'dark',
            [styles.selectedHeader]: selected,
          },
        )}
      ></NodeHeader>
    </section>
  );
}

export function IterationStartNode({
  isConnectable = true,
  selected,
}: NodeProps<IIterationStartNode>) {
  const { theme } = useTheme();

  return (
    <section
      className={cn('bg-white p-2 rounded-xl', {
        [styles.dark]: theme === 'dark',
        [styles.selectedNode]: selected,
      })}
    >
      <Handle
        type="source"
        position={Position.Right}
        isConnectable={isConnectable}
        className={styles.handle}
        style={RightHandleStyle}
        isConnectableEnd={false}
      ></Handle>
      <div>
        <ListRestart className="size-7" />
      </div>
    </section>
  );
}