@topconsultnpm/sdkui-react-beta 6.16.1 → 6.16.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/lib/components/features/workflow/diagram/DiagramItemComponent.js +23 -9
- package/lib/components/features/workflow/diagram/DiagramItemForm.d.ts +9 -0
- package/lib/components/features/workflow/diagram/DiagramItemForm.js +25 -0
- package/lib/components/features/workflow/diagram/WFDiagram.js +95 -57
- package/lib/components/features/workflow/diagram/workflowHelpers.d.ts +16 -2
- package/lib/components/features/workflow/diagram/workflowHelpers.js +75 -12
- package/lib/components/forms/TMChooserForm.js +2 -2
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React, { useState, useCallback, useRef, useEffect, useMemo } from 'react';
|
|
3
3
|
import styled, { keyframes, css } from 'styled-components';
|
|
4
|
-
import DiagramItemSvgContent from './DiagramItemSvgContent';
|
|
5
|
-
import { calculateDiagramItemFullDimensions, PADDING_TOP, SPACING_SVG_TEXT, SVG_ICON_SIZE } from './workflowHelpers';
|
|
4
|
+
import DiagramItemSvgContent from './DiagramItemSvgContent';
|
|
5
|
+
import { calculateDiagramItemFullDimensions, FONT_SIZE, MAX_ITEM_WIDTH, MAX_LINES, PADDING_HORIZONTAL, PADDING_TOP, SPACING_SVG_TEXT, SVG_ICON_SIZE, wrapText } from './workflowHelpers';
|
|
6
6
|
const blink = keyframes `
|
|
7
7
|
0%, 100% { opacity: 1; }
|
|
8
8
|
50% { opacity: 0.4; }
|
|
@@ -90,8 +90,8 @@ const DiagramItemComponent = ({ item, isSelected, isCurrent, readOnly, onClick,
|
|
|
90
90
|
const [textDimensions, setTextDimensions] = useState({ width: 0, height: 0 });
|
|
91
91
|
// Calcola le dimensioni totali dell'elemento usando la funzione di utilità
|
|
92
92
|
const { calculatedWidth, calculatedHeight } = useMemo(() => {
|
|
93
|
-
return calculateDiagramItemFullDimensions(textDimensions);
|
|
94
|
-
}, [textDimensions]);
|
|
93
|
+
return calculateDiagramItemFullDimensions(item, textDimensions);
|
|
94
|
+
}, [item.ItemName, textDimensions]);
|
|
95
95
|
useEffect(() => {
|
|
96
96
|
setCurrentPosition({ x: item.Left, y: item.Top });
|
|
97
97
|
}, [item.Left, item.Top, item.ID]);
|
|
@@ -197,6 +197,9 @@ const DiagramItemComponent = ({ item, isSelected, isCurrent, readOnly, onClick,
|
|
|
197
197
|
const handleMouseLeave = useCallback(() => {
|
|
198
198
|
setIsHovered(false);
|
|
199
199
|
}, []);
|
|
200
|
+
const handleDoubleClick = useCallback(() => {
|
|
201
|
+
onDoubleClick?.(item.ID);
|
|
202
|
+
}, [onDoubleClick, item.ID]);
|
|
200
203
|
const renderContent = () => {
|
|
201
204
|
const renderConnectorWithHitArea = (cx, cy, connectorName) => (_jsxs(_Fragment, { children: [_jsx(Connector, { cx: cx, cy: cy, r: 4, "$isVisible": isHovered && !readOnly, "$isReadOnly": readOnly }), _jsx(ConnectorHitArea, { cx: cx, cy: cy, r: 15, "$isVisible": isHovered && !readOnly, "$isReadOnly": readOnly, "data-is-connector": "true", onMouseDown: (e) => {
|
|
202
205
|
if (readOnly)
|
|
@@ -219,11 +222,22 @@ const DiagramItemComponent = ({ item, isSelected, isCurrent, readOnly, onClick,
|
|
|
219
222
|
// Se non c'è testo, centra verticalmente l'icona SVG all'interno dell'altezza calcolata
|
|
220
223
|
svgY = (calculatedHeight - iconRenderHeight) / 2;
|
|
221
224
|
}
|
|
222
|
-
//
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
225
|
+
// Calculate text lines for wrapping
|
|
226
|
+
let textLines = [];
|
|
227
|
+
let isTruncated = false;
|
|
228
|
+
if (item.ItemName) {
|
|
229
|
+
const canvas = document.createElement('canvas');
|
|
230
|
+
const context = canvas.getContext('2d');
|
|
231
|
+
if (context) {
|
|
232
|
+
context.font = `${FONT_SIZE}px sans-serif`;
|
|
233
|
+
textLines = wrapText(item.ItemName, MAX_ITEM_WIDTH - (PADDING_HORIZONTAL * 2), MAX_LINES, context);
|
|
234
|
+
// Check if the last line contains an ellipsis to determine truncation
|
|
235
|
+
isTruncated = textLines[textLines.length - 1].endsWith('...');
|
|
236
|
+
console.log('isTruncated ', isTruncated);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return (_jsxs(_Fragment, { children: [isTruncated && _jsx("title", { children: item.ItemName }), _jsx("rect", { x: "0", y: "0", width: calculatedWidth, height: calculatedHeight, className: "item-main-shape" }), _jsx("g", { transform: `translate(${svgX}, ${svgY})`, children: _jsx(DiagramItemSvgContent, { itemType: item.Type, width: iconRenderWidth, height: iconRenderHeight }) }), textLines.length > 0 && (_jsx("text", { ref: textRef, x: calculatedWidth / 2, dominantBaseline: "central", className: "item-text", children: textLines.map((line, index) => (_jsx("tspan", { x: calculatedWidth / 2, dy: index === 0 ? PADDING_TOP + SVG_ICON_SIZE + SPACING_SVG_TEXT : FONT_SIZE + 1, children: line }, index))) })), connectors] }));
|
|
226
240
|
};
|
|
227
|
-
return (_jsx(StyledDiagramItem, { ref: diagramItemRef, transform: `translate(${currentPosition.x}, ${currentPosition.y})`, "$isSelected": isSelected, "$itemType": item.Type, "$isDragging": isDragging, "$isHovered": isHovered, "$isReadOnly": readOnly, onMouseDown: handleMouseDown, onClick: handleItemClick, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onDoubleClick:
|
|
241
|
+
return (_jsx(StyledDiagramItem, { ref: diagramItemRef, transform: `translate(${currentPosition.x}, ${currentPosition.y})`, "$isSelected": isSelected, "$itemType": item.Type, "$isDragging": isDragging, "$isHovered": isHovered, "$isReadOnly": readOnly, onMouseDown: handleMouseDown, onClick: handleItemClick, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onDoubleClick: handleDoubleClick, children: _jsx(AnimatingGroup, { "$isCurrent": isCurrent, children: renderContent() }) }));
|
|
228
242
|
};
|
|
229
243
|
export default React.memo(DiagramItemComponent);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { DiagramItem } from './interfaces';
|
|
3
|
+
interface DiagramItemFormProps {
|
|
4
|
+
itemToEdit: DiagramItem;
|
|
5
|
+
onClose: () => void;
|
|
6
|
+
onApply: (updatedItem: DiagramItem) => void;
|
|
7
|
+
}
|
|
8
|
+
declare const DiagramItemForm: React.FC<DiagramItemFormProps>;
|
|
9
|
+
export default DiagramItemForm;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react'; // Importa useState
|
|
3
|
+
import TMModal from '../../../base/TMModal';
|
|
4
|
+
import { DiagramItemTypes } from './interfaces';
|
|
5
|
+
const DiagramItemForm = ({ itemToEdit, onClose, onApply }) => {
|
|
6
|
+
// Usa uno stato locale per le modifiche
|
|
7
|
+
const [localItem, setLocalItem] = useState(itemToEdit);
|
|
8
|
+
if (!localItem) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
// Gestore per l'input
|
|
12
|
+
const handleNameChange = (event) => {
|
|
13
|
+
setLocalItem({
|
|
14
|
+
...localItem,
|
|
15
|
+
ItemName: event.target.value
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
// Gestore per il salvataggio
|
|
19
|
+
const handleSave = () => {
|
|
20
|
+
onApply(localItem);
|
|
21
|
+
onClose();
|
|
22
|
+
};
|
|
23
|
+
return (_jsxs(TMModal, { title: DiagramItemTypes[localItem.Type].toString(), onClose: onClose, isModal: true, width: '50%', height: '50%', children: [_jsx("div", { children: _jsx("input", { type: "text", value: localItem.ItemName, onChange: handleNameChange }) }), _jsx("button", { onClick: handleSave, children: "Applica" })] }));
|
|
24
|
+
};
|
|
25
|
+
export default DiagramItemForm;
|
|
@@ -9,9 +9,9 @@ import DiagramItemComponent from './DiagramItemComponent';
|
|
|
9
9
|
import DiagramItemSvgContent from './DiagramItemSvgContent';
|
|
10
10
|
import { calculateArrowAngle, getConnectionPoint, isConnectionNonLinear, validateDiagram } from './workflowHelpers';
|
|
11
11
|
import { IconFlowChart, IconUndo, IconRestore, IconAdjust, IconCopy, IconCut, IconPaste, IconPin, IconUnpin, IconChevronRight, IconCloseOutline, IconNew, SDKUI_Localizator } from '../../../../helper';
|
|
12
|
-
import TMModal from '../../../base/TMModal';
|
|
13
12
|
import { TMExceptionBoxManager } from '../../../base/TMPopUp';
|
|
14
13
|
import { StyledLoadingContainer, StyledSpinner } from '../../../base/Styled';
|
|
14
|
+
import DiagramItemForm from './DiagramItemForm';
|
|
15
15
|
const CanvasContainer = styled.div `
|
|
16
16
|
position: relative;
|
|
17
17
|
width: 100%;
|
|
@@ -173,6 +173,10 @@ const StyledSvg = styled.svg `
|
|
|
173
173
|
min-width: calc(100% - 5px);
|
|
174
174
|
min-height: calc(100% - 5px);
|
|
175
175
|
background-color: transparent;
|
|
176
|
+
|
|
177
|
+
&:focus {
|
|
178
|
+
outline: none;
|
|
179
|
+
}
|
|
176
180
|
`;
|
|
177
181
|
const ScalableGroup = styled.g `
|
|
178
182
|
transform: translate(${props => props.$translateX}px, ${props => props.$translateY}px) scale(${props => props.$scale});
|
|
@@ -266,33 +270,48 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, readOnly = false, zoomLevel
|
|
|
266
270
|
const totalHeight = finalMaxY - finalMinY;
|
|
267
271
|
return { svgWidth: Math.max(0, totalWidth * zoomLevel), svgHeight: Math.max(0, totalHeight * zoomLevel) };
|
|
268
272
|
}, [wfDiagram, zoomLevel]);
|
|
269
|
-
const updateWfDiagram = useCallback((newDiagram) => {
|
|
273
|
+
// const updateWfDiagram = useCallback((newDiagram: WfDiagram) => {
|
|
274
|
+
// if (readOnly) return;
|
|
275
|
+
// try {
|
|
276
|
+
// validateDiagram(newDiagram);
|
|
277
|
+
// setWfDiagram(newDiagram);
|
|
278
|
+
// if (!isUndoingRedoing.current) {
|
|
279
|
+
// setWfDiagramHistory(prevHistory => {
|
|
280
|
+
// const newHistory = prevHistory.slice(0, historyIndex + 1);
|
|
281
|
+
// return [...newHistory, newDiagram];
|
|
282
|
+
// });
|
|
283
|
+
// setHistoryIndex(prevIndex => prevIndex + 1);
|
|
284
|
+
// }
|
|
285
|
+
// } catch (e: any) {
|
|
286
|
+
// TMExceptionBoxManager.show({ exception: e });
|
|
287
|
+
// }
|
|
288
|
+
// }, [historyIndex, readOnly]);
|
|
289
|
+
// const updateDiagramAndHistory = useCallback((newDiagram: WfDiagram) => {
|
|
290
|
+
// if (readOnly) return;
|
|
291
|
+
// if (!isUndoingRedoing.current) {
|
|
292
|
+
// const newHistory = wfDiagramHistory.slice(0, historyIndex + 1);
|
|
293
|
+
// setWfDiagramHistory([...newHistory, newDiagram]);
|
|
294
|
+
// setHistoryIndex(newHistory.length);
|
|
295
|
+
// }
|
|
296
|
+
// setWfDiagram(newDiagram);
|
|
297
|
+
// }, [wfDiagramHistory, historyIndex, isUndoingRedoing, setWfDiagramHistory, setHistoryIndex, setWfDiagram, readOnly]);
|
|
298
|
+
const updateDiagram = useCallback((newDiagram, validate = true) => {
|
|
270
299
|
if (readOnly)
|
|
271
300
|
return;
|
|
272
301
|
try {
|
|
273
|
-
|
|
274
|
-
|
|
302
|
+
if (validate) {
|
|
303
|
+
validateDiagram(newDiagram);
|
|
304
|
+
}
|
|
275
305
|
if (!isUndoingRedoing.current) {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
});
|
|
280
|
-
setHistoryIndex(prevIndex => prevIndex + 1);
|
|
306
|
+
const newHistory = wfDiagramHistory.slice(0, historyIndex + 1);
|
|
307
|
+
setWfDiagramHistory([...newHistory, newDiagram]);
|
|
308
|
+
setHistoryIndex(newHistory.length);
|
|
281
309
|
}
|
|
310
|
+
setWfDiagram(newDiagram);
|
|
282
311
|
}
|
|
283
312
|
catch (e) {
|
|
284
313
|
TMExceptionBoxManager.show({ exception: e });
|
|
285
314
|
}
|
|
286
|
-
}, [historyIndex, readOnly]);
|
|
287
|
-
const updateDiagramAndHistory = useCallback((newDiagram) => {
|
|
288
|
-
if (readOnly)
|
|
289
|
-
return;
|
|
290
|
-
if (!isUndoingRedoing.current) {
|
|
291
|
-
const newHistory = wfDiagramHistory.slice(0, historyIndex + 1);
|
|
292
|
-
setWfDiagramHistory([...newHistory, newDiagram]);
|
|
293
|
-
setHistoryIndex(newHistory.length);
|
|
294
|
-
}
|
|
295
|
-
setWfDiagram(newDiagram);
|
|
296
315
|
}, [wfDiagramHistory, historyIndex, isUndoingRedoing, setWfDiagramHistory, setHistoryIndex, setWfDiagram, readOnly]);
|
|
297
316
|
const handleUndo = useCallback(() => {
|
|
298
317
|
if (readOnly)
|
|
@@ -337,8 +356,8 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, readOnly = false, zoomLevel
|
|
|
337
356
|
};
|
|
338
357
|
setSelectedItems(new Set());
|
|
339
358
|
setSelectedConnections(new Set());
|
|
340
|
-
|
|
341
|
-
}, [wfDiagram, selectedItems, selectedConnections, setWfDiagram, setSelectedItems, setSelectedConnections,
|
|
359
|
+
updateDiagram(newWfDiagram, false);
|
|
360
|
+
}, [wfDiagram, selectedItems, selectedConnections, setWfDiagram, setSelectedItems, setSelectedConnections, updateDiagram, readOnly]);
|
|
342
361
|
const handleCopy = useCallback(() => {
|
|
343
362
|
if (readOnly)
|
|
344
363
|
return;
|
|
@@ -374,8 +393,8 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, readOnly = false, zoomLevel
|
|
|
374
393
|
};
|
|
375
394
|
setSelectedItems(new Set());
|
|
376
395
|
setSelectedConnections(new Set());
|
|
377
|
-
|
|
378
|
-
}, [wfDiagram, selectedItems, setSelectedItems, setSelectedConnections,
|
|
396
|
+
updateDiagram(newWfDiagram, false);
|
|
397
|
+
}, [wfDiagram, selectedItems, setSelectedItems, setSelectedConnections, updateDiagram, readOnly]);
|
|
379
398
|
const handlePaste = useCallback(() => {
|
|
380
399
|
if (readOnly)
|
|
381
400
|
return;
|
|
@@ -424,8 +443,8 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, readOnly = false, zoomLevel
|
|
|
424
443
|
DiagramItems: combinedDiagramItems,
|
|
425
444
|
Connections: combinedConnections,
|
|
426
445
|
};
|
|
427
|
-
|
|
428
|
-
}, [wfDiagram, copiedItems, copiedConnections, isCutOperation,
|
|
446
|
+
updateDiagram(newWfDiagram, false);
|
|
447
|
+
}, [wfDiagram, copiedItems, copiedConnections, isCutOperation, updateDiagram, setSelectedItems, setSelectedConnections, readOnly]);
|
|
429
448
|
const handleNew = useCallback(() => {
|
|
430
449
|
if (readOnly)
|
|
431
450
|
return;
|
|
@@ -478,17 +497,20 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, readOnly = false, zoomLevel
|
|
|
478
497
|
setItemToEdit(itemFound);
|
|
479
498
|
setIsModalOpen(true);
|
|
480
499
|
}
|
|
481
|
-
}, [wfDiagram]);
|
|
500
|
+
}, [wfDiagram, readOnly]);
|
|
482
501
|
const handleCloseModal = useCallback(() => {
|
|
483
502
|
if (readOnly)
|
|
484
503
|
return;
|
|
485
|
-
setIsModalOpen(
|
|
486
|
-
|
|
487
|
-
|
|
504
|
+
setIsModalOpen(prevIsModalOpen => {
|
|
505
|
+
return false;
|
|
506
|
+
});
|
|
507
|
+
}, [readOnly]);
|
|
488
508
|
const handleKeyDown = useCallback((event) => {
|
|
489
509
|
if (readOnly)
|
|
490
510
|
return;
|
|
491
511
|
if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Delete', 'Backspace', 'z', 'y'].includes(event.key)) {
|
|
512
|
+
// Prevent the event from bubbling up to parent components (like the TabPanel)
|
|
513
|
+
event.stopPropagation();
|
|
492
514
|
if (['z', 'y'].includes(event.key) && !event.ctrlKey) {
|
|
493
515
|
return;
|
|
494
516
|
}
|
|
@@ -552,7 +574,7 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, readOnly = false, zoomLevel
|
|
|
552
574
|
...wfDiagram,
|
|
553
575
|
DiagramItems: newDiagramItems,
|
|
554
576
|
};
|
|
555
|
-
|
|
577
|
+
updateDiagram(newWfDiagram, false);
|
|
556
578
|
return;
|
|
557
579
|
}
|
|
558
580
|
}
|
|
@@ -560,7 +582,7 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, readOnly = false, zoomLevel
|
|
|
560
582
|
handleDelete();
|
|
561
583
|
return;
|
|
562
584
|
}
|
|
563
|
-
}, [wfDiagram, selectedItems, selectedConnections, handleUndo, handleRedo, handleDelete,
|
|
585
|
+
}, [wfDiagram, selectedItems, selectedConnections, handleUndo, handleRedo, handleDelete, updateDiagram, handleCopy, handleCut, handlePaste, readOnly]);
|
|
564
586
|
const calculateConnectionPath = useCallback((connection, sourceItem, sinkItem) => {
|
|
565
587
|
const sourcePoint = getConnectionPoint(sourceItem, connection.Source.ConnectorName);
|
|
566
588
|
const sinkPoint = getConnectionPoint(sinkItem, connection.Sink.ConnectorName);
|
|
@@ -893,9 +915,9 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, readOnly = false, zoomLevel
|
|
|
893
915
|
return { ...diagram, DiagramItems: newDiagramItems };
|
|
894
916
|
};
|
|
895
917
|
const getAdjustedAndRecalculatedDiagram = useCallback((diagramToProcess) => {
|
|
896
|
-
//
|
|
918
|
+
// Aggiusta le posizioni degli elementi
|
|
897
919
|
const adjustedItemsDiagram = autoAdjustDiagram(diagramToProcess);
|
|
898
|
-
//
|
|
920
|
+
// Ricalcola le connessioni basandosi sulle nuove posizioni
|
|
899
921
|
const diagramItemsMap = new Map(adjustedItemsDiagram.DiagramItems.map(item => [item.ID, item]));
|
|
900
922
|
const adjustedConnections = adjustedItemsDiagram.Connections.map(conn => {
|
|
901
923
|
const sourceItem = diagramItemsMap.get(conn.Source.ParentDiagramItem.ID);
|
|
@@ -907,15 +929,15 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, readOnly = false, zoomLevel
|
|
|
907
929
|
}
|
|
908
930
|
return conn;
|
|
909
931
|
});
|
|
910
|
-
//
|
|
932
|
+
// Ritorna l'oggetto diagramma finale e completo
|
|
911
933
|
return { ...adjustedItemsDiagram, Connections: adjustedConnections };
|
|
912
934
|
}, [calculateConnectionPath]);
|
|
913
935
|
const handleAutoAdjust = useCallback(() => {
|
|
914
936
|
if (readOnly || !wfDiagram)
|
|
915
937
|
return;
|
|
916
938
|
const finalDiagram = getAdjustedAndRecalculatedDiagram(wfDiagram);
|
|
917
|
-
|
|
918
|
-
}, [wfDiagram, readOnly,
|
|
939
|
+
updateDiagram(finalDiagram, false);
|
|
940
|
+
}, [wfDiagram, readOnly, updateDiagram, getAdjustedAndRecalculatedDiagram]);
|
|
919
941
|
const handleMouseDown = useCallback((event) => {
|
|
920
942
|
if (readOnly)
|
|
921
943
|
return;
|
|
@@ -1105,10 +1127,10 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, readOnly = false, zoomLevel
|
|
|
1105
1127
|
...prevDiagram,
|
|
1106
1128
|
DiagramItems: prevDiagram.DiagramItems.map(item => item.ID === id ? { ...item, Left: finalX, Top: finalY } : item),
|
|
1107
1129
|
};
|
|
1108
|
-
|
|
1130
|
+
updateDiagram(updatedDiagram);
|
|
1109
1131
|
return updatedDiagram;
|
|
1110
1132
|
});
|
|
1111
|
-
}, [
|
|
1133
|
+
}, [updateDiagram, readOnly]);
|
|
1112
1134
|
const handleConnectorMouseDown = useCallback((itemId, connectorName, event) => {
|
|
1113
1135
|
if (readOnly || !wfDiagram)
|
|
1114
1136
|
return;
|
|
@@ -1175,7 +1197,7 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, readOnly = false, zoomLevel
|
|
|
1175
1197
|
...wfDiagram,
|
|
1176
1198
|
Connections: [...wfDiagram.Connections, newConnection],
|
|
1177
1199
|
};
|
|
1178
|
-
|
|
1200
|
+
updateDiagram(updatedDiagram);
|
|
1179
1201
|
}
|
|
1180
1202
|
else if (isDraggingExistingConnectionEndpoint && draggingConnectionId && draggingEndpointType && wfDiagram) {
|
|
1181
1203
|
// Logica per la riconnessione di un endpoint esistente
|
|
@@ -1200,7 +1222,7 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, readOnly = false, zoomLevel
|
|
|
1200
1222
|
...wfDiagram,
|
|
1201
1223
|
Connections: updatedConnections,
|
|
1202
1224
|
};
|
|
1203
|
-
|
|
1225
|
+
updateDiagram(updatedDiagram);
|
|
1204
1226
|
// Resetta tutti gli stati di trascinamento dell'endpoint
|
|
1205
1227
|
setIsDraggingExistingConnectionEndpoint(false);
|
|
1206
1228
|
setDraggingConnectionId(null);
|
|
@@ -1212,7 +1234,7 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, readOnly = false, zoomLevel
|
|
|
1212
1234
|
setTempConnectionSource(null);
|
|
1213
1235
|
setTempConnectionEnd(null);
|
|
1214
1236
|
setMouseDownPos(null);
|
|
1215
|
-
}, [isDrawingConnection, tempConnectionSource, wfDiagram,
|
|
1237
|
+
}, [isDrawingConnection, tempConnectionSource, wfDiagram, updateDiagram, readOnly, isDraggingExistingConnectionEndpoint, draggingConnectionId, draggingEndpointType, draggingConnectionFixedPoint]);
|
|
1216
1238
|
const handleDragOver = useCallback((event) => {
|
|
1217
1239
|
if (readOnly) {
|
|
1218
1240
|
event.preventDefault();
|
|
@@ -1244,11 +1266,11 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, readOnly = false, zoomLevel
|
|
|
1244
1266
|
...wfDiagram,
|
|
1245
1267
|
DiagramItems: [...wfDiagram.DiagramItems, newItem],
|
|
1246
1268
|
};
|
|
1247
|
-
|
|
1269
|
+
updateDiagram(updatedDiagram);
|
|
1248
1270
|
setIsDraggingFromToolbox(false);
|
|
1249
1271
|
setDraggedItemType(null);
|
|
1250
1272
|
}
|
|
1251
|
-
}, [isDraggingFromToolbox, draggedItemType, wfDiagram,
|
|
1273
|
+
}, [isDraggingFromToolbox, draggedItemType, wfDiagram, updateDiagram, zoomLevel, readOnly]);
|
|
1252
1274
|
const currentSelectionRect = useMemo(() => {
|
|
1253
1275
|
if (isDrawingSelectionRect && selectionRectStart && selectionRectEnd) {
|
|
1254
1276
|
const x = Math.min(selectionRectStart.x, selectionRectEnd.x);
|
|
@@ -1275,6 +1297,7 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, readOnly = false, zoomLevel
|
|
|
1275
1297
|
setDraggedItemType(null);
|
|
1276
1298
|
};
|
|
1277
1299
|
const handleItemDimensionsChange = useCallback((itemId, width, height) => {
|
|
1300
|
+
console.log('itemId', itemId, 'width', width, 'height', height);
|
|
1278
1301
|
setWfDiagram(prevDiagram => {
|
|
1279
1302
|
if (!prevDiagram)
|
|
1280
1303
|
return null;
|
|
@@ -1282,10 +1305,23 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, readOnly = false, zoomLevel
|
|
|
1282
1305
|
...prevDiagram,
|
|
1283
1306
|
DiagramItems: prevDiagram.DiagramItems.map(item => item.ID === itemId ? { ...item, Width: width, Height: height } : item),
|
|
1284
1307
|
};
|
|
1285
|
-
|
|
1308
|
+
updateDiagram(updatedDiagram);
|
|
1286
1309
|
return updatedDiagram;
|
|
1287
1310
|
});
|
|
1288
1311
|
}, []);
|
|
1312
|
+
const handleUpdateDiagramItem = useCallback((updatedItem) => {
|
|
1313
|
+
setWfDiagram(prevDiagram => {
|
|
1314
|
+
if (!prevDiagram)
|
|
1315
|
+
return null;
|
|
1316
|
+
const updatedDiagramItems = prevDiagram.DiagramItems.map(item => {
|
|
1317
|
+
if (item.ID === updatedItem.ID) {
|
|
1318
|
+
return updatedItem;
|
|
1319
|
+
}
|
|
1320
|
+
return item;
|
|
1321
|
+
});
|
|
1322
|
+
return { ...prevDiagram, DiagramItems: updatedDiagramItems };
|
|
1323
|
+
});
|
|
1324
|
+
}, []);
|
|
1289
1325
|
const availableItemTypes = useMemo(() => {
|
|
1290
1326
|
return [
|
|
1291
1327
|
DiagramItemTypes.Approval,
|
|
@@ -1305,15 +1341,23 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, readOnly = false, zoomLevel
|
|
|
1305
1341
|
];
|
|
1306
1342
|
}, []);
|
|
1307
1343
|
useEffect(() => {
|
|
1344
|
+
// se undo/redo, il `xmlDiagramString` è cambiato ma la storia non deve essere resettata.
|
|
1345
|
+
if (isUndoingRedoing.current) {
|
|
1346
|
+
isUndoingRedoing.current = false;
|
|
1347
|
+
return;
|
|
1348
|
+
}
|
|
1308
1349
|
setIsLoading(true);
|
|
1309
1350
|
try {
|
|
1310
1351
|
let initialDiagram = xmlDiagramString ? parseWfDiagramXml(xmlDiagramString) : null;
|
|
1311
1352
|
if (initialDiagram) {
|
|
1312
1353
|
const finalDiagram = getAdjustedAndRecalculatedDiagram(initialDiagram);
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1354
|
+
// Aggiungi un controllo per evitare di resettare la storia se il diagramma è lo stesso.
|
|
1355
|
+
if (JSON.stringify(wfDiagram) !== JSON.stringify(finalDiagram)) {
|
|
1356
|
+
setWfDiagram(finalDiagram);
|
|
1357
|
+
initialDiagramRef.current = finalDiagram;
|
|
1358
|
+
setWfDiagramHistory([finalDiagram]);
|
|
1359
|
+
setHistoryIndex(0);
|
|
1360
|
+
}
|
|
1317
1361
|
}
|
|
1318
1362
|
else {
|
|
1319
1363
|
setWfDiagram(null);
|
|
@@ -1335,13 +1379,8 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, readOnly = false, zoomLevel
|
|
|
1335
1379
|
isUndoingRedoing.current = false;
|
|
1336
1380
|
}
|
|
1337
1381
|
}, [wfDiagram]);
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
return () => {
|
|
1341
|
-
document.removeEventListener('keydown', handleKeyDown);
|
|
1342
|
-
};
|
|
1343
|
-
}, [handleKeyDown]);
|
|
1344
|
-
return (_jsxs(CanvasContainer, { children: [!readOnly && (_jsxs(ToolbarContainer, { "$isCollapsed": isToolbarCollapsed, "$isFloating": isToolbarFloating, "$isToolboxVisible": isToolboxVisible, children: [_jsx(ButtonGroup, { "$isFloating": isToolbarFloating, children: _jsxs("button", { onClick: handleToggleToolboxVisibility, title: "Show toolbox", children: [_jsx(IconFlowChart, {}), !isToolbarCollapsed && _jsx("span", { children: "Mostra/nascondi toolbox" })] }) }), _jsxs(ButtonGroup, { "$isFloating": isToolbarFloating, children: [_jsxs("button", { onClick: handleUndo, disabled: historyIndex === 0, title: "Undo", children: [_jsx(IconUndo, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "Undo" })] }), _jsxs("button", { onClick: handleRedo, disabled: historyIndex === wfDiagramHistory.length - 1, title: "Redo", children: [_jsx(IconUndo, { style: { transform: 'scaleX(-1)' } }), " ", !isToolbarCollapsed && _jsx("span", { children: "Redo" })] }), _jsxs("button", { onClick: handleRestore, title: "Restore", children: [_jsx(IconRestore, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "Restore" })] }), _jsxs("button", { onClick: handleNew, title: "New diagram", disabled: readOnly, children: [_jsx(IconNew, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "New" })] })] }), _jsx(ButtonGroup, { "$isFloating": isToolbarFloating, children: _jsxs("button", { onClick: handleAutoAdjust, title: "Auto adjust", children: [_jsx(IconAdjust, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "Auto Adjust" })] }) }), _jsxs(ButtonGroup, { "$isFloating": isToolbarFloating, children: [_jsxs("button", { onClick: handleCopy, disabled: selectedItems.size === 0, title: "Copy", children: [_jsx(IconCopy, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "Copy" })] }), _jsxs("button", { onClick: handleCut, disabled: selectedItems.size === 0, title: "Cut", children: [_jsx(IconCut, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "Cut" })] }), _jsxs("button", { onClick: handlePaste, disabled: copiedItems.length === 0 && copiedConnections.length === 0, title: "Paste", children: [_jsx(IconPaste, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "Paste" })] })] }), _jsxs("button", { onClick: handleToggleToolbarMode, title: isToolbarFloating ? "Dock Toolbar" : "Float Toolbar", children: [isToolbarFloating ? _jsx(IconPin, {}) : _jsx(IconUnpin, {}), !isToolbarCollapsed && !isToolbarFloating && _jsx("span", { children: "Toggle Mode" })] }), !isToolbarFloating && _jsx(ToolbarToggle, { onClick: () => setIsToolbarCollapsed(!isToolbarCollapsed), title: isToolbarCollapsed ? "Expand Toolbar" : "Collapse Toolbar", children: isToolbarCollapsed ? _jsx(IconChevronRight, {}) : _jsx(IconCloseOutline, {}) })] })), !readOnly && (_jsx(ToolboxContainer, { "$isVisible": isToolboxVisible, children: isToolboxVisible && availableItemTypes.map(type => (_jsxs(ToolboxItem, { draggable: true, onDragStart: (e) => handleToolboxDragStart(e, type), onDragEnd: handleToolboxDragEnd, children: [_jsx(DiagramItemSvgContent, { itemType: type, width: 40, height: 40, isToolboxPreview: true }), _jsx("span", { children: DiagramItemTypes[type] })] }, type))) })), _jsx(SvgScrollContainer, { children: isLoading ? (_jsxs(StyledLoadingContainer, { children: [_jsx(StyledSpinner, {}), _jsx("span", { children: `${'Caricamento diagramma'}...` })] })) : wfDiagram ? (_jsx(StyledSvg, { ref: svgRef, onMouseMove: handleMouseMove, onMouseUp: handleMouseUp, onMouseDown: handleMouseDown, onDrop: handleDropOnCanvas, onDragOver: handleDragOver, width: svgWidth, height: svgHeight, children: _jsxs(ScalableGroup, { "$scale": zoomLevel, "$translateX": translateX, "$translateY": translateY, children: [wfDiagram?.DiagramItems.map(item => (_jsx(DiagramItemComponent, { readOnly: readOnly, item: item, isSelected: selectedItems.has(item.ID), isCurrent: item.ID === currentSetID, onClick: handleDiagramItemClick, onDrag: handleDrag, onDragEnd: handleDragEnd, onConnectorMouseDown: handleConnectorMouseDown, onConnectorMouseUp: handleConnectorMouseUp, onDimensionsChange: handleItemDimensionsChange, onDoubleClick: handleDoubleClickItem }, item.ID))), calculatedConnections.map(connection => {
|
|
1382
|
+
return (_jsxs(CanvasContainer, { children: [!readOnly && (_jsxs(ToolbarContainer, { "$isCollapsed": isToolbarCollapsed, "$isFloating": isToolbarFloating, "$isToolboxVisible": isToolboxVisible, children: [_jsx(ButtonGroup, { "$isFloating": isToolbarFloating, children: _jsxs("button", { onClick: handleToggleToolboxVisibility, title: "Show toolbox", children: [_jsx(IconFlowChart, {}), !isToolbarCollapsed && _jsx("span", { children: "Mostra/nascondi toolbox" })] }) }), _jsxs(ButtonGroup, { "$isFloating": isToolbarFloating, children: [_jsxs("button", { onClick: handleUndo, disabled: historyIndex === 0, title: "Undo", children: [_jsx(IconUndo, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "Undo" })] }), _jsxs("button", { onClick: handleRedo, disabled: historyIndex === wfDiagramHistory.length - 1, title: "Redo", children: [_jsx(IconUndo, { style: { transform: 'scaleX(-1)' } }), " ", !isToolbarCollapsed && _jsx("span", { children: "Redo" })] }), _jsxs("button", { onClick: handleRestore, title: "Restore", children: [_jsx(IconRestore, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "Restore" })] }), _jsxs("button", { onClick: handleNew, title: "New diagram", disabled: readOnly, children: [_jsx(IconNew, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "New" })] })] }), _jsx(ButtonGroup, { "$isFloating": isToolbarFloating, children: _jsxs("button", { onClick: handleAutoAdjust, title: "Auto adjust", children: [_jsx(IconAdjust, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "Auto Adjust" })] }) }), _jsxs(ButtonGroup, { "$isFloating": isToolbarFloating, children: [_jsxs("button", { onClick: handleCopy, disabled: selectedItems.size === 0, title: "Copy", children: [_jsx(IconCopy, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "Copy" })] }), _jsxs("button", { onClick: handleCut, disabled: selectedItems.size === 0, title: "Cut", children: [_jsx(IconCut, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "Cut" })] }), _jsxs("button", { onClick: handlePaste, disabled: copiedItems.length === 0 && copiedConnections.length === 0, title: "Paste", children: [_jsx(IconPaste, {}), " ", !isToolbarCollapsed && _jsx("span", { children: "Paste" })] })] }), _jsxs("button", { onClick: handleToggleToolbarMode, title: isToolbarFloating ? "Dock Toolbar" : "Float Toolbar", children: [isToolbarFloating ? _jsx(IconPin, {}) : _jsx(IconUnpin, {}), !isToolbarCollapsed && !isToolbarFloating && _jsx("span", { children: "Toggle Mode" })] }), !isToolbarFloating && _jsx(ToolbarToggle, { onClick: () => setIsToolbarCollapsed(!isToolbarCollapsed), title: isToolbarCollapsed ? "Expand Toolbar" : "Collapse Toolbar", children: isToolbarCollapsed ? _jsx(IconChevronRight, {}) : _jsx(IconCloseOutline, {}) })] })), !readOnly && (_jsx(ToolboxContainer, { "$isVisible": isToolboxVisible, children: isToolboxVisible && availableItemTypes.map(type => (_jsxs(ToolboxItem, { draggable: true, onDragStart: (e) => handleToolboxDragStart(e, type), onDragEnd: handleToolboxDragEnd, children: [_jsx(DiagramItemSvgContent, { itemType: type, width: 40, height: 40, isToolboxPreview: true }), _jsx("span", { children: DiagramItemTypes[type] })] }, type))) })), _jsx(SvgScrollContainer, { children: isLoading ?
|
|
1383
|
+
(_jsxs(StyledLoadingContainer, { children: [_jsx(StyledSpinner, {}), _jsx("span", { children: `${'Caricamento diagramma'}...` })] })) : wfDiagram ? (_jsx(StyledSvg, { ref: svgRef, tabIndex: 0, onKeyDownCapture: handleKeyDown, onMouseMove: handleMouseMove, onMouseUp: handleMouseUp, onMouseDown: handleMouseDown, onDrop: handleDropOnCanvas, onDragOver: handleDragOver, width: svgWidth, height: svgHeight, children: _jsxs(ScalableGroup, { "$scale": zoomLevel, "$translateX": translateX, "$translateY": translateY, children: [wfDiagram?.DiagramItems.map(item => (_jsx(DiagramItemComponent, { readOnly: readOnly, item: item, isSelected: selectedItems.has(item.ID), isCurrent: item.ID === currentSetID, onClick: handleDiagramItemClick, onDrag: handleDrag, onDragEnd: handleDragEnd, onConnectorMouseDown: handleConnectorMouseDown, onConnectorMouseUp: handleConnectorMouseUp, onDimensionsChange: handleItemDimensionsChange, onDoubleClick: handleDoubleClickItem }, item.ID))), calculatedConnections.map(connection => {
|
|
1345
1384
|
const sourceItem = wfDiagram?.DiagramItems.find(item => item.ID === connection.Source.ParentDiagramItem.ID);
|
|
1346
1385
|
const sinkItem = wfDiagram?.DiagramItems.find(item => item.ID === connection.Sink.ParentDiagramItem.ID);
|
|
1347
1386
|
if (!sourceItem || !sinkItem)
|
|
@@ -1352,7 +1391,6 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, readOnly = false, zoomLevel
|
|
|
1352
1391
|
// Determina se questa è la connessione che stiamo trascinando
|
|
1353
1392
|
const isThisConnectionBeingDragged = isDraggingExistingConnectionEndpoint && draggingConnectionId === connection.ID;
|
|
1354
1393
|
return (_jsx(ConnectionComponent, { connection: connection, isSelected: selectedConnections.has(connection.ID), sourcePoint: sourcePoint, sinkPoint: sinkPoint, isTemporary: isThisConnectionBeingDragged, onClick: handleConnectionClick, onConnectionEndpointMouseDown: handleConnectionEndpointMouseDown }, connection.ID));
|
|
1355
|
-
}), isDrawingConnection && tempConnectionPathData && (_jsx(TempConnectionPath, { d: tempConnectionPathData })), isDraggingExistingConnectionEndpoint && tempConnectionPathData && (_jsx(TempConnectionPath, { d: tempConnectionPathData })), isDrawingSelectionRect && currentSelectionRect && (_jsx(SelectionRect, { x: currentSelectionRect.x, y: currentSelectionRect.y, width: currentSelectionRect.width, height: currentSelectionRect.height }))] }) }))
|
|
1356
|
-
: (_jsx(DiagramMessage, { children: `${SDKUI_Localizator.WorkflowDiagramMissingOrInvalid} ...` })) }), isModalOpen && itemToEdit && (_jsx(TMModal, { title: DiagramItemTypes[itemToEdit.Type].toString(), onClose: handleCloseModal, isModal: true, width: '50%', height: '50%', children: _jsx("div", { children: itemToEdit.ItemName }) }))] }));
|
|
1394
|
+
}), isDrawingConnection && tempConnectionPathData && (_jsx(TempConnectionPath, { d: tempConnectionPathData })), isDraggingExistingConnectionEndpoint && tempConnectionPathData && (_jsx(TempConnectionPath, { d: tempConnectionPathData })), isDrawingSelectionRect && currentSelectionRect && (_jsx(SelectionRect, { x: currentSelectionRect.x, y: currentSelectionRect.y, width: currentSelectionRect.width, height: currentSelectionRect.height }))] }) })) : (_jsx(DiagramMessage, { children: `${SDKUI_Localizator.WorkflowDiagramMissingOrInvalid} ...` })) }), isModalOpen && itemToEdit && (_jsx(DiagramItemForm, { itemToEdit: itemToEdit, onClose: handleCloseModal, onApply: handleUpdateDiagramItem }))] }));
|
|
1357
1395
|
};
|
|
1358
1396
|
export default WFDiagram;
|
|
@@ -37,14 +37,28 @@ export declare const PADDING_TOP = 5;
|
|
|
37
37
|
export declare const PADDING_BOTTOM = 5;
|
|
38
38
|
export declare const PADDING_HORIZONTAL = 5;
|
|
39
39
|
export declare const SPACING_SVG_TEXT = 0;
|
|
40
|
+
export declare const FONT_SIZE = 11;
|
|
41
|
+
export declare const MAX_ITEM_WIDTH = 130;
|
|
42
|
+
export declare const MIN_ITEM_WIDTH = 64;
|
|
43
|
+
export declare const MAX_LINES = 2;
|
|
44
|
+
/**
|
|
45
|
+
* Breaks a string into multiple lines to fit a maximum width, adding an ellipsis if it exceeds the maximum number of lines.
|
|
46
|
+
*
|
|
47
|
+
* @param text The string to be wrapped.
|
|
48
|
+
* @param maxWidth The maximum width for a single line of text.
|
|
49
|
+
* @param maxLines The maximum number of lines allowed before truncation.
|
|
50
|
+
* @returns An array of strings, where each element is a line of text.
|
|
51
|
+
*/
|
|
52
|
+
export declare const wrapText: (text: string, maxWidth: number, maxLines: number, ctx: CanvasRenderingContext2D) => string[];
|
|
40
53
|
/**
|
|
41
54
|
* Calculates the full dimensions of a diagram item, including the icon and text.
|
|
42
55
|
* This function is based on already measured or estimated text dimensions.
|
|
43
56
|
*
|
|
57
|
+
* @param item The DiagramItem.
|
|
44
58
|
* @param textDimensions The dimensions (width, height) of the item's text.
|
|
45
59
|
* @returns An object with the calculatedWidth and calculatedHeight of the item.
|
|
46
|
-
|
|
47
|
-
export declare const calculateDiagramItemFullDimensions: (textDimensions: TextDimensions) => {
|
|
60
|
+
*/
|
|
61
|
+
export declare const calculateDiagramItemFullDimensions: (item: DiagramItem, textDimensions: TextDimensions) => {
|
|
48
62
|
calculatedWidth: number;
|
|
49
63
|
calculatedHeight: number;
|
|
50
64
|
};
|
|
@@ -72,30 +72,93 @@ export const isConnectionNonLinear = (sourceRect, sinkRect, sourceConnectorName,
|
|
|
72
72
|
// If none of the above conditions are true, the connection is considered "linear"
|
|
73
73
|
return false;
|
|
74
74
|
};
|
|
75
|
-
// Layout constants
|
|
76
|
-
// of DiagramItemComponent.tsx
|
|
75
|
+
// Layout constants of DiagramItemComponent.tsx
|
|
77
76
|
export const SVG_ICON_SIZE = 60;
|
|
78
77
|
export const PADDING_TOP = 5;
|
|
79
78
|
export const PADDING_BOTTOM = 5;
|
|
80
79
|
export const PADDING_HORIZONTAL = 5;
|
|
81
80
|
export const SPACING_SVG_TEXT = 0;
|
|
81
|
+
export const FONT_SIZE = 11;
|
|
82
|
+
export const MAX_ITEM_WIDTH = 130;
|
|
83
|
+
export const MIN_ITEM_WIDTH = 64;
|
|
84
|
+
export const MAX_LINES = 2;
|
|
85
|
+
/**
|
|
86
|
+
* Breaks a string into multiple lines to fit a maximum width, adding an ellipsis if it exceeds the maximum number of lines.
|
|
87
|
+
*
|
|
88
|
+
* @param text The string to be wrapped.
|
|
89
|
+
* @param maxWidth The maximum width for a single line of text.
|
|
90
|
+
* @param maxLines The maximum number of lines allowed before truncation.
|
|
91
|
+
* @returns An array of strings, where each element is a line of text.
|
|
92
|
+
*/
|
|
93
|
+
export const wrapText = (text, maxWidth, maxLines, ctx) => {
|
|
94
|
+
if (!text || !ctx) {
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
// Per un calcolo accurato, usiamo un contesto canvas
|
|
98
|
+
// La logica precedente aveva un piccolo problema con la gestione degli spazi
|
|
99
|
+
const words = text.split(' ');
|
|
100
|
+
let lines = [];
|
|
101
|
+
let currentLine = '';
|
|
102
|
+
for (let i = 0; i < words.length; i++) {
|
|
103
|
+
const word = words[i];
|
|
104
|
+
let testLine = currentLine.length > 0 ? currentLine + ' ' + word : word;
|
|
105
|
+
const metrics = ctx.measureText(testLine);
|
|
106
|
+
const testWidth = metrics.width;
|
|
107
|
+
if (testWidth > maxWidth) {
|
|
108
|
+
lines.push(currentLine);
|
|
109
|
+
currentLine = word;
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
currentLine = testLine;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
lines.push(currentLine);
|
|
116
|
+
// Gestisce il caso dell'ellissi
|
|
117
|
+
if (lines.length > maxLines) {
|
|
118
|
+
let lastLine = lines[maxLines - 1];
|
|
119
|
+
while (ctx.measureText(lastLine + '...').width > maxWidth) {
|
|
120
|
+
lastLine = lastLine.slice(0, -1);
|
|
121
|
+
}
|
|
122
|
+
lines[maxLines - 1] = lastLine + '...';
|
|
123
|
+
lines = lines.slice(0, maxLines);
|
|
124
|
+
}
|
|
125
|
+
return lines;
|
|
126
|
+
};
|
|
82
127
|
/**
|
|
83
128
|
* Calculates the full dimensions of a diagram item, including the icon and text.
|
|
84
129
|
* This function is based on already measured or estimated text dimensions.
|
|
85
130
|
*
|
|
131
|
+
* @param item The DiagramItem.
|
|
86
132
|
* @param textDimensions The dimensions (width, height) of the item's text.
|
|
87
133
|
* @returns An object with the calculatedWidth and calculatedHeight of the item.
|
|
88
|
-
|
|
89
|
-
export const calculateDiagramItemFullDimensions = (textDimensions) => {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
134
|
+
*/
|
|
135
|
+
export const calculateDiagramItemFullDimensions = (item, textDimensions) => {
|
|
136
|
+
// Calcola la larghezza del testo con padding
|
|
137
|
+
const textWidthWithPadding = textDimensions.width + (PADDING_HORIZONTAL * 2);
|
|
138
|
+
// Applica i vincoli: la larghezza è il valore maggiore tra il minimo e il minore tra la larghezza calcolata e il massimo
|
|
139
|
+
const finalCalculatedWidth = Math.max(MIN_ITEM_WIDTH, Math.min(textWidthWithPadding, MAX_ITEM_WIDTH));
|
|
140
|
+
const textHeight = textDimensions.height;
|
|
141
|
+
let finalCalculatedHeight;
|
|
142
|
+
if (item.ItemName) {
|
|
143
|
+
// Calculate height based on wrapped text lines
|
|
144
|
+
const canvas = document.createElement('canvas');
|
|
145
|
+
const context = canvas.getContext('2d');
|
|
146
|
+
if (context) {
|
|
147
|
+
context.font = `${FONT_SIZE}px sans-serif`;
|
|
148
|
+
const lines = wrapText(item.ItemName, MAX_ITEM_WIDTH - (PADDING_HORIZONTAL * 2), MAX_LINES, context);
|
|
149
|
+
// Calculate height based on number of lines
|
|
150
|
+
finalCalculatedHeight = PADDING_TOP + SVG_ICON_SIZE + SPACING_SVG_TEXT + (lines.length * FONT_SIZE) + PADDING_BOTTOM;
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
// Fallback if canvas context is not available
|
|
154
|
+
finalCalculatedHeight = PADDING_TOP + SVG_ICON_SIZE + SPACING_SVG_TEXT + textHeight + PADDING_BOTTOM;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
// No text, so height is just icon + padding
|
|
159
|
+
finalCalculatedHeight = PADDING_TOP + SVG_ICON_SIZE + PADDING_BOTTOM;
|
|
160
|
+
}
|
|
97
161
|
// Applies the guarantee that dimensions are never less than 64px
|
|
98
|
-
finalCalculatedWidth = Math.max(finalCalculatedWidth, 64);
|
|
99
162
|
finalCalculatedHeight = Math.max(finalCalculatedHeight, 64);
|
|
100
163
|
return { calculatedWidth: finalCalculatedWidth, calculatedHeight: finalCalculatedHeight };
|
|
101
164
|
};
|
|
@@ -86,8 +86,8 @@ const TMChooserForm = ({ children, title, allowMultipleSelection = false, allowA
|
|
|
86
86
|
...summaryItems ?? {}
|
|
87
87
|
});
|
|
88
88
|
}, [manageUseLocalizedName, summaryItems]);
|
|
89
|
-
return (_jsx(TMModal, { title: renderTitle(), width: width ?? '550px', height: height ?? '600px', toolbar: _jsx(ToolbarButtons, {}), onClose: onClose, children:
|
|
90
|
-
filteredItems.length > 0
|
|
89
|
+
return (_jsx(TMModal, { title: renderTitle(), width: width ?? '550px', height: height ?? '600px', toolbar: _jsx(ToolbarButtons, {}), onClose: onClose, children: children ??
|
|
90
|
+
filteredItems.length > 0
|
|
91
91
|
? _jsx(TMDataGrid, { dataSource: filteredItems, keyExpr: keyName, dataColumns: dataColumns, focusedRowKey: focusedRowKey, selectedRowKeys: selectedRowKeys, searchPanelFocusStarting: true, headerFilter: { visible: true }, selection: { mode: allowMultipleSelection ? 'multiple' : 'single', showCheckBoxesMode: 'always', selectAllMode: 'allPages' }, grouping: allowGrouping ? { autoExpandAll: false, expandMode: 'rowClick' } : undefined, summary: customSummary, onFocusedRowChanged: handleFocusedRowChange, onSelectionChanged: handleSelectionChanged, onRowDblClick: handleRowDoubleClick })
|
|
92
92
|
: _jsx(TMLayoutContainer, { gap: 30, alignItems: 'center', justifyContent: 'center', children: _jsx(TMLayoutItem, { children: _jsx("p", { style: { height: "100%", color: TMColors.primaryColor, fontSize: "1.5rem", display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: SDKUI_Localizator.NoDataToDisplay }) }) }) }));
|
|
93
93
|
};
|