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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +28 -2
  2. package/lib/components/NewComponents/ContextMenu/styles.d.ts +4 -4
  3. package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +6 -6
  4. package/lib/components/base/Styled.d.ts +1 -1
  5. package/lib/components/base/TMAreaManager.js +11 -0
  6. package/lib/components/base/TMCounterBar.d.ts +2 -2
  7. package/lib/components/base/TMCounterContainer.d.ts +2 -1
  8. package/lib/components/base/TMCustomButton.d.ts +1 -1
  9. package/lib/components/base/TMDataGrid.js +12 -2
  10. package/lib/components/base/TMDataGridExportForm.d.ts +2 -1
  11. package/lib/components/base/TMDataGridExportForm.js +19 -8
  12. package/lib/components/base/TMFileManager.d.ts +2 -1
  13. package/lib/components/base/TMFileManagerDataGridView.d.ts +2 -1
  14. package/lib/components/base/TMFileManagerDataGridView.js +4 -4
  15. package/lib/components/base/TMFileManagerThumbnailItems.d.ts +1 -1
  16. package/lib/components/base/TMFileManagerThumbnailItems.js +3 -3
  17. package/lib/components/base/TMFileManagerThumbnailsView.d.ts +1 -1
  18. package/lib/components/base/TMFileManagerUtils.d.ts +7 -0
  19. package/lib/components/base/TMFileManagerUtils.js +14 -1
  20. package/lib/components/base/TMLayout.d.ts +4 -4
  21. package/lib/components/base/TMList.d.ts +2 -1
  22. package/lib/components/base/TMListView.d.ts +1 -1
  23. package/lib/components/base/TMModal.js +2 -2
  24. package/lib/components/base/TMPopUp.d.ts +1 -0
  25. package/lib/components/base/TMPopUp.js +59 -2
  26. package/lib/components/base/TMSpinner.d.ts +5 -2
  27. package/lib/components/base/TMSpinner.js +33 -6
  28. package/lib/components/base/TMTab.d.ts +4 -3
  29. package/lib/components/base/TMTooltip.d.ts +1 -1
  30. package/lib/components/base/TMTreeView.d.ts +16 -13
  31. package/lib/components/base/TMTreeView.js +242 -79
  32. package/lib/components/base/TMUserAvatar.d.ts +2 -1
  33. package/lib/components/base/TMVilViewer.d.ts +2 -1
  34. package/lib/components/base/TMWaitPanel.d.ts +5 -2
  35. package/lib/components/base/TMWaitPanel.js +8 -6
  36. package/lib/components/choosers/TMDistinctValues.js +1 -1
  37. package/lib/components/choosers/TMDynDataListItemChooser.d.ts +1 -1
  38. package/lib/components/choosers/TMDynDataListItemChooser.js +6 -1
  39. package/lib/components/choosers/TMGroupChooser.js +1 -1
  40. package/lib/components/choosers/TMInvoiceRetrieveFormats.d.ts +2 -1
  41. package/lib/components/choosers/TMOrderRetrieveFormats.d.ts +2 -1
  42. package/lib/components/choosers/TMRelationChooser.d.ts +3 -3
  43. package/lib/components/choosers/TMUserChooser.d.ts +2 -2
  44. package/lib/components/editors/TMEditorStyled.d.ts +6 -6
  45. package/lib/components/editors/TMFormulaEditor.d.ts +2 -1
  46. package/lib/components/editors/TMFormulaEditor.js +98 -49
  47. package/lib/components/editors/TMHtmlContentDisplay.d.ts +2 -1
  48. package/lib/components/editors/TMHtmlEditor.d.ts +2 -1
  49. package/lib/components/editors/TMMetadataEditor.js +6 -2
  50. package/lib/components/editors/TMMetadataValues.js +23 -6
  51. package/lib/components/editors/TMTextBox.d.ts +1 -0
  52. package/lib/components/editors/TMTextBox.js +2 -1
  53. package/lib/components/editors/TMTreeDropDown.d.ts +1 -1
  54. package/lib/components/features/assistant/TMToppyDraggableHelpCenter.d.ts +1 -1
  55. package/lib/components/features/blog/TMBlogCommentForm.d.ts +2 -1
  56. package/lib/components/features/blog/TMBlogCommentForm.js +5 -2
  57. package/lib/components/features/documents/TMCopyToFolderForm.js +46 -24
  58. package/lib/components/features/documents/TMDcmtForm.d.ts +2 -0
  59. package/lib/components/features/documents/TMDcmtForm.js +21 -10
  60. package/lib/components/features/documents/TMDcmtFormActionButtons.d.ts +1 -1
  61. package/lib/components/features/documents/TMDcmtIcon.d.ts +4 -1
  62. package/lib/components/features/documents/TMDcmtIcon.js +6 -33
  63. package/lib/components/features/documents/TMDcmtPreview.d.ts +1 -1
  64. package/lib/components/features/documents/TMDcmtTasks.d.ts +2 -1
  65. package/lib/components/features/documents/TMDragDropOverlay.d.ts +1 -1
  66. package/lib/components/features/documents/TMFileUploader.js +1 -1
  67. package/lib/components/features/documents/TMMasterDetailDcmts.d.ts +2 -2
  68. package/lib/components/features/documents/TMMasterDetailDcmts.js +55 -16
  69. package/lib/components/features/documents/TMMergeToPdfForm.d.ts +2 -3
  70. package/lib/components/features/documents/TMMergeToPdfForm.js +115 -56
  71. package/lib/components/features/documents/TMRelationViewer.d.ts +12 -10
  72. package/lib/components/features/documents/TMRelationViewer.js +405 -95
  73. package/lib/components/features/documents/copyAndMergeDcmtsShared.d.ts +4 -16
  74. package/lib/components/features/documents/copyAndMergeDcmtsShared.js +47 -61
  75. package/lib/components/features/documents/mergePdfUtils.d.ts +52 -0
  76. package/lib/components/features/documents/mergePdfUtils.js +268 -0
  77. package/lib/components/features/search/TMDcmtCheckoutInfoForm.d.ts +2 -1
  78. package/lib/components/features/search/TMMetadataOutputForm.d.ts +18 -0
  79. package/lib/components/features/search/TMMetadataOutputForm.js +225 -0
  80. package/lib/components/features/search/TMMetadataSorterForm.d.ts +18 -0
  81. package/lib/components/features/search/TMMetadataSorterForm.js +243 -0
  82. package/lib/components/features/search/TMSavedQuerySelector.d.ts +2 -2
  83. package/lib/components/features/search/TMSearch.d.ts +2 -2
  84. package/lib/components/features/search/TMSearch.js +2 -2
  85. package/lib/components/features/search/TMSearchQueryEditor.js +14 -8
  86. package/lib/components/features/search/TMSearchQueryPanel.js +249 -58
  87. package/lib/components/features/search/TMSearchResult.d.ts +3 -2
  88. package/lib/components/features/search/TMSearchResult.js +94 -25
  89. package/lib/components/features/search/TMSearchResultFloatingActionButton.d.ts +1 -1
  90. package/lib/components/features/search/TMSignatureInfoContent.d.ts +2 -1
  91. package/lib/components/features/search/TMViewHistoryDcmt.d.ts +2 -1
  92. package/lib/components/features/search/TMViewHistoryDcmt.js +1 -1
  93. package/lib/components/features/search/metadataFormHelper.d.ts +16 -0
  94. package/lib/components/features/search/metadataFormHelper.js +77 -0
  95. package/lib/components/features/tasks/TMTaskForm.d.ts +1 -1
  96. package/lib/components/features/tasks/TMTaskFormUtils.d.ts +10 -10
  97. package/lib/components/features/tasks/TMTasksAgenda.d.ts +1 -1
  98. package/lib/components/features/tasks/TMTasksCalendar.d.ts +1 -1
  99. package/lib/components/features/tasks/TMTasksHeader.d.ts +1 -1
  100. package/lib/components/features/tasks/TMTasksPanelContent.d.ts +1 -1
  101. package/lib/components/features/tasks/TMTasksUtilsView.d.ts +5 -5
  102. package/lib/components/features/tasks/TMTasksView.d.ts +1 -1
  103. package/lib/components/features/wg/TMWGsCopyMoveForm.d.ts +3 -2
  104. package/lib/components/features/workflow/TMWorkflowPopup.d.ts +8 -7
  105. package/lib/components/forms/Login/Chooser.d.ts +2 -2
  106. package/lib/components/forms/Login/TMLoginForm.js +15 -3
  107. package/lib/components/forms/TMChooserForm.d.ts +2 -1
  108. package/lib/components/forms/TMSaveForm.d.ts +4 -4
  109. package/lib/components/grids/TMBlogAttachments.d.ts +2 -1
  110. package/lib/components/grids/TMBlogAttachments.js +2 -2
  111. package/lib/components/grids/TMBlogHeader.d.ts +1 -1
  112. package/lib/components/grids/TMBlogsPost.d.ts +1 -1
  113. package/lib/components/grids/TMBlogsPost.js +5 -3
  114. package/lib/components/grids/TMBlogsPostUtils.d.ts +10 -9
  115. package/lib/components/grids/TMBlogsPostUtils.js +3 -1
  116. package/lib/components/grids/TMValidationItemsList.d.ts +2 -1
  117. package/lib/components/layout/panelManager/TMPanelManagerContainer.d.ts +2 -1
  118. package/lib/components/layout/panelManager/TMPanelManagerContext.d.ts +2 -2
  119. package/lib/components/layout/panelManager/TMPanelManagerToolbar.d.ts +1 -1
  120. package/lib/components/layout/panelManager/TMPanelManagerWithPersistenceProvider.d.ts +2 -2
  121. package/lib/components/layout/panelManager/TMPanelWrapper.d.ts +2 -2
  122. package/lib/components/pages/TMPage.d.ts +1 -1
  123. package/lib/components/settings/SettingsAppearance.d.ts +2 -1
  124. package/lib/components/sidebar/TMAboutApp.d.ts +2 -1
  125. package/lib/components/sidebar/TMHeader.d.ts +3 -3
  126. package/lib/components/viewers/TMDataListItemViewer.d.ts +3 -2
  127. package/lib/components/viewers/TMDataUserIdItemViewer.d.ts +3 -2
  128. package/lib/components/viewers/TMMidViewer.d.ts +2 -2
  129. package/lib/components/viewers/TMTidViewer.d.ts +2 -2
  130. package/lib/components/viewers/TMTidViewer.js +14 -2
  131. package/lib/components/wizard/TMWizard.d.ts +1 -0
  132. package/lib/components/wizard/TMWizard.js +5 -3
  133. package/lib/helper/Enum_Localizator.js +2 -0
  134. package/lib/helper/MergePdfManager.d.ts +45 -0
  135. package/lib/helper/MergePdfManager.js +148 -0
  136. package/lib/helper/SDKUI_Globals.d.ts +1 -0
  137. package/lib/helper/SDKUI_Globals.js +3 -1
  138. package/lib/helper/SDKUI_Localizator.d.ts +40 -0
  139. package/lib/helper/SDKUI_Localizator.js +412 -12
  140. package/lib/helper/TMCommandsContextMenu.d.ts +1 -1
  141. package/lib/helper/TMIcons.d.ts +278 -278
  142. package/lib/helper/TMPdfViewer.d.ts +2 -1
  143. package/lib/helper/TMToppyMessage.d.ts +2 -2
  144. package/lib/helper/TMUtils.d.ts +57 -21
  145. package/lib/helper/TMUtils.js +159 -1
  146. package/lib/helper/certificateImportHelper.d.ts +43 -0
  147. package/lib/helper/certificateImportHelper.js +403 -0
  148. package/lib/helper/checkinCheckoutManager.d.ts +4 -3
  149. package/lib/helper/checkinCheckoutManager.js +29 -11
  150. package/lib/helper/helpers.d.ts +3 -2
  151. package/lib/helper/helpers.js +10 -0
  152. package/lib/helper/index.d.ts +1 -0
  153. package/lib/helper/index.js +1 -0
  154. package/lib/hooks/useCheckInOutOperations.d.ts +4 -3
  155. package/lib/hooks/useDataUserIdItem.js +1 -1
  156. package/lib/hooks/useDcmtOperations.d.ts +20 -2
  157. package/lib/hooks/useDcmtOperations.js +244 -25
  158. package/lib/hooks/useDocumentOperations.d.ts +2 -2
  159. package/lib/hooks/useDocumentOperations.js +52 -13
  160. package/lib/hooks/useInputDialog.d.ts +2 -1
  161. package/lib/hooks/useRelatedDocuments.js +4 -4
  162. package/lib/services/platform_services.d.ts +7 -6
  163. package/lib/ts/types.d.ts +3 -1
  164. package/lib/ts/types.js +2 -0
  165. package/package.json +15 -7
@@ -1,9 +1,147 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useCallback, useEffect, useRef } from 'react';
2
+ import React, { useCallback, useEffect, useMemo, useRef, memo } from 'react';
3
+ import { List } from 'react-window';
3
4
  import styled from 'styled-components';
4
5
  import { IconArrowLeft, IconArrowRight, IconChevronDown, IconChevronRight, SDKUI_Localizator } from '../../helper';
5
6
  import TMButton from './TMButton';
6
- const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMultipleSelection, onDataChanged, calculateItemsForNode, itemRender, onNodeUpdate, onFocusedItemChanged, onSelectionChanged, shouldDelayFocusOnEvent, onItemContextMenu, autoSelectChildren = true, itemsPerPage = 100, showLoadMoreButton = true }) => {
7
+ // Componente riga virtualizzata memoizzato
8
+ const VirtualRowComponent = memo(({ ariaAttributes, index, style, flattenedItems, focusedItemKey, selectedItemKeys, allowMultipleSelection, hasVisibleItems, handleNodeToggle, handleNodeClick, handleCheckboxChange, hasPartialChildSelection, itemRender, onItemContextMenu }) => {
9
+ const item = flattenedItems[index];
10
+ if (!item)
11
+ return null;
12
+ const { node, depth } = item;
13
+ const isSelected = node.key === focusedItemKey;
14
+ return (_jsx("div", { ...ariaAttributes, "data-node-key": node.key, style: {
15
+ ...style,
16
+ paddingLeft: depth * 20,
17
+ display: 'flex',
18
+ alignItems: 'center',
19
+ width: 'fit-content',
20
+ minWidth: '100%',
21
+ paddingRight: 10,
22
+ boxSizing: 'border-box'
23
+ }, children: _jsxs(StyledTreeNode, { "$isSelected": isSelected, children: [_jsx("div", { style: {
24
+ display: 'flex',
25
+ alignItems: 'center',
26
+ justifyContent: 'center',
27
+ minHeight: '18px',
28
+ minWidth: '18px',
29
+ maxHeight: '18px',
30
+ maxWidth: '18px',
31
+ flexShrink: 0
32
+ }, onClick: (e) => { handleNodeToggle(node.key, e.ctrlKey); }, children: hasVisibleItems(node)
33
+ ? node.expanded
34
+ ? _jsx(IconChevronDown, { cursor: 'pointer', fontSize: 14 })
35
+ : _jsx(IconChevronRight, { cursor: 'pointer', fontSize: 14 })
36
+ : _jsx("div", { style: { height: '18px', width: '18px' } }) }), allowMultipleSelection && (_jsx("input", { type: "checkbox", checked: selectedItemKeys.has(node.key), onChange: (e) => handleCheckboxChange(node, e.target.checked), onClick: (e) => e.stopPropagation(), style: { flexShrink: 0 }, ref: input => {
37
+ if (input) {
38
+ // Imposta lo stato visuale "trattino" sulla checkbox quando il container
39
+ // ha alcuni figli selezionati ma non tutti. Necessario usare ref perché
40
+ // "indeterminate" è una proprietà DOM, non un attributo HTML.
41
+ input.indeterminate = hasPartialChildSelection(node);
42
+ }
43
+ } })), _jsx(StyledItemContent, { onClick: (e) => { handleNodeClick(node, e); }, onContextMenu: (e) => {
44
+ if (onItemContextMenu) {
45
+ e.preventDefault();
46
+ onItemContextMenu(node, e);
47
+ }
48
+ }, children: itemRender(node) })] }) }));
49
+ }, (prevProps, nextProps) => {
50
+ // Custom comparison: re-render solo se i dati rilevanti per questa riga cambiano
51
+ const prevItem = prevProps.flattenedItems[prevProps.index];
52
+ const nextItem = nextProps.flattenedItems[nextProps.index];
53
+ if (!prevItem || !nextItem)
54
+ return prevItem === nextItem;
55
+ const prevNode = prevItem.node;
56
+ const nextNode = nextItem.node;
57
+ // Controlla se questa riga specifica è cambiata
58
+ return (prevNode.key === nextNode.key &&
59
+ prevNode.expanded === nextNode.expanded &&
60
+ prevItem.depth === nextItem.depth &&
61
+ (prevNode.key === prevProps.focusedItemKey) === (nextNode.key === nextProps.focusedItemKey) &&
62
+ prevProps.selectedItemKeys.has(prevNode.key) === nextProps.selectedItemKeys.has(nextNode.key) &&
63
+ prevProps.allowMultipleSelection === nextProps.allowMultipleSelection);
64
+ });
65
+ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMultipleSelection, onDataChanged, calculateItemsForNode, itemRender, onNodeUpdate, onFocusedItemChanged, onSelectionChanged, shouldDelayFocusOnEvent, onItemContextMenu, autoSelectChildren = true, itemsPerPage = 100, showLoadMoreButton = true, enableVirtualization = false }) => {
66
+ // Altezza fissa per ogni riga nella virtualizzazione
67
+ const VIRTUAL_ROW_HEIGHT = 26;
68
+ const listRef = useRef(null);
69
+ const containerRef = useRef(null);
70
+ const [containerSize, setContainerSize] = React.useState({ width: 0, height: 0 });
71
+ // Ref per selectedItems - permette alle callback memoizzate di accedere sempre al valore più recente
72
+ const selectedItemsRef = useRef(selectedItems);
73
+ selectedItemsRef.current = selectedItems;
74
+ // Ref per handleCheckboxChange - permette all'useEffect di accedere alla funzione prima che sia definita
75
+ const handleCheckboxChangeRef = useRef(() => { });
76
+ // Filtra gli items da mostrare in base alla paginazione (definito prima per essere usato da flattenTreeWithDepth)
77
+ const getVisibleItems = useCallback((node) => {
78
+ if (!node.items)
79
+ return [];
80
+ const totalItems = node.items.length;
81
+ // Se non c'è paginazione attiva o gli items sono pochi, mostra tutti
82
+ if (totalItems <= itemsPerPage || !showLoadMoreButton) {
83
+ return node.items;
84
+ }
85
+ // Altrimenti mostra solo gli items della pagina corrente
86
+ const currentPage = node.currentPage ?? 0;
87
+ const startIndex = currentPage * itemsPerPage;
88
+ const endIndex = startIndex + itemsPerPage;
89
+ return node.items.slice(startIndex, endIndex);
90
+ }, [itemsPerPage, showLoadMoreButton]);
91
+ // Misura le dimensioni del container per react-window
92
+ useEffect(() => {
93
+ if (!enableVirtualization || !containerRef.current)
94
+ return;
95
+ const resizeObserver = new ResizeObserver((entries) => {
96
+ for (const entry of entries) {
97
+ const { width, height } = entry.contentRect;
98
+ setContainerSize({ width, height });
99
+ }
100
+ });
101
+ resizeObserver.observe(containerRef.current);
102
+ return () => resizeObserver.disconnect();
103
+ }, [enableVirtualization]);
104
+ // Flatten tree con informazioni di profondità per la virtualizzazione
105
+ const flattenTreeWithDepth = useCallback((nodes, depth = 0, parentKey) => {
106
+ let flatList = [];
107
+ nodes.forEach(node => {
108
+ if (!node.hidden) {
109
+ flatList.push({ node, depth, parentKey });
110
+ if (node.expanded && node.items) {
111
+ const visibleItems = getVisibleItems(node);
112
+ flatList = flatList.concat(flattenTreeWithDepth(visibleItems, depth + 1, node.key));
113
+ }
114
+ }
115
+ });
116
+ return flatList;
117
+ }, [getVisibleItems]);
118
+ // Lista piatta per la virtualizzazione
119
+ const flattenedItems = useMemo(() => {
120
+ if (!enableVirtualization)
121
+ return [];
122
+ return flattenTreeWithDepth(dataSource);
123
+ }, [enableVirtualization, dataSource, flattenTreeWithDepth]);
124
+ // Scroll verso l'elemento focalizzato quando cambia (navigazione con frecce)
125
+ useEffect(() => {
126
+ if (!focusedItem?.key)
127
+ return;
128
+ if (enableVirtualization) {
129
+ // Lista virtualizzata: usa scrollToRow per garantire che l'elemento sia visibile
130
+ const index = flattenedItems.findIndex(item => item.node.key === focusedItem.key);
131
+ if (index >= 0 && listRef.current) {
132
+ listRef.current.scrollToRow({ index, align: 'smart' });
133
+ }
134
+ }
135
+ else {
136
+ // Lista standard: usa scrollIntoView
137
+ if (containerRef.current) {
138
+ const element = containerRef.current.querySelector(`[data-node-key="${focusedItem.key}"]`);
139
+ if (element) {
140
+ element.scrollIntoView({ block: 'nearest', inline: 'nearest' });
141
+ }
142
+ }
143
+ }
144
+ }, [focusedItem?.key, enableVirtualization, flattenedItems]);
7
145
  useEffect(() => {
8
146
  const handleKeyDown = (event) => {
9
147
  if (!focusedItem)
@@ -33,9 +171,14 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
33
171
  handled = true;
34
172
  }
35
173
  break;
36
- // case ' ':
37
- // allowMultipleSelection && handleCheckboxChange(focusedItem, !selectedItems.some(item => item.key === focusedItem.key));
38
- // break;
174
+ case ' ':
175
+ case 'Spacebar': // IE/Edge legacy
176
+ if (allowMultipleSelection) {
177
+ const isCurrentlySelected = selectedItemsRef.current.some(item => item.key === focusedItem.key);
178
+ handleCheckboxChangeRef.current(focusedItem, !isCurrentlySelected);
179
+ handled = true;
180
+ }
181
+ break;
39
182
  // case '*':
40
183
  // handleExpandAllNodes();
41
184
  // break;
@@ -57,7 +200,7 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
57
200
  return () => {
58
201
  window.removeEventListener('keydown', handleKeyDown, true);
59
202
  };
60
- }, [focusedItem, dataSource, onFocusedItemChanged]);
203
+ }, [focusedItem, dataSource, onFocusedItemChanged, allowMultipleSelection]);
61
204
  const findNextItem = (nodes, currentItem) => {
62
205
  const flatList = flattenTree(nodes);
63
206
  const currentIndex = flatList.findIndex(item => item.key === currentItem.key);
@@ -138,22 +281,19 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
138
281
  }
139
282
  if (delayFocus) {
140
283
  // Logica per il ritardo del focus (es. click singolo su icona desktop, gestito dal padre)
141
- if (clickTimeoutRef.current) {
142
- // Questo è il secondo click di un potenziale doppio click.
143
- // Annulla l'azione di focus dal click singolo precedente.
144
- clearTimeout(clickTimeoutRef.current);
145
- clickTimeoutRef.current = null;
146
- lastClickedNodeKeyRef.current = undefined;
147
- return; // Non attivare onFocusedItemChanged per il doppio click
284
+ // Il focus viene ritardato per permettere al doppio click di registrarsi sull'icona,
285
+ // ma il focus avviene comunque (sia con click singolo che doppio)
286
+ if (!clickTimeoutRef.current) {
287
+ // Primo click: imposta il timer per il focus
288
+ lastClickedNodeKeyRef.current = node.key;
289
+ clickTimeoutRef.current = setTimeout(() => {
290
+ onFocusedItemChanged?.(node);
291
+ clickTimeoutRef.current = null;
292
+ lastClickedNodeKeyRef.current = undefined;
293
+ }, 200);
148
294
  }
149
- // Primo click di un potenziale doppio click o un click singolo che necessita di ritardo
150
- lastClickedNodeKeyRef.current = node.key;
151
- clickTimeoutRef.current = setTimeout(() => {
152
- // Se il timer scade, significa che è stato solo un click singolo.
153
- onFocusedItemChanged?.(node);
154
- clickTimeoutRef.current = null;
155
- lastClickedNodeKeyRef.current = undefined;
156
- }, 200);
295
+ // Se c'è già un timer attivo (secondo click di doppio click), non fare nulla
296
+ // Il focus avverrà comunque quando scade il timer del primo click
157
297
  }
158
298
  else {
159
299
  // Logica per il focus immediato (per tutti gli altri click, o se shouldDelayFocusOnEvent è false)
@@ -165,7 +305,9 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
165
305
  onFocusedItemChanged?.(node); // Chiama onFocusedItemChanged immediatamente
166
306
  }
167
307
  }, [onFocusedItemChanged, calculateItemsForNode, onNodeUpdate]);
168
- const handleCheckboxChange = (node, checked) => {
308
+ const handleCheckboxChange = useCallback((node, checked) => {
309
+ // Usa la ref per accedere sempre al valore più recente di selectedItems
310
+ const currentSelectedItems = selectedItemsRef.current;
169
311
  // Funzione helper per trovare il parent di un nodo e verificare se tutti i suoi figli sono selezionati
170
312
  const findAndCheckParents = (items, targetNode, currentSelection) => {
171
313
  const parentsToAdd = [];
@@ -202,11 +344,14 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
202
344
  if (node.isContainer && autoSelectChildren) {
203
345
  // Quando selezioni un container, aggiungi il container stesso + tutti i figli (se autoSelectChildren è true)
204
346
  const allChildren = flattenTree(node.items || []);
205
- newSelectedItems = [...selectedItems, node, ...allChildren];
347
+ // Rimuovi eventuali duplicati: filtra gli elementi già presenti nella selezione
348
+ const childrenKeys = new Set(allChildren.map(child => child.key));
349
+ const filteredSelectedItems = currentSelectedItems.filter(item => !childrenKeys.has(item.key) && item.key !== node.key);
350
+ newSelectedItems = [...filteredSelectedItems, node, ...allChildren];
206
351
  }
207
- else if (!selectedItems.some(item => item.key === node.key)) {
352
+ else if (!currentSelectedItems.some(item => item.key === node.key)) {
208
353
  // Quando selezioni un figlio o un container con autoSelectChildren=false, aggiungi solo il nodo
209
- newSelectedItems = [...selectedItems, node];
354
+ newSelectedItems = [...currentSelectedItems, node];
210
355
  // Verifica se selezionando questo figlio sono ora selezionati tutti i figli del parent (solo se autoSelectChildren è true)
211
356
  if (autoSelectChildren) {
212
357
  const parentsToAdd = findAndCheckParents(dataSource, node, newSelectedItems);
@@ -214,17 +359,17 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
214
359
  }
215
360
  }
216
361
  else {
217
- newSelectedItems = selectedItems;
362
+ newSelectedItems = currentSelectedItems;
218
363
  }
219
364
  }
220
365
  else if (node.isContainer && autoSelectChildren) {
221
366
  // Quando deselezioni un container, rimuovi il container stesso + tutti i figli (solo se autoSelectChildren è true)
222
367
  const childKeys = flattenTree(node.items || []).map(item => item.key);
223
- newSelectedItems = selectedItems.filter(item => item.key !== node.key && !childKeys.includes(item.key));
368
+ newSelectedItems = currentSelectedItems.filter(item => item.key !== node.key && !childKeys.includes(item.key));
224
369
  }
225
370
  else {
226
371
  // Quando deselezioni un figlio o un container con autoSelectChildren=false, rimuovi solo il nodo
227
- newSelectedItems = selectedItems.filter(item => item.key !== node.key);
372
+ newSelectedItems = currentSelectedItems.filter(item => item.key !== node.key);
228
373
  // Se il figlio apparteneva a un parent che era selezionato, rimuovi anche il parent (solo se autoSelectChildren è true)
229
374
  if (autoSelectChildren && !node.isContainer) {
230
375
  const removeParentContainers = (items) => {
@@ -246,28 +391,10 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
246
391
  }
247
392
  }
248
393
  onSelectionChanged?.(newSelectedItems);
249
- };
250
- // const handleExpandAllNodes = () => {
251
- // const expandAll = (nodes: T[]): T[] => {
252
- // return nodes.map(node => ({
253
- // ...node,
254
- // expanded: true,
255
- // items: node.items ? expandAll(node.items as T[]) : node.items
256
- // }));
257
- // };
258
- // setTreeData(prevData => expandAll(prevData));
259
- // };
260
- // const handleCollapseAllNodes = () => {
261
- // const collapseAll = (nodes: T[]): T[] => {
262
- // return nodes.map(node => ({
263
- // ...node,
264
- // expanded: false,
265
- // items: node.items ? collapseAll(node.items as T[]) : node.items
266
- // }));
267
- // };
268
- // setTreeData(prevData => collapseAll(prevData));
269
- // };
270
- const isIndeterminate = (node) => {
394
+ }, [autoSelectChildren, dataSource, onSelectionChanged]);
395
+ // Aggiorna la ref con l'ultima versione di handleCheckboxChange
396
+ handleCheckboxChangeRef.current = handleCheckboxChange;
397
+ const hasPartialChildSelection = (node) => {
271
398
  // Lo stato indeterminate ha senso solo quando autoSelectChildren è true
272
399
  if (!autoSelectChildren)
273
400
  return false;
@@ -278,13 +405,6 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
278
405
  const selectedCount = childKeys.filter(key => selectedChildKeys.includes(key)).length;
279
406
  return selectedCount > 0 && selectedCount < childKeys.length;
280
407
  };
281
- const isFullySelected = (node) => {
282
- if (!node.isContainer || !node.items)
283
- return false;
284
- const childKeys = flattenTree(node.items).map(item => item.key);
285
- const selectedChildKeys = selectedItems.map(item => item.key);
286
- return childKeys.every(key => selectedChildKeys.includes(key));
287
- };
288
408
  const hasVisibleItems = (node) => {
289
409
  // If node has explicit isExpandible value, use that
290
410
  if (node.isExpandible !== undefined) {
@@ -315,21 +435,6 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
315
435
  const updatedData = updateNodePage(dataSource);
316
436
  onDataChanged?.(updatedData);
317
437
  }, [dataSource, onDataChanged, onNodeUpdate]);
318
- // Filtra gli items da mostrare in base alla paginazione
319
- const getVisibleItems = useCallback((node) => {
320
- if (!node.items)
321
- return [];
322
- const totalItems = node.items.length;
323
- // Se non c'è paginazione attiva o gli items sono pochi, mostra tutti
324
- if (totalItems <= itemsPerPage || !showLoadMoreButton) {
325
- return node.items;
326
- }
327
- // Altrimenti mostra solo gli items della pagina corrente
328
- const currentPage = node.currentPage ?? 0;
329
- const startIndex = currentPage * itemsPerPage;
330
- const endIndex = startIndex + itemsPerPage;
331
- return node.items.slice(startIndex, endIndex);
332
- }, [itemsPerPage, showLoadMoreButton]);
333
438
  // Verifica se c'è bisogno del paginatore
334
439
  const needsPagination = useCallback((node) => {
335
440
  if (!showLoadMoreButton || !node.items)
@@ -343,7 +448,7 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
343
448
  return Math.ceil(node.items.length / itemsPerPage);
344
449
  }, [itemsPerPage]);
345
450
  const renderTree = useCallback((nodes) => {
346
- return nodes.map(node => !node.hidden && (_jsxs("div", { style: { width: '100%', margin: 0, padding: 0 }, children: [_jsxs(StyledTreeNode, { "$isSelected": node.key === focusedItem?.key, children: [_jsx("div", { style: {
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: {
347
452
  display: 'flex',
348
453
  alignItems: 'center',
349
454
  justifyContent: 'center',
@@ -358,28 +463,86 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
358
463
  : _jsx(IconChevronRight, { cursor: 'pointer', fontSize: 14 })
359
464
  : _jsx("div", { style: { height: '18px', width: '18px' } }) }), allowMultipleSelection && (_jsx("input", { type: "checkbox", checked: selectedItems.some(item => item.key === node.key), onChange: (e) => handleCheckboxChange(node, e.target.checked), onClick: (e) => e.stopPropagation(), style: { flexShrink: 0 }, ref: input => {
360
465
  if (input) {
361
- input.indeterminate = isIndeterminate(node);
466
+ // Imposta lo stato visuale "trattino" () sulla checkbox quando il container
467
+ // ha alcuni figli selezionati ma non tutti. Necessario usare ref perché
468
+ // "indeterminate" è una proprietà DOM, non un attributo HTML.
469
+ input.indeterminate = hasPartialChildSelection(node);
362
470
  }
363
- } })), _jsx("div", { style: { display: 'flex', alignItems: 'center', flex: 1, minWidth: 0 }, onClick: (e) => { handleNodeClick(node, e); }, onContextMenu: (e) => {
471
+ } })), _jsx(StyledItemContent, { onClick: (e) => { handleNodeClick(node, e); }, onContextMenu: (e) => {
364
472
  if (onItemContextMenu) {
365
473
  e.preventDefault();
366
474
  onItemContextMenu(node, e);
367
475
  }
368
- }, children: itemRender(node) })] }), node.expanded && node.items && (_jsxs("div", { style: { paddingLeft: 20, width: '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)));
476
+ }, 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)));
369
477
  }, [handleNodeClick, handleNodeToggle, handleCheckboxChange, focusedItem, selectedItems, allowMultipleSelection, getVisibleItems, needsPagination, handlePageChange, getTotalPages, onItemContextMenu]);
370
- return (_jsx("div", { style: { height: '100%', width: '100%', overflowY: 'auto', overflowX: 'hidden', padding: '0px 5px 2px 2px' }, children: renderTree(dataSource) }));
478
+ // Calcola selectedItemKeys ad ogni render per garantire sincronizzazione con selectedItems
479
+ const selectedItemKeys = new Set(selectedItems.map(s => s.key));
480
+ // Memoizza rowPropsData per evitare re-render della List
481
+ const rowPropsData = useMemo(() => ({
482
+ flattenedItems,
483
+ focusedItemKey: focusedItem?.key,
484
+ selectedItemKeys,
485
+ allowMultipleSelection,
486
+ hasVisibleItems,
487
+ handleNodeToggle,
488
+ handleNodeClick,
489
+ handleCheckboxChange,
490
+ hasPartialChildSelection: hasPartialChildSelection,
491
+ itemRender,
492
+ onItemContextMenu
493
+ }), [
494
+ flattenedItems,
495
+ focusedItem?.key,
496
+ selectedItemKeys,
497
+ allowMultipleSelection,
498
+ hasVisibleItems,
499
+ handleNodeToggle,
500
+ handleNodeClick,
501
+ handleCheckboxChange,
502
+ hasPartialChildSelection,
503
+ itemRender,
504
+ onItemContextMenu
505
+ ]);
506
+ // Render virtualizzato con react-window v2
507
+ if (enableVirtualization) {
508
+ return (_jsx(StyledTreeContainer, { ref: containerRef, children: containerSize.height > 0 && (_jsx(List, { listRef: listRef, rowCount: flattenedItems.length, rowHeight: VIRTUAL_ROW_HEIGHT, rowComponent: VirtualRowComponent, rowProps: rowPropsData, style: { height: containerSize.height, width: '100%' }, overscanCount: 5 })) }));
509
+ }
510
+ // Render standard (non virtualizzato) con scrolling orizzontale
511
+ return (_jsx(StyledTreeContainer, { ref: containerRef, children: _jsx("div", { children: renderTree(dataSource) }) }));
371
512
  };
372
513
  export default TMTreeView;
514
+ // Container principale con scrolling orizzontale
515
+ export const StyledTreeContainer = styled.div `
516
+ height: 100%;
517
+ width: 100%;
518
+ overflow-y: auto;
519
+ overflow-x: auto;
520
+ padding: 0px 0px 2px 2px;
521
+
522
+ /* Contenitore interno che si espande per accomodare nodi annidati */
523
+ & > div {
524
+ width: fit-content;
525
+ min-width: 100%;
526
+ }
527
+ `;
528
+ // Contenuto dell'item - niente ellipsis per permettere scrolling orizzontale del container
529
+ export const StyledItemContent = styled.div `
530
+ display: flex;
531
+ align-items: center;
532
+ flex-shrink: 0;
533
+ white-space: nowrap;
534
+ `;
373
535
  export const StyledTreeNode = styled.div `
374
536
  display: flex;
375
537
  flex-direction: row;
376
- width: 100%;
377
- min-width: 0;
538
+ width: fit-content;
539
+ min-width: 100%;
378
540
  min-height: 22px;
379
541
  max-height: 30px;
380
542
  gap: 5px;
381
543
  align-items: center;
382
544
  padding: 0;
545
+ padding-right: 10px; /* Spazio extra a destra per evitare che il testo tocchi il bordo */
383
546
  margin: 0;
384
547
  background: ${(props) => props.$isSelected ? 'oklch(from var(--dx-color-primary) l c h / .2) !important' : 'transparent'};
385
548
 
@@ -1,8 +1,9 @@
1
+ import React from 'react';
1
2
  interface TMUserAvatarProps {
2
3
  displayName: string;
3
4
  nameForColorCalculation: string;
4
5
  tooltipName?: string;
5
6
  returnType?: 'jsx' | 'svg';
6
7
  }
7
- declare const TMUserAvatar: (props: TMUserAvatarProps) => string | import("react/jsx-runtime").JSX.Element;
8
+ declare const TMUserAvatar: (props: TMUserAvatarProps) => string | React.JSX.Element;
8
9
  export default TMUserAvatar;
@@ -1,5 +1,6 @@
1
+ import React from 'react';
1
2
  import { ValidationItem } from '@topconsultnpm/sdk-ts';
2
3
  declare const TMVilViewer: ({ vil }: {
3
4
  vil?: ValidationItem[];
4
- }) => import("react/jsx-runtime").JSX.Element | null;
5
+ }) => React.JSX.Element | null;
5
6
  export default TMVilViewer;
@@ -1,3 +1,4 @@
1
+ import React from 'react';
1
2
  import { ITMLayoutContainerProps } from './TMLayout';
2
3
  interface ITMWaitPanelProps {
3
4
  title?: string;
@@ -12,8 +13,9 @@ interface ITMWaitPanelProps {
12
13
  isCancelable?: boolean;
13
14
  abortController?: AbortController;
14
15
  onAbortClick?: (abortController: AbortController | undefined) => void;
16
+ useHighZIndex?: boolean;
15
17
  }
16
- export declare const TMWaitPanel: (props: ITMWaitPanelProps) => import("react/jsx-runtime").JSX.Element;
18
+ export declare const TMWaitPanel: (props: ITMWaitPanelProps) => React.JSX.Element;
17
19
  interface ITMLayoutWaitingContainerProps extends ITMLayoutContainerProps {
18
20
  showWaitPanel?: boolean;
19
21
  waitPanelTitle?: string;
@@ -27,6 +29,7 @@ interface ITMLayoutWaitingContainerProps extends ITMLayoutContainerProps {
27
29
  waitPanelMaxValueSecondary?: number;
28
30
  isCancelable?: boolean;
29
31
  abortController?: AbortController;
32
+ usePortal?: boolean;
30
33
  }
31
- export declare const TMLayoutWaitingContainer: ({ showWaitPanel, showWaitPanelPrimary, showWaitPanelSecondary, waitPanelTitle, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, isCancelable, abortController, gap, onClick, justifyContent, alignItems, children, direction }: ITMLayoutWaitingContainerProps) => import("react/jsx-runtime").JSX.Element;
34
+ export declare const TMLayoutWaitingContainer: ({ showWaitPanel, showWaitPanelPrimary, showWaitPanelSecondary, waitPanelTitle, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, isCancelable, abortController, usePortal, gap, onClick, justifyContent, alignItems, children, direction }: ITMLayoutWaitingContainerProps) => React.JSX.Element;
32
35
  export {};
@@ -1,4 +1,5 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { createPortal } from 'react-dom';
2
3
  import styled from 'styled-components';
3
4
  import TMLayoutContainer from './TMLayout';
4
5
  import { SDKUI_Localizator } from '../../helper';
@@ -8,7 +9,7 @@ const StyledWaitPanelOverlay = styled.div `
8
9
  position: fixed;
9
10
  top: 0;
10
11
  left: 0;
11
- z-index: 1501;
12
+ z-index: ${props => props.$useHighZIndex ? 2000000001 : 1501};
12
13
  transition: all;
13
14
  overflow: visible;
14
15
  background-color: rgba(0, 0, 0, 0.4);
@@ -36,7 +37,7 @@ const StyledProgressText = styled.p ` font-weight: bold; color: #333; margin: 0;
36
37
  const StyledMessage = styled.p ` color: #666; font-size: 0.9em; margin-top: 10px; `;
37
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; } `;
38
39
  export const TMWaitPanel = (props) => {
39
- const { title, showPrimary, textPrimary, valuePrimary, maxValuePrimary, showSecondary, textSecondary, valueSecondary, maxValueSecondary, isCancelable, abortController, onAbortClick } = props;
40
+ const { title, showPrimary, textPrimary, valuePrimary, maxValuePrimary, showSecondary, textSecondary, valueSecondary, maxValueSecondary, isCancelable, abortController, onAbortClick, useHighZIndex } = props;
40
41
  const calculateProgress = (value = 0, maxValue = 0) => {
41
42
  if (maxValue === 0)
42
43
  return 0;
@@ -45,10 +46,11 @@ export const TMWaitPanel = (props) => {
45
46
  };
46
47
  let progressValue1 = calculateProgress(valuePrimary, maxValuePrimary);
47
48
  let progressValue2 = calculateProgress(valueSecondary, maxValueSecondary);
48
- return (_jsx(StyledWaitPanelOverlay, { children: _jsxs(StyledWaitPanel, { children: [_jsx(StyledTitle, { children: title }), showPrimary &&
49
+ return (_jsx(StyledWaitPanelOverlay, { "$useHighZIndex": useHighZIndex, children: _jsxs(StyledWaitPanel, { children: [_jsx(StyledTitle, { children: title }), showPrimary &&
49
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 &&
50
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 })] }) }));
51
52
  };
52
- export const TMLayoutWaitingContainer = ({ showWaitPanel, showWaitPanelPrimary, showWaitPanelSecondary, waitPanelTitle, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, isCancelable, abortController, gap = 3, onClick, justifyContent = 'flex-start', alignItems = 'flex-start', children, direction = 'vertical' }) => {
53
- return (_jsxs(TMLayoutContainer, { gap: gap, justifyContent: justifyContent, alignItems: alignItems, direction: direction, children: [children, showWaitPanel && (_jsx(TMWaitPanel, { title: waitPanelTitle, showPrimary: showWaitPanelPrimary, textPrimary: waitPanelTextPrimary, valuePrimary: waitPanelValuePrimary, maxValuePrimary: waitPanelMaxValuePrimary, showSecondary: showWaitPanelSecondary, textSecondary: waitPanelTextSecondary, valueSecondary: waitPanelValueSecondary, maxValueSecondary: waitPanelMaxValueSecondary, isCancelable: isCancelable, abortController: abortController, onAbortClick: (abortController) => { setTimeout(() => { abortController?.abort(); }, 1000); } }))] }));
53
+ export const TMLayoutWaitingContainer = ({ showWaitPanel, showWaitPanelPrimary, showWaitPanelSecondary, waitPanelTitle, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, isCancelable, abortController, usePortal = false, gap = 3, onClick, justifyContent = 'flex-start', alignItems = 'flex-start', children, direction = 'vertical' }) => {
54
+ const waitPanelElement = showWaitPanel ? (_jsx(TMWaitPanel, { title: waitPanelTitle, showPrimary: showWaitPanelPrimary, textPrimary: waitPanelTextPrimary, valuePrimary: waitPanelValuePrimary, maxValuePrimary: waitPanelMaxValuePrimary, showSecondary: showWaitPanelSecondary, textSecondary: waitPanelTextSecondary, valueSecondary: waitPanelValueSecondary, maxValueSecondary: waitPanelMaxValueSecondary, isCancelable: isCancelable, abortController: abortController, onAbortClick: (abortController) => { setTimeout(() => { abortController?.abort(); }, 1000); }, useHighZIndex: usePortal })) : null;
55
+ return (_jsxs(_Fragment, { children: [usePortal && waitPanelElement && createPortal(waitPanelElement, document.body), _jsxs(TMLayoutContainer, { gap: gap, justifyContent: justifyContent, alignItems: alignItems, direction: direction, children: [children, !usePortal && waitPanelElement] })] }));
54
56
  };
@@ -11,7 +11,7 @@ import TMPanel from '../base/TMPanel';
11
11
  import TMModal from '../base/TMModal';
12
12
  import { useDataListItem } from '../../hooks/useDataListItem';
13
13
  import { useDataUserIdItem } from '../../hooks/useDataUserIdItem';
14
- const StyledDistinctValues = styled.div `display: flex; flex-direction: column; height: 100%; overflow: hidden; gap: 10px;`;
14
+ const StyledDistinctValues = styled.div `display: flex; flex-direction: column; height: 100%; overflow: hidden; gap: 10px; position: relative;`;
15
15
  const TMDistinctValues = ({ tid, mid, layoutMode = LayoutModes.None, allowAppendMode = true, showHeader = true, isModal, separator = " ", onSelectionChanged, onClosePanelCallback }) => {
16
16
  const [focusedItem, setFocusedItem] = useState();
17
17
  const [dataSource, setDataSource] = useState([]);
@@ -39,4 +39,4 @@ interface ITMDynDataListItemChooserFormProps extends ITMChooserFormProps<DataLis
39
39
  dynDL?: DynamicDataListDescriptor;
40
40
  searchResult?: SearchResultDescriptor;
41
41
  }
42
- export declare const TMDynDataListItemChooserForm: (props: ITMDynDataListItemChooserFormProps) => import("react/jsx-runtime").JSX.Element;
42
+ export declare const TMDynDataListItemChooserForm: (props: ITMDynDataListItemChooserFormProps) => React.JSX.Element;
@@ -84,10 +84,15 @@ const TMDynDataListItemChooser = ({ tid, md, width = '100%', titleForm, openChoo
84
84
  _jsx(TMTooltip, { content: SDKUI_Localizator.ValueNotPresent, children: _jsx(IconWarning, { color: TMColors.warning }) });
85
85
  };
86
86
  const renderTemplate = () => {
87
+ const isPlaceholder = values?.[0] === placeHolder;
88
+ // Selezione singola: mostra direttamente il primo valore
89
+ if (!allowMultipleSelection) {
90
+ const singleDescription = getValueDescription(values?.[0]);
91
+ return (_jsx(StyledDivHorizontal, { style: { width: '100%', color: isPlaceholder ? '#a9a9a9' : 'inherit', alignItems: 'center' }, children: dataSource && singleDescription && _jsxs(StyledDivHorizontal, { style: { alignItems: 'center', gap: '8px' }, children: [getIcon(), _jsx("p", { children: singleDescription })] }) }));
92
+ }
87
93
  const MIN_COUNT_FOR_BADGE = 1;
88
94
  const MAX_VISIBLE_ITEMS = 3;
89
95
  const MAX_TOOLTIP_ITEMS = 50;
90
- const isPlaceholder = values?.[0] === placeHolder;
91
96
  const descriptions = getDescriptions(MAX_VISIBLE_ITEMS);
92
97
  const remainingCount = (values?.length ?? 0) - MAX_VISIBLE_ITEMS;
93
98
  const totalCount = values?.length ?? 0;
@@ -11,7 +11,7 @@ export const TMGroupChooserForm = (props) => {
11
11
  TMSpinner.hide();
12
12
  return items ?? [];
13
13
  };
14
- return (_jsx(TMChooserForm, { title: SDK_Localizator.Groups, allowMultipleSelection: props.allowMultipleSelection, width: props.width, height: props.height, manageUseLocalizedName: true, hasShowOnlySelectedItems: true, selectedIDs: props.selectedIDs, startWithShowOnlySelectedItems: false, cellRenderIcon: () => _jsx(IconUserGroup, { color: '#767676' }), dataSource: props.dataSource, getItems: getItems, onClose: props.onClose, onChoose: (IDs) => { props.onChoose?.(IDs); } }));
14
+ return (_jsx(TMChooserForm, { title: SDK_Localizator.Groups, allowMultipleSelection: props.allowMultipleSelection, width: props.width, height: props.height, manageUseLocalizedName: props.manageUseLocalizedName ?? true, hasShowOnlySelectedItems: true, selectedIDs: props.selectedIDs, startWithShowOnlySelectedItems: false, cellRenderIcon: () => _jsx(IconUserGroup, { color: '#767676' }), dataSource: props.dataSource, getItems: getItems, onClose: props.onClose, onChoose: (IDs) => { props.onChoose?.(IDs); } }));
15
15
  };
16
16
  export const TMGroupIdViewer = (props) => {
17
17
  const [group, setGroup] = useState(null);
@@ -1,4 +1,5 @@
1
+ import React from 'react';
1
2
  import { InvoiceRetrieveFormats } from '@topconsultnpm/sdk-ts';
2
3
  import { ITMEnumDataBinding } from '../../ts';
3
- declare const TMInvoiceRetrieveFormats: ({ value, valueOrig, onValueChanged, valuesToExclude, label, width }: ITMEnumDataBinding<InvoiceRetrieveFormats>) => import("react/jsx-runtime").JSX.Element;
4
+ declare const TMInvoiceRetrieveFormats: ({ value, valueOrig, onValueChanged, valuesToExclude, label, width }: ITMEnumDataBinding<InvoiceRetrieveFormats>) => React.JSX.Element;
4
5
  export default TMInvoiceRetrieveFormats;
@@ -1,4 +1,5 @@
1
+ import React from 'react';
1
2
  import { OrderRetrieveFormats } from '@topconsultnpm/sdk-ts';
2
3
  import { ITMEnumDataBinding } from '../../ts';
3
- declare const TMOrderRetrieveFormats: ({ value, valueOrig, onValueChanged, valuesToExclude, label, width }: ITMEnumDataBinding<OrderRetrieveFormats>) => import("react/jsx-runtime").JSX.Element;
4
+ declare const TMOrderRetrieveFormats: ({ value, valueOrig, onValueChanged, valuesToExclude, label, width }: ITMEnumDataBinding<OrderRetrieveFormats>) => React.JSX.Element;
4
5
  export default TMOrderRetrieveFormats;
@@ -19,13 +19,13 @@ export declare const TMRelationIdViewer: ({ relationType, relationId, showIcon,
19
19
  relationId?: number;
20
20
  showIcon?: boolean;
21
21
  noneSelectionText?: string;
22
- }) => import("react/jsx-runtime").JSX.Element;
22
+ }) => React.JSX.Element;
23
23
  export declare const TMRelationIcon: ({ rd, relationType }: {
24
24
  rd: RelationDescriptor | undefined;
25
25
  relationType?: RelationTypes;
26
- }) => import("react/jsx-runtime").JSX.Element;
26
+ }) => React.JSX.Element;
27
27
  export declare const TMRelationTooltip: ({ rd, relationType, children }: {
28
28
  rd?: RelationDescriptor;
29
29
  relationType: RelationTypes | undefined;
30
30
  children: React.ReactNode;
31
- }) => import("react/jsx-runtime").JSX.Element;
31
+ }) => React.JSX.Element;
@@ -38,8 +38,8 @@ interface ITMUserChooserFormProps extends ITMChooserFormProps<UserDescriptor> {
38
38
  export declare const TMUserChooserForm: React.FunctionComponent<ITMUserChooserFormProps>;
39
39
  export declare const TMUserIcon: ({ ud }: {
40
40
  ud?: UserDescriptor;
41
- }) => import("react/jsx-runtime").JSX.Element | null;
41
+ }) => React.JSX.Element | null;
42
42
  export declare const TMUserTooltip: ({ ud, children }: {
43
43
  ud?: UserDescriptor;
44
44
  children: React.ReactNode;
45
- }) => import("react/jsx-runtime").JSX.Element;
45
+ }) => React.JSX.Element;