@topconsultnpm/sdkui-react 6.20.0-dev1.66 → 6.20.0-dev1.68

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.
@@ -59,6 +59,8 @@ const TMContextMenu = ({ items, trigger = 'right', children, target, externalCon
59
59
  const touchEvent = e;
60
60
  const element = e.currentTarget;
61
61
  const touch = touchEvent.touches[0];
62
+ // Prevent text selection during long press
63
+ e.preventDefault();
62
64
  let state = touchStateMap.get(element);
63
65
  if (!state) {
64
66
  state = { timeout: null, startX: 0, startY: 0, longPressTriggered: false };
@@ -75,16 +77,27 @@ const TMContextMenu = ({ items, trigger = 'right', children, target, externalCon
75
77
  // Haptic feedback
76
78
  if ('vibrate' in navigator)
77
79
  navigator.vibrate(50);
78
- const syntheticEvent = new MouseEvent('contextmenu', {
80
+ // First, trigger a click to select/focus the item
81
+ const clickEvent = new MouseEvent('click', {
79
82
  bubbles: true,
80
83
  cancelable: true,
81
84
  clientX: touch.clientX,
82
85
  clientY: touch.clientY,
83
86
  });
84
- element.dispatchEvent(syntheticEvent);
87
+ element.dispatchEvent(clickEvent);
88
+ // Small delay to ensure click is processed before opening context menu
89
+ setTimeout(() => {
90
+ const syntheticEvent = new MouseEvent('contextmenu', {
91
+ bubbles: true,
92
+ cancelable: true,
93
+ clientX: touch.clientX,
94
+ clientY: touch.clientY,
95
+ });
96
+ element.dispatchEvent(syntheticEvent);
97
+ }, 10);
85
98
  if (state)
86
99
  state.timeout = null;
87
- }, 500);
100
+ }, 400);
88
101
  };
89
102
  const handleTouchMove = (e) => {
90
103
  const touchEvent = e;
@@ -122,14 +135,16 @@ const TMContextMenu = ({ items, trigger = 'right', children, target, externalCon
122
135
  // Attach listeners to all matching elements
123
136
  elements.forEach(element => {
124
137
  const el = element;
125
- // Prevent iOS native callout
138
+ // Prevent iOS native callout and text selection
126
139
  const style = el.style;
127
140
  style.webkitTouchCallout = 'none';
128
141
  style.webkitUserSelect = 'none';
129
- el.addEventListener('touchstart', handleTouchStart, { passive: true });
142
+ style.userSelect = 'none';
143
+ el.addEventListener('touchstart', handleTouchStart, { passive: false });
130
144
  el.addEventListener('touchmove', handleTouchMove, { passive: true });
131
145
  el.addEventListener('touchend', handleTouchEnd);
132
146
  el.addEventListener('touchcancel', handleTouchEnd);
147
+ el.addEventListener('contextmenu', (e) => e.preventDefault(), { capture: true });
133
148
  el.addEventListener('click', handleClick, { capture: true });
134
149
  });
135
150
  return () => {
@@ -138,6 +153,7 @@ const TMContextMenu = ({ items, trigger = 'right', children, target, externalCon
138
153
  const style = el.style;
139
154
  style.webkitTouchCallout = '';
140
155
  style.webkitUserSelect = '';
156
+ style.userSelect = '';
141
157
  el.removeEventListener('touchstart', handleTouchStart);
142
158
  el.removeEventListener('touchmove', handleTouchMove);
143
159
  el.removeEventListener('touchend', handleTouchEnd);
@@ -268,7 +284,7 @@ const TMContextMenu = ({ items, trigger = 'right', children, target, externalCon
268
284
  parentNames: [],
269
285
  });
270
286
  }
271
- }, 500);
287
+ }, 400);
272
288
  };
273
289
  const handleTouchMove = (e) => {
274
290
  if (!isIOS || trigger !== 'right' || !touchStartPos.current)
@@ -411,6 +427,7 @@ const TMContextMenu = ({ items, trigger = 'right', children, target, externalCon
411
427
  display: 'inline-block',
412
428
  WebkitTouchCallout: isIOS ? 'none' : undefined,
413
429
  WebkitUserSelect: isIOS ? 'none' : undefined,
430
+ userSelect: isIOS ? 'none' : undefined,
414
431
  }, children: children })), menuState.visible && createPortal(_jsxs(_Fragment, { children: [_jsxs(S.MenuContainer, { ref: menuRef, "$x": menuState.position.x, "$y": menuState.position.y, "$openLeft": openLeft, "$openUp": openUp, "$isPositioned": isCalculated, "$externalControl": !!externalControl, children: [isMobile && menuState.parentNames.length > 0 && (_jsxs(S.MobileMenuHeader, { children: [_jsx(S.BackButton, { onClick: handleBack, "aria-label": "Go back", children: _jsx(IconArrowLeft, {}) }), _jsx(S.HeaderTitle, { children: currentParentName })] })), renderMenuItems(currentMenu, 0)] }), !isMobile && hoveredSubmenus.map((submenu, idx) => (_jsx(S.Submenu, { "$parentRect": submenu.parentRect, "$openUp": submenu.openUp, "data-submenu": "true", onMouseEnter: handleSubmenuMouseEnter, onMouseLeave: () => handleMouseLeave(submenu.depth), children: renderMenuItems(submenu.items, submenu.depth) }, `submenu-${submenu.depth}-${idx}`)))] }), document.body)] }));
415
432
  };
416
433
  export default TMContextMenu;
@@ -4,7 +4,8 @@ import { ContextMenu } from '../ContextMenu';
4
4
  import ShowAlert from '../../base/TMAlert';
5
5
  import TMTooltip from '../../base/TMTooltip';
6
6
  import * as S from './styles';
7
- import { IconAdd, IconApply, IconMenuVertical, IconPin, IconSeparator, IconUndo, SDKUI_Globals, SDKUI_Localizator } from '../../../helper';
7
+ import { IconAdd, IconCloseOutline, IconMenuVertical, IconPin, IconSave, IconSeparator, IconUndo, SDKUI_Globals, SDKUI_Localizator } from '../../../helper';
8
+ import { ButtonNames, TMMessageBoxManager } from '../../base/TMPopUp';
8
9
  const Separator = (props) => (_jsx("svg", { viewBox: "0 0 24 24", fill: "currentColor", height: "1em", width: "1em", ...props, children: _jsx("path", { d: "M12 2v20", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round" }) }));
9
10
  const IconDraggableDots = (props) => (_jsx("svg", { fontSize: 18, viewBox: "0 0 24 24", fill: "currentColor", height: "1em", width: "1em", ...props, children: _jsx("path", { d: "M9 3a2 2 0 11-4 0 2 2 0 014 0zm0 9a2 2 0 11-4 0 2 2 0 014 0zm0 9a2 2 0 11-4 0 2 2 0 014 0zm10-18a2 2 0 11-4 0 2 2 0 014 0zm0 9a2 2 0 11-4 0 2 2 0 014 0zm0 9a2 2 0 11-4 0 2 2 0 014 0z" }) }));
10
11
  const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained = false, defaultPosition = { x: 100, y: 100 }, maxItems = 100, }) => {
@@ -603,6 +604,45 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
603
604
  const snapshotIds = stateSnapshot.current.items.map(i => i.id).join(',');
604
605
  return currentIds !== snapshotIds;
605
606
  };
607
+ const handleClose = () => {
608
+ // If all items removed, exit without asking and restore last items
609
+ if (state.items.length === 0 && stateSnapshot.current) {
610
+ setState(s => ({
611
+ ...s,
612
+ items: [...stateSnapshot.current.items],
613
+ orientation: stateSnapshot.current.orientation,
614
+ position: { ...stateSnapshot.current.position },
615
+ isConfigMode: false,
616
+ }));
617
+ stateSnapshot.current = null;
618
+ return;
619
+ }
620
+ // If no changes, simply exit config mode
621
+ if (!hasChanges()) {
622
+ stateSnapshot.current = null;
623
+ const cleanedItems = removeTrailingSeparators(state.items);
624
+ setState(s => ({ ...s, isConfigMode: false, items: cleanedItems }));
625
+ return;
626
+ }
627
+ // If there are changes, ask for confirmation
628
+ TMMessageBoxManager.show({
629
+ message: 'Perderai le tue modifiche, sei sicuro?',
630
+ buttons: [ButtonNames.YES, ButtonNames.NO],
631
+ onButtonClick: (buttonName) => {
632
+ if (buttonName === ButtonNames.YES && stateSnapshot.current) {
633
+ // Restore snapshot and exit config mode
634
+ setState(s => ({
635
+ ...s,
636
+ items: [...stateSnapshot.current.items],
637
+ orientation: stateSnapshot.current.orientation,
638
+ position: { ...stateSnapshot.current.position },
639
+ isConfigMode: false,
640
+ }));
641
+ stateSnapshot.current = null;
642
+ }
643
+ },
644
+ });
645
+ };
606
646
  const toggleOrientation = () => {
607
647
  const newOrientation = state.orientation === 'horizontal' ? 'vertical' : 'horizontal';
608
648
  if (state.orientation === 'horizontal' && newOrientation === 'vertical') {
@@ -740,6 +780,8 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
740
780
  currentOnClick();
741
781
  }
742
782
  }, disabled: state.isConfigMode ? isDisabled && !state.isConfigMode : isDisabled, children: item.icon }) }), state.isConfigMode && (_jsx(S.RemoveButton, { onClick: () => removeItem(item.id), children: "\u00D7" }))] }, item.id));
743
- }), !state.isConfigMode && contextMenuItems.length > 0 && (_jsx(ContextMenu, { items: getContextMenuItemsWithPinIcons(), trigger: "left", keepOpenOnClick: true, children: _jsx(S.ContextMenuButton, { children: _jsx(IconMenuVertical, {}) }) })), state.isConfigMode && state.items.length < maxItems && contextMenuItems.length > 0 && (_jsx(ContextMenu, { items: getPinContextMenuItems(), trigger: "left", keepOpenOnClick: true, children: _jsx(TMTooltip, { content: SDKUI_Localizator.Add, children: _jsx(S.AddButton, { children: _jsx(IconAdd, {}) }) }) })), state.isConfigMode && (_jsxs(_Fragment, { children: [_jsx(S.Separator, { "$orientation": state.orientation }), _jsxs(S.ButtonGroup, { "$orientation": state.orientation, children: [_jsx(TMTooltip, { content: SDKUI_Localizator.Undo, position: state.orientation === 'horizontal' ? 'right' : 'top', children: _jsx(S.UndoButton, { onClick: handleUndo, disabled: !hasChanges(), children: _jsx(IconUndo, { fontSize: 18 }) }) }), _jsx(TMTooltip, { content: state.items.length === 0 ? 'Devi aggiungere almeno un item' : SDKUI_Localizator.ApplyAndClose, position: state.orientation === 'horizontal' ? 'right' : 'top', children: _jsx(S.ApplyButton, { onClick: toggleConfigMode, disabled: state.items.length === 0, children: _jsx(IconApply, { fontSize: 20 }) }) })] })] }))] })] }));
783
+ }), !state.isConfigMode && contextMenuItems.length > 0 && (_jsx(ContextMenu, { items: getContextMenuItemsWithPinIcons(), trigger: "left", keepOpenOnClick: true, children: _jsx(S.ContextMenuButton, { children: _jsx(IconMenuVertical, {}) }) })), state.isConfigMode && state.items.length < maxItems && contextMenuItems.length > 0 && (_jsx(ContextMenu, { items: getPinContextMenuItems(), trigger: "left", keepOpenOnClick: true, children: _jsx(TMTooltip, { content: SDKUI_Localizator.Add, children: _jsx(S.AddButton, { children: _jsx(IconAdd, {}) }) }) })), state.isConfigMode && (_jsxs(_Fragment, { children: [_jsx(S.Separator, { "$orientation": state.orientation }), _jsxs(S.ButtonGroup, { "$orientation": state.orientation, children: [_jsx(TMTooltip, { content: SDKUI_Localizator.Undo, position: state.orientation === 'horizontal' ? 'right' : 'top', children: _jsx(S.UndoButton, { onClick: handleUndo, disabled: !hasChanges(), children: _jsx(IconUndo, { fontSize: 18 }) }) }), _jsx(TMTooltip, { content: state.items.length === 0
784
+ ? 'Devi aggiungere almeno un item'
785
+ : SDKUI_Localizator.Save, position: state.orientation === 'horizontal' ? 'right' : 'top', children: _jsx(S.ApplyButton, { onClick: toggleConfigMode, disabled: state.items.length === 0 || !hasChanges(), children: _jsx(IconSave, { fontSize: 20 }) }) }), _jsx(TMTooltip, { content: SDKUI_Localizator.Close, position: state.orientation === 'horizontal' ? 'right' : 'top', children: _jsx(S.CloseButton, { onClick: handleClose, children: _jsx(IconCloseOutline, { fontSize: 20 }) }) })] })] }))] })] }));
744
786
  };
745
787
  export default TMFloatingMenuBar;
@@ -33,6 +33,7 @@ export declare const MenuButton: import("styled-components/dist/types").IStyledC
33
33
  }>> & string;
34
34
  export declare const ConfigButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>> & string;
35
35
  export declare const ApplyButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>> & string;
36
+ export declare const CloseButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>> & string;
36
37
  export declare const ContextMenuButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Omit<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "$isActive"> & {
37
38
  $isActive?: boolean;
38
39
  }, "ref"> & {
@@ -74,7 +74,7 @@ export const GripHandle = styled.div `
74
74
  display: flex;
75
75
  align-items: center;
76
76
  justify-content: center;
77
- padding: ${props => props.$orientation === 'horizontal' ? '10px 6px' : '6px 10px'};
77
+ padding: ${props => props.$orientation === 'horizontal' ? '6px 4px' : '4px 6px'};
78
78
  cursor: grab;
79
79
  color: rgba(255, 255, 255, 0.7);
80
80
  transition: all 0.2s ease;
@@ -98,7 +98,7 @@ export const GripHandle = styled.div `
98
98
  export const Separator = styled.div `
99
99
  background: rgba(255, 255, 255, 0.25);
100
100
  width: ${props => props.$orientation === 'horizontal' ? '1px' : '100%'};
101
- height: ${props => props.$orientation === 'horizontal' ? '24px' : '1px'};
101
+ height: ${props => props.$orientation === 'horizontal' ? '20px' : '1px'};
102
102
  margin: ${props => props.$orientation === 'horizontal' ? '0 4px' : '4px 0'};
103
103
  flex-shrink: 0;
104
104
  `;
@@ -111,8 +111,8 @@ export const ItemSeparator = styled.div `
111
111
  display: flex;
112
112
  align-items: center;
113
113
  justify-content: center;
114
- width: 34px;
115
- height: 34px;
114
+ width: 30px;
115
+ height: 30px;
116
116
  background: transparent;
117
117
  border-radius: 8px;
118
118
  cursor: grab;
@@ -122,7 +122,7 @@ export const ItemSeparator = styled.div `
122
122
  content: '';
123
123
  background: rgba(255, 255, 255, 0.25);
124
124
  width: ${props.$orientation === 'horizontal' ? '2px' : '100%'};
125
- height: ${props.$orientation === 'horizontal' ? '20px' : '2px'};
125
+ height: ${props.$orientation === 'horizontal' ? '18px' : '2px'};
126
126
  border-radius: 1px;
127
127
  }
128
128
 
@@ -137,7 +137,7 @@ export const ItemSeparator = styled.div `
137
137
  /* Normal mode: simple line with tight spacing */
138
138
  background: rgba(255, 255, 255, 0.25);
139
139
  width: ${props.$orientation === 'horizontal' ? '1px' : '100%'};
140
- height: ${props.$orientation === 'horizontal' ? '24px' : '1px'};
140
+ height: ${props.$orientation === 'horizontal' ? '20px' : '1px'};
141
141
  margin: ${props.$orientation === 'horizontal' ? '0 2px' : '2px 0'};
142
142
  `}
143
143
  `;
@@ -145,8 +145,8 @@ export const MenuButton = styled.button `
145
145
  display: flex;
146
146
  align-items: center;
147
147
  justify-content: center;
148
- width: 34px;
149
- height: 34px;
148
+ width: 30px;
149
+ height: 30px;
150
150
  background: transparent;
151
151
  border: none;
152
152
  border-radius: 8px;
@@ -243,6 +243,40 @@ export const ApplyButton = styled.button `
243
243
  height: 20px;
244
244
  }
245
245
  `;
246
+ export const CloseButton = styled.button `
247
+ display: flex;
248
+ align-items: center;
249
+ justify-content: center;
250
+ width: 24px;
251
+ height: 24px;
252
+ background: transparent;
253
+ border: none;
254
+ border-radius: 4px;
255
+ color: rgba(239, 68, 68, 1);
256
+ font-size: 10px;
257
+ cursor: pointer;
258
+ transition: all 0.2s ease;
259
+ padding: 3px;
260
+
261
+ &:hover:not(:disabled) {
262
+ background: rgba(255, 255, 255, 0.1);
263
+ color: rgba(239, 68, 68, 1);
264
+ }
265
+
266
+ &:active:not(:disabled) {
267
+ transform: scale(0.9);
268
+ }
269
+
270
+ &:disabled {
271
+ opacity: 0.3;
272
+ cursor: default;
273
+ }
274
+
275
+ svg {
276
+ width: 20px;
277
+ height: 20px;
278
+ }
279
+ `;
246
280
  export const ContextMenuButton = styled(MenuButton) `
247
281
  svg {
248
282
  transform: translateY(0);
@@ -252,13 +286,13 @@ export const AddButton = styled.button `
252
286
  display: flex;
253
287
  align-items: center;
254
288
  justify-content: center;
255
- width: 28px;
256
- height: 28px;
289
+ width: 26px;
290
+ height: 26px;
257
291
  background: rgba(255, 255, 255, 0.15);
258
292
  border: 1px dashed rgba(255, 255, 255, 0.4);
259
293
  border-radius: 8px;
260
294
  color: white;
261
- font-size: 20px;
295
+ font-size: 18px;
262
296
  font-weight: bold;
263
297
  line-height: 0;
264
298
  cursor: pointer;
@@ -25,7 +25,7 @@ export declare const WorkFlowApproveRejectPopUp: ({ TID, DID, deviceType, isReje
25
25
  onClose?: () => void;
26
26
  onCompleted?: () => Promise<void>;
27
27
  }) => import("react/jsx-runtime").JSX.Element;
28
- export declare const WorkFlowReAssignPopUp: ({ DID, TID, deviceType, onClose, selectedItems, onCompleted, wf }: {
28
+ export declare const WorkFlowReAssignPopUp: ({ DID, TID, deviceType, onClose, selectedItems, onCompleted, wf, workItemDetail }: {
29
29
  TID?: number;
30
30
  DID?: number;
31
31
  deviceType?: DeviceType;
@@ -33,6 +33,7 @@ export declare const WorkFlowReAssignPopUp: ({ DID, TID, deviceType, onClose, se
33
33
  selectedItems?: any[];
34
34
  onCompleted?: () => Promise<void>;
35
35
  wf?: WFDescriptor;
36
+ workItemDetail?: WorkItemDetail;
36
37
  }) => import("react/jsx-runtime").JSX.Element;
37
38
  /**
38
39
  * Modal per forzare l'approvazione di un work item
@@ -95,6 +95,7 @@ export const WorkFlowApproveRejectPopUp = ({ TID = 0, DID = 0, deviceType = Devi
95
95
  for (const { TID, DID } of items) {
96
96
  await workflowEngine.WorkItem_CompleteOrRejectAsync(TID, DID, commentValue, isReject);
97
97
  }
98
+ ShowAlert({ mode: 'success', position: 'TOP_RIGHT', title: isReject === 0 ? SDKUI_Localizator.WorkitemApprove : SDKUI_Localizator.WorkitemReject, message: SDKUI_Localizator.OperationSuccess, duration: 3000 });
98
99
  }
99
100
  catch (e) {
100
101
  TMExceptionBoxManager.show({ exception: e });
@@ -103,7 +104,6 @@ export const WorkFlowApproveRejectPopUp = ({ TID = 0, DID = 0, deviceType = Devi
103
104
  onCompleted?.();
104
105
  onClose?.();
105
106
  TMSpinner.hide();
106
- ShowAlert({ mode: 'success', position: 'TOP_RIGHT', title: isReject === 0 ? SDKUI_Localizator.WorkitemApprove : SDKUI_Localizator.WorkitemReject, message: SDKUI_Localizator.OperationSuccess, duration: 3000 });
107
107
  }
108
108
  };
109
109
  const workflowAction = isReject === 0 ? SDKUI_Localizator.Approve : SDKUI_Localizator.Reject;
@@ -113,23 +113,33 @@ export const WorkFlowApproveRejectPopUp = ({ TID = 0, DID = 0, deviceType = Devi
113
113
  ? _jsx(TMButton, { btnStyle: 'advanced', showTooltip: false, icon: _jsx(IconApply, {}), caption: SDKUI_Localizator.Approve, disabled: false, onClick: () => completeOrRejectAsync(isReject), advancedColor: TMColors.success })
114
114
  : _jsx(TMButton, { btnStyle: 'advanced', showTooltip: false, icon: _jsx(IconCloseOutline, {}), caption: SDKUI_Localizator.Reject, disabled: disable, onClick: () => { !disable && completeOrRejectAsync(isReject); }, advancedColor: TMColors.error }) })] }) }));
115
115
  };
116
- export const WorkFlowReAssignPopUp = ({ DID = 0, TID = 0, deviceType = DeviceType.DESKTOP, onClose, selectedItems = [], onCompleted, wf }) => {
116
+ export const WorkFlowReAssignPopUp = ({ DID = 0, TID = 0, deviceType = DeviceType.DESKTOP, onClose, selectedItems = [], onCompleted, wf, workItemDetail }) => {
117
117
  const [commentValue, setCommentValue] = useState('');
118
118
  const [selectedUserID, setSelectedUserID] = useState([]);
119
119
  const [participants, setParticipants] = useState([]);
120
120
  const disable = commentValue.length === 0 || !selectedUserID;
121
+ // Determina se siamo nel contesto CtrlWorkflow (quando abbiamo workItemDetail)
122
+ const isCtrlWorkflowContext = !!workItemDetail;
121
123
  const reAssignWorkFlowAsync = async () => {
122
124
  try {
123
125
  TMSpinner.show();
124
126
  const workflowEngine = SDK_Globals.tmSession?.NewWorkflowEngine();
125
127
  if (!workflowEngine)
126
128
  throw new Error("Workflow engine is not available");
127
- const items = selectedItems.length > 0
128
- ? selectedItems.map(({ TID, DID }) => ({ TID, DID }))
129
- : [{ TID, DID }];
130
- for (const { TID, DID } of items) {
131
- await SDK_Globals.tmSession?.NewWorkflowEngine().WorkItem_ReassignAsync(TID, DID, selectedUserID?.[0], commentValue);
129
+ if (isCtrlWorkflowContext && workItemDetail) {
130
+ // Contesto CtrlWorkflow: usa WFCtrl_ReassignWIAsync
131
+ await workflowEngine.WFCtrl_ReassignWIAsync(workItemDetail.wfid, workItemDetail.did, selectedUserID?.[0], commentValue);
132
132
  }
133
+ else {
134
+ // Contesto WorkItem: usa WorkItem_ReassignAsync
135
+ const items = selectedItems.length > 0
136
+ ? selectedItems.map(({ TID, DID }) => ({ TID, DID }))
137
+ : [{ TID, DID }];
138
+ for (const { TID, DID } of items) {
139
+ await workflowEngine.WorkItem_ReassignAsync(TID, DID, selectedUserID?.[0], commentValue);
140
+ }
141
+ }
142
+ ShowAlert({ mode: 'success', position: 'TOP_RIGHT', title: SDKUI_Localizator.WorkitemReassign, message: SDKUI_Localizator.OperationSuccess, duration: 3000 });
133
143
  }
134
144
  catch (e) {
135
145
  TMExceptionBoxManager.show({ exception: e });
@@ -138,11 +148,10 @@ export const WorkFlowReAssignPopUp = ({ DID = 0, TID = 0, deviceType = DeviceTyp
138
148
  onCompleted?.();
139
149
  onClose?.();
140
150
  TMSpinner.hide();
141
- ShowAlert({ mode: 'success', position: 'TOP_RIGHT', title: SDKUI_Localizator.WorkitemReassign, message: SDKUI_Localizator.OperationSuccess, duration: 3000 });
142
151
  }
143
152
  };
144
153
  // Determina il TID da usare
145
- const tidToUse = selectedItems?.[0]?.TID ?? TID;
154
+ const tidToUse = workItemDetail?.tid ?? selectedItems?.[0]?.TID ?? TID;
146
155
  useEffect(() => {
147
156
  let isMounted = true;
148
157
  const fetchData = async () => {
@@ -169,8 +178,11 @@ export const WorkFlowReAssignPopUp = ({ DID = 0, TID = 0, deviceType = DeviceTyp
169
178
  };
170
179
  fetchData();
171
180
  return () => { isMounted = false; };
172
- }, [tidToUse, wf]);
173
- return (_jsx(TMModal, { onClose: onClose, width: '600px', height: '270px', isModal: true, title: SDKUI_Localizator.Reassign + (selectedItems.length > 0 ? ' (' + selectedItems.length + ' workitem)' : ''), children: _jsxs(StyledModalBodyWrapper, { children: [_jsxs(StyledModalContentContainer, { children: [_jsx(TMUserChooser, { dataSource: participants, values: selectedUserID, onValueChanged: (IDs) => {
181
+ }, [tidToUse, wf, workItemDetail]);
182
+ // Determina il conteggio degli item da mostrare nel titolo
183
+ const itemCount = workItemDetail ? 1 : selectedItems.length;
184
+ const titleSuffix = itemCount > 0 ? ` (${itemCount} workitem)` : '';
185
+ return (_jsx(TMModal, { onClose: onClose, width: '600px', height: '270px', isModal: true, title: SDKUI_Localizator.Reassign + titleSuffix, children: _jsxs(StyledModalBodyWrapper, { children: [_jsxs(StyledModalContentContainer, { children: [_jsx(TMUserChooser, { dataSource: participants, values: selectedUserID, onValueChanged: (IDs) => {
174
186
  setSelectedUserID(IDs ?? []);
175
187
  } }), _jsxs("p", { style: { color: commentValue.length === 0 ? TMColors.error : 'black' }, children: [SDKUI_Localizator.CommentText, " ", commentValue.length === 0 && _jsx("span", { children: ` (${SDKUI_Localizator.RequiredField})` }), " "] }), _jsx(StyledTextArea, { maxLength: 200, "$isValid": commentValue.length !== 0, value: commentValue, onChange: (e) => setCommentValue(e.target.value) }), _jsx(CharacterCounter, { children: `${200 - commentValue.length} ${SDKUI_Localizator.CharactersRemaining}` })] }), _jsx(StyledModalFooter, { children: _jsx(TMButton, { btnStyle: 'advanced', showTooltip: false, icon: _jsx(IconUser, { fontSize: 16 }), caption: SDKUI_Localizator.Reassign, disabled: disable, onClick: () => !disable && reAssignWorkFlowAsync(), advancedColor: TMColors.tertiary }) })] }) }));
176
188
  };
@@ -308,6 +320,7 @@ export const WorkFlowMoreInfoPopUp = ({ DID = 0, TID = 0, deviceType = DeviceTyp
308
320
  name: `${TASK_MORE_INFO_PREFIX_NAME}${nameInput}`
309
321
  };
310
322
  await SDK_Globals.tmSession?.NewWorkflowEngine().WorkItem_MoreInfoAsync(TID, DID, taskWithPrefix);
323
+ ShowAlert({ mode: 'success', position: 'TOP_RIGHT', title: SDKUI_Localizator.MoreInformation, message: SDKUI_Localizator.MoreInfoSent, duration: 3000 });
311
324
  }
312
325
  catch (e) {
313
326
  TMExceptionBoxManager.show({ exception: e });
@@ -316,7 +329,6 @@ export const WorkFlowMoreInfoPopUp = ({ DID = 0, TID = 0, deviceType = DeviceTyp
316
329
  onCompleted?.();
317
330
  onClose?.();
318
331
  TMSpinner.hide();
319
- ShowAlert({ mode: 'success', position: 'TOP_RIGHT', title: SDKUI_Localizator.MoreInformation, message: SDKUI_Localizator.MoreInfoSent, duration: 3000 });
320
332
  }
321
333
  };
322
334
  useEffect(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react",
3
- "version": "6.20.0-dev1.66",
3
+ "version": "6.20.0-dev1.68",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",