@topconsultnpm/sdkui-react-beta 6.13.75 → 6.13.76
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/TMFileManager.js +1 -0
- package/lib/components/features/documents/TMDcmtBlog.d.ts +1 -0
- package/lib/components/features/documents/TMDcmtBlog.js +31 -16
- package/lib/components/features/documents/TMDcmtForm.js +6 -24
- package/lib/components/features/documents/TMDcmtPreview.d.ts +1 -0
- package/lib/components/features/documents/TMDcmtPreview.js +25 -12
- package/lib/components/features/search/TMSearchResult.js +2 -2
- package/lib/components/layout/panelManager/TMPanelWrapper.d.ts +1 -1
- package/lib/components/layout/panelManager/TMPanelWrapper.js +31 -8
- package/package.json +1 -1
|
@@ -7,27 +7,42 @@ import TMSpinner from '../../base/TMSpinner';
|
|
|
7
7
|
import TMBlogs from '../../grids/TMBlogs';
|
|
8
8
|
import { TMNothingToShow } from './TMDcmtPreview';
|
|
9
9
|
import { IconBoard } from '../../../helper';
|
|
10
|
-
const TMDcmtBlog = ({ tid, did }) => {
|
|
10
|
+
const TMDcmtBlog = ({ tid, did, isVisible }) => {
|
|
11
11
|
const [blogsDatasource, setBlogsDatasource] = useState([]);
|
|
12
|
+
const [hasLoadedDataOnce, setHasLoadedDataOnce] = useState(false); //traccia se *qualsiasi* dato è stato caricato per la prima volta
|
|
13
|
+
const [lastLoadedDid, setLastLoadedDid] = useState(undefined); // `lastLoadedDid` tiene traccia dell'ultimo `did` per cui abbiamo caricato i dati
|
|
12
14
|
useEffect(() => {
|
|
13
|
-
if (!tid || !did)
|
|
15
|
+
if (!tid || !did) {
|
|
16
|
+
setBlogsDatasource([]);
|
|
17
|
+
setLastLoadedDid(undefined); // Reset per consentire un nuovo caricamento quando tid/did diventano validi
|
|
14
18
|
return;
|
|
15
|
-
loadDataAsync(tid, did);
|
|
16
|
-
}, [did]);
|
|
17
|
-
const loadDataAsync = async (tid, did) => {
|
|
18
|
-
try {
|
|
19
|
-
TMSpinner.show({ description: 'Caricamento - Bacheca...' });
|
|
20
|
-
let res = await SDK_Globals.tmSession?.NewSearchEngine().BlogRetrieveAsync(tid, did);
|
|
21
|
-
setBlogsDatasource(res ?? []);
|
|
22
19
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
// Condizione per eseguire il fetch:
|
|
21
|
+
// 1. Il pannello è visibile
|
|
22
|
+
// 2. E (non abbiamo ancora caricato dati O il `did` è cambiato rispetto all'ultima volta)
|
|
23
|
+
const shouldFetch = isVisible && (!hasLoadedDataOnce || did !== lastLoadedDid);
|
|
24
|
+
// Esegui la chiamata API solo se il pannello è visibile E i dati non sono già stati caricati
|
|
25
|
+
// O, se vuoi ricaricare ogni volta che diventa visibile (ma è meno efficiente per "pesante")
|
|
26
|
+
if (shouldFetch) {
|
|
27
|
+
const fetchDataAsync = async (tid, did) => {
|
|
28
|
+
try {
|
|
29
|
+
TMSpinner.show({ description: 'Caricamento - Bacheca...' });
|
|
30
|
+
let res = await SDK_Globals.tmSession?.NewSearchEngine().BlogRetrieveAsync(tid, did);
|
|
31
|
+
setBlogsDatasource(res ?? []);
|
|
32
|
+
setHasLoadedDataOnce(true); // Marca che abbiamo caricato dati almeno una volta
|
|
33
|
+
setLastLoadedDid(did); // Memorizza il `did` per cui abbiamo caricato
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
let err = e;
|
|
37
|
+
TMExceptionBoxManager.show({ exception: err });
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
TMSpinner.hide();
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
fetchDataAsync(tid, did);
|
|
26
44
|
}
|
|
27
|
-
|
|
28
|
-
TMSpinner.hide();
|
|
29
|
-
}
|
|
30
|
-
};
|
|
45
|
+
}, [tid, did, isVisible, hasLoadedDataOnce, lastLoadedDid]);
|
|
31
46
|
return (_jsx(StyledContainer, { children: _jsx(StyledSectionContainer, { style: { position: 'relative' }, children: _jsx(StyledBoardContainer, { children: !did ? _jsx(TMNothingToShow, { text: 'Nessun documento selezionato.', secondText: 'Bacheca non disponibile.', icon: _jsx(IconBoard, { fontSize: 96 }) }) :
|
|
32
47
|
_jsx(TMBlogs, { id: "dcmt-blog", allData: blogsDatasource, showExtendedAttachments: false }) }) }) }));
|
|
33
48
|
};
|
|
@@ -446,10 +446,10 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
|
446
446
|
'tmDcmtPreview': true,
|
|
447
447
|
};
|
|
448
448
|
const initialPanelDimensions = {
|
|
449
|
-
'tmDcmtForm': { width: '
|
|
450
|
-
'tmBlog': { width: '
|
|
451
|
-
'tmSysMetadata': { width: '
|
|
452
|
-
'tmDcmtPreview': { width: '
|
|
449
|
+
'tmDcmtForm': { width: '20%', height: '100%' },
|
|
450
|
+
'tmBlog': { width: '30%', height: '100%' },
|
|
451
|
+
'tmSysMetadata': { width: '20%', height: '100%' },
|
|
452
|
+
'tmDcmtPreview': { width: '30%', height: '100%' },
|
|
453
453
|
};
|
|
454
454
|
const initialPanels = useMemo(() => [
|
|
455
455
|
{
|
|
@@ -493,24 +493,6 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
|
|
|
493
493
|
toolbarOptions: { icon: _jsx(IconShow, { fontSize: 24 }), disabled: isPreviewDisabled, visible: true, orderNumber: 4, isActive: allInitialPanelVisibility['tmDcmtPreview'] }
|
|
494
494
|
}
|
|
495
495
|
], [tmDcmtForm, tmBlog, tmSysMetadata, tmDcmtPreview, isPreviewDisabled, isBoardDisabled, isSysMetadataDisabled, isClosable]);
|
|
496
|
-
// {showDcmtFormSidebar && <TMCommandsPanel
|
|
497
|
-
// isMobile={deviceType === DeviceType.MOBILE}
|
|
498
|
-
// items={[
|
|
499
|
-
// ...(layoutMode === LayoutModes.Ark ? [
|
|
500
|
-
// { icon: <IconRoundFileUpload />, selected: isOpenPreview, disabled: isPreviewDisabled, onClick: () => { if (!isPreviewDisabled) setIsOpenPreview(!isOpenPreview); } }
|
|
501
|
-
// ] : []),
|
|
502
|
-
// ...(layoutMode !== LayoutModes.Ark ? [
|
|
503
|
-
// ...(deviceType === DeviceType.MOBILE ? [{ icon: <IconArrowLeft />, onClick: isClosable ? undefined : handleClose }] : []),
|
|
504
|
-
// { icon: <IconPreview />, selected: isOpenDcmtForm, onClick: () => { setIsOpenDcmtForm(!isOpenDcmtForm); } },
|
|
505
|
-
// { icon: <IconShow />, selected: isOpenPreview, disabled: isPreviewDisabled, onClick: () => { if (!isPreviewDisabled) setIsOpenPreview(!isOpenPreview); } },
|
|
506
|
-
// { icon: <IconBoard />, selected: isOpenBoard, disabled: isBoardDisabled, onClick: () => { if (!isBoardDisabled) { closeMiddlePanel(); setIsOpenBoard(!isOpenBoard); } } },
|
|
507
|
-
// { icon: <IconDcmtTypeSys />, selected: isOpenSysMetadata, disabled: isSysMetadataDisabled, onClick: () => { if (!isSysMetadataDisabled) { closeMiddlePanel(); setIsOpenSysMetadata(!isOpenSysMetadata); } } },
|
|
508
|
-
// ] : []),
|
|
509
|
-
// ...(allowRelations && currentTIDHasMasterRelations ? [{ icon: <IconDetailDcmts />, selected: isOpenMaster, disabled: isMasterDisabled, onClick: () => { if (!isMasterDisabled) setIsOpenMaster(!isOpenMaster); } }] : []),
|
|
510
|
-
// ...(allowRelations && currentTIDHasDetailRelations ? [{ icon: <IconDetailDcmts transform='scale(-1, 1)' />, selected: isOpenDetails, disabled: isDetailsDisabled, onClick: () => { if (!isDetailsDisabled) setIsOpenDetails(!isOpenDetails); } }] : []),
|
|
511
|
-
// ...customRightSidebarItems
|
|
512
|
-
// ]}
|
|
513
|
-
// />}
|
|
514
496
|
const renderDcmtForm = () => {
|
|
515
497
|
return (_jsxs("div", { style: {
|
|
516
498
|
display: 'flex',
|
|
@@ -603,9 +585,9 @@ const ToppyImage = styled.img `
|
|
|
603
585
|
export const ToppyHelpCenter = ({ content, onClick, deviceType, top = -200 }) => {
|
|
604
586
|
return (_jsxs(ToppyContainer, { children: [_jsx(ToppyImage, { "$isMobile": deviceType === DeviceType.MOBILE, onClick: onClick, src: toppy, alt: "Toppy" }), _jsx("div", { style: { top: deviceType === DeviceType.MOBILE ? -180 : top, right: deviceType === DeviceType.MOBILE ? 20 : 1, transform: 'rotate(20deg)', position: 'absolute', width: 'max-content', height: 'max-content' }, children: content })] }));
|
|
605
587
|
};
|
|
606
|
-
const TMDcmtPreviewWrapper = ({ currentDcmt, layoutMode, fromDTD, dcmtFile, deviceType, onFileUpload }) => {
|
|
588
|
+
const TMDcmtPreviewWrapper = ({ currentDcmt, layoutMode, fromDTD, dcmtFile, deviceType, isVisible, onFileUpload }) => {
|
|
607
589
|
const { setPanelVisibilityById, toggleMaximize, isResizingActive } = useTMPanelManagerContext();
|
|
608
590
|
return (layoutMode === LayoutModes.Update ?
|
|
609
|
-
_jsx(TMDcmtPreview, { onClosePanel: () => setPanelVisibilityById('tmDcmtPreview', false), onMaximizePanel: () => toggleMaximize('tmDcmtPreview'), dcmtData: currentDcmt, isResizingActive: isResizingActive }) :
|
|
591
|
+
_jsx(TMDcmtPreview, { isVisible: isVisible, onClosePanel: () => setPanelVisibilityById('tmDcmtPreview', false), onMaximizePanel: () => toggleMaximize('tmDcmtPreview'), dcmtData: currentDcmt, isResizingActive: isResizingActive }) :
|
|
610
592
|
_jsx(TMFileUploader, { onFileUpload: onFileUpload, onClose: () => setPanelVisibilityById('tmDcmtPreview', false), isRequired: fromDTD?.archiveConstraint === ArchiveConstraints.ContentCompulsory && dcmtFile === null, defaultBlob: dcmtFile, deviceType: deviceType, isResizingActive: isResizingActive }));
|
|
611
593
|
};
|
|
@@ -15,7 +15,7 @@ import { TMSaveFormButtonPrevious, TMSaveFormButtonNext } from '../../forms/TMSa
|
|
|
15
15
|
import { StyledAnimatedComponentOpacity } from '../../base/Styled';
|
|
16
16
|
import TMPanel from '../../base/TMPanel';
|
|
17
17
|
import { DeviceType, useDeviceType } from '../../base/TMDeviceProvider';
|
|
18
|
-
const TMDcmtPreview = ({ dcmtData, isResizingActive,
|
|
18
|
+
const TMDcmtPreview = ({ dcmtData, isResizingActive, isVisible, canNext, canPrev, onClosePanel, onNext, onPrev, onMaximizePanel }) => {
|
|
19
19
|
const [dcmtBlob, setDcmtBlob] = useState(undefined);
|
|
20
20
|
const [showPreview, setShowPreview] = useState(false);
|
|
21
21
|
const [isFromCache, setIsFromCache] = useState(false);
|
|
@@ -24,24 +24,37 @@ const TMDcmtPreview = ({ dcmtData, isResizingActive, onClosePanel, canNext, canP
|
|
|
24
24
|
const cacheKey = dcmtData ? `${dcmtData.tid}-${dcmtData.did}` : '00';
|
|
25
25
|
const deviceType = useDeviceType();
|
|
26
26
|
const isMobile = deviceType === DeviceType.MOBILE;
|
|
27
|
+
const [hasLoadedDataOnce, setHasLoadedDataOnce] = useState(false);
|
|
28
|
+
const [lastLoadedDid, setLastLoadedDid] = useState(undefined);
|
|
27
29
|
useEffect(() => {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
loadDocumentWithCache();
|
|
34
|
-
setShowPreview(true);
|
|
30
|
+
if (!dcmtData) {
|
|
31
|
+
setLastLoadedDid(undefined); // Reset
|
|
32
|
+
setDcmtBlob(undefined);
|
|
33
|
+
setError('');
|
|
34
|
+
setShowPreview(false);
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
|
-
|
|
37
|
+
const currentCacheKey = `${dcmtData.tid}-${dcmtData.did}`;
|
|
38
|
+
const shouldFetch = isVisible && (!hasLoadedDataOnce || currentCacheKey !== lastLoadedDid);
|
|
39
|
+
if (isDcmtFileInCache(currentCacheKey)) {
|
|
38
40
|
loadDocumentWithCache();
|
|
39
41
|
setShowPreview(true);
|
|
42
|
+
return;
|
|
40
43
|
}
|
|
41
|
-
|
|
42
|
-
|
|
44
|
+
if (shouldFetch) {
|
|
45
|
+
setDcmtBlob(undefined);
|
|
46
|
+
setError('');
|
|
47
|
+
if ((extensionHandler(dcmtData.fileExt) !== FileExtensionHandler.NONE) && ((dcmtData.fileSize ?? 0) <= (SDKUI_Globals.userSettings.searchSettings.previewThreshold * 1024))) {
|
|
48
|
+
loadDocumentWithCache();
|
|
49
|
+
setShowPreview(true);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
setShowPreview(false);
|
|
53
|
+
}
|
|
54
|
+
setHasLoadedDataOnce(true);
|
|
55
|
+
setLastLoadedDid(currentCacheKey);
|
|
43
56
|
}
|
|
44
|
-
}, [dcmtData]);
|
|
57
|
+
}, [dcmtData?.did, isVisible, hasLoadedDataOnce, lastLoadedDid]);
|
|
45
58
|
const loadDocumentWithCache = async () => {
|
|
46
59
|
const rfo = new RetrieveFileOptions();
|
|
47
60
|
rfo.retrieveReason = DcmtOpers.None;
|
|
@@ -696,7 +696,7 @@ const TMSearchResultSelector = ({ searchResults = [], onSelectionChanged }) => {
|
|
|
696
696
|
return (_jsx("div", { style: { height: '100%', width: '100%', overflow: 'auto' }, children: sortedCategories.map((category) => (_jsxs("div", { children: [_jsxs(StyledGroupTemplate, { onClick: () => toggleCategory(category), children: [activeCategories.includes(category) ? _jsx(IconChevronDown, {}) : _jsx(IconChevronDown, { transform: 'scale(-1, 1)' }), renderGroupTemplate(category)] }, category), activeCategories.includes(category) && (_jsx("div", { style: { padding: '5px' }, children: groupedResults[category].map((result, index) => (_jsx(StyledItemTemplate, { "$isSelected": selectedResult === result, onClick: () => handleSelect(result), children: renderItemTemplate(result) }, index))) }))] }, category))) }));
|
|
697
697
|
};
|
|
698
698
|
//#endregion TMSearchResultSelector
|
|
699
|
-
const TMDcmtPreviewWrapper = ({ currentDcmt }) => {
|
|
699
|
+
const TMDcmtPreviewWrapper = ({ currentDcmt, isVisible }) => {
|
|
700
700
|
const { setPanelVisibilityById, toggleMaximize, isResizingActive } = useTMPanelManagerContext();
|
|
701
|
-
return (_jsx(TMDcmtPreview, { onClosePanel: () => setPanelVisibilityById('tmDcmtPreview', false), onMaximizePanel: () => toggleMaximize('tmDcmtPreview'), dcmtData: currentDcmt, isResizingActive: isResizingActive }));
|
|
701
|
+
return (_jsx(TMDcmtPreview, { onClosePanel: () => setPanelVisibilityById('tmDcmtPreview', false), onMaximizePanel: () => toggleMaximize('tmDcmtPreview'), dcmtData: currentDcmt, isResizingActive: isResizingActive, isVisible: isVisible }));
|
|
702
702
|
};
|
|
@@ -4,5 +4,5 @@ interface TMPanelWrapperProps {
|
|
|
4
4
|
panel: TMPanelDefinition;
|
|
5
5
|
children: ReactNode;
|
|
6
6
|
}
|
|
7
|
-
declare const TMPanelWrapper: (props: TMPanelWrapperProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
declare const TMPanelWrapper: (props: TMPanelWrapperProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
8
8
|
export default TMPanelWrapper;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useMemo } from 'react';
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React, { useMemo, useState, useEffect } from 'react';
|
|
3
3
|
import { useTMPanelManagerContext } from './TMPanelManagerContext';
|
|
4
|
-
import {
|
|
4
|
+
import { useDeviceType, DeviceType } from '../../base/TMDeviceProvider';
|
|
5
5
|
import TMPanel from '../../base/TMPanel';
|
|
6
6
|
const TMPanelWrapper = (props) => {
|
|
7
7
|
const { panel, children } = props;
|
|
@@ -16,15 +16,23 @@ const TMPanelWrapper = (props) => {
|
|
|
16
16
|
// Extract panel dimensions based on panel id
|
|
17
17
|
const width = panelDimensions[panel.id].width;
|
|
18
18
|
const height = panelDimensions[panel.id].height;
|
|
19
|
-
// Determine visibility:
|
|
19
|
+
// Determine visibility:
|
|
20
20
|
// - If any panels are maximized, only show those maximized panels
|
|
21
21
|
// - Otherwise, rely on the normal panel visibility state
|
|
22
|
-
const
|
|
22
|
+
const isCurrentlyVisible = maximizedPanels.length > 0 ? maximizedPanels.includes(panel.id) : panelVisibility[panel.id];
|
|
23
|
+
// NUOVO STATO: Traccia se il pannello è mai stato reso visibile
|
|
24
|
+
const [hasBeenRenderedOnce, setHasBeenRenderedOnce] = useState(isCurrentlyVisible);
|
|
25
|
+
// NUOVO useEffect: Aggiorna hasBeenRenderedOnce quando il pannello diventa visibile per la prima volta
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (isCurrentlyVisible && !hasBeenRenderedOnce) {
|
|
28
|
+
setHasBeenRenderedOnce(true);
|
|
29
|
+
}
|
|
30
|
+
}, [isCurrentlyVisible, hasBeenRenderedOnce]);
|
|
23
31
|
const panelStyles = {
|
|
24
32
|
margin: '0',
|
|
25
|
-
// overflow: 'hidden',
|
|
26
33
|
boxSizing: 'border-box',
|
|
27
|
-
|
|
34
|
+
// Applica 'flex' o 'none' solo se è già stato reso visibile almeno una volta
|
|
35
|
+
display: isCurrentlyVisible ? 'flex' : 'none',
|
|
28
36
|
flexDirection: 'column',
|
|
29
37
|
minWidth: '50px',
|
|
30
38
|
minHeight: '50px',
|
|
@@ -32,7 +40,22 @@ const TMPanelWrapper = (props) => {
|
|
|
32
40
|
height: height,
|
|
33
41
|
pointerEvents: 'auto',
|
|
34
42
|
};
|
|
43
|
+
// Rende il pannello solo se è attualmente visibile O se è già stato reso visibile una volta.
|
|
44
|
+
// Se non è mai stato reso visibile E non è attualmente visibile, non renderizza nulla (o un placeholder vuoto).
|
|
45
|
+
if (!isCurrentlyVisible && !hasBeenRenderedOnce) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
// Clona il child e passa una prop 'isVisible'
|
|
49
|
+
const childrenWithProps = React.Children.map(children, child => {
|
|
50
|
+
if (React.isValidElement(child)) {
|
|
51
|
+
return React.cloneElement(child, { isVisible: isCurrentlyVisible });
|
|
52
|
+
}
|
|
53
|
+
return child;
|
|
54
|
+
});
|
|
35
55
|
return (_jsx("div", { "data-panel-id": panel.id, style: panelStyles, children: panel.contentOptions?.panelContainer ?
|
|
36
|
-
|
|
56
|
+
_jsxs(TMPanel, { ...panel.contentOptions.panelContainer, allowMaximize: !isMobile, onHeaderDoubleClick: isMaximizable ? () => toggleMaximize(panel.id) : undefined, onMaximize: isMaximizable ? () => toggleMaximize(panel.id) : undefined, onClose: isClosable ? () => togglePanelVisibility(panel.id) : undefined, children: [childrenWithProps, " "] })
|
|
57
|
+
:
|
|
58
|
+
childrenWithProps // Usa i children clonati
|
|
59
|
+
}));
|
|
37
60
|
};
|
|
38
61
|
export default TMPanelWrapper;
|