@topconsultnpm/sdkui-react 6.21.0-dev1.9 → 6.21.0-dev2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +2 -2
  2. package/lib/components/NewComponents/ContextMenu/styles.d.ts +43 -19
  3. package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.js +1 -1
  4. package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +79 -27
  5. package/lib/components/base/Styled.d.ts +76 -40
  6. package/lib/components/base/TMAreaManager.js +28 -11
  7. package/lib/components/base/TMFileManagerDataGridView.js +2 -2
  8. package/lib/components/base/TMFileManagerUtils.d.ts +6 -2
  9. package/lib/components/base/TMPanel.js +1 -0
  10. package/lib/components/base/TMTreeView.d.ts +5 -3
  11. package/lib/components/choosers/TMDataListItemChooser.js +56 -2
  12. package/lib/components/choosers/TMDynDataListItemChooser.d.ts +1 -1
  13. package/lib/components/choosers/TMDynDataListItemChooser.js +51 -23
  14. package/lib/components/editors/TMDropDown.js +2 -2
  15. package/lib/components/editors/TMEditorStyled.d.ts +42 -10
  16. package/lib/components/editors/TMFormulaEditor.js +15 -3
  17. package/lib/components/editors/TMMetadataEditor.js +4 -3
  18. package/lib/components/editors/TMMetadataValues.js +1 -1
  19. package/lib/components/features/archive/TMArchive.js +1 -1
  20. package/lib/components/features/documents/TMDcmtBlog.d.ts +1 -0
  21. package/lib/components/features/documents/TMDcmtBlog.js +2 -2
  22. package/lib/components/features/documents/TMDcmtForm.js +49 -21
  23. package/lib/components/features/documents/TMDcmtFormActionButtons.js +244 -60
  24. package/lib/components/features/documents/TMDcmtPreview.d.ts +5 -3
  25. package/lib/components/features/documents/TMDragDropOverlay.js +7 -2
  26. package/lib/components/features/documents/TMFileUploader.js +5 -4
  27. package/lib/components/features/documents/TMMasterDetailDcmts.js +25 -51
  28. package/lib/components/features/documents/TMRelationViewer.js +1 -0
  29. package/lib/components/features/search/TMSavedQuerySelector.js +1 -1
  30. package/lib/components/features/search/TMSearch.js +2 -0
  31. package/lib/components/features/search/TMSearchQueryEditor.js +13 -1
  32. package/lib/components/features/search/TMSearchQueryPanel.d.ts +3 -3
  33. package/lib/components/features/search/TMSearchResult.js +15 -2
  34. package/lib/components/features/search/TMViewHistoryDcmt.js +6 -0
  35. package/lib/components/features/workflow/TMWorkflowPopup.js +3 -0
  36. package/lib/components/features/workflow/diagram/DiagramItemForm.js +5 -1
  37. package/lib/components/features/workflow/diagram/WFDiagram.js +7 -1
  38. package/lib/components/features/workflow/diagram/WorkitemRecipientsEditor.d.ts +1 -1
  39. package/lib/components/features/workflow/diagram/xmlParser.js +13 -14
  40. package/lib/components/forms/Login/ChangePasswordInputs.d.ts +1 -1
  41. package/lib/components/forms/Login/TMLoginForm.js +15 -5
  42. package/lib/components/forms/TMChooserForm.js +25 -2
  43. package/lib/components/grids/TMBlogsPost.js +1 -1
  44. package/lib/components/index.d.ts +1 -0
  45. package/lib/components/index.js +1 -0
  46. package/lib/components/layout/panelManager/TMPanelManagerToolbar.d.ts +5 -2
  47. package/lib/components/pages/TMPage.js +4 -2
  48. package/lib/components/query/TMQueryCountButton.d.ts +11 -0
  49. package/lib/components/query/TMQueryCountButton.js +32 -0
  50. package/lib/components/query/TMQueryEditor.d.ts +10 -6
  51. package/lib/components/query/TMQueryEditor.js +42 -5
  52. package/lib/components/query/TMQuerySummary.js +3 -2
  53. package/lib/components/sidebar/TMCommandsPanel.d.ts +4 -2
  54. package/lib/components/viewers/TMDataListItemViewer.d.ts +2 -1
  55. package/lib/components/viewers/TMDataListItemViewer.js +2 -2
  56. package/lib/components/viewers/TMTidViewer.js +1 -1
  57. package/lib/helper/SDKUI_Globals.d.ts +2 -0
  58. package/lib/helper/SDKUI_Localizator.d.ts +1 -0
  59. package/lib/helper/SDKUI_Localizator.js +10 -0
  60. package/lib/helper/TMPdfViewer.js +143 -86
  61. package/lib/helper/TMUtils.d.ts +4 -9
  62. package/lib/helper/TMUtils.js +12 -74
  63. package/lib/helper/checkinCheckoutManager.d.ts +6 -1
  64. package/lib/helper/checkinCheckoutManager.js +203 -9
  65. package/lib/helper/helpers.js +8 -6
  66. package/lib/hooks/useCheckInOutOperations.d.ts +1 -1
  67. package/lib/hooks/useCheckInOutOperations.js +9 -4
  68. package/lib/hooks/useDcmtOperations.d.ts +1 -0
  69. package/lib/hooks/useDcmtOperations.js +75 -5
  70. package/lib/hooks/useDocumentOperations.js +17 -4
  71. package/lib/hooks/useForm.js +20 -14
  72. package/lib/hooks/useInputDialog.d.ts +2 -0
  73. package/lib/hooks/useInputDialog.js +37 -0
  74. package/lib/hooks/useQueryParametersDialog.js +5 -5
  75. package/lib/services/platform_services.d.ts +1 -1
  76. package/lib/services/platform_services.js +8 -0
  77. package/lib/ts/types.d.ts +1 -0
  78. package/package.json +11 -12
@@ -2,7 +2,6 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
3
  import styled from 'styled-components';
4
4
  import { IconFolderOpen, IconScanner, SDKUI_Localizator, formatBytes, IconClear, extensionHandler, IconCloseOutline, IconMenuVertical, TMCommandsContextMenu, IconEdit, isPdfEditorAvailable, SDKUI_Globals } from '../../../helper';
5
- import { useBetaFeatures } from '../../../hooks/useBetaFeatures';
6
5
  import usePreventFileDrop from '../../../hooks/usePreventFileDrop';
7
6
  import { FileExtensionHandler } from '../../../ts';
8
7
  import { TMColors } from '../../../utils/theme';
@@ -24,7 +23,6 @@ const isScannerLicenseConfigured = () => {
24
23
  }
25
24
  };
26
25
  const TMFileUploader = ({ fromDTD, deviceType = DeviceType.DESKTOP, onClose, onFileUpload, openFileUploaderPdfEditor, onScanRequest, isRequired = false, defaultBlob = null, isResizingActive, showTMPanel = true, enableDragDropOverlay = false, showScannerIcon = true }) => {
27
- const isBetaFeaturesEnabled = useBetaFeatures();
28
26
  const [dragOver, setDragOver] = useState(false);
29
27
  const [uploadedFile, setUploadedFile] = useState(defaultBlob);
30
28
  const [fileName, setFileName] = useState('');
@@ -54,7 +52,10 @@ const TMFileUploader = ({ fromDTD, deviceType = DeviceType.DESKTOP, onClose, onF
54
52
  };
55
53
  const handleDragOver = (e) => {
56
54
  e.preventDefault();
57
- setDragOver(true);
55
+ // Attiva solo se si trascina un file, non testo selezionato
56
+ if (e.dataTransfer?.types.includes('Files')) {
57
+ setDragOver(true);
58
+ }
58
59
  };
59
60
  const handleDragLeave = () => {
60
61
  setDragOver(false);
@@ -96,7 +97,7 @@ const TMFileUploader = ({ fromDTD, deviceType = DeviceType.DESKTOP, onClose, onF
96
97
  document.getElementById('fileInput')?.click();
97
98
  }, []);
98
99
  let content = !uploadedFile ?
99
- _jsxs("div", { style: { display: 'flex', gap: 10, width: '100%', height: '100%' }, children: [_jsx(HiddenInput, { id: "fileInput", type: "file", onChange: handleInputChange }), _jsxs(UploadContainer, { ref: uploaderRef, tabIndex: 0, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, style: { backgroundColor: dragOver ? '#76b1e6' : 'white' }, onDoubleClick: browseHandler, "$isRequired": isRequired, children: [_jsxs("div", { style: { display: 'flex', gap: '10px', flexDirection: 'column', position: 'absolute', right: 5, top: 5 }, children: [_jsx(TMButton, { btnStyle: 'icon', caption: 'Sfoglia', color: isRequired && !uploadedFile ? 'error' : 'primary', onClick: browseHandler, icon: _jsx(IconFolderOpen, { fontSize: 22 }) }), isBetaFeaturesEnabled && showScannerIcon && isScannerLicenseConfigured() && onScanRequest && _jsx(TMButton, { btnStyle: 'icon', caption: 'Scanner', color: 'primary', onClick: () => { onScanRequest((file) => { onFileUpload?.(file); }); }, icon: _jsx(IconScanner, { fontSize: 22 }) }), isBetaFeaturesEnabled && showScannerIcon && isScannerLicenseConfigured() && !onScanRequest && _jsx(TMButton, { btnStyle: 'icon', caption: 'Scanner', color: 'primary', onClick: () => { ShowAlert({ message: 'Funzionalità scanner non disponibile in questo contesto.', mode: 'info', duration: 3000, title: 'Scanner' }); }, icon: _jsx(IconScanner, { fontSize: 22 }) })] }), _jsx("p", { style: { fontSize: '1.2rem', fontWeight: 'bold' }, children: deviceType === DeviceType.MOBILE ? 'Clicca per sfogliare il tuo file' : 'Trascina il tuo file o fai doppio click per sfogliarlo' }), isRequired && _jsxs("p", { style: { fontWeight: 'bold' }, children: [" ", SDKUI_Localizator.RequiredField, " "] })] })] }) :
100
+ _jsxs("div", { style: { display: 'flex', gap: 10, width: '100%', height: '100%' }, children: [_jsx(HiddenInput, { id: "fileInput", type: "file", onChange: handleInputChange }), _jsxs(UploadContainer, { ref: uploaderRef, tabIndex: 0, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, style: { backgroundColor: dragOver ? '#76b1e6' : 'white' }, onDoubleClick: browseHandler, "$isRequired": isRequired, children: [_jsxs("div", { style: { display: 'flex', gap: '10px', flexDirection: 'column', position: 'absolute', right: 5, top: 5 }, children: [_jsx(TMButton, { btnStyle: 'icon', caption: 'Sfoglia', color: isRequired && !uploadedFile ? 'error' : 'primary', onClick: browseHandler, icon: _jsx(IconFolderOpen, { fontSize: 22 }) }), showScannerIcon && isScannerLicenseConfigured() && onScanRequest && _jsx(TMButton, { btnStyle: 'icon', caption: 'Scanner', color: 'primary', onClick: () => { onScanRequest((file) => { onFileUpload?.(file); }); }, icon: _jsx(IconScanner, { fontSize: 22 }) }), showScannerIcon && isScannerLicenseConfigured() && !onScanRequest && _jsx(TMButton, { btnStyle: 'icon', caption: 'Scanner', color: 'primary', onClick: () => { ShowAlert({ message: SDKUI_Localizator.ScanFeatureUnavailableInThisContext, mode: 'info', duration: 3000, title: 'Scanner' }); }, icon: _jsx(IconScanner, { fontSize: 22 }) })] }), _jsx("p", { style: { fontSize: '1.2rem', fontWeight: 'bold' }, children: deviceType === DeviceType.MOBILE ? 'Clicca per sfogliare il tuo file' : 'Trascina il tuo file o fai doppio click per sfogliarlo' }), isRequired && _jsxs("p", { style: { fontWeight: 'bold' }, children: [" ", SDKUI_Localizator.RequiredField, " "] })] })] }) :
100
101
  _jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 10, width: '100%', height: '100%' }, children: [_jsxs("div", { style: { backgroundColor: 'white', padding: '5px 10px', borderRadius: 8, display: 'flex', alignItems: 'center', justifyContent: 'space-between', color: TMColors.primaryColor }, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 5 }, children: [_jsx("p", { children: "File name:" }), _jsxs("div", { style: { fontWeight: 'bold' }, children: [fileName, " ", _jsxs("span", { children: [" ", ` (${formatBytes(fileSize)})`, " "] })] })] }), uploadedFile && _jsx(TMButton, { btnStyle: 'icon', color: 'error', caption: 'Pulisci', onClick: () => clearFile(true), icon: _jsx(IconClear, { fontSize: 22 }) })] }), extensionHandler(fileExt) === FileExtensionHandler.READY_TO_SHOW ? _jsx(TMFileViewer, { fileBlob: uploadedFile, isResizingActive: isResizingActive }) :
101
102
  _jsx("div", { style: { backgroundColor: '#f6dbdb', padding: '5px 10px', borderRadius: 8, display: 'flex', alignItems: 'center', justifyContent: 'space-between', color: TMColors.error }, children: _jsxs("div", { children: [" ", 'Anteprima non disponibile.', fileExt && _jsx("b", { children: ` (*.${fileExt})` })] }) })] });
102
103
  const innerContent = (_jsxs("div", { style: { width: '100%', height: '100%', padding: '2px', display: 'flex', flexDirection: 'column', gap: 10 }, children: [enableDragDropOverlay && _jsx(TMDragDropOverlay, { handleFile: handleFile, refocusAfterFileInput: refocusAfterFileInput }), content] }));
@@ -3,7 +3,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
3
  import { DcmtTypeListCacheService, LayoutModes, SDK_Globals, SDK_Localizator } from '@topconsultnpm/sdk-ts';
4
4
  import TMRelationViewer from './TMRelationViewer';
5
5
  import TMContextMenu from '../../NewComponents/ContextMenu/TMContextMenu';
6
- import { IconMultipleSelection, IconCheckFile, IconDetailDcmts, SDKUI_Localizator, IconMenuVertical, IconDataList, IconPreview, IconSearchCheck, IconBoard, IconDcmtTypeSys, IconShow, getMoreInfoTasksForDocument, isApprovalWorkflowView, searchResultToMetadataValues } from '../../../helper';
6
+ import { IconMultipleSelection, IconCheckFile, IconDetailDcmts, SDKUI_Localizator, IconMenuVertical, IconDataList, IconPreview, IconSearchCheck, IconBoard, IconDcmtTypeSys, IconShow, getMoreInfoTasksForDocument, isApprovalWorkflowView, searchResultToMetadataValues, IconRefresh } from '../../../helper';
7
7
  import { FormModes, SearchResultContext } from '../../../ts';
8
8
  import { TMColors } from '../../../utils/theme';
9
9
  import ShowAlert from '../../base/TMAlert';
@@ -14,7 +14,7 @@ import { TMPanelManagerProvider, useTMPanelManagerContext } from '../../layout/p
14
14
  import TMSearchResult from '../search/TMSearchResult';
15
15
  import TMDcmtForm from './TMDcmtForm';
16
16
  import { TMNothingToShow } from './TMDcmtPreview';
17
- import { Spinner } from '../..';
17
+ import { Spinner, TMButton } from '../..';
18
18
  import { useDocumentOperations } from '../../../hooks/useDocumentOperations';
19
19
  const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, deviceType, inputDcmts, isForMaster, showCurrentDcmtIndicator = true, allowNavigation, canNext, canPrev, onNext, onPrev, onBack, appendMasterDcmts, onTaskCreateRequest, onRefreshAfterAddDcmtToFavs, editPdfForm, openS4TViewer, onOpenS4TViewerRequest, onOpenPdfEditorRequest, datagridUtility, dcmtUtility }) => {
20
20
  const floatingBarContainerRef = useRef(null);
@@ -29,8 +29,8 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
29
29
  const [contextMenuPosition, setContextMenuPosition] = useState({ x: 0, y: 0 });
30
30
  const [dtdFocused, setDtdFocused] = useState();
31
31
  const [refreshKey, setRefreshKey] = useState(0);
32
- // Stato per gestire la transizione fluida durante il refresh
33
- const [isRefreshing, setIsRefreshing] = useState(false);
32
+ // Separate refresh key for TMFormOrResultWrapper only (doesn't affect tmTreeView)
33
+ const [refreshKeyFormOrResult, setRefreshKeyFormOrResult] = useState(0);
34
34
  /** State for transformed focusedItem metadata values (similar to formData in TMDcmtForm) */
35
35
  const [focusedItemFormData, setFocusedItemFormData] = useState([]);
36
36
  // Trigger operationItems refresh (after file substitution, etc.)
@@ -39,20 +39,15 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
39
39
  const onRefreshOperationsDatagrid = useCallback(async () => {
40
40
  setRefreshOperationsTrigger(prev => prev + 1);
41
41
  }, []);
42
- // Refresh con transizione fluida: fade-out -> update -> fade-in
43
- const onRefreshSearch = async () => {
44
- await dcmtUtility?.onRefreshPreviewForm?.();
45
- // Avvia fade-out
46
- setIsRefreshing(true);
47
- // Attendi che il fade-out sia completato, poi aggiorna
48
- setTimeout(() => {
49
- setRefreshKey(prev => prev + 1);
50
- onRefreshOperationsDatagrid();
51
- // Attendi un po' per dare tempo al re-render, poi fade-in
52
- setTimeout(() => {
53
- setIsRefreshing(false);
54
- }, 300); // Durata extra dell'overlay dopo l'update
55
- }, 200); // Durata del fade-out
42
+ // Refresh ALL panels (tree view + search results) with fade-out -> update -> fade-in transition
43
+ const onRefreshAllPanels = async () => {
44
+ await dcmtUtility?.onRefreshPreviewForm?.(); // Refresh preview form data
45
+ setFocusedItem(undefined); // Clear focused item to avoid stale references
46
+ setTimeout(async () => {
47
+ setRefreshKey(prev => prev + 1); // Force re-render of tmTreeView
48
+ setRefreshKeyFormOrResult(prev => prev + 1); // Force re-render of TMFormOrResultWrapper
49
+ await onRefreshOperationsDatagrid(); // Refresh operation items
50
+ }, 200); // Wait for fade-out animation
56
51
  };
57
52
  useEffect(() => {
58
53
  const fetchFocusedItemMetadata = async () => {
@@ -134,11 +129,11 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
134
129
  // searchResult: selectedSearchResult,
135
130
  datagridUtility: {
136
131
  visibleItems: [],
137
- onRefreshSearchAsyncDatagrid: datagridUtility?.onRefreshSearchAsyncDatagrid,
138
- onRefreshDataRowsAsync: datagridUtility?.onRefreshDataRowsAsync,
139
- refreshFocusedDataRowAsync: datagridUtility?.refreshFocusedDataRowAsync,
140
- onRefreshBlogDatagrid: datagridUtility?.onRefreshBlogDatagrid,
141
- onRefreshPreviewDatagrid: datagridUtility?.onRefreshPreviewDatagrid,
132
+ onRefreshSearchAsyncDatagrid: onRefreshAllPanels,
133
+ onRefreshDataRowsAsync: onRefreshAllPanels,
134
+ refreshFocusedDataRowAsync: onRefreshAllPanels,
135
+ onRefreshBlogDatagrid: onRefreshAllPanels,
136
+ onRefreshPreviewDatagrid: onRefreshAllPanels,
142
137
  refreshOperationsTrigger,
143
138
  onRefreshOperationsDatagrid,
144
139
  },
@@ -148,10 +143,10 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
148
143
  selectedDcmtSearchResultRelations: dcmtUtility?.selectedDcmtSearchResultRelations,
149
144
  dcmtTIDHasDetailRelations: dcmtUtility?.dcmtTIDHasDetailRelations,
150
145
  dcmtTIDHasMasterRelations: dcmtUtility?.dcmtTIDHasMasterRelations,
151
- updateCurrentDcmt: onRefreshSearch,
146
+ updateCurrentDcmt: onRefreshAllPanels,
152
147
  onCloseDcmtForm: dcmtUtility?.onCloseDcmtForm,
153
148
  onRefreshBlogForm: dcmtUtility?.onRefreshBlogForm,
154
- onRefreshPreviewForm: onRefreshSearch,
149
+ onRefreshPreviewForm: onRefreshAllPanels,
155
150
  taskFormDialogComponent: dcmtUtility?.taskFormDialogComponent,
156
151
  s4TViewerDialogComponent: dcmtUtility?.s4TViewerDialogComponent
157
152
  },
@@ -271,7 +266,7 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
271
266
  }
272
267
  }
273
268
  ];
274
- const toolbar = _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '10px' }, children: [allowMultipleSelection && _jsx("p", { style: { color: TMColors.colorHeader, textAlign: 'center', padding: '1px 4px', borderRadius: '3px', display: 'flex' }, children: `${selectedItems.filter(item => item.isDcmt).length} selezionati` }), allowNavigation && canPrev != undefined && _jsx(TMSaveFormButtonPrevious, { btnStyle: 'icon', iconColor: 'white', isModified: false, formMode: FormModes.ReadOnly, canPrev: canPrev, onPrev: onPrev }), allowNavigation && canNext != undefined && _jsx(TMSaveFormButtonNext, { btnStyle: 'icon', iconColor: 'white', isModified: false, formMode: FormModes.ReadOnly, canNext: canNext, onNext: onNext }), _jsx(TMContextMenu, { items: commandsMenuItems, trigger: 'left', children: _jsx(IconMenuVertical, { color: 'white', cursor: 'pointer' }) })] });
269
+ const toolbar = _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '10px' }, children: [allowMultipleSelection && _jsx("p", { style: { color: TMColors.colorHeader, textAlign: 'center', padding: '1px 4px', borderRadius: '3px', display: 'flex' }, children: `${selectedItems.filter(item => item.isDcmt).length} selezionati` }), allowNavigation && canPrev != undefined && _jsx(TMSaveFormButtonPrevious, { btnStyle: 'icon', iconColor: 'white', isModified: false, formMode: FormModes.ReadOnly, canPrev: canPrev, onPrev: onPrev }), allowNavigation && canNext != undefined && _jsx(TMSaveFormButtonNext, { btnStyle: 'icon', iconColor: 'white', isModified: false, formMode: FormModes.ReadOnly, canNext: canNext, onNext: onNext }), _jsx(TMButton, { btnStyle: 'icon', icon: _jsx(IconRefresh, { color: 'white' }), caption: SDKUI_Localizator.Refresh, onClick: onRefreshAllPanels }), _jsx(TMContextMenu, { items: commandsMenuItems, trigger: 'left', children: _jsx(IconMenuVertical, { color: 'white', cursor: 'pointer' }) })] });
275
270
  const getTitle = () => isForMaster ? `${SDKUI_Localizator.DcmtsMaster} - ${dtdMaster?.nameLoc}` : SDKUI_Localizator.DcmtsDetail;
276
271
  const isMobile = deviceType === DeviceType.MOBILE;
277
272
  const tmTreeView = useMemo(() => _jsx(_Fragment, { children: !inputDcmts || inputDcmts.length === 0
@@ -290,7 +285,7 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
290
285
  position: contextMenuPosition,
291
286
  onClose: () => setContextMenuVisible(false)
292
287
  } })] }) }), [inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, allowMultipleSelection, focusedItem, selectedItems, handleFocusedItemChanged, handleSelectedItemsChanged, handleNoRelationsFound, onItemContextMenu, contextMenuVisible, contextMenuPosition, refreshKey, focusedItemFormData]);
293
- const tmFormOrResult = useMemo(() => _jsx(TMFormOrResultWrapper, { refreshKey: refreshKey, deviceType: deviceType, focusedItem: focusedItem, onTaskCreateRequest: onTaskCreateRequest, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, onRefreshAfterAddDcmtToFavs: onRefreshAfterAddDcmtToFavs, editPdfForm: editPdfForm, openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, onOpenPdfEditorRequest: onOpenPdfEditorRequest }), [focusedItem, deviceType, allTasks, handleNavigateToWGs, handleNavigateToDossiers, editPdfForm, openS4TViewer, onOpenS4TViewerRequest, onOpenPdfEditorRequest, onRefreshAfterAddDcmtToFavs, refreshKey]);
288
+ const tmFormOrResult = useMemo(() => _jsx(TMFormOrResultWrapper, { refreshKey: refreshKeyFormOrResult, deviceType: deviceType, focusedItem: focusedItem, onTaskCreateRequest: onTaskCreateRequest, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, onRefreshAfterAddDcmtToFavs: onRefreshAfterAddDcmtToFavs, editPdfForm: editPdfForm, openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, onOpenPdfEditorRequest: onOpenPdfEditorRequest, onRefreshSearchResults: onRefreshAllPanels }), [focusedItem, deviceType, allTasks, handleNavigateToWGs, handleNavigateToDossiers, editPdfForm, openS4TViewer, onOpenS4TViewerRequest, onOpenPdfEditorRequest, onRefreshAfterAddDcmtToFavs, refreshKeyFormOrResult]);
294
289
  const initialPanelDimensions = {
295
290
  'tmTreeView': { width: '50%', height: '100%' },
296
291
  'tmFormOrResult': { width: '50%', height: '100%' },
@@ -367,28 +362,7 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
367
362
  toolbarOptions: { icon: _jsx(IconSearchCheck, { fontSize: 24 }), visible: false, orderNumber: 2, isActive: allInitialPanelVisibility['tmFormOrResult'] }
368
363
  }
369
364
  ], [tmTreeView, tmFormOrResult, focusedItem?.isDcmt, dtdMaster]);
370
- return (_jsxs("div", { style: { width: '100%', height: '100%', position: 'relative' }, children: [isCheckingFirstLoad && (_jsx(Spinner, { description: SDKUI_Localizator.Loading, flat: true })), _jsxs("div", { style: isCheckingFirstLoad ? { position: 'absolute', width: 0, height: 0, overflow: 'hidden', opacity: 0, pointerEvents: 'none' } : { width: '100%', height: '100%' }, children: [_jsx(TMPanelManagerProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: initialPanelDimensions, initialDimensions: initialPanelDimensions, initialMobilePanelId: 'tmTreeView', children: _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", showToolbar: true }) }), _jsxs("div", { style: {
371
- position: 'absolute',
372
- top: 0,
373
- left: 0,
374
- right: 0,
375
- bottom: 0,
376
- backgroundColor: 'rgba(255, 255, 255, 0.7)',
377
- display: 'flex',
378
- alignItems: 'center',
379
- justifyContent: 'center',
380
- opacity: isRefreshing ? 1 : 0,
381
- pointerEvents: isRefreshing ? 'auto' : 'none',
382
- transition: 'opacity 200ms ease-in-out',
383
- zIndex: 10,
384
- }, children: [_jsx("div", { style: {
385
- width: 40,
386
- height: 40,
387
- border: '3px solid #e0e0e0',
388
- borderTopColor: TMColors.primaryColor,
389
- borderRadius: '50%',
390
- animation: 'spin 0.8s linear infinite',
391
- } }), _jsx("style", { children: `@keyframes spin { to { transform: rotate(360deg); } }` })] }), renderDcmtOperations, renderFloatingBar] })] }));
365
+ return (_jsxs("div", { style: { width: '100%', height: '100%', position: 'relative' }, children: [isCheckingFirstLoad && (_jsx(Spinner, { description: SDKUI_Localizator.Loading, flat: true })), _jsxs("div", { style: isCheckingFirstLoad ? { position: 'absolute', width: 0, height: 0, overflow: 'hidden', opacity: 0, pointerEvents: 'none' } : { width: '100%', height: '100%' }, children: [_jsx(TMPanelManagerProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: initialPanelDimensions, initialDimensions: initialPanelDimensions, initialMobilePanelId: 'tmTreeView', children: _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", showToolbar: true }) }), renderDcmtOperations, renderFloatingBar] })] }));
392
366
  };
393
367
  export default TMMasterDetailDcmts;
394
368
  /**
@@ -430,11 +404,11 @@ const TMRelationViewerWrapper = ({ refreshKey, inputDcmts, isForMaster, showCurr
430
404
  }, [onItemContextMenu, handleFocusedItemChanged]);
431
405
  return (_jsx(TMRelationViewer, { inputDcmts: inputDcmts, isForMaster: isForMaster, showCurrentDcmtIndicator: showCurrentDcmtIndicator, initialShowZeroDcmts: showZeroDcmts, customItemRender: customItemRender, allowMultipleSelection: allowMultipleSelection, focusedItem: focusedItem, selectedItems: selectedItems, onFocusedItemChanged: handleFocusedItemChanged, onSelectedItemsChanged: onSelectedItemsChanged, maxDepthLevel: 1, invertMasterNavigation: false, onNoRelationsFound: onNoRelationsFound, onItemContextMenu: onContextMenu, focusedItemFormData: focusedItemFormData }, refreshKey));
432
406
  };
433
- const TMFormOrResultWrapper = ({ refreshKey, deviceType, focusedItem, onTaskCreateRequest, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, onRefreshAfterAddDcmtToFavs, editPdfForm, openS4TViewer, onOpenS4TViewerRequest, onOpenPdfEditorRequest, onRefreshSearchAsyncDatagrid }) => {
407
+ const TMFormOrResultWrapper = ({ refreshKey, deviceType, focusedItem, onTaskCreateRequest, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, onRefreshAfterAddDcmtToFavs, editPdfForm, openS4TViewer, onOpenS4TViewerRequest, onOpenPdfEditorRequest, onRefreshSearchAsyncDatagrid, onRefreshSearchResults }) => {
434
408
  const { setPanelVisibilityById } = useTMPanelManagerContext();
435
409
  return (_jsx(_Fragment, { children: focusedItem?.isDcmt ?
436
410
  _jsx(TMDcmtForm, { groupId: 'tmFormOrResult', TID: focusedItem?.tid, DID: focusedItem.did, allowButtonsRefs: true, isClosable: deviceType !== DeviceType.MOBILE, allowNavigation: false, allowRelations: deviceType !== DeviceType.MOBILE, showDcmtFormSidebar: false, onClose: () => { setPanelVisibilityById('tmTreeView', true); }, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, moreInfoTasks: getMoreInfoTasksForDocument(allTasks, focusedItem?.tid, focusedItem?.did), openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, onOpenPdfEditorRequest: onOpenPdfEditorRequest, datagridUtility: {
437
411
  onRefreshSearchAsyncDatagrid,
438
412
  } }, refreshKey) :
439
- _jsx(TMSearchResult, { groupId: 'tmFormOrResult', isClosable: deviceType !== DeviceType.MOBILE, context: SearchResultContext.METADATA_SEARCH, allowFloatingBar: false, allowRelations: false, openDcmtFormAsModal: true, searchResults: focusedItem?.searchResult ?? [], showSearchResultSidebar: false, showDcmtFormSidebar: false, onTaskCreateRequest: onTaskCreateRequest, onClose: () => { setPanelVisibilityById('tmTreeView', true); }, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, editPdfForm: editPdfForm, onOpenPdfEditorRequest: onOpenPdfEditorRequest, openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, enablePinIcons: false, onRefreshAfterAddDcmtToFavs: onRefreshAfterAddDcmtToFavs }, refreshKey) }));
413
+ _jsx(TMSearchResult, { groupId: 'tmFormOrResult', isClosable: deviceType !== DeviceType.MOBILE, context: SearchResultContext.METADATA_SEARCH, allowFloatingBar: false, allowRelations: false, openDcmtFormAsModal: true, searchResults: focusedItem?.searchResult ?? [], showSearchResultSidebar: false, showDcmtFormSidebar: false, onTaskCreateRequest: onTaskCreateRequest, onClose: () => { setPanelVisibilityById('tmTreeView', true); }, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, editPdfForm: editPdfForm, onOpenPdfEditorRequest: onOpenPdfEditorRequest, openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, enablePinIcons: false, onRefreshAfterAddDcmtToFavs: onRefreshAfterAddDcmtToFavs, showBackButton: false, onRefreshSearchAsyncDatagrid: onRefreshSearchResults }, refreshKey) }));
440
414
  };
@@ -628,6 +628,7 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
628
628
  isZero: dcmt.DID === 0,
629
629
  isMaster: !isForMaster,
630
630
  isLoaded: true,
631
+ isLogDel: docRow?.ISLOGDEL?.value,
631
632
  hidden: false,
632
633
  values: docRow,
633
634
  searchResult: result ? [result] : [],
@@ -201,7 +201,7 @@ const TMSavedQuerySelector = React.memo(({ items, selectedId, allowShowSearch =
201
201
  alignItems: 'center',
202
202
  justifyContent: 'center',
203
203
  minWidth: 0
204
- }, children: [_jsx("p", { style: {
204
+ }, children: [_jsx("p", { title: sqd.name, style: {
205
205
  fontSize: '1rem',
206
206
  fontWeight: sqd.id === 1 ? 600 : 'normal',
207
207
  whiteSpace: 'nowrap',
@@ -53,6 +53,8 @@ const TMSearch = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTask
53
53
  if (inputSqdID) {
54
54
  SavedQueryCacheService.GetAsync(inputSqdID).then(async (resultSqd) => {
55
55
  await setSQDAsync(resultSqd);
56
+ // Mostra la vista Search per visualizzare i filtri della SavedQuery caricata
57
+ setCurrentSearchView(TMSearchViews.Search);
56
58
  });
57
59
  }
58
60
  }, [inputSqdID]);
@@ -148,6 +148,18 @@ const TMSearchWhereItemEditor = React.memo(({ whereItem, queryParamsDynDataList,
148
148
  let dtd = await DcmtTypeListCacheService.GetAsync(whereItem.tid, true);
149
149
  return dtd?.metadata?.find(o => o.id === whereItem.mid);
150
150
  };
151
+ // Rimuove gli apici singoli da valori separati da virgola: 'msegato','plevolella' -> msegato,plevolella
152
+ const stripQuotes = (value) => {
153
+ if (!value || typeof value !== 'string')
154
+ return value;
155
+ return value.split(',').map(item => {
156
+ const trimmed = item.trim();
157
+ if (trimmed.startsWith("'") && trimmed.endsWith("'")) {
158
+ return trimmed.slice(1, -1);
159
+ }
160
+ return trimmed;
161
+ }).join(',');
162
+ };
151
163
  const normalizeValue = (value, isForValue1 = true) => {
152
164
  let newValues = [];
153
165
  let newValue = value;
@@ -161,7 +173,7 @@ const TMSearchWhereItemEditor = React.memo(({ whereItem, queryParamsDynDataList,
161
173
  }
162
174
  onValueChanged?.(newValues);
163
175
  };
164
- return (_jsxs(StyledRowItem, { style: { marginBottom: 0, width: '100%' }, children: [showValue1 && _jsx(TMMetadataEditor, { openChooserBySingleClick: openChooserBySingleClick, isSelected: isSelected, tid: whereItem.tid, mid: whereItem.mid, layoutMode: LayoutModes.None, isEditable: isEditableList, value: whereItem.value1, queryOperator: whereItem.operator, queryParamsDynDataList: queryParamsDynDataList, autoFocus: autoFocus ?? false, containerElement: undefined, onValueChanged: (value) => { normalizeValue(value, true); }, onCascadeRefreshDynDataLists: onCascadeRefreshDynDataLists, onCascadeUpdateMIDs: onCascadeUpdateMIDs, updateIsModalOpen: updateIsModalOpen }), showValue2 && _jsx(TMMetadataEditor, { openChooserBySingleClick: openChooserBySingleClick, isSelected: isSelected, tid: whereItem.tid, mid: whereItem.mid, layoutMode: LayoutModes.None, isEditable: isEditableList, value: whereItem.value2, queryOperator: whereItem.operator, autoFocus: autoFocus ?? false, containerElement: undefined, onValueChanged: (value) => { normalizeValue(value, false); }, updateIsModalOpen: updateIsModalOpen })] }));
176
+ return (_jsxs(StyledRowItem, { style: { marginBottom: 0, width: '100%' }, children: [showValue1 && _jsx(TMMetadataEditor, { openChooserBySingleClick: openChooserBySingleClick, isSelected: isSelected, tid: whereItem.tid, mid: whereItem.mid, layoutMode: LayoutModes.None, isEditable: isEditableList, value: stripQuotes(whereItem.value1), queryOperator: whereItem.operator, queryParamsDynDataList: queryParamsDynDataList, autoFocus: autoFocus ?? false, containerElement: undefined, onValueChanged: (value) => { normalizeValue(value, true); }, onCascadeRefreshDynDataLists: onCascadeRefreshDynDataLists, onCascadeUpdateMIDs: onCascadeUpdateMIDs, updateIsModalOpen: updateIsModalOpen }), showValue2 && _jsx(TMMetadataEditor, { openChooserBySingleClick: openChooserBySingleClick, isSelected: isSelected, tid: whereItem.tid, mid: whereItem.mid, layoutMode: LayoutModes.None, isEditable: isEditableList, value: stripQuotes(whereItem.value2), queryOperator: whereItem.operator, autoFocus: autoFocus ?? false, containerElement: undefined, onValueChanged: (value) => { normalizeValue(value, false); }, updateIsModalOpen: updateIsModalOpen })] }));
165
177
  });
166
178
  const TMSearchWhereItemCard = React.memo(({ index, whereItem, isSelected, queryParamsDynDataList, showEditor, showCompleteMetadataName, showId, isEditableList, onWhereItemChange, onHideEditor, onCascadeRefreshDynDataLists, onCascadeUpdateMIDs, updateIsModalOpen }) => {
167
179
  const [isOpen, setIsOpen] = useState(false);
@@ -25,6 +25,6 @@ interface ITMSearchQueryPanelProps {
25
25
  declare const TMSearchQueryPanel: React.FunctionComponent<ITMSearchQueryPanelProps>;
26
26
  export default TMSearchQueryPanel;
27
27
  export declare const refreshLastSearch: (qd: QueryDescriptor | undefined) => Promise<SearchResultDescriptor[] | undefined>;
28
- export declare const StyledToppyTextContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
29
- export declare const StyledToppyText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>> & string;
30
- export declare const StyledToppyImage: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, never>> & string;
28
+ export declare const StyledToppyTextContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
29
+ export declare const StyledToppyText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never> & Partial<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, never>>> & string;
30
+ export declare const StyledToppyImage: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, never> & Partial<Pick<React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, never>>> & string;
@@ -658,6 +658,7 @@ handleNavigateToWGs, handleNavigateToDossiers, }) => {
658
658
  }
659
659
  return (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', height: '100%', overflow: 'hidden', width: '100%' }, children: [_jsx("div", { style: { padding: '10px', overflow: 'auto', flex: 1 }, children: _jsx("div", { dangerouslySetInnerHTML: { __html: ftExplanation } }) }), _jsxs(StyledIndexingInfoSection, { children: [_jsxs(StyledIndexingToggle, { onClick: handleToggleIndexingInfo, disabled: loadingIndexingInfo, children: [_jsx(StyledLeftContent, { children: _jsx("span", { children: SDKUI_Localizator.IndexingInformation }) }), _jsx(StyledRightContent, { children: _jsx(StyledChevron, { "$isOpen": showIndexingInfo, children: "\u25BC" }) })] }), showIndexingInfo && indexingInfo && (_jsxs(StyledIndexingInfoBox, { children: [_jsx("div", { dangerouslySetInnerHTML: { __html: indexingInfo } }), loadingIndexingInfo && (_jsxs("div", { style: { position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', background: 'rgba(255, 255, 255, 0.9)', padding: '10px', borderRadius: '4px', boxShadow: '0 2px 8px rgba(0,0,0,0.15)' }, children: [SDKUI_Localizator.Loading, "..."] }))] }))] })] }));
660
660
  }, [selectedSearchResult, focusedItem, indexingInfo, showIndexingInfo, loadingIndexingInfo]);
661
+ const isBoardDisabled = useMemo(() => fromDTD?.hasBlog !== 1, [fromDTD?.hasBlog]);
661
662
  const allInitialPanelVisibility = {
662
663
  'tmSearchResult': true,
663
664
  'tmBlog': false,
@@ -726,9 +727,9 @@ handleNavigateToWGs, handleNavigateToDossiers, }) => {
726
727
  width: '100%',
727
728
  height: '100%',
728
729
  }, children: _jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, showWaitPanelSecondary: showSecondary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, waitPanelTextSecondary: waitPanelTextSecondary, waitPanelValueSecondary: waitPanelValueSecondary, waitPanelMaxValueSecondary: waitPanelMaxValueSecondary, isCancelable: true, abortController: abortController, children: _jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showCicoWaitPanel, showWaitPanelPrimary: showCicoPrimaryProgress, waitPanelTitle: cicoWaitPanelTitle, waitPanelTextPrimary: cicoPrimaryProgressText, waitPanelValuePrimary: cicoPrimaryProgressValue, waitPanelMaxValuePrimary: cicoPrimaryProgressMax, isCancelable: true, abortController: abortControllerLocal, children: (groupId && groupId.length > 0) ?
729
- _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", parentId: groupId, showToolbar: showSearchResultSidebar })
730
+ _jsxs(_Fragment, { children: [_jsx(PanelDisabledStateHandler, { isBoardDisabled: isBoardDisabled }), _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", parentId: groupId, showToolbar: showSearchResultSidebar })] })
730
731
  :
731
- _jsx(TMPanelManagerProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: initialPanelDimensions, initialDimensions: initialPanelDimensions, initialMobilePanelId: 'tmSearchResult', children: _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", parentId: groupId, showToolbar: showSearchResultSidebar }) }) }) }) }), renderDcmtOperations] }));
732
+ _jsxs(TMPanelManagerProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: initialPanelDimensions, initialDimensions: initialPanelDimensions, initialMobilePanelId: 'tmSearchResult', children: [_jsx(PanelDisabledStateHandler, { isBoardDisabled: isBoardDisabled }), _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", parentId: groupId, showToolbar: showSearchResultSidebar })] }) }) }) }), renderDcmtOperations] }));
732
733
  };
733
734
  export default TMSearchResult;
734
735
  const TMSearchResultGrid = ({ openInOffice, fromDTD, operationItems, allUsers, inputFocusedItem, allowMultipleSelection = true, showExportForm = false, onFocusedItemChanged, onDownloadDcmtsAsync, onVisibleItemChanged, inputSelectedItems = [], lastUpdateSearchTime, searchResult, onSelectionChanged, onDblClick, showSearchTMDatagrid, updateDataColumnsFromDataGrid, updateDataSourceFromDataGrid, updateSelectedRowKeysFromDataGrid }) => {
@@ -1238,6 +1239,18 @@ const TMSearchResultSelector = ({ searchResults = [], disableAccordionIfSingleCa
1238
1239
  return (_jsx(TMAccordionNew, { groups: accordionGroups, selectedItem: selectedResult, onSelectedItemChange: (result) => handleSelect(result) }));
1239
1240
  };
1240
1241
  //#endregion TMSearchResultSelector
1242
+ const PanelDisabledStateHandler = ({ isBoardDisabled }) => {
1243
+ const { setPanelVisibilityById, setToolbarButtonDisabled, panelVisibility } = useTMPanelManagerContext();
1244
+ useEffect(() => {
1245
+ // Aggiorna lo stato disabled del bottone toolbar
1246
+ setToolbarButtonDisabled('tmBlog', isBoardDisabled);
1247
+ // Chiude il pannello solo se è attualmente visibile e deve essere disabilitato
1248
+ if (isBoardDisabled && panelVisibility['tmBlog']) {
1249
+ setPanelVisibilityById('tmBlog', false);
1250
+ }
1251
+ }, [isBoardDisabled, setPanelVisibilityById, setToolbarButtonDisabled, panelVisibility]);
1252
+ return null;
1253
+ };
1241
1254
  const TMDcmtPreviewWrapper = ({ refreshPreviewTrigger, currentDcmt, isVisible }) => {
1242
1255
  const { setPanelVisibilityById, toggleMaximize, isResizingActive, countVisibleLeafPanels } = useTMPanelManagerContext();
1243
1256
  const deviceType = useDeviceType();
@@ -87,6 +87,12 @@ const TMViewHistoryDcmt = (props) => {
87
87
  IsSigned: row.IsSigned ? row.IsSigned.toString() === '1' : false,
88
88
  };
89
89
  });
90
+ // Sort by LastUpdateTime ascending
91
+ historyFileItems.sort((a, b) => {
92
+ const dateA = a.LastUpdateTime ? new Date(a.LastUpdateTime).getTime() : 0;
93
+ const dateB = b.LastUpdateTime ? new Date(b.LastUpdateTime).getTime() : 0;
94
+ return dateA - dateB;
95
+ });
90
96
  return historyFileItems;
91
97
  }
92
98
  return [];
@@ -14,6 +14,7 @@ import TMTextArea from "../../editors/TMTextArea";
14
14
  import ShowAlert from "../../base/TMAlert";
15
15
  import { FormModes } from "../../../ts";
16
16
  import TMTaskForm from "../tasks/TMTaskForm";
17
+ import { useWorkflowApprove } from "../../../hooks/useWorkflowApprove";
17
18
  const StyledWorkFlowOperationButtonsContainer = styled.div `
18
19
  display: flex;
19
20
  align-items: center;
@@ -64,6 +65,7 @@ export const WorkFlowOperationButtons = (props) => {
64
65
  return (_jsx(StyledWorkFlowOperationButtonsContainer, { "$isMobile": isMobile, children: isSignWorkflow ? (_jsxs(_Fragment, { children: [_jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconSignaturePencil, {}), caption: SDKUI_Localizator.SignatureAndApprove, width: "160px", disabled: signApproveDisable, onClick: () => !signApproveDisable && onSignApprove?.(), onMouseDown: e => e.stopPropagation(), advancedColor: "#1a9a49", color: "success" }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconCloseOutline, {}), caption: SDKUI_Localizator.Reject, disabled: rejectDisable, onClick: () => !rejectDisable && onReject?.(), onMouseDown: e => e.stopPropagation(), advancedColor: TMColors.error, color: "error" }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconInfo, { fontSize: 16 }), caption: SDKUI_Localizator.MoreInformation, width: "180px", disabled: infoDisable, onClick: () => !infoDisable && onMoreInfo?.(), onMouseDown: e => e.stopPropagation(), advancedColor: TMColors.info, color: "info" })] })) : (_jsxs(_Fragment, { children: [_jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconApply, {}), caption: SDKUI_Localizator.Approve, disabled: approveDisable, onClick: () => !approveDisable && onApprove?.(), advancedColor: "#1a9a49", color: "success" }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconCloseOutline, {}), caption: SDKUI_Localizator.Reject, disabled: rejectDisable, onClick: () => !rejectDisable && onReject?.(), advancedColor: TMColors.error, color: "error" }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconUser, { fontSize: 16 }), caption: SDKUI_Localizator.Reassign, disabled: reassignDisable, onClick: () => !reassignDisable && onReAssign?.(), advancedColor: TMColors.tertiary, color: "tertiary" }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconInfo, { fontSize: 16 }), caption: SDKUI_Localizator.MoreInformation, width: "180px", disabled: infoDisable, onClick: () => !infoDisable && onMoreInfo?.(), advancedColor: TMColors.info, color: "info" })] })) }));
65
66
  };
66
67
  export const WorkFlowApproveRejectPopUp = ({ TID = 0, DID = 0, deviceType = DeviceType.DESKTOP, isReject, selectedItems = [], onClose, onCompleted }) => {
68
+ const { refreshWorkflowApprove } = useWorkflowApprove();
67
69
  const [commentValue, setCommentValue] = useState('');
68
70
  const disable = commentValue.length === 0;
69
71
  const completeOrRejectAsync = async (isReject) => {
@@ -79,6 +81,7 @@ export const WorkFlowApproveRejectPopUp = ({ TID = 0, DID = 0, deviceType = Devi
79
81
  await workflowEngine.WorkItem_CompleteOrRejectAsync(TID, DID, commentValue, isReject);
80
82
  }
81
83
  ShowAlert({ mode: 'success', position: 'TOP_RIGHT', title: isReject === 0 ? SDKUI_Localizator.WorkitemApprove : SDKUI_Localizator.WorkitemReject, message: SDKUI_Localizator.OperationSuccess, duration: 3000 });
84
+ await refreshWorkflowApprove();
82
85
  }
83
86
  catch (e) {
84
87
  TMExceptionBoxManager.show({ exception: e });
@@ -70,7 +70,11 @@ const ButtonsContainer = styled.div `
70
70
  `;
71
71
  const SET_RULE_DATASOURCE = [
72
72
  { value: WorkItemSetRules.Ands_AND_Ors, display: "Ands_AND_Ors" },
73
- { value: WorkItemSetRules.Ands_OR_Ors, display: "Ands_OR_Ors" }
73
+ { value: WorkItemSetRules.Ands_OR_Ors, display: "Ands_OR_Ors" },
74
+ { value: WorkItemSetRules.Ands_AND_Ors_AssignModeOrs, display: "Ands_AND_Ors_AssignModeOrs" },
75
+ { value: WorkItemSetRules.Ands_OR_Ors_AssignModeOrs, display: "Ands_OR_Ors_AssignModeOrs" },
76
+ { value: WorkItemSetRules.Ands_AND_Ors_WaitForAllAnds, display: "Ands_AND_Ors_WaitForAllAnds" },
77
+ { value: WorkItemSetRules.Ands_OR_Ors_WaitForAllAnds, display: "Ands_OR_Ors_WaitForAllAnds" }
74
78
  ];
75
79
  const SEVERITY_DATASOURCE = [
76
80
  { value: Severities.Critical, display: "Critical" },
@@ -341,6 +341,7 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, allowEdit = true, onDiagram
341
341
  const isUndoingRedoing = useRef(false);
342
342
  const initialDiagramRef = useRef(null);
343
343
  const notifiedXmlRef = useRef(null);
344
+ const serializationGenRef = useRef(0);
344
345
  const svgRef = useRef(null);
345
346
  const containerRef = useRef(null);
346
347
  const [isDrawingConnection, setIsDrawingConnection] = useState(false);
@@ -430,10 +431,15 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, allowEdit = true, onDiagram
430
431
  setHistoryIndex(newHistory.length);
431
432
  }
432
433
  setWfDiagram(newDiagram);
434
+ const currentGen = ++serializationGenRef.current;
433
435
  (async () => {
434
436
  try {
435
437
  // await è necessario per attendere il risultato stringa
436
438
  const newXml = await serializeWfDiagramToXml(newDiagram);
439
+ // Ignora serializzazioni obsolete: se nel frattempo è partita una nuova serializzazione,
440
+ // questa è vecchia e non deve sovrascrivere il risultato più recente.
441
+ if (currentGen !== serializationGenRef.current)
442
+ return;
437
443
  notifiedXmlRef.current = newXml;
438
444
  // Chiama il callback per notificare TMWFEditor
439
445
  // L'invio dell'XML al genitore avviene solo a serializzazione completata.
@@ -449,7 +455,7 @@ const WFDiagram = ({ xmlDiagramString, currentSetID, allowEdit = true, onDiagram
449
455
  catch (e) {
450
456
  TMExceptionBoxManager.show({ exception: e });
451
457
  }
452
- }, [wfDiagramHistory, historyIndex, isUndoingRedoing, setWfDiagramHistory, setHistoryIndex, setWfDiagram, isReadOnly]);
458
+ }, [wfDiagramHistory, historyIndex, isUndoingRedoing, setWfDiagramHistory, setHistoryIndex, setWfDiagram, isReadOnly, onDiagramChange]);
453
459
  const handleUndo = useCallback(() => {
454
460
  if (isReadOnly)
455
461
  return;
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { QueryDescriptor } from '@topconsultnpm/sdk-ts';
3
3
  import { WorkItemActor } from './RecipientList';
4
- export declare const RecipientsContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
4
+ export declare const RecipientsContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
5
5
  export declare const tosToActors: (tosString: string) => {
6
6
  andRecipients: WorkItemActor[];
7
7
  orRecipients: WorkItemActor[];
@@ -67,14 +67,13 @@ export const getSeveritiesNumber = (severity) => {
67
67
  };
68
68
  export const getWorkItemSetRulesNumber = (setRule) => {
69
69
  switch (setRule) {
70
- case WorkItemSetRules.Ands_AND_Ors:
71
- return 0;
72
- case WorkItemSetRules.Ands_OR_Ors:
73
- return 1;
74
- case WorkItemSetRules.Custom:
75
- return 2;
76
- default:
77
- return 0;
70
+ case WorkItemSetRules.Ands_AND_Ors: return 0;
71
+ case WorkItemSetRules.Ands_OR_Ors: return 1;
72
+ case WorkItemSetRules.Ands_AND_Ors_AssignModeOrs: return 2;
73
+ case WorkItemSetRules.Ands_OR_Ors_AssignModeOrs: return 3;
74
+ case WorkItemSetRules.Ands_AND_Ors_WaitForAllAnds: return 4;
75
+ case WorkItemSetRules.Ands_OR_Ors_WaitForAllAnds: return 5;
76
+ default: return 0;
78
77
  }
79
78
  };
80
79
  export const getWFAppTypesNumber = (appType) => {
@@ -147,12 +146,12 @@ const mapSeverity = (severityValue) => {
147
146
  // Funzione helper per mappare i valori numerici di WorkItemSetRules
148
147
  const mapWorkItemSetRules = (ruleValue) => {
149
148
  switch (ruleValue) {
150
- case 0:
151
- return WorkItemSetRules.Ands_AND_Ors;
152
- case 1:
153
- return WorkItemSetRules.Ands_OR_Ors;
154
- case 2:
155
- return WorkItemSetRules.Custom;
149
+ case 0: return WorkItemSetRules.Ands_AND_Ors;
150
+ case 1: return WorkItemSetRules.Ands_OR_Ors;
151
+ case 2: return WorkItemSetRules.Ands_AND_Ors_AssignModeOrs;
152
+ case 3: return WorkItemSetRules.Ands_OR_Ors_AssignModeOrs;
153
+ case 4: return WorkItemSetRules.Ands_AND_Ors_WaitForAllAnds;
154
+ case 5: return WorkItemSetRules.Ands_OR_Ors_WaitForAllAnds;
156
155
  default:
157
156
  console.warn(`Valore WorkItemSetRules sconosciuto: ${ruleValue}. Ritorno WorkItemSetRules.Ands_AND_Ors.`);
158
157
  return WorkItemSetRules.Ands_AND_Ors;
@@ -11,4 +11,4 @@ interface ChangePasswordInputsProps {
11
11
  }
12
12
  declare const ChangePasswordInputs: React.FC<ChangePasswordInputsProps>;
13
13
  export default ChangePasswordInputs;
14
- export declare const Divider: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
14
+ export declare const Divider: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
@@ -328,8 +328,8 @@ const TMLoginForm = (props) => {
328
328
  const nextStepHandler = async () => {
329
329
  if (!endpoint || (!dcmtArchive && !manualArchiveID))
330
330
  return;
331
- if (loginStep === 1 && !dcmtArchive && manualArchiveID) {
332
- const isValid = await validateManualArchiveAsync();
331
+ if (loginStep === 1 && manualArchiveID) {
332
+ const isValid = await fetchManualArchiveByIdAsync();
333
333
  if (!isValid)
334
334
  return;
335
335
  }
@@ -359,17 +359,27 @@ const TMLoginForm = (props) => {
359
359
  return;
360
360
  setLoginStep(prev => prev - 1);
361
361
  }, [loginStep]);
362
- const validateManualArchiveAsync = async () => {
363
- if (!tmSession || !manualArchiveID)
362
+ /** Retrieves and sets the archive descriptor from server using the manually entered ID. */
363
+ const fetchManualArchiveByIdAsync = async () => {
364
+ // Early exit if session or manual archive ID is not available
365
+ if (!tmSession || !manualArchiveID) {
366
+ setDcmtArchive(undefined);
364
367
  return false;
368
+ }
369
+ ;
365
370
  try {
366
371
  TMSpinner.show({ description: '' });
372
+ // Create archive engine and retrieve archive descriptor by ID
367
373
  const archiveEngine = tmSession.NewArchiveEngine();
368
- await archiveEngine.RetrieveAsync(manualArchiveID);
374
+ const result = await archiveEngine.RetrieveAsync(manualArchiveID);
375
+ // Update state with retrieved archive if valid
376
+ setDcmtArchive(result);
369
377
  return true;
370
378
  }
371
379
  catch (e) {
380
+ // Display error to user if retrieval fails
372
381
  TMExceptionBoxManager.show({ exception: e });
382
+ setDcmtArchive(undefined);
373
383
  return false;
374
384
  }
375
385
  finally {
@@ -16,17 +16,40 @@ const TMChooserForm = ({ children, title, allowMultipleSelection = false, allowA
16
16
  const [selectedRowKeys, setSelectedRowKeys] = useState(selectedIDs ?? []);
17
17
  const [focusedRowKey, setFocusedRowKey] = useState(selectedIDs?.[0]);
18
18
  const [selectedRowCounter, setSelectedRowCounter] = useState([]);
19
+ // Helper per confronto case-insensitive
20
+ const includesCaseInsensitive = (arr, value) => {
21
+ if (!arr)
22
+ return false;
23
+ if (typeof value === 'string') {
24
+ return arr.some(item => typeof item === 'string' && item.toLowerCase() === value.toLowerCase());
25
+ }
26
+ return arr.includes(value);
27
+ };
19
28
  useEffect(() => { doGetItems(false); }, [getItems]);
29
+ // Normalizza selectedRowKeys per corrispondere al case reale dei dati
30
+ const normalizeSelectedKeys = useCallback((items, keys) => {
31
+ return keys.map(key => {
32
+ if (typeof key === 'string') {
33
+ const match = items.find((item) => typeof item[keyName] === 'string' && item[keyName].toLowerCase() === key.toLowerCase());
34
+ return match ? match[keyName] : key;
35
+ }
36
+ return key;
37
+ });
38
+ }, [keyName]);
20
39
  useEffect(() => {
40
+ const normalizedKeys = normalizeSelectedKeys(allItems, selectedRowKeys);
41
+ if (JSON.stringify(normalizedKeys) !== JSON.stringify(selectedRowKeys)) {
42
+ setSelectedRowKeys(normalizedKeys);
43
+ }
21
44
  if (showOnlySelectedItems)
22
- setFilteredItems(allItems.filter((o) => selectedRowKeys?.includes(o[keyName])));
45
+ setFilteredItems(allItems.filter((o) => includesCaseInsensitive(normalizedKeys, o[keyName])));
23
46
  else
24
47
  setFilteredItems(allItems);
25
48
  }, [showOnlySelectedItems, allItems, selectedRowKeys, keyName]);
26
49
  useEffect(() => {
27
50
  setSelectedRowCounter(selectedRowKeys);
28
51
  }, [selectedRowKeys]);
29
- const getSelectedIDs = () => { return filteredItems.filter((o) => selectedRowKeys?.includes(o[keyName])).map((item) => { return convertID ? convertID(item) : item[keyName]; }); };
52
+ const getSelectedIDs = () => { return filteredItems.filter((o) => includesCaseInsensitive(selectedRowKeys, o[keyName])).map((item) => { return convertID ? convertID(item) : item[keyName]; }); };
30
53
  const getFocusedIDs = () => { return filteredItems.filter((o) => o[keyName] == focusedRowKey).map((item) => { return convertID ? convertID(item) : item[keyName]; }); };
31
54
  const renderTitle = () => { return title ? `${title} (${selectedRowCounter.length}/${filteredItems.length})` : SDKUI_Localizator.Select; };
32
55
  const doGetItems = (refreshCache) => {
@@ -41,7 +41,7 @@ const TMBlogsPost = (props) => {
41
41
  // State to manage the layout mode of the document form
42
42
  const [layoutMode, setLayoutMode] = useState("extended");
43
43
  const COMPACT_WIDTH_THRESHOLD = 465;
44
- const COMPACT_HEIGHT_THRESHOLD = 500;
44
+ const COMPACT_HEIGHT_THRESHOLD = 400;
45
45
  // State to store an array of blog posts, which can be either BlogPost or HomeBlogPost type
46
46
  const [blogPosts, setBlogPosts] = useState([]);
47
47
  // State to store the first unread post
@@ -62,6 +62,7 @@ export { default as TMBlogAttachments } from './grids/TMBlogAttachments';
62
62
  export { default as TMBlogCommentForm } from './features/blog/TMBlogCommentForm';
63
63
  export * from './query/TMQueryEditor';
64
64
  export * from './query/TMQuerySummary';
65
+ export * from './query/TMQueryCountButton';
65
66
  export { default as TMToppyDraggableHelpCenter } from './features/assistant/TMToppyDraggableHelpCenter';
66
67
  export * from './features/documents/TMDcmtForm';
67
68
  export * from './features/documents/TMDcmtIcon';
@@ -68,6 +68,7 @@ export { default as TMBlogCommentForm } from './features/blog/TMBlogCommentForm'
68
68
  //query
69
69
  export * from './query/TMQueryEditor';
70
70
  export * from './query/TMQuerySummary';
71
+ export * from './query/TMQueryCountButton';
71
72
  //assistant
72
73
  export { default as TMToppyDraggableHelpCenter } from './features/assistant/TMToppyDraggableHelpCenter';
73
74
  //documents