@topconsultnpm/sdkui-react 6.19.0-dev2.17 → 6.19.0-dev2.19

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.
@@ -13,6 +13,7 @@ import TMButton from "./TMButton";
13
13
  import { TMSearchBar } from "../sidebar/TMHeader";
14
14
  import TMFileManagerThumbnailsView from "./TMFileManagerThumbnailsView";
15
15
  import TMFileManagerDataGridView from "./TMFileManagerDataGridView";
16
+ import { UserListCacheService } from "@topconsultnpm/sdk-ts";
16
17
  const TMFileManager = (props) => {
17
18
  // Destructure props
18
19
  const {
@@ -44,6 +45,14 @@ const TMFileManager = (props) => {
44
45
  const [droppedFiles, setDroppedFiles] = useState([]);
45
46
  // State to track whether a file drag operation is in progress
46
47
  const [isDragging, setIsDragging] = useState(false);
48
+ const [allUsers, setAllUsers] = useState([]);
49
+ useEffect(() => {
50
+ const fetchAllUsers = async () => {
51
+ const users = await UserListCacheService.GetAllAsync();
52
+ setAllUsers(users ?? []);
53
+ };
54
+ fetchAllUsers();
55
+ }, []);
47
56
  // useEffect runs whenever `treeFs` changes
48
57
  useEffect(() => {
49
58
  // Initialize an empty array to hold tree view directory data
@@ -219,6 +228,6 @@ const TMFileManager = (props) => {
219
228
  pointerEvents: "none",
220
229
  backdropFilter: "blur(3px)",
221
230
  textShadow: "0 2px 4px rgba(0,0,0,0.5)"
222
- }, children: SDKUI_Localizator.DropFileToShare }), viewMode === 'thumbnails' && _jsx(TMFileManagerThumbnailsView, { items: filteredFileItems ?? [], focusedFile: focusedFile, handleFocusedFile: handleFocusedFile, selectedFiles: selectedFiles, handleSelectedFiles: handleSelectedFiles, fileContextMenuItems: fileContextMenuItems, searchText: searchText, userID: userID, draftThumbViewAnchor: draftThumbViewAnchor, setDraftThumbViewAnchor: setDraftThumbViewAnchor, onDoubleClickHandler: onDoubleClickHandler }), viewMode === 'details' && _jsx(TMFileManagerDataGridView, { items: filteredFileItems ?? [], focusedFile: focusedFile, handleFocusedFile: handleFocusedFile, selectedFiles: selectedFiles, handleSelectedFiles: handleSelectedFiles, fileContextMenuItems: fileContextMenuItems, searchText: searchText, userID: userID, onDoubleClickHandler: onDoubleClickHandler })] })] })] }) }) });
231
+ }, children: SDKUI_Localizator.DropFileToShare }), viewMode === 'thumbnails' && _jsx(TMFileManagerThumbnailsView, { items: filteredFileItems ?? [], allUsers: allUsers, focusedFile: focusedFile, handleFocusedFile: handleFocusedFile, selectedFiles: selectedFiles, handleSelectedFiles: handleSelectedFiles, fileContextMenuItems: fileContextMenuItems, searchText: searchText, userID: userID, draftThumbViewAnchor: draftThumbViewAnchor, setDraftThumbViewAnchor: setDraftThumbViewAnchor, onDoubleClickHandler: onDoubleClickHandler }), viewMode === 'details' && _jsx(TMFileManagerDataGridView, { items: filteredFileItems ?? [], allUsers: allUsers, focusedFile: focusedFile, handleFocusedFile: handleFocusedFile, selectedFiles: selectedFiles, handleSelectedFiles: handleSelectedFiles, fileContextMenuItems: fileContextMenuItems, searchText: searchText, userID: userID, onDoubleClickHandler: onDoubleClickHandler })] })] })] }) }) });
223
232
  };
224
233
  export default TMFileManager;
@@ -1,6 +1,8 @@
1
1
  import { FileItem, TMFileManagerContextMenuItem } from "./TMFileManagerUtils";
2
+ import { UserDescriptor } from "@topconsultnpm/sdk-ts";
2
3
  interface TMFileManagerDataGridViewProps {
3
4
  items: Array<FileItem>;
5
+ allUsers: Array<UserDescriptor>;
4
6
  focusedFile: FileItem | undefined;
5
7
  handleFocusedFile: (fileItem: FileItem | undefined) => void;
6
8
  selectedFiles: Array<FileItem>;
@@ -5,7 +5,7 @@ import TMDataGrid from "./TMDataGrid";
5
5
  import TMDcmtIcon from "../features/documents/TMDcmtIcon";
6
6
  import TMTooltip from "./TMTooltip";
7
7
  const TMFileManagerDataGridView = (props) => {
8
- const { items, focusedFile, handleFocusedFile, selectedFiles, handleSelectedFiles, fileContextMenuItems, searchText, userID, onDoubleClickHandler } = props;
8
+ const { items, allUsers, focusedFile, handleFocusedFile, selectedFiles, handleSelectedFiles, fileContextMenuItems, searchText, userID, onDoubleClickHandler } = props;
9
9
  // State hook to store the currently focused row key, initially set to undefined
10
10
  const [focusedRowKey, setFocusedRowKey] = useState(focusedFile?.id);
11
11
  // State to store selected row keys
@@ -16,6 +16,15 @@ const TMFileManagerDataGridView = (props) => {
16
16
  useEffect(() => {
17
17
  setSelectedRowKeys(selectedFiles.map(selectedFile => selectedFile.id));
18
18
  }, [selectedFiles]);
19
+ const findCheckOutUserName = useCallback((checkOutUserName, checkOutUserID) => {
20
+ if (checkOutUserName) {
21
+ return checkOutUserName;
22
+ }
23
+ else {
24
+ let checkOutUser = allUsers.find(user => user.id === checkOutUserID);
25
+ return checkOutUser ? checkOutUser.name : '-';
26
+ }
27
+ }, [allUsers]);
19
28
  // DataGrid Callback
20
29
  // Handles focus change in the data grid
21
30
  const onFocusedRowChanged = useCallback((e) => {
@@ -58,7 +67,7 @@ const TMFileManagerDataGridView = (props) => {
58
67
  const checkoutUsedId = checkOutUserID;
59
68
  const editMode = checkoutDate && checkoutUsedId && userID && userID === checkoutUsedId;
60
69
  const lockMode = checkoutDate && checkoutUsedId && userID && userID !== checkoutUsedId;
61
- const editLockTooltipText = _jsxs(_Fragment, { children: [_jsxs("div", { style: { textAlign: "center" }, children: [editMode && (_jsxs(_Fragment, { children: [_jsx("i", { style: { fontSize: "18px", color: "#28a745", fontWeight: "bold" }, className: "dx-icon-edit" }), SDKUI_Localizator.CurrentUserExtract] })), lockMode && (_jsxs(_Fragment, { children: [_jsx("i", { style: { fontSize: "18px", color: "#28a745", fontWeight: "bold" }, className: "dx-icon-lock" }), SDKUI_Localizator.ExtractedFromOtherUser] }))] }), _jsx("hr", {}), _jsxs("div", { style: { textAlign: "left" }, children: [_jsxs("ul", { children: [_jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.ExtractedBy }), ": ", checkOutUserName ?? '-', " (ID: ", checkOutUserID, ")"] }), _jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.ExtractedOn }), ": ", Globalization.getDateTimeDisplayValue(checkoutDate?.toString())] })] }), _jsx("hr", {}), _jsx("ul", { children: _jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.Version }), ": ", version ?? 1] }) }), _jsx("hr", {}), _jsxs("ul", { children: [_jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.Type }), ": ", ext] }), _jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.CreationTime }), ": ", Globalization.getDateTimeDisplayValue(creationTime?.toString())] }), _jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.LastUpdateTime }), ": ", Globalization.getDateTimeDisplayValue(lastUpdateTime?.toString())] })] })] })] });
70
+ const editLockTooltipText = _jsxs(_Fragment, { children: [_jsxs("div", { style: { textAlign: "center" }, children: [editMode && (_jsxs(_Fragment, { children: [_jsx("i", { style: { fontSize: "18px", color: "#28a745", fontWeight: "bold" }, className: "dx-icon-edit" }), SDKUI_Localizator.CurrentUserExtract] })), lockMode && (_jsxs(_Fragment, { children: [_jsx("i", { style: { fontSize: "18px", color: "#28a745", fontWeight: "bold" }, className: "dx-icon-lock" }), SDKUI_Localizator.ExtractedFromOtherUser] }))] }), _jsx("hr", {}), _jsxs("div", { style: { textAlign: "left" }, children: [_jsxs("ul", { children: [_jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.ExtractedBy }), ": ", findCheckOutUserName(checkOutUserName, checkOutUserID) ?? '-', " (ID: ", checkOutUserID, ")"] }), _jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.ExtractedOn }), ": ", Globalization.getDateTimeDisplayValue(checkoutDate?.toString())] })] }), _jsx("hr", {}), _jsx("ul", { children: _jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.Version }), ": ", version ?? 1] }) }), _jsx("hr", {}), _jsxs("ul", { children: [_jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.Type }), ": ", ext] }), _jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.CreationTime }), ": ", Globalization.getDateTimeDisplayValue(creationTime?.toString())] }), _jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.LastUpdateTime }), ": ", Globalization.getDateTimeDisplayValue(lastUpdateTime?.toString())] })] })] })] });
62
71
  return _jsxs("div", { style: { display: "inline-flex", alignItems: "center", gap: "4px" }, children: [editMode && _jsx(TMTooltip, { content: editLockTooltipText, children: _jsx("i", { style: { fontSize: "18px", color: "#28a745", fontWeight: "bold" }, className: "dx-icon-edit" }) }), lockMode && _jsx(TMTooltip, { content: editLockTooltipText, children: _jsx("i", { style: { fontSize: "18px", color: "#28a745", fontWeight: "bold" }, className: "dx-icon-lock" }) }), renderHighlightedText(cellData.value, searchText, false)] });
63
72
  }, [searchText]);
64
73
  const cellExtRender = useCallback((cellData) => {
@@ -1,7 +1,9 @@
1
1
  import React from 'react';
2
2
  import { FileItem } from './TMFileManagerUtils';
3
+ import { UserDescriptor } from '@topconsultnpm/sdk-ts';
3
4
  export interface TMFileManagerThumbnailItemsProps {
4
5
  items: Array<FileItem>;
6
+ allUsers: Array<UserDescriptor>;
5
7
  paginatedItems: Array<FileItem>;
6
8
  focusedFile: FileItem | undefined;
7
9
  handleFocusedFile: (fileItem: FileItem | undefined) => void;
@@ -6,7 +6,7 @@ import TMTooltip from './TMTooltip';
6
6
  import TMDcmtIcon from '../features/documents/TMDcmtIcon';
7
7
  const TMFileManagerThumbnailItems = (props) => {
8
8
  // Destructuring props for cleaner usage
9
- const { items, paginatedItems, selectedFiles, searchText, userID, onDoubleClick, handleSelectedFiles, handleFocusedFile, setDraftThumbViewAnchor } = props;
9
+ const { items, allUsers, paginatedItems, selectedFiles, searchText, userID, onDoubleClick, handleSelectedFiles, handleFocusedFile, setDraftThumbViewAnchor } = props;
10
10
  // Ref for the scrollable container
11
11
  const containerRef = useRef(null);
12
12
  // Stores index of the last selected item for shift selection
@@ -112,6 +112,16 @@ const TMFileManagerThumbnailItems = (props) => {
112
112
  setDraftThumbViewAnchor(e.currentTarget);
113
113
  handleFocusedFile(item);
114
114
  }, []);
115
+ const findCheckOutUserName = useCallback((item) => {
116
+ if (item.checkOutUserName) {
117
+ return item.checkOutUserName;
118
+ }
119
+ else {
120
+ const checkOutUserID = item.checkOutUserID;
121
+ let checkOutUser = allUsers.find(user => user.id === checkOutUserID);
122
+ return checkOutUser ? checkOutUser.name : '-';
123
+ }
124
+ }, [allUsers]);
115
125
  return _jsx("div", { style: { width: "100%", height: "100%" }, children: paginatedItems.map(item => {
116
126
  const isSelected = selectedFiles?.map(file => file.id).includes(item.id) ?? false;
117
127
  const checkoutDate = item.checkoutDate;
@@ -130,7 +140,7 @@ const TMFileManagerThumbnailItems = (props) => {
130
140
  bgColor = isSelected ? colors.PRIMARY_BLUE : backgroundColors.lockMode;
131
141
  bgHoverColor = isSelected ? colors.PRIMARY_BLUE : "#fff59d";
132
142
  }
133
- const editLockTooltipText = _jsxs(_Fragment, { children: [_jsxs("div", { style: { textAlign: "center" }, children: [editMode && (_jsxs(_Fragment, { children: [_jsx("i", { style: { fontSize: "18px", color: colors.MEDIUM_GREEN, fontWeight: "bold" }, className: "dx-icon-edit" }), SDKUI_Localizator.CurrentUserExtract] })), lockMode && (_jsxs(_Fragment, { children: [_jsx("i", { style: { fontSize: "18px", color: colors.MEDIUM_GREEN, fontWeight: "bold" }, className: "dx-icon-lock" }), SDKUI_Localizator.ExtractedFromOtherUser] }))] }), _jsx("hr", {}), _jsxs("div", { style: { textAlign: "left" }, children: [_jsxs("ul", { children: [_jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.ExtractedBy }), ": ", item.checkOutUserName ?? '-', " (ID: ", item.checkOutUserID, ")"] }), _jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.ExtractedOn }), ": ", Globalization.getDateTimeDisplayValue(item.checkoutDate?.toString())] })] }), _jsx("hr", {}), _jsx("ul", { children: _jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.Version }), ": ", item.version ?? 1] }) }), _jsx("hr", {}), _jsxs("ul", { children: [_jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.Type }), ": ", item.ext] }), _jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.CreationTime }), ": ", Globalization.getDateTimeDisplayValue(item.creationTime?.toString())] }), _jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.LastUpdateTime }), ": ", Globalization.getDateTimeDisplayValue(item.lastUpdateTime?.toString())] })] })] })] });
143
+ const editLockTooltipText = _jsxs(_Fragment, { children: [_jsxs("div", { style: { textAlign: "center" }, children: [editMode && (_jsxs(_Fragment, { children: [_jsx("i", { style: { fontSize: "18px", color: colors.MEDIUM_GREEN, fontWeight: "bold" }, className: "dx-icon-edit" }), SDKUI_Localizator.CurrentUserExtract] })), lockMode && (_jsxs(_Fragment, { children: [_jsx("i", { style: { fontSize: "18px", color: colors.MEDIUM_GREEN, fontWeight: "bold" }, className: "dx-icon-lock" }), SDKUI_Localizator.ExtractedFromOtherUser] }))] }), _jsx("hr", {}), _jsxs("div", { style: { textAlign: "left" }, children: [_jsxs("ul", { children: [_jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.ExtractedBy }), ": ", findCheckOutUserName(item) ?? '-', " (ID: ", item.checkOutUserID, ")"] }), _jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.ExtractedOn }), ": ", Globalization.getDateTimeDisplayValue(item.checkoutDate?.toString())] })] }), _jsx("hr", {}), _jsx("ul", { children: _jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.Version }), ": ", item.version ?? 1] }) }), _jsx("hr", {}), _jsxs("ul", { children: [_jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.Type }), ": ", item.ext] }), _jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.CreationTime }), ": ", Globalization.getDateTimeDisplayValue(item.creationTime?.toString())] }), _jsxs("li", { children: ["- ", _jsx("span", { style: { fontWeight: 'bold' }, children: SDKUI_Localizator.LastUpdateTime }), ": ", Globalization.getDateTimeDisplayValue(item.lastUpdateTime?.toString())] })] })] })] });
134
144
  const tooltipContent = (_jsxs("div", { style: { textAlign: 'left' }, children: [_jsxs("div", { children: [_jsx("span", { style: { fontWeight: 'bold' }, children: "ID:" }), " ", item.id ?? '-'] }), _jsxs("div", { children: [_jsx("span", { style: { fontWeight: 'bold' }, children: "DID:" }), " ", item.did ?? '-'] }), _jsxs("div", { children: [_jsx("span", { style: { fontWeight: 'bold' }, children: "TID:" }), " ", item.tid ?? '-'] }), _jsx("hr", {}), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Name, ":"] }), " ", item.name ?? '-'] }), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Author, ":"] }), " ", item.updaterName ?? '-'] }), _jsx("hr", {}), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Version, ":"] }), " ", item.version] }), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Size, ":"] }), " ", formatBytes(item.size ?? 0)] }), _jsx("hr", {}), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.CreationTime, ":"] }), " ", Globalization.getDateTimeDisplayValue(item.creationTime)] }), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.LastUpdateTime, ":"] }), " ", Globalization.getDateTimeDisplayValue(item.lastUpdateTime)] })] }));
135
145
  return _jsx(TMFileItemContainer, { className: "tm-file-manager-thumbnail-items", ref: containerRef, id: "tm-file-manager-thumbnail-item-" + item.id.toString(), "$backgroundColor": bgColor, "$bgHoverColor": bgHoverColor, "$textColor": textColor, onDoubleClick: () => onDoubleClickHandler(item), onContextMenu: (e) => onContextMenu(e, item), onClick: (e) => onClickHandler(e, item), tabIndex: 0, onKeyDown: handleKeyDown, onKeyUp: handleKeyUp, children: _jsxs("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', width: '100%' }, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', flex: 1, minWidth: 0 }, children: [_jsxs("div", { style: { marginRight: '16px', flexShrink: 0 }, children: [_jsx(TMDcmtIcon, { tid: item.tid, did: item.did, fileExtension: item.ext, downloadMode: 'openInNewWindow', tooltipContent: tooltipContent }), editMode && _jsx(TMTooltip, { content: editLockTooltipText, children: _jsx("i", { style: { fontSize: "18px", color: !isSelected ? colors.MEDIUM_GREEN : '#fff', fontWeight: "bold" }, className: "dx-icon-edit" }) }), lockMode && _jsx(TMTooltip, { content: editLockTooltipText, children: _jsx("i", { style: { fontSize: "18px", color: !isSelected ? colors.MEDIUM_GREEN : '#fff', fontWeight: "bold" }, className: "dx-icon-lock" }) })] }), _jsxs("div", { style: { overflow: 'hidden', minWidth: 0 }, children: [_jsx("div", { style: { whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', width: '100%', display: 'block', fontSize: '1rem', fontWeight: "bold" }, children: _jsx(TMTooltip, { parentStyle: { overflow: 'hidden' }, childStyle: { whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', width: '100%', display: 'block' }, children: renderHighlightedText(item.name, searchText, isSelected) }) }), _jsx("div", { style: { whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', width: '100%', display: 'block', fontSize: 'calc(1rem - 1px)' }, children: formatBytes(item.size ?? 0) })] })] }), item.version && (_jsx("div", { style: { flexShrink: 0, marginLeft: '12px', whiteSpace: 'nowrap' }, children: _jsx(TMTooltip, { content: SDKUI_Localizator.Version, children: _jsx("div", { style: { border: "2px solid #28a745", backgroundColor: "#28a745", color: "#ffffff", borderRadius: '50%', width: '30px', height: '30px', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '12px', fontWeight: 'bold' }, children: item.version }) }) }))] }) }, "tm-file-manager-thumbnail-item-" + item.id);
136
146
  }) });
@@ -1,7 +1,9 @@
1
1
  import React from "react";
2
2
  import { FileItem, TMFileManagerContextMenuItem } from "./TMFileManagerUtils";
3
+ import { UserDescriptor } from "@topconsultnpm/sdk-ts";
3
4
  interface TMFileManagerThumbnailsViewProps {
4
5
  items: Array<FileItem>;
6
+ allUsers: Array<UserDescriptor>;
5
7
  focusedFile: FileItem | undefined;
6
8
  handleFocusedFile: (fileItem: FileItem | undefined) => void;
7
9
  selectedFiles: Array<FileItem>;
@@ -5,7 +5,7 @@ import { ContextMenu, Pagination, ScrollView } from "devextreme-react";
5
5
  import TMFileManagerThumbnailItems from "./TMFileManagerThumbnailItems";
6
6
  import { SDKUI_Localizator } from "../../helper";
7
7
  const TMFileManagerThumbnailsView = (props) => {
8
- const { items, focusedFile, handleFocusedFile, selectedFiles = [], handleSelectedFiles, fileContextMenuItems, searchText, userID, onDoubleClickHandler, draftThumbViewAnchor, setDraftThumbViewAnchor } = props;
8
+ const { items, allUsers, focusedFile, handleFocusedFile, selectedFiles = [], handleSelectedFiles, fileContextMenuItems, searchText, userID, onDoubleClickHandler, draftThumbViewAnchor, setDraftThumbViewAnchor } = props;
9
9
  const PAGE_SIZES = [TMFileManagerPageSize.Small, TMFileManagerPageSize.Medium, TMFileManagerPageSize.Large];
10
10
  const initPageSize = TMFileManagerPageSize.Small;
11
11
  const showPagination = (items?.length ?? 0) > initPageSize;
@@ -39,7 +39,7 @@ const TMFileManagerThumbnailsView = (props) => {
39
39
  handleSelectedFiles?.([]);
40
40
  };
41
41
  return items.length > 0 ?
42
- _jsxs("div", { style: { width: "100%", height: "100%" }, onContextMenu: onBackgroundContextMenu, children: [_jsx(ScrollView, { width: "100%", height: showPagination ? "calc(100% - 50px)" : "100%", useNative: true, direction: 'vertical', children: _jsx(TMFileManagerThumbnailItems, { items: items, paginatedItems: paginatedItems, focusedFile: focusedFile, selectedFiles: selectedFiles, userID: userID, searchText: searchText, handleFocusedFile: handleFocusedFile, handleSelectedFiles: handleSelectedFiles, onDoubleClick: handleItemDoubleClick, setDraftThumbViewAnchor: setDraftThumbViewAnchor }) }), showPagination && _jsx(Pagination, { height: "50px", showInfo: true, showNavigationButtons: true, allowedPageSizes: PAGE_SIZES, displayMode: 'compact', itemCount: items.length, pageIndex: pageIndex, pageSize: pageSize, onPageIndexChange: setPageIndex, onPageSizeChange: setPageSize }), draftThumbViewAnchor && _jsx(ContextMenu, { id: 'fileViewContextMenuMobile', dataSource: fileContextMenuItems, target: draftThumbViewAnchor, onHiding: closeViewContextMenu })] })
42
+ _jsxs("div", { style: { width: "100%", height: "100%" }, onContextMenu: onBackgroundContextMenu, children: [_jsx(ScrollView, { width: "100%", height: showPagination ? "calc(100% - 50px)" : "100%", useNative: true, direction: 'vertical', children: _jsx(TMFileManagerThumbnailItems, { items: items, allUsers: allUsers, paginatedItems: paginatedItems, focusedFile: focusedFile, selectedFiles: selectedFiles, userID: userID, searchText: searchText, handleFocusedFile: handleFocusedFile, handleSelectedFiles: handleSelectedFiles, onDoubleClick: handleItemDoubleClick, setDraftThumbViewAnchor: setDraftThumbViewAnchor }) }), showPagination && _jsx(Pagination, { height: "50px", showInfo: true, showNavigationButtons: true, allowedPageSizes: PAGE_SIZES, displayMode: 'compact', itemCount: items.length, pageIndex: pageIndex, pageSize: pageSize, onPageIndexChange: setPageIndex, onPageSizeChange: setPageSize }), draftThumbViewAnchor && _jsx(ContextMenu, { id: 'fileViewContextMenuMobile', dataSource: fileContextMenuItems, target: draftThumbViewAnchor, onHiding: closeViewContextMenu })] })
43
43
  :
44
44
  _jsxs("div", { onContextMenu: onBackgroundContextMenu, style: { width: "100%", height: "100%", display: 'flex', justifyContent: 'center', alignItems: 'center', marginTop: '10px' }, children: [SDKUI_Localizator.FolderIsEmpty, draftThumbViewAnchor && _jsx(ContextMenu, { id: 'fileViewContextMenuMobile', dataSource: fileContextMenuItems, target: draftThumbViewAnchor, onHiding: closeViewContextMenu })] });
45
45
  };
@@ -142,12 +142,16 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
142
142
  const [treeData, setTreeData] = useState([]);
143
143
  const [showZeroDcmts, setShowZeroDcmts] = useState(initialShowZeroDcmts);
144
144
  const [staticItemsState, setStaticItemsState] = useState([]);
145
- // Wait Panel State (only used if allowWaitPanel is true)
146
145
  const [showWaitPanel, setShowWaitPanel] = useState(false);
147
146
  const [waitPanelTextPrimary, setWaitPanelTextPrimary] = useState('');
148
147
  const [waitPanelValuePrimary, setWaitPanelValuePrimary] = useState(0);
149
148
  const [waitPanelMaxValuePrimary, setWaitPanelMaxValuePrimary] = useState(0);
150
149
  const [abortController] = useState(new AbortController());
150
+ const [showExpansionWaitPanel, setShowExpansionWaitPanel] = useState(false);
151
+ const [expansionWaitPanelText, setExpansionWaitPanelText] = useState('');
152
+ const [expansionWaitPanelValue, setExpansionWaitPanelValue] = useState(0);
153
+ const [expansionWaitPanelMaxValue, setExpansionWaitPanelMaxValue] = useState(0);
154
+ const [expansionAbortController, setExpansionAbortController] = useState(undefined);
151
155
  // Ref to track last loaded input to prevent unnecessary reloads
152
156
  const lastLoadedInputRef = React.useRef('');
153
157
  // Ref to track if user has manually expanded/collapsed static items
@@ -560,30 +564,55 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
560
564
  // If container is already loaded, return items
561
565
  if (node.isLoaded)
562
566
  return node.items;
563
- // Load sub-documents for each document in the container
564
- const newItems = [];
565
- for (const dcmt of node.items ?? []) {
566
- const item = { ...dcmt }; // Create a new reference
567
- if (item.tid && item.did && !item.isLoaded) {
568
- // Nella modalità originale (invertMasterNavigation=false),
569
- // i documenti detail non devono caricare i master come figli
570
- if (isForMaster && !invertMasterNavigation) {
571
- // Carica i detail dei detail (navigazione naturale detail→detail)
572
- const loadedItems = await getDetailDcmtsAsync(item.tid, item.did, 1);
573
- item.items = updateHiddenProperty(loadedItems);
567
+ const newAbortController = new AbortController();
568
+ setExpansionAbortController(newAbortController);
569
+ const itemsToLoad = node.items?.length ?? 0;
570
+ setShowExpansionWaitPanel(true);
571
+ setExpansionWaitPanelMaxValue(itemsToLoad);
572
+ setExpansionWaitPanelValue(0);
573
+ setExpansionWaitPanelText(`Caricamento documenti correlati...`);
574
+ try {
575
+ const newItems = [];
576
+ let processedCount = 0;
577
+ for (const dcmt of node.items ?? []) {
578
+ if (newAbortController.signal.aborted) {
579
+ console.log('Folder expansion aborted by user');
580
+ return node.items;
574
581
  }
575
- else {
576
- // Modalità standard o invertita
577
- const loadedItems = isForMaster
578
- ? await getMasterDcmtsAsync(item.tid, item.did, 1)
579
- : await getDetailDcmtsAsync(item.tid, item.did, 1);
580
- item.items = updateHiddenProperty(loadedItems);
582
+ const item = { ...dcmt };
583
+ if (item.tid && item.did && !item.isLoaded) {
584
+ // Update progress
585
+ processedCount++;
586
+ setExpansionWaitPanelValue(processedCount);
587
+ setExpansionWaitPanelText(`Caricamento ${processedCount} di ${itemsToLoad}...`);
588
+ // Nella modalità originale (invertMasterNavigation=false),
589
+ // i documenti detail non devono caricare i master come figli
590
+ if (isForMaster && !invertMasterNavigation) {
591
+ // Carica i detail dei detail (navigazione naturale detail→detail)
592
+ const loadedItems = await getDetailDcmtsAsync(item.tid, item.did, 1);
593
+ item.items = updateHiddenProperty(loadedItems);
594
+ }
595
+ else {
596
+ // Modalità standard o invertita
597
+ const loadedItems = isForMaster
598
+ ? await getMasterDcmtsAsync(item.tid, item.did, 1)
599
+ : await getDetailDcmtsAsync(item.tid, item.did, 1);
600
+ item.items = updateHiddenProperty(loadedItems);
601
+ }
602
+ item.isLoaded = true;
581
603
  }
582
- item.isLoaded = true;
604
+ newItems.push(item);
583
605
  }
584
- newItems.push(item);
606
+ return newItems;
607
+ }
608
+ catch (error) {
609
+ console.error('Error loading folder contents:', error);
610
+ return node.items;
611
+ }
612
+ finally {
613
+ setShowExpansionWaitPanel(false);
614
+ setExpansionAbortController(undefined);
585
615
  }
586
- return newItems;
587
616
  }, [isForMaster, invertMasterNavigation, getDetailDcmtsAsync, getMasterDcmtsAsync, updateHiddenProperty]);
588
617
  /**
589
618
  * Default item renderer with metadata display (adapted from TMMasterDetailDcmts.tsx)
@@ -715,6 +744,10 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
715
744
  if (mergedTreeData.length === 0) {
716
745
  return _jsx("div", { style: { padding: '20px', textAlign: 'center', color: '#666' }, children: "Nessuna relazione disponibile." });
717
746
  }
718
- return (_jsx(TMTreeView, { dataSource: mergedTreeData, itemRender: finalItemRender, calculateItemsForNode: calculateItemsForNode, onDataChanged: handleDataChanged, focusedItem: focusedItem, onFocusedItemChanged: handleFocusedItemChanged, allowMultipleSelection: allowMultipleSelection, selectedItems: selectedItems, onSelectionChanged: handleSelectedItemsChanged }));
747
+ return (_jsxs(_Fragment, { children: [_jsx(TMTreeView, { dataSource: mergedTreeData, itemRender: finalItemRender, calculateItemsForNode: calculateItemsForNode, onDataChanged: handleDataChanged, focusedItem: focusedItem, onFocusedItemChanged: handleFocusedItemChanged, allowMultipleSelection: allowMultipleSelection, selectedItems: selectedItems, onSelectionChanged: handleSelectedItemsChanged }), showExpansionWaitPanel && (_jsx(TMWaitPanel, { title: isForMaster ? 'Caricamento documenti master' : 'Caricamento documenti dettaglio', showPrimary: true, textPrimary: expansionWaitPanelText, valuePrimary: expansionWaitPanelValue, maxValuePrimary: expansionWaitPanelMaxValue, isCancelable: true, abortController: expansionAbortController, onAbortClick: (abortController) => {
748
+ setTimeout(() => {
749
+ abortController?.abort();
750
+ }, 100);
751
+ } }))] }));
719
752
  };
720
753
  export default TMRelationViewer;
@@ -74,6 +74,7 @@ interface TMBlogsPostProps {
74
74
  externalBlogPost?: BlogPost;
75
75
  /** Optional function to reset the external blog post */
76
76
  resetExternalBlogPost?: () => void;
77
+ visible?: boolean;
77
78
  allTasks?: Array<TaskDescriptor>;
78
79
  getAllTasks?: () => Promise<void>;
79
80
  deleteTaskByIdsCallback?: (deletedTaskIds: Array<number>) => Promise<void>;
@@ -30,7 +30,7 @@ const TMBlogsPost = (props) => {
30
30
  isRestoreEnabled: false,
31
31
  isRefreshEnabled: false,
32
32
  isCreateContextualTask: false,
33
- }, showFloatingCommentButton = false, showCommentFormCallback, showTaskFormCallback, refreshCallback, showId, setShowId, refreshHomePageNews, markBlogAsRead, externalBlogPost, resetExternalBlogPost, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, } = props;
33
+ }, showFloatingCommentButton = false, showCommentFormCallback, showTaskFormCallback, refreshCallback, showId, setShowId, refreshHomePageNews, markBlogAsRead, externalBlogPost, resetExternalBlogPost, visible = true, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, } = props;
34
34
  const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync } = useDcmtOperations();
35
35
  const bottomRef = useRef(null);
36
36
  const containerRef = useRef(null);
@@ -222,6 +222,11 @@ const TMBlogsPost = (props) => {
222
222
  if (setShowId)
223
223
  setShowId(localShowId);
224
224
  }, [localShowId]);
225
+ useEffect(() => {
226
+ if (!visible) {
227
+ closeContextMenu();
228
+ }
229
+ }, [visible]);
225
230
  const toggleHeaderClick = () => {
226
231
  setCurrentHeader(prevState => {
227
232
  if (prevState === undefined) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react",
3
- "version": "6.19.0-dev2.17",
3
+ "version": "6.19.0-dev2.19",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",