@topconsultnpm/sdkui-react 6.22.0-t1 → 6.22.0-t3

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 (286) 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 +92 -76
  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/TMAlert.js +6 -8
  11. package/lib/components/base/TMAreaManager.js +53 -55
  12. package/lib/components/base/TMButton.d.ts +13 -0
  13. package/lib/components/base/TMButton.js +139 -7
  14. package/lib/components/base/TMClosableList.js +3 -3
  15. package/lib/components/base/TMCustomButton.js +40 -48
  16. package/lib/components/base/TMDataGrid.d.ts +4 -0
  17. package/lib/components/base/TMDataGrid.js +292 -12
  18. package/lib/components/base/TMDataGridExportForm.js +39 -30
  19. package/lib/components/base/TMDropDownMenu.js +1 -1
  20. package/lib/components/base/TMEditorBase.d.ts +2 -0
  21. package/lib/components/base/TMFileManager.js +5 -3
  22. package/lib/components/base/TMFileManagerDataGridView.js +12 -3
  23. package/lib/components/base/TMFileManagerThumbnailItems.js +20 -10
  24. package/lib/components/base/TMFileManagerUtils.d.ts +6 -6
  25. package/lib/components/base/TMFileManagerUtils.js +37 -1
  26. package/lib/components/base/TMLayout.d.ts +2 -2
  27. package/lib/components/base/TMLayout.js +3 -3
  28. package/lib/components/base/TMList.js +1 -1
  29. package/lib/components/base/TMListView.js +3 -3
  30. package/lib/components/base/TMModal.d.ts +11 -0
  31. package/lib/components/base/TMModal.js +47 -13
  32. package/lib/components/base/TMPanel.d.ts +6 -0
  33. package/lib/components/base/TMPanel.js +141 -28
  34. package/lib/components/base/TMPopUp.js +5 -2
  35. package/lib/components/base/TMResizableMenu.js +2 -2
  36. package/lib/components/base/TMRightSidebar.js +1 -1
  37. package/lib/components/base/TMShowAllOrMaxItemsButton.js +1 -1
  38. package/lib/components/base/TMSpinner.d.ts +2 -1
  39. package/lib/components/base/TMSpinner.js +9 -7
  40. package/lib/components/base/TMTab.js +2 -2
  41. package/lib/components/base/TMTabControl.d.ts +106 -0
  42. package/lib/components/base/TMTabControl.js +664 -0
  43. package/lib/components/base/TMToggleButton.js +2 -2
  44. package/lib/components/base/TMToolbarCard.js +3 -3
  45. package/lib/components/base/TMTooltip.d.ts +2 -1
  46. package/lib/components/base/TMTooltip.js +24 -8
  47. package/lib/components/base/TMTreeView.d.ts +13 -7
  48. package/lib/components/base/TMTreeView.js +143 -70
  49. package/lib/components/base/TMWaitPanel.js +3 -3
  50. package/lib/components/base/waitPanel/TMWaitPanelConfirm.d.ts +12 -0
  51. package/lib/components/base/waitPanel/TMWaitPanelConfirm.js +185 -0
  52. package/lib/components/base/waitPanel/TMWaitPanelManager.d.ts +169 -0
  53. package/lib/components/base/waitPanel/TMWaitPanelManager.js +320 -0
  54. package/lib/components/base/waitPanel/TMWaitPanelView.d.ts +53 -0
  55. package/lib/components/base/waitPanel/TMWaitPanelView.js +274 -0
  56. package/lib/components/base/waitPanel/index.d.ts +1 -0
  57. package/lib/components/base/waitPanel/index.js +1 -0
  58. package/lib/components/choosers/TMCultureIDPicker.js +2 -2
  59. package/lib/components/choosers/TMDataListItemChooser.js +1 -1
  60. package/lib/components/choosers/TMDataListItemPicker.js +2 -2
  61. package/lib/components/choosers/TMDcmtTypeChooser.js +5 -4
  62. package/lib/components/choosers/TMDiskChooser.js +1 -1
  63. package/lib/components/choosers/TMDistinctValues.d.ts +9 -7
  64. package/lib/components/choosers/TMDistinctValues.js +157 -141
  65. package/lib/components/choosers/TMDynDataListItemChooser.js +1 -1
  66. package/lib/components/choosers/TMImageIDChooser.js +1 -1
  67. package/lib/components/choosers/TMMetadataChooser.js +3 -3
  68. package/lib/components/choosers/TMPathChooser.js +17 -34
  69. package/lib/components/choosers/TMQuickSearchInfo.d.ts +13 -0
  70. package/lib/components/choosers/TMQuickSearchInfo.js +279 -0
  71. package/lib/components/choosers/TMQuickSearchSettingsForm.d.ts +16 -0
  72. package/lib/components/choosers/TMQuickSearchSettingsForm.js +94 -0
  73. package/lib/components/choosers/TMRelationChooser.js +1 -1
  74. package/lib/components/choosers/TMSelectedValuesSummary.d.ts +13 -0
  75. package/lib/components/choosers/TMSelectedValuesSummary.js +89 -0
  76. package/lib/components/choosers/TMUserChooser.js +1 -1
  77. package/lib/components/editors/TMCheckBox.js +1 -1
  78. package/lib/components/editors/TMDateBox.d.ts +16 -1
  79. package/lib/components/editors/TMDateBox.js +90 -22
  80. package/lib/components/editors/TMDropDown.d.ts +3 -0
  81. package/lib/components/editors/TMDropDown.js +197 -5
  82. package/lib/components/editors/TMEditorStyled.d.ts +21 -43
  83. package/lib/components/editors/TMFormulaEditor.js +1 -1
  84. package/lib/components/editors/TMHtmlContentDisplay.js +1 -1
  85. package/lib/components/editors/TMLocalizedTextBox.js +1 -1
  86. package/lib/components/editors/TMMetadataEditor.d.ts +5 -1
  87. package/lib/components/editors/TMMetadataEditor.js +27 -23
  88. package/lib/components/editors/TMMetadataValues.js +6 -6
  89. package/lib/components/editors/TMRadioButton.js +2 -2
  90. package/lib/components/editors/TMSummary.js +3 -3
  91. package/lib/components/editors/TMTextArea.d.ts +1 -0
  92. package/lib/components/editors/TMTextArea.js +25 -17
  93. package/lib/components/editors/TMTextBox.d.ts +2 -0
  94. package/lib/components/editors/TMTextBox.js +32 -21
  95. package/lib/components/editors/TMTextExpression.js +1 -1
  96. package/lib/components/features/archive/TMArchive.js +24 -5
  97. package/lib/components/features/assistant/TMHelpOnLineChat.d.ts +29 -0
  98. package/lib/components/features/assistant/TMHelpOnLineChat.js +1384 -0
  99. package/lib/components/features/assistant/TMToppyDraggableHelpCenter.js +4 -4
  100. package/lib/components/features/assistant/TMToppySpeechBubble.js +1 -1
  101. package/lib/components/features/assistant/dataset/Designer-Suggested-Questions.json +102 -0
  102. package/lib/components/features/assistant/dataset/Login-Suggested-Questions.json +32 -0
  103. package/lib/components/features/assistant/dataset/Surfer-Suggested-Questions.json +102 -0
  104. package/lib/components/features/documents/TMBatchUpdateForm.js +22 -9
  105. package/lib/components/features/documents/TMCopyToFolderForm.js +50 -42
  106. package/lib/components/features/documents/TMDcmtBlog.d.ts +3 -0
  107. package/lib/components/features/documents/TMDcmtBlog.js +4 -4
  108. package/lib/components/features/documents/TMDcmtForm.d.ts +7 -0
  109. package/lib/components/features/documents/TMDcmtForm.js +281 -113
  110. package/lib/components/features/documents/TMDcmtFormActionButtons.d.ts +11 -0
  111. package/lib/components/features/documents/TMDcmtFormActionButtons.js +79 -9
  112. package/lib/components/features/documents/TMDcmtIcon.d.ts +1 -3
  113. package/lib/components/features/documents/TMDcmtIcon.js +8 -8
  114. package/lib/components/features/documents/TMDcmtPreview.d.ts +7 -5
  115. package/lib/components/features/documents/TMDcmtPreview.js +16 -10
  116. package/lib/components/features/documents/TMDcmtTasks.js +2 -9
  117. package/lib/components/features/documents/TMDownloadRelationViewerSection.js +1 -1
  118. package/lib/components/features/documents/TMFileUploader.js +7 -7
  119. package/lib/components/features/documents/TMMasterDetailDcmts.d.ts +2 -0
  120. package/lib/components/features/documents/TMMasterDetailDcmts.js +95 -108
  121. package/lib/components/features/documents/TMMasterInfoFields.d.ts +20 -0
  122. package/lib/components/features/documents/TMMasterInfoFields.js +185 -0
  123. package/lib/components/features/documents/TMMergeToPdfForm.d.ts +1 -2
  124. package/lib/components/features/documents/TMMergeToPdfForm.js +83 -56
  125. package/lib/components/features/documents/TMMultiMasterDetailDcmtsForm.d.ts +46 -0
  126. package/lib/components/features/documents/TMMultiMasterDetailDcmtsForm.js +320 -0
  127. package/lib/components/features/documents/TMMultiMasterDetailDcmtsUtils.d.ts +370 -0
  128. package/lib/components/features/documents/TMMultiMasterDetailDcmtsUtils.js +283 -0
  129. package/lib/components/features/documents/TMRelationViewer.d.ts +29 -9
  130. package/lib/components/features/documents/TMRelationViewer.js +310 -208
  131. package/lib/components/features/documents/copyAndMergeDcmtsShared.d.ts +1 -1
  132. package/lib/components/features/documents/relationTreeState.d.ts +32 -0
  133. package/lib/components/features/documents/relationTreeState.js +89 -0
  134. package/lib/components/features/search/TMMetadataOutputForm.js +1 -1
  135. package/lib/components/features/search/TMMetadataSorterForm.js +1 -1
  136. package/lib/components/features/search/TMSavedQuerySelector.js +2 -2
  137. package/lib/components/features/search/TMSearch.d.ts +1 -1
  138. package/lib/components/features/search/TMSearch.js +172 -34
  139. package/lib/components/features/search/TMSearchQueryEditor.js +7 -5
  140. package/lib/components/features/search/TMSearchQueryPanel.d.ts +14 -4
  141. package/lib/components/features/search/TMSearchQueryPanel.js +153 -62
  142. package/lib/components/features/search/TMSearchResult.d.ts +21 -0
  143. package/lib/components/features/search/TMSearchResult.js +461 -152
  144. package/lib/components/features/search/TMSignatureInfoContent.js +1 -1
  145. package/lib/components/features/search/TMTreeSelector.js +130 -83
  146. package/lib/components/features/search/TMViewHistoryDcmt.js +14 -25
  147. package/lib/components/features/tasks/TMTaskForm.js +1 -1
  148. package/lib/components/features/tasks/TMTaskFormUtils.js +3 -3
  149. package/lib/components/features/tasks/TMTasksAgenda.js +1 -1
  150. package/lib/components/features/tasks/TMTasksCalendar.js +1 -1
  151. package/lib/components/features/tasks/TMTasksHeader.js +1 -1
  152. package/lib/components/features/tasks/TMTasksUtilsView.js +1 -1
  153. package/lib/components/features/tasks/TMTasksView.js +97 -102
  154. package/lib/components/features/wg/TMWGsCopyMoveForm.js +92 -92
  155. package/lib/components/features/workflow/TMWorkflowPopup.d.ts +10 -0
  156. package/lib/components/features/workflow/TMWorkflowPopup.js +9 -5
  157. package/lib/components/features/workflow/diagram/ConnectionComponent.js +3 -3
  158. package/lib/components/features/workflow/diagram/DiagramItemComponent.js +3 -3
  159. package/lib/components/features/workflow/diagram/DiagramItemForm.js +1 -1
  160. package/lib/components/features/workflow/diagram/DiagramItemSvgContent.js +1 -1
  161. package/lib/components/features/workflow/diagram/RecipientList.js +1 -1
  162. package/lib/components/features/workflow/diagram/WFDiagram.js +4 -4
  163. package/lib/components/features/workflow/diagram/WorkitemRecipientsEditor.d.ts +3 -1
  164. package/lib/components/forms/Login/ChangePasswordInputs.d.ts +3 -1
  165. package/lib/components/forms/Login/Menu.js +1 -1
  166. package/lib/components/forms/Login/OTPReader.js +1 -1
  167. package/lib/components/forms/Login/PasswordStrengthChecker.js +1 -1
  168. package/lib/components/forms/Login/RapidAccessLogin.js +2 -2
  169. package/lib/components/forms/Login/RecoverPasswordFlow.js +2 -2
  170. package/lib/components/forms/Login/SelectBox.js +1 -1
  171. package/lib/components/forms/Login/StepIndicator.js +1 -1
  172. package/lib/components/forms/Login/TMLoginForm.js +7 -7
  173. package/lib/components/forms/Login/TextBox.js +1 -1
  174. package/lib/components/forms/TMApplyForm.js +3 -3
  175. package/lib/components/forms/TMChooserForm.js +1 -1
  176. package/lib/components/forms/TMResultDialog.js +1 -1
  177. package/lib/components/forms/TMSaveForm.js +3 -3
  178. package/lib/components/grids/TMBlogAttachments.js +14 -3
  179. package/lib/components/grids/TMBlogHeader.js +5 -1
  180. package/lib/components/grids/TMBlogsPost.d.ts +2 -0
  181. package/lib/components/grids/TMBlogsPost.js +122 -99
  182. package/lib/components/grids/TMBlogsPostUtils.d.ts +1 -0
  183. package/lib/components/grids/TMBlogsPostUtils.js +15 -4
  184. package/lib/components/grids/TMRecentsManager.js +4 -4
  185. package/lib/components/grids/TMValidationItemsList.js +1 -1
  186. package/lib/components/index.d.ts +6 -0
  187. package/lib/components/index.js +5 -0
  188. package/lib/components/layout/panelManager/TMPanelManagerContainer.d.ts +1 -0
  189. package/lib/components/layout/panelManager/TMPanelManagerContainer.js +25 -15
  190. package/lib/components/layout/panelManager/TMPanelManagerContext.js +68 -93
  191. package/lib/components/layout/panelManager/TMPanelManagerToolbar.d.ts +4 -5
  192. package/lib/components/layout/panelManager/TMPanelManagerToolbar.js +1 -1
  193. package/lib/components/layout/panelManager/TMPanelWrapper.js +3 -3
  194. package/lib/components/layout/panelManager/types.d.ts +3 -0
  195. package/lib/components/layout/panelManager/utils.js +13 -11
  196. package/lib/components/pages/TMPage.js +30 -32
  197. package/lib/components/query/TMQueryCountButton.js +1 -1
  198. package/lib/components/query/TMQueryEditor.d.ts +17 -10
  199. package/lib/components/query/TMQueryEditor.js +9 -8
  200. package/lib/components/sidebar/TMCommandsPanel.d.ts +4 -4
  201. package/lib/components/sidebar/TMCommandsPanel.js +1 -1
  202. package/lib/components/sidebar/TMHeader.d.ts +1 -0
  203. package/lib/components/sidebar/TMHeader.js +37 -27
  204. package/lib/components/sidebar/TMSidebar.js +1 -1
  205. package/lib/components/sidebar/TMSidebarItem.js +1 -1
  206. package/lib/components/viewers/TMMidViewer.js +6 -3
  207. package/lib/components/viewers/TMTidViewer.js +89 -28
  208. package/lib/components/wizard/TMStepIndicator.js +3 -3
  209. package/lib/css/tm-sdkui.css +1 -1
  210. package/lib/devextreme-license.d.ts +1 -0
  211. package/lib/devextreme-license.js +3 -0
  212. package/lib/helper/Enum_Localizator.d.ts +4 -4
  213. package/lib/helper/Enum_Localizator.js +1 -0
  214. package/lib/helper/Globalization.d.ts +1 -1
  215. package/lib/helper/SDKUI_Globals.d.ts +110 -0
  216. package/lib/helper/SDKUI_Globals.js +151 -0
  217. package/lib/helper/SDKUI_Localizator.d.ts +756 -677
  218. package/lib/helper/SDKUI_Localizator.js +790 -0
  219. package/lib/helper/TMAppUpdatedModal.d.ts +2 -0
  220. package/lib/helper/TMAppUpdatedModal.js +134 -0
  221. package/lib/helper/TMIcons.d.ts +1 -0
  222. package/lib/helper/TMIcons.js +4 -3
  223. package/lib/helper/TMPdfViewer.js +1 -1
  224. package/lib/helper/TMToppyMessage.js +1 -1
  225. package/lib/helper/TMUtils.d.ts +51 -4
  226. package/lib/helper/TMUtils.js +273 -12
  227. package/lib/helper/ZipManager.d.ts +1 -1
  228. package/lib/helper/ZipManager.js +2 -1
  229. package/lib/helper/checkinCheckoutManager.d.ts +1 -1
  230. package/lib/helper/checkinCheckoutManager.js +1 -1
  231. package/lib/helper/dataGridSearchHelper.d.ts +28 -0
  232. package/lib/helper/dataGridSearchHelper.js +51 -0
  233. package/lib/helper/dcmtsHelper.d.ts +22 -0
  234. package/lib/helper/dcmtsHelper.js +60 -1
  235. package/lib/helper/helpers.d.ts +24 -2
  236. package/lib/helper/helpers.js +59 -3
  237. package/lib/helper/index.d.ts +2 -0
  238. package/lib/helper/index.js +2 -0
  239. package/lib/helper/queryHelper.d.ts +6 -1
  240. package/lib/helper/queryHelper.js +8 -3
  241. package/lib/hooks/tmDistinctValuesGridHelper.d.ts +16 -0
  242. package/lib/hooks/tmDistinctValuesGridHelper.js +31 -0
  243. package/lib/hooks/useArchiveListForm.d.ts +39 -0
  244. package/lib/hooks/useArchiveListForm.js +46 -0
  245. package/lib/hooks/useCaseFlowApprove.d.ts +56 -0
  246. package/lib/hooks/useCaseFlowApprove.js +157 -0
  247. package/lib/hooks/useCheckInOutOperations.d.ts +0 -6
  248. package/lib/hooks/useCheckInOutOperations.js +14 -34
  249. package/lib/hooks/useDataUserIdItem.d.ts +1 -0
  250. package/lib/hooks/useDataUserIdItem.js +1 -0
  251. package/lib/hooks/useDcmtOperations.d.ts +3 -12
  252. package/lib/hooks/useDcmtOperations.js +187 -179
  253. package/lib/hooks/useDocumentOperations.d.ts +5 -0
  254. package/lib/hooks/useDocumentOperations.js +64 -33
  255. package/lib/hooks/useInputDialog.js +1 -1
  256. package/lib/hooks/useMultiMasterDetailDcmts.d.ts +98 -0
  257. package/lib/hooks/useMultiMasterDetailDcmts.js +758 -0
  258. package/lib/hooks/usePreventFileDrop.js +9 -0
  259. package/lib/hooks/useQueryParametersDialog.js +1 -1
  260. package/lib/hooks/useRelatedDocuments.d.ts +1 -0
  261. package/lib/hooks/useRelatedDocuments.js +22 -27
  262. package/lib/hooks/useShowDossiersV5.d.ts +12 -0
  263. package/lib/hooks/useShowDossiersV5.js +37 -0
  264. package/lib/hooks/useTMDistinctValuesMetadataDisplay.d.ts +18 -0
  265. package/lib/hooks/useTMDistinctValuesMetadataDisplay.js +103 -0
  266. package/lib/hooks/useTMDistinctValuesQuickSearch.d.ts +49 -0
  267. package/lib/hooks/useTMDistinctValuesQuickSearch.js +307 -0
  268. package/lib/hooks/useTMDistinctValuesSelection.d.ts +42 -0
  269. package/lib/hooks/useTMDistinctValuesSelection.js +103 -0
  270. package/lib/hooks/useTMDistinctValuesSource.d.ts +29 -0
  271. package/lib/hooks/useTMDistinctValuesSource.js +105 -0
  272. package/lib/hooks/useWorkflowApprove.js +33 -17
  273. package/lib/index.d.ts +2 -0
  274. package/lib/index.js +5 -2
  275. package/lib/services/caseflow/CaseFlowService.d.ts +277 -0
  276. package/lib/services/caseflow/CaseFlowService.js +761 -0
  277. package/lib/services/caseflow/CaseFlowTemplateCacheService.d.ts +28 -0
  278. package/lib/services/caseflow/CaseFlowTemplateCacheService.js +121 -0
  279. package/lib/services/caseflow/caseFlowNameCache.d.ts +32 -0
  280. package/lib/services/caseflow/caseFlowNameCache.js +116 -0
  281. package/lib/services/caseflow/caseFlowWorkItemUtils.d.ts +61 -0
  282. package/lib/services/caseflow/caseFlowWorkItemUtils.js +113 -0
  283. package/lib/services/index.d.ts +4 -0
  284. package/lib/services/index.js +4 -0
  285. package/lib/services/platform_services.d.ts +4 -4
  286. package/package.json +16 -13
@@ -2,14 +2,14 @@ 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
4
  import { calcResponsiveSizes, getExceptionMessage, IconFolderOpen, IconPlay, IconUndo, SDKUI_Globals, SDKUI_Localizator, } from '../../../helper';
5
- import { DcmtOpers, FileFormats, GeneralRetrieveFormats, ResultTypes, RetrieveFileOptions, ValidationItem, } from '@topconsultnpm/sdk-ts';
5
+ import { DcmtOpers, FileFormats, GeneralRetrieveFormats, InvoiceRetrieveFormats, OrderRetrieveFormats, ResultTypes, ValidationItem, } from '@topconsultnpm/sdk-ts';
6
6
  import TMModal from '../../base/TMModal';
7
7
  import { useDeviceType } from '../../base/TMDeviceProvider';
8
8
  import TMTextBox from '../../editors/TMTextBox';
9
9
  import { ButtonNames, TMMessageBoxManager } from '../../base/TMPopUp';
10
10
  import { useDcmtOperations } from '../../../hooks/useDcmtOperations';
11
- import { TMLayoutWaitingContainer } from '../../base/TMWaitPanel';
12
11
  import { TMSplitterLayout } from '../../base/TMLayout';
12
+ import TMWaitPanelManager from '../../base/waitPanel/TMWaitPanelManager';
13
13
  import { TMColors } from '../../../utils/theme';
14
14
  import TMDownloadRelationViewerSection from './TMDownloadRelationViewerSection';
15
15
  import { getDcmtInfosToDownload, getFloatingLabelStyle, isDirectoryPickerSupported, MIN_PDF_FOR_MERGE, } from './copyAndMergeDcmtsShared';
@@ -18,23 +18,44 @@ import ShowAlert from '../../base/TMAlert';
18
18
  import TMTooltip from '../../base/TMTooltip';
19
19
  import MergePdfManager from '../../../helper/MergePdfManager';
20
20
  import { TMResultManager } from '../../forms/TMResultDialog';
21
+ /**
22
+ * Converte il formato di visualizzazione fatture impostato dall'utente nel corrispondente formato PDF:
23
+ * il foglio di stile SDI resta SDI, in tutti gli altri casi si usa ASW.
24
+ */
25
+ const toPdfInvoiceRetrieveFormat = (format) => {
26
+ switch (format) {
27
+ case InvoiceRetrieveFormats.SDI_HTML:
28
+ case InvoiceRetrieveFormats.SDI_PDF:
29
+ return InvoiceRetrieveFormats.SDI_PDF;
30
+ default:
31
+ return InvoiceRetrieveFormats.ASW_PDF;
32
+ }
33
+ };
34
+ /**
35
+ * Converte il formato di visualizzazione ordini impostato dall'utente nel corrispondente formato PDF:
36
+ * il foglio di stile NSO resta NSO, in tutti gli altri casi si usa ER.
37
+ */
38
+ const toPdfOrderRetrieveFormat = (format) => {
39
+ switch (format) {
40
+ case OrderRetrieveFormats.NSO_HTML:
41
+ case OrderRetrieveFormats.NSO_PDF:
42
+ return OrderRetrieveFormats.NSO_PDF;
43
+ default:
44
+ return OrderRetrieveFormats.ER_PDF;
45
+ }
46
+ };
21
47
  /**
22
48
  * Form per l'unione di più documenti PDF in un singolo file.
23
- * Condivide TMDownloadRelationViewerSection e gli helper in copyAndMergeDcmtsShared
24
- * con TMCopyToFolderForm.
49
+ * Condivide TMDownloadRelationViewerSection e gli helper in copyAndMergeDcmtsShared con TMCopyToFolderForm.
25
50
  */
26
51
  const TMMergeToPdfForm = (props) => {
27
52
  const { mode, selectedDcmtInfos, selectedItemsFull, onClose, showTMRelationViewer, allTasks, getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers } = props;
28
- const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync, } = useDcmtOperations();
53
+ // Il wait panel del download lo apre e lo aggiorna l'hook: qui serve solo la funzione.
54
+ const { downloadDcmtsAsync } = useDcmtOperations();
29
55
  const deviceType = useDeviceType();
30
56
  const [pdfFileName, setPdfFileName] = useState(`${SDKUI_Localizator.Result.toLowerCase()}.pdf`);
31
57
  const [destinationFolder, setDestinationFolder] = useState('Download');
32
58
  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);
38
59
  // ---- Ref per la selezione cartella (File System Access API) ----
39
60
  const folderHandleRef = useRef(null);
40
61
  const skipSelectFolderRef = useRef(false);
@@ -131,32 +152,36 @@ const TMMergeToPdfForm = (props) => {
131
152
  // Raccoglie gli errori come downloadDcmtsAsync
132
153
  const metadataConversionResults = [];
133
154
  if (metadataOnlyDcmts.length > 0) {
134
- setIsMergingPdf(true);
135
- setMergeProgressMax(metadataOnlyDcmts.length);
136
- setMergeProgressValue(0);
137
- setMergeProgressText('Creazione PDF metadati...');
155
+ const metadataPanel = TMWaitPanelManager.show({
156
+ title: SDKUI_Localizator.MergeToPdf,
157
+ subtitle: 'Creazione PDF metadati...',
158
+ max: metadataOnlyDcmts.length,
159
+ });
138
160
  for (let i = 0; i < metadataOnlyDcmts.length; i++) {
139
161
  const dcmt = metadataOnlyDcmts[i];
140
162
  try {
141
- setMergeProgressValue(i);
142
- setMergeProgressText(`Creazione PDF metadati... (${i + 1}/${metadataOnlyDcmts.length})`);
163
+ metadataPanel.setSubtitle(`Creazione PDF metadati... (${i + 1}/${metadataOnlyDcmts.length})`);
143
164
  const conversionResult = await createMetadataPdfFromDocument(dcmt);
144
165
  if (conversionResult) {
145
166
  pdfFilesMap.set(`${dcmt.TID}_${dcmt.DID}`, conversionResult.file);
146
167
  metadataConversionResults.push({ rowIndex: i, id1: dcmt.TID, id2: dcmt.DID, resultType: ResultTypes.SUCCESS });
168
+ metadataPanel.ok();
147
169
  }
148
170
  else {
149
171
  // createMetadataPdfFromDocument ha restituito null (errore interno loggato)
150
172
  metadataConversionResults.push({ rowIndex: i, id1: dcmt.TID, id2: dcmt.DID, resultType: ResultTypes.ERROR, description: 'Creazione PDF metadati fallita' });
173
+ metadataPanel.error();
151
174
  }
152
175
  }
153
176
  catch (error) {
154
177
  console.error(`Errore creazione PDF metadati per TID=${dcmt.TID}, DID=${dcmt.DID}`, error);
155
178
  metadataConversionResults.push({ rowIndex: i, id1: dcmt.TID, id2: dcmt.DID, resultType: ResultTypes.ERROR, description: getExceptionMessage(error) });
179
+ metadataPanel.error();
156
180
  }
181
+ // Avanza a conversione conclusa: con un solo documento la barra non parte dal 100%
182
+ await metadataPanel.step();
157
183
  }
158
- setMergeProgressValue(metadataOnlyDcmts.length);
159
- setIsMergingPdf(false);
184
+ metadataPanel.close();
160
185
  // Mostra riepilogo errori se presenti (come downloadDcmtsAsync)
161
186
  const hasErrors = metadataConversionResults.some(r => r.resultType === ResultTypes.ERROR);
162
187
  if (hasErrors) {
@@ -165,12 +190,13 @@ const TMMergeToPdfForm = (props) => {
165
190
  }
166
191
  // Per i documenti con file, usa il download normale
167
192
  if (dcmtsWithFile.length > 0) {
168
- const rfo = new RetrieveFileOptions();
169
- rfo.retrieveReason = DcmtOpers.None;
170
- rfo.generalRetrieveFormat = GeneralRetrieveFormats.OriginalUnsigned;
171
- rfo.cvtFormat = FileFormats.PDF;
172
- rfo.invoiceRetrieveFormat = SDKUI_Globals.userSettings?.searchSettings.invoiceRetrieveFormat;
173
- rfo.orderRetrieveFormat = SDKUI_Globals.userSettings?.searchSettings.orderRetrieveFormat;
193
+ const rfo = {
194
+ retrieveReason: DcmtOpers.None,
195
+ generalRetrieveFormat: GeneralRetrieveFormats.OriginalUnsigned,
196
+ cvtFormat: FileFormats.PDF,
197
+ invoiceRetrieveFormat: toPdfInvoiceRetrieveFormat(SDKUI_Globals.userSettings?.searchSettings.invoiceRetrieveFormat),
198
+ orderRetrieveFormat: toPdfOrderRetrieveFormat(SDKUI_Globals.userSettings?.searchSettings.orderRetrieveFormat),
199
+ };
174
200
  const collectFileForMerge = async (file, dcmtInfo) => {
175
201
  pdfFilesMap.set(`${dcmtInfo.TID}_${dcmtInfo.DID}`, file);
176
202
  };
@@ -201,16 +227,17 @@ const TMMergeToPdfForm = (props) => {
201
227
  if (!pdfFiles)
202
228
  return;
203
229
  const finalName = pdfFileName.trim().toLowerCase().endsWith('.pdf') ? pdfFileName.trim() : pdfFileName.trim() + '.pdf';
204
- // Inizializza progress bar per il merge
205
- setIsMergingPdf(true);
206
- setMergeProgressMax(pdfFiles.length);
207
- setMergeProgressValue(0);
208
- setMergeProgressText(SDKUI_Localizator.MergeToPdf);
230
+ // Il merge non e' interrompibile: pannello senza Interrompi.
231
+ const mergePanel = TMWaitPanelManager.show({
232
+ title: SDKUI_Localizator.MergeToPdf,
233
+ subtitle: SDKUI_Localizator.MergeToPdf,
234
+ max: pdfFiles.length,
235
+ showCounters: false,
236
+ });
209
237
  try {
210
238
  const mergeOptions = {
211
239
  onProgress: (current, total, file) => {
212
- setMergeProgressValue(current);
213
- setMergeProgressText(`${SDKUI_Localizator.MergeToPdf}: ${file.name}`);
240
+ mergePanel.update({ value: current, subtitle: `${SDKUI_Localizator.MergeToPdf}: ${file.name}` });
214
241
  }
215
242
  };
216
243
  // Se c'è una cartella selezionata (non Download di default), salva direttamente nella cartella
@@ -234,7 +261,7 @@ const TMMergeToPdfForm = (props) => {
234
261
  return;
235
262
  }
236
263
  finally {
237
- setIsMergingPdf(false);
264
+ mergePanel.close();
238
265
  }
239
266
  onClose();
240
267
  };
@@ -335,29 +362,29 @@ const TMMergeToPdfForm = (props) => {
335
362
  ? SDKUI_Localizator.FileNotPdfWillBeExcluded.replaceParams(extLabel)
336
363
  : SDKUI_Localizator.FilesNotPdfWillBeExcluded.replaceParams(nonPdfSelectedItems.length.toString(), extLabel);
337
364
  })() }))] })] }))] })] }));
338
- 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: {
339
- display: 'flex',
340
- alignItems: 'center',
341
- justifyContent: 'center',
342
- gap: '6px',
343
- padding: '8px 20px',
344
- fontSize: '0.95rem',
345
- fontWeight: 600,
346
- color: '#fff',
347
- background: (!isFormValid() || (showTMRelationViewer && selectedItemsRelationViewer.filter(i => i.isDcmt).length === 0) || !hasEnoughPdfForMerge)
348
- ? '#b0b0b0'
349
- : 'linear-gradient(135deg, #28a745 0%, #218838 100%)',
350
- border: 'none',
351
- borderRadius: '6px',
352
- cursor: (!isFormValid() || (showTMRelationViewer && selectedItemsRelationViewer.filter(i => i.isDcmt).length === 0) || !hasEnoughPdfForMerge) ? 'not-allowed' : 'pointer',
353
- boxShadow: (!isFormValid() || (showTMRelationViewer && selectedItemsRelationViewer.filter(i => i.isDcmt).length === 0) || !hasEnoughPdfForMerge)
354
- ? 'none'
355
- : '0 2px 8px rgba(40, 167, 69, 0.35)',
356
- transition: 'all 0.2s ease',
357
- }, children: [_jsx(IconPlay, {}), _jsx("span", { children: mergeableSelectedCount === 0
358
- ? SDKUI_Localizator.MergeToPdf
359
- : mergeableSelectedCount > 999
360
- ? _jsx(TMTooltip, { content: mergeableSelectedCount.toString(), children: SDKUI_Localizator.MergeFilesToPdf.replaceParams('999+') })
361
- : SDKUI_Localizator.MergeFilesToPdf.replaceParams(mergeableSelectedCount.toString()) })] }) })] }) }) }));
365
+ return (_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: {
366
+ display: 'flex',
367
+ alignItems: 'center',
368
+ justifyContent: 'center',
369
+ gap: '6px',
370
+ padding: '8px 20px',
371
+ fontSize: '0.95rem',
372
+ fontWeight: 600,
373
+ color: '#fff',
374
+ background: (!isFormValid() || (showTMRelationViewer && selectedItemsRelationViewer.filter(i => i.isDcmt).length === 0) || !hasEnoughPdfForMerge)
375
+ ? '#b0b0b0'
376
+ : 'linear-gradient(135deg, #28a745 0%, #218838 100%)',
377
+ border: 'none',
378
+ borderRadius: '6px',
379
+ cursor: (!isFormValid() || (showTMRelationViewer && selectedItemsRelationViewer.filter(i => i.isDcmt).length === 0) || !hasEnoughPdfForMerge) ? 'not-allowed' : 'pointer',
380
+ boxShadow: (!isFormValid() || (showTMRelationViewer && selectedItemsRelationViewer.filter(i => i.isDcmt).length === 0) || !hasEnoughPdfForMerge)
381
+ ? 'none'
382
+ : '0 2px 8px rgba(40, 167, 69, 0.35)',
383
+ transition: 'all 0.2s ease',
384
+ }, children: [_jsx(IconPlay, {}), _jsx("span", { children: mergeableSelectedCount === 0
385
+ ? SDKUI_Localizator.MergeToPdf
386
+ : mergeableSelectedCount > 999
387
+ ? _jsx(TMTooltip, { content: mergeableSelectedCount.toString(), children: SDKUI_Localizator.MergeFilesToPdf.replaceParams('999+') })
388
+ : SDKUI_Localizator.MergeFilesToPdf.replaceParams(mergeableSelectedCount.toString()) })] }) })] }) }));
362
389
  };
363
390
  export default TMMergeToPdfForm;
@@ -0,0 +1,46 @@
1
+ import React from "react";
2
+ import { DcmtTypeDescriptor, HomeBlogPost, ObjectRef, TaskDescriptor } from "@topconsultnpm/sdk-ts";
3
+ import { DcmtInfo, IGraphometricManagerProp, TaskContext } from "../../../ts";
4
+ import { IntesiCertificateData } from "../../../helper";
5
+ interface TMMultiMasterDetailDcmtsFormProps {
6
+ /** Tipo documento del master (per individuare le relazioni di dettaglio) */
7
+ dtd: DcmtTypeDescriptor;
8
+ /** Documento master da cui parte l'archiviazione dei dettagli */
9
+ masterDcmt: DcmtInfo;
10
+ /** Funzione per la chiusura del modale */
11
+ onClose: () => void;
12
+ /** true se nella lista da cui è stato aperto il modale c'è un documento precedente/successivo */
13
+ canNavigateMaster?: (dir: 'next' | 'prev') => boolean;
14
+ /** Sposta il focus della lista di provenienza: il master del modale segue quel documento.
15
+ * Senza questa callback le frecce di navigazione non si mostrano */
16
+ onNavigateMaster?: (dir: 'next' | 'prev') => void;
17
+ allTasks?: Array<TaskDescriptor>;
18
+ getAllTasks?: () => Promise<void>;
19
+ deleteTaskByIdsCallback?: (deletedTaskIds: Array<number>) => Promise<void>;
20
+ addTaskCallback?: (task: TaskDescriptor) => Promise<void>;
21
+ editTaskCallback?: (task: TaskDescriptor) => Promise<void>;
22
+ handleNavigateToWGs?: (value: HomeBlogPost | number) => Promise<void>;
23
+ handleNavigateToDossiers?: (value: HomeBlogPost | number) => Promise<void>;
24
+ showDcmtFormSidebar?: boolean;
25
+ showTodoDcmtForm?: boolean;
26
+ openFileUploaderPdfEditor?: (fromDTD?: DcmtTypeDescriptor, file?: File | null, handleFile?: (file: File) => void) => void;
27
+ graphometricManager?: IGraphometricManagerProp;
28
+ editPdfForm?: boolean;
29
+ openS4TViewer?: boolean;
30
+ showToppyDraggableHelpCenter?: boolean;
31
+ toppyHelpCenterUsePortal?: boolean;
32
+ fetchRemoteCertificates?: (email: string) => Promise<IntesiCertificateData[]>;
33
+ onOpenS4TViewerRequest?: (dcmtInfo: Array<DcmtInfo>, refreshDocumentPreview?: () => Promise<void>) => void;
34
+ onOpenPdfEditorRequest?: (dcmtInfo: Array<DcmtInfo>, refreshDocumentPreview?: () => Promise<void>) => void;
35
+ onReferenceClick?: (ref: ObjectRef) => void;
36
+ onTaskCreateRequest?: (taskContext: TaskContext, onTaskCreated?: (task?: TaskDescriptor) => void) => void;
37
+ onRefreshAfterAddDcmtToFavs?: () => void;
38
+ onFileOpened?: (blob: File | undefined) => void;
39
+ passToArchiveCallback?: (outputMids: Array<{
40
+ mid: number;
41
+ value: string;
42
+ }>, tid?: number) => void;
43
+ openWGsCopyMoveForm?: (mode: "copyToWgDraft" | "copyToWgArchivedDoc", dcmtTypeDescriptor: DcmtTypeDescriptor, documents: Array<DcmtInfo>) => void;
44
+ }
45
+ declare const TMMultiMasterDetailDcmtsForm: (props: TMMultiMasterDetailDcmtsFormProps) => React.JSX.Element | null;
46
+ export default TMMultiMasterDetailDcmtsForm;
@@ -0,0 +1,320 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
3
+ import { LayoutModes } from "@topconsultnpm/sdk-ts";
4
+ import { LoadIndicator } from "devextreme-react/load-indicator";
5
+ import { SearchResultContext } from "../../../ts";
6
+ import { getFullFileExtension, getMultiDetailModalSize, getMultiDetailPanelStates, hasMultiDetailPanelStates, hoverStyle, IconArchive, IconArrowDown, IconArrowUp, IconDelete, IconDuplicate, IconEdit, IconEraser, IconInfo, IconMenuVertical, IconRefresh, IconSearch, IconSearchCheck, saveMultiDetailModalSize, saveMultiDetailPanelStates, SDKUI_Localizator } from "../../../helper";
7
+ import { TMColors } from "../../../utils/theme";
8
+ import { DeviceType, useDeviceType } from "../../base/TMDeviceProvider";
9
+ import TMModal from "../../base/TMModal";
10
+ import TMDataGrid from "../../base/TMDataGrid";
11
+ import TMTooltip from "../../base/TMTooltip";
12
+ import { TMDcmtTypeIcon } from "../../viewers/TMTidViewer";
13
+ import { ContextMenu } from "../../NewComponents/ContextMenu";
14
+ import { TMPanelManagerWithPersistenceProvider } from "../../layout/panelManager/TMPanelManagerWithPersistenceProvider";
15
+ import TMPanelManagerContainer from "../../layout/panelManager/TMPanelManagerContainer";
16
+ import TMSearchResult from "../search/TMSearchResult";
17
+ import TMDcmtForm from "./TMDcmtForm";
18
+ import TMDcmtIcon from "./TMDcmtIcon";
19
+ import TMMasterInfoFields from "./TMMasterInfoFields";
20
+ import { MultiDetailArchivePhase, useMultiMasterDetailDcmts } from "../../../hooks/useMultiMasterDetailDcmts";
21
+ import { accordionStyles, getDtdDisplayName, INLINE_EDITABLE_CELL_CLASS, multiDetailStyles, PANEL_GUTTER_PX, renderAccordionHeader, renderSelectDcmtType, renderStepper, SECTION_HEADER_HEIGHT_PX, sectionPanelHeights, TMSectionPanelsHeights, TMSummaryResizeTracker, TMSummarySectionSlot } from "./TMMultiMasterDetailDcmtsUtils";
22
+ // Stili delle sezioni in TMMultiMasterDetailDcmtsUtils (vedi accordionStyles e multiDetailStyles)
23
+ const styles = {
24
+ content: { display: 'flex', flexDirection: 'column', height: '100%', minHeight: 0 },
25
+ header: { display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '6px 12px', borderBottom: `1px solid ${TMColors.card_background}`, flexShrink: 0 },
26
+ // Opzioni nella barra del titolo: stesse misure e colore della chiusura DevExtreme (.dx-popup-title .dx-closebutton)
27
+ titleMenuIcon: { display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: '18px', height: '18px', margin: '1px 0 0', color: `var(--dx-color-text, ${TMColors.text_normal})`, cursor: 'pointer' },
28
+ titleMenuIconDisabled: { cursor: 'default', opacity: 0.4 },
29
+ titleActions: { display: 'inline-flex', alignItems: 'center', gap: '10px' },
30
+ loader: { display: 'flex', flex: 1, alignItems: 'center', justifyContent: 'center' },
31
+ summaryContainer: { display: 'flex', flexDirection: 'column', flex: 1, padding: '8px 12px 10px', minHeight: 0, gap: '8px' },
32
+ // I pannelli ripartiscono l'altezza in percentuale: serve un'altezza definita che non dipenda dal
33
+ // contenuto, da qui il riempimento in posizione assoluta dello spazio residuo
34
+ panelsHost: { position: 'relative', flex: 1, minHeight: 0, minWidth: 0 },
35
+ panelsHostFill: { position: 'absolute', top: 0, right: 0, bottom: 0, left: 0, display: 'flex' },
36
+ gridWrapper: { position: 'relative', flex: 1, minHeight: 0 },
37
+ actionsCell: { display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '14px' },
38
+ actionIcon: { cursor: 'pointer', display: 'flex' },
39
+ fileCell: { overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' },
40
+ fab: { position: 'absolute', bottom: '18px', right: '20px', width: '42px', height: '42px', borderRadius: '50%', backgroundColor: TMColors.button_floating_background, color: '#fff', border: 'none', cursor: 'pointer', boxShadow: '0 2px 6px rgba(0,0,0,0.2)', zIndex: 1000, transition: 'background-color 0.3s ease, transform 0.2s ease', display: 'flex', justifyContent: 'center', alignItems: 'center' },
41
+ footer: { display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'center', flexWrap: 'wrap', gap: '14px', paddingTop: '8px', borderTop: `1px solid ${TMColors.card_background}`, flexShrink: 0 },
42
+ footerLabel: { display: 'inline-flex', alignItems: 'center', gap: '8px', cursor: 'pointer', color: TMColors.label_normal, fontSize: '12px', userSelect: 'none', padding: '5px 10px', borderRadius: '16px', background: 'transparent', border: `1px solid ${TMColors.card_background}`, transition: 'all 0.15s ease' },
43
+ archiveButton: { display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: '8px', height: '38px', padding: '0 22px', border: 'none', borderRadius: '10px', fontSize: '14px', fontWeight: 600, letterSpacing: '0.2px', color: '#ffffff', cursor: 'pointer', transition: 'transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease' },
44
+ checkbox: { width: '16px', height: '16px', accentColor: TMColors.primary, cursor: 'pointer', margin: 0 },
45
+ };
46
+ /** Sezione mostrata per prima su mobile, dove i pannelli si vedono uno alla volta */
47
+ const MOBILE_SECTION = 'archiveList';
48
+ const TMMultiMasterDetailDcmtsForm = (props) => {
49
+ const { dtd, masterDcmt, onClose, canNavigateMaster, onNavigateMaster, allTasks, getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, showDcmtFormSidebar, showTodoDcmtForm, openFileUploaderPdfEditor, graphometricManager, editPdfForm, openS4TViewer, showToppyDraggableHelpCenter, toppyHelpCenterUsePortal, fetchRemoteCertificates, onOpenS4TViewerRequest, onOpenPdfEditorRequest, onReferenceClick, onTaskCreateRequest, onRefreshAfterAddDcmtToFavs, onFileOpened, passToArchiveCallback, openWGsCopyMoveForm } = props;
50
+ const { isLoading, isSummaryReady, phase, setPhase, detailRelationItems, selectedRelation, selectedItem, hasMultipleTypes, selectRelation, backToTypeSelection, isBackLocked, closeModal, isMasterNavigationEnabled, canNavigateMasterPrev, canNavigateMasterNext, navigateMaster, sectionsOpen, setSectionOpen, openAllSections, clearLayout, layoutResetToken, hasSavedLayout, setHasSavedLayout, canUpdateMaster, masterFieldsCount, getMasterMetadataAsync, masterInfoReloadToken, isOpenMasterForm, setIsOpenMasterForm, handleMasterSavedAsync, archivedDetailResults, archivedDetailsCount, isLoadingArchivedDetails, refreshArchivedDetailsAsync, detailColumns, detailSupportsFile, archiveRows, currentRows, focusedRowKey, setFocusedRowKey, selectedRowKeys, setSelectedRowKeys, isOpenAddForm, editingRowId, editingRow, formInputMids, openAddForm, openEditForm, closeAddForm, deleteRow, duplicateRow, upsertRow, updateRowValues, copyArchivedDetailToRows, stopOnFirstError, setStopOnFirstError, isArchiving, archiveAllAsync, } = useMultiMasterDetailDcmts({ dtd, masterDcmt, onClose, canNavigateMaster, onNavigateMaster });
51
+ const deviceType = useDeviceType();
52
+ // Su mobile il panel manager mostra un pannello alla volta: le sezioni si raggiungono dalla sua barra
53
+ const isMobile = useMemo(() => deviceType === DeviceType.MOBILE, [deviceType]);
54
+ // Un pannello alla volta non lascia spazio da cedere: le sezioni chiuse nella vista impilata si
55
+ // aprono qui, altrimenti il pannello a schermo mostrerebbe la sola testata
56
+ useEffect(() => {
57
+ if (isMobile && isSummaryReady)
58
+ openAllSections();
59
+ }, [isMobile, isSummaryReady]);
60
+ // Le altezze sono una scelta dell'utente solo da quando sposta un separatore: quelle calcolate all'apertura
61
+ // o al collasso di una sezione non vanno salvate. Con un layout già salvato lo sono comunque
62
+ const hasUserResizedRef = useRef(false);
63
+ useEffect(() => { hasUserResizedRef.current = hasMultiDetailPanelStates(); }, [layoutResetToken]);
64
+ const persistPanelStatesOnUserResize = useCallback((panelStates) => {
65
+ if (!hasUserResizedRef.current)
66
+ return;
67
+ saveMultiDetailPanelStates(panelStates);
68
+ setHasSavedLayout(true);
69
+ }, []);
70
+ // Ricerca nella griglia dei dettagli da archiviare, come in TMSearch (vedi useDocumentOperations)
71
+ const [showGridSearch, setShowGridSearch] = useState(false);
72
+ const toggleGridSearchItem = {
73
+ name: showGridSearch ? SDKUI_Localizator.HideSearch : SDKUI_Localizator.ShowSearch,
74
+ icon: _jsx(IconSearch, { fontSize: 18 }),
75
+ beginGroup: true,
76
+ onClick: () => setShowGridSearch(prev => !prev),
77
+ };
78
+ const isSummaryPhase = phase === MultiDetailArchivePhase.ArchiveSummary;
79
+ // Dimensioni del modale, ricordate per passo. Si salvano senza aggiornare lo stato: il cambio di
80
+ // dimensioni ricentrerebbe il popup appena ridimensionato dall'utente
81
+ const modalStep = isSummaryPhase ? 'archiveSummary' : 'selectDcmtType';
82
+ const defaultModalSize = isSummaryPhase ? { width: '95%', height: '95%' } : { width: '720px', height: 'auto' };
83
+ const modalSize = useMemo(() => getMultiDetailModalSize(modalStep) ?? defaultModalSize, [modalStep, layoutResetToken]);
84
+ const persistModalSize = useCallback((size) => {
85
+ saveMultiDetailModalSize(modalStep, { width: `${size.width}px`, height: `${size.height}px` });
86
+ setHasSavedLayout(true);
87
+ }, [modalStep, setHasSavedLayout]);
88
+ const baseTitle = SDKUI_Localizator.ArchiveMultipleDetailDocuments;
89
+ // Con un solo tipo il nome è mostrato direttamente nel titolo del modale
90
+ const modalTitle = !hasMultipleTypes && selectedItem ? `${baseTitle}: ${getDtdDisplayName(selectedItem.detailDtd)}` : baseTitle;
91
+ const isArchiveDisabled = isArchiving || currentRows.length === 0;
92
+ const archiveButtonCaption = currentRows.length > 0
93
+ ? `${SDKUI_Localizator.Archive} ${currentRows.length} ${currentRows.length === 1 ? 'dettaglio' : 'dettagli'}`
94
+ : SDKUI_Localizator.Archive;
95
+ const steps = [
96
+ ...(hasMultipleTypes ? [{ phase: MultiDetailArchivePhase.SelectDcmtType, label: SDKUI_Localizator.DcmtType }] : []),
97
+ {
98
+ phase: MultiDetailArchivePhase.ArchiveSummary,
99
+ // Nel riepilogo lo step mostra il tipo selezionato (icona + nome)
100
+ label: selectedItem
101
+ ? (_jsxs("span", { style: multiDetailStyles.stepTypeLabel, children: [_jsx(TMDcmtTypeIcon, { dtd: selectedItem.detailDtd }), _jsx("span", { style: multiDetailStyles.stepTypeLabelText, children: getDtdDisplayName(selectedItem.detailDtd) })] }))
102
+ : SDKUI_Localizator.Summary,
103
+ },
104
+ ];
105
+ // Colonne della griglia: icona del documento, metadati del tipo, file e azioni
106
+ const gridColumns = useMemo(() => {
107
+ const iconColumn = {
108
+ caption: '', width: 50, alignment: 'center',
109
+ allowSorting: false, allowFiltering: false, allowResizing: false, allowReordering: false, allowHiding: false, allowEditing: false,
110
+ cellRender: (cell) => {
111
+ const file = cell.data?.__file;
112
+ return _jsx(TMDcmtIcon, { fileExtension: file ? getFullFileExtension(file.name) : undefined, fileCount: file ? 1 : 0, tooltipContent: file?.name });
113
+ },
114
+ };
115
+ const fileColumn = {
116
+ caption: 'File', width: 220, allowSorting: false, allowEditing: false,
117
+ cellRender: (cell) => {
118
+ const file = cell.data?.__file;
119
+ return _jsx("span", { style: { ...styles.fileCell, color: file ? TMColors.text_normal : TMColors.label_normal }, children: file ? file.name : '' });
120
+ },
121
+ };
122
+ const actionsColumn = {
123
+ caption: '', width: 110, alignment: 'center',
124
+ allowSorting: false, allowFiltering: false, allowHeaderFiltering: false, allowResizing: false,
125
+ allowReordering: false, allowHiding: false, showInColumnChooser: false, allowEditing: false,
126
+ cssClass: 'tm-row-actions',
127
+ cellRender: (cell) => (_jsxs("div", { style: styles.actionsCell, children: [_jsx(TMTooltip, { content: SDKUI_Localizator.Update, children: _jsx("span", { style: styles.actionIcon, onClick: () => openEditForm(cell.data), children: _jsx(IconEdit, { fontSize: 18, color: TMColors.primary }) }) }), _jsx(TMTooltip, { content: SDKUI_Localizator.Duplicate, children: _jsx("span", { style: styles.actionIcon, onClick: () => duplicateRow(cell.data), children: _jsx(IconDuplicate, { fontSize: 18, color: TMColors.tertiary }) }) }), _jsx(TMTooltip, { content: SDKUI_Localizator.Remove, children: _jsx("span", { style: styles.actionIcon, onClick: () => deleteRow(cell.data), children: _jsx(IconDelete, { fontSize: 18, color: TMColors.error }) }) })] })),
128
+ };
129
+ return [actionsColumn, iconColumn, ...detailColumns, ...(detailSupportsFile ? [fileColumn] : [])];
130
+ }, [detailColumns, detailSupportsFile]);
131
+ // ----- Griglia dei dettagli: opzioni e callback con identità stabile -------------------------
132
+ // Un nuovo riferimento a ogni render farebbe rifare a DevExtreme il setup di selezione/editing
133
+ const gridSelection = useMemo(() => ({ mode: 'single', showCheckBoxesMode: 'none' }), []);
134
+ const gridEditing = useMemo(() => ({
135
+ mode: 'cell',
136
+ allowUpdating: true,
137
+ allowAdding: false,
138
+ allowDeleting: false,
139
+ startEditAction: 'click',
140
+ selectTextOnEditStart: false,
141
+ }), []);
142
+ const handleSelectionChanged = useCallback((e) => {
143
+ setSelectedRowKeys(e.selectedRowKeys ?? []);
144
+ }, [setSelectedRowKeys]);
145
+ const handleFocusedRowChanged = useCallback((e) => {
146
+ setFocusedRowKey(e.row?.key);
147
+ }, [setFocusedRowKey]);
148
+ const handleRowUpdating = useCallback((e) => {
149
+ updateRowValues(e.key, e.newData);
150
+ }, [updateRowValues]);
151
+ // Il doppio clic apre il form della riga, tranne su azioni e celle modificabili in linea
152
+ const handleCellDblClick = useCallback((e) => {
153
+ if (e.rowType !== 'data')
154
+ return;
155
+ const cssClass = e.column?.cssClass ?? '';
156
+ if (cssClass === 'tm-row-actions' || cssClass === INLINE_EDITABLE_CELL_CLASS)
157
+ return;
158
+ openEditForm(e.data);
159
+ }, [openEditForm]);
160
+ // Menu contestuale con le stesse azioni della colonna
161
+ const contextMenuItems = useMemo(() => [
162
+ { name: SDKUI_Localizator.Update, icon: _jsx(IconEdit, { fontSize: 18, color: TMColors.primary }), operationType: 'singleRow', onClick: (id) => openEditForm(archiveRows.find(r => r.id === id)) },
163
+ { name: SDKUI_Localizator.Duplicate, icon: _jsx(IconDuplicate, { fontSize: 18, color: TMColors.tertiary }), operationType: 'singleRow', onClick: (id) => duplicateRow(archiveRows.find(r => r.id === id)) },
164
+ { name: SDKUI_Localizator.Remove, icon: _jsx(IconDelete, { fontSize: 18, color: TMColors.error }), operationType: 'singleRow', beginGroup: true, onClick: (id) => deleteRow(archiveRows.find(r => r.id === id)) },
165
+ toggleGridSearchItem,
166
+ ], [archiveRows, showGridSearch]);
167
+ // Menu delle opzioni del modale, aperto dal pulsante a tre punti nella barra del titolo.
168
+ // Con il layout di default non c'è niente da cancellare, quindi la voce non compare
169
+ const optionsMenuItems = useMemo(() => hasSavedLayout
170
+ ? [{ name: SDKUI_Localizator.RemoveLayout, icon: _jsx(IconEraser, { fontSize: 18, color: TMColors.error }), onClick: clearLayout }]
171
+ : [], [clearLayout, hasSavedLayout]);
172
+ // Le opzioni riguardano i pannelli del riepilogo: fuori da quella fase non hanno effetto, e su mobile
173
+ // non c'è un layout da cancellare (i pannelli si vedono uno alla volta, a tutta altezza)
174
+ const renderOptionsMenu = () => {
175
+ // Senza voci non si mostra il pulsante, per non aprire un menu vuoto
176
+ if (!isSummaryPhase || isMobile || optionsMenuItems.length === 0)
177
+ return undefined;
178
+ return (_jsx(ContextMenu, { trigger: 'left', items: optionsMenuItems, children: _jsx(TMTooltip, { content: SDKUI_Localizator.Options, children: _jsx("span", { style: styles.titleMenuIcon, "aria-label": SDKUI_Localizator.Options, children: _jsx(IconMenuVertical, { fontSize: 16, color: "white" }) }) }) }));
179
+ };
180
+ const renderMasterNavigation = () => {
181
+ if (!isMasterNavigationEnabled)
182
+ return undefined;
183
+ const renderArrow = (dir, isEnabled, icon, tooltip) => (_jsx(TMTooltip, { content: tooltip, children: _jsx("span", { role: 'button', "aria-label": tooltip, "aria-disabled": !isEnabled, onClick: isEnabled ? () => navigateMaster(dir) : undefined, style: { ...styles.titleMenuIcon, ...(isEnabled ? {} : styles.titleMenuIconDisabled) }, children: icon }) }));
184
+ return (_jsxs(_Fragment, { children: [renderArrow('prev', canNavigateMasterPrev, _jsx(IconArrowUp, { fontSize: 16, color: "white" }), SDKUI_Localizator.Previous), renderArrow('next', canNavigateMasterNext, _jsx(IconArrowDown, { fontSize: 16, color: "white" }), SDKUI_Localizator.Next)] }));
185
+ };
186
+ // Azioni nella barra del titolo: navigazione del master e opzioni del layout
187
+ const renderTitleActions = () => {
188
+ const navigation = renderMasterNavigation();
189
+ const optionsMenu = renderOptionsMenu();
190
+ if (!navigation && !optionsMenu)
191
+ return undefined;
192
+ return _jsxs("div", { style: styles.titleActions, children: [navigation, optionsMenu] });
193
+ };
194
+ // ----- Sezione: informazioni del master -----------------------------------------------------
195
+ const renderMasterInfo = (panel) => {
196
+ const isOpen = sectionsOpen.masterInfo;
197
+ const editMasterButton = canUpdateMaster
198
+ ? (_jsx(TMTooltip, { content: `${SDKUI_Localizator.Update}: ${getDtdDisplayName(dtd)}`, children: _jsx("button", { type: 'button', onClick: (e) => { e.stopPropagation(); setIsOpenMasterForm(true); }, style: accordionStyles.accordionExpandBtn, ...hoverStyle({ background: TMColors.primary_container, color: TMColors.primary }, { background: 'transparent', color: TMColors.label_normal }), children: _jsx(IconEdit, { fontSize: 16 }) }) }))
199
+ : undefined;
200
+ return (_jsxs("div", { style: { ...accordionStyles.accordion, ...accordionStyles.accordionInPanel }, children: [renderAccordionHeader({
201
+ section: 'masterInfo',
202
+ isOpen,
203
+ tooltip: isOpen ? SDKUI_Localizator.HideMasterInfo : SDKUI_Localizator.ShowMasterInfo,
204
+ count: masterFieldsCount,
205
+ title: (_jsxs(_Fragment, { children: [_jsx(TMDcmtTypeIcon, { dtd: dtd }), _jsxs("span", { style: multiDetailStyles.stepTypeLabelText, children: ["Master: ", getDtdDisplayName(dtd)] })] })),
206
+ actions: editMasterButton,
207
+ panel,
208
+ onToggleOpen: setSectionOpen,
209
+ }), isOpen && (_jsx(TMMasterInfoFields, { dtd: dtd, dcmt: masterDcmt, getValuesByMidAsync: getMasterMetadataAsync, reloadToken: masterInfoReloadToken, isExpandedView: panel.isMaximized }))] }));
210
+ };
211
+ // ----- Sezione: dettagli già archiviati -----------------------------------------------------
212
+ const renderArchivedDetails = (panel) => {
213
+ const isOpen = sectionsOpen.archivedDetails;
214
+ const hasResults = archivedDetailResults.length > 0 && archivedDetailsCount > 0;
215
+ // Ricarica i dettagli già archiviati: la sezione va aperta, altrimenti l'esito non sarebbe visibile
216
+ const refreshArchivedButton = (_jsx(TMTooltip, { content: SDKUI_Localizator.Refresh, children: _jsx("button", { type: 'button', onClick: (e) => { e.stopPropagation(); setSectionOpen('archivedDetails', true); refreshArchivedDetailsAsync(); }, disabled: isLoadingArchivedDetails, style: { ...accordionStyles.accordionExpandBtn, ...(isLoadingArchivedDetails ? { cursor: 'default', opacity: 0.5 } : {}) }, "aria-label": SDKUI_Localizator.Refresh, ...(isLoadingArchivedDetails ? {} : hoverStyle({ background: TMColors.primary_container, color: TMColors.primary }, { background: 'transparent', color: TMColors.label_normal })), children: _jsx(IconRefresh, { fontSize: 16 }) }) }));
217
+ return (_jsxs("div", { style: { ...accordionStyles.accordion, ...accordionStyles.accordionInPanel }, children: [renderAccordionHeader({
218
+ section: 'archivedDetails',
219
+ isOpen,
220
+ tooltip: isOpen ? SDKUI_Localizator.HideArchivedDetails : SDKUI_Localizator.ShowArchivedDetails,
221
+ count: archivedDetailsCount,
222
+ title: (_jsxs(_Fragment, { children: [_jsx(IconSearchCheck, { fontSize: 15 }), _jsx("span", { style: multiDetailStyles.stepTypeLabelText, children: SDKUI_Localizator.ArchivedDetails })] })),
223
+ actions: refreshArchivedButton,
224
+ panel,
225
+ onToggleOpen: setSectionOpen,
226
+ }), isOpen && (_jsx("div", { style: { ...accordionStyles.accordionListBody, ...(panel.isMaximized ? { borderTop: 'none' } : {}) }, children: isLoadingArchivedDetails
227
+ ? _jsxs("div", { style: accordionStyles.accordionListPlaceholder, children: [_jsx(LoadIndicator, { height: 30, width: 30 }), SDKUI_Localizator.Loading] })
228
+ : (hasResults
229
+ ? _jsx(TMSearchResult, { showToolbarHeader: false, showCounterConfig: false, showActionsColumn: true, compactPager: !panel.isMaximized, context: SearchResultContext.METADATA_SEARCH, searchResults: archivedDetailResults, onClose: () => setSectionOpen('archivedDetails', false), showBackButton: false, showToolbarCloseButton: false, allowFloatingBar: false, allowRelations: false, openDcmtFormAsModal: true, showSearchResultSidebar: false, showDcmtFormSidebar: true, autoFocusFirstRow: false, onRefreshSearchAsyncDatagrid: refreshArchivedDetailsAsync, onRowDuplicateRequest: copyArchivedDetailToRows, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, showTodoDcmtForm: showTodoDcmtForm, openFileUploaderPdfEditor: openFileUploaderPdfEditor, graphometricManager: graphometricManager, editPdfForm: editPdfForm, openS4TViewer: openS4TViewer, showToppyDraggableHelpCenter: showToppyDraggableHelpCenter, toppyHelpCenterUsePortal: toppyHelpCenterUsePortal, fetchRemoteCertificates: fetchRemoteCertificates, onOpenS4TViewerRequest: onOpenS4TViewerRequest, onOpenPdfEditorRequest: onOpenPdfEditorRequest, onReferenceClick: onReferenceClick, onTaskCreateRequest: onTaskCreateRequest, onRefreshAfterAddDcmtToFavs: onRefreshAfterAddDcmtToFavs, onFileOpened: onFileOpened, passToArchiveCallback: passToArchiveCallback, openWGsCopyMoveForm: openWGsCopyMoveForm })
230
+ : _jsx("div", { style: accordionStyles.accordionListPlaceholder, children: SDKUI_Localizator.NoDataToDisplay })) }))] }));
231
+ };
232
+ // ----- Sezione: dettagli da archiviare ------------------------------------------------------
233
+ const renderArchiveList = (panel) => {
234
+ const isOpen = sectionsOpen.archiveList;
235
+ return (_jsxs("div", { style: { ...accordionStyles.accordion, ...accordionStyles.accordionInPanel }, children: [renderAccordionHeader({
236
+ section: 'archiveList',
237
+ isOpen,
238
+ tooltip: isOpen ? SDKUI_Localizator.HideDetailsToArchive : SDKUI_Localizator.ShowDetailsToArchive,
239
+ count: currentRows.length,
240
+ title: (_jsxs(_Fragment, { children: [_jsx(IconArchive, { fontSize: 15 }), _jsx("span", { style: multiDetailStyles.stepTypeLabelText, children: SDKUI_Localizator.DetailsToArchive })] })),
241
+ panel,
242
+ onToggleOpen: setSectionOpen,
243
+ }), isOpen && (_jsxs("div", { style: { ...styles.gridWrapper, ...(panel.isMaximized ? {} : { borderTop: `1px solid ${TMColors.card_background}` }) }, children: [_jsx(TMDataGrid, { dataColumns: gridColumns, dataSource: currentRows, keyExpr: "id", height: "100%", showSearchPanel: showGridSearch, showGroupPanel: false, showFilterPanel: false, showHeaderFilter: true, selection: gridSelection, selectedRowKeys: selectedRowKeys, onSelectionChanged: handleSelectionChanged, focusedRowKey: focusedRowKey, onFocusedRowChanged: handleFocusedRowChanged, onCellDblClick: handleCellDblClick, editing: gridEditing, onRowUpdating: handleRowUpdating, customContextMenuItems: contextMenuItems }), _jsx("button", { type: "button", onClick: openAddForm, style: styles.fab, ...hoverStyle({ backgroundColor: '#D94A9F', transform: 'scale(1.1)', boxShadow: '0 4px 12px rgba(37, 89, 165, 0.6)' }, { backgroundColor: TMColors.button_floating_background, transform: 'scale(1)', boxShadow: '0 2px 6px rgba(0,0,0,0.2)' }), children: _jsx(TMTooltip, { content: SDKUI_Localizator.Add, children: _jsx("i", { className: "dx-icon-add", style: { fontSize: '22px' } }) }) })] }))] }));
244
+ };
245
+ // ----- Pannelli del riepilogo, uno per sezione ----------------------------------------------
246
+ const renderSectionsInPanels = () => {
247
+ const definitions = [
248
+ { section: 'masterInfo', name: `Master: ${getDtdDisplayName(dtd)}`, icon: _jsx(IconInfo, { fontSize: 22 }), count: masterFieldsCount, render: renderMasterInfo },
249
+ ...(selectedRelation?.detailTID !== undefined
250
+ ? [{ section: 'archivedDetails', name: SDKUI_Localizator.ArchivedDetails, icon: _jsx(IconSearchCheck, { fontSize: 22 }), count: archivedDetailsCount, render: renderArchivedDetails }]
251
+ : []),
252
+ { section: 'archiveList', name: SDKUI_Localizator.DetailsToArchive, icon: _jsx(IconArchive, { fontSize: 22 }), count: currentRows.length, render: renderArchiveList },
253
+ ];
254
+ const panels = definitions.map((definition, index) => ({
255
+ id: definition.section,
256
+ name: definition.name,
257
+ currentGroupDirection: 'vertical',
258
+ contentOptions: {
259
+ // Ingrandire una sezione collassata la apre: altrimenti il pannello a tutto schermo sarebbe vuoto
260
+ component: _jsx(TMSummarySectionSlot, { section: definition.section, render: definition.render, onBeforeMaximize: (section) => setSectionOpen(section, true) }),
261
+ // Una sezione chiusa vale 0% di altezza: è questo minimo a tenerne a schermo la testata
262
+ minHeight: `${SECTION_HEADER_HEIGHT_PX}px`,
263
+ // La sezione collassata è alta quanto la sua testata: i separatori non la ingrandiscono
264
+ isCollapsed: !sectionsOpen[definition.section],
265
+ },
266
+ // Barra dei pannelli: su mobile è l'unico modo per passare da una sezione all'altra
267
+ toolbarOptions: { icon: definition.icon, visible: true, isActive: true, orderNumber: index + 1, count: definition.count, tooltip: definition.name },
268
+ }));
269
+ const sections = panels.map(panel => panel.id);
270
+ // Le altezze salvate sono il punto di partenza, ma è il collasso corrente a decidere le quote
271
+ const savedStates = getMultiDetailPanelStates();
272
+ const savedDimensions = hasMultiDetailPanelStates()
273
+ ? sections.reduce((acc, section) => {
274
+ if (savedStates[section])
275
+ acc[section] = { width: savedStates[section].width, height: savedStates[section].height };
276
+ return acc;
277
+ }, {})
278
+ : undefined;
279
+ // Con un pannello alla volta non ci sono quote da spartire: quello a schermo prende tutta l'altezza.
280
+ // Le quote proporzionali (e il layout salvato) valgono solo per i pannelli impilati
281
+ const fullHeights = sections.reduce((acc, section) => { acc[section] = { width: '100%', height: '100%' }; return acc; }, {});
282
+ const initialDimensions = isMobile ? fullHeights : sectionPanelHeights(sections, sectionsOpen, savedDimensions);
283
+ const initialVisibility = sections.reduce((acc, section) => { acc[section] = isMobile ? section === MOBILE_SECTION : true; return acc; }, {});
284
+ return (_jsx("div", { style: styles.panelsHost, children: _jsx("div", { style: styles.panelsHostFill, children: _jsxs(TMPanelManagerWithPersistenceProvider
285
+ // Le dimensioni sono lette solo al montaggio: dopo la cancellazione del layout, e al
286
+ // passaggio fra impilato e un pannello alla volta, i pannelli vanno rimontati
287
+ , { panels: panels, initialVisibility: initialVisibility, defaultDimensions: initialDimensions, initialDimensions: initialDimensions, initialMobilePanelId: MOBILE_SECTION,
288
+ // Su mobile il layout è imposto dal dispositivo: salvarlo sovrascriverebbe quello dell'utente
289
+ isPersistenceEnabled: !isMobile,
290
+ // Le altezze si salvano solo dopo che l'utente ha spostato un separatore (vedi TMSummaryResizeTracker)
291
+ persistPanelStates: !isMobile ? persistPanelStatesOnUserResize : undefined, children: [_jsx(TMSummaryResizeTracker, { onUserResize: () => { hasUserResizedRef.current = true; } }), _jsx(TMSectionPanelsHeights, { sections: sections, sectionsOpen: sectionsOpen }), _jsx(TMPanelManagerContainer, { panels: panels, direction: 'vertical', showToolbar: isMobile, minPanelSizePx: SECTION_HEADER_HEIGHT_PX, gutterSizePx: isMobile ? undefined : PANEL_GUTTER_PX })] }, `${layoutResetToken}-${isMobile}`) }) }));
292
+ };
293
+ const renderArchiveSummary = () => (_jsxs("div", { style: styles.summaryContainer, children: [renderSectionsInPanels(), _jsxs("div", { style: styles.footer, children: [_jsxs("label", { style: styles.footerLabel, ...hoverStyle({ borderColor: TMColors.primary, color: TMColors.text_normal }, { borderColor: TMColors.card_background, color: TMColors.label_normal }), children: [_jsx("input", { type: "checkbox", checked: stopOnFirstError, onChange: (e) => setStopOnFirstError(e.target.checked), style: styles.checkbox }), SDKUI_Localizator.StopOnFirstError] }), _jsxs("button", { type: "button", onClick: archiveAllAsync, disabled: isArchiveDisabled, style: {
294
+ ...styles.archiveButton,
295
+ background: isArchiveDisabled ? TMColors.disabled : TMColors.success,
296
+ boxShadow: isArchiveDisabled ? 'none' : `0 4px 14px ${TMColors.success}55`,
297
+ cursor: isArchiveDisabled ? 'default' : 'pointer',
298
+ opacity: isArchiveDisabled ? 0.6 : 1,
299
+ }, ...(isArchiveDisabled ? {} : hoverStyle({ transform: 'translateY(-2px)', boxShadow: `0 6px 20px ${TMColors.success}77`, filter: 'brightness(1.06)' }, { transform: 'translateY(0)', boxShadow: `0 4px 14px ${TMColors.success}55`, filter: 'brightness(1)' })), children: [_jsx(IconArchive, {}), archiveButtonCaption] })] })] }));
300
+ // ----- Render principale --------------------------------------------------------------------
301
+ if (isLoading)
302
+ return null;
303
+ return _jsxs(_Fragment, { children: [_jsx("div", { style: { width: 0, height: 0 }, children: _jsx(TMModal, { width: modalSize.width, height: modalSize.height, onClose: closeModal, onResized: persistModalSize, sizeResetToken: layoutResetToken, title: modalTitle, hidePopup: false, askClosingConfirm: archiveRows.length > 0, recenterOnResize: true, titleActions: renderTitleActions(), children: _jsxs("div", { style: styles.content, children: [hasMultipleTypes && _jsx("div", { style: styles.header, children: renderStepper({
304
+ steps,
305
+ phase,
306
+ hasMultipleTypes,
307
+ isBackLocked,
308
+ showBackArrow: isSummaryPhase,
309
+ onBack: backToTypeSelection,
310
+ onStepClick: (stepPhase) => (stepPhase === MultiDetailArchivePhase.SelectDcmtType ? backToTypeSelection() : setPhase(stepPhase)),
311
+ }) }), !isSummaryPhase
312
+ ? renderSelectDcmtType({ detailRelationItems, selectedRelation, onSelectRelation: selectRelation })
313
+ : (isSummaryReady
314
+ ? renderArchiveSummary()
315
+ : _jsx("div", { style: styles.loader, children: _jsx(LoadIndicator, { height: 40, width: 40 }) }))] }) }) }), isOpenAddForm && selectedRelation?.detailTID && (_jsx(TMDcmtForm, { isModal: true, titleModal: getDtdDisplayName(selectedItem?.detailDtd), TID: selectedRelation.detailTID, layoutMode: LayoutModes.Ark, showBackButton: false, allowButtonsRefs: false, inputMids: formInputMids, inputFile: editingRow?.__file ?? null, archiveListMode: {
316
+ isEditingRow: editingRowId !== undefined,
317
+ onUpsertRow: (values, file) => upsertRow(values, file),
318
+ }, onClose: closeAddForm, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, showDcmtFormSidebar: showDcmtFormSidebar, showTodoDcmtForm: showTodoDcmtForm, openFileUploaderPdfEditor: openFileUploaderPdfEditor, graphometricManager: graphometricManager })), isOpenMasterForm && masterDcmt?.TID !== undefined && masterDcmt?.DID !== undefined && (_jsx(TMDcmtForm, { isModal: true, titleModal: `${SDKUI_Localizator.Update}: ${getDtdDisplayName(dtd)}`, TID: masterDcmt.TID, DID: masterDcmt.DID, layoutMode: LayoutModes.Update, showBackButton: false, allowRelations: false, allowButtonsRefs: false, onSavedAsyncCallback: handleMasterSavedAsync, onClose: () => setIsOpenMasterForm(false), allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, onTaskCreateRequest: onTaskCreateRequest, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, showDcmtFormSidebar: showDcmtFormSidebar, showTodoDcmtForm: showTodoDcmtForm, openFileUploaderPdfEditor: openFileUploaderPdfEditor, graphometricManager: graphometricManager, editPdfForm: editPdfForm, openS4TViewer: openS4TViewer, fetchRemoteCertificates: fetchRemoteCertificates, onOpenS4TViewerRequest: onOpenS4TViewerRequest, onOpenPdfEditorRequest: onOpenPdfEditorRequest, onReferenceClick: onReferenceClick }))] });
319
+ };
320
+ export default TMMultiMasterDetailDcmtsForm;