@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.
- package/lib/components/base/TMPanel.d.ts +1 -1
- package/lib/components/base/TMPanel.js +21 -15
- package/lib/components/features/archive/TMArchive.js +7 -11
- package/lib/components/features/documents/TMDcmtForm.js +5 -13
- package/lib/components/features/search/TMSearch.js +5 -14
- package/lib/components/features/search/TMSearchQueryPanel.js +9 -7
- package/lib/helper/helpers.d.ts +4 -0
- package/lib/helper/helpers.js +44 -0
- package/package.json +1 -1
|
@@ -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 {
|
|
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',
|
|
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
|
-
|
|
73
|
-
|
|
74
|
-
if (keepActiveState)
|
|
72
|
+
const handleFocus = useCallback(() => {
|
|
73
|
+
if (!isActive) {
|
|
75
74
|
setIsActive(true);
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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
|
|
50
|
-
|
|
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
|
|
330
|
-
|
|
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
|
|
135
|
-
|
|
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
|
|
150
|
-
|
|
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,
|
|
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);
|
|
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 (
|
|
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(
|
|
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); } },
|
package/lib/helper/helpers.d.ts
CHANGED
|
@@ -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[];
|
package/lib/helper/helpers.js
CHANGED
|
@@ -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
|
+
}
|