@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.
- package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +28 -2
- package/lib/components/NewComponents/ContextMenu/styles.d.ts +4 -4
- package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +6 -6
- package/lib/components/base/Styled.d.ts +1 -1
- package/lib/components/base/TMAreaManager.js +11 -0
- package/lib/components/base/TMCounterBar.d.ts +2 -2
- package/lib/components/base/TMCounterContainer.d.ts +2 -1
- package/lib/components/base/TMCustomButton.d.ts +1 -1
- package/lib/components/base/TMDataGrid.js +12 -2
- package/lib/components/base/TMDataGridExportForm.d.ts +2 -1
- package/lib/components/base/TMDataGridExportForm.js +19 -8
- package/lib/components/base/TMFileManager.d.ts +2 -1
- package/lib/components/base/TMFileManagerDataGridView.d.ts +2 -1
- package/lib/components/base/TMFileManagerDataGridView.js +4 -4
- package/lib/components/base/TMFileManagerThumbnailItems.d.ts +1 -1
- package/lib/components/base/TMFileManagerThumbnailItems.js +3 -3
- package/lib/components/base/TMFileManagerThumbnailsView.d.ts +1 -1
- package/lib/components/base/TMFileManagerUtils.d.ts +7 -0
- package/lib/components/base/TMFileManagerUtils.js +14 -1
- package/lib/components/base/TMLayout.d.ts +4 -4
- package/lib/components/base/TMList.d.ts +2 -1
- package/lib/components/base/TMListView.d.ts +1 -1
- package/lib/components/base/TMModal.js +2 -2
- package/lib/components/base/TMPopUp.d.ts +1 -0
- package/lib/components/base/TMPopUp.js +59 -2
- package/lib/components/base/TMSpinner.d.ts +5 -2
- package/lib/components/base/TMSpinner.js +33 -6
- package/lib/components/base/TMTab.d.ts +4 -3
- package/lib/components/base/TMTooltip.d.ts +1 -1
- package/lib/components/base/TMTreeView.d.ts +16 -13
- package/lib/components/base/TMTreeView.js +242 -79
- package/lib/components/base/TMUserAvatar.d.ts +2 -1
- package/lib/components/base/TMVilViewer.d.ts +2 -1
- package/lib/components/base/TMWaitPanel.d.ts +5 -2
- package/lib/components/base/TMWaitPanel.js +8 -6
- package/lib/components/choosers/TMDistinctValues.js +1 -1
- package/lib/components/choosers/TMDynDataListItemChooser.d.ts +1 -1
- package/lib/components/choosers/TMDynDataListItemChooser.js +6 -1
- package/lib/components/choosers/TMGroupChooser.js +1 -1
- package/lib/components/choosers/TMInvoiceRetrieveFormats.d.ts +2 -1
- package/lib/components/choosers/TMOrderRetrieveFormats.d.ts +2 -1
- package/lib/components/choosers/TMRelationChooser.d.ts +3 -3
- package/lib/components/choosers/TMUserChooser.d.ts +2 -2
- package/lib/components/editors/TMEditorStyled.d.ts +6 -6
- package/lib/components/editors/TMFormulaEditor.d.ts +2 -1
- package/lib/components/editors/TMFormulaEditor.js +98 -49
- package/lib/components/editors/TMHtmlContentDisplay.d.ts +2 -1
- package/lib/components/editors/TMHtmlEditor.d.ts +2 -1
- package/lib/components/editors/TMMetadataEditor.js +6 -2
- package/lib/components/editors/TMMetadataValues.js +23 -6
- package/lib/components/editors/TMTextBox.d.ts +1 -0
- package/lib/components/editors/TMTextBox.js +2 -1
- package/lib/components/editors/TMTreeDropDown.d.ts +1 -1
- package/lib/components/features/assistant/TMToppyDraggableHelpCenter.d.ts +1 -1
- package/lib/components/features/blog/TMBlogCommentForm.d.ts +2 -1
- package/lib/components/features/blog/TMBlogCommentForm.js +5 -2
- package/lib/components/features/documents/TMCopyToFolderForm.js +46 -24
- package/lib/components/features/documents/TMDcmtForm.d.ts +2 -0
- package/lib/components/features/documents/TMDcmtForm.js +21 -10
- package/lib/components/features/documents/TMDcmtFormActionButtons.d.ts +1 -1
- package/lib/components/features/documents/TMDcmtIcon.d.ts +4 -1
- package/lib/components/features/documents/TMDcmtIcon.js +6 -33
- package/lib/components/features/documents/TMDcmtPreview.d.ts +1 -1
- package/lib/components/features/documents/TMDcmtTasks.d.ts +2 -1
- package/lib/components/features/documents/TMDragDropOverlay.d.ts +1 -1
- package/lib/components/features/documents/TMFileUploader.js +1 -1
- package/lib/components/features/documents/TMMasterDetailDcmts.d.ts +2 -2
- package/lib/components/features/documents/TMMasterDetailDcmts.js +55 -16
- package/lib/components/features/documents/TMMergeToPdfForm.d.ts +2 -3
- package/lib/components/features/documents/TMMergeToPdfForm.js +115 -56
- package/lib/components/features/documents/TMRelationViewer.d.ts +12 -10
- package/lib/components/features/documents/TMRelationViewer.js +405 -95
- package/lib/components/features/documents/copyAndMergeDcmtsShared.d.ts +4 -16
- package/lib/components/features/documents/copyAndMergeDcmtsShared.js +47 -61
- package/lib/components/features/documents/mergePdfUtils.d.ts +52 -0
- package/lib/components/features/documents/mergePdfUtils.js +268 -0
- package/lib/components/features/search/TMDcmtCheckoutInfoForm.d.ts +2 -1
- package/lib/components/features/search/TMMetadataOutputForm.d.ts +18 -0
- package/lib/components/features/search/TMMetadataOutputForm.js +225 -0
- package/lib/components/features/search/TMMetadataSorterForm.d.ts +18 -0
- package/lib/components/features/search/TMMetadataSorterForm.js +243 -0
- package/lib/components/features/search/TMSavedQuerySelector.d.ts +2 -2
- package/lib/components/features/search/TMSearch.d.ts +2 -2
- package/lib/components/features/search/TMSearch.js +2 -2
- package/lib/components/features/search/TMSearchQueryEditor.js +14 -8
- package/lib/components/features/search/TMSearchQueryPanel.js +249 -58
- package/lib/components/features/search/TMSearchResult.d.ts +3 -2
- package/lib/components/features/search/TMSearchResult.js +94 -25
- package/lib/components/features/search/TMSearchResultFloatingActionButton.d.ts +1 -1
- package/lib/components/features/search/TMSignatureInfoContent.d.ts +2 -1
- package/lib/components/features/search/TMViewHistoryDcmt.d.ts +2 -1
- package/lib/components/features/search/TMViewHistoryDcmt.js +1 -1
- package/lib/components/features/search/metadataFormHelper.d.ts +16 -0
- package/lib/components/features/search/metadataFormHelper.js +77 -0
- package/lib/components/features/tasks/TMTaskForm.d.ts +1 -1
- package/lib/components/features/tasks/TMTaskFormUtils.d.ts +10 -10
- package/lib/components/features/tasks/TMTasksAgenda.d.ts +1 -1
- package/lib/components/features/tasks/TMTasksCalendar.d.ts +1 -1
- package/lib/components/features/tasks/TMTasksHeader.d.ts +1 -1
- package/lib/components/features/tasks/TMTasksPanelContent.d.ts +1 -1
- package/lib/components/features/tasks/TMTasksUtilsView.d.ts +5 -5
- package/lib/components/features/tasks/TMTasksView.d.ts +1 -1
- package/lib/components/features/wg/TMWGsCopyMoveForm.d.ts +3 -2
- package/lib/components/features/workflow/TMWorkflowPopup.d.ts +8 -7
- package/lib/components/forms/Login/Chooser.d.ts +2 -2
- package/lib/components/forms/Login/TMLoginForm.js +15 -3
- package/lib/components/forms/TMChooserForm.d.ts +2 -1
- package/lib/components/forms/TMSaveForm.d.ts +4 -4
- package/lib/components/grids/TMBlogAttachments.d.ts +2 -1
- package/lib/components/grids/TMBlogAttachments.js +2 -2
- package/lib/components/grids/TMBlogHeader.d.ts +1 -1
- package/lib/components/grids/TMBlogsPost.d.ts +1 -1
- package/lib/components/grids/TMBlogsPost.js +5 -3
- package/lib/components/grids/TMBlogsPostUtils.d.ts +10 -9
- package/lib/components/grids/TMBlogsPostUtils.js +3 -1
- package/lib/components/grids/TMValidationItemsList.d.ts +2 -1
- package/lib/components/layout/panelManager/TMPanelManagerContainer.d.ts +2 -1
- package/lib/components/layout/panelManager/TMPanelManagerContext.d.ts +2 -2
- package/lib/components/layout/panelManager/TMPanelManagerToolbar.d.ts +1 -1
- package/lib/components/layout/panelManager/TMPanelManagerWithPersistenceProvider.d.ts +2 -2
- package/lib/components/layout/panelManager/TMPanelWrapper.d.ts +2 -2
- package/lib/components/pages/TMPage.d.ts +1 -1
- package/lib/components/settings/SettingsAppearance.d.ts +2 -1
- package/lib/components/sidebar/TMAboutApp.d.ts +2 -1
- package/lib/components/sidebar/TMHeader.d.ts +3 -3
- package/lib/components/viewers/TMDataListItemViewer.d.ts +3 -2
- package/lib/components/viewers/TMDataUserIdItemViewer.d.ts +3 -2
- package/lib/components/viewers/TMMidViewer.d.ts +2 -2
- package/lib/components/viewers/TMTidViewer.d.ts +2 -2
- package/lib/components/viewers/TMTidViewer.js +14 -2
- package/lib/components/wizard/TMWizard.d.ts +1 -0
- package/lib/components/wizard/TMWizard.js +5 -3
- package/lib/helper/Enum_Localizator.js +2 -0
- package/lib/helper/MergePdfManager.d.ts +45 -0
- package/lib/helper/MergePdfManager.js +148 -0
- package/lib/helper/SDKUI_Globals.d.ts +1 -0
- package/lib/helper/SDKUI_Globals.js +3 -1
- package/lib/helper/SDKUI_Localizator.d.ts +40 -0
- package/lib/helper/SDKUI_Localizator.js +412 -12
- package/lib/helper/TMCommandsContextMenu.d.ts +1 -1
- package/lib/helper/TMIcons.d.ts +278 -278
- package/lib/helper/TMPdfViewer.d.ts +2 -1
- package/lib/helper/TMToppyMessage.d.ts +2 -2
- package/lib/helper/TMUtils.d.ts +57 -21
- package/lib/helper/TMUtils.js +159 -1
- package/lib/helper/certificateImportHelper.d.ts +43 -0
- package/lib/helper/certificateImportHelper.js +403 -0
- package/lib/helper/checkinCheckoutManager.d.ts +4 -3
- package/lib/helper/checkinCheckoutManager.js +29 -11
- package/lib/helper/helpers.d.ts +3 -2
- package/lib/helper/helpers.js +10 -0
- package/lib/helper/index.d.ts +1 -0
- package/lib/helper/index.js +1 -0
- package/lib/hooks/useCheckInOutOperations.d.ts +4 -3
- package/lib/hooks/useDataUserIdItem.js +1 -1
- package/lib/hooks/useDcmtOperations.d.ts +20 -2
- package/lib/hooks/useDcmtOperations.js +244 -25
- package/lib/hooks/useDocumentOperations.d.ts +2 -2
- package/lib/hooks/useDocumentOperations.js +52 -13
- package/lib/hooks/useInputDialog.d.ts +2 -1
- package/lib/hooks/useRelatedDocuments.js +4 -4
- package/lib/services/platform_services.d.ts +7 -6
- package/lib/ts/types.d.ts +3 -1
- package/lib/ts/types.js +2 -0
- 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
|
-
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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
|
-
//
|
|
150
|
-
|
|
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
|
-
|
|
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 (!
|
|
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 = [...
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
-
//
|
|
251
|
-
|
|
252
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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:
|
|
377
|
-
min-width:
|
|
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 |
|
|
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
|
-
}) =>
|
|
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) =>
|
|
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) =>
|
|
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
|
-
|
|
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) =>
|
|
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>) =>
|
|
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>) =>
|
|
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
|
-
}) =>
|
|
22
|
+
}) => React.JSX.Element;
|
|
23
23
|
export declare const TMRelationIcon: ({ rd, relationType }: {
|
|
24
24
|
rd: RelationDescriptor | undefined;
|
|
25
25
|
relationType?: RelationTypes;
|
|
26
|
-
}) =>
|
|
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
|
-
}) =>
|
|
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
|
-
}) =>
|
|
41
|
+
}) => React.JSX.Element | null;
|
|
42
42
|
export declare const TMUserTooltip: ({ ud, children }: {
|
|
43
43
|
ud?: UserDescriptor;
|
|
44
44
|
children: React.ReactNode;
|
|
45
|
-
}) =>
|
|
45
|
+
}) => React.JSX.Element;
|