@topconsultnpm/sdkui-react 6.22.0-dev2.9 → 6.22.0-dev3.11

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 (314) hide show
  1. package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +3 -3
  2. package/lib/components/NewComponents/ContextMenu/hooks.d.ts +1 -1
  3. package/lib/components/NewComponents/ContextMenu/styles.d.ts +45 -43
  4. package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.js +6 -6
  5. package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +80 -73
  6. package/lib/components/base/Styled.d.ts +93 -77
  7. package/lib/components/base/Styled.js +7 -5
  8. package/lib/components/base/TMAccordionNew.js +7 -7
  9. package/lib/components/base/TMAlert.d.ts +32 -32
  10. package/lib/components/base/TMAreaManager.js +1 -1
  11. package/lib/components/base/TMButton.js +4 -4
  12. package/lib/components/base/TMClosableList.js +3 -3
  13. package/lib/components/base/TMCounterBar.d.ts +2 -2
  14. package/lib/components/base/TMCounterContainer.d.ts +2 -1
  15. package/lib/components/base/TMCustomButton.d.ts +1 -1
  16. package/lib/components/base/TMCustomButton.js +1 -1
  17. package/lib/components/base/TMDataGrid.d.ts +4 -0
  18. package/lib/components/base/TMDataGrid.js +292 -12
  19. package/lib/components/base/TMDataGridExportForm.d.ts +2 -1
  20. package/lib/components/base/TMDropDownMenu.js +1 -1
  21. package/lib/components/base/TMEditorBase.d.ts +2 -0
  22. package/lib/components/base/TMFileManager.d.ts +2 -1
  23. package/lib/components/base/TMFileManager.js +5 -3
  24. package/lib/components/base/TMFileManagerDataGridView.d.ts +2 -1
  25. package/lib/components/base/TMFileManagerDataGridView.js +12 -3
  26. package/lib/components/base/TMFileManagerThumbnailItems.d.ts +1 -1
  27. package/lib/components/base/TMFileManagerThumbnailItems.js +20 -10
  28. package/lib/components/base/TMFileManagerThumbnailsView.d.ts +1 -1
  29. package/lib/components/base/TMFileManagerUtils.d.ts +6 -6
  30. package/lib/components/base/TMFileManagerUtils.js +37 -1
  31. package/lib/components/base/TMLayout.d.ts +6 -6
  32. package/lib/components/base/TMLayout.js +3 -3
  33. package/lib/components/base/TMList.d.ts +2 -1
  34. package/lib/components/base/TMList.js +1 -1
  35. package/lib/components/base/TMListView.d.ts +1 -1
  36. package/lib/components/base/TMListView.js +3 -3
  37. package/lib/components/base/TMModal.d.ts +11 -0
  38. package/lib/components/base/TMModal.js +47 -13
  39. package/lib/components/base/TMPanel.d.ts +6 -0
  40. package/lib/components/base/TMPanel.js +224 -111
  41. package/lib/components/base/TMPopUp.js +5 -2
  42. package/lib/components/base/TMResizableMenu.js +2 -2
  43. package/lib/components/base/TMRightSidebar.js +1 -1
  44. package/lib/components/base/TMShowAllOrMaxItemsButton.js +1 -1
  45. package/lib/components/base/TMSpinner.d.ts +2 -1
  46. package/lib/components/base/TMSpinner.js +2 -2
  47. package/lib/components/base/TMTab.d.ts +4 -3
  48. package/lib/components/base/TMTab.js +2 -2
  49. package/lib/components/base/TMTabControl.d.ts +101 -0
  50. package/lib/components/base/TMTabControl.js +653 -0
  51. package/lib/components/base/TMToggleButton.js +2 -2
  52. package/lib/components/base/TMToolbarCard.js +3 -3
  53. package/lib/components/base/TMTooltip.d.ts +2 -1
  54. package/lib/components/base/TMTooltip.js +24 -8
  55. package/lib/components/base/TMTreeView.d.ts +14 -8
  56. package/lib/components/base/TMTreeView.js +123 -70
  57. package/lib/components/base/TMUserAvatar.d.ts +2 -1
  58. package/lib/components/base/TMVilViewer.d.ts +2 -1
  59. package/lib/components/base/TMWaitPanel.d.ts +3 -2
  60. package/lib/components/base/TMWaitPanel.js +2 -2
  61. package/lib/components/choosers/TMCultureIDPicker.js +2 -2
  62. package/lib/components/choosers/TMDataListItemChooser.js +1 -1
  63. package/lib/components/choosers/TMDataListItemPicker.js +2 -2
  64. package/lib/components/choosers/TMDcmtTypeChooser.js +5 -4
  65. package/lib/components/choosers/TMDiskChooser.js +1 -1
  66. package/lib/components/choosers/TMDistinctValues.d.ts +9 -7
  67. package/lib/components/choosers/TMDistinctValues.js +157 -141
  68. package/lib/components/choosers/TMDynDataListItemChooser.d.ts +1 -1
  69. package/lib/components/choosers/TMDynDataListItemChooser.js +1 -1
  70. package/lib/components/choosers/TMImageIDChooser.js +1 -1
  71. package/lib/components/choosers/TMInvoiceRetrieveFormats.d.ts +2 -1
  72. package/lib/components/choosers/TMMetadataChooser.js +3 -3
  73. package/lib/components/choosers/TMOrderRetrieveFormats.d.ts +2 -1
  74. package/lib/components/choosers/TMQuickSearchInfo.d.ts +13 -0
  75. package/lib/components/choosers/TMQuickSearchInfo.js +279 -0
  76. package/lib/components/choosers/TMQuickSearchSettingsForm.d.ts +16 -0
  77. package/lib/components/choosers/TMQuickSearchSettingsForm.js +94 -0
  78. package/lib/components/choosers/TMRelationChooser.d.ts +3 -3
  79. package/lib/components/choosers/TMRelationChooser.js +1 -1
  80. package/lib/components/choosers/TMSelectedValuesSummary.d.ts +13 -0
  81. package/lib/components/choosers/TMSelectedValuesSummary.js +89 -0
  82. package/lib/components/choosers/TMUserChooser.d.ts +2 -2
  83. package/lib/components/choosers/TMUserChooser.js +1 -1
  84. package/lib/components/editors/TMCheckBox.js +1 -1
  85. package/lib/components/editors/TMDropDown.d.ts +3 -0
  86. package/lib/components/editors/TMDropDown.js +197 -5
  87. package/lib/components/editors/TMEditorStyled.d.ts +21 -43
  88. package/lib/components/editors/TMFormulaEditor.d.ts +1 -1
  89. package/lib/components/editors/TMFormulaEditor.js +1 -1
  90. package/lib/components/editors/TMHtmlContentDisplay.d.ts +2 -1
  91. package/lib/components/editors/TMHtmlContentDisplay.js +1 -1
  92. package/lib/components/editors/TMHtmlEditor.d.ts +2 -1
  93. package/lib/components/editors/TMLocalizedTextBox.js +1 -1
  94. package/lib/components/editors/TMMetadataValues.js +6 -6
  95. package/lib/components/editors/TMRadioButton.js +2 -2
  96. package/lib/components/editors/TMSummary.js +3 -3
  97. package/lib/components/editors/TMTextArea.js +3 -3
  98. package/lib/components/editors/TMTextBox.js +3 -3
  99. package/lib/components/editors/TMTextExpression.js +1 -1
  100. package/lib/components/editors/TMTreeDropDown.d.ts +1 -1
  101. package/lib/components/features/archive/TMArchive.js +17 -3
  102. package/lib/components/features/assistant/TMToppyDraggableHelpCenter.d.ts +1 -1
  103. package/lib/components/features/assistant/TMToppyDraggableHelpCenter.js +2 -2
  104. package/lib/components/features/assistant/TMToppySpeechBubble.js +1 -1
  105. package/lib/components/features/blog/TMBlogCommentForm.d.ts +2 -1
  106. package/lib/components/features/documents/TMBatchUpdateForm.js +20 -6
  107. package/lib/components/features/documents/TMCopyToFolderForm.js +61 -22
  108. package/lib/components/features/documents/TMDcmtBlog.d.ts +3 -0
  109. package/lib/components/features/documents/TMDcmtBlog.js +4 -4
  110. package/lib/components/features/documents/TMDcmtForm.d.ts +7 -0
  111. package/lib/components/features/documents/TMDcmtForm.js +181 -54
  112. package/lib/components/features/documents/TMDcmtFormActionButtons.d.ts +12 -1
  113. package/lib/components/features/documents/TMDcmtFormActionButtons.js +79 -9
  114. package/lib/components/features/documents/TMDcmtIcon.d.ts +2 -1
  115. package/lib/components/features/documents/TMDcmtIcon.js +5 -3
  116. package/lib/components/features/documents/TMDcmtPreview.d.ts +8 -6
  117. package/lib/components/features/documents/TMDcmtPreview.js +12 -8
  118. package/lib/components/features/documents/TMDcmtTasks.d.ts +2 -1
  119. package/lib/components/features/documents/TMDownloadRelationViewerSection.js +1 -1
  120. package/lib/components/features/documents/TMDragDropOverlay.d.ts +1 -1
  121. package/lib/components/features/documents/TMFileUploader.js +28 -28
  122. package/lib/components/features/documents/TMMasterDetailDcmts.js +116 -34
  123. package/lib/components/features/documents/TMMasterInfoFields.d.ts +20 -0
  124. package/lib/components/features/documents/TMMasterInfoFields.js +184 -0
  125. package/lib/components/features/documents/TMMergeToPdfForm.d.ts +3 -3
  126. package/lib/components/features/documents/TMMergeToPdfForm.js +42 -10
  127. package/lib/components/features/documents/TMMultiMasterDetailDcmtsForm.d.ts +46 -0
  128. package/lib/components/features/documents/TMMultiMasterDetailDcmtsForm.js +321 -0
  129. package/lib/components/features/documents/TMMultiMasterDetailDcmtsUtils.d.ts +370 -0
  130. package/lib/components/features/documents/TMMultiMasterDetailDcmtsUtils.js +283 -0
  131. package/lib/components/features/documents/TMRelationViewer.d.ts +24 -3
  132. package/lib/components/features/documents/TMRelationViewer.js +110 -52
  133. package/lib/components/features/documents/copyAndMergeDcmtsShared.d.ts +1 -1
  134. package/lib/components/features/search/TMDcmtCheckoutInfoForm.d.ts +2 -1
  135. package/lib/components/features/search/TMMetadataOutputForm.d.ts +2 -1
  136. package/lib/components/features/search/TMMetadataOutputForm.js +1 -1
  137. package/lib/components/features/search/TMMetadataSorterForm.d.ts +2 -1
  138. package/lib/components/features/search/TMMetadataSorterForm.js +1 -1
  139. package/lib/components/features/search/TMSavedQuerySelector.d.ts +2 -2
  140. package/lib/components/features/search/TMSavedQuerySelector.js +2 -2
  141. package/lib/components/features/search/TMSearch.d.ts +1 -1
  142. package/lib/components/features/search/TMSearch.js +146 -21
  143. package/lib/components/features/search/TMSearchQueryEditor.js +7 -5
  144. package/lib/components/features/search/TMSearchQueryPanel.d.ts +13 -3
  145. package/lib/components/features/search/TMSearchQueryPanel.js +142 -68
  146. package/lib/components/features/search/TMSearchResult.d.ts +16 -0
  147. package/lib/components/features/search/TMSearchResult.js +517 -188
  148. package/lib/components/features/search/TMSearchResultFloatingActionButton.d.ts +1 -1
  149. package/lib/components/features/search/TMSignatureInfoContent.d.ts +2 -1
  150. package/lib/components/features/search/TMSignatureInfoContent.js +1 -1
  151. package/lib/components/features/search/TMTreeSelector.js +121 -70
  152. package/lib/components/features/search/TMViewHistoryDcmt.d.ts +2 -1
  153. package/lib/components/features/tasks/TMTaskForm.d.ts +1 -1
  154. package/lib/components/features/tasks/TMTaskForm.js +1 -1
  155. package/lib/components/features/tasks/TMTaskFormUtils.d.ts +10 -10
  156. package/lib/components/features/tasks/TMTaskFormUtils.js +3 -3
  157. package/lib/components/features/tasks/TMTasksAgenda.d.ts +1 -1
  158. package/lib/components/features/tasks/TMTasksAgenda.js +1 -1
  159. package/lib/components/features/tasks/TMTasksCalendar.d.ts +1 -1
  160. package/lib/components/features/tasks/TMTasksCalendar.js +1 -1
  161. package/lib/components/features/tasks/TMTasksHeader.d.ts +1 -1
  162. package/lib/components/features/tasks/TMTasksHeader.js +1 -1
  163. package/lib/components/features/tasks/TMTasksPanelContent.d.ts +1 -1
  164. package/lib/components/features/tasks/TMTasksUtilsView.d.ts +5 -5
  165. package/lib/components/features/tasks/TMTasksUtilsView.js +1 -1
  166. package/lib/components/features/tasks/TMTasksView.d.ts +1 -1
  167. package/lib/components/features/tasks/TMTasksView.js +7 -13
  168. package/lib/components/features/wg/TMWGsCopyMoveForm.d.ts +3 -2
  169. package/lib/components/features/wg/TMWGsCopyMoveForm.js +1 -1
  170. package/lib/components/features/workflow/TMWorkflowPopup.d.ts +18 -7
  171. package/lib/components/features/workflow/TMWorkflowPopup.js +9 -5
  172. package/lib/components/features/workflow/diagram/ConnectionComponent.js +3 -3
  173. package/lib/components/features/workflow/diagram/DiagramItemComponent.js +3 -3
  174. package/lib/components/features/workflow/diagram/DiagramItemForm.js +1 -1
  175. package/lib/components/features/workflow/diagram/DiagramItemSvgContent.js +1 -1
  176. package/lib/components/features/workflow/diagram/RecipientList.js +1 -1
  177. package/lib/components/features/workflow/diagram/WFDiagram.js +4 -4
  178. package/lib/components/features/workflow/diagram/WorkitemRecipientsEditor.d.ts +3 -1
  179. package/lib/components/forms/Login/ChangePasswordInputs.d.ts +3 -1
  180. package/lib/components/forms/Login/Chooser.d.ts +2 -2
  181. package/lib/components/forms/Login/Menu.js +1 -1
  182. package/lib/components/forms/Login/OTPReader.js +1 -1
  183. package/lib/components/forms/Login/PasswordStrengthChecker.js +1 -1
  184. package/lib/components/forms/Login/RapidAccessLogin.js +2 -2
  185. package/lib/components/forms/Login/RecoverPasswordFlow.js +2 -2
  186. package/lib/components/forms/Login/SelectBox.js +1 -1
  187. package/lib/components/forms/Login/StepIndicator.js +1 -1
  188. package/lib/components/forms/Login/TMLoginForm.js +7 -7
  189. package/lib/components/forms/Login/TextBox.js +1 -1
  190. package/lib/components/forms/TMApplyForm.js +3 -3
  191. package/lib/components/forms/TMChooserForm.d.ts +2 -1
  192. package/lib/components/forms/TMChooserForm.js +1 -1
  193. package/lib/components/forms/TMSaveForm.d.ts +4 -4
  194. package/lib/components/forms/TMSaveForm.js +3 -3
  195. package/lib/components/grids/TMBlogAttachments.d.ts +2 -1
  196. package/lib/components/grids/TMBlogAttachments.js +14 -3
  197. package/lib/components/grids/TMBlogHeader.d.ts +1 -1
  198. package/lib/components/grids/TMBlogHeader.js +5 -1
  199. package/lib/components/grids/TMBlogsPost.d.ts +3 -1
  200. package/lib/components/grids/TMBlogsPost.js +31 -4
  201. package/lib/components/grids/TMBlogsPostUtils.d.ts +10 -9
  202. package/lib/components/grids/TMBlogsPostUtils.js +15 -4
  203. package/lib/components/grids/TMRecentsManager.js +4 -4
  204. package/lib/components/grids/TMValidationItemsList.d.ts +2 -1
  205. package/lib/components/grids/TMValidationItemsList.js +1 -1
  206. package/lib/components/index.d.ts +2 -0
  207. package/lib/components/index.js +2 -0
  208. package/lib/components/layout/panelManager/TMPanelManagerContainer.d.ts +3 -1
  209. package/lib/components/layout/panelManager/TMPanelManagerContainer.js +25 -15
  210. package/lib/components/layout/panelManager/TMPanelManagerContext.d.ts +2 -2
  211. package/lib/components/layout/panelManager/TMPanelManagerContext.js +68 -93
  212. package/lib/components/layout/panelManager/TMPanelManagerToolbar.d.ts +5 -6
  213. package/lib/components/layout/panelManager/TMPanelManagerToolbar.js +1 -1
  214. package/lib/components/layout/panelManager/TMPanelManagerWithPersistenceProvider.d.ts +2 -2
  215. package/lib/components/layout/panelManager/TMPanelWrapper.d.ts +2 -2
  216. package/lib/components/layout/panelManager/TMPanelWrapper.js +3 -3
  217. package/lib/components/layout/panelManager/types.d.ts +3 -0
  218. package/lib/components/layout/panelManager/utils.js +13 -11
  219. package/lib/components/pages/TMPage.d.ts +1 -1
  220. package/lib/components/pages/TMPage.js +1 -1
  221. package/lib/components/query/TMQueryCountButton.js +1 -1
  222. package/lib/components/query/TMQueryEditor.d.ts +14 -10
  223. package/lib/components/query/TMQueryEditor.js +7 -7
  224. package/lib/components/settings/SettingsAppearance.d.ts +2 -1
  225. package/lib/components/sidebar/TMAboutApp.d.ts +2 -1
  226. package/lib/components/sidebar/TMCommandsPanel.d.ts +4 -4
  227. package/lib/components/sidebar/TMCommandsPanel.js +1 -1
  228. package/lib/components/sidebar/TMHeader.d.ts +3 -3
  229. package/lib/components/sidebar/TMHeader.js +36 -26
  230. package/lib/components/sidebar/TMSidebar.js +1 -1
  231. package/lib/components/sidebar/TMSidebarItem.js +1 -1
  232. package/lib/components/viewers/TMDataListItemViewer.d.ts +3 -2
  233. package/lib/components/viewers/TMDataUserIdItemViewer.d.ts +3 -2
  234. package/lib/components/viewers/TMMidViewer.d.ts +2 -2
  235. package/lib/components/viewers/TMMidViewer.js +6 -3
  236. package/lib/components/viewers/TMTidViewer.d.ts +2 -2
  237. package/lib/components/viewers/TMTidViewer.js +89 -28
  238. package/lib/components/wizard/TMStepIndicator.js +3 -3
  239. package/lib/css/tm-sdkui.css +1 -1
  240. package/lib/devextreme-license.d.ts +1 -0
  241. package/lib/devextreme-license.js +3 -0
  242. package/lib/helper/Enum_Localizator.d.ts +4 -4
  243. package/lib/helper/Enum_Localizator.js +1 -0
  244. package/lib/helper/Globalization.d.ts +1 -1
  245. package/lib/helper/SDKUI_Globals.d.ts +110 -0
  246. package/lib/helper/SDKUI_Globals.js +151 -0
  247. package/lib/helper/SDKUI_Localizator.d.ts +735 -687
  248. package/lib/helper/SDKUI_Localizator.js +480 -0
  249. package/lib/helper/TMAppUpdatedModal.d.ts +2 -0
  250. package/lib/helper/TMAppUpdatedModal.js +134 -0
  251. package/lib/helper/TMCommandsContextMenu.d.ts +1 -1
  252. package/lib/helper/TMIcons.d.ts +280 -279
  253. package/lib/helper/TMIcons.js +4 -3
  254. package/lib/helper/TMPdfViewer.d.ts +2 -1
  255. package/lib/helper/TMPdfViewer.js +1 -1
  256. package/lib/helper/TMToppyMessage.d.ts +2 -2
  257. package/lib/helper/TMToppyMessage.js +1 -1
  258. package/lib/helper/TMUtils.d.ts +23 -4
  259. package/lib/helper/TMUtils.js +25 -3
  260. package/lib/helper/checkinCheckoutManager.d.ts +1 -1
  261. package/lib/helper/checkinCheckoutManager.js +1 -1
  262. package/lib/helper/dataGridSearchHelper.d.ts +28 -0
  263. package/lib/helper/dataGridSearchHelper.js +51 -0
  264. package/lib/helper/dcmtsHelper.d.ts +20 -0
  265. package/lib/helper/dcmtsHelper.js +58 -1
  266. package/lib/helper/helpers.d.ts +13 -2
  267. package/lib/helper/helpers.js +27 -3
  268. package/lib/helper/index.d.ts +2 -0
  269. package/lib/helper/index.js +2 -0
  270. package/lib/helper/queryHelper.d.ts +6 -1
  271. package/lib/helper/queryHelper.js +8 -3
  272. package/lib/hooks/tmDistinctValuesGridHelper.d.ts +16 -0
  273. package/lib/hooks/tmDistinctValuesGridHelper.js +31 -0
  274. package/lib/hooks/useArchiveListForm.d.ts +39 -0
  275. package/lib/hooks/useArchiveListForm.js +46 -0
  276. package/lib/hooks/useCaseFlowApprove.d.ts +56 -0
  277. package/lib/hooks/useCaseFlowApprove.js +157 -0
  278. package/lib/hooks/useDataUserIdItem.d.ts +1 -0
  279. package/lib/hooks/useDataUserIdItem.js +1 -0
  280. package/lib/hooks/useDcmtOperations.d.ts +7 -0
  281. package/lib/hooks/useDcmtOperations.js +141 -71
  282. package/lib/hooks/useDocumentOperations.d.ts +4 -0
  283. package/lib/hooks/useDocumentOperations.js +53 -11
  284. package/lib/hooks/useInputDialog.d.ts +2 -1
  285. package/lib/hooks/useInputDialog.js +1 -1
  286. package/lib/hooks/useMultiMasterDetailDcmts.d.ts +113 -0
  287. package/lib/hooks/useMultiMasterDetailDcmts.js +760 -0
  288. package/lib/hooks/useQueryParametersDialog.js +1 -1
  289. package/lib/hooks/useRelatedDocuments.d.ts +1 -0
  290. package/lib/hooks/useRelatedDocuments.js +22 -27
  291. package/lib/hooks/useShowDossiersV5.d.ts +12 -0
  292. package/lib/hooks/useShowDossiersV5.js +37 -0
  293. package/lib/hooks/useTMDistinctValuesMetadataDisplay.d.ts +18 -0
  294. package/lib/hooks/useTMDistinctValuesMetadataDisplay.js +103 -0
  295. package/lib/hooks/useTMDistinctValuesQuickSearch.d.ts +49 -0
  296. package/lib/hooks/useTMDistinctValuesQuickSearch.js +307 -0
  297. package/lib/hooks/useTMDistinctValuesSelection.d.ts +42 -0
  298. package/lib/hooks/useTMDistinctValuesSelection.js +103 -0
  299. package/lib/hooks/useTMDistinctValuesSource.d.ts +29 -0
  300. package/lib/hooks/useTMDistinctValuesSource.js +105 -0
  301. package/lib/index.d.ts +2 -0
  302. package/lib/index.js +5 -2
  303. package/lib/services/caseflow/CaseFlowService.d.ts +247 -0
  304. package/lib/services/caseflow/CaseFlowService.js +720 -0
  305. package/lib/services/caseflow/CaseFlowTemplateCacheService.d.ts +28 -0
  306. package/lib/services/caseflow/CaseFlowTemplateCacheService.js +121 -0
  307. package/lib/services/caseflow/caseFlowNameCache.d.ts +32 -0
  308. package/lib/services/caseflow/caseFlowNameCache.js +116 -0
  309. package/lib/services/caseflow/caseFlowWorkItemUtils.d.ts +61 -0
  310. package/lib/services/caseflow/caseFlowWorkItemUtils.js +113 -0
  311. package/lib/services/index.d.ts +4 -0
  312. package/lib/services/index.js +4 -0
  313. package/lib/services/platform_services.d.ts +7 -6
  314. package/package.json +16 -13
@@ -0,0 +1,31 @@
1
+ import { DataColumnTypes, SDK_Globals } from '@topconsultnpm/sdk-ts';
2
+ import { formatDateTimeByMetadataFormat } from '../helper';
3
+ /**
4
+ * Funzioni condivise dalle due sorgenti di TMDistinctValues (valori distinti e ricerca rapida):
5
+ * stanno fuori dagli hook perché non dipendono da alcuno stato.
6
+ */
7
+ // rowIndex è la chiave delle griglie di TMDistinctValues: va riallineato all'ordine finale delle righe
8
+ export const withRowIndex = (rows) => {
9
+ rows.forEach((row, index) => { row.rowIndex = index; });
10
+ return rows;
11
+ };
12
+ export const toGridDataType = (dataType) => {
13
+ switch (dataType) {
14
+ case DataColumnTypes.DateTime: return 'datetime';
15
+ case DataColumnTypes.Bool: return 'boolean';
16
+ case DataColumnTypes.Number: return 'number';
17
+ default: return 'string';
18
+ }
19
+ };
20
+ // Nome del metadato con cui viene intestata la colonna, nella lingua scelta dall'utente
21
+ export const getMetadataName = (columnMd) => (SDK_Globals.useLocalizedName ? columnMd?.nameLoc : columnMd?.name) ?? columnMd?.name ?? columnMd?.nameLoc ?? undefined;
22
+ // Le date vanno mostrate con il formato definito sul metadato, come nel risultato di ricerca
23
+ export const getDateDisplayFormat = (format, formatCulture) => ({
24
+ // La griglia passa al formatter un oggetto Date già istanziato, ma il valore può arrivare anche come stringa
25
+ formatter: (value) => formatDateTimeByMetadataFormat(value instanceof Date ? value : new Date(value), format, formatCulture)
26
+ });
27
+ /**
28
+ * Risolve il MID della colonna di un risultato di ricerca: la proprietà estesa è la fonte principale,
29
+ * in mancanza resta l'allineamento posizionale tra selectMIDs e colonne del risultato.
30
+ */
31
+ export const getColumnMid = (column, selectMIDs, columnIndex) => Number(column?.extendedProperties?.['MID'] ?? 0) || (selectMIDs?.[columnIndex] ?? 0);
@@ -0,0 +1,39 @@
1
+ import { MutableRefObject } from 'react';
2
+ import { MetadataValueDescriptorEx } from '../ts';
3
+ /** Modalità "aggiungi a elenco": il form non archivia a sistema, restituisce i metadati al chiamante (TMMultiMasterDetailDcmts). */
4
+ export interface ArchiveListMode {
5
+ /** true quando si modifica una riga già presente nell'elenco ("Modifica" al posto di "Aggiungi"). */
6
+ isEditingRow: boolean;
7
+ /** Restituisce metadati e file al chiamante, che aggiunge o aggiorna la riga nell'elenco (senza archiviare). */
8
+ onUpsertRow: (metadataValues: Array<MetadataValueDescriptorEx>, file: File | undefined, tid?: number) => void;
9
+ }
10
+ interface UseArchiveListFormParams {
11
+ /** Assente = modalità "aggiungi a elenco" spenta. */
12
+ mode?: ArchiveListMode;
13
+ /** Valori della riga in modifica, con cui pre-compilare il form. */
14
+ editingRowValues?: Array<{
15
+ mid: number;
16
+ value: string;
17
+ }>;
18
+ /** Template vuoto del form. */
19
+ formDataOrig: Array<MetadataValueDescriptorEx>;
20
+ /** Ref ai valori correnti del form (per leggerli al submit senza stale closure). */
21
+ formDataRef: MutableRefObject<Array<MetadataValueDescriptorEx>>;
22
+ /** Ref al file caricato. */
23
+ dcmtFileRef: MutableRefObject<File | null>;
24
+ tid?: number;
25
+ isModal?: boolean;
26
+ /** Id del form, usato come parentId del message box quando è in modale. */
27
+ id?: string;
28
+ /** Svuota il form dopo aver restituito i valori. */
29
+ clearForm: () => void;
30
+ }
31
+ /** Isola la logica della modalità "aggiungi a elenco": valori di riferimento, submit e chiusura del form. */
32
+ export declare const useArchiveListForm: ({ mode, editingRowValues, formDataOrig, formDataRef, dcmtFileRef, tid, isModal, id, clearForm, }: UseArchiveListFormParams) => {
33
+ enabled: boolean;
34
+ isEditingRow: boolean;
35
+ referenceValues: MetadataValueDescriptorEx[];
36
+ submit: () => void;
37
+ requestClose: (isModified: boolean, onClose?: () => void) => boolean;
38
+ };
39
+ export {};
@@ -0,0 +1,46 @@
1
+ import { useCallback, useMemo } from 'react';
2
+ import { ButtonNames, TMMessageBoxManager } from '../components';
3
+ /** Isola la logica della modalità "aggiungi a elenco": valori di riferimento, submit e chiusura del form. */
4
+ export const useArchiveListForm = ({ mode, editingRowValues, formDataOrig, formDataRef, dcmtFileRef, tid, isModal, id, clearForm, }) => {
5
+ const enabled = !!mode;
6
+ const isEditingRow = !!mode?.isEditingRow;
7
+ // Valori con cui si confronta il form per capire cosa è cambiato (flag "modificato" ed evidenza gialla).
8
+ // Modificando una riga si parte dai suoi valori, così i campi pre-compilati non risultano subito modificati.
9
+ const referenceValues = useMemo(() => {
10
+ if (!isEditingRow || !editingRowValues || editingRowValues.length === 0)
11
+ return formDataOrig;
12
+ return formDataOrig.map(md => {
13
+ const rowValue = editingRowValues.find(rv => rv.mid === md.mid);
14
+ return rowValue ? { ...md, value: rowValue.value } : md;
15
+ });
16
+ }, [isEditingRow, editingRowValues, formDataOrig]);
17
+ // Restituisce metadati e file al chiamante, poi svuota il form.
18
+ const submit = useCallback(() => {
19
+ if (!mode)
20
+ return;
21
+ const values = formDataRef.current.filter(md => md.mid !== undefined && md.mid > 99);
22
+ mode.onUpsertRow(values, dcmtFileRef.current ?? undefined, tid);
23
+ clearForm();
24
+ }, [mode, formDataRef, dcmtFileRef, tid, clearForm]);
25
+ // Gestisce la chiusura del form
26
+ const requestClose = useCallback((isModified, onClose) => {
27
+ if (!mode)
28
+ return false;
29
+ if (!isModified) {
30
+ onClose?.();
31
+ return true;
32
+ }
33
+ TMMessageBoxManager.show({
34
+ parentId: isModal ? "TMDcmtFormShowConfirmForClose-" + id : undefined,
35
+ message: "Chiudendo, le modifiche andranno perse. Proseguire?",
36
+ buttons: [ButtonNames.YES, ButtonNames.NO],
37
+ onButtonClick: (e) => {
38
+ // Sì: scarta le modifiche e chiude senza aggiungere all'elenco. No: resta sul form.
39
+ if (e == ButtonNames.YES)
40
+ onClose?.();
41
+ }
42
+ });
43
+ return true;
44
+ }, [mode, isModal, id]);
45
+ return { enabled, isEditingRow, referenceValues, submit, requestClose };
46
+ };
@@ -0,0 +1,56 @@
1
+ import { CaseFlowInstanceDescriptor, CaseFlowWorkItem } from '@topconsultnpm/sdk-ts';
2
+ /**
3
+ * Attività (workitem) delle PRATICHE assegnate all'utente, con il documento su
4
+ * cui lavorano già risolto.
5
+ *
6
+ * Gemello di `useWorkflowApprove` per il modulo CaseFlow: i dati stanno in una
7
+ * cache di modulo e le istanze del hook si sincronizzano con un evento, così il
8
+ * form del documento — da qualunque punto venga aperto — sa che su quel TID/DID
9
+ * c'è una firma da fare o un'approvazione da dare, senza che il chiamante debba
10
+ * passargli nulla.
11
+ */
12
+ /** Workitem di pratica già risolto sul documento cui si riferisce. */
13
+ export interface CaseFlowDcmtWorkItem {
14
+ caseflow: CaseFlowInstanceDescriptor;
15
+ workItem: CaseFlowWorkItem;
16
+ tid: number;
17
+ did: number;
18
+ }
19
+ /**
20
+ * Ricarica i workitem di pratica dell'utente. Con `force` ignora la finestra
21
+ * anti-raffica (da usare dopo un'operazione che li ha modificati).
22
+ */
23
+ export declare const refreshCaseFlowApproveData: (force?: boolean) => Promise<void>;
24
+ /**
25
+ * Workitem di pratica pendenti su quel documento (lettura sincrona dalla cache).
26
+ *
27
+ * TID/DID vanno NORMALIZZATI: pur essendo tipati `number`, arrivano come stringhe
28
+ * quando il documento è aperto da una griglia (righe di datagrid) — per lo stesso
29
+ * motivo il resto della libreria fa `Number(TID)`/`Number(DID)` in ogni confronto.
30
+ * Senza normalizzazione il confronto stretto falliva, e l'attività risultava
31
+ * assente aprendo il documento dalla ricerca mentre compariva dal widget "Per te".
32
+ */
33
+ export declare const getCaseFlowWorkItemsByDcmt: (tid?: number | string, did?: number | string) => CaseFlowDcmtWorkItem[];
34
+ /** Svuota la cache (logout / cambio archivio). */
35
+ export declare const clearCaseFlowApproveData: () => void;
36
+ /** Completa il workitem di pratica e ricarica la cache. */
37
+ export declare const completeCaseFlowWorkItem: (item: CaseFlowDcmtWorkItem, comment?: string) => Promise<void>;
38
+ /** Rifiuta il workitem di pratica (motivo obbligatorio) e ricarica la cache. */
39
+ export declare const rejectCaseFlowWorkItem: (item: CaseFlowDcmtWorkItem, reason: string) => Promise<void>;
40
+ /**
41
+ * Completa l'attività di FIRMA di una pratica sul documento indicato, se esiste.
42
+ * La chiama il viewer di firma quando la firma è riuscita: è il gemello di quanto
43
+ * già avviene per i workitem del workflow legacy.
44
+ * @returns true se un'attività è stata completata.
45
+ */
46
+ export declare const completeCaseFlowSignatureForDcmt: (tid: number | string, did: number | string, comment?: string) => Promise<boolean>;
47
+ /**
48
+ * Attività di pratica sul documento indicato. Senza sessione o senza attività
49
+ * l'elenco è vuoto e nulla cambia nella UI.
50
+ */
51
+ export declare const useCaseFlowApprove: (tid?: number | string, did?: number | string) => {
52
+ caseFlowWorkItems: CaseFlowDcmtWorkItem[];
53
+ refreshCaseFlowApprove: typeof refreshCaseFlowApproveData;
54
+ completeCaseFlowWorkItem: typeof completeCaseFlowWorkItem;
55
+ rejectCaseFlowWorkItem: typeof rejectCaseFlowWorkItem;
56
+ };
@@ -0,0 +1,157 @@
1
+ import { useCallback, useEffect, useState } from 'react';
2
+ import { SDK_Globals } from '@topconsultnpm/sdk-ts';
3
+ import { CaseFlowService } from '../services/caseflow/CaseFlowService';
4
+ import { getWorkItemTargetDoc, isMoreInfoWorkItem, isSignatureWorkItem } from '../services/caseflow/caseFlowWorkItemUtils';
5
+ const CASEFLOW_APPROVE_CHANGED_EVENT = 'onCaseFlowApproveChange';
6
+ let cache = [];
7
+ let inFlight;
8
+ let lastLoadedAt = 0;
9
+ /**
10
+ * Finestra minima fra due ricariche: il form del documento chiede un refresh a
11
+ * ogni apertura e la lista è una scansione delle istanze, non una query puntuale.
12
+ */
13
+ const MIN_RELOAD_INTERVAL_MS = 15000;
14
+ const notifyChanged = () => {
15
+ if (typeof window === 'undefined')
16
+ return;
17
+ window.dispatchEvent(new CustomEvent(CASEFLOW_APPROVE_CHANGED_EVENT));
18
+ };
19
+ /**
20
+ * Ricarica la cache: i workitem pendenti dell'utente, risolti sul documento su
21
+ * cui lavorano. Le richieste di informazioni sono escluse (si rispondono nella
22
+ * pratica, non sul documento) come i workitem senza documento.
23
+ */
24
+ const reload = async () => {
25
+ const userId = SDK_Globals.tmSession?.SessionDescr?.userID;
26
+ if (userId == null) {
27
+ cache = [];
28
+ return;
29
+ }
30
+ const groups = await CaseFlowService.getMyPendingWorkItems(userId);
31
+ const resolved = [];
32
+ for (const { caseflow, workItems } of groups) {
33
+ // Le richieste di informazioni si rispondono nella pratica, non sul documento.
34
+ const relevant = workItems.filter(wi => !isMoreInfoWorkItem(wi));
35
+ if (relevant.length === 0)
36
+ continue;
37
+ // Il TID dell'azione è autorato sul TEMPLATE e non materializzato
38
+ // sull'istanza: senza template risolto il documento non è calcolabile.
39
+ if (caseflow.cftid != null) {
40
+ await CaseFlowService.getTemplate(caseflow.cftid);
41
+ }
42
+ // I DOCUMENTI AGGANCIATI non arrivano dalla RetrieveAll (che porta solo i
43
+ // dati delle card): serve la Retrieve completa, altrimenti `dcmts` è vuoto
44
+ // e nessun workitem risulterebbe associato a un documento.
45
+ let instance = caseflow;
46
+ if ((instance.dcmts?.length ?? 0) === 0 && instance.id != null) {
47
+ instance = (await CaseFlowService.getCaseflow(instance.id, instance.cftid)) ?? instance;
48
+ }
49
+ for (const wi of relevant) {
50
+ const target = getWorkItemTargetDoc(instance, wi);
51
+ if (!target)
52
+ continue;
53
+ resolved.push({ caseflow: instance, workItem: wi, tid: target.tid, did: target.did });
54
+ }
55
+ }
56
+ cache = resolved;
57
+ lastLoadedAt = Date.now();
58
+ // Diagnostica del bring-up: se il Toppy non compare, qui si vede a che punto
59
+ // la catena si interrompe (nessun workitem / nessun documento risolto).
60
+ // Rimuovibile una volta stabilizzato il flusso.
61
+ console.debug('[CaseFlow] attività su documenti:', {
62
+ istanzeConPendenti: groups.length,
63
+ workItemPendenti: groups.reduce((n, g) => n + g.workItems.length, 0),
64
+ risolteSuDocumento: resolved.length,
65
+ documenti: resolved.map(r => `${r.tid}/${r.did}`),
66
+ });
67
+ };
68
+ /**
69
+ * Ricarica i workitem di pratica dell'utente. Con `force` ignora la finestra
70
+ * anti-raffica (da usare dopo un'operazione che li ha modificati).
71
+ */
72
+ export const refreshCaseFlowApproveData = async (force = false) => {
73
+ if (inFlight)
74
+ return inFlight;
75
+ if (!force && lastLoadedAt > 0 && Date.now() - lastLoadedAt < MIN_RELOAD_INTERVAL_MS)
76
+ return;
77
+ inFlight = reload()
78
+ .catch(error => { console.error('Errore nel caricare le attività di pratica sui documenti', error); })
79
+ .finally(() => { inFlight = undefined; notifyChanged(); });
80
+ return inFlight;
81
+ };
82
+ /**
83
+ * Workitem di pratica pendenti su quel documento (lettura sincrona dalla cache).
84
+ *
85
+ * TID/DID vanno NORMALIZZATI: pur essendo tipati `number`, arrivano come stringhe
86
+ * quando il documento è aperto da una griglia (righe di datagrid) — per lo stesso
87
+ * motivo il resto della libreria fa `Number(TID)`/`Number(DID)` in ogni confronto.
88
+ * Senza normalizzazione il confronto stretto falliva, e l'attività risultava
89
+ * assente aprendo il documento dalla ricerca mentre compariva dal widget "Per te".
90
+ */
91
+ export const getCaseFlowWorkItemsByDcmt = (tid, did) => {
92
+ const t = Number(tid);
93
+ const d = Number(did);
94
+ if (!Number.isFinite(t) || !Number.isFinite(d))
95
+ return [];
96
+ return cache.filter(r => Number(r.tid) === t && Number(r.did) === d);
97
+ };
98
+ /** Svuota la cache (logout / cambio archivio). */
99
+ export const clearCaseFlowApproveData = () => {
100
+ cache = [];
101
+ lastLoadedAt = 0;
102
+ notifyChanged();
103
+ };
104
+ /** Completa il workitem di pratica e ricarica la cache. */
105
+ export const completeCaseFlowWorkItem = async (item, comment) => {
106
+ if (item.caseflow.id == null || item.workItem.id == null)
107
+ return;
108
+ await CaseFlowService.completeWorkItem(item.caseflow.id, item.workItem.id, comment?.trim() || undefined);
109
+ await refreshCaseFlowApproveData(true);
110
+ };
111
+ /** Rifiuta il workitem di pratica (motivo obbligatorio) e ricarica la cache. */
112
+ export const rejectCaseFlowWorkItem = async (item, reason) => {
113
+ if (item.caseflow.id == null || item.workItem.id == null)
114
+ return;
115
+ await CaseFlowService.rejectWorkItem(item.caseflow.id, item.workItem.id, reason);
116
+ await refreshCaseFlowApproveData(true);
117
+ };
118
+ /**
119
+ * Completa l'attività di FIRMA di una pratica sul documento indicato, se esiste.
120
+ * La chiama il viewer di firma quando la firma è riuscita: è il gemello di quanto
121
+ * già avviene per i workitem del workflow legacy.
122
+ * @returns true se un'attività è stata completata.
123
+ */
124
+ export const completeCaseFlowSignatureForDcmt = async (tid, did, comment) => {
125
+ const target = getCaseFlowWorkItemsByDcmt(tid, did).find(r => isSignatureWorkItem(r.workItem));
126
+ if (!target)
127
+ return false;
128
+ await completeCaseFlowWorkItem(target, comment);
129
+ return true;
130
+ };
131
+ /**
132
+ * Attività di pratica sul documento indicato. Senza sessione o senza attività
133
+ * l'elenco è vuoto e nulla cambia nella UI.
134
+ */
135
+ export const useCaseFlowApprove = (tid, did) => {
136
+ const readItems = useCallback(() => getCaseFlowWorkItemsByDcmt(tid, did), [tid, did]);
137
+ const [caseFlowWorkItems, setCaseFlowWorkItems] = useState(readItems);
138
+ useEffect(() => { setCaseFlowWorkItems(readItems()); }, [readItems]);
139
+ useEffect(() => {
140
+ const handleChange = () => setCaseFlowWorkItems(readItems());
141
+ window.addEventListener(CASEFLOW_APPROVE_CHANGED_EVENT, handleChange);
142
+ return () => window.removeEventListener(CASEFLOW_APPROVE_CHANGED_EVENT, handleChange);
143
+ }, [readItems]);
144
+ // All'apertura di un documento la cache può essere vecchia (attività assegnate
145
+ // dopo l'ultimo caricamento) o non ancora popolata.
146
+ useEffect(() => {
147
+ if (tid == null || did == null)
148
+ return;
149
+ void refreshCaseFlowApproveData();
150
+ }, [tid, did]);
151
+ return {
152
+ caseFlowWorkItems,
153
+ refreshCaseFlowApprove: refreshCaseFlowApproveData,
154
+ completeCaseFlowWorkItem,
155
+ rejectCaseFlowWorkItem,
156
+ };
157
+ };
@@ -3,6 +3,7 @@ import { UserDescriptor } from '@topconsultnpm/sdk-ts';
3
3
  export declare const useDataUserIdItem: () => {
4
4
  loadUsersAsync: (userIDs: Set<number>) => Promise<void>;
5
5
  getUserItem: (userId: number) => UserDescriptor | undefined;
6
+ getCompleteUserName: (domain: string | undefined, name: string | undefined) => string | undefined;
6
7
  clearCache: () => void;
7
8
  hasUser: (userId: number) => boolean;
8
9
  usersCache: React.MutableRefObject<Map<number, UserDescriptor>>;
@@ -90,6 +90,7 @@ export const useDataUserIdItem = () => {
90
90
  return {
91
91
  loadUsersAsync,
92
92
  getUserItem,
93
+ getCompleteUserName,
93
94
  clearCache,
94
95
  hasUser,
95
96
  usersCache: usersCacheRef,
@@ -24,6 +24,13 @@ export interface DownloadDcmtsAsyncParams {
24
24
  * - false (default): usa il nome file recuperato dal backend (file.name) come priorità
25
25
  */
26
26
  useInputFileName?: boolean;
27
+ /**
28
+ * Numero di download eseguiti in parallelo (default 1 = sequenziale, comportamento preesistente).
29
+ * Valori > 1 vanno usati solo quando il chiamante consuma i file via
30
+ * `onFileDownloaded`: nel percorso senza callback ogni file genera un click su un
31
+ * tag <a download>, e più click ravvicinati vengono bloccati dal browser.
32
+ */
33
+ downloadConcurrency?: number;
27
34
  }
28
35
  export interface UseDcmtOperationsReturn {
29
36
  abortController: AbortController;
@@ -9,6 +9,10 @@ import { importCertificatesAsync } from '../helper/certificateImportHelper';
9
9
  import { isXMLFileExt } from '../helper/dcmtsHelper';
10
10
  import { ShowConfirm } from '../components/base/TMConfirm';
11
11
  import { generateTargetFileName } from '../components/features/documents/copyAndMergeDcmtsShared';
12
+ /** Limite massimo di download paralleli accettato da `downloadDcmtsAsync`. */
13
+ const MAX_DOWNLOAD_CONCURRENCY = 8;
14
+ /** Intervallo minimo (ms) fra due aggiornamenti della progress bar di download. */
15
+ const DOWNLOAD_PROGRESS_THROTTLE_MS = 100;
12
16
  const isScannerLicenseConfigured = () => {
13
17
  try {
14
18
  const scannerLicense = SDKUI_Globals.userSettings.advancedSettings.scannerLicense;
@@ -257,7 +261,7 @@ export const useDcmtOperations = () => {
257
261
  ShowAlert({ message: SDKUI_Localizator.ZipCreatedSavedInFolder.replaceParams(zipFileName, "Zip creato con successo"), mode: 'success', duration: 5000, title: SDKUI_Localizator.CompressToZipFile });
258
262
  }
259
263
  };
260
- const _downloadDcmtsAsync = async (inputDcmts, downloadMode = "download", onFileDownloaded, skipConfirmation = false, retrieveOptions, useCache = true, showSuccessAlert = true, useInputFileName = false) => {
264
+ const _downloadDcmtsAsync = async (inputDcmts, downloadMode = "download", onFileDownloaded, skipConfirmation = false, retrieveOptions, useCache = true, showSuccessAlert = true, useInputFileName = false, downloadConcurrency = 1) => {
261
265
  if (inputDcmts === undefined)
262
266
  return;
263
267
  if (inputDcmts.length <= 0)
@@ -286,85 +290,150 @@ export const useDcmtOperations = () => {
286
290
  setShowSecondary(true);
287
291
  setWaitPanelTitle(operationTitle);
288
292
  abortController = new AbortController();
289
- const rfo = new RetrieveFileOptions();
290
- rfo.retrieveReason = retrieveOptions?.retrieveReason ?? DcmtOpers.ShowFile;
291
- if (retrieveOptions?.cvtFormat !== undefined)
292
- rfo.cvtFormat = retrieveOptions.cvtFormat;
293
- if (retrieveOptions?.generalRetrieveFormat !== undefined)
294
- rfo.generalRetrieveFormat = retrieveOptions.generalRetrieveFormat;
295
- rfo.invoiceRetrieveFormat = retrieveOptions?.invoiceRetrieveFormat ?? SDKUI_Globals.userSettings.searchSettings.invoiceRetrieveFormat;
296
- rfo.orderRetrieveFormat = retrieveOptions?.orderRetrieveFormat ?? SDKUI_Globals.userSettings.searchSettings.orderRetrieveFormat;
297
- let result = [];
298
- setWaitPanelMaxValuePrimary(inputDcmts.length);
299
- let firstBlock = true;
300
- let maxFileSize = 0;
301
- for (let i = 0; i < inputDcmts.length; i++) {
302
- if (abortController.signal.aborted) {
303
- result.push({ rowIndex: i, id1: inputDcmts[i].TID, id2: inputDcmts[i].DID, resultType: ResultTypes.WARNING, description: `Operazione interrotta. Elaborati ${i + 1} documenti` });
304
- break;
293
+ // Riferimento const: il narrowing su inputDcmts non sopravvive dentro le closure del pool.
294
+ const dcmts = inputDcmts;
295
+ /**
296
+ * Ogni richiesta usa la propria istanza di RetrieveFileOptions: con il pool più
297
+ * download sono in volo contemporaneamente e non possono condividere lo stesso oggetto.
298
+ */
299
+ const buildRetrieveFileOptions = (dcmt) => {
300
+ const rfo = new RetrieveFileOptions();
301
+ rfo.retrieveReason = retrieveOptions?.retrieveReason ?? DcmtOpers.ShowFile;
302
+ if (retrieveOptions?.cvtFormat !== undefined)
303
+ rfo.cvtFormat = retrieveOptions.cvtFormat;
304
+ if (retrieveOptions?.generalRetrieveFormat !== undefined)
305
+ rfo.generalRetrieveFormat = retrieveOptions.generalRetrieveFormat;
306
+ rfo.invoiceRetrieveFormat = retrieveOptions?.invoiceRetrieveFormat ?? SDKUI_Globals.userSettings.searchSettings.invoiceRetrieveFormat;
307
+ rfo.orderRetrieveFormat = retrieveOptions?.orderRetrieveFormat ?? SDKUI_Globals.userSettings.searchSettings.orderRetrieveFormat;
308
+ return rfo;
309
+ };
310
+ const results = new Array(dcmts.length);
311
+ setWaitPanelMaxValuePrimary(dcmts.length);
312
+ // ---- Progress secondaria: aggregata sui download in volo e throttlata ----
313
+ // Gli eventi di avanzamento di axios arrivano a ogni chunk: senza throttle ognuno
314
+ // provoca un re-render dell'intera form (relation viewer compreso).
315
+ const inFlightBytes = new Map();
316
+ let pendingSecondary;
317
+ let secondaryTimer;
318
+ const flushSecondaryProgress = () => {
319
+ secondaryTimer = undefined;
320
+ if (!pendingSecondary)
321
+ return;
322
+ setWaitPanelMaxValueSecondary(pendingSecondary.max);
323
+ setWaitPanelValueSecondary(pendingSecondary.value);
324
+ setWaitPanelTextSecondary(pendingSecondary.text);
325
+ pendingSecondary = undefined;
326
+ };
327
+ const publishSecondaryProgress = () => {
328
+ let loaded = 0;
329
+ let total = 0;
330
+ for (const bytes of inFlightBytes.values()) {
331
+ loaded += bytes.loaded;
332
+ total += bytes.total;
305
333
  }
306
- try {
307
- setWaitPanelTextPrimary(`Download file ${i + 1} di ${inputDcmts.length}`);
308
- let file;
309
- const cacheKey = `${inputDcmts[i].TID}-${inputDcmts[i].DID}`;
310
- if (useCache && dcmtsFileCacheDownload.has(cacheKey)) {
311
- file = dcmtsFileCacheDownload.get(cacheKey);
334
+ pendingSecondary = total > 0
335
+ ? { value: loaded, max: total, text: `Downloading... ${Globalization.getNumberDisplayValue(loaded, true)} / ${Globalization.getNumberDisplayValue(total, true)}` }
336
+ : { value: 0, max: 0, text: '' };
337
+ if (secondaryTimer === undefined)
338
+ secondaryTimer = setTimeout(flushSecondaryProgress, DOWNLOAD_PROGRESS_THROTTLE_MS);
339
+ };
340
+ // ---- Pool di download ----
341
+ let nextIndex = 0;
342
+ let started = 0;
343
+ let completed = 0;
344
+ let abortReported = false;
345
+ const downloadOne = async (i) => {
346
+ started++;
347
+ setWaitPanelTextPrimary(`Download file ${started} di ${dcmts.length}`);
348
+ let file;
349
+ const cacheKey = `${dcmts[i].TID}-${dcmts[i].DID}`;
350
+ if (useCache && dcmtsFileCacheDownload.has(cacheKey)) {
351
+ file = dcmtsFileCacheDownload.get(cacheKey);
352
+ }
353
+ else {
354
+ inFlightBytes.set(i, { loaded: 0, total: 0 });
355
+ try {
356
+ file = await SDK_Globals.tmSession?.NewSearchEngine().RetrieveFileAsync(dcmts[i].TID, dcmts[i].DID, buildRetrieveFileOptions(dcmts[i]), abortController.signal, (pd) => {
357
+ inFlightBytes.set(i, { loaded: pd.ProgressBarValue, total: pd.ProgressBarMaximum ?? 0 });
358
+ publishSecondaryProgress();
359
+ });
360
+ }
361
+ finally {
362
+ inFlightBytes.delete(i);
363
+ publishSecondaryProgress();
364
+ }
365
+ }
366
+ completed++;
367
+ setWaitPanelValuePrimary(completed);
368
+ if (downloadMode === "openInNewWindow") {
369
+ if (onFileDownloaded && file) {
370
+ onFileDownloaded(file, dcmts[i]);
312
371
  }
313
372
  else {
314
- file = await SDK_Globals.tmSession?.NewSearchEngine().RetrieveFileAsync(inputDcmts[i].TID, inputDcmts[i].DID, rfo, abortController.signal, (pd) => {
315
- if (firstBlock) {
316
- maxFileSize = pd.ProgressBarMaximum ?? 0;
317
- setWaitPanelMaxValueSecondary(maxFileSize);
318
- firstBlock = false;
319
- }
320
- setWaitPanelValueSecondary(pd.ProgressBarValue);
321
- setWaitPanelTextSecondary(`Downloading... ${Globalization.getNumberDisplayValue(pd.ProgressBarValue, true)} / ${Globalization.getNumberDisplayValue(maxFileSize, true)}`);
322
- if (pd.ProgressBarValue === pd.ProgressBarMaximum) {
323
- setWaitPanelMaxValueSecondary(0);
324
- setWaitPanelValueSecondary(0);
325
- setWaitPanelTextSecondary('');
326
- firstBlock = true;
327
- }
328
- });
373
+ window.open(window.URL.createObjectURL(file), '_blank', 'noopener');
329
374
  }
330
- setWaitPanelValuePrimary(i + 1);
331
- const fileURL = window.URL.createObjectURL(file);
332
- if (downloadMode === "openInNewWindow") {
333
- (onFileDownloaded && file)
334
- ? onFileDownloaded(file, inputDcmts[i])
335
- : window.open(fileURL, '_blank', 'noopener');
375
+ }
376
+ else {
377
+ if (onFileDownloaded && file) {
378
+ await onFileDownloaded(file, dcmts[i]);
336
379
  }
337
380
  else {
338
- if (onFileDownloaded && file) {
339
- await onFileDownloaded(file, inputDcmts[i]);
340
- }
341
- else {
342
- const alink2 = document.createElement('a');
343
- alink2.href = fileURL;
344
- // Usa useInputFileName per determinare la priorità del nome file
345
- alink2.download = getDownloadFileName(file, inputDcmts[i], useInputFileName);
346
- alink2.target = "_blank";
347
- alink2.rel = "noreferrer";
348
- alink2.click();
349
- }
381
+ // L'object URL serve solo in questo ramo: creato qui e revocato dopo il
382
+ // click, così i blob non restano agganciati al documento per sempre.
383
+ const fileURL = window.URL.createObjectURL(file);
384
+ const alink2 = document.createElement('a');
385
+ alink2.href = fileURL;
386
+ // Usa useInputFileName per determinare la priorità del nome file
387
+ alink2.download = getDownloadFileName(file, dcmts[i], useInputFileName);
388
+ alink2.target = "_blank";
389
+ alink2.rel = "noreferrer";
390
+ alink2.click();
391
+ // 60s come per l'iframe di stampa: revocare troppo presto può far fallire
392
+ // il download se il browser non ha ancora risolto il blob URL.
393
+ setTimeout(() => window.URL.revokeObjectURL(fileURL), 60000);
350
394
  }
351
- if (useCache) {
352
- if (dcmtsFileCacheDownload.size >= CACHE_SIZE_LIMIT) {
353
- const oldestKey = dcmtsFileCacheDownload.keys().next().value;
354
- dcmtsFileCacheDownload.delete(oldestKey);
355
- }
356
- dcmtsFileCacheDownload.set(cacheKey, file);
395
+ }
396
+ if (useCache) {
397
+ if (dcmtsFileCacheDownload.size >= CACHE_SIZE_LIMIT) {
398
+ const oldestKey = dcmtsFileCacheDownload.keys().next().value;
399
+ dcmtsFileCacheDownload.delete(oldestKey);
357
400
  }
358
- result.push({ rowIndex: i, id1: inputDcmts[i].TID, id2: inputDcmts[i].DID, resultType: ResultTypes.SUCCESS });
401
+ dcmtsFileCacheDownload.set(cacheKey, file);
359
402
  }
360
- catch (ex) {
361
- result.push({ rowIndex: i, id1: inputDcmts[i].TID, id2: inputDcmts[i].DID, resultType: ResultTypes.ERROR, description: getExceptionMessage(ex) });
362
- const err = ex;
363
- if (err.name === 'CanceledError') {
364
- ShowAlert({ message: err.message, mode: 'warning', duration: 3000, title: 'Abort' });
403
+ results[i] = { rowIndex: i, id1: dcmts[i].TID, id2: dcmts[i].DID, resultType: ResultTypes.SUCCESS };
404
+ };
405
+ const runWorker = async () => {
406
+ while (true) {
407
+ const i = nextIndex++;
408
+ if (i >= dcmts.length)
409
+ return;
410
+ if (abortController.signal.aborted) {
411
+ // Un solo avviso di interruzione anche quando più worker si fermano insieme.
412
+ if (!abortReported) {
413
+ abortReported = true;
414
+ results[i] = { rowIndex: i, id1: dcmts[i].TID, id2: dcmts[i].DID, resultType: ResultTypes.WARNING, description: `Operazione interrotta. Elaborati ${completed} documenti` };
415
+ }
416
+ return;
417
+ }
418
+ try {
419
+ await downloadOne(i);
420
+ }
421
+ catch (ex) {
422
+ results[i] = { rowIndex: i, id1: dcmts[i].TID, id2: dcmts[i].DID, resultType: ResultTypes.ERROR, description: getExceptionMessage(ex) };
423
+ const err = ex;
424
+ if (err.name === 'CanceledError') {
425
+ ShowAlert({ message: err.message, mode: 'warning', duration: 3000, title: 'Abort' });
426
+ }
365
427
  }
366
428
  }
367
- }
429
+ };
430
+ // `|| 1` intercetta NaN/0/negativi: senza, Array.from({length: NaN}) non creerebbe
431
+ // alcun worker e il download terminerebbe in silenzio senza scaricare nulla.
432
+ const workers = Math.max(1, Math.min(Math.trunc(downloadConcurrency) || 1, MAX_DOWNLOAD_CONCURRENCY, dcmts.length));
433
+ await Promise.all(Array.from({ length: workers }, () => runWorker()));
434
+ if (secondaryTimer !== undefined)
435
+ clearTimeout(secondaryTimer);
436
+ const result = results.filter((r) => r !== undefined);
368
437
  setWaitPanelTextPrimary('');
369
438
  setWaitPanelMaxValuePrimary(0);
370
439
  setWaitPanelValuePrimary(0);
@@ -436,12 +505,13 @@ export const useDcmtOperations = () => {
436
505
  };
437
506
  const downloadDcmtsAsync = async (params) => {
438
507
  const { inputDcmts, downloadType = DownloadTypes.Attachment, downloadMode = "download", onFileDownloaded, confirmAttachments, skipConfirmation = false, retrieveOptions, useCache = true, showSuccessAlert = true, useInputFileName = false, // Default: usa il nome dal backend
508
+ downloadConcurrency = 1, // Default: sequenziale
439
509
  } = params;
440
510
  switch (downloadType) {
441
511
  // Per il download di documenti, passa useInputFileName per controllare la priorità del nome
442
- case DownloadTypes.Dcmt: return await _downloadDcmtsAsync(inputDcmts, downloadMode, onFileDownloaded, skipConfirmation, retrieveOptions, useCache, showSuccessAlert, useInputFileName);
512
+ case DownloadTypes.Dcmt: return await _downloadDcmtsAsync(inputDcmts, downloadMode, onFileDownloaded, skipConfirmation, retrieveOptions, useCache, showSuccessAlert, useInputFileName, downloadConcurrency);
443
513
  case DownloadTypes.Attachment: return await _downloadAttachmentsAsync(inputDcmts, confirmAttachments, showSuccessAlert);
444
- default: return await _downloadDcmtsAsync(inputDcmts, undefined, undefined, skipConfirmation, retrieveOptions, useCache, showSuccessAlert, useInputFileName);
514
+ default: return await _downloadDcmtsAsync(inputDcmts, undefined, undefined, skipConfirmation, retrieveOptions, useCache, showSuccessAlert, useInputFileName, downloadConcurrency);
445
515
  }
446
516
  };
447
517
  const uploadDcmtsAsync = async (inputDcmts, operationTitle, operType, actionAfterOperationAsync) => {
@@ -105,10 +105,13 @@ interface UseDocumentOperationsProps {
105
105
  }
106
106
  export interface UseDocumentOperationsResult {
107
107
  operationItems: Array<TMContextMenuItemProps>;
108
+ selectedDcmtInfos: Array<DcmtInfo>;
108
109
  renderFloatingBar: React.ReactNode;
109
110
  renderDcmtOperations: React.ReactNode;
110
111
  features: {
111
112
  isOpenDcmtForm: boolean;
113
+ /** Il form del documento è aperto come popup sopra il contenuto, che resta visibile sotto */
114
+ isDcmtFormModal: boolean;
112
115
  openFormHandler: (layoutMode: LayoutModes) => void;
113
116
  dcmtFormLayoutMode: LayoutModes;
114
117
  onDcmtFormOpenChange: (isOpen: boolean, layoutMode: LayoutModes) => void;
@@ -118,6 +121,7 @@ export interface UseDocumentOperationsResult {
118
121
  closeDcmtFormHandler: () => void;
119
122
  handleSignApprove: () => void;
120
123
  showSearchTMDatagrid: boolean;
124
+ showDcmtTypesSelection: boolean;
121
125
  showExportForm: boolean;
122
126
  checkoutInfo: UseCheckInOutOperationsReturn;
123
127
  relatedDocumentsInfo: UseRelatedDocumentsReturn;