@flowuent-org/diagramming-core 1.0.5 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,8 +15,7 @@
15
15
  "entryFile": "packages/diagrams/src/index.ts",
16
16
  "external": ["react", "react-dom", "react/jsx-runtime"],
17
17
  "rollupConfig": "packages/diagrams/rollup.config.js",
18
- "compiler": "swc",
19
- "skipTypeCheck": false,
18
+ "compiler": "babel",
20
19
  "assets": [
21
20
  {
22
21
  "glob": "packages/diagrams/README.md",
@@ -1,31 +1,26 @@
1
- const getRollupOptions = require('@nx/react/plugins/bundle-rollup');
2
- const preserveDirectives = require('rollup-preserve-directives').default;
3
-
4
- module.exports = (options) => {
5
- // Get the default Nx Rollup options
6
- const nxRollupOptions = getRollupOptions(options);
7
-
8
- // Enable tree shaking
9
- nxRollupOptions.treeshake = true; // Explicitly enable tree shaking
10
-
11
- // Filter out rollup-plugin-typescript2 (rpt2) which has path issues on Windows
12
- // But keep @rollup/plugin-typescript if it exists
13
- nxRollupOptions.plugins = (Array.isArray(nxRollupOptions.plugins) ? nxRollupOptions.plugins : [])
14
- .filter(plugin => {
15
- // Remove rollup-plugin-typescript2 (rpt2) - it has cross-platform path issues
16
- return !(plugin && plugin.name === 'rpt2');
17
- });
18
-
19
- // Add the preserveDirectives plugin
20
- nxRollupOptions.plugins.push(preserveDirectives());
21
-
22
- // Externalize MUI packages
23
- nxRollupOptions.external = [
24
- ...(Array.isArray(nxRollupOptions.external) ? nxRollupOptions.external : []),
25
- '@mui/material',
26
- '@mui/icons-material',
27
- /^@mui\/icons-material\/.*/,
28
- ];
29
-
30
- return nxRollupOptions;
31
- };
1
+ const getRollupOptions = require('@nx/react/plugins/bundle-rollup');
2
+ const preserveDirectives = require('rollup-preserve-directives').default;
3
+
4
+ module.exports = (options) => {
5
+ // Get the default Nx Rollup options
6
+ const nxRollupOptions = getRollupOptions(options);
7
+
8
+ // Enable tree shaking
9
+ nxRollupOptions.treeshake = true; // Explicitly enable tree shaking
10
+
11
+ // Add the preserveDirectives plugin to the existing plugins
12
+ nxRollupOptions.plugins = [
13
+ ...(Array.isArray(nxRollupOptions.plugins) ? nxRollupOptions.plugins : []),
14
+ preserveDirectives(),
15
+ ];
16
+
17
+ // Externalize MUI packages
18
+ nxRollupOptions.external = [
19
+ ...(Array.isArray(nxRollupOptions.external) ? nxRollupOptions.external : []),
20
+ '@mui/material',
21
+ '@mui/icons-material',
22
+ /^@mui\/icons-material\/.*/,
23
+ ];
24
+
25
+ return nxRollupOptions;
26
+ };
@@ -1,76 +1,76 @@
1
- import React, { useCallback, useEffect, useRef, useState } from 'react';
2
- import { Box, TextField } from '@mui/material';
3
- import { ICardNode } from '../types/card-node';
4
- import { useCustomReactFlow } from '../hooks/customUseReactFlow';
5
- import { useNodeId, useNodeTitle } from '../contexts/CardDataProvider';
6
-
7
- export const CardEditableTitle = React.memo(() => {
8
- const title = useNodeTitle()
9
- const nodeId = useNodeId()
10
- const { getNodes, setNodes } = useCustomReactFlow();
11
- const [text, setText] = useState(title);
12
- const inputRef = useRef<HTMLInputElement>(null);
13
-
14
- useEffect(() => {
15
- if (title !== text) setText(title);
16
- }, [title]);
17
-
18
- const changeTitle = useCallback(
19
- (val: string) => {
20
- const prevNodes = [...getNodes()] as ICardNode[];
21
- const newNodes: ICardNode[] = prevNodes.map((node) => {
22
- if (node.id === nodeId) {
23
- return {
24
- ...node,
25
- data: { ...node.data, title: val },
26
- };
27
- } else return node;
28
- });
29
- setNodes(newNodes);
30
- },
31
- [getNodes, setNodes, nodeId],
32
- );
33
-
34
- const handleSave = useCallback(() => {
35
- changeTitle(text ?? '');
36
- }, [text, changeTitle]);
37
-
38
- const handleKeyDown = useCallback(
39
- (e: React.KeyboardEvent<HTMLInputElement>) => {
40
- if (e.key === 'Enter') {
41
- handleSave();
42
- } else if (e.key === 'Escape') {
43
- setText(title);
44
- }
45
- },
46
- [handleSave, title],
47
- );
48
-
49
- return (
50
- <Box
51
- sx={{
52
- display: 'flex',
53
- justifyContent: 'center',
54
- width: '100%',
55
- my: 1,
56
- backgroundColor: '#6B04F1',
57
- borderRadius: '3px',
58
- }}
59
- >
60
- <TextField
61
- size={'small'}
62
- inputProps={{
63
- style: { fontSize: '18px', fontWeight: 'bold', textAlign: 'center', color: '#fff' },
64
- }}
65
- variant="outlined"
66
- value={text}
67
- onChange={(e) => setText(e.target.value)}
68
- onKeyDown={handleKeyDown}
69
- inputRef={inputRef}
70
- fullWidth
71
- />
72
- </Box>
73
- );
74
- });
75
-
76
- export default CardEditableTitle;
1
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
2
+ import { Box, TextField } from '@mui/material';
3
+ import { ICardNode } from '../types/card-node';
4
+ import { useCustomReactFlow } from '../hooks/customUseReactFlow';
5
+ import { useNodeId, useNodeTitle } from '@flowuent-labs/diagrams';
6
+
7
+ export const CardEditableTitle = React.memo(() => {
8
+ const title = useNodeTitle()
9
+ const nodeId = useNodeId()
10
+ const { getNodes, setNodes } = useCustomReactFlow();
11
+ const [text, setText] = useState(title);
12
+ const inputRef = useRef<HTMLInputElement>(null);
13
+
14
+ useEffect(() => {
15
+ if (title !== text) setText(title);
16
+ }, [title]);
17
+
18
+ const changeTitle = useCallback(
19
+ (val: string) => {
20
+ const prevNodes = [...getNodes()] as ICardNode[];
21
+ const newNodes: ICardNode[] = prevNodes.map((node) => {
22
+ if (node.id === nodeId) {
23
+ return {
24
+ ...node,
25
+ data: { ...node.data, title: val },
26
+ };
27
+ } else return node;
28
+ });
29
+ setNodes(newNodes);
30
+ },
31
+ [getNodes, setNodes, nodeId],
32
+ );
33
+
34
+ const handleSave = useCallback(() => {
35
+ changeTitle(text ?? '');
36
+ }, [text, changeTitle]);
37
+
38
+ const handleKeyDown = useCallback(
39
+ (e: React.KeyboardEvent<HTMLInputElement>) => {
40
+ if (e.key === 'Enter') {
41
+ handleSave();
42
+ } else if (e.key === 'Escape') {
43
+ setText(title);
44
+ }
45
+ },
46
+ [handleSave, title],
47
+ );
48
+
49
+ return (
50
+ <Box
51
+ sx={{
52
+ display: 'flex',
53
+ justifyContent: 'center',
54
+ width: '100%',
55
+ my: 1,
56
+ backgroundColor: '#6B04F1',
57
+ borderRadius: '3px',
58
+ }}
59
+ >
60
+ <TextField
61
+ size={'small'}
62
+ inputProps={{
63
+ style: { fontSize: '18px', fontWeight: 'bold', textAlign: 'center', color: '#fff' },
64
+ }}
65
+ variant="outlined"
66
+ value={text}
67
+ onChange={(e) => setText(e.target.value)}
68
+ onKeyDown={handleKeyDown}
69
+ inputRef={inputRef}
70
+ fullWidth
71
+ />
72
+ </Box>
73
+ );
74
+ });
75
+
76
+ export default CardEditableTitle;
@@ -278,6 +278,19 @@ export const AutomationApiNode: React.FC<AutomationApiNodeProps> = ({ data, sele
278
278
  transition: 'all 0.2s ease',
279
279
  cursor: 'pointer',
280
280
  overflow: 'hidden',
281
+ ...(data.status === 'Running' && {
282
+ animation: 'pulse-glow 2s ease-in-out infinite',
283
+ '@keyframes pulse-glow': {
284
+ '0%, 100%': {
285
+ boxShadow: '0 0 20px rgba(251, 191, 36, 0.4), 0 0 40px rgba(251, 191, 36, 0.2)',
286
+ borderColor: 'rgba(251, 191, 36, 0.6)',
287
+ },
288
+ '50%': {
289
+ boxShadow: '0 0 30px rgba(251, 191, 36, 0.6), 0 0 60px rgba(251, 191, 36, 0.3)',
290
+ borderColor: 'rgba(251, 191, 36, 0.9)',
291
+ },
292
+ },
293
+ }),
281
294
  }}
282
295
  onClick={handleJsonClick}
283
296
  >
@@ -322,8 +335,16 @@ export const AutomationApiNode: React.FC<AutomationApiNodeProps> = ({ data, sele
322
335
  label={data.status}
323
336
  size="small"
324
337
  sx={{
325
- backgroundColor: 'rgba(16, 185, 129, 0.1)',
326
- color: '#86EFAC',
338
+ backgroundColor: data.status === 'Completed'
339
+ ? 'rgba(37, 99, 235, 0.1)'
340
+ : data.status === 'Running'
341
+ ? 'rgba(251, 191, 36, 0.1)'
342
+ : 'rgba(16, 185, 129, 0.1)',
343
+ color: data.status === 'Completed'
344
+ ? '#93C5FD'
345
+ : data.status === 'Running'
346
+ ? '#FCD34D'
347
+ : '#86EFAC',
327
348
  fontWeight: 500,
328
349
  fontSize: '12px',
329
350
  height: '24px',
@@ -370,7 +391,7 @@ export const AutomationApiNode: React.FC<AutomationApiNodeProps> = ({ data, sele
370
391
  {t('automation.apiNode.additionalInfo')}
371
392
  </Typography>
372
393
 
373
- {(data.formData?.executionResult || data.formData?.schemaMatch) && (
394
+ {data.status === 'Completed' && (data.formData?.executionResult || data.formData?.schemaMatch) && (
374
395
  <>
375
396
  {/* Schema Row */}
376
397
  <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
@@ -207,6 +207,19 @@ export const AutomationEndNode: React.FC<AutomationEndNodeProps> = ({ data, sele
207
207
  transition: 'all 0.2s ease',
208
208
  cursor: 'pointer',
209
209
  overflow: 'hidden',
210
+ ...(data.status === 'Running' && {
211
+ animation: 'pulse-glow 2s ease-in-out infinite',
212
+ '@keyframes pulse-glow': {
213
+ '0%, 100%': {
214
+ boxShadow: '0 0 20px rgba(251, 191, 36, 0.4), 0 0 40px rgba(251, 191, 36, 0.2)',
215
+ borderColor: 'rgba(251, 191, 36, 0.6)',
216
+ },
217
+ '50%': {
218
+ boxShadow: '0 0 30px rgba(251, 191, 36, 0.6), 0 0 60px rgba(251, 191, 36, 0.3)',
219
+ borderColor: 'rgba(251, 191, 36, 0.9)',
220
+ },
221
+ },
222
+ }),
210
223
  }}
211
224
  onClick={handleJsonClick}
212
225
  >
@@ -251,8 +264,16 @@ export const AutomationEndNode: React.FC<AutomationEndNodeProps> = ({ data, sele
251
264
  label={data.status}
252
265
  size="small"
253
266
  sx={{
254
- backgroundColor: 'rgba(16, 185, 129, 0.1)',
255
- color: '#86EFAC',
267
+ backgroundColor: data.status === 'Completed'
268
+ ? 'rgba(37, 99, 235, 0.1)'
269
+ : data.status === 'Running'
270
+ ? 'rgba(251, 191, 36, 0.1)'
271
+ : 'rgba(16, 185, 129, 0.1)',
272
+ color: data.status === 'Completed'
273
+ ? '#93C5FD'
274
+ : data.status === 'Running'
275
+ ? '#FCD34D'
276
+ : '#86EFAC',
256
277
  fontWeight: 500,
257
278
  fontSize: '12px',
258
279
  height: '24px',
@@ -282,6 +282,19 @@ export const AutomationFormattingNode: React.FC<AutomationFormattingNodeProps> =
282
282
  transition: 'all 0.2s ease',
283
283
  cursor: 'pointer',
284
284
  overflow: 'hidden',
285
+ ...(data.status === 'Running' && {
286
+ animation: 'pulse-glow 2s ease-in-out infinite',
287
+ '@keyframes pulse-glow': {
288
+ '0%, 100%': {
289
+ boxShadow: '0 0 20px rgba(251, 191, 36, 0.4), 0 0 40px rgba(251, 191, 36, 0.2)',
290
+ borderColor: 'rgba(251, 191, 36, 0.6)',
291
+ },
292
+ '50%': {
293
+ boxShadow: '0 0 30px rgba(251, 191, 36, 0.6), 0 0 60px rgba(251, 191, 36, 0.3)',
294
+ borderColor: 'rgba(251, 191, 36, 0.9)',
295
+ },
296
+ },
297
+ }),
285
298
  }}
286
299
  onClick={handleJsonClick}
287
300
  >
@@ -326,8 +339,16 @@ export const AutomationFormattingNode: React.FC<AutomationFormattingNodeProps> =
326
339
  label={data.status}
327
340
  size="small"
328
341
  sx={{
329
- backgroundColor: 'rgba(16, 185, 129, 0.1)',
330
- color: '#86EFAC',
342
+ backgroundColor: data.status === 'Completed'
343
+ ? 'rgba(37, 99, 235, 0.1)'
344
+ : data.status === 'Running'
345
+ ? 'rgba(251, 191, 36, 0.1)'
346
+ : 'rgba(16, 185, 129, 0.1)',
347
+ color: data.status === 'Completed'
348
+ ? '#93C5FD'
349
+ : data.status === 'Running'
350
+ ? '#FCD34D'
351
+ : '#86EFAC',
331
352
  fontWeight: 500,
332
353
  fontSize: '12px',
333
354
  height: '24px',
@@ -408,7 +429,7 @@ export const AutomationFormattingNode: React.FC<AutomationFormattingNodeProps> =
408
429
  </Box>
409
430
  </Box>
410
431
 
411
- {(data.formData?.executionResult || data.formData?.schemaMatch) && (
432
+ {data.status === 'Completed' && (data.formData?.executionResult || data.formData?.schemaMatch) && (
412
433
  <>
413
434
  {/* Schema Row */}
414
435
  <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
@@ -208,6 +208,19 @@ export const AutomationStartNode: React.FC<AutomationStartNodeProps> = ({ data,
208
208
  transition: 'all 0.2s ease',
209
209
  cursor: 'pointer',
210
210
  overflow: 'hidden',
211
+ ...(data.status === 'Running' && {
212
+ animation: 'pulse-glow 2s ease-in-out infinite',
213
+ '@keyframes pulse-glow': {
214
+ '0%, 100%': {
215
+ boxShadow: '0 0 20px rgba(251, 191, 36, 0.4), 0 0 40px rgba(251, 191, 36, 0.2)',
216
+ borderColor: 'rgba(251, 191, 36, 0.6)',
217
+ },
218
+ '50%': {
219
+ boxShadow: '0 0 30px rgba(251, 191, 36, 0.6), 0 0 60px rgba(251, 191, 36, 0.3)',
220
+ borderColor: 'rgba(251, 191, 36, 0.9)',
221
+ },
222
+ },
223
+ }),
211
224
  }}
212
225
  onClick={handleJsonClick}
213
226
  >
@@ -252,8 +265,16 @@ export const AutomationStartNode: React.FC<AutomationStartNodeProps> = ({ data,
252
265
  label={data.status}
253
266
  size="small"
254
267
  sx={{
255
- backgroundColor: 'rgba(16, 185, 129, 0.1)',
256
- color: '#86EFAC',
268
+ backgroundColor: data.status === 'Completed'
269
+ ? 'rgba(37, 99, 235, 0.1)'
270
+ : data.status === 'Running'
271
+ ? 'rgba(251, 191, 36, 0.1)'
272
+ : 'rgba(16, 185, 129, 0.1)',
273
+ color: data.status === 'Completed'
274
+ ? '#93C5FD'
275
+ : data.status === 'Running'
276
+ ? '#FCD34D'
277
+ : '#86EFAC',
257
278
  fontWeight: 500,
258
279
  fontSize: '12px',
259
280
  height: '24px',
@@ -1,5 +1,5 @@
1
1
  import { DiagramState } from './diagramStoreTypes';
2
- import { ICardNode } from '../types/card-node';
2
+ import { ICardNode } from '@flowuent-labs/diagrams';
3
3
 
4
4
  // Helper function to handle node deletion and edge updates
5
5
  export const onWorkflowNodeDelete = (
@@ -1,119 +1,121 @@
1
- import { Edge } from '@xyflow/react';
2
- import { closestPoint } from '../../utils/closestPoint';
3
- import { DiagramStore } from '../../contexts/DiagramProvider';
4
- import { EdgeTypes } from './custom-edge.type';
5
- import { HistoryEvent } from '../../types/history-event';
6
- import { ICardNode } from '../../types/card-node';
7
- import { useCustomReactFlow } from '../../hooks/customUseReactFlow';
8
- import { useDiagram } from '../../contexts/DiagramProvider';
9
- import React, { useCallback } from 'react';
10
- import { v4 as uuidv4 } from 'uuid';
11
- import addToHistory from '../../utils/addToHistory';
12
-
13
- export const useCreateBendPoint = (
14
- currentEdge: Edge,
15
- sourceNode: ICardNode,
16
- targetNode: ICardNode,
17
- pathRef: React.RefObject<SVGPathElement>,
18
- ) => {
19
- const { setEdges, getEdge, screenToFlowPosition, addNodes } =
20
- useCustomReactFlow();
21
- const store = useDiagram<DiagramStore>();
22
- const { diagramType, nodes, edges, setStore } = store;
23
-
24
- return useCallback(
25
- (evt: React.MouseEvent<SVGPathElement, MouseEvent>) => {
26
- if (diagramType === 'workflow') {
27
- return;
28
- }
29
- evt.preventDefault();
30
- evt.stopPropagation();
31
- if (!pathRef.current) return;
32
-
33
- const position = screenToFlowPosition({
34
- x: evt.clientX,
35
- y: evt.clientY,
36
- });
37
- const cpoint = closestPoint(pathRef.current, [position.x, position.y]);
38
- if (!currentEdge || !sourceNode || !targetNode)
39
- throw new Error(
40
- 'Invalid Edge found with source, target or curr edge missing',
41
- );
42
-
43
- const nodesAndEdgesBefore = {
44
- nodes: [...nodes],
45
- edges: [...edges],
46
- };
47
- const nodeId = uuidv4();
48
- const newBendPoint: ICardNode = {
49
- id: nodeId,
50
- position: { x: cpoint[0], y: cpoint[1] },
51
- data: { nodeId: nodeId },
52
- type: 'bendPoint',
53
- };
54
- const newEdge: Edge = {
55
- id: uuidv4(),
56
- source: newBendPoint.id,
57
- target: currentEdge.target,
58
- type:
59
- currentEdge.type === EdgeTypes.Default ||
60
- currentEdge.type === EdgeTypes.Bend2Target
61
- ? EdgeTypes.Bend2Target
62
- : EdgeTypes.Bend2Bend,
63
- };
64
- newEdge.markerEnd =
65
- newEdge.type === EdgeTypes.Bend2Target
66
- ? currentEdge.markerEnd
67
- : undefined;
68
- currentEdge.target = newBendPoint.id;
69
- currentEdge.type =
70
- currentEdge.type === EdgeTypes.Default ||
71
- currentEdge.type === EdgeTypes.Source2Bend
72
- ? EdgeTypes.Source2Bend
73
- : EdgeTypes.Bend2Bend;
74
- delete currentEdge.markerEnd;
75
- currentEdge.markerStart =
76
- currentEdge.type === EdgeTypes.Source2Bend
77
- ? currentEdge.markerStart
78
- : undefined;
79
-
80
- const newEdges = [
81
- ...edges.filter((e) => e.id !== currentEdge.id),
82
- currentEdge,
83
- newEdge,
84
- ];
85
- const newNodes = [...nodes, newBendPoint];
86
- const nodesAndEdgesAfter = {
87
- nodes: newNodes,
88
- edges: newEdges,
89
- };
90
-
91
- const event: HistoryEvent = {
92
- forward: {
93
- t: 'complex-change',
94
- type: 'complex',
95
- nodesAndEdges: nodesAndEdgesAfter,
96
- },
97
- backward: {
98
- t: 'complex-change',
99
- type: 'complex',
100
- nodesAndEdges: nodesAndEdgesBefore,
101
- },
102
- title: 'Bend point created in the middle of ' + currentEdge.id,
103
- };
104
- setStore({
105
- ...addToHistory(store, [event]),
106
- ...nodesAndEdgesAfter,
107
- });
108
- },
109
- [
110
- pathRef.current,
111
- currentEdge.id,
112
- getEdge,
113
- setEdges,
114
- addNodes,
115
- sourceNode,
116
- targetNode,
117
- ],
118
- );
119
- };
1
+ import { Edge } from '@xyflow/react';
2
+ import {
3
+ closestPoint,
4
+ DiagramStore,
5
+ EdgeTypes,
6
+ HistoryEvent,
7
+ ICardNode,
8
+ useCustomReactFlow,
9
+ useDiagram,
10
+ } from '@flowuent-labs/diagrams';
11
+ import React, { useCallback } from 'react';
12
+ import { v4 as uuidv4 } from 'uuid';
13
+ import addToHistory from '../../utils/addToHistory';
14
+
15
+ export const useCreateBendPoint = (
16
+ currentEdge: Edge,
17
+ sourceNode: ICardNode,
18
+ targetNode: ICardNode,
19
+ pathRef: React.RefObject<SVGPathElement>,
20
+ ) => {
21
+ const { setEdges, getEdge, screenToFlowPosition, addNodes } =
22
+ useCustomReactFlow();
23
+ const store = useDiagram<DiagramStore>();
24
+ const { diagramType, nodes, edges, setStore } = store;
25
+
26
+ return useCallback(
27
+ (evt: React.MouseEvent<SVGPathElement, MouseEvent>) => {
28
+ if (diagramType === 'workflow') {
29
+ return;
30
+ }
31
+ evt.preventDefault();
32
+ evt.stopPropagation();
33
+ if (!pathRef.current) return;
34
+
35
+ const position = screenToFlowPosition({
36
+ x: evt.clientX,
37
+ y: evt.clientY,
38
+ });
39
+ const cpoint = closestPoint(pathRef.current, [position.x, position.y]);
40
+ if (!currentEdge || !sourceNode || !targetNode)
41
+ throw new Error(
42
+ 'Invalid Edge found with source, target or curr edge missing',
43
+ );
44
+
45
+ const nodesAndEdgesBefore = {
46
+ nodes: [...nodes],
47
+ edges: [...edges],
48
+ };
49
+ const nodeId = uuidv4();
50
+ const newBendPoint: ICardNode = {
51
+ id: nodeId,
52
+ position: { x: cpoint[0], y: cpoint[1] },
53
+ data: { nodeId: nodeId },
54
+ type: 'bendPoint',
55
+ };
56
+ const newEdge: Edge = {
57
+ id: uuidv4(),
58
+ source: newBendPoint.id,
59
+ target: currentEdge.target,
60
+ type:
61
+ currentEdge.type === EdgeTypes.Default ||
62
+ currentEdge.type === EdgeTypes.Bend2Target
63
+ ? EdgeTypes.Bend2Target
64
+ : EdgeTypes.Bend2Bend,
65
+ };
66
+ newEdge.markerEnd =
67
+ newEdge.type === EdgeTypes.Bend2Target
68
+ ? currentEdge.markerEnd
69
+ : undefined;
70
+ currentEdge.target = newBendPoint.id;
71
+ currentEdge.type =
72
+ currentEdge.type === EdgeTypes.Default ||
73
+ currentEdge.type === EdgeTypes.Source2Bend
74
+ ? EdgeTypes.Source2Bend
75
+ : EdgeTypes.Bend2Bend;
76
+ delete currentEdge.markerEnd;
77
+ currentEdge.markerStart =
78
+ currentEdge.type === EdgeTypes.Source2Bend
79
+ ? currentEdge.markerStart
80
+ : undefined;
81
+
82
+ const newEdges = [
83
+ ...edges.filter((e) => e.id !== currentEdge.id),
84
+ currentEdge,
85
+ newEdge,
86
+ ];
87
+ const newNodes = [...nodes, newBendPoint];
88
+ const nodesAndEdgesAfter = {
89
+ nodes: newNodes,
90
+ edges: newEdges,
91
+ };
92
+
93
+ const event: HistoryEvent = {
94
+ forward: {
95
+ t: 'complex-change',
96
+ type: 'complex',
97
+ nodesAndEdges: nodesAndEdgesAfter,
98
+ },
99
+ backward: {
100
+ t: 'complex-change',
101
+ type: 'complex',
102
+ nodesAndEdges: nodesAndEdgesBefore,
103
+ },
104
+ title: 'Bend point created in the middle of ' + currentEdge.id,
105
+ };
106
+ setStore({
107
+ ...addToHistory(store, [event]),
108
+ ...nodesAndEdgesAfter,
109
+ });
110
+ },
111
+ [
112
+ pathRef.current,
113
+ currentEdge.id,
114
+ getEdge,
115
+ setEdges,
116
+ addNodes,
117
+ sourceNode,
118
+ targetNode,
119
+ ],
120
+ );
121
+ };