@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.
@@ -50,6 +50,7 @@ const TMFileManager = (props) => {
50
50
  return;
51
51
  event.preventDefault();
52
52
  setTreeViewAnchor(event.currentTarget);
53
+ handleFocusedFolder?.(undefined);
53
54
  };
54
55
  // Handle closing the context menu
55
56
  const closeTreeViewContextMenu = useCallback(() => {
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  interface ITMDcmtBlogProps {
3
3
  tid: number | undefined;
4
4
  did: number | undefined;
5
+ isVisible?: boolean;
5
6
  }
6
7
  declare const TMDcmtBlog: React.FC<ITMDcmtBlogProps>;
7
8
  export default TMDcmtBlog;
@@ -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
- catch (e) {
24
- let err = e;
25
- TMExceptionBoxManager.show({ exception: err });
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
- finally {
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: '25%', height: '100%' },
450
- 'tmBlog': { width: '25%', height: '100%' },
451
- 'tmSysMetadata': { width: '25%', height: '100%' },
452
- 'tmDcmtPreview': { width: '25%', height: '100%' },
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
  };
@@ -5,6 +5,7 @@ interface ITMDcmtPreviewProps {
5
5
  canNext?: boolean;
6
6
  canPrev?: boolean;
7
7
  isResizingActive?: boolean;
8
+ isVisible?: boolean;
8
9
  onNext?: () => void;
9
10
  onPrev?: () => void;
10
11
  onClosePanel?: () => void;
@@ -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, onClosePanel, canNext, canPrev, onNext, onPrev, onMaximizePanel }) => {
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
- setDcmtBlob(undefined);
29
- setError('');
30
- if (!dcmtData)
31
- return;
32
- if (isDcmtFileInCache(cacheKey)) {
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
- if ((extensionHandler(dcmtData.fileExt) !== FileExtensionHandler.NONE) && ((dcmtData.fileSize ?? 0) <= (SDKUI_Globals.userSettings.searchSettings.previewThreshold * 1024))) {
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
- else {
42
- setShowPreview(false);
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 { DeviceType, useDeviceType } from '../../base/TMDeviceProvider';
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 isVisible = maximizedPanels.length > 0 ? maximizedPanels.includes(panel.id) : panelVisibility[panel.id];
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
- display: isVisible ? 'flex' : 'none',
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
- _jsx(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: children }) : children }));
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react-beta",
3
- "version": "6.13.75",
3
+ "version": "6.13.76",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",