@topconsultnpm/sdkui-react 6.21.0-dev1.2 → 6.21.0-dev1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/lib/components/base/TMAreaManager.js +18 -3
  2. package/lib/components/base/TMPanel.js +1 -0
  3. package/lib/components/base/TMTreeView.d.ts +2 -1
  4. package/lib/components/base/TMTreeView.js +8 -3
  5. package/lib/components/choosers/TMUserChooser.js +3 -1
  6. package/lib/components/features/archive/TMArchive.js +1 -1
  7. package/lib/components/features/documents/TMDcmtForm.js +12 -8
  8. package/lib/components/features/documents/TMFileUploader.d.ts +1 -1
  9. package/lib/components/features/documents/TMFileUploader.js +3 -3
  10. package/lib/components/features/documents/TMMasterDetailDcmts.d.ts +27 -2
  11. package/lib/components/features/documents/TMMasterDetailDcmts.js +215 -20
  12. package/lib/components/features/documents/TMRelationViewer.d.ts +12 -1
  13. package/lib/components/features/documents/TMRelationViewer.js +49 -10
  14. package/lib/components/features/search/TMSavedQuerySelector.js +1 -1
  15. package/lib/components/features/search/TMSearch.d.ts +1 -0
  16. package/lib/components/features/search/TMSearch.js +2 -2
  17. package/lib/components/features/search/TMSearchResult.d.ts +1 -0
  18. package/lib/components/features/search/TMSearchResult.js +18 -4
  19. package/lib/components/features/search/TMViewHistoryDcmt.js +6 -0
  20. package/lib/components/features/workflow/diagram/DiagramItemForm.js +5 -1
  21. package/lib/components/features/workflow/diagram/WFDiagram.js +7 -1
  22. package/lib/components/features/workflow/diagram/xmlParser.js +13 -14
  23. package/lib/components/pages/TMPage.js +4 -2
  24. package/lib/components/query/TMQueryEditor.js +20 -1
  25. package/lib/helper/SDKUI_Globals.d.ts +2 -0
  26. package/lib/helper/checkinCheckoutManager.d.ts +1 -1
  27. package/lib/helper/checkinCheckoutManager.js +18 -4
  28. package/lib/hooks/useDcmtOperations.d.ts +1 -0
  29. package/lib/hooks/useDcmtOperations.js +75 -4
  30. package/lib/hooks/useDocumentOperations.d.ts +1 -0
  31. package/lib/hooks/useDocumentOperations.js +46 -12
  32. package/lib/hooks/useInputDialog.d.ts +2 -0
  33. package/lib/hooks/useInputDialog.js +34 -0
  34. package/package.json +55 -55
@@ -390,7 +390,9 @@ const TMAreaManager = (props = { selectionMode: 'multiple', isPathChooser: false
390
390
  const deleteItem = async (item) => {
391
391
  const ad = item.dataItem.dataItem;
392
392
  const aid = ad.id;
393
- const subFolder = item.parentPath === ad.name ? '' : item.parentPath.replace(ad.name + '/', '');
393
+ const subFolderOld = item.parentPath === ad.name ? '' : item.parentPath.replace(ad.name + '/', '');
394
+ const subFolder = getSubFolder(item.parentPath, ad.name);
395
+ console.log("Delete item with subfolder: ", subFolder, " old subfolder: ", subFolderOld);
394
396
  const tms = props.tmSession ?? SDK_Globals.tmSession;
395
397
  if (item.isDirectory) {
396
398
  await tms?.NewAreaEngine().DeleteFoldersAsync(aid, subFolder, [item.name]).catch((err) => { throw new FileSystemError(5, item, err.message ?? SDKUI_Localizator.GetFolderDeletionErrorMessage); });
@@ -594,16 +596,29 @@ const TMAreaManager = (props = { selectionMode: 'multiple', isPathChooser: false
594
596
  throw new FileSystemError(5, undefined, error.message ?? SDKUI_Localizator.Error);
595
597
  }
596
598
  };
599
+ const getSubFolder = (dir, startStr) => {
600
+ //Se devo controllare che inizi per il nome dell'area, se non inizia ritorno la dir così com'è (caso di file aperto da percorso completo)
601
+ if (startStr && !dir.startsWith(startStr)) {
602
+ return dir;
603
+ }
604
+ //In tutti gli altri casi rimuovo la prima cartella del percorso (che corrisponde al nome dell'area) e la restituisco come subfolder
605
+ const parts = dir.split("/");
606
+ console.log(parts);
607
+ let subFolder = parts.slice(1).join("/");
608
+ console.log(subFolder);
609
+ return subFolder;
610
+ };
597
611
  const onCurrentDirectoryChanged = (e) => {
598
612
  setCurrentRoute(e.directory.path);
599
613
  setFocusedFileSystemItem(e.directory);
614
+ console.log("Current directory changed: ", e.directory);
600
615
  if (e.directory.path === '' && e.directory.name === '')
601
616
  return;
602
617
  let ad = e.directory.dataItem.dataItem;
603
618
  if (!ad)
604
619
  return;
605
620
  let aid = ad.id;
606
- let subFolder = e.directory.path.replace(ad.name + '/', '').replace(ad.name, '');
621
+ let subFolder = getSubFolder(e.directory.path);
607
622
  setAreaFolder(getAreaPath(aid, subFolder));
608
623
  e.component.option("fileSystemProvider").getItems(e.directory).then((items) => {
609
624
  setParentDirectoryFileSystemItems(items);
@@ -728,6 +743,6 @@ const TMAreaManager = (props = { selectionMode: 'multiple', isPathChooser: false
728
743
  onItemCopied={() => setCounter(counter => counter + 1)}
729
744
  onItemDeleted={() => setCounter(counter => counter - 1)}
730
745
  onFileUploaded={() => setCounter(counter => counter + 1)} */
731
- onCurrentDirectoryChanged: onCurrentDirectoryChanged, selectionMode: props.selectionMode === 'single' ? 'single' : selectionMode, children: [_jsxs(Toolbar, { children: [_jsx(Item, { name: "showNavPane", visible: true }), _jsx(Item, { name: "create", visible: true }), _jsx(Item, { name: "upload", visible: true }), _jsx(Item, { name: "separator", location: 'after' }), _jsx(Item, { name: "switchView", visible: true }), _jsx(Item, { name: "refresh", visible: true })] }), _jsx(ContextMenu, { items: ["create", "upload", "rename", "move", "copy", "delete", "refresh", "download"] }), _jsx(Permissions, { copy: focusedFileSystemItem && focusedFileSystemItem.name !== "" && !areasRoots.has(focusedFileSystemItem.name), move: focusedFileSystemItem && focusedFileSystemItem.name !== "" && !areasRoots.has(focusedFileSystemItem.name), create: focusedFileSystemItem && focusedFileSystemItem.name !== "", upload: focusedFileSystemItem && focusedFileSystemItem.name !== "", rename: focusedFileSystemItem && focusedFileSystemItem.name !== "" && !areasRoots.has(focusedFileSystemItem.name), delete: focusedFileSystemItem && focusedFileSystemItem.name !== "" && !areasRoots.has(focusedFileSystemItem.name), download: true }), _jsx(ItemView, { children: _jsxs(Details, { children: [_jsx(Column, { dataField: "thumbnail", cssClass: 'file-thumbnail' }, "thumbnail"), _jsx(Column, { dataField: "name", caption: SDKUI_Localizator.Name }, "name"), _jsx(Column, { dataField: 'size', width: '120px', alignment: 'center', dataType: 'number', caption: SDKUI_Localizator.File_Size }, "size"), _jsx(Column, { dataField: 'dateModified', width: '160px', alignment: 'center', dataType: 'datetime', caption: SDKUI_Localizator.Date_Modified }, "dateModified")] }) }), _jsx(Notifications, { showPopup: true, showPanel: true })] }), _jsx("div", { style: { width: "100%", height: "30px", overflowY: "hidden" }, children: _jsx(TMCounterContainer, { items: counterValues }) })] }) }));
746
+ onCurrentDirectoryChanged: onCurrentDirectoryChanged, selectionMode: props.selectionMode === 'single' ? 'single' : selectionMode, children: [_jsxs(Toolbar, { children: [_jsx(Item, { name: "showNavPane", visible: true }), _jsx(Item, { name: "create", visible: true }), _jsx(Item, { name: "upload", visible: true }), _jsx(Item, { name: "separator", location: 'after' }), _jsx(Item, { name: "switchView", visible: true }), _jsx(Item, { name: "refresh", visible: true })] }), _jsx(ContextMenu, { items: ["create", "upload", "rename", "move", "copy", "delete", "refresh", "download"] }), "const primo = areasRoots.values().next().value;", _jsx(Permissions, { copy: focusedFileSystemItem && focusedFileSystemItem.name !== "" && getSubFolder(focusedFileSystemItem.path).length > 0, move: focusedFileSystemItem && focusedFileSystemItem.name !== "" && getSubFolder(focusedFileSystemItem.path).length > 0, create: focusedFileSystemItem && focusedFileSystemItem.name !== "", upload: focusedFileSystemItem && focusedFileSystemItem.name !== "", rename: focusedFileSystemItem && focusedFileSystemItem.name !== "" && getSubFolder(focusedFileSystemItem.path).length > 0, delete: focusedFileSystemItem && focusedFileSystemItem.name !== "" && getSubFolder(focusedFileSystemItem.path).length > 0, download: true }), _jsx(ItemView, { children: _jsxs(Details, { children: [_jsx(Column, { dataField: "thumbnail", cssClass: 'file-thumbnail' }, "thumbnail"), _jsx(Column, { dataField: "name", caption: SDKUI_Localizator.Name }, "name"), _jsx(Column, { dataField: 'size', width: '120px', alignment: 'center', dataType: 'number', caption: SDKUI_Localizator.File_Size }, "size"), _jsx(Column, { dataField: 'dateModified', width: '160px', alignment: 'center', dataType: 'datetime', caption: SDKUI_Localizator.Date_Modified }, "dateModified")] }) }), _jsx(Notifications, { showPopup: true, showPanel: true })] }), _jsx("div", { style: { width: "100%", height: "30px", overflowY: "hidden" }, children: _jsx(TMCounterContainer, { items: counterValues }) })] }) }));
732
747
  };
733
748
  export default TMAreaManager;
@@ -26,6 +26,7 @@ const StyledPanelContainer = styled.div `
26
26
  height: ${({ $isMaximized }) => $isMaximized ? `calc(100vh - 50px - (${Gutters.getGutters()}px * 2))` : '100%'};
27
27
  z-index: ${({ $isMaximized }) => $isMaximized ? 2000 : 'auto'};
28
28
  margin: ${({ $isMaximized }) => $isMaximized ? `${Gutters.getGutters()}px` : '0'};
29
+ outline: none;
29
30
  /* transition: all 0.2s; */
30
31
  `;
31
32
  const StyledPanelHeader = styled.div `
@@ -23,11 +23,12 @@ interface ITMTreeViewProps<T extends ITMTreeItem> {
23
23
  onNodeUpdate?: (updatedNode: T) => void;
24
24
  onDataChanged?: (items: T[]) => void;
25
25
  shouldDelayFocusOnEvent?: (node: T, event: React.MouseEvent) => boolean;
26
+ onItemContextMenu?: (item: T, e: React.MouseEvent) => void;
26
27
  autoSelectChildren?: boolean;
27
28
  itemsPerPage?: number;
28
29
  showLoadMoreButton?: boolean;
29
30
  }
30
- declare const TMTreeView: <T extends ITMTreeItem>({ dataSource, focusedItem, selectedItems, allowMultipleSelection, onDataChanged, calculateItemsForNode, itemRender, onNodeUpdate, onFocusedItemChanged, onSelectionChanged, shouldDelayFocusOnEvent, autoSelectChildren, itemsPerPage, showLoadMoreButton }: ITMTreeViewProps<T>) => import("react/jsx-runtime").JSX.Element;
31
+ declare const TMTreeView: <T extends ITMTreeItem>({ dataSource, focusedItem, selectedItems, allowMultipleSelection, onDataChanged, calculateItemsForNode, itemRender, onNodeUpdate, onFocusedItemChanged, onSelectionChanged, shouldDelayFocusOnEvent, onItemContextMenu, autoSelectChildren, itemsPerPage, showLoadMoreButton }: ITMTreeViewProps<T>) => import("react/jsx-runtime").JSX.Element;
31
32
  export default TMTreeView;
32
33
  export declare const StyledTreeNode: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
33
34
  $isSelected?: boolean;
@@ -3,7 +3,7 @@ import { useCallback, useEffect, useRef } from 'react';
3
3
  import styled from 'styled-components';
4
4
  import { IconArrowLeft, IconArrowRight, IconChevronDown, IconChevronRight, SDKUI_Localizator } from '../../helper';
5
5
  import TMButton from './TMButton';
6
- const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMultipleSelection, onDataChanged, calculateItemsForNode, itemRender, onNodeUpdate, onFocusedItemChanged, onSelectionChanged, shouldDelayFocusOnEvent, autoSelectChildren = true, itemsPerPage = 100, showLoadMoreButton = true }) => {
6
+ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMultipleSelection, onDataChanged, calculateItemsForNode, itemRender, onNodeUpdate, onFocusedItemChanged, onSelectionChanged, shouldDelayFocusOnEvent, onItemContextMenu, autoSelectChildren = true, itemsPerPage = 100, showLoadMoreButton = true }) => {
7
7
  useEffect(() => {
8
8
  const handleKeyDown = (event) => {
9
9
  if (!focusedItem)
@@ -350,8 +350,13 @@ const TMTreeView = ({ dataSource = [], focusedItem, selectedItems = [], allowMul
350
350
  if (input) {
351
351
  input.indeterminate = isIndeterminate(node);
352
352
  }
353
- } })), _jsx("div", { style: { display: 'flex', alignItems: 'center', flex: 1, minWidth: 0 }, onClick: (e) => { handleNodeClick(node, e); }, 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)));
354
- }, [handleNodeClick, handleNodeToggle, handleCheckboxChange, focusedItem, selectedItems, allowMultipleSelection, getVisibleItems, needsPagination, handlePageChange, getTotalPages]);
353
+ } })), _jsx("div", { style: { display: 'flex', alignItems: 'center', flex: 1, minWidth: 0 }, onClick: (e) => { handleNodeClick(node, e); }, onContextMenu: (e) => {
354
+ if (onItemContextMenu) {
355
+ e.preventDefault();
356
+ onItemContextMenu(node, e);
357
+ }
358
+ }, 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)));
359
+ }, [handleNodeClick, handleNodeToggle, handleCheckboxChange, focusedItem, selectedItems, allowMultipleSelection, getVisibleItems, needsPagination, handlePageChange, getTotalPages, onItemContextMenu]);
355
360
  return (_jsx("div", { style: { height: '100%', width: '100%', overflowY: 'auto', overflowX: 'hidden', padding: '0px 5px 2px 2px' }, children: renderTree(dataSource) }));
356
361
  };
357
362
  export default TMTreeView;
@@ -37,7 +37,9 @@ export const TMUserChooserForm = ({ allowMultipleSelection, columns, hideRefresh
37
37
  const dataColumns = useMemo(() => {
38
38
  return [
39
39
  { dataField: 'domain', caption: SDKUI_Localizator.Domain, dataType: 'string' },
40
- { dataField: 'name', caption: SDKUI_Localizator.UserName, dataType: 'string' }
40
+ { dataField: 'name', caption: SDKUI_Localizator.UserName, dataType: 'string' },
41
+ { dataField: 'fn', caption: SDKUI_Localizator.User_FirstName, dataType: 'string' },
42
+ { dataField: 'ln', caption: SDKUI_Localizator.User_LastName, dataType: 'string' }
41
43
  ];
42
44
  }, []);
43
45
  const getItems = async (refreshCache) => {
@@ -77,7 +77,7 @@ const TMArchive = ({ onDcmtTypeSelect = undefined, inputTID, inputFile = null, c
77
77
  if (onDcmtTypeSelect)
78
78
  onDcmtTypeSelect(tidToUse);
79
79
  passToSearch(tidToUse, outputMids);
80
- } : undefined, isSharedDcmt: isSharedArchive, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, moreInfoTasks: getMoreInfoTasksForDocument(allTasks, currentTID, currentTID === inputTID ? inputDID : undefined), openFileUploaderPdfEditor: openFileUploaderPdfEditor, onScanRequest: onScanRequest }, currentTID)
80
+ } : undefined, showBackButton: false, isSharedDcmt: isSharedArchive, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, moreInfoTasks: getMoreInfoTasksForDocument(allTasks, currentTID, currentTID === inputTID ? inputDID : undefined), openFileUploaderPdfEditor: openFileUploaderPdfEditor, onScanRequest: onScanRequest }, currentTID)
81
81
  :
82
82
  _jsx(TMPanel, { title: 'Archiviazione', allowMaximize: false, children: _jsxs(TMLayoutContainer, { gap: 30, alignItems: 'center', justifyContent: 'center', children: [_jsx(StyledToppyTextContainer, { children: _jsx(StyledToppyText, { children: SDKUI_Localizator.DcmtTypeSelect }) }), _jsx(StyledToppyImage, { src: Logo, alt: 'Toppy' })] }) }), [currentTID, deviceType, mruTIDs, inputFile, currentInputMids, enableDragDropOverlay, isSharedArchive, allTasks]);
83
83
  const allInitialPanelVisibility = {
@@ -1018,8 +1018,8 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
1018
1018
  }
1019
1019
  }, [TID, DID, triggerBlogRefresh, onRefreshBlogDatagrid]);
1020
1020
  const checkoutBadge = useMemo(() => {
1021
- const { cicoEnabled, checkoutStatus } = getDcmtCicoStatus(formData, allUsers, fromDTD);
1022
- if (!cicoEnabled || !checkoutStatus.isCheckedOut)
1021
+ const { checkoutStatus } = getDcmtCicoStatus(formData, allUsers, fromDTD);
1022
+ if (!checkoutStatus.isCheckedOut)
1023
1023
  return null;
1024
1024
  return (_jsx(Ribbon, { "$isMobile": isMobile, children: _jsx(TMTooltip, { content: checkoutStatus.editLockTooltipText, position: "right", children: _jsx("span", { children: checkoutStatus.mode === 'editMode' ? SDKUI_Localizator.CheckOut : 'Locked' }) }) }));
1025
1025
  }, [formData, fromDTD, isMobile]);
@@ -1238,7 +1238,7 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
1238
1238
  },
1239
1239
  {
1240
1240
  id: 'tmDcmtPreview',
1241
- name: SDKUI_Localizator.PreviewDocument,
1241
+ name: layoutMode === LayoutModes.Update ? SDKUI_Localizator.PreviewDocument : SDKUI_Localizator.UploadFile,
1242
1242
  contentOptions: { component: tmDcmtPreview },
1243
1243
  toolbarOptions: {
1244
1244
  icon: _jsx(IconShow, { fontSize: 24 }),
@@ -1421,8 +1421,8 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
1421
1421
  position: 'relative',
1422
1422
  overflow: 'hidden'
1423
1423
  }, children: [_jsxs("div", { style: { width: '100%', height: '100%', display: isOpenDetails || isOpenMaster ? 'none' : 'flex' }, children: [isNavigating && _jsx(Spinner, { description: SDKUI_Localizator.Loading, flat: false }), (fromDTD) && _jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: useWaitPanelLocalState ? showWaitPanelLocal : showWaitPanel, showWaitPanelPrimary: useWaitPanelLocalState ? showPrimaryLocal : showPrimary, showWaitPanelSecondary: useWaitPanelLocalState ? showSecondaryLocal : showSecondary, waitPanelTitle: useWaitPanelLocalState ? waitPanelTitleLocal : waitPanelTitle, waitPanelTextPrimary: useWaitPanelLocalState ? waitPanelTextPrimaryLocal : waitPanelTextPrimary, waitPanelValuePrimary: useWaitPanelLocalState ? waitPanelValuePrimaryLocal : waitPanelValuePrimary, waitPanelMaxValuePrimary: useWaitPanelLocalState ? waitPanelMaxValuePrimaryLocal : waitPanelMaxValuePrimary, waitPanelTextSecondary: useWaitPanelLocalState ? waitPanelTextSecondaryLocal : waitPanelTextSecondary, waitPanelValueSecondary: useWaitPanelLocalState ? waitPanelValueSecondaryLocal : waitPanelValueSecondary, waitPanelMaxValueSecondary: useWaitPanelLocalState ? waitPanelMaxValueSecondaryLocal : waitPanelMaxValueSecondary, isCancelable: useWaitPanelLocalState ? dcmtFile ? dcmtFile.size >= 1000000 : false : true, abortController: useWaitPanelLocalState ? abortControllerLocal : abortController, children: _jsxs(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showCicoWaitPanel, showWaitPanelPrimary: showCicoPrimaryProgress, waitPanelTitle: cicoWaitPanelTitle, waitPanelTextPrimary: cicoPrimaryProgressText, waitPanelValuePrimary: cicoPrimaryProgressValue, waitPanelMaxValuePrimary: cicoPrimaryProgressMax, isCancelable: true, abortController: abortControllerLocal, children: [(groupId && groupId.length > 0)
1424
- ? _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", parentId: groupId, showToolbar: showDcmtFormSidebar })
1425
- : _jsxs(TMPanelManagerWithPersistenceProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: defaultPanelDimensions, initialDimensions: defaultPanelDimensions, initialMobilePanelId: 'tmDcmtForm', isPersistenceEnabled: !isMobile ? hasSavedLayout() : false, persistPanelStates: !isMobile ? (state) => persistPanelStates(state) : undefined, persistedPanelStates: getPersistedPanelStates(), children: [_jsx(PanelDisabledStateHandler, { isWFDisabled: isWFDisabled, isSysMetadataDisabled: isSysMetadataDisabled, isBoardDisabled: isBoardDisabled, isDcmtTasksDisabled: isDcmtTasksDisabled }), _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", parentId: groupId, showToolbar: showDcmtFormSidebar })] }), isOpenDistinctValues &&
1424
+ ? _jsxs(_Fragment, { children: [_jsx(PanelDisabledStateHandler, { isWFDisabled: isWFDisabled, isSysMetadataDisabled: isSysMetadataDisabled, isBoardDisabled: isBoardDisabled, isDcmtTasksDisabled: isDcmtTasksDisabled, isPreviewDisabled: isPreviewDisabled }), _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", parentId: groupId, showToolbar: showDcmtFormSidebar })] })
1425
+ : _jsxs(TMPanelManagerWithPersistenceProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: defaultPanelDimensions, initialDimensions: defaultPanelDimensions, initialMobilePanelId: 'tmDcmtForm', isPersistenceEnabled: !isMobile ? hasSavedLayout() : false, persistPanelStates: !isMobile ? (state) => persistPanelStates(state) : undefined, persistedPanelStates: getPersistedPanelStates(), children: [_jsx(PanelDisabledStateHandler, { isWFDisabled: isWFDisabled, isSysMetadataDisabled: isSysMetadataDisabled, isBoardDisabled: isBoardDisabled, isDcmtTasksDisabled: isDcmtTasksDisabled, isPreviewDisabled: isPreviewDisabled }), _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", parentId: groupId, showToolbar: showDcmtFormSidebar })] }), isOpenDistinctValues &&
1426
1426
  _jsx(TMDistinctValues, { tid: TID, mid: focusedMetadataValue?.mid, isModal: true, showHeader: false, layoutMode: layoutMode, onClosePanelCallback: () => setIsOpenDistinctValues(false), onSelectionChanged: (e) => {
1427
1427
  if (!e)
1428
1428
  return;
@@ -1512,7 +1512,7 @@ const validateMaxLength = (mvd, value, validationItems) => {
1512
1512
  };
1513
1513
  //#endregion Validation
1514
1514
  // Synchronizes panel visibility and toolbar button disabled states when panels become disabled
1515
- const PanelDisabledStateHandler = ({ isWFDisabled, isSysMetadataDisabled, isBoardDisabled, isDcmtTasksDisabled }) => {
1515
+ const PanelDisabledStateHandler = ({ isWFDisabled, isSysMetadataDisabled, isBoardDisabled, isDcmtTasksDisabled, isPreviewDisabled }) => {
1516
1516
  const { setPanelVisibilityById, setToolbarButtonDisabled, panelVisibility } = useTMPanelManagerContext();
1517
1517
  useEffect(() => {
1518
1518
  // Aggiorna lo stato disabled del bottone toolbar
@@ -1520,6 +1520,7 @@ const PanelDisabledStateHandler = ({ isWFDisabled, isSysMetadataDisabled, isBoar
1520
1520
  setToolbarButtonDisabled('tmBlog', isBoardDisabled);
1521
1521
  setToolbarButtonDisabled('tmWF', isWFDisabled);
1522
1522
  setToolbarButtonDisabled('tmDcmtTasks', isDcmtTasksDisabled);
1523
+ setToolbarButtonDisabled('tmDcmtPreview', isPreviewDisabled);
1523
1524
  // Chiude il pannello solo se è attualmente visibile e deve essere disabilitato
1524
1525
  if (isSysMetadataDisabled && panelVisibility['tmSysMetadata']) {
1525
1526
  setPanelVisibilityById('tmSysMetadata', false);
@@ -1533,7 +1534,10 @@ const PanelDisabledStateHandler = ({ isWFDisabled, isSysMetadataDisabled, isBoar
1533
1534
  if (isDcmtTasksDisabled && panelVisibility['tmDcmtTasks']) {
1534
1535
  setPanelVisibilityById('tmDcmtTasks', false);
1535
1536
  }
1536
- }, [isSysMetadataDisabled, isBoardDisabled, isWFDisabled, isDcmtTasksDisabled, setPanelVisibilityById, setToolbarButtonDisabled, panelVisibility]);
1537
+ if (isPreviewDisabled && panelVisibility['tmDcmtPreview']) {
1538
+ setPanelVisibilityById('tmDcmtPreview', false);
1539
+ }
1540
+ }, [isSysMetadataDisabled, isBoardDisabled, isWFDisabled, isDcmtTasksDisabled, isPreviewDisabled, setPanelVisibilityById, setToolbarButtonDisabled, panelVisibility]);
1537
1541
  return null;
1538
1542
  };
1539
1543
  const TMDcmtPreviewWrapper = ({ refreshPreviewTrigger, fromDTD, currentDcmt, layoutMode, dcmtFile, deviceType, isVisible, onFileUpload, openFileUploaderPdfEditor, enableDragDropOverlay = false, onScanRequest }) => {
@@ -1541,7 +1545,7 @@ const TMDcmtPreviewWrapper = ({ refreshPreviewTrigger, fromDTD, currentDcmt, lay
1541
1545
  const isMobile = deviceType === DeviceType.MOBILE;
1542
1546
  return (layoutMode === LayoutModes.Update ?
1543
1547
  _jsx(TMDcmtPreview, { dcmtData: currentDcmt, isVisible: isVisible, onClosePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => setPanelVisibilityById('tmDcmtPreview', false) : undefined, allowMaximize: !isMobile && countVisibleLeafPanels() > 1, onMaximizePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => toggleMaximize("tmDcmtPreview") : undefined, isResizingActive: isResizingActive }, refreshPreviewTrigger) :
1544
- _jsx(TMFileUploader, { fromDTD: fromDTD, onFileUpload: onFileUpload, openPdfEditor: openFileUploaderPdfEditor, onClose: (!isMobile && countVisibleLeafPanels() > 1) ? () => setPanelVisibilityById('tmDcmtPreview', false) : undefined, isRequired: fromDTD?.archiveConstraint === ArchiveConstraints.ContentCompulsory && dcmtFile === null, defaultBlob: dcmtFile, deviceType: deviceType, isResizingActive: isResizingActive, enableDragDropOverlay: panelVisibility['tmDcmtPreview'] && enableDragDropOverlay, onScanRequest: onScanRequest }));
1548
+ _jsx(TMFileUploader, { fromDTD: fromDTD, onFileUpload: onFileUpload, openFileUploaderPdfEditor: openFileUploaderPdfEditor, onClose: (!isMobile && countVisibleLeafPanels() > 1) ? () => setPanelVisibilityById('tmDcmtPreview', false) : undefined, isRequired: fromDTD?.archiveConstraint === ArchiveConstraints.ContentCompulsory && dcmtFile === null, defaultBlob: dcmtFile, deviceType: deviceType, isResizingActive: isResizingActive, enableDragDropOverlay: panelVisibility['tmDcmtPreview'] && enableDragDropOverlay, onScanRequest: onScanRequest }));
1545
1549
  };
1546
1550
  const Ribbon = styled.div `
1547
1551
  font-size: 0.85rem;
@@ -4,7 +4,7 @@ import { DcmtTypeDescriptor } from '@topconsultnpm/sdk-ts';
4
4
  interface ITMFileUploader {
5
5
  fromDTD?: DcmtTypeDescriptor;
6
6
  onFileUpload?: (file: File | null) => void;
7
- openPdfEditor?: (fromDTD?: DcmtTypeDescriptor, file?: File | null, handleFile?: (file: File) => void) => void;
7
+ openFileUploaderPdfEditor?: (fromDTD?: DcmtTypeDescriptor, file?: File | null, handleFile?: (file: File) => void) => void;
8
8
  onClose?: () => void;
9
9
  onScanRequest?: (onFileScanned: (file: File) => void) => void;
10
10
  isRequired?: boolean;
@@ -23,7 +23,7 @@ const isScannerLicenseConfigured = () => {
23
23
  return false;
24
24
  }
25
25
  };
26
- const TMFileUploader = ({ fromDTD, deviceType = DeviceType.DESKTOP, onClose, onFileUpload, openPdfEditor, onScanRequest, isRequired = false, defaultBlob = null, isResizingActive, showTMPanel = true, enableDragDropOverlay = false, showScannerIcon = true }) => {
26
+ const TMFileUploader = ({ fromDTD, deviceType = DeviceType.DESKTOP, onClose, onFileUpload, openFileUploaderPdfEditor, onScanRequest, isRequired = false, defaultBlob = null, isResizingActive, showTMPanel = true, enableDragDropOverlay = false, showScannerIcon = true }) => {
27
27
  const isBetaFeaturesEnabled = useBetaFeatures();
28
28
  const [dragOver, setDragOver] = useState(false);
29
29
  const [uploadedFile, setUploadedFile] = useState(defaultBlob);
@@ -101,11 +101,11 @@ const TMFileUploader = ({ fromDTD, deviceType = DeviceType.DESKTOP, onClose, onF
101
101
  _jsx("div", { style: { backgroundColor: '#f6dbdb', padding: '5px 10px', borderRadius: 8, display: 'flex', alignItems: 'center', justifyContent: 'space-between', color: TMColors.error }, children: _jsxs("div", { children: [" ", 'Anteprima non disponibile.', fileExt && _jsx("b", { children: ` (*.${fileExt})` })] }) })] });
102
102
  const innerContent = (_jsxs("div", { style: { width: '100%', height: '100%', padding: '2px', display: 'flex', flexDirection: 'column', gap: 10 }, children: [enableDragDropOverlay && _jsx(TMDragDropOverlay, { handleFile: handleFile, refocusAfterFileInput: refocusAfterFileInput }), content] }));
103
103
  const toolbar = useMemo(() => {
104
- return (_jsxs(_Fragment, { children: [(isPdfEditorAvailable(fromDTD, fileExt) && openPdfEditor) && (_jsx(TMCommandsContextMenu, { target: "#TMPanel-FileUploader-Commands-Header", menuItems: [
104
+ return (_jsxs(_Fragment, { children: [(isPdfEditorAvailable(fromDTD, fileExt) && openFileUploaderPdfEditor) && (_jsx(TMCommandsContextMenu, { target: "#TMPanel-FileUploader-Commands-Header", menuItems: [
105
105
  {
106
106
  icon: _jsx(IconEdit, {}),
107
107
  text: 'PDF Editor',
108
- onClick: () => openPdfEditor(fromDTD, uploadedFile, handleFile)
108
+ onClick: () => openFileUploaderPdfEditor(fromDTD, uploadedFile, handleFile)
109
109
  }
110
110
  ], showEvent: "click", children: _jsx(IconMenuVertical, { id: "TMPanel-FileUploader-Commands-Header", color: "white", cursor: "pointer" }) })), deviceType !== DeviceType.MOBILE && (_jsx(StyledHeaderIcon, { onClick: onClose, "$color": "white", children: _jsx(TMTooltip, { content: SDKUI_Localizator.Close, children: _jsx(IconCloseOutline, {}) }) }))] }));
111
111
  }, [deviceType, fromDTD, onClose]);
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
- import { HomeBlogPost, TaskDescriptor } from '@topconsultnpm/sdk-ts';
3
- import { DcmtInfo, TaskContext } from '../../../ts';
2
+ import { HomeBlogPost, SearchResultDescriptor, TaskDescriptor } from '@topconsultnpm/sdk-ts';
3
+ import { DcmtInfo, TaskContext, MetadataValueDescriptorEx } from '../../../ts';
4
4
  import { DeviceContextProps } from '../../base/TMDeviceProvider';
5
5
  interface ITMMasterDetailDcmtsProps extends DeviceContextProps {
6
6
  allTasks?: Array<TaskDescriptor>;
@@ -21,6 +21,31 @@ interface ITMMasterDetailDcmtsProps extends DeviceContextProps {
21
21
  onBack?: () => void;
22
22
  appendMasterDcmts?: (tid: number | undefined, did: number | undefined) => void;
23
23
  onTaskCreateRequest?: (taskContext: TaskContext, onTaskCreated?: (task?: TaskDescriptor) => void) => void;
24
+ onRefreshAfterAddDcmtToFavs?: () => void;
25
+ editPdfForm?: boolean;
26
+ openS4TViewer?: boolean;
27
+ onOpenS4TViewerRequest?: (dcmtInfo: Array<DcmtInfo>, refreshDocumentPreview?: (() => Promise<void>)) => void;
28
+ onOpenPdfEditorRequest?: ((dcmtInfo: Array<DcmtInfo>, refreshDocumentPreview?: () => Promise<void>) => void);
29
+ datagridUtility?: {
30
+ onRefreshSearchAsyncDatagrid?: () => Promise<void>;
31
+ onRefreshDataRowsAsync?: (() => Promise<void>);
32
+ refreshFocusedDataRowAsync?: (tid: number | undefined, did: number | undefined, refreshUI?: boolean, metadataResult?: SearchResultDescriptor | null) => Promise<void>;
33
+ onRefreshBlogDatagrid?: () => Promise<void>;
34
+ onRefreshPreviewDatagrid?: () => Promise<void>;
35
+ };
36
+ dcmtUtility?: {
37
+ approvalVID?: number;
38
+ dcmtDataRowForCicoStatus?: Array<MetadataValueDescriptorEx> | any;
39
+ selectedDcmtSearchResultRelations?: SearchResultDescriptor;
40
+ dcmtTIDHasDetailRelations?: boolean;
41
+ dcmtTIDHasMasterRelations?: boolean;
42
+ updateCurrentDcmt?: () => Promise<void>;
43
+ onCloseDcmtForm?: () => void;
44
+ onRefreshBlogForm?: () => Promise<void>;
45
+ onRefreshPreviewForm?: () => Promise<void>;
46
+ taskFormDialogComponent?: React.ReactNode;
47
+ s4TViewerDialogComponent?: React.ReactNode;
48
+ };
24
49
  }
25
50
  declare const TMMasterDetailDcmts: React.FC<ITMMasterDetailDcmtsProps>;
26
51
  export default TMMasterDetailDcmts;
@@ -1,9 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useCallback, useEffect, useMemo, useState } from 'react';
3
- import { DcmtTypeListCacheService, SDK_Localizator } from '@topconsultnpm/sdk-ts';
2
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
+ import { DcmtTypeListCacheService, LayoutModes, SDK_Globals, SDK_Localizator } from '@topconsultnpm/sdk-ts';
4
4
  import TMRelationViewer from './TMRelationViewer';
5
5
  import TMContextMenu from '../../NewComponents/ContextMenu/TMContextMenu';
6
- import { IconMultipleSelection, IconCheckFile, IconDetailDcmts, SDKUI_Localizator, IconMenuVertical, IconDataList, IconPreview, IconSearchCheck, IconBoard, IconDcmtTypeSys, IconShow, getMoreInfoTasksForDocument } from '../../../helper';
6
+ import { IconMultipleSelection, IconCheckFile, IconDetailDcmts, SDKUI_Localizator, IconMenuVertical, IconDataList, IconPreview, IconSearchCheck, IconBoard, IconDcmtTypeSys, IconShow, getMoreInfoTasksForDocument, isApprovalWorkflowView, searchResultToMetadataValues, IconRefresh } from '../../../helper';
7
7
  import { FormModes, SearchResultContext } from '../../../ts';
8
8
  import { TMColors } from '../../../utils/theme';
9
9
  import ShowAlert from '../../base/TMAlert';
@@ -14,8 +14,10 @@ import { TMPanelManagerProvider, useTMPanelManagerContext } from '../../layout/p
14
14
  import TMSearchResult from '../search/TMSearchResult';
15
15
  import TMDcmtForm from './TMDcmtForm';
16
16
  import { TMNothingToShow } from './TMDcmtPreview';
17
- import { Spinner } from '../..';
18
- const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, deviceType, inputDcmts, isForMaster, showCurrentDcmtIndicator = true, allowNavigation, canNext, canPrev, onNext, onPrev, onBack, appendMasterDcmts, onTaskCreateRequest }) => {
17
+ import { Spinner, TMButton } from '../..';
18
+ import { useDocumentOperations } from '../../../hooks/useDocumentOperations';
19
+ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, deviceType, inputDcmts, isForMaster, showCurrentDcmtIndicator = true, allowNavigation, canNext, canPrev, onNext, onPrev, onBack, appendMasterDcmts, onTaskCreateRequest, onRefreshAfterAddDcmtToFavs, editPdfForm, openS4TViewer, onOpenS4TViewerRequest, onOpenPdfEditorRequest, datagridUtility, dcmtUtility }) => {
20
+ const floatingBarContainerRef = useRef(null);
19
21
  const [focusedItem, setFocusedItem] = useState();
20
22
  const [selectedItems, setSelectedItems] = useState([]);
21
23
  const [showZeroDcmts, setShowZeroDcmts] = useState(false);
@@ -23,6 +25,174 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
23
25
  const [dtdMaster, setDtdMaster] = useState();
24
26
  const [noRelationsOnFirstLoad, setNoRelationsOnFirstLoad] = useState(false);
25
27
  const [isCheckingFirstLoad, setIsCheckingFirstLoad] = useState(true);
28
+ const [contextMenuVisible, setContextMenuVisible] = useState(false);
29
+ const [contextMenuPosition, setContextMenuPosition] = useState({ x: 0, y: 0 });
30
+ const [dtdFocused, setDtdFocused] = useState();
31
+ const [refreshKey, setRefreshKey] = useState(0);
32
+ // Separate refresh key for TMFormOrResultWrapper only (doesn't affect tmTreeView)
33
+ const [refreshKeyFormOrResult, setRefreshKeyFormOrResult] = useState(0);
34
+ /** State for transformed focusedItem metadata values (similar to formData in TMDcmtForm) */
35
+ const [focusedItemFormData, setFocusedItemFormData] = useState([]);
36
+ // Trigger operationItems refresh (after file substitution, etc.)
37
+ const [refreshOperationsTrigger, setRefreshOperationsTrigger] = useState(0);
38
+ // Increments trigger counter to force operationItems to re-calculate
39
+ const onRefreshOperationsDatagrid = useCallback(async () => {
40
+ setRefreshOperationsTrigger(prev => prev + 1);
41
+ }, []);
42
+ // Refresh ALL panels (tree view + search results) with fade-out -> update -> fade-in transition
43
+ const onRefreshAllPanels = async () => {
44
+ await dcmtUtility?.onRefreshPreviewForm?.(); // Refresh preview form data
45
+ setFocusedItem(undefined); // Clear focused item to avoid stale references
46
+ setTimeout(async () => {
47
+ setRefreshKey(prev => prev + 1); // Force re-render of tmTreeView
48
+ setRefreshKeyFormOrResult(prev => prev + 1); // Force re-render of TMFormOrResultWrapper
49
+ await onRefreshOperationsDatagrid(); // Refresh operation items
50
+ }, 200); // Wait for fade-out animation
51
+ };
52
+ useEffect(() => {
53
+ const fetchFocusedItemMetadata = async () => {
54
+ if (!focusedItem?.tid || !focusedItem?.did) {
55
+ setFocusedItemFormData([]);
56
+ return;
57
+ }
58
+ try {
59
+ const tid = focusedItem?.tid;
60
+ const did = focusedItem?.did;
61
+ const metadata = await SDK_Globals.tmSession?.NewSearchEngine().GetMetadataAsync(tid, did, true);
62
+ // Transform metadata to MetadataValueDescriptorEx[] (similar to setMetadataList in TMDcmtForm)
63
+ if (metadata) {
64
+ const dtdResult = metadata.dtdResult;
65
+ const rows = dtdResult?.rows ? dtdResult.rows[0] : [];
66
+ const mids = metadata.selectMIDs;
67
+ // Get DTD with metadata descriptors
68
+ const dtdWithMetadata = await DcmtTypeListCacheService.GetWithNotGrantedAsync(tid, did, metadata);
69
+ const mdList = dtdWithMetadata?.metadata ?? [];
70
+ const metadataList = searchResultToMetadataValues(tid, dtdResult, rows, mids, mdList, LayoutModes.Update);
71
+ setFocusedItemFormData(structuredClone(metadataList));
72
+ }
73
+ }
74
+ catch (error) {
75
+ console.error('Error fetching focusedItem metadata:', error);
76
+ setFocusedItemFormData([]);
77
+ }
78
+ };
79
+ fetchFocusedItemMetadata();
80
+ }, [focusedItem?.tid, focusedItem?.did, refreshOperationsTrigger]);
81
+ // Load dtdFocused when focusedItem changes
82
+ useEffect(() => {
83
+ const loadDtdFocused = async () => {
84
+ if (!focusedItem?.tid) {
85
+ setDtdFocused(undefined);
86
+ return;
87
+ }
88
+ const dtd = await DcmtTypeListCacheService.GetAsync(focusedItem.tid);
89
+ setDtdFocused(dtd);
90
+ };
91
+ loadDtdFocused();
92
+ }, [focusedItem?.tid]);
93
+ const openTaskFormHandler = (onTaskCreated) => {
94
+ if (selectedItems.length > 1)
95
+ return;
96
+ const item = selectedItems.length === 1 ? selectedItems[0] : focusedItem;
97
+ if (item && item.tid && item.did) {
98
+ const createTaskFromDocumentOrWorkItem = async () => {
99
+ try {
100
+ const dtd = await DcmtTypeListCacheService.GetWithNotGrantedAsync(item.tid, item?.did);
101
+ if (dtd) {
102
+ const isWorkItem = isApprovalWorkflowView(dtd);
103
+ if (item.tid === undefined || item.did === undefined) {
104
+ console.error("TID or DID is undefined for the selected item.");
105
+ return;
106
+ }
107
+ const name = `${dtd.name ?? '-'} (DID: ${item.did})`;
108
+ onTaskCreateRequest?.(isWorkItem
109
+ ? { workItem: { tid: item.tid, did: item.did, name } }
110
+ : { document: { tid: item.tid, did: item.did, name } }, onTaskCreated);
111
+ }
112
+ }
113
+ catch (error) {
114
+ console.error("Error fetching data:", error);
115
+ }
116
+ };
117
+ createTaskFromDocumentOrWorkItem();
118
+ }
119
+ };
120
+ const { operationItems, renderFloatingBar, renderDcmtOperations, features } = useDocumentOperations({
121
+ context: SearchResultContext.MASTER_DETAIL,
122
+ documentData: {
123
+ dtd: dtdFocused,
124
+ selectedItems: selectedItems ? selectedItems.map(item => ({ TID: item.tid, DID: item.did, FILEEXT: item.fileExt })) : [],
125
+ focusedItem: focusedItem ? { TID: focusedItem.tid, DID: focusedItem.did, FILEEXT: focusedItem.fileExt } : undefined,
126
+ currentSearchResults: [],
127
+ currentMetadataValues: [],
128
+ allUsers: [],
129
+ // searchResult: selectedSearchResult,
130
+ datagridUtility: {
131
+ visibleItems: [],
132
+ onRefreshSearchAsyncDatagrid: onRefreshAllPanels,
133
+ onRefreshDataRowsAsync: onRefreshAllPanels,
134
+ refreshFocusedDataRowAsync: onRefreshAllPanels,
135
+ onRefreshBlogDatagrid: onRefreshAllPanels,
136
+ onRefreshPreviewDatagrid: onRefreshAllPanels,
137
+ refreshOperationsTrigger,
138
+ onRefreshOperationsDatagrid,
139
+ },
140
+ dcmtUtility: {
141
+ approvalVID: dcmtUtility?.approvalVID,
142
+ dcmtDataRowForCicoStatus: focusedItemFormData, // Passa i metadata trasformati del focusedItem per le operazioni di CICO
143
+ selectedDcmtSearchResultRelations: dcmtUtility?.selectedDcmtSearchResultRelations,
144
+ dcmtTIDHasDetailRelations: dcmtUtility?.dcmtTIDHasDetailRelations,
145
+ dcmtTIDHasMasterRelations: dcmtUtility?.dcmtTIDHasMasterRelations,
146
+ updateCurrentDcmt: onRefreshAllPanels,
147
+ onCloseDcmtForm: dcmtUtility?.onCloseDcmtForm,
148
+ onRefreshBlogForm: dcmtUtility?.onRefreshBlogForm,
149
+ onRefreshPreviewForm: onRefreshAllPanels,
150
+ taskFormDialogComponent: dcmtUtility?.taskFormDialogComponent,
151
+ s4TViewerDialogComponent: dcmtUtility?.s4TViewerDialogComponent
152
+ },
153
+ },
154
+ uiConfig: {
155
+ floatingBarContainerRef,
156
+ openS4TViewer,
157
+ showDcmtFormSidebar: true,
158
+ openDcmtFormAsModal: true,
159
+ allowFloatingBar: false,
160
+ enablePinIcons: false,
161
+ allowRelations: true,
162
+ inputDcmtFormLayoutMode: LayoutModes.Update,
163
+ },
164
+ tasks: {
165
+ allTasks: allTasks,
166
+ getAllTasks: getAllTasks,
167
+ deleteTaskByIdsCallback: deleteTaskByIdsCallback,
168
+ addTaskCallback: addTaskCallback,
169
+ editTaskCallback: editTaskCallback
170
+ },
171
+ callbacks: {
172
+ // Refresh operations (data consistency)
173
+ /* onSavedAsyncCallback, */
174
+ // Workflow operations
175
+ /* onWFOperationCompleted, */
176
+ // Navigation
177
+ /* canNavigateHandler,
178
+ onNavigateHandler, */
179
+ handleNavigateToWGs,
180
+ handleNavigateToDossiers,
181
+ /* onReferenceClick, */
182
+ // Document forms/operations
183
+ /* openAddDocumentForm,
184
+ openCommentFormCallback,
185
+ onFileOpened,
186
+ passToArchiveCallback,
187
+ openWGsCopyMoveForm, */
188
+ onOpenS4TViewerRequest,
189
+ onOpenPdfEditorRequest,
190
+ // Task related
191
+ onTaskCreateRequest,
192
+ openTaskFormHandler,
193
+ onRefreshAfterAddDcmtToFavs,
194
+ },
195
+ });
26
196
  // Load dtdMaster when inputDcmts changes
27
197
  useEffect(() => {
28
198
  const loadDtdMaster = async () => {
@@ -53,6 +223,12 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
53
223
  setNoRelationsOnFirstLoad(true);
54
224
  }
55
225
  }, [isCheckingFirstLoad]);
226
+ const onItemContextMenu = useCallback((item, e) => {
227
+ if (!item.isDcmt)
228
+ return; // Show context menu only for document items
229
+ setContextMenuPosition({ x: e.clientX, y: e.clientY });
230
+ setContextMenuVisible(true);
231
+ }, []);
56
232
  // Show warning alert and navigate back when no relations found on first load
57
233
  useEffect(() => {
58
234
  if (noRelationsOnFirstLoad) {
@@ -90,17 +266,26 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
90
266
  }
91
267
  }
92
268
  ];
93
- const toolbar = _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '10px' }, children: [allowMultipleSelection && _jsx("p", { style: { color: TMColors.colorHeader, textAlign: 'center', padding: '1px 4px', borderRadius: '3px', display: 'flex' }, children: `${selectedItems.filter(item => item.isDcmt).length} selezionati` }), allowNavigation && canPrev != undefined && _jsx(TMSaveFormButtonPrevious, { btnStyle: 'icon', iconColor: 'white', isModified: false, formMode: FormModes.ReadOnly, canPrev: canPrev, onPrev: onPrev }), allowNavigation && canNext != undefined && _jsx(TMSaveFormButtonNext, { btnStyle: 'icon', iconColor: 'white', isModified: false, formMode: FormModes.ReadOnly, canNext: canNext, onNext: onNext }), _jsx(TMContextMenu, { items: commandsMenuItems, trigger: 'left', children: _jsx(IconMenuVertical, { color: 'white', cursor: 'pointer' }) })] });
269
+ const toolbar = _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '10px' }, children: [allowMultipleSelection && _jsx("p", { style: { color: TMColors.colorHeader, textAlign: 'center', padding: '1px 4px', borderRadius: '3px', display: 'flex' }, children: `${selectedItems.filter(item => item.isDcmt).length} selezionati` }), allowNavigation && canPrev != undefined && _jsx(TMSaveFormButtonPrevious, { btnStyle: 'icon', iconColor: 'white', isModified: false, formMode: FormModes.ReadOnly, canPrev: canPrev, onPrev: onPrev }), allowNavigation && canNext != undefined && _jsx(TMSaveFormButtonNext, { btnStyle: 'icon', iconColor: 'white', isModified: false, formMode: FormModes.ReadOnly, canNext: canNext, onNext: onNext }), _jsx(TMButton, { btnStyle: 'icon', icon: _jsx(IconRefresh, { color: 'white' }), caption: SDKUI_Localizator.Refresh, onClick: onRefreshAllPanels }), _jsx(TMContextMenu, { items: commandsMenuItems, trigger: 'left', children: _jsx(IconMenuVertical, { color: 'white', cursor: 'pointer' }) })] });
94
270
  const getTitle = () => isForMaster ? `${SDKUI_Localizator.DcmtsMaster} - ${dtdMaster?.nameLoc}` : SDKUI_Localizator.DcmtsDetail;
95
271
  const isMobile = deviceType === DeviceType.MOBILE;
96
272
  const tmTreeView = useMemo(() => _jsx(_Fragment, { children: !inputDcmts || inputDcmts.length === 0
97
273
  ?
98
274
  _jsx(TMNothingToShow, { text: getTitle(), secondText: SDKUI_Localizator.NoDataToDisplay, icon: isForMaster ? _jsx(IconDetailDcmts, { fontSize: 96, transform: 'scale(-1, 1)' }) : _jsx(IconDetailDcmts, { fontSize: 96 }) })
99
275
  :
100
- _jsx(TMRelationViewerWrapper, { inputDcmts: inputDcmts, isForMaster: isForMaster, showCurrentDcmtIndicator: showCurrentDcmtIndicator, showZeroDcmts: showZeroDcmts,
101
- // customItemRender={customItemRender}
102
- allowMultipleSelection: allowMultipleSelection, focusedItem: focusedItem, selectedItems: selectedItems, onFocusedItemChanged: handleFocusedItemChanged, onSelectedItemsChanged: handleSelectedItemsChanged, onNoRelationsFound: handleNoRelationsFound }) }), [inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, allowMultipleSelection, focusedItem, selectedItems, handleFocusedItemChanged, handleSelectedItemsChanged, handleNoRelationsFound]);
103
- const tmFormOrResult = useMemo(() => _jsx(TMFormOrResultWrapper, { deviceType: deviceType, focusedItem: focusedItem, onTaskCreateRequest: onTaskCreateRequest, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }), [focusedItem, deviceType, allTasks, handleNavigateToWGs, handleNavigateToDossiers]);
276
+ _jsxs("div", { ref: floatingBarContainerRef, style: { width: "100%", height: "100%" }, onContextMenu: (e) => {
277
+ // Mostra context menu anche sullo spazio bianco (quando non si clicca su un item)
278
+ e.preventDefault();
279
+ setContextMenuPosition({ x: e.clientX, y: e.clientY });
280
+ setContextMenuVisible(true);
281
+ }, children: [_jsx(TMRelationViewerWrapper, { refreshKey: refreshKey, inputDcmts: inputDcmts, isForMaster: isForMaster, showCurrentDcmtIndicator: showCurrentDcmtIndicator, showZeroDcmts: showZeroDcmts,
282
+ // customItemRender={customItemRender}
283
+ allowMultipleSelection: allowMultipleSelection, focusedItem: focusedItem, selectedItems: selectedItems, onFocusedItemChanged: handleFocusedItemChanged, onSelectedItemsChanged: handleSelectedItemsChanged, onNoRelationsFound: handleNoRelationsFound, onItemContextMenu: onItemContextMenu, focusedItemFormData: focusedItemFormData }), _jsx(TMContextMenu, { items: operationItems, externalControl: {
284
+ visible: contextMenuVisible,
285
+ position: contextMenuPosition,
286
+ onClose: () => setContextMenuVisible(false)
287
+ } })] }) }), [inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, allowMultipleSelection, focusedItem, selectedItems, handleFocusedItemChanged, handleSelectedItemsChanged, handleNoRelationsFound, onItemContextMenu, contextMenuVisible, contextMenuPosition, refreshKey, focusedItemFormData]);
288
+ const tmFormOrResult = useMemo(() => _jsx(TMFormOrResultWrapper, { refreshKey: refreshKeyFormOrResult, deviceType: deviceType, focusedItem: focusedItem, onTaskCreateRequest: onTaskCreateRequest, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, onRefreshAfterAddDcmtToFavs: onRefreshAfterAddDcmtToFavs, editPdfForm: editPdfForm, openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, onOpenPdfEditorRequest: onOpenPdfEditorRequest, onRefreshSearchResults: onRefreshAllPanels }), [focusedItem, deviceType, allTasks, handleNavigateToWGs, handleNavigateToDossiers, editPdfForm, openS4TViewer, onOpenS4TViewerRequest, onOpenPdfEditorRequest, onRefreshAfterAddDcmtToFavs, refreshKeyFormOrResult]);
104
289
  const initialPanelDimensions = {
105
290
  'tmTreeView': { width: '50%', height: '100%' },
106
291
  'tmFormOrResult': { width: '50%', height: '100%' },
@@ -177,7 +362,7 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
177
362
  toolbarOptions: { icon: _jsx(IconSearchCheck, { fontSize: 24 }), visible: false, orderNumber: 2, isActive: allInitialPanelVisibility['tmFormOrResult'] }
178
363
  }
179
364
  ], [tmTreeView, tmFormOrResult, focusedItem?.isDcmt, dtdMaster]);
180
- return (_jsxs("div", { style: { width: '100%', height: '100%', position: 'relative' }, children: [isCheckingFirstLoad && (_jsx(Spinner, { description: SDKUI_Localizator.Loading, flat: true })), _jsx("div", { style: isCheckingFirstLoad ? { position: 'absolute', width: 0, height: 0, overflow: 'hidden', opacity: 0, pointerEvents: 'none' } : { width: '100%', height: '100%' }, children: _jsx(TMPanelManagerProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: initialPanelDimensions, initialDimensions: initialPanelDimensions, initialMobilePanelId: 'tmTreeView', children: _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", showToolbar: true }) }) })] }));
365
+ return (_jsxs("div", { style: { width: '100%', height: '100%', position: 'relative' }, children: [isCheckingFirstLoad && (_jsx(Spinner, { description: SDKUI_Localizator.Loading, flat: true })), _jsxs("div", { style: isCheckingFirstLoad ? { position: 'absolute', width: 0, height: 0, overflow: 'hidden', opacity: 0, pointerEvents: 'none' } : { width: '100%', height: '100%' }, children: [_jsx(TMPanelManagerProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: initialPanelDimensions, initialDimensions: initialPanelDimensions, initialMobilePanelId: 'tmTreeView', children: _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", showToolbar: true }) }), renderDcmtOperations, renderFloatingBar] })] }));
181
366
  };
182
367
  export default TMMasterDetailDcmts;
183
368
  /**
@@ -186,7 +371,7 @@ export default TMMasterDetailDcmts;
186
371
  * - Panel visibility toggling
187
372
  * - Focus delay handling
188
373
  */
189
- const TMRelationViewerWrapper = ({ inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, customItemRender, allowMultipleSelection, focusedItem, selectedItems, onFocusedItemChanged, onSelectedItemsChanged, onNoRelationsFound }) => {
374
+ const TMRelationViewerWrapper = ({ refreshKey, inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, customItemRender, allowMultipleSelection, focusedItem, selectedItems, onFocusedItemChanged, onSelectedItemsChanged, onNoRelationsFound, onItemContextMenu, focusedItemFormData }) => {
190
375
  const { setPanelVisibilityById, setToolbarButtonVisibility } = useTMPanelManagerContext();
191
376
  // Handle focused item changes with panel visibility management
192
377
  const handleFocusedItemChanged = useCallback((item) => {
@@ -205,15 +390,25 @@ const TMRelationViewerWrapper = ({ inputDcmts, isForMaster, showCurrentDcmtIndic
205
390
  setToolbarButtonVisibility('tmDcmtForm', false);
206
391
  }
207
392
  }, [onFocusedItemChanged, setPanelVisibilityById, setToolbarButtonVisibility]);
208
- return (_jsx(TMRelationViewer, { inputDcmts: inputDcmts, isForMaster: isForMaster, showCurrentDcmtIndicator: showCurrentDcmtIndicator, initialShowZeroDcmts: showZeroDcmts, customItemRender: customItemRender, allowMultipleSelection: allowMultipleSelection, focusedItem: focusedItem, selectedItems: selectedItems, onFocusedItemChanged: handleFocusedItemChanged, onSelectedItemsChanged: onSelectedItemsChanged, maxDepthLevel: 1, invertMasterNavigation: false, onNoRelationsFound: onNoRelationsFound }));
393
+ const onContextMenu = useCallback((item, e) => {
394
+ // Ferma la propagazione per evitare che l'evento arrivi al div contenitore
395
+ // (che ha il suo handler per il context menu sullo spazio bianco)
396
+ e.stopPropagation();
397
+ handleFocusedItemChanged(item);
398
+ // Il setTimeout è necessario per permettere a React di completare il re-render
399
+ // dopo il cambio di focus (handleFocusedItemChanged aggiorna stato e visibilità pannelli).
400
+ // Senza il delay, il context menu potrebbe mostrare opzioni basate sul vecchio stato.
401
+ setTimeout(() => {
402
+ onItemContextMenu?.(item, e);
403
+ }, 100);
404
+ }, [onItemContextMenu, handleFocusedItemChanged]);
405
+ return (_jsx(TMRelationViewer, { inputDcmts: inputDcmts, isForMaster: isForMaster, showCurrentDcmtIndicator: showCurrentDcmtIndicator, initialShowZeroDcmts: showZeroDcmts, customItemRender: customItemRender, allowMultipleSelection: allowMultipleSelection, focusedItem: focusedItem, selectedItems: selectedItems, onFocusedItemChanged: handleFocusedItemChanged, onSelectedItemsChanged: onSelectedItemsChanged, maxDepthLevel: 1, invertMasterNavigation: false, onNoRelationsFound: onNoRelationsFound, onItemContextMenu: onContextMenu, focusedItemFormData: focusedItemFormData }, refreshKey));
209
406
  };
210
- const TMFormOrResultWrapper = ({ deviceType, focusedItem, onTaskCreateRequest, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers }) => {
407
+ const TMFormOrResultWrapper = ({ refreshKey, deviceType, focusedItem, onTaskCreateRequest, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, onRefreshAfterAddDcmtToFavs, editPdfForm, openS4TViewer, onOpenS4TViewerRequest, onOpenPdfEditorRequest, onRefreshSearchAsyncDatagrid, onRefreshSearchResults }) => {
211
408
  const { setPanelVisibilityById } = useTMPanelManagerContext();
212
409
  return (_jsx(_Fragment, { children: focusedItem?.isDcmt ?
213
- _jsx(TMDcmtForm, { groupId: 'tmFormOrResult', TID: focusedItem?.tid, DID: focusedItem.did, allowButtonsRefs: true, isClosable: deviceType !== DeviceType.MOBILE, allowNavigation: false, allowRelations: deviceType !== DeviceType.MOBILE, showDcmtFormSidebar: false, onClose: () => {
214
- setPanelVisibilityById('tmTreeView', true);
215
- }, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, moreInfoTasks: getMoreInfoTasksForDocument(allTasks, focusedItem?.tid, focusedItem?.did) }) :
216
- _jsx(TMSearchResult, { groupId: 'tmFormOrResult', isClosable: deviceType !== DeviceType.MOBILE, context: SearchResultContext.METADATA_SEARCH, allowFloatingBar: false, allowRelations: false, openDcmtFormAsModal: true, searchResults: focusedItem?.searchResult ?? [], showSearchResultSidebar: false, showDcmtFormSidebar: false, onTaskCreateRequest: onTaskCreateRequest, onClose: () => {
217
- setPanelVisibilityById('tmTreeView', true);
218
- }, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }) }));
410
+ _jsx(TMDcmtForm, { groupId: 'tmFormOrResult', TID: focusedItem?.tid, DID: focusedItem.did, allowButtonsRefs: true, isClosable: deviceType !== DeviceType.MOBILE, allowNavigation: false, allowRelations: deviceType !== DeviceType.MOBILE, showDcmtFormSidebar: false, onClose: () => { setPanelVisibilityById('tmTreeView', true); }, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, moreInfoTasks: getMoreInfoTasksForDocument(allTasks, focusedItem?.tid, focusedItem?.did), openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, onOpenPdfEditorRequest: onOpenPdfEditorRequest, datagridUtility: {
411
+ onRefreshSearchAsyncDatagrid,
412
+ } }, refreshKey) :
413
+ _jsx(TMSearchResult, { groupId: 'tmFormOrResult', isClosable: deviceType !== DeviceType.MOBILE, context: SearchResultContext.METADATA_SEARCH, allowFloatingBar: false, allowRelations: false, openDcmtFormAsModal: true, searchResults: focusedItem?.searchResult ?? [], showSearchResultSidebar: false, showDcmtFormSidebar: false, onTaskCreateRequest: onTaskCreateRequest, onClose: () => { setPanelVisibilityById('tmTreeView', true); }, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, editPdfForm: editPdfForm, onOpenPdfEditorRequest: onOpenPdfEditorRequest, openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, enablePinIcons: false, onRefreshAfterAddDcmtToFavs: onRefreshAfterAddDcmtToFavs, showBackButton: false, onRefreshSearchAsyncDatagrid: onRefreshSearchResults }, refreshKey) }));
219
414
  };