@flowuent-org/diagramming-core 1.2.0 → 1.2.2
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.
- package/apps/diagramming/src/AutomationDiagramData.ts +65 -1
- package/package.json +1 -1
- package/packages/diagrams/src/lib/components/CanvasSearchBar.tsx +281 -0
- package/packages/diagrams/src/lib/components/automation/AutomationApiNode.tsx +4 -2
- package/packages/diagrams/src/lib/components/automation/AutomationEndNode.tsx +3 -1
- package/packages/diagrams/src/lib/components/automation/AutomationFormattingNode.tsx +3 -1
- package/packages/diagrams/src/lib/components/automation/AutomationNavigationNode.tsx +584 -0
- package/packages/diagrams/src/lib/components/automation/AutomationNoteNode.tsx +3 -1
- package/packages/diagrams/src/lib/components/automation/AutomationSheetsNode.tsx +3 -1
- package/packages/diagrams/src/lib/components/automation/AutomationStartNode.tsx +4 -2
- package/packages/diagrams/src/lib/components/automation/index.ts +1 -0
- package/packages/diagrams/src/lib/contexts/SearchContext.tsx +78 -0
- package/packages/diagrams/src/lib/templates/DiagramContainer.tsx +79 -76
- package/packages/diagrams/src/lib/templates/DiagramContent.tsx +276 -61
- package/packages/diagrams/src/lib/types/automation-node-data-types.ts +22 -2
- package/packages/diagrams/src/lib/types/node-types.ts +2 -0
- package/packages/diagrams/src/lib/utils/highlightText.tsx +93 -0
|
@@ -149,6 +149,51 @@ export const automationDefaultNodes = [
|
|
|
149
149
|
height: 150,
|
|
150
150
|
measured: { width: 336, height: 150 },
|
|
151
151
|
},
|
|
152
|
+
{
|
|
153
|
+
id: 'navigation-node',
|
|
154
|
+
type: 'AutomationNavigationNode',
|
|
155
|
+
position: { x: 600, y: 200 },
|
|
156
|
+
data: {
|
|
157
|
+
// Display data for the node UI
|
|
158
|
+
label: 'Navigate to Website',
|
|
159
|
+
description: 'Navigate to the target website and wait for page load',
|
|
160
|
+
status: 'Ready',
|
|
161
|
+
navigationType: 'navigate',
|
|
162
|
+
url: 'https://example.com',
|
|
163
|
+
lastRun: 'Never',
|
|
164
|
+
backgroundColor: '#181C25',
|
|
165
|
+
textColor: '#ffffff',
|
|
166
|
+
borderColor: '#1e293b',
|
|
167
|
+
iconName: 'Navigation',
|
|
168
|
+
// Form data for configuration
|
|
169
|
+
formData: {
|
|
170
|
+
nodeId: 'navigation-node',
|
|
171
|
+
title: 'Navigate to Website',
|
|
172
|
+
type: 'navigation',
|
|
173
|
+
navigationType: 'navigate',
|
|
174
|
+
url: 'https://example.com',
|
|
175
|
+
timeout: 30000,
|
|
176
|
+
retryCount: 3,
|
|
177
|
+
outputVariable: 'navigationResult',
|
|
178
|
+
errorHandling: {
|
|
179
|
+
onError: 'retry',
|
|
180
|
+
maxRetries: 3,
|
|
181
|
+
fallbackAction: 'skip',
|
|
182
|
+
},
|
|
183
|
+
isPinned: false,
|
|
184
|
+
isBlock: false,
|
|
185
|
+
blocks: [],
|
|
186
|
+
parallelChildrenCount: 0,
|
|
187
|
+
conditions: {
|
|
188
|
+
combinator: 'and',
|
|
189
|
+
rules: [],
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
width: 336,
|
|
194
|
+
height: 150,
|
|
195
|
+
measured: { width: 336, height: 150 },
|
|
196
|
+
},
|
|
152
197
|
{
|
|
153
198
|
id: 'ai-suggestion-node',
|
|
154
199
|
type: 'AutomationAISuggestionNode',
|
|
@@ -504,8 +549,27 @@ export const automationDefaultEdges = [
|
|
|
504
549
|
},
|
|
505
550
|
},
|
|
506
551
|
{
|
|
507
|
-
id: 'edge-api-to-
|
|
552
|
+
id: 'edge-api-to-navigation',
|
|
508
553
|
source: 'api-call-node',
|
|
554
|
+
target: 'navigation-node',
|
|
555
|
+
sourceHandle: 'right',
|
|
556
|
+
targetHandle: 'left',
|
|
557
|
+
data: {
|
|
558
|
+
label: '',
|
|
559
|
+
type: 'flow',
|
|
560
|
+
},
|
|
561
|
+
style: {
|
|
562
|
+
stroke: '#ffffff',
|
|
563
|
+
strokeWidth: 2,
|
|
564
|
+
},
|
|
565
|
+
markerEnd: {
|
|
566
|
+
type: MarkerType.ArrowClosed,
|
|
567
|
+
color: '#ffffff',
|
|
568
|
+
},
|
|
569
|
+
},
|
|
570
|
+
{
|
|
571
|
+
id: 'edge-navigation-to-formatting',
|
|
572
|
+
source: 'navigation-node',
|
|
509
573
|
target: 'data-formatting-node',
|
|
510
574
|
sourceHandle: 'right',
|
|
511
575
|
targetHandle: 'left',
|
package/package.json
CHANGED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import React, { useState, useEffect, useRef, useCallback } from 'react';
|
|
2
|
+
import { Box, TextField, IconButton, Typography, Paper } from '@mui/material';
|
|
3
|
+
import { RiCloseLine, RiArrowUpLine, RiArrowDownLine } from 'react-icons/ri';
|
|
4
|
+
import { Node } from '@xyflow/react';
|
|
5
|
+
import { useSearch } from '../contexts/SearchContext';
|
|
6
|
+
|
|
7
|
+
interface CanvasSearchBarProps {
|
|
8
|
+
nodes: Node[];
|
|
9
|
+
onClose: () => void;
|
|
10
|
+
onNodeSelect: (nodeId: string) => void;
|
|
11
|
+
onViewportChange: (nodeId: string) => void;
|
|
12
|
+
getViewport: () => { x: number; y: number; zoom: number };
|
|
13
|
+
setViewport: (viewport: { x: number; y: number; zoom: number }) => void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const CanvasSearchBar: React.FC<CanvasSearchBarProps> = ({
|
|
17
|
+
nodes,
|
|
18
|
+
onClose,
|
|
19
|
+
onNodeSelect,
|
|
20
|
+
onViewportChange,
|
|
21
|
+
getViewport,
|
|
22
|
+
setViewport,
|
|
23
|
+
}) => {
|
|
24
|
+
const { searchQuery, setSearchQuery } = useSearch();
|
|
25
|
+
const [currentMatchIndex, setCurrentMatchIndex] = useState(0);
|
|
26
|
+
const [matchingNodes, setMatchingNodes] = useState<Node[]>([]);
|
|
27
|
+
const inputRef = useRef<HTMLInputElement>(null);
|
|
28
|
+
|
|
29
|
+
// Focus input when component mounts
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
inputRef.current?.focus();
|
|
32
|
+
}, []);
|
|
33
|
+
|
|
34
|
+
// Search nodes when query changes
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
if (!searchQuery.trim()) {
|
|
37
|
+
setMatchingNodes([]);
|
|
38
|
+
setCurrentMatchIndex(0);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const searchLower = searchQuery.toLowerCase().trim();
|
|
43
|
+
const matches = nodes.filter((node) => {
|
|
44
|
+
const label = (node.data as any)?.label?.toLowerCase() || '';
|
|
45
|
+
const id = node.id.toLowerCase();
|
|
46
|
+
const description = (node.data as any)?.description?.toLowerCase() || '';
|
|
47
|
+
return (
|
|
48
|
+
label.includes(searchLower) ||
|
|
49
|
+
id.includes(searchLower) ||
|
|
50
|
+
description.includes(searchLower)
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
setMatchingNodes(matches);
|
|
55
|
+
setCurrentMatchIndex(0);
|
|
56
|
+
|
|
57
|
+
// Navigate to first match if any
|
|
58
|
+
if (matches.length > 0) {
|
|
59
|
+
navigateToNode(matches[0].id);
|
|
60
|
+
}
|
|
61
|
+
}, [searchQuery, nodes]);
|
|
62
|
+
|
|
63
|
+
// Navigate to a specific node
|
|
64
|
+
const navigateToNode = useCallback(
|
|
65
|
+
(nodeId: string) => {
|
|
66
|
+
const node = nodes.find((n) => n.id === nodeId);
|
|
67
|
+
if (!node) return;
|
|
68
|
+
|
|
69
|
+
// Center view on the node
|
|
70
|
+
const viewport = getViewport();
|
|
71
|
+
setViewport({
|
|
72
|
+
x: -node.position.x + window.innerWidth / 2 - (node.width || 0) / 2,
|
|
73
|
+
y: -node.position.y + window.innerHeight / 2 - (node.height || 0) / 2,
|
|
74
|
+
zoom: viewport.zoom,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// Select the node
|
|
78
|
+
onNodeSelect(nodeId);
|
|
79
|
+
onViewportChange(nodeId);
|
|
80
|
+
},
|
|
81
|
+
[nodes, getViewport, setViewport, onNodeSelect, onViewportChange]
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
// Navigate to next match
|
|
85
|
+
const handleNextMatch = useCallback(() => {
|
|
86
|
+
if (matchingNodes.length === 0) return;
|
|
87
|
+
const nextIndex = (currentMatchIndex + 1) % matchingNodes.length;
|
|
88
|
+
setCurrentMatchIndex(nextIndex);
|
|
89
|
+
navigateToNode(matchingNodes[nextIndex].id);
|
|
90
|
+
}, [matchingNodes, currentMatchIndex, navigateToNode]);
|
|
91
|
+
|
|
92
|
+
// Navigate to previous match
|
|
93
|
+
const handlePreviousMatch = useCallback(() => {
|
|
94
|
+
if (matchingNodes.length === 0) return;
|
|
95
|
+
const prevIndex =
|
|
96
|
+
currentMatchIndex === 0 ? matchingNodes.length - 1 : currentMatchIndex - 1;
|
|
97
|
+
setCurrentMatchIndex(prevIndex);
|
|
98
|
+
navigateToNode(matchingNodes[prevIndex].id);
|
|
99
|
+
}, [matchingNodes, currentMatchIndex, navigateToNode]);
|
|
100
|
+
|
|
101
|
+
// Clear search query when closing
|
|
102
|
+
const handleClose = useCallback(() => {
|
|
103
|
+
setSearchQuery('');
|
|
104
|
+
onClose();
|
|
105
|
+
}, [setSearchQuery, onClose]);
|
|
106
|
+
|
|
107
|
+
// Handle keyboard shortcuts
|
|
108
|
+
useEffect(() => {
|
|
109
|
+
const handleKeyDown = (event: KeyboardEvent) => {
|
|
110
|
+
if (event.key === 'Escape') {
|
|
111
|
+
handleClose();
|
|
112
|
+
} else if (event.key === 'Enter') {
|
|
113
|
+
if (event.shiftKey) {
|
|
114
|
+
handlePreviousMatch();
|
|
115
|
+
} else {
|
|
116
|
+
handleNextMatch();
|
|
117
|
+
}
|
|
118
|
+
} else if (event.key === 'ArrowDown' && event.ctrlKey) {
|
|
119
|
+
event.preventDefault();
|
|
120
|
+
handleNextMatch();
|
|
121
|
+
} else if (event.key === 'ArrowUp' && event.ctrlKey) {
|
|
122
|
+
event.preventDefault();
|
|
123
|
+
handlePreviousMatch();
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
document.addEventListener('keydown', handleKeyDown);
|
|
128
|
+
return () => {
|
|
129
|
+
document.removeEventListener('keydown', handleKeyDown);
|
|
130
|
+
};
|
|
131
|
+
}, [handleClose, handleNextMatch, handlePreviousMatch]);
|
|
132
|
+
|
|
133
|
+
return (
|
|
134
|
+
<Paper
|
|
135
|
+
elevation={8}
|
|
136
|
+
sx={{
|
|
137
|
+
position: 'fixed',
|
|
138
|
+
top: 16,
|
|
139
|
+
left: '50%',
|
|
140
|
+
transform: 'translateX(-50%)',
|
|
141
|
+
zIndex: 10000,
|
|
142
|
+
display: 'flex',
|
|
143
|
+
alignItems: 'center',
|
|
144
|
+
gap: 1,
|
|
145
|
+
p: 1,
|
|
146
|
+
bgcolor: '#1F2937',
|
|
147
|
+
border: '1px solid #374151',
|
|
148
|
+
borderRadius: '8px',
|
|
149
|
+
minWidth: '400px',
|
|
150
|
+
boxShadow: '0 4px 20px rgba(0, 0, 0, 0.5)',
|
|
151
|
+
}}
|
|
152
|
+
>
|
|
153
|
+
<TextField
|
|
154
|
+
inputRef={inputRef}
|
|
155
|
+
placeholder="Search nodes..."
|
|
156
|
+
value={searchQuery}
|
|
157
|
+
onChange={(e) => setSearchQuery(e.target.value)}
|
|
158
|
+
size="small"
|
|
159
|
+
autoFocus
|
|
160
|
+
sx={{
|
|
161
|
+
flex: 1,
|
|
162
|
+
'& .MuiOutlinedInput-root': {
|
|
163
|
+
bgcolor: '#111827',
|
|
164
|
+
color: '#fff',
|
|
165
|
+
borderRadius: '6px',
|
|
166
|
+
'& fieldset': {
|
|
167
|
+
borderColor: '#374151',
|
|
168
|
+
},
|
|
169
|
+
'&:hover fieldset': {
|
|
170
|
+
borderColor: '#4B5563',
|
|
171
|
+
},
|
|
172
|
+
'&.Mui-focused fieldset': {
|
|
173
|
+
borderColor: '#3b82f6',
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
'& .MuiInputBase-input': {
|
|
177
|
+
color: '#fff',
|
|
178
|
+
fontSize: '14px',
|
|
179
|
+
'&::placeholder': {
|
|
180
|
+
color: '#9CA3AF',
|
|
181
|
+
opacity: 1,
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
}}
|
|
185
|
+
/>
|
|
186
|
+
|
|
187
|
+
{/* Match count and navigation */}
|
|
188
|
+
{searchQuery.trim() && matchingNodes.length > 0 && (
|
|
189
|
+
<Box
|
|
190
|
+
sx={{
|
|
191
|
+
display: 'flex',
|
|
192
|
+
alignItems: 'center',
|
|
193
|
+
gap: 0.5,
|
|
194
|
+
px: 1,
|
|
195
|
+
borderRight: '1px solid #374151',
|
|
196
|
+
borderLeft: '1px solid #374151',
|
|
197
|
+
}}
|
|
198
|
+
>
|
|
199
|
+
<Typography
|
|
200
|
+
variant="caption"
|
|
201
|
+
sx={{
|
|
202
|
+
color: '#9CA3AF',
|
|
203
|
+
fontSize: '12px',
|
|
204
|
+
minWidth: '50px',
|
|
205
|
+
textAlign: 'center',
|
|
206
|
+
}}
|
|
207
|
+
>
|
|
208
|
+
{currentMatchIndex + 1}/{matchingNodes.length}
|
|
209
|
+
</Typography>
|
|
210
|
+
<IconButton
|
|
211
|
+
size="small"
|
|
212
|
+
onClick={handlePreviousMatch}
|
|
213
|
+
disabled={matchingNodes.length === 0}
|
|
214
|
+
sx={{
|
|
215
|
+
color: '#9CA3AF',
|
|
216
|
+
'&:hover': {
|
|
217
|
+
bgcolor: 'rgba(255, 255, 255, 0.1)',
|
|
218
|
+
color: '#fff',
|
|
219
|
+
},
|
|
220
|
+
'&:disabled': {
|
|
221
|
+
color: '#4B5563',
|
|
222
|
+
},
|
|
223
|
+
}}
|
|
224
|
+
title="Previous match (Shift+Enter or Ctrl+↑)"
|
|
225
|
+
>
|
|
226
|
+
<RiArrowUpLine size={16} />
|
|
227
|
+
</IconButton>
|
|
228
|
+
<IconButton
|
|
229
|
+
size="small"
|
|
230
|
+
onClick={handleNextMatch}
|
|
231
|
+
disabled={matchingNodes.length === 0}
|
|
232
|
+
sx={{
|
|
233
|
+
color: '#9CA3AF',
|
|
234
|
+
'&:hover': {
|
|
235
|
+
bgcolor: 'rgba(255, 255, 255, 0.1)',
|
|
236
|
+
color: '#fff',
|
|
237
|
+
},
|
|
238
|
+
'&:disabled': {
|
|
239
|
+
color: '#4B5563',
|
|
240
|
+
},
|
|
241
|
+
}}
|
|
242
|
+
title="Next match (Enter or Ctrl+↓)"
|
|
243
|
+
>
|
|
244
|
+
<RiArrowDownLine size={16} />
|
|
245
|
+
</IconButton>
|
|
246
|
+
</Box>
|
|
247
|
+
)}
|
|
248
|
+
|
|
249
|
+
{/* No results indicator */}
|
|
250
|
+
{searchQuery.trim() && matchingNodes.length === 0 && (
|
|
251
|
+
<Typography
|
|
252
|
+
variant="caption"
|
|
253
|
+
sx={{
|
|
254
|
+
color: '#EF4444',
|
|
255
|
+
fontSize: '12px',
|
|
256
|
+
px: 1,
|
|
257
|
+
}}
|
|
258
|
+
>
|
|
259
|
+
No matches
|
|
260
|
+
</Typography>
|
|
261
|
+
)}
|
|
262
|
+
|
|
263
|
+
{/* Close button */}
|
|
264
|
+
<IconButton
|
|
265
|
+
size="small"
|
|
266
|
+
onClick={handleClose}
|
|
267
|
+
sx={{
|
|
268
|
+
color: '#9CA3AF',
|
|
269
|
+
'&:hover': {
|
|
270
|
+
bgcolor: 'rgba(255, 255, 255, 0.1)',
|
|
271
|
+
color: '#fff',
|
|
272
|
+
},
|
|
273
|
+
}}
|
|
274
|
+
title="Close (Esc)"
|
|
275
|
+
>
|
|
276
|
+
<RiCloseLine size={18} />
|
|
277
|
+
</IconButton>
|
|
278
|
+
</Paper>
|
|
279
|
+
);
|
|
280
|
+
};
|
|
281
|
+
|
|
@@ -21,6 +21,7 @@ import { AISuggestion } from './AISuggestionsModal';
|
|
|
21
21
|
import { AISuggestionsPanel } from './AISuggestionsPanel';
|
|
22
22
|
import { NodeActionButtons } from './NodeActionButtons';
|
|
23
23
|
import { showNodeAIAssistantPopup } from './NodeAIAssistantPopup';
|
|
24
|
+
import { useSearch } from '../../contexts/SearchContext';
|
|
24
25
|
|
|
25
26
|
interface AutomationApiNodeProps {
|
|
26
27
|
data: {
|
|
@@ -60,6 +61,7 @@ interface AutomationApiNodeProps {
|
|
|
60
61
|
|
|
61
62
|
export const AutomationApiNode: React.FC<AutomationApiNodeProps> = ({ data, selected }) => {
|
|
62
63
|
const { t } = useTranslation();
|
|
64
|
+
const { highlightText } = useSearch();
|
|
63
65
|
const [isJsonOpen, setIsJsonOpen] = useState(false);
|
|
64
66
|
const [showSuggestions, setShowSuggestions] = useState(false);
|
|
65
67
|
const rootRef = useRef<any>(null);
|
|
@@ -346,7 +348,7 @@ export const AutomationApiNode: React.FC<AutomationApiNodeProps> = ({ data, sele
|
|
|
346
348
|
<IconComponent sx={{ color: 'white', fontSize: '18px' }} />
|
|
347
349
|
</Box>
|
|
348
350
|
<Typography variant="h6" sx={{ fontWeight: 600, fontSize: '16px' }}>
|
|
349
|
-
{data.label}
|
|
351
|
+
{highlightText(data.label)}
|
|
350
352
|
</Typography>
|
|
351
353
|
</Box>
|
|
352
354
|
<Chip
|
|
@@ -399,7 +401,7 @@ export const AutomationApiNode: React.FC<AutomationApiNodeProps> = ({ data, sele
|
|
|
399
401
|
lineHeight: 1.4,
|
|
400
402
|
margin: 0
|
|
401
403
|
}}>
|
|
402
|
-
{data.description}
|
|
404
|
+
{highlightText(data.description)}
|
|
403
405
|
</Typography>
|
|
404
406
|
</Box>
|
|
405
407
|
</Box>
|
|
@@ -12,6 +12,7 @@ import { AISuggestion } from './AISuggestionsModal';
|
|
|
12
12
|
import { AISuggestionsPanel } from './AISuggestionsPanel';
|
|
13
13
|
import { NodeActionButtons } from './NodeActionButtons';
|
|
14
14
|
import { showNodeAIAssistantPopup } from './NodeAIAssistantPopup';
|
|
15
|
+
import { useSearch } from '../../contexts/SearchContext';
|
|
15
16
|
|
|
16
17
|
interface AutomationEndNodeProps {
|
|
17
18
|
data: {
|
|
@@ -40,6 +41,7 @@ interface AutomationEndNodeProps {
|
|
|
40
41
|
|
|
41
42
|
export const AutomationEndNode: React.FC<AutomationEndNodeProps> = ({ data, selected }) => {
|
|
42
43
|
const { t } = useTranslation();
|
|
44
|
+
const { highlightText } = useSearch();
|
|
43
45
|
const [isJsonOpen, setIsJsonOpen] = useState(false);
|
|
44
46
|
const [showSuggestions, setShowSuggestions] = useState(false);
|
|
45
47
|
const rootRef = useRef<any>(null);
|
|
@@ -275,7 +277,7 @@ export const AutomationEndNode: React.FC<AutomationEndNodeProps> = ({ data, sele
|
|
|
275
277
|
<IconComponent sx={{ color: 'white', fontSize: '18px' }} />
|
|
276
278
|
</Box>
|
|
277
279
|
<Typography variant="h6" sx={{ fontWeight: 600, fontSize: '16px' }}>
|
|
278
|
-
{data.label}
|
|
280
|
+
{highlightText(data.label)}
|
|
279
281
|
</Typography>
|
|
280
282
|
</Box>
|
|
281
283
|
<Chip
|
|
@@ -21,6 +21,7 @@ import { AISuggestion } from './AISuggestionsModal';
|
|
|
21
21
|
import { AISuggestionsPanel } from './AISuggestionsPanel';
|
|
22
22
|
import { NodeActionButtons } from './NodeActionButtons';
|
|
23
23
|
import { showNodeAIAssistantPopup } from './NodeAIAssistantPopup';
|
|
24
|
+
import { useSearch } from '../../contexts/SearchContext';
|
|
24
25
|
|
|
25
26
|
interface AutomationFormattingNodeProps {
|
|
26
27
|
data: {
|
|
@@ -65,6 +66,7 @@ interface AutomationFormattingNodeProps {
|
|
|
65
66
|
|
|
66
67
|
export const AutomationFormattingNode: React.FC<AutomationFormattingNodeProps> = ({ data, selected }) => {
|
|
67
68
|
const { t } = useTranslation();
|
|
69
|
+
const { highlightText } = useSearch();
|
|
68
70
|
const [isJsonOpen, setIsJsonOpen] = useState(false);
|
|
69
71
|
const [showSuggestions, setShowSuggestions] = useState(false);
|
|
70
72
|
const rootRef = useRef<any>(null);
|
|
@@ -349,7 +351,7 @@ export const AutomationFormattingNode: React.FC<AutomationFormattingNodeProps> =
|
|
|
349
351
|
<IconComponent sx={{ color: 'white', fontSize: '18px' }} />
|
|
350
352
|
</Box>
|
|
351
353
|
<Typography variant="h6" sx={{ fontWeight: 600, fontSize: '16px' }}>
|
|
352
|
-
{data.label}
|
|
354
|
+
{highlightText(data.label)}
|
|
353
355
|
</Typography>
|
|
354
356
|
</Box>
|
|
355
357
|
<Chip
|