@flowuent-org/diagramming-core 1.0.8 → 1.1.1

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.
Files changed (40) hide show
  1. package/apps/diagramming/src/AutomationDiagramData.ts +22 -0
  2. package/apps/diagramming/src/components/AddNodeView.tsx +252 -252
  3. package/apps/diagramming/src/main.tsx +463 -463
  4. package/apps/diagramming/src/node-data.ts +664 -664
  5. package/apps/diagramming/src/stencil-items.ts +31 -31
  6. package/apps/diagramming/src/vite-env.d.ts +1 -1
  7. package/package.json +1 -1
  8. package/packages/diagrams/NODE_DATA_UPDATE_API.md +430 -430
  9. package/packages/diagrams/README.md +7 -463
  10. package/packages/diagrams/UNDO_REDO_API.md +306 -306
  11. package/packages/diagrams/package.json +27 -27
  12. package/packages/diagrams/project.json +42 -42
  13. package/packages/diagrams/rollup.config.js +26 -26
  14. package/packages/diagrams/src/DiagramFlow.tsx +7 -7
  15. package/packages/diagrams/src/index.ts +116 -116
  16. package/packages/diagrams/src/index.ts.bak +99 -99
  17. package/packages/diagrams/src/lib/atoms/CardEditableTitle.tsx +76 -76
  18. package/packages/diagrams/src/lib/atoms/ExpressionInput.tsx +437 -437
  19. package/packages/diagrams/src/lib/components/DiagramPanel.tsx +331 -331
  20. package/packages/diagrams/src/lib/components/automation/AISuggestionsModal.tsx +269 -0
  21. package/packages/diagrams/src/lib/components/automation/AISuggestionsPanel.tsx +227 -0
  22. package/packages/diagrams/src/lib/components/automation/AutomationAISuggestionNode.tsx +178 -115
  23. package/packages/diagrams/src/lib/components/automation/AutomationApiNode.tsx +133 -27
  24. package/packages/diagrams/src/lib/components/automation/AutomationEndNode.tsx +134 -28
  25. package/packages/diagrams/src/lib/components/automation/AutomationFormattingNode.tsx +132 -27
  26. package/packages/diagrams/src/lib/components/automation/AutomationNoteNode.tsx +124 -17
  27. package/packages/diagrams/src/lib/components/automation/AutomationSheetsNode.tsx +122 -15
  28. package/packages/diagrams/src/lib/components/automation/index.ts +3 -0
  29. package/packages/diagrams/src/lib/contexts/onWorkflowNodeDelete.ts +65 -65
  30. package/packages/diagrams/src/lib/organisms/CustomEdge/useCreateBendPoint.tsx +121 -121
  31. package/packages/diagrams/src/lib/organisms/WorkFlowNode/NodeActionButtons.tsx +45 -45
  32. package/packages/diagrams/src/lib/templates/node-forms/CallForm.tsx +370 -370
  33. package/packages/diagrams/src/lib/templates/systemFlow/components/FloatingEdge.tsx +219 -219
  34. package/packages/diagrams/src/lib/types/card-node.ts +68 -68
  35. package/packages/diagrams/src/lib/types/node-types.ts +29 -29
  36. package/packages/diagrams/src/lib/utils/AutomationExecutionEngine.ts +1179 -1179
  37. package/packages/diagrams/tsconfig.lib.json +25 -25
  38. package/tsconfig.base.json +29 -30
  39. package/TRANSLATION_FIX_SUMMARY.md +0 -118
  40. package/packages/diagrams/I18N_SETUP.md +0 -126
@@ -0,0 +1,269 @@
1
+ import React from 'react';
2
+ import { createRoot } from 'react-dom/client';
3
+ import { Box, Typography, Card, CardContent, IconButton, Chip } from '@mui/material';
4
+ import { Close as CloseIcon, Lightbulb as LightbulbIcon, Star as StarIcon } from '@mui/icons-material';
5
+ import { RiCloseLine } from 'react-icons/ri';
6
+
7
+ export interface AISuggestion {
8
+ id: string;
9
+ title: string;
10
+ description: string;
11
+ tags: string[];
12
+ onClick?: () => void;
13
+ }
14
+
15
+ interface AISuggestionsModalProps {
16
+ suggestions: AISuggestion[];
17
+ onClose: () => void;
18
+ onSuggestionClick?: (suggestion: AISuggestion) => void;
19
+ }
20
+
21
+ export const AISuggestionsModal: React.FC<AISuggestionsModalProps> = ({
22
+ suggestions,
23
+ onClose,
24
+ onSuggestionClick,
25
+ }) => {
26
+ const handleSuggestionClick = (suggestion: AISuggestion) => {
27
+ if (onSuggestionClick) {
28
+ onSuggestionClick(suggestion);
29
+ }
30
+ onClose();
31
+ };
32
+
33
+ return (
34
+ <>
35
+ {/* Backdrop */}
36
+ <Box
37
+ data-backdrop
38
+ onClick={onClose}
39
+ sx={{
40
+ position: 'fixed',
41
+ top: 0,
42
+ left: 0,
43
+ right: 0,
44
+ bottom: 0,
45
+ bgcolor: 'rgba(0, 0, 0, 0.5)',
46
+ zIndex: 9999,
47
+ }}
48
+ />
49
+ {/* Modal */}
50
+ <Card
51
+ id="ai-suggestions-modal"
52
+ sx={{
53
+ position: 'fixed',
54
+ top: '50%',
55
+ left: '50%',
56
+ transform: 'translate(-50%, -50%)',
57
+ zIndex: 10000,
58
+ width: '480px',
59
+ maxHeight: '80vh',
60
+ overflow: 'auto',
61
+ bgcolor: '#1F2937',
62
+ color: '#fff',
63
+ border: '1px solid #374151',
64
+ borderRadius: '12px',
65
+ boxShadow: '0 20px 25px -5px rgba(0, 0, 0, 0.5), 0 10px 10px -5px rgba(0, 0, 0, 0.2)',
66
+ '&::-webkit-scrollbar': {
67
+ width: '6px',
68
+ },
69
+ '&::-webkit-scrollbar-track': {
70
+ background: 'transparent',
71
+ },
72
+ '&::-webkit-scrollbar-thumb': {
73
+ background: '#4B5563',
74
+ borderRadius: '3px',
75
+ '&:hover': {
76
+ background: '#6B7280',
77
+ },
78
+ },
79
+ }}
80
+ >
81
+ <CardContent sx={{ bgcolor: '#1F2937', color: '#fff', p: 0 }}>
82
+ {/* Header */}
83
+ <Box
84
+ sx={{
85
+ display: 'flex',
86
+ alignItems: 'center',
87
+ justifyContent: 'space-between',
88
+ p: 3,
89
+ borderBottom: '1px solid #374151',
90
+ }}
91
+ >
92
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5 }}>
93
+ <StarIcon sx={{ color: '#3b82f6', fontSize: '20px' }} />
94
+ <Typography variant="h6" sx={{ color: '#fff', fontSize: '18px', fontWeight: 600 }}>
95
+ AI Suggestions
96
+ </Typography>
97
+ </Box>
98
+ <IconButton
99
+ aria-label="close"
100
+ onClick={onClose}
101
+ sx={{
102
+ color: '#9CA3AF',
103
+ '&:hover': {
104
+ color: '#fff',
105
+ bgcolor: 'rgba(255, 255, 255, 0.1)',
106
+ },
107
+ }}
108
+ >
109
+ <RiCloseLine />
110
+ </IconButton>
111
+ </Box>
112
+
113
+ {/* Suggestions List */}
114
+ <Box sx={{ p: 2 }}>
115
+ {suggestions.map((suggestion) => (
116
+ <Card
117
+ key={suggestion.id}
118
+ onClick={() => handleSuggestionClick(suggestion)}
119
+ sx={{
120
+ mb: 2,
121
+ bgcolor: '#111827',
122
+ border: '1px solid #374151',
123
+ borderRadius: '8px',
124
+ cursor: 'pointer',
125
+ transition: 'all 0.2s ease',
126
+ '&:hover': {
127
+ bgcolor: '#1F2937',
128
+ borderColor: '#4B5563',
129
+ transform: 'translateY(-2px)',
130
+ boxShadow: '0 4px 12px rgba(0, 0, 0, 0.3)',
131
+ },
132
+ '&:last-child': {
133
+ mb: 0,
134
+ },
135
+ }}
136
+ >
137
+ <CardContent sx={{ p: 2.5 }}>
138
+ <Box sx={{ display: 'flex', gap: 2, mb: 2 }}>
139
+ <Box
140
+ sx={{
141
+ width: '40px',
142
+ height: '40px',
143
+ minWidth: '40px',
144
+ borderRadius: '8px',
145
+ bgcolor: '#1F2937',
146
+ display: 'flex',
147
+ alignItems: 'center',
148
+ justifyContent: 'center',
149
+ }}
150
+ >
151
+ <LightbulbIcon sx={{ color: '#3b82f6', fontSize: '20px' }} />
152
+ </Box>
153
+ <Box sx={{ flex: 1 }}>
154
+ <Typography
155
+ variant="h6"
156
+ sx={{
157
+ color: '#fff',
158
+ fontSize: '16px',
159
+ fontWeight: 600,
160
+ mb: 1,
161
+ }}
162
+ >
163
+ {suggestion.title}
164
+ </Typography>
165
+ <Typography
166
+ variant="body2"
167
+ sx={{
168
+ color: '#9CA3AF',
169
+ fontSize: '13px',
170
+ lineHeight: 1.5,
171
+ }}
172
+ >
173
+ {suggestion.description}
174
+ </Typography>
175
+ </Box>
176
+ </Box>
177
+
178
+ {/* Tags */}
179
+ <Box sx={{ display: 'flex', gap: 1, flexWrap: 'wrap' }}>
180
+ {suggestion.tags.map((tag, index) => (
181
+ <Chip
182
+ key={index}
183
+ label={tag}
184
+ size="small"
185
+ sx={{
186
+ bgcolor: '#1F2937',
187
+ color: '#9CA3AF',
188
+ fontSize: '11px',
189
+ height: '24px',
190
+ borderRadius: '12px',
191
+ border: '1px solid #374151',
192
+ '& .MuiChip-label': {
193
+ px: 1.5,
194
+ },
195
+ }}
196
+ />
197
+ ))}
198
+ </Box>
199
+ </CardContent>
200
+ </Card>
201
+ ))}
202
+ </Box>
203
+
204
+ {/* Footer */}
205
+ <Box
206
+ sx={{
207
+ p: 2,
208
+ borderTop: '1px solid #374151',
209
+ textAlign: 'center',
210
+ }}
211
+ >
212
+ <Typography
213
+ variant="body2"
214
+ sx={{
215
+ color: '#6B7280',
216
+ fontSize: '12px',
217
+ }}
218
+ >
219
+ Click to add a suggestion to your workflow
220
+ </Typography>
221
+ </Box>
222
+ </CardContent>
223
+ </Card>
224
+ </>
225
+ );
226
+ };
227
+
228
+ /**
229
+ * Show AI Suggestions Modal using portal
230
+ */
231
+ export const showAISuggestionsModal = (
232
+ suggestions: AISuggestion[],
233
+ onSuggestionClick?: (suggestion: AISuggestion) => void
234
+ ): (() => void) => {
235
+ const portalRoot = document.createElement('div');
236
+ document.body.appendChild(portalRoot);
237
+
238
+ const root = createRoot(portalRoot);
239
+
240
+ const handleClose = () => {
241
+ root.unmount();
242
+ if (portalRoot.parentNode) {
243
+ document.body.removeChild(portalRoot);
244
+ }
245
+ };
246
+
247
+ // Handle click outside - backdrop handles this, but keep for safety
248
+ const handleClickOutside = (event: MouseEvent) => {
249
+ const target = event.target as Element;
250
+ if (!target.closest('#ai-suggestions-modal') && !target.closest('[data-backdrop]')) {
251
+ handleClose();
252
+ }
253
+ };
254
+
255
+ setTimeout(() => {
256
+ document.addEventListener('mousedown', handleClickOutside);
257
+ }, 0);
258
+
259
+ root.render(
260
+ <AISuggestionsModal
261
+ suggestions={suggestions}
262
+ onClose={handleClose}
263
+ onSuggestionClick={onSuggestionClick}
264
+ />
265
+ );
266
+
267
+ return handleClose;
268
+ };
269
+
@@ -0,0 +1,227 @@
1
+ import React from 'react';
2
+ import { useReactFlow, Node, Edge, MarkerType } from '@xyflow/react';
3
+ import { Box, Typography, Card, CardContent, Chip } from '@mui/material';
4
+ import { Lightbulb as LightbulbIcon, Star as StarIcon } from '@mui/icons-material';
5
+ import { AISuggestion } from './AISuggestionsModal';
6
+
7
+ interface AISuggestionsPanelProps {
8
+ suggestions: AISuggestion[];
9
+ parentNodeId: string;
10
+ onSuggestionClick?: (suggestion: AISuggestion) => void;
11
+ onClose?: () => void;
12
+ }
13
+
14
+ export const AISuggestionsPanel: React.FC<AISuggestionsPanelProps> = ({
15
+ suggestions,
16
+ parentNodeId,
17
+ onSuggestionClick,
18
+ onClose,
19
+ }) => {
20
+ const { getNodes, setNodes, setEdges, getNode } = useReactFlow();
21
+
22
+ const handleSuggestionClick = (suggestion: AISuggestion) => {
23
+ const nodes = getNodes();
24
+ const parentNode = getNode(parentNodeId);
25
+ if (!parentNode) return;
26
+
27
+ // Calculate position for new node - below the parent node
28
+ // Node height + button height (~40px) + panel height (~400px) + spacing
29
+ const nodeHeight = parentNode.height || 150;
30
+ const panelHeight = suggestions.length * 180 + 100; // Approximate height per suggestion + padding
31
+ const newNodeY = parentNode.position.y + nodeHeight + 40 + panelHeight + 40;
32
+
33
+ // Create new AI Suggestion node
34
+ const newNodeId = `ai-suggestion-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
35
+
36
+ // Add example mappings and benefits based on suggestion type
37
+ const isCitationExtraction = suggestion.title.toLowerCase().includes('citation');
38
+ const formData: any = {
39
+ badgeText: 'Suggested Node',
40
+ pointers: suggestion.tags,
41
+ lastRun: 'Never',
42
+ };
43
+
44
+ // Add example mapping for citation extraction
45
+ if (isCitationExtraction) {
46
+ formData.mapping = { from: 'references', to: 'source_text' };
47
+ formData.benefits = [
48
+ 'Ensures proper attribution',
49
+ 'Creates standardized reference format',
50
+ 'Enables source verification',
51
+ ];
52
+ }
53
+
54
+ const newNode: Node = {
55
+ id: newNodeId,
56
+ type: 'AutomationAISuggestionNode',
57
+ position: {
58
+ x: parentNode.position.x,
59
+ y: newNodeY,
60
+ },
61
+ data: {
62
+ label: suggestion.title,
63
+ description: suggestion.description,
64
+ iconName: 'Lightbulb',
65
+ formData,
66
+ backgroundColor: 'rgba(24, 28, 37, 0.65)', // Transparent background
67
+ textColor: '#ffffff',
68
+ borderColor: '#1e293b',
69
+ },
70
+ width: 336,
71
+ height: 150,
72
+ measured: { width: 336, height: 150 },
73
+ };
74
+
75
+ // Add the new node
76
+ setNodes([...nodes, newNode]);
77
+
78
+ // Create edge from parent to new node with dotted line (unconfirmed)
79
+ const edgeId = `edge-${parentNodeId}-${newNodeId}`;
80
+ const newEdge: Edge = {
81
+ id: edgeId,
82
+ source: parentNodeId,
83
+ target: newNodeId,
84
+ sourceHandle: 'right',
85
+ targetHandle: 'left',
86
+ data: {
87
+ label: '',
88
+ type: 'flow',
89
+ isSuggested: true, // Flag to indicate this is a suggested/unconfirmed connection
90
+ },
91
+ style: {
92
+ stroke: '#ffffff',
93
+ strokeWidth: 2,
94
+ strokeDasharray: '5,5', // Dotted line
95
+ },
96
+ markerEnd: {
97
+ type: MarkerType.ArrowClosed,
98
+ color: '#ffffff',
99
+ },
100
+ };
101
+
102
+ setEdges((prevEdges) => [...prevEdges, newEdge]);
103
+
104
+ // Store edge ID in node data for later reference
105
+ formData.edgeId = edgeId;
106
+
107
+ // Call callback if provided
108
+ if (onSuggestionClick) {
109
+ onSuggestionClick(suggestion);
110
+ }
111
+
112
+ // Close the panel
113
+ if (onClose) {
114
+ onClose();
115
+ }
116
+ };
117
+
118
+ return (
119
+ <Box
120
+ sx={{
121
+ position: 'absolute',
122
+ top: '100%',
123
+ left: '50%',
124
+ transform: 'translateX(-50%)',
125
+ marginTop: '64px', // Below the button (12px) + button height (~40px) + spacing (12px)
126
+ zIndex: 1000,
127
+ minWidth: '250px',
128
+ pointerEvents: 'auto',
129
+
130
+ }}
131
+ >
132
+ <Card
133
+ sx={{
134
+ bgcolor: '#181C25',
135
+ borderRadius: '12px',
136
+ boxShadow: '0 20px 25px -5px rgba(0, 0, 0, 0.5)',
137
+ padding: '10px',
138
+ }}
139
+ >
140
+ {/* Header */}
141
+ <Box
142
+ sx={{
143
+ display: 'flex',
144
+ alignItems: 'center',
145
+ gap: '10px',
146
+ pb: '10px',
147
+ }}
148
+ >
149
+ <StarIcon sx={{ color: '#2563EB', fontSize: '12px' }} />
150
+ <Typography sx={{ color: '#E5E7EB', fontSize: '12px', fontWeight: 500 }}>
151
+ AI Suggestions
152
+ </Typography>
153
+ </Box>
154
+
155
+ {/* Suggestions List */}
156
+ <Box sx={{ }}>
157
+ {suggestions.map((suggestion) => (
158
+ <Card key={suggestion.id} onClick={() => handleSuggestionClick(suggestion)} sx={{ mb: 1, bgcolor: '#2563EB1A', border: '1px solid #2563EB', borderRadius: '8px', cursor: 'pointer', transition: 'all 0.2s ease', '&:last-child': { mb: 0, } }} >
159
+ <CardContent>
160
+ <Box sx={{ display: 'flex' }}>
161
+
162
+
163
+ <Box sx={{ flex: 1 }}>
164
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
165
+ <LightbulbIcon sx={{ color: '#3b82f6', fontSize: '20px' }} />
166
+ <Typography
167
+ sx={{
168
+ color: '#E5E7EB',
169
+ fontSize: '12px',
170
+ fontWeight: 500,
171
+ mb: 1,
172
+ }}
173
+ >
174
+ {suggestion.title}
175
+ </Typography>
176
+ </Box>
177
+ <Typography
178
+ sx={{
179
+ color: '#9CA3AF',
180
+ fontSize: '10px',
181
+ lineHeight: '16px',
182
+ mb: '10px',
183
+ }}
184
+ >
185
+ {suggestion.description}
186
+ </Typography>
187
+ </Box>
188
+ </Box>
189
+
190
+ {/* Tags */}
191
+ <Box sx={{ display: 'flex', gap: 1, flexWrap: 'wrap' }}>
192
+ {suggestion.tags.map((tag, index) => (
193
+ <Chip
194
+ key={index}
195
+ label={tag}
196
+ sx={{
197
+ bgcolor: '#2D3748',
198
+ color: '#A5B4FC',
199
+ fontSize: '10px',
200
+ fontWeight: 400,
201
+ height: '24px',
202
+ borderRadius: '5px',
203
+ }}
204
+ />
205
+ ))}
206
+ </Box>
207
+ </CardContent>
208
+ </Card>
209
+ ))}
210
+ </Box>
211
+
212
+ {/* Footer */}
213
+ <Box sx={{ pt: '10px' }}>
214
+ <Typography
215
+ sx={{
216
+ color: '#9CA3AF',
217
+ fontSize: '10px',
218
+ }}
219
+ >
220
+ Click to add a suggestion to your workflow
221
+ </Typography>
222
+ </Box>
223
+ </Card>
224
+ </Box>
225
+ );
226
+ };
227
+