@topconsultnpm/sdkui-react 6.19.0 → 6.20.0-dev1.100

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 (166) hide show
  1. package/lib/assets/Toppy-help-center.png +0 -0
  2. package/lib/components/NewComponents/ContextMenu/TMContextMenu.d.ts +4 -0
  3. package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +441 -0
  4. package/lib/components/NewComponents/ContextMenu/hooks.d.ts +18 -0
  5. package/lib/components/NewComponents/ContextMenu/hooks.js +120 -0
  6. package/lib/components/NewComponents/ContextMenu/index.d.ts +5 -0
  7. package/lib/components/NewComponents/ContextMenu/index.js +3 -0
  8. package/lib/components/NewComponents/ContextMenu/styles.d.ts +35 -0
  9. package/lib/components/NewComponents/ContextMenu/styles.js +428 -0
  10. package/lib/components/NewComponents/ContextMenu/types.d.ts +39 -0
  11. package/lib/components/NewComponents/ContextMenu/types.js +1 -0
  12. package/lib/components/NewComponents/ContextMenu/useLongPress.d.ts +21 -0
  13. package/lib/components/NewComponents/ContextMenu/useLongPress.js +112 -0
  14. package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.d.ts +4 -0
  15. package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.js +821 -0
  16. package/lib/components/NewComponents/FloatingMenuBar/index.d.ts +2 -0
  17. package/lib/components/NewComponents/FloatingMenuBar/index.js +2 -0
  18. package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +54 -0
  19. package/lib/components/NewComponents/FloatingMenuBar/styles.js +419 -0
  20. package/lib/components/NewComponents/FloatingMenuBar/types.d.ts +36 -0
  21. package/lib/components/NewComponents/FloatingMenuBar/types.js +1 -0
  22. package/lib/components/base/TMAccordion.js +2 -2
  23. package/lib/components/base/TMAccordionNew.js +35 -14
  24. package/lib/components/base/TMCustomButton.js +61 -17
  25. package/lib/components/base/TMDataGrid.d.ts +7 -4
  26. package/lib/components/base/TMDataGrid.js +153 -11
  27. package/lib/components/base/TMDropDownMenu.js +19 -18
  28. package/lib/components/base/TMFileManager.d.ts +4 -3
  29. package/lib/components/base/TMFileManager.js +32 -24
  30. package/lib/components/base/TMFileManagerDataGridView.d.ts +3 -2
  31. package/lib/components/base/TMFileManagerDataGridView.js +1 -11
  32. package/lib/components/base/TMFileManagerThumbnailItems.d.ts +7 -1
  33. package/lib/components/base/TMFileManagerThumbnailItems.js +5 -2
  34. package/lib/components/base/TMFileManagerThumbnailsView.d.ts +17 -4
  35. package/lib/components/base/TMFileManagerThumbnailsView.js +18 -6
  36. package/lib/components/base/TMFileManagerUtils.d.ts +0 -12
  37. package/lib/components/base/TMListView.js +33 -15
  38. package/lib/components/base/TMPanel.d.ts +1 -1
  39. package/lib/components/base/TMPanel.js +1 -1
  40. package/lib/components/choosers/TMDistinctValues.js +1 -1
  41. package/lib/components/choosers/TMInvoiceRetrieveFormats.js +1 -1
  42. package/lib/components/choosers/TMMetadataChooser.js +8 -1
  43. package/lib/components/choosers/TMOrderRetrieveFormats.js +1 -1
  44. package/lib/components/choosers/TMUserChooser.d.ts +0 -5
  45. package/lib/components/choosers/TMUserChooser.js +25 -45
  46. package/lib/components/editors/TMDateBox.js +18 -9
  47. package/lib/components/editors/TMHtmlEditor.js +1 -1
  48. package/lib/components/editors/TMMetadataValues.js +37 -5
  49. package/lib/components/editors/TMTextArea.js +18 -30
  50. package/lib/components/editors/TMTextBox.js +6 -3
  51. package/lib/components/features/archive/TMArchive.js +2 -2
  52. package/lib/components/features/assistant/TMToppyDraggableHelpCenter.d.ts +15 -0
  53. package/lib/components/features/assistant/TMToppyDraggableHelpCenter.js +460 -0
  54. package/lib/components/features/assistant/TMToppySpeechBubble.d.ts +11 -0
  55. package/lib/components/features/assistant/TMToppySpeechBubble.js +126 -0
  56. package/lib/components/features/documents/TMDcmtBlog.d.ts +1 -7
  57. package/lib/components/features/documents/TMDcmtBlog.js +29 -2
  58. package/lib/components/features/documents/TMDcmtForm.d.ts +14 -2
  59. package/lib/components/features/documents/TMDcmtForm.js +466 -232
  60. package/lib/components/features/documents/TMDcmtPreview.js +44 -78
  61. package/lib/components/features/documents/TMDcmtTasks.js +9 -9
  62. package/lib/components/features/documents/TMMasterDetailDcmts.js +38 -53
  63. package/lib/components/features/documents/TMRelationViewer.d.ts +1 -1
  64. package/lib/components/features/documents/TMRelationViewer.js +2 -2
  65. package/lib/components/features/search/TMDcmtCheckoutInfoForm.d.ts +8 -0
  66. package/lib/components/features/search/{TMSearchResultCheckoutInfoForm.js → TMDcmtCheckoutInfoForm.js} +6 -11
  67. package/lib/components/features/search/TMSavedQuerySelector.js +72 -67
  68. package/lib/components/features/search/TMSearch.d.ts +3 -0
  69. package/lib/components/features/search/TMSearch.js +45 -10
  70. package/lib/components/features/search/TMSearchQueryPanel.d.ts +1 -0
  71. package/lib/components/features/search/TMSearchQueryPanel.js +19 -18
  72. package/lib/components/features/search/TMSearchResult.d.ts +3 -0
  73. package/lib/components/features/search/TMSearchResult.js +229 -160
  74. package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +3 -3
  75. package/lib/components/features/search/TMSearchResultsMenuItems.js +216 -180
  76. package/lib/components/features/search/TMSignSettingsForm.js +1 -1
  77. package/lib/components/features/search/TMSignatureInfoContent.d.ts +6 -0
  78. package/lib/components/features/search/TMSignatureInfoContent.js +140 -0
  79. package/lib/components/features/search/{TMViewHistoryDcmtForm.d.ts → TMViewHistoryDcmt.d.ts} +3 -3
  80. package/lib/components/features/search/{TMViewHistoryDcmtForm.js → TMViewHistoryDcmt.js} +83 -13
  81. package/lib/components/features/tasks/TMTaskForm.js +20 -1
  82. package/lib/components/features/tasks/TMTasksAgenda.d.ts +3 -1
  83. package/lib/components/features/tasks/TMTasksAgenda.js +48 -9
  84. package/lib/components/features/tasks/TMTasksCalendar.d.ts +2 -0
  85. package/lib/components/features/tasks/TMTasksCalendar.js +19 -7
  86. package/lib/components/features/tasks/TMTasksUtils.d.ts +2 -2
  87. package/lib/components/features/tasks/TMTasksUtils.js +43 -36
  88. package/lib/components/features/tasks/TMTasksView.js +28 -19
  89. package/lib/components/features/workflow/TMWorkflowPopup.d.ts +33 -2
  90. package/lib/components/features/workflow/TMWorkflowPopup.js +139 -34
  91. package/lib/components/features/workflow/diagram/DiagramItemComponent.d.ts +2 -0
  92. package/lib/components/features/workflow/diagram/DiagramItemComponent.js +12 -7
  93. package/lib/components/features/workflow/diagram/RecipientList.js +3 -2
  94. package/lib/components/features/workflow/diagram/WFDiagram.d.ts +4 -0
  95. package/lib/components/features/workflow/diagram/WFDiagram.js +164 -13
  96. package/lib/components/forms/Login/LoginValidatorService.d.ts +2 -0
  97. package/lib/components/forms/Login/LoginValidatorService.js +7 -2
  98. package/lib/components/forms/Login/TMLoginForm.js +34 -6
  99. package/lib/components/forms/TMChooserForm.js +1 -1
  100. package/lib/components/grids/TMBlogsPost.js +56 -31
  101. package/lib/components/grids/TMRecentsManager.js +20 -10
  102. package/lib/components/index.d.ts +5 -3
  103. package/lib/components/index.js +5 -3
  104. package/lib/components/query/TMQueryEditor.d.ts +2 -1
  105. package/lib/components/query/TMQueryEditor.js +92 -92
  106. package/lib/components/settings/SettingsAppearance.d.ts +2 -1
  107. package/lib/components/settings/SettingsAppearance.js +99 -30
  108. package/lib/components/viewers/TMDataListItemViewer.d.ts +2 -1
  109. package/lib/components/viewers/TMDataListItemViewer.js +35 -71
  110. package/lib/components/viewers/TMDataUserIdItemViewer.d.ts +8 -0
  111. package/lib/components/viewers/TMDataUserIdItemViewer.js +39 -0
  112. package/lib/css/tm-sdkui.css +1 -1
  113. package/lib/helper/SDKUI_Globals.d.ts +22 -14
  114. package/lib/helper/SDKUI_Globals.js +6 -0
  115. package/lib/helper/SDKUI_Localizator.d.ts +24 -1
  116. package/lib/helper/SDKUI_Localizator.js +255 -1
  117. package/lib/helper/TMCommandsContextMenu.d.ts +4 -2
  118. package/lib/helper/TMCommandsContextMenu.js +15 -4
  119. package/lib/helper/TMIcons.d.ts +4 -0
  120. package/lib/helper/TMIcons.js +13 -3
  121. package/lib/helper/TMPdfViewer.d.ts +8 -0
  122. package/lib/helper/TMPdfViewer.js +373 -0
  123. package/lib/helper/TMUtils.d.ts +3 -1
  124. package/lib/helper/TMUtils.js +51 -0
  125. package/lib/helper/checkinCheckoutManager.d.ts +85 -0
  126. package/lib/helper/checkinCheckoutManager.js +348 -0
  127. package/lib/helper/devextremeCustomMessages.d.ts +30 -0
  128. package/lib/helper/devextremeCustomMessages.js +30 -0
  129. package/lib/helper/helpers.d.ts +3 -1
  130. package/lib/helper/helpers.js +31 -4
  131. package/lib/helper/index.d.ts +3 -0
  132. package/lib/helper/index.js +3 -0
  133. package/lib/helper/queryHelper.d.ts +1 -1
  134. package/lib/helper/queryHelper.js +46 -4
  135. package/lib/helper/workItemsHelper.d.ts +6 -0
  136. package/lib/helper/workItemsHelper.js +230 -0
  137. package/lib/hooks/useCheckInOutOperations.d.ts +28 -0
  138. package/lib/hooks/useCheckInOutOperations.js +223 -0
  139. package/lib/hooks/useDataListItem.d.ts +12 -0
  140. package/lib/hooks/useDataListItem.js +132 -0
  141. package/lib/hooks/useDataUserIdItem.d.ts +10 -0
  142. package/lib/hooks/useDataUserIdItem.js +96 -0
  143. package/lib/hooks/useSettingsFeedback.d.ts +11 -0
  144. package/lib/hooks/useSettingsFeedback.js +38 -0
  145. package/lib/hooks/useWorkflowApprove.d.ts +4 -0
  146. package/lib/hooks/useWorkflowApprove.js +14 -1
  147. package/lib/index.d.ts +1 -0
  148. package/lib/index.js +3 -2
  149. package/lib/services/platform_services.d.ts +3 -3
  150. package/lib/ts/types.d.ts +61 -1
  151. package/lib/utils/theme.d.ts +1 -1
  152. package/lib/utils/theme.js +1 -1
  153. package/package.json +55 -52
  154. package/lib/components/base/TMContextMenu.d.ts +0 -25
  155. package/lib/components/base/TMContextMenu.js +0 -109
  156. package/lib/components/base/TMContextMenuOLD.d.ts +0 -26
  157. package/lib/components/base/TMContextMenuOLD.js +0 -56
  158. package/lib/components/base/TMFloatingToolbar.d.ts +0 -9
  159. package/lib/components/base/TMFloatingToolbar.js +0 -101
  160. package/lib/components/features/assistant/ToppyDraggableHelpCenter.d.ts +0 -30
  161. package/lib/components/features/assistant/ToppyDraggableHelpCenter.js +0 -482
  162. package/lib/components/features/assistant/ToppySpeechBubble.d.ts +0 -9
  163. package/lib/components/features/assistant/ToppySpeechBubble.js +0 -117
  164. package/lib/components/features/search/TMSearchResultCheckoutInfoForm.d.ts +0 -8
  165. package/lib/helper/cicoHelper.d.ts +0 -31
  166. package/lib/helper/cicoHelper.js +0 -155
@@ -333,7 +333,7 @@ const TMSignSettingsForm = (props) => {
333
333
  fontWeight: 'bold',
334
334
  color: isModified ? MODIFIED_COLOR : '#777',
335
335
  transition: 'opacity 0.2s ease'
336
- }, onMouseEnter: (e) => { e.currentTarget.style.opacity = '0.9'; }, onMouseLeave: (e) => { e.currentTarget.style.opacity = '0.5'; }, children: "\u00D7" })] }));
336
+ }, onMouseEnter: (e) => { e.currentTarget.style.opacity = '0.9'; }, onMouseLeave: (e) => { e.currentTarget.style.opacity = '0.5'; }, children: _jsx("i", { className: "dx-icon-close" }) })] }));
337
337
  };
338
338
  const renderMultiSignerTag = (tagData) => {
339
339
  const handleRemoveTag = () => {
@@ -0,0 +1,6 @@
1
+ import { DcmtInfo } from "../../../ts";
2
+ interface TMSignatureInfoContentProps {
3
+ inputDcmt: DcmtInfo;
4
+ }
5
+ declare const TMSignatureInfoContent: (props: TMSignatureInfoContentProps) => import("react/jsx-runtime").JSX.Element | null;
6
+ export default TMSignatureInfoContent;
@@ -0,0 +1,140 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useState } from "react";
3
+ import { SDK_Globals } from "@topconsultnpm/sdk-ts";
4
+ import { IconCopy, getExceptionMessage } from "../../../helper";
5
+ import TMSpinner from "../../base/TMSpinner";
6
+ const TMSignatureInfoContent = (props) => {
7
+ const { inputDcmt } = props;
8
+ const [selectedHash, setSelectedHash] = useState('sha256');
9
+ const [signerInfo, setSignerInfo] = useState(undefined);
10
+ const [error, setError] = useState(undefined);
11
+ const [copiedHash, setCopiedHash] = useState(false);
12
+ useEffect(() => {
13
+ const fetchSignerInfo = async () => {
14
+ TMSpinner.show();
15
+ try {
16
+ const ue = SDK_Globals.tmSession?.NewUpdateEngineByID();
17
+ if (!ue) {
18
+ setError("Sessione non disponibile");
19
+ TMSpinner.hide();
20
+ return;
21
+ }
22
+ ue.TID = inputDcmt.TID;
23
+ ue.DID = inputDcmt.DID;
24
+ const signerInfoDescriptor = await ue.GetSignersAsync();
25
+ if (!signerInfoDescriptor) {
26
+ setError("Informazioni di firma non disponibili");
27
+ TMSpinner.hide();
28
+ return;
29
+ }
30
+ setSignerInfo(signerInfoDescriptor);
31
+ setError(undefined);
32
+ TMSpinner.hide();
33
+ }
34
+ catch (err) {
35
+ setError(getExceptionMessage(err));
36
+ TMSpinner.hide();
37
+ }
38
+ };
39
+ fetchSignerInfo();
40
+ }, [inputDcmt]);
41
+ const hashButtonStyle = (isActive) => ({
42
+ padding: '8px 16px',
43
+ margin: '0 2px',
44
+ border: isActive ? '2px solid #0078d4' : '1px solid #ccc',
45
+ borderRadius: '6px',
46
+ background: isActive ? '#e6f2ff' : '#fff',
47
+ color: isActive ? '#0078d4' : '#333',
48
+ cursor: 'pointer',
49
+ fontSize: '13px',
50
+ fontWeight: isActive ? '600' : '400',
51
+ transition: 'all 0.2s ease',
52
+ outline: 'none',
53
+ userSelect: 'none',
54
+ whiteSpace: 'nowrap'
55
+ });
56
+ const getHashValue = () => {
57
+ switch (selectedHash) {
58
+ case 'sha256': return signerInfo?.shA256;
59
+ case 'sha1': return signerInfo?.shA1;
60
+ case 'sha256base64': return signerInfo?.shA256Base64;
61
+ }
62
+ };
63
+ const getHashLabel = () => {
64
+ switch (selectedHash) {
65
+ case 'sha256': return 'SHA-256';
66
+ case 'sha1': return 'SHA-1';
67
+ case 'sha256base64': return 'SHA-256 (Base64)';
68
+ }
69
+ };
70
+ const copyToClipboard = async () => {
71
+ const value = getHashValue();
72
+ if (value) {
73
+ try {
74
+ await navigator.clipboard.writeText(value);
75
+ setCopiedHash(true);
76
+ setTimeout(() => setCopiedHash(false), 2000);
77
+ }
78
+ catch (err) {
79
+ console.error('Failed to copy:', err);
80
+ }
81
+ }
82
+ };
83
+ if (error) {
84
+ return (_jsx("div", { style: {
85
+ padding: '20px',
86
+ textAlign: 'center',
87
+ color: '#d32f2f',
88
+ background: '#ffebee',
89
+ borderRadius: '8px'
90
+ }, children: error }));
91
+ }
92
+ if (!signerInfo) {
93
+ return null;
94
+ }
95
+ return (_jsxs("div", { style: { lineHeight: "1.5em", overflowY: "auto", maxHeight: "500px", paddingRight: "8px", boxSizing: "border-box", userSelect: 'text' }, children: [signerInfo.signers && signerInfo.signers.length > 0 ? (_jsxs("div", { children: [_jsxs("h4", { style: { margin: '0 0 12px 0', color: '#0078d4', fontSize: '16px' }, children: ["Firme digitali (", signerInfo.signers.length, ")"] }), signerInfo.signers.map((signer, idx) => (_jsxs("div", { style: {
96
+ border: "1px solid #d0d0d0",
97
+ borderRadius: "8px",
98
+ padding: "16px",
99
+ marginBottom: "12px",
100
+ background: "linear-gradient(135deg, #ffffff 0%, #f9f9f9 100%)",
101
+ boxShadow: "0 2px 4px rgba(0,0,0,0.08)",
102
+ userSelect: 'text',
103
+ }, children: [_jsxs("h3", { style: { margin: "0 0 12px", color: "#0078d4", fontSize: '15px', fontWeight: '600' }, children: ["Firma ", signer.levelAndIndex] }), _jsxs("div", { style: {
104
+ display: 'grid',
105
+ gap: '10px',
106
+ fontSize: '13px'
107
+ }, children: [_jsxs("div", { children: [_jsx("strong", { style: { color: '#555' }, children: "Intestatario:" }), _jsx("div", { style: { marginTop: '4px', color: '#333' }, children: signer.info1 ?? '-' })] }), _jsxs("div", { children: [_jsx("strong", { style: { color: '#555' }, children: "Riferimento temporale:" }), _jsx("div", { style: { marginTop: '4px', color: '#333' }, children: signer.info2 ?? '-' })] }), _jsxs("div", { children: [_jsx("strong", { style: { color: '#555' }, children: "Dettagli:" }), _jsx("div", { style: { marginTop: '4px', color: '#333' }, children: signer.info3 ?? '-' })] })] })] }, idx)))] })) : (_jsx("div", { style: {
108
+ padding: '20px',
109
+ textAlign: 'center',
110
+ color: '#666',
111
+ background: '#f5f5f5',
112
+ borderRadius: '8px'
113
+ }, children: "Nessuna firma trovata" })), signerInfo.shA256 && (_jsxs("div", { style: {
114
+ marginBottom: '12px',
115
+ padding: '16px',
116
+ background: '#f5f5f5',
117
+ borderRadius: '8px',
118
+ border: '1px solid #e0e0e0'
119
+ }, children: [_jsxs("div", { style: { marginBottom: '12px', display: 'flex', gap: '4px', flexWrap: 'wrap' }, children: [signerInfo.shA256 && (_jsx("button", { onClick: () => setSelectedHash('sha256'), style: hashButtonStyle(selectedHash === 'sha256'), children: "SHA-256" })), signerInfo.shA1 && (_jsx("button", { onClick: () => setSelectedHash('sha1'), style: hashButtonStyle(selectedHash === 'sha1'), children: "SHA-1" })), signerInfo.shA256Base64 && (_jsx("button", { onClick: () => setSelectedHash('sha256base64'), style: hashButtonStyle(selectedHash === 'sha256base64'), children: "Base64" }))] }), _jsxs("div", { style: {
120
+ background: '#fff',
121
+ padding: '12px',
122
+ borderRadius: '6px',
123
+ wordBreak: 'break-all',
124
+ fontSize: '12px',
125
+ border: '1px solid #d0d0d0',
126
+ userSelect: 'text',
127
+ }, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '6px' }, children: [_jsxs("strong", { style: { color: '#0078d4', fontSize: '14px' }, children: [getHashLabel(), ":"] }), _jsxs("button", { onClick: copyToClipboard, style: {
128
+ background: copiedHash ? '#d4edda' : 'transparent',
129
+ border: 'none',
130
+ cursor: 'pointer',
131
+ padding: '4px 8px',
132
+ borderRadius: '4px',
133
+ display: 'flex',
134
+ alignItems: 'center',
135
+ gap: '4px',
136
+ transition: 'all 0.2s ease',
137
+ color: copiedHash ? '#155724' : '#666'
138
+ }, title: "Copia", children: [_jsx(IconCopy, { width: 16, height: 16 }), copiedHash && _jsx("span", { style: { fontSize: '11px' }, children: "Copiato" })] })] }), _jsx("div", { style: { color: '#333' }, children: getHashValue() })] })] }))] }));
139
+ };
140
+ export default TMSignatureInfoContent;
@@ -1,7 +1,7 @@
1
1
  import { DcmtInfo } from "../../../ts/types";
2
2
  import { DeviceType } from "../../base/TMDeviceProvider";
3
3
  import { DcmtTypeDescriptor, HomeBlogPost, TaskDescriptor } from "@topconsultnpm/sdk-ts";
4
- interface TMViewHistoryDcmtFormProps {
4
+ interface TMViewHistoryDcmtProps {
5
5
  fromDTD: DcmtTypeDescriptor;
6
6
  deviceType: DeviceType | undefined;
7
7
  inputDcmt: DcmtInfo;
@@ -14,5 +14,5 @@ interface TMViewHistoryDcmtFormProps {
14
14
  handleNavigateToWGs?: (value: HomeBlogPost | number) => Promise<void>;
15
15
  handleNavigateToDossiers?: (value: HomeBlogPost | number) => Promise<void>;
16
16
  }
17
- declare const TMViewHistoryDcmtForm: (props: TMViewHistoryDcmtFormProps) => import("react/jsx-runtime").JSX.Element;
18
- export default TMViewHistoryDcmtForm;
17
+ declare const TMViewHistoryDcmt: (props: TMViewHistoryDcmtProps) => import("react/jsx-runtime").JSX.Element;
18
+ export default TMViewHistoryDcmt;
@@ -1,16 +1,21 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useCallback, useEffect, useMemo, useState } from "react";
3
- import { FormModes } from "../../../ts/types";
4
- import { associateColumnsToRows, calcResponsiveSizes, formatBytes, Globalization, SDKUI_Localizator } from "../../../helper";
3
+ import { DownloadTypes, FormModes } from "../../../ts/types";
4
+ import { associateColumnsToRows, calcResponsiveSizes, formatBytes, getExceptionMessage, getMoreInfoTasksForDocument, Globalization, SDKUI_Localizator } from "../../../helper";
5
5
  import TMModal from "../../base/TMModal";
6
- import { SDK_Globals, UpdateEngineByID, UserListCacheService } from "@topconsultnpm/sdk-ts";
6
+ import { DeleteEngine, ResultTypes, SDK_Globals, UpdateEngineByID, UserListCacheService } from "@topconsultnpm/sdk-ts";
7
7
  import TMSpinner from "../../base/TMSpinner";
8
- import { TMExceptionBoxManager } from "../../base/TMPopUp";
8
+ import { ButtonNames, TMExceptionBoxManager, TMMessageBoxManager } from "../../base/TMPopUp";
9
9
  import TMDcmtIcon from "../documents/TMDcmtIcon";
10
10
  import TMDataGrid from "../../base/TMDataGrid";
11
11
  import TMDcmtForm from "../documents/TMDcmtForm";
12
- const TMViewHistoryDcmtForm = (props) => {
12
+ import { useDcmtOperations } from "../../../hooks/useDcmtOperations";
13
+ import { TMLayoutWaitingContainer } from "../../base/TMWaitPanel";
14
+ import { TMResultManager } from "../../forms/TMResultDialog";
15
+ let abortLocalController = new AbortController();
16
+ const TMViewHistoryDcmt = (props) => {
13
17
  const { deviceType, inputDcmt, onClose, fromDTD, allTasks, getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers } = props;
18
+ const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync } = useDcmtOperations();
14
19
  const [dcmtHistory, setDcmtHistory] = useState([]);
15
20
  // showId is a state variable that determines whether an ID-related component or feature should be displayed
16
21
  const [showId, setShowId] = useState(false);
@@ -28,6 +33,18 @@ const TMViewHistoryDcmtForm = (props) => {
28
33
  const [showDcmtForm, setShowDcmtForm] = useState(false);
29
34
  // Memoized value to get the selected draft based on the focused row key
30
35
  const selectedDcmt = useMemo(() => dcmtHistory.find(dcmt => dcmt.id === focusedRowKey), [focusedRowKey, dcmtHistory]);
36
+ // State variable to control the visibility of the wait panel.
37
+ const [showLocalWaitPanel, setShowLocalWaitPanel] = useState(false);
38
+ // State variable to store the title of the wait panel.
39
+ const [waitLocalPanelTitle, setWaitLocalPanelTitle] = useState('');
40
+ // State variable to control the visibility of the primary section of the wait panel.
41
+ const [showLocalPrimary, setShowLocalPrimary] = useState(false);
42
+ // State variable to store the primary text of the wait panel.
43
+ const [waitLocalPanelTextPrimary, setWaitLocalPanelTextPrimary] = useState('');
44
+ // State variable to track the current value of the primary progress indicator in the wait panel.
45
+ const [waitLocalPanelValuePrimary, setWaitLocalPanelValuePrimary] = useState(0);
46
+ // State variable to define the maximum value for the primary progress indicator in the wait panel.
47
+ const [waitLocalPanelMaxValuePrimary, setWaitLocalPanelMaxValuePrimary] = useState(0);
31
48
  const getParticipantById = (id, users) => {
32
49
  if (users.length === 0)
33
50
  return null;
@@ -111,6 +128,60 @@ const TMViewHistoryDcmtForm = (props) => {
111
128
  setSelectedIndex(-1);
112
129
  }
113
130
  }, [dcmtHistory]);
131
+ const downloadFilesCallback = async () => {
132
+ if (focusedRowKey === undefined)
133
+ return;
134
+ const focusedRow = dcmtHistory.find(dcmt => dcmt.id === focusedRowKey);
135
+ const files = [];
136
+ if (focusedRow && focusedRow.TID && focusedRow.DID && focusedRow.FileExt) {
137
+ files.push({ TID: Number(focusedRow.TID), DID: Number(focusedRow.DID), FILEEXT: focusedRow.FileExt });
138
+ }
139
+ if (files.length > 0)
140
+ await downloadDcmtsAsync(files, DownloadTypes.Dcmt, "download");
141
+ };
142
+ const deleteFilesCallback = () => {
143
+ if (!focusedRowKey)
144
+ return;
145
+ const currentDcmt = dcmtHistory.find(dcmt => dcmt.id === focusedRowKey);
146
+ if (currentDcmt && currentDcmt.id) {
147
+ const msg = SDKUI_Localizator.Delete_ConfirmFor1.replaceParams((fromDTD.name ?? SDKUI_Localizator.SearchResult) + " - DID " + currentDcmt.DID + ", " + SDKUI_Localizator.Version + ": " + currentDcmt.Version);
148
+ TMMessageBoxManager.show({
149
+ title: SDKUI_Localizator.Delete, message: msg, buttons: [ButtonNames.YES, ButtonNames.NO],
150
+ onButtonClick: async (e) => {
151
+ if (e !== ButtonNames.YES)
152
+ return;
153
+ setWaitLocalPanelTitle(SDKUI_Localizator.Delete);
154
+ setShowLocalWaitPanel(true);
155
+ setShowLocalPrimary(true);
156
+ abortLocalController = new AbortController();
157
+ let result = [];
158
+ let i = 0;
159
+ setWaitLocalPanelMaxValuePrimary(1);
160
+ if (abortLocalController.signal.aborted) {
161
+ result.push({ rowIndex: i, id1: currentDcmt.id, id2: currentDcmt.id, resultType: ResultTypes.WARNING, description: `Operazione interrotta. Elaborate ${i}` });
162
+ }
163
+ else {
164
+ setWaitLocalPanelTextPrimary(SDKUI_Localizator.Delete);
165
+ const deleteEngine = new DeleteEngine(SDK_Globals.tmSession);
166
+ await deleteEngine.PhysDeleteByIDAsync(Number(currentDcmt.TID), Number(currentDcmt.DID), false)
167
+ .then(async () => {
168
+ result.push({ rowIndex: Number(currentDcmt.TID), id1: Number(currentDcmt.TID), id2: Number(currentDcmt.DID), description: SDKUI_Localizator.DeletionCompletedSuccessfully, resultType: ResultTypes.SUCCESS });
169
+ await loadData();
170
+ })
171
+ .catch((err) => {
172
+ result.push({ rowIndex: Number(currentDcmt.TID), id1: Number(currentDcmt.TID), id2: Number(currentDcmt.DID), resultType: ResultTypes.ERROR, description: getExceptionMessage(err) });
173
+ });
174
+ }
175
+ setFocusedRowKey(undefined);
176
+ setWaitLocalPanelTextPrimary('');
177
+ setWaitLocalPanelMaxValuePrimary(0);
178
+ setWaitLocalPanelValuePrimary(0);
179
+ setShowLocalWaitPanel(false);
180
+ TMResultManager.show(result, SDKUI_Localizator.Delete, "ID", undefined);
181
+ }
182
+ });
183
+ }
184
+ };
114
185
  const cellExtRender = useCallback((cellData) => {
115
186
  const data = cellData.data;
116
187
  const tooltipContent = (_jsxs("div", { style: { textAlign: 'left' }, children: [_jsxs("div", { children: [_jsx("span", { style: { fontWeight: 'bold' }, children: "ID:" }), " ", data.id ?? '-'] }), _jsxs("div", { children: [_jsx("span", { style: { fontWeight: 'bold' }, children: "DID:" }), " ", data.DID ?? '-'] }), _jsxs("div", { children: [_jsx("span", { style: { fontWeight: 'bold' }, children: "TID:" }), " ", data.TID ?? '-'] }), _jsx("hr", {}), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Author, ":"] }), " ", data.UpdaterDisplayName ?? '-'] }), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Version, ":"] }), " ", data.Version] }), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.Size, ":"] }), " ", formatBytes(Number(data.FileSize ?? 0))] }), _jsx("hr", {}), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.CreationTime, ":"] }), " ", Globalization.getDateTimeDisplayValue(data.CreationTime)] }), _jsxs("div", { children: [_jsxs("span", { style: { fontWeight: 'bold' }, children: [SDKUI_Localizator.LastUpdateTime, ":"] }), " ", Globalization.getDateTimeDisplayValue(data.LastUpdateTime)] })] }));
@@ -128,20 +199,19 @@ const TMViewHistoryDcmtForm = (props) => {
128
199
  disabled: focusedRowKey === undefined,
129
200
  onClick: () => setShowDcmtForm(true),
130
201
  },
131
- /* {
202
+ {
132
203
  icon: "download",
133
204
  text: 'Download',
134
- tooltip: SURFER_Localizator.DownloadSelectedDraftFile,
135
205
  disabled: focusedRowKey === undefined,
136
206
  onClick: () => downloadFilesCallback(),
137
207
  },
138
208
  {
139
209
  icon: "trash",
140
210
  text: SDKUI_Localizator.Delete,
141
- disabled: isGroupArchived || focusedRowKey === undefined,
211
+ disabled: focusedRowKey === undefined,
142
212
  onClick: deleteFilesCallback,
143
213
  beginGroup: true
144
- }, */
214
+ },
145
215
  {
146
216
  icon: showSearch ? "eyeclose" : "eyeopen",
147
217
  onClick: () => setShowSearch(prevShowSearch => !prevShowSearch),
@@ -203,13 +273,13 @@ const TMViewHistoryDcmtForm = (props) => {
203
273
  return ([
204
274
  { dataField: "id", caption: "ID", dataType: 'string', visible: showId },
205
275
  { dataField: "FileExt", caption: "", cellRender: cellExtRender },
206
- { dataField: "Version", caption: "V." },
276
+ { dataField: "Version", caption: "V.", dataType: 'number' },
207
277
  { dataField: "FileSizeDisplay", caption: SDKUI_Localizator.Size },
208
278
  { dataField: "UpdaterDisplayName", caption: SDKUI_Localizator.Author },
209
279
  { dataField: "LastUpdateTimeDisplay", caption: SDKUI_Localizator.LastUpdateTime },
210
280
  ]);
211
281
  }, [showId]);
212
- return _jsxs(TMModal, { title: `${SDKUI_Localizator.SearchResult} \u2014 ${SDKUI_Localizator.History + ": " + (fromDTD.nameLoc ?? SDKUI_Localizator.Document) + " (DID:" + inputDcmt.DID})`, width: calcResponsiveSizes(deviceType, '700px', '700px', '95%'), height: calcResponsiveSizes(deviceType, '80%', '80%', '95%'), onClose: onClose, children: [_jsx(TMDataGrid, { dataSource: dcmtHistory, dataColumns: dataColumns, focusedRowKey: focusedRowKey, selection: selection, onContextMenuPreparing: onContextMenuPreparing, onFocusedRowChanged: onFocusedRowChanged, onCellDblClick: onCellDblClick, noDataText: SDKUI_Localizator.NoDataToDisplay, showSearchPanel: showSearch }), (showDcmtForm && selectedDcmt !== undefined) &&
213
- _jsx(TMDcmtForm, { TID: Number(selectedDcmt.TID), DID: Number(selectedDcmt.DID), formMode: FormModes.ReadOnly, isModal: true, widthModal: "95%", heightModal: "95%", titleModal: fromDTD.name ?? SDKUI_Localizator.SearchResult, allowNavigation: dcmtHistory.length > 0, itemIndex: selectedIndex + 1, count: dcmtHistory.length, onClose: () => { setShowDcmtForm(false); }, canNext: canNavigateHandler('next'), canPrev: canNavigateHandler('prev'), onNext: () => onNavigateHandler('next'), onPrev: () => onNavigateHandler('prev'), allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback })] });
282
+ return _jsx(TMModal, { title: `${SDKUI_Localizator.SearchResult} \u2014 ${SDKUI_Localizator.History + ": " + (fromDTD.nameLoc ?? SDKUI_Localizator.Document) + " (DID:" + inputDcmt.DID})`, width: calcResponsiveSizes(deviceType, '700px', '700px', '95%'), height: calcResponsiveSizes(deviceType, '80%', '80%', '95%'), onClose: onClose, children: _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: _jsxs(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showLocalWaitPanel, showWaitPanelPrimary: showLocalPrimary, waitPanelTitle: waitLocalPanelTitle, waitPanelTextPrimary: waitLocalPanelTextPrimary, waitPanelValuePrimary: waitLocalPanelValuePrimary, waitPanelMaxValuePrimary: waitLocalPanelMaxValuePrimary, isCancelable: true, abortController: abortLocalController, children: [_jsx(TMDataGrid, { dataSource: dcmtHistory, dataColumns: dataColumns, focusedRowKey: focusedRowKey, selection: selection, onContextMenuPreparing: onContextMenuPreparing, onFocusedRowChanged: onFocusedRowChanged, onCellDblClick: onCellDblClick, noDataText: SDKUI_Localizator.NoDataToDisplay, showSearchPanel: showSearch }), (showDcmtForm && selectedDcmt !== undefined) &&
283
+ _jsx(TMDcmtForm, { TID: Number(selectedDcmt.TID), DID: Number(selectedDcmt.DID), formMode: FormModes.ReadOnly, isModal: true, widthModal: "95%", heightModal: "95%", titleModal: fromDTD.name ?? SDKUI_Localizator.SearchResult, allowNavigation: dcmtHistory.length > 0, itemIndex: selectedIndex + 1, count: dcmtHistory.length, onClose: () => { setShowDcmtForm(false); }, canNext: canNavigateHandler('next'), canPrev: canNavigateHandler('prev'), onNext: () => onNavigateHandler('next'), onPrev: () => onNavigateHandler('prev'), allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, moreInfoTasks: getMoreInfoTasksForDocument(allTasks ?? [], Number(selectedDcmt.TID), Number(selectedDcmt.DID)) })] }) }) });
214
284
  };
215
- export default TMViewHistoryDcmtForm;
285
+ export default TMViewHistoryDcmt;
@@ -325,6 +325,25 @@ const TMTaskForm = (props) => {
325
325
  await editTaskCallback(task);
326
326
  onClose?.();
327
327
  };
328
+ const handleNavigateToReference = (ref) => {
329
+ switch (ref.objClass) {
330
+ case ObjectClasses.Dossier:
331
+ if (ref.objID)
332
+ handleNavigateToDossiers(ref.objID);
333
+ else
334
+ console.log("Dossier reference missing objID");
335
+ break;
336
+ case ObjectClasses.WorkingGroup:
337
+ if (ref.objID)
338
+ handleNavigateToWGs(ref.objID);
339
+ else
340
+ console.log("Working Group reference missing objID");
341
+ break;
342
+ // Handle other object types as needed
343
+ default:
344
+ console.warn(`Unhandled object type: ${ref.objClass}`);
345
+ }
346
+ };
328
347
  return (_jsx("div", { style: { width: "100%", height: "100%", overflow: "auto" }, ref: containerRef, children: _jsx(TMSaveForm, { width: width, height: height, id: id, title: title, isModal: isModal, formMode: formMode, onSaveAsync: saveDataAsync, onClose: onCloseCallback, onUndo: onUndoCallback, exception: exception, isModified: calcIsModified(formData, formDataOrig), validationItems: validationItems, showBackButton: showBackButton, hasNavigation: (hasNavigation && formMode !== FormModes.Create), canNext: canNext(), onNext: onNextCallback, canPrev: canPrev(), onPrev: onPrevCallback, showToolbar: !(showDcmtForm && formData?.iD1 && formData?.iD2), children: _jsxs(_Fragment, { children: [_jsx(ScrollView, { direction: "vertical", useNative: true, height: "calc(100% - 35px)", children: _jsx("div", { style: { marginRight: "5px" }, children: _jsxs(TMLayoutContainer, { direction: 'vertical', gap: 2, children: [(formMode === FormModes.Update && areDifferentIDs(formDataOrig?.fromID, SDK_Globals.tmSession?.SessionDescr?.userID)) && _jsx(TMConditionalWrapper, { condition: !isMobile, wrapper: children => _jsx("div", { style: { display: 'flex', flexDirection: 'row', width: '100%', gap: 10 }, children: children }), children: _jsxs("div", { style: { width: '100%', display: 'flex', alignItems: 'center', color: "#E29000" }, children: [_jsx("i", { className: "dx-icon-info", style: { fontSize: 20 } }), "\u00A0", _jsx("span", { children: SDKUI_Localizator.TaskAssignedMessage.replaceParams(formDataOrig?.fromName ?? '') })] }) }), taskContext?.workItem === undefined && (!areDifferentIDs(formData?.fromID, SDK_Globals.tmSession?.SessionDescr?.userID)
329
348
  && !areDifferentIDs(formData?.toID, SDK_Globals.tmSession?.SessionDescr?.userID))
330
349
  && _jsx(TMConditionalWrapper, { condition: !isMobile, wrapper: children => _jsx("div", { style: { display: 'flex', flexDirection: 'row', width: '100%', gap: 10 }, children: children }), children: _jsxs("div", { style: { width: '100%', display: 'flex', alignItems: 'center', color: "#2559A5" }, children: [_jsx("i", { className: "dx-icon-info", style: { fontSize: 20 } }), "\u00A0", _jsx("span", { children: SDKUI_Localizator.PersonalTaskAssignmentMessage })] }) }), (!areDifferentIDs(formData?.fromID, SDK_Globals.tmSession?.SessionDescr?.userID)
@@ -387,6 +406,6 @@ const TMTaskForm = (props) => {
387
406
  : _jsx(TMTextBox, { label: SDKUI_Localizator.Priority, value: getPriorityLocalizatorValue(formData?.priority ?? Priorities.Low), readOnly: true }) })] }) }), _jsx(TMConditionalWrapper, { condition: !isMobile, wrapper: children => _jsx("div", { style: { display: 'flex', flexDirection: 'row', width: '100%', gap: 10 }, children: children }), children: _jsxs(_Fragment, { children: [_jsx("div", { style: { width: isMobile ? '100%' : '50%', marginTop: 10 }, children: !fieldsReadOnly.startDate ? _jsx(TMDateBox, { id: "start-date", resetTimeToZeroOnKeyPress: false, label: SDKUI_Localizator.StartDate, dateDisplayType: DateDisplayTypes.DateTime, value: formData?.startTime, isModifiedWhen: formData?.startTime !== formDataOrig?.startTime, validationItems: validationItems?.filter(o => o.PropertyName === SDKUI_Localizator.ErrorStartEndDate), onContentReady: handleStartTimeContentReady, onValueChange: (value) => { setFormData({ ...formData ?? {}, startTime: value }); }, showClearButton: true }) : _jsx(TMTextBox, { label: SDKUI_Localizator.StartDate, value: formData?.startTime ? formatDate(formData?.startTime) : '', readOnly: true }) }), _jsx("div", { style: { width: isMobile ? '100%' : '50%', marginTop: 10 }, children: !fieldsReadOnly.startDate ? _jsx(TMDateBox, { id: "end-date", resetTimeToZeroOnKeyPress: false, label: SDKUI_Localizator.Expiration, dateDisplayType: DateDisplayTypes.DateTime, value: formData?.endTime, isModifiedWhen: formData?.endTime !== formDataOrig?.endTime, validationItems: validationItems?.filter(o => o.PropertyName === SDKUI_Localizator.ErrorStartEndDate || o.PropertyName === SDKUI_Localizator.ErrorEndRemDate), onContentReady: handleEndTimeContentReady, onValueChange: (value) => { setFormData({ ...formData ?? {}, endTime: value }); }, showClearButton: true, readOnly: fieldsReadOnly.endDate }) : _jsx(TMTextBox, { label: SDKUI_Localizator.Expiration, value: formData?.endTime ? formatDate(formData?.endTime) : '', readOnly: true }) })] }) }), _jsx(TMConditionalWrapper, { condition: !isMobile, wrapper: children => _jsx("div", { style: { display: 'flex', flexDirection: 'row', width: '100%', gap: 3 }, children: children }), children: _jsx("div", { style: { width: isMobile ? '100%' : '50%', marginTop: 10 }, children: _jsx(TMDateBox, { id: "alert-time", resetTimeToZeroOnKeyPress: false, label: SDKUI_Localizator.Reminder, dateDisplayType: DateDisplayTypes.DateTime, value: formData?.remTime ?? undefined, isModifiedWhen: formData?.remTime !== formDataOrig?.remTime, validationItems: validationItems?.filter(o => o.PropertyName === SDKUI_Localizator.ErrorEndRemDate), onValueChange: (value) => { setFormData({ ...formData ?? {}, remTime: value }); }, showClearButton: true, readOnly: fieldsReadOnly.remTime }) }) }), (formData?.state && [Task_States.Completed, Task_States.Waiting, Task_States.Deferred].includes(formData?.state) ||
388
407
  (formData?.response ?? "") !== "") && _jsx(TMConditionalWrapper, { condition: !isMobile, wrapper: children => _jsx("div", { style: { display: 'flex', flexDirection: 'row', width: '100%', gap: 3 }, children: children }), children: _jsx("div", { style: { width: isMobile ? '100%' : '50%', marginTop: 10 }, children: _jsxs(ResponseCommentWrapper, { children: [_jsx(ResponseCommentTextArea, { id: "responseId", name: "response", "$isValid": true, value: formData?.response ?? '', onChange: onAnswerChange, "$isModifiedWhen": formData?.response !== formDataOrig?.response, disabled: (formData?.response ?? "") !== "" &&
389
408
  (formData?.state && ![Task_States.Completed, Task_States.Waiting, Task_States.Deferred].includes(formData?.state)) }), _jsxs(ResponseCommentLabel, { htmlFor: "responseId", children: [SDKUI_Localizator.Answer, _jsxs(TMTooltip, { content: SDKUI_Localizator.AnswerTooltip, children: [" ", _jsx("i", { className: 'dx-icon-info' }), " "] })] }), _jsx(ResponseCommentCharacterCounter, { children: `${500 - (formData?.response ?? '').length} ${SDKUI_Localizator.CharactersRemaining}` })] }) }) })] }) }) }), (showDcmtForm && formData?.iD1 && formData?.iD2) &&
390
- _jsx(TMDcmtForm, { titleModal: formData.iD1Name ?? '-', isModal: true, TID: formData.iD1, DID: formData.iD2, allowButtonsRefs: true, taskMoreInfo: formData, onWFOperationCompleted: refreshWorkflowApprove, onTaskCompleted: onTaskCompleted, onClose: () => { setShowDcmtForm(false); }, onOpenS4TViewerRequest: onOpenS4TViewerRequest, s4TViewerDialogComponent: s4TViewerDialogComponent, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers })] }) }) }));
409
+ _jsx(TMDcmtForm, { titleModal: formData.iD1Name ?? '-', isModal: true, TID: formData.iD1, DID: formData.iD2, allowButtonsRefs: true, moreInfoTasks: [formData], onWFOperationCompleted: refreshWorkflowApprove, onTaskCompleted: onTaskCompleted, onClose: () => { setShowDcmtForm(false); }, onOpenS4TViewerRequest: onOpenS4TViewerRequest, s4TViewerDialogComponent: s4TViewerDialogComponent, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, onReferenceClick: handleNavigateToReference })] }) }) }));
391
410
  };
392
411
  export default TMTaskForm;
@@ -1,6 +1,7 @@
1
1
  import React from "react";
2
2
  import { TaskDescriptor } from "@topconsultnpm/sdk-ts";
3
3
  import { FormModes } from "../../../ts";
4
+ import { TMContextMenuItemProps } from "../../NewComponents/ContextMenu";
4
5
  interface TMTasksAgendaProps {
5
6
  id: string;
6
7
  showId: boolean;
@@ -12,6 +13,7 @@ interface TMTasksAgendaProps {
12
13
  setCurrentAgendaDate: React.Dispatch<React.SetStateAction<Date>>;
13
14
  openTaskForm: (formMode: FormModes, task?: TaskDescriptor) => void;
14
15
  handleFocusedRowChange: (row: TaskDescriptor | undefined) => void;
16
+ menuItems: TMContextMenuItemProps[];
15
17
  }
16
- declare const TMTasksAgenda: React.MemoExoticComponent<(props: TMTasksAgendaProps) => import("react/jsx-runtime").JSX.Element>;
18
+ declare const TMTasksAgenda: (props: TMTasksAgendaProps) => import("react/jsx-runtime").JSX.Element;
17
19
  export default TMTasksAgenda;
@@ -1,5 +1,5 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- import React, { useCallback, useEffect, useState } from "react";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
3
3
  import ArrayStore from "devextreme/data/array_store";
4
4
  import Scheduler from "devextreme-react/scheduler";
5
5
  import { calculateNumberOfDays, highlightTaskText, priorityLegend, renderTaskIcons } from "./TMTasksUtilsView";
@@ -11,14 +11,31 @@ import { FormModes } from "../../../ts";
11
11
  import { SDKUI_Localizator } from "../../../helper";
12
12
  import TMCustomSearchBar from "../../../helper/TMCustomSearchBar";
13
13
  import TMTooltip from "../../base/TMTooltip";
14
- const TMTasksAgenda = React.memo((props) => {
14
+ import TMContextMenu from "../../NewComponents/ContextMenu/TMContextMenu";
15
+ const MemoizedScheduler = React.memo(({ dataSource, currentAgendaDate, appointmentRender, onAppointmentDblClick, onCurrentDateChange, onAppointmentContextMenu, onAppointmentClick }) => {
15
16
  const views = ['agenda'];
16
- const { id, showId, showSearch, visualizedTasks, fromCell, toCell, currentAgendaDate, setCurrentAgendaDate, openTaskForm, handleFocusedRowChange } = props;
17
+ return (_jsx(Scheduler, { id: "tasks-agenda", defaultCurrentView: "agenda", dataSource: dataSource, width: "100%", height: "100%", editing: false, views: views, currentDate: currentAgendaDate, appointmentRender: appointmentRender, onAppointmentDblClick: onAppointmentDblClick, onCurrentDateChange: onCurrentDateChange, onAppointmentContextMenu: onAppointmentContextMenu, onAppointmentClick: onAppointmentClick }));
18
+ });
19
+ const TMTasksAgenda = (props) => {
20
+ const { id, showId, showSearch, visualizedTasks, fromCell, toCell, currentAgendaDate, setCurrentAgendaDate, openTaskForm, handleFocusedRowChange, menuItems } = props;
17
21
  const [schedulerData, setSchedulerData] = useState([]);
18
22
  const [loading, setLoading] = useState(false);
19
23
  const [searchText, setSearchText] = useState('');
24
+ const [contextMenuVisible, setContextMenuVisible] = useState(false);
25
+ const [contextMenuPosition, setContextMenuPosition] = useState({ x: 0, y: 0 });
26
+ const prevTasksRef = useRef({ length: 0 });
20
27
  useEffect(() => {
21
- setSchedulerData(convertToSchedulerAppointments(visualizedTasks));
28
+ const currentSignature = {
29
+ length: visualizedTasks.length,
30
+ firstId: visualizedTasks[0]?.id,
31
+ lastId: visualizedTasks[visualizedTasks.length - 1]?.id
32
+ };
33
+ if (prevTasksRef.current.length !== currentSignature.length ||
34
+ prevTasksRef.current.firstId !== currentSignature.firstId ||
35
+ prevTasksRef.current.lastId !== currentSignature.lastId) {
36
+ prevTasksRef.current = currentSignature;
37
+ setSchedulerData(convertToSchedulerAppointments(visualizedTasks));
38
+ }
22
39
  }, [visualizedTasks]);
23
40
  useEffect(() => {
24
41
  let timeoutId;
@@ -74,13 +91,16 @@ const TMTasksAgenda = React.memo((props) => {
74
91
  if (e === undefined || e.event === undefined || e.appointmentData.id === undefined)
75
92
  return;
76
93
  e.event.preventDefault();
94
+ e.event.stopPropagation();
77
95
  const { id } = e.appointmentData;
78
- // Update the state with the new set of selected appointments
79
96
  const task = visualizedTasks.find(task => task.id === id);
80
97
  if (task) {
81
98
  handleFocusedRowChange(task);
82
99
  }
83
- }, []);
100
+ const event = e.event;
101
+ setContextMenuPosition({ x: event.clientX, y: event.clientY });
102
+ setContextMenuVisible(true);
103
+ }, [visualizedTasks, handleFocusedRowChange]);
84
104
  const onCurrentDateChange = useCallback((value) => {
85
105
  // Exit early if it's not a valid Date
86
106
  if (!(value instanceof Date) || isNaN(value.getTime())) {
@@ -101,7 +121,26 @@ const TMTasksAgenda = React.memo((props) => {
101
121
  openTaskForm(FormModes.Update, task);
102
122
  }
103
123
  }, [visualizedTasks]);
124
+ const handleWrapperContextMenu = useCallback((e) => {
125
+ handleFocusedRowChange(undefined);
126
+ setContextMenuPosition({ x: e.clientX, y: e.clientY });
127
+ setContextMenuVisible(true);
128
+ }, [handleFocusedRowChange]);
129
+ const handleCloseContextMenu = useCallback(() => {
130
+ setContextMenuVisible(false);
131
+ }, []);
132
+ const dataSourceRef = useRef(new ArrayStore({ key: `tasks-agenda-data`, data: schedulerData }));
133
+ const dataLengthRef = useRef(0);
134
+ if (dataLengthRef.current !== schedulerData.length) {
135
+ dataLengthRef.current = schedulerData.length;
136
+ dataSourceRef.current = new ArrayStore({ key: `tasks-agenda-data`, data: schedulerData });
137
+ }
138
+ const memoizedDataSource = useMemo(() => dataSourceRef.current, [schedulerData.length]);
104
139
  return _jsxs("div", { style: { height: "100%", width: "100%" }, children: [_jsxs("div", { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', width: '100%', height: "48px" }, children: [_jsx("div", { style: { width: showSearch ? "160px" : "0", marginLeft: '10px' }, children: showSearch && (_jsx(TMCustomSearchBar, { initialValue: searchText, onSearchChange: (value) => setSearchText(value) })) }), _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: "default" }, children: _jsxs(TMTooltip, { content: priorityLegend(), children: [" ", SDKUI_Localizator.PriorityLegend] }) })] }), _jsx("div", { style: { height: "calc(100% - 48px)", width: "100%" }, children: loading ? _jsx("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", height: "100%", width: "100%" }, children: _jsx(LoadIndicator, {}) })
105
- : _jsx("div", { id: `tasks-agenda-wrapper-${id}`, style: { width: "100%", height: "100%" }, onContextMenu: () => { handleFocusedRowChange(undefined); }, onClick: () => { handleFocusedRowChange(undefined); }, children: _jsx(Scheduler, { id: "tasks-agenda", defaultCurrentView: "agenda", dataSource: new ArrayStore({ key: `tasks-agenda-data`, data: schedulerData }), width: "100%", height: "100%", editing: false, views: views, currentDate: currentAgendaDate, appointmentRender: appointmentRender, onAppointmentDblClick: handleAppointmentDblClick, onCurrentDateChange: onCurrentDateChange, onAppointmentContextMenu: onAppointmentContextMenu, onAppointmentClick: handleAppointmentClick }) }) })] });
106
- });
140
+ : _jsxs(_Fragment, { children: [_jsx(TMContextMenu, { items: menuItems, externalControl: {
141
+ visible: contextMenuVisible,
142
+ position: contextMenuPosition,
143
+ onClose: handleCloseContextMenu
144
+ } }), _jsx("div", { id: `tasks-agenda-wrapper-${id}`, style: { width: "100%", height: "100%" }, onContextMenu: handleWrapperContextMenu, children: _jsx(MemoizedScheduler, { dataSource: memoizedDataSource, currentAgendaDate: currentAgendaDate, appointmentRender: appointmentRender, onAppointmentDblClick: handleAppointmentDblClick, onCurrentDateChange: onCurrentDateChange, onAppointmentContextMenu: onAppointmentContextMenu, onAppointmentClick: handleAppointmentClick }) })] }) })] });
145
+ };
107
146
  export default TMTasksAgenda;
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { TaskDescriptor } from "@topconsultnpm/sdk-ts";
3
3
  import { FormModes } from '../../../ts';
4
+ import { TMContextMenuItemProps } from '../../NewComponents/ContextMenu/types';
4
5
  interface TMTasksCalendarProps {
5
6
  id: string;
6
7
  visualizedTasks: Array<TaskDescriptor>;
@@ -16,6 +17,7 @@ interface TMTasksCalendarProps {
16
17
  setCalendarEndDate: React.Dispatch<React.SetStateAction<Date | undefined>>;
17
18
  focusedRowKey: number | undefined;
18
19
  handleFocusedRowChange: (row: TaskDescriptor | undefined) => void;
20
+ menuItems: TMContextMenuItemProps[];
19
21
  }
20
22
  declare const TMTasksCalendar: (props: TMTasksCalendarProps) => import("react/jsx-runtime").JSX.Element;
21
23
  export default TMTasksCalendar;
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import ArrayStore from 'devextreme/data/array_store';
3
3
  import { useCallback, useEffect, useRef, useState } from 'react';
4
4
  import { Priorities, Task_States } from "@topconsultnpm/sdk-ts";
@@ -10,13 +10,15 @@ import { FormModes } from '../../../ts';
10
10
  import { SDKUI_Localizator } from '../../../helper';
11
11
  import TMTooltip from '../../base/TMTooltip';
12
12
  import TMCustomSearchBar from '../../../helper/TMCustomSearchBar';
13
+ import TMContextMenu from '../../NewComponents/ContextMenu/TMContextMenu';
13
14
  const views = ['month'];
14
- let clickTimeout = null; // Timeout reference
15
+ let clickTimeout = null;
15
16
  let clickCount = 0; // Click counter
16
17
  let lastClickedCell = null;
17
18
  const TMTasksCalendar = (props) => {
18
- const { id, visualizedTasks, showId, showSearch, fromCell, toCell, openTaskForm, onDeleteCallback, currentCalendarDate, setCurrentCalendarDate, focusedRowKey, handleFocusedRowChange, setCalendarStartDate, setCalendarEndDate } = props;
19
+ const { id, visualizedTasks, showId, showSearch, fromCell, toCell, openTaskForm, onDeleteCallback, currentCalendarDate, setCurrentCalendarDate, focusedRowKey, handleFocusedRowChange, setCalendarStartDate, setCalendarEndDate, menuItems } = props;
19
20
  const [isMobile, setIsMobile] = useState(false);
21
+ const [contextMenuControl, setContextMenuControl] = useState({ visible: false, position: { x: 0, y: 0 } });
20
22
  const mobileBreakpoint = 768;
21
23
  const [schedulerData, setSchedulerData] = useState([]);
22
24
  const [isRange, setIsRange] = useState(false);
@@ -228,13 +230,23 @@ const TMTasksCalendar = (props) => {
228
230
  }
229
231
  }
230
232
  };
231
- const onWrapperContextMenu = useCallback(() => {
232
- handleFocusedRowChange(undefined);
233
- }, []);
234
233
  const onWrapperClick = useCallback(() => {
235
234
  handleFocusedRowChange(undefined);
236
235
  }, []);
236
+ const handleWrapperContextMenu = useCallback((e) => {
237
+ setContextMenuControl({
238
+ visible: true,
239
+ position: { x: e.clientX, y: e.clientY }
240
+ });
241
+ }, []);
242
+ const handleCloseContextMenu = useCallback(() => {
243
+ setContextMenuControl(prev => ({ ...prev, visible: false }));
244
+ }, []);
237
245
  return (_jsxs("div", { style: { width: "100%", height: "100%" }, children: [_jsxs("div", { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', width: '100%', height: "48px", padding: 5 }, children: [_jsx("div", { style: { width: showSearch ? "160px" : "0", marginLeft: '10px' }, children: showSearch && (_jsx(TMCustomSearchBar, { initialValue: searchText, onSearchChange: (value) => setSearchText(value) })) }), _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: "default" }, children: _jsx(TMTooltip, { content: priorityLegend(), children: SDKUI_Localizator.PriorityLegend }) })] }), _jsx("div", { style: { height: "calc(100% - 48px)", width: "100%" }, children: loading ? _jsx("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", height: "100%", width: "100%" }, children: _jsx(LoadIndicator, {}) })
238
- : _jsx("div", { id: `tasks-calendar-wrapper-${id}`, style: { width: "100%", height: "100%" }, onContextMenu: onWrapperContextMenu, onClick: onWrapperClick, children: _jsx(Scheduler, { ref: schedulerRef, id: "tasks-calendar", dataSource: new ArrayStore({ key: 'tasks-calendar-data', data: schedulerData }), views: views, defaultCurrentView: "month", adaptivityEnabled: isMobile, editing: false, width: "100%", height: "100%", currentDate: currentCalendarDate, appointmentComponent: appointmentComponent, onAppointmentFormOpening: handleAppointmentFormOpening, appointmentTooltipComponent: appointmentTooltipComponent, onAppointmentDblClick: handleAppointmentDblClick, onCurrentDateChange: onCurrentCalendarDateChange, onAppointmentContextMenu: onAppointmentContextMenu, onCellContextMenu: onCellContextMenu, onCellClick: handleCellClick, onAppointmentClick: handleAppointmentClick, onContentReady: handleContentReady, onOptionChanged: onOptionChanged, children: _jsx(Resource, { dataSource: prioritiesResourceData, fieldExpr: "priority", label: "Priority" }) }) }) })] }));
246
+ : _jsxs(_Fragment, { children: [_jsx(TMContextMenu, { items: menuItems, externalControl: {
247
+ visible: contextMenuControl.visible,
248
+ position: contextMenuControl.position,
249
+ onClose: handleCloseContextMenu
250
+ } }), _jsx("div", { id: `tasks-calendar-wrapper-${id}`, style: { width: "100%", height: "100%" }, onContextMenu: handleWrapperContextMenu, onClick: onWrapperClick, children: _jsx(Scheduler, { ref: schedulerRef, id: "tasks-calendar", dataSource: new ArrayStore({ key: 'tasks-calendar-data', data: schedulerData }), views: views, defaultCurrentView: "month", adaptivityEnabled: isMobile, editing: false, width: "100%", height: "100%", currentDate: currentCalendarDate, appointmentComponent: appointmentComponent, onAppointmentFormOpening: handleAppointmentFormOpening, appointmentTooltipComponent: appointmentTooltipComponent, onAppointmentDblClick: handleAppointmentDblClick, onCurrentDateChange: onCurrentCalendarDateChange, onAppointmentContextMenu: onAppointmentContextMenu, onCellContextMenu: onCellContextMenu, onCellClick: handleCellClick, onAppointmentClick: handleAppointmentClick, onContentReady: handleContentReady, onOptionChanged: onOptionChanged, children: _jsx(Resource, { dataSource: prioritiesResourceData, fieldExpr: "priority", label: "Priority" }) }) })] }) })] }));
239
251
  };
240
252
  export default TMTasksCalendar;
@@ -2,7 +2,7 @@ import { Appointment } from 'devextreme/ui/scheduler';
2
2
  import { ContextMenuTypes } from 'devextreme-react/context-menu';
3
3
  import { TaskDescriptor, Task_States, PdGs, Priorities, ValidationItem } from '@topconsultnpm/sdk-ts';
4
4
  import { FormModes, TaskContext } from '../../../ts';
5
- import { TMDataGridContextMenuItem } from '../../base/TMDataGrid';
5
+ import { TMContextMenuItemProps } from '../../NewComponents/ContextMenu';
6
6
  export declare const TEXT_SELECTED_COLOR = "#ff5e1a";
7
7
  export declare const BG_COLOR_INACTIVE_WIDGET = "#fff";
8
8
  export declare const BG_COLOR_ACTIVE_WIDGET = "#fff0b7";
@@ -100,7 +100,7 @@ export declare const gotoPDGExtendedLabel: (gotoVisible: boolean, pdg: PdGs, iD1
100
100
  export declare const convertToSchedulerAppointments: (tasks: Array<TaskDescriptor>) => Array<Appointment>;
101
101
  export declare const formatDate: (date: Date) => string;
102
102
  export declare const areDifferentIDs: (fromID: number | undefined, userID: number | undefined) => boolean;
103
- export declare const createTasksMenuItems: (taskDescriptor: TaskDescriptor | undefined, showId: boolean, setShowId: React.Dispatch<React.SetStateAction<boolean>>, showSearch: boolean, setShowSearch: React.Dispatch<React.SetStateAction<boolean>>, openTaskForm: (formMode: FormModes, task?: TaskDescriptor, isContextual?: boolean) => void, openEditTaskForm: (rowId: number | undefined) => void, openDuplicateTaskForm: (rowId: number | undefined) => void, onDeleteCallback: (rowIds: Array<number>) => void, markAsStatus: (rowIds: Array<number>, status: Task_States) => void, getAllTasks: () => Promise<void>, fromWG: boolean, showContextualWG: boolean, setShowContextualWG: React.Dispatch<React.SetStateAction<boolean>>, fromDossier: boolean, showContextualDossier: boolean, setShowContextualDossier: React.Dispatch<React.SetStateAction<boolean>>, fromDocument: boolean, showContextualDocument: boolean, setShowContextualDocument: React.Dispatch<React.SetStateAction<boolean>>, showGoToToday: boolean, handleGoToToday?: () => void, fromDatagrid?: boolean) => Array<TMDataGridContextMenuItem>;
103
+ export declare const createTasksMenuItems: (taskDescriptor: TaskDescriptor | undefined, showId: boolean, setShowId: React.Dispatch<React.SetStateAction<boolean>>, showSearch: boolean, setShowSearch: React.Dispatch<React.SetStateAction<boolean>>, openTaskForm: (formMode: FormModes, task?: TaskDescriptor, isContextual?: boolean) => void, openEditTaskForm: (rowId: number | undefined) => void, openDuplicateTaskForm: (rowId: number | undefined) => void, onDeleteCallback: (rowIds: Array<number>) => void, markAsStatus: (rowIds: Array<number>, status: Task_States) => void, getAllTasks: () => Promise<void>, fromWG: boolean, showContextualWG: boolean, setShowContextualWG: React.Dispatch<React.SetStateAction<boolean>>, fromDossier: boolean, showContextualDossier: boolean, setShowContextualDossier: React.Dispatch<React.SetStateAction<boolean>>, fromDocument: boolean, showContextualDocument: boolean, setShowContextualDocument: React.Dispatch<React.SetStateAction<boolean>>, showGoToToday: boolean, handleGoToToday?: () => void, fromDatagrid?: boolean) => Array<TMContextMenuItemProps>;
104
104
  export declare const checkIfNew: (fromId: number | undefined, isNew: number | undefined) => boolean;
105
105
  export declare const getNewTaskCount: (tasks: Array<TaskDescriptor>) => number;
106
106
  export declare const isTaskAssignedToAnotherUser: (task: TaskDescriptor) => boolean;