@topconsultnpm/sdkui-react 6.19.0-dev2.53 → 6.19.0-dev2.55

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.
@@ -5,6 +5,8 @@ import styled from 'styled-components';
5
5
  import Toppy from '../../../assets/Toppy-generico.png';
6
6
  import { DeviceType } from '../../base/TMDeviceProvider';
7
7
  import ToppySpeechBubble from './ToppySpeechBubble';
8
+ import { SDKUI_Localizator } from '../../../helper';
9
+ import { IconWindowMaximize } from '../../../helper/TMIcons';
8
10
  /**
9
11
  * Styled component per il contenitore di Toppy
10
12
  * Gestisce il posizionamento, le dimensioni e le animazioni
@@ -107,6 +109,45 @@ const ToppyButton = styled.div.attrs((props) => ({
107
109
  }
108
110
  }
109
111
  `;
112
+ /**
113
+ * Pulsante di espansione quando Toppy è minimizzato
114
+ */
115
+ const ExpandButton = styled.button `
116
+ position: absolute;
117
+ top: -8px;
118
+ right: -8px;
119
+ width: 24px;
120
+ height: 24px;
121
+ border-radius: 50%;
122
+ border: 2px solid rgba(255, 255, 255, 0.9);
123
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
124
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4), 0 0 20px rgba(118, 75, 162, 0.2);
125
+ cursor: pointer;
126
+ display: flex;
127
+ align-items: center;
128
+ justify-content: center;
129
+ transition: all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
130
+ z-index: 10001;
131
+ color: white;
132
+ font-size: 14px;
133
+
134
+ &:hover {
135
+ background: linear-gradient(135deg, #764ba2 0%, #f093fb 100%);
136
+ box-shadow: 0 6px 20px rgba(118, 75, 162, 0.6), 0 0 30px rgba(240, 147, 251, 0.4);
137
+ border-color: rgba(255, 255, 255, 1);
138
+ transform: scale(1.1);
139
+ }
140
+
141
+ &:active {
142
+ transform: scale(0.95);
143
+ box-shadow: 0 2px 8px rgba(102, 126, 234, 0.4);
144
+ }
145
+
146
+ &:focus {
147
+ outline: none;
148
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4), 0 0 0 3px rgba(102, 126, 234, 0.2);
149
+ }
150
+ `;
110
151
  /**
111
152
  * Overlay trasparente per bloccare le interazioni durante il drag
112
153
  * Previene problemi di performance con iframe e altri elementi interattivi
@@ -141,6 +182,9 @@ const ToppyDraggableHelpCenter = ({ content, deviceType, align = 'right', onTopp
141
182
  // Ref e stato per tracciare le dimensioni della speech bubble
142
183
  const bubbleRef = useRef(null);
143
184
  const [bubbleSize, setBubbleSize] = useState({ width: 0, height: 0 });
185
+ // Ref per tracciare il dragging dell'ExpandButton
186
+ const isExpandButtonDraggingRef = useRef(false);
187
+ const expandButtonMouseDownPosRef = useRef(null);
144
188
  const isMobile = deviceType === DeviceType.MOBILE;
145
189
  /**
146
190
  * Effect per aggiornare le dimensioni della bubble quando cambia il contenuto
@@ -386,7 +430,29 @@ const ToppyDraggableHelpCenter = ({ content, deviceType, align = 'right', onTopp
386
430
  }, [isDragging]);
387
431
  // Renderizza l'overlay solo durante il drag
388
432
  const renderDragOverlay = isDragging && _jsx(DragOverlay, {});
389
- 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, onContextMenu: (e) => e.preventDefault(), onDoubleClick: !isMobile ? toggleCollapse : undefined, children: [(content && !isCollapsed) && (_jsx(ToppySpeechBubble, { ref: bubbleRef, align: align, onClose: toggleCollapse, children: content })), _jsx("img", { src: Toppy, alt: "Toppy Help", draggable: false, onClick: isMobile ? toggleCollapse : undefined })] })] }));
433
+ 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, 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) => {
434
+ isExpandButtonDraggingRef.current = false;
435
+ expandButtonMouseDownPosRef.current = { x: e.clientX, y: e.clientY };
436
+ }, onMouseMove: (e) => {
437
+ if (!expandButtonMouseDownPosRef.current)
438
+ return;
439
+ const deltaX = Math.abs(e.clientX - expandButtonMouseDownPosRef.current.x);
440
+ const deltaY = Math.abs(e.clientY - expandButtonMouseDownPosRef.current.y);
441
+ // Considera drag solo se il movimento supera 3px
442
+ if (deltaX > 3 || deltaY > 3) {
443
+ isExpandButtonDraggingRef.current = true;
444
+ }
445
+ }, onMouseUp: () => {
446
+ expandButtonMouseDownPosRef.current = null;
447
+ }, onClick: (e) => {
448
+ if (isExpandButtonDraggingRef.current) {
449
+ e.stopPropagation();
450
+ e.preventDefault();
451
+ return;
452
+ }
453
+ e.stopPropagation();
454
+ toggleCollapse(e);
455
+ }, 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, onClick: isMobile ? toggleCollapse : undefined })] })] }));
390
456
  // Renderizza nel document.body usando un Portal se usePortal è true, altrimenti renderizza normalmente
391
457
  return usePortal ? ReactDOM.createPortal(toppyContent, document.body) : toppyContent;
392
458
  };
@@ -1,7 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { forwardRef } from 'react';
2
+ import React, { forwardRef } from 'react';
3
3
  import styled from 'styled-components';
4
4
  import { SDKUI_Localizator } from '../../../helper';
5
+ import { IconCloseOutline } from '../../../helper/TMIcons';
5
6
  // Styled component
6
7
  const Bubble = styled.div `
7
8
  position: absolute;
@@ -63,25 +64,8 @@ const CloseButton = styled.button `
63
64
  justify-content: center;
64
65
  transition: all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
65
66
  z-index: 10001;
66
-
67
- &::before,
68
- &::after {
69
- content: '';
70
- position: absolute;
71
- width: 11px;
72
- height: 2px;
73
- background: white;
74
- border-radius: 2px;
75
- transition: all 0.3s ease;
76
- }
77
-
78
- &::before {
79
- transform: rotate(45deg);
80
- }
81
-
82
- &::after {
83
- transform: rotate(-45deg);
84
- }
67
+ color: white;
68
+ font-size: 14px;
85
69
 
86
70
  &:hover {
87
71
  background: linear-gradient(135deg, #764ba2 0%, #f093fb 100%);
@@ -90,7 +74,7 @@ const CloseButton = styled.button `
90
74
  }
91
75
 
92
76
  &:active {
93
- transform: rotate(90deg) scale(0.95);
77
+ transform: scale(0.95);
94
78
  box-shadow: 0 2px 8px rgba(102, 126, 234, 0.4);
95
79
  }
96
80
 
@@ -101,6 +85,33 @@ const CloseButton = styled.button `
101
85
  `;
102
86
  // Componente con forwardRef
103
87
  const ToppySpeechBubble = forwardRef(({ align = 'right', children, className, onClose }, ref) => {
104
- return (_jsxs(Bubble, { ref: ref, "$align": align, className: className, children: [onClose && (_jsx(CloseButton, { onClick: onClose, "aria-label": SDKUI_Localizator.Close, title: SDKUI_Localizator.Close, type: "button" })), children] }));
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(IconCloseOutline, {}) })), children] }));
105
116
  });
106
117
  export default ToppySpeechBubble;
@@ -6,7 +6,7 @@ declare const TABLET_WIDTH = 1024;
6
6
  declare const MOBILE_WIDTH = 640;
7
7
  declare const calcResponsiveDirection: (deviceType: DeviceType, desktopDir: "horizontal" | "vertical", tabletDir: "horizontal" | "vertical", mobileDir: "horizontal" | "vertical") => "horizontal" | "vertical";
8
8
  declare const openApps: (appModule: AppModules, tmSession: ITopMediaSession, appRoutes?: any[]) => Promise<void>;
9
- export declare const setSDK_GlobalsInfoAsync: (tms: ITopMediaSession | undefined) => Promise<ITopMediaSession>;
9
+ export declare const setSDK_GlobalsInfoAsync: (tms: ITopMediaSession | undefined) => Promise<void>;
10
10
  declare const calcResponsiveSizes: (deviceType: DeviceType | undefined, desktopSize: string, tabletSize: string, mobileSize: string) => string;
11
11
  declare const getColor: (color: ColorsType) => string;
12
12
  /**
@@ -1,7 +1,7 @@
1
1
  import { Fragment as _Fragment, jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Colors } from "../utils/theme";
3
3
  import { ButtonNames, DeviceType, TMExceptionBoxManager, TMMessageBoxManager, TMSpinner } from "../components";
4
- import { AccessLevels, MetadataDataDomains, MetadataDataTypes, MetadataDescriptor, MetadataFormatDescriptor, MetadataFormats, MetadataPermission, SDK_Globals, SystemMIDs, SystemMIDsAsNumber, TopMediaServer } from "@topconsultnpm/sdk-ts";
4
+ import { AccessLevels, MetadataDataDomains, MetadataDataTypes, MetadataDescriptor, MetadataFormatDescriptor, MetadataFormats, MetadataPermission, SDK_Globals, SetGlobalsInfoAsync, SystemMIDs, SystemMIDsAsNumber, TopMediaServer } from "@topconsultnpm/sdk-ts";
5
5
  import { Buffer } from 'buffer';
6
6
  import { buildTypes, FileExtensionHandler, FormModes, moduleTypes } from "../ts";
7
7
  import { SDKUI_Localizator } from "./SDKUI_Localizator";
@@ -37,22 +37,12 @@ const openApps = async (appModule, tmSession, appRoutes) => {
37
37
  }
38
38
  };
39
39
  export const setSDK_GlobalsInfoAsync = async (tms) => {
40
- const tmServer = new TopMediaServer(tms?.TopMediaServer?.BaseAddress);
41
- const tmSessionNew = tmServer?.NewSession();
42
- if (tmSessionNew) {
43
- tmSessionNew.SessionDescr = tms?.SessionDescr;
44
- }
45
- SDK_Globals.tmSession = tmSessionNew;
46
- SDK_Globals.tmSession.AutoRefresh = true;
47
- if (SDK_Globals.license == undefined) {
48
- try {
49
- SDK_Globals.license = await tmSessionNew.NewLicenseEngine().RetrieveAsync();
50
- }
51
- catch (e) {
52
- TMExceptionBoxManager.show({ title: 'Errore caricamento licenza', exception: e });
53
- }
40
+ try {
41
+ await SetGlobalsInfoAsync(tms);
42
+ }
43
+ catch (e) {
44
+ TMExceptionBoxManager.show({ exception: e.message });
54
45
  }
55
- return tmSessionNew;
56
46
  };
57
47
  const calcResponsiveSizes = (deviceType, desktopSize, tabletSize, mobileSize) => {
58
48
  if (deviceType === DeviceType.DESKTOP)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react",
3
- "version": "6.19.0-dev2.53",
3
+ "version": "6.19.0-dev2.55",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",
@@ -39,7 +39,7 @@
39
39
  "lib"
40
40
  ],
41
41
  "dependencies": {
42
- "@topconsultnpm/sdk-ts": "6.19.0-dev2.5",
42
+ "@topconsultnpm/sdk-ts": "6.19.0-dev2.6",
43
43
  "buffer": "^6.0.3",
44
44
  "devextreme": "25.1.7",
45
45
  "devextreme-react": "25.1.7",