@topconsultnpm/sdkui-react 6.20.0-dev1.13 → 6.20.0-dev1.130
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/assets/Toppy-help-center.png +0 -0
- package/lib/assets/headergradient.svg +87 -0
- package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +322 -30
- package/lib/components/NewComponents/ContextMenu/hooks.d.ts +8 -1
- package/lib/components/NewComponents/ContextMenu/hooks.js +80 -8
- package/lib/components/NewComponents/ContextMenu/index.d.ts +3 -0
- package/lib/components/NewComponents/ContextMenu/index.js +2 -0
- package/lib/components/NewComponents/ContextMenu/styles.d.ts +9 -1
- package/lib/components/NewComponents/ContextMenu/styles.js +146 -47
- package/lib/components/NewComponents/ContextMenu/types.d.ts +22 -3
- package/lib/components/NewComponents/ContextMenu/useLongPress.d.ts +21 -0
- package/lib/components/NewComponents/ContextMenu/useLongPress.js +112 -0
- package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.js +620 -125
- package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +25 -5
- package/lib/components/NewComponents/FloatingMenuBar/styles.js +215 -59
- package/lib/components/NewComponents/FloatingMenuBar/types.d.ts +12 -3
- package/lib/components/base/TMAccordionNew.js +35 -14
- package/lib/components/base/TMButton.js +6 -0
- package/lib/components/base/TMClosableList.js +4 -0
- package/lib/components/base/TMCustomButton.js +61 -17
- package/lib/components/base/TMDataGrid.d.ts +7 -4
- package/lib/components/base/TMDataGrid.js +153 -11
- package/lib/components/base/TMDropDownMenu.js +21 -18
- package/lib/components/base/TMFileManager.d.ts +4 -3
- package/lib/components/base/TMFileManager.js +32 -24
- package/lib/components/base/TMFileManagerDataGridView.d.ts +3 -2
- package/lib/components/base/TMFileManagerDataGridView.js +1 -11
- package/lib/components/base/TMFileManagerThumbnailItems.d.ts +7 -1
- package/lib/components/base/TMFileManagerThumbnailItems.js +5 -2
- package/lib/components/base/TMFileManagerThumbnailsView.d.ts +17 -4
- package/lib/components/base/TMFileManagerThumbnailsView.js +18 -6
- package/lib/components/base/TMFileManagerUtils.d.ts +0 -12
- package/lib/components/base/TMListView.js +33 -15
- package/lib/components/base/TMPanel.d.ts +1 -1
- package/lib/components/base/TMPanel.js +4 -2
- package/lib/components/base/TMPopUp.js +6 -0
- package/lib/components/base/TMToolbarCard.js +2 -0
- package/lib/components/base/TMTreeView.d.ts +2 -1
- package/lib/components/base/TMTreeView.js +33 -26
- package/lib/components/choosers/TMDataListItemChooser.d.ts +2 -0
- package/lib/components/choosers/TMDataListItemChooser.js +8 -2
- package/lib/components/choosers/TMDcmtTypeChooser.d.ts +1 -0
- package/lib/components/choosers/TMDcmtTypeChooser.js +11 -3
- package/lib/components/choosers/TMDistinctValues.js +2 -2
- package/lib/components/choosers/TMDynDataListItemChooser.d.ts +2 -0
- package/lib/components/choosers/TMDynDataListItemChooser.js +8 -2
- package/lib/components/choosers/TMInvoiceRetrieveFormats.js +1 -1
- package/lib/components/choosers/TMMetadataChooser.d.ts +2 -0
- package/lib/components/choosers/TMMetadataChooser.js +19 -4
- package/lib/components/choosers/TMOrderRetrieveFormats.js +1 -1
- package/lib/components/choosers/TMUserChooser.d.ts +2 -5
- package/lib/components/choosers/TMUserChooser.js +33 -47
- package/lib/components/editors/TMCheckBox.js +2 -0
- package/lib/components/editors/TMDateBox.js +18 -9
- package/lib/components/editors/TMEditorStyled.js +7 -0
- package/lib/components/editors/TMLocalizedTextBox.d.ts +3 -1
- package/lib/components/editors/TMLocalizedTextBox.js +16 -14
- package/lib/components/editors/TMMetadataEditor.d.ts +1 -0
- package/lib/components/editors/TMMetadataEditor.js +4 -4
- package/lib/components/editors/TMMetadataTextBox.d.ts +9 -0
- package/lib/components/editors/TMMetadataTextBox.js +92 -0
- package/lib/components/editors/TMMetadataValues.d.ts +2 -0
- package/lib/components/editors/TMMetadataValues.js +26 -8
- package/lib/components/editors/TMRadioButton.js +2 -0
- package/lib/components/editors/TMTextArea.js +18 -30
- package/lib/components/editors/TMTextBox.d.ts +1 -1
- package/lib/components/editors/TMTextBox.js +29 -4
- package/lib/components/editors/TMTextExpression.js +6 -91
- package/lib/components/features/archive/TMArchive.js +2 -2
- package/lib/components/features/assistant/TMToppyDraggableHelpCenter.d.ts +15 -0
- package/lib/components/features/assistant/TMToppyDraggableHelpCenter.js +462 -0
- package/lib/components/features/assistant/TMToppySpeechBubble.d.ts +11 -0
- package/lib/components/features/assistant/TMToppySpeechBubble.js +126 -0
- package/lib/components/features/documents/TMDcmtBlog.js +1 -1
- package/lib/components/features/documents/TMDcmtForm.d.ts +14 -2
- package/lib/components/features/documents/TMDcmtForm.js +576 -292
- package/lib/components/features/documents/TMDcmtPreview.js +42 -155
- package/lib/components/features/documents/TMDcmtTasks.js +9 -9
- package/lib/components/features/documents/TMMasterDetailDcmts.js +38 -53
- package/lib/components/features/documents/TMRelationViewer.d.ts +1 -1
- package/lib/components/features/documents/TMRelationViewer.js +2 -2
- package/lib/components/features/search/TMDcmtCheckoutInfoForm.d.ts +8 -0
- package/lib/components/features/search/{TMSearchResultCheckoutInfoForm.js → TMDcmtCheckoutInfoForm.js} +2 -2
- package/lib/components/features/search/TMSavedQuerySelector.js +72 -67
- package/lib/components/features/search/TMSearch.d.ts +3 -0
- package/lib/components/features/search/TMSearch.js +50 -11
- package/lib/components/features/search/TMSearchQueryEditor.d.ts +1 -0
- package/lib/components/features/search/TMSearchQueryEditor.js +10 -10
- package/lib/components/features/search/TMSearchQueryPanel.d.ts +1 -0
- package/lib/components/features/search/TMSearchQueryPanel.js +40 -25
- package/lib/components/features/search/TMSearchResult.d.ts +3 -0
- package/lib/components/features/search/TMSearchResult.js +370 -252
- package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +3 -3
- package/lib/components/features/search/TMSearchResultsMenuItems.js +227 -171
- package/lib/components/features/search/TMSignSettingsForm.js +1 -1
- package/lib/components/features/search/TMSignatureInfoContent.d.ts +6 -0
- package/lib/components/features/search/TMSignatureInfoContent.js +140 -0
- package/lib/components/features/search/TMViewHistoryDcmt.js +47 -52
- package/lib/components/features/tasks/TMTaskForm.js +75 -25
- package/lib/components/features/tasks/TMTasksAgenda.d.ts +3 -1
- package/lib/components/features/tasks/TMTasksAgenda.js +48 -9
- package/lib/components/features/tasks/TMTasksCalendar.d.ts +2 -0
- package/lib/components/features/tasks/TMTasksCalendar.js +19 -7
- package/lib/components/features/tasks/TMTasksUtils.d.ts +2 -2
- package/lib/components/features/tasks/TMTasksUtils.js +57 -37
- package/lib/components/features/tasks/TMTasksView.js +28 -19
- package/lib/components/features/workflow/TMWorkflowPopup.d.ts +33 -2
- package/lib/components/features/workflow/TMWorkflowPopup.js +140 -34
- package/lib/components/features/workflow/diagram/DiagramItemComponent.d.ts +2 -0
- package/lib/components/features/workflow/diagram/DiagramItemComponent.js +14 -7
- package/lib/components/features/workflow/diagram/DiagramItemForm.js +1 -1
- package/lib/components/features/workflow/diagram/RecipientList.js +3 -2
- package/lib/components/features/workflow/diagram/WFDiagram.d.ts +4 -0
- package/lib/components/features/workflow/diagram/WFDiagram.js +164 -13
- package/lib/components/forms/Login/LoginValidatorService.d.ts +2 -0
- package/lib/components/forms/Login/LoginValidatorService.js +7 -2
- package/lib/components/forms/Login/TMLoginForm.js +35 -7
- package/lib/components/forms/TMChooserForm.js +1 -1
- package/lib/components/grids/TMBlogsPost.js +56 -31
- package/lib/components/grids/TMRecentsManager.js +20 -10
- package/lib/components/grids/TMValidationItemsList.js +6 -0
- package/lib/components/index.d.ts +6 -3
- package/lib/components/index.js +6 -3
- package/lib/components/layout/panelManager/TMPanelManagerContext.js +13 -5
- package/lib/components/query/TMQueryEditor.d.ts +6 -1
- package/lib/components/query/TMQueryEditor.js +105 -101
- package/lib/components/settings/SettingsAppearance.d.ts +2 -1
- package/lib/components/settings/SettingsAppearance.js +99 -30
- package/lib/components/sidebar/TMHeader.js +11 -7
- package/lib/components/sidebar/TMSidebar.d.ts +0 -1
- package/lib/components/sidebar/TMSidebar.js +16 -44
- package/lib/components/sidebar/TMSidebarItem.js +36 -17
- package/lib/components/viewers/TMDataListItemViewer.d.ts +2 -1
- package/lib/components/viewers/TMDataListItemViewer.js +35 -71
- package/lib/components/viewers/TMDataUserIdItemViewer.d.ts +8 -0
- package/lib/components/viewers/TMDataUserIdItemViewer.js +39 -0
- package/lib/css/tm-sdkui.css +1 -1
- package/lib/helper/SDKUI_Globals.d.ts +22 -0
- package/lib/helper/SDKUI_Globals.js +10 -1
- package/lib/helper/SDKUI_Localizator.d.ts +21 -3
- package/lib/helper/SDKUI_Localizator.js +196 -10
- package/lib/helper/TMCommandsContextMenu.d.ts +4 -2
- package/lib/helper/TMCommandsContextMenu.js +15 -4
- package/lib/helper/TMIcons.d.ts +4 -0
- package/lib/helper/TMIcons.js +13 -3
- package/lib/helper/TMPdfViewer.d.ts +8 -0
- package/lib/helper/TMPdfViewer.js +373 -0
- package/lib/helper/TMToppyMessage.js +4 -0
- package/lib/helper/checkinCheckoutManager.d.ts +31 -1
- package/lib/helper/checkinCheckoutManager.js +112 -30
- package/lib/helper/devextremeCustomMessages.d.ts +30 -0
- package/lib/helper/devextremeCustomMessages.js +30 -0
- package/lib/helper/helpers.d.ts +30 -2
- package/lib/helper/helpers.js +132 -4
- package/lib/helper/index.d.ts +2 -0
- package/lib/helper/index.js +2 -0
- package/lib/helper/queryHelper.d.ts +2 -2
- package/lib/helper/queryHelper.js +80 -24
- package/lib/helper/workItemsHelper.d.ts +6 -0
- package/lib/helper/workItemsHelper.js +230 -0
- package/lib/hooks/useCheckInOutOperations.d.ts +28 -0
- package/lib/hooks/useCheckInOutOperations.js +223 -0
- package/lib/hooks/useDataListItem.d.ts +12 -0
- package/lib/hooks/useDataListItem.js +132 -0
- package/lib/hooks/useDataUserIdItem.d.ts +10 -0
- package/lib/hooks/useDataUserIdItem.js +96 -0
- package/lib/hooks/useFloatingBarPinnedItems.d.ts +11 -0
- package/lib/hooks/useFloatingBarPinnedItems.js +54 -0
- package/lib/hooks/useMetadataExpression.d.ts +19 -0
- package/lib/hooks/useMetadataExpression.js +99 -0
- package/lib/hooks/useSettingsFeedback.d.ts +11 -0
- package/lib/hooks/useSettingsFeedback.js +38 -0
- package/lib/hooks/useWorkflowApprove.d.ts +4 -0
- package/lib/hooks/useWorkflowApprove.js +14 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +3 -2
- package/lib/services/platform_services.d.ts +3 -3
- package/lib/ts/types.d.ts +61 -1
- package/lib/utils/theme.d.ts +1 -1
- package/lib/utils/theme.js +1 -1
- package/package.json +6 -5
- package/lib/components/NewComponents/Notification/Notification.d.ts +0 -4
- package/lib/components/NewComponents/Notification/Notification.js +0 -60
- package/lib/components/NewComponents/Notification/NotificationContainer.d.ts +0 -8
- package/lib/components/NewComponents/Notification/NotificationContainer.js +0 -33
- package/lib/components/NewComponents/Notification/index.d.ts +0 -2
- package/lib/components/NewComponents/Notification/index.js +0 -2
- package/lib/components/NewComponents/Notification/styles.d.ts +0 -21
- package/lib/components/NewComponents/Notification/styles.js +0 -180
- package/lib/components/NewComponents/Notification/types.d.ts +0 -18
- package/lib/components/NewComponents/Notification/types.js +0 -1
- package/lib/components/base/TMContextMenu.d.ts +0 -25
- package/lib/components/base/TMContextMenu.js +0 -109
- package/lib/components/base/TMContextMenuOLD.d.ts +0 -26
- package/lib/components/base/TMContextMenuOLD.js +0 -56
- package/lib/components/base/TMFloatingToolbar.d.ts +0 -9
- package/lib/components/base/TMFloatingToolbar.js +0 -101
- package/lib/components/features/assistant/ToppyDraggableHelpCenter.d.ts +0 -30
- package/lib/components/features/assistant/ToppyDraggableHelpCenter.js +0 -482
- package/lib/components/features/assistant/ToppySpeechBubble.d.ts +0 -9
- package/lib/components/features/assistant/ToppySpeechBubble.js +0 -117
- package/lib/components/features/search/TMSearchResultCheckoutInfoForm.d.ts +0 -8
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
import { jsx as _jsx,
|
|
2
|
-
import { useState, useEffect, useCallback, useRef, useMemo } from 'react';
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useEffect, useCallback, useRef, useMemo, useLayoutEffect } from 'react';
|
|
3
3
|
import { DiagramItemTypes, ArrowSymbol } from './interfaces';
|
|
4
4
|
import { parseWfDiagramXml, serializeWfDiagramToXml } from './xmlParser';
|
|
5
5
|
import styled, { css, keyframes } from 'styled-components';
|
|
6
|
-
import { CultureIDs, DataListCacheService, SearchEngine, WFAppTypes, WorkItemStatus } from "@topconsultnpm/sdk-ts";
|
|
6
|
+
import { AppModules, CultureIDs, DataListCacheService, SDK_Globals, SearchEngine, WFAppTypes, WorkItemStatus } from "@topconsultnpm/sdk-ts";
|
|
7
7
|
import ConnectionComponent from './ConnectionComponent';
|
|
8
8
|
import DiagramItemComponent from './DiagramItemComponent';
|
|
9
9
|
import DiagramItemSvgContent from './DiagramItemSvgContent';
|
|
10
10
|
import { calculateArrowAngle, downloadFile, getConnectionPoint, getNewWfDiagram, isConnectionNonLinear, validateDiagram } from './workflowHelpers';
|
|
11
|
-
import { IconFlowChart, IconUndo, IconRestore, IconAdjust, IconCopy, IconCut, IconPaste, IconPin, IconUnpin, IconChevronRight, IconCloseOutline, IconNew, SDKUI_Localizator, generateUUID, IconExport, IconImport, IconWindowMaximize, IconZoomIn, IconZoomOut, IconPencil, IconLock, LocalizeDiagramItemType, IconWindowMinimize } from '../../../../helper';
|
|
11
|
+
import { IconFlowChart, IconUndo, IconRestore, IconAdjust, IconCopy, IconCut, IconPaste, IconPin, IconUnpin, IconChevronRight, IconCloseOutline, IconNew, SDKUI_Localizator, generateUUID, IconExport, IconImport, IconWindowMaximize, IconZoomIn, IconZoomOut, IconPencil, IconLock, LocalizeDiagramItemType, IconWindowMinimize, IconZoomAuto } from '../../../../helper';
|
|
12
12
|
import { ButtonNames, TMExceptionBoxManager, TMMessageBoxManager } from '../../../base/TMPopUp';
|
|
13
13
|
import { StyledLoadingContainer, StyledSpinner } from '../../../base/Styled';
|
|
14
14
|
import DiagramItemForm from './DiagramItemForm';
|
|
15
15
|
import ReactDOM from 'react-dom';
|
|
16
16
|
import ConnectionForm from './ConnectionForm';
|
|
17
|
+
import TMFloatingMenuBar from '../../../NewComponents/FloatingMenuBar';
|
|
17
18
|
const ZoomLevelText = styled.span `
|
|
18
19
|
font-size: 0.9em;
|
|
19
20
|
color: #555;
|
|
@@ -21,6 +22,7 @@ const ZoomLevelText = styled.span `
|
|
|
21
22
|
background-color: white;
|
|
22
23
|
padding: 2px 4px; /* Aggiunto un leggero padding per chiarezza */
|
|
23
24
|
border-radius: 4px;
|
|
25
|
+
width: 40px;
|
|
24
26
|
|
|
25
27
|
/* A. Modalità Compressa (non Floating & Collapsed) */
|
|
26
28
|
${props => !props.$isFloating && props.$isCollapsed
|
|
@@ -317,13 +319,15 @@ const DiagramMessage = styled.div `
|
|
|
317
319
|
color: #555;
|
|
318
320
|
text-align: center;
|
|
319
321
|
`;
|
|
320
|
-
const WFDiagram = ({ xmlDiagramString, currentSetID, allowEdit = true, onDiagramChange }) => {
|
|
322
|
+
const WFDiagram = ({ xmlDiagramString, currentSetID, allowEdit = true, onDiagramChange, workitems, defaultAutoZoom = false, onDiagramItemClick }) => {
|
|
321
323
|
const [isReadOnly, setIsReadOnly] = useState(true);
|
|
322
324
|
const [isFullScreen, setIsFullScreen] = useState(false);
|
|
323
325
|
const [zoomLevel, setZoomLevel] = useState(1);
|
|
324
326
|
const [translateX, setTranslateX] = useState(0);
|
|
325
327
|
const [translateY, setTranslateY] = useState(0);
|
|
328
|
+
const [isAutoZoomEnabled, setIsAutoZoomEnabled] = useState(defaultAutoZoom);
|
|
326
329
|
const [isLoading, setIsLoading] = useState(true);
|
|
330
|
+
const [isInitialZoomCalculated, setIsInitialZoomCalculated] = useState(!defaultAutoZoom);
|
|
327
331
|
const [wfDiagram, setWfDiagram] = useState(null);
|
|
328
332
|
const [selectedItems, setSelectedItems] = useState(new Set());
|
|
329
333
|
const [selectedConnections, setSelectedConnections] = useState(new Set());
|
|
@@ -333,11 +337,29 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, allowEdit = true, onDiagram
|
|
|
333
337
|
const initialDiagramRef = useRef(null);
|
|
334
338
|
const notifiedXmlRef = useRef(null);
|
|
335
339
|
const svgRef = useRef(null);
|
|
340
|
+
const containerRef = useRef(null);
|
|
336
341
|
const [isDrawingConnection, setIsDrawingConnection] = useState(false);
|
|
337
342
|
const [tempConnectionSource, setTempConnectionSource] = useState(null);
|
|
338
343
|
const [tempConnectionEnd, setTempConnectionEnd] = useState(null);
|
|
339
344
|
const [mouseDownPos, setMouseDownPos] = useState(null);
|
|
340
345
|
const [isDraggingExistingConnectionEndpoint, setIsDraggingExistingConnectionEndpoint] = useState(false);
|
|
346
|
+
// Helper function per ottenere il colore di sfondo basato sullo stato del workitem
|
|
347
|
+
const getWorkItemBackgroundColor = useCallback((setID) => {
|
|
348
|
+
if (!workitems || workitems.length === 0)
|
|
349
|
+
return undefined;
|
|
350
|
+
const workitem = workitems.find(wi => wi.setID === setID);
|
|
351
|
+
if (!workitem || !workitem.setStatus || workitem.setStatus.value === undefined)
|
|
352
|
+
return undefined;
|
|
353
|
+
const statusValue = typeof workitem.setStatus.value === 'number'
|
|
354
|
+
? workitem.setStatus.value
|
|
355
|
+
: parseInt(String(workitem.setStatus.value), 10);
|
|
356
|
+
switch (statusValue) {
|
|
357
|
+
case 0: return '#FFFACD'; // Giallo pastello (lemon chiffon) (nuovo)
|
|
358
|
+
case 1: return '#C8E6C9'; // Verde pastello (completato)
|
|
359
|
+
case -1: return '#FFCDD2'; // Rosso pastello (rifiutato)
|
|
360
|
+
default: return '#e0e0e0'; // Grigio di default
|
|
361
|
+
}
|
|
362
|
+
}, [workitems]);
|
|
341
363
|
const [draggingConnectionId, setDraggingConnectionId] = useState(null);
|
|
342
364
|
const [draggingEndpointType, setDraggingEndpointType] = useState(null);
|
|
343
365
|
const [draggingConnectionFixedPoint, setDraggingConnectionFixedPoint] = useState(null);
|
|
@@ -1236,6 +1258,12 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, allowEdit = true, onDiagram
|
|
|
1236
1258
|
setDraggedItemType(null);
|
|
1237
1259
|
}, [isDrawingConnection, tempConnectionSource, tempConnectionEnd, isDrawingSelectionRect, selectionRectStart, selectionRectEnd, wfDiagram, zoomLevel, translateX, translateY, isReadOnly, isDraggingExistingConnectionEndpoint, draggingConnectionId, draggingEndpointType, draggingConnectionFixedPoint]);
|
|
1238
1260
|
const handleDiagramItemClick = useCallback((id, event) => {
|
|
1261
|
+
// Se allowEdit è false e ci sono workitems, delega al parent se la callback è definita
|
|
1262
|
+
if (!allowEdit && workitems && workitems.length > 0 && onDiagramItemClick) {
|
|
1263
|
+
event.stopPropagation();
|
|
1264
|
+
onDiagramItemClick(id, event);
|
|
1265
|
+
return;
|
|
1266
|
+
}
|
|
1239
1267
|
if (isReadOnly)
|
|
1240
1268
|
return;
|
|
1241
1269
|
event.stopPropagation();
|
|
@@ -1258,7 +1286,7 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, allowEdit = true, onDiagram
|
|
|
1258
1286
|
});
|
|
1259
1287
|
if (!isCtrlPressed)
|
|
1260
1288
|
setSelectedConnections(new Set());
|
|
1261
|
-
}, [isReadOnly]);
|
|
1289
|
+
}, [isReadOnly, allowEdit, workitems, onDiagramItemClick]);
|
|
1262
1290
|
const handleConnectionClick = useCallback((id, event) => {
|
|
1263
1291
|
if (isReadOnly)
|
|
1264
1292
|
return;
|
|
@@ -1607,6 +1635,54 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, allowEdit = true, onDiagram
|
|
|
1607
1635
|
const handleZoomOut = useCallback(() => {
|
|
1608
1636
|
setZoomLevel(prev => Math.max(prev - 0.1, 0.5)); // Limite min a 0.5
|
|
1609
1637
|
}, []);
|
|
1638
|
+
const calculateOptimalZoom = useCallback(() => {
|
|
1639
|
+
if (!wfDiagram || !containerRef.current || wfDiagram.DiagramItems.length === 0) {
|
|
1640
|
+
return 1;
|
|
1641
|
+
}
|
|
1642
|
+
// Calcola il bounding box del diagramma
|
|
1643
|
+
let minX = Infinity;
|
|
1644
|
+
let minY = Infinity;
|
|
1645
|
+
let maxX = -Infinity;
|
|
1646
|
+
let maxY = -Infinity;
|
|
1647
|
+
wfDiagram.DiagramItems.forEach(item => {
|
|
1648
|
+
minX = Math.min(minX, item.Left);
|
|
1649
|
+
minY = Math.min(minY, item.Top);
|
|
1650
|
+
maxX = Math.max(maxX, item.Left + item.Width);
|
|
1651
|
+
maxY = Math.max(maxY, item.Top + item.Height + 50);
|
|
1652
|
+
});
|
|
1653
|
+
const padding = 100; // Padding intorno al diagramma
|
|
1654
|
+
const diagramWidth = maxX - minX + (padding * 2);
|
|
1655
|
+
const diagramHeight = maxY - minY + (padding * 2);
|
|
1656
|
+
// Ottieni le dimensioni del container
|
|
1657
|
+
const containerWidth = containerRef.current.clientWidth;
|
|
1658
|
+
const containerHeight = containerRef.current.clientHeight;
|
|
1659
|
+
// Calcola il fattore di zoom per far entrare tutto il contenuto
|
|
1660
|
+
const zoomX = containerWidth / diagramWidth;
|
|
1661
|
+
const zoomY = containerHeight / diagramHeight;
|
|
1662
|
+
// Usa il fattore più piccolo per garantire che tutto sia visibile
|
|
1663
|
+
let optimalZoom = Math.min(zoomX, zoomY, 2.0); // Max 2.0
|
|
1664
|
+
// Applica un minimo di 0.3 per evitare zoom troppo piccoli
|
|
1665
|
+
optimalZoom = Math.max(optimalZoom, 0.3);
|
|
1666
|
+
// Arrotonda per eccesso alla decina più vicina (in percentuale)
|
|
1667
|
+
const zoomPercentage = optimalZoom * 100;
|
|
1668
|
+
const roundedPercentage = Math.ceil(zoomPercentage / 10) * 10;
|
|
1669
|
+
// Limita al massimo 100%
|
|
1670
|
+
const finalPercentage = Math.min(roundedPercentage, 100);
|
|
1671
|
+
return finalPercentage / 100;
|
|
1672
|
+
}, [wfDiagram]);
|
|
1673
|
+
const handleToggleAutoZoom = useCallback(() => {
|
|
1674
|
+
setIsAutoZoomEnabled(prev => {
|
|
1675
|
+
const newValue = !prev;
|
|
1676
|
+
if (newValue) {
|
|
1677
|
+
// Se si attiva AutoZoom, calcola lo zoom ottimale, altrimenti mantieni il livello di zoom corrente
|
|
1678
|
+
const optimalZoom = calculateOptimalZoom();
|
|
1679
|
+
setZoomLevel(optimalZoom);
|
|
1680
|
+
setTranslateX(0);
|
|
1681
|
+
setTranslateY(0);
|
|
1682
|
+
}
|
|
1683
|
+
return newValue;
|
|
1684
|
+
});
|
|
1685
|
+
}, [calculateOptimalZoom]);
|
|
1610
1686
|
const formattedZoomLevel = useMemo(() => {
|
|
1611
1687
|
return `${Math.round(zoomLevel * 100)}%`;
|
|
1612
1688
|
}, [zoomLevel]);
|
|
@@ -1645,8 +1721,6 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, allowEdit = true, onDiagram
|
|
|
1645
1721
|
catch (error) {
|
|
1646
1722
|
console.error("Errore durante l'elaborazione del diagramma:", error);
|
|
1647
1723
|
setWfDiagram(null);
|
|
1648
|
-
}
|
|
1649
|
-
finally {
|
|
1650
1724
|
setIsLoading(false);
|
|
1651
1725
|
}
|
|
1652
1726
|
}, [xmlDiagramString, getAdjustedAndRecalculatedDiagram]);
|
|
@@ -1655,11 +1729,78 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, allowEdit = true, onDiagram
|
|
|
1655
1729
|
isUndoingRedoing.current = false;
|
|
1656
1730
|
}
|
|
1657
1731
|
}, [wfDiagram]);
|
|
1732
|
+
// useLayoutEffect viene eseguito PRIMA del paint del browser, evitando il flash visivo
|
|
1733
|
+
useLayoutEffect(() => {
|
|
1734
|
+
if (defaultAutoZoom && !isInitialZoomCalculated && wfDiagram && wfDiagram.DiagramItems.length > 0 && containerRef.current) {
|
|
1735
|
+
const container = containerRef.current;
|
|
1736
|
+
// Calcola il bounding box del diagramma
|
|
1737
|
+
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
1738
|
+
wfDiagram.DiagramItems.forEach(item => {
|
|
1739
|
+
minX = Math.min(minX, item.Left);
|
|
1740
|
+
minY = Math.min(minY, item.Top);
|
|
1741
|
+
maxX = Math.max(maxX, item.Left + item.Width);
|
|
1742
|
+
maxY = Math.max(maxY, item.Top + item.Height + 50);
|
|
1743
|
+
});
|
|
1744
|
+
const padding = 100;
|
|
1745
|
+
const diagramWidth = maxX - minX + (padding * 2);
|
|
1746
|
+
const diagramHeight = maxY - minY + (padding * 2);
|
|
1747
|
+
const containerWidth = container.clientWidth;
|
|
1748
|
+
const containerHeight = container.clientHeight;
|
|
1749
|
+
if (containerWidth > 0 && containerHeight > 0) {
|
|
1750
|
+
const zoomX = containerWidth / diagramWidth;
|
|
1751
|
+
const zoomY = containerHeight / diagramHeight;
|
|
1752
|
+
let optimalZoom = Math.min(zoomX, zoomY, 2.0);
|
|
1753
|
+
optimalZoom = Math.max(optimalZoom, 0.3);
|
|
1754
|
+
const zoomPercentage = optimalZoom * 100;
|
|
1755
|
+
const roundedPercentage = Math.ceil(zoomPercentage / 10) * 10;
|
|
1756
|
+
const finalPercentage = Math.min(roundedPercentage, 100);
|
|
1757
|
+
setZoomLevel(finalPercentage / 100);
|
|
1758
|
+
setIsInitialZoomCalculated(true);
|
|
1759
|
+
setIsLoading(false);
|
|
1760
|
+
}
|
|
1761
|
+
else {
|
|
1762
|
+
// Se il container non ha dimensioni, riprova al prossimo render
|
|
1763
|
+
requestAnimationFrame(() => {
|
|
1764
|
+
setIsInitialZoomCalculated(false);
|
|
1765
|
+
});
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1768
|
+
else if (!defaultAutoZoom && wfDiagram && isLoading) {
|
|
1769
|
+
// Se non c'è autozoom, rimuovi il loading appena il diagramma è pronto
|
|
1770
|
+
setIsLoading(false);
|
|
1771
|
+
}
|
|
1772
|
+
}, [wfDiagram, defaultAutoZoom, isInitialZoomCalculated, isLoading]);
|
|
1773
|
+
// Gestisce AutoZoom: ricalcola lo zoom quando il diagramma cambia o il container viene ridimensionato
|
|
1774
|
+
useEffect(() => {
|
|
1775
|
+
if (!containerRef.current || !isAutoZoomEnabled || !isInitialZoomCalculated) {
|
|
1776
|
+
return;
|
|
1777
|
+
}
|
|
1778
|
+
// Funzione per ricalcolare e applicare lo zoom se necessario
|
|
1779
|
+
const updateZoom = () => {
|
|
1780
|
+
if (wfDiagram && wfDiagram.DiagramItems.length > 0) {
|
|
1781
|
+
const newZoom = calculateOptimalZoom();
|
|
1782
|
+
if (newZoom !== undefined && Math.abs(zoomLevel - newZoom) > 0.001) {
|
|
1783
|
+
setZoomLevel(newZoom);
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1786
|
+
};
|
|
1787
|
+
// Ricalcola lo zoom quando il diagramma cambia
|
|
1788
|
+
updateZoom();
|
|
1789
|
+
// Installa ResizeObserver per reagire ai ridimensionamenti del container
|
|
1790
|
+
const container = containerRef.current;
|
|
1791
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
1792
|
+
updateZoom();
|
|
1793
|
+
});
|
|
1794
|
+
resizeObserver.observe(container);
|
|
1795
|
+
return () => {
|
|
1796
|
+
resizeObserver.disconnect();
|
|
1797
|
+
};
|
|
1798
|
+
}, [isAutoZoomEnabled, wfDiagram, calculateOptimalZoom, isInitialZoomCalculated, zoomLevel]);
|
|
1658
1799
|
const handleCanvasDoubleClick = useCallback((event) => {
|
|
1659
|
-
if (isReadOnly) {
|
|
1800
|
+
if (isReadOnly && allowEdit) {
|
|
1660
1801
|
toggleReadOnlyMode();
|
|
1661
1802
|
}
|
|
1662
|
-
}, [isReadOnly, toggleReadOnlyMode]);
|
|
1803
|
+
}, [isReadOnly, allowEdit, toggleReadOnlyMode]);
|
|
1663
1804
|
const handleFullScreenKeyDown = useCallback((event) => {
|
|
1664
1805
|
if (event.key === 'Escape') {
|
|
1665
1806
|
// Blocca sempre la propagazione per evitare che TMSaveForm riceva l'evento
|
|
@@ -1672,6 +1813,7 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, allowEdit = true, onDiagram
|
|
|
1672
1813
|
}
|
|
1673
1814
|
}, [isModalOpen, isConnectionModalOpen]);
|
|
1674
1815
|
const fullScreenRef = useRef(null);
|
|
1816
|
+
const diagramRef = useRef(null);
|
|
1675
1817
|
// Gestione focus automatico quando si entra in fullscreen
|
|
1676
1818
|
useEffect(() => {
|
|
1677
1819
|
if (isFullScreen && fullScreenRef.current) {
|
|
@@ -1679,8 +1821,18 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, allowEdit = true, onDiagram
|
|
|
1679
1821
|
}
|
|
1680
1822
|
}, [isFullScreen]);
|
|
1681
1823
|
const diagramContent = (_jsxs(CanvasContainer, { onDoubleClick: handleCanvasDoubleClick, children: [_jsx("input", { ref: fileInputRef, type: "file", accept: ".xml" // Filtra per file XML
|
|
1682
|
-
, onChange: handleFileChange, style: { display: 'none' } }),
|
|
1683
|
-
|
|
1824
|
+
, onChange: handleFileChange, style: { display: 'none' } }), SDK_Globals.tmSession?.SessionDescr?.appModuleID === AppModules.SURFER ?
|
|
1825
|
+
_jsx(TMFloatingMenuBar, { containerRef: diagramRef, defaultPosition: { x: 45, y: 85 }, enableConfigMode: false, fixedItems: [
|
|
1826
|
+
{ icon: _jsx(IconZoomIn, {}), name: SDKUI_Localizator.ZoomIn, disabled: isAutoZoomEnabled, onClick: () => { handleZoomIn(); }, id: 'zoom-in', isPinned: true },
|
|
1827
|
+
{ icon: _jsx(IconZoomOut, {}), name: SDKUI_Localizator.ZoomOut, disabled: isAutoZoomEnabled, onClick: () => { handleZoomOut(); }, id: 'zoom-out', isPinned: true },
|
|
1828
|
+
{ icon: _jsx(IconZoomAuto, {}), name: 'AutoZoom', onClick: () => { handleToggleAutoZoom(); }, id: 'zoom-auto', isPinned: true, isToggle: isAutoZoomEnabled },
|
|
1829
|
+
{ icon: _jsx(_Fragment, {}), name: 'Zoom Level', onClick: () => { }, id: 'zoom-level', isPinned: true, staticItem: _jsx(ZoomLevelText, { "$isFloating": isToolbarFloating, "$isCollapsed": isToolbarCollapsed, children: formattedZoomLevel }) }
|
|
1830
|
+
], isConstrained: true }) :
|
|
1831
|
+
_jsxs(ToolbarContainer, { "$isCollapsed": isToolbarCollapsed, "$isFloating": isToolbarFloating, "$isToolboxVisible": isToolboxVisible, "$isReadOnly": isReadOnly, children: [allowEdit && _jsx(ButtonGroup, { "$isFloating": isToolbarFloating, children: _jsxs("button", { onClick: toggleReadOnlyMode, title: isReadOnly ? SDKUI_Localizator.Design : SDKUI_Localizator.ReadOnly, children: [isReadOnly ? _jsx(IconPencil, {}) : _jsx(IconLock, {}), !isToolbarCollapsed && _jsx("span", { children: isReadOnly ? SDKUI_Localizator.Design : SDKUI_Localizator.ReadOnly })] }) }), allowEdit && _jsxs(ButtonGroup, { "$isFloating": isToolbarFloating, children: [!isReadOnly && _jsxs("button", { onClick: handleToggleToolboxVisibility, title: SDKUI_Localizator.ShowToolbox, children: [_jsx(IconFlowChart, {}), !isToolbarCollapsed && _jsx("span", { children: SDKUI_Localizator.ShowToolboxToggle })] }), _jsxs("button", { onClick: toggleFullScreenMode, title: SDKUI_Localizator.ShowFullScreen, children: [isFullScreen ? _jsx(IconWindowMinimize, {}) : _jsx(IconWindowMaximize, {}), !isToolbarCollapsed && _jsx("span", { children: SDKUI_Localizator.ShowFullScreen })] })] }), _jsxs(ButtonGroup, { "$isFloating": isToolbarFloating, children: [_jsxs("button", { onClick: handleZoomIn, title: SDKUI_Localizator.ZoomIn, disabled: isAutoZoomEnabled, children: [_jsx(IconZoomIn, {}), !isToolbarCollapsed && _jsx("span", { children: SDKUI_Localizator.ZoomIn })] }), _jsxs("button", { onClick: handleZoomOut, title: SDKUI_Localizator.ZoomOut, disabled: isAutoZoomEnabled, children: [_jsx(IconZoomOut, {}), !isToolbarCollapsed && _jsx("span", { children: SDKUI_Localizator.ZoomOut })] }), _jsxs("button", { onClick: handleToggleAutoZoom, title: "AutoZoom", style: { backgroundColor: isAutoZoomEnabled ? '#66b3ff' : undefined }, children: [_jsx(IconZoomAuto, {}), !isToolbarCollapsed && _jsx("span", { children: "AutoZoom" })] }), _jsx(ZoomLevelText, { "$isFloating": isToolbarFloating, "$isCollapsed": isToolbarCollapsed, children: formattedZoomLevel })] }), !isReadOnly && _jsxs(ButtonGroup, { "$isFloating": isToolbarFloating, children: [_jsxs("button", { onClick: handleUndo, disabled: historyIndex === 0, title: SDKUI_Localizator.Undo, children: [_jsx(IconUndo, {}), " ", !isToolbarCollapsed && _jsx("span", { children: SDKUI_Localizator.Undo })] }), _jsxs("button", { onClick: handleRedo, disabled: historyIndex === wfDiagramHistory.length - 1, title: SDKUI_Localizator.Redo, children: [_jsx(IconUndo, { style: { transform: 'scaleX(-1)' } }), " ", !isToolbarCollapsed && _jsx("span", { children: SDKUI_Localizator.Redo })] }), _jsxs("button", { onClick: handleRestore, title: SDKUI_Localizator.Restore, children: [_jsx(IconRestore, {}), " ", !isToolbarCollapsed && _jsx("span", { children: SDKUI_Localizator.Restore })] }), _jsxs("button", { onClick: handleNew, title: SDKUI_Localizator.DiagramNew, disabled: isReadOnly, children: [_jsx(IconNew, {}), " ", !isToolbarCollapsed && _jsx("span", { children: SDKUI_Localizator.DiagramNew })] }), _jsxs("button", { onClick: handleExportDiagram, disabled: isReadOnly || !wfDiagram, title: SDKUI_Localizator.Export, children: [_jsx(IconExport, {}), _jsx("span", { children: SDKUI_Localizator.Export })] }), _jsxs("button", { onClick: handleImportDiagramClick, disabled: isReadOnly, title: SDKUI_Localizator.Import, children: [_jsx(IconImport, {}), _jsx("span", { children: SDKUI_Localizator.Import })] })] }), !isReadOnly && _jsx(ButtonGroup, { "$isFloating": isToolbarFloating, children: _jsxs("button", { onClick: handleAutoAdjust, title: SDKUI_Localizator.AutoAdjust, children: [_jsx(IconAdjust, {}), " ", !isToolbarCollapsed && _jsx("span", { children: SDKUI_Localizator.AutoAdjust })] }) }), !isReadOnly && _jsxs(ButtonGroup, { "$isFloating": isToolbarFloating, children: [_jsxs("button", { onClick: handleCopy, disabled: selectedItems.size === 0, title: SDKUI_Localizator.Copy, children: [_jsx(IconCopy, {}), " ", !isToolbarCollapsed && _jsx("span", { children: SDKUI_Localizator.Copy })] }), _jsxs("button", { onClick: handleCut, disabled: selectedItems.size === 0, title: SDKUI_Localizator.Cut, children: [_jsx(IconCut, {}), " ", !isToolbarCollapsed && _jsx("span", { children: SDKUI_Localizator.Cut })] }), _jsxs("button", { onClick: handlePaste, disabled: copiedItems.length === 0 && copiedConnections.length === 0, title: SDKUI_Localizator.Paste, children: [_jsx(IconPaste, {}), " ", !isToolbarCollapsed && _jsx("span", { children: SDKUI_Localizator.Paste })] })] }), allowEdit && _jsxs("button", { onClick: handleToggleToolbarMode, title: isToolbarFloating ? SDKUI_Localizator.ToolbarDock : SDKUI_Localizator.ToolbarFloat, children: [isToolbarFloating ? _jsx(IconPin, {}) : _jsx(IconUnpin, {}), !isToolbarCollapsed && !isToolbarFloating && _jsx("span", { children: SDKUI_Localizator.ToggleMode })] }), !isToolbarFloating && _jsx(ToolbarToggle, { onClick: () => setIsToolbarCollapsed(!isToolbarCollapsed), title: isToolbarCollapsed ? SDKUI_Localizator.ToolbarExpand : SDKUI_Localizator.ToolbarCollapse, children: isToolbarCollapsed ? _jsx(IconChevronRight, {}) : _jsx(IconCloseOutline, {}) })] }), !isReadOnly && (_jsx(ToolboxContainer, { "$isVisible": isToolboxVisible, children: isToolboxVisible && availableItemTypes.map(type => (_jsxs(ToolboxItem, { draggable: true, onDragStart: (e) => handleToolboxDragStart(e, type), onDragEnd: handleToolboxDragEnd, children: [_jsx(ToolboxIconWrapper, { children: _jsx(DiagramItemSvgContent, { itemType: type, width: 38, height: 38, isToolboxPreview: true }) }), _jsx("span", { children: LocalizeDiagramItemType(type) })] }, type))) })), _jsx(SvgScrollContainer, { ref: containerRef, children: isLoading ?
|
|
1832
|
+
(_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, style: {
|
|
1833
|
+
opacity: (defaultAutoZoom && !isInitialZoomCalculated) ? 0 : 1,
|
|
1834
|
+
transition: 'opacity 0.15s ease-in'
|
|
1835
|
+
}, children: _jsxs(ScalableGroup, { "$scale": zoomLevel, "$translateX": translateX, "$translateY": translateY, children: [wfDiagram?.DiagramItems.map(item => (_jsx(DiagramItemComponent, { wf: wfDiagram?.Info, readOnly: isReadOnly, allowItemClick: !allowEdit && workitems && workitems.length > 0 && !!onDiagramItemClick, 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, backgroundColor: getWorkItemBackgroundColor(item.ID) }, item.ID))), calculatedConnections.map(connection => {
|
|
1684
1836
|
const sourceItem = wfDiagram?.DiagramItems.find(item => item.ID === connection.Source.ParentDiagramItem.ID);
|
|
1685
1837
|
const sinkItem = wfDiagram?.DiagramItems.find(item => item.ID === connection.Sink.ParentDiagramItem.ID);
|
|
1686
1838
|
if (!sourceItem || !sinkItem)
|
|
@@ -1692,7 +1844,6 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, allowEdit = true, onDiagram
|
|
|
1692
1844
|
const isThisConnectionBeingDragged = isDraggingExistingConnectionEndpoint && draggingConnectionId === connection.ID;
|
|
1693
1845
|
return (_jsx(ConnectionComponent, { connection: connection, isSelected: selectedConnections.has(connection.ID), sourcePoint: sourcePoint, sinkPoint: sinkPoint, isTemporary: isThisConnectionBeingDragged, onClick: handleConnectionClick, onDoubleClick: handleDoubleClickConnection, onConnectionEndpointMouseDown: handleConnectionEndpointMouseDown }, connection.ID));
|
|
1694
1846
|
}), 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, wf: wfDiagram?.Info, onClose: handleCloseModal, onApply: handleUpdateDiagramItem })), isConnectionModalOpen && connectionToEdit && (_jsx(ConnectionForm, { connectionToEdit: connectionToEdit, onClose: () => setIsConnectionModalOpen(false), onApply: handleUpdateConnection }))] }));
|
|
1695
|
-
const diagramRef = useRef(null);
|
|
1696
1847
|
return (_jsxs(_Fragment, { children: [!isFullScreen && (_jsx(DiagramWrapper, { ref: diagramRef, children: diagramContent })), isFullScreen && ReactDOM.createPortal(_jsx(FullScreenContainer, { ref: fullScreenRef, tabIndex: 0, onKeyDown: handleFullScreenKeyDown, children: diagramContent }), document.body)] }));
|
|
1697
1848
|
};
|
|
1698
1849
|
export default WFDiagram;
|
|
@@ -3,6 +3,8 @@ import { TMEndpointsType } from './TMLoginForm';
|
|
|
3
3
|
export interface LoginData {
|
|
4
4
|
endpoint: TMEndpointsType;
|
|
5
5
|
dcmtArchive: ArchiveDescriptor;
|
|
6
|
+
manualArchiveID?: string;
|
|
7
|
+
hasArchives?: boolean;
|
|
6
8
|
authenticationMode: AuthenticationModes;
|
|
7
9
|
username?: string;
|
|
8
10
|
password?: string;
|
|
@@ -27,8 +27,13 @@ export class LoginValidator {
|
|
|
27
27
|
if (!data.endpoint?.Description?.trim()) {
|
|
28
28
|
addError("endpoint", SDKUI_Localizator.RequiredField);
|
|
29
29
|
}
|
|
30
|
-
if (
|
|
31
|
-
|
|
30
|
+
if (data.hasArchives) {
|
|
31
|
+
if (!data.dcmtArchive?.description?.trim()) {
|
|
32
|
+
addError("dcmtArchive", SDKUI_Localizator.RequiredField);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
else if (!data.manualArchiveID?.trim()) {
|
|
36
|
+
addError("manualArchiveID", SDKUI_Localizator.RequiredField);
|
|
32
37
|
}
|
|
33
38
|
if (!data.authenticationMode || data.authenticationMode === AuthenticationModes.None) {
|
|
34
39
|
addError("authenticationMode", SDKUI_Localizator.RequiredField);
|
|
@@ -8,6 +8,7 @@ import frMessages from "devextreme/localization/messages/fr.json";
|
|
|
8
8
|
import itMessages from "devextreme/localization/messages/it.json";
|
|
9
9
|
import ptMessages from "devextreme/localization/messages/pt.json";
|
|
10
10
|
import { locale as dxlocale, loadMessages } from "devextreme/localization";
|
|
11
|
+
import { devextremeCustomMessages } from "../../../helper/devextremeCustomMessages";
|
|
11
12
|
import styled from "styled-components";
|
|
12
13
|
import Menu from "./Menu";
|
|
13
14
|
import TextBox from "./TextBox";
|
|
@@ -81,6 +82,7 @@ export const useCultureID = ({ cultureID = CultureIDs.It_IT }) => {
|
|
|
81
82
|
loadMessages(frMessages);
|
|
82
83
|
loadMessages(itMessages);
|
|
83
84
|
loadMessages(ptMessages);
|
|
85
|
+
loadMessages(devextremeCustomMessages); // Fix traduzioni mancanti in DevExtreme
|
|
84
86
|
}, []);
|
|
85
87
|
return (currentCultureID);
|
|
86
88
|
};
|
|
@@ -111,6 +113,7 @@ const TMLoginForm = (props) => {
|
|
|
111
113
|
const [showCultureIDs, setShowCultureIDs] = useState(false);
|
|
112
114
|
const [dcmtArchives, setDcmtArchives] = useState([]);
|
|
113
115
|
const [dcmtArchive, setDcmtArchive] = useState();
|
|
116
|
+
const [manualArchiveID, setManualArchiveID] = useState('');
|
|
114
117
|
const [authMode, setAuthMode] = useState(AuthenticationModes.TopMedia);
|
|
115
118
|
const [username, setUsername] = useState('SysAdmin');
|
|
116
119
|
const [password, setPassword] = useState('');
|
|
@@ -131,6 +134,8 @@ const TMLoginForm = (props) => {
|
|
|
131
134
|
authenticationMode: authMode,
|
|
132
135
|
cultureID: props.cultureID ?? CultureIDs.It_IT,
|
|
133
136
|
dcmtArchive: dcmtArchive,
|
|
137
|
+
manualArchiveID: manualArchiveID,
|
|
138
|
+
hasArchives: dcmtArchives.length > 0,
|
|
134
139
|
endpoint: endpoint,
|
|
135
140
|
authDomain: authDomain,
|
|
136
141
|
authDomainOnBehalfOf: authDomain,
|
|
@@ -142,7 +147,7 @@ const TMLoginForm = (props) => {
|
|
|
142
147
|
username: username,
|
|
143
148
|
usernameOnBehalfOf: usernameOnBehalf
|
|
144
149
|
};
|
|
145
|
-
}, [authMode, props.cultureID, dcmtArchive, endpoint, authDomain, otpCode, password, passwordOnBehalf, saveLoginName, saveLoginEnable, username, usernameOnBehalf]);
|
|
150
|
+
}, [authMode, props.cultureID, dcmtArchive, manualArchiveID, dcmtArchives.length, endpoint, authDomain, otpCode, password, passwordOnBehalf, saveLoginName, saveLoginEnable, username, usernameOnBehalf]);
|
|
146
151
|
const inputRefs = useMemo(() => {
|
|
147
152
|
switch (authMode) {
|
|
148
153
|
case AuthenticationModes.TopMedia:
|
|
@@ -259,7 +264,7 @@ const TMLoginForm = (props) => {
|
|
|
259
264
|
{ value: AuthenticationModes.TopMediaWithMFA, display: LOGINLocalizator.TopMediaWithMFA },
|
|
260
265
|
{ value: AuthenticationModes.TopMediaOnBehalfOf, display: SDKUI_Localizator.AuthMode_OnBehalfOf },
|
|
261
266
|
{ value: AuthenticationModes.WindowsThroughTopMedia, display: SDKUI_Localizator.AuthMode_WindowsViaTopMedia },
|
|
262
|
-
{ value: AuthenticationModes.MSAzure, display: '
|
|
267
|
+
{ value: AuthenticationModes.MSAzure, display: 'Microsoft Entra ID' }];
|
|
263
268
|
}, [props.cultureID]);
|
|
264
269
|
const accessPointAdditionalIcons = useMemo(() => {
|
|
265
270
|
return [
|
|
@@ -302,7 +307,7 @@ const TMLoginForm = (props) => {
|
|
|
302
307
|
}, []);
|
|
303
308
|
const disableContinueBtn = useMemo(() => {
|
|
304
309
|
switch (loginStep) {
|
|
305
|
-
case 1: return fieldValidations('endpoint').length > 0 || fieldValidations('dcmtArchive').length > 0;
|
|
310
|
+
case 1: return fieldValidations('endpoint').length > 0 || fieldValidations('dcmtArchive').length > 0 || fieldValidations('manualArchiveID').length > 0;
|
|
306
311
|
case 2: return fieldValidations('authenticationMode').length > 0 || fieldValidations('username').length > 0 || fieldValidations('password').length > 0;
|
|
307
312
|
default: return false;
|
|
308
313
|
}
|
|
@@ -321,8 +326,13 @@ const TMLoginForm = (props) => {
|
|
|
321
326
|
return tmSession;
|
|
322
327
|
}, [endpoint, username, dcmtArchive]);
|
|
323
328
|
const nextStepHandler = async () => {
|
|
324
|
-
if (!endpoint || !dcmtArchive)
|
|
329
|
+
if (!endpoint || (!dcmtArchive && !manualArchiveID))
|
|
325
330
|
return;
|
|
331
|
+
if (loginStep === 1 && !dcmtArchive && manualArchiveID) {
|
|
332
|
+
const isValid = await validateManualArchiveAsync();
|
|
333
|
+
if (!isValid)
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
326
336
|
if (loginStep === 1) {
|
|
327
337
|
setLoginStep(2);
|
|
328
338
|
}
|
|
@@ -349,6 +359,23 @@ const TMLoginForm = (props) => {
|
|
|
349
359
|
return;
|
|
350
360
|
setLoginStep(prev => prev - 1);
|
|
351
361
|
}, [loginStep]);
|
|
362
|
+
const validateManualArchiveAsync = async () => {
|
|
363
|
+
if (!tmSession || !manualArchiveID)
|
|
364
|
+
return false;
|
|
365
|
+
try {
|
|
366
|
+
TMSpinner.show({ description: '' });
|
|
367
|
+
const archiveEngine = tmSession.NewArchiveEngine();
|
|
368
|
+
await archiveEngine.RetrieveAsync(manualArchiveID);
|
|
369
|
+
return true;
|
|
370
|
+
}
|
|
371
|
+
catch (e) {
|
|
372
|
+
TMExceptionBoxManager.show({ exception: e });
|
|
373
|
+
return false;
|
|
374
|
+
}
|
|
375
|
+
finally {
|
|
376
|
+
TMSpinner.hide();
|
|
377
|
+
}
|
|
378
|
+
};
|
|
352
379
|
const getArchivesAsync = async () => {
|
|
353
380
|
if (!tmSession)
|
|
354
381
|
return;
|
|
@@ -392,7 +419,7 @@ const TMLoginForm = (props) => {
|
|
|
392
419
|
const sdInput = {
|
|
393
420
|
authenticationMode: authMode,
|
|
394
421
|
appModuleID: props.appModule,
|
|
395
|
-
archiveID: dcmtArchive?.id,
|
|
422
|
+
archiveID: dcmtArchive?.id ?? (dcmtArchives.length === 0 && manualArchiveID ? manualArchiveID : undefined),
|
|
396
423
|
description: dcmtArchive?.description,
|
|
397
424
|
userName: username,
|
|
398
425
|
password: password,
|
|
@@ -594,7 +621,7 @@ const TMLoginForm = (props) => {
|
|
|
594
621
|
}
|
|
595
622
|
}, [SDK_Globals.appModule]);
|
|
596
623
|
return (_jsxs(StyledWrapper, { children: [!isMobile && _jsxs(StyledVersionContainer, { children: [_jsxs(StyledVersion, { children: [_jsxs(StyledVersionName, { children: [_jsx("span", { style: { color: TMColors.primary }, children: "\u25CF" }), SDK_Globals.appModule] }), _jsxs("p", { children: ["v.", SDK_Globals.appVersion] })] }), _jsxs(StyledVersion, { children: [_jsxs(StyledVersionName, { children: [_jsx("span", { style: { color: TMColors.tertiary }, children: "\u25CF" }), "SDKUI"] }), _jsxs("p", { children: ["v.", SDK_Globals.sdkuiVersion] })] }), _jsxs(StyledVersion, { children: [_jsxs(StyledVersionName, { children: [_jsx("span", { style: { color: TMColors.error }, children: "\u25CF" }), "SDK"] }), _jsxs("p", { children: ["v.", SDK_Globals.sdkVersion] })] })] }), _jsxs(StyledLoginContainer, { "$isMobile": isMobile, children: [_jsxs(StyledLeftSection, { "$isMobile": isMobile, "$isConnector": props.isConnector ?? false, children: [isMobile && _jsxs(StyledTopBar, { children: [_jsx(StyledTitle, { children: SDKUI_Localizator.WelcomeTo.replaceParams('') + ' ' + welcomeAppNameHeader + ' ' + 'v.' + SDK_Globals.appVersion }), _jsx(StyledMobileVersionIcon, { onClick: showVersionPopup, children: _jsx(IconInfo, { fontSize: 20, color: TMColors.primary }) })] }), _jsx(StyledOverlay, { "$isMobile": isMobile, children: _jsx(StyledCustomLogo, { style: { backgroundImage: `url(${showDefaultLogo ? 'logo-default.svg' : 'logo-custom.svg'})` } }) }), (windowHeight === WindowHeight.LARGE || !isMobile) && _jsxs(StyledPoweredByContainer, { "$isMobile": isMobile, children: [" ", showDefaultLogo ? 'Powered by TopConsult' : _jsx("img", { src: "/logo-default.svg", alt: "Logo", width: isMobile ? 50 : 100 }), " "] })] }), _jsxs(StyledRightSection, { "$isMobile": isMobile, children: [((((getDeviceType() === 'desktop' || isDesktop || isTablet) && windowHeight !== WindowHeight.SMALL)) && !isMobile) && _jsxs(StyledLogoContainer, { "$isMobile": isMobile, children: [_jsx(StyledWelcomeText, { children: SDKUI_Localizator.WelcomeTo.replaceParams('') }), _jsx(StyledLogo, { children: _jsx("img", { src: six, alt: "six", height: 50 }) }), _jsx(StyledWelcomeText, { children: welcomeAppName })] }), _jsxs(StyledToolbarContainer, { children: [_jsx(StyledLanguageChooser, { onClick: () => setShowCultureIDs(true), children: _jsx(TMTooltip, { content: SDKUI_Localizator.CultureID, children: _jsx("img", { src: getCultureIDImg(), alt: "Lang", width: 25, height: 25 }) }) }), loginStep !== 3 && _jsx(TMButton, { btnStyle: "icon", onClick: () => setShowRapidAccess(true), icon: _jsx(IconFastAccess, { fontSize: 20 }), caption: LOGINLocalizator.QuickAccess }), showPasswordOperations && _jsx(TMButton, { disabled: disablePasswordOperations, btnStyle: "icon", onClick: () => setShowChangePassword(true), icon: _jsx(IconPasswordOutline, { fontSize: 19 }), caption: SDKUI_Localizator.ChangePassword })] }), _jsxs(StyledFormContainer, { "$isMobile": isMobile, "$windowHeight": windowHeight, children: [loginStep === 1 &&
|
|
597
|
-
_jsxs(StyledStepContainer, { "$deviceType": deviceType, children: [_jsx(Chooser, { isDropDown: isDesktop, dataSource: props.endpoints, value: 'Description', columns: accessPointChooserColumns, additionalIcons: accessPointAdditionalIcons, icon: _jsx(IconAccessPoint, {}), label: SDKUI_Localizator.Endpoint, onSelectionChanged: (ep) => { setEndpoint(ep); setDcmtArchive(undefined); }, validationItems: fieldValidations('endpoint'), selectedRow: endpoint ?? undefined }), _jsx(Chooser, { isDropDown: isDesktop, dataSource: dcmtArchives, value: 'description', columns: dcmtArchiveChooserColumns, icon: _jsx(IconArchiveDoc, {}), label: SDKUI_Localizator.ArchiveID, onSelectionChanged: (arch) => setDcmtArchive(arch), validationItems: fieldValidations('dcmtArchive'), disabled: !endpoint, selectedRow: dcmtArchive ?? undefined })] }), loginStep === 2 &&
|
|
624
|
+
_jsxs(StyledStepContainer, { "$deviceType": deviceType, children: [_jsx(Chooser, { isDropDown: isDesktop, dataSource: props.endpoints, value: 'Description', columns: accessPointChooserColumns, additionalIcons: accessPointAdditionalIcons, icon: _jsx(IconAccessPoint, {}), label: SDKUI_Localizator.Endpoint, onSelectionChanged: (ep) => { setEndpoint(ep); setDcmtArchive(undefined); }, validationItems: fieldValidations('endpoint'), selectedRow: endpoint ?? undefined }), dcmtArchives.length > 0 ? (_jsx(Chooser, { isDropDown: isDesktop, dataSource: dcmtArchives, value: 'description', columns: dcmtArchiveChooserColumns, icon: _jsx(IconArchiveDoc, {}), label: SDKUI_Localizator.ArchiveID, onSelectionChanged: (arch) => setDcmtArchive(arch), validationItems: fieldValidations('dcmtArchive'), disabled: !endpoint, selectedRow: dcmtArchive ?? undefined })) : (_jsx(TextBox, { type: "text", icon: _jsx(IconArchiveDoc, {}), label: SDKUI_Localizator.ArchiveID, value: manualArchiveID, onValueChanged: (value) => setManualArchiveID(value), validationItems: fieldValidations('manualArchiveID'), disabled: !endpoint, placeHolder: 'Inserisci archivio' }))] }), loginStep === 2 &&
|
|
598
625
|
_jsxs(_Fragment, { children: [_jsxs(StyledSummaryContainer, { style: {
|
|
599
626
|
display: 'flex',
|
|
600
627
|
justifyContent: 'center',
|
|
@@ -604,7 +631,7 @@ const TMLoginForm = (props) => {
|
|
|
604
631
|
marginBottom: windowHeight === WindowHeight.SMALL ? '30px' : '25px',
|
|
605
632
|
width: '100%',
|
|
606
633
|
minHeight: '15px'
|
|
607
|
-
}, children: [_jsxs(StyledDescription, { children: [_jsx(TMTooltip, { content: SDKUI_Localizator.Endpoint, children: _jsx(IconAccessPoint, { color: TMColors.primary, fontSize: 16 }) }), _jsx(TMTooltip, { content: endpoint?.Description ?? '', children: _jsx("p", { children: endpoint?.Description && endpoint.Description.length > 20 ? endpoint.Description.substring(0, 20) + '...' : endpoint?.Description }) })] }), _jsxs(StyledDescription, { children: [_jsx(TMTooltip, { content: SDKUI_Localizator.ArchiveID, children: _jsx(IconArchiveDoc, { color: TMColors.primary, fontSize: 16 }) }), _jsx(TMTooltip, { content: dcmtArchive
|
|
634
|
+
}, children: [_jsxs(StyledDescription, { children: [_jsx(TMTooltip, { content: SDKUI_Localizator.Endpoint, children: _jsx(IconAccessPoint, { color: TMColors.primary, fontSize: 16 }) }), _jsx(TMTooltip, { content: endpoint?.Description ?? '', children: _jsx("p", { children: endpoint?.Description && endpoint.Description.length > 20 ? endpoint.Description.substring(0, 20) + '...' : endpoint?.Description }) })] }), _jsxs(StyledDescription, { children: [_jsx(TMTooltip, { content: SDKUI_Localizator.ArchiveID, children: _jsx(IconArchiveDoc, { color: TMColors.primary, fontSize: 16 }) }), _jsx(TMTooltip, { content: dcmtArchive ? (dcmtArchive.description ?? '') : manualArchiveID, children: _jsx(StyledArchiveText, { children: dcmtArchive ? (dcmtArchive.description ?? '') : manualArchiveID }) })] })] }), _jsxs(StyledStepContainer, { "$windowHeight": windowHeight, "$deviceType": deviceType, children: [_jsx(SelectBox, { value: authMode, options: authModeOptions, onValueChanged: (value) => setAuthMode(value), validationItems: fieldValidations('authenticationMode'), icon: _jsx(IconLogin, {}), label: SDKUI_Localizator.AuthMode }), _jsxs(StyledCredentialWrapper, { children: [authMode === AuthenticationModes.WindowsThroughTopMedia && _jsx(TextBox, { ref: authDomainRef, value: authDomain, onValueChanged: (e) => setAuthDomain(e), validationItems: fieldValidations('authDomain'), type: "text", icon: _jsx(IconWeb, {}), label: SDKUI_Localizator.Domain }), authMode !== AuthenticationModes.MSAzure && _jsx(CeredentialContainer, { isMobile: isMobile, ref: usernameRef, secondaryRef: passwordRef, usernameValidator: fieldValidations('username'), passwordValidator: fieldValidations('password'), authMode: authMode, username: username, password: password, onUsernameChanged: (un) => setUsername(un), onPasswordChanged: (ps) => setPassword(ps) }), authMode === AuthenticationModes.TopMediaOnBehalfOf &&
|
|
608
635
|
_jsxs(StyledCredentialWrapper, { children: [_jsx(TextBox, { value: authDomain, ref: authDomainRef, onValueChanged: (e) => setAuthDomain(e), validationItems: fieldValidations('authDomain'), type: "text", icon: _jsx(IconWeb, {}), label: SDKUI_Localizator.Domain }), _jsx(CeredentialContainer, { isMobile: isMobile, ref: usernameOnBehalfOfRef, secondaryRef: passwordOnBehalfOfRRef, usernameValidator: fieldValidations('usernameOnBehalfOf'), passwordValidator: fieldValidations('passwordOnBehalfOf'), authMode: AuthenticationModes.TopMediaOnBehalfOf, username: usernameOnBehalf, password: passwordOnBehalf, onUsernameChanged: (un) => setUsernameOnBehalf(un), onPasswordChanged: (ps) => setPasswordOnBehalf(ps) })] })] }), authMode !== AuthenticationModes.TopMediaWithMFA &&
|
|
609
636
|
_jsx(RapidAccessContainer, { isSaveEnable: saveLoginEnable, name: saveLoginName, nameValidationItems: fieldValidations('rapidAccessName'), onEnableSaveChange: () => setSaveLoginEnable(!saveLoginEnable), onNameChange: (name) => setSaveLoginName(name) })] })] }), loginStep === 3 &&
|
|
610
637
|
_jsxs(StyledStepThreeContainer, { "$isMobile": isMobile, children: [_jsx(OTPReader, { isMobile: isMobile, digits: otpCode, onChange: handleDigitChange, onFullChange: handleFullChange, text: _jsxs("div", { children: [" ", LOGINLocalizator.EnterOtpInstructions, " "] }), header: '', additionalButtons: [
|
|
@@ -703,6 +730,7 @@ const StyledLogo = styled.div ` display: flex; gap: 5px; align-items: center; `;
|
|
|
703
730
|
const StyledFormContainer = styled.div ` display: flex; flex-direction: column; padding: ${props => getPadding(props.$windowHeight, props.$isMobile)} ; align-items: center; justify-content: center; gap: 10px; width: 100%; height: fit-content; max-height: calc(100% - 100px); margin-top : ${props => !props.$isMobile && props.$windowHeight === WindowHeight.MEDIUM ? '70px' : '0'} ; `;
|
|
704
731
|
const StyledButtonContainer = styled.div ` display: flex; align-items: center; justify-content: center; padding: ${props => props.$windowHeight !== WindowHeight.SMALL ? '10px' : '0'}; width: 100%; margin-top: ${props => props.$windowHeight !== WindowHeight.SMALL ? '10px' : '0'}; `;
|
|
705
732
|
const StyledDescription = styled.div ` display: flex; align-items: center; gap: 2px; `;
|
|
733
|
+
const StyledArchiveText = styled.p ` max-width: 150px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; `;
|
|
706
734
|
const StyledRapidLoginSave = styled.div ` display: flex; flex-direction: column; width: 100%; gap: 2px; `;
|
|
707
735
|
const StyledForgetPassword = styled.div ` position: absolute; bottom: ${props => props.$isMobile ? '15px' : '25px'}; left: 50%; transform: translateX(-50%); font-size: 0.8rem; `;
|
|
708
736
|
const StyledBackButton = styled.div ` position: absolute; top: 20px; left: 20px; `;
|
|
@@ -88,7 +88,7 @@ const TMChooserForm = ({ children, title, allowMultipleSelection = false, allowA
|
|
|
88
88
|
}, [manageUseLocalizedName, summaryItems]);
|
|
89
89
|
return (_jsx(TMModal, { title: renderTitle(), width: width ?? '550px', height: height ?? '600px', toolbar: _jsx(ToolbarButtons, {}), onClose: onClose, children: children ??
|
|
90
90
|
filteredItems.length > 0
|
|
91
|
-
? _jsx(TMDataGrid, { dataSource: filteredItems, keyExpr: keyName, dataColumns: dataColumns, focusedRowKey: focusedRowKey, selectedRowKeys: selectedRowKeys,
|
|
91
|
+
? _jsx(TMDataGrid, { dataSource: filteredItems, keyExpr: keyName, dataColumns: dataColumns, focusedRowKey: focusedRowKey, selectedRowKeys: selectedRowKeys, searchPanelFocusTrigger: 1, headerFilter: { visible: true }, selection: { mode: allowMultipleSelection ? 'multiple' : 'single', showCheckBoxesMode: 'always', selectAllMode: 'allPages' }, grouping: allowGrouping ? { autoExpandAll: false, expandMode: 'rowClick' } : undefined, summary: customSummary, showFilterPanel: showFilterPanel, 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
|
};
|
|
94
94
|
export default TMChooserForm;
|