@topconsultnpm/sdkui-react 6.20.0-test1 → 6.20.0

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 (109) 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/TMPanel.js +6 -4
  6. package/lib/components/base/TMPopUp.js +4 -0
  7. package/lib/components/base/TMTreeView.d.ts +3 -1
  8. package/lib/components/base/TMTreeView.js +68 -21
  9. package/lib/components/choosers/TMDataListItemChooser.js +1 -1
  10. package/lib/components/choosers/TMDataListItemEditor.d.ts +11 -0
  11. package/lib/components/choosers/TMDataListItemEditor.js +130 -0
  12. package/lib/components/choosers/TMDataListItemFields.d.ts +11 -0
  13. package/lib/components/choosers/TMDataListItemFields.js +61 -0
  14. package/lib/components/choosers/TMDataListItemPicker.d.ts +2 -0
  15. package/lib/components/choosers/TMDataListItemPicker.js +182 -18
  16. package/lib/components/choosers/TMDynDataListItemChooser.js +11 -6
  17. package/lib/components/choosers/TMImageIDChooser.d.ts +16 -0
  18. package/lib/components/choosers/TMImageIDChooser.js +53 -0
  19. package/lib/components/choosers/TMMetadataChooser.js +1 -1
  20. package/lib/components/choosers/TMUserChooser.js +1 -1
  21. package/lib/components/editors/TMDateBox.js +1 -1
  22. package/lib/components/editors/TMHtmlEditor.js +1 -1
  23. package/lib/components/editors/TMLocalizedTextBox.d.ts +1 -0
  24. package/lib/components/editors/TMLocalizedTextBox.js +3 -3
  25. package/lib/components/editors/TMMetadataValues.js +203 -41
  26. package/lib/components/editors/TMTextArea.d.ts +1 -0
  27. package/lib/components/editors/TMTextArea.js +6 -6
  28. package/lib/components/editors/TMTextBox.js +9 -10
  29. package/lib/components/features/archive/TMArchive.d.ts +3 -1
  30. package/lib/components/features/archive/TMArchive.js +31 -44
  31. package/lib/components/features/blog/TMBlogCommentForm.d.ts +3 -0
  32. package/lib/components/features/blog/TMBlogCommentForm.js +42 -36
  33. package/lib/components/features/documents/TMDcmtForm.d.ts +3 -1
  34. package/lib/components/features/documents/TMDcmtForm.js +215 -54
  35. package/lib/components/features/documents/TMDcmtPreview.js +66 -13
  36. package/lib/components/features/documents/TMDcmtTasks.d.ts +3 -1
  37. package/lib/components/features/documents/TMDcmtTasks.js +2 -2
  38. package/lib/components/features/documents/TMFileUploader.d.ts +5 -0
  39. package/lib/components/features/documents/TMFileUploader.js +28 -6
  40. package/lib/components/features/documents/TMMasterDetailDcmts.js +31 -85
  41. package/lib/components/features/documents/TMRelationViewer.d.ts +7 -1
  42. package/lib/components/features/documents/TMRelationViewer.js +497 -111
  43. package/lib/components/features/search/TMSearchQueryPanel.js +6 -6
  44. package/lib/components/features/search/TMSearchResult.d.ts +2 -0
  45. package/lib/components/features/search/TMSearchResult.js +106 -86
  46. package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +1 -1
  47. package/lib/components/features/search/TMSearchResultsMenuItems.js +6 -18
  48. package/lib/components/features/search/TMSignatureInfoContent.js +10 -6
  49. package/lib/components/features/search/TMTreeSelector.js +1 -1
  50. package/lib/components/features/tasks/TMTaskForm.d.ts +1 -0
  51. package/lib/components/features/tasks/TMTaskForm.js +61 -193
  52. package/lib/components/features/tasks/TMTaskFormUtils.d.ts +80 -0
  53. package/lib/components/features/tasks/TMTaskFormUtils.js +559 -0
  54. package/lib/components/features/tasks/TMTasksUtils.d.ts +3 -1
  55. package/lib/components/features/tasks/TMTasksUtils.js +46 -16
  56. package/lib/components/features/tasks/TMTasksUtilsView.d.ts +0 -7
  57. package/lib/components/features/tasks/TMTasksUtilsView.js +7 -14
  58. package/lib/components/features/tasks/TMTasksView.js +5 -3
  59. package/lib/components/features/workflow/TMWorkflowPopup.d.ts +20 -3
  60. package/lib/components/features/workflow/TMWorkflowPopup.js +21 -109
  61. package/lib/components/features/workflow/diagram/ConnectionComponent.d.ts +1 -0
  62. package/lib/components/features/workflow/diagram/ConnectionComponent.js +6 -2
  63. package/lib/components/features/workflow/diagram/DiagramItemForm.d.ts +2 -0
  64. package/lib/components/features/workflow/diagram/DiagramItemForm.js +32 -25
  65. package/lib/components/features/workflow/diagram/RecipientList.d.ts +3 -1
  66. package/lib/components/features/workflow/diagram/RecipientList.js +13 -9
  67. package/lib/components/features/workflow/diagram/WFDiagram.js +102 -5
  68. package/lib/components/features/workflow/diagram/workflowHelpers.js +31 -19
  69. package/lib/components/forms/Login/TMLoginForm.js +1 -1
  70. package/lib/components/forms/TMSaveForm.js +61 -13
  71. package/lib/components/grids/TMBlogsPost.js +8 -8
  72. package/lib/components/grids/TMBlogsPostUtils.js +2 -2
  73. package/lib/components/grids/TMRecentsManager.js +1 -1
  74. package/lib/components/index.d.ts +2 -0
  75. package/lib/components/index.js +2 -0
  76. package/lib/components/layout/panelManager/TMPanelManagerContainer.js +3 -2
  77. package/lib/components/pages/TMPage.js +4 -0
  78. package/lib/components/query/TMQueryEditor.d.ts +1 -0
  79. package/lib/components/query/TMQueryEditor.js +3 -3
  80. package/lib/components/viewers/TMMidViewer.js +2 -1
  81. package/lib/components/viewers/TMTidViewer.js +7 -3
  82. package/lib/helper/Enum_Localizator.js +5 -0
  83. package/lib/helper/GlobalStyles.js +3 -0
  84. package/lib/helper/SDKUI_Globals.d.ts +12 -0
  85. package/lib/helper/SDKUI_Globals.js +21 -1
  86. package/lib/helper/SDKUI_Localizator.d.ts +31 -7
  87. package/lib/helper/SDKUI_Localizator.js +286 -46
  88. package/lib/helper/TMIcons.d.ts +2 -1
  89. package/lib/helper/TMIcons.js +4 -1
  90. package/lib/helper/TMUtils.d.ts +33 -41
  91. package/lib/helper/TMUtils.js +157 -170
  92. package/lib/helper/helpers.d.ts +6 -2
  93. package/lib/helper/helpers.js +24 -8
  94. package/lib/helper/index.d.ts +1 -0
  95. package/lib/helper/index.js +1 -0
  96. package/lib/helper/queryHelper.js +1 -1
  97. package/lib/hooks/useBetaFeatures.d.ts +1 -0
  98. package/lib/hooks/useBetaFeatures.js +41 -0
  99. package/lib/hooks/useDataUserIdItem.js +2 -2
  100. package/lib/hooks/useDcmtOperations.js +14 -2
  101. package/lib/hooks/useRelatedDocuments.js +64 -42
  102. package/lib/index.d.ts +1 -0
  103. package/lib/index.js +1 -0
  104. package/lib/services/platform_services.d.ts +1 -1
  105. package/lib/services/platform_services.js +4 -0
  106. package/lib/ts/types.d.ts +3 -0
  107. package/package.json +2 -2
  108. package/lib/components/features/search/TMSignSettingsForm.d.ts +0 -9
  109. package/lib/components/features/search/TMSignSettingsForm.js +0 -621
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useMemo, useRef, useState } from 'react';
3
3
  import styled from 'styled-components';
4
- import { RetrieveFileOptions, DcmtOpers, GeneralRetrieveFormats, FileFormats } from '@topconsultnpm/sdk-ts';
5
- import { extensionHandler, sleep, getExceptionMessage, formatBytes, IconMenuVertical, IconCloseCircle, IconClear, IconCloseOutline, IconPreview, SDKUI_Globals, IconZoomOutLinear, IconZoomInLinear, IconPrintOutline, SDKUI_Localizator, IconRefresh, IconCache } from '../../../helper';
4
+ import { RetrieveFileOptions, DcmtOpers, GeneralRetrieveFormats, FileFormats, SDK_Globals } from '@topconsultnpm/sdk-ts';
5
+ import { extensionHandler, sleep, getExceptionMessage, formatBytes, IconMenuVertical, IconCloseCircle, IconClear, IconCloseOutline, IconPreview, SDKUI_Globals, IconZoomOutLinear, IconZoomInLinear, IconPrintOutline, SDKUI_Localizator, IconRefresh, IconCache, dcmtsFileCachePreview, CACHE_SIZE_LIMIT } from '../../../helper';
6
6
  import { useDcmtOperations } from '../../../hooks/useDcmtOperations';
7
7
  import { FileExtensionHandler, FormModes } from '../../../ts';
8
8
  import { TMColors } from '../../../utils/theme';
@@ -29,7 +29,15 @@ const TMDcmtPreview = ({ dcmtData, isResizingActive, isVisible, canNext, canPrev
29
29
  const [error, setError] = useState('');
30
30
  const [isAbortError, setIsAbortError] = useState(false);
31
31
  const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, getDcmtFileAsync, clearDcmtsFileCache, removeDcmtsFileCache, isDcmtFileInCache } = useDcmtOperations();
32
- const cacheKey = dcmtData ? `${dcmtData.tid}-${dcmtData.did}` : '00';
32
+ const isBasketMode = !!(dcmtData?.btid !== undefined && dcmtData?.bid !== undefined && dcmtData?.bfid !== undefined);
33
+ const getCacheKey = () => {
34
+ if (!dcmtData)
35
+ return '00';
36
+ if (isBasketMode)
37
+ return `basket-${dcmtData.btid}-${dcmtData.bid}-${dcmtData.bfid}`;
38
+ return `${dcmtData.tid}-${dcmtData.did}`;
39
+ };
40
+ const cacheKey = getCacheKey();
33
41
  const [hasLoadedDataOnce, setHasLoadedDataOnce] = useState(false);
34
42
  const [lastLoadedDid, setLastLoadedDid] = useState(undefined);
35
43
  useEffect(() => {
@@ -41,10 +49,10 @@ const TMDcmtPreview = ({ dcmtData, isResizingActive, isVisible, canNext, canPrev
41
49
  setShowPreview(false);
42
50
  return;
43
51
  }
44
- const currentCacheKey = `${dcmtData.tid}-${dcmtData.did}`;
52
+ const currentCacheKey = isBasketMode ? `basket-${dcmtData.btid}-${dcmtData.bid}-${dcmtData.bfid}` : `${dcmtData.tid}-${dcmtData.did}`;
45
53
  const shouldFetch = isVisible && (!hasLoadedDataOnce || currentCacheKey !== lastLoadedDid);
46
54
  if (isDcmtFileInCache(currentCacheKey)) {
47
- loadDocumentWithCache();
55
+ isBasketMode ? loadBasketFile() : loadDocumentWithCache();
48
56
  setShowPreview(true);
49
57
  return;
50
58
  }
@@ -52,7 +60,11 @@ const TMDcmtPreview = ({ dcmtData, isResizingActive, isVisible, canNext, canPrev
52
60
  setDcmtBlob(undefined);
53
61
  setError('');
54
62
  setIsAbortError(false);
55
- if ((extensionHandler(dcmtData.fileExt) !== FileExtensionHandler.NONE) && ((dcmtData.fileSize ?? 0) <= (SDKUI_Globals.userSettings.searchSettings.previewThreshold * 1024))) {
63
+ if (isBasketMode) {
64
+ loadBasketFile();
65
+ setShowPreview(true);
66
+ }
67
+ else if ((extensionHandler(dcmtData.fileExt) !== FileExtensionHandler.NONE) && ((dcmtData.fileSize ?? 0) <= (SDKUI_Globals.userSettings.searchSettings.previewThreshold * 1024))) {
56
68
  loadDocumentWithCache();
57
69
  setShowPreview(true);
58
70
  }
@@ -63,6 +75,47 @@ const TMDcmtPreview = ({ dcmtData, isResizingActive, isVisible, canNext, canPrev
63
75
  setLastLoadedDid(currentCacheKey);
64
76
  }
65
77
  }, [dcmtData?.did, isVisible, hasLoadedDataOnce, lastLoadedDid]);
78
+ const loadBasketFile = async () => {
79
+ try {
80
+ // Check cache first
81
+ if (dcmtsFileCachePreview.has(cacheKey)) {
82
+ setDcmtBlob(dcmtsFileCachePreview.get(cacheKey));
83
+ setIsFromCache(true);
84
+ setError('');
85
+ setIsAbortError(false);
86
+ return;
87
+ }
88
+ await sleep(300);
89
+ const basketEngine = SDK_Globals.tmSession?.NewBasketEngine();
90
+ const cvtFormat = extensionHandler(dcmtData?.fileExt) === FileExtensionHandler.CONVERTIBLE ? FileFormats.PDF : FileFormats.None;
91
+ const file = await basketEngine?.RetrieveFileAsync(dcmtData?.btid, dcmtData?.bid, dcmtData?.bfid, cvtFormat, abortController.signal);
92
+ // Store in cache
93
+ if (file) {
94
+ if (dcmtsFileCachePreview.size >= CACHE_SIZE_LIMIT) {
95
+ const oldestKey = dcmtsFileCachePreview.keys().next().value;
96
+ dcmtsFileCachePreview.delete(oldestKey);
97
+ }
98
+ dcmtsFileCachePreview.set(cacheKey, file);
99
+ }
100
+ setDcmtBlob(file);
101
+ setIsFromCache(false);
102
+ setError('');
103
+ setIsAbortError(false);
104
+ }
105
+ catch (ex) {
106
+ const err = ex;
107
+ if (err.name === 'CanceledError') {
108
+ setError('Operazione annullata.');
109
+ setIsAbortError(true);
110
+ ShowAlert({ message: err.message, mode: 'warning', duration: 3000, title: 'Abort' });
111
+ }
112
+ else {
113
+ setError(getExceptionMessage(ex));
114
+ setIsAbortError(false);
115
+ TMExceptionBoxManager.show({ exception: ex });
116
+ }
117
+ }
118
+ };
66
119
  const loadDocumentWithCache = async () => {
67
120
  const rfo = new RetrieveFileOptions();
68
121
  rfo.retrieveReason = DcmtOpers.None;
@@ -94,7 +147,7 @@ const TMDcmtPreview = ({ dcmtData, isResizingActive, isVisible, canNext, canPrev
94
147
  };
95
148
  const titleHandler = () => {
96
149
  let title = 'Anteprima ';
97
- if (!dcmtData?.did)
150
+ if (!dcmtData?.did && !isBasketMode)
98
151
  return title;
99
152
  let extensionInfo;
100
153
  if (dcmtData.fileExt !== null) {
@@ -120,7 +173,7 @@ const TMDcmtPreview = ({ dcmtData, isResizingActive, isVisible, canNext, canPrev
120
173
  setIsAbortError(false);
121
174
  setDcmtBlob(undefined);
122
175
  try {
123
- await loadDocumentWithCache();
176
+ isBasketMode ? await loadBasketFile() : await loadDocumentWithCache();
124
177
  }
125
178
  catch (error) {
126
179
  console.error('Error reopening document:', error);
@@ -132,7 +185,7 @@ const TMDcmtPreview = ({ dcmtData, isResizingActive, isVisible, canNext, canPrev
132
185
  ], [cacheKey, removeDcmtsFileCache, clearDcmtsFileCache, setIsFromCache]);
133
186
  return (_jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, showWaitPanelSecondary: showSecondary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, waitPanelTextSecondary: waitPanelTextSecondary, waitPanelValueSecondary: waitPanelValueSecondary, waitPanelMaxValueSecondary: waitPanelMaxValueSecondary, isCancelable: true, abortController: abortController, children: _jsx(TMPanel, { padding: '0', title: titleHandler(), onClose: onClosePanel, allowMaximize: allowMaximize, onMaximize: onMaximizePanel, onHeaderDoubleClick: onMaximizePanel, toolbar: _jsxs("div", { style: { width: 'max-content', display: 'flex', alignItems: 'center', gap: '10px' }, children: [onPrev && _jsx(TMSaveFormButtonPrevious, { btnStyle: 'icon', isModified: false, formMode: FormModes.ReadOnly, canPrev: canPrev, onPrev: onPrev }), onNext && _jsx(TMSaveFormButtonNext, { btnStyle: 'icon', isModified: false, formMode: FormModes.ReadOnly, canNext: canNext, onNext: onNext }), _jsx(StyledHeaderIcon, { "$color": TMColors.primaryColor, children: _jsx(ContextMenu, { items: cacheMenuItems, trigger: "left", children: _jsx(IconMenuVertical, {}) }) }), _jsx(StyledHeaderIcon, { onClick: reOpenDcmt, "$color": TMColors.primaryColor, children: _jsx(TMTooltip, { content: SDKUI_Localizator.ReopenDocument, children: _jsx(IconRefresh, {}) }) })] }), children: error
134
187
  ? _jsx(ErrorContent, { error: error, isAbortError: isAbortError, onRetry: reOpenDcmt })
135
- : renderedPreview(dcmtData?.tid, dcmtData?.did, dcmtData?.fileExt, dcmtData?.fileSize, dcmtData?.fileCount, extensionHandler(dcmtData?.fileExt), showPreview, isResizingActive, () => { loadDocumentWithCache(); setShowPreview(true); }, dcmtBlob) }) }));
188
+ : renderedPreview(dcmtData?.tid, dcmtData?.did, dcmtData?.fileExt, dcmtData?.fileSize, dcmtData?.fileCount, extensionHandler(dcmtData?.fileExt), showPreview, isResizingActive, () => { isBasketMode ? loadBasketFile() : loadDocumentWithCache(); setShowPreview(true); }, dcmtBlob, isBasketMode) }) }));
136
189
  };
137
190
  export default TMDcmtPreview;
138
191
  export const TMFileViewer = ({ fileBlob, isResizingActive }) => {
@@ -382,13 +435,13 @@ const ImageViewer = ({ fileBlob, alt = 'Image', className }) => {
382
435
  export const TMNothingToShow = ({ text = '', secondText, fileExt, icon = _jsx(IconPreview, { fontSize: 96 }) }) => {
383
436
  return (_jsx(StyledAnimatedComponentOpacity, { style: { width: '100%', height: '100%' }, children: _jsxs(StyledPanelStatusContainer, { children: [icon, _jsxs(StyledPreviewNotAvailable, { children: [text && _jsx("div", { children: text }), _jsxs("div", { children: [" ", secondText ?? SDKUI_Localizator.PreviewNotAvailable, fileExt && _jsx("b", { children: ` (*.${fileExt})` })] })] })] }) }));
384
437
  };
385
- const renderedPreview = (tid, did, fileExt, fileSize, fileCount, extHandler, showPreview, isResizingActive, onDownloadShowPreviewClick, dcmtBlob) => {
386
- if (!did)
438
+ const renderedPreview = (tid, did, fileExt, fileSize, fileCount, extHandler, showPreview, isResizingActive, onDownloadShowPreviewClick, dcmtBlob, isBasketMode) => {
439
+ if (!isBasketMode && !did)
387
440
  return _jsx(TMNothingToShow, { text: `${SDKUI_Localizator.NoDcmtSelected}.` });
388
- if (fileCount == 0) {
441
+ if (!isBasketMode && fileCount == 0) {
389
442
  return _jsx(TMNothingToShow, { text: SDKUI_Localizator.MetadataOnlyDocument });
390
443
  }
391
- if (fileExt && extHandler === FileExtensionHandler.NONE) {
444
+ if (!isBasketMode && fileExt && extHandler === FileExtensionHandler.NONE) {
392
445
  return _jsx(TMNothingToShow, { fileExt: fileExt });
393
446
  }
394
447
  if (showPreview) {
@@ -1,5 +1,5 @@
1
1
  import { FormModes, TaskContext } from "../../../ts";
2
- import { TaskDescriptor } from "@topconsultnpm/sdk-ts";
2
+ import { HomeBlogPost, TaskDescriptor } from "@topconsultnpm/sdk-ts";
3
3
  interface TMDcmtTasksProps {
4
4
  taskContext: TaskContext;
5
5
  allTasks: Array<TaskDescriptor>;
@@ -8,6 +8,8 @@ interface TMDcmtTasksProps {
8
8
  addTaskCallback: (task: TaskDescriptor) => Promise<void>;
9
9
  editTaskCallback: (task: TaskDescriptor) => Promise<void>;
10
10
  afterTaskSaved: (task: TaskDescriptor | undefined, formMode: FormModes | undefined, forceRefresh?: boolean) => Promise<void>;
11
+ handleNavigateToWGs?: (value: HomeBlogPost | number) => Promise<void>;
12
+ handleNavigateToDossiers?: (value: HomeBlogPost | number) => Promise<void>;
11
13
  }
12
14
  declare const TMDcmtTasks: (props: TMDcmtTasksProps) => import("react/jsx-runtime").JSX.Element;
13
15
  export default TMDcmtTasks;
@@ -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,14 +1,19 @@
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;
9
13
  isResizingActive?: boolean;
10
14
  showTMPanel?: boolean;
11
15
  enableDragDropOverlay?: boolean;
16
+ showScannerIcon?: boolean;
12
17
  }
13
18
  declare const TMFileUploader: React.FC<ITMFileUploader>;
14
19
  export default TMFileUploader;
@@ -1,17 +1,30 @@
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, isPdfEditorAvailable, SDKUI_Globals } from '../../../helper';
5
+ import { useBetaFeatures } from '../../../hooks/useBetaFeatures';
5
6
  import usePreventFileDrop from '../../../hooks/usePreventFileDrop';
6
7
  import { FileExtensionHandler } from '../../../ts';
7
8
  import { TMColors } from '../../../utils/theme';
8
9
  import TMButton from '../../base/TMButton';
10
+ import ShowAlert from '../../base/TMAlert';
9
11
  import { DeviceType } from '../../base/TMDeviceProvider';
10
12
  import TMTooltip from '../../base/TMTooltip';
11
13
  import { TMFileViewer, StyledHeaderIcon } from './TMDcmtPreview';
12
14
  import TMPanel from '../../base/TMPanel';
13
15
  import TMDragDropOverlay from './TMDragDropOverlay';
14
- const TMFileUploader = ({ deviceType = DeviceType.DESKTOP, onClose, onFileUpload, isRequired = false, defaultBlob = null, isResizingActive, showTMPanel = true, enableDragDropOverlay = false }) => {
16
+ // Helper per verificare se la licenza scanner è disponibile
17
+ const isScannerLicenseConfigured = () => {
18
+ try {
19
+ const scannerLicense = SDKUI_Globals.userSettings.advancedSettings.scannerLicense;
20
+ return scannerLicense && scannerLicense.trim() !== '';
21
+ }
22
+ catch {
23
+ return false;
24
+ }
25
+ };
26
+ const TMFileUploader = ({ fromDTD, deviceType = DeviceType.DESKTOP, onClose, onFileUpload, openPdfEditor, onScanRequest, isRequired = false, defaultBlob = null, isResizingActive, showTMPanel = true, enableDragDropOverlay = false, showScannerIcon = true }) => {
27
+ const isBetaFeaturesEnabled = useBetaFeatures();
15
28
  const [dragOver, setDragOver] = useState(false);
16
29
  const [uploadedFile, setUploadedFile] = useState(defaultBlob);
17
30
  const [fileName, setFileName] = useState('');
@@ -83,11 +96,20 @@ const TMFileUploader = ({ deviceType = DeviceType.DESKTOP, onClose, onFileUpload
83
96
  document.getElementById('fileInput')?.click();
84
97
  }, []);
85
98
  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, " "] })] })] }) :
99
+ _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 }) }), isBetaFeaturesEnabled && showScannerIcon && isScannerLicenseConfigured() && onScanRequest && _jsx(TMButton, { btnStyle: 'icon', caption: 'Scanner', color: 'primary', onClick: () => { onScanRequest((file) => { onFileUpload?.(file); }); }, icon: _jsx(IconScanner, { fontSize: 22 }) }), isBetaFeaturesEnabled && showScannerIcon && isScannerLicenseConfigured() && !onScanRequest && _jsx(TMButton, { btnStyle: 'icon', caption: 'Scanner', color: 'primary', onClick: () => { ShowAlert({ message: 'Funzionalità scanner non disponibile in questo contesto.', mode: 'info', duration: 3000, title: 'Scanner' }); }, 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
100
  _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
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})` })] }) })] });
89
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] }));
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);
103
+ const toolbar = useMemo(() => {
104
+ return (_jsxs(_Fragment, { children: [(isPdfEditorAvailable(fromDTD, fileExt) && openPdfEditor) && (_jsx(TMCommandsContextMenu, { target: "#TMPanel-FileUploader-Commands-Header", menuItems: [
105
+ {
106
+ icon: _jsx(IconEdit, {}),
107
+ text: 'PDF Editor',
108
+ onClick: () => openPdfEditor(fromDTD, uploadedFile, handleFile)
109
+ }
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
+ }, [deviceType, fromDTD, onClose]);
112
+ 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
113
  };
92
114
  const UploadContainer = styled.div `
93
115
  position: relative;
@@ -3,7 +3,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
3
3
  import { DcmtTypeListCacheService, SDK_Localizator } from '@topconsultnpm/sdk-ts';
4
4
  import TMRelationViewer from './TMRelationViewer';
5
5
  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';
6
+ import { IconMultipleSelection, IconCheckFile, IconDetailDcmts, SDKUI_Localizator, IconMenuVertical, IconDataList, IconPreview, IconSearchCheck, IconBoard, IconDcmtTypeSys, IconShow, getMoreInfoTasksForDocument } from '../../../helper';
7
7
  import { FormModes, SearchResultContext } from '../../../ts';
8
8
  import { TMColors } from '../../../utils/theme';
9
9
  import ShowAlert from '../../base/TMAlert';
@@ -14,14 +14,15 @@ 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 '../..';
17
18
  const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, deviceType, inputDcmts, isForMaster, showCurrentDcmtIndicator = true, allowNavigation, canNext, canPrev, onNext, onPrev, onBack, appendMasterDcmts, onTaskCreateRequest }) => {
18
- const [id, setID] = useState('');
19
19
  const [focusedItem, setFocusedItem] = useState();
20
20
  const [selectedItems, setSelectedItems] = useState([]);
21
21
  const [showZeroDcmts, setShowZeroDcmts] = useState(false);
22
22
  const [allowMultipleSelection, setAllowMultipleSelection] = useState(false);
23
23
  const [dtdMaster, setDtdMaster] = useState();
24
- useEffect(() => { setID(genUniqueId()); }, []);
24
+ const [noRelationsOnFirstLoad, setNoRelationsOnFirstLoad] = useState(false);
25
+ const [isCheckingFirstLoad, setIsCheckingFirstLoad] = useState(true);
25
26
  // Load dtdMaster when inputDcmts changes
26
27
  useEffect(() => {
27
28
  const loadDtdMaster = async () => {
@@ -40,10 +41,31 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
40
41
  }, [inputDcmts?.length, inputDcmts?.[0]?.TID, isForMaster]);
41
42
  const handleFocusedItemChanged = useCallback((item) => {
42
43
  setFocusedItem(item);
44
+ if (item) {
45
+ setIsCheckingFirstLoad(false);
46
+ }
43
47
  }, []);
44
48
  const handleSelectedItemsChanged = useCallback((items) => {
45
49
  setSelectedItems(items);
46
50
  }, []);
51
+ const handleNoRelationsFound = useCallback(() => {
52
+ if (isCheckingFirstLoad) {
53
+ setNoRelationsOnFirstLoad(true);
54
+ }
55
+ }, [isCheckingFirstLoad]);
56
+ // Show warning alert and navigate back when no relations found on first load
57
+ useEffect(() => {
58
+ if (noRelationsOnFirstLoad) {
59
+ setNoRelationsOnFirstLoad(false);
60
+ ShowAlert({
61
+ message: SDKUI_Localizator.RelatedDcmtsNotFound,
62
+ title: SDKUI_Localizator.RelationsNotFound,
63
+ duration: 3000,
64
+ mode: 'warning',
65
+ });
66
+ onBack?.();
67
+ }
68
+ }, [noRelationsOnFirstLoad, onBack]);
47
69
  const commandsMenuItems = [
48
70
  {
49
71
  icon: _jsx(IconMultipleSelection, { color: allowMultipleSelection ? TMColors.tertiary : TMColors.text_normal }),
@@ -66,85 +88,9 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
66
88
  onClick: () => {
67
89
  appendMasterDcmts?.(focusedItem?.tid, focusedItem?.did);
68
90
  }
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
91
  }
146
92
  ];
147
- 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' }) })] });
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' }) })] });
148
94
  const getTitle = () => isForMaster ? `${SDKUI_Localizator.DcmtsMaster} - ${dtdMaster?.nameLoc}` : SDKUI_Localizator.DcmtsDetail;
149
95
  const isMobile = deviceType === DeviceType.MOBILE;
150
96
  const tmTreeView = useMemo(() => _jsx(_Fragment, { children: !inputDcmts || inputDcmts.length === 0
@@ -153,7 +99,7 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
153
99
  :
154
100
  _jsx(TMRelationViewerWrapper, { inputDcmts: inputDcmts, isForMaster: isForMaster, showCurrentDcmtIndicator: showCurrentDcmtIndicator, showZeroDcmts: showZeroDcmts,
155
101
  // customItemRender={customItemRender}
156
- allowMultipleSelection: allowMultipleSelection, focusedItem: focusedItem, selectedItems: selectedItems, onFocusedItemChanged: handleFocusedItemChanged, onSelectedItemsChanged: handleSelectedItemsChanged }) }), [inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, allowMultipleSelection, focusedItem, selectedItems, handleFocusedItemChanged, handleSelectedItemsChanged]);
102
+ allowMultipleSelection: allowMultipleSelection, focusedItem: focusedItem, selectedItems: selectedItems, onFocusedItemChanged: handleFocusedItemChanged, onSelectedItemsChanged: handleSelectedItemsChanged, onNoRelationsFound: handleNoRelationsFound }) }), [inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, allowMultipleSelection, focusedItem, selectedItems, handleFocusedItemChanged, handleSelectedItemsChanged, handleNoRelationsFound]);
157
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]);
158
104
  const initialPanelDimensions = {
159
105
  'tmTreeView': { width: '50%', height: '100%' },
@@ -231,7 +177,7 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
231
177
  toolbarOptions: { icon: _jsx(IconSearchCheck, { fontSize: 24 }), visible: false, orderNumber: 2, isActive: allInitialPanelVisibility['tmFormOrResult'] }
232
178
  }
233
179
  ], [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 }) }));
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 }) }) })] }));
235
181
  };
236
182
  export default TMMasterDetailDcmts;
237
183
  /**
@@ -240,7 +186,7 @@ export default TMMasterDetailDcmts;
240
186
  * - Panel visibility toggling
241
187
  * - Focus delay handling
242
188
  */
243
- const TMRelationViewerWrapper = ({ inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, customItemRender, allowMultipleSelection, focusedItem, selectedItems, onFocusedItemChanged, onSelectedItemsChanged }) => {
189
+ const TMRelationViewerWrapper = ({ inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, customItemRender, allowMultipleSelection, focusedItem, selectedItems, onFocusedItemChanged, onSelectedItemsChanged, onNoRelationsFound }) => {
244
190
  const { setPanelVisibilityById, setToolbarButtonVisibility } = useTMPanelManagerContext();
245
191
  // Handle focused item changes with panel visibility management
246
192
  const handleFocusedItemChanged = useCallback((item) => {
@@ -259,7 +205,7 @@ const TMRelationViewerWrapper = ({ inputDcmts, isForMaster, showCurrentDcmtIndic
259
205
  setToolbarButtonVisibility('tmDcmtForm', false);
260
206
  }
261
207
  }, [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 }));
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 }));
263
209
  };
264
210
  const TMFormOrResultWrapper = ({ deviceType, focusedItem, onTaskCreateRequest, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers }) => {
265
211
  const { setPanelVisibilityById } = useTMPanelManagerContext();
@@ -267,7 +213,7 @@ const TMFormOrResultWrapper = ({ deviceType, focusedItem, onTaskCreateRequest, a
267
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: () => {
268
214
  setPanelVisibilityById('tmTreeView', true);
269
215
  }, 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: () => {
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: () => {
271
217
  setPanelVisibilityById('tmTreeView', true);
272
218
  }, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }) }));
273
219
  };
@@ -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