@topconsultnpm/sdkui-react-beta 6.14.27 → 6.14.28

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.
@@ -1,3 +1,7 @@
1
+ import React from 'react';
2
+ export interface ITMDropDownMenuRef {
3
+ focus: () => void;
4
+ }
1
5
  export interface ITMDropDownMenu {
2
6
  content: JSX.Element;
3
7
  color?: string;
@@ -14,5 +18,5 @@ export interface ITMDropDownMenuItem {
14
18
  beginGroup?: boolean;
15
19
  onClick?: () => void;
16
20
  }
17
- declare const TMDropDownMenu: ({ content, items, disabled, color, backgroundColor, borderRadius }: ITMDropDownMenu) => import("react/jsx-runtime").JSX.Element;
21
+ declare const TMDropDownMenu: React.ForwardRefExoticComponent<ITMDropDownMenu & React.RefAttributes<ITMDropDownMenuRef>>;
18
22
  export default TMDropDownMenu;
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useEffect, useState } from 'react';
2
+ import { useEffect, useState, forwardRef, useRef, useImperativeHandle } from 'react';
3
3
  import styled from 'styled-components';
4
4
  import ContextMenu from 'devextreme-react/context-menu';
5
5
  import { FontSize, TMColors } from '../../utils/theme';
@@ -30,10 +30,16 @@ const StyledMenuItem = styled.div `
30
30
  width: 100%;
31
31
  font-size: ${FontSize.defaultFontSize};
32
32
  `;
33
- const TMDropDownMenu = ({ content, items, disabled = false, color = TMColors.text_normal, backgroundColor = TMColors.default_background, borderRadius }) => {
33
+ const TMDropDownMenu = forwardRef(({ content, items, disabled = false, color = TMColors.text_normal, backgroundColor = TMColors.default_background, borderRadius }, ref) => {
34
34
  const [id, setID] = useState('');
35
+ const dropDownMenuElementRef = useRef(null); // Ref all'elemento DOM div principale
35
36
  useEffect(() => { setID(genUniqueId()); }, [content]);
37
+ useImperativeHandle(ref, () => ({
38
+ focus: () => {
39
+ dropDownMenuElementRef.current?.focus();
40
+ },
41
+ }));
36
42
  const renderItemTemplate = (itemData) => (_jsxs(StyledMenuItem, { children: [itemData.icon && _jsx("div", { style: { display: 'flex', alignItems: 'center' }, children: itemData.icon }), _jsx("span", { style: { flexGrow: 1 }, children: itemData.text }), itemData.items && _jsx("span", { className: "dx-icon-spinright dx-icon", style: { marginLeft: '10px' } })] }));
37
- return (_jsxs(_Fragment, { children: [_jsx(StyledContent, { id: `idContainer${id}`, tabIndex: disabled ? -1 : 0, "$disabled": disabled, "$color": color, "$backgroundColor": backgroundColor, "$borderRadius": borderRadius, children: content }), _jsx(ContextMenu, { target: `#idContainer${id}`, dataSource: items, showEvent: 'click', itemRender: renderItemTemplate })] }));
38
- };
43
+ return (_jsxs(_Fragment, { children: [_jsx(StyledContent, { id: `idContainer${id}`, ref: dropDownMenuElementRef, tabIndex: disabled ? -1 : 0, "$disabled": disabled, "$color": color, "$backgroundColor": backgroundColor, "$borderRadius": borderRadius, children: content }), _jsx(ContextMenu, { target: `#idContainer${id}`, dataSource: items, showEvent: 'click', itemRender: renderItemTemplate, onHidden: (e) => dropDownMenuElementRef.current?.focus() })] }));
44
+ });
39
45
  export default TMDropDownMenu;
@@ -66,28 +66,45 @@ const StyledPanelContent = styled.div `
66
66
  }
67
67
  `;
68
68
  const TMPanel = ({ allowMaximize = true, color, backgroundColor, backgroundColorContainer, children, showHeader = true, title, totalItems, displayedItemsCount, toolbar, padding = '5px', isVisible = true, onBack, onClose, onHeaderDoubleClick, onMaximize, onActiveChanged }) => {
69
- const [isActive, setIsActive] = useState(false);
69
+ const [isPanelActive, setIsPanelActive] = useState(false);
70
70
  const [isMaximized, setIsMaximized] = useState(false);
71
- const titleRowRef = useRef(null);
71
+ const panelRef = useRef(null);
72
+ const pendingFocusCheck = useRef(null); // Per un timer
73
+ const setActiveStatus = useCallback((isActive) => {
74
+ if (isPanelActive !== isActive) { // Solo se lo stato cambia
75
+ setIsPanelActive(isActive);
76
+ onActiveChanged?.(isActive);
77
+ }
78
+ }, [isPanelActive, onActiveChanged]);
72
79
  const handleFocus = useCallback(() => {
73
- if (!isActive) {
74
- setIsActive(true);
75
- onActiveChanged?.(true);
80
+ // Se c'è un check di pending blur, annullalo
81
+ if (pendingFocusCheck.current) {
82
+ clearTimeout(pendingFocusCheck.current);
83
+ pendingFocusCheck.current = null;
76
84
  }
77
- }, [isActive, onActiveChanged]);
78
- const handleBlur = useCallback(() => {
79
- // Usiamo un setTimeout per dare il tempo al browser di spostare il focus
80
- // e controllare se il focus è andato a un figlio che poi si è disconnesso
81
- // o se il focus è uscito definitivamente dal pannello
82
- // setTimeout(() => {
83
- if (!document.activeElement || !document.activeElement.closest('tmpanel-container')) {
84
- if (isActive) {
85
- setIsActive(false);
86
- onActiveChanged?.(false);
87
- }
85
+ setActiveStatus(true);
86
+ }, [setActiveStatus]);
87
+ const handleBlur = useCallback((event) => {
88
+ // Pulisci qualsiasi check precedente (importante se ci sono blur rapidi)
89
+ if (pendingFocusCheck.current) {
90
+ clearTimeout(pendingFocusCheck.current);
88
91
  }
89
- // }, 0); // Un piccolo ritardo per consentire al browser di stabilire il nuovo activeElement
90
- }, [isActive, onActiveChanged]);
92
+ // Programma un controllo dopo un brevissimo ritardo
93
+ // Questo permette al browser e a DevExtreme di stabilizzare il focus
94
+ pendingFocusCheck.current = setTimeout(() => {
95
+ const currentActiveElement = document.activeElement;
96
+ // Se l'elemento attivo corrente è all'interno del pannello,
97
+ // non fare nulla (il focus è interno)
98
+ if (panelRef.current?.contains(currentActiveElement)) {
99
+ setActiveStatus(true); // Assicurati che sia attivo
100
+ }
101
+ else {
102
+ // Il focus è realmente uscito
103
+ setActiveStatus(false);
104
+ }
105
+ pendingFocusCheck.current = null; // Resetta il timer
106
+ }, 50); // Piccolo ritardo, 50ms è un buon punto di partenza
107
+ }, [setActiveStatus]);
91
108
  // handler for external maximize management
92
109
  const handleMaximize = () => {
93
110
  setIsMaximized(prevState => {
@@ -98,21 +115,21 @@ const TMPanel = ({ allowMaximize = true, color, backgroundColor, backgroundColor
98
115
  return newValue;
99
116
  });
100
117
  };
101
- return (_jsxs(StyledPanelContainer, { className: "tmpanel-container", "$isMaximized": onMaximize ? false : isMaximized, style: {
118
+ return (_jsxs(StyledPanelContainer, { className: "tmpanel-container", ref: panelRef, "$isMaximized": onMaximize ? false : isMaximized, style: {
102
119
  visibility: isVisible ? 'visible' : 'hidden',
103
- }, children: [showHeader &&
104
- _jsx(StyledPanelHeader, { "$backgroundColor": backgroundColor, "$color": color, "$isActive": isActive, onDoubleClick: () => {
120
+ }, tabIndex: -1, onFocus: handleFocus, onBlur: handleBlur, onClick: handleFocus, children: [showHeader &&
121
+ _jsx(StyledPanelHeader, { "$backgroundColor": backgroundColor, "$color": color, "$isActive": isPanelActive, onDoubleClick: () => {
105
122
  if (onHeaderDoubleClick)
106
123
  onHeaderDoubleClick();
107
124
  else
108
125
  allowMaximize && handleMaximize();
109
- }, tabIndex: -1, onFocus: handleFocus, onBlur: handleBlur, onClick: handleFocus, children: _jsxs("div", { style: {
126
+ }, children: _jsxs("div", { style: {
110
127
  display: 'flex',
111
128
  flexDirection: 'row',
112
129
  alignItems: 'center',
113
130
  width: '100%',
114
131
  minWidth: 0
115
- }, children: [_jsxs("div", { ref: titleRowRef, style: {
132
+ }, children: [_jsxs("div", { style: {
116
133
  display: 'flex',
117
134
  flexDirection: 'row',
118
135
  alignItems: 'center',
@@ -143,6 +160,6 @@ const TMPanel = ({ allowMaximize = true, color, backgroundColor, backgroundColor
143
160
  marginLeft: 10
144
161
  }, children: [toolbar, allowMaximize && _jsx(TMButton, { color: 'primaryOutline', caption: isMaximized ? SDKUI_Localizator.Minimize : SDKUI_Localizator.Maximize, icon: isMaximized
145
162
  ? _jsx(IconWindowMinimize, { fontSize: 16 })
146
- : _jsx(IconWindowMaximize, { fontSize: 16 }), btnStyle: 'icon', onClick: handleMaximize }), onClose && _jsx(TMButton, { color: 'primaryOutline', caption: SDKUI_Localizator.Close, icon: _jsx(IconClearButton, {}), btnStyle: 'icon', onClick: () => { setIsMaximized(false); onClose?.(); } })] })] }) }), _jsx(StyledPanelContent, { "$height": showHeader ? "calc(100% - 40px)" : "100%", "$padding": padding, "$backgroundColor": backgroundColorContainer ?? `#FFFFFF`, tabIndex: -1, onFocus: handleFocus, onBlur: handleBlur, onClick: handleFocus, children: children })] }));
163
+ : _jsx(IconWindowMaximize, { fontSize: 16 }), btnStyle: 'icon', onClick: handleMaximize }), onClose && _jsx(TMButton, { color: 'primaryOutline', caption: SDKUI_Localizator.Close, icon: _jsx(IconClearButton, {}), btnStyle: 'icon', onClick: () => { setIsMaximized(false); onClose?.(); } })] })] }) }), _jsx(StyledPanelContent, { "$height": showHeader ? "calc(100% - 40px)" : "100%", "$padding": padding, "$backgroundColor": backgroundColorContainer ?? `#FFFFFF`, children: children })] }));
147
164
  };
148
165
  export default TMPanel;
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useMemo, useState } from 'react';
2
+ import { useMemo, useRef, useState } from 'react';
3
3
  import { SDK_Localizator, DataListCacheService } from '@topconsultnpm/sdk-ts-beta';
4
4
  import { StyledDivHorizontal } from '../base/Styled';
5
5
  import { IconSearch, SDKUI_Localizator, TMImageLibrary } from '../../helper';
@@ -13,8 +13,12 @@ const TMDataListItemChooser = ({ labelColor, dataListId, icon, backgroundColor,
13
13
  const isPlaceholder = values?.[0] === placeHolder;
14
14
  return (_jsxs(StyledDivHorizontal, { style: { minWidth: '125px', color: isPlaceholder ? '#a9a9a9' : 'inherit' }, children: [values && values.length > 0 && _jsx(TMDataListItemViewer, { dataListId: dataListId, value: values?.[0] }), values && values.length > 1 && _jsx("p", { style: { marginLeft: '10px' }, children: `(+${values.length - 1} ${values.length == 2 ? 'altro' : 'altri'})` })] }));
15
15
  };
16
- return (_jsxs(_Fragment, { children: [_jsx(TMSummary, { placeHolder: placeHolder, labelColor: labelColor, icon: icon, buttons: buttons, readOnly: readOnly, backgroundColor: backgroundColor, showBorder: showBorder, hasValue: values && values.length > 0, showClearButton: showClearButton, iconEditButton: _jsx(IconSearch, { fontSize: 16 }), onEditorClick: () => !readOnly && setShowChooser(true), elementStyle: elementStyle, isModifiedWhen: isModifiedWhen, label: label, openEditorOnSummaryClick: openChooserBySingleClick, template: renderTemplate(), onClearClick: showClearButton ? () => { onValueChanged?.([]); } : undefined, validationItems: validationItems }), showChooser &&
17
- _jsx(TMDataListItemChooserForm, { allowMultipleSelection: allowMultipleSelection, title: titleForm, dataListId: dataListId, selectedIDs: values, onClose: () => setShowChooser(false), onChoose: (IDs) => { onValueChanged?.(IDs); } })] }));
16
+ const summaryInputRef = useRef(null);
17
+ return (_jsxs(_Fragment, { children: [_jsx(TMSummary, { ref: summaryInputRef, placeHolder: placeHolder, labelColor: labelColor, icon: icon, buttons: buttons, readOnly: readOnly, backgroundColor: backgroundColor, showBorder: showBorder, hasValue: values && values.length > 0, showClearButton: showClearButton, iconEditButton: _jsx(IconSearch, { fontSize: 16 }), onEditorClick: () => !readOnly && setShowChooser(true), elementStyle: elementStyle, isModifiedWhen: isModifiedWhen, label: label, openEditorOnSummaryClick: openChooserBySingleClick, template: renderTemplate(), onClearClick: showClearButton ? () => { onValueChanged?.([]); } : undefined, validationItems: validationItems }), showChooser &&
18
+ _jsx(TMDataListItemChooserForm, { allowMultipleSelection: allowMultipleSelection, title: titleForm, dataListId: dataListId, selectedIDs: values, onClose: () => {
19
+ setShowChooser(false);
20
+ summaryInputRef.current?.focus();
21
+ }, onChoose: (IDs) => { onValueChanged?.(IDs); } })] }));
18
22
  };
19
23
  export default TMDataListItemChooser;
20
24
  const cellRenderIcon = (data) => _jsx(TMImageLibrary, { imageID: data.data?.imageID });
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useEffect, useState } from 'react';
2
+ import { useEffect, useRef, useState } from 'react';
3
3
  import { DataColumnTypes, SDK_Localizator, DataListCacheService, SDK_Globals, LayoutModes } from '@topconsultnpm/sdk-ts-beta';
4
4
  import { IconDetails, IconSearch, getDataColumnName, Globalization, SDKUI_Localizator, searchResultDescriptorToSimpleArray, IsParametricQuery, IconWarning } from '../../helper';
5
5
  import { StyledDivHorizontal } from '../base/Styled';
@@ -13,6 +13,7 @@ const TMDynDataListItemChooser = ({ tid, md, titleForm, openChooserBySingleClick
13
13
  const [showChooser, setShowChooser] = useState(false);
14
14
  const [dynDl, setDynDl] = useState();
15
15
  const [dataSource, setDataSource] = useState();
16
+ const summaryInputRef = useRef(null);
16
17
  useEffect(() => {
17
18
  let d = md?.dynDL_Cfgs?.[0];
18
19
  if (md?.dynDL_IsMultiCfg == 1) {
@@ -80,7 +81,10 @@ const TMDynDataListItemChooser = ({ tid, md, titleForm, openChooserBySingleClick
80
81
  return (_jsxs(StyledDivHorizontal, { style: { minWidth: '125px', color: isPlaceholder ? '#a9a9a9' : 'inherit' }, children: [dataSource && _jsxs(StyledDivHorizontal, { children: [getIcon(), _jsx("p", { style: { marginLeft: '5px' }, children: getDescription() })] }), values && values.length > 1 && _jsx("p", { style: { marginLeft: '10px' }, children: `(+${values.length - 1} ${values.length == 2 ? 'altro' : 'altri'})` })] }));
81
82
  };
82
83
  return (_jsxs(_Fragment, { children: [_jsx(TMSummary, { placeHolder: placeHolder, icon: icon, labelColor: labelColor, backgroundColor: backgroundColor, buttons: buttons, showBorder: showBorder, readOnly: readOnly, hasValue: values && values.length > 0, showClearButton: showClearButton, iconEditButton: _jsx(IconSearch, { fontSize: 16 }), onEditorClick: () => !readOnly && setShowChooser(true), elementStyle: elementStyle, isModifiedWhen: isModifiedWhen, openEditorOnSummaryClick: openChooserBySingleClick, label: label, template: renderTemplate(), onClearClick: showClearButton ? () => { onValueChanged?.([]); } : undefined, validationItems: validationItems }), showChooser &&
83
- _jsx(TMDynDataListItemChooserForm, { TID: tid, MID: md?.id, dynDL: dynDl, title: titleForm, allowMultipleSelection: allowMultipleSelection, searchResult: dataSource, selectedIDs: values, onClose: () => setShowChooser(false), onChoose: (IDs) => {
84
+ _jsx(TMDynDataListItemChooserForm, { TID: tid, MID: md?.id, dynDL: dynDl, title: titleForm, allowMultipleSelection: allowMultipleSelection, searchResult: dataSource, selectedIDs: values, onClose: () => {
85
+ setShowChooser(false);
86
+ summaryInputRef.current?.focus();
87
+ }, onChoose: (IDs) => {
84
88
  onValueChanged?.(IDs);
85
89
  if (!dynDl)
86
90
  return;
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useEffect, useMemo, useState } from 'react';
2
+ import { useEffect, useMemo, useRef, useState } from 'react';
3
3
  import { OwnershipLevels, SDK_Localizator, UserLevels, UserListCacheService } from '@topconsultnpm/sdk-ts-beta';
4
4
  import { SDKUI_Localizator, IconSearch, IconUserLevelMember, IconUserLevelAdministrator, IconUserLevelSystemAdministrator, IconUserLevelAutonomousAdministrator, IconWarning, LocalizeOwnershipLevels, LocalizeUserLevels } from '../../helper';
5
5
  import { StyledDivHorizontal, StyledTooltipContainer, StyledTooltipSeparatorItem } from '../base/Styled';
@@ -14,12 +14,16 @@ const TMUserChooser = ({ labelColor, titleForm, filter, readOnly = false, icon,
14
14
  useEffect(() => {
15
15
  setShowChooser(initialShowChooser);
16
16
  }, [initialShowChooser]);
17
+ const summaryInputRef = useRef(null);
17
18
  const renderTemplate = () => {
18
19
  const isPlaceholder = values?.[0] === placeHolder;
19
20
  return (_jsxs(StyledDivHorizontal, { style: { minWidth: '125px', color: isPlaceholder ? '#a9a9a9' : 'inherit' }, children: [values && values.length > 0 && _jsx(TMUserIdViewer, { userId: values?.[0], showIcon: true, noneSelectionText: '' }), values && values.length > 1 && _jsx("p", { style: { marginLeft: '10px' }, children: `(+${values.length - 1} ${values.length == 2 ? 'altro' : 'altri'})` })] }));
20
21
  };
21
- return (_jsxs(_Fragment, { children: [_jsx(TMSummary, { disabled: disabled, placeHolder: placeHolder, readOnly: readOnly, labelColor: labelColor, icon: icon, backgroundColor: backgroundColor, buttons: buttons, showBorder: showBorder, hasValue: values && values.length > 0, showClearButton: showClearButton, iconEditButton: _jsx(IconSearch, { fontSize: 16 }), onEditorClick: () => !readOnly && setShowChooser(true), elementStyle: elementStyle, isModifiedWhen: isModifiedWhen, openEditorOnSummaryClick: openChooserBySingleClick, label: label, template: renderTemplate(), onClearClick: showClearButton ? () => { onValueChanged?.([]); } : undefined, validationItems: validationItems }), showChooser &&
22
- _jsx(TMUserChooserForm, { title: titleForm, allowMultipleSelection: allowMultipleSelection, hasShowOnlySelectedItems: true, dataSource: dataSource, filter: filter, selectedIDs: values, hideRefresh: hideRefresh, hideShowId: hideShowId, onClose: () => setShowChooser(false), onChoose: (IDs) => { onValueChanged?.(IDs); } })] }));
22
+ return (_jsxs(_Fragment, { children: [_jsx(TMSummary, { ref: summaryInputRef, disabled: disabled, placeHolder: placeHolder, readOnly: readOnly, labelColor: labelColor, icon: icon, backgroundColor: backgroundColor, buttons: buttons, showBorder: showBorder, hasValue: values && values.length > 0, showClearButton: showClearButton, iconEditButton: _jsx(IconSearch, { fontSize: 16 }), onEditorClick: () => !readOnly && setShowChooser(true), elementStyle: elementStyle, isModifiedWhen: isModifiedWhen, openEditorOnSummaryClick: openChooserBySingleClick, label: label, template: renderTemplate(), onClearClick: showClearButton ? () => { onValueChanged?.([]); } : undefined, validationItems: validationItems }), showChooser &&
23
+ _jsx(TMUserChooserForm, { title: titleForm, allowMultipleSelection: allowMultipleSelection, hasShowOnlySelectedItems: true, dataSource: dataSource, filter: filter, selectedIDs: values, hideRefresh: hideRefresh, hideShowId: hideShowId, onClose: () => {
24
+ setShowChooser(false);
25
+ summaryInputRef.current?.focus();
26
+ }, onChoose: (IDs) => { onValueChanged?.(IDs); } })] }));
23
27
  };
24
28
  export default TMUserChooser;
25
29
  export const TMUserChooserForm = ({ allowMultipleSelection, columns, hideRefresh = false, hideShowId = false, startWithShowOnlySelectedItems = true, filter, title, hasShowOnlySelectedItems, width, height, selectedIDs, dataSource, onClose, onChoose }) => {
@@ -1,6 +1,9 @@
1
1
  import React from 'react';
2
2
  import { ITMEditorBase } from '../base/TMEditorBase';
3
- interface ITMSummary extends ITMEditorBase {
3
+ export interface ITMSummaryRef {
4
+ focus: () => void;
5
+ }
6
+ interface ITMSummaryProps extends ITMEditorBase {
4
7
  showBorder?: boolean;
5
8
  borderRadius?: string;
6
9
  showEditButton?: boolean;
@@ -13,5 +16,5 @@ interface ITMSummary extends ITMEditorBase {
13
16
  onClearClick?: () => void;
14
17
  onValueChanged?: (e: React.ChangeEvent<HTMLInputElement>) => void;
15
18
  }
16
- declare const TMSummary: React.FunctionComponent<ITMSummary>;
19
+ declare const TMSummary: React.ForwardRefExoticComponent<ITMSummaryProps & React.RefAttributes<ITMSummaryRef>>;
17
20
  export default TMSummary;
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { forwardRef, useRef, useImperativeHandle } from 'react';
2
3
  import styled from 'styled-components';
3
4
  import { FontSize, TMColors } from '../../utils/theme';
4
5
  import { StyledEditorContainer, StyledEditorIcon, StyledEditorLabel, TMEditorsDefaultBorderRadius, editorColorManager } from './TMEditorStyled';
@@ -46,11 +47,22 @@ const StyledEditorButtonIcon2 = styled.div `
46
47
  border-bottom-color: ${TMColors.primary};
47
48
  }
48
49
  `;
49
- const TMSummary = ({ placeHolder, readOnly, labelColor, hasValue, borderRadius = '4px', validationItems = [], buttons = [], label = '', onClearClick, openEditorOnSummaryClick = true, onEditorClick, backgroundColor = 'transparent', showBorder = true, isModifiedWhen, elementStyle, width = '100%', height = '100%', fontSize = FontSize.defaultFontSize, icon, showEditButton = true, showClearButton, iconEditButton, iconeEditTooltip, labelPosition = 'left', template, disabled = false, onValueChanged }) => {
50
+ const TMSummary = forwardRef(({ placeHolder, readOnly, labelColor, hasValue, borderRadius = '4px', validationItems = [], buttons = [], label = '', onClearClick, openEditorOnSummaryClick = true, onEditorClick, backgroundColor = 'transparent', showBorder = true, isModifiedWhen, elementStyle, width = '100%', height = '100%', fontSize = FontSize.defaultFontSize, icon, showEditButton = true, showClearButton, iconEditButton, iconeEditTooltip, labelPosition = 'left', template, disabled = false, onValueChanged }, ref) => {
51
+ const summaryElementRef = useRef(null); // Ref all'elemento DOM div principale
52
+ // Espone il metodo focus() tramite useImperativeHandle
53
+ useImperativeHandle(ref, () => ({
54
+ focus: () => {
55
+ summaryElementRef.current?.focus();
56
+ },
57
+ }));
58
+ const handleClearClick = (e) => {
59
+ e.stopPropagation(); // Evita che il click sul bottone di clear propaghi all'onClick del div
60
+ onClearClick?.();
61
+ };
50
62
  const renderTemplateField = () => {
51
- return (_jsxs(StyledSummaryTemplateInput, { "$readOnly": readOnly, tabIndex: 0, "$backgroundColor": backgroundColor, "$borderRadius": borderRadius, "$isModified": isModifiedWhen, "$vil": validationItems, "$disabled": disabled, "$showBorder": showBorder, "$fontSize": fontSize, "$width": width, "$height": height, onChange: onValueChanged, children: [_jsx("div", { onClick: () => { if (openEditorOnSummaryClick && !disabled)
63
+ return (_jsxs(StyledSummaryTemplateInput, { ref: summaryElementRef, "$readOnly": readOnly, tabIndex: 0, "$backgroundColor": backgroundColor, "$borderRadius": borderRadius, "$isModified": isModifiedWhen, "$vil": validationItems, "$disabled": disabled, "$showBorder": showBorder, "$fontSize": fontSize, "$width": width, "$height": height, onChange: onValueChanged, children: [_jsx("div", { onClick: () => { if (openEditorOnSummaryClick && !disabled)
52
64
  onEditorClick?.(); }, onDoubleClick: () => { if (!openEditorOnSummaryClick && !disabled)
53
- onEditorClick?.(); }, style: { display: 'flex', flexDirection: 'row', justifyContent: 'space-between', userSelect: 'text', alignItems: 'center', width: '100%', minHeight: '16px', cursor: (openEditorOnSummaryClick && !readOnly) ? 'pointer' : 'default' }, children: template }), _jsxs("div", { style: { display: 'flex', flexDirection: 'row', gap: '3px', justifyContent: 'flex-start', alignItems: 'center', pointerEvents: disabled ? 'none' : 'auto', opacity: disabled ? 0.4 : 1 }, children: [showClearButton && hasValue && _jsx(StyledEditorButtonIcon2, { tabIndex: disabled ? -1 : 0, onKeyDown: (e) => e.code === 'Space' && onClearClick?.(), onClick: onClearClick, children: _jsx(TMTooltip, { content: SDKUI_Localizator.Clear, children: _jsx(IconClearButton, {}) }) }), showEditButton && _jsx(StyledEditorButtonIcon2, { tabIndex: disabled ? -1 : 0, onKeyDown: (e) => e.code === 'Space' && onEditorClick?.(), onClick: onEditorClick, children: _jsx(TMTooltip, { content: iconeEditTooltip ?? SDKUI_Localizator.Update, children: iconEditButton ?? _jsx(IconPencil, {}) }) }), buttons.map((buttonItem) => {
65
+ onEditorClick?.(); }, style: { display: 'flex', flexDirection: 'row', justifyContent: 'space-between', userSelect: 'text', alignItems: 'center', width: '100%', minHeight: '16px', cursor: (openEditorOnSummaryClick && !readOnly) ? 'pointer' : 'default' }, children: template }), _jsxs("div", { style: { display: 'flex', flexDirection: 'row', gap: '3px', justifyContent: 'flex-start', alignItems: 'center', pointerEvents: disabled ? 'none' : 'auto', opacity: disabled ? 0.4 : 1 }, children: [showClearButton && hasValue && _jsx(StyledEditorButtonIcon2, { tabIndex: disabled ? -1 : 0, onKeyDown: (e) => e.code === 'Space' && onClearClick?.(), onClick: handleClearClick, children: _jsx(TMTooltip, { content: SDKUI_Localizator.Clear, children: _jsx(IconClearButton, {}) }) }), showEditButton && _jsx(StyledEditorButtonIcon2, { tabIndex: disabled ? -1 : 0, onKeyDown: (e) => e.code === 'Space' && onEditorClick?.(), onClick: onEditorClick, children: _jsx(TMTooltip, { content: iconeEditTooltip ?? SDKUI_Localizator.Update, children: iconEditButton ?? _jsx(IconPencil, {}) }) }), buttons.map((buttonItem) => {
54
66
  return (_jsx(StyledEditorButtonIcon2, { onClick: buttonItem.onClick, children: _jsx(TMTooltip, { content: buttonItem.text, children: buttonItem.icon }) }, buttonItem.text));
55
67
  })] })] }));
56
68
  };
@@ -61,5 +73,5 @@ const TMSummary = ({ placeHolder, readOnly, labelColor, hasValue, borderRadius =
61
73
  return (_jsxs(TMLayoutContainer, { direction: 'horizontal', children: [icon && _jsx(TMLayoutItem, { width: '20px', children: icon && _jsx(StyledEditorIcon, { "$disabled": disabled, "$vil": validationItems, "$isModified": isModifiedWhen, children: icon }) }), _jsx(TMLayoutItem, { children: _jsxs(StyledEditorContainer, { "$width": width, children: [label && renderLabel(), renderTemplateField(), _jsx(TMVilViewer, { vil: validationItems })] }) })] }));
62
74
  };
63
75
  return (_jsx("div", { style: elementStyle, children: renderSummary() }));
64
- };
76
+ });
65
77
  export default TMSummary;
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import React, { useCallback, useEffect, useMemo, useState } from 'react';
2
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
3
  import { LayoutModes, DcmtTypeListCacheService, PlatformObjectValidator, MetadataDataTypes, QueryOperators, DataListCacheService, MetadataDataDomains, SDK_Localizator, UserListCacheService } from '@topconsultnpm/sdk-ts-beta';
4
4
  import styled from 'styled-components';
5
5
  import { LocalizeQueryOperators, getDefaultOperator, SDKUI_Localizator, IconUndo, IconPencil, IconDataList, IconFunction, IconMenuVertical, IconClearButton, displayMetadataValue, SDKUI_Globals } from '../../../helper';
@@ -248,6 +248,7 @@ const TMSearchWhereItemViewer = React.memo(({ isSelected = false, whereItem, sho
248
248
  });
249
249
  const WhereItemRow = React.memo(({ whereItem, index, dcmtTypesList, isExpertMode, isSelected, isEditable, currentEditingMID, queryParamsDynDataList, onItemChange, onItemSelect, onAdvancedMenuClick, onCascadeRefreshDynDataLists, onCascadeUpdateMIDs, onHideMobileEditor }) => {
250
250
  const deviceType = useDeviceType();
251
+ const dropDownMenuRef = useRef(null);
251
252
  // Trova il metadata descriptor per l'item corrente
252
253
  const md = useMemo(() => {
253
254
  const dtd = dcmtTypesList.find(o => o.id === whereItem.tid);
@@ -323,6 +324,7 @@ const WhereItemRow = React.memo(({ whereItem, index, dcmtTypesList, isExpertMode
323
324
  icon: isEditable ? _jsx(IconUndo, {}) : _jsx(IconPencil, {}),
324
325
  onClick: () => {
325
326
  onAdvancedMenuClick({ tid: whereItem.tid, mid: whereItem.mid, button: AdvancedMenuButtons.MakeEditable });
327
+ dropDownMenuRef.current?.focus();
326
328
  }
327
329
  }] : []),
328
330
  {
@@ -331,6 +333,7 @@ const WhereItemRow = React.memo(({ whereItem, index, dcmtTypesList, isExpertMode
331
333
  onClick: () => {
332
334
  onItemSelect(whereItem.tid, whereItem.mid); // Seleziona prima di chiamare l'azione
333
335
  onAdvancedMenuClick({ tid: whereItem.tid, mid: whereItem.mid, button: AdvancedMenuButtons.DistinctValues });
336
+ dropDownMenuRef.current?.focus();
334
337
  }
335
338
  }
336
339
  ];
@@ -351,5 +354,5 @@ const WhereItemRow = React.memo(({ whereItem, index, dcmtTypesList, isExpertMode
351
354
  ? _jsx(IconFunction, { color: "#1a89d3", fontSize: 14, style: { position: "absolute", top: '-5px', left: '-10px' } })
352
355
  : isEditable
353
356
  ? _jsx(IconPencil, { color: "#138603", fontSize: 14, style: { position: "absolute", top: '-5px', left: '-10px' } })
354
- : null] }), _jsx("div", { style: { gridColumn: 4 }, children: _jsx(TMDropDownMenu, { backgroundColor: 'white', color: TMColors.button_icon, borderRadius: '3px', content: _jsx(TMButton, { btnStyle: 'icon', icon: _jsx(IconMenuVertical, {}), showTooltip: false }), items: advancedMenuItems }) })] }));
357
+ : null] }), _jsx("div", { style: { gridColumn: 4 }, children: _jsx(TMDropDownMenu, { ref: dropDownMenuRef, backgroundColor: 'white', color: TMColors.button_icon, borderRadius: '3px', content: _jsx(TMButton, { btnStyle: 'icon', icon: _jsx(IconMenuVertical, {}), showTooltip: false }), items: advancedMenuItems }) })] }));
355
358
  });
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState } from "react";
2
+ import { useEffect, useState } from "react";
3
3
  import { SDK_Globals } from '@topconsultnpm/sdk-ts-beta';
4
4
  import styled from "styled-components";
5
5
  import { SDKUI_Localizator, IconApply, IconCloseOutline, IconUser, IconInfo } from "../../../helper";
@@ -66,7 +66,7 @@ export const WorkFlowApproveRejectPopUp = ({ TID = 0, DID = 0, deviceType = Devi
66
66
  };
67
67
  export const WorkFlowReAssignPopUp = ({ DID = 0, TID = 0, deviceType = DeviceType.DESKTOP, onClose, selectedItems = [], onCompleted }) => {
68
68
  const [commentValue, setCommentValue] = useState('');
69
- const [selectedUserID, setSelectedUserID] = useState();
69
+ const [selectedUserID, setSelectedUserID] = useState([]);
70
70
  const [participants, setParticipants] = useState([]);
71
71
  const disable = commentValue.length === 0 || !selectedUserID;
72
72
  const count = () => { return selectedItems.length.toString() + ' Workitem'; };
@@ -80,7 +80,7 @@ export const WorkFlowReAssignPopUp = ({ DID = 0, TID = 0, deviceType = DeviceTyp
80
80
  ? selectedItems.map(({ TID, DID }) => ({ TID, DID }))
81
81
  : [{ TID, DID }];
82
82
  for (const { TID, DID } of items) {
83
- await SDK_Globals.tmSession?.NewWorkflowEngine().WorkItem_ReassignAsync(TID, DID, selectedUserID, commentValue);
83
+ await SDK_Globals.tmSession?.NewWorkflowEngine().WorkItem_ReassignAsync(TID, DID, selectedUserID?.[0], commentValue);
84
84
  }
85
85
  }
86
86
  catch (e) {
@@ -96,5 +96,8 @@ export const WorkFlowReAssignPopUp = ({ DID = 0, TID = 0, deviceType = DeviceTyp
96
96
  // SDK_Globals.tmSession?.NewWorkflowEngine().RetrieveAllAsync().then((o) => console.log('WFs', o));
97
97
  // SDK_Globals.tmSession?.NewWorkflowEngine().RetrieveAsync(11283).then((o) => console.log('WF', o));
98
98
  // }, [])
99
- return (_jsx(TMModal, { toolbar: _jsx(TMButton, { btnStyle: 'advanced', showTooltip: false, icon: _jsx(IconUser, { fontSize: 16 }), caption: 'Riassegna', disabled: disable, onClick: () => !disable && reAssignWorkFlowAsync(), advancedColor: TMColors.tertiary }), onClose: onClose, width: deviceType === DeviceType.MOBILE ? '95%' : '60%', height: '60%', isModal: true, title: 'Riassegna workflow ' + (selectedItems.length > 0 ? '(' + count() + ')' : ''), children: _jsxs("div", { style: { width: '100%', height: '100%', padding: '10px', display: 'flex', flexDirection: 'column', gap: 5 }, children: [_jsx(TMUserChooser, { value: selectedUserID, onValueChanged: (e) => setSelectedUserID(e) }), _jsxs("p", { style: { color: commentValue.length === 0 ? TMColors.error : 'black' }, children: ["Commento ", commentValue.length === 0 && _jsx("span", { children: ' (Campo obbligatorio)' }), " "] }), _jsx(StyledTextArea, { "$isValid": commentValue.length !== 0, value: commentValue, onChange: (e) => setCommentValue(e.target.value) })] }) }));
99
+ useEffect(() => { }, []);
100
+ return (_jsx(TMModal, { toolbar: _jsx(TMButton, { btnStyle: 'advanced', showTooltip: false, icon: _jsx(IconUser, { fontSize: 16 }), caption: 'Riassegna', disabled: disable, onClick: () => !disable && reAssignWorkFlowAsync(), advancedColor: TMColors.tertiary }), onClose: onClose, width: deviceType === DeviceType.MOBILE ? '95%' : '60%', height: '60%', isModal: true, title: 'Riassegna workflow ' + (selectedItems.length > 0 ? '(' + count() + ')' : ''), children: _jsxs("div", { style: { width: '100%', height: '100%', padding: '10px', display: 'flex', flexDirection: 'column', gap: 5 }, children: [_jsx(TMUserChooser, { values: selectedUserID, onValueChanged: (IDs) => {
101
+ setSelectedUserID(IDs ?? []);
102
+ } }), _jsxs("p", { style: { color: commentValue.length === 0 ? TMColors.error : 'black' }, children: ["Commento ", commentValue.length === 0 && _jsx("span", { children: ' (Campo obbligatorio)' }), " "] }), _jsx(StyledTextArea, { "$isValid": commentValue.length !== 0, value: commentValue, onChange: (e) => setCommentValue(e.target.value) })] }) }));
100
103
  };
@@ -42,7 +42,6 @@ const TMDataListItemViewer = ({ dataListId, value, viewMode = DataListViewModes.
42
42
  else {
43
43
  stringValue = value;
44
44
  }
45
- console.log('getIcon', stringValue);
46
45
  if (FormulaHelper.isFormula(stringValue))
47
46
  return null;
48
47
  return dataListItem ? _jsx(TMImageLibrary, { imageID: dataListItem.imageID }) : _jsx(IconWarning, { color: TMColors.warning });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react-beta",
3
- "version": "6.14.27",
3
+ "version": "6.14.28",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",