@topconsultnpm/sdkui-react 6.20.0-dev2.8 → 6.20.0-dev3.1

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 (86) hide show
  1. package/lib/components/NewComponents/ContextMenu/styles.d.ts +3 -1
  2. package/lib/components/NewComponents/ContextMenu/styles.js +7 -5
  3. package/lib/components/base/Styled.d.ts +4 -1
  4. package/lib/components/base/Styled.js +11 -3
  5. package/lib/components/base/TMTreeView.d.ts +3 -1
  6. package/lib/components/base/TMTreeView.js +64 -21
  7. package/lib/components/choosers/TMDataListItemEditor.d.ts +11 -0
  8. package/lib/components/choosers/TMDataListItemEditor.js +130 -0
  9. package/lib/components/choosers/TMDataListItemFields.d.ts +11 -0
  10. package/lib/components/choosers/TMDataListItemFields.js +61 -0
  11. package/lib/components/choosers/TMDataListItemPicker.d.ts +1 -0
  12. package/lib/components/choosers/TMDataListItemPicker.js +178 -18
  13. package/lib/components/choosers/TMDynDataListItemChooser.js +11 -6
  14. package/lib/components/choosers/TMImageIDChooser.d.ts +16 -0
  15. package/lib/components/choosers/TMImageIDChooser.js +53 -0
  16. package/lib/components/choosers/TMMetadataChooser.js +1 -1
  17. package/lib/components/editors/TMDateBox.js +1 -1
  18. package/lib/components/editors/TMHtmlEditor.js +1 -1
  19. package/lib/components/editors/TMLocalizedTextBox.d.ts +1 -0
  20. package/lib/components/editors/TMLocalizedTextBox.js +3 -3
  21. package/lib/components/editors/TMMetadataValues.js +3 -1
  22. package/lib/components/editors/TMTextBox.js +9 -10
  23. package/lib/components/features/archive/TMArchive.d.ts +2 -1
  24. package/lib/components/features/archive/TMArchive.js +31 -44
  25. package/lib/components/features/blog/TMBlogCommentForm.d.ts +3 -0
  26. package/lib/components/features/blog/TMBlogCommentForm.js +42 -36
  27. package/lib/components/features/documents/TMDcmtForm.d.ts +3 -1
  28. package/lib/components/features/documents/TMDcmtForm.js +197 -45
  29. package/lib/components/features/documents/TMDcmtTasks.d.ts +3 -1
  30. package/lib/components/features/documents/TMDcmtTasks.js +2 -2
  31. package/lib/components/features/documents/TMFileUploader.d.ts +4 -0
  32. package/lib/components/features/documents/TMFileUploader.js +23 -6
  33. package/lib/components/features/documents/TMMasterDetailDcmts.js +68 -84
  34. package/lib/components/features/documents/TMRelationViewer.d.ts +7 -1
  35. package/lib/components/features/documents/TMRelationViewer.js +395 -78
  36. package/lib/components/features/search/TMSearchResult.d.ts +2 -0
  37. package/lib/components/features/search/TMSearchResult.js +82 -79
  38. package/lib/components/features/search/TMSearchResultsMenuItems.js +2 -2
  39. package/lib/components/features/tasks/TMTaskForm.d.ts +1 -0
  40. package/lib/components/features/tasks/TMTaskForm.js +61 -193
  41. package/lib/components/features/tasks/TMTaskFormUtils.d.ts +80 -0
  42. package/lib/components/features/tasks/TMTaskFormUtils.js +559 -0
  43. package/lib/components/features/tasks/TMTasksUtils.d.ts +3 -1
  44. package/lib/components/features/tasks/TMTasksUtils.js +46 -16
  45. package/lib/components/features/tasks/TMTasksUtilsView.d.ts +0 -7
  46. package/lib/components/features/tasks/TMTasksUtilsView.js +7 -14
  47. package/lib/components/features/tasks/TMTasksView.js +5 -3
  48. package/lib/components/features/workflow/TMWorkflowPopup.d.ts +20 -3
  49. package/lib/components/features/workflow/TMWorkflowPopup.js +14 -92
  50. package/lib/components/features/workflow/diagram/ConnectionComponent.d.ts +1 -0
  51. package/lib/components/features/workflow/diagram/ConnectionComponent.js +6 -2
  52. package/lib/components/features/workflow/diagram/DiagramItemForm.js +1 -1
  53. package/lib/components/features/workflow/diagram/WFDiagram.js +75 -5
  54. package/lib/components/forms/Login/TMLoginForm.js +1 -1
  55. package/lib/components/forms/TMSaveForm.js +61 -13
  56. package/lib/components/grids/TMBlogsPost.js +8 -8
  57. package/lib/components/grids/TMBlogsPostUtils.js +2 -2
  58. package/lib/components/index.d.ts +2 -0
  59. package/lib/components/index.js +2 -0
  60. package/lib/components/pages/TMPage.js +4 -0
  61. package/lib/components/query/TMQueryEditor.d.ts +1 -0
  62. package/lib/components/query/TMQueryEditor.js +2 -2
  63. package/lib/helper/Enum_Localizator.js +5 -0
  64. package/lib/helper/GlobalStyles.js +3 -0
  65. package/lib/helper/SDKUI_Globals.d.ts +8 -0
  66. package/lib/helper/SDKUI_Globals.js +12 -0
  67. package/lib/helper/SDKUI_Localizator.d.ts +19 -3
  68. package/lib/helper/SDKUI_Localizator.js +182 -22
  69. package/lib/helper/TMIcons.d.ts +2 -1
  70. package/lib/helper/TMIcons.js +4 -1
  71. package/lib/helper/TMUtils.d.ts +5 -0
  72. package/lib/helper/TMUtils.js +10 -5
  73. package/lib/helper/helpers.d.ts +6 -2
  74. package/lib/helper/helpers.js +24 -8
  75. package/lib/helper/index.d.ts +1 -0
  76. package/lib/helper/index.js +1 -0
  77. package/lib/helper/queryHelper.js +1 -1
  78. package/lib/hooks/useBetaFeatures.d.ts +1 -0
  79. package/lib/hooks/useBetaFeatures.js +41 -0
  80. package/lib/hooks/useDcmtOperations.js +14 -2
  81. package/lib/hooks/useRelatedDocuments.js +34 -11
  82. package/lib/index.d.ts +1 -0
  83. package/lib/index.js +1 -0
  84. package/lib/services/platform_services.d.ts +1 -1
  85. package/lib/services/platform_services.js +4 -0
  86. package/package.json +2 -2
@@ -6,7 +6,7 @@ import { useTMPanelManagerContext } from "../../layout/panelManager/TMPanelManag
6
6
  import TMPanel from "../../base/TMPanel";
7
7
  import TMTasksPanelContent from "../tasks/TMTasksPanelContent";
8
8
  const TMDcmtTasks = (props) => {
9
- const { taskContext, allTasks, getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, afterTaskSaved } = props;
9
+ const { taskContext, allTasks, getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, afterTaskSaved, handleNavigateToWGs, handleNavigateToDossiers } = props;
10
10
  // Get the current device type (e.g., mobile, tablet, desktop) using a custom hook.
11
11
  const deviceType = useDeviceType();
12
12
  // This avoids unnecessary re-renders by only recalculating when deviceType changes.
@@ -19,6 +19,6 @@ const TMDcmtTasks = (props) => {
19
19
  text: SDKUI_Localizator.Refresh,
20
20
  },
21
21
  ], children: _jsx(IconMenuVertical, { id: "TMTaksPanel-Commands-Header", color: 'white', cursor: 'pointer' }) }), []);
22
- return _jsx("div", { style: { width: "100%", height: "100%", position: 'relative' }, children: _jsx(TMPanel, { title: SDKUI_Localizator.Widget_Activities, allowMaximize: !isMobile && countVisibleLeafPanels() > 1, onClose: countVisibleLeafPanels() > 1 ? () => togglePanelVisibility("tmDcmtTasks") : undefined, onMaximize: countVisibleLeafPanels() > 1 ? () => toggleMaximize("tmDcmtTasks") : undefined, toolbar: toolbar, children: _jsx(TMTasksPanelContent, { id: "dcmtTasks", taskContext: taskContext, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: () => { return Promise.resolve(); }, handleNavigateToDossiers: () => { return Promise.resolve(); }, afterTaskSaved: afterTaskSaved }) }) });
22
+ return _jsx("div", { style: { width: "100%", height: "100%", position: 'relative' }, children: _jsx(TMPanel, { title: SDKUI_Localizator.Widget_Activities, allowMaximize: !isMobile && countVisibleLeafPanels() > 1, onClose: countVisibleLeafPanels() > 1 ? () => togglePanelVisibility("tmDcmtTasks") : undefined, onMaximize: countVisibleLeafPanels() > 1 ? () => toggleMaximize("tmDcmtTasks") : undefined, toolbar: toolbar, children: _jsx(TMTasksPanelContent, { id: "dcmtTasks", taskContext: taskContext, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs ? handleNavigateToWGs : () => { return Promise.resolve(); }, handleNavigateToDossiers: handleNavigateToDossiers ? handleNavigateToDossiers : () => { return Promise.resolve(); }, afterTaskSaved: afterTaskSaved }) }) });
23
23
  };
24
24
  export default TMDcmtTasks;
@@ -1,8 +1,12 @@
1
1
  import React from 'react';
2
2
  import { DeviceType } from '../../base/TMDeviceProvider';
3
+ import { DcmtTypeDescriptor } from '@topconsultnpm/sdk-ts';
3
4
  interface ITMFileUploader {
5
+ fromDTD?: DcmtTypeDescriptor;
4
6
  onFileUpload?: (file: File | null) => void;
7
+ openPdfEditor?: (fromDTD?: DcmtTypeDescriptor, file?: File | null, handleFile?: (file: File) => void) => void;
5
8
  onClose?: () => void;
9
+ onScanRequest?: (onFileScanned: (file: File) => void) => void;
6
10
  isRequired?: boolean;
7
11
  defaultBlob?: File | null;
8
12
  deviceType?: DeviceType;
@@ -1,17 +1,19 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useCallback, useEffect, useRef, useState } from 'react';
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
3
  import styled from 'styled-components';
4
- import { IconFolderOpen, SDKUI_Localizator, formatBytes, IconClear, extensionHandler, IconCloseOutline } from '../../../helper';
4
+ import { IconFolderOpen, IconScanner, SDKUI_Localizator, formatBytes, IconClear, extensionHandler, IconCloseOutline, IconMenuVertical, TMCommandsContextMenu, IconEdit } from '../../../helper';
5
5
  import usePreventFileDrop from '../../../hooks/usePreventFileDrop';
6
6
  import { FileExtensionHandler } from '../../../ts';
7
7
  import { TMColors } from '../../../utils/theme';
8
8
  import TMButton from '../../base/TMButton';
9
+ import ShowAlert from '../../base/TMAlert';
9
10
  import { DeviceType } from '../../base/TMDeviceProvider';
10
11
  import TMTooltip from '../../base/TMTooltip';
11
12
  import { TMFileViewer, StyledHeaderIcon } from './TMDcmtPreview';
12
13
  import TMPanel from '../../base/TMPanel';
13
14
  import TMDragDropOverlay from './TMDragDropOverlay';
14
- const TMFileUploader = ({ deviceType = DeviceType.DESKTOP, onClose, onFileUpload, isRequired = false, defaultBlob = null, isResizingActive, showTMPanel = true, enableDragDropOverlay = false }) => {
15
+ import { LicenseModuleStatus, SDK_Globals } from '@topconsultnpm/sdk-ts';
16
+ const TMFileUploader = ({ fromDTD, deviceType = DeviceType.DESKTOP, onClose, onFileUpload, openPdfEditor, onScanRequest, isRequired = false, defaultBlob = null, isResizingActive, showTMPanel = true, enableDragDropOverlay = false }) => {
15
17
  const [dragOver, setDragOver] = useState(false);
16
18
  const [uploadedFile, setUploadedFile] = useState(defaultBlob);
17
19
  const [fileName, setFileName] = useState('');
@@ -83,11 +85,26 @@ const TMFileUploader = ({ deviceType = DeviceType.DESKTOP, onClose, onFileUpload
83
85
  document.getElementById('fileInput')?.click();
84
86
  }, []);
85
87
  let content = !uploadedFile ?
86
- _jsxs("div", { style: { display: 'flex', gap: 10, width: '100%', height: '100%' }, children: [_jsx(HiddenInput, { id: "fileInput", type: "file", onChange: handleInputChange }), _jsxs(UploadContainer, { ref: uploaderRef, tabIndex: 0, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, style: { backgroundColor: dragOver ? '#76b1e6' : 'white' }, onDoubleClick: browseHandler, "$isRequired": isRequired, children: [_jsx("div", { style: { display: 'flex', gap: '10px', flexDirection: 'column', position: 'absolute', right: 5, top: 5 }, children: _jsx(TMButton, { btnStyle: 'icon', caption: 'Sfoglia', color: isRequired && !uploadedFile ? 'error' : 'primary', onClick: browseHandler, icon: _jsx(IconFolderOpen, { fontSize: 22 }) }) }), _jsx("p", { style: { fontSize: '1.2rem', fontWeight: 'bold' }, children: deviceType === DeviceType.MOBILE ? 'Clicca per sfogliare il tuo file' : 'Trascina il tuo file o fai doppio click per sfogliarlo' }), isRequired && _jsxs("p", { style: { fontWeight: 'bold' }, children: [" ", SDKUI_Localizator.RequiredField, " "] })] })] }) :
88
+ _jsxs("div", { style: { display: 'flex', gap: 10, width: '100%', height: '100%' }, children: [_jsx(HiddenInput, { id: "fileInput", type: "file", onChange: handleInputChange }), _jsxs(UploadContainer, { ref: uploaderRef, tabIndex: 0, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, style: { backgroundColor: dragOver ? '#76b1e6' : 'white' }, onDoubleClick: browseHandler, "$isRequired": isRequired, children: [_jsxs("div", { style: { display: 'flex', gap: '10px', flexDirection: 'column', position: 'absolute', right: 5, top: 5 }, children: [_jsx(TMButton, { btnStyle: 'icon', caption: 'Sfoglia', color: isRequired && !uploadedFile ? 'error' : 'primary', onClick: browseHandler, icon: _jsx(IconFolderOpen, { fontSize: 22 }) }), _jsx(TMButton, { btnStyle: 'icon', caption: 'Scanner', color: 'primary', onClick: () => { if (onScanRequest) {
89
+ onScanRequest((file) => { onFileUpload?.(file); });
90
+ }
91
+ else {
92
+ ShowAlert({ message: 'Funzionalità scanner in fase di sviluppo.', mode: 'info', duration: 3000, title: 'Work in progress' });
93
+ } }, icon: _jsx(IconScanner, { fontSize: 22 }) })] }), _jsx("p", { style: { fontSize: '1.2rem', fontWeight: 'bold' }, children: deviceType === DeviceType.MOBILE ? 'Clicca per sfogliare il tuo file' : 'Trascina il tuo file o fai doppio click per sfogliarlo' }), isRequired && _jsxs("p", { style: { fontWeight: 'bold' }, children: [" ", SDKUI_Localizator.RequiredField, " "] })] })] }) :
87
94
  _jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 10, width: '100%', height: '100%' }, children: [_jsxs("div", { style: { backgroundColor: 'white', padding: '5px 10px', borderRadius: 8, display: 'flex', alignItems: 'center', justifyContent: 'space-between', color: TMColors.primaryColor }, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 5 }, children: [_jsx("p", { children: "File name:" }), _jsxs("div", { style: { fontWeight: 'bold' }, children: [fileName, " ", _jsxs("span", { children: [" ", ` (${formatBytes(fileSize)})`, " "] })] })] }), uploadedFile && _jsx(TMButton, { btnStyle: 'icon', color: 'error', caption: 'Pulisci', onClick: () => clearFile(true), icon: _jsx(IconClear, { fontSize: 22 }) })] }), extensionHandler(fileExt) === FileExtensionHandler.READY_TO_SHOW ? _jsx(TMFileViewer, { fileBlob: uploadedFile, isResizingActive: isResizingActive }) :
88
95
  _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})` })] }) })] });
89
96
  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] }));
90
- return showTMPanel ? (_jsx(TMPanel, { ref: fileUploaderPanelRef, panelID: 'file-uploader-panel', title: SDKUI_Localizator.FileUpload, onBack: deviceType === DeviceType.MOBILE ? () => onClose?.() : undefined, toolbar: deviceType !== DeviceType.MOBILE ? (_jsx(StyledHeaderIcon, { onClick: onClose, "$color": 'white', children: _jsx(TMTooltip, { content: SDKUI_Localizator.Close, children: _jsx(IconCloseOutline, {}) }) })) : undefined, children: innerContent })) : (innerContent);
97
+ const toolbar = useMemo(() => {
98
+ const isPdfEditorLicensed = SDK_Globals?.license?.dcmtArchiveLicenses?.[0]?.siX_60007?.status === LicenseModuleStatus.Licensed;
99
+ return (_jsxs(_Fragment, { children: [(isPdfEditorLicensed && fileExt && fileExt.toLowerCase() === 'pdf') && (_jsx(TMCommandsContextMenu, { target: "#TMPanel-FileUploader-Commands-Header", menuItems: [
100
+ {
101
+ icon: _jsx(IconEdit, {}),
102
+ text: 'PDF Editor',
103
+ onClick: () => openPdfEditor?.(fromDTD, uploadedFile, handleFile)
104
+ }
105
+ ], 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, {}) }) }))] }));
106
+ }, [deviceType, onClose]);
107
+ return showTMPanel ? (_jsx(TMPanel, { ref: fileUploaderPanelRef, panelID: 'file-uploader-panel', title: SDKUI_Localizator.FileUpload, onBack: deviceType === DeviceType.MOBILE ? () => onClose?.() : undefined, toolbar: toolbar, children: innerContent })) : (innerContent);
91
108
  };
92
109
  const UploadContainer = styled.div `
93
110
  position: relative;
@@ -1,12 +1,12 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useCallback, useEffect, useMemo, useState } from 'react';
2
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
3
  import { DcmtTypeListCacheService, SDK_Localizator } from '@topconsultnpm/sdk-ts';
4
+ import styled from 'styled-components';
4
5
  import TMRelationViewer from './TMRelationViewer';
5
6
  import TMContextMenu from '../../NewComponents/ContextMenu/TMContextMenu';
6
- import { genUniqueId, IconMultipleSelection, IconCheckFile, IconDetailDcmts, SDKUI_Localizator, IconMail, IconDcmtTypeOnlyMetadata, IconCopy, IconMenuVertical, IconDataList, IconPreview, IconSearchCheck, IconBoard, IconDcmtTypeSys, IconShow, getMoreInfoTasksForDocument } from '../../../helper';
7
+ import { genUniqueId, IconMultipleSelection, IconCheckFile, IconDetailDcmts, SDKUI_Localizator, IconMenuVertical, IconDataList, IconPreview, IconSearchCheck, IconBoard, IconDcmtTypeSys, IconShow, getMoreInfoTasksForDocument } from '../../../helper';
7
8
  import { FormModes, SearchResultContext } from '../../../ts';
8
9
  import { TMColors } from '../../../utils/theme';
9
- import ShowAlert from '../../base/TMAlert';
10
10
  import { DeviceType } from '../../base/TMDeviceProvider';
11
11
  import { TMSaveFormButtonPrevious, TMSaveFormButtonNext } from '../../forms/TMSaveForm';
12
12
  import TMPanelManagerContainer from '../../layout/panelManager/TMPanelManagerContainer';
@@ -14,6 +14,44 @@ 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 TMButton from '../../base/TMButton';
18
+ const StyledNoRelationsOverlay = styled.div `
19
+ width: 100%;
20
+ height: 100%;
21
+ position: fixed;
22
+ top: 0;
23
+ left: 0;
24
+ z-index: 1501;
25
+ overflow: visible;
26
+ background-color: rgba(0, 0, 0, 0.5);
27
+ backdrop-filter: blur(8px);
28
+ `;
29
+ const StyledNoRelationsPanel = styled.div `
30
+ position: absolute;
31
+ top: 50%;
32
+ left: 50%;
33
+ transform: translate(-50%, -50%);
34
+ width: 400px;
35
+ background: white;
36
+ border-radius: 8px;
37
+ padding: 20px;
38
+ text-align: center;
39
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
40
+ display: flex;
41
+ flex-direction: column;
42
+ align-items: center;
43
+ `;
44
+ const StyledNoRelationsTitle = styled.h2 `
45
+ margin: 0 0 20px 0;
46
+ font-size: 1.3em;
47
+ color: #333;
48
+ `;
49
+ const StyledNoRelationsMessage = styled.p `
50
+ color: #666;
51
+ font-size: 1em;
52
+ margin: 0 0 25px 0;
53
+ line-height: 1.4;
54
+ `;
17
55
  const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, deviceType, inputDcmts, isForMaster, showCurrentDcmtIndicator = true, allowNavigation, canNext, canPrev, onNext, onPrev, onBack, appendMasterDcmts, onTaskCreateRequest }) => {
18
56
  const [id, setID] = useState('');
19
57
  const [focusedItem, setFocusedItem] = useState();
@@ -21,6 +59,10 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
21
59
  const [showZeroDcmts, setShowZeroDcmts] = useState(false);
22
60
  const [allowMultipleSelection, setAllowMultipleSelection] = useState(false);
23
61
  const [dtdMaster, setDtdMaster] = useState();
62
+ const [showNoRelationsModal, setShowNoRelationsModal] = useState(false);
63
+ const [shouldGoBackOnClose, setShouldGoBackOnClose] = useState(false);
64
+ // Ref to track if this is the first load (vs navigation with onPrev/onNext)
65
+ const isFirstLoadRef = useRef(true);
24
66
  useEffect(() => { setID(genUniqueId()); }, []);
25
67
  // Load dtdMaster when inputDcmts changes
26
68
  useEffect(() => {
@@ -40,10 +82,23 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
40
82
  }, [inputDcmts?.length, inputDcmts?.[0]?.TID, isForMaster]);
41
83
  const handleFocusedItemChanged = useCallback((item) => {
42
84
  setFocusedItem(item);
85
+ // When data is loaded and an item is focused, mark as no longer first load
86
+ if (item) {
87
+ isFirstLoadRef.current = false;
88
+ }
43
89
  }, []);
44
90
  const handleSelectedItemsChanged = useCallback((items) => {
45
91
  setSelectedItems(items);
46
92
  }, []);
93
+ const handleNoRelationsFound = useCallback(() => {
94
+ // Show modal only on first load, not during navigation with onPrev/onNext
95
+ if (isFirstLoadRef.current) {
96
+ setShowNoRelationsModal(true);
97
+ setShouldGoBackOnClose(true);
98
+ }
99
+ // Mark as no longer first load
100
+ isFirstLoadRef.current = false;
101
+ }, []);
47
102
  const commandsMenuItems = [
48
103
  {
49
104
  icon: _jsx(IconMultipleSelection, { color: allowMultipleSelection ? TMColors.tertiary : TMColors.text_normal }),
@@ -66,82 +121,6 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
66
121
  onClick: () => {
67
122
  appendMasterDcmts?.(focusedItem?.tid, focusedItem?.did);
68
123
  }
69
- },
70
- {
71
- icon: _jsx(IconMail, {}),
72
- name: "Invia per posta",
73
- disabled: false,
74
- beginGroup: true,
75
- submenu: [
76
- {
77
- icon: _jsx(IconMail, {}),
78
- name: "I documenti selezionati",
79
- disabled: false,
80
- onClick: () => ShowAlert({ message: "TODO", mode: 'info', title: `${"TODO"}`, duration: 3000 })
81
- },
82
- {
83
- icon: _jsx(IconMail, {}),
84
- name: "I documenti di primo livello e tutti i documenti correlati",
85
- disabled: false,
86
- onClick: () => ShowAlert({ message: "TODO", mode: 'info', title: `${"TODO"}`, duration: 3000 })
87
- },
88
- {
89
- icon: _jsx(IconMail, {}),
90
- name: "I documenti di primo livello e i documenti correlati personalizzando l'operazione",
91
- disabled: false,
92
- onClick: () => ShowAlert({ message: "TODO", mode: 'info', title: `${"TODO"}`, duration: 3000 })
93
- },
94
- ]
95
- },
96
- {
97
- icon: _jsx(IconDcmtTypeOnlyMetadata, {}),
98
- name: "Unisci in un file PDF",
99
- disabled: false,
100
- submenu: [
101
- {
102
- icon: _jsx(IconDcmtTypeOnlyMetadata, {}),
103
- name: "I documenti selezionati",
104
- disabled: false,
105
- onClick: () => ShowAlert({ message: "TODO", mode: 'info', title: `${"TODO"}`, duration: 3000 })
106
- },
107
- {
108
- icon: _jsx(IconDcmtTypeOnlyMetadata, {}),
109
- name: "I documenti di primo livello e tutti i documenti correlati",
110
- disabled: false,
111
- onClick: () => ShowAlert({ message: "TODO", mode: 'info', title: `${"TODO"}`, duration: 3000 })
112
- },
113
- {
114
- icon: _jsx(IconDcmtTypeOnlyMetadata, {}),
115
- name: "I documenti di primo livello e i documenti correlati personalizzando l'operazione",
116
- disabled: false,
117
- onClick: () => ShowAlert({ message: "TODO", mode: 'info', title: `${"TODO"}`, duration: 3000 })
118
- },
119
- ]
120
- },
121
- {
122
- icon: _jsx(IconCopy, {}),
123
- name: "Copia in una cartella",
124
- disabled: false,
125
- submenu: [
126
- {
127
- icon: _jsx(IconCopy, {}),
128
- name: "I documenti selezionati",
129
- disabled: false,
130
- onClick: () => ShowAlert({ message: "TODO", mode: 'info', title: `${"TODO"}`, duration: 3000 })
131
- },
132
- {
133
- icon: _jsx(IconCopy, {}),
134
- name: "I documenti di primo livello e tutti i documenti correlati",
135
- disabled: false,
136
- onClick: () => ShowAlert({ message: "TODO", mode: 'info', title: `${"TODO"}`, duration: 3000 })
137
- },
138
- {
139
- icon: _jsx(IconCopy, {}),
140
- name: "I documenti di primo livello e i documenti correlati personalizzando l'operazione",
141
- disabled: false,
142
- onClick: () => ShowAlert({ message: "TODO", mode: 'info', title: `${"TODO"}`, duration: 3000 })
143
- },
144
- ]
145
124
  }
146
125
  ];
147
126
  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.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' }) })] });
@@ -153,7 +132,7 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
153
132
  :
154
133
  _jsx(TMRelationViewerWrapper, { inputDcmts: inputDcmts, isForMaster: isForMaster, showCurrentDcmtIndicator: showCurrentDcmtIndicator, showZeroDcmts: showZeroDcmts,
155
134
  // customItemRender={customItemRender}
156
- allowMultipleSelection: allowMultipleSelection, focusedItem: focusedItem, selectedItems: selectedItems, onFocusedItemChanged: handleFocusedItemChanged, onSelectedItemsChanged: handleSelectedItemsChanged }) }), [inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, allowMultipleSelection, focusedItem, selectedItems, handleFocusedItemChanged, handleSelectedItemsChanged]);
135
+ allowMultipleSelection: allowMultipleSelection, focusedItem: focusedItem, selectedItems: selectedItems, onFocusedItemChanged: handleFocusedItemChanged, onSelectedItemsChanged: handleSelectedItemsChanged, onNoRelationsFound: handleNoRelationsFound }) }), [inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, allowMultipleSelection, focusedItem, selectedItems, handleFocusedItemChanged, handleSelectedItemsChanged, handleNoRelationsFound]);
157
136
  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]);
158
137
  const initialPanelDimensions = {
159
138
  'tmTreeView': { width: '50%', height: '100%' },
@@ -231,7 +210,12 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
231
210
  toolbarOptions: { icon: _jsx(IconSearchCheck, { fontSize: 24 }), visible: false, orderNumber: 2, isActive: allInitialPanelVisibility['tmFormOrResult'] }
232
211
  }
233
212
  ], [tmTreeView, tmFormOrResult, focusedItem?.isDcmt, dtdMaster]);
234
- return (_jsx(TMPanelManagerProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: initialPanelDimensions, initialDimensions: initialPanelDimensions, initialMobilePanelId: 'tmTreeView', children: _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", showToolbar: true }) }));
213
+ return (_jsxs(_Fragment, { children: [_jsx(TMPanelManagerProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: initialPanelDimensions, initialDimensions: initialPanelDimensions, initialMobilePanelId: 'tmTreeView', children: _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", showToolbar: true }) }), showNoRelationsModal && (_jsx(StyledNoRelationsOverlay, { children: _jsxs(StyledNoRelationsPanel, { children: [_jsx(StyledNoRelationsTitle, { children: SDKUI_Localizator.RelationsNotFound }), _jsx(StyledNoRelationsMessage, { children: SDKUI_Localizator.RelatedDcmtsNotFound }), _jsx(TMButton, { caption: "OK", showTooltip: false, onClick: () => {
214
+ setShowNoRelationsModal(false);
215
+ if (shouldGoBackOnClose) {
216
+ onBack?.();
217
+ }
218
+ }, btnStyle: "normal" })] }) }))] }));
235
219
  };
236
220
  export default TMMasterDetailDcmts;
237
221
  /**
@@ -240,7 +224,7 @@ export default TMMasterDetailDcmts;
240
224
  * - Panel visibility toggling
241
225
  * - Focus delay handling
242
226
  */
243
- const TMRelationViewerWrapper = ({ inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, customItemRender, allowMultipleSelection, focusedItem, selectedItems, onFocusedItemChanged, onSelectedItemsChanged }) => {
227
+ const TMRelationViewerWrapper = ({ inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, customItemRender, allowMultipleSelection, focusedItem, selectedItems, onFocusedItemChanged, onSelectedItemsChanged, onNoRelationsFound }) => {
244
228
  const { setPanelVisibilityById, setToolbarButtonVisibility } = useTMPanelManagerContext();
245
229
  // Handle focused item changes with panel visibility management
246
230
  const handleFocusedItemChanged = useCallback((item) => {
@@ -259,7 +243,7 @@ const TMRelationViewerWrapper = ({ inputDcmts, isForMaster, showCurrentDcmtIndic
259
243
  setToolbarButtonVisibility('tmDcmtForm', false);
260
244
  }
261
245
  }, [onFocusedItemChanged, setPanelVisibilityById, setToolbarButtonVisibility]);
262
- 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 }));
246
+ 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 }));
263
247
  };
264
248
  const TMFormOrResultWrapper = ({ deviceType, focusedItem, onTaskCreateRequest, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers }) => {
265
249
  const { setPanelVisibilityById } = useTMPanelManagerContext();
@@ -267,7 +251,7 @@ const TMFormOrResultWrapper = ({ deviceType, focusedItem, onTaskCreateRequest, a
267
251
  _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: () => {
268
252
  setPanelVisibilityById('tmTreeView', true);
269
253
  }, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, moreInfoTasks: getMoreInfoTasksForDocument(allTasks, focusedItem?.tid, focusedItem?.did) }) :
270
- _jsx(TMSearchResult, { groupId: 'tmFormOrResult', isClosable: deviceType !== DeviceType.MOBILE, context: SearchResultContext.METADATA_SEARCH, allowFloatingBar: false, allowRelations: false, openDcmtFormAsModal: true, searchResults: focusedItem?.searchResult ?? [], showSearchResultSidebar: false, onTaskCreateRequest: onTaskCreateRequest, onClose: () => {
254
+ _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: () => {
271
255
  setPanelVisibilityById('tmTreeView', true);
272
256
  }, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }) }));
273
257
  };
@@ -16,8 +16,9 @@ export interface RelationTreeItem extends ITMTreeItem {
16
16
  isRoot?: boolean;
17
17
  isMaster?: boolean;
18
18
  isCorrelated?: boolean;
19
- isLoaded?: boolean;
20
19
  isSeparator?: boolean;
20
+ isInfoMessage?: boolean;
21
+ isLogDel?: number;
21
22
  values?: any;
22
23
  searchResult?: SearchResultDescriptor[];
23
24
  itemsCount?: number;
@@ -92,6 +93,11 @@ export interface TMRelationViewerProps {
92
93
  * If not provided, uses the document type name.
93
94
  */
94
95
  labelMainContainer?: string;
96
+ /**
97
+ * Callback invoked when no relations are found for any of the input documents.
98
+ * Useful to notify parent component that there are no correlated documents to display.
99
+ */
100
+ onNoRelationsFound?: () => void;
95
101
  }
96
102
  /**
97
103
  * Check if document type has detail relations