@topconsultnpm/sdkui-react 6.21.0-t1 → 6.21.0-t2

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 (91) hide show
  1. package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +4 -4
  2. package/lib/components/base/TMAccordionNew.d.ts +1 -0
  3. package/lib/components/base/TMAccordionNew.js +6 -5
  4. package/lib/components/base/TMAreaManager.js +19 -3
  5. package/lib/components/base/TMDataGrid.js +2 -2
  6. package/lib/components/base/TMModal.d.ts +1 -0
  7. package/lib/components/base/TMModal.js +2 -2
  8. package/lib/components/base/TMPanel.d.ts +7 -4
  9. package/lib/components/base/TMPanel.js +58 -26
  10. package/lib/components/base/TMTreeView.js +12 -2
  11. package/lib/components/base/TMWaitPanel.js +7 -4
  12. package/lib/components/choosers/TMDistinctValues.js +35 -21
  13. package/lib/components/choosers/TMUserChooser.d.ts +4 -0
  14. package/lib/components/choosers/TMUserChooser.js +7 -5
  15. package/lib/components/editors/TMDateBox.js +4 -2
  16. package/lib/components/editors/TMFormulaEditor.d.ts +2 -0
  17. package/lib/components/editors/TMFormulaEditor.js +75 -21
  18. package/lib/components/editors/TMMetadataValues.js +2 -1
  19. package/lib/components/editors/TMRadioButton.js +7 -5
  20. package/lib/components/editors/TMTextArea.d.ts +2 -0
  21. package/lib/components/editors/TMTextArea.js +6 -3
  22. package/lib/components/editors/TMTextBox.d.ts +2 -0
  23. package/lib/components/editors/TMTextBox.js +3 -3
  24. package/lib/components/features/archive/TMArchive.js +1 -1
  25. package/lib/components/features/documents/TMCopyToFolderForm.d.ts +24 -0
  26. package/lib/components/features/documents/TMCopyToFolderForm.js +379 -0
  27. package/lib/components/features/documents/TMDcmtForm.d.ts +1 -0
  28. package/lib/components/features/documents/TMDcmtForm.js +147 -45
  29. package/lib/components/features/documents/TMDcmtFormActionButtons.js +259 -60
  30. package/lib/components/features/documents/TMDcmtPreview.d.ts +1 -0
  31. package/lib/components/features/documents/TMDcmtPreview.js +2 -2
  32. package/lib/components/features/documents/TMDcmtTasks.d.ts +1 -0
  33. package/lib/components/features/documents/TMDcmtTasks.js +2 -2
  34. package/lib/components/features/documents/TMDownloadRelationViewerSection.d.ts +23 -0
  35. package/lib/components/features/documents/TMDownloadRelationViewerSection.js +173 -0
  36. package/lib/components/features/documents/TMFileUploader.js +1 -1
  37. package/lib/components/features/documents/TMMasterDetailDcmts.d.ts +4 -0
  38. package/lib/components/features/documents/TMMasterDetailDcmts.js +29 -9
  39. package/lib/components/features/documents/TMMergeToPdfForm.d.ts +26 -0
  40. package/lib/components/features/documents/TMMergeToPdfForm.js +293 -0
  41. package/lib/components/features/documents/TMRelationViewer.d.ts +13 -0
  42. package/lib/components/features/documents/TMRelationViewer.js +75 -6
  43. package/lib/components/features/documents/copyAndMergeDcmtsShared.d.ts +71 -0
  44. package/lib/components/features/documents/copyAndMergeDcmtsShared.js +304 -0
  45. package/lib/components/features/search/SignatureParamsManager.d.ts +70 -0
  46. package/lib/components/features/search/SignatureParamsManager.js +145 -0
  47. package/lib/components/features/search/TMSavedQuerySelector.d.ts +2 -2
  48. package/lib/components/features/search/TMSavedQuerySelector.js +3 -2
  49. package/lib/components/features/search/TMSearch.d.ts +6 -1
  50. package/lib/components/features/search/TMSearch.js +16 -10
  51. package/lib/components/features/search/TMSearchQueryPanel.js +1 -1
  52. package/lib/components/features/search/TMSearchResult.d.ts +4 -0
  53. package/lib/components/features/search/TMSearchResult.js +118 -22
  54. package/lib/components/features/search/TMViewHistoryDcmt.js +1 -2
  55. package/lib/components/features/workflow/TMWorkflowPopup.js +3 -0
  56. package/lib/components/features/workflow/diagram/queryDescriptorParser.js +3 -6
  57. package/lib/components/forms/Login/TMLoginForm.d.ts +9 -0
  58. package/lib/components/forms/Login/TMLoginForm.js +61 -0
  59. package/lib/components/forms/TMResultDialog.d.ts +1 -1
  60. package/lib/components/forms/TMResultDialog.js +4 -2
  61. package/lib/components/grids/TMBlogAttachments.d.ts +1 -0
  62. package/lib/components/grids/TMBlogAttachments.js +38 -12
  63. package/lib/components/grids/TMBlogsPost.js +7 -1
  64. package/lib/components/grids/TMBlogsPostUtils.js +11 -17
  65. package/lib/components/index.d.ts +1 -0
  66. package/lib/components/index.js +1 -0
  67. package/lib/components/pages/TMPage.js +3 -1
  68. package/lib/components/query/TMQueryEditor.js +2 -2
  69. package/lib/components/viewers/TMTidViewer.js +1 -1
  70. package/lib/helper/GlobalStyles.js +6 -0
  71. package/lib/helper/SDKUI_Globals.d.ts +15 -0
  72. package/lib/helper/SDKUI_Globals.js +15 -1
  73. package/lib/helper/SDKUI_Localizator.d.ts +106 -2
  74. package/lib/helper/SDKUI_Localizator.js +1060 -12
  75. package/lib/helper/TMPdfViewer.js +25 -24
  76. package/lib/helper/TMUtils.d.ts +20 -0
  77. package/lib/helper/TMUtils.js +17 -0
  78. package/lib/helper/ZipManager.d.ts +56 -0
  79. package/lib/helper/ZipManager.js +127 -0
  80. package/lib/helper/index.d.ts +1 -0
  81. package/lib/helper/index.js +1 -0
  82. package/lib/hooks/useDataUserIdItem.js +6 -4
  83. package/lib/hooks/useDcmtOperations.d.ts +9 -2
  84. package/lib/hooks/useDcmtOperations.js +78 -35
  85. package/lib/hooks/useDocumentOperations.d.ts +5 -0
  86. package/lib/hooks/useDocumentOperations.js +238 -27
  87. package/lib/hooks/useForm.js +5 -2
  88. package/lib/hooks/useResizeObserver.d.ts +1 -1
  89. package/lib/hooks/useResizeObserver.js +16 -15
  90. package/lib/ts/types.d.ts +1 -0
  91. package/package.json +3 -2
@@ -1,23 +1,36 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useMemo, useRef } from "react";
2
+ import { useCallback, useMemo, useRef, useState } from "react";
3
3
  import { ObjectClasses, SDK_Globals } from "@topconsultnpm/sdk-ts";
4
- import { TASK_MORE_INFO_PREFIX_NAME, SDKUI_Localizator, PDGS_COLORS } from "../../../helper";
4
+ import { TASK_MORE_INFO_PREFIX_NAME, SDKUI_Localizator, PDGS_COLORS, calcResponsiveSizes } from "../../../helper";
5
5
  import { TMColors } from "../../../utils/theme";
6
- import { ReferencesContainer, StyledReferenceButton } from "../../base/Styled";
6
+ import { StyledReferenceButton } from "../../base/Styled";
7
7
  import TMButton from "../../base/TMButton";
8
+ import TMModal from "../../base/TMModal";
8
9
  import TMTooltip from "../../base/TMTooltip";
9
10
  import { WorkFlowOperationButtons } from "../workflow/TMWorkflowPopup";
10
11
  const TMDcmtFormActionButtons = (props) => {
11
12
  const { showToppyForApprove, workItems, deviceType, isMobile, handleSignApprove, updateShowApprovePopup, updateShowRejectPopup, updateShowReAssignPopup, updateShowMoreInfoPopup, fromDTD, showToppyForCompleteMoreInfo, moreInfoTasks, setShowCommentForm, showToppyForReferences, dcmtReferences, referenceActionMap, handleNavigateToReference, setShowMoreInfoTaskPopup, setShowMoreInfoTaskTask } = props;
13
+ const [showAllMoreInfoModal, setShowAllMoreInfoModal] = useState(false);
14
+ const [showAllDossiersModal, setShowAllDossiersModal] = useState(false);
15
+ const [showAllWorkingGroupsModal, setShowAllWorkingGroupsModal] = useState(false);
12
16
  const tasksNumber = useMemo(() => moreInfoTasks?.length ?? 0, [moreInfoTasks]);
13
- const currentTask = useMemo(() => {
17
+ const firstTask = useMemo(() => {
14
18
  if (!moreInfoTasks || moreInfoTasks.length === 0)
15
19
  return null;
16
- if (moreInfoTasks.length === 1)
17
- return moreInfoTasks[0];
18
- // If there are multiple tasks, we cannot determine which one is relevant, so we return null
19
- return null;
20
+ return moreInfoTasks[0];
20
21
  }, [moreInfoTasks]);
22
+ // Verifica se la More Info Card sarà effettivamente renderizzata (non null)
23
+ const isMoreInfoCardVisible = useMemo(() => {
24
+ if (!firstTask)
25
+ return false;
26
+ const userID = SDK_Globals.tmSession?.SessionDescr?.userID;
27
+ const isSender = firstTask?.fromID !== undefined && firstTask.fromID === userID;
28
+ const isRecipient = firstTask?.toID !== undefined && firstTask.toID === userID;
29
+ // Caso 4: L'utente è sia mittente che destinatario - la card non viene renderizzata
30
+ if (isSender && isRecipient)
31
+ return false;
32
+ return true;
33
+ }, [firstTask]);
21
34
  const { hasMoreInfo, hasApprove, hasReferences } = useMemo(() => {
22
35
  const referencesExist = showToppyForReferences && dcmtReferences?.some(ref => ref.objClass === ObjectClasses.Dossier || ref.objClass === ObjectClasses.WorkingGroup);
23
36
  return {
@@ -31,8 +44,34 @@ const TMDcmtFormActionButtons = (props) => {
31
44
  showToppyForReferences,
32
45
  dcmtReferences
33
46
  ]);
47
+ // Raggruppa references per categoria
48
+ const { dossierRefs, workingGroupRefs } = useMemo(() => {
49
+ const dossiers = dcmtReferences?.filter(ref => ref.objClass === ObjectClasses.Dossier) ?? [];
50
+ const workingGroups = dcmtReferences?.filter(ref => ref.objClass === ObjectClasses.WorkingGroup) ?? [];
51
+ return { dossierRefs: dossiers, workingGroupRefs: workingGroups };
52
+ }, [dcmtReferences]);
53
+ const refButtonMouseMoved = useRef(false);
54
+ const handleRefButtonMouseDown = useCallback(() => { refButtonMouseMoved.current = false; }, []);
55
+ const handleRefButtonMouseMove = useCallback(() => { refButtonMouseMoved.current = true; }, []);
56
+ const handleRefButtonClick = useCallback((ref) => {
57
+ if (!refButtonMouseMoved.current) {
58
+ handleNavigateToReference(ref);
59
+ }
60
+ }, [handleNavigateToReference]);
34
61
  const Divider = () => (_jsx("div", { style: { height: '1px', width: '100%', background: 'linear-gradient(to right, transparent, rgba(255,255,255,0.4), transparent)', margin: '3px 0', opacity: 0.8, } }));
35
- return _jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: '10px' }, children: [hasMoreInfo && (tasksNumber === 1 ? (_jsx("div", { style: { display: 'flex', gap: "10px", flexDirection: 'column', alignItems: 'center' }, children: _jsx("div", { style: {
62
+ const truncate = (str, maxLength) => str && str.length > maxLength ? str.substring(0, maxLength) + '...' : str;
63
+ const formatBadgeCount = (count) => count > 99 ? '99+' : `+${count}`;
64
+ const renderMoreInfoCard = (task, showOthersIndicator = false) => {
65
+ const userID = SDK_Globals.tmSession?.SessionDescr?.userID;
66
+ const isSender = task?.fromID !== undefined && task.fromID === userID;
67
+ const isRecipient = task?.toID !== undefined && task.toID === userID;
68
+ const senderNameTruncated = task?.fromName ? truncate(task.fromName, 30) : 'N/A';
69
+ const recipientNameTruncated = task?.toName ? truncate(task.toName, 30) : 'N/A';
70
+ const taskNameTrunc = task?.name ? truncate(task.name.replace(TASK_MORE_INFO_PREFIX_NAME ?? '', ''), 30) : 'N/A';
71
+ // Caso 4: L'utente è sia mittente che destinatario - non renderizzare nulla
72
+ if (isSender && isRecipient)
73
+ return null;
74
+ return (_jsxs("div", { style: { position: 'relative', display: 'flex' }, children: [_jsxs("div", { style: {
36
75
  padding: '10px',
37
76
  color: '#FFFFFF',
38
77
  maxWidth: '240px',
@@ -46,58 +85,218 @@ const TMDcmtFormActionButtons = (props) => {
46
85
  textAlign: 'center',
47
86
  gap: '10px',
48
87
  cursor: 'default',
49
- }, children: (() => {
88
+ flex: 1,
89
+ }, children: [(isSender && !isRecipient) && (_jsx(TaskLink, { messagePrefix: `Hai richiesto maggiori informazioni a "${recipientNameTruncated}" tramite l'attività`, name: task.name ?? 'N/A', taskNameTrunc: taskNameTrunc ?? 'N/A', description: task.description ?? 'N/A', currentTask: task, setShowMoreInfoTaskPopup: setShowMoreInfoTaskPopup, setShowMoreInfoTaskTask: setShowMoreInfoTaskTask })), (isRecipient && !isSender) && (_jsxs("div", { style: {
90
+ display: 'flex',
91
+ flexDirection: 'column',
92
+ alignItems: 'center',
93
+ gap: '10px'
94
+ }, children: [_jsx(TaskLink, { messagePrefix: `"${senderNameTruncated}" ti ha richiesto maggiori informazioni tramite l'attività`, name: task.name ?? 'N/A', taskNameTrunc: taskNameTrunc ?? 'N/A', description: task.description ?? 'N/A', currentTask: task, setShowMoreInfoTaskPopup: setShowMoreInfoTaskPopup, setShowMoreInfoTaskTask: setShowMoreInfoTaskTask }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx("span", { className: "dx-icon-chat" }), caption: SDKUI_Localizator.CommentAndComplete, width: "180px", disabled: false, onClick: () => setShowCommentForm(true), onMouseDown: e => e.stopPropagation(), advancedColor: TMColors.success, color: "success" })] })), (!isSender && !isRecipient) && (_jsx(TaskLink, { messagePrefix: `Richiesta maggiori informazioni tramite l'attività`, name: task.name ?? 'N/A', taskNameTrunc: taskNameTrunc ?? 'N/A', description: task.description ?? 'N/A', currentTask: task, setShowMoreInfoTaskPopup: setShowMoreInfoTaskPopup, setShowMoreInfoTaskTask: setShowMoreInfoTaskTask }))] }), showOthersIndicator && tasksNumber > 1 && ((() => {
95
+ const bgColor = '#0077BE';
96
+ const bgColorHover = '#1E90FF';
97
+ return (_jsx("div", { onClick: () => setShowAllMoreInfoModal(true), onMouseDown: e => e.stopPropagation(), style: {
98
+ position: 'absolute',
99
+ right: '-36px',
100
+ top: '50%',
101
+ transform: 'translateY(-50%)',
102
+ width: '28px',
103
+ height: '28px',
104
+ background: bgColor,
105
+ border: '2px solid rgba(255,255,255,0.5)',
106
+ borderRadius: '50%',
107
+ display: 'flex',
108
+ alignItems: 'center',
109
+ justifyContent: 'center',
110
+ cursor: 'pointer',
111
+ color: '#FFFFFF',
112
+ fontSize: '11px',
113
+ fontWeight: 700,
114
+ boxShadow: '0 2px 8px rgba(0, 0, 50, 0.3)',
115
+ transition: 'all 0.2s',
116
+ }, onMouseEnter: e => {
117
+ e.currentTarget.style.background = bgColorHover;
118
+ e.currentTarget.style.transform = 'translateY(-50%) scale(1.1)';
119
+ }, onMouseLeave: e => {
120
+ e.currentTarget.style.background = bgColor;
121
+ e.currentTarget.style.transform = 'translateY(-50%)';
122
+ }, children: formatBadgeCount(tasksNumber - 1) }));
123
+ })())] }));
124
+ };
125
+ const renderReferenceCard = (ref, allRefs, showOthersIndicator, onShowAll, onClickRef) => {
126
+ const mapEntry = referenceActionMap[String(ref.objClass)];
127
+ const label = mapEntry?.label ?? 'Vai a riferimento';
128
+ const othersCount = allRefs.length - 1;
129
+ let backgroundColor;
130
+ switch (ref.objClass) {
131
+ case ObjectClasses.WorkingGroup:
132
+ backgroundColor = PDGS_COLORS.WORKING_GROUP;
133
+ break;
134
+ case ObjectClasses.Dossier:
135
+ backgroundColor = PDGS_COLORS.DOSSIER;
136
+ break;
137
+ case ObjectClasses.Document:
138
+ backgroundColor = PDGS_COLORS.DOCUMENT;
139
+ break;
140
+ default:
141
+ backgroundColor = "#C2388B";
142
+ break;
143
+ }
144
+ return (_jsxs("div", { style: { position: 'relative', display: 'inline-flex' }, children: [_jsxs(StyledReferenceButton, { onMouseDown: handleRefButtonMouseDown, onMouseMove: handleRefButtonMouseMove, onClick: () => {
145
+ handleRefButtonClick(ref);
146
+ onClickRef?.();
147
+ }, onDoubleClick: (e) => { e.preventDefault(); e.stopPropagation(); }, "$bgColor": backgroundColor, children: [_jsx("span", { children: label }), _jsx("span", { children: `"${ref.objName}"` })] }), showOthersIndicator && othersCount > 0 && (_jsx("div", { onClick: (e) => { e.stopPropagation(); onShowAll(); }, onMouseDown: e => e.stopPropagation(), style: {
148
+ position: 'absolute',
149
+ right: '-36px',
150
+ top: '50%',
151
+ transform: 'translateY(-50%)',
152
+ width: '28px',
153
+ height: '28px',
154
+ background: backgroundColor,
155
+ border: '2px solid rgba(255,255,255,0.5)',
156
+ borderRadius: '50%',
157
+ display: 'flex',
158
+ alignItems: 'center',
159
+ justifyContent: 'center',
160
+ cursor: 'pointer',
161
+ color: '#FFFFFF',
162
+ fontSize: '11px',
163
+ fontWeight: 700,
164
+ boxShadow: '0 2px 8px rgba(0, 0, 50, 0.3)',
165
+ transition: 'all 0.2s',
166
+ }, onMouseEnter: e => {
167
+ e.currentTarget.style.filter = 'brightness(1.2)';
168
+ e.currentTarget.style.transform = 'translateY(-50%) scale(1.1)';
169
+ }, onMouseLeave: e => {
170
+ e.currentTarget.style.filter = 'none';
171
+ e.currentTarget.style.transform = 'translateY(-50%)';
172
+ }, children: formatBadgeCount(othersCount) }))] }));
173
+ };
174
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: '10px' }, children: [hasMoreInfo && firstTask && isMoreInfoCardVisible && (_jsx("div", { style: { display: 'flex', gap: "10px", flexDirection: 'column', alignItems: 'center', paddingRight: tasksNumber > 1 ? '36px' : '0' }, children: renderMoreInfoCard(firstTask, tasksNumber > 1) })), hasMoreInfo && isMoreInfoCardVisible && hasApprove && _jsx(Divider, {}), hasApprove && (workItems.length === 1 ?
175
+ _jsx(WorkFlowOperationButtons, { dtd: fromDTD, deviceType: deviceType, onApprove: () => updateShowApprovePopup(true), onSignApprove: handleSignApprove, onReject: () => updateShowRejectPopup(true), onReAssign: () => updateShowReAssignPopup(true), onMoreInfo: () => updateShowMoreInfoPopup(true) })
176
+ :
177
+ _jsxs("div", { style: { padding: 10, color: 'white', maxWidth: '180px', borderRadius: 10, background: '#1B1464 0% 0% no-repeat padding-box', border: '1px solid #FFFFFF' }, children: [`Questo documento è associato a ${workItems.length} workitem.`, _jsx("br", {}), `Per approvare, vai alla pagina "Approvazione workflow".`] })), (hasApprove && hasReferences) || (hasMoreInfo && isMoreInfoCardVisible && !hasApprove && hasReferences) ? (_jsx(Divider, {})) : null, hasReferences && (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: '10px', alignItems: 'center' }, children: [dossierRefs.length > 0 && (_jsx("div", { style: { paddingRight: dossierRefs.length > 1 ? '36px' : '0' }, children: renderReferenceCard(dossierRefs[0], dossierRefs, dossierRefs.length > 1, () => setShowAllDossiersModal(true)) })), workingGroupRefs.length > 0 && (_jsx("div", { style: { paddingRight: workingGroupRefs.length > 1 ? '36px' : '0' }, children: renderReferenceCard(workingGroupRefs[0], workingGroupRefs, workingGroupRefs.length > 1, () => setShowAllWorkingGroupsModal(true)) }))] }))] }), showAllMoreInfoModal && moreInfoTasks && moreInfoTasks.length > 1 && (_jsx(TMModal, { title: `Altre richieste maggiori informazioni (${moreInfoTasks.length - 1})`, onClose: () => setShowAllMoreInfoModal(false), width: calcResponsiveSizes(deviceType, '450px', '450px', '95%'), height: 'auto', children: _jsx("div", { style: {
178
+ display: 'flex',
179
+ flexDirection: 'column',
180
+ gap: '8px',
181
+ padding: '15px',
182
+ maxHeight: '50vh',
183
+ overflowY: 'auto',
184
+ scrollbarWidth: 'thin',
185
+ scrollbarColor: '#888 #f1f1f1'
186
+ }, children: moreInfoTasks.slice(1).map((task, index) => {
50
187
  const userID = SDK_Globals.tmSession?.SessionDescr?.userID;
51
- const isSender = currentTask?.fromID !== undefined && currentTask.fromID === userID;
52
- const isRecipient = currentTask?.toID !== undefined && currentTask.toID === userID;
53
- const truncate = (str, maxLength) => str && str.length > maxLength ? str.substring(0, maxLength) + '...' : str;
54
- const senderNameTruncated = currentTask?.fromName ? truncate(currentTask.fromName, 30) : 'N/A';
55
- const recipientNameTruncated = currentTask?.toName ? truncate(currentTask.toName, 30) : 'N/A';
56
- const taskNameTrunc = currentTask?.name ? truncate(currentTask.name.replace(TASK_MORE_INFO_PREFIX_NAME ?? '', ''), 30) : 'N/A';
57
- return (_jsxs(_Fragment, { children: [(isSender && !isRecipient) && (_jsx(TaskLink, { messagePrefix: `Hai richiesto maggiori informazioni a "${recipientNameTruncated}" tramite l'attività`, name: currentTask.name ?? 'N/A', taskNameTrunc: taskNameTrunc ?? 'N/A', description: currentTask.description ?? 'N/A', currentTask: currentTask, setShowMoreInfoTaskPopup: setShowMoreInfoTaskPopup, setShowMoreInfoTaskTask: setShowMoreInfoTaskTask })), (isRecipient && !isSender) && (_jsxs("div", { style: {
58
- display: 'flex',
59
- flexDirection: 'column',
60
- alignItems: 'center',
61
- gap: '10px'
62
- }, children: [_jsx(TaskLink, { messagePrefix: `"${senderNameTruncated}" ti ha richiesto maggiori informazioni tramite l'attività`, name: currentTask.name ?? 'N/A', taskNameTrunc: taskNameTrunc ?? 'N/A', description: currentTask.description ?? 'N/A', currentTask: currentTask, setShowMoreInfoTaskPopup: setShowMoreInfoTaskPopup, setShowMoreInfoTaskTask: setShowMoreInfoTaskTask }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx("span", { className: "dx-icon-chat" }), caption: SDKUI_Localizator.CommentAndComplete, width: "180px", disabled: false, onClick: () => setShowCommentForm(true), onMouseDown: e => e.stopPropagation(), advancedColor: TMColors.success, color: "success" })] }))] }));
63
- })() }) })) : (_jsx("div", { style: {
64
- padding: '10px',
65
- color: '#FFFFFF',
66
- maxWidth: '240px',
67
- background: 'linear-gradient(135deg, #1E90FF 0%, #0077BE 60%, #00509E 100%)',
68
- border: '1px solid rgba(255,255,255,0.15)',
69
- boxShadow: '0 8px 20px rgba(0, 0, 50, 0.4)',
70
- backdropFilter: 'blur(6px)',
71
- display: 'flex',
72
- flexDirection: 'column',
73
- alignItems: 'center',
74
- textAlign: 'center',
75
- gap: '10px',
76
- cursor: 'default',
77
- }, children: `Ci sono ${moreInfoTasks?.length ?? 0} richieste di maggiori informazioni. ${SDKUI_Localizator.ManageFromTaskPanel}` }))), hasMoreInfo && hasApprove && _jsx(Divider, {}), hasApprove && (workItems.length === 1 ?
78
- _jsx(WorkFlowOperationButtons, { dtd: fromDTD, deviceType: deviceType, onApprove: () => updateShowApprovePopup(true), onSignApprove: handleSignApprove, onReject: () => updateShowRejectPopup(true), onReAssign: () => updateShowReAssignPopup(true), onMoreInfo: () => updateShowMoreInfoPopup(true) })
79
- :
80
- _jsxs("div", { style: { padding: 10, color: 'white', maxWidth: '180px', borderRadius: 10, background: '#1B1464 0% 0% no-repeat padding-box', border: '1px solid #FFFFFF' }, children: [`Questo documento è associato a ${workItems.length} workitem.`, _jsx("br", {}), `Per approvare, vai alla pagina "Approvazione workflow".`] })), (hasApprove && hasReferences) || (hasMoreInfo && !hasApprove && hasReferences) ? (_jsx(Divider, {})) : null, hasReferences && (_jsx(ReferencesContainer, { children: dcmtReferences?.filter(ref => ref.objClass === ObjectClasses.Dossier || ref.objClass === ObjectClasses.WorkingGroup)
81
- .map((ref, index) => {
82
- const mapEntry = referenceActionMap[String(ref.objClass)];
83
- const label = mapEntry?.label ?? 'Vai a riferimento';
84
- let backgroundColor;
85
- switch (ref.objClass) {
86
- case ObjectClasses.WorkingGroup:
87
- backgroundColor = PDGS_COLORS.WORKING_GROUP;
88
- break;
89
- case ObjectClasses.Dossier:
90
- backgroundColor = PDGS_COLORS.DOSSIER;
91
- break;
92
- case ObjectClasses.Document:
93
- backgroundColor = PDGS_COLORS.DOCUMENT;
94
- break;
95
- default:
96
- backgroundColor = "#C2388B";
97
- break;
98
- }
99
- return (_jsxs(StyledReferenceButton, { onClick: () => handleNavigateToReference(ref), onDoubleClick: (e) => { e.preventDefault(); e.stopPropagation(); }, "$bgColor": backgroundColor, children: [_jsx("span", { children: label }), _jsx("span", { children: `"${ref.objName}"` })] }, `ref-${index}-${ref.objID}`));
100
- }) }))] });
188
+ const isSender = task?.fromID !== undefined && task.fromID === userID;
189
+ const isRecipient = task?.toID !== undefined && task.toID === userID;
190
+ const taskName = task?.name?.replace(TASK_MORE_INFO_PREFIX_NAME ?? '', '') ?? 'N/A';
191
+ let roleInfo = '';
192
+ if (isSender && !isRecipient) {
193
+ roleInfo = `Richiesta a: ${task.toName ?? 'N/A'}`;
194
+ }
195
+ else if (isRecipient && !isSender) {
196
+ roleInfo = `Da: ${task.fromName ?? 'N/A'}`;
197
+ }
198
+ return (_jsxs("div", { onClick: () => {
199
+ setShowMoreInfoTaskPopup(true);
200
+ setShowMoreInfoTaskTask(task);
201
+ setShowAllMoreInfoModal(false);
202
+ }, style: {
203
+ display: 'flex',
204
+ alignItems: 'center',
205
+ gap: '12px',
206
+ padding: '12px 16px',
207
+ borderRadius: '8px',
208
+ backgroundColor: '#f5f5f5',
209
+ cursor: 'pointer',
210
+ transition: 'background-color 0.2s',
211
+ }, onMouseEnter: e => e.currentTarget.style.backgroundColor = '#e8e8e8', onMouseLeave: e => e.currentTarget.style.backgroundColor = '#f5f5f5', children: [_jsx("div", { style: {
212
+ width: '8px',
213
+ height: '8px',
214
+ borderRadius: '50%',
215
+ backgroundColor: '#0077BE',
216
+ flexShrink: 0
217
+ } }), _jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: '2px' }, children: [_jsx("span", { style: {
218
+ fontSize: '1rem',
219
+ color: '#333',
220
+ wordBreak: 'break-word',
221
+ fontWeight: 500
222
+ }, children: taskName }), roleInfo && (_jsx("span", { style: {
223
+ fontSize: '1rem',
224
+ color: '#333',
225
+ wordBreak: 'break-word'
226
+ }, children: roleInfo }))] })] }, `moreinfo-task-${index}-${task.id}`));
227
+ }) }) })), showAllDossiersModal && dossierRefs.length > 1 && (_jsx(TMModal, { title: `Altre ${SDKUI_Localizator.Dossiers} (${dossierRefs.length - 1})`, onClose: () => setShowAllDossiersModal(false), width: calcResponsiveSizes(deviceType, '450px', '450px', '95%'), height: calcResponsiveSizes(deviceType, 'auto', 'auto', '95%'), children: _jsx("div", { style: {
228
+ display: 'flex',
229
+ flexDirection: 'column',
230
+ gap: '8px',
231
+ padding: '15px',
232
+ maxHeight: '50vh',
233
+ overflowY: 'auto',
234
+ scrollbarWidth: 'thin',
235
+ scrollbarColor: '#888 #f1f1f1'
236
+ }, children: dossierRefs.slice(1).map((ref, index) => {
237
+ const mapEntry = referenceActionMap[String(ref.objClass)];
238
+ const label = mapEntry?.label ?? 'Vai a riferimento';
239
+ return (_jsxs("div", { onClick: () => { handleNavigateToReference(ref); setShowAllDossiersModal(false); }, style: {
240
+ display: 'flex',
241
+ alignItems: 'center',
242
+ gap: '12px',
243
+ padding: '12px 16px',
244
+ borderRadius: '8px',
245
+ backgroundColor: '#f5f5f5',
246
+ cursor: 'pointer',
247
+ transition: 'background-color 0.2s',
248
+ }, onMouseEnter: e => e.currentTarget.style.backgroundColor = '#e8e8e8', onMouseLeave: e => e.currentTarget.style.backgroundColor = '#f5f5f5', children: [_jsx("div", { style: {
249
+ width: '8px',
250
+ height: '8px',
251
+ borderRadius: '50%',
252
+ backgroundColor: PDGS_COLORS.DOSSIER,
253
+ flexShrink: 0
254
+ } }), _jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: '2px' }, children: [_jsxs("span", { style: {
255
+ fontSize: '1rem',
256
+ color: '#333'
257
+ }, children: [label, ":"] }), _jsx("span", { style: {
258
+ fontSize: '1rem',
259
+ color: '#333',
260
+ wordBreak: 'break-word',
261
+ fontWeight: 500
262
+ }, children: ref.objName })] })] }, `dossier-ref-${index}-${ref.objID}`));
263
+ }) }) })), showAllWorkingGroupsModal && workingGroupRefs.length > 1 && (_jsx(TMModal, { title: `Altri ${SDKUI_Localizator.WorkingGroups} (${workingGroupRefs.length - 1})`, onClose: () => setShowAllWorkingGroupsModal(false), width: calcResponsiveSizes(deviceType, '450px', '450px', '95%'), height: calcResponsiveSizes(deviceType, 'auto', 'auto', '95%'), children: _jsx("div", { style: {
264
+ display: 'flex',
265
+ flexDirection: 'column',
266
+ gap: '8px',
267
+ padding: '15px',
268
+ maxHeight: '50vh',
269
+ overflowY: 'auto',
270
+ scrollbarWidth: 'thin',
271
+ scrollbarColor: '#888 #f1f1f1'
272
+ }, children: workingGroupRefs.slice(1).map((ref, index) => {
273
+ const mapEntry = referenceActionMap[String(ref.objClass)];
274
+ const label = mapEntry?.label ?? 'Vai a riferimento';
275
+ return (_jsxs("div", { onClick: () => { handleNavigateToReference(ref); setShowAllWorkingGroupsModal(false); }, style: {
276
+ display: 'flex',
277
+ alignItems: 'center',
278
+ gap: '12px',
279
+ padding: '12px 16px',
280
+ borderRadius: '8px',
281
+ backgroundColor: '#f5f5f5',
282
+ cursor: 'pointer',
283
+ transition: 'background-color 0.2s',
284
+ }, onMouseEnter: e => e.currentTarget.style.backgroundColor = '#e8e8e8', onMouseLeave: e => e.currentTarget.style.backgroundColor = '#f5f5f5', children: [_jsx("div", { style: {
285
+ width: '8px',
286
+ height: '8px',
287
+ borderRadius: '50%',
288
+ backgroundColor: PDGS_COLORS.WORKING_GROUP,
289
+ flexShrink: 0
290
+ } }), _jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: '2px' }, children: [_jsxs("span", { style: {
291
+ fontSize: '1rem',
292
+ color: '#333'
293
+ }, children: [label, ":"] }), _jsx("span", { style: {
294
+ fontSize: '1rem',
295
+ color: '#333',
296
+ wordBreak: 'break-word',
297
+ fontWeight: 500
298
+ }, children: ref.objName })] })] }, `wg-ref-${index}-${ref.objID}`));
299
+ }) }) }))] }));
101
300
  };
102
301
  export default TMDcmtFormActionButtons;
103
302
  const TaskLink = (props) => {
@@ -9,6 +9,7 @@ interface ITMDcmtPreviewProps {
9
9
  onNext?: () => void;
10
10
  onPrev?: () => void;
11
11
  onClosePanel?: () => void;
12
+ onBack?: () => void;
12
13
  allowMaximize?: boolean;
13
14
  onMaximizePanel?: () => void;
14
15
  }
@@ -22,7 +22,7 @@ const ErrorContent = ({ error, isAbortError, onRetry }) => {
22
22
  }
23
23
  return _jsx(TMNothingToShow, { icon: _jsx(IconCloseOutline, { fontSize: 92, color: TMColors.error }), text: error });
24
24
  };
25
- const TMDcmtPreview = ({ dcmtData, isResizingActive, isVisible, canNext, canPrev, onClosePanel, onNext, onPrev, allowMaximize = true, onMaximizePanel }) => {
25
+ const TMDcmtPreview = ({ dcmtData, isResizingActive, isVisible, canNext, canPrev, onClosePanel, onBack, onNext, onPrev, allowMaximize = true, onMaximizePanel }) => {
26
26
  const [dcmtBlob, setDcmtBlob] = useState(undefined);
27
27
  const [showPreview, setShowPreview] = useState(false);
28
28
  const [isFromCache, setIsFromCache] = useState(false);
@@ -183,7 +183,7 @@ const TMDcmtPreview = ({ dcmtData, isResizingActive, isVisible, canNext, canPrev
183
183
  { icon: _jsx(IconCloseCircle, {}), name: SDKUI_Localizator.RemoveFromCache, onClick: () => { removeDcmtsFileCache(cacheKey); setIsFromCache(false); } },
184
184
  { icon: _jsx(IconClear, {}), name: SDKUI_Localizator.ClearCache, onClick: () => { clearDcmtsFileCache(); setIsFromCache(false); } },
185
185
  ], [cacheKey, removeDcmtsFileCache, clearDcmtsFileCache, setIsFromCache]);
186
- return (_jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, showWaitPanelSecondary: showSecondary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, waitPanelTextSecondary: waitPanelTextSecondary, waitPanelValueSecondary: waitPanelValueSecondary, waitPanelMaxValueSecondary: waitPanelMaxValueSecondary, isCancelable: true, abortController: abortController, children: _jsx(TMPanel, { padding: '0', title: titleHandler(), onClose: onClosePanel, allowMaximize: allowMaximize, onMaximize: onMaximizePanel, onHeaderDoubleClick: onMaximizePanel, toolbar: _jsxs("div", { style: { width: 'max-content', display: 'flex', alignItems: 'center', gap: '10px' }, children: [onPrev && _jsx(TMSaveFormButtonPrevious, { btnStyle: 'icon', isModified: false, formMode: FormModes.ReadOnly, canPrev: canPrev, onPrev: onPrev }), onNext && _jsx(TMSaveFormButtonNext, { btnStyle: 'icon', isModified: false, formMode: FormModes.ReadOnly, canNext: canNext, onNext: onNext }), _jsx(StyledHeaderIcon, { "$color": TMColors.primaryColor, children: _jsx(ContextMenu, { items: cacheMenuItems, trigger: "left", children: _jsx(IconMenuVertical, {}) }) }), _jsx(StyledHeaderIcon, { onClick: reOpenDcmt, "$color": TMColors.primaryColor, children: _jsx(TMTooltip, { content: SDKUI_Localizator.ReopenDocument, children: _jsx(IconRefresh, {}) }) })] }), children: error
186
+ return (_jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, showWaitPanelSecondary: showSecondary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, waitPanelTextSecondary: waitPanelTextSecondary, waitPanelValueSecondary: waitPanelValueSecondary, waitPanelMaxValueSecondary: waitPanelMaxValueSecondary, isCancelable: true, abortController: abortController, children: _jsx(TMPanel, { padding: '0', title: titleHandler(), onClose: onClosePanel, onBack: onBack, allowMaximize: allowMaximize, onMaximize: onMaximizePanel, onHeaderDoubleClick: onMaximizePanel, toolbar: _jsxs("div", { style: { width: 'max-content', display: 'flex', alignItems: 'center', gap: '10px' }, children: [onPrev && _jsx(TMSaveFormButtonPrevious, { btnStyle: 'icon', isModified: false, formMode: FormModes.ReadOnly, canPrev: canPrev, onPrev: onPrev }), onNext && _jsx(TMSaveFormButtonNext, { btnStyle: 'icon', isModified: false, formMode: FormModes.ReadOnly, canNext: canNext, onNext: onNext }), _jsx(StyledHeaderIcon, { "$color": TMColors.primaryColor, children: _jsx(ContextMenu, { items: cacheMenuItems, trigger: "left", children: _jsx(IconMenuVertical, {}) }) }), _jsx(StyledHeaderIcon, { onClick: reOpenDcmt, "$color": TMColors.primaryColor, children: _jsx(TMTooltip, { content: SDKUI_Localizator.ReopenDocument, children: _jsx(IconRefresh, {}) }) })] }), children: error
187
187
  ? _jsx(ErrorContent, { error: error, isAbortError: isAbortError, onRetry: reOpenDcmt })
188
188
  : renderedPreview(dcmtData?.tid, dcmtData?.did, dcmtData?.fileExt, dcmtData?.fileSize, dcmtData?.fileCount, extensionHandler(dcmtData?.fileExt), showPreview, isResizingActive, () => { isBasketMode ? loadBasketFile() : loadDocumentWithCache(); setShowPreview(true); }, dcmtBlob, isBasketMode) }) }));
189
189
  };
@@ -10,6 +10,7 @@ interface TMDcmtTasksProps {
10
10
  afterTaskSaved: (task: TaskDescriptor | undefined, formMode: FormModes | undefined, forceRefresh?: boolean) => Promise<void>;
11
11
  handleNavigateToWGs?: (value: HomeBlogPost | number) => Promise<void>;
12
12
  handleNavigateToDossiers?: (value: HomeBlogPost | number) => Promise<void>;
13
+ onBack?: () => void;
13
14
  }
14
15
  declare const TMDcmtTasks: (props: TMDcmtTasksProps) => import("react/jsx-runtime").JSX.Element;
15
16
  export default TMDcmtTasks;
@@ -6,7 +6,7 @@ import { useTMPanelManagerContext } from "../../layout/panelManager/TMPanelManag
6
6
  import TMPanel from "../../base/TMPanel";
7
7
  import TMTasksPanelContent from "../tasks/TMTasksPanelContent";
8
8
  const TMDcmtTasks = (props) => {
9
- const { taskContext, allTasks, getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, afterTaskSaved, handleNavigateToWGs, handleNavigateToDossiers } = props;
9
+ const { taskContext, allTasks, getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, afterTaskSaved, handleNavigateToWGs, handleNavigateToDossiers, onBack } = props;
10
10
  // Get the current device type (e.g., mobile, tablet, desktop) using a custom hook.
11
11
  const deviceType = useDeviceType();
12
12
  // This avoids unnecessary re-renders by only recalculating when deviceType changes.
@@ -19,6 +19,6 @@ const TMDcmtTasks = (props) => {
19
19
  text: SDKUI_Localizator.Refresh,
20
20
  },
21
21
  ], children: _jsx(IconMenuVertical, { id: "TMTaksPanel-Commands-Header", color: 'white', cursor: 'pointer' }) }), []);
22
- return _jsx("div", { style: { width: "100%", height: "100%", position: 'relative' }, children: _jsx(TMPanel, { title: SDKUI_Localizator.Widget_Activities, allowMaximize: !isMobile && countVisibleLeafPanels() > 1, onClose: countVisibleLeafPanels() > 1 ? () => togglePanelVisibility("tmDcmtTasks") : undefined, onMaximize: countVisibleLeafPanels() > 1 ? () => toggleMaximize("tmDcmtTasks") : undefined, toolbar: toolbar, children: _jsx(TMTasksPanelContent, { id: "dcmtTasks", taskContext: taskContext, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs ? handleNavigateToWGs : () => { return Promise.resolve(); }, handleNavigateToDossiers: handleNavigateToDossiers ? handleNavigateToDossiers : () => { return Promise.resolve(); }, afterTaskSaved: afterTaskSaved }) }) });
22
+ return _jsx("div", { style: { width: "100%", height: "100%", position: 'relative' }, children: _jsx(TMPanel, { title: SDKUI_Localizator.Widget_Activities, allowMaximize: !isMobile && countVisibleLeafPanels() > 1, onClose: countVisibleLeafPanels() > 1 ? () => togglePanelVisibility("tmDcmtTasks") : undefined, onMaximize: countVisibleLeafPanels() > 1 ? () => toggleMaximize("tmDcmtTasks") : undefined, toolbar: toolbar, onBack: onBack, children: _jsx(TMTasksPanelContent, { id: "dcmtTasks", taskContext: taskContext, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs ? handleNavigateToWGs : () => { return Promise.resolve(); }, handleNavigateToDossiers: handleNavigateToDossiers ? handleNavigateToDossiers : () => { return Promise.resolve(); }, afterTaskSaved: afterTaskSaved }) }) });
23
23
  };
24
24
  export default TMDcmtTasks;
@@ -0,0 +1,23 @@
1
+ import React from 'react';
2
+ import { HomeBlogPost, TaskDescriptor } from '@topconsultnpm/sdk-ts';
3
+ import { DcmtInfo } from '../../../ts';
4
+ import { IRelatedDcmt } from './TMMasterDetailDcmts';
5
+ interface ITMDownloadRelationViewerSectionProps {
6
+ selectedDcmtInfos: Array<DcmtInfo>;
7
+ /** Notifica al parent la lista dei documenti correlati selezionati (deduplicati) */
8
+ onSelectionChanged: (items: Array<IRelatedDcmt>) => void;
9
+ allTasks?: Array<TaskDescriptor>;
10
+ getAllTasks?: () => Promise<void>;
11
+ deleteTaskByIdsCallback?: (deletedTaskIds: Array<number>) => Promise<void>;
12
+ addTaskCallback?: (task: TaskDescriptor) => Promise<void>;
13
+ editTaskCallback?: (task: TaskDescriptor) => Promise<void>;
14
+ handleNavigateToWGs?: (value: HomeBlogPost | number) => Promise<void>;
15
+ handleNavigateToDossiers?: (value: HomeBlogPost | number) => Promise<void>;
16
+ }
17
+ /**
18
+ * Sezione condivisa tra TMCopyToFolderForm e TMMergeToPdfForm
19
+ * che mostra l'elenco dei documenti correlati e il tree di selezione
20
+ * per tipo documento / "solo metadati".
21
+ */
22
+ declare const TMDownloadRelationViewerSection: React.FC<ITMDownloadRelationViewerSectionProps>;
23
+ export default TMDownloadRelationViewerSection;