@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
@@ -52,7 +52,7 @@ const TMToggleButton = ({ color = 'primary', value, label, elementStyle, fontSiz
52
52
  setCurrentColor(isModifiedWhen ? 'tertiary' : color);
53
53
  }, [isModifiedWhen, color]);
54
54
  const renderTooltip = () => { return (showTooltip && _jsx("div", { children: label })); };
55
- return (_jsx(TMTooltip, { hideAfterDelay: true, content: renderTooltip(), children: _jsxs(StyledToggleButtonWrapper, { children: [_jsx(StyledToggleButtonContainer, { "$value": value, "$color": currentColor, style: elementStyle, onClick: onValueChanged, children: _jsx(StyledToggleButtonSwitch, { "$value": value, children: _jsx(StyledToggleValue, { children: value ? 'ON' : 'OFF' }) }) }), !showTooltip && label &&
56
- _jsx(StyledToggleButtonLabel, { "$color": isModifiedWhen ? Colors.tertiary : Colors.primary, children: label })] }) }));
55
+ return (_jsx(TMTooltip, { hideAfterDelay: true, content: renderTooltip(), children: _jsxs(StyledToggleButtonWrapper, { children: [_jsx(StyledToggleButtonContainer, { $value: value, $color: currentColor, style: elementStyle, onClick: onValueChanged, children: _jsx(StyledToggleButtonSwitch, { $value: value, children: _jsx(StyledToggleValue, { children: value ? 'ON' : 'OFF' }) }) }), !showTooltip && label &&
56
+ _jsx(StyledToggleButtonLabel, { $color: isModifiedWhen ? Colors.tertiary : Colors.primary, children: label })] }) }));
57
57
  };
58
58
  export default TMToggleButton;
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import styled from 'styled-components';
3
3
  import TMRightSidebar from './TMRightSidebar';
4
4
  import { IconArrowLeft, SDKUI_Localizator } from '../../helper';
@@ -46,8 +46,8 @@ const StyledSearchCardContent = styled.div `
46
46
  -webkit-user-select: none;
47
47
  `;
48
48
  const TMToolbarCard = ({ items = [], onItemClick, selectedItem, showPanel, color = TMColors.colorHeader, backgroundColor = TMColors.backgroundColorHeader, backgroundColorContainer, children, showHeader = true, title, totalItems, displayedItemsCount, toolbar, padding = '3px', onBack, onClose, onHeaderDoubleClick }) => {
49
- return (_jsxs(StyledSearchCard, { children: [showHeader && _jsx(StyledSearchCardHeader, { "$backgroundColor": backgroundColor, "$color": color, onDoubleClick: () => { if (onHeaderDoubleClick)
50
- onHeaderDoubleClick(); }, children: _jsxs("div", { style: { display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', width: '100%' }, children: [_jsxs("div", { style: { display: 'flex', flexDirection: 'row', alignItems: 'center', gap: '8px' }, children: [onBack && _jsx(TMButton, { btnStyle: 'icon', icon: _jsx("div", { style: { backgroundColor: 'white', minWidth: '24px', minHeight: '24px', borderRadius: '24px', display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: _jsx(IconArrowLeft, { color: TMColors.primaryColor }) }), caption: SDKUI_Localizator.Back, onClick: onBack }), _jsxs("div", { style: { display: 'flex', flexDirection: 'row', alignItems: 'center' }, children: [_jsx("p", { children: title }), Boolean(displayedItemsCount && displayedItemsCount > 0) && (_jsxs(_Fragment, { children: [_jsx(StyledBadge, { "$backgroundColor": '#679CE8', children: displayedItemsCount }), Boolean(totalItems && totalItems > 0) && _jsx("span", { children: "\u00A0\u00A0/\u00A0" })] })), Boolean(totalItems && totalItems > 0) && _jsx(StyledBadge, { "$backgroundColor": '#679CE8', children: totalItems })] })] }), _jsxs("div", { style: { display: 'flex', flexDirection: 'row', alignItems: 'center', gap: '5px' }, children: [toolbar, onClose && _jsx(TMButton, { color: 'primaryOutline', caption: SDKUI_Localizator.Close, icon: _jsx("i", { className: 'dx-icon-remove', style: { color: "white" } }), btnStyle: 'icon', onClick: () => onClose?.() })] })] }) }), _jsxs(StyledSearchCardContent, { "$height": showHeader ? "calc(100% - 35px)" : "100%", "$padding": padding, "$backgroundColor": backgroundColorContainer ?? `${TMColors.backgroundColorHeader}12`, children: [_jsx("div", { style: { width: items.length > 0 ? 'calc(100% - 30px)' : '100%' }, children: children }), items.length > 0 &&
49
+ return (_jsxs(StyledSearchCard, { children: [showHeader && _jsx(StyledSearchCardHeader, { $backgroundColor: backgroundColor, $color: color, onDoubleClick: () => { if (onHeaderDoubleClick)
50
+ onHeaderDoubleClick(); }, children: _jsxs("div", { style: { display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', width: '100%' }, children: [_jsxs("div", { style: { display: 'flex', flexDirection: 'row', alignItems: 'center', gap: '8px' }, children: [onBack && _jsx(TMButton, { btnStyle: 'icon', icon: _jsx("div", { style: { backgroundColor: 'white', minWidth: '24px', minHeight: '24px', borderRadius: '24px', display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: _jsx(IconArrowLeft, { color: TMColors.primaryColor }) }), caption: SDKUI_Localizator.Back, onClick: onBack }), _jsxs("div", { style: { display: 'flex', flexDirection: 'row', alignItems: 'center' }, children: [_jsx("p", { children: title }), Boolean(displayedItemsCount && displayedItemsCount > 0) && (_jsxs(_Fragment, { children: [_jsx(StyledBadge, { $backgroundColor: '#679CE8', children: displayedItemsCount }), Boolean(totalItems && totalItems > 0) && _jsx("span", { children: "\u00A0\u00A0/\u00A0" })] })), Boolean(totalItems && totalItems > 0) && _jsx(StyledBadge, { $backgroundColor: '#679CE8', children: totalItems })] })] }), _jsxs("div", { style: { display: 'flex', flexDirection: 'row', alignItems: 'center', gap: '5px' }, children: [toolbar, onClose && _jsx(TMButton, { color: 'primaryOutline', caption: SDKUI_Localizator.Close, icon: _jsx("i", { className: 'dx-icon-remove', style: { color: "white" } }), btnStyle: 'icon', onClick: () => onClose?.() })] })] }) }), _jsxs(StyledSearchCardContent, { $height: showHeader ? "calc(100% - 35px)" : "100%", $padding: padding, $backgroundColor: backgroundColorContainer ?? `${TMColors.backgroundColorHeader}12`, children: [_jsx("div", { style: { width: items.length > 0 ? 'calc(100% - 30px)' : '100%' }, children: children }), items.length > 0 &&
51
51
  _jsx(TMRightSidebar, { items: items, onItemClick: onItemClick, selectedItem: selectedItem, showPanel: showPanel })] })] }));
52
52
  };
53
53
  export default TMToolbarCard;
@@ -9,6 +9,7 @@ interface ITMTooltipProps extends ITooltipOptions {
9
9
  hideAfterDelay?: boolean;
10
10
  parentStyle?: React.CSSProperties;
11
11
  childStyle?: React.CSSProperties;
12
+ allowContentInteraction?: boolean;
12
13
  }
13
- declare const TMTooltip: ({ children, position, content, hideAfterDelay, parentStyle, childStyle }: ITMTooltipProps) => React.JSX.Element;
14
+ declare const TMTooltip: ({ children, position, content, hideAfterDelay, parentStyle, childStyle, allowContentInteraction }: ITMTooltipProps) => React.JSX.Element;
14
15
  export default TMTooltip;
@@ -1,20 +1,36 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useState } from 'react';
2
+ import { useEffect, useRef, useState } from 'react';
3
3
  import { Tooltip } from 'devextreme-react/tooltip';
4
4
  import { genUniqueId } from '../../helper';
5
5
  import { DeviceType, useDeviceType } from './TMDeviceProvider';
6
- const TMTooltip = ({ children, position, content, hideAfterDelay, parentStyle, childStyle }) => {
6
+ /** Tempo per spostare il mouse dall'elemento al contenuto del tooltip, quando è interattivo */
7
+ const HIDE_DELAY_MS = 400;
8
+ const TMTooltip = ({ children, position, content, hideAfterDelay, parentStyle, childStyle, allowContentInteraction = false }) => {
7
9
  const [showTooltip, setShowTooltip] = useState(false);
8
- const [id, setID] = useState('');
9
- useEffect(() => { setID(genUniqueId()); }, [children]);
10
+ const [id] = useState(() => genUniqueId());
11
+ const hideTimerRef = useRef();
10
12
  useEffect(() => {
11
- window.addEventListener('click', () => setShowTooltip(false));
12
- return () => window.removeEventListener('click', () => setShowTooltip(false));
13
+ const hide = () => setShowTooltip(false);
14
+ window.addEventListener('click', hide);
15
+ return () => window.removeEventListener('click', hide);
13
16
  }, []);
17
+ useEffect(() => { return () => clearTimeout(hideTimerRef.current); }, []);
14
18
  const deviceType = useDeviceType();
15
- return (_jsxs("div", { style: parentStyle, children: [_jsx("div", { id: `idContainerTooltip${id}`, style: { display: 'flex', alignItems: 'center', height: 'max-content', width: 'max-content', ...childStyle }, onMouseEnter: () => { setShowTooltip(true); }, onMouseLeave: () => { setShowTooltip(false); }, onTouchStart: () => { setShowTooltip(true); }, onClick: () => { if (deviceType === DeviceType.DESKTOP || !hideAfterDelay)
19
+ const cancelHide = () => clearTimeout(hideTimerRef.current);
20
+ const show = () => { cancelHide(); setShowTooltip(true); };
21
+ const hide = () => {
22
+ cancelHide();
23
+ if (!allowContentInteraction) {
24
+ setShowTooltip(false);
25
+ return;
26
+ }
27
+ hideTimerRef.current = setTimeout(() => setShowTooltip(false), HIDE_DELAY_MS);
28
+ };
29
+ return (_jsxs("div", { style: parentStyle, children: [_jsx("div", { id: `idContainerTooltip${id}`, style: { display: 'flex', alignItems: 'center', height: 'max-content', width: 'max-content', ...childStyle }, onMouseEnter: show, onMouseLeave: hide, onTouchStart: show, onClick: () => { if (deviceType === DeviceType.DESKTOP || !hideAfterDelay)
16
30
  return; setTimeout(() => { setShowTooltip(false); }, 1500); }, onTouchEnd: () => { if (deviceType === DeviceType.DESKTOP || !hideAfterDelay)
17
31
  return; setTimeout(() => { setShowTooltip(false); }, 1500); }, children: children }), content &&
18
- _jsx(Tooltip, { target: `#idContainerTooltip${id}`, hideOnOutsideClick: true, visible: showTooltip, position: position ?? 'bottom', onHidden: () => setShowTooltip(false), children: content })] }));
32
+ _jsx(Tooltip, { target: `#idContainerTooltip${id}`, hideOnOutsideClick: true, visible: showTooltip, position: position ?? 'bottom', onHidden: () => setShowTooltip(false), children: allowContentInteraction
33
+ ? _jsx("div", { style: { pointerEvents: 'all' }, onMouseEnter: cancelHide, onMouseLeave: hide, children: content })
34
+ : content })] }));
19
35
  };
20
36
  export default TMTooltip;
@@ -31,11 +31,17 @@ interface ITMTreeViewProps {
31
31
  }
32
32
  declare const TMTreeView: ({ dataSource, focusedItem, selectedItems, allowMultipleSelection, onDataChanged, calculateItemsForNode, itemRender, onNodeUpdate, onFocusedItemChanged, onSelectionChanged, shouldDelayFocusOnEvent, onItemContextMenu, autoSelectChildren, itemsPerPage, showLoadMoreButton, enableVirtualization }: ITMTreeViewProps) => React.JSX.Element;
33
33
  export default TMTreeView;
34
- export declare const StyledTreeContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
35
- export declare const StyledItemContent: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
36
- export declare const StyledTreeNode: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "$isSelected"> & {
34
+ export declare const StyledTreeContainer: import("styled-components/dist/types").IStyledComponentBase<"web", Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "style"> & {
35
+ style?: React.CSSProperties | import("styled-components/dist/types").CSSPropertiesWithVars | undefined;
36
+ }> & string;
37
+ export declare const StyledItemContent: import("styled-components/dist/types").IStyledComponentBase<"web", Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "style"> & {
38
+ style?: React.CSSProperties | import("styled-components/dist/types").CSSPropertiesWithVars | undefined;
39
+ }> & string;
40
+ export declare const StyledTreeNode: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Merged<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "style"> & {
41
+ style?: React.CSSProperties | import("styled-components/dist/types").CSSPropertiesWithVars | undefined;
42
+ }, {
37
43
  $isSelected?: boolean;
38
- }, never> & Partial<Pick<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "$isSelected"> & {
39
- $isSelected?: boolean;
40
- }, never>>> & string;
41
- export declare const StyledStickyPaginator: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
44
+ }>> & string;
45
+ export declare const StyledStickyPaginator: import("styled-components/dist/types").IStyledComponentBase<"web", Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "style"> & {
46
+ style?: React.CSSProperties | import("styled-components/dist/types").CSSPropertiesWithVars | undefined;
47
+ }> & string;
@@ -4,6 +4,17 @@ import { List } from 'react-window';
4
4
  import styled from 'styled-components';
5
5
  import { IconArrowLeft, IconArrowRight, IconChevronDown, IconChevronRight, SDKUI_Localizator } from '../../helper';
6
6
  import TMButton from './TMButton';
7
+ // Campi in cui frecce, +, - e spazio servono alla digitazione (checkbox e bottoni esclusi)
8
+ const NON_TEXT_INPUT_TYPES = new Set(['checkbox', 'radio', 'button', 'submit', 'reset', 'image', 'file', 'color', 'range']);
9
+ const isEditableElement = (el) => {
10
+ if (el.isContentEditable)
11
+ return true;
12
+ if (el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement)
13
+ return true;
14
+ if (el instanceof HTMLInputElement)
15
+ return !NON_TEXT_INPUT_TYPES.has(el.type);
16
+ return false;
17
+ };
7
18
  // Componente riga virtualizzata memoizzato
8
19
  const VirtualRowComponent = memo(({ ariaAttributes, index, style, flattenedItems, focusedItemKey, selectedItemKeys, allowMultipleSelection, hasVisibleItems, handleNodeToggle, handleNodeClick, handleCheckboxChange, hasPartialChildSelection, itemRender, onItemContextMenu }) => {
9
20
  const item = flattenedItems[index];
@@ -20,7 +31,7 @@ const VirtualRowComponent = memo(({ ariaAttributes, index, style, flattenedItems
20
31
  minWidth: '100%',
21
32
  paddingRight: 10,
22
33
  boxSizing: 'border-box'
23
- }, children: _jsxs(StyledTreeNode, { "$isSelected": isSelected, children: [_jsx("div", { style: {
34
+ }, children: _jsxs(StyledTreeNode, { $isSelected: isSelected, children: [_jsx("div", { style: {
24
35
  display: 'flex',
25
36
  alignItems: 'center',
26
37
  justifyContent: 'center',
@@ -54,13 +65,16 @@ const VirtualRowComponent = memo(({ ariaAttributes, index, style, flattenedItems
54
65
  return prevItem === nextItem;
55
66
  const prevNode = prevItem.node;
56
67
  const nextNode = nextItem.node;
57
- // Controlla se questa riga specifica è cambiata
58
- return (prevNode.key === nextNode.key &&
59
- prevNode.expanded === nextNode.expanded &&
68
+ // Controlla se questa riga specifica è cambiata: confronta l'identità del nodo (non i soli
69
+ // campi key/expanded) per non lasciare visualizzato un nodo obsoleto. Gli handler non servono:
70
+ // hanno identità stabile e leggono lo stato dalle ref.
71
+ return (prevNode === nextNode &&
60
72
  prevItem.depth === nextItem.depth &&
61
73
  (prevNode.key === prevProps.focusedItemKey) === (nextNode.key === nextProps.focusedItemKey) &&
62
74
  prevProps.selectedItemKeys.has(prevNode.key) === nextProps.selectedItemKeys.has(nextNode.key) &&
63
- prevProps.allowMultipleSelection === nextProps.allowMultipleSelection);
75
+ prevProps.allowMultipleSelection === nextProps.allowMultipleSelection &&
76
+ prevProps.itemRender === nextProps.itemRender &&
77
+ prevProps.onItemContextMenu === nextProps.onItemContextMenu);
64
78
  });
65
79
  const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMultipleSelection, onDataChanged, calculateItemsForNode, itemRender, onNodeUpdate, onFocusedItemChanged, onSelectionChanged, shouldDelayFocusOnEvent, onItemContextMenu, autoSelectChildren = true, itemsPerPage = 100, showLoadMoreButton = true, enableVirtualization = false }) => {
66
80
  // Altezza fissa per ogni riga nella virtualizzazione
@@ -71,12 +85,35 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
71
85
  // Ref per selectedItems - permette alle callback memoizzate di accedere sempre al valore più recente
72
86
  const selectedItemsRef = useRef(selectedItems);
73
87
  selectedItemsRef.current = selectedItems;
88
+ // Ref per props e callback usate dagli handler: una riga virtualizzata memoizzata conserva le
89
+ // props del render precedente, quindi gli handler non devono catturare lo stato nella closure.
90
+ const dataSourceRef = useRef(dataSource);
91
+ dataSourceRef.current = dataSource;
92
+ const autoSelectChildrenRef = useRef(autoSelectChildren);
93
+ autoSelectChildrenRef.current = autoSelectChildren;
94
+ const calculateItemsForNodeRef = useRef(calculateItemsForNode);
95
+ calculateItemsForNodeRef.current = calculateItemsForNode;
96
+ const onNodeUpdateRef = useRef(onNodeUpdate);
97
+ onNodeUpdateRef.current = onNodeUpdate;
98
+ const onDataChangedRef = useRef(onDataChanged);
99
+ onDataChangedRef.current = onDataChanged;
100
+ const onFocusedItemChangedRef = useRef(onFocusedItemChanged);
101
+ onFocusedItemChangedRef.current = onFocusedItemChanged;
102
+ const onSelectionChangedRef = useRef(onSelectionChanged);
103
+ onSelectionChangedRef.current = onSelectionChanged;
104
+ const shouldDelayFocusOnEventRef = useRef(shouldDelayFocusOnEvent);
105
+ shouldDelayFocusOnEventRef.current = shouldDelayFocusOnEvent;
74
106
  // Ref per handleCheckboxChange - permette all'useEffect di accedere alla funzione prima che sia definita
75
107
  const handleCheckboxChangeRef = useRef(() => { });
76
108
  // Filtra gli items da mostrare in base alla paginazione (definito prima per essere usato da flattenTreeWithDepth)
77
109
  const getVisibleItems = useCallback((node) => {
78
110
  if (!node.items)
79
111
  return [];
112
+ // Con la virtualizzazione react-window renderizza già solo le righe visibili:
113
+ // la paginazione nasconderebbe gli items oltre itemsPerPage senza renderizzare
114
+ // il paginatore, presente solo nel render standard (renderTree).
115
+ if (enableVirtualization)
116
+ return node.items;
80
117
  const totalItems = node.items.length;
81
118
  // Se non c'è paginazione attiva o gli items sono pochi, mostra tutti
82
119
  if (totalItems <= itemsPerPage || !showLoadMoreButton) {
@@ -87,7 +124,7 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
87
124
  const startIndex = currentPage * itemsPerPage;
88
125
  const endIndex = startIndex + itemsPerPage;
89
126
  return node.items.slice(startIndex, endIndex);
90
- }, [itemsPerPage, showLoadMoreButton]);
127
+ }, [itemsPerPage, showLoadMoreButton, enableVirtualization]);
91
128
  // Misura le dimensioni del container per react-window
92
129
  useEffect(() => {
93
130
  if (!enableVirtualization || !containerRef.current)
@@ -121,15 +158,26 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
121
158
  return [];
122
159
  return flattenTreeWithDepth(dataSource);
123
160
  }, [enableVirtualization, dataSource, flattenTreeWithDepth]);
161
+ // Chiave dell'ultimo elemento verso cui si è effettivamente scrollato.
162
+ // Evita di ripetere lo scroll quando cambia solo la struttura dell'albero
163
+ // (es. espansione di un nodo) a parità di elemento focalizzato.
164
+ const lastScrolledKeyRef = useRef(undefined);
124
165
  // Scroll verso l'elemento focalizzato quando cambia (navigazione con frecce)
125
166
  useEffect(() => {
126
- if (!focusedItem?.key)
167
+ if (!focusedItem?.key) {
168
+ lastScrolledKeyRef.current = undefined;
169
+ return;
170
+ }
171
+ // Focus invariato: l'effect è stato rieseguito solo perché l'albero è cambiato
172
+ // (espansione/collasso di un nodo). La posizione di scroll non va toccata.
173
+ if (lastScrolledKeyRef.current === focusedItem.key)
127
174
  return;
128
175
  if (enableVirtualization) {
129
176
  // Lista virtualizzata: usa scrollToRow per garantire che l'elemento sia visibile
130
177
  const index = flattenedItems.findIndex(item => item.node.key === focusedItem.key);
131
178
  if (index >= 0 && listRef.current) {
132
179
  listRef.current.scrollToRow({ index, align: 'smart' });
180
+ lastScrolledKeyRef.current = focusedItem.key;
133
181
  }
134
182
  }
135
183
  else {
@@ -138,6 +186,7 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
138
186
  const element = containerRef.current.querySelector(`[data-node-key="${focusedItem.key}"]`);
139
187
  if (element) {
140
188
  element.scrollIntoView({ block: 'nearest', inline: 'nearest' });
189
+ lastScrolledKeyRef.current = focusedItem.key;
141
190
  }
142
191
  }
143
192
  }
@@ -146,6 +195,9 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
146
195
  const handleKeyDown = (event) => {
147
196
  if (!focusedItem)
148
197
  return;
198
+ // Non rubare i tasti ai campi editabili (es. input di un pannello sovrapposto)
199
+ if (event.target instanceof HTMLElement && isEditableElement(event.target))
200
+ return;
149
201
  let newFocusedItem = null;
150
202
  let handled = false;
151
203
  switch (event.key) {
@@ -211,7 +263,7 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
211
263
  const currentIndex = flatList.findIndex(item => item.key === currentItem.key);
212
264
  return flatList[currentIndex - 1] || null;
213
265
  };
214
- const flattenTree = (nodes) => {
266
+ const flattenTree = useCallback((nodes) => {
215
267
  let flatList = [];
216
268
  nodes.forEach(node => {
217
269
  if (!node.hidden) {
@@ -222,45 +274,57 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
222
274
  }
223
275
  });
224
276
  return flatList;
225
- };
226
- const handleNodeToggle = async (key, ctrlKey) => {
227
- const updateNodeRecursively = async (nodes) => {
228
- const updatedNodes = await Promise.all(nodes.map(async (node) => {
229
- if (node.key === key) {
230
- if (node.expanded) {
231
- // Collassa il nodo
232
- const updatedNode = { ...node, expanded: false };
233
- onNodeUpdate?.(updatedNode);
234
- return updatedNode;
235
- }
236
- else {
237
- // Espandi il nodo
238
- let newItems = node.items;
239
- // Solo se calculateItemsForNode è definito E (ctrl è premuto O non è già caricato)
240
- if (calculateItemsForNode && (ctrlKey || !node.isLoaded)) {
241
- // Se ctrl è premuto, passa un nodo con isLoaded resettato per forzare il refresh
242
- const nodeForCalculation = ctrlKey ? { ...node, isLoaded: false } : node;
243
- newItems = await calculateItemsForNode(nodeForCalculation);
244
- const updatedNode = { ...node, expanded: true, items: newItems, isLoaded: true };
245
- onNodeUpdate?.(updatedNode);
246
- return updatedNode;
247
- }
248
- // Altrimenti usa semplicemente gli items esistenti
249
- return { ...node, expanded: true };
250
- }
251
- }
252
- if (node.items) {
253
- const updatedItems = await updateNodeRecursively(node.items);
254
- return { ...node, items: updatedItems };
255
- }
277
+ }, []);
278
+ const findNodeByKey = useCallback((nodes, key) => {
279
+ for (const node of nodes) {
280
+ if (node.key === key)
256
281
  return node;
257
- }));
258
- return updatedNodes;
259
- };
260
- updateNodeRecursively(dataSource).then(updatedData => {
261
- onDataChanged?.(updatedData);
282
+ if (node.items) {
283
+ const found = findNodeByKey(node.items, key);
284
+ if (found)
285
+ return found;
286
+ }
287
+ }
288
+ return null;
289
+ }, []);
290
+ const handleNodeToggle = useCallback(async (key, ctrlKey) => {
291
+ // dataSourceRef è letta alla chiamata, non alla creazione della closure
292
+ const target = findNodeByKey(dataSourceRef.current, key);
293
+ if (!target)
294
+ return;
295
+ const calculateItems = calculateItemsForNodeRef.current;
296
+ let updatedNode;
297
+ if (target.expanded) {
298
+ // Collassa il nodo
299
+ updatedNode = { ...target, expanded: false };
300
+ onNodeUpdateRef.current?.(updatedNode);
301
+ }
302
+ else if (calculateItems && (ctrlKey || !target.isLoaded)) {
303
+ // Espandi il nodo caricando gli items.
304
+ // Solo se calculateItemsForNode è definito E (ctrl è premuto O non è già caricato).
305
+ // Se ctrl è premuto, passa un nodo con isLoaded resettato per forzare il refresh.
306
+ const nodeForCalculation = ctrlKey ? { ...target, isLoaded: false } : target;
307
+ const newItems = await calculateItems(nodeForCalculation);
308
+ updatedNode = { ...target, expanded: true, items: newItems, isLoaded: true };
309
+ onNodeUpdateRef.current?.(updatedNode);
310
+ }
311
+ else {
312
+ // Altrimenti usa semplicemente gli items esistenti
313
+ updatedNode = { ...target, expanded: true };
314
+ }
315
+ // Rimpiazzo sull'albero riletto dopo l'await: non sovrascrive i toggle fatti durante la fetch
316
+ let replaced = false;
317
+ const replaceNode = (nodes) => nodes.map(node => {
318
+ if (!replaced && node.key === key) {
319
+ replaced = true;
320
+ return updatedNode;
321
+ }
322
+ if (node.items)
323
+ return { ...node, items: replaceNode(node.items) };
324
+ return node;
262
325
  });
263
- };
326
+ onDataChangedRef.current?.(replaceNode(dataSourceRef.current));
327
+ }, [findNodeByKey]);
264
328
  // Ref per distinguere click singolo/doppio sulla riga (esempio TMDcmtIcon)
265
329
  const clickTimeoutRef = useRef(null);
266
330
  const lastClickedNodeKeyRef = useRef(undefined);
@@ -271,7 +335,8 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
271
335
  return;
272
336
  }
273
337
  // Se shouldDelayFocusOnEvent non è fornita, il comportamento predefinito è il focus immediato (false)
274
- const delayFocus = shouldDelayFocusOnEvent ? shouldDelayFocusOnEvent(node, e) : false;
338
+ const shouldDelay = shouldDelayFocusOnEventRef.current;
339
+ const delayFocus = shouldDelay ? shouldDelay(node, e) : false;
275
340
  // Reset del timer se il click è su un nodo diverso dal precedente
276
341
  if (lastClickedNodeKeyRef.current && lastClickedNodeKeyRef.current !== node.key) {
277
342
  if (clickTimeoutRef.current) {
@@ -287,7 +352,7 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
287
352
  // Primo click: imposta il timer per il focus
288
353
  lastClickedNodeKeyRef.current = node.key;
289
354
  clickTimeoutRef.current = setTimeout(() => {
290
- onFocusedItemChanged?.(node);
355
+ onFocusedItemChangedRef.current?.(node);
291
356
  clickTimeoutRef.current = null;
292
357
  lastClickedNodeKeyRef.current = undefined;
293
358
  }, 200);
@@ -302,12 +367,14 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
302
367
  clickTimeoutRef.current = null;
303
368
  lastClickedNodeKeyRef.current = undefined;
304
369
  }
305
- onFocusedItemChanged?.(node); // Chiama onFocusedItemChanged immediatamente
370
+ onFocusedItemChangedRef.current?.(node); // Chiama onFocusedItemChanged immediatamente
306
371
  }
307
- }, [onFocusedItemChanged, calculateItemsForNode, onNodeUpdate]);
372
+ }, []);
308
373
  const handleCheckboxChange = useCallback((node, checked) => {
309
- // Usa la ref per accedere sempre al valore più recente di selectedItems
374
+ // Usa le ref per accedere sempre ai valori più recenti
310
375
  const currentSelectedItems = selectedItemsRef.current;
376
+ const currentDataSource = dataSourceRef.current;
377
+ const autoSelect = autoSelectChildrenRef.current;
311
378
  // Funzione helper per trovare il parent di un nodo e verificare se tutti i suoi figli sono selezionati
312
379
  const findAndCheckParents = (items, targetNode, currentSelection) => {
313
380
  const parentsToAdd = [];
@@ -341,7 +408,7 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
341
408
  };
342
409
  let newSelectedItems;
343
410
  if (checked) {
344
- if (node.isContainer && autoSelectChildren) {
411
+ if (node.isContainer && autoSelect) {
345
412
  // Quando selezioni un container, aggiungi il container stesso + tutti i figli (se autoSelectChildren è true)
346
413
  const allChildren = flattenTree(node.items || []);
347
414
  // Rimuovi eventuali duplicati: filtra gli elementi già presenti nella selezione
@@ -353,8 +420,8 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
353
420
  // Quando selezioni un figlio o un container con autoSelectChildren=false, aggiungi solo il nodo
354
421
  newSelectedItems = [...currentSelectedItems, node];
355
422
  // Verifica se selezionando questo figlio sono ora selezionati tutti i figli del parent (solo se autoSelectChildren è true)
356
- if (autoSelectChildren) {
357
- const parentsToAdd = findAndCheckParents(dataSource, node, newSelectedItems);
423
+ if (autoSelect) {
424
+ const parentsToAdd = findAndCheckParents(currentDataSource, node, newSelectedItems);
358
425
  newSelectedItems = [...newSelectedItems, ...parentsToAdd];
359
426
  }
360
427
  }
@@ -362,7 +429,7 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
362
429
  newSelectedItems = currentSelectedItems;
363
430
  }
364
431
  }
365
- else if (node.isContainer && autoSelectChildren) {
432
+ else if (node.isContainer && autoSelect) {
366
433
  // Quando deselezioni un container, rimuovi il container stesso + tutti i figli (solo se autoSelectChildren è true)
367
434
  const childKeys = flattenTree(node.items || []).map(item => item.key);
368
435
  newSelectedItems = currentSelectedItems.filter(item => item.key !== node.key && !childKeys.includes(item.key));
@@ -371,7 +438,7 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
371
438
  // Quando deselezioni un figlio o un container con autoSelectChildren=false, rimuovi solo il nodo
372
439
  newSelectedItems = currentSelectedItems.filter(item => item.key !== node.key);
373
440
  // Se il figlio apparteneva a un parent che era selezionato, rimuovi anche il parent (solo se autoSelectChildren è true)
374
- if (autoSelectChildren && !node.isContainer) {
441
+ if (autoSelect && !node.isContainer) {
375
442
  const removeParentContainers = (items) => {
376
443
  const parentsToRemove = [];
377
444
  items.forEach(item => {
@@ -386,26 +453,32 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
386
453
  });
387
454
  return parentsToRemove;
388
455
  };
389
- const parentsToRemove = removeParentContainers(dataSource);
456
+ const parentsToRemove = removeParentContainers(currentDataSource);
390
457
  newSelectedItems = newSelectedItems.filter(item => !parentsToRemove.includes(item.key));
391
458
  }
392
459
  }
393
- onSelectionChanged?.(newSelectedItems);
394
- }, [autoSelectChildren, dataSource, onSelectionChanged]);
460
+ onSelectionChangedRef.current?.(newSelectedItems);
461
+ }, [flattenTree]);
395
462
  // Aggiorna la ref con l'ultima versione di handleCheckboxChange
396
463
  handleCheckboxChangeRef.current = handleCheckboxChange;
397
- const hasPartialChildSelection = (node) => {
464
+ const hasPartialChildSelection = useCallback((node) => {
398
465
  // Lo stato indeterminate ha senso solo quando autoSelectChildren è true
399
- if (!autoSelectChildren)
466
+ if (!autoSelectChildrenRef.current)
400
467
  return false;
401
468
  if (!node.isContainer || !node.items)
402
469
  return false;
403
470
  const childKeys = flattenTree(node.items).map(item => item.key);
404
- const selectedChildKeys = selectedItems.map(item => item.key);
471
+ const selectedChildKeys = selectedItemsRef.current.map(item => item.key);
405
472
  const selectedCount = childKeys.filter(key => selectedChildKeys.includes(key)).length;
406
473
  return selectedCount > 0 && selectedCount < childKeys.length;
407
- };
408
- const hasVisibleItems = (node) => {
474
+ }, [flattenTree]);
475
+ const hasVisibleItems = useCallback((node) => {
476
+ // Nodo già caricato: conta i figli visibili (isExpandible è solo una stima a priori)
477
+ if (node.isLoaded) {
478
+ if (!node.items)
479
+ return false;
480
+ return node.items.filter(o => !o.hidden).length > 0;
481
+ }
409
482
  // If node has explicit isExpandible value, use that
410
483
  if (node.isExpandible !== undefined) {
411
484
  return node.isExpandible;
@@ -416,14 +489,14 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
416
489
  if (node.items.length <= 0)
417
490
  return false;
418
491
  return node.items.filter(o => !o.hidden).length > 0;
419
- };
492
+ }, []);
420
493
  // Gestisce il cambio di pagina per un nodo
421
494
  const handlePageChange = useCallback((nodeKey, newPage) => {
422
495
  const updateNodePage = (nodes) => {
423
496
  return nodes.map(node => {
424
497
  if (node.key === nodeKey) {
425
498
  const updatedNode = { ...node, currentPage: newPage };
426
- onNodeUpdate?.(updatedNode);
499
+ onNodeUpdateRef.current?.(updatedNode);
427
500
  return updatedNode;
428
501
  }
429
502
  if (node.items) {
@@ -432,9 +505,9 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
432
505
  return node;
433
506
  });
434
507
  };
435
- const updatedData = updateNodePage(dataSource);
436
- onDataChanged?.(updatedData);
437
- }, [dataSource, onDataChanged, onNodeUpdate]);
508
+ const updatedData = updateNodePage(dataSourceRef.current);
509
+ onDataChangedRef.current?.(updatedData);
510
+ }, []);
438
511
  // Verifica se c'è bisogno del paginatore
439
512
  const needsPagination = useCallback((node) => {
440
513
  if (!showLoadMoreButton || !node.items)
@@ -448,7 +521,7 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
448
521
  return Math.ceil(node.items.length / itemsPerPage);
449
522
  }, [itemsPerPage]);
450
523
  const renderTree = useCallback((nodes) => {
451
- return nodes.map(node => !node.hidden && (_jsxs("div", { style: { width: 'fit-content', minWidth: '100%', margin: 0, padding: 0 }, children: [_jsxs(StyledTreeNode, { "$isSelected": node.key === focusedItem?.key, "data-node-key": node.key, children: [_jsx("div", { style: {
524
+ return nodes.map(node => !node.hidden && (_jsxs("div", { style: { width: 'fit-content', minWidth: '100%', margin: 0, padding: 0 }, children: [_jsxs(StyledTreeNode, { $isSelected: node.key === focusedItem?.key, "data-node-key": node.key, children: [_jsx("div", { style: {
452
525
  display: 'flex',
453
526
  alignItems: 'center',
454
527
  justifyContent: 'center',
@@ -474,7 +547,7 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
474
547
  onItemContextMenu(node, e);
475
548
  }
476
549
  }, children: itemRender(node) })] }), node.expanded && node.items && (_jsxs("div", { style: { paddingLeft: 20, width: 'fit-content', minWidth: '100%' }, children: [renderTree(getVisibleItems(node)), needsPagination(node) && (_jsxs(StyledStickyPaginator, { children: [_jsx(TMButton, { btnStyle: 'icon', onClick: () => handlePageChange(node.key, (node.currentPage ?? 0) - 1), showTooltip: false, caption: "\u25C4", icon: _jsx(IconArrowLeft, { color: 'white' }), disabled: (node.currentPage ?? 0) <= 0 }), _jsx("span", { style: { fontSize: '11px', whiteSpace: 'nowrap', fontWeight: 500, overflow: 'hidden', textOverflow: 'ellipsis', minWidth: 0, color: 'white' }, children: SDKUI_Localizator.PaginationInfo.replaceParams((node.currentPage ?? 0) + 1, getTotalPages(node), node.items?.length ?? 0) }), _jsx(TMButton, { btnStyle: 'icon', onClick: () => handlePageChange(node.key, (node.currentPage ?? 0) + 1), showTooltip: false, caption: "\u25BA", icon: _jsx(IconArrowRight, { color: 'white' }), disabled: (node.currentPage ?? 0) >= getTotalPages(node) - 1 })] }))] }))] }, node.key)));
477
- }, [handleNodeClick, handleNodeToggle, handleCheckboxChange, focusedItem, selectedItems, allowMultipleSelection, getVisibleItems, needsPagination, handlePageChange, getTotalPages, onItemContextMenu]);
550
+ }, [handleNodeClick, handleNodeToggle, handleCheckboxChange, hasVisibleItems, hasPartialChildSelection, itemRender, focusedItem, selectedItems, allowMultipleSelection, getVisibleItems, needsPagination, handlePageChange, getTotalPages, onItemContextMenu]);
478
551
  // Calcola selectedItemKeys ad ogni render per garantire sincronizzazione con selectedItems
479
552
  const selectedItemKeys = new Set(selectedItems.map(s => s.key));
480
553
  // Memoizza rowPropsData per evitare re-render della List
@@ -1,4 +1,4 @@
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 { createPortal } from 'react-dom';
3
3
  import styled from 'styled-components';
4
4
  import TMLayoutContainer from './TMLayout';
@@ -34,7 +34,7 @@ const StyledTitle = styled.h2 ` margin: 0; font-size: 1.5em; color: #333; `;
34
34
  const StyledProgressBarContainer = styled.div ` width: 100%; height: 20px; background: #e0e0e0; border-radius: 10px; overflow: hidden; margin: 20px 0; `;
35
35
  const StyledProgressBar = styled.div ` height: 100%; background: #4caf50; transition: width 0.3s ease; `;
36
36
  const StyledProgressText = styled.p ` font-weight: bold; color: #333; margin: 0; `;
37
- const StyledMessage = styled.p ` color: #666; font-size: 0.9em; margin-top: 10px; `;
37
+ const StyledMessage = styled.p ` color: #666; font-size: 0.9em; margin-top: 10px; white-space: pre-line; `;
38
38
  const StyledAbortButton = styled.button ` background: #ff4d4d; color: white; border: none; border-radius: 5px; padding: 10px 20px; font-size: 1em; cursor: pointer; margin-top: 20px; &:hover { background: #ff6666; } `;
39
39
  export const TMWaitPanel = (props) => {
40
40
  const { title, showPrimary, textPrimary, valuePrimary, maxValuePrimary, showSecondary, textSecondary, valueSecondary, maxValueSecondary, isCancelable, abortController, onAbortClick, useHighZIndex } = props;
@@ -46,7 +46,7 @@ export const TMWaitPanel = (props) => {
46
46
  };
47
47
  let progressValue1 = calculateProgress(valuePrimary, maxValuePrimary);
48
48
  let progressValue2 = calculateProgress(valueSecondary, maxValueSecondary);
49
- return (_jsx(StyledWaitPanelOverlay, { "$useHighZIndex": useHighZIndex, children: _jsxs(StyledWaitPanel, { children: [_jsx(StyledTitle, { children: title }), showPrimary &&
49
+ return (_jsx(StyledWaitPanelOverlay, { $useHighZIndex: useHighZIndex, children: _jsxs(StyledWaitPanel, { children: [_jsx(StyledTitle, { children: title }), showPrimary &&
50
50
  _jsxs("div", { style: { width: '100%', height: '100px' }, children: [_jsx(StyledProgressBarContainer, { children: _jsx(StyledProgressBar, { style: { width: `${progressValue1.toFixed(2)}%` } }) }), _jsxs(StyledProgressText, { children: [progressValue1.toFixed(2), "%"] }), _jsx(StyledMessage, { children: textPrimary })] }), showSecondary &&
51
51
  _jsxs("div", { style: { width: '100%', height: '100px' }, children: [_jsx(StyledProgressBarContainer, { children: _jsx(StyledProgressBar, { style: { width: `${progressValue2.toFixed(2)}%` } }) }), _jsxs(StyledProgressText, { children: [progressValue2.toFixed(2), "%"] }), _jsx(StyledMessage, { children: textSecondary })] }), isCancelable && _jsx(StyledAbortButton, { onClick: () => onAbortClick?.(abortController), children: SDKUI_Localizator.Abort })] }) }));
52
52
  };
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ export interface ITMWaitPanelConfirmProps {
3
+ /** Deve stare sopra l'overlay del pannello: il manager passa il suo z-index + 1. */
4
+ zIndex?: number;
5
+ /** Conferma: l'operazione va interrotta. */
6
+ onYes?: () => void;
7
+ /** Annulla: l'operazione riprende. Usata anche dalla X. */
8
+ onNo?: () => void;
9
+ }
10
+ /** Il ref punta all'overlay, che il manager mostra e nasconde via `style.display`. */
11
+ declare const TMWaitPanelConfirm: React.ForwardRefExoticComponent<ITMWaitPanelConfirmProps & React.RefAttributes<HTMLDivElement>>;
12
+ export default TMWaitPanelConfirm;