@topconsultnpm/sdkui-react 6.21.0-dev1.8 → 6.21.0-dev2.10

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 (87) hide show
  1. package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +2 -2
  2. package/lib/components/NewComponents/ContextMenu/styles.d.ts +43 -19
  3. package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.js +1 -1
  4. package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +79 -27
  5. package/lib/components/base/Styled.d.ts +76 -40
  6. package/lib/components/base/TMAccordionNew.d.ts +1 -0
  7. package/lib/components/base/TMAccordionNew.js +5 -5
  8. package/lib/components/base/TMAreaManager.js +47 -14
  9. package/lib/components/base/TMFileManagerDataGridView.js +2 -2
  10. package/lib/components/base/TMFileManagerUtils.d.ts +6 -2
  11. package/lib/components/base/TMPanel.js +1 -0
  12. package/lib/components/base/TMTreeView.d.ts +5 -3
  13. package/lib/components/choosers/TMDataListItemChooser.js +56 -2
  14. package/lib/components/choosers/TMDynDataListItemChooser.d.ts +1 -1
  15. package/lib/components/choosers/TMDynDataListItemChooser.js +51 -23
  16. package/lib/components/editors/TMDateBox.js +4 -2
  17. package/lib/components/editors/TMDropDown.js +2 -2
  18. package/lib/components/editors/TMEditorStyled.d.ts +42 -10
  19. package/lib/components/editors/TMFormulaEditor.js +15 -3
  20. package/lib/components/editors/TMMetadataEditor.js +4 -3
  21. package/lib/components/editors/TMMetadataValues.js +1 -1
  22. package/lib/components/editors/TMTextArea.d.ts +2 -0
  23. package/lib/components/editors/TMTextArea.js +6 -3
  24. package/lib/components/features/archive/TMArchive.js +1 -1
  25. package/lib/components/features/documents/TMDcmtBlog.d.ts +1 -0
  26. package/lib/components/features/documents/TMDcmtBlog.js +2 -2
  27. package/lib/components/features/documents/TMDcmtForm.js +49 -21
  28. package/lib/components/features/documents/TMDcmtFormActionButtons.js +259 -60
  29. package/lib/components/features/documents/TMDcmtPreview.d.ts +5 -3
  30. package/lib/components/features/documents/TMDragDropOverlay.js +7 -2
  31. package/lib/components/features/documents/TMFileUploader.js +5 -4
  32. package/lib/components/features/documents/TMMasterDetailDcmts.js +30 -56
  33. package/lib/components/features/documents/TMRelationViewer.js +1 -0
  34. package/lib/components/features/search/TMSavedQuerySelector.js +1 -1
  35. package/lib/components/features/search/TMSearch.js +2 -0
  36. package/lib/components/features/search/TMSearchQueryEditor.js +13 -1
  37. package/lib/components/features/search/TMSearchQueryPanel.d.ts +3 -3
  38. package/lib/components/features/search/TMSearchResult.js +15 -2
  39. package/lib/components/features/search/TMViewHistoryDcmt.js +7 -2
  40. package/lib/components/features/workflow/TMWorkflowPopup.js +3 -0
  41. package/lib/components/features/workflow/diagram/DiagramItemForm.js +5 -1
  42. package/lib/components/features/workflow/diagram/WFDiagram.js +7 -1
  43. package/lib/components/features/workflow/diagram/WorkitemRecipientsEditor.d.ts +1 -1
  44. package/lib/components/features/workflow/diagram/xmlParser.js +13 -14
  45. package/lib/components/forms/Login/ChangePasswordInputs.d.ts +1 -1
  46. package/lib/components/forms/Login/TMLoginForm.js +15 -5
  47. package/lib/components/forms/TMChooserForm.js +25 -2
  48. package/lib/components/grids/TMBlogAttachments.d.ts +1 -0
  49. package/lib/components/grids/TMBlogAttachments.js +38 -12
  50. package/lib/components/grids/TMBlogsPost.js +8 -2
  51. package/lib/components/grids/TMBlogsPostUtils.js +11 -17
  52. package/lib/components/index.d.ts +1 -0
  53. package/lib/components/index.js +1 -0
  54. package/lib/components/layout/panelManager/TMPanelManagerToolbar.d.ts +5 -2
  55. package/lib/components/pages/TMPage.js +4 -2
  56. package/lib/components/query/TMQueryCountButton.d.ts +11 -0
  57. package/lib/components/query/TMQueryCountButton.js +32 -0
  58. package/lib/components/query/TMQueryEditor.d.ts +10 -6
  59. package/lib/components/query/TMQueryEditor.js +42 -5
  60. package/lib/components/query/TMQuerySummary.js +3 -2
  61. package/lib/components/sidebar/TMCommandsPanel.d.ts +4 -2
  62. package/lib/components/viewers/TMDataListItemViewer.d.ts +2 -1
  63. package/lib/components/viewers/TMDataListItemViewer.js +2 -2
  64. package/lib/components/viewers/TMTidViewer.js +1 -1
  65. package/lib/helper/GlobalStyles.js +6 -0
  66. package/lib/helper/SDKUI_Globals.d.ts +2 -0
  67. package/lib/helper/SDKUI_Localizator.d.ts +1 -0
  68. package/lib/helper/SDKUI_Localizator.js +10 -0
  69. package/lib/helper/TMPdfViewer.js +143 -86
  70. package/lib/helper/TMUtils.d.ts +4 -9
  71. package/lib/helper/TMUtils.js +12 -74
  72. package/lib/helper/checkinCheckoutManager.d.ts +6 -1
  73. package/lib/helper/checkinCheckoutManager.js +203 -9
  74. package/lib/helper/helpers.js +8 -6
  75. package/lib/hooks/useCheckInOutOperations.d.ts +1 -1
  76. package/lib/hooks/useCheckInOutOperations.js +9 -4
  77. package/lib/hooks/useDcmtOperations.d.ts +1 -0
  78. package/lib/hooks/useDcmtOperations.js +75 -5
  79. package/lib/hooks/useDocumentOperations.js +17 -4
  80. package/lib/hooks/useForm.js +20 -14
  81. package/lib/hooks/useInputDialog.d.ts +2 -0
  82. package/lib/hooks/useInputDialog.js +37 -0
  83. package/lib/hooks/useQueryParametersDialog.js +5 -5
  84. package/lib/services/platform_services.d.ts +1 -1
  85. package/lib/services/platform_services.js +8 -0
  86. package/lib/ts/types.d.ts +1 -0
  87. package/package.json +11 -12
@@ -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) => {
@@ -25,7 +25,9 @@ export declare const TMNothingToShow: ({ text, secondText, fileExt, icon }: {
25
25
  fileExt?: string;
26
26
  icon?: any;
27
27
  }) => import("react/jsx-runtime").JSX.Element;
28
- export declare const StyledHeaderIcon: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
28
+ export declare const StyledHeaderIcon: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "$color"> & {
29
29
  $color: string;
30
- }>> & string;
31
- export declare const StyledPanelStatusContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
30
+ }, never> & Partial<Pick<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "$color"> & {
31
+ $color: string;
32
+ }, never>>> & string;
33
+ export declare const StyledPanelStatusContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
@@ -8,7 +8,10 @@ const TMDragDropOverlay = (props) => {
8
8
  useEffect(() => {
9
9
  const handleWindowDragEnter = (e) => {
10
10
  e.preventDefault();
11
- setDragOver(true);
11
+ // Attiva solo se si trascina un file
12
+ if (e.dataTransfer?.types.includes('Files')) {
13
+ setDragOver(true);
14
+ }
12
15
  };
13
16
  const handleWindowDragOver = (e) => {
14
17
  e.preventDefault();
@@ -60,7 +63,9 @@ const TMDragDropOverlay = (props) => {
60
63
  boxShadow: '0 8px 20px rgba(0,0,0,0.3)',
61
64
  backdropFilter: 'blur(5px)',
62
65
  transition: 'opacity 0.2s, transform 0.2s, background 0.2s',
63
- }, onDragEnter: (e) => { e.preventDefault(); e.stopPropagation(); setDragOver(true); }, onDragOver: (e) => { e.preventDefault(); e.stopPropagation(); setDragOver(true); }, onDragLeave: (e) => {
66
+ }, onDragEnter: (e) => { e.preventDefault(); e.stopPropagation(); if (e.dataTransfer?.types.includes('Files'))
67
+ setDragOver(true); }, onDragOver: (e) => { e.preventDefault(); e.stopPropagation(); if (e.dataTransfer?.types.includes('Files'))
68
+ setDragOver(true); }, onDragLeave: (e) => {
64
69
  e.preventDefault();
65
70
  e.stopPropagation();
66
71
  // Solo se il cursore ha lasciato il div principale
@@ -2,7 +2,6 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
3
  import styled from 'styled-components';
4
4
  import { IconFolderOpen, IconScanner, SDKUI_Localizator, formatBytes, IconClear, extensionHandler, IconCloseOutline, IconMenuVertical, TMCommandsContextMenu, IconEdit, isPdfEditorAvailable, SDKUI_Globals } from '../../../helper';
5
- import { useBetaFeatures } from '../../../hooks/useBetaFeatures';
6
5
  import usePreventFileDrop from '../../../hooks/usePreventFileDrop';
7
6
  import { FileExtensionHandler } from '../../../ts';
8
7
  import { TMColors } from '../../../utils/theme';
@@ -24,7 +23,6 @@ const isScannerLicenseConfigured = () => {
24
23
  }
25
24
  };
26
25
  const TMFileUploader = ({ fromDTD, deviceType = DeviceType.DESKTOP, onClose, onFileUpload, openFileUploaderPdfEditor, onScanRequest, isRequired = false, defaultBlob = null, isResizingActive, showTMPanel = true, enableDragDropOverlay = false, showScannerIcon = true }) => {
27
- const isBetaFeaturesEnabled = useBetaFeatures();
28
26
  const [dragOver, setDragOver] = useState(false);
29
27
  const [uploadedFile, setUploadedFile] = useState(defaultBlob);
30
28
  const [fileName, setFileName] = useState('');
@@ -54,7 +52,10 @@ const TMFileUploader = ({ fromDTD, deviceType = DeviceType.DESKTOP, onClose, onF
54
52
  };
55
53
  const handleDragOver = (e) => {
56
54
  e.preventDefault();
57
- setDragOver(true);
55
+ // Attiva solo se si trascina un file, non testo selezionato
56
+ if (e.dataTransfer?.types.includes('Files')) {
57
+ setDragOver(true);
58
+ }
58
59
  };
59
60
  const handleDragLeave = () => {
60
61
  setDragOver(false);
@@ -96,7 +97,7 @@ const TMFileUploader = ({ fromDTD, deviceType = DeviceType.DESKTOP, onClose, onF
96
97
  document.getElementById('fileInput')?.click();
97
98
  }, []);
98
99
  let content = !uploadedFile ?
99
- _jsxs("div", { style: { display: 'flex', gap: 10, width: '100%', height: '100%' }, children: [_jsx(HiddenInput, { id: "fileInput", type: "file", onChange: handleInputChange }), _jsxs(UploadContainer, { ref: uploaderRef, tabIndex: 0, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, style: { backgroundColor: dragOver ? '#76b1e6' : 'white' }, onDoubleClick: browseHandler, "$isRequired": isRequired, children: [_jsxs("div", { style: { display: 'flex', gap: '10px', flexDirection: 'column', position: 'absolute', right: 5, top: 5 }, children: [_jsx(TMButton, { btnStyle: 'icon', caption: 'Sfoglia', color: isRequired && !uploadedFile ? 'error' : 'primary', onClick: browseHandler, icon: _jsx(IconFolderOpen, { fontSize: 22 }) }), isBetaFeaturesEnabled && showScannerIcon && isScannerLicenseConfigured() && onScanRequest && _jsx(TMButton, { btnStyle: 'icon', caption: 'Scanner', color: 'primary', onClick: () => { onScanRequest((file) => { onFileUpload?.(file); }); }, icon: _jsx(IconScanner, { fontSize: 22 }) }), isBetaFeaturesEnabled && showScannerIcon && isScannerLicenseConfigured() && !onScanRequest && _jsx(TMButton, { btnStyle: 'icon', caption: 'Scanner', color: 'primary', onClick: () => { ShowAlert({ message: 'Funzionalità scanner non disponibile in questo contesto.', mode: 'info', duration: 3000, title: 'Scanner' }); }, icon: _jsx(IconScanner, { fontSize: 22 }) })] }), _jsx("p", { style: { fontSize: '1.2rem', fontWeight: 'bold' }, children: deviceType === DeviceType.MOBILE ? 'Clicca per sfogliare il tuo file' : 'Trascina il tuo file o fai doppio click per sfogliarlo' }), isRequired && _jsxs("p", { style: { fontWeight: 'bold' }, children: [" ", SDKUI_Localizator.RequiredField, " "] })] })] }) :
100
+ _jsxs("div", { style: { display: 'flex', gap: 10, width: '100%', height: '100%' }, children: [_jsx(HiddenInput, { id: "fileInput", type: "file", onChange: handleInputChange }), _jsxs(UploadContainer, { ref: uploaderRef, tabIndex: 0, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, style: { backgroundColor: dragOver ? '#76b1e6' : 'white' }, onDoubleClick: browseHandler, "$isRequired": isRequired, children: [_jsxs("div", { style: { display: 'flex', gap: '10px', flexDirection: 'column', position: 'absolute', right: 5, top: 5 }, children: [_jsx(TMButton, { btnStyle: 'icon', caption: 'Sfoglia', color: isRequired && !uploadedFile ? 'error' : 'primary', onClick: browseHandler, icon: _jsx(IconFolderOpen, { fontSize: 22 }) }), showScannerIcon && isScannerLicenseConfigured() && onScanRequest && _jsx(TMButton, { btnStyle: 'icon', caption: 'Scanner', color: 'primary', onClick: () => { onScanRequest((file) => { onFileUpload?.(file); }); }, icon: _jsx(IconScanner, { fontSize: 22 }) }), showScannerIcon && isScannerLicenseConfigured() && !onScanRequest && _jsx(TMButton, { btnStyle: 'icon', caption: 'Scanner', color: 'primary', onClick: () => { ShowAlert({ message: SDKUI_Localizator.ScanFeatureUnavailableInThisContext, mode: 'info', duration: 3000, title: 'Scanner' }); }, icon: _jsx(IconScanner, { fontSize: 22 }) })] }), _jsx("p", { style: { fontSize: '1.2rem', fontWeight: 'bold' }, children: deviceType === DeviceType.MOBILE ? 'Clicca per sfogliare il tuo file' : 'Trascina il tuo file o fai doppio click per sfogliarlo' }), isRequired && _jsxs("p", { style: { fontWeight: 'bold' }, children: [" ", SDKUI_Localizator.RequiredField, " "] })] })] }) :
100
101
  _jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 10, width: '100%', height: '100%' }, children: [_jsxs("div", { style: { backgroundColor: 'white', padding: '5px 10px', borderRadius: 8, display: 'flex', alignItems: 'center', justifyContent: 'space-between', color: TMColors.primaryColor }, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 5 }, children: [_jsx("p", { children: "File name:" }), _jsxs("div", { style: { fontWeight: 'bold' }, children: [fileName, " ", _jsxs("span", { children: [" ", ` (${formatBytes(fileSize)})`, " "] })] })] }), uploadedFile && _jsx(TMButton, { btnStyle: 'icon', color: 'error', caption: 'Pulisci', onClick: () => clearFile(true), icon: _jsx(IconClear, { fontSize: 22 }) })] }), extensionHandler(fileExt) === FileExtensionHandler.READY_TO_SHOW ? _jsx(TMFileViewer, { fileBlob: uploadedFile, isResizingActive: isResizingActive }) :
101
102
  _jsx("div", { style: { backgroundColor: '#f6dbdb', padding: '5px 10px', borderRadius: 8, display: 'flex', alignItems: 'center', justifyContent: 'space-between', color: TMColors.error }, children: _jsxs("div", { children: [" ", 'Anteprima non disponibile.', fileExt && _jsx("b", { children: ` (*.${fileExt})` })] }) })] });
102
103
  const innerContent = (_jsxs("div", { style: { width: '100%', height: '100%', padding: '2px', display: 'flex', flexDirection: 'column', gap: 10 }, children: [enableDragDropOverlay && _jsx(TMDragDropOverlay, { handleFile: handleFile, refocusAfterFileInput: refocusAfterFileInput }), content] }));