@topconsultnpm/sdkui-react 6.20.0-dev1.11 → 6.20.0-dev1.110

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 (175) hide show
  1. package/lib/assets/Toppy-help-center.png +0 -0
  2. package/lib/assets/headergradient.svg +87 -0
  3. package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +285 -28
  4. package/lib/components/NewComponents/ContextMenu/hooks.d.ts +8 -1
  5. package/lib/components/NewComponents/ContextMenu/hooks.js +80 -8
  6. package/lib/components/NewComponents/ContextMenu/index.d.ts +3 -0
  7. package/lib/components/NewComponents/ContextMenu/index.js +2 -0
  8. package/lib/components/NewComponents/ContextMenu/styles.d.ts +9 -1
  9. package/lib/components/NewComponents/ContextMenu/styles.js +157 -37
  10. package/lib/components/NewComponents/ContextMenu/types.d.ts +14 -1
  11. package/lib/components/NewComponents/ContextMenu/useLongPress.d.ts +21 -0
  12. package/lib/components/NewComponents/ContextMenu/useLongPress.js +112 -0
  13. package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.js +563 -112
  14. package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +21 -5
  15. package/lib/components/NewComponents/FloatingMenuBar/styles.js +210 -58
  16. package/lib/components/NewComponents/FloatingMenuBar/types.d.ts +8 -2
  17. package/lib/components/base/TMAccordionNew.js +35 -14
  18. package/lib/components/base/TMCustomButton.js +61 -17
  19. package/lib/components/base/TMDataGrid.d.ts +7 -4
  20. package/lib/components/base/TMDataGrid.js +153 -11
  21. package/lib/components/base/TMDropDownMenu.js +19 -18
  22. package/lib/components/base/TMFileManager.d.ts +4 -3
  23. package/lib/components/base/TMFileManager.js +32 -24
  24. package/lib/components/base/TMFileManagerDataGridView.d.ts +3 -2
  25. package/lib/components/base/TMFileManagerDataGridView.js +1 -11
  26. package/lib/components/base/TMFileManagerThumbnailItems.d.ts +7 -1
  27. package/lib/components/base/TMFileManagerThumbnailItems.js +5 -2
  28. package/lib/components/base/TMFileManagerThumbnailsView.d.ts +17 -4
  29. package/lib/components/base/TMFileManagerThumbnailsView.js +18 -6
  30. package/lib/components/base/TMFileManagerUtils.d.ts +0 -12
  31. package/lib/components/base/TMListView.js +33 -15
  32. package/lib/components/base/TMPanel.d.ts +1 -1
  33. package/lib/components/base/TMPanel.js +1 -1
  34. package/lib/components/choosers/TMDistinctValues.js +2 -2
  35. package/lib/components/choosers/TMInvoiceRetrieveFormats.js +1 -1
  36. package/lib/components/choosers/TMMetadataChooser.js +8 -1
  37. package/lib/components/choosers/TMOrderRetrieveFormats.js +1 -1
  38. package/lib/components/choosers/TMUserChooser.d.ts +0 -5
  39. package/lib/components/choosers/TMUserChooser.js +25 -45
  40. package/lib/components/editors/TMDateBox.js +18 -9
  41. package/lib/components/editors/TMLocalizedTextBox.d.ts +3 -1
  42. package/lib/components/editors/TMLocalizedTextBox.js +16 -14
  43. package/lib/components/editors/TMMetadataTextBox.d.ts +9 -0
  44. package/lib/components/editors/TMMetadataTextBox.js +92 -0
  45. package/lib/components/editors/TMMetadataValues.js +23 -5
  46. package/lib/components/editors/TMTextArea.js +18 -30
  47. package/lib/components/editors/TMTextBox.d.ts +1 -1
  48. package/lib/components/editors/TMTextBox.js +6 -3
  49. package/lib/components/editors/TMTextExpression.js +6 -91
  50. package/lib/components/features/archive/TMArchive.js +2 -2
  51. package/lib/components/features/assistant/TMToppyDraggableHelpCenter.d.ts +15 -0
  52. package/lib/components/features/assistant/TMToppyDraggableHelpCenter.js +460 -0
  53. package/lib/components/features/assistant/TMToppySpeechBubble.d.ts +11 -0
  54. package/lib/components/features/assistant/TMToppySpeechBubble.js +126 -0
  55. package/lib/components/features/documents/TMDcmtForm.d.ts +14 -2
  56. package/lib/components/features/documents/TMDcmtForm.js +457 -206
  57. package/lib/components/features/documents/TMDcmtPreview.js +44 -110
  58. package/lib/components/features/documents/TMDcmtTasks.js +9 -9
  59. package/lib/components/features/documents/TMMasterDetailDcmts.js +38 -53
  60. package/lib/components/features/documents/TMRelationViewer.d.ts +1 -1
  61. package/lib/components/features/documents/TMRelationViewer.js +2 -2
  62. package/lib/components/features/search/TMDcmtCheckoutInfoForm.d.ts +8 -0
  63. package/lib/components/features/search/{TMSearchResultCheckoutInfoForm.js → TMDcmtCheckoutInfoForm.js} +2 -2
  64. package/lib/components/features/search/TMSavedQuerySelector.js +72 -67
  65. package/lib/components/features/search/TMSearch.d.ts +3 -0
  66. package/lib/components/features/search/TMSearch.js +50 -11
  67. package/lib/components/features/search/TMSearchQueryPanel.d.ts +1 -0
  68. package/lib/components/features/search/TMSearchQueryPanel.js +29 -21
  69. package/lib/components/features/search/TMSearchResult.d.ts +3 -0
  70. package/lib/components/features/search/TMSearchResult.js +208 -250
  71. package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +3 -3
  72. package/lib/components/features/search/TMSearchResultsMenuItems.js +205 -169
  73. package/lib/components/features/search/TMSignSettingsForm.js +1 -1
  74. package/lib/components/features/search/TMSignatureInfoContent.d.ts +6 -0
  75. package/lib/components/features/search/TMSignatureInfoContent.js +140 -0
  76. package/lib/components/features/search/TMViewHistoryDcmt.js +2 -2
  77. package/lib/components/features/tasks/TMTaskForm.js +20 -1
  78. package/lib/components/features/tasks/TMTasksAgenda.d.ts +3 -1
  79. package/lib/components/features/tasks/TMTasksAgenda.js +48 -9
  80. package/lib/components/features/tasks/TMTasksCalendar.d.ts +2 -0
  81. package/lib/components/features/tasks/TMTasksCalendar.js +19 -7
  82. package/lib/components/features/tasks/TMTasksUtils.d.ts +2 -2
  83. package/lib/components/features/tasks/TMTasksUtils.js +43 -36
  84. package/lib/components/features/tasks/TMTasksView.js +28 -19
  85. package/lib/components/features/workflow/TMWorkflowPopup.d.ts +33 -2
  86. package/lib/components/features/workflow/TMWorkflowPopup.js +139 -34
  87. package/lib/components/features/workflow/diagram/DiagramItemComponent.d.ts +2 -0
  88. package/lib/components/features/workflow/diagram/DiagramItemComponent.js +12 -7
  89. package/lib/components/features/workflow/diagram/DiagramItemForm.js +1 -1
  90. package/lib/components/features/workflow/diagram/RecipientList.js +3 -2
  91. package/lib/components/features/workflow/diagram/WFDiagram.d.ts +4 -0
  92. package/lib/components/features/workflow/diagram/WFDiagram.js +164 -13
  93. package/lib/components/forms/Login/LoginValidatorService.d.ts +2 -0
  94. package/lib/components/forms/Login/LoginValidatorService.js +7 -2
  95. package/lib/components/forms/Login/TMLoginForm.js +34 -6
  96. package/lib/components/forms/TMChooserForm.js +1 -1
  97. package/lib/components/grids/TMBlogsPost.js +56 -31
  98. package/lib/components/grids/TMRecentsManager.js +20 -10
  99. package/lib/components/index.d.ts +6 -3
  100. package/lib/components/index.js +6 -3
  101. package/lib/components/query/TMQueryEditor.d.ts +2 -1
  102. package/lib/components/query/TMQueryEditor.js +92 -92
  103. package/lib/components/settings/SettingsAppearance.d.ts +2 -1
  104. package/lib/components/settings/SettingsAppearance.js +99 -30
  105. package/lib/components/sidebar/TMHeader.js +7 -7
  106. package/lib/components/sidebar/TMSidebar.d.ts +0 -1
  107. package/lib/components/sidebar/TMSidebar.js +16 -44
  108. package/lib/components/sidebar/TMSidebarItem.js +34 -17
  109. package/lib/components/viewers/TMDataListItemViewer.d.ts +2 -1
  110. package/lib/components/viewers/TMDataListItemViewer.js +35 -71
  111. package/lib/components/viewers/TMDataUserIdItemViewer.d.ts +8 -0
  112. package/lib/components/viewers/TMDataUserIdItemViewer.js +39 -0
  113. package/lib/css/tm-sdkui.css +1 -1
  114. package/lib/helper/SDKUI_Globals.d.ts +22 -0
  115. package/lib/helper/SDKUI_Globals.js +10 -1
  116. package/lib/helper/SDKUI_Localizator.d.ts +17 -1
  117. package/lib/helper/SDKUI_Localizator.js +167 -1
  118. package/lib/helper/TMCommandsContextMenu.d.ts +4 -2
  119. package/lib/helper/TMCommandsContextMenu.js +15 -4
  120. package/lib/helper/TMIcons.d.ts +4 -0
  121. package/lib/helper/TMIcons.js +13 -3
  122. package/lib/helper/TMPdfViewer.d.ts +8 -0
  123. package/lib/helper/TMPdfViewer.js +373 -0
  124. package/lib/helper/checkinCheckoutManager.d.ts +31 -1
  125. package/lib/helper/checkinCheckoutManager.js +112 -30
  126. package/lib/helper/devextremeCustomMessages.d.ts +30 -0
  127. package/lib/helper/devextremeCustomMessages.js +30 -0
  128. package/lib/helper/helpers.d.ts +28 -1
  129. package/lib/helper/helpers.js +130 -3
  130. package/lib/helper/index.d.ts +2 -0
  131. package/lib/helper/index.js +2 -0
  132. package/lib/helper/queryHelper.d.ts +1 -1
  133. package/lib/helper/queryHelper.js +33 -3
  134. package/lib/helper/workItemsHelper.d.ts +6 -0
  135. package/lib/helper/workItemsHelper.js +230 -0
  136. package/lib/hooks/useCheckInOutOperations.d.ts +28 -0
  137. package/lib/hooks/useCheckInOutOperations.js +223 -0
  138. package/lib/hooks/useDataListItem.d.ts +12 -0
  139. package/lib/hooks/useDataListItem.js +132 -0
  140. package/lib/hooks/useDataUserIdItem.d.ts +10 -0
  141. package/lib/hooks/useDataUserIdItem.js +96 -0
  142. package/lib/hooks/useMetadataExpression.d.ts +19 -0
  143. package/lib/hooks/useMetadataExpression.js +99 -0
  144. package/lib/hooks/useSettingsFeedback.d.ts +11 -0
  145. package/lib/hooks/useSettingsFeedback.js +38 -0
  146. package/lib/hooks/useWorkflowApprove.d.ts +4 -0
  147. package/lib/hooks/useWorkflowApprove.js +14 -1
  148. package/lib/index.d.ts +1 -0
  149. package/lib/index.js +3 -2
  150. package/lib/services/platform_services.d.ts +3 -3
  151. package/lib/ts/types.d.ts +61 -1
  152. package/lib/utils/theme.d.ts +1 -1
  153. package/lib/utils/theme.js +1 -1
  154. package/package.json +7 -4
  155. package/lib/components/NewComponents/Notification/Notification.d.ts +0 -4
  156. package/lib/components/NewComponents/Notification/Notification.js +0 -60
  157. package/lib/components/NewComponents/Notification/NotificationContainer.d.ts +0 -8
  158. package/lib/components/NewComponents/Notification/NotificationContainer.js +0 -33
  159. package/lib/components/NewComponents/Notification/index.d.ts +0 -2
  160. package/lib/components/NewComponents/Notification/index.js +0 -2
  161. package/lib/components/NewComponents/Notification/styles.d.ts +0 -21
  162. package/lib/components/NewComponents/Notification/styles.js +0 -180
  163. package/lib/components/NewComponents/Notification/types.d.ts +0 -18
  164. package/lib/components/NewComponents/Notification/types.js +0 -1
  165. package/lib/components/base/TMContextMenu.d.ts +0 -25
  166. package/lib/components/base/TMContextMenu.js +0 -109
  167. package/lib/components/base/TMContextMenuOLD.d.ts +0 -26
  168. package/lib/components/base/TMContextMenuOLD.js +0 -56
  169. package/lib/components/base/TMFloatingToolbar.d.ts +0 -9
  170. package/lib/components/base/TMFloatingToolbar.js +0 -101
  171. package/lib/components/features/assistant/ToppyDraggableHelpCenter.d.ts +0 -30
  172. package/lib/components/features/assistant/ToppyDraggableHelpCenter.js +0 -482
  173. package/lib/components/features/assistant/ToppySpeechBubble.d.ts +0 -9
  174. package/lib/components/features/assistant/ToppySpeechBubble.js +0 -117
  175. package/lib/components/features/search/TMSearchResultCheckoutInfoForm.d.ts +0 -8
@@ -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 { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useCallback, useEffect, useMemo, useState } from "react";
3
3
  import { DownloadTypes, FormModes } from "../../../ts/types";
4
- import { associateColumnsToRows, calcResponsiveSizes, formatBytes, getExceptionMessage, Globalization, SDKUI_Localizator } from "../../../helper";
4
+ import { associateColumnsToRows, calcResponsiveSizes, formatBytes, getExceptionMessage, getMoreInfoTasksForDocument, Globalization, SDKUI_Localizator } from "../../../helper";
5
5
  import TMModal from "../../base/TMModal";
6
6
  import { DeleteEngine, ResultTypes, SDK_Globals, UpdateEngineByID, UserListCacheService } from "@topconsultnpm/sdk-ts";
7
7
  import TMSpinner from "../../base/TMSpinner";
@@ -280,6 +280,6 @@ const TMViewHistoryDcmt = (props) => {
280
280
  ]);
281
281
  }, [showId]);
282
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 })] }) }) });
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)) })] }) }) });
284
284
  };
285
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;
@@ -1,3 +1,4 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
1
2
  import { Task_States, PdGs, Priorities, ValidationItem, SDK_Localizator, ResultTypes, SDK_Globals } from '@topconsultnpm/sdk-ts';
2
3
  import { TMColors } from '../../../utils/theme';
3
4
  import { SDKUI_Localizator } from '../../../helper';
@@ -399,59 +400,65 @@ export const areDifferentIDs = (fromID, userID) => {
399
400
  export const createTasksMenuItems = (taskDescriptor, showId, setShowId, showSearch, setShowSearch, openTaskForm, openEditTaskForm, openDuplicateTaskForm, onDeleteCallback, markAsStatus, getAllTasks, fromWG, showContextualWG, setShowContextualWG, fromDossier, showContextualDossier, setShowContextualDossier, fromDocument, showContextualDocument, setShowContextualDocument, showGoToToday, handleGoToToday, fromDatagrid = true) => {
400
401
  const isTaskDescriptorDefined = taskDescriptor !== undefined;
401
402
  const isTaskFromAnotherUser = isTaskDescriptorDefined && areDifferentIDs(taskDescriptor.fromID, SDK_Globals.tmSession?.SessionDescr?.userID);
403
+ const getRowIdsAsArray = (rowIds) => {
404
+ if (fromDatagrid) {
405
+ return Array.isArray(rowIds) ? rowIds : [rowIds];
406
+ }
407
+ return taskDescriptor?.id ? [taskDescriptor.id] : [];
408
+ };
402
409
  const menuItems = [
403
410
  {
404
411
  id: 'createContextualTask',
405
- text: SDKUI_Localizator.CreateContextualTask,
406
- icon: 'plus',
412
+ name: SDKUI_Localizator.CreateContextualTask,
413
+ icon: _jsx("span", { className: "dx-icon-plus" }),
407
414
  onClick: () => { openTaskForm(FormModes.Create, undefined, true); },
408
415
  disabled: false
409
416
  },
410
417
  {
411
- text: SDKUI_Localizator.Create,
412
- icon: 'plus',
418
+ name: SDKUI_Localizator.Create,
419
+ icon: _jsx("span", { className: "dx-icon-plus" }),
413
420
  onClick: () => { openTaskForm(FormModes.Create, undefined, false); },
414
421
  disabled: false
415
422
  },
416
423
  {
417
- text: SDKUI_Localizator.Update,
418
- icon: 'edit',
419
- onClick: openEditTaskForm,
424
+ name: SDKUI_Localizator.Update,
425
+ icon: _jsx("span", { className: "dx-icon-edit" }),
426
+ onClick: (rowId) => openEditTaskForm(fromDatagrid ? rowId : taskDescriptor?.id),
420
427
  operationType: 'singleRow',
421
428
  disabled: fromDatagrid ? false : !isTaskDescriptorDefined
422
429
  },
423
430
  {
424
- text: SDKUI_Localizator.Duplicate,
425
- icon: 'copy',
426
- onClick: openDuplicateTaskForm,
431
+ name: SDKUI_Localizator.Duplicate,
432
+ icon: _jsx("span", { className: "dx-icon-copy" }),
433
+ onClick: (rowId) => openDuplicateTaskForm(fromDatagrid ? rowId : taskDescriptor?.id),
427
434
  operationType: 'singleRow',
428
435
  disabled: fromDatagrid ? isTaskFromAnotherUser : !isTaskDescriptorDefined || isTaskFromAnotherUser
429
436
  },
430
437
  {
431
- text: SDKUI_Localizator.Delete,
432
- icon: 'trash',
433
- onClick: onDeleteCallback,
438
+ name: SDKUI_Localizator.Delete,
439
+ icon: _jsx("span", { className: "dx-icon-trash" }),
440
+ onClick: (rowIds) => onDeleteCallback(getRowIdsAsArray(rowIds)),
434
441
  operationType: 'multiRow',
435
442
  disabled: fromDatagrid ? isTaskFromAnotherUser : !isTaskDescriptorDefined || isTaskFromAnotherUser
436
443
  },
437
444
  {
438
- icon: 'optionsgear',
439
- text: SDKUI_Localizator.MarkAs,
445
+ icon: _jsx("span", { className: "dx-icon-optionsgear" }),
446
+ name: SDKUI_Localizator.MarkAs,
440
447
  id: "markAs",
441
448
  operationType: 'multiRow',
442
449
  disabled: fromDatagrid ? false : !isTaskDescriptorDefined,
443
- items: [
444
- { icon: 'product', text: SDKUI_Localizator.NewFemale, operationType: 'multiRow', onClick: (rowIds) => markAsStatus(rowIds, Task_States.NotStarted) },
445
- { icon: 'refresh', text: SDKUI_Localizator.InProgress, operationType: 'multiRow', onClick: (rowIds) => markAsStatus(rowIds, Task_States.InProgress) },
446
- { icon: 'check', text: SDKUI_Localizator.Completed, operationType: 'multiRow', onClick: (rowIds) => markAsStatus(rowIds, Task_States.Completed) },
447
- { icon: 'taskstop', text: SDKUI_Localizator.Pending, operationType: 'multiRow', onClick: (rowIds) => markAsStatus(rowIds, Task_States.Waiting) },
448
- { icon: 'clock', text: SDKUI_Localizator.Postponed, operationType: 'multiRow', onClick: (rowIds) => markAsStatus(rowIds, Task_States.Deferred) }
450
+ submenu: [
451
+ { icon: _jsx("span", { className: "dx-icon-product" }), name: SDKUI_Localizator.NewFemale, operationType: 'multiRow', onClick: (rowIds) => markAsStatus(getRowIdsAsArray(rowIds), Task_States.NotStarted) },
452
+ { icon: _jsx("span", { className: "dx-icon-refresh" }), name: SDKUI_Localizator.InProgress, operationType: 'multiRow', onClick: (rowIds) => markAsStatus(getRowIdsAsArray(rowIds), Task_States.InProgress) },
453
+ { icon: _jsx("span", { className: "dx-icon-check" }), name: SDKUI_Localizator.Completed, operationType: 'multiRow', onClick: (rowIds) => markAsStatus(getRowIdsAsArray(rowIds), Task_States.Completed) },
454
+ { icon: _jsx("span", { className: "dx-icon-taskstop" }), name: SDKUI_Localizator.Pending, operationType: 'multiRow', onClick: (rowIds) => markAsStatus(getRowIdsAsArray(rowIds), Task_States.Waiting) },
455
+ { icon: _jsx("span", { className: "dx-icon-clock" }), name: SDKUI_Localizator.Postponed, operationType: 'multiRow', onClick: (rowIds) => markAsStatus(getRowIdsAsArray(rowIds), Task_States.Deferred) }
449
456
  ]
450
457
  },
451
458
  {
452
459
  id: 'wgContextFilter',
453
- text: showContextualWG ? SDKUI_Localizator.RemoveContextualFilter : SDKUI_Localizator.ApplyContextualFilter,
454
- icon: 'filter',
460
+ name: showContextualWG ? SDKUI_Localizator.RemoveContextualFilter : SDKUI_Localizator.ApplyContextualFilter,
461
+ icon: _jsx("span", { className: "dx-icon-filter" }),
455
462
  onClick: () => { setShowContextualWG(prev => !prev); },
456
463
  disabled: false,
457
464
  beginGroup: true,
@@ -459,8 +466,8 @@ export const createTasksMenuItems = (taskDescriptor, showId, setShowId, showSear
459
466
  },
460
467
  {
461
468
  id: 'dossierContextFilter',
462
- text: showContextualDossier ? SDKUI_Localizator.RemoveContextualFilter : SDKUI_Localizator.ApplyContextualFilter,
463
- icon: 'filter',
469
+ name: showContextualDossier ? SDKUI_Localizator.RemoveContextualFilter : SDKUI_Localizator.ApplyContextualFilter,
470
+ icon: _jsx("span", { className: "dx-icon-filter" }),
464
471
  onClick: () => { setShowContextualDossier(prev => !prev); },
465
472
  disabled: false,
466
473
  beginGroup: !fromWG && !fromDocument,
@@ -468,38 +475,38 @@ export const createTasksMenuItems = (taskDescriptor, showId, setShowId, showSear
468
475
  },
469
476
  {
470
477
  id: 'documentContextFilter',
471
- text: showContextualDocument ? SDKUI_Localizator.RemoveContextualFilter : SDKUI_Localizator.ApplyContextualFilter,
472
- icon: 'filter',
478
+ name: showContextualDocument ? SDKUI_Localizator.RemoveContextualFilter : SDKUI_Localizator.ApplyContextualFilter,
479
+ icon: _jsx("span", { className: "dx-icon-filter" }),
473
480
  onClick: () => { setShowContextualDocument(prev => !prev); },
474
481
  disabled: false,
475
482
  beginGroup: !fromDossier && !fromWG,
476
483
  visible: fromDocument
477
484
  },
478
485
  {
479
- icon: "event",
486
+ icon: _jsx("span", { className: "dx-icon-event" }),
480
487
  onClick: () => { if (handleGoToToday) {
481
488
  handleGoToToday();
482
489
  } },
483
- text: SDKUI_Localizator.GoToToday,
490
+ name: SDKUI_Localizator.GoToToday,
484
491
  disabled: false,
485
492
  beginGroup: true,
486
493
  },
487
494
  {
488
495
  beginGroup: true,
489
- icon: showSearch ? "eyeclose" : "eyeopen",
496
+ icon: showSearch ? _jsx("span", { className: "dx-icon-eyeclose" }) : _jsx("span", { className: "dx-icon-eyeopen" }),
490
497
  onClick: () => setShowSearch(prevShowSearch => !prevShowSearch),
491
- text: showSearch ? SDKUI_Localizator.HideSearch : SDKUI_Localizator.ShowSearch,
498
+ name: showSearch ? SDKUI_Localizator.HideSearch : SDKUI_Localizator.ShowSearch,
492
499
  disabled: false
493
500
  },
494
501
  {
495
- icon: showId ? "eyeclose" : "eyeopen",
502
+ icon: showId ? _jsx("span", { className: "dx-icon-eyeclose" }) : _jsx("span", { className: "dx-icon-eyeopen" }),
496
503
  onClick: () => setShowId(prevShowId => !prevShowId),
497
- text: showId ? SDKUI_Localizator.ID_Hide : SDKUI_Localizator.ID_Show,
504
+ name: showId ? SDKUI_Localizator.ID_Hide : SDKUI_Localizator.ID_Show,
498
505
  disabled: false
499
506
  },
500
507
  {
501
- text: SDKUI_Localizator.Refresh,
502
- icon: 'refresh',
508
+ name: SDKUI_Localizator.Refresh,
509
+ icon: _jsx("span", { className: "dx-icon-refresh" }),
503
510
  onClick: () => getAllTasks(),
504
511
  disabled: false,
505
512
  },
@@ -529,7 +536,7 @@ export const createTasksMenuItems = (taskDescriptor, showId, setShowId, showSear
529
536
  item.visible === undefined);
530
537
  }
531
538
  if (showGoToToday === false) {
532
- filteredMenuItems = filteredMenuItems.filter(item => item.text !== SDKUI_Localizator.GoToToday);
539
+ filteredMenuItems = filteredMenuItems.filter(item => item.name !== SDKUI_Localizator.GoToToday);
533
540
  }
534
541
  return filteredMenuItems;
535
542
  };