@topconsultnpm/sdkui-react 6.19.0-test.1 → 6.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. package/lib/assets/IconsS4t/add.svg +12 -12
  2. package/lib/assets/IconsS4t/aggiorna.svg +18 -18
  3. package/lib/assets/IconsS4t/bookmark.svg +42 -42
  4. package/lib/assets/IconsS4t/cancella.svg +15 -15
  5. package/lib/assets/IconsS4t/check-box.svg +19 -19
  6. package/lib/assets/IconsS4t/down-arrow-signBook.svg +40 -40
  7. package/lib/assets/IconsS4t/down.svg +28 -28
  8. package/lib/assets/IconsS4t/edit-file.svg +19 -19
  9. package/lib/assets/IconsS4t/edita.svg +32 -32
  10. package/lib/assets/IconsS4t/firma.svg +19 -19
  11. package/lib/assets/IconsS4t/icona_download.svg +16 -16
  12. package/lib/assets/IconsS4t/info.svg +51 -51
  13. package/lib/assets/IconsS4t/left.svg +20 -20
  14. package/lib/assets/IconsS4t/line.svg +40 -40
  15. package/lib/assets/IconsS4t/more.svg +19 -19
  16. package/lib/assets/IconsS4t/plus.svg +23 -23
  17. package/lib/assets/IconsS4t/printer.svg +49 -49
  18. package/lib/assets/IconsS4t/radio-on-button.svg +25 -25
  19. package/lib/assets/IconsS4t/rectangle.svg +41 -41
  20. package/lib/assets/IconsS4t/redo.svg +19 -19
  21. package/lib/assets/IconsS4t/right-arrow-signBook-finish.svg +40 -40
  22. package/lib/assets/IconsS4t/right-arrow-signBook.svg +40 -40
  23. package/lib/assets/IconsS4t/right.svg +22 -22
  24. package/lib/assets/IconsS4t/searchbar.svg +21 -21
  25. package/lib/assets/IconsS4t/text-box.svg +36 -36
  26. package/lib/assets/IconsS4t/tick.svg +8 -8
  27. package/lib/assets/IconsS4t/trash-white.svg +10 -10
  28. package/lib/assets/IconsS4t/undo.svg +19 -19
  29. package/lib/assets/IconsS4t/up.svg +32 -32
  30. package/lib/assets/IconsS4t/video-streaming.svg +2 -2
  31. package/lib/assets/IconsS4t/zoom-in.svg +58 -58
  32. package/lib/assets/IconsS4t/zoom-out.svg +56 -56
  33. package/lib/assets/icomoon.svg +96 -96
  34. package/lib/assets/italy.svg +16 -16
  35. package/lib/assets/six.svg +3 -3
  36. package/lib/assets/thumbnails/index.ts +39 -39
  37. package/lib/assets/topmedia-six.svg +65 -65
  38. package/lib/assets/topmeida-six-bianco.svg +65 -65
  39. package/lib/components/base/Styled.js +302 -302
  40. package/lib/components/base/TMAccordion.js +43 -43
  41. package/lib/components/base/TMAccordionNew.d.ts +28 -0
  42. package/lib/components/base/TMAccordionNew.js +326 -0
  43. package/lib/components/base/TMAreaManager.js +23 -23
  44. package/lib/components/base/TMButton.d.ts +1 -0
  45. package/lib/components/base/TMButton.js +136 -136
  46. package/lib/components/base/TMClosableList.js +46 -46
  47. package/lib/components/base/TMConfirm.js +20 -20
  48. package/lib/components/base/TMContextMenu.js +4 -4
  49. package/lib/components/base/TMContextMenuOLD.js +25 -25
  50. package/lib/components/base/TMCounterBar.js +32 -32
  51. package/lib/components/base/TMCounterContainer.js +30 -30
  52. package/lib/components/base/TMCustomButton.d.ts +1 -1
  53. package/lib/components/base/TMCustomButton.js +90 -35
  54. package/lib/components/base/TMDataGridExportForm.d.ts +1 -1
  55. package/lib/components/base/TMDataGridExportForm.js +9 -3
  56. package/lib/components/base/TMDropDownMenu.js +24 -24
  57. package/lib/components/base/TMFileManager.js +12 -3
  58. package/lib/components/base/TMFileManagerDataGridView.d.ts +2 -0
  59. package/lib/components/base/TMFileManagerDataGridView.js +12 -3
  60. package/lib/components/base/TMFileManagerThumbnailItems.d.ts +2 -0
  61. package/lib/components/base/TMFileManagerThumbnailItems.js +12 -2
  62. package/lib/components/base/TMFileManagerThumbnailsView.d.ts +2 -0
  63. package/lib/components/base/TMFileManagerThumbnailsView.js +2 -2
  64. package/lib/components/base/TMFileManagerUtils.js +19 -19
  65. package/lib/components/base/TMFloatingToolbar.js +34 -34
  66. package/lib/components/base/TMLayout.js +44 -44
  67. package/lib/components/base/TMList.js +34 -34
  68. package/lib/components/base/TMModal.d.ts +2 -0
  69. package/lib/components/base/TMModal.js +79 -34
  70. package/lib/components/base/TMPanel.js +57 -57
  71. package/lib/components/base/TMPopUp.js +186 -117
  72. package/lib/components/base/TMProgressBar.js +20 -20
  73. package/lib/components/base/TMResizableMenu.js +28 -28
  74. package/lib/components/base/TMRightSidebar.js +40 -40
  75. package/lib/components/base/TMSpinner.js +121 -121
  76. package/lib/components/base/TMTab.js +11 -11
  77. package/lib/components/base/TMToggleButton.js +36 -36
  78. package/lib/components/base/TMToolbarCard.js +35 -35
  79. package/lib/components/base/TMTooltip.d.ts +1 -1
  80. package/lib/components/base/TMTooltip.js +1 -1
  81. package/lib/components/base/TMTreeView.js +16 -16
  82. package/lib/components/base/TMUserAvatar.js +7 -7
  83. package/lib/components/base/TMWaitPanel.js +30 -24
  84. package/lib/components/choosers/TMCultureIDPicker.js +35 -35
  85. package/lib/components/choosers/TMDataListItemChooser.js +1 -1
  86. package/lib/components/choosers/TMDataListItemPicker.js +54 -54
  87. package/lib/components/choosers/TMDcmtTypeChooser.js +2 -2
  88. package/lib/components/choosers/TMDynDataListItemChooser.js +5 -4
  89. package/lib/components/choosers/TMMetadataChooser.d.ts +4 -1
  90. package/lib/components/choosers/TMMetadataChooser.js +31 -8
  91. package/lib/components/choosers/TMUserChooser.d.ts +4 -0
  92. package/lib/components/choosers/TMUserChooser.js +21 -5
  93. package/lib/components/editors/TMCheckBox.js +24 -24
  94. package/lib/components/editors/TMDateBox.d.ts +1 -1
  95. package/lib/components/editors/TMDropDown.js +43 -43
  96. package/lib/components/editors/TMEditorStyled.js +71 -71
  97. package/lib/components/editors/TMHtmlContentDisplay.js +16 -16
  98. package/lib/components/editors/TMLocalizedTextBox.js +31 -31
  99. package/lib/components/editors/TMMetadataValues.js +71 -22
  100. package/lib/components/editors/TMRadioButton.js +39 -39
  101. package/lib/components/editors/TMSummary.js +39 -39
  102. package/lib/components/editors/TMTextArea.d.ts +1 -0
  103. package/lib/components/editors/TMTextArea.js +56 -22
  104. package/lib/components/editors/TMTextBox.js +53 -23
  105. package/lib/components/editors/TMTextExpression.js +36 -28
  106. package/lib/components/features/assistant/ToppyDraggableHelpCenter.d.ts +30 -0
  107. package/lib/components/features/assistant/ToppyDraggableHelpCenter.js +482 -0
  108. package/lib/components/features/assistant/ToppySpeechBubble.d.ts +9 -0
  109. package/lib/components/features/assistant/ToppySpeechBubble.js +117 -0
  110. package/lib/components/features/blog/TMBlogCommentForm.d.ts +2 -0
  111. package/lib/components/features/blog/TMBlogCommentForm.js +21 -9
  112. package/lib/components/features/documents/TMDcmtBlog.js +1 -1
  113. package/lib/components/features/documents/TMDcmtForm.d.ts +1 -0
  114. package/lib/components/features/documents/TMDcmtForm.js +331 -65
  115. package/lib/components/features/documents/TMDcmtIcon.js +17 -12
  116. package/lib/components/features/documents/TMDcmtPreview.js +75 -38
  117. package/lib/components/features/documents/TMFileUploader.js +21 -21
  118. package/lib/components/features/documents/TMRelationViewer.js +56 -23
  119. package/lib/components/features/search/TMSavedQuerySelector.js +53 -53
  120. package/lib/components/features/search/TMSearch.js +2 -2
  121. package/lib/components/features/search/TMSearchQueryEditor.js +14 -14
  122. package/lib/components/features/search/TMSearchQueryPanel.js +41 -59
  123. package/lib/components/features/search/TMSearchResult.js +256 -51
  124. package/lib/components/features/search/TMSearchResultCheckoutInfoForm.d.ts +8 -0
  125. package/lib/components/features/search/TMSearchResultCheckoutInfoForm.js +134 -0
  126. package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +3 -2
  127. package/lib/components/features/search/TMSearchResultsMenuItems.js +94 -59
  128. package/lib/components/features/search/TMSignSettingsForm.d.ts +9 -0
  129. package/lib/components/features/search/TMSignSettingsForm.js +621 -0
  130. package/lib/components/features/search/TMTreeSelector.js +67 -67
  131. package/lib/components/features/search/TMViewHistoryDcmtForm.d.ts +18 -0
  132. package/lib/components/features/search/TMViewHistoryDcmtForm.js +215 -0
  133. package/lib/components/features/tasks/TMTaskForm.js +42 -36
  134. package/lib/components/features/tasks/TMTasksAgenda.js +4 -4
  135. package/lib/components/features/tasks/TMTasksCalendar.js +2 -2
  136. package/lib/components/features/tasks/TMTasksHeader.js +1 -1
  137. package/lib/components/features/tasks/TMTasksUtils.d.ts +2 -1
  138. package/lib/components/features/tasks/TMTasksUtils.js +18 -3
  139. package/lib/components/features/tasks/TMTasksUtilsView.js +26 -4
  140. package/lib/components/features/tasks/TMTasksView.js +12 -6
  141. package/lib/components/features/wg/TMWGsCopyMoveForm.js +9 -9
  142. package/lib/components/features/workflow/TMWorkflowPopup.js +44 -44
  143. package/lib/components/features/workflow/diagram/ConnectionComponent.js +29 -29
  144. package/lib/components/features/workflow/diagram/ConnectionForm.js +10 -10
  145. package/lib/components/features/workflow/diagram/DiagramItemComponent.js +57 -57
  146. package/lib/components/features/workflow/diagram/DiagramItemForm.js +40 -35
  147. package/lib/components/features/workflow/diagram/DiagramItemSvgContent.js +12 -12
  148. package/lib/components/features/workflow/diagram/RecipientList.js +39 -39
  149. package/lib/components/features/workflow/diagram/WFDiagram.js +317 -285
  150. package/lib/components/features/workflow/diagram/WorkitemRecipientsEditor.js +4 -4
  151. package/lib/components/forms/Login/Chooser.js +35 -35
  152. package/lib/components/forms/Login/Menu.js +22 -22
  153. package/lib/components/forms/Login/SelectBox.js +46 -46
  154. package/lib/components/forms/Login/TMLoginForm.js +14 -14
  155. package/lib/components/forms/Login/TextBox.js +57 -57
  156. package/lib/components/forms/TMResultDialog.js +8 -2
  157. package/lib/components/forms/TMSaveForm.js +3 -11
  158. package/lib/components/grids/TMBlogAttachments.d.ts +0 -14
  159. package/lib/components/grids/TMBlogAttachments.js +10 -5
  160. package/lib/components/grids/TMBlogsPost.d.ts +8 -3
  161. package/lib/components/grids/TMBlogsPost.js +100 -39
  162. package/lib/components/grids/TMBlogsPostUtils.d.ts +1 -0
  163. package/lib/components/grids/TMBlogsPostUtils.js +32 -11
  164. package/lib/components/grids/TMRecentsManager.js +52 -52
  165. package/lib/components/grids/TMValidationItemsList.js +48 -48
  166. package/lib/components/index.d.ts +2 -1
  167. package/lib/components/index.js +2 -1
  168. package/lib/components/layout/panelManager/TMPanelManagerContainer.d.ts +1 -0
  169. package/lib/components/layout/panelManager/TMPanelManagerContainer.js +14 -14
  170. package/lib/components/layout/panelManager/TMPanelManagerContext.js +0 -1
  171. package/lib/components/layout/panelManager/TMPanelManagerToolbar.js +36 -35
  172. package/lib/components/layout/panelManager/types.d.ts +1 -0
  173. package/lib/components/pages/TMPage.js +1 -1
  174. package/lib/components/query/TMQueryEditor.js +17 -17
  175. package/lib/components/query/TMQuerySummary.d.ts +1 -0
  176. package/lib/components/query/TMQuerySummary.js +15 -15
  177. package/lib/components/settings/SettingsAppearance.js +9 -1
  178. package/lib/components/sidebar/TMCommandsPanel.js +10 -10
  179. package/lib/components/sidebar/TMHeader.js +307 -307
  180. package/lib/components/sidebar/TMSidebar.js +24 -24
  181. package/lib/components/sidebar/TMSidebarItem.js +21 -21
  182. package/lib/components/viewers/TMDataListItemViewer.d.ts +1 -1
  183. package/lib/components/viewers/TMMidViewer.d.ts +1 -1
  184. package/lib/components/viewers/TMTidViewer.d.ts +1 -1
  185. package/lib/components/wizard/TMStepIndicator.js +102 -102
  186. package/lib/components/wizard/TMWizard.js +29 -29
  187. package/lib/helper/GlobalStyles.d.ts +2 -0
  188. package/lib/helper/GlobalStyles.js +10 -0
  189. package/lib/helper/Globalization.d.ts +1 -0
  190. package/lib/helper/Globalization.js +30 -0
  191. package/lib/helper/SDKUI_Globals.d.ts +9 -0
  192. package/lib/helper/SDKUI_Globals.js +10 -1
  193. package/lib/helper/SDKUI_Localizator.d.ts +59 -2
  194. package/lib/helper/SDKUI_Localizator.js +617 -22
  195. package/lib/helper/TMCustomSearchBar.js +1 -1
  196. package/lib/helper/TMIcons.d.ts +6 -1
  197. package/lib/helper/TMIcons.js +22 -2
  198. package/lib/helper/TMToppyMessage.d.ts +1 -0
  199. package/lib/helper/TMToppyMessage.js +33 -32
  200. package/lib/helper/TMUtils.d.ts +42 -4
  201. package/lib/helper/TMUtils.js +227 -60
  202. package/lib/helper/cicoHelper.d.ts +31 -0
  203. package/lib/helper/cicoHelper.js +155 -0
  204. package/lib/helper/dcmtsHelper.d.ts +2 -1
  205. package/lib/helper/dcmtsHelper.js +56 -17
  206. package/lib/helper/helpers.d.ts +8 -1
  207. package/lib/helper/helpers.js +43 -21
  208. package/lib/helper/index.d.ts +1 -0
  209. package/lib/helper/index.js +1 -0
  210. package/lib/hooks/useDcmtOperations.d.ts +1 -1
  211. package/lib/hooks/useDcmtOperations.js +10 -6
  212. package/lib/hooks/useRelatedDocuments.js +35 -26
  213. package/lib/ts/types.d.ts +3 -1
  214. package/package.json +54 -54
  215. package/lib/components/features/assistant/ToppyHelpCenter.d.ts +0 -12
  216. package/lib/components/features/assistant/ToppyHelpCenter.js +0 -173
@@ -0,0 +1,482 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useRef, useState, useEffect } from 'react';
3
+ import ReactDOM from 'react-dom';
4
+ import styled from 'styled-components';
5
+ import Toppy from '../../../assets/Toppy-generico.png';
6
+ import { DeviceType } from '../../base/TMDeviceProvider';
7
+ import ToppySpeechBubble from './ToppySpeechBubble';
8
+ import { SDKUI_Localizator } from '../../../helper';
9
+ import { IconWindowMaximize } from '../../../helper/TMIcons';
10
+ /**
11
+ * Styled component per il contenitore di Toppy
12
+ * Gestisce il posizionamento, le dimensioni e le animazioni
13
+ */
14
+ const ToppyButton = styled.div.attrs((props) => ({
15
+ style: {
16
+ // Applica left/top come stili inline per evitare la generazione di troppe classi CSS
17
+ ...(props.$x !== undefined && props.$y !== undefined
18
+ ? {
19
+ left: `${props.$x}px`,
20
+ top: `${props.$y}px`,
21
+ bottom: 'auto',
22
+ right: 'auto',
23
+ }
24
+ : {}),
25
+ // Cursore applicato come stile inline
26
+ cursor: props.$isDragging ? 'grabbing' : 'grab',
27
+ },
28
+ })) `
29
+ /* Visibilità controllata dalla prop */
30
+ display: ${(props) => (props.$isVisible ? 'flex' : 'none')};
31
+ position: ${(props) => props.$usePortal ? 'fixed' : 'absolute'};
32
+
33
+ /* Posizionamento di default quando non è draggato (x e y non sono definiti) */
34
+ ${(props) => props.$x === undefined || props.$y === undefined
35
+ ? `
36
+ bottom: ${props.$isMobile ? (props.$isCollapsed ? '-20px' : '-50px') : '-20px'};
37
+ ${props.$align === 'left' ? 'left: 10px;' : 'right: 10px;'};
38
+ `
39
+ : ''}
40
+
41
+ /* Z-index alto per assicurare che sia sempre in primo piano */
42
+ z-index: 2147483647;
43
+ background-color: transparent;
44
+ border: none;
45
+ padding: 0;
46
+ outline: none;
47
+
48
+ /* Dimensioni dinamiche in base allo stato collassato e al tipo di dispositivo
49
+ Usa min() per adattarsi su schermi piccoli */
50
+ width: ${(props) => {
51
+ return props.$isCollapsed ? 'min(60px, 100%)' : '120px';
52
+ }};
53
+ height: ${(props) => {
54
+ return props.$isCollapsed ? 'min(70px, 100%)' : '140px';
55
+ }};
56
+ max-width: 100%;
57
+ max-height: 100%;
58
+
59
+ user-select: none;
60
+
61
+ img {
62
+ /* Dimensioni dell'immagine in base allo stato collassato e al tipo di dispositivo */
63
+ width: ${(props) => props.$isCollapsed ? (props.$isMobile ? '40px' : '60px') : (props.$isMobile ? '80px' : '120px')};
64
+ height: ${(props) => props.$isCollapsed ? (props.$isMobile ? '40px' : '60px') : (props.$isMobile ? '100px' : '140px')};
65
+ pointer-events: ${(props) => (props.$isMobile ? 'auto' : 'none')};
66
+ border-radius: 50%; /* Rende l'immagine circolare */
67
+ /* Rotazione leggera in base all'allineamento */
68
+ transform: ${(props) => props.$isCollapsed
69
+ ? 'rotate(0deg)'
70
+ : props.$align === 'left' ? 'rotate(20deg)' : 'rotate(-20deg)'};
71
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
72
+
73
+ /* Animazione di pulsazione quando è collassato per attirare l'attenzione */
74
+ ${(props) => props.$isCollapsed && `animation: toppyPulse 1.5s infinite;`}
75
+ }
76
+
77
+ /* Keyframes per l'animazione di pulsazione */
78
+ @keyframes toppyPulse {
79
+ 0% {
80
+ /* Dimensione normale all'inizio */
81
+ transform: scale(1) rotate(0deg);
82
+ box-shadow: 0 0 0 rgba(0, 113, 188, 0.5);
83
+ }
84
+ 50% {
85
+ /* Ingrandimento e glow al 50% dell'animazione */
86
+ transform: scale(1.1) rotate(0deg);
87
+ box-shadow: 0 0 15px 5px rgba(0, 113, 188, 0.6);
88
+ }
89
+ 100% {
90
+ /* Ritorno alla dimensione normale */
91
+ transform: scale(1) rotate(0deg);
92
+ box-shadow: 0 0 0 rgba(0, 113, 188, 0.5);
93
+ }
94
+ }
95
+ `;
96
+ /**
97
+ * Pulsante di espansione quando Toppy è minimizzato
98
+ */
99
+ const ExpandButton = styled.button `
100
+ position: absolute;
101
+ top: -8px;
102
+ right: -8px;
103
+ width: 24px;
104
+ height: 24px;
105
+ border-radius: 50%;
106
+ border: 2px solid rgba(255, 255, 255, 0.9);
107
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
108
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4), 0 0 20px rgba(118, 75, 162, 0.2);
109
+ cursor: pointer;
110
+ display: flex;
111
+ align-items: center;
112
+ justify-content: center;
113
+ transition: all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
114
+ z-index: 10001;
115
+ color: white;
116
+ font-size: 14px;
117
+
118
+ &:hover {
119
+ background: linear-gradient(135deg, #764ba2 0%, #f093fb 100%);
120
+ box-shadow: 0 6px 20px rgba(118, 75, 162, 0.6), 0 0 30px rgba(240, 147, 251, 0.4);
121
+ border-color: rgba(255, 255, 255, 1);
122
+ transform: scale(1.1);
123
+ }
124
+
125
+ &:active {
126
+ transform: scale(0.95);
127
+ box-shadow: 0 2px 8px rgba(102, 126, 234, 0.4);
128
+ }
129
+
130
+ &:focus {
131
+ outline: none;
132
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4), 0 0 0 3px rgba(102, 126, 234, 0.2);
133
+ }
134
+ `;
135
+ /**
136
+ * Overlay trasparente per bloccare le interazioni durante il drag
137
+ * Previene problemi di performance con iframe e altri elementi interattivi
138
+ */
139
+ const DragOverlay = styled.div `
140
+ position: fixed;
141
+ top: 0;
142
+ left: 0;
143
+ right: 0;
144
+ bottom: 0;
145
+ z-index: 2147483646;
146
+ cursor: grabbing;
147
+ `;
148
+ /**
149
+ * Componente ToppyDraggableHelpCenter
150
+ *
151
+ * Renderizza un assistente virtuale (Toppy) draggable che può mostrare contenuti
152
+ * in una speech bubble. Il componente può essere trascinato all'interno del suo
153
+ * contenitore e può essere collassato/espanso con un doppio click.
154
+ */
155
+ const ToppyDraggableHelpCenter = ({ content, deviceType, align = 'right', onToppyImageClick, initialIsCollapsed, isVisible = true, usePortal = false, }) => {
156
+ // Configurazione del layout e dei limiti di posizionamento di Toppy
157
+ const LAYOUT_CONFIG = {
158
+ bottomOffsetDesktop: 20, // Quanto Toppy può uscire dal bordo inferiore su desktop
159
+ bottomOffsetMobileCollapsed: 20, // Quanto Toppy può uscire dal bordo inferiore su mobile quando è collassato
160
+ bottomOffsetMobileExpanded: 50, // Quanto Toppy può uscire dal bordo inferiore su mobile quando è espanso
161
+ buttonOffset: 8, // Spazio extra per i bottoni posizionati a -8px (ExpandButton, CloseButton)
162
+ closeButtonOffset: 8, // Offset dei bottoni che sporgono dalla bubble (CloseButton sulla bubble)
163
+ bubbleBuffer: 5, // Buffer di sicurezza per evitare sovrapposizioni con la bubble
164
+ minTopOffset: 8 // Limite minimo dall'alto per evitare che i bottoni superiori escano
165
+ };
166
+ // Ref per il contenitore principale
167
+ const buttonRef = useRef(null);
168
+ // Stato per controllare se il componente è collassato o espanso
169
+ const [isCollapsed, setIsCollapsed] = useState(initialIsCollapsed ?? false);
170
+ // Stato per tracciare se il componente è in fase di trascinamento
171
+ const [isDragging, setIsDragging] = useState(false);
172
+ // Posizione corrente del componente (null = posizione di default)
173
+ const [position, setPosition] = useState(null);
174
+ // Offset del mouse rispetto all'angolo superiore sinistro del componente durante il drag
175
+ const dragOffset = useRef({ x: 0, y: 0 });
176
+ // Ref e stato per tracciare le dimensioni della speech bubble
177
+ const bubbleRef = useRef(null);
178
+ const [bubbleSize, setBubbleSize] = useState({ width: 0, height: 0 });
179
+ // Ref per tracciare il dragging dell'ExpandButton
180
+ const isExpandButtonDraggingRef = useRef(false);
181
+ const expandButtonMouseDownPosRef = useRef(null);
182
+ const isMobile = deviceType === DeviceType.MOBILE;
183
+ /**
184
+ * Effect per aggiornare le dimensioni della bubble quando cambia il contenuto
185
+ * o lo stato di collassamento. Necessario per calcolare correttamente i limiti
186
+ * di trascinamento.
187
+ */
188
+ useEffect(() => {
189
+ if (bubbleRef.current) {
190
+ const rect = bubbleRef.current.getBoundingClientRect();
191
+ setBubbleSize({ width: rect.width, height: rect.height });
192
+ }
193
+ }, [content, isCollapsed]);
194
+ /**
195
+ * Effect per verificare e aggiustare la posizione quando cambia lo stato di collassamento
196
+ */
197
+ useEffect(() => {
198
+ if (!buttonRef.current || !position)
199
+ return;
200
+ const rect = buttonRef.current.getBoundingClientRect();
201
+ // Spazio extra occupato dalla bubble quando non è collassato
202
+ const extraHeight = !isCollapsed ? bubbleSize.height + LAYOUT_CONFIG.closeButtonOffset : 0;
203
+ const extraWidth = !isCollapsed ? bubbleSize.width + LAYOUT_CONFIG.closeButtonOffset : 0;
204
+ let minX = 0;
205
+ let maxX;
206
+ let maxY;
207
+ const minY = LAYOUT_CONFIG.minTopOffset;
208
+ if (usePortal) {
209
+ // Calcola i limiti usando le dimensioni del viewport
210
+ maxX = window.innerWidth - rect.width - LAYOUT_CONFIG.buttonOffset;
211
+ maxY = window.innerHeight - rect.height + (isMobile ? (isCollapsed ? LAYOUT_CONFIG.bottomOffsetMobileCollapsed : LAYOUT_CONFIG.bottomOffsetMobileExpanded) : LAYOUT_CONFIG.bottomOffsetDesktop);
212
+ }
213
+ else {
214
+ // Calcola i limiti usando le dimensioni del parent
215
+ const parent = buttonRef.current.offsetParent;
216
+ if (!parent)
217
+ return;
218
+ const parentRect = parent.getBoundingClientRect();
219
+ maxX = parentRect.width - rect.width - LAYOUT_CONFIG.buttonOffset;
220
+ maxY = parentRect.height - rect.height + (isMobile ? (isCollapsed ? LAYOUT_CONFIG.bottomOffsetMobileCollapsed : LAYOUT_CONFIG.bottomOffsetMobileExpanded) : LAYOUT_CONFIG.bottomOffsetDesktop);
221
+ }
222
+ if (!isCollapsed) {
223
+ if (align === 'right') {
224
+ minX = Math.max(0, extraWidth - rect.width);
225
+ }
226
+ else {
227
+ maxX = Math.min(maxX, (usePortal ? window.innerWidth : buttonRef.current.offsetParent?.getBoundingClientRect().width || 0) - extraWidth);
228
+ }
229
+ }
230
+ // Verifica se la posizione corrente è fuori dai limiti
231
+ const isOutOfBounds = position.x < minX ||
232
+ position.x > maxX ||
233
+ position.y < Math.max(minY, extraHeight + LAYOUT_CONFIG.bubbleBuffer) ||
234
+ position.y > maxY;
235
+ // Se è fuori dai limiti, aggiusta la posizione
236
+ if (isOutOfBounds) {
237
+ const adjustedX = Math.max(minX, Math.min(position.x, maxX));
238
+ const adjustedY = Math.max(Math.max(minY, extraHeight + LAYOUT_CONFIG.bubbleBuffer), Math.min(position.y, maxY));
239
+ setPosition({ x: adjustedX, y: adjustedY });
240
+ }
241
+ }, [isCollapsed, bubbleSize, usePortal, align]);
242
+ /**
243
+ * Effect per resettare la posizione quando il parent o la finestra vengono ridimensionati
244
+ */
245
+ useEffect(() => {
246
+ if (!buttonRef.current || !position)
247
+ return;
248
+ const handleResize = () => {
249
+ if (!buttonRef.current || !position)
250
+ return;
251
+ const rect = buttonRef.current.getBoundingClientRect();
252
+ // Spazio extra occupato dalla bubble quando non è collassato
253
+ const extraHeight = !isCollapsed ? bubbleSize.height + LAYOUT_CONFIG.closeButtonOffset : 0;
254
+ const extraWidth = !isCollapsed ? bubbleSize.width + LAYOUT_CONFIG.closeButtonOffset : 0;
255
+ let minX = 0;
256
+ let maxX;
257
+ let maxY;
258
+ const minY = LAYOUT_CONFIG.minTopOffset;
259
+ if (usePortal) {
260
+ maxX = window.innerWidth - rect.width - LAYOUT_CONFIG.buttonOffset;
261
+ maxY = window.innerHeight - rect.height + (isMobile ? (isCollapsed ? LAYOUT_CONFIG.bottomOffsetMobileCollapsed : LAYOUT_CONFIG.bottomOffsetMobileExpanded) : LAYOUT_CONFIG.bottomOffsetDesktop);
262
+ }
263
+ else {
264
+ const parent = buttonRef.current.offsetParent;
265
+ if (!parent)
266
+ return;
267
+ const parentRect = parent.getBoundingClientRect();
268
+ maxX = parentRect.width - rect.width - LAYOUT_CONFIG.buttonOffset;
269
+ maxY = parentRect.height - rect.height + (isMobile ? (isCollapsed ? LAYOUT_CONFIG.bottomOffsetMobileCollapsed : LAYOUT_CONFIG.bottomOffsetMobileExpanded) : LAYOUT_CONFIG.bottomOffsetDesktop);
270
+ }
271
+ if (!isCollapsed) {
272
+ if (align === 'right') {
273
+ minX = Math.max(0, extraWidth - rect.width);
274
+ }
275
+ else {
276
+ maxX = Math.min(maxX, (usePortal ? window.innerWidth : buttonRef.current.offsetParent?.getBoundingClientRect().width || 0) - extraWidth);
277
+ }
278
+ }
279
+ const isOutOfBounds = position.x < minX ||
280
+ position.x > maxX ||
281
+ position.y < Math.max(minY, extraHeight + LAYOUT_CONFIG.bubbleBuffer) ||
282
+ position.y > maxY;
283
+ if (isOutOfBounds) {
284
+ setPosition(null);
285
+ }
286
+ };
287
+ // Observer per il parent se non usa Portal
288
+ let resizeObserver;
289
+ if (!usePortal) {
290
+ const parent = buttonRef.current.offsetParent;
291
+ if (parent) {
292
+ resizeObserver = new ResizeObserver(handleResize);
293
+ resizeObserver.observe(parent);
294
+ }
295
+ }
296
+ window.addEventListener('resize', handleResize);
297
+ return () => {
298
+ resizeObserver?.disconnect();
299
+ window.removeEventListener('resize', handleResize);
300
+ };
301
+ }, [position, isCollapsed, bubbleSize, align, usePortal]);
302
+ /**
303
+ * Effect per impostare automaticamente lo stato collassato su dispositivi mobile
304
+ * se non è stato specificato un valore iniziale.
305
+ */
306
+ useEffect(() => {
307
+ if (initialIsCollapsed === undefined && deviceType === DeviceType.MOBILE) {
308
+ setIsCollapsed(true);
309
+ }
310
+ }, [deviceType, initialIsCollapsed]);
311
+ /**
312
+ * Gestisce il toggle dello stato collassato/espanso
313
+ * Chiamato dal doppio click sul componente
314
+ */
315
+ const toggleCollapse = (e) => {
316
+ e?.stopPropagation();
317
+ setIsCollapsed(!isCollapsed);
318
+ onToppyImageClick?.();
319
+ };
320
+ /**
321
+ * Gestisce l'inizio del trascinamento
322
+ * Salva la posizione relativa del mouse rispetto al componente (offset)
323
+ * per mantenere il punto di presa durante il trascinamento
324
+ */
325
+ const handleMouseDown = (e) => {
326
+ if (!buttonRef.current)
327
+ return;
328
+ const rect = buttonRef.current.getBoundingClientRect();
329
+ // Calcola l'offset tra il punto di click e l'angolo superiore sinistro del componente
330
+ dragOffset.current = {
331
+ x: e.clientX - rect.left,
332
+ y: e.clientY - rect.top,
333
+ };
334
+ setIsDragging(true);
335
+ e.preventDefault();
336
+ };
337
+ /**
338
+ * Gestisce l'inizio del trascinamento per eventi touch
339
+ */
340
+ const handleTouchStart = (e) => {
341
+ if (!buttonRef.current)
342
+ return;
343
+ const touch = e.touches[0];
344
+ const rect = buttonRef.current.getBoundingClientRect();
345
+ // Calcola l'offset tra il punto di touch e l'angolo superiore sinistro del componente
346
+ dragOffset.current = {
347
+ x: touch.clientX - rect.left,
348
+ y: touch.clientY - rect.top,
349
+ };
350
+ setIsDragging(true);
351
+ e.preventDefault();
352
+ };
353
+ /**
354
+ * Gestisce il movimento durante il trascinamento
355
+ * Calcola la nuova posizione rispettando i limiti del parent o viewport
356
+ * e tenendo conto delle dimensioni della speech bubble quando espansa
357
+ */
358
+ const handleMouseMove = (e) => {
359
+ if (!isDragging || !buttonRef.current)
360
+ return;
361
+ // Estrae le coordinate dal tipo di evento appropriato
362
+ const clientX = 'touches' in e ? e.touches[0].clientX : e.clientX;
363
+ const clientY = 'touches' in e ? e.touches[0].clientY : e.clientY;
364
+ const rect = buttonRef.current.getBoundingClientRect();
365
+ // Spazio extra occupato dalla bubble quando non è collassato
366
+ const extraHeight = !isCollapsed ? bubbleSize.height + LAYOUT_CONFIG.closeButtonOffset : 0;
367
+ const extraWidth = !isCollapsed ? bubbleSize.width + LAYOUT_CONFIG.closeButtonOffset : 0;
368
+ let minX = 0;
369
+ let maxX;
370
+ let maxY;
371
+ let newX;
372
+ let newY;
373
+ const minY = LAYOUT_CONFIG.minTopOffset;
374
+ if (usePortal) {
375
+ // Calcola i limiti usando il viewport
376
+ maxX = window.innerWidth - rect.width - LAYOUT_CONFIG.buttonOffset;
377
+ maxY = window.innerHeight - rect.height + (isMobile ? (isCollapsed ? LAYOUT_CONFIG.bottomOffsetMobileCollapsed : LAYOUT_CONFIG.bottomOffsetMobileExpanded) : LAYOUT_CONFIG.bottomOffsetDesktop);
378
+ if (!isCollapsed) {
379
+ if (align === 'right') {
380
+ minX = Math.max(0, extraWidth - rect.width);
381
+ }
382
+ else {
383
+ maxX = Math.min(maxX, window.innerWidth - extraWidth);
384
+ }
385
+ }
386
+ newX = Math.max(minX, Math.min(clientX - dragOffset.current.x, maxX));
387
+ newY = Math.max(Math.max(minY, extraHeight + LAYOUT_CONFIG.bubbleBuffer), Math.min(clientY - dragOffset.current.y, maxY));
388
+ }
389
+ else {
390
+ // Calcola i limiti usando il parent
391
+ const parent = buttonRef.current.offsetParent;
392
+ if (!parent)
393
+ return;
394
+ const parentRect = parent.getBoundingClientRect();
395
+ maxX = parentRect.width - rect.width - LAYOUT_CONFIG.buttonOffset;
396
+ maxY = parentRect.height - rect.height + (isMobile ? (isCollapsed ? LAYOUT_CONFIG.bottomOffsetMobileCollapsed : LAYOUT_CONFIG.bottomOffsetMobileExpanded) : LAYOUT_CONFIG.bottomOffsetDesktop);
397
+ if (!isCollapsed) {
398
+ if (align === 'right') {
399
+ minX = Math.max(0, extraWidth - rect.width);
400
+ }
401
+ else {
402
+ maxX = Math.min(maxX, parentRect.width - extraWidth);
403
+ }
404
+ }
405
+ newX = Math.max(minX, Math.min(clientX - parentRect.left - dragOffset.current.x, maxX));
406
+ newY = Math.max(Math.max(minY, extraHeight + LAYOUT_CONFIG.bubbleBuffer), Math.min(clientY - parentRect.top - dragOffset.current.y, maxY));
407
+ }
408
+ setPosition({ x: newX, y: newY });
409
+ };
410
+ /**
411
+ * Gestisce il rilascio del mouse alla fine del trascinamento
412
+ * Se il movimento è stato minimo (< 5px), viene interpretato come un click
413
+ * e viene chiamato il callback onToppyImageClick
414
+ */
415
+ const handleMouseUp = (e) => {
416
+ if (isDragging) {
417
+ setIsDragging(false);
418
+ // Estrae le coordinate dal tipo di evento appropriato
419
+ const clientX = 'changedTouches' in e ? e.changedTouches[0].clientX : e.clientX;
420
+ const clientY = 'changedTouches' in e ? e.changedTouches[0].clientY : e.clientY;
421
+ const rect = buttonRef.current?.getBoundingClientRect();
422
+ if (rect) {
423
+ // Calcola la distanza totale del movimento usando il teorema di Pitagora
424
+ const moveDistance = Math.hypot(clientX - (rect.left + dragOffset.current.x), clientY - (rect.top + dragOffset.current.y));
425
+ // Se il movimento è stato minimo, trattalo come un click
426
+ if (moveDistance < 5 && onToppyImageClick) {
427
+ onToppyImageClick();
428
+ }
429
+ }
430
+ }
431
+ };
432
+ /**
433
+ * Effect per gestire gli event listener durante il trascinamento
434
+ * Gli eventi sono registrati sul document per catturare il movimento
435
+ * anche quando il mouse o il touch esce dal componente
436
+ */
437
+ useEffect(() => {
438
+ if (isDragging) {
439
+ // Eventi mouse per desktop
440
+ document.addEventListener('mousemove', handleMouseMove);
441
+ document.addEventListener('mouseup', handleMouseUp);
442
+ // Eventi touch per mobile
443
+ document.addEventListener('touchmove', handleMouseMove);
444
+ document.addEventListener('touchend', handleMouseUp);
445
+ return () => {
446
+ document.removeEventListener('mousemove', handleMouseMove);
447
+ document.removeEventListener('mouseup', handleMouseUp);
448
+ document.removeEventListener('touchmove', handleMouseMove);
449
+ document.removeEventListener('touchend', handleMouseUp);
450
+ };
451
+ }
452
+ return undefined;
453
+ }, [isDragging]);
454
+ // Renderizza l'overlay solo durante il drag
455
+ const renderDragOverlay = isDragging && _jsx(DragOverlay, {});
456
+ const toppyContent = (_jsxs(_Fragment, { children: [renderDragOverlay, _jsxs(ToppyButton, { ref: buttonRef, "$align": align, "$isDragging": isDragging, "$x": position?.x, "$y": position?.y, "$isVisible": isVisible, "$isCollapsed": isCollapsed, "$isMobile": isMobile, "$usePortal": usePortal, onMouseDown: !isMobile ? handleMouseDown : undefined, onTouchStart: isMobile ? handleTouchStart : undefined, onContextMenu: (e) => e.preventDefault(), onDoubleClick: !isMobile ? toggleCollapse : undefined, children: [(content && !isCollapsed) && (_jsx(ToppySpeechBubble, { ref: bubbleRef, align: align, onClose: toggleCollapse, children: content })), (content && isCollapsed) && (_jsx(ExpandButton, { onMouseDown: (e) => {
457
+ isExpandButtonDraggingRef.current = false;
458
+ expandButtonMouseDownPosRef.current = { x: e.clientX, y: e.clientY };
459
+ }, onMouseMove: (e) => {
460
+ if (!expandButtonMouseDownPosRef.current)
461
+ return;
462
+ const deltaX = Math.abs(e.clientX - expandButtonMouseDownPosRef.current.x);
463
+ const deltaY = Math.abs(e.clientY - expandButtonMouseDownPosRef.current.y);
464
+ // Considera drag solo se il movimento supera 3px
465
+ if (deltaX > 3 || deltaY > 3) {
466
+ isExpandButtonDraggingRef.current = true;
467
+ }
468
+ }, onMouseUp: () => {
469
+ expandButtonMouseDownPosRef.current = null;
470
+ }, onClick: (e) => {
471
+ if (isExpandButtonDraggingRef.current) {
472
+ e.stopPropagation();
473
+ e.preventDefault();
474
+ return;
475
+ }
476
+ e.stopPropagation();
477
+ toggleCollapse(e);
478
+ }, onContextMenu: (e) => e.preventDefault(), "aria-label": SDKUI_Localizator.Maximize, title: SDKUI_Localizator.Maximize, type: "button", children: _jsx(IconWindowMaximize, {}) })), _jsx("img", { src: Toppy, alt: "Toppy Help", draggable: false })] })] }));
479
+ // Renderizza nel document.body usando un Portal se usePortal è true, altrimenti renderizza normalmente
480
+ return usePortal ? ReactDOM.createPortal(toppyContent, document.body) : toppyContent;
481
+ };
482
+ export default ToppyDraggableHelpCenter;
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ interface ToppySpeechBubbleProps {
3
+ align?: 'left' | 'right';
4
+ children: React.ReactNode;
5
+ className?: string;
6
+ onClose?: () => void;
7
+ }
8
+ declare const ToppySpeechBubble: React.ForwardRefExoticComponent<ToppySpeechBubbleProps & React.RefAttributes<HTMLDivElement>>;
9
+ export default ToppySpeechBubble;
@@ -0,0 +1,117 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React, { forwardRef } from 'react';
3
+ import styled from 'styled-components';
4
+ import { SDKUI_Localizator } from '../../../helper';
5
+ import { IconWindowMinimize } from '../../../helper/TMIcons';
6
+ // Styled component
7
+ const Bubble = styled.div `
8
+ position: absolute;
9
+ bottom: 145px;
10
+ ${({ $align }) => ($align === 'left' ? 'left: 0px;' : 'right: 0px;')}
11
+ width: max-content;
12
+ padding: 10px;
13
+ background: linear-gradient(180deg, rgba(0, 113, 188, 0.45) 0%,rgba(27, 20, 100, 0.65) 100%);
14
+ border-radius: 18px;
15
+ box-shadow: 0 10px 28px rgba(0, 0, 0, 0.18);
16
+ font-size: 14px;
17
+ line-height: 1.4;
18
+ color: #333;
19
+ z-index: 10000;
20
+
21
+ &::after {
22
+ transform: ${({ $align }) => ($align === 'left' ? 'skewX(15deg)' : 'skewX(-15deg)')};
23
+ content: "";
24
+ position: absolute;
25
+ top: 100%;
26
+ ${({ $align }) => ($align === 'left' ? 'left: 20px;' : 'right: 15px;')}
27
+ border-width: 32px 32px 0 0;
28
+ border-style: solid;
29
+ border-color: #FFFFFF transparent;
30
+ display: block;
31
+ width: 0;
32
+ height: 0;
33
+ z-index: 1;
34
+ }
35
+
36
+ &::before {
37
+ transform: ${({ $align }) => ($align === 'left' ? 'skewX(15deg)' : 'skewX(-15deg)')};
38
+ content: "";
39
+ position: absolute;
40
+ top: 100%;
41
+ ${({ $align }) => ($align === 'left' ? 'left: 20px;' : 'right: 15px;')}
42
+ border-width: 32px 32px 0 0;
43
+ border-style: solid;
44
+ border-color: rgba(27, 20, 100, 0.65) transparent;
45
+ display: block;
46
+ width: 0;
47
+ height: 0;
48
+ z-index: 2;
49
+ }
50
+ `;
51
+ const CloseButton = styled.button `
52
+ position: absolute;
53
+ top: -8px;
54
+ right: -8px;
55
+ width: 24px;
56
+ height: 24px;
57
+ border-radius: 50%;
58
+ border: 2px solid rgba(255, 255, 255, 0.9);
59
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
60
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4), 0 0 20px rgba(118, 75, 162, 0.2);
61
+ cursor: pointer;
62
+ display: flex;
63
+ align-items: center;
64
+ justify-content: center;
65
+ transition: all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
66
+ z-index: 10001;
67
+ color: white;
68
+ font-size: 14px;
69
+
70
+ &:hover {
71
+ background: linear-gradient(135deg, #764ba2 0%, #f093fb 100%);
72
+ box-shadow: 0 6px 20px rgba(118, 75, 162, 0.6), 0 0 30px rgba(240, 147, 251, 0.4);
73
+ border-color: rgba(255, 255, 255, 1);
74
+ }
75
+
76
+ &:active {
77
+ transform: scale(0.95);
78
+ box-shadow: 0 2px 8px rgba(102, 126, 234, 0.4);
79
+ }
80
+
81
+ &:focus {
82
+ outline: none;
83
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4), 0 0 0 3px rgba(102, 126, 234, 0.2);
84
+ }
85
+ `;
86
+ // Componente con forwardRef
87
+ const ToppySpeechBubble = forwardRef(({ align = 'right', children, className, onClose }, ref) => {
88
+ const isDraggingRef = React.useRef(false);
89
+ const mouseDownPosRef = React.useRef(null);
90
+ const handleMouseDown = (e) => {
91
+ isDraggingRef.current = false;
92
+ mouseDownPosRef.current = { x: e.clientX, y: e.clientY };
93
+ };
94
+ const handleMouseMove = (e) => {
95
+ if (!mouseDownPosRef.current)
96
+ return;
97
+ const deltaX = Math.abs(e.clientX - mouseDownPosRef.current.x);
98
+ const deltaY = Math.abs(e.clientY - mouseDownPosRef.current.y);
99
+ // Considera drag solo se il movimento supera 3px
100
+ if (deltaX > 3 || deltaY > 3) {
101
+ isDraggingRef.current = true;
102
+ }
103
+ };
104
+ const handleClick = (e) => {
105
+ if (isDraggingRef.current) {
106
+ e.stopPropagation();
107
+ e.preventDefault();
108
+ return;
109
+ }
110
+ onClose?.();
111
+ };
112
+ const handleMouseUp = () => {
113
+ mouseDownPosRef.current = null;
114
+ };
115
+ return (_jsxs(Bubble, { ref: ref, "$align": align, className: className, children: [onClose && (_jsx(CloseButton, { onMouseDown: handleMouseDown, onMouseMove: handleMouseMove, onMouseUp: handleMouseUp, onClick: handleClick, "aria-label": SDKUI_Localizator.Minimize, title: SDKUI_Localizator.Minimize, type: "button", children: _jsx(IconWindowMinimize, {}) })), children] }));
116
+ });
117
+ export default ToppySpeechBubble;
@@ -6,12 +6,14 @@ interface TMBlogCommentFormProps {
6
6
  participants: Array<UserDescriptor>;
7
7
  onClose: () => void;
8
8
  showAttachmentsSection?: boolean;
9
+ removeAndEditAttachment?: boolean;
9
10
  selectedAttachments?: Array<FileItem>;
10
11
  selectedAttachmentDid?: Array<number>;
11
12
  allFileItems?: FileItem;
12
13
  allArchivedDocumentsFileItems?: Array<FileItem>;
13
14
  onFilterCreated?: (predicate: (post: BlogPost) => boolean) => void;
14
15
  refreshCallback?: () => Promise<void>;
16
+ isCommentRequired?: boolean;
15
17
  }
16
18
  declare const TMBlogCommentForm: (props: TMBlogCommentFormProps) => import("react/jsx-runtime").JSX.Element;
17
19
  export default TMBlogCommentForm;