@topconsultnpm/sdkui-react 6.21.0-t2 → 6.21.0-t4

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 (165) hide show
  1. package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +28 -2
  2. package/lib/components/NewComponents/ContextMenu/styles.d.ts +4 -4
  3. package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +6 -6
  4. package/lib/components/base/Styled.d.ts +1 -1
  5. package/lib/components/base/TMAreaManager.js +11 -0
  6. package/lib/components/base/TMCounterBar.d.ts +2 -2
  7. package/lib/components/base/TMCounterContainer.d.ts +2 -1
  8. package/lib/components/base/TMCustomButton.d.ts +1 -1
  9. package/lib/components/base/TMDataGrid.js +12 -2
  10. package/lib/components/base/TMDataGridExportForm.d.ts +2 -1
  11. package/lib/components/base/TMDataGridExportForm.js +19 -8
  12. package/lib/components/base/TMFileManager.d.ts +2 -1
  13. package/lib/components/base/TMFileManagerDataGridView.d.ts +2 -1
  14. package/lib/components/base/TMFileManagerDataGridView.js +4 -4
  15. package/lib/components/base/TMFileManagerThumbnailItems.d.ts +1 -1
  16. package/lib/components/base/TMFileManagerThumbnailItems.js +3 -3
  17. package/lib/components/base/TMFileManagerThumbnailsView.d.ts +1 -1
  18. package/lib/components/base/TMFileManagerUtils.d.ts +7 -0
  19. package/lib/components/base/TMFileManagerUtils.js +14 -1
  20. package/lib/components/base/TMLayout.d.ts +4 -4
  21. package/lib/components/base/TMList.d.ts +2 -1
  22. package/lib/components/base/TMListView.d.ts +1 -1
  23. package/lib/components/base/TMModal.js +2 -2
  24. package/lib/components/base/TMPopUp.d.ts +1 -0
  25. package/lib/components/base/TMPopUp.js +59 -2
  26. package/lib/components/base/TMSpinner.d.ts +5 -2
  27. package/lib/components/base/TMSpinner.js +33 -6
  28. package/lib/components/base/TMTab.d.ts +4 -3
  29. package/lib/components/base/TMTooltip.d.ts +1 -1
  30. package/lib/components/base/TMTreeView.d.ts +16 -13
  31. package/lib/components/base/TMTreeView.js +242 -79
  32. package/lib/components/base/TMUserAvatar.d.ts +2 -1
  33. package/lib/components/base/TMVilViewer.d.ts +2 -1
  34. package/lib/components/base/TMWaitPanel.d.ts +5 -2
  35. package/lib/components/base/TMWaitPanel.js +8 -6
  36. package/lib/components/choosers/TMDistinctValues.js +1 -1
  37. package/lib/components/choosers/TMDynDataListItemChooser.d.ts +1 -1
  38. package/lib/components/choosers/TMDynDataListItemChooser.js +6 -1
  39. package/lib/components/choosers/TMGroupChooser.js +1 -1
  40. package/lib/components/choosers/TMInvoiceRetrieveFormats.d.ts +2 -1
  41. package/lib/components/choosers/TMOrderRetrieveFormats.d.ts +2 -1
  42. package/lib/components/choosers/TMRelationChooser.d.ts +3 -3
  43. package/lib/components/choosers/TMUserChooser.d.ts +2 -2
  44. package/lib/components/editors/TMEditorStyled.d.ts +6 -6
  45. package/lib/components/editors/TMFormulaEditor.d.ts +2 -1
  46. package/lib/components/editors/TMFormulaEditor.js +98 -49
  47. package/lib/components/editors/TMHtmlContentDisplay.d.ts +2 -1
  48. package/lib/components/editors/TMHtmlEditor.d.ts +2 -1
  49. package/lib/components/editors/TMMetadataEditor.js +6 -2
  50. package/lib/components/editors/TMMetadataValues.js +23 -6
  51. package/lib/components/editors/TMTextBox.d.ts +1 -0
  52. package/lib/components/editors/TMTextBox.js +2 -1
  53. package/lib/components/editors/TMTreeDropDown.d.ts +1 -1
  54. package/lib/components/features/assistant/TMToppyDraggableHelpCenter.d.ts +1 -1
  55. package/lib/components/features/blog/TMBlogCommentForm.d.ts +2 -1
  56. package/lib/components/features/blog/TMBlogCommentForm.js +5 -2
  57. package/lib/components/features/documents/TMCopyToFolderForm.js +46 -24
  58. package/lib/components/features/documents/TMDcmtForm.d.ts +2 -0
  59. package/lib/components/features/documents/TMDcmtForm.js +21 -10
  60. package/lib/components/features/documents/TMDcmtFormActionButtons.d.ts +1 -1
  61. package/lib/components/features/documents/TMDcmtIcon.d.ts +4 -1
  62. package/lib/components/features/documents/TMDcmtIcon.js +6 -33
  63. package/lib/components/features/documents/TMDcmtPreview.d.ts +1 -1
  64. package/lib/components/features/documents/TMDcmtTasks.d.ts +2 -1
  65. package/lib/components/features/documents/TMDragDropOverlay.d.ts +1 -1
  66. package/lib/components/features/documents/TMFileUploader.js +1 -1
  67. package/lib/components/features/documents/TMMasterDetailDcmts.d.ts +2 -2
  68. package/lib/components/features/documents/TMMasterDetailDcmts.js +55 -16
  69. package/lib/components/features/documents/TMMergeToPdfForm.d.ts +2 -3
  70. package/lib/components/features/documents/TMMergeToPdfForm.js +115 -56
  71. package/lib/components/features/documents/TMRelationViewer.d.ts +12 -10
  72. package/lib/components/features/documents/TMRelationViewer.js +405 -95
  73. package/lib/components/features/documents/copyAndMergeDcmtsShared.d.ts +4 -16
  74. package/lib/components/features/documents/copyAndMergeDcmtsShared.js +47 -61
  75. package/lib/components/features/documents/mergePdfUtils.d.ts +52 -0
  76. package/lib/components/features/documents/mergePdfUtils.js +268 -0
  77. package/lib/components/features/search/TMDcmtCheckoutInfoForm.d.ts +2 -1
  78. package/lib/components/features/search/TMMetadataOutputForm.d.ts +18 -0
  79. package/lib/components/features/search/TMMetadataOutputForm.js +225 -0
  80. package/lib/components/features/search/TMMetadataSorterForm.d.ts +18 -0
  81. package/lib/components/features/search/TMMetadataSorterForm.js +243 -0
  82. package/lib/components/features/search/TMSavedQuerySelector.d.ts +2 -2
  83. package/lib/components/features/search/TMSearch.d.ts +2 -2
  84. package/lib/components/features/search/TMSearch.js +2 -2
  85. package/lib/components/features/search/TMSearchQueryEditor.js +14 -8
  86. package/lib/components/features/search/TMSearchQueryPanel.js +249 -58
  87. package/lib/components/features/search/TMSearchResult.d.ts +3 -2
  88. package/lib/components/features/search/TMSearchResult.js +94 -25
  89. package/lib/components/features/search/TMSearchResultFloatingActionButton.d.ts +1 -1
  90. package/lib/components/features/search/TMSignatureInfoContent.d.ts +2 -1
  91. package/lib/components/features/search/TMViewHistoryDcmt.d.ts +2 -1
  92. package/lib/components/features/search/TMViewHistoryDcmt.js +1 -1
  93. package/lib/components/features/search/metadataFormHelper.d.ts +16 -0
  94. package/lib/components/features/search/metadataFormHelper.js +77 -0
  95. package/lib/components/features/tasks/TMTaskForm.d.ts +1 -1
  96. package/lib/components/features/tasks/TMTaskFormUtils.d.ts +10 -10
  97. package/lib/components/features/tasks/TMTasksAgenda.d.ts +1 -1
  98. package/lib/components/features/tasks/TMTasksCalendar.d.ts +1 -1
  99. package/lib/components/features/tasks/TMTasksHeader.d.ts +1 -1
  100. package/lib/components/features/tasks/TMTasksPanelContent.d.ts +1 -1
  101. package/lib/components/features/tasks/TMTasksUtilsView.d.ts +5 -5
  102. package/lib/components/features/tasks/TMTasksView.d.ts +1 -1
  103. package/lib/components/features/wg/TMWGsCopyMoveForm.d.ts +3 -2
  104. package/lib/components/features/workflow/TMWorkflowPopup.d.ts +8 -7
  105. package/lib/components/forms/Login/Chooser.d.ts +2 -2
  106. package/lib/components/forms/Login/TMLoginForm.js +15 -3
  107. package/lib/components/forms/TMChooserForm.d.ts +2 -1
  108. package/lib/components/forms/TMSaveForm.d.ts +4 -4
  109. package/lib/components/grids/TMBlogAttachments.d.ts +2 -1
  110. package/lib/components/grids/TMBlogAttachments.js +2 -2
  111. package/lib/components/grids/TMBlogHeader.d.ts +1 -1
  112. package/lib/components/grids/TMBlogsPost.d.ts +1 -1
  113. package/lib/components/grids/TMBlogsPost.js +5 -3
  114. package/lib/components/grids/TMBlogsPostUtils.d.ts +10 -9
  115. package/lib/components/grids/TMBlogsPostUtils.js +3 -1
  116. package/lib/components/grids/TMValidationItemsList.d.ts +2 -1
  117. package/lib/components/layout/panelManager/TMPanelManagerContainer.d.ts +2 -1
  118. package/lib/components/layout/panelManager/TMPanelManagerContext.d.ts +2 -2
  119. package/lib/components/layout/panelManager/TMPanelManagerToolbar.d.ts +1 -1
  120. package/lib/components/layout/panelManager/TMPanelManagerWithPersistenceProvider.d.ts +2 -2
  121. package/lib/components/layout/panelManager/TMPanelWrapper.d.ts +2 -2
  122. package/lib/components/pages/TMPage.d.ts +1 -1
  123. package/lib/components/settings/SettingsAppearance.d.ts +2 -1
  124. package/lib/components/sidebar/TMAboutApp.d.ts +2 -1
  125. package/lib/components/sidebar/TMHeader.d.ts +3 -3
  126. package/lib/components/viewers/TMDataListItemViewer.d.ts +3 -2
  127. package/lib/components/viewers/TMDataUserIdItemViewer.d.ts +3 -2
  128. package/lib/components/viewers/TMMidViewer.d.ts +2 -2
  129. package/lib/components/viewers/TMTidViewer.d.ts +2 -2
  130. package/lib/components/viewers/TMTidViewer.js +14 -2
  131. package/lib/components/wizard/TMWizard.d.ts +1 -0
  132. package/lib/components/wizard/TMWizard.js +5 -3
  133. package/lib/helper/Enum_Localizator.js +2 -0
  134. package/lib/helper/MergePdfManager.d.ts +45 -0
  135. package/lib/helper/MergePdfManager.js +148 -0
  136. package/lib/helper/SDKUI_Globals.d.ts +1 -0
  137. package/lib/helper/SDKUI_Globals.js +3 -1
  138. package/lib/helper/SDKUI_Localizator.d.ts +40 -0
  139. package/lib/helper/SDKUI_Localizator.js +412 -12
  140. package/lib/helper/TMCommandsContextMenu.d.ts +1 -1
  141. package/lib/helper/TMIcons.d.ts +278 -278
  142. package/lib/helper/TMPdfViewer.d.ts +2 -1
  143. package/lib/helper/TMToppyMessage.d.ts +2 -2
  144. package/lib/helper/TMUtils.d.ts +57 -21
  145. package/lib/helper/TMUtils.js +159 -1
  146. package/lib/helper/certificateImportHelper.d.ts +43 -0
  147. package/lib/helper/certificateImportHelper.js +403 -0
  148. package/lib/helper/checkinCheckoutManager.d.ts +4 -3
  149. package/lib/helper/checkinCheckoutManager.js +29 -11
  150. package/lib/helper/helpers.d.ts +3 -2
  151. package/lib/helper/helpers.js +10 -0
  152. package/lib/helper/index.d.ts +1 -0
  153. package/lib/helper/index.js +1 -0
  154. package/lib/hooks/useCheckInOutOperations.d.ts +4 -3
  155. package/lib/hooks/useDataUserIdItem.js +1 -1
  156. package/lib/hooks/useDcmtOperations.d.ts +20 -2
  157. package/lib/hooks/useDcmtOperations.js +244 -25
  158. package/lib/hooks/useDocumentOperations.d.ts +2 -2
  159. package/lib/hooks/useDocumentOperations.js +52 -13
  160. package/lib/hooks/useInputDialog.d.ts +2 -1
  161. package/lib/hooks/useRelatedDocuments.js +4 -4
  162. package/lib/services/platform_services.d.ts +7 -6
  163. package/lib/ts/types.d.ts +3 -1
  164. package/lib/ts/types.js +2 -0
  165. package/package.json +15 -7
@@ -7,16 +7,18 @@ import { IconMultipleSelection, IconCheckFile, IconDetailDcmts, SDKUI_Localizato
7
7
  import { FormModes, SearchResultContext } from '../../../ts';
8
8
  import { TMColors } from '../../../utils/theme';
9
9
  import ShowAlert from '../../base/TMAlert';
10
- import { DeviceType } from '../../base/TMDeviceProvider';
10
+ import { DeviceType, useDeviceType } from '../../base/TMDeviceProvider';
11
11
  import { TMSaveFormButtonPrevious, TMSaveFormButtonNext } from '../../forms/TMSaveForm';
12
12
  import TMPanelManagerContainer from '../../layout/panelManager/TMPanelManagerContainer';
13
13
  import { TMPanelManagerProvider, useTMPanelManagerContext } from '../../layout/panelManager/TMPanelManagerContext';
14
14
  import TMSearchResult from '../search/TMSearchResult';
15
15
  import TMDcmtForm from './TMDcmtForm';
16
16
  import { TMNothingToShow } from './TMDcmtPreview';
17
- import { Spinner, TMButton } from '../..';
17
+ import { Spinner, TMButton, TMLayoutWaitingContainer } from '../..';
18
18
  import { useDocumentOperations } from '../../../hooks/useDocumentOperations';
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, mergePdfManager }) => {
19
+ import TMToppyMessage from '../../../helper/TMToppyMessage';
20
+ import TMPanel from '../../base/TMPanel';
21
+ 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, fetchRemoteCertificates }) => {
20
22
  const floatingBarContainerRef = useRef(null);
21
23
  const [focusedItem, setFocusedItem] = useState();
22
24
  const [selectedItems, setSelectedItems] = useState([]);
@@ -27,6 +29,8 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
27
29
  const [isCheckingFirstLoad, setIsCheckingFirstLoad] = useState(true);
28
30
  const [contextMenuVisible, setContextMenuVisible] = useState(false);
29
31
  const [contextMenuPosition, setContextMenuPosition] = useState({ x: 0, y: 0 });
32
+ // Track if TMRelationViewer is loading (used to disable context menu during loading)
33
+ const [isRelationViewerLoading, setIsRelationViewerLoading] = useState(false);
30
34
  const [dtdFocused, setDtdFocused] = useState();
31
35
  const [refreshKey, setRefreshKey] = useState(0);
32
36
  // Separate refresh key for TMFormOrResultWrapper only (doesn't affect tmTreeView)
@@ -145,6 +149,7 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
145
149
  currentSearchResults: [],
146
150
  currentMetadataValues: [],
147
151
  allUsers: [],
152
+ fetchRemoteCertificates,
148
153
  // searchResult: selectedSearchResult,
149
154
  datagridUtility: {
150
155
  visibleItems: [],
@@ -211,8 +216,8 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
211
216
  openTaskFormHandler,
212
217
  onRefreshAfterAddDcmtToFavs,
213
218
  },
214
- mergePdfManager: mergePdfManager
215
219
  });
220
+ const { dcmtOperations: { abortController, showWaitPanel, showPrimary, waitPanelTitle, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, }, } = features;
216
221
  // Load dtdMaster when inputDcmts changes
217
222
  useEffect(() => {
218
223
  const loadDtdMaster = async () => {
@@ -265,14 +270,14 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
265
270
  const commandsMenuItems = [
266
271
  {
267
272
  icon: _jsx(IconMultipleSelection, { color: allowMultipleSelection ? TMColors.tertiary : TMColors.text_normal }),
268
- name: "Selezione multipla",
273
+ name: allowMultipleSelection ? SDKUI_Localizator.DisableMultipleSelection : SDKUI_Localizator.EnableMultipleSelection,
269
274
  onClick: () => {
270
275
  setAllowMultipleSelection(prev => !prev);
271
276
  }
272
277
  },
273
278
  {
274
- icon: _jsx(IconCheckFile, {}),
275
- name: "Consenti dettagli con 0 documenti",
279
+ icon: _jsx(IconCheckFile, { color: showZeroDcmts ? TMColors.tertiary : TMColors.text_normal }),
280
+ name: showZeroDcmts ? SDKUI_Localizator.HideDetailsWithZeroDocs : SDKUI_Localizator.ShowDetailsWithZeroDocs,
276
281
  onClick: () => {
277
282
  setShowZeroDcmts(prev => !prev);
278
283
  }
@@ -294,18 +299,23 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
294
299
  _jsx(TMNothingToShow, { text: getTitle(), secondText: SDKUI_Localizator.NoDataToDisplay, icon: isForMaster ? _jsx(IconDetailDcmts, { fontSize: 96, transform: 'scale(-1, 1)' }) : _jsx(IconDetailDcmts, { fontSize: 96 }) })
295
300
  :
296
301
  _jsxs("div", { ref: floatingBarContainerRef, style: { width: "100%", height: "100%" }, onContextMenu: (e) => {
302
+ // Disable context menu when loading
303
+ if (isRelationViewerLoading) {
304
+ e.preventDefault();
305
+ return;
306
+ }
297
307
  // Mostra context menu anche sullo spazio bianco (quando non si clicca su un item)
298
308
  e.preventDefault();
299
309
  setContextMenuPosition({ x: e.clientX, y: e.clientY });
300
310
  setContextMenuVisible(true);
301
311
  }, children: [_jsx(TMRelationViewerWrapper, { refreshKey: refreshKey, inputDcmts: inputDcmts, isForMaster: isForMaster, showCurrentDcmtIndicator: showCurrentDcmtIndicator, showZeroDcmts: showZeroDcmts,
302
312
  // customItemRender={customItemRender}
303
- allowMultipleSelection: allowMultipleSelection, focusedItem: focusedItem, selectedItems: selectedItems, onFocusedItemChanged: handleFocusedItemChanged, onSelectedItemsChanged: handleSelectedItemsChanged, onNoRelationsFound: handleNoRelationsFound, onItemContextMenu: onItemContextMenu, focusedItemFormData: focusedItemFormData }), _jsx(TMContextMenu, { items: operationItems, externalControl: {
313
+ allowMultipleSelection: allowMultipleSelection, focusedItem: focusedItem, selectedItems: selectedItems, onFocusedItemChanged: handleFocusedItemChanged, onSelectedItemsChanged: handleSelectedItemsChanged, onNoRelationsFound: handleNoRelationsFound, onItemContextMenu: isRelationViewerLoading ? undefined : onItemContextMenu, focusedItemFormData: focusedItemFormData, onLoadingStateChanged: setIsRelationViewerLoading }), _jsx(TMContextMenu, { items: operationItems, externalControl: {
304
314
  visible: contextMenuVisible,
305
315
  position: contextMenuPosition,
306
316
  onClose: () => setContextMenuVisible(false)
307
- } })] }) }), [inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, allowMultipleSelection, focusedItem, selectedItems, handleFocusedItemChanged, handleSelectedItemsChanged, handleNoRelationsFound, onItemContextMenu, contextMenuVisible, contextMenuPosition, refreshKey, focusedItemFormData]);
308
- 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, handleNavigateToReference: handleNavigateToReference, onRefreshAfterAddDcmtToFavs: onRefreshAfterAddDcmtToFavs, editPdfForm: editPdfForm, openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, onOpenPdfEditorRequest: onOpenPdfEditorRequest, onRefreshSearchResults: onRefreshAllPanels, mergePdfManager: mergePdfManager }), [focusedItem, deviceType, allTasks, handleNavigateToWGs, handleNavigateToDossiers, handleNavigateToReference, editPdfForm, openS4TViewer, onOpenS4TViewerRequest, onOpenPdfEditorRequest, onRefreshAfterAddDcmtToFavs, refreshKeyFormOrResult]);
317
+ } })] }) }), [inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, allowMultipleSelection, focusedItem, selectedItems, handleFocusedItemChanged, handleSelectedItemsChanged, handleNoRelationsFound, onItemContextMenu, contextMenuVisible, contextMenuPosition, refreshKey, focusedItemFormData, isRelationViewerLoading]);
318
+ 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, handleNavigateToReference: handleNavigateToReference, onRefreshAfterAddDcmtToFavs: onRefreshAfterAddDcmtToFavs, editPdfForm: editPdfForm, openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, onOpenPdfEditorRequest: onOpenPdfEditorRequest, onRefreshSearchResults: onRefreshAllPanels }), [focusedItem, deviceType, allTasks, handleNavigateToWGs, handleNavigateToDossiers, handleNavigateToReference, editPdfForm, openS4TViewer, onOpenS4TViewerRequest, onOpenPdfEditorRequest, onRefreshAfterAddDcmtToFavs, refreshKeyFormOrResult]);
309
319
  const initialPanelDimensions = {
310
320
  'tmTreeView': { width: '50%', height: '100%' },
311
321
  'tmFormOrResult': { width: '50%', height: '100%' },
@@ -382,7 +392,7 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
382
392
  toolbarOptions: { icon: _jsx(IconSearchCheck, { fontSize: 24 }), visible: false, orderNumber: 2, isActive: allInitialPanelVisibility['tmFormOrResult'] }
383
393
  }
384
394
  ], [tmTreeView, tmFormOrResult, focusedItem?.isDcmt, dtdMaster]);
385
- 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] })] }));
395
+ 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(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(TMPanelManagerProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: initialPanelDimensions, initialDimensions: initialPanelDimensions, initialMobilePanelId: 'tmTreeView', children: _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", showToolbar: true }) }) }), renderDcmtOperations, renderFloatingBar] })] }));
386
396
  };
387
397
  export default TMMasterDetailDcmts;
388
398
  /**
@@ -391,8 +401,37 @@ export default TMMasterDetailDcmts;
391
401
  * - Panel visibility toggling
392
402
  * - Focus delay handling
393
403
  */
394
- const TMRelationViewerWrapper = ({ refreshKey, inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, customItemRender, allowMultipleSelection, focusedItem, selectedItems, onFocusedItemChanged, onSelectedItemsChanged, onNoRelationsFound, onItemContextMenu, focusedItemFormData }) => {
404
+ const TMRelationViewerWrapper = ({ refreshKey, inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, customItemRender, allowMultipleSelection, focusedItem, selectedItems, onFocusedItemChanged, onSelectedItemsChanged, onNoRelationsFound, onItemContextMenu, focusedItemFormData, onLoadingStateChanged }) => {
395
405
  const { setPanelVisibilityById, setToolbarButtonVisibility } = useTMPanelManagerContext();
406
+ // Monitor device type changes to restore panel visibility when switching from mobile to desktop
407
+ const deviceType = useDeviceType();
408
+ const prevDeviceTypeRef = useRef(deviceType);
409
+ // Restore panel visibility when switching from mobile to desktop
410
+ useEffect(() => {
411
+ const prevDeviceType = prevDeviceTypeRef.current;
412
+ prevDeviceTypeRef.current = deviceType;
413
+ // When switching from mobile to desktop, restore panel visibility based on current focused item
414
+ if (prevDeviceType === DeviceType.MOBILE && deviceType !== DeviceType.MOBILE) {
415
+ // Small delay to let the panel manager complete its internal state update
416
+ setTimeout(() => {
417
+ // Force tmFormOrResult panel to be visible
418
+ setPanelVisibilityById('tmFormOrResult', true);
419
+ // Restore child panel visibility based on focused item
420
+ if (focusedItem?.isDcmt) {
421
+ setPanelVisibilityById('tmSearchResult', false);
422
+ setPanelVisibilityById('tmDcmtForm', true);
423
+ setToolbarButtonVisibility('tmSearchResult', false);
424
+ setToolbarButtonVisibility('tmDcmtForm', true);
425
+ }
426
+ else {
427
+ setPanelVisibilityById('tmSearchResult', true);
428
+ setPanelVisibilityById('tmDcmtForm', false);
429
+ setToolbarButtonVisibility('tmSearchResult', true);
430
+ setToolbarButtonVisibility('tmDcmtForm', false);
431
+ }
432
+ }, 50);
433
+ }
434
+ }, [deviceType, focusedItem, setPanelVisibilityById, setToolbarButtonVisibility]);
396
435
  // Handle focused item changes with panel visibility management
397
436
  const handleFocusedItemChanged = useCallback((item) => {
398
437
  onFocusedItemChanged?.(item);
@@ -422,13 +461,13 @@ const TMRelationViewerWrapper = ({ refreshKey, inputDcmts, isForMaster, showCurr
422
461
  onItemContextMenu?.(item, e);
423
462
  }, 100);
424
463
  }, [onItemContextMenu, handleFocusedItemChanged]);
425
- 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, showExpandAllButton: true, onNoRelationsFound: onNoRelationsFound, onItemContextMenu: onContextMenu, focusedItemFormData: focusedItemFormData }, refreshKey));
464
+ 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, showExpandAllButton: true, onNoRelationsFound: onNoRelationsFound, onItemContextMenu: onContextMenu, focusedItemFormData: focusedItemFormData, onLoadingStateChanged: onLoadingStateChanged }, refreshKey));
426
465
  };
427
- const TMFormOrResultWrapper = ({ refreshKey, deviceType, focusedItem, onTaskCreateRequest, allTasks = [], mergePdfManager, getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, onRefreshAfterAddDcmtToFavs, editPdfForm, openS4TViewer, onOpenS4TViewerRequest, onOpenPdfEditorRequest, onRefreshSearchAsyncDatagrid, onRefreshSearchResults, handleNavigateToReference }) => {
466
+ const TMFormOrResultWrapper = ({ refreshKey, deviceType, focusedItem, onTaskCreateRequest, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, onRefreshAfterAddDcmtToFavs, editPdfForm, openS4TViewer, onOpenS4TViewerRequest, onOpenPdfEditorRequest, onRefreshSearchAsyncDatagrid, onRefreshSearchResults, handleNavigateToReference, fetchRemoteCertificates }) => {
428
467
  const { setPanelVisibilityById } = useTMPanelManagerContext();
429
468
  return (_jsx(_Fragment, { children: focusedItem?.isDcmt ?
430
469
  _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, onReferenceClick: handleNavigateToReference, moreInfoTasks: getMoreInfoTasksForDocument(allTasks, focusedItem?.tid, focusedItem?.did), openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, onOpenPdfEditorRequest: onOpenPdfEditorRequest, datagridUtility: {
431
470
  onRefreshSearchAsyncDatagrid,
432
- } }, refreshKey) :
433
- _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, mergePdfManager: mergePdfManager, onReferenceClick: handleNavigateToReference }, refreshKey) }));
471
+ }, fetchRemoteCertificates: fetchRemoteCertificates }, refreshKey) :
472
+ focusedItem?.searchResult === undefined ? (_jsx(TMPanel, { title: SDKUI_Localizator.SearchResult, children: _jsx(TMToppyMessage, { message: SDKUI_Localizator.SelectDocumentToViewSearchResults }) })) : (_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, autoFocusFirstRow: 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, onReferenceClick: handleNavigateToReference, fetchRemoteCertificates: fetchRemoteCertificates }, refreshKey)) }));
434
473
  };
@@ -1,14 +1,13 @@
1
1
  import React from 'react';
2
2
  import { DcmtInfo } from '../../../ts';
3
- import { MergePdfManagerType } from '../../../helper';
4
3
  import { HomeBlogPost, TaskDescriptor } from '@topconsultnpm/sdk-ts';
5
4
  import { TMCopyToFolderMode } from '../../../hooks/useDocumentOperations';
6
5
  interface ITMMergeToPdfFormProps {
7
6
  mode: TMCopyToFolderMode;
8
7
  selectedDcmtInfos: Array<DcmtInfo>;
8
+ selectedItemsFull: Array<any>;
9
9
  onClose: () => void;
10
10
  showTMRelationViewer: boolean;
11
- mergePdfManager?: MergePdfManagerType;
12
11
  allTasks?: Array<TaskDescriptor>;
13
12
  getAllTasks?: () => Promise<void>;
14
13
  deleteTaskByIdsCallback?: (deletedTaskIds: Array<number>) => Promise<void>;
@@ -22,5 +21,5 @@ interface ITMMergeToPdfFormProps {
22
21
  * Condivide TMDownloadRelationViewerSection e gli helper in copyAndMergeDcmtsShared
23
22
  * con TMCopyToFolderForm.
24
23
  */
25
- declare const TMMergeToPdfForm: React.FC<ITMMergeToPdfFormProps>;
24
+ declare const TMMergeToPdfForm: (props: ITMMergeToPdfFormProps) => React.JSX.Element;
26
25
  export default TMMergeToPdfForm;
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useRef, useState } from 'react';
3
3
  import { DownloadTypes } from '../../../ts';
4
- import { calcResponsiveSizes, IconFolderOpen, IconPlay, IconUndo, isConvertibleToPdfExt, SDKUI_Globals, SDKUI_Localizator, } from '../../../helper';
4
+ import { calcResponsiveSizes, getExceptionMessage, IconFolderOpen, IconPlay, IconUndo, SDKUI_Globals, SDKUI_Localizator, } from '../../../helper';
5
5
  import { DcmtOpers, FileFormats, GeneralRetrieveFormats, ResultTypes, RetrieveFileOptions, ValidationItem, } from '@topconsultnpm/sdk-ts';
6
6
  import TMModal from '../../base/TMModal';
7
7
  import { useDeviceType } from '../../base/TMDeviceProvider';
@@ -12,20 +12,29 @@ import { TMLayoutWaitingContainer } from '../../base/TMWaitPanel';
12
12
  import { TMSplitterLayout } from '../../base/TMLayout';
13
13
  import { TMColors } from '../../../utils/theme';
14
14
  import TMDownloadRelationViewerSection from './TMDownloadRelationViewerSection';
15
- import { getDcmtInfosToDownload, getFloatingLabelStyle, isDirectoryPickerSupported, isPdfExt, MIN_PDF_FOR_MERGE, } from './copyAndMergeDcmtsShared';
15
+ import { getDcmtInfosToDownload, getFloatingLabelStyle, isDirectoryPickerSupported, MIN_PDF_FOR_MERGE, } from './copyAndMergeDcmtsShared';
16
+ import { createMetadataPdfFromDocument, getMergePdfSelectionStats, isMetadataOnlyDcmt } from './mergePdfUtils';
16
17
  import ShowAlert from '../../base/TMAlert';
17
18
  import TMTooltip from '../../base/TMTooltip';
19
+ import MergePdfManager from '../../../helper/MergePdfManager';
20
+ import { TMResultManager } from '../../forms/TMResultDialog';
18
21
  /**
19
22
  * Form per l'unione di più documenti PDF in un singolo file.
20
23
  * Condivide TMDownloadRelationViewerSection e gli helper in copyAndMergeDcmtsShared
21
24
  * con TMCopyToFolderForm.
22
25
  */
23
- const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationViewer, mergePdfManager, allTasks, getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers }) => {
26
+ const TMMergeToPdfForm = (props) => {
27
+ const { mode, selectedDcmtInfos, selectedItemsFull, onClose, showTMRelationViewer, allTasks, getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers } = props;
24
28
  const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync, } = useDcmtOperations();
25
29
  const deviceType = useDeviceType();
26
- const [pdfFileName, setPdfFileName] = useState('merged.pdf');
30
+ const [pdfFileName, setPdfFileName] = useState(`${SDKUI_Localizator.Result.toLowerCase()}.pdf`);
27
31
  const [destinationFolder, setDestinationFolder] = useState('Download');
28
32
  const [selectedItemsRelationViewer, setSelectedItemsRelationViewer] = useState([]);
33
+ // ---- Stato per il merge PDF (progress bar) ----
34
+ const [isMergingPdf, setIsMergingPdf] = useState(false);
35
+ const [mergeProgressText, setMergeProgressText] = useState('');
36
+ const [mergeProgressValue, setMergeProgressValue] = useState(0);
37
+ const [mergeProgressMax, setMergeProgressMax] = useState(0);
29
38
  // ---- Ref per la selezione cartella (File System Access API) ----
30
39
  const folderHandleRef = useRef(null);
31
40
  const skipSelectFolderRef = useRef(false);
@@ -73,36 +82,7 @@ const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationView
73
82
  pdfValidationItems.push(new ValidationItem(ResultTypes.ERROR, SDKUI_Localizator.PdfFileName, SDKUI_Localizator.RequiredField));
74
83
  }
75
84
  // ---- Statistiche selezione PDF / convertibili / non-PDF ----
76
- const convertibleSelectedItems = (() => {
77
- if (showTMRelationViewer) {
78
- return selectedItemsRelationViewer
79
- .filter(i => i.isDcmt && isConvertibleToPdfExt(i.fileExt))
80
- .map(i => ({ key: `${i.tid}_${i.did}`, ext: i.fileExt ?? undefined }));
81
- }
82
- return selectedDcmtInfos
83
- .filter(d => isConvertibleToPdfExt(d.FILEEXT))
84
- .map(d => ({ key: `${d.TID}_${d.DID}`, ext: d.FILEEXT }));
85
- })();
86
- const hasConvertibleSelected = convertibleSelectedItems.length > 0;
87
- const nonPdfSelectedItems = (() => {
88
- if (showTMRelationViewer) {
89
- return selectedItemsRelationViewer
90
- .filter(i => i.isDcmt && !isPdfExt(i.fileExt) && !isConvertibleToPdfExt(i.fileExt))
91
- .map(i => ({ key: `${i.tid}_${i.did}`, ext: i.fileExt ?? undefined }));
92
- }
93
- return selectedDcmtInfos
94
- .filter(d => !isPdfExt(d.FILEEXT) && !isConvertibleToPdfExt(d.FILEEXT))
95
- .map(d => ({ key: `${d.TID}_${d.DID}`, ext: d.FILEEXT }));
96
- })();
97
- const hasNonPdfSelected = nonPdfSelectedItems.length > 0;
98
- // Conteggio file unibili: PDF nativi + file convertibili
99
- const mergeableSelectedCount = (() => {
100
- if (showTMRelationViewer) {
101
- return selectedItemsRelationViewer.filter(i => i.isDcmt && (isPdfExt(i.fileExt) || isConvertibleToPdfExt(i.fileExt))).length;
102
- }
103
- return selectedDcmtInfos.filter(d => isPdfExt(d.FILEEXT) || isConvertibleToPdfExt(d.FILEEXT)).length;
104
- })();
105
- const hasEnoughPdfForMerge = mergeableSelectedCount >= MIN_PDF_FOR_MERGE;
85
+ const { convertibleSelectedItems, hasConvertibleSelected, nonPdfSelectedItems, hasNonPdfSelected, metadataOnlySelectedItems, hasMetadataOnlySelected, mergeableSelectedCount, hasEnoughPdfForMerge, } = getMergePdfSelectionStats(selectedDcmtInfos, selectedItemsFull, selectedItemsRelationViewer, showTMRelationViewer);
106
86
  const isFormValid = () => pdfValidationItems.length === 0;
107
87
  // ---- Recupero dei file PDF da unire (condiviso tra Esegui e Anteprima) ----
108
88
  const collectPdfFilesToMerge = async () => {
@@ -127,17 +107,81 @@ const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationView
127
107
  });
128
108
  return null;
129
109
  }
110
+ // Mappa per lookup veloce di FILECOUNT e FILEEXT da selectedItemsFull
111
+ const fileInfoMap = new Map(selectedItemsFull.map(d => [`${d.TID}_${d.DID}`, { fileExt: d.FILEEXT, fileCount: d.FILECOUNT }]));
112
+ // Mappa per i risultati: mantiene l'ordine originale
113
+ const pdfFilesMap = new Map();
114
+ // Identifica documenti di soli metadati e documenti con file
115
+ const metadataOnlyDcmts = [];
116
+ const dcmtsWithFile = [];
117
+ for (const dcmt of pdfDcmtInfosToDownload) {
118
+ const key = `${dcmt.TID}_${dcmt.DID}`;
119
+ const info = fileInfoMap.get(key);
120
+ if (isMetadataOnlyDcmt(info?.fileExt, info?.fileCount)) {
121
+ metadataOnlyDcmts.push(dcmt);
122
+ }
123
+ else {
124
+ dcmtsWithFile.push(dcmt);
125
+ }
126
+ }
127
+ // Per i documenti di soli metadati, genera PDF con createMetadataPdfFromDocument
128
+ // Raccoglie gli errori come downloadDcmtsAsync
129
+ const metadataConversionResults = [];
130
+ if (metadataOnlyDcmts.length > 0) {
131
+ setIsMergingPdf(true);
132
+ setMergeProgressMax(metadataOnlyDcmts.length);
133
+ setMergeProgressValue(0);
134
+ setMergeProgressText('Creazione PDF metadati...');
135
+ for (let i = 0; i < metadataOnlyDcmts.length; i++) {
136
+ const dcmt = metadataOnlyDcmts[i];
137
+ try {
138
+ setMergeProgressValue(i);
139
+ setMergeProgressText(`Creazione PDF metadati... (${i + 1}/${metadataOnlyDcmts.length})`);
140
+ const conversionResult = await createMetadataPdfFromDocument(dcmt);
141
+ if (conversionResult) {
142
+ pdfFilesMap.set(`${dcmt.TID}_${dcmt.DID}`, conversionResult.file);
143
+ metadataConversionResults.push({ rowIndex: i, id1: dcmt.TID, id2: dcmt.DID, resultType: ResultTypes.SUCCESS });
144
+ }
145
+ else {
146
+ // createMetadataPdfFromDocument ha restituito null (errore interno loggato)
147
+ metadataConversionResults.push({ rowIndex: i, id1: dcmt.TID, id2: dcmt.DID, resultType: ResultTypes.ERROR, description: 'Creazione PDF metadati fallita' });
148
+ }
149
+ }
150
+ catch (error) {
151
+ console.error(`Errore creazione PDF metadati per TID=${dcmt.TID}, DID=${dcmt.DID}`, error);
152
+ metadataConversionResults.push({ rowIndex: i, id1: dcmt.TID, id2: dcmt.DID, resultType: ResultTypes.ERROR, description: getExceptionMessage(error) });
153
+ }
154
+ }
155
+ setMergeProgressValue(metadataOnlyDcmts.length);
156
+ setIsMergingPdf(false);
157
+ // Mostra riepilogo errori se presenti (come downloadDcmtsAsync)
158
+ const hasErrors = metadataConversionResults.some(r => r.resultType === ResultTypes.ERROR);
159
+ if (hasErrors) {
160
+ TMResultManager.show(metadataConversionResults, 'Conversione PDF metadati', 'TID', 'DID', undefined, undefined, false);
161
+ }
162
+ }
163
+ // Per i documenti con file, usa il download normale
164
+ if (dcmtsWithFile.length > 0) {
165
+ const rfo = new RetrieveFileOptions();
166
+ rfo.retrieveReason = DcmtOpers.None;
167
+ rfo.generalRetrieveFormat = GeneralRetrieveFormats.OriginalUnsigned;
168
+ rfo.cvtFormat = FileFormats.PDF;
169
+ rfo.invoiceRetrieveFormat = SDKUI_Globals.userSettings?.searchSettings.invoiceRetrieveFormat;
170
+ rfo.orderRetrieveFormat = SDKUI_Globals.userSettings?.searchSettings.orderRetrieveFormat;
171
+ const collectFileForMerge = async (file, dcmtInfo) => {
172
+ pdfFilesMap.set(`${dcmtInfo.TID}_${dcmtInfo.DID}`, file);
173
+ };
174
+ await downloadDcmtsAsync({ inputDcmts: dcmtsWithFile, downloadType: DownloadTypes.Dcmt, downloadMode: 'download', onFileDownloaded: collectFileForMerge, skipConfirmation: true, retrieveOptions: rfo, useCache: false });
175
+ }
176
+ // Ricostruisci l'array pdfFiles nell'ordine originale di selezione
130
177
  const pdfFiles = [];
131
- const rfo = new RetrieveFileOptions();
132
- rfo.retrieveReason = DcmtOpers.None;
133
- rfo.generalRetrieveFormat = GeneralRetrieveFormats.OriginalUnsigned;
134
- rfo.cvtFormat = FileFormats.PDF;
135
- rfo.invoiceRetrieveFormat = SDKUI_Globals.userSettings?.searchSettings.invoiceRetrieveFormat;
136
- rfo.orderRetrieveFormat = SDKUI_Globals.userSettings?.searchSettings.orderRetrieveFormat;
137
- const collectFileForMerge = async (file, _dcmtInfo) => {
138
- pdfFiles.push(file);
139
- };
140
- await downloadDcmtsAsync(pdfDcmtInfosToDownload, DownloadTypes.Dcmt, 'download', collectFileForMerge, undefined, true, rfo, false);
178
+ for (const dcmt of pdfDcmtInfosToDownload) {
179
+ const key = `${dcmt.TID}_${dcmt.DID}`;
180
+ const file = pdfFilesMap.get(key);
181
+ if (file) {
182
+ pdfFiles.push(file);
183
+ }
184
+ }
141
185
  if (pdfFiles.length === 0) {
142
186
  TMMessageBoxManager.show({ message: SDKUI_Localizator.NoFilesAvailableForMerge, buttons: [ButtonNames.OK] });
143
187
  return null;
@@ -150,18 +194,25 @@ const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationView
150
194
  TMMessageBoxManager.show({ message: SDKUI_Localizator.PleaseCorrectErrorsBeforeProceeding, buttons: [ButtonNames.OK] });
151
195
  return;
152
196
  }
153
- if (!mergePdfManager) {
154
- TMMessageBoxManager.show({ message: SDKUI_Localizator.PdfMergeFeatureNotAvailable, buttons: [ButtonNames.OK] });
155
- return;
156
- }
157
197
  const pdfFiles = await collectPdfFilesToMerge();
158
198
  if (!pdfFiles)
159
199
  return;
160
200
  const finalName = pdfFileName.trim().toLowerCase().endsWith('.pdf') ? pdfFileName.trim() : pdfFileName.trim() + '.pdf';
201
+ // Inizializza progress bar per il merge
202
+ setIsMergingPdf(true);
203
+ setMergeProgressMax(pdfFiles.length);
204
+ setMergeProgressValue(0);
205
+ setMergeProgressText(SDKUI_Localizator.MergeToPdf);
161
206
  try {
207
+ const mergeOptions = {
208
+ onProgress: (current, total, file) => {
209
+ setMergeProgressValue(current);
210
+ setMergeProgressText(`${SDKUI_Localizator.MergeToPdf}: ${file.name}`);
211
+ }
212
+ };
162
213
  // Se c'è una cartella selezionata (non Download di default), salva direttamente nella cartella
163
214
  if (folderHandleRef.current) {
164
- const mergedFile = await mergePdfManager.mergeToFile(pdfFiles, finalName);
215
+ const mergedFile = await MergePdfManager.mergeToFile(pdfFiles, finalName, mergeOptions);
165
216
  const fileHandle = await folderHandleRef.current.getFileHandle(finalName, { create: true });
166
217
  const writable = await fileHandle.createWritable();
167
218
  await writable.write(mergedFile);
@@ -170,7 +221,7 @@ const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationView
170
221
  }
171
222
  else {
172
223
  // Altrimenti usa il download standard del browser
173
- await mergePdfManager.mergeAndDownload(pdfFiles, finalName);
224
+ await MergePdfManager.mergeAndDownload(pdfFiles, finalName, mergeOptions);
174
225
  ShowAlert({ message: SDKUI_Localizator.PdfMergedSavedInFolder.replaceParams('Download'), mode: 'success', duration: 5000, title: SDKUI_Localizator.MergeToPdf });
175
226
  }
176
227
  }
@@ -179,6 +230,9 @@ const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationView
179
230
  TMMessageBoxManager.show({ message: SDKUI_Localizator.PdfMergeError, buttons: [ButtonNames.OK] });
180
231
  return;
181
232
  }
233
+ finally {
234
+ setIsMergingPdf(false);
235
+ }
182
236
  onClose();
183
237
  };
184
238
  // ---- Render della sezione configurazione (solo PDF file name + warning) ----
@@ -228,7 +282,7 @@ const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationView
228
282
  width: 'max-content',
229
283
  backgroundColor: TMColors.default_background,
230
284
  zIndex: 1,
231
- }, children: SDKUI_Localizator.Path }), _jsxs("div", { style: { border: `1px solid ${TMColors.border_normal}`, borderRadius: '5px', padding: '4px 10px 4px 13px', display: 'flex', alignItems: 'center', gap: '8px', backgroundColor: '#fafafa' }, children: [_jsx(IconFolderOpen, {}), _jsx("span", { style: { fontSize: '0.9rem', color: '#333' }, children: "Download" })] }), _jsx("span", { style: { fontSize: '0.8rem', color: '#888', fontStyle: 'italic', marginTop: '4px', display: 'block' }, children: SDKUI_Localizator.BrowserDoesNotSupportFolderSelection })] }) })), _jsx("div", { style: { flex: '1.5 1 420px', minWidth: '350px', width: '100%' }, children: _jsx(TMTextBox, { label: SDKUI_Localizator.PdfFileName, value: pdfFileName, validationItems: pdfValidationItems, autoComplete: "one-time-code", onValueChanged: (e) => setPdfFileName(e.target.value) }) })] }), (hasConvertibleSelected || !hasEnoughPdfForMerge || hasNonPdfSelected) && (_jsxs("div", { style: {
285
+ }, children: SDKUI_Localizator.Path }), _jsxs("div", { style: { border: `1px solid ${TMColors.border_normal}`, borderRadius: '5px', padding: '4px 10px 4px 13px', display: 'flex', alignItems: 'center', gap: '8px', backgroundColor: '#fafafa' }, children: [_jsx(IconFolderOpen, {}), _jsx("span", { style: { fontSize: '0.9rem', color: '#333' }, children: "Download" })] }), _jsx("span", { style: { fontSize: '0.8rem', color: '#888', fontStyle: 'italic', marginTop: '4px', display: 'block' }, children: SDKUI_Localizator.BrowserDoesNotSupportFolderSelection })] }) })), _jsx("div", { style: { flex: '1.5 1 420px', minWidth: '350px', width: '100%' }, children: _jsx(TMTextBox, { label: SDKUI_Localizator.PdfFileName, value: pdfFileName, validationItems: pdfValidationItems, autoComplete: "one-time-code", onValueChanged: (e) => setPdfFileName(e.target.value) }) })] }), (hasConvertibleSelected || hasMetadataOnlySelected || !hasEnoughPdfForMerge || hasNonPdfSelected) && (_jsxs("div", { style: {
232
286
  display: 'flex',
233
287
  flexDirection: 'column',
234
288
  gap: '6px',
@@ -248,14 +302,19 @@ const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationView
248
302
  borderBottom: '1px solid #e0e0e0',
249
303
  paddingBottom: '6px',
250
304
  marginBottom: '2px'
251
- }, children: SDKUI_Localizator.NotesAndWarnings }), _jsxs("ul", { style: { margin: 0, paddingLeft: '18px', display: 'flex', flexDirection: 'column', gap: '4px' }, children: [hasConvertibleSelected && (_jsx("li", { style: { color: '#00527a' }, children: (() => {
252
- const extSet = Array.from(new Set(convertibleSelectedItems.map(i => (i.ext ?? '').toString().trim().toLowerCase().replace(/^\./, '')).filter(e => e.length > 0)));
305
+ }, children: SDKUI_Localizator.NotesAndWarnings }), _jsxs("ul", { style: { margin: 0, paddingLeft: '18px', display: 'flex', flexDirection: 'column', gap: '4px' }, children: [(hasConvertibleSelected || hasMetadataOnlySelected) && (_jsx("li", { style: { color: '#00527a' }, children: (() => {
306
+ // Combina convertibili + metadataOnly
307
+ const allConvertible = [...convertibleSelectedItems, ...metadataOnlySelectedItems];
308
+ const extSet = Array.from(new Set([
309
+ ...convertibleSelectedItems.map(i => (i.ext ?? '').toString().trim().toLowerCase().replace(/^\./, '')).filter(e => e.length > 0),
310
+ ...(hasMetadataOnlySelected ? ['metadati'] : [])
311
+ ]));
253
312
  const extLabel = extSet.length > 0
254
313
  ? ` (${extSet.map(e => '.' + e).join(', ')})`
255
314
  : '';
256
- return convertibleSelectedItems.length === 1
315
+ return allConvertible.length === 1
257
316
  ? SDKUI_Localizator.DocumentWillBeConvertedDuringMerge.replaceParams(extLabel)
258
- : SDKUI_Localizator.DocumentsWillBeConvertedDuringMerge.replaceParams(convertibleSelectedItems.length.toString(), extLabel);
317
+ : SDKUI_Localizator.DocumentsWillBeConvertedDuringMerge.replaceParams(allConvertible.length.toString(), extLabel);
259
318
  })() })), !hasEnoughPdfForMerge && (_jsx("li", { style: { color: '#7a5d00' }, children: mergeableSelectedCount === 0
260
319
  ? SDKUI_Localizator.NoPdfOrConvertibleFilesSelected_Param.replaceParams(MIN_PDF_FOR_MERGE.toString())
261
320
  : SDKUI_Localizator.OnlyOnePdfOrConvertibleFileSelected.replaceParams(MIN_PDF_FOR_MERGE.toString()) })), hasNonPdfSelected && (_jsx("li", { style: { color: '#7a5d00' }, children: (() => {
@@ -265,7 +324,7 @@ const TMMergeToPdfForm = ({ mode, selectedDcmtInfos, onClose, showTMRelationView
265
324
  ? SDKUI_Localizator.FileNotPdfWillBeExcluded.replaceParams(extLabel)
266
325
  : SDKUI_Localizator.FilesNotPdfWillBeExcluded.replaceParams(nonPdfSelectedItems.length.toString(), extLabel);
267
326
  })() }))] })] }))] })] }));
268
- return (_jsx(TMModal, { width: calcResponsiveSizes(deviceType, showTMRelationViewer ? '90%' : '500px', showTMRelationViewer ? '90%' : '500px', '95%'), height: showTMRelationViewer ? '95%' : 'auto', title: getTitle(), onClose: onClose, showCloseButton: true, 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: _jsxs("div", { onContextMenu: (e) => e.preventDefault(), style: { display: 'flex', flexDirection: 'column', gap: '16px', padding: '16px', width: '100%', height: '100%', boxSizing: 'border-box', overflow: 'hidden' }, children: [showTMRelationViewer ? (_jsx("div", { style: { flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column' }, children: _jsxs(TMSplitterLayout, { direction: 'vertical', showSeparator: true, separatorSize: 8, separatorColor: 'transparent', separatorActiveColor: 'transparent', overflow: 'hidden', min: ["50", "50"], start: ["70%", "30%"], children: [_jsx(TMDownloadRelationViewerSection, { selectedDcmtInfos: selectedDcmtInfos, onSelectionChanged: setSelectedItemsRelationViewer, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }), configSection] }, "TMMergeToPdf-relation-config") })) : (configSection), _jsx("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center', flexShrink: 0, marginTop: '12px' }, children: _jsxs("button", { disabled: !isFormValid() || (showTMRelationViewer && selectedItemsRelationViewer.filter(i => i.isDcmt).length === 0) || !hasEnoughPdfForMerge, onClick: run, style: {
327
+ return (_jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel || isMergingPdf, showWaitPanelPrimary: isMergingPdf ? true : showPrimary, showWaitPanelSecondary: isMergingPdf ? false : showSecondary, waitPanelTitle: isMergingPdf ? SDKUI_Localizator.MergeToPdf : waitPanelTitle, waitPanelTextPrimary: isMergingPdf ? mergeProgressText : waitPanelTextPrimary, waitPanelValuePrimary: isMergingPdf ? mergeProgressValue : waitPanelValuePrimary, waitPanelMaxValuePrimary: isMergingPdf ? mergeProgressMax : waitPanelMaxValuePrimary, waitPanelTextSecondary: isMergingPdf ? '' : waitPanelTextSecondary, waitPanelValueSecondary: isMergingPdf ? 0 : waitPanelValueSecondary, waitPanelMaxValueSecondary: isMergingPdf ? 0 : waitPanelMaxValueSecondary, isCancelable: !isMergingPdf, abortController: abortController, usePortal: true, children: _jsx(TMModal, { width: calcResponsiveSizes(deviceType, showTMRelationViewer ? '90%' : '500px', showTMRelationViewer ? '90%' : '500px', '95%'), height: showTMRelationViewer ? '95%' : 'auto', title: getTitle(), onClose: onClose, showCloseButton: true, children: _jsxs("div", { onContextMenu: (e) => e.preventDefault(), style: { display: 'flex', flexDirection: 'column', gap: '16px', padding: '16px', width: '100%', height: '100%', boxSizing: 'border-box', overflow: 'hidden' }, children: [showTMRelationViewer ? (_jsx("div", { style: { flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column' }, children: _jsxs(TMSplitterLayout, { direction: 'vertical', showSeparator: true, separatorSize: 8, separatorColor: 'transparent', separatorActiveColor: 'transparent', overflow: 'hidden', min: ["50", "50"], start: ["70%", "30%"], children: [_jsx(TMDownloadRelationViewerSection, { selectedDcmtInfos: selectedDcmtInfos, onSelectionChanged: setSelectedItemsRelationViewer, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }), configSection] }, "TMMergeToPdf-relation-config") })) : (configSection), _jsx("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center', flexShrink: 0, marginTop: '12px' }, children: _jsxs("button", { disabled: !isFormValid() || (showTMRelationViewer && selectedItemsRelationViewer.filter(i => i.isDcmt).length === 0) || !hasEnoughPdfForMerge, onClick: run, style: {
269
328
  display: 'flex',
270
329
  alignItems: 'center',
271
330
  justifyContent: 'center',
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { DcmtTypeDescriptor, SearchResultDescriptor, DataColumnDescriptor } from "@topconsultnpm/sdk-ts";
3
+ import { DcmtMetadataMap } from '../../../helper';
3
4
  import { DcmtInfo, MetadataValueDescriptorEx } from '../../../ts';
4
5
  import { ITMTreeItem } from '../../base/TMTreeView';
5
6
  /**
@@ -19,7 +20,7 @@ export interface RelationTreeItem extends ITMTreeItem {
19
20
  isSeparator?: boolean;
20
21
  isInfoMessage?: boolean;
21
22
  isLogDel?: number;
22
- values?: any;
23
+ values?: DcmtMetadataMap;
23
24
  searchResult?: SearchResultDescriptor[];
24
25
  itemsCount?: number;
25
26
  fileExt?: string;
@@ -72,7 +73,10 @@ export interface TMRelationViewerProps {
72
73
  * Value rendering respects DataDomain (uses TMDataListItemViewer for lists, TMDataUserIdItemViewer for users, etc.)
73
74
  */
74
75
  showMetadataNames?: boolean;
75
- /** Maximum depth level for recursive loading (default: 2) */
76
+ /**
77
+ * Maximum depth level for recursive loading (default: 2).
78
+ * Use 0 for unlimited depth (expand as much as possible).
79
+ */
76
80
  maxDepthLevel?: number;
77
81
  /**
78
82
  * If true (default), when isForMaster=true shows: detail doc → master docs as children (inverted navigation)
@@ -122,6 +126,11 @@ export interface TMRelationViewerProps {
122
126
  * (root container + first document + first correlation folder).
123
127
  */
124
128
  defaultExpandAll?: boolean;
129
+ /**
130
+ * Callback invoked when loading state changes.
131
+ * Useful to disable interactions (like context menu) during loading.
132
+ */
133
+ onLoadingStateChanged?: (isLoading: boolean) => void;
125
134
  }
126
135
  /**
127
136
  * Check if document type has detail relations
@@ -131,14 +140,6 @@ export declare const hasDetailRelations: (mTID: number | undefined) => Promise<b
131
140
  * Check if document type has master relations
132
141
  */
133
142
  export declare const hasMasterRelations: (dTID: number | undefined) => Promise<boolean>;
134
- /**
135
- * Get metadata keys excluding system metadata
136
- */
137
- export declare const getMetadataKeys: (obj: any) => string[];
138
- /**
139
- * Get display value keys for a document (max 5, prioritize SYS_Abstract)
140
- */
141
- export declare const getDcmtDisplayValue: (obj: any) => string[];
142
143
  /**
143
144
  * Get display value formatted by column type
144
145
  */
@@ -147,5 +148,6 @@ export declare const getDisplayValueByColumn: (col: DataColumnDescriptor | undef
147
148
  * Convert SearchResultDescriptor to structured data source with metadata
148
149
  */
149
150
  export declare const searchResultToDataSource: (searchResult: SearchResultDescriptor | undefined, hideSysMetadata?: boolean) => Promise<any[]>;
151
+ export declare const DEFAULT_RELATION_EXPAND_LEVEL = 4;
150
152
  declare const TMRelationViewer: React.FC<TMRelationViewerProps>;
151
153
  export default TMRelationViewer;