@topconsultnpm/sdkui-react-beta 6.14.40 → 6.14.42

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.
@@ -72,6 +72,8 @@ export interface TMFileManagerProps {
72
72
  showPanel?: boolean;
73
73
  /** Callback to handle panel close */
74
74
  onClosePanel?: () => void;
75
+ /** Flag to allow panel maximization */
76
+ allowMaximize?: boolean;
75
77
  /** Callback to handle back button */
76
78
  onMaximizePanel?: () => void;
77
79
  /** Context menu items for folders */
@@ -22,7 +22,7 @@ export var TMFileManagerPageSize;
22
22
  })(TMFileManagerPageSize || (TMFileManagerPageSize = {}));
23
23
  const TMFileManager = (props) => {
24
24
  // Destructure the treeFs prop to get the root file system
25
- const { treeFs, selectedFolder, selectedFiles, focusedFile, userID, handleSelectedFiles, handleFocusedFile, handleFocusedFolder, handleSelectedFolder, viewMode: initialViewMode, onDoubleClickHandler, handleDropFileCallback, dcmtsFound, folderContextMenuItems, fileContextMenuItems, showPanel = false, onClosePanel, onMaximizePanel } = props;
25
+ const { treeFs, selectedFolder, selectedFiles, focusedFile, userID, handleSelectedFiles, handleFocusedFile, handleFocusedFolder, handleSelectedFolder, viewMode: initialViewMode, onDoubleClickHandler, handleDropFileCallback, dcmtsFound, folderContextMenuItems, fileContextMenuItems, showPanel = false, onClosePanel, allowMaximize = true, onMaximizePanel } = props;
26
26
  // State to manage the current view mode ('thumbnails' or 'details')
27
27
  const [viewMode, setViewMode] = useState(initialViewMode ?? 'thumbnails');
28
28
  // State to store the search text entered by the user
@@ -181,7 +181,7 @@ const TMFileManager = (props) => {
181
181
  };
182
182
  // Main render of the file manager component with a split layout
183
183
  return _jsxs("div", { style: { height: "100%", width: "100%" }, children: [!isMobile &&
184
- _jsx(TMPanel, { title: SDKUI_Localizator.Drafts, totalItems: dcmtsFound ?? 0, showHeader: showPanel, onClose: onClosePanel, onMaximize: onMaximizePanel, onHeaderDoubleClick: onMaximizePanel, toolbar: _jsxs(_Fragment, { children: [_jsx(IconMenuVertical, { id: "TMPanel-Draft-Commands-Header", color: 'white', cursor: 'pointer' }), _jsx(ContextMenu, { showEvent: 'click', dataSource: [
184
+ _jsx(TMPanel, { title: SDKUI_Localizator.Drafts, totalItems: dcmtsFound ?? 0, showHeader: showPanel, onClose: onClosePanel, allowMaximize: allowMaximize, onMaximize: onMaximizePanel, onHeaderDoubleClick: onMaximizePanel, toolbar: _jsxs(_Fragment, { children: [_jsx(IconMenuVertical, { id: "TMPanel-Draft-Commands-Header", color: 'white', cursor: 'pointer' }), _jsx(ContextMenu, { showEvent: 'click', dataSource: [
185
185
  {
186
186
  icon: isLeftPanelCollapsed ? "eyeclose" : "eyeopen",
187
187
  onClick: () => setIsLeftPanelCollapsed(prev => !prev),
@@ -51,7 +51,7 @@ const TMArchive = ({ inputTID, fileFromConnector = null }) => {
51
51
  const tmFormElement = useMemo(() => currentTID ?
52
52
  _jsx(TMDcmtForm, { TID: currentTID, DID: undefined, groupId: 'tmForm', layoutMode: LayoutModes.Ark, onClose: deviceType === DeviceType.MOBILE ? () => setCurrentTID(undefined) : undefined, onSaveRecents: (TIDs) => setMruTIDs(TIDs), showDcmtFormSidebar: false, fileFromConnector: fileFromConnector })
53
53
  :
54
- _jsx(TMPanel, { title: 'Archiviazione', children: _jsxs(TMLayoutContainer, { gap: 30, alignItems: 'center', justifyContent: 'center', children: [_jsxs(TMLayoutItem, { width: 'max-content', height: 'max-content', children: [" ", _jsxs(StyledToppyTextContainer, { children: [" ", _jsxs(StyledToppyText, { children: [" ", SDKUI_Localizator.DcmtTypeSelect, " "] }), " "] }), " "] }), _jsxs(TMLayoutItem, { width: 'max-content', height: 'max-content', children: [" ", _jsx("img", { src: Logo, width: 120, alt: '' }), " "] })] }) }), [currentTID, deviceType, mruTIDs, fileFromConnector]);
54
+ _jsx(TMPanel, { title: 'Archiviazione', allowMaximize: false, children: _jsxs(TMLayoutContainer, { gap: 30, alignItems: 'center', justifyContent: 'center', children: [_jsxs(TMLayoutItem, { width: 'max-content', height: 'max-content', children: [" ", _jsxs(StyledToppyTextContainer, { children: [" ", _jsxs(StyledToppyText, { children: [" ", SDKUI_Localizator.DcmtTypeSelect, " "] }), " "] }), " "] }), _jsxs(TMLayoutItem, { width: 'max-content', height: 'max-content', children: [" ", _jsx("img", { src: Logo, width: 120, alt: '' }), " "] })] }) }), [currentTID, deviceType, mruTIDs, fileFromConnector]);
55
55
  const allInitialPanelVisibility = {
56
56
  'tmTreeSelector': true,
57
57
  'tmRecentsManager': true,
@@ -116,8 +116,8 @@ const TMArchive = ({ inputTID, fileFromConnector = null }) => {
116
116
  };
117
117
  export default TMArchive;
118
118
  const TMTreeSelectorWrapper = ({ isMobile, onSelectedTIDChanged }) => {
119
- const { setPanelVisibilityById, toggleMaximize, setToolbarButtonVisibility } = useTMPanelManagerContext();
120
- return (_jsx(TMTreeSelector, { onClosePanel: () => setPanelVisibilityById('tmTreeSelector', false), onMaximizePanel: () => toggleMaximize('tmTreeSelector'), onSelectedTIDChanged: (tid) => {
119
+ const { setPanelVisibilityById, toggleMaximize, setToolbarButtonVisibility, countVisibleLeafPanels } = useTMPanelManagerContext();
120
+ return (_jsx(TMTreeSelector, { onClosePanel: !isMobile && countVisibleLeafPanels() > 1 ? () => setPanelVisibilityById('tmTreeSelector', false) : undefined, allowMaximize: !isMobile && countVisibleLeafPanels() > 1, onMaximizePanel: !isMobile && countVisibleLeafPanels() > 1 ? () => toggleMaximize("tmTreeSelector") : undefined, onSelectedTIDChanged: (tid) => {
121
121
  onSelectedTIDChanged?.(tid);
122
122
  if (isMobile)
123
123
  setPanelVisibilityById('tmForm', true);
@@ -633,8 +633,9 @@ export const ToppyHelpCenter = ({ content, onClick, deviceType, top = -200 }) =>
633
633
  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 })] }));
634
634
  };
635
635
  const TMDcmtPreviewWrapper = ({ currentDcmt, layoutMode, fromDTD, dcmtFile, deviceType, isVisible, onFileUpload }) => {
636
- const { setPanelVisibilityById, toggleMaximize, isResizingActive } = useTMPanelManagerContext();
636
+ const { setPanelVisibilityById, toggleMaximize, isResizingActive, countVisibleLeafPanels } = useTMPanelManagerContext();
637
+ const isMobile = deviceType === DeviceType.MOBILE;
637
638
  return (layoutMode === LayoutModes.Update ?
638
- _jsx(TMDcmtPreview, { isVisible: isVisible, onClosePanel: () => setPanelVisibilityById('tmDcmtPreview', false), onMaximizePanel: () => toggleMaximize('tmDcmtPreview'), dcmtData: currentDcmt, isResizingActive: isResizingActive }) :
639
- _jsx(TMFileUploader, { onFileUpload: onFileUpload, onClose: () => setPanelVisibilityById('tmDcmtPreview', false), isRequired: fromDTD?.archiveConstraint === ArchiveConstraints.ContentCompulsory && dcmtFile === null, defaultBlob: dcmtFile, deviceType: deviceType, isResizingActive: isResizingActive }));
639
+ _jsx(TMDcmtPreview, { isVisible: isVisible, onClosePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => setPanelVisibilityById('tmDcmtPreview', false) : undefined, allowMaximize: !isMobile && countVisibleLeafPanels() > 1, onMaximizePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => toggleMaximize("tmDcmtPreview") : undefined, dcmtData: currentDcmt, isResizingActive: isResizingActive }) :
640
+ _jsx(TMFileUploader, { onFileUpload: onFileUpload, onClose: (!isMobile && countVisibleLeafPanels() > 1) ? () => setPanelVisibilityById('tmDcmtPreview', false) : undefined, isRequired: fromDTD?.archiveConstraint === ArchiveConstraints.ContentCompulsory && dcmtFile === null, defaultBlob: dcmtFile, deviceType: deviceType, isResizingActive: isResizingActive }));
640
641
  };
@@ -9,6 +9,7 @@ interface ITMDcmtPreviewProps {
9
9
  onNext?: () => void;
10
10
  onPrev?: () => void;
11
11
  onClosePanel?: () => void;
12
+ allowMaximize?: boolean;
12
13
  onMaximizePanel?: () => void;
13
14
  }
14
15
  declare const TMDcmtPreview: React.FC<ITMDcmtPreviewProps>;
@@ -14,16 +14,13 @@ import { TMLayoutWaitingContainer } from '../../base/TMWaitPanel';
14
14
  import { TMSaveFormButtonPrevious, TMSaveFormButtonNext } from '../../forms/TMSaveForm';
15
15
  import { StyledAnimatedComponentOpacity } from '../../base/Styled';
16
16
  import TMPanel from '../../base/TMPanel';
17
- import { DeviceType, useDeviceType } from '../../base/TMDeviceProvider';
18
- const TMDcmtPreview = ({ dcmtData, isResizingActive, isVisible, canNext, canPrev, onClosePanel, onNext, onPrev, onMaximizePanel }) => {
17
+ const TMDcmtPreview = ({ dcmtData, isResizingActive, isVisible, canNext, canPrev, onClosePanel, onNext, onPrev, allowMaximize = true, onMaximizePanel }) => {
19
18
  const [dcmtBlob, setDcmtBlob] = useState(undefined);
20
19
  const [showPreview, setShowPreview] = useState(false);
21
20
  const [isFromCache, setIsFromCache] = useState(false);
22
21
  const [error, setError] = useState('');
23
22
  const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, getDcmtFileAsync, clearDcmtsFileCache, removeDcmtsFileCache, isDcmtFileInCache } = useDcmtOperations();
24
23
  const cacheKey = dcmtData ? `${dcmtData.tid}-${dcmtData.did}` : '00';
25
- const deviceType = useDeviceType();
26
- const isMobile = deviceType === DeviceType.MOBILE;
27
24
  const [hasLoadedDataOnce, setHasLoadedDataOnce] = useState(false);
28
25
  const [lastLoadedDid, setLastLoadedDid] = useState(undefined);
29
26
  useEffect(() => {
@@ -100,7 +97,7 @@ const TMDcmtPreview = ({ dcmtData, isResizingActive, isVisible, canNext, canPrev
100
97
  }
101
98
  return title;
102
99
  };
103
- return (_jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, showWaitPanelSecondary: showSecondary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, waitPanelTextSecondary: waitPanelTextSecondary, waitPanelValueSecondary: waitPanelValueSecondary, waitPanelMaxValueSecondary: waitPanelMaxValueSecondary, isCancelable: true, abortController: abortController, children: _jsx(TMPanel, { padding: '0', title: titleHandler(), onClose: isMobile ? undefined : onClosePanel, allowMaximize: !isMobile, onMaximize: isMobile ? undefined : onMaximizePanel, onHeaderDoubleClick: isMobile ? undefined : onMaximizePanel, toolbar: _jsxs("div", { style: { width: 'max-content', display: 'flex', alignItems: 'center', gap: '10px' }, children: [onPrev && _jsx(TMSaveFormButtonPrevious, { btnStyle: 'icon', isModified: false, formMode: FormModes.ReadOnly, canPrev: canPrev, onPrev: onPrev }), onNext && _jsx(TMSaveFormButtonNext, { btnStyle: 'icon', isModified: false, formMode: FormModes.ReadOnly, canNext: canNext, onNext: onNext }), _jsx(StyledHeaderIcon, { "$color": TMColors.primaryColor, children: _jsx(TMDropDownMenu, { backgroundColor: 'white', borderRadius: '3px', content: _jsx(TMButton, { btnStyle: 'icon', caption: 'Altro', icon: _jsx(IconMenuVertical, {}), showTooltip: false }), items: [
100
+ return (_jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, showWaitPanelSecondary: showSecondary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, waitPanelTextSecondary: waitPanelTextSecondary, waitPanelValueSecondary: waitPanelValueSecondary, waitPanelMaxValueSecondary: waitPanelMaxValueSecondary, isCancelable: true, abortController: abortController, children: _jsx(TMPanel, { padding: '0', title: titleHandler(), onClose: onClosePanel, allowMaximize: allowMaximize, onMaximize: onMaximizePanel, onHeaderDoubleClick: onMaximizePanel, toolbar: _jsxs("div", { style: { width: 'max-content', display: 'flex', alignItems: 'center', gap: '10px' }, children: [onPrev && _jsx(TMSaveFormButtonPrevious, { btnStyle: 'icon', isModified: false, formMode: FormModes.ReadOnly, canPrev: canPrev, onPrev: onPrev }), onNext && _jsx(TMSaveFormButtonNext, { btnStyle: 'icon', isModified: false, formMode: FormModes.ReadOnly, canNext: canNext, onNext: onNext }), _jsx(StyledHeaderIcon, { "$color": TMColors.primaryColor, children: _jsx(TMDropDownMenu, { backgroundColor: 'white', borderRadius: '3px', content: _jsx(TMButton, { btnStyle: 'icon', caption: 'Altro', icon: _jsx(IconMenuVertical, {}), showTooltip: false }), items: [
104
101
  { icon: _jsx(IconCloseCircle, {}), text: "Rimuovi elemento dalla cache", onClick: () => { removeDcmtsFileCache(cacheKey); setIsFromCache(false); } },
105
102
  { icon: _jsx(IconClear, {}), text: "Cancella la cache", onClick: () => { clearDcmtsFileCache(); setIsFromCache(false); } },
106
103
  ] }, "btn13") })] }), children: error
@@ -202,8 +202,8 @@ const TMSearch = ({ inputTID, inputSqdID, isExpertMode = SDKUI_Globals.userSetti
202
202
  };
203
203
  export default TMSearch;
204
204
  const TMTreeSelectorWrapper = ({ isMobile, onSelectedTIDChanged }) => {
205
- const { setPanelVisibilityById, toggleMaximize } = useTMPanelManagerContext();
206
- return (_jsx(TMTreeSelector, { onClosePanel: () => setPanelVisibilityById('TMTreeSelector', false), onMaximizePanel: () => toggleMaximize('TMTreeSelector'), onSelectedTIDChanged: (tid) => {
205
+ const { setPanelVisibilityById, toggleMaximize, countVisibleLeafPanels } = useTMPanelManagerContext();
206
+ return (_jsx(TMTreeSelector, { onClosePanel: !isMobile && countVisibleLeafPanels() > 1 ? () => setPanelVisibilityById('TMTreeSelector', false) : undefined, allowMaximize: !isMobile && countVisibleLeafPanels() > 1, onMaximizePanel: !isMobile && countVisibleLeafPanels() > 1 ? () => toggleMaximize("TMTreeSelector") : undefined, onSelectedTIDChanged: (tid) => {
207
207
  onSelectedTIDChanged?.(tid);
208
208
  isMobile && setPanelVisibilityById('TMSearchQueryPanel', true);
209
209
  } }));
@@ -218,8 +218,10 @@ const TMRecentsManagerWrapper = ({ mruTIDs, currentMruTID, deviceType, onSelecte
218
218
  } }));
219
219
  };
220
220
  const TMSearchQueryPanelWrapper = ({ fromDTD, SQD, isExpertMode, showBackToResultButton, onSearchCompleted, onSqdSaved, onBackToResult }) => {
221
- const { setPanelVisibilityById, toggleMaximize } = useTMPanelManagerContext();
222
- return (_jsx(TMSearchQueryPanel, { onClosePanel: () => setPanelVisibilityById('TMSearchQueryPanel', false), onMaximizePanel: () => toggleMaximize('TMSearchQueryPanel'), isExpertMode: isExpertMode, fromDTD: fromDTD, SQD: SQD, onSearchCompleted: onSearchCompleted, onSqdSaved: onSqdSaved, showBackToResultButton: showBackToResultButton, onBackToResult: onBackToResult }));
221
+ const { setPanelVisibilityById, toggleMaximize, countVisibleLeafPanels } = useTMPanelManagerContext();
222
+ const deviceType = useDeviceType();
223
+ const isMobile = deviceType === DeviceType.MOBILE;
224
+ return (_jsx(TMSearchQueryPanel, { onClosePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => setPanelVisibilityById('TMSearchQueryPanel', false) : undefined, allowMaximize: !isMobile && countVisibleLeafPanels() > 1, onMaximizePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => toggleMaximize("TMSearchQueryPanel") : undefined, isExpertMode: isExpertMode, fromDTD: fromDTD, SQD: SQD, onSearchCompleted: onSearchCompleted, onSqdSaved: onSqdSaved, showBackToResultButton: showBackToResultButton, onBackToResult: onBackToResult }));
223
225
  };
224
226
  const TMSavedQuerySelectorWrapper = ({ items, selectedId, allowShowSearch, manageDefault, onRefreshData, onItemClick, onDeleted }) => {
225
227
  const { setPanelVisibilityById } = useTMPanelManagerContext();
@@ -10,6 +10,7 @@ interface ITMSearchQueryPanelProps {
10
10
  onSqdSaved?: (newSqd: SavedQueryDescriptor) => void;
11
11
  onSearchCompleted?: (searchResult: SearchResultDescriptor[], qd: QueryDescriptor | undefined) => void;
12
12
  onClosePanel?: () => void;
13
+ allowMaximize?: boolean;
13
14
  onMaximizePanel?: () => void;
14
15
  }
15
16
  declare const TMSearchQueryPanel: React.FunctionComponent<ITMSearchQueryPanelProps>;
@@ -23,7 +23,7 @@ import TMQueryEditor from '../../query/TMQueryEditor';
23
23
  import TMSavedQueryForm from './TMSavedQueryForm';
24
24
  import { AdvancedMenuButtons } from '../../editors/TMMetadataValues';
25
25
  import TMShowAllOrMaxItemsButton from '../../base/TMShowAllOrMaxItemsButton';
26
- const TMSearchQueryPanel = ({ fromDTD, showBackToResultButton, isExpertMode = SDKUI_Globals.userSettings.advancedSettings.expertMode === 1, SQD, onSearchCompleted, onSqdSaved, onBack, onClosePanel, onMaximizePanel, onBackToResult }) => {
26
+ const TMSearchQueryPanel = ({ fromDTD, showBackToResultButton, isExpertMode = SDKUI_Globals.userSettings.advancedSettings.expertMode === 1, SQD, onSearchCompleted, onSqdSaved, onBack, onClosePanel, allowMaximize = true, onMaximizePanel, onBackToResult }) => {
27
27
  const [confirmQueryParams, ConfirmQueryParamsDialog] = useQueryParametersDialog();
28
28
  const [qd, setQd] = useState();
29
29
  const [shouldSearch, setShouldSearch] = useState(false);
@@ -229,7 +229,7 @@ const TMSearchQueryPanel = ({ fromDTD, showBackToResultButton, isExpertMode = SD
229
229
  }
230
230
  setQd({ ...qd, orderBy: newOrderBy });
231
231
  }, [qd, fromDTD?.metadata, SQD?.masterTID]);
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) ?
232
+ return (_jsxs(_Fragment, { children: [_jsxs(TMPanel, { title: fromDTD?.nameLoc ?? SDKUI_Localizator.Search_Metadata, allowMaximize: allowMaximize, onMaximize: onMaximizePanel, onHeaderDoubleClick: onMaximizePanel, onBack: onBack, onActiveChanged: handlePanelActiveChanged, toolbar: _jsx(_Fragment, { children: (SQD && !showSqdForm) ?
233
233
  _jsx(TMDropDownMenu, { backgroundColor: 'white', borderRadius: '3px', content: _jsx(TMButton, { btnStyle: 'icon', caption: 'Altro', icon: _jsx(IconMenuVertical, { color: 'white' }), showTooltip: false }), items: [
234
234
  ...(showBackToResultButton ? [{ icon: _jsx(IconArrowRight, {}), text: "Vai a risultato", onClick: () => { onBackToResult?.(); } }] : []),
235
235
  { icon: _jsx(IconAddCircleOutline, {}), beginGroup: true, text: SDKUI_Localizator.SavedQueryNew, onClick: () => { openSqdForm(FormModes.Create); } },
@@ -725,6 +725,8 @@ const TMSearchResultSelector = ({ searchResults = [], selectedTID, onSelectionCh
725
725
  };
726
726
  //#endregion TMSearchResultSelector
727
727
  const TMDcmtPreviewWrapper = ({ currentDcmt, isVisible }) => {
728
- const { setPanelVisibilityById, toggleMaximize, isResizingActive } = useTMPanelManagerContext();
729
- return (_jsx(TMDcmtPreview, { onClosePanel: () => setPanelVisibilityById('tmDcmtPreview', false), onMaximizePanel: () => toggleMaximize('tmDcmtPreview'), dcmtData: currentDcmt, isResizingActive: isResizingActive, isVisible: isVisible }));
728
+ const { setPanelVisibilityById, toggleMaximize, isResizingActive, countVisibleLeafPanels } = useTMPanelManagerContext();
729
+ const deviceType = useDeviceType();
730
+ const isMobile = deviceType === DeviceType.MOBILE;
731
+ return (_jsx(TMDcmtPreview, { onClosePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => setPanelVisibilityById('tmDcmtPreview', false) : undefined, allowMaximize: !isMobile && countVisibleLeafPanels() > 1, onMaximizePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => toggleMaximize("tmDcmtPreview") : undefined, dcmtData: currentDcmt, isResizingActive: isResizingActive, isVisible: isVisible }));
730
732
  };
@@ -5,6 +5,7 @@ interface ITMTreeSelectorProps {
5
5
  isVisible?: boolean;
6
6
  onSelectedTIDChanged?: (tid: number | undefined, treeId?: number | undefined) => void;
7
7
  onClosePanel?: () => void;
8
+ allowMaximize?: boolean;
8
9
  onMaximizePanel?: () => void;
9
10
  }
10
11
  declare const TMTreeSelector: React.FC<ITMTreeSelectorProps>;
@@ -11,10 +11,7 @@ import TMLayoutContainer, { TMLayoutItem } from '../../base/TMLayout';
11
11
  import TMPanel from '../../base/TMPanel';
12
12
  import TMTidViewer from '../../viewers/TMTidViewer';
13
13
  import { TMColors } from '../../../utils/theme';
14
- import { useDeviceType, DeviceType } from '../../base/TMDeviceProvider';
15
- const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelectedTIDChanged, onClosePanel, onMaximizePanel }) => {
16
- const deviceType = useDeviceType();
17
- const isMobile = deviceType === DeviceType.MOBILE;
14
+ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelectedTIDChanged, onClosePanel, allowMaximize = true, onMaximizePanel }) => {
18
15
  const [trees, setTrees] = useState([]);
19
16
  const [treeItems, setTreeItems] = useState([]);
20
17
  const [selectedTreeId, setSelectedTreeId] = useState(0);
@@ -94,7 +91,7 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
94
91
  }
95
92
  ;
96
93
  }, []);
97
- return (_jsx(TMPanel, { title: SDK_Localizator.Trees, isVisible: isVisible, totalItems: trees.length, onClose: isMobile ? undefined : onClosePanel, allowMaximize: !isMobile, onMaximize: isMobile ? undefined : onMaximizePanel, onHeaderDoubleClick: isMobile ? undefined : onMaximizePanel, toolbar: _jsx(TMButton, { btnStyle: 'icon', caption: defaultTreeId == selectedTreeId ? SDKUI_Localizator.TreeRemoveDefault : SDKUI_Localizator.SetAsDefault, icon: defaultTreeId == selectedTreeId ? _jsx(IconStarRemove, { color: 'rgb(243, 114, 92)' }) : _jsx(IconStar, { color: 'rgb(248, 215, 117)' }), onClick: () => {
94
+ return (_jsx(TMPanel, { title: SDK_Localizator.Trees, isVisible: isVisible, totalItems: trees.length, onClose: onClosePanel, allowMaximize: allowMaximize, onMaximize: onMaximizePanel, onHeaderDoubleClick: onMaximizePanel, toolbar: _jsx(TMButton, { btnStyle: 'icon', caption: defaultTreeId == selectedTreeId ? SDKUI_Localizator.TreeRemoveDefault : SDKUI_Localizator.SetAsDefault, icon: defaultTreeId == selectedTreeId ? _jsx(IconStarRemove, { color: 'rgb(243, 114, 92)' }) : _jsx(IconStar, { color: 'rgb(248, 215, 117)' }), onClick: () => {
98
95
  if (defaultTreeId == selectedTreeId) {
99
96
  SDKUI_Globals.userSettings.searchSettings.defaultTree = -1;
100
97
  setDefaultTreeId(-1);
@@ -21,6 +21,7 @@ interface TMPanelManagerContextType {
21
21
  setToolbarButtonDisabled: (id: string, isDisabled: boolean) => void;
22
22
  isResizingActive: boolean;
23
23
  updateIsResizingActive: (isActive: boolean) => void;
24
+ countVisibleLeafPanels: () => number;
24
25
  }
25
26
  interface TMPanelManagerProviderProps {
26
27
  children: ReactNode;
@@ -217,6 +217,13 @@ export const TMPanelManagerProvider = (props) => {
217
217
  const updateIsResizingActive = useCallback((isActive) => {
218
218
  setIsResizingActive(isActive);
219
219
  }, []);
220
+ // Counts how many panels are currently visible and are not parent panels
221
+ const countVisibleLeafPanels = useCallback(() => {
222
+ // Get panel IDs that are leaf nodes (i.e., have no children)
223
+ const leafPanelIds = Array.from(hierarchyMap.entries()).filter(([_, info]) => info.childrenIds.length === 0).map(([id]) => id);
224
+ // Count how many of those are currently visible
225
+ return leafPanelIds.filter(id => panelVisibility[id]).length;
226
+ }, [hierarchyMap, panelVisibility]);
220
227
  return (_jsx(TMPanelManagerContext.Provider, { value: {
221
228
  panelVisibility,
222
229
  panelDimensions,
@@ -232,6 +239,7 @@ export const TMPanelManagerProvider = (props) => {
232
239
  setToolbarButtonDisabled,
233
240
  isResizingActive,
234
241
  updateIsResizingActive,
242
+ countVisibleLeafPanels
235
243
  }, children: children }));
236
244
  };
237
245
  export const useTMPanelManagerContext = () => {
@@ -27,7 +27,7 @@ export const StyledToolbarButton = styled.button `
27
27
  const TMPanelManagerToolbar = (props) => {
28
28
  const { panels } = props;
29
29
  // Get panel visibility toggling function and visibility state from context
30
- const { togglePanelVisibility, panelVisibility, toolbarButtonsDisabled, toolbarButtonsVisibility } = useTMPanelManagerContext();
30
+ const { togglePanelVisibility, countVisibleLeafPanels, panelVisibility, toolbarButtonsDisabled, toolbarButtonsVisibility } = useTMPanelManagerContext();
31
31
  // Get the current device type (e.g., mobile, tablet, desktop) using a custom hook
32
32
  const deviceType = useDeviceType();
33
33
  // This avoids unnecessary re-renders by only recalculating when deviceType changes
@@ -41,6 +41,15 @@ const TMPanelManagerToolbar = (props) => {
41
41
  // Update state with the filtered and sorted leaf panels for the toolbar
42
42
  setVisibleLeafPanels(visibleLeafPanelsSorted);
43
43
  }, [toolbarButtonsVisibility]);
44
+ // Callback for toolbar button click, prevents hiding the last visible panel to ensure at least one panel is always visible
45
+ const onClickCallback = (panelId, isActive) => {
46
+ // If the panel is currently active and it's the only visible panel, do nothing
47
+ if (isActive && countVisibleLeafPanels() <= 1) {
48
+ return undefined; // Prevent hiding the last visible panel
49
+ }
50
+ // Otherwise, toggle the panel visibility normally
51
+ togglePanelVisibility(panelId);
52
+ };
44
53
  return (_jsx("div", { style: {
45
54
  display: 'flex',
46
55
  flexDirection: isMobile ? 'row' : 'column',
@@ -52,7 +61,7 @@ const TMPanelManagerToolbar = (props) => {
52
61
  }, children: visibleLeafPanels.filter(panel => toolbarButtonsVisibility[panel.id]).map(visibleLeafPanel => {
53
62
  const isActive = panelVisibility[visibleLeafPanel.id];
54
63
  const isDisabled = toolbarButtonsDisabled[visibleLeafPanel.id];
55
- return _jsx(TMTooltip, { content: visibleLeafPanel.name, position: isMobile ? 'top' : 'left', children: _jsx(StyledToolbarButton, { disabled: isDisabled, "$isDisabled": isDisabled, onClick: () => togglePanelVisibility(visibleLeafPanel.id), "$isActive": isActive || visibleLeafPanel.toolbarOptions?.alwaysActiveColor, children: typeof visibleLeafPanel.toolbarOptions?.icon === 'string' ? (_jsx("i", { className: `dx-icon dx-icon-${visibleLeafPanel.toolbarOptions?.icon}` })) : (visibleLeafPanel.toolbarOptions?.icon) }, visibleLeafPanel.id) }, visibleLeafPanel.id);
64
+ return _jsx(TMTooltip, { content: visibleLeafPanel.name, position: isMobile ? 'top' : 'left', children: _jsx(StyledToolbarButton, { disabled: isDisabled, "$isDisabled": isDisabled, onClick: () => onClickCallback(visibleLeafPanel.id, isActive), "$isActive": isActive || visibleLeafPanel.toolbarOptions?.alwaysActiveColor, children: typeof visibleLeafPanel.toolbarOptions?.icon === 'string' ? (_jsx("i", { className: `dx-icon dx-icon-${visibleLeafPanel.toolbarOptions?.icon}` })) : (visibleLeafPanel.toolbarOptions?.icon) }, visibleLeafPanel.id) }, visibleLeafPanel.id);
56
65
  }) }));
57
66
  };
58
67
  export default TMPanelManagerToolbar;
@@ -5,7 +5,7 @@ import { useDeviceType, DeviceType } from '../../base/TMDeviceProvider';
5
5
  import TMPanel from '../../base/TMPanel';
6
6
  const TMPanelWrapper = (props) => {
7
7
  const { panel, children } = props;
8
- const { panelVisibility, panelDimensions, togglePanelVisibility, maximizedPanels, toggleMaximize } = useTMPanelManagerContext();
8
+ const { panelVisibility, panelDimensions, togglePanelVisibility, maximizedPanels, toggleMaximize, countVisibleLeafPanels } = useTMPanelManagerContext();
9
9
  // Default to true if isMaximizable or isClosable is undefined, ensuring safe and expected behavior
10
10
  const isMaximizable = panel.contentOptions?.isMaximizable ?? true;
11
11
  const isClosable = panel.contentOptions?.isClosable ?? true;
@@ -51,7 +51,7 @@ const TMPanelWrapper = (props) => {
51
51
  childWithProps = React.cloneElement(children, { isVisible: isCurrentlyVisible });
52
52
  }
53
53
  return (_jsx("div", { "data-panel-id": panel.id, style: panelStyles, children: panel.contentOptions?.panelContainer ?
54
- _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: [childWithProps, " "] })
54
+ _jsxs(TMPanel, { ...panel.contentOptions.panelContainer, allowMaximize: !isMobile && countVisibleLeafPanels() > 1, onHeaderDoubleClick: isMaximizable && countVisibleLeafPanels() > 1 ? () => toggleMaximize(panel.id) : undefined, onMaximize: isMaximizable && countVisibleLeafPanels() > 1 ? () => toggleMaximize(panel.id) : undefined, onClose: isClosable && countVisibleLeafPanels() > 1 ? () => togglePanelVisibility(panel.id) : undefined, children: [childWithProps, " "] })
55
55
  :
56
56
  childWithProps // Usa i children clonati
57
57
  }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react-beta",
3
- "version": "6.14.40",
3
+ "version": "6.14.42",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",
@@ -42,7 +42,7 @@
42
42
  "lib"
43
43
  ],
44
44
  "dependencies": {
45
- "@topconsultnpm/sdk-ts-beta": "6.14.7",
45
+ "@topconsultnpm/sdk-ts-beta": "6.14.8",
46
46
  "buffer": "^6.0.3",
47
47
  "devextreme": "24.2.6",
48
48
  "devextreme-react": "24.2.6",