@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.
@@ -1,306 +1,306 @@
1
- # Undo/Redo API Documentation
2
-
3
- ## Overview
4
-
5
- The diagramming library provides comprehensive undo/redo functionality for all diagram types, including automation diagrams. This document explains how to expose and use undo/redo controls externally when using the library.
6
-
7
- ## How Undo/Redo Works
8
-
9
- ### Internal Implementation
10
-
11
- 1. **History Management**: The system maintains a `history` array and `historyIndex` in the DiagramStore
12
- 2. **Change Tracking**: Every change to nodes/edges is tracked and stored as `HistoryEvent` objects
13
- 3. **State Restoration**: Changes are applied in reverse (undo) or forward (redo) direction
14
- 4. **Keyboard Shortcuts**: Ctrl+Z (undo) and Ctrl+Y/Cmd+Shift+Z (redo) work automatically
15
-
16
- ### Key Components
17
-
18
- - **DiagramProvider**: Contains the main store with `undo()` and `redo()` methods
19
- - **History System**: Tracks all changes with forward/backward operations
20
- - **DownloadPanel**: Built-in undo/redo buttons (can be hidden)
21
-
22
- ## External Undo/Redo Control
23
-
24
- ### Method 1: Using Ref-based API (Recommended)
25
-
26
- The `DiagrammingPage` component now supports a ref that exposes undo/redo functionality:
27
-
28
- ```typescript
29
- import React, { useRef } from 'react';
30
- import { DiagrammingPage, DiagrammingPageRef } from '@flowuent-org/diagrams';
31
-
32
- const MyComponent = () => {
33
- const diagramRef = useRef<DiagrammingPageRef>(null);
34
-
35
- const handleUndo = () => {
36
- if (diagramRef.current?.canUndo()) {
37
- diagramRef.current.undo();
38
- }
39
- };
40
-
41
- const handleRedo = () => {
42
- if (diagramRef.current?.canRedo()) {
43
- diagramRef.current.redo();
44
- }
45
- };
46
-
47
- return (
48
- <div>
49
- {/* Your external undo/redo buttons */}
50
- <button onClick={handleUndo} disabled={!diagramRef.current?.canUndo()}>
51
- Undo
52
- </button>
53
- <button onClick={handleRedo} disabled={!diagramRef.current?.canRedo()}>
54
- Redo
55
- </button>
56
-
57
- {/* The diagram */}
58
- <DiagrammingPage
59
- ref={diagramRef}
60
- diagramType="automation"
61
- defaultNodes={nodes}
62
- defaultEdges={edges}
63
- availableFunctions={[]}
64
- id={1}
65
- />
66
- </div>
67
- );
68
- };
69
- ```
70
-
71
- ### Available Methods
72
-
73
- The `DiagrammingPageRef` interface provides these methods:
74
-
75
- ```typescript
76
- interface DiagrammingPageRef {
77
- undo: () => void; // Perform undo operation
78
- redo: () => void; // Perform redo operation
79
- canUndo: () => boolean; // Check if undo is available
80
- canRedo: () => boolean; // Check if redo is available
81
- reset: () => void; // Clear the diagram
82
- getHistoryLength: () => number; // Get total history length
83
- getHistoryIndex: () => number; // Get current history index
84
- }
85
- ```
86
-
87
- ### Method 2: Using DownloadPanel with Hidden Built-in Controls
88
-
89
- You can hide the built-in undo/redo buttons and use your own:
90
-
91
- ```typescript
92
- import { DiagrammingPage, DownloadPanel } from '@flowuent-org/diagrams';
93
-
94
- const MyComponent = () => {
95
- return (
96
- <DiagrammingPage
97
- diagramType="automation"
98
- defaultNodes={nodes}
99
- defaultEdges={edges}
100
- availableFunctions={[]}
101
- id={1}
102
- >
103
- {/* Hide built-in undo/redo buttons */}
104
- <DownloadPanel
105
- hideUndo={true}
106
- hideRedo={true}
107
- position="top-left"
108
- />
109
-
110
- {/* Your custom controls */}
111
- <YourCustomControls />
112
- </DiagrammingPage>
113
- );
114
- };
115
- ```
116
-
117
- ## Complete Example
118
-
119
- Here's a complete example showing how to implement external undo/redo controls:
120
-
121
- ```typescript
122
- import React, { useRef, useState, useEffect } from 'react';
123
- import { Button, Box, Typography, IconButton } from '@mui/material';
124
- import { UndoIcon, RedoIcon, ClearIcon } from '@mui/icons-material';
125
- import { DiagrammingPage, DiagrammingPageRef } from '@flowuent-org/diagrams';
126
- import { ICardNode } from '@flowuent-org/diagrams';
127
- import { Edge } from '@xyflow/react';
128
-
129
- const AutomationDiagramWithExternalControls: React.FC = () => {
130
- const diagramRef = useRef<DiagrammingPageRef>(null);
131
- const [canUndo, setCanUndo] = useState(false);
132
- const [canRedo, setCanRedo] = useState(false);
133
- const [historyInfo, setHistoryInfo] = useState({ index: 0, length: 0 });
134
-
135
- // Sample automation diagram data
136
- const defaultNodes: ICardNode[] = [
137
- {
138
- id: '1',
139
- type: 'AutomationStartNode',
140
- position: { x: 100, y: 100 },
141
- data: { label: 'Start Process' }
142
- },
143
- {
144
- id: '2',
145
- type: 'AutomationApiNode',
146
- position: { x: 300, y: 100 },
147
- data: { label: 'API Call' }
148
- },
149
- {
150
- id: '3',
151
- type: 'AutomationEndNode',
152
- position: { x: 500, y: 100 },
153
- data: { label: 'End Process' }
154
- }
155
- ];
156
-
157
- const defaultEdges: Edge[] = [
158
- { id: 'e1-2', source: '1', target: '2' },
159
- { id: 'e2-3', source: '2', target: '3' }
160
- ];
161
-
162
- const updateButtonStates = () => {
163
- if (diagramRef.current) {
164
- setCanUndo(diagramRef.current.canUndo());
165
- setCanRedo(diagramRef.current.canRedo());
166
- setHistoryInfo({
167
- index: diagramRef.current.getHistoryIndex(),
168
- length: diagramRef.current.getHistoryLength()
169
- });
170
- }
171
- };
172
-
173
- const handleUndo = () => {
174
- if (diagramRef.current?.canUndo()) {
175
- diagramRef.current.undo();
176
- updateButtonStates();
177
- }
178
- };
179
-
180
- const handleRedo = () => {
181
- if (diagramRef.current?.canRedo()) {
182
- diagramRef.current.redo();
183
- updateButtonStates();
184
- }
185
- };
186
-
187
- const handleReset = () => {
188
- diagramRef.current?.reset();
189
- updateButtonStates();
190
- };
191
-
192
- // Update button states when diagram changes
193
- useEffect(() => {
194
- const interval = setInterval(updateButtonStates, 100);
195
- return () => clearInterval(interval);
196
- }, []);
197
-
198
- return (
199
- <Box sx={{ height: '100vh', display: 'flex', flexDirection: 'column' }}>
200
- {/* External Controls Toolbar */}
201
- <Box sx={{
202
- p: 2,
203
- bgcolor: '#f5f5f5',
204
- borderBottom: '1px solid #ddd',
205
- display: 'flex',
206
- gap: 2,
207
- alignItems: 'center',
208
- boxShadow: '0 2px 4px rgba(0,0,0,0.1)'
209
- }}>
210
- <Typography variant="h6" sx={{ fontWeight: 'bold' }}>
211
- Automation Diagram Controls
212
- </Typography>
213
-
214
- <Box sx={{ display: 'flex', gap: 1, ml: 2 }}>
215
- <IconButton
216
- onClick={handleUndo}
217
- disabled={!canUndo}
218
- sx={{
219
- bgcolor: canUndo ? '#1976d2' : '#e0e0e0',
220
- color: canUndo ? 'white' : '#9e9e9e',
221
- '&:hover': {
222
- bgcolor: canUndo ? '#1565c0' : '#e0e0e0'
223
- }
224
- }}
225
- >
226
- <UndoIcon />
227
- </IconButton>
228
-
229
- <IconButton
230
- onClick={handleRedo}
231
- disabled={!canRedo}
232
- sx={{
233
- bgcolor: canRedo ? '#1976d2' : '#e0e0e0',
234
- color: canRedo ? 'white' : '#9e9e9e',
235
- '&:hover': {
236
- bgcolor: canRedo ? '#1565c0' : '#e0e0e0'
237
- }
238
- }}
239
- >
240
- <RedoIcon />
241
- </IconButton>
242
-
243
- <IconButton
244
- onClick={handleReset}
245
- sx={{
246
- bgcolor: '#d32f2f',
247
- color: 'white',
248
- '&:hover': {
249
- bgcolor: '#c62828'
250
- }
251
- }}
252
- >
253
- <ClearIcon />
254
- </IconButton>
255
- </Box>
256
-
257
- <Typography variant="body2" sx={{ ml: 'auto', color: '#666' }}>
258
- History: {historyInfo.index} / {historyInfo.length}
259
- </Typography>
260
- </Box>
261
-
262
- {/* Diagram */}
263
- <Box sx={{ flex: 1 }}>
264
- <DiagrammingPage
265
- ref={diagramRef}
266
- diagramType="automation"
267
- defaultNodes={defaultNodes}
268
- defaultEdges={defaultEdges}
269
- availableFunctions={[]}
270
- id={1}
271
- onChange={() => {
272
- // Update button states when diagram changes
273
- setTimeout(updateButtonStates, 100);
274
- }}
275
- />
276
- </Box>
277
- </Box>
278
- );
279
- };
280
-
281
- export default AutomationDiagramWithExternalControls;
282
- ```
283
-
284
- ## Integration Steps for Your Team Member
285
-
286
- 1. **Install the updated library** with the new ref-based API
287
- 2. **Create a ref** to the DiagrammingPage component
288
- 3. **Add external buttons** that call the ref methods
289
- 4. **Handle state updates** to enable/disable buttons appropriately
290
- 5. **Test the functionality** with various diagram operations
291
-
292
- ## Key Benefits
293
-
294
- - **Full Control**: Complete control over undo/redo UI and behavior
295
- - **State Awareness**: Know when undo/redo is available
296
- - **History Information**: Access to history length and current index
297
- - **Keyboard Support**: Built-in keyboard shortcuts still work
298
- - **Flexible Integration**: Works with any UI framework or custom components
299
-
300
- ## Notes
301
-
302
- - The undo/redo functionality works automatically for all diagram types
303
- - History is maintained per diagram instance
304
- - Changes are tracked for node/edge additions, deletions, modifications, and movements
305
- - The system prevents infinite loops and handles edge cases gracefully
306
- - Keyboard shortcuts (Ctrl+Z, Ctrl+Y) work alongside external controls
1
+ # Undo/Redo API Documentation
2
+
3
+ ## Overview
4
+
5
+ The diagramming library provides comprehensive undo/redo functionality for all diagram types, including automation diagrams. This document explains how to expose and use undo/redo controls externally when using the library.
6
+
7
+ ## How Undo/Redo Works
8
+
9
+ ### Internal Implementation
10
+
11
+ 1. **History Management**: The system maintains a `history` array and `historyIndex` in the DiagramStore
12
+ 2. **Change Tracking**: Every change to nodes/edges is tracked and stored as `HistoryEvent` objects
13
+ 3. **State Restoration**: Changes are applied in reverse (undo) or forward (redo) direction
14
+ 4. **Keyboard Shortcuts**: Ctrl+Z (undo) and Ctrl+Y/Cmd+Shift+Z (redo) work automatically
15
+
16
+ ### Key Components
17
+
18
+ - **DiagramProvider**: Contains the main store with `undo()` and `redo()` methods
19
+ - **History System**: Tracks all changes with forward/backward operations
20
+ - **DownloadPanel**: Built-in undo/redo buttons (can be hidden)
21
+
22
+ ## External Undo/Redo Control
23
+
24
+ ### Method 1: Using Ref-based API (Recommended)
25
+
26
+ The `DiagrammingPage` component now supports a ref that exposes undo/redo functionality:
27
+
28
+ ```typescript
29
+ import React, { useRef } from 'react';
30
+ import { DiagrammingPage, DiagrammingPageRef } from '@flowuent-labs/diagrams';
31
+
32
+ const MyComponent = () => {
33
+ const diagramRef = useRef<DiagrammingPageRef>(null);
34
+
35
+ const handleUndo = () => {
36
+ if (diagramRef.current?.canUndo()) {
37
+ diagramRef.current.undo();
38
+ }
39
+ };
40
+
41
+ const handleRedo = () => {
42
+ if (diagramRef.current?.canRedo()) {
43
+ diagramRef.current.redo();
44
+ }
45
+ };
46
+
47
+ return (
48
+ <div>
49
+ {/* Your external undo/redo buttons */}
50
+ <button onClick={handleUndo} disabled={!diagramRef.current?.canUndo()}>
51
+ Undo
52
+ </button>
53
+ <button onClick={handleRedo} disabled={!diagramRef.current?.canRedo()}>
54
+ Redo
55
+ </button>
56
+
57
+ {/* The diagram */}
58
+ <DiagrammingPage
59
+ ref={diagramRef}
60
+ diagramType="automation"
61
+ defaultNodes={nodes}
62
+ defaultEdges={edges}
63
+ availableFunctions={[]}
64
+ id={1}
65
+ />
66
+ </div>
67
+ );
68
+ };
69
+ ```
70
+
71
+ ### Available Methods
72
+
73
+ The `DiagrammingPageRef` interface provides these methods:
74
+
75
+ ```typescript
76
+ interface DiagrammingPageRef {
77
+ undo: () => void; // Perform undo operation
78
+ redo: () => void; // Perform redo operation
79
+ canUndo: () => boolean; // Check if undo is available
80
+ canRedo: () => boolean; // Check if redo is available
81
+ reset: () => void; // Clear the diagram
82
+ getHistoryLength: () => number; // Get total history length
83
+ getHistoryIndex: () => number; // Get current history index
84
+ }
85
+ ```
86
+
87
+ ### Method 2: Using DownloadPanel with Hidden Built-in Controls
88
+
89
+ You can hide the built-in undo/redo buttons and use your own:
90
+
91
+ ```typescript
92
+ import { DiagrammingPage, DownloadPanel } from '@flowuent-labs/diagrams';
93
+
94
+ const MyComponent = () => {
95
+ return (
96
+ <DiagrammingPage
97
+ diagramType="automation"
98
+ defaultNodes={nodes}
99
+ defaultEdges={edges}
100
+ availableFunctions={[]}
101
+ id={1}
102
+ >
103
+ {/* Hide built-in undo/redo buttons */}
104
+ <DownloadPanel
105
+ hideUndo={true}
106
+ hideRedo={true}
107
+ position="top-left"
108
+ />
109
+
110
+ {/* Your custom controls */}
111
+ <YourCustomControls />
112
+ </DiagrammingPage>
113
+ );
114
+ };
115
+ ```
116
+
117
+ ## Complete Example
118
+
119
+ Here's a complete example showing how to implement external undo/redo controls:
120
+
121
+ ```typescript
122
+ import React, { useRef, useState, useEffect } from 'react';
123
+ import { Button, Box, Typography, IconButton } from '@mui/material';
124
+ import { UndoIcon, RedoIcon, ClearIcon } from '@mui/icons-material';
125
+ import { DiagrammingPage, DiagrammingPageRef } from '@flowuent-labs/diagrams';
126
+ import { ICardNode } from '@flowuent-labs/diagrams';
127
+ import { Edge } from '@xyflow/react';
128
+
129
+ const AutomationDiagramWithExternalControls: React.FC = () => {
130
+ const diagramRef = useRef<DiagrammingPageRef>(null);
131
+ const [canUndo, setCanUndo] = useState(false);
132
+ const [canRedo, setCanRedo] = useState(false);
133
+ const [historyInfo, setHistoryInfo] = useState({ index: 0, length: 0 });
134
+
135
+ // Sample automation diagram data
136
+ const defaultNodes: ICardNode[] = [
137
+ {
138
+ id: '1',
139
+ type: 'AutomationStartNode',
140
+ position: { x: 100, y: 100 },
141
+ data: { label: 'Start Process' }
142
+ },
143
+ {
144
+ id: '2',
145
+ type: 'AutomationApiNode',
146
+ position: { x: 300, y: 100 },
147
+ data: { label: 'API Call' }
148
+ },
149
+ {
150
+ id: '3',
151
+ type: 'AutomationEndNode',
152
+ position: { x: 500, y: 100 },
153
+ data: { label: 'End Process' }
154
+ }
155
+ ];
156
+
157
+ const defaultEdges: Edge[] = [
158
+ { id: 'e1-2', source: '1', target: '2' },
159
+ { id: 'e2-3', source: '2', target: '3' }
160
+ ];
161
+
162
+ const updateButtonStates = () => {
163
+ if (diagramRef.current) {
164
+ setCanUndo(diagramRef.current.canUndo());
165
+ setCanRedo(diagramRef.current.canRedo());
166
+ setHistoryInfo({
167
+ index: diagramRef.current.getHistoryIndex(),
168
+ length: diagramRef.current.getHistoryLength()
169
+ });
170
+ }
171
+ };
172
+
173
+ const handleUndo = () => {
174
+ if (diagramRef.current?.canUndo()) {
175
+ diagramRef.current.undo();
176
+ updateButtonStates();
177
+ }
178
+ };
179
+
180
+ const handleRedo = () => {
181
+ if (diagramRef.current?.canRedo()) {
182
+ diagramRef.current.redo();
183
+ updateButtonStates();
184
+ }
185
+ };
186
+
187
+ const handleReset = () => {
188
+ diagramRef.current?.reset();
189
+ updateButtonStates();
190
+ };
191
+
192
+ // Update button states when diagram changes
193
+ useEffect(() => {
194
+ const interval = setInterval(updateButtonStates, 100);
195
+ return () => clearInterval(interval);
196
+ }, []);
197
+
198
+ return (
199
+ <Box sx={{ height: '100vh', display: 'flex', flexDirection: 'column' }}>
200
+ {/* External Controls Toolbar */}
201
+ <Box sx={{
202
+ p: 2,
203
+ bgcolor: '#f5f5f5',
204
+ borderBottom: '1px solid #ddd',
205
+ display: 'flex',
206
+ gap: 2,
207
+ alignItems: 'center',
208
+ boxShadow: '0 2px 4px rgba(0,0,0,0.1)'
209
+ }}>
210
+ <Typography variant="h6" sx={{ fontWeight: 'bold' }}>
211
+ Automation Diagram Controls
212
+ </Typography>
213
+
214
+ <Box sx={{ display: 'flex', gap: 1, ml: 2 }}>
215
+ <IconButton
216
+ onClick={handleUndo}
217
+ disabled={!canUndo}
218
+ sx={{
219
+ bgcolor: canUndo ? '#1976d2' : '#e0e0e0',
220
+ color: canUndo ? 'white' : '#9e9e9e',
221
+ '&:hover': {
222
+ bgcolor: canUndo ? '#1565c0' : '#e0e0e0'
223
+ }
224
+ }}
225
+ >
226
+ <UndoIcon />
227
+ </IconButton>
228
+
229
+ <IconButton
230
+ onClick={handleRedo}
231
+ disabled={!canRedo}
232
+ sx={{
233
+ bgcolor: canRedo ? '#1976d2' : '#e0e0e0',
234
+ color: canRedo ? 'white' : '#9e9e9e',
235
+ '&:hover': {
236
+ bgcolor: canRedo ? '#1565c0' : '#e0e0e0'
237
+ }
238
+ }}
239
+ >
240
+ <RedoIcon />
241
+ </IconButton>
242
+
243
+ <IconButton
244
+ onClick={handleReset}
245
+ sx={{
246
+ bgcolor: '#d32f2f',
247
+ color: 'white',
248
+ '&:hover': {
249
+ bgcolor: '#c62828'
250
+ }
251
+ }}
252
+ >
253
+ <ClearIcon />
254
+ </IconButton>
255
+ </Box>
256
+
257
+ <Typography variant="body2" sx={{ ml: 'auto', color: '#666' }}>
258
+ History: {historyInfo.index} / {historyInfo.length}
259
+ </Typography>
260
+ </Box>
261
+
262
+ {/* Diagram */}
263
+ <Box sx={{ flex: 1 }}>
264
+ <DiagrammingPage
265
+ ref={diagramRef}
266
+ diagramType="automation"
267
+ defaultNodes={defaultNodes}
268
+ defaultEdges={defaultEdges}
269
+ availableFunctions={[]}
270
+ id={1}
271
+ onChange={() => {
272
+ // Update button states when diagram changes
273
+ setTimeout(updateButtonStates, 100);
274
+ }}
275
+ />
276
+ </Box>
277
+ </Box>
278
+ );
279
+ };
280
+
281
+ export default AutomationDiagramWithExternalControls;
282
+ ```
283
+
284
+ ## Integration Steps for Your Team Member
285
+
286
+ 1. **Install the updated library** with the new ref-based API
287
+ 2. **Create a ref** to the DiagrammingPage component
288
+ 3. **Add external buttons** that call the ref methods
289
+ 4. **Handle state updates** to enable/disable buttons appropriately
290
+ 5. **Test the functionality** with various diagram operations
291
+
292
+ ## Key Benefits
293
+
294
+ - **Full Control**: Complete control over undo/redo UI and behavior
295
+ - **State Awareness**: Know when undo/redo is available
296
+ - **History Information**: Access to history length and current index
297
+ - **Keyboard Support**: Built-in keyboard shortcuts still work
298
+ - **Flexible Integration**: Works with any UI framework or custom components
299
+
300
+ ## Notes
301
+
302
+ - The undo/redo functionality works automatically for all diagram types
303
+ - History is maintained per diagram instance
304
+ - Changes are tracked for node/edge additions, deletions, modifications, and movements
305
+ - The system prevents infinite loops and handles edge cases gracefully
306
+ - Keyboard shortcuts (Ctrl+Z, Ctrl+Y) work alongside external controls