@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
@@ -1,9 +1,9 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
3
  import { DcmtTypeListCacheService, LayoutModes, ObjectClasses, SDK_Globals, SDK_Localizator } from '@topconsultnpm/sdk-ts';
4
4
  import TMRelationViewer from './TMRelationViewer';
5
5
  import TMContextMenu from '../../NewComponents/ContextMenu/TMContextMenu';
6
- import { IconMultipleSelection, IconCheckFile, IconDetailDcmts, SDKUI_Localizator, IconMenuVertical, IconDataList, IconPreview, IconSearchCheck, IconBoard, IconDcmtTypeSys, IconShow, getMoreInfoTasksForDocument, isApprovalWorkflowView, searchResultToMetadataValues, IconRefresh } from '../../../helper';
6
+ import { IconMultipleSelection, IconCheckFile, IconDetailDcmts, SDKUI_Localizator, IconMenuVertical, IconDataList, IconPreview, IconSearchCheck, IconBoard, IconDcmtTypeSys, IconShow, getMoreInfoTasksForDocument, isApprovalWorkflowView, searchResultToMetadataValues, IconRefresh, SDKUI_Globals } from '../../../helper';
7
7
  import { FormModes, SearchResultContext } from '../../../ts';
8
8
  import { TMColors } from '../../../utils/theme';
9
9
  import ShowAlert from '../../base/TMAlert';
@@ -14,16 +14,17 @@ import { TMPanelManagerProvider, useTMPanelManagerContext } from '../../layout/p
14
14
  import TMSearchResult from '../search/TMSearchResult';
15
15
  import TMDcmtForm from './TMDcmtForm';
16
16
  import { TMNothingToShow } from './TMDcmtPreview';
17
- import { TMButton, TMLayoutWaitingContainer } from '../..';
17
+ import { TMButton } from '../..';
18
+ import TMLayoutContainer from '../../base/TMLayout';
18
19
  import { useDocumentOperations } from '../../../hooks/useDocumentOperations';
19
20
  import TMToppyMessage from '../../../helper/TMToppyMessage';
20
21
  import TMPanel from '../../base/TMPanel';
21
- import sixLogo from '../../../assets/six.png';
22
- const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, deviceType, inputDcmts, isForMaster, showCurrentDcmtIndicator = true, allowNavigation, canNext, canPrev, onNext, onPrev, onBack, appendMasterDcmts, onTaskCreateRequest, onRefreshAfterAddDcmtToFavs, editPdfForm, openS4TViewer, onOpenS4TViewerRequest, onOpenPdfEditorRequest, datagridUtility, dcmtUtility, fetchRemoteCertificates }) => {
22
+ import TMSpinner from '../../base/TMSpinner';
23
+ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, deviceType, inputDcmts, isForMaster, showCurrentDcmtIndicator = true, allowNavigation, canNext, canPrev, onNext, onPrev, onBack, onFirstLoadCompleted, appendMasterDcmts, onTaskCreateRequest, onRefreshAfterAddDcmtToFavs, editPdfForm, openS4TViewer, onOpenS4TViewerRequest, onOpenPdfEditorRequest, datagridUtility, dcmtUtility, fetchRemoteCertificates }) => {
23
24
  const floatingBarContainerRef = useRef(null);
24
25
  const [focusedItem, setFocusedItem] = useState();
25
26
  const [selectedItems, setSelectedItems] = useState([]);
26
- const [showZeroDcmts, setShowZeroDcmts] = useState(false);
27
+ const [showZeroDcmts, setShowZeroDcmts] = useState(() => SDKUI_Globals.userSettings?.searchSettings?.relationShowZeroDcmts ?? false);
27
28
  const [allowMultipleSelection, setAllowMultipleSelection] = useState(false);
28
29
  const [dtdMaster, setDtdMaster] = useState();
29
30
  const [noRelationsOnFirstLoad, setNoRelationsOnFirstLoad] = useState(false);
@@ -32,6 +33,11 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
32
33
  const [contextMenuPosition, setContextMenuPosition] = useState({ x: 0, y: 0 });
33
34
  // Track if TMRelationViewer is loading (used to disable context menu during loading)
34
35
  const [isRelationViewerLoading, setIsRelationViewerLoading] = useState(false);
36
+ // Funzione fornita da TMRelationViewer per interrompere il calcolo delle correlazioni
37
+ // (nessuna ulteriore chiamata GetMetadata). È sincrona: invocabile anche subito prima di uscire.
38
+ const stopRelationsCalculationRef = useRef(undefined);
39
+ // True quando si sta uscendo dalla maschera: evita l'alert sui risultati parziali
40
+ const isLeavingRef = useRef(false);
35
41
  // Track if loading has ever been TRUE (to distinguish initial false from post-load false)
36
42
  const hasLoadingBeenTrueRef = useRef(false);
37
43
  // Track the previous loading state to detect transitions
@@ -40,6 +46,13 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
40
46
  const [refreshKey, setRefreshKey] = useState(0);
41
47
  // Separate refresh key for TMFormOrResultWrapper only (doesn't affect tmTreeView)
42
48
  const [refreshKeyFormOrResult, setRefreshKeyFormOrResult] = useState(0);
49
+ // Stato dell'albero conservato qui perché il bump di refreshKey rimonta TMRelationViewer:
50
+ // una ref interna al viewer non sopravvivrebbe. Riletto dal useMemo di tmTreeView,
51
+ // che si ricalcola proprio al refresh.
52
+ const treeStateRef = useRef(undefined);
53
+ const handleTreeStateChange = useCallback((state) => {
54
+ treeStateRef.current = state;
55
+ }, []);
43
56
  /** State for transformed focusedItem metadata values (similar to formData in TMDcmtForm) */
44
57
  const [focusedItemFormData, setFocusedItemFormData] = useState([]);
45
58
  // Trigger operationItems refresh (after file substitution, etc.)
@@ -59,10 +72,67 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
59
72
  setIsCheckingFirstLoad(false);
60
73
  }
61
74
  }, [isRelationViewerLoading, isCheckingFirstLoad]);
75
+ useEffect(() => {
76
+ if (!isCheckingFirstLoad)
77
+ onFirstLoadCompleted?.();
78
+ }, [isCheckingFirstLoad, onFirstLoadCompleted]);
79
+ // Dal montaggio fino all'apertura del wait panel del viewer (il tempo di caricare i
80
+ // tipi documento) la pagina resta nascosta: senza spinner non si vedrebbe nulla.
81
+ const [waitingFirstLoad, setWaitingFirstLoad] = useState(true);
82
+ useEffect(() => {
83
+ if (!waitingFirstLoad)
84
+ return;
85
+ // Da qui in avanti e' il wait panel a dare riscontro
86
+ if (isRelationViewerLoading) {
87
+ setWaitingFirstLoad(false);
88
+ return;
89
+ }
90
+ TMSpinner.show({ description: SDKUI_Localizator.Loading });
91
+ return () => TMSpinner.hide();
92
+ }, [waitingFirstLoad, isRelationViewerLoading]);
62
93
  // Increments trigger counter to force operationItems to re-calculate
63
94
  const onRefreshOperationsDatagrid = useCallback(async () => {
64
95
  setRefreshOperationsTrigger(prev => prev + 1);
65
96
  }, []);
97
+ // Riceve da TMRelationViewer la funzione per interrompere il calcolo
98
+ const handleStopCalculationReady = useCallback((stopCalculation) => {
99
+ stopRelationsCalculationRef.current = stopCalculation;
100
+ }, []);
101
+ // Esce dalla maschera interrompendo anche le chiamate GetMetadata ancora in coda:
102
+ // l'interruzione è invocata in modo sincrono perché onBack può smontare il componente
103
+ // (un effect non farebbe in tempo a propagare l'interruzione)
104
+ const handleBack = useCallback(() => {
105
+ isLeavingRef.current = true;
106
+ stopRelationsCalculationRef.current?.();
107
+ onBack?.();
108
+ }, [onBack]);
109
+ // Letta da handleRelationsCalculationStopped, che deve restare stabile: arriva fino
110
+ // alle dipendenze di loadData nel viewer, dove un cambio farebbe ripartire il calcolo
111
+ const handleBackRef = useRef(handleBack);
112
+ handleBackRef.current = handleBack;
113
+ // Notifica all'utente che i dati mostrati sono parziali
114
+ const handleRelationsCalculationStopped = useCallback((loadedCount, totalCount) => {
115
+ if (isLeavingRef.current)
116
+ return;
117
+ // Interrotto prima di calcolare qualcosa: non c'è nulla da mostrare, si torna indietro
118
+ if (loadedCount === 0) {
119
+ ShowAlert({
120
+ message: SDKUI_Localizator.RelationsCalculationStoppedEmpty,
121
+ title: SDKUI_Localizator.Attention,
122
+ duration: 6000,
123
+ mode: 'warning',
124
+ });
125
+ handleBackRef.current();
126
+ return;
127
+ }
128
+ // Testo breve: il box di ShowAlert ha altezza fissa e taglia oltre le due righe
129
+ ShowAlert({
130
+ message: SDKUI_Localizator.RelationsCalculationStoppedProgress.replaceParams(loadedCount.toString(), totalCount.toString()),
131
+ title: SDKUI_Localizator.Attention,
132
+ duration: 6000,
133
+ mode: 'info',
134
+ });
135
+ }, []);
66
136
  // Refresh ALL panels (tree view + search results) with fade-out -> update -> fade-in transition
67
137
  const onRefreshAllPanels = async () => {
68
138
  await dcmtUtility?.onRefreshPreviewForm?.(); // Refresh preview form data
@@ -237,7 +307,12 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
237
307
  onRefreshAfterAddDcmtToFavs,
238
308
  },
239
309
  });
240
- const { dcmtOperations: { abortController, showWaitPanel, showPrimary, waitPanelTitle, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, }, } = features;
310
+ // Nuovi documenti in input: il componente non sta più uscendo dalla maschera
311
+ // (chiave stabile: l'array inputDcmts può essere ricreato a ogni render)
312
+ const inputDcmtsKey = useMemo(() => (inputDcmts ?? []).map(d => `${d.TID}-${d.DID}`).join('|'), [inputDcmts]);
313
+ useEffect(() => {
314
+ isLeavingRef.current = false;
315
+ }, [inputDcmtsKey]);
241
316
  // Load dtdMaster when inputDcmts changes
242
317
  useEffect(() => {
243
318
  const loadDtdMaster = async () => {
@@ -300,7 +375,11 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
300
375
  icon: _jsx(IconCheckFile, { color: showZeroDcmts ? TMColors.tertiary : TMColors.text_normal }),
301
376
  name: showZeroDcmts ? SDKUI_Localizator.HideDetailsWithZeroDocs : SDKUI_Localizator.ShowDetailsWithZeroDocs,
302
377
  onClick: () => {
303
- setShowZeroDcmts(prev => !prev);
378
+ setShowZeroDcmts(prev => {
379
+ const newValue = !prev;
380
+ SDKUI_Globals.userSettings.searchSettings.relationShowZeroDcmts = newValue;
381
+ return newValue;
382
+ });
304
383
  }
305
384
  },
306
385
  {
@@ -331,11 +410,11 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
331
410
  setContextMenuVisible(true);
332
411
  }, children: [_jsx(TMRelationViewerWrapper, { refreshKey: refreshKey, inputDcmts: inputDcmts, isForMaster: isForMaster, showCurrentDcmtIndicator: showCurrentDcmtIndicator, showZeroDcmts: showZeroDcmts,
333
412
  // customItemRender={customItemRender}
334
- allowMultipleSelection: allowMultipleSelection, focusedItem: focusedItem, selectedItems: selectedItems, onFocusedItemChanged: handleFocusedItemChanged, onSelectedItemsChanged: handleSelectedItemsChanged, onNoRelationsFound: handleNoRelationsFound, onItemContextMenu: isRelationViewerLoading ? undefined : onItemContextMenu, focusedItemFormData: focusedItemFormData, onLoadingStateChanged: setIsRelationViewerLoading }), _jsx(TMContextMenu, { items: operationItems, externalControl: {
413
+ allowMultipleSelection: allowMultipleSelection, focusedItem: focusedItem, selectedItems: selectedItems, onFocusedItemChanged: handleFocusedItemChanged, onSelectedItemsChanged: handleSelectedItemsChanged, onNoRelationsFound: handleNoRelationsFound, onItemContextMenu: isRelationViewerLoading ? undefined : onItemContextMenu, onLoadingStateChanged: setIsRelationViewerLoading, onStopCalculationReady: handleStopCalculationReady, onCalculationStopped: handleRelationsCalculationStopped, initialTreeState: treeStateRef.current, onTreeStateChange: handleTreeStateChange }), _jsx(TMContextMenu, { items: operationItems, externalControl: {
335
414
  visible: contextMenuVisible,
336
415
  position: contextMenuPosition,
337
416
  onClose: () => setContextMenuVisible(false)
338
- } })] }) }), [inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, allowMultipleSelection, focusedItem, selectedItems, handleFocusedItemChanged, handleSelectedItemsChanged, handleNoRelationsFound, onItemContextMenu, contextMenuVisible, contextMenuPosition, refreshKey, focusedItemFormData, isRelationViewerLoading]);
417
+ } })] }) }), [inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, allowMultipleSelection, focusedItem, selectedItems, handleFocusedItemChanged, handleSelectedItemsChanged, handleNoRelationsFound, onItemContextMenu, contextMenuVisible, contextMenuPosition, refreshKey, focusedItemFormData, isRelationViewerLoading, handleStopCalculationReady, handleRelationsCalculationStopped, handleTreeStateChange]);
339
418
  const tmFormOrResult = useMemo(() => _jsx(TMFormOrResultWrapper, { refreshKey: refreshKeyFormOrResult, deviceType: deviceType, focusedItem: focusedItem, onTaskCreateRequest: onTaskCreateRequest, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, handleNavigateToReference: handleNavigateToReference, onRefreshAfterAddDcmtToFavs: onRefreshAfterAddDcmtToFavs, editPdfForm: editPdfForm, openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, onOpenPdfEditorRequest: onOpenPdfEditorRequest, onRefreshSearchResults: onRefreshAllPanels }), [focusedItem, deviceType, allTasks, handleNavigateToWGs, handleNavigateToDossiers, handleNavigateToReference, editPdfForm, openS4TViewer, onOpenS4TViewerRequest, onOpenPdfEditorRequest, onRefreshAfterAddDcmtToFavs, refreshKeyFormOrResult]);
340
419
  const initialPanelDimensions = {
341
420
  'tmTreeView': { width: '50%', height: '100%' },
@@ -366,7 +445,9 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
366
445
  title: getTitle(),
367
446
  toolbar: toolbar,
368
447
  allowMaximize: !isMobile,
369
- onBack: onBack
448
+ // handleBack interrompe il calcolo prima di uscire.
449
+ // Resta undefined se il padre non ha passato onBack (nessun pulsante indietro)
450
+ onBack: onBack ? handleBack : undefined
370
451
  }
371
452
  },
372
453
  toolbarOptions: {
@@ -413,10 +494,7 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
413
494
  toolbarOptions: { icon: _jsx(IconSearchCheck, { fontSize: 24 }), visible: false, orderNumber: 2, isActive: allInitialPanelVisibility['tmFormOrResult'] }
414
495
  }
415
496
  ], [tmTreeView, tmFormOrResult, focusedItem?.isDcmt, dtdMaster]);
416
- return (_jsxs("div", { style: { width: '100%', height: '100%', position: 'relative' }, children: [isCheckingFirstLoad && (_jsx(TMLoadingOverlay, { onCancel: () => {
417
- setIsCheckingFirstLoad(false);
418
- onBack?.();
419
- } })), _jsxs("div", { style: isCheckingFirstLoad ? { position: 'absolute', width: 0, height: 0, overflow: 'hidden', opacity: 0, pointerEvents: 'none' } : { width: '100%', height: '100%' }, children: [_jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, showWaitPanelSecondary: showSecondary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, waitPanelTextSecondary: waitPanelTextSecondary, waitPanelValueSecondary: waitPanelValueSecondary, waitPanelMaxValueSecondary: waitPanelMaxValueSecondary, isCancelable: true, abortController: abortController, children: _jsx(TMPanelManagerProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: initialPanelDimensions, initialDimensions: initialPanelDimensions, initialMobilePanelId: 'tmTreeView', children: _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", showToolbar: true }) }) }), renderDcmtOperations, renderFloatingBar] })] }));
497
+ return (_jsx("div", { style: { width: '100%', height: '100%', position: 'relative' }, children: _jsxs("div", { style: isCheckingFirstLoad ? { position: 'absolute', width: 0, height: 0, overflow: 'hidden', opacity: 0, pointerEvents: 'none' } : { width: '100%', height: '100%' }, children: [_jsx(TMLayoutContainer, { direction: 'vertical', children: _jsx(TMPanelManagerProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: initialPanelDimensions, initialDimensions: initialPanelDimensions, initialMobilePanelId: 'tmTreeView', children: _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", showToolbar: true }) }) }), renderDcmtOperations, renderFloatingBar] }) }));
420
498
  };
421
499
  export default TMMasterDetailDcmts;
422
500
  /**
@@ -425,7 +503,7 @@ export default TMMasterDetailDcmts;
425
503
  * - Panel visibility toggling
426
504
  * - Focus delay handling
427
505
  */
428
- const TMRelationViewerWrapper = ({ refreshKey, inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, customItemRender, allowMultipleSelection, focusedItem, selectedItems, onFocusedItemChanged, onSelectedItemsChanged, onNoRelationsFound, onItemContextMenu, focusedItemFormData, onLoadingStateChanged }) => {
506
+ const TMRelationViewerWrapper = ({ refreshKey, inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, customItemRender, allowMultipleSelection, focusedItem, selectedItems, onFocusedItemChanged, onSelectedItemsChanged, onNoRelationsFound, onItemContextMenu, onLoadingStateChanged, onStopCalculationReady, onCalculationStopped, initialTreeState, onTreeStateChange }) => {
429
507
  const { setPanelVisibilityById, setToolbarButtonVisibility } = useTMPanelManagerContext();
430
508
  // Monitor device type changes to restore panel visibility when switching from mobile to desktop
431
509
  const deviceType = useDeviceType();
@@ -485,7 +563,7 @@ const TMRelationViewerWrapper = ({ refreshKey, inputDcmts, isForMaster, showCurr
485
563
  onItemContextMenu?.(item, e);
486
564
  }, 100);
487
565
  }, [onItemContextMenu, handleFocusedItemChanged]);
488
- return (_jsx(TMRelationViewer, { inputDcmts: inputDcmts, isForMaster: isForMaster, showCurrentDcmtIndicator: showCurrentDcmtIndicator, initialShowZeroDcmts: showZeroDcmts, customItemRender: customItemRender, allowMultipleSelection: allowMultipleSelection, focusedItem: focusedItem, selectedItems: selectedItems, onFocusedItemChanged: handleFocusedItemChanged, onSelectedItemsChanged: onSelectedItemsChanged, maxDepthLevel: 1, invertMasterNavigation: false, showExpandAllButton: true, onNoRelationsFound: onNoRelationsFound, onItemContextMenu: onContextMenu, focusedItemFormData: focusedItemFormData, onLoadingStateChanged: onLoadingStateChanged }, refreshKey));
566
+ return (_jsx(TMRelationViewer, { inputDcmts: inputDcmts, isForMaster: isForMaster, showCurrentDcmtIndicator: showCurrentDcmtIndicator, initialShowZeroDcmts: showZeroDcmts, customItemRender: customItemRender, allowMultipleSelection: allowMultipleSelection, focusedItem: focusedItem, selectedItems: selectedItems, onFocusedItemChanged: handleFocusedItemChanged, onSelectedItemsChanged: onSelectedItemsChanged, maxDepthLevel: 1, invertMasterNavigation: false, showExpandAllButton: true, onNoRelationsFound: onNoRelationsFound, onItemContextMenu: onContextMenu, onLoadingStateChanged: onLoadingStateChanged, onStopCalculationReady: onStopCalculationReady, onCalculationStopped: onCalculationStopped, initialTreeState: initialTreeState, onTreeStateChange: onTreeStateChange }, refreshKey));
489
567
  };
490
568
  const TMFormOrResultWrapper = ({ refreshKey, deviceType, focusedItem, onTaskCreateRequest, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, onRefreshAfterAddDcmtToFavs, editPdfForm, openS4TViewer, onOpenS4TViewerRequest, onOpenPdfEditorRequest, onRefreshSearchAsyncDatagrid, onRefreshSearchResults, handleNavigateToReference, fetchRemoteCertificates }) => {
491
569
  const { setPanelVisibilityById } = useTMPanelManagerContext();
@@ -495,94 +573,3 @@ const TMFormOrResultWrapper = ({ refreshKey, deviceType, focusedItem, onTaskCrea
495
573
  }, fetchRemoteCertificates: fetchRemoteCertificates }, refreshKey) :
496
574
  focusedItem?.searchResult === undefined ? (_jsx(TMPanel, { title: SDKUI_Localizator.SearchResult, children: _jsx(TMToppyMessage, { message: SDKUI_Localizator.SelectDocumentToViewSearchResults }) })) : (_jsx(TMSearchResult, { groupId: 'tmFormOrResult', isClosable: deviceType !== DeviceType.MOBILE, context: SearchResultContext.METADATA_SEARCH, allowFloatingBar: false, allowRelations: false, openDcmtFormAsModal: true, searchResults: focusedItem?.searchResult ?? [], showSearchResultSidebar: false, showDcmtFormSidebar: false, autoFocusFirstRow: false, onTaskCreateRequest: onTaskCreateRequest, onClose: () => { setPanelVisibilityById('tmTreeView', true); }, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, editPdfForm: editPdfForm, onOpenPdfEditorRequest: onOpenPdfEditorRequest, openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, enablePinIcons: false, onRefreshAfterAddDcmtToFavs: onRefreshAfterAddDcmtToFavs, showBackButton: false, onRefreshSearchAsyncDatagrid: onRefreshSearchResults, onReferenceClick: handleNavigateToReference, fetchRemoteCertificates: fetchRemoteCertificates }, refreshKey)) }));
497
575
  };
498
- const TMLoadingOverlay = ({ onCancel, description, cancelText }) => {
499
- return (_jsx("div", { style: {
500
- position: 'absolute',
501
- top: 0,
502
- left: 0,
503
- width: '100%',
504
- height: '100%',
505
- backgroundColor: 'rgba(248, 250, 252, 0.92)',
506
- zIndex: 1000,
507
- display: 'flex',
508
- justifyContent: 'center',
509
- alignItems: 'center',
510
- }, children: _jsxs("div", { style: {
511
- display: 'flex',
512
- flexDirection: 'column',
513
- alignItems: 'center',
514
- gap: '16px',
515
- padding: '24px 32px',
516
- background: '#fcfcfc',
517
- borderRadius: '8px',
518
- boxShadow: '0 4px 16px rgba(0, 0, 0, 0.1)',
519
- }, children: [_jsxs("div", { style: { position: 'relative', width: '80px', height: '80px' }, children: [_jsx("img", { style: {
520
- position: 'absolute',
521
- top: '50%',
522
- left: '50%',
523
- transform: 'translate(-54%, -54%)'
524
- }, src: sixLogo, width: 35, alt: "" }), _jsx("style", { children: `
525
- @keyframes tmSpinnerRotate {
526
- 0% { transform: rotate(0deg); }
527
- 100% { transform: rotate(360deg); }
528
- }
529
- .tm-spinner-animation {
530
- display: inline-block;
531
- width: 80px;
532
- height: 80px;
533
- position: absolute;
534
- top: 50%;
535
- left: 50%;
536
- transform: translate(-50%, -50%);
537
- }
538
- .tm-spinner-animation div {
539
- animation: tmSpinnerRotate 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
540
- transform-origin: 40px 40px;
541
- }
542
- .tm-spinner-animation div:after {
543
- content: " ";
544
- display: block;
545
- position: absolute;
546
- width: 7px;
547
- height: 7px;
548
- border-radius: 50%;
549
- background: #0c448e;
550
- margin: -4px 0 0 -4px;
551
- }
552
- .tm-spinner-animation div:nth-child(1) { animation-delay: -0.036s; }
553
- .tm-spinner-animation div:nth-child(1):after { top: 63px; left: 63px; background: #f7a51f; }
554
- .tm-spinner-animation div:nth-child(2) { animation-delay: -0.072s; }
555
- .tm-spinner-animation div:nth-child(2):after { top: 68px; left: 56px; background: #f7a51f; }
556
- .tm-spinner-animation div:nth-child(3) { animation-delay: -0.108s; }
557
- .tm-spinner-animation div:nth-child(3):after { top: 71px; left: 48px; background: #d3237b; }
558
- .tm-spinner-animation div:nth-child(4) { animation-delay: -0.144s; }
559
- .tm-spinner-animation div:nth-child(4):after { top: 72px; left: 40px; background: #d3237b; }
560
- .tm-spinner-animation div:nth-child(5) { animation-delay: -0.18s; }
561
- .tm-spinner-animation div:nth-child(5):after { top: 71px; left: 32px; background: #d12a1c; }
562
- .tm-spinner-animation div:nth-child(6) { animation-delay: -0.216s; }
563
- .tm-spinner-animation div:nth-child(6):after { top: 68px; left: 24px; background: #d12a1c; }
564
- .tm-spinner-animation div:nth-child(7) { animation-delay: -0.252s; }
565
- .tm-spinner-animation div:nth-child(7):after { top: 63px; left: 17px; background: #782b7d; }
566
- .tm-spinner-animation div:nth-child(8) { animation-delay: -0.288s; }
567
- .tm-spinner-animation div:nth-child(8):after { top: 56px; left: 12px; background: #782b7d; }
568
- ` }), _jsxs("div", { className: "tm-spinner-animation", children: [_jsx("div", {}), _jsx("div", {}), _jsx("div", {}), _jsx("div", {}), _jsx("div", {}), _jsx("div", {}), _jsx("div", {}), _jsx("div", {})] })] }), _jsx("span", { style: { fontSize: '14px', color: '#334155', textAlign: 'center' }, children: description ?? SDKUI_Localizator.Loading }), onCancel && (_jsx("button", { onClick: onCancel, style: {
569
- marginTop: '4px',
570
- padding: '8px 24px',
571
- fontSize: '13px',
572
- fontWeight: 500,
573
- color: '#64748b',
574
- background: 'transparent',
575
- border: '1.5px solid #cbd5e1',
576
- borderRadius: '6px',
577
- cursor: 'pointer',
578
- transition: 'all 0.2s ease',
579
- }, onMouseEnter: (e) => {
580
- e.currentTarget.style.background = '#f1f5f9';
581
- e.currentTarget.style.borderColor = '#94a3b8';
582
- e.currentTarget.style.color = '#475569';
583
- }, onMouseLeave: (e) => {
584
- e.currentTarget.style.background = 'transparent';
585
- e.currentTarget.style.borderColor = '#cbd5e1';
586
- e.currentTarget.style.color = '#64748b';
587
- }, children: cancelText ?? SDKUI_Localizator.Cancel }))] }) }));
588
- };
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import { DcmtTypeDescriptor } from '@topconsultnpm/sdk-ts';
3
+ import { DcmtInfo } from '../../../ts';
4
+ interface TMMasterInfoFieldsProps {
5
+ /** Tipo documento: definisce i metadati (utente) da mostrare e come formattarli */
6
+ dtd: DcmtTypeDescriptor | undefined;
7
+ /** Documento di cui mostrare i metadati: se cambia, i valori vengono riletti */
8
+ dcmt: DcmtInfo | undefined;
9
+ /** Legge i valori del documento indicizzati per mid (il chiamante li tiene in cache) */
10
+ getValuesByMidAsync: () => Promise<Map<number, any>>;
11
+ /** Incrementare per forzare la rilettura dei valori (es. dopo il salvataggio del documento) */
12
+ reloadToken?: number;
13
+ /**
14
+ * Vista a tutto schermo: c'è spazio per tutti i metadati, quindi niente limite dell'anteprima
15
+ * ed è qui che compare la ricerca per nome/valore.
16
+ */
17
+ isExpandedView?: boolean;
18
+ }
19
+ declare const TMMasterInfoFields: ({ dtd, dcmt, getValuesByMidAsync, reloadToken, isExpandedView }: TMMasterInfoFieldsProps) => React.JSX.Element;
20
+ export default TMMasterInfoFields;
@@ -0,0 +1,185 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useState } from 'react';
3
+ import { DataListViewModes, MetadataDataDomains, SDK_Globals } from '@topconsultnpm/sdk-ts';
4
+ import { hoverStyle, IconChevronDown, IconClearButton, IconCopy, IconSearch, IconSuccess, SDKUI_Localizator } from '../../../helper';
5
+ import { canViewMetadata, formatScalarValue, getUserMetadataSorted } from '../../../helper/dcmtsHelper';
6
+ import { useDataListItem } from '../../../hooks/useDataListItem';
7
+ import { TMColors } from '../../../utils/theme';
8
+ import ShowAlert from '../../base/TMAlert';
9
+ import TMTooltip from '../../base/TMTooltip';
10
+ // Metadati mostrati in linea prima del pulsante "mostra tutti".
11
+ const PREVIEW_COUNT = 12;
12
+ const styles = {
13
+ wrapper: { display: 'flex', flexDirection: 'column', flex: 1, minHeight: 0, borderTop: `1px solid ${TMColors.card_background}` },
14
+ body: { flex: 1, minHeight: 0, padding: '13px 10px 9px', display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(185px, 1fr))', gridAutoRows: 'max-content', alignContent: 'start', columnGap: '10px', rowGap: '13px', overflow: 'auto' },
15
+ item: { position: 'relative', display: 'flex', alignItems: 'center', minWidth: 0, minHeight: '30px', padding: '5px 10px 4px', borderRadius: '8px', border: `1px solid ${TMColors.card_background}`, background: TMColors.default_background, transition: 'border-color 0.15s ease, box-shadow 0.15s ease' },
16
+ // Come per il pulsante copia, la posizione sta sull'ancora del tooltip; il troncamento con i
17
+ // puntini deve invece stare sull'elemento che contiene il testo
18
+ label: { position: 'absolute', top: '-7px', left: '8px', maxWidth: 'calc(100% - 16px)', minWidth: 0, padding: '0 5px', background: TMColors.default_background },
19
+ labelText: { maxWidth: '100%', fontSize: '9px', fontWeight: 700, lineHeight: '13px', letterSpacing: '0.5px', textTransform: 'uppercase', color: TMColors.label_normal, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' },
20
+ value: { display: 'block', width: '100%', fontSize: '12.5px', fontWeight: 500, color: TMColors.text_normal, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', userSelect: 'text', cursor: 'text', minHeight: '17px', lineHeight: '17px' },
21
+ emptyValue: { color: TMColors.disabled, fontWeight: 400 },
22
+ // Pulsante di copia: pastiglia sul bordo superiore della card, come la caption
23
+ // La posizione sta sull'ancora e non sul pulsante: è il contenitore del tooltip, che deve stare
24
+ // dove si vede il pulsante, altrimenti il tooltip si aprirebbe altrove
25
+ copyBtnAnchor: { position: 'absolute', top: '-9px', right: '6px', transition: 'opacity 0.15s ease' },
26
+ copyBtn: { display: 'flex', alignItems: 'center', justifyContent: 'center', width: '18px', height: '18px', padding: 0, borderRadius: '50%', border: `1px solid ${TMColors.card_background}`, background: TMColors.default_background, color: TMColors.label_normal, cursor: 'pointer', transition: 'background 0.15s ease, color 0.15s ease, border-color 0.15s ease' },
27
+ placeholder: { gridColumn: '1 / -1', padding: '6px 2px', color: TMColors.label_normal, fontSize: '12px' },
28
+ // Barra di ricerca
29
+ searchBar: { display: 'flex', alignItems: 'center', gap: '8px', padding: '12px 14px 0', flexShrink: 0 },
30
+ searchBox: { position: 'relative', display: 'flex', alignItems: 'center', flex: 1, minWidth: 0, maxWidth: '300px', height: '26px', borderRadius: '13px', border: `1px solid ${TMColors.card_background}`, background: TMColors.toolbar_background, transition: 'border-color 0.15s ease, box-shadow 0.15s ease' },
31
+ searchIcon: { flexShrink: 0, margin: '0 3px 0 9px', color: TMColors.label_normal, display: 'flex' },
32
+ searchInput: { flex: 1, minWidth: 0, height: '100%', padding: '0 2px', margin: 0, border: 'none', outline: 'none', background: 'transparent', fontSize: '12px', color: TMColors.text_normal },
33
+ searchClear: { display: 'flex', alignItems: 'center', justifyContent: 'center', width: '18px', height: '18px', marginRight: '5px', padding: 0, border: 'none', borderRadius: '50%', background: 'transparent', color: TMColors.label_normal, cursor: 'pointer', flexShrink: 0, transition: 'background 0.15s ease, color 0.15s ease' },
34
+ searchCount: { fontSize: '11px', fontWeight: 600, color: TMColors.label_normal, whiteSpace: 'nowrap', flexShrink: 0 },
35
+ // Pulsante "mostra tutti / comprimi"
36
+ footer: { display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '2px 10px 9px', flexShrink: 0 },
37
+ showAllBtn: { display: 'inline-flex', alignItems: 'center', gap: '6px', height: '24px', padding: '0 13px', borderRadius: '12px', border: `1px solid ${TMColors.primary_container}`, background: TMColors.primary_container, color: TMColors.primary, fontSize: '11.5px', fontWeight: 700, letterSpacing: '0.2px', cursor: 'pointer', transition: 'background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease' },
38
+ };
39
+ // Sui dispositivi touch l'hover non esiste: il pulsante di copia deve restare sempre visibile
40
+ const SUPPORTS_HOVER = typeof window === 'undefined' || window.matchMedia?.('(hover: hover)')?.matches !== false;
41
+ // Colori del pulsante di copia nei suoi tre stati
42
+ const COPY_BTN_IDLE = { background: TMColors.default_background, borderColor: TMColors.card_background, color: TMColors.label_normal };
43
+ const COPY_BTN_HOVER = { background: TMColors.primary_container, borderColor: TMColors.primary, color: TMColors.primary };
44
+ const COPY_BTN_COPIED = { background: TMColors.default_background, borderColor: TMColors.success, color: TMColors.success };
45
+ // Card di un singolo metadato: hover e feedback della copia sono locali, così non si ridisegna tutta la griglia
46
+ const MetadataCard = ({ caption, copyText, children }) => {
47
+ const [isHovered, setIsHovered] = useState(false);
48
+ const [isCopied, setIsCopied] = useState(false);
49
+ // Il feedback "copiato" si spegne da solo: il timer va annullato se la card sparisce prima
50
+ useEffect(() => {
51
+ if (!isCopied)
52
+ return;
53
+ const timerID = setTimeout(() => setIsCopied(false), 1400);
54
+ return () => clearTimeout(timerID);
55
+ }, [isCopied]);
56
+ const copyAsync = async () => {
57
+ try {
58
+ await navigator.clipboard.writeText(copyText);
59
+ setIsCopied(true);
60
+ }
61
+ catch {
62
+ ShowAlert({ message: SDKUI_Localizator.FailedToCopyToClipboard, mode: 'error', title: SDKUI_Localizator.CopyToClipboard, duration: 3000 });
63
+ }
64
+ };
65
+ // Il pulsante resta visibile durante il feedback e quando ha il focus (accessibilità da tastiera)
66
+ const isCopyVisible = copyText !== '' && (!SUPPORTS_HOVER || isHovered || isCopied);
67
+ return (_jsxs("div", { style: styles.item, onMouseEnter: (e) => { setIsHovered(true); Object.assign(e.currentTarget.style, { borderColor: TMColors.primary, boxShadow: '0 2px 8px rgba(37, 89, 165, 0.14)' }); }, onMouseLeave: (e) => { setIsHovered(false); Object.assign(e.currentTarget.style, { borderColor: TMColors.card_background, boxShadow: 'none' }); }, children: [_jsx(TMTooltip, { content: caption, parentStyle: { ...styles.label, maxWidth: isCopyVisible ? 'calc(100% - 38px)' : 'calc(100% - 16px)' }, childStyle: { maxWidth: '100%', minWidth: 0 }, children: _jsx("span", { style: styles.labelText, children: caption }) }), children, copyText !== '' && (_jsx(TMTooltip, { content: isCopied ? SDKUI_Localizator.CopiedSuccessfully : SDKUI_Localizator.CopyToClipboard, parentStyle: { ...styles.copyBtnAnchor, opacity: isCopyVisible ? 1 : 0, pointerEvents: isCopyVisible ? 'auto' : 'none' }, children: _jsx("button", { type: 'button', style: { ...styles.copyBtn, ...(isCopied ? COPY_BTN_COPIED : COPY_BTN_IDLE) }, "aria-label": SDKUI_Localizator.CopyToClipboard, onClick: copyAsync, onFocus: () => setIsHovered(true), onBlur: () => setIsHovered(false), ...hoverStyle(isCopied ? COPY_BTN_COPIED : COPY_BTN_HOVER, isCopied ? COPY_BTN_COPIED : COPY_BTN_IDLE), children: isCopied ? _jsx(IconSuccess, { fontSize: 11 }) : _jsx(IconCopy, { fontSize: 11 }) }) }))] }));
68
+ };
69
+ // Riepilogo dei metadati di un documento in card compatte
70
+ const TMMasterInfoFields = ({ dtd, dcmt, getValuesByMidAsync, reloadToken, isExpandedView = false }) => {
71
+ const { renderDataListCell, loadDataListsAsync, getDataListItem } = useDataListItem();
72
+ const [rows, setRows] = useState([]);
73
+ // Finché la prima lettura non è conclusa non si mostra "nessun dato" (evita il lampo al primo render)
74
+ const [isLoaded, setIsLoaded] = useState(false);
75
+ const [filter, setFilter] = useState('');
76
+ const [showAll, setShowAll] = useState(false);
77
+ // Carica i metadati del documento (valori + liste dati referenziate).
78
+ // getValuesByMidAsync è volutamente fuori dalle dipendenze: il chiamante la ricrea a ogni render
79
+ useEffect(() => {
80
+ let cancelled = false;
81
+ const loadAsync = async () => {
82
+ try {
83
+ if (!dcmt?.TID || !dcmt?.DID) {
84
+ setRows([]);
85
+ return;
86
+ }
87
+ // I metadati che l'utente non può vedere non si mostrano, come nel risultato di ricerca
88
+ const metadata = getUserMetadataSorted(dtd).filter(canViewMetadata);
89
+ // Precarica le liste dati referenziate dai metadati, così le card mostrano subito il valore leggibile
90
+ const dataListIDs = new Set();
91
+ metadata.forEach(md => { if (md.dataDomain === MetadataDataDomains.DataList && md.dataListID)
92
+ dataListIDs.add(md.dataListID); });
93
+ await loadDataListsAsync(dataListIDs);
94
+ const valueByMid = await getValuesByMidAsync();
95
+ if (cancelled)
96
+ return;
97
+ setRows(metadata.map(md => ({
98
+ mid: md.id,
99
+ caption: (SDK_Globals.useLocalizedName ? md.nameLoc : md.name) ?? md.name ?? '',
100
+ value: valueByMid.get(md.id),
101
+ dataListID: (md.dataDomain === MetadataDataDomains.DataList && md.dataListID) ? md.dataListID : 0,
102
+ viewMode: md.dataListViewMode ?? DataListViewModes.None,
103
+ dataType: md.dataType,
104
+ format: md.format?.format,
105
+ formatCulture: md.format?.formatCulture,
106
+ })));
107
+ }
108
+ catch {
109
+ if (!cancelled)
110
+ setRows([]);
111
+ }
112
+ finally {
113
+ if (!cancelled)
114
+ setIsLoaded(true);
115
+ }
116
+ };
117
+ // Cambiando documento/tipo documento il filtro non ha più senso: si riparte dall'anteprima
118
+ setFilter('');
119
+ setShowAll(false);
120
+ loadAsync();
121
+ return () => { cancelled = true; };
122
+ }, [dtd?.id, dcmt?.TID, dcmt?.DID, reloadToken]);
123
+ // La barra di ricerca esiste solo nella vista ingrandita: tornando in linea il filtro non è più
124
+ // visibile e resterebbe attivo, nascondendo i primi metadati dell'anteprima
125
+ useEffect(() => {
126
+ if (isExpandedView)
127
+ return;
128
+ setFilter('');
129
+ setShowAll(false);
130
+ }, [isExpandedView]);
131
+ // Testo su cui cerca il filtro: valore visualizzato del metadato (per le liste dati il nome dell'item)
132
+ const getSearchText = (item) => {
133
+ if (item.value === undefined || item.value === null || item.value === '')
134
+ return '';
135
+ if (item.dataListID > 0) {
136
+ const dataListItem = getDataListItem(item.dataListID, item.value);
137
+ return dataListItem ? `${dataListItem.name ?? ''} ${dataListItem.value ?? ''}` : String(item.value);
138
+ }
139
+ return formatScalarValue(item.value, item.dataType, item.format, item.formatCulture);
140
+ };
141
+ // Testo copiato negli appunti: quello che l'utente vede nella card (per le liste dati il nome dell'item)
142
+ const getCopyText = (item) => {
143
+ if (item.value === undefined || item.value === null || item.value === '')
144
+ return '';
145
+ if (item.dataListID > 0) {
146
+ const dataListItem = getDataListItem(item.dataListID, item.value);
147
+ return dataListItem?.name ?? String(item.value);
148
+ }
149
+ return formatScalarValue(item.value, item.dataType, item.format, item.formatCulture);
150
+ };
151
+ // Ricerca case insensitive su nome e valore del metadato
152
+ const query = filter.trim().toLowerCase();
153
+ const filteredRows = useMemo(() => {
154
+ if (!query)
155
+ return rows;
156
+ return rows.filter(item => item.caption.toLowerCase().includes(query) || getSearchText(item).toLowerCase().includes(query));
157
+ }, [rows, query]);
158
+ const renderCard = (item) => {
159
+ const hasValue = item.value !== undefined && item.value !== null && item.value !== '';
160
+ const displayNode = item.dataListID > 0 && hasValue ? renderDataListCell(item.value, item.dataListID, item.viewMode) : (hasValue ? formatScalarValue(item.value, item.dataType, item.format, item.formatCulture) : '');
161
+ return (_jsx(MetadataCard, { caption: item.caption, copyText: getCopyText(item), children: hasValue
162
+ ? (_jsx(TMTooltip, { content: displayNode, parentStyle: { flex: 1, minWidth: 0 }, childStyle: { maxWidth: '100%', minWidth: 0 }, children: _jsx("span", { style: { ...styles.value, minWidth: 0 }, children: displayNode }) }))
163
+ // Segnaposto per i metadati vuoti: la card mantiene la stessa altezza
164
+ : _jsx("span", { style: { ...styles.value, ...styles.emptyValue }, children: "\u2014" }) }, item.mid));
165
+ };
166
+ // Ricerca dei metadati: solo nella vista ingrandita e solo quando sono troppi per essere trovati a vista
167
+ const renderSearchBar = () => (_jsxs("div", { style: styles.searchBar, children: [_jsxs("div", { style: styles.searchBox, children: [_jsx(IconSearch, { fontSize: 13, style: styles.searchIcon }), _jsx("input", { type: 'text', value: filter, placeholder: `${SDKUI_Localizator.SearchAction}...`, style: styles.searchInput, onChange: (e) => setFilter(e.target.value),
168
+ // Esc svuota il filtro senza propagare la chiusura del modale
169
+ onKeyDown: (e) => { if (e.key === 'Escape' && filter !== '') {
170
+ e.preventDefault();
171
+ e.stopPropagation();
172
+ setFilter('');
173
+ } }, onFocus: (e) => Object.assign(e.currentTarget.parentElement?.style ?? {}, { borderColor: TMColors.primary, boxShadow: '0 0 0 2px rgba(37, 89, 165, 0.14)' }), onBlur: (e) => Object.assign(e.currentTarget.parentElement?.style ?? {}, { borderColor: TMColors.card_background, boxShadow: 'none' }) }), filter !== '' && (_jsx(TMTooltip, { content: SDKUI_Localizator.Clear, parentStyle: { display: 'flex', flexShrink: 0 }, children: _jsx("button", { type: 'button', style: styles.searchClear, "aria-label": SDKUI_Localizator.Clear, onClick: () => setFilter(''), ...hoverStyle({ background: TMColors.primary_container, color: TMColors.primary }, { background: 'transparent', color: TMColors.label_normal }), children: _jsx(IconClearButton, { fontSize: 13 }) }) }))] }), _jsxs("span", { style: styles.searchCount, children: [filteredRows.length, "/", rows.length] })] }));
174
+ // La ricerca sta solo nella vista ingrandita: in linea lo spazio è poco e l'elenco è limitato
175
+ // all'anteprima, con il pulsante per aprirlo tutto
176
+ const hasSearch = isExpandedView && rows.length > PREVIEW_COUNT;
177
+ const isCapped = !isExpandedView && !showAll && filteredRows.length > PREVIEW_COUNT;
178
+ const canCollapse = !isExpandedView && showAll && filteredRows.length > PREVIEW_COUNT;
179
+ const visibleRows = isCapped ? filteredRows.slice(0, PREVIEW_COUNT) : filteredRows;
180
+ const hiddenCount = filteredRows.length - visibleRows.length;
181
+ return (_jsxs("div", { style: { ...styles.wrapper, ...(isExpandedView ? { borderTop: 'none' } : {}) }, children: [hasSearch && renderSearchBar(), _jsx("div", { style: { ...styles.body, ...(isExpandedView ? { padding: '18px 14px 14px' } : {}) }, children: visibleRows.length > 0
182
+ ? visibleRows.map(renderCard)
183
+ : (isLoaded && _jsx("span", { style: styles.placeholder, children: SDKUI_Localizator.NoDataToDisplay })) }), (isCapped || canCollapse) && (_jsx("div", { style: styles.footer, children: _jsxs("button", { type: 'button', style: styles.showAllBtn, onClick: () => setShowAll(!showAll), ...hoverStyle({ background: TMColors.primary, borderColor: TMColors.primary, color: '#ffffff', boxShadow: '0 2px 6px rgba(37, 89, 165, 0.25)' }, { background: TMColors.primary_container, borderColor: TMColors.primary_container, color: TMColors.primary, boxShadow: 'none' }), children: [isCapped ? `${SDKUI_Localizator.ShowAll} (+${hiddenCount})` : SDKUI_Localizator.Collapse, _jsx(IconChevronDown, { fontSize: 13, style: { transform: isCapped ? 'none' : 'rotate(180deg)', transition: 'transform 0.2s ease' } })] }) }))] }));
184
+ };
185
+ export default TMMasterInfoFields;
@@ -18,8 +18,7 @@ interface ITMMergeToPdfFormProps {
18
18
  }
19
19
  /**
20
20
  * Form per l'unione di più documenti PDF in un singolo file.
21
- * Condivide TMDownloadRelationViewerSection e gli helper in copyAndMergeDcmtsShared
22
- * con TMCopyToFolderForm.
21
+ * Condivide TMDownloadRelationViewerSection e gli helper in copyAndMergeDcmtsShared con TMCopyToFolderForm.
23
22
  */
24
23
  declare const TMMergeToPdfForm: (props: ITMMergeToPdfFormProps) => React.JSX.Element;
25
24
  export default TMMergeToPdfForm;