@topconsultnpm/sdkui-react-beta 6.13.39 → 6.13.41

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.
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useLayoutEffect, useRef, useState } from 'react';
2
+ import { useEffect, 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';
@@ -68,7 +68,6 @@ const StyledPanelContent = styled.div `
68
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 }) => {
69
69
  const [isActive, setIsActive] = useState(false);
70
70
  const [isMaximized, setIsMaximized] = useState(false);
71
- const [minWidth, setMinWidth] = useState(undefined);
72
71
  const titleRowRef = useRef(null);
73
72
  // If keepActiveState is true, always force isActive to true
74
73
  useEffect(() => {
@@ -83,11 +82,6 @@ const TMPanel = ({ allowMaximize = true, color, backgroundColor, backgroundColor
83
82
  if (!keepActiveState)
84
83
  setIsActive(false);
85
84
  };
86
- useLayoutEffect(() => {
87
- if (titleRowRef.current) {
88
- setMinWidth(titleRowRef.current.offsetWidth);
89
- }
90
- }, [title, displayedItemsCount, totalItems, onBack]);
91
85
  // handler for external maximize management
92
86
  const handleMaximize = () => {
93
87
  setIsMaximized(prevState => {
@@ -99,7 +93,6 @@ const TMPanel = ({ allowMaximize = true, color, backgroundColor, backgroundColor
99
93
  });
100
94
  };
101
95
  return (_jsxs(StyledPanelContainer, { "$isMaximized": onMaximize ? false : isMaximized, style: {
102
- ...(minWidth ? { minWidth } : {}),
103
96
  visibility: isVisible ? 'visible' : 'hidden',
104
97
  }, children: [showHeader &&
105
98
  _jsx(StyledPanelHeader, { "$backgroundColor": backgroundColor, "$color": color, "$isActive": isActive, onDoubleClick: () => {
@@ -107,8 +100,26 @@ const TMPanel = ({ allowMaximize = true, color, backgroundColor, backgroundColor
107
100
  onHeaderDoubleClick();
108
101
  else
109
102
  allowMaximize && handleMaximize();
110
- }, tabIndex: -1, onFocus: handleFocus, onBlur: handleBlur, onClick: handleFocus, children: _jsxs("div", { style: { display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', width: '100%' }, children: [_jsxs("div", { ref: titleRowRef, style: { display: 'flex', flexDirection: 'row', alignItems: 'center', gap: '8px' }, children: [onBack &&
111
- _jsx(TMButton, { btnStyle: 'icon', icon: _jsx(IconArrowLeft, {}), caption: SDKUI_Localizator.Back, onClick: onBack }), _jsx("div", { style: { display: 'flex', flexDirection: 'row', alignItems: 'center' }, children: _jsxs("p", { style: {
103
+ }, tabIndex: -1, onFocus: handleFocus, onBlur: handleBlur, onClick: handleFocus, children: _jsxs("div", { style: {
104
+ display: 'flex',
105
+ flexDirection: 'row',
106
+ alignItems: 'center',
107
+ width: '100%',
108
+ minWidth: 0
109
+ }, children: [_jsxs("div", { ref: titleRowRef, style: {
110
+ display: 'flex',
111
+ flexDirection: 'row',
112
+ alignItems: 'center',
113
+ gap: '8px',
114
+ flex: 1,
115
+ minWidth: 0
116
+ }, children: [onBack &&
117
+ _jsx(TMButton, { btnStyle: 'icon', icon: _jsx(IconArrowLeft, {}), caption: SDKUI_Localizator.Back, onClick: onBack }), _jsx("div", { style: {
118
+ display: 'flex',
119
+ flexDirection: 'row',
120
+ alignItems: 'center',
121
+ overflow: 'hidden',
122
+ }, children: _jsxs("p", { style: {
112
123
  whiteSpace: 'nowrap',
113
124
  overflow: 'hidden',
114
125
  textOverflow: 'ellipsis',
@@ -117,7 +128,14 @@ const TMPanel = ({ allowMaximize = true, color, backgroundColor, backgroundColor
117
128
  ? ` (${displayedItemsCount} / ${totalItems})`
118
129
  : isPositiveNumber(totalItems)
119
130
  ? ` (${totalItems})`
120
- : ''] }) })] }), _jsxs("div", { style: { display: 'flex', flexDirection: 'row', alignItems: 'center', gap: '5px' }, children: [toolbar, allowMaximize && _jsx(TMButton, { color: 'primaryOutline', caption: isMaximized ? SDKUI_Localizator.Minimize : SDKUI_Localizator.Maximize, icon: isMaximized
131
+ : ''] }) })] }), _jsxs("div", { style: {
132
+ display: 'flex',
133
+ flexDirection: 'row',
134
+ alignItems: 'center',
135
+ gap: '5px',
136
+ flexShrink: 0,
137
+ marginLeft: 10
138
+ }, children: [toolbar, allowMaximize && _jsx(TMButton, { color: 'primaryOutline', caption: isMaximized ? SDKUI_Localizator.Minimize : SDKUI_Localizator.Maximize, icon: isMaximized
121
139
  ? _jsx(IconWindowMinimize, { fontSize: 16 })
122
140
  : _jsx(IconWindowMaximize, { fontSize: 16 }), btnStyle: 'icon', onClick: handleMaximize }), onClose && _jsx(TMButton, { color: 'primaryOutline', caption: SDKUI_Localizator.Close, icon: _jsx(IconClearButton, {}), btnStyle: 'icon', onClick: () => { setIsMaximized(false); onClose?.(); } })] })] }) }), _jsx(StyledPanelContent, { "$height": showHeader ? "calc(100% - 40px)" : "100%", "$padding": padding, "$backgroundColor": backgroundColorContainer ?? `#FFFFFF`, tabIndex: -1, onFocus: handleFocus, onBlur: handleBlur, onClick: handleFocus, children: children })] }));
123
141
  };
@@ -5,6 +5,7 @@ type TMPanelManagerProps = {
5
5
  showToolbar?: boolean;
6
6
  toolbarMode?: number;
7
7
  gutters?: number;
8
+ minPanelPercent?: number;
8
9
  };
9
10
  declare const TMPanelManager: (props: TMPanelManagerProps) => import("react/jsx-runtime").JSX.Element;
10
11
  export default TMPanelManager;
@@ -1,12 +1,12 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useMemo, useRef, useState } from 'react';
2
+ import { useEffect, useMemo, useState } from 'react';
3
3
  import { flattenPanels, isAtLeastOnePanelVisible, isPanelArray } from './TMPanelManagerUtils';
4
4
  import { SDKUI_Globals, IconInfo, SDKUI_Localizator } from '../../helper';
5
5
  import { useDeviceType, DeviceType } from './TMDeviceProvider';
6
6
  import TMPanel from './TMPanel';
7
7
  import TMPanelManagerToolbar from './TMPanelManagerToolbar';
8
8
  const TMPanelManager = (props) => {
9
- const { panels, initialMobilePanelId, showToolbar = true, toolbarMode = 0, gutters = SDKUI_Globals.userSettings.themeSettings.gutters } = props;
9
+ const { panels, initialMobilePanelId, showToolbar = true, toolbarMode = 0, gutters = SDKUI_Globals.userSettings.themeSettings.gutters, minPanelPercent = 5 } = props;
10
10
  const deviceType = useDeviceType();
11
11
  let isMobile = useMemo(() => { return deviceType === DeviceType.MOBILE; }, [deviceType]);
12
12
  const allPanels = useMemo(() => flattenPanels(panels), [panels]);
@@ -15,9 +15,8 @@ const TMPanelManager = (props) => {
15
15
  allPanels.forEach(p => map.set(p.fullId, p));
16
16
  return map;
17
17
  }, [allPanels]);
18
- const panelRefs = useRef({});
19
18
  // Active buttons state & panel map
20
- const [activeButtons, setActiveButtons] = useState(() => Object.fromEntries(allPanels.map(p => [p.fullId, p.config.toolbarOptions?.isActive ?? false])));
19
+ const [activeButtons, setActiveButtons] = useState({});
21
20
  const [originalSizes, setOriginalSizes] = useState(new Map());
22
21
  const [panelsState, setPanelsState] = useState(new Map());
23
22
  const [maximizedPanelPath, setMaximizedPanelPath] = useState([]);
@@ -61,6 +60,12 @@ const TMPanelManager = (props) => {
61
60
  setOriginalSizes(newOriginalSizes);
62
61
  setPanelsState(newState);
63
62
  }, [panels]);
63
+ useEffect(() => {
64
+ if (allPanels.length > 0) {
65
+ const initialButtons = Object.fromEntries(allPanels.map(p => [p.fullId, p.config.toolbarOptions?.isActive ?? false]));
66
+ setActiveButtons(initialButtons);
67
+ }
68
+ }, [allPanels]);
64
69
  useEffect(() => {
65
70
  // If there are no original sizes available, exit early
66
71
  if (!originalSizes.size)
@@ -143,12 +148,12 @@ const TMPanelManager = (props) => {
143
148
  let newCurrent = Math.min(currentSize + deltaPercent, 100);
144
149
  let newNext = Math.min(nextSize - deltaPercent, 100);
145
150
  // Enforce minimum panel size
146
- if (newCurrent < 5) {
147
- newCurrent = 5;
151
+ if (newCurrent < minPanelPercent) {
152
+ newCurrent = minPanelPercent;
148
153
  newNext = total - newCurrent;
149
154
  }
150
- else if (newNext < 5) {
151
- newNext = 5;
155
+ else if (newNext < minPanelPercent) {
156
+ newNext = minPanelPercent;
152
157
  newCurrent = total - newNext;
153
158
  }
154
159
  // Safely get current and next panel data
@@ -219,7 +224,7 @@ const TMPanelManager = (props) => {
219
224
  return newActive;
220
225
  });
221
226
  }
222
- }, [isMobile]);
227
+ }, [isMobile, panelMap]);
223
228
  // Handler for starting to drag a column divider (for resizing panels horizontally)
224
229
  const onColumnMouseDown = (panelKey) => {
225
230
  setIsColumnDragging(panelKey); // Set the state to indicate which column is being dragged
@@ -404,11 +409,9 @@ const TMPanelManager = (props) => {
404
409
  flexGrow: 1,
405
410
  overflow: 'auto',
406
411
  };
407
- return (_jsxs("div", { ref: el => {
408
- panelRefs.current[fullId] = el;
409
- }, style: panelStyle, children: [_jsx("div", { style: contentStyle, children: hasChildren
412
+ return (_jsxs("div", { style: panelStyle, children: [_jsx("div", { style: contentStyle, children: hasChildren
410
413
  ? renderPanels(panel.contentOptions.content, fullId, 'vertical')
411
- : panel.contentOptions?.panelContainer ? _jsx(TMPanel, { title: panel.contentOptions.panelContainer.title, totalItems: panel.contentOptions.panelContainer.totalItems, displayedItemsCount: panel.contentOptions.panelContainer.displayedItemsCount, onClose: () => handleTogglePanel(fullId), onMaximize: () => handleToggleMaximize(fullId), onHeaderDoubleClick: () => handleToggleMaximize(fullId), allowMaximize: !isMobile, children: typeof panel.contentOptions.content === "function" ? panel.contentOptions.content(handleTogglePanel, handleToggleMaximize, handleVisibilityButton, handleDisableButton) : panel.contentOptions.content })
414
+ : panel.contentOptions?.panelContainer ? _jsx(TMPanel, { title: panel.contentOptions.panelContainer.title, totalItems: panel.contentOptions.panelContainer.totalItems, displayedItemsCount: panel.contentOptions.panelContainer.displayedItemsCount, onBack: panel.contentOptions.panelContainer.onBack, onClose: () => handleTogglePanel(fullId), onMaximize: () => handleToggleMaximize(fullId), onHeaderDoubleClick: () => handleToggleMaximize(fullId), allowMaximize: !isMobile, toolbar: panel.contentOptions.panelContainer.toolbar, children: typeof panel.contentOptions.content === "function" ? panel.contentOptions.content(handleTogglePanel, handleToggleMaximize, handleVisibilityButton, handleDisableButton) : panel.contentOptions.content })
412
415
  :
413
416
  typeof panel.contentOptions.content === "function" ? panel.contentOptions.content(handleTogglePanel, handleToggleMaximize, handleVisibilityButton, handleDisableButton) : panel.contentOptions.content }), !isLastVisible && isActive && maximizedPanelPath.length === 0 && (_jsx("div", { style: {
414
417
  cursor: direction === 'horizontal' ? 'col-resize' : 'row-resize',
@@ -431,16 +434,16 @@ const TMPanelManager = (props) => {
431
434
  } }))] }, fullId));
432
435
  });
433
436
  };
434
- return (_jsxs("div", { style: { display: 'flex', flexDirection: isMobile ? 'column' : 'row', height: '100%', width: '100%', gap: gutters }, children: [_jsx("div", { style: {
437
+ return (_jsxs("div", { style: { display: 'flex', flexDirection: isMobile ? 'column' : 'row', height: '100%', width: '100%', gap: !isMobile ? gutters : 0 }, children: [_jsx("div", { style: {
435
438
  display: 'flex',
436
439
  flexGrow: 1,
437
- width: isAtLeastOnePanelVisible(activeButtons) ? `calc(100% - ${showToolbar ? (isMobile ? 0 : 60) : 0}px)` : '0%',
438
- height: isAtLeastOnePanelVisible(activeButtons) ? `calc(100% - ${isMobile ? 60 : 0}px)` : '0%',
440
+ width: isAtLeastOnePanelVisible(activeButtons) ? `calc(100% - ${showToolbar ? (isMobile ? 0 : 70) : 0}px)` : '0%',
441
+ height: isAtLeastOnePanelVisible(activeButtons) ? `calc(100% - ${isMobile ? 55 : 0}px)` : '0%',
439
442
  visibility: isAtLeastOnePanelVisible(activeButtons) ? 'visible' : 'hidden',
440
443
  flexDirection: 'row',
441
444
  }, children: renderPanels(panels, '', 'horizontal') }), !isAtLeastOnePanelVisible(activeButtons) && (_jsxs("div", { style: {
442
- width: '100%',
443
- height: isMobile ? 'calc(100% - 60px)' : '100%',
445
+ width: `calc(100% - ${showToolbar ? (isMobile ? 0 : 70) : 0}px)`,
446
+ height: `calc(100% - ${isMobile ? 55 : 0}px)`,
444
447
  display: 'flex',
445
448
  flexDirection: 'column',
446
449
  alignItems: 'center',
@@ -451,14 +454,14 @@ const TMPanelManager = (props) => {
451
454
  color: '#555',
452
455
  fontSize: '18px',
453
456
  }, children: [_jsx(IconInfo, { style: { fontSize: 50 } }), _jsx("div", { children: SDKUI_Localizator.NoPanelSelected })] })), showToolbar && _jsx("div", { style: toolbarMode === 0 ? {
454
- width: isMobile ? '100%' : '60px',
455
- height: isMobile ? '60px' : '100%',
457
+ width: isMobile ? '100%' : '50px',
458
+ height: isMobile ? '50px' : '100%',
456
459
  borderLeft: '1px solid #ccc',
457
460
  display: 'flex',
458
461
  flexDirection: isMobile ? 'row' : 'column',
459
- padding: '8px',
462
+ padding: '10px',
460
463
  boxSizing: 'border-box',
461
- gap: '6px',
464
+ gap: '10px',
462
465
  backgroundColor: '#f9f9f9',
463
466
  } : {
464
467
  display: 'flex',
@@ -5,6 +5,8 @@ import { SDK_Globals } from '@topconsultnpm/sdk-ts-beta';
5
5
  import { TMExceptionBoxManager } from '../../base/TMPopUp';
6
6
  import TMSpinner from '../../base/TMSpinner';
7
7
  import TMBlogs from '../../grids/TMBlogs';
8
+ import { TMNothingToShow } from './TMDcmtPreview';
9
+ import { IconBoard } from '../../../helper';
8
10
  const TMDcmtBlog = ({ tid, did }) => {
9
11
  const [blogsDatasource, setBlogsDatasource] = useState([]);
10
12
  useEffect(() => {
@@ -26,7 +28,8 @@ const TMDcmtBlog = ({ tid, did }) => {
26
28
  TMSpinner.hide();
27
29
  }
28
30
  };
29
- return (_jsx(StyledContainer, { children: _jsx(StyledSectionContainer, { style: { position: 'relative' }, children: _jsx(StyledBoardContainer, { children: _jsx(TMBlogs, { id: "dcmt-blog", allData: blogsDatasource, showExtendedAttachments: false }) }) }) }));
31
+ 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
+ _jsx(TMBlogs, { id: "dcmt-blog", allData: blogsDatasource, showExtendedAttachments: false }) }) }) }));
30
33
  };
31
34
  export default TMDcmtBlog;
32
35
  const StyledContainer = styled.div ` user-select: none; overflow: hidden; background-color: #ffffff; width: calc(100%); height: calc(100%); display: flex; gap: 10px; `;
@@ -1,11 +1,11 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useCallback, useEffect, useState } from 'react';
2
+ import { useCallback, useEffect, useMemo, useState } from 'react';
3
3
  import { DataColumnTypes, DcmtTypeListCacheService, MetadataDataDomains, MetadataFormats, RelationCacheService, RelationTypes, ResultTypes, SDK_Globals, SystemMIDs } from '@topconsultnpm/sdk-ts-beta';
4
4
  import { ContextMenu } from 'devextreme-react';
5
5
  import { TMNothingToShow } from './TMDcmtPreview';
6
6
  import TMDcmtForm from './TMDcmtForm';
7
7
  import TMSearchResult from '../search/TMSearchResult';
8
- import { genUniqueId, getExceptionMessage, IconFolder, IconShow, IconPreview, IconBoard, IconDcmtTypeSys, IconCheckFile, IconDetailDcmts, SDKUI_Localizator, svgToString, IconMail, IconDcmtTypeOnlyMetadata, IconCopy, IconMultipleSelection, IconMenuVertical, SDKUI_Globals } from '../../../helper';
8
+ import { genUniqueId, getExceptionMessage, IconFolder, IconShow, IconBoard, IconDcmtTypeSys, IconCheckFile, IconDetailDcmts, SDKUI_Localizator, svgToString, IconMail, IconDcmtTypeOnlyMetadata, IconCopy, IconMultipleSelection, IconMenuVertical, IconSearchCheck, IconDataList } from '../../../helper';
9
9
  import { hasDetailRelations } from '../../../helper/dcmtsHelper';
10
10
  import { FormModes, SearchResultContext } from '../../../ts';
11
11
  import { TMColors } from '../../../utils/theme';
@@ -13,7 +13,6 @@ import { StyledDivHorizontal, StyledBadge } from '../../base/Styled';
13
13
  import ShowAlert from '../../base/TMAlert';
14
14
  import TMButton from '../../base/TMButton';
15
15
  import { DeviceType } from '../../base/TMDeviceProvider';
16
- import { TMSplitterLayout, TMLayoutItem } from '../../base/TMLayout';
17
16
  import { TMExceptionBoxManager } from '../../base/TMPopUp';
18
17
  import TMSpinner from '../../base/TMSpinner';
19
18
  import { TMLayoutWaitingContainer } from '../../base/TMWaitPanel';
@@ -24,8 +23,7 @@ import TMDataListItemViewer from '../../viewers/TMDataListItemViewer';
24
23
  import { TMDcmtTypeTooltip } from '../../viewers/TMTidViewer';
25
24
  import TMTreeView from '../../base/TMTreeView';
26
25
  import TMDcmtIcon from './TMDcmtIcon';
27
- import TMPanel from '../../base/TMPanel';
28
- import TMCommandsPanel from '../../sidebar/TMCommandsPanel';
26
+ import TMPanelManager from '../../base/TMPanelManager';
29
27
  let abortController = new AbortController();
30
28
  const TMMasterDetailDcmts = ({ deviceType, inputDcmts, isForMaster, showCurrentDcmtIndicator = true, allowNavigation, canNext, canPrev, onNext, onPrev, onBack, appendMasterDcmts, onTaskCreateRequest }) => {
31
29
  const [id, setID] = useState('');
@@ -380,28 +378,137 @@ const TMMasterDetailDcmts = ({ deviceType, inputDcmts, isForMaster, showCurrentD
380
378
  const toolbar = _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '10px' }, children: [allowMultipleSelection && _jsx("p", { style: { color: TMColors.colorHeader, textAlign: 'center', padding: '1px 4px', borderRadius: '3px', display: 'flex' }, children: `${selectedItems.length} selezionati` }), _jsx(TMButton, { btnStyle: 'icon', caption: 'Selezione multipla', icon: _jsx(IconMultipleSelection, { fontSize: 16, color: allowMultipleSelection ? TMColors.tertiary : 'white' }), onClick: () => setAllowMultipleSelection(!allowMultipleSelection) }), allowNavigation && canPrev != undefined && _jsx(TMSaveFormButtonPrevious, { btnStyle: 'icon', iconColor: 'white', isModified: false, formMode: FormModes.ReadOnly, canPrev: canPrev, onPrev: onPrev }), allowNavigation && canNext != undefined && _jsx(TMSaveFormButtonNext, { btnStyle: 'icon', iconColor: 'white', isModified: false, formMode: FormModes.ReadOnly, canNext: canNext, onNext: onNext }), _jsx(IconMenuVertical, { id: `commands-detail-${id}`, color: 'white', cursor: 'pointer' }), _jsx(ContextMenu, { showEvent: 'click', dataSource: commandsMenuItems, target: `#commands-detail-${id}` })] });
381
379
  const getTitle = () => isForMaster ? `${SDKUI_Localizator.DcmtsMaster} - ${dtdMaster?.nameLoc}` : SDKUI_Localizator.DcmtsDetail;
382
380
  const isMobile = deviceType === DeviceType.MOBILE;
383
- return (_jsxs("div", { style: {
384
- display: 'flex',
385
- flexDirection: isMobile ? 'column' : 'row',
386
- justifyContent: 'space-between',
387
- gap: SDKUI_Globals.userSettings.themeSettings.gutters,
388
- width: '100%',
389
- height: '100%',
390
- }, children: [_jsx("div", { style: { flex: 1, minWidth: 0, height: '100%' }, children: _jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, isCancelable: true, abortController: abortController, children: _jsxs(TMSplitterLayout, { direction: 'horizontal', overflow: 'visible', separatorSize: SDKUI_Globals.userSettings.themeSettings.gutters, separatorColor: 'transparent', showSeparator: focusedItem != undefined, separatorActiveColor: 'transparent', min: ['0', '0'], start: focusedItem && (showDcmtForm || showPreview || showBoard || showSysMetadata) ? deviceType != DeviceType.MOBILE ? ["40%", "60%"] : ["0%", "100%"] : ["100%", "0%"], children: [_jsx(TMPanel, { title: getTitle(), toolbar: toolbar, onBack: onBack, children: isLoading ? _jsx(_Fragment, {}) :
391
- data.length <= 0
392
- ?
393
- _jsx(TMNothingToShow, { text: getTitle(), secondText: SDKUI_Localizator.NoDataToDisplay, icon: isForMaster ? _jsx(IconDetailDcmts, { fontSize: 96, transform: 'scale(-1, 1)' }) : _jsx(IconDetailDcmts, { fontSize: 96 }) })
394
- :
395
- _jsx(TMTreeView, { dataSource: data, allowMultipleSelection: allowMultipleSelection, calculateItemsForNode: calculateItemsForNode, itemRender: renderItem, focusedItem: focusedItem, selectedItems: selectedItems, onFocusedItemChanged: handleFocusedItemChanged, onSelectionChanged: handleSelectedItemsChanged, onDataChanged: (items) => setData(updateHiddenProperty(items)) }) }), _jsx(TMLayoutItem, { children: focusedItem?.isDcmt ?
396
- _jsx(TMDcmtForm, { TID: focusedItem?.tid, DID: focusedItem.did, isClosable: deviceType !== DeviceType.MOBILE, allowNavigation: false, allowRelations: deviceType !== DeviceType.MOBILE, showDcmtFormSidebar: deviceType === DeviceType.MOBILE, showPreview: showPreview, showBoard: showBoard, showSysMetadata: showSysMetadata, showDcmtForm: showDcmtForm, onClose: () => { setShowDcmtForm(false); }, onClosePreviewPanel: () => { setShowPreview(false); } }) :
397
- _jsx(TMSearchResult, { context: SearchResultContext.METADATA_SEARCH, searchResults: focusedItem?.searchResult ?? [], showSearchResultSidebar: false, onClose: () => { setShowDcmtForm(false); }, onClosePreviewPanel: () => { setShowPreview(false); }, onTaskCreateRequest: onTaskCreateRequest }) })] }, "TMDetails-panel") }) }), _jsx(TMCommandsPanel, { isMobile: isMobile, items: [
398
- { icon: _jsx(IconShow, {}), selected: showPreview, onClick: () => { setShowPreview(!showPreview); } },
399
- { icon: _jsx(IconPreview, {}), selected: showDcmtForm, onClick: () => { setShowDcmtForm(!showDcmtForm); } },
400
- { icon: _jsx(IconBoard, {}), selected: showBoard, onClick: () => { setShowSysMetadata(false); setShowBoard(!showBoard); } },
401
- { icon: _jsx(IconDcmtTypeSys, {}), selected: showSysMetadata, onClick: () => { setShowBoard(false); setShowSysMetadata(!showSysMetadata); } },
402
- { icon: _jsx(IconCheckFile, {}), selected: showZeroDcmts, onClick: () => { setShowZeroDcmts(!showZeroDcmts); } },
403
- { icon: _jsx(IconDetailDcmts, { transform: 'scale(-1, 1)' }), disabled: !focusedItem?.isDcmt, onClick: () => { appendMasterDcmts?.(focusedItem?.tid, focusedItem?.did); } }
404
- ] })] }));
381
+ const renderTMTreeView = (handleTogglePanel) => _jsx(_Fragment, { children: isLoading ? _jsx(_Fragment, {}) :
382
+ data.length <= 0
383
+ ?
384
+ _jsx(TMNothingToShow, { text: getTitle(), secondText: SDKUI_Localizator.NoDataToDisplay, icon: isForMaster ? _jsx(IconDetailDcmts, { fontSize: 96, transform: 'scale(-1, 1)' }) : _jsx(IconDetailDcmts, { fontSize: 96 }) })
385
+ :
386
+ _jsx(TMTreeView, { dataSource: data, allowMultipleSelection: allowMultipleSelection, calculateItemsForNode: calculateItemsForNode, itemRender: renderItem, focusedItem: focusedItem, selectedItems: selectedItems, onFocusedItemChanged: handleFocusedItemChanged, onSelectionChanged: handleSelectedItemsChanged, onDataChanged: (items) => setData(updateHiddenProperty(items)) }) });
387
+ const renderTMFormOrResult = useMemo(() => (handleTogglePanel) => {
388
+ return (_jsx(_Fragment, { children: focusedItem?.isDcmt ?
389
+ _jsx(TMDcmtForm, { TID: focusedItem?.tid, DID: focusedItem.did, isClosable: deviceType !== DeviceType.MOBILE, allowNavigation: false, allowRelations: deviceType !== DeviceType.MOBILE, showDcmtFormSidebar: deviceType === DeviceType.MOBILE, showPreview: showPreview, showBoard: showBoard, showSysMetadata: showSysMetadata, showDcmtForm: showDcmtForm, onClose: () => { setShowDcmtForm(false); }, onClosePreviewPanel: () => { setShowPreview(false); } }) :
390
+ _jsx(TMSearchResult, { context: SearchResultContext.METADATA_SEARCH, allowFloatingBar: false, searchResults: focusedItem?.searchResult ?? [], showPreview: showPreview, showSearchResultSidebar: false, onClose: () => { setShowDcmtForm(false); }, onClosePreviewPanel: () => {
391
+ setShowPreview(false);
392
+ handleTogglePanel("commandPreview");
393
+ }, onTaskCreateRequest: onTaskCreateRequest }) }));
394
+ }, [focusedItem, showPreview, showBoard, showSysMetadata, showDcmtForm, deviceType]);
395
+ const panelsConfig = [
396
+ {
397
+ id: 'TMTreeView',
398
+ name: getTitle(),
399
+ toolbarOptions: { icon: _jsx(IconDataList, { fontSize: 24 }), visible: true, isActive: true, orderNumber: 1 },
400
+ type: 'content',
401
+ contentOptions: {
402
+ visible: true,
403
+ height: '100%',
404
+ width: '20%',
405
+ content: renderTMTreeView,
406
+ panelContainer: {
407
+ title: getTitle(),
408
+ allowMaximize: !isMobile,
409
+ onBack: onBack,
410
+ toolbar: toolbar
411
+ },
412
+ },
413
+ },
414
+ {
415
+ id: 'TMFormOrResult',
416
+ name: focusedItem?.isDcmt ? "Form del documento" : SDKUI_Localizator.SearchResult,
417
+ toolbarOptions: { icon: _jsx(IconSearchCheck, { fontSize: 24 }), visible: true, isActive: true, orderNumber: 2 },
418
+ type: 'content',
419
+ contentOptions: {
420
+ visible: true,
421
+ height: '100%',
422
+ width: '20%',
423
+ content: renderTMFormOrResult,
424
+ },
425
+ },
426
+ {
427
+ id: 'commandPreview',
428
+ name: SDKUI_Localizator.PreviewDocument,
429
+ toolbarOptions: {
430
+ icon: _jsx(IconShow, { fontSize: 24 }),
431
+ visible: true,
432
+ disabled: !focusedItem,
433
+ isActive: showPreview,
434
+ orderNumber: 3,
435
+ },
436
+ type: 'button',
437
+ buttonOptions: {
438
+ onClick: () => {
439
+ setShowPreview(prev => !prev);
440
+ },
441
+ },
442
+ },
443
+ {
444
+ id: 'commandSysMetadata',
445
+ name: SDKUI_Localizator.MetadataSystem,
446
+ toolbarOptions: {
447
+ icon: _jsx(IconDcmtTypeSys, { fontSize: 24 }),
448
+ visible: true,
449
+ disabled: !focusedItem,
450
+ isActive: showSysMetadata,
451
+ orderNumber: 3,
452
+ },
453
+ type: 'button',
454
+ buttonOptions: {
455
+ onClick: () => {
456
+ setShowSysMetadata(prev => !prev);
457
+ },
458
+ },
459
+ },
460
+ {
461
+ id: 'commandBoard',
462
+ name: SDKUI_Localizator.BlogCase,
463
+ toolbarOptions: {
464
+ icon: _jsx(IconBoard, { fontSize: 24 }),
465
+ disabled: !focusedItem,
466
+ visible: true,
467
+ isActive: showBoard,
468
+ orderNumber: 3,
469
+ },
470
+ type: 'button',
471
+ buttonOptions: {
472
+ onClick: () => {
473
+ setShowBoard(prev => !prev);
474
+ },
475
+ },
476
+ },
477
+ {
478
+ id: 'commandZeroDcmts',
479
+ name: "Consenti dettagli con 0 documenti",
480
+ toolbarOptions: {
481
+ icon: _jsx(IconCheckFile, { fontSize: 24 }),
482
+ visible: true,
483
+ isActive: showZeroDcmts,
484
+ orderNumber: 3,
485
+ },
486
+ type: 'button',
487
+ buttonOptions: {
488
+ onClick: () => {
489
+ setShowZeroDcmts(prev => !prev);
490
+ },
491
+ },
492
+ },
493
+ {
494
+ id: 'commandMasterDcmts',
495
+ name: SDKUI_Localizator.DcmtsMaster,
496
+ toolbarOptions: {
497
+ icon: _jsx(IconDetailDcmts, { transform: 'scale(-1, 1)', fontSize: 24 }),
498
+ disabled: !focusedItem?.isDcmt,
499
+ visible: true,
500
+ isActive: false,
501
+ orderNumber: 3,
502
+ },
503
+ type: 'button',
504
+ buttonOptions: {
505
+ onClick: () => {
506
+ appendMasterDcmts?.(focusedItem?.tid, focusedItem?.did);
507
+ },
508
+ },
509
+ },
510
+ ];
511
+ return (_jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, isCancelable: true, abortController: abortController, children: _jsx(TMPanelManager, { panels: panelsConfig, initialMobilePanelId: 'TMTreeView', toolbarMode: 1 }) }));
405
512
  };
406
513
  export default TMMasterDetailDcmts;
407
514
  function getMetadataKeys(obj) {
@@ -4,7 +4,7 @@ import styled from 'styled-components';
4
4
  import { SharingModes, SDK_Globals, SDK_Localizator } from '@topconsultnpm/sdk-ts-beta';
5
5
  import { LocalizeSharingModes } from '../../../helper/Enum_Localizator';
6
6
  import ContextMenu from 'devextreme-react/cjs/context-menu';
7
- import { SDKUI_Localizator, Globalization, svgToString, IconStar, IconDelete, IconDashboard, IconSavedQuery, IconApply, IconInfo } from '../../../helper';
7
+ import { SDKUI_Localizator, Globalization, svgToString, IconStar, IconDelete, IconDashboard, IconSavedQuery, IconApply, IconInfo, IconCloseOutline } from '../../../helper';
8
8
  import { TMColors } from '../../../utils/theme';
9
9
  import ShowAlert from '../../base/TMAlert';
10
10
  import TMButton from '../../base/TMButton';
@@ -13,6 +13,8 @@ import TMSpinner from '../../base/TMSpinner';
13
13
  import TMTooltip from '../../base/TMTooltip';
14
14
  import { TMSearchBar } from '../../sidebar/TMHeader';
15
15
  import { DeviceType, useDeviceType } from '../../base/TMDeviceProvider';
16
+ import { StyledDivHorizontal, StyledOffCanvasPanel } from '../../base/Styled';
17
+ import { useOutsideClick } from '../../../hooks/useOutsideClick';
16
18
  const StyledSqdItem = styled.div `
17
19
  display: flex;
18
20
  flex-direction: column;
@@ -33,9 +35,13 @@ const StyledSqdItem = styled.div `
33
35
  left: -2px;
34
36
  top: 50%;
35
37
  transform: translateY(-50%);
36
- opacity: ${({ $isMobile }) => ($isMobile ? 1 : 0)};
38
+ opacity: 0;
37
39
  transition: opacity 0.2s;
38
- pointer-events: ${({ $isMobile }) => ($isMobile ? 'auto' : 'none')};
40
+ pointer-events: none;
41
+ // On mobile, never show
42
+ ${({ $isMobile }) => $isMobile && `
43
+ display: none !important;
44
+ `}
39
45
  }
40
46
 
41
47
  &:hover .info-icon {
@@ -62,13 +68,31 @@ export const getTooltipBySqd = (sqd) => {
62
68
  return (_jsxs("div", { style: { textAlign: "left" }, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 10 }, children: [_jsx(IconSavedQuery, { color: getSharingModeColor(sqd.sharingMode), fontSize: 20, style: { flexShrink: 0 } }), _jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [_jsxs("div", { children: ["ID: ", sqd.id] }), _jsxs("div", { children: ["Master TID: ", sqd.masterTID] }), sqd.description && _jsx("div", { children: `${SDKUI_Localizator.Description}: ${sqd.description}` })] })] }), _jsx("hr", {}), _jsxs("div", { children: [SDKUI_Localizator.OwnerName, ": ", sqd.ownerName, " (", sqd.ownerID, ")"] }), _jsx("div", { children: LocalizeSharingModes(sqd.sharingMode) }), _jsxs("div", { children: ["Default: ", sqd.isDefault == 1 ? SDKUI_Localizator.Yes : SDKUI_Localizator.No] }), _jsxs("div", { children: ["Filtro semplice", ": ", sqd.isEasyWhere == 1 ? SDKUI_Localizator.Yes : SDKUI_Localizator.No] }), _jsxs("div", { children: ["Esegui ricerca immediatamente", ": ", sqd.runSearchWhenSelected == 1 ? SDKUI_Localizator.Yes : SDKUI_Localizator.No] }), _jsx("hr", {}), _jsxs("div", { children: [SDKUI_Localizator.CreationTime, ": ", Globalization.getDateTimeDisplayValue(sqd.creationTime)] }), _jsxs("div", { children: [SDKUI_Localizator.LastUpdateTime, ": ", Globalization.getDateTimeDisplayValue(sqd.lastUpdateTime)] })] }));
63
69
  };
64
70
  const initialSQDsMaxItems = 12;
65
- const SavedQueryContexMenu = ({ sqd, manageDefault, deleteAsync, favManageAsync, setDefaultAsync }) => _jsx(ContextMenu, { items: manageDefault ? [
66
- { text: SDKUI_Localizator.SetAsDefault2, icon: svgToString(_jsx(IconStar, { color: 'rgb(248, 215, 117)' })) },
67
- { text: SDKUI_Localizator.Delete, disabled: (sqd.id == 1), icon: svgToString(_jsx(IconDelete, {})) },
68
- { text: SDKUI_Localizator.AddToHomePage, disabled: (sqd.id == 1), icon: svgToString(_jsx(IconDashboard, {})) }
69
- ] : [
70
- { text: SDKUI_Localizator.Delete, disabled: (sqd.id == 1), icon: svgToString(_jsx(IconDelete, {})) },
71
- { text: SDKUI_Localizator.AddToHomePage, disabled: (sqd.id == 1), icon: svgToString(_jsx(IconDashboard, {})) }
71
+ const SavedQueryContexMenu = ({ sqd, manageDefault, isMobile, deleteAsync, favManageAsync, setDefaultAsync, setInfoSQD }) => _jsx(ContextMenu, { items: [
72
+ ...(manageDefault ? [{
73
+ text: SDKUI_Localizator.SetAsDefault2,
74
+ icon: svgToString(_jsx(IconStar, { color: 'rgb(248, 215, 117)' })),
75
+ onClick: () => setDefaultAsync(sqd)
76
+ }] : []),
77
+ {
78
+ text: SDKUI_Localizator.Delete,
79
+ disabled: (sqd.id == 1),
80
+ icon: svgToString(_jsx(IconDelete, {})),
81
+ onClick: () => deleteAsync(sqd)
82
+ },
83
+ {
84
+ text: SDKUI_Localizator.AddToHomePage,
85
+ disabled: (sqd.id == 1),
86
+ icon: svgToString(_jsx(IconDashboard, {})),
87
+ onClick: () => favManageAsync?.(sqd)
88
+ },
89
+ ...(isMobile ? [
90
+ {
91
+ text: SDKUI_Localizator.About,
92
+ icon: svgToString(_jsx(IconInfo, { color: TMColors.info })),
93
+ onClick: () => { setInfoSQD?.(sqd); }
94
+ }
95
+ ] : [])
72
96
  ], target: `#sqd-item-${sqd.id}`, onItemClick: (e) => {
73
97
  if (e.itemIndex == 0)
74
98
  setDefaultAsync?.(sqd);
@@ -82,8 +106,12 @@ const TMSavedQuerySelector = React.memo(({ items, selectedId, allowShowSearch =
82
106
  const [selectedItem, setSelectedItem] = useState();
83
107
  const [searchText, setSearchText] = useState('');
84
108
  const [showAllRoot, setShowAllRoot] = useState(false);
109
+ const [infoSQD, setInfoSQD] = useState();
85
110
  const deviceType = useDeviceType();
86
111
  const isMobile = deviceType === DeviceType.MOBILE;
112
+ const panelRef = useOutsideClick(() => {
113
+ setInfoSQD(undefined);
114
+ });
87
115
  useEffect(() => { loadDataAsync(false); }, [items]);
88
116
  useEffect(() => { setSelectedItem(dataSource.find(o => o.id == selectedId)); }, [selectedId, dataSource]);
89
117
  const loadDataAsync = async (refreshCache) => {
@@ -176,9 +204,9 @@ const TMSavedQuerySelector = React.memo(({ items, selectedId, allowShowSearch =
176
204
  justifyContent: 'center',
177
205
  fontSize: '1rem',
178
206
  fontWeight: 'bold'
179
- }, children: _jsx(IconApply, { fontSize: 24, color: 'green' }) }), _jsx(SavedQueryContexMenu, { sqd: sqd, manageDefault: manageDefault, setDefaultAsync: () => setDefaultSQDAsync(sqd), deleteAsync: () => deleteSQDAsync(sqd), favManageAsync: () => favManageSQDAsync(sqd) })] }, sqd.id))) }), dataSource.length > initialSQDsMaxItems && searchText.length <= 0 &&
207
+ }, children: _jsx(IconApply, { fontSize: 24, color: 'green' }) }), _jsx(SavedQueryContexMenu, { sqd: sqd, manageDefault: manageDefault, isMobile: isMobile, setInfoSQD: setInfoSQD, setDefaultAsync: () => setDefaultSQDAsync(sqd), deleteAsync: () => deleteSQDAsync(sqd), favManageAsync: () => favManageSQDAsync(sqd) })] }, sqd.id))) }), dataSource.length > initialSQDsMaxItems && searchText.length <= 0 &&
180
208
  _jsx(TMButton, { elementStyle: { display: 'flex', justifyContent: 'flex-end', padding: '10px' }, btnStyle: 'icon', caption: showAllRoot ? "Mostra meno" : `Mostra tutte le ricerche (+${dataSource.length - initialSQDsMaxItems})`, icon: showAllRoot ?
181
209
  _jsx("div", { style: { backgroundColor: TMColors.primaryColor, minWidth: '30px', minHeight: '30px', borderRadius: '10px', display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: _jsx("p", { style: { color: 'white' }, children: `-${dataSource.length - initialSQDsMaxItems}` }) }) :
182
- _jsx("div", { style: { backgroundColor: TMColors.primaryColor, minWidth: '30px', minHeight: '30px', borderRadius: '10px', display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: _jsx("p", { style: { color: 'white' }, children: `+${dataSource.length - initialSQDsMaxItems}` }) }), onClick: () => setShowAllRoot(!showAllRoot) })] }));
210
+ _jsx("div", { style: { backgroundColor: TMColors.primaryColor, minWidth: '30px', minHeight: '30px', borderRadius: '10px', display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: _jsx("p", { style: { color: 'white' }, children: `+${dataSource.length - initialSQDsMaxItems}` }) }), onClick: () => setShowAllRoot(!showAllRoot) }), _jsxs(StyledOffCanvasPanel, { ref: panelRef, "$isOpen": isMobile && infoSQD !== undefined, children: [_jsxs(StyledDivHorizontal, { style: { gap: 10, padding: '10px 8px', width: '100%', alignItems: 'center' }, children: [_jsx("p", { style: { fontSize: '1.1rem', fontWeight: 'bold' }, children: `${SDK_Localizator.SavedQuery} - ${SDKUI_Localizator.About}` }), _jsx(IconCloseOutline, { style: { marginLeft: 'auto', cursor: 'pointer' }, onClick: () => setInfoSQD(undefined) })] }), getTooltipBySqd(infoSQD)] })] }));
183
211
  });
184
212
  export default TMSavedQuerySelector;
@@ -169,7 +169,7 @@ const TMSearch = ({ inputTID, inputSqdID, isExpertMode = SDKUI_Globals.userSetti
169
169
  onSQDItemClick(sqd, setSQDAsync);
170
170
  isMobile && handleTogglePanel('TMSearchQueryPanel');
171
171
  }, onDeleted: (sqd) => onSQDDeleted(sqd, sqd.id == currentSQD?.id ? undefined : currentSQD, setSQDAsync) }) })] });
172
- const panels = [
172
+ const panelsConfig = [
173
173
  {
174
174
  id: 'TMTreeSelector',
175
175
  name: SDK_Localizator.Trees,
@@ -243,7 +243,7 @@ const TMSearch = ({ inputTID, inputSqdID, isExpertMode = SDKUI_Globals.userSetti
243
243
  },
244
244
  },
245
245
  ];
246
- return (_jsxs(_Fragment, { children: [_jsx(StyledMultiViewPanel, { "$isVisible": currentSearchView === TMSearchViews.Search, children: _jsx(TMPanelManager, { panels: panels, initialMobilePanelId: 'TMRecentsManager', toolbarMode: 1 }) }), searchResult.length > 0 &&
246
+ return (_jsxs(_Fragment, { children: [_jsx(StyledMultiViewPanel, { "$isVisible": currentSearchView === TMSearchViews.Search, children: _jsx(TMPanelManager, { panels: panelsConfig, initialMobilePanelId: 'TMRecentsManager', toolbarMode: 1 }) }), searchResult.length > 0 &&
247
247
  _jsx(TMSearchResult, { isVisible: currentSearchView === TMSearchViews.Result, context: SearchResultContext.METADATA_SEARCH, searchResults: searchResult, onRefreshAfterAddDcmtToFavs: onRefreshAfterAddDcmtToFavs, onRefreshSearchAsync: async () => {
248
248
  setSearchResult(await refreshLastSearch(lastQdSearched) ?? []);
249
249
  }, onTaskCreateRequest: onTaskCreateRequest, onClose: () => { setCurrentSearchView(TMSearchViews.Search); } })] }));