@topconsultnpm/sdkui-react-beta 6.12.109 → 6.12.111

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.
@@ -18,9 +18,9 @@ const TMDataGrid = React.forwardRef((props, ref) => {
18
18
  // custom options
19
19
  dataColumns = [], pageSize = TMDataGridPageSize.Large, showHeaderFilter = true, showFilterPanel = false, showLoadPanel = true, showSearchPanel = true, searchPanelToolbarPosition = 'before', counterConfig = { show: false, items: new Map() },
20
20
  // events and callbacks
21
- onSelectionChanged, onFocusedRowChanged, onRowDblClick, onRowClick, onCellClick, onOptionChanged, onContentReady, onContextMenuPreparing, onInitialized, onEditorPreparing, onCellPrepared, onRowPrepared, onRowUpdating, onRowExpanded, onRowCollapsed, onRowUpdated, onSaved, onEditCanceled, onEditingStart, onEditingChange, customizeColumns, scrolling = { mode: 'standard', useNative: Number(SDKUI_Globals.userSettings?.themeSettings.gridSettings.useNativeScrollbar) === 1 }, paging = { enabled: true, pageSize: pageSize }, pager = { visible: true, showInfo: true, showNavigationButtons: true }, selection = { mode: 'multiple', showCheckBoxesMode: "always", selectAllMode: "allPages" }, sorting, summary, stateStoring, columnChooser, grouping, groupPanel, filterRow, headerFilter, editing, rowDragging, masterDetail,
21
+ onSelectionChanged, onFocusedRowChanged, onRowDblClick, onRowClick, onCellClick, onOptionChanged, onContentReady, onContextMenuPreparing, onInitialized, onEditorPreparing, onCellPrepared, onRowPrepared, onRowUpdating, onRowExpanded, onRowCollapsed, onRowUpdated, onSaved, onEditCanceled, onEditingStart, onEditingChange, customizeColumns, scrolling = { mode: 'standard', useNative: SDKUI_Globals.userSettings?.themeSettings.gridSettings.useNativeScrollbar === 1 }, paging = { enabled: true, pageSize: pageSize }, pager = { visible: true, showInfo: true, showNavigationButtons: true }, selection = { mode: 'multiple', showCheckBoxesMode: "always", selectAllMode: "allPages" }, sorting, summary, stateStoring, columnChooser, grouping, groupPanel, filterRow, headerFilter, editing, rowDragging, masterDetail,
22
22
  // other properties
23
- disabled = false, autoNavigateToFocusedRow = true, columnResizingMode = 'widget', columnHidingEnabled = true, columnAutoWidth = true, allowColumnResizing = true, allowColumnReordering = true, showBorders = true, showRowLines = Number(SDKUI_Globals.userSettings?.themeSettings.gridSettings.showRowLines) === 1, showColumnLines = Number(SDKUI_Globals.userSettings?.themeSettings.gridSettings.showColumnLines) === 1, showColumnHeaders = true, rowAlternationEnabled = false, wordWrapEnabled = false, noDataText,
23
+ disabled = false, autoNavigateToFocusedRow = true, columnResizingMode = 'widget', columnHidingEnabled = true, columnAutoWidth = true, allowColumnResizing = true, allowColumnReordering = true, showBorders = true, showRowLines = SDKUI_Globals.userSettings?.themeSettings.gridSettings.showRowLines === 1, showColumnLines = SDKUI_Globals.userSettings?.themeSettings.gridSettings.showColumnLines === 1, showColumnHeaders = true, rowAlternationEnabled = false, wordWrapEnabled = false, noDataText,
24
24
  // styles
25
25
  id, width = '100%', height = '100%', } = props;
26
26
  const [counterValues, setCounterValues] = useState(new Map());
@@ -23,7 +23,6 @@ const TMDcmtPreview = ({ dcmtData, onClose, canNext, canPrev, onNext, onPrev })
23
23
  const [error, setError] = useState('');
24
24
  const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, getDcmtFileAsync, clearDcmtsFileCache, removeDcmtsFileCache, isDcmtFileInCache } = useDcmtOperations();
25
25
  const cacheKey = dcmtData ? `${dcmtData.tid}-${dcmtData.did}` : '00';
26
- const FILE_SIZE_LIMIT = 500000;
27
26
  useEffect(() => {
28
27
  setDcmtBlob(undefined);
29
28
  setError('');
@@ -34,7 +33,7 @@ const TMDcmtPreview = ({ dcmtData, onClose, canNext, canPrev, onNext, onPrev })
34
33
  setShowPreview(true);
35
34
  return;
36
35
  }
37
- if ((extensionHandler(dcmtData.fileExt) !== FileExtensionHandler.NONE) && ((dcmtData.fileSize ?? 0) <= FILE_SIZE_LIMIT)) {
36
+ if ((extensionHandler(dcmtData.fileExt) !== FileExtensionHandler.NONE) && ((dcmtData.fileSize ?? 0) <= SDKUI_Globals.userSettings.searchSettings.previewThreshold)) {
38
37
  loadDocumentWithCache();
39
38
  setShowPreview(true);
40
39
  }
@@ -158,7 +158,7 @@ const TMSearch = ({ inputTID, inputSqdID, onRefreshAfterAddDcmtToFavs, onTaskCre
158
158
  newMruTIDS.splice(index, 1);
159
159
  SDKUI_Globals.userSettings.searchSettings.mruTIDs = newMruTIDS.filter(tid => tid != undefined && tid != null);
160
160
  setMruTIDs(newMruTIDS);
161
- } }) }), _jsx(TMSearchQueryPanel, { fromDTD: fromDTD, SQD: currentSQD, isOpenDistinctValuesPanel: showDistinctValuesPanel, rightSidebarItems: rightSidebarItems, onFocusedMetadataChanged: setFocusedTidMid, onRightSidebarItemClick: rightSidebarItemClickHandler, onCloseDistinctValuesPanel: () => setShowDistinctValuesPanel(false), onSearchCompleted: (searchResult, qd) => {
161
+ } }) }), _jsx(TMSearchQueryPanel, { fromDTD: fromDTD, SQD: currentSQD, isOpenDistinctValuesPanel: showDistinctValuesPanel, rightSidebarItems: rightSidebarItems, onBack: deviceType !== DeviceType.DESKTOP ? () => { setCurrentTID(0); } : undefined, onFocusedMetadataChanged: setFocusedTidMid, onRightSidebarItemClick: rightSidebarItemClickHandler, onCloseDistinctValuesPanel: () => setShowDistinctValuesPanel(false), onSearchCompleted: (searchResult, qd) => {
162
162
  setSearchResult(searchResult);
163
163
  if (searchResult.length <= 0)
164
164
  return;
@@ -7,6 +7,7 @@ interface ITMSearchQueryPanelProps {
7
7
  SQD?: SavedQueryDescriptor;
8
8
  isOpenDistinctValuesPanel?: boolean;
9
9
  rightSidebarItems?: ITMRightSidebarItem[];
10
+ onBack?: () => void;
10
11
  onRightSidebarItemClick?: (item: string) => void;
11
12
  onSqdSaved?: (newSqd: SavedQueryDescriptor) => void;
12
13
  onFocusedMetadataChanged?: (tid_mid: TID_MID | undefined) => void;
@@ -21,7 +21,7 @@ import TMDistinctValues from '../../choosers/TMDistinctValues';
21
21
  import { TMMetadataChooserForm } from '../../choosers/TMMetadataChooser';
22
22
  import TMQueryEditor from '../../query/TMQueryEditor';
23
23
  import TMSavedQueryForm from './TMSavedQueryForm';
24
- const TMSearchQueryPanel = ({ fromDTD, rightSidebarItems, isOpenDistinctValuesPanel = false, SQD, onRightSidebarItemClick, onSearchCompleted, onFocusedMetadataChanged, onCloseDistinctValuesPanel, onSqdSaved }) => {
24
+ const TMSearchQueryPanel = ({ fromDTD, rightSidebarItems, isOpenDistinctValuesPanel = false, SQD, onRightSidebarItemClick, onSearchCompleted, onFocusedMetadataChanged, onCloseDistinctValuesPanel, onSqdSaved, onBack }) => {
25
25
  const [confirmQueryParams, ConfirmQueryParamsDialog] = useQueryParametersDialog();
26
26
  const [qd, setQd] = useState();
27
27
  const [lastQdParams, setLastQdParams] = useState([]);
@@ -99,9 +99,7 @@ const TMSearchQueryPanel = ({ fromDTD, rightSidebarItems, isOpenDistinctValuesPa
99
99
  }
100
100
  }
101
101
  };
102
- return (_jsxs(TMSplitterLayout, { direction: 'horizontal', showSeparator: deviceType !== DeviceType.MOBILE && isOpenDistinctValuesPanel, separatorSize: 8, separatorColor: 'transparent', separatorActiveColor: 'transparent', min: ['0', '0'], start: deviceType === DeviceType.MOBILE ? ['100%', '0%'] : (isOpenDistinctValuesPanel ? ['55%', '45%'] : ['100%', '0%']), children: [_jsxs(TMToolbarCard, { title: fromDTD?.nameLoc ?? SDKUI_Localizator.Search_Metadata, items: rightSidebarItems, onItemClick: onRightSidebarItemClick,
103
- // onBack={deviceType !== DeviceType.DESKTOP ? () => { setCurrentTID(0) } : undefined}
104
- toolbar: _jsx(_Fragment, { children: (SQD && !showSqdForm) ?
102
+ return (_jsxs(TMSplitterLayout, { direction: 'horizontal', showSeparator: deviceType !== DeviceType.MOBILE && isOpenDistinctValuesPanel, separatorSize: 8, separatorColor: 'transparent', separatorActiveColor: 'transparent', min: ['0', '0'], start: deviceType === DeviceType.MOBILE ? ['100%', '0%'] : (isOpenDistinctValuesPanel ? ['55%', '45%'] : ['100%', '0%']), children: [_jsxs(TMToolbarCard, { title: fromDTD?.nameLoc ?? SDKUI_Localizator.Search_Metadata, items: rightSidebarItems, onItemClick: onRightSidebarItemClick, onBack: onBack, toolbar: _jsx(_Fragment, { children: (SQD && !showSqdForm) ?
105
103
  _jsx(TMDropDownMenu, { backgroundColor: 'white', borderRadius: '3px', content: _jsx(TMButton, { btnStyle: 'icon', caption: 'Altro', icon: _jsx(IconMenuVertical, { color: 'white' }), showTooltip: false }), items: [
106
104
  { icon: _jsx(IconAddCircleOutline, {}), text: SDKUI_Localizator.SavedQueryNew, onClick: () => { openSqdForm(FormModes.Create); } },
107
105
  { icon: _jsx(IconEdit, {}), text: SDKUI_Localizator.SavedQueryUpdate, disabled: (SQD && SQD.id == 1), onClick: () => { openSqdForm(FormModes.Update); } },
@@ -7,7 +7,7 @@ import { ContextMenu } from 'devextreme-react';
7
7
  import { genUniqueId, IconShow, IconBoard, IconDcmtTypeSys, IconDetailDcmts, SDKUI_Localizator, IconTag, IconDetails, IconCommand, IconDelete, IconRefresh, IconMenuVertical, IconDownload, IconSignature, deepCompare, getDataColumnName, searchResultDescriptorToSimpleArray, IconArchive, IconActivityLog, IconStar, IconFreeSearch, IconChevronDown, searchResultToMetadataValues } from '../../../helper';
8
8
  import { useDcmtOperations } from '../../../hooks/useDcmtOperations';
9
9
  import { useInputAttachmentsDialog, useInputCvtFormatDialog } from '../../../hooks/useInputDialog';
10
- import { DcmtOperationTypes, FormModes, SearchResultContext } from '../../../ts';
10
+ import { DcmtOperationTypes, FormModes, SearchResultContext, DownloadTypes } from '../../../ts';
11
11
  import { TMColors } from '../../../utils/theme';
12
12
  import { StyledModalContainer, StyledBadge, StyledMultiViewPanel } from '../../base/Styled';
13
13
  import ShowAlert from '../../base/TMAlert';
@@ -439,7 +439,7 @@ const TMSearchResult = ({ context = SearchResultContext.METADATA_SEARCH, isVisib
439
439
  , {
440
440
  // allowMultipleSelection={allowMultipleSelection}
441
441
  inputFocusedItem: focusedItem, inputSelectedItems: selectedItems, searchResult: searchResults.length > 1 ? selectedSearchResult : searchResults[0], lastUpdateSearchTime: lastUpdateSearchTime, onDblClick: () => openFormHandler(LayoutModes.Update), onContextMenuPreparing: onContextMenuPreparing, onSelectionChanged: (items) => { setSelectedItems(items); }, onVisibleItemChanged: setVisibleItems, onFocusedItemChanged: setFocusedItem }), allowFloatingBar && showFloatingBar && deviceType !== DeviceType.MOBILE &&
442
- _jsxs(TMFloatingToolbar, { backgroundColor: TMColors.primaryColor, initialLeft: '10px', initialTop: 'calc(100% - 75px)', children: [fromDTD?.perm?.canRetrieveFile === AccessLevels.Yes && _jsx(TMButton, { btnStyle: 'icon', caption: "Download file", disabled: fromDTD?.perm?.canRetrieveFile !== AccessLevels.Yes, icon: _jsx(IconDownload, { color: 'white' }), onClick: () => { downloadDcmtsAsync(getSelectedDcmtsOrFocused(selectedItems, focusedItem)); } }), _jsx(TMButton, { btnStyle: 'icon', caption: 'Firma e marca', icon: _jsx(IconSignature, { color: 'white' }), onClick: () => { ShowAlert({ message: "TODO Firma e marca ", mode: 'info', title: `${"TODO"}`, duration: 3000 }); } }), _jsx(IconMenuVertical, { id: `commands-floating-${id}`, color: 'white', cursor: 'pointer' }), _jsx(CommandsContextMenu, { target: `#commands-floating-${id}`, menuItems: getCommandsMenuItems(fromDTD, selectedItems, focusedItem, context, showFloatingBar, setShowFloatingBar, openFormHandler, downloadDcmtsAsync, runOperationAsync, onRefreshSearchAsync, refreshSelectionDataRowsAsync, onRefreshAfterAddDcmtToFavs, confirmFormat, openConfirmAttachmentsDialog, openTaskFormHandler, openDetailDcmtsFormHandler, openMasterDcmtsFormHandler, openBatchUpdateFormHandler) })] })] })] }), showApprovePopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onUpdate: onUpdate, selectedItems: getSelectedDcmtsOrFocused(selectedItems, focusedItem), op: 0, onClose: () => setShowApprovePopup(false) }), showRejectPopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onUpdate: onUpdate, selectedItems: getSelectedDcmtsOrFocused(selectedItems, focusedItem), op: 1, onClose: () => setShowRejectPopup(false) }), showReAssignPopup && _jsx(WorkFlowReAssignPopUp, { deviceType: deviceType, onUpdate: onUpdate, selectedItems: getSelectedDcmtsOrFocused(selectedItems, focusedItem), onClose: () => setShowReAssignPopup(false) })] }), _jsx(ConfirmFormatDialog, {}), _jsx(ConfirmAttachmentsDialog, {})] }) }), isOpenBatchUpdate ?
442
+ _jsxs(TMFloatingToolbar, { backgroundColor: TMColors.primaryColor, initialLeft: '10px', initialTop: 'calc(100% - 75px)', children: [fromDTD?.perm?.canRetrieveFile === AccessLevels.Yes && _jsx(TMButton, { btnStyle: 'icon', caption: "Download file", disabled: fromDTD?.perm?.canRetrieveFile !== AccessLevels.Yes, icon: _jsx(IconDownload, { color: 'white' }), onClick: () => { downloadDcmtsAsync(getSelectedDcmtsOrFocused(selectedItems, focusedItem), DownloadTypes.Dcmt); } }), _jsx(TMButton, { btnStyle: 'icon', caption: 'Firma e marca', icon: _jsx(IconSignature, { color: 'white' }), onClick: () => { ShowAlert({ message: "TODO Firma e marca ", mode: 'info', title: `${"TODO"}`, duration: 3000 }); } }), _jsx(IconMenuVertical, { id: `commands-floating-${id}`, color: 'white', cursor: 'pointer' }), _jsx(CommandsContextMenu, { target: `#commands-floating-${id}`, menuItems: getCommandsMenuItems(fromDTD, selectedItems, focusedItem, context, showFloatingBar, setShowFloatingBar, openFormHandler, downloadDcmtsAsync, runOperationAsync, onRefreshSearchAsync, refreshSelectionDataRowsAsync, onRefreshAfterAddDcmtToFavs, confirmFormat, openConfirmAttachmentsDialog, openTaskFormHandler, openDetailDcmtsFormHandler, openMasterDcmtsFormHandler, openBatchUpdateFormHandler) })] })] })] }), showApprovePopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onUpdate: onUpdate, selectedItems: getSelectedDcmtsOrFocused(selectedItems, focusedItem), op: 0, onClose: () => setShowApprovePopup(false) }), showRejectPopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onUpdate: onUpdate, selectedItems: getSelectedDcmtsOrFocused(selectedItems, focusedItem), op: 1, onClose: () => setShowRejectPopup(false) }), showReAssignPopup && _jsx(WorkFlowReAssignPopUp, { deviceType: deviceType, onUpdate: onUpdate, selectedItems: getSelectedDcmtsOrFocused(selectedItems, focusedItem), onClose: () => setShowReAssignPopup(false) })] }), _jsx(ConfirmFormatDialog, {}), _jsx(ConfirmAttachmentsDialog, {})] }) }), isOpenBatchUpdate ?
443
443
  _jsx(StyledModalContainer, { style: { backgroundColor: 'white' }, children: _jsx(TMBatchUpdateForm, { inputDcmts: getSelectionDcmtInfo(), TID: focusedItem ? focusedItem?.TID : selectedItems[0]?.TID, DID: focusedItem ? focusedItem?.DID : selectedItems[0]?.DID, onBack: () => setIsOpenBatchUpdate(false), onSavedCallbackAsync: async () => {
444
444
  setIsOpenBatchUpdate(false);
445
445
  setIsModifiedBatchUpdate(false);
@@ -465,7 +465,7 @@ const TMSearchResult = ({ context = SearchResultContext.METADATA_SEARCH, isVisib
465
465
  _jsxs(StyledModalContainer, { style: { backgroundColor: 'white' }, children: [_jsx(TMMasterDetailDcmts, { deviceType: deviceType, inputDcmts: getSelectionDcmtInfo(), isForMaster: true, allowNavigation: focusedItem && selectedItems.length <= 0, canNext: canNavigateHandler('next'), canPrev: canNavigateHandler('prev'), onNext: () => onNavigateHandler('next'), onPrev: () => onNavigateHandler('prev'), onBack: () => setIsOpenMaster(false), appendMasterDcmts: handleAddItem }), secondaryMasterDcmts.length > 0 && secondaryMasterDcmts.map((dcmt, index) => {
466
466
  return (_jsx(StyledModalContainer, { style: { backgroundColor: 'white' }, children: _jsx(TMMasterDetailDcmts, { deviceType: deviceType, inputDcmts: [dcmt], isForMaster: true, allowNavigation: false, onBack: () => handleRemoveItem(dcmt.TID, dcmt.DID), appendMasterDcmts: handleAddItem }) }, `${index}-${dcmt.DID}`));
467
467
  })] }), isOpenDcmtForm &&
468
- _jsx(StyledModalContainer, { style: { backgroundColor: 'white' }, children: _jsx(TMDcmtForm, { TID: focusedItem?.TID, DID: focusedItem?.DID, layoutMode: dcmtFormLayoutMode, showPreview: true, count: visibleItems.length, itemIndex: visibleItems.findIndex(o => o.rowIndex === focusedItem?.rowIndex) + 1, canNext: canNavigateHandler('next'), canPrev: canNavigateHandler('prev'), onNext: () => onNavigateHandler('next'), onPrev: () => onNavigateHandler('prev'), onClose: () => { setIsOpenDcmtForm(false); }, onSavedAsyncCallback: async (tid, did) => { await refreshFocusedDataRowAsync(tid, did, true); } }) })] }) }));
468
+ _jsx(StyledModalContainer, { style: { backgroundColor: 'white' }, children: _jsx(TMDcmtForm, { TID: focusedItem?.TID, DID: focusedItem?.DID, layoutMode: dcmtFormLayoutMode, showPreview: deviceType !== DeviceType.MOBILE, count: visibleItems.length, itemIndex: visibleItems.findIndex(o => o.rowIndex === focusedItem?.rowIndex) + 1, canNext: canNavigateHandler('next'), canPrev: canNavigateHandler('prev'), onNext: () => onNavigateHandler('next'), onPrev: () => onNavigateHandler('prev'), onClose: () => { setIsOpenDcmtForm(false); }, onSavedAsyncCallback: async (tid, did) => { await refreshFocusedDataRowAsync(tid, did, true); } }) })] }) }));
469
469
  };
470
470
  export default TMSearchResult;
471
471
  const renderDcmtIcon = (cellData) => _jsx(TMDcmtIcon, { fileExtension: cellData.data.FILEEXT, fileCount: cellData.data.FILECOUNT, isLexProt: cellData.data.IsLexProt, isMail: cellData.data.ISMAIL, isShared: cellData.data.ISSHARED, isSigned: cellData.data.ISSIGNED });
@@ -50,8 +50,6 @@ interface TMBlogsProps {
50
50
  }>;
51
51
  /** Optional callback function to update the list of visualized blog posts */
52
52
  updateVisualizedBlogCallback?: (blogPosts: Array<BlogPost | HomeBlogPost>) => void;
53
- /** Optional callback to handle clicks on attachment folder files */
54
- handleClickAttachmentFolderFileCallback?: (folderId: number, draftId: number) => void;
55
53
  /** Optional callback to handle navigation to working groups */
56
54
  handleNavigateToWGs?: (selectedWorkingGroupId: number) => void;
57
55
  /** Optional boolean to control the visibility of an ID */
@@ -65,6 +63,7 @@ interface TMBlogsProps {
65
63
  isShowHideFilterEnabled: boolean;
66
64
  isShowHideIDEnaled: boolean;
67
65
  isCommentEnabled: boolean;
66
+ isDownloadAttachmentEnabled: boolean;
68
67
  isDeleteEnabled: boolean;
69
68
  isRestoreEnabled: boolean;
70
69
  isRefreshEnabled: boolean;
@@ -15,12 +15,14 @@ import { TMResultManager } from '../forms/TMResultDialog';
15
15
  import { TMSearchBar } from '../sidebar/TMHeader';
16
16
  import { AttachmentElement, BlogPostContainer, colors, findFileItemByDraftID, highlightText, IconAndHeaderElement, isHeaderFullyHidden, OwnerInitialsBadge, TMBlogsFilterCategoryId } from './TMBlogsUtils';
17
17
  import { useDcmtOperations } from '../../hooks/useDcmtOperations';
18
- let abortController = new AbortController();
18
+ import { DownloadTypes } from '../../ts';
19
+ let localAbortController = new AbortController();
19
20
  const TMBlogs = (props) => {
20
- const { id, allData, showExtendedAttachments = true, treeFs, draftLatestInfoMap, archivedDocumentMap, updateVisualizedBlogCallback, handleClickAttachmentFolderFileCallback, height, width, scrollToBottom = true, viewMode = 'thumbnails', header, showIconHeader = true, color = colors.PRIMARY_BLUE, handleNavigateToWGs, showId, setShowId, currentWorkingGroup, contextMenuParams = {
21
+ const { id, allData, showExtendedAttachments = true, treeFs, draftLatestInfoMap, archivedDocumentMap, updateVisualizedBlogCallback, height, width, scrollToBottom = true, viewMode = 'thumbnails', header, showIconHeader = true, color = colors.PRIMARY_BLUE, handleNavigateToWGs, showId, setShowId, currentWorkingGroup, contextMenuParams = {
21
22
  isShowHideFilterEnabled: true,
22
23
  isShowHideIDEnaled: true,
23
24
  isCommentEnabled: false,
25
+ isDownloadAttachmentEnabled: false,
24
26
  isDeleteEnabled: false,
25
27
  isRestoreEnabled: false,
26
28
  isRefreshEnabled: false,
@@ -28,6 +30,7 @@ const TMBlogs = (props) => {
28
30
  }, refreshCallback, newPosts = [], showCommentFormCallback, showTaskFormCallback, showContextMenu = true } = props;
29
31
  // Get the current device type (e.g., mobile, tablet, desktop) using a custom hook.
30
32
  const deviceType = useDeviceType();
33
+ const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync } = useDcmtOperations();
31
34
  // This avoids unnecessary re-renders by only recalculating when deviceType changes.
32
35
  let isMobile = useMemo(() => { return deviceType === DeviceType.MOBILE; }, [deviceType]);
33
36
  // State to manage the current rendering mode of the component (either 'thumbnails' or 'details')
@@ -45,11 +48,12 @@ const TMBlogs = (props) => {
45
48
  // State to manage the focused file
46
49
  const [focusedBlog, setFocusedBlog] = useState(undefined);
47
50
  // State to manage the focused file
51
+ const [focusedAttachment, setFocusedAttachment] = useState(undefined);
52
+ // State to manage the focused file
48
53
  const [dcmtTypeDescriptors, setDcmtTypeDescriptors] = useState(new Map());
49
- // State to store context menu items for file manager actions
50
- const [menuItems, setMenuItems] = useState([]);
51
54
  // State to manage the anchor element for context menu positioning
52
55
  const [anchorEl, setAnchorEl] = useState(null);
56
+ const contextMenuRef = useRef(null);
53
57
  // State to store the current header value. Initialized with the provided 'header' prop.
54
58
  const [currentHeader, setCurrentHeader] = useState(header);
55
59
  // State to track whether the header is fully hidden based on the current header value
@@ -61,17 +65,17 @@ const TMBlogs = (props) => {
61
65
  // Ref to the container
62
66
  const containerRef = useRef(null);
63
67
  // State variable to control the visibility of the wait panel.
64
- const [showWaitPanel, setShowWaitPanel] = useState(false);
68
+ const [localShowWaitPanel, setLocalShowWaitPanel] = useState(false);
65
69
  // State variable to store the title of the wait panel.
66
- const [waitPanelTitle, setWaitPanelTitle] = useState('');
70
+ const [localWaitPanelTitle, setLocalWaitPanelTitle] = useState('');
67
71
  // State variable to control the visibility of the primary section of the wait panel.
68
- const [showPrimary, setShowPrimary] = useState(false);
72
+ const [localShowPrimary, setLocalShowPrimary] = useState(false);
69
73
  // State variable to store the primary text of the wait panel.
70
- const [waitPanelTextPrimary, setWaitPanelTextPrimary] = useState('');
74
+ const [localWaitPanelTextPrimary, setLocalWaitPanelTextPrimary] = useState('');
71
75
  // State variable to track the current value of the primary progress indicator in the wait panel.
72
- const [waitPanelValuePrimary, setWaitPanelValuePrimary] = useState(0);
76
+ const [localWaitPanelValuePrimary, setLocalWaitPanelValuePrimary] = useState(0);
73
77
  // State variable to define the maximum value for the primary progress indicator in the wait panel.
74
- const [waitPanelMaxValuePrimary, setWaitPanelMaxValuePrimary] = useState(0);
78
+ const [localWaitPanelMaxValuePrimary, setLocalWaitPanelMaxValuePrimary] = useState(0);
75
79
  // Data source for the number of posts to display in the UI
76
80
  const postsToShowDataSource = [
77
81
  { value: 30, display: SDKUI_Localizator.Latest + ' 30' },
@@ -110,59 +114,58 @@ const TMBlogs = (props) => {
110
114
  return;
111
115
  if (focusedBlog === undefined || focusedBlog.id === undefined || currentWorkingGroup === undefined || currentWorkingGroup.id === undefined)
112
116
  return Promise.resolve();
113
- setWaitPanelTitle(del ? SDKUI_Localizator.Delete : SDKUI_Localizator.Restore);
114
- setShowWaitPanel(true);
115
- setShowPrimary(true);
116
- abortController = new AbortController();
117
+ setLocalWaitPanelTitle(del ? SDKUI_Localizator.Delete : SDKUI_Localizator.Restore);
118
+ setLocalShowWaitPanel(true);
119
+ setLocalShowPrimary(true);
120
+ localAbortController = new AbortController();
117
121
  let result = [];
118
122
  let i = 0;
119
- setWaitPanelMaxValuePrimary(1);
123
+ setLocalWaitPanelMaxValuePrimary(1);
120
124
  if (abortController.signal.aborted) {
121
125
  result.push({ rowIndex: i, id1: focusedBlog.id, id2: focusedBlog.id, resultType: ResultTypes.WARNING, description: `Operazione interrotta. Elaborate ${i}` });
122
126
  }
123
127
  else {
124
- setWaitPanelTextPrimary(del ? SDKUI_Localizator.Delete : SDKUI_Localizator.Restore);
128
+ setLocalWaitPanelTextPrimary(del ? SDKUI_Localizator.Delete : SDKUI_Localizator.Restore);
125
129
  const workingGroupEngine = new WorkingGroupEngine(SDK_Globals.tmSession);
126
130
  await workingGroupEngine.BlogPostDeleteOrUndeleteAsync(currentWorkingGroup.id, focusedBlog.id, del)
127
131
  .then(() => {
128
132
  result.push({ rowIndex: 1, id1: currentWorkingGroup.id, id2: 0, description: SDKUI_Localizator.UpdateCompletedSuccessfully, resultType: ResultTypes.SUCCESS });
129
133
  TMResultManager.show(result, del ? SDKUI_Localizator.Delete : SDKUI_Localizator.Restore, "ID", undefined);
130
- setFocusedBlog(undefined);
134
+ handleFocusedBlog(undefined);
131
135
  refresh();
132
136
  })
133
137
  .catch((err) => {
134
138
  result.push({ rowIndex: 1, id1: currentWorkingGroup.id, id2: currentWorkingGroup.id, resultType: ResultTypes.ERROR, description: getExceptionMessage(err) });
135
139
  });
136
140
  }
137
- setWaitPanelTextPrimary('');
138
- setWaitPanelMaxValuePrimary(0);
139
- setWaitPanelValuePrimary(0);
140
- setShowWaitPanel(false);
141
+ setLocalWaitPanelTextPrimary('');
142
+ setLocalWaitPanelMaxValuePrimary(0);
143
+ setLocalWaitPanelValuePrimary(0);
144
+ setLocalShowWaitPanel(false);
141
145
  TMResultManager.show(result, del ? SDKUI_Localizator.Delete : SDKUI_Localizator.Restore, "ID", undefined);
142
146
  }
143
147
  });
144
148
  };
149
+ const handleFocusedAttachment = (attachment) => {
150
+ setFocusedAttachment(attachment);
151
+ };
152
+ const handleFocusedBlog = (blog) => {
153
+ setFocusedBlog(blog);
154
+ setFocusedAttachment(undefined);
155
+ };
145
156
  const refresh = () => {
146
157
  if (refreshCallback)
147
158
  refreshCallback();
148
159
  };
160
+ const downloadAttachment = () => {
161
+ if (focusedAttachment === undefined)
162
+ return;
163
+ if (downloadDcmtsAsync)
164
+ downloadDcmtsAsync([{ TID: focusedAttachment.TID, DID: focusedAttachment.DID, fileName: focusedAttachment.fileName }], DownloadTypes.Dcmt);
165
+ };
149
166
  // ContexMenuItems array contains a list of context menu items for a blog
150
167
  const contextMenuItems = useMemo(() => {
151
168
  let menuItemsElements = [
152
- {
153
- icon: isHeaderHidden ? 'eyeopen' : 'eyeclose',
154
- text: isHeaderHidden ? SDKUI_Localizator.ShowFilters : SDKUI_Localizator.HideFilters,
155
- visible: contextMenuParams.isShowHideFilterEnabled,
156
- onClick: toggleHeaderClick,
157
- disabled: false,
158
- },
159
- {
160
- icon: localShowId ? 'eyeclose' : 'eyeopen',
161
- onClick: () => setLocalShowId(prevShowId => !prevShowId),
162
- text: localShowId ? SDKUI_Localizator.ID_Hide : SDKUI_Localizator.ID_Show,
163
- visible: contextMenuParams.isShowHideIDEnaled,
164
- disabled: false,
165
- },
166
169
  {
167
170
  icon: "chat",
168
171
  text: SDKUI_Localizator.Comment,
@@ -170,7 +173,13 @@ const TMBlogs = (props) => {
170
173
  disabled: false,
171
174
  onClick: () => { if (showCommentFormCallback)
172
175
  showCommentFormCallback(); },
173
- beginGroup: true
176
+ },
177
+ {
178
+ icon: "download",
179
+ text: 'Download',
180
+ visible: contextMenuParams.isDownloadAttachmentEnabled && focusedAttachment !== undefined,
181
+ disabled: focusedAttachment === undefined,
182
+ onClick: downloadAttachment,
174
183
  },
175
184
  {
176
185
  icon: "trash",
@@ -178,6 +187,7 @@ const TMBlogs = (props) => {
178
187
  visible: contextMenuParams.isDeleteEnabled,
179
188
  onClick: () => deleteOrUndeleteCommentCallback(true),
180
189
  disabled: focusedBlog?.ownerID !== SDK_Globals.tmSession?.SessionDescr?.userID || focusedBlog === undefined || (focusedBlog && (focusedBlog.isDel !== undefined && focusedBlog.isDel !== 0)),
190
+ beginGroup: true
181
191
  },
182
192
  {
183
193
  icon: "undo",
@@ -195,6 +205,21 @@ const TMBlogs = (props) => {
195
205
  disabled: false,
196
206
  beginGroup: true
197
207
  },
208
+ {
209
+ icon: isHeaderHidden ? 'eyeopen' : 'eyeclose',
210
+ text: isHeaderHidden ? SDKUI_Localizator.ShowFilters : SDKUI_Localizator.HideFilters,
211
+ visible: contextMenuParams.isShowHideFilterEnabled,
212
+ onClick: toggleHeaderClick,
213
+ disabled: false,
214
+ beginGroup: true
215
+ },
216
+ {
217
+ icon: localShowId ? 'eyeclose' : 'eyeopen',
218
+ onClick: () => setLocalShowId(prevShowId => !prevShowId),
219
+ text: localShowId ? SDKUI_Localizator.ID_Hide : SDKUI_Localizator.ID_Show,
220
+ visible: contextMenuParams.isShowHideIDEnaled,
221
+ disabled: false,
222
+ },
198
223
  {
199
224
  icon: "refresh",
200
225
  text: SDKUI_Localizator.Refresh,
@@ -205,7 +230,7 @@ const TMBlogs = (props) => {
205
230
  },
206
231
  ];
207
232
  return menuItemsElements;
208
- }, [isHeaderHidden, localShowId, setLocalShowId, focusedBlog]);
233
+ }, [isHeaderHidden, localShowId, setLocalShowId, focusedBlog, focusedAttachment]);
209
234
  useEffect(() => {
210
235
  if (currentWorkingGroup === undefined)
211
236
  setNewPostCount(0);
@@ -317,7 +342,7 @@ const TMBlogs = (props) => {
317
342
  // Update the state with the filtered and limited list of blogs
318
343
  setBlogPosts(filteredBlogs);
319
344
  if (focusedBlog && focusedBlog.id && filteredBlogs.find(filteredBlog => focusedBlog.id === filteredBlog.id) === undefined)
320
- setFocusedBlog(undefined);
345
+ handleFocusedBlog(undefined);
321
346
  }, [allData, appliedGlobalFilters, searchText, postsToShow, currentHeader]);
322
347
  useEffect(() => {
323
348
  if (viewMode)
@@ -334,7 +359,6 @@ const TMBlogs = (props) => {
334
359
  }, [focusedBlog]);
335
360
  const ThumbnailView = () => {
336
361
  const scrollRef = useRef(null);
337
- const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync } = useDcmtOperations();
338
362
  useEffect(() => {
339
363
  if (focusedBlog && focusedBlog.id) { // containerRef.current
340
364
  const focusedElement = document.getElementById(focusedBlog.id.toString());
@@ -350,7 +374,7 @@ const TMBlogs = (props) => {
350
374
  }, [blogPosts, viewMode, focusedBlog]);
351
375
  const attachmentDetails = (attachments, isSelected) => {
352
376
  return _jsx("div", { style: { marginTop: "10px", overflow: "hidden" }, children: attachments.map(attachment => {
353
- return AttachmentElement(attachment, treeFs, draftLatestInfoMap, archivedDocumentMap, dcmtTypeDescriptors, isSelected, searchText, color, handleClickAttachmentFolderFileCallback, downloadDcmtsAsync);
377
+ return AttachmentElement(attachment, treeFs, draftLatestInfoMap, archivedDocumentMap, dcmtTypeDescriptors, isSelected, searchText, color, downloadDcmtsAsync, handleFocusedAttachment, setAnchorEl, contextMenuRef);
354
378
  }) });
355
379
  };
356
380
  return _jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, showWaitPanelSecondary: showSecondary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, waitPanelTextSecondary: waitPanelTextSecondary, waitPanelValueSecondary: waitPanelValueSecondary, waitPanelMaxValueSecondary: waitPanelMaxValueSecondary, isCancelable: true, abortController: abortController, children: _jsx("div", { ref: scrollRef, style: { backgroundColor: "rgba(191, 191, 191, 0.15)", height: "100%", padding: "5px", overflowY: "auto", width: "100%" }, children: blogPosts.length === 0 ?
@@ -383,14 +407,14 @@ const TMBlogs = (props) => {
383
407
  handleNavigateToWGs(id);
384
408
  };
385
409
  const onClickCallback = () => {
386
- setFocusedBlog(blogPost);
410
+ handleFocusedBlog(blogPost);
387
411
  };
388
412
  const handleKeyDown = (event) => {
389
413
  event.preventDefault();
390
414
  if (event.key === 'ArrowDown' && focusedBlog) {
391
415
  const currentIndex = blogPosts.findIndex(post => post.id === focusedBlog.id);
392
416
  if (blogPosts[currentIndex + 1]) {
393
- setFocusedBlog(blogPosts[currentIndex + 1]);
417
+ handleFocusedBlog(blogPosts[currentIndex + 1]);
394
418
  }
395
419
  ;
396
420
  }
@@ -400,12 +424,17 @@ const TMBlogs = (props) => {
400
424
  if (event.key === 'ArrowUp' && focusedBlog) {
401
425
  const currentIndex = blogPosts.findIndex(post => post.id === focusedBlog.id);
402
426
  if (blogPosts[currentIndex - 1]) {
403
- setFocusedBlog(blogPosts[currentIndex - 1]);
427
+ handleFocusedBlog(blogPosts[currentIndex - 1]);
404
428
  }
405
429
  ;
406
430
  }
407
431
  };
408
- return (_jsxs(BlogPostContainer, { id: id + "-" + blogPost.id.toString(), ref: containerRef, "$color": textColor, "$textDecoration": blogPost.isDel ? 'line-through' : 'none', "$backgroundColor": bgColor, "$isNew": Boolean(blogPost.newPosts ?? 0) || isNew, "$canNavigate": canNavigate(), onClick: onClickCallback, onDoubleClick: headerClickCallback, tabIndex: 0, onKeyDown: handleKeyDown, onKeyUp: handleKeyUp, children: [_jsxs("div", { style: { display: "flex", alignItems: "center" }, children: [OwnerInitialsBadge(blogPost), _jsx("div", { style: { flex: "1 1 auto", minWidth: "0" }, children: _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: "wrap", overflow: "hidden" }, children: [_jsxs("div", { children: [_jsxs("div", { style: { fontWeight: "bold", fontSize: "13px", display: "flex", alignItems: "center" }, children: [(showIconHeader && (blogPost.header && blogPost.classID))
432
+ const onContextMenu = (e) => {
433
+ e.preventDefault();
434
+ setAnchorEl(e.currentTarget);
435
+ handleFocusedAttachment(undefined);
436
+ };
437
+ return (_jsxs(BlogPostContainer, { id: id + "-" + blogPost.id.toString(), ref: containerRef, "$color": textColor, "$textDecoration": blogPost.isDel ? 'line-through' : 'none', "$backgroundColor": bgColor, "$isNew": Boolean(blogPost.newPosts ?? 0) || isNew, "$canNavigate": canNavigate(), onClick: onClickCallback, onDoubleClick: headerClickCallback, tabIndex: 0, onKeyDown: handleKeyDown, onKeyUp: handleKeyUp, onContextMenu: onContextMenu, children: [_jsxs("div", { style: { display: "flex", alignItems: "center" }, children: [OwnerInitialsBadge(blogPost), _jsx("div", { style: { flex: "1 1 auto", minWidth: "0" }, children: _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: "wrap", overflow: "hidden" }, children: [_jsxs("div", { children: [_jsxs("div", { style: { fontWeight: "bold", fontSize: "13px", display: "flex", alignItems: "center" }, children: [(showIconHeader && (blogPost.header && blogPost.classID))
409
438
  ? (IconAndHeaderElement(blogPost, iconColor, isSelected, headerClickCallback, searchText)) :
410
439
  _jsx("span", { style: { marginLeft: showIconHeader ? "5px" : "0" }, children: highlightText(blogPost.ownerName ?? '', searchText, isSelected) }), (blogPost?.newPosts ?? 0) > 0 && (_jsx("div", { style: {
411
440
  marginLeft: "5px",
@@ -481,9 +510,9 @@ const TMBlogs = (props) => {
481
510
  const data = cellData.data;
482
511
  const { attachments } = data;
483
512
  return _jsx("div", { style: { marginTop: "10px", overflow: "hidden" }, children: (attachments && attachments.length > 0) ? attachments.map(attachment => {
484
- return AttachmentElement(attachment, treeFs, draftLatestInfoMap, archivedDocumentMap, dcmtTypeDescriptors, false, searchText, color, handleClickAttachmentFolderFileCallback, downloadDcmtsAsync);
513
+ return AttachmentElement(attachment, treeFs, draftLatestInfoMap, archivedDocumentMap, dcmtTypeDescriptors, false, searchText, color, downloadDcmtsAsync, handleFocusedAttachment, setAnchorEl, contextMenuRef);
485
514
  }) : '' });
486
- }, [treeFs, draftLatestInfoMap, dcmtTypeDescriptors, color, handleClickAttachmentFolderFileCallback, searchText]);
515
+ }, [treeFs, draftLatestInfoMap, dcmtTypeDescriptors, color, searchText]);
487
516
  const cellDatetimeRender = useCallback((cellData) => {
488
517
  const data = cellData.data;
489
518
  const { value } = cellData;
@@ -494,7 +523,7 @@ const TMBlogs = (props) => {
494
523
  // Handles focus change in the data grid
495
524
  const onFocusedRowChanged = useCallback((e) => {
496
525
  if (e.row)
497
- setFocusedBlog(e.row.data);
526
+ handleFocusedBlog(e.row.data);
498
527
  }, []);
499
528
  const onContextMenuPreparing = (e) => {
500
529
  if (e === undefined)
@@ -532,18 +561,19 @@ const TMBlogs = (props) => {
532
561
  setPostsToShow(Number(value));
533
562
  }
534
563
  };
535
- const onContextMenu = (event) => {
536
- if (event === undefined)
537
- return;
538
- event.preventDefault();
539
- setAnchorEl(event.currentTarget);
540
- setMenuItems(showContextMenu ? contextMenuItems : []);
541
- };
542
564
  // Handle closing the context menu
543
565
  const closeContextMenu = useCallback(() => {
544
566
  setAnchorEl(null);
545
567
  }, []);
546
- return _jsx("div", { style: { height: height ?? '100%', width: width ?? '100%' }, children: _jsxs(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, isCancelable: true, abortController: abortController, children: [(currentHeader && !isHeaderHidden) && (_jsx("div", { style: { display: 'block', width: '100%', overflowX: 'auto', overflowY: 'hidden', whiteSpace: 'nowrap' }, onContextMenu: e => e.preventDefault(), children: _jsx(ScrollView, { width: "100%", height: "auto", direction: "horizontal", useNative: true, children: _jsxs("div", { style: {
568
+ const onContextMenu = (event) => {
569
+ if (event === undefined)
570
+ return;
571
+ if (blogPosts.length === 0) {
572
+ event.preventDefault();
573
+ setAnchorEl(event.currentTarget);
574
+ }
575
+ };
576
+ return _jsx("div", { style: { height: height ?? '100%', width: width ?? '100%' }, children: _jsxs(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: localShowWaitPanel, showWaitPanelPrimary: localShowPrimary, waitPanelTitle: localWaitPanelTitle, waitPanelTextPrimary: localWaitPanelTextPrimary, waitPanelValuePrimary: localWaitPanelValuePrimary, waitPanelMaxValuePrimary: localWaitPanelMaxValuePrimary, isCancelable: true, abortController: localAbortController, children: [(currentHeader && !isHeaderHidden) && (_jsx("div", { style: { display: 'block', width: '100%', overflowX: 'auto', overflowY: 'hidden', whiteSpace: 'nowrap' }, onContextMenu: e => e.preventDefault(), children: _jsx(ScrollView, { width: "100%", height: "auto", direction: "horizontal", useNative: true, children: _jsxs("div", { style: {
547
577
  display: 'flex',
548
578
  flexDirection: 'row',
549
579
  gap: '8px',
@@ -561,6 +591,6 @@ const TMBlogs = (props) => {
561
591
  minWidth: isMobile ? '90px' : '120px',
562
592
  width: isMobile ? '90px' : '150px',
563
593
  height: '29px',
564
- } }))] }) }) })), _jsxs("div", { style: { height: `calc(100% - ${currentHeader && !isHeaderHidden ? '50px' : '0px'})`, width: "100%", overflow: 'auto', display: 'block' }, children: [_jsx("div", { style: { display: renderMode === 'thumbnails' ? 'block' : 'none', width: "100%", height: "100%" }, onContextMenu: onContextMenu, children: ThumbnailView() }), _jsx("div", { style: { display: renderMode === 'details' ? 'block' : 'none', width: "100%", height: "100%" }, children: DataGridView() }), anchorEl && _jsx(ContextMenu, { dataSource: menuItems, target: anchorEl, onHiding: closeContextMenu })] })] }) });
594
+ } }))] }) }) })), _jsxs("div", { style: { height: `calc(100% - ${currentHeader && !isHeaderHidden ? '50px' : '0px'})`, width: "100%", overflow: 'auto', display: 'block' }, children: [_jsx("div", { style: { display: renderMode === 'thumbnails' ? 'block' : 'none', width: "100%", height: "100%" }, onContextMenu: onContextMenu, children: ThumbnailView() }), _jsx("div", { style: { display: renderMode === 'details' ? 'block' : 'none', width: "100%", height: "100%" }, children: DataGridView() }), anchorEl && _jsx(ContextMenu, { ref: contextMenuRef, dataSource: contextMenuItems, target: anchorEl, onHiding: closeContextMenu })] })] }) });
565
595
  };
566
596
  export default TMBlogs;
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import { BlogPost, BlogPostAttachment, DcmtTypeDescriptor, HomeBlogPost } from "@topconsultnpm/sdk-ts-beta";
3
3
  import { FileItem } from '../base/TMFileManager';
4
4
  import { DcmtInfo, DownloadTypes } from '../../ts';
5
+ import { ContextMenuRef } from 'devextreme-react/cjs/context-menu';
5
6
  export declare const DRAFT_TYPE_TID = 6;
6
7
  export declare const colors: {
7
8
  DARK_BLUE: string;
@@ -72,7 +73,7 @@ export declare const AttachmentElement: (attachment: BlogPostAttachment, treeFs:
72
73
  did: number;
73
74
  fileExt: string;
74
75
  fileSize: string;
75
- }> | undefined, dcmtTypeDescriptors: Map<number, DcmtTypeDescriptor>, isSelected: boolean, searchText: string, color: string, handleClickAttachmentFolderFileCallback: ((folderId: number, draftId: number) => void) | undefined, downloadDcmtsAsync: (inputDcmts: Array<DcmtInfo> | undefined, downloadType: DownloadTypes) => Promise<void>) => import("react/jsx-runtime").JSX.Element;
76
+ }> | undefined, dcmtTypeDescriptors: Map<number, DcmtTypeDescriptor>, isSelected: boolean, searchText: string, color: string, downloadDcmtsAsync: (inputDcmts: Array<DcmtInfo> | undefined, downloadType: DownloadTypes) => Promise<void>, handleFocusedAttachment: (attachment: DcmtInfo | undefined) => void, setAnchorEl: (value: React.SetStateAction<HTMLElement | null>) => void, contextMenuRef: React.MutableRefObject<ContextMenuRef<any> | null>) => import("react/jsx-runtime").JSX.Element;
76
77
  export declare const OwnerInitialsBadge: (blogPost: BlogPost | HomeBlogPost) => import("react/jsx-runtime").JSX.Element;
77
78
  export declare const IconAndHeaderElement: (blogPost: BlogPost | HomeBlogPost, iconColor: string, isSelected: boolean, headerClickCallback: () => void, searchText: string) => import("react/jsx-runtime").JSX.Element;
78
79
  export declare const findFileItemByDraftID: (tree: FileItem | undefined, draftID: number | undefined) => FileItem | null;
@@ -130,17 +130,8 @@ export const getAttachmentInfo = (attachment, treeFs, draftLatestInfoMap, archiv
130
130
  }
131
131
  return { name, nameElement, folderId, fileExt, draftExist, archivedDocumentsExist };
132
132
  };
133
- export const AttachmentElement = (attachment, treeFs, draftLatestInfoMap, archivedDocumentMap, dcmtTypeDescriptors, isSelected, searchText, color, handleClickAttachmentFolderFileCallback, downloadDcmtsAsync) => {
133
+ export const AttachmentElement = (attachment, treeFs, draftLatestInfoMap, archivedDocumentMap, dcmtTypeDescriptors, isSelected, searchText, color, downloadDcmtsAsync, handleFocusedAttachment, setAnchorEl, contextMenuRef) => {
134
134
  const { name, nameElement, folderId, fileExt, draftExist } = getAttachmentInfo(attachment, treeFs, draftLatestInfoMap, archivedDocumentMap, dcmtTypeDescriptors, isSelected, searchText, color);
135
- const onClickCallback = (e) => {
136
- e.preventDefault();
137
- e.stopPropagation();
138
- if (attachment.tid === DRAFT_TYPE_TID && treeFs && draftExist) {
139
- const folderIdAttachment = folderId === 0 ? -1 : folderId;
140
- if (handleClickAttachmentFolderFileCallback && attachment.draftID)
141
- handleClickAttachmentFolderFileCallback(folderIdAttachment, attachment.draftID);
142
- }
143
- };
144
135
  const onDoubleClick = (e) => {
145
136
  e.preventDefault();
146
137
  e.stopPropagation();
@@ -149,7 +140,19 @@ export const AttachmentElement = (attachment, treeFs, draftLatestInfoMap, archiv
149
140
  if (downloadDcmtsAsync)
150
141
  downloadDcmtsAsync([{ TID: attachment.tid, DID: attachment.did, fileName }], DownloadTypes.Dcmt);
151
142
  };
152
- return _jsx("div", { onClick: onClickCallback, onDoubleClick: onDoubleClick, style: {
143
+ const onContextMenu = (e) => {
144
+ const archiveID = SDK_Globals.tmSession?.SessionDescr?.archiveID;
145
+ const fileName = `${removeFileExtension(name)}_${archiveID}_${attachment.tid}_${attachment.did}.${fileExt}`;
146
+ handleFocusedAttachment({ TID: attachment.tid, DID: attachment.did, fileName });
147
+ setAnchorEl(e.currentTarget);
148
+ e.preventDefault();
149
+ e.stopPropagation();
150
+ // Slight delay to ensure state update before showing context menu
151
+ setTimeout(() => {
152
+ contextMenuRef.current?.instance()?.show();
153
+ }, 0);
154
+ };
155
+ return _jsx("div", { onDoubleClick: onDoubleClick, onContextMenu: onContextMenu, style: {
153
156
  display: 'inline-flex',
154
157
  padding: '8px 12px',
155
158
  margin: '4px',
@@ -1,2 +1,7 @@
1
- declare const SettingsAppearance: () => import("react/jsx-runtime").JSX.Element;
1
+ declare const SettingsAppearance: ({ landingPagesOptions }: {
2
+ landingPagesOptions?: {
3
+ display: string;
4
+ value: string;
5
+ }[];
6
+ }) => import("react/jsx-runtime").JSX.Element;
2
7
  export default SettingsAppearance;
@@ -1,11 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useState } from 'react';
3
- import { FontSize } from '../../utils/theme';
4
3
  import TMLayoutContainer from '../base/TMLayout';
5
4
  import TMDropDown from '../editors/TMDropDown';
6
5
  import TMCheckBox from '../editors/TMCheckBox';
7
6
  import TMButton from '../base/TMButton';
8
- import { SDKUI_Globals, SDKUI_Localizator } from '../../helper';
7
+ import { SDKUI_Globals, SDKUI_Localizator, ThemeSettings } from '../../helper';
9
8
  const fontSizes = [
10
9
  { value: "10px", display: "10px" },
11
10
  { value: "11px", display: "11px" },
@@ -19,10 +18,13 @@ const fontSizes = [
19
18
  { value: "19px", display: "19px" },
20
19
  { value: "20px", display: "20px" }
21
20
  ];
22
- const SettingsAppearance = () => {
23
- const [, forceUpdate] = useState(0); // Dummy state to force re-renders
24
- const triggerUIUpdate = () => forceUpdate((prev) => prev + 1); // Increment dummy state to re-render
25
- return (_jsxs(TMLayoutContainer, { children: [_jsx("p", { style: { fontSize: '1.h1rem', fontWeight: 'bold' }, children: 'Font' }), _jsx(TMDropDown, { label: SDKUI_Localizator.Size, dataSource: fontSizes, width: '150px', value: SDKUI_Globals.userSettings.themeSettings.fontSize, onValueChanged: (e) => {
21
+ const SettingsAppearance = ({ landingPagesOptions }) => {
22
+ const [, setForceUpdate] = useState(0); // Dummy state to force re-renders
23
+ const triggerUIUpdate = () => setForceUpdate((prev) => prev + 1); // Increment dummy state to re-render
24
+ return (_jsxs(TMLayoutContainer, { children: [landingPagesOptions && _jsx("p", { style: { fontSize: '1.h1rem', fontWeight: 'bold', marginBottom: '5px' }, children: 'Pagina iniziale' }), landingPagesOptions && _jsx(TMDropDown, { dataSource: landingPagesOptions, value: SDKUI_Globals.userSettings.landingPage, width: '250px', onValueChanged: (e) => {
25
+ SDKUI_Globals.userSettings.landingPage = e.target.value;
26
+ triggerUIUpdate();
27
+ } }), _jsx("p", { style: { fontSize: '1.h1rem', fontWeight: 'bold', marginTop: '10px' }, children: 'Font' }), _jsx(TMDropDown, { label: SDKUI_Localizator.Size, dataSource: fontSizes, width: '150px', value: SDKUI_Globals.userSettings.themeSettings.fontSize, onValueChanged: (e) => {
26
28
  let newpx = e.target.value;
27
29
  SDKUI_Globals.userSettings.themeSettings.fontSize = newpx;
28
30
  triggerUIUpdate();
@@ -36,10 +38,7 @@ const SettingsAppearance = () => {
36
38
  SDKUI_Globals.userSettings.themeSettings.gridSettings.useNativeScrollbar = newValue;
37
39
  triggerUIUpdate();
38
40
  } }), _jsx(TMButton, { elementStyle: { marginTop: '10px' }, caption: SDKUI_Localizator.Restore, showTooltip: false, onClick: () => {
39
- SDKUI_Globals.userSettings.themeSettings.fontSize = FontSize.defaultFontSizeInPixel;
40
- SDKUI_Globals.userSettings.themeSettings.gridSettings.showRowLines = 0;
41
- SDKUI_Globals.userSettings.themeSettings.gridSettings.showColumnLines = 0;
42
- SDKUI_Globals.userSettings.themeSettings.gridSettings.useNativeScrollbar = 1;
41
+ SDKUI_Globals.userSettings.themeSettings = new ThemeSettings();
43
42
  triggerUIUpdate();
44
43
  } })] }));
45
44
  };
@@ -1,12 +1,13 @@
1
1
  import { InvoiceRetrieveFormats, OrderRetrieveFormats } from "@topconsultnpm/sdk-ts-beta";
2
2
  export declare class UserSettings {
3
- userID: number | undefined;
4
3
  archiveID: string | undefined;
5
4
  landingPage: string;
6
- themeSettings: ThemeSettings;
7
- searchSettings: SearchSettings2;
5
+ userID: number | undefined;
6
+ advancedSettings: AdvancedSettings;
8
7
  archivingSettings: ArchivingSettings;
9
8
  fullTextSettings: FullTextSettings;
9
+ searchSettings: SearchSettings2;
10
+ themeSettings: ThemeSettings;
10
11
  /** Load settings from local storage or other sources */
11
12
  static LoadSettings(userID: number | undefined, archiveID: string | undefined): UserSettings;
12
13
  /** Save settings to local storage or other sources */
@@ -32,10 +33,14 @@ export declare class SearchSettings2 {
32
33
  }
33
34
  export declare class ArchivingSettings {
34
35
  mruTIDs: number[];
36
+ defaultTree: number;
35
37
  }
36
38
  export declare class FullTextSettings {
37
39
  mruTerms: string[];
38
40
  }
41
+ export declare class AdvancedSettings {
42
+ expertMode: number;
43
+ }
39
44
  export declare class SDKUI_Globals {
40
45
  static userSettings: UserSettings;
41
46
  }
@@ -2,13 +2,14 @@ import { InvoiceRetrieveFormats, LocalStorageService, OrderRetrieveFormats } fro
2
2
  import { FontSize } from "../utils/theme";
3
3
  export class UserSettings {
4
4
  constructor() {
5
- this.userID = undefined;
6
5
  this.archiveID = undefined;
7
6
  this.landingPage = '';
8
- this.themeSettings = new ThemeSettings();
9
- this.searchSettings = new SearchSettings2();
7
+ this.userID = undefined;
8
+ this.advancedSettings = new AdvancedSettings();
10
9
  this.archivingSettings = new ArchivingSettings();
11
10
  this.fullTextSettings = new FullTextSettings();
11
+ this.searchSettings = new SearchSettings2();
12
+ this.themeSettings = new ThemeSettings();
12
13
  }
13
14
  /** Load settings from local storage or other sources */
14
15
  static LoadSettings(userID, archiveID) {
@@ -62,8 +63,8 @@ export class ThemeSettings {
62
63
  }
63
64
  export class SearchSettings2 {
64
65
  constructor() {
65
- this.invoiceRetrieveFormat = InvoiceRetrieveFormats.ASW_PDF;
66
- this.orderRetrieveFormat = OrderRetrieveFormats.ER_PDF;
66
+ this.invoiceRetrieveFormat = InvoiceRetrieveFormats.ASW_HTML;
67
+ this.orderRetrieveFormat = OrderRetrieveFormats.NSO_HTML;
67
68
  this.mruTIDs = [];
68
69
  this.defaultTree = -1;
69
70
  this.previewThreshold = 500000;
@@ -75,6 +76,7 @@ export class SearchSettings2 {
75
76
  export class ArchivingSettings {
76
77
  constructor() {
77
78
  this.mruTIDs = [];
79
+ this.defaultTree = -1;
78
80
  }
79
81
  }
80
82
  export class FullTextSettings {
@@ -82,6 +84,11 @@ export class FullTextSettings {
82
84
  this.mruTerms = [];
83
85
  }
84
86
  }
87
+ export class AdvancedSettings {
88
+ constructor() {
89
+ this.expertMode = 0;
90
+ }
91
+ }
85
92
  export class SDKUI_Globals {
86
93
  }
87
94
  SDKUI_Globals.userSettings = new UserSettings();
@@ -35,8 +35,8 @@ export function useDcmtOperations() {
35
35
  abortController = new AbortController();
36
36
  const rfo = new RetrieveFileOptions();
37
37
  rfo.retrieveReason = DcmtOpers.ShowFile;
38
- rfo.invoiceRetrieveFormat = SDKUI_Globals.userSettings?.searchSettings?.invoiceRetrieveFormat;
39
- rfo.orderRetrieveFormat = SDKUI_Globals.userSettings?.searchSettings?.orderRetrieveFormat;
38
+ rfo.invoiceRetrieveFormat = SDKUI_Globals.userSettings.searchSettings.invoiceRetrieveFormat;
39
+ rfo.orderRetrieveFormat = SDKUI_Globals.userSettings.searchSettings.orderRetrieveFormat;
40
40
  let result = [];
41
41
  setWaitPanelMaxValuePrimary(inputDcmts.length);
42
42
  let firstBlock = true;
@@ -50,7 +50,7 @@ TMColors._colorHeader = "black";
50
50
  class FontSize {
51
51
  }
52
52
  FontSize.defaultFontSize = '1rem';
53
- FontSize.defaultFontSizeInPixel = '12px';
53
+ FontSize.defaultFontSizeInPixel = '13px';
54
54
  class TMMargin {
55
55
  }
56
56
  TMMargin.defultMargin = '5px';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react-beta",
3
- "version": "6.12.109",
3
+ "version": "6.12.111",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",