@topconsultnpm/sdkui-react-beta 6.14.15 → 6.14.16

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.
@@ -11,12 +11,12 @@ export interface ITMPanelProps {
11
11
  totalItems?: number;
12
12
  toolbar?: any;
13
13
  padding?: string;
14
- keepActiveState?: boolean;
15
14
  isVisible?: boolean;
16
15
  onBack?: () => void;
17
16
  onClose?: () => void;
18
17
  onHeaderDoubleClick?: () => void;
19
18
  onMaximize?: (isMaximized: boolean) => void;
19
+ onActiveChanged?: (isActive: boolean) => void;
20
20
  }
21
21
  declare const TMPanel: React.FC<ITMPanelProps>;
22
22
  export default TMPanel;
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useRef, useState } from 'react';
2
+ import { useCallback, useRef, useState } from 'react';
3
3
  import styled from 'styled-components';
4
4
  import { IconArrowLeft, IconClearButton, IconWindowMaximize, IconWindowMinimize, isPositiveNumber, SDKUI_Globals, SDKUI_Localizator } from '../../helper';
5
5
  import TMButton from './TMButton';
@@ -65,23 +65,29 @@ const StyledPanelContent = styled.div `
65
65
  outline: none;
66
66
  }
67
67
  `;
68
- const TMPanel = ({ allowMaximize = true, color, backgroundColor, backgroundColorContainer, children, showHeader = true, title, totalItems, displayedItemsCount, toolbar, padding = '5px', keepActiveState = false, isVisible = true, onBack, onClose, onHeaderDoubleClick, onMaximize }) => {
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
69
  const [isActive, setIsActive] = useState(false);
70
70
  const [isMaximized, setIsMaximized] = useState(false);
71
71
  const titleRowRef = useRef(null);
72
- // If keepActiveState is true, always force isActive to true
73
- useEffect(() => {
74
- if (keepActiveState)
72
+ const handleFocus = useCallback(() => {
73
+ if (!isActive) {
75
74
  setIsActive(true);
76
- }, [keepActiveState]);
77
- const handleFocus = () => {
78
- if (!keepActiveState)
79
- setIsActive(true);
80
- };
81
- const handleBlur = () => {
82
- if (!keepActiveState)
83
- setIsActive(false);
84
- };
75
+ onActiveChanged?.(true);
76
+ }
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
+ }
88
+ }
89
+ }, 0); // Un piccolo ritardo per consentire al browser di stabilire il nuovo activeElement
90
+ }, [isActive, onActiveChanged]);
85
91
  // handler for external maximize management
86
92
  const handleMaximize = () => {
87
93
  setIsMaximized(prevState => {
@@ -92,7 +98,7 @@ const TMPanel = ({ allowMaximize = true, color, backgroundColor, backgroundColor
92
98
  return newValue;
93
99
  });
94
100
  };
95
- return (_jsxs(StyledPanelContainer, { "$isMaximized": onMaximize ? false : isMaximized, style: {
101
+ return (_jsxs(StyledPanelContainer, { className: "tmpanel-container", "$isMaximized": onMaximize ? false : isMaximized, style: {
96
102
  visibility: isVisible ? 'visible' : 'hidden',
97
103
  }, children: [showHeader &&
98
104
  _jsx(StyledPanelHeader, { "$backgroundColor": backgroundColor, "$color": color, "$isActive": isActive, onDoubleClick: () => {
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useMemo, useState } from 'react';
3
3
  import Logo from '../../../assets/Toppy-generico.png';
4
4
  import { DcmtTypeListCacheService, LayoutModes, SDK_Localizator } from '@topconsultnpm/sdk-ts-beta';
5
- import { IconTree, SDKUI_Globals, SDKUI_Localizator, IconRecentlyViewed, IconPreview, IconShow, IconBoard, IconDcmtTypeSys } from '../../../helper';
5
+ import { IconTree, SDKUI_Globals, SDKUI_Localizator, IconRecentlyViewed, IconPreview, IconShow, IconBoard, IconDcmtTypeSys, removeMruTid } from '../../../helper';
6
6
  import { useDeviceType, DeviceType } from '../../base/TMDeviceProvider';
7
7
  import TMLayoutContainer, { TMLayoutItem } from '../../base/TMLayout';
8
8
  import TMRecentsManager from '../../grids/TMRecentsManager';
@@ -13,13 +13,12 @@ import TMPanel from '../../base/TMPanel';
13
13
  import { TMPanelManagerProvider, useTMPanelManagerContext } from '../../layout/panelManager/TMPanelManagerContext';
14
14
  import TMPanelManagerContainer from '../../layout/panelManager/TMPanelManagerContainer';
15
15
  const TMArchive = ({ inputTID, fileFromConnector = null }) => {
16
- const TIDs = SDKUI_Globals.userSettings.archivingSettings.mruTIDs;
17
16
  const [currentTID, setCurrentTID] = useState(0);
18
- const [mruTIDs, setMruTIDs] = useState(TIDs);
17
+ const [mruTIDs, setMruTIDs] = useState([]);
19
18
  const [currentMruTID, setCurrentMruTID] = useState(0);
20
19
  const [fromDTD, setFromDTD] = useState();
21
20
  const deviceType = useDeviceType();
22
- useEffect(() => { setMruTIDs(TIDs); }, []);
21
+ useEffect(() => { console.log(SDKUI_Globals.userSettings.archivingSettings.mruTIDs); setMruTIDs(SDKUI_Globals.userSettings.archivingSettings.mruTIDs); }, []);
23
22
  useEffect(() => {
24
23
  if (!inputTID)
25
24
  return;
@@ -33,10 +32,9 @@ const TMArchive = ({ inputTID, fileFromConnector = null }) => {
33
32
  setFromDTD(dtd);
34
33
  });
35
34
  }, [currentTID]);
36
- const setSearchByTID = (tid) => { setCurrentTID(tid); };
37
35
  const isMobile = deviceType === DeviceType.MOBILE;
38
36
  const tmTreeSelectorElement = useMemo(() => _jsx(TMTreeSelectorWrapper, { isMobile: isMobile, onSelectedTIDChanged: (tid) => {
39
- setSearchByTID(tid);
37
+ setCurrentTID(tid);
40
38
  if (tid && mruTIDs.includes(tid))
41
39
  setCurrentMruTID(tid);
42
40
  else
@@ -46,11 +44,8 @@ const TMArchive = ({ inputTID, fileFromConnector = null }) => {
46
44
  setCurrentMruTID(tid);
47
45
  setCurrentTID(tid);
48
46
  }, onDeletedTID: (tid) => {
49
- let newMruTIDS = mruTIDs.slice();
50
- let index = newMruTIDS.findIndex(o => o == tid);
51
- if (index >= 0)
52
- newMruTIDS.splice(index, 1);
53
- SDKUI_Globals.userSettings.searchSettings.mruTIDs = newMruTIDS.filter(tid => tid != undefined && tid != null);
47
+ let newMruTIDS = removeMruTid(SDKUI_Globals.userSettings.archivingSettings.mruTIDs, tid);
48
+ SDKUI_Globals.userSettings.archivingSettings.mruTIDs = newMruTIDS;
54
49
  setMruTIDs(newMruTIDS);
55
50
  } }), [mruTIDs, currentMruTID, deviceType]);
56
51
  const tmFormElement = useMemo(() => currentTID ?
@@ -136,6 +131,7 @@ const TMTreeSelectorWrapper = ({ isMobile, onSelectedTIDChanged }) => {
136
131
  };
137
132
  const TMRecentsManagerWrapper = ({ mruTIDs, currentMruTID, deviceType, onSelectedTID, onDeletedTID }) => {
138
133
  const { setPanelVisibilityById, setToolbarButtonVisibility } = useTMPanelManagerContext();
134
+ useEffect(() => { console.log('TMRecentsManagerWrapper -mruTIDs', mruTIDs); }, [mruTIDs]);
139
135
  return (_jsx(TMRecentsManager, { mruTIDs: mruTIDs, currentMruTID: currentMruTID, deviceType: deviceType, onSelectedTID: (tid) => {
140
136
  onSelectedTID?.(tid);
141
137
  if (deviceType === DeviceType.MOBILE)
@@ -31,10 +31,10 @@ import TMModal from '../../base/TMModal';
31
31
  import toppy from '../../../assets/Toppy-generico.png';
32
32
  import { TMPanelManagerProvider, useTMPanelManagerContext } from '../../layout/panelManager/TMPanelManagerContext';
33
33
  import TMPanelManagerContainer from '../../layout/panelManager/TMPanelManagerContainer';
34
+ import { updateMruTids } from '../../../helper';
34
35
  let abortControllerLocal = new AbortController();
35
36
  //#endregion
36
37
  const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes.Update, onClose, onSavedAsyncCallback, TID, DID, formMode = FormModes.Update, canNext, canPrev, count, itemIndex, onNext, onPrev, allowNavigation = true, allowRelations = true, isClosable = false, isExpertMode = SDKUI_Globals.userSettings.advancedSettings.expertMode === 1, showDcmtFormSidebar = true, invokedByTodo = false, titleModal, isModal = false, widthModal = "100%", heightModal = "100%", groupId, onWFOperationCompleted, fileFromConnector = null, }) => {
37
- const mruTIDs = SDKUI_Globals.userSettings.archivingSettings.mruTIDs;
38
38
  const [id, setID] = useState('');
39
39
  const [showWaitPanelLocal, setShowWaitPanelLocal] = useState(false);
40
40
  const [waitPanelTitleLocal, setWaitPanelTitleLocal] = useState('');
@@ -326,14 +326,8 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
326
326
  });
327
327
  await setMetadataListAsync(fromDTD?.metadata ?? [], true, res);
328
328
  resetHandler();
329
- let newMruTIDS = mruTIDs ? mruTIDs.slice() : [];
330
- let index = newMruTIDS.findIndex((o) => o == TID);
331
- if (index >= 0)
332
- newMruTIDS.splice(index, 1);
333
- if (newMruTIDS.length >= 10)
334
- newMruTIDS.splice(0, 1);
335
- newMruTIDS.push(TID);
336
- SDKUI_Globals.userSettings.archivingSettings.mruTIDs = newMruTIDS.filter(tid => tid != undefined && tid != null);
329
+ let newMruTIDS = updateMruTids(SDKUI_Globals.userSettings.archivingSettings.mruTIDs, TID);
330
+ SDKUI_Globals.userSettings.archivingSettings.mruTIDs = newMruTIDS;
337
331
  onSaveRecents?.(newMruTIDS);
338
332
  ShowAlert({ mode: 'success', title: 'Archiviazione', message: 'Il documento è stato archiviato con successo', duration: 3000 });
339
333
  }
@@ -585,10 +579,8 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
585
579
  isEditable: true,
586
580
  value: FormulaHelper.addFormulaTag(newFormula.expression)
587
581
  }));
588
- } }), (isModal && onClose) && _jsx("div", { id: "TMDcmtFormShowConfirmForClose-" + id })] }), (fromDTD?.templateTID === TemplateTIDs.WF_WIApprView && !isOpenDetails && !isOpenMaster) &&
589
- _jsx(ToppyHelpCenter, { deviceType: deviceType,
590
- // onClick={() => isMobile ? openConfigureMode?.() : undefined}
591
- content: _jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: '10px' }, children: _jsx(WorkFlowOperationButtons, { onApprove: () => setShowApprovePopup(true), onReject: () => setShowRejectPopup(true), onReAssign: () => setShowReAssignPopup(true), isInDcmtForm: deviceType === DeviceType.MOBILE }) }) }), isOpenDetails &&
582
+ } }), (isModal && onClose) && _jsx("div", { id: "TMDcmtFormShowConfirmForClose-" + id })] }), (fromDTD?.templateTID === TemplateTIDs.WF_WIApprView && !isOpenDetails && !isOpenMaster && layoutMode === LayoutModes.Update) &&
583
+ _jsx(ToppyHelpCenter, { deviceType: deviceType, content: _jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: '10px' }, children: _jsx(WorkFlowOperationButtons, { onApprove: () => setShowApprovePopup(true), onReject: () => setShowRejectPopup(true), onReAssign: () => setShowReAssignPopup(true), isInDcmtForm: deviceType === DeviceType.MOBILE }) }) }), isOpenDetails &&
592
584
  _jsx(StyledModalContainer, { style: { backgroundColor: 'white' }, children: _jsx(TMMasterDetailDcmts, { deviceType: deviceType, isForMaster: false, inputDcmts: getSelectionDcmtInfo(), allowNavigation: allowNavigation, canNext: canNext, canPrev: canPrev, onNext: onNext, onPrev: onPrev, onBack: () => setIsOpenDetails(false) }) }), isOpenMaster &&
593
585
  _jsxs(StyledModalContainer, { style: { backgroundColor: 'white' }, children: [_jsx(TMMasterDetailDcmts, { deviceType: deviceType, inputDcmts: getSelectionDcmtInfo(), isForMaster: true, allowNavigation: allowNavigation, canNext: canNext, canPrev: canPrev, onNext: onNext, onPrev: onPrev, onBack: () => setIsOpenMaster(false), appendMasterDcmts: handleAddItem }), secondaryMasterDcmts.length > 0 && secondaryMasterDcmts.map((dcmt, index) => {
594
586
  return (_jsx(StyledModalContainer, { style: { backgroundColor: 'white' }, children: _jsx(TMMasterDetailDcmts, { deviceType: deviceType, inputDcmts: [dcmt], isForMaster: true, allowNavigation: false, onBack: () => handleRemoveItem(dcmt.TID, dcmt.DID), appendMasterDcmts: handleAddItem }) }, `${index}-${dcmt.DID}`));
@@ -5,7 +5,7 @@ import TMSavedQuerySelector from './TMSavedQuerySelector';
5
5
  import TMTreeSelector from './TMTreeSelector';
6
6
  import { TabPanel, Item } from 'devextreme-react/tab-panel';
7
7
  import TMSearchQueryPanel, { refreshLastSearch } from './TMSearchQueryPanel';
8
- import { getSysAllDcmtsSQD, IconFilter, IconRecentlyViewed, IconSavedQuery, IconTree, SDKUI_Globals, SDKUI_Localizator } from '../../../helper';
8
+ import { getSysAllDcmtsSQD, IconFilter, IconRecentlyViewed, IconSavedQuery, IconTree, removeMruTid, SDKUI_Globals, SDKUI_Localizator, updateMruTids } from '../../../helper';
9
9
  import TMSearchResult from './TMSearchResult';
10
10
  import TMRecentsManager from '../../grids/TMRecentsManager';
11
11
  import { SearchResultContext } from '../../../ts';
@@ -131,11 +131,8 @@ const TMSearch = ({ inputTID, inputSqdID, isExpertMode = SDKUI_Globals.userSetti
131
131
  setCurrentMruTID(tid);
132
132
  setCurrentTID(tid);
133
133
  }, onDeletedTID: (tid) => {
134
- let newMruTIDS = mruTIDs.slice();
135
- let index = newMruTIDS.findIndex(o => o == tid);
136
- if (index >= 0)
137
- newMruTIDS.splice(index, 1);
138
- SDKUI_Globals.userSettings.searchSettings.mruTIDs = newMruTIDS.filter(tid => tid != undefined && tid != null);
134
+ let newMruTIDS = removeMruTid(SDKUI_Globals.userSettings.searchSettings.mruTIDs, tid);
135
+ SDKUI_Globals.userSettings.searchSettings.mruTIDs = newMruTIDS;
139
136
  setMruTIDs(newMruTIDS);
140
137
  } }), [mruTIDs, currentMruTID, deviceType]);
141
138
  const tmSearchQueryPanelElement = useMemo(() => _jsx(TMSearchQueryPanelWrapper, { isExpertMode: isExpertMode, showBackToResultButton: searchResult.length > 0, fromDTD: fromDTD, SQD: currentSQD, onBackToResult: () => { setCurrentSearchView(TMSearchViews.Result); }, onSearchCompleted: (searchResult, qd) => {
@@ -146,16 +143,10 @@ const TMSearch = ({ inputTID, inputSqdID, isExpertMode = SDKUI_Globals.userSetti
146
143
  setCurrentSearchView(TMSearchViews.Result);
147
144
  // Salvataggio ultimi 10 TIDs
148
145
  let fromTID = searchResult?.[0].fromTID;
149
- let newMruTIDS = mruTIDs.slice();
150
- let index = newMruTIDS.findIndex(o => o == fromTID);
151
- if (index >= 0)
152
- newMruTIDS.splice(index, 1);
153
- if (newMruTIDS.length >= 10)
154
- newMruTIDS.splice(0, 1);
155
- newMruTIDS.push(fromTID);
146
+ let newMruTIDS = updateMruTids(SDKUI_Globals.userSettings.searchSettings.mruTIDs, fromTID);
147
+ SDKUI_Globals.userSettings.searchSettings.mruTIDs = newMruTIDS;
156
148
  setMruTIDs(newMruTIDS);
157
149
  setCurrentMruTID(fromTID);
158
- SDKUI_Globals.userSettings.searchSettings.mruTIDs = newMruTIDS.filter(tid => tid != undefined && tid != null);
159
150
  }, onSqdSaved: async (newSqd) => {
160
151
  await loadDataSQDsAsync(true, newSqd.masterTID);
161
152
  await setSQDAsync(newSqd);
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useCallback, useEffect, useRef, useState } from 'react';
2
+ import { useCallback, useEffect, useState } from 'react';
3
3
  import { PlatformObjectValidator, WhereItem, SDK_Localizator, OrderByItem, SelectItem, SelectItemVisibilities, SDK_Globals, SavedQueryCacheService, SearchEngine, QueryOperators } from '@topconsultnpm/sdk-ts-beta';
4
4
  import styled from 'styled-components';
5
5
  import TMSearchQueryEditor from './TMSearchQueryEditor';
@@ -26,7 +26,8 @@ import TMShowAllOrMaxItemsButton from '../../base/TMShowAllOrMaxItemsButton';
26
26
  const TMSearchQueryPanel = ({ fromDTD, showBackToResultButton, isExpertMode = SDKUI_Globals.userSettings.advancedSettings.expertMode === 1, SQD, onSearchCompleted, onSqdSaved, onBack, onClosePanel, onMaximizePanel, onBackToResult }) => {
27
27
  const [confirmQueryParams, ConfirmQueryParamsDialog] = useQueryParametersDialog();
28
28
  const [qd, setQd] = useState();
29
- const [shouldSearch, setShouldSearch] = useState(false); // Nuovo stato per attivare la ricerca
29
+ const [shouldSearch, setShouldSearch] = useState(false);
30
+ const [isQueryPanelActive, setIsQueryPanelActive] = useState(false);
30
31
  const [lastQdParams, setLastQdParams] = useState([]);
31
32
  const [dcmtTypesList, setDcmtTypesList] = useState([]);
32
33
  const [showSqdForm, setShowSqdForm] = useState(false);
@@ -41,7 +42,6 @@ const TMSearchQueryPanel = ({ fromDTD, showBackToResultButton, isExpertMode = SD
41
42
  const deviceType = useDeviceType();
42
43
  const isMobile = deviceType === DeviceType.MOBILE;
43
44
  let initialMaxItems = deviceType === DeviceType.MOBILE ? 8 : 12;
44
- const panelRef = useRef(null);
45
45
  useEffect(() => {
46
46
  if (!SQD)
47
47
  return;
@@ -59,8 +59,7 @@ const TMSearchQueryPanel = ({ fromDTD, showBackToResultButton, isExpertMode = SD
59
59
  }, [shouldSearch, qd, showAdvancedSearch]);
60
60
  useEffect(() => {
61
61
  const handleKeyDown = (e) => {
62
- if (panelRef.current &&
63
- panelRef.current.contains(document.activeElement)) {
62
+ if (isQueryPanelActive) {
64
63
  if (e.key === 'Enter') {
65
64
  e.preventDefault();
66
65
  // Disattiva l'elemento attivo per forzare l'onBlur
@@ -76,7 +75,7 @@ const TMSearchQueryPanel = ({ fromDTD, showBackToResultButton, isExpertMode = SD
76
75
  return () => {
77
76
  window.removeEventListener('keydown', handleKeyDown);
78
77
  };
79
- }, []);
78
+ }, [isQueryPanelActive]);
80
79
  const setDataAsync = async (sqd) => {
81
80
  let newSqd = (sqd?.id == 1) ? sqd : await SavedQueryCacheService.GetAsync(sqd?.id);
82
81
  let newQd = SearchEngine.NormalizeQueryDescriptor(newSqd?.qd);
@@ -146,6 +145,9 @@ const TMSearchQueryPanel = ({ fromDTD, showBackToResultButton, isExpertMode = SD
146
145
  setQd(newQd);
147
146
  }
148
147
  }, []);
148
+ const handlePanelActiveChanged = useCallback((isActive) => {
149
+ setIsQueryPanelActive(isActive);
150
+ }, []);
149
151
  const handleAdvancedMenuClick = useCallback((e) => {
150
152
  if (e.button === AdvancedMenuButtons.DistinctValues) {
151
153
  setShowDistinctValuesPanel(true);
@@ -227,7 +229,7 @@ const TMSearchQueryPanel = ({ fromDTD, showBackToResultButton, isExpertMode = SD
227
229
  }
228
230
  setQd({ ...qd, orderBy: newOrderBy });
229
231
  }, [qd, fromDTD?.metadata, SQD?.masterTID]);
230
- return (_jsxs("div", { ref: panelRef, style: { height: '100%' }, children: [_jsxs(TMPanel, { title: fromDTD?.nameLoc ?? SDKUI_Localizator.Search_Metadata, allowMaximize: !isMobile, onMaximize: isMobile ? undefined : onMaximizePanel, onHeaderDoubleClick: isMobile ? undefined : onMaximizePanel, onBack: onBack, toolbar: _jsx(_Fragment, { children: (SQD && !showSqdForm) ?
232
+ return (_jsxs(_Fragment, { children: [_jsxs(TMPanel, { title: fromDTD?.nameLoc ?? SDKUI_Localizator.Search_Metadata, allowMaximize: !isMobile, onMaximize: isMobile ? undefined : onMaximizePanel, onHeaderDoubleClick: isMobile ? undefined : onMaximizePanel, onBack: onBack, onActiveChanged: handlePanelActiveChanged, toolbar: _jsx(_Fragment, { children: (SQD && !showSqdForm) ?
231
233
  _jsx(TMDropDownMenu, { backgroundColor: 'white', borderRadius: '3px', content: _jsx(TMButton, { btnStyle: 'icon', caption: 'Altro', icon: _jsx(IconMenuVertical, { color: 'white' }), showTooltip: false }), items: [
232
234
  ...(showBackToResultButton ? [{ icon: _jsx(IconArrowRight, {}), text: "Vai a risultato", onClick: () => { onBackToResult?.(); } }] : []),
233
235
  { icon: _jsx(IconAddCircleOutline, {}), beginGroup: true, text: SDKUI_Localizator.SavedQueryNew, onClick: () => { openSqdForm(FormModes.Create); } },
@@ -57,3 +57,7 @@ export declare function getContrastColor(inputColor: string): {
57
57
  bgColor: string;
58
58
  textColor: string;
59
59
  };
60
+ /** Adds TID to a list of "most recently used" (MRU) TIDs, keeping a maximum of 10 elements */
61
+ export declare function updateMruTids(currentMruTIDs: number[] | undefined | null, newTid: unknown): number[];
62
+ /** Remove TID to a list of "most recently used" (MRU) TIDs, keeping a maximum of 10 elements */
63
+ export declare function removeMruTid(currentMruTIDs: number[] | undefined | null, tidToRemove: unknown): number[];
@@ -718,3 +718,47 @@ export function getContrastColor(inputColor) {
718
718
  textColor: luminance > 0.6 ? '#2559A5' : '#FFFFFF'
719
719
  };
720
720
  }
721
+ // #endregion
722
+ /** Adds TID to a list of "most recently used" (MRU) TIDs, keeping a maximum of 10 elements */
723
+ export function updateMruTids(currentMruTIDs, newTid) {
724
+ // 1. Make sure newTid is a valid number.
725
+ // Using unknown forces validation.
726
+ // This is a best practice for robust functions that need to handle potentially non-compliant input.
727
+ const tidAsNumber = Number(newTid);
728
+ if (isNaN(tidAsNumber)) {
729
+ console.warn(`Tentativo di aggiungere un TID non numerico: ${newTid}. Ignorato.`);
730
+ return currentMruTIDs ? currentMruTIDs.filter(tid => tid != null) : [];
731
+ }
732
+ // 2. Initialize or copy existing MRU list.
733
+ let updatedMruTIDs = currentMruTIDs ? currentMruTIDs.filter(tid => tid != null) : [];
734
+ // 3. Remove the TID if it already exists to avoid duplicates and update its position.
735
+ const existingIndex = updatedMruTIDs.findIndex((o) => o === tidAsNumber);
736
+ if (existingIndex >= 0) {
737
+ updatedMruTIDs.splice(existingIndex, 1);
738
+ }
739
+ // 4. Remove oldest element if list exceeds maximum size of 10.
740
+ if (updatedMruTIDs.length >= 10) {
741
+ updatedMruTIDs.splice(0, 1); // Rimuove il primo elemento (il più vecchio)
742
+ }
743
+ // 5. Add new TID to queue (most recent).
744
+ updatedMruTIDs.push(tidAsNumber);
745
+ return updatedMruTIDs;
746
+ }
747
+ /** Remove TID to a list of "most recently used" (MRU) TIDs, keeping a maximum of 10 elements */
748
+ export function removeMruTid(currentMruTIDs, tidToRemove) {
749
+ // 1. Make sure tidToRemove is a valid number.
750
+ const tidAsNumber = Number(tidToRemove);
751
+ if (isNaN(tidAsNumber)) {
752
+ console.warn(`Tentativo di rimuovere un TID non numerico: ${tidToRemove}. Ignorato.`);
753
+ return currentMruTIDs ? currentMruTIDs.filter(tid => tid != null) : [];
754
+ }
755
+ // 2. Initialize or copy existing MRU list.
756
+ let updatedMruTIDs = currentMruTIDs ? currentMruTIDs.filter(tid => tid != null) : [];
757
+ // 3. Find the TID index to remove.
758
+ const indexToRemove = updatedMruTIDs.findIndex((o) => o === tidAsNumber);
759
+ // 4. If the TID is found, remove it from the list.
760
+ if (indexToRemove >= 0) {
761
+ updatedMruTIDs.splice(indexToRemove, 1);
762
+ }
763
+ return updatedMruTIDs;
764
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react-beta",
3
- "version": "6.14.15",
3
+ "version": "6.14.16",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",