@topconsultnpm/sdkui-react-beta 6.13.12 → 6.13.14

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.
@@ -0,0 +1,237 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React, { useEffect, useMemo, useState } from 'react';
3
+ import { SDKUI_Globals, SDKUI_Localizator, IconWindowMinimize, IconWindowMaximize, IconInfo } from '../../helper';
4
+ import TMButton from './TMButton';
5
+ import { useDeviceType, DeviceType } from './TMDeviceProvider';
6
+ import TMPanel from './TMPanel';
7
+ import { calculatePanelSizes, DesktopToolbar, getDynamicColumnWidth, getInitialMobilePanelID, MobileToolbar } from './TMPanelManagerMatrixUtils';
8
+ const TMPanelManagerMatrix = (props) => {
9
+ // Destructure props
10
+ const { panelMatrixMap, toolbar, initialMobilePanelID, gutters = SDKUI_Globals.userSettings.themeSettings.gutters } = props;
11
+ // Get the current device type (e.g., mobile, tablet, desktop) using a custom hook.
12
+ const deviceType = useDeviceType();
13
+ // This avoids unnecessary re-renders by only recalculating when deviceType changes.
14
+ let isMobile = useMemo(() => { return deviceType === DeviceType.MOBILE; }, [deviceType]);
15
+ // State for toolbar items
16
+ const [toolbarState, setToolbarState] = useState(toolbar);
17
+ // State to track which panel IDs are currently hidden
18
+ const [hiddenPanelIds, setHiddenPanelIds] = useState(new Set());
19
+ // State to store the current widths of all column, represented as a Map
20
+ const [columnWidths, setColumnWidths] = useState(new Map());
21
+ // State to store the current heights of all panels, represented as a Map
22
+ const [panelHeights, setPanelHeights] = useState(new Map());
23
+ // State to track maximized panel
24
+ const [maximizedPanelId, setMaximizedPanelId] = useState(null);
25
+ // Memoized computation of visible columns and the total number of visible panels
26
+ const { visibleColumns, totalVisiblePanels } = useMemo(() => {
27
+ let totalVisiblePanels = 0;
28
+ const visibleColumns = [];
29
+ for (const [columnKey, column] of panelMatrixMap.entries()) {
30
+ // Filter visible rows in the current column
31
+ const visibleRows = column.rows.filter(row => !hiddenPanelIds.has(row.id));
32
+ // If any visible rows exist, include the column and count them
33
+ if (visibleRows.length > 0) {
34
+ visibleColumns.push(columnKey);
35
+ totalVisiblePanels += visibleRows.length;
36
+ }
37
+ }
38
+ return { visibleColumns, totalVisiblePanels };
39
+ }, [panelMatrixMap, hiddenPanelIds]);
40
+ // Effect hook to update column widths
41
+ useEffect(() => {
42
+ const newColumnWidths = new Map();
43
+ Array.from(panelMatrixMap.entries()).forEach(([columnKey, col]) => {
44
+ if (!maximizedPanelId) {
45
+ const width = getDynamicColumnWidth(col, hiddenPanelIds, Array.from(panelMatrixMap.values()));
46
+ newColumnWidths.set(columnKey, { width });
47
+ }
48
+ });
49
+ setColumnWidths(newColumnWidths);
50
+ }, [panelMatrixMap, hiddenPanelIds, maximizedPanelId]);
51
+ // Effect hook to set initial hidden panels and their heights
52
+ useEffect(() => {
53
+ const initialHidden = new Set();
54
+ if (isMobile) {
55
+ // On mobile, only show the first selected mobile panel; hide the rest
56
+ let firstMobilePanelID = initialMobilePanelID ?? getInitialMobilePanelID(panelMatrixMap);
57
+ panelMatrixMap.forEach(col => {
58
+ col.rows.forEach(row => {
59
+ if (row.id !== firstMobilePanelID)
60
+ initialHidden.add(row.id);
61
+ });
62
+ });
63
+ }
64
+ else {
65
+ // On non-mobile devices, hide panels that are marked as `hidden`
66
+ panelMatrixMap.forEach(col => {
67
+ col.rows.forEach(row => {
68
+ if (row.hidden)
69
+ initialHidden.add(row.id);
70
+ });
71
+ });
72
+ }
73
+ // Update state with the calculated hidden panels and panel sizes
74
+ setHiddenPanelIds(initialHidden);
75
+ setPanelHeights(calculatePanelSizes(panelMatrixMap, initialHidden));
76
+ }, [panelMatrixMap, isMobile]);
77
+ // Function to toggle the disabled of a toolbar given its item
78
+ const toggleToolbarItemDisabled = (toolbarItem) => {
79
+ if (!toolbarItem)
80
+ return;
81
+ setToolbarState(prevToolbar => {
82
+ if (!prevToolbar)
83
+ return prevToolbar;
84
+ return {
85
+ ...prevToolbar,
86
+ items: prevToolbar.items.map(item => item.id === toolbarItem.id ? { ...item, disabled: !item.disabled } : item)
87
+ };
88
+ });
89
+ };
90
+ // Function to toggle the visibility of a toolbar given its item
91
+ const toggleToolbarItemVisibility = (toolbarItem) => {
92
+ if (!toolbarItem)
93
+ return;
94
+ setToolbarState(prevToolbar => {
95
+ if (!prevToolbar)
96
+ return prevToolbar;
97
+ return {
98
+ ...prevToolbar,
99
+ items: prevToolbar.items.map(item => item.id === toolbarItem.id ? { ...item, visible: !(item.visible ?? true) } : item)
100
+ };
101
+ });
102
+ };
103
+ // Function to toggle the visibility of a panel given its item
104
+ const togglePanelVisibility = (toolbarItem) => {
105
+ if (!toolbarItem)
106
+ return;
107
+ setHiddenPanelIds(prevHidden => {
108
+ let newHidden;
109
+ if (isMobile) {
110
+ // On mobile, make only the selected panel visible; hide all others
111
+ newHidden = new Set();
112
+ panelMatrixMap.forEach(col => {
113
+ col.rows.forEach(row => {
114
+ if (row.id !== toolbarItem.panelManagerMatrixRowId) {
115
+ newHidden.add(row.id);
116
+ }
117
+ });
118
+ });
119
+ }
120
+ else {
121
+ // On non-mobile devices, toggle visibility normally
122
+ newHidden = new Set(prevHidden);
123
+ // Hide alternative panels if any
124
+ if (toolbarItem.alternativePanelManagerMatrixRowId?.length) {
125
+ toolbarItem.alternativePanelManagerMatrixRowId.forEach(altId => newHidden.add(altId));
126
+ }
127
+ // Toggle clicked panel visibility
128
+ if (newHidden.has(toolbarItem.panelManagerMatrixRowId)) {
129
+ newHidden.delete(toolbarItem.panelManagerMatrixRowId);
130
+ }
131
+ else {
132
+ // If the panel is maximized, call maximizeMinimizePanelCallback to minimize it
133
+ if (maximizedPanelId === toolbarItem.panelManagerMatrixRowId) {
134
+ maximizeMinimizePanelCallback(true, toolbarItem.panelManagerMatrixRowId);
135
+ }
136
+ newHidden.add(toolbarItem.panelManagerMatrixRowId);
137
+ }
138
+ }
139
+ setPanelHeights(calculatePanelSizes(panelMatrixMap, newHidden));
140
+ return newHidden;
141
+ });
142
+ };
143
+ const maximizeMinimizePanelCallback = (isMaximized, id) => {
144
+ const maximized = isMaximized ? null : id;
145
+ setMaximizedPanelId(maximized);
146
+ };
147
+ return (_jsx("div", { style: { width: '100%', height: '100%' }, children: _jsxs("div", { style: {
148
+ display: isMobile ? 'block' : 'flex',
149
+ flexDirection: 'row',
150
+ width: "100%",
151
+ height: '100%'
152
+ }, children: [_jsx("div", { style: {
153
+ display: 'flex',
154
+ flexDirection: 'row',
155
+ width: (toolbarState && toolbarState.items.length > 0) ? `calc(100% - ${isMobile ? "0px" : "40px"})` : '100%',
156
+ height: `calc(100% - ${isMobile ? "60px" : "0px"})`,
157
+ columnGap: maximizedPanelId ? '0px' : `${gutters}px`,
158
+ }, children: visibleColumns.length > 0 ? visibleColumns.map((column, colIndex) => {
159
+ // Retrieve the column data from the panelMatrixMap using the current column key
160
+ const col = panelMatrixMap.get(column);
161
+ // Check if the current column contains the maximized panel
162
+ const hasMaximized = !!col?.rows?.some(row => row.id === maximizedPanelId);
163
+ const isLastColumn = colIndex === visibleColumns.length - 1;
164
+ // Define the base style for all columns with flex layout, full height, smooth width transition, and no minimum width
165
+ const columnBaseStyle = { display: 'flex', flexDirection: 'column', height: '100%', transition: isMobile ? 'none' : 'width 0.3s', };
166
+ // Declare a variable to hold the final computed style for the column
167
+ let columnStyle;
168
+ if (maximizedPanelId) {
169
+ // If a panel is maximized, if it does, give the column full width
170
+ columnStyle = hasMaximized ? { ...columnBaseStyle, width: '100%' } : { ...columnBaseStyle, width: '0px', overflow: 'hidden' };
171
+ }
172
+ else {
173
+ // Otherwise, hide this column by setting width to 0 and hiding overflow
174
+ const savedWidth = columnWidths.get(column)?.width ?? getDynamicColumnWidth(col, hiddenPanelIds, Array.from(panelMatrixMap.values()));
175
+ columnStyle = { ...columnBaseStyle, width: savedWidth };
176
+ }
177
+ return (_jsx(React.Fragment, { children: _jsx("div", { style: columnStyle, children: col?.rows?.map((row) => {
178
+ const isHiddenPanel = hiddenPanelIds.has(row.id);
179
+ const visibleRows = col.rows?.filter(r => !hiddenPanelIds.has(r.id));
180
+ const isLastVisible = visibleRows.length > 0 && visibleRows[visibleRows.length - 1].id === row.id;
181
+ const isMaximized = maximizedPanelId === row.id;
182
+ const baseStyle = {
183
+ backgroundColor: '#f5f5f5',
184
+ borderRadius: '8px',
185
+ display: 'block',
186
+ transition: isMobile ? 'none' : 'all 0.3s ease',
187
+ boxShadow: '0 0 8px #D3D3D3BF',
188
+ };
189
+ const hiddenStyle = {
190
+ minWidth: '0px',
191
+ width: '0px',
192
+ height: '0px',
193
+ visibility: 'hidden',
194
+ opacity: 0,
195
+ marginBottom: '0px',
196
+ };
197
+ const maximizedStyle = {
198
+ minWidth: '50px',
199
+ width: '100%',
200
+ height: '100%',
201
+ visibility: 'visible',
202
+ opacity: 1,
203
+ marginBottom: '0px',
204
+ };
205
+ const defaultStyle = {
206
+ minWidth: isHiddenPanel ? '0px' : '50px',
207
+ width: '100%',
208
+ height: isHiddenPanel ? '0px' : panelHeights.get(row.id)?.height ?? '100%',
209
+ visibility: isHiddenPanel ? 'hidden' : 'visible',
210
+ opacity: isHiddenPanel ? 0 : 1,
211
+ marginBottom: (isHiddenPanel || isLastVisible) ? '0px' : `${gutters}px`,
212
+ };
213
+ const panelStyle = maximizedPanelId ? (isMaximized ? { ...baseStyle, ...maximizedStyle } : hiddenStyle) : { ...baseStyle, ...defaultStyle };
214
+ return _jsx("div", { style: panelStyle, children: row.panel ? _jsx(TMPanel, { title: row.panel.title, totalItems: row.panel.totalItems ?? undefined, displayedItemsCount: row.panel.displayedItemsCount ?? undefined, onHeaderDoubleClick: () => maximizeMinimizePanelCallback(isMaximized, row.id), onClose: (!isMobile && toolbarState) ? () => togglePanelVisibility(toolbarState.items.find(item => item.panelManagerMatrixRowId === row.id)) : undefined, allowMaximize: false, toolbar: _jsx("div", { style: { width: 'max-content', display: 'flex', alignItems: 'center', gap: '10px' }, children: ((row.panel?.showCustomMaximizeMinimizeButton ?? true) && !isMobile && totalVisiblePanels > 1) && _jsx(TMButton, { caption: isMaximized ? SDKUI_Localizator.Minimize : SDKUI_Localizator.Maximize, icon: isMaximized ? _jsx(IconWindowMinimize, {}) : _jsx(IconWindowMaximize, {}), btnStyle: 'icon', onClick: () => maximizeMinimizePanelCallback(isMaximized, row.id) }) }), children: typeof row.content === "function" ? row.content(togglePanelVisibility, toggleToolbarItemDisabled, toggleToolbarItemVisibility) : row.content })
215
+ : typeof row.content === "function" ? row.content(togglePanelVisibility, toggleToolbarItemDisabled, toggleToolbarItemVisibility) : row.content }, "TMPanelManagerMatrix-r-" + row.id);
216
+ }) }) }, "TMPanelManagerMatrix-c-" + column));
217
+ }) : _jsxs("div", { style: {
218
+ width: '100%',
219
+ height: '100%',
220
+ display: 'flex',
221
+ flexDirection: 'column',
222
+ alignItems: 'center',
223
+ justifyContent: 'center',
224
+ backgroundColor: '#fff',
225
+ border: '1px solid #ddd',
226
+ borderRadius: '12px',
227
+ boxShadow: '0 4px 10px rgba(0, 0, 0, 0.05)',
228
+ padding: '40px',
229
+ textAlign: 'center',
230
+ color: '#555',
231
+ fontSize: '18px',
232
+ gap: '16px'
233
+ }, children: [_jsx(IconInfo, { style: { fontSize: 50 } }), _jsx("div", { children: SDKUI_Localizator.NoPanelSelected })] }) }), toolbarState && toolbarState.items.length > 0 && (!isMobile
234
+ ? DesktopToolbar(toolbarState, hiddenPanelIds, togglePanelVisibility)
235
+ : MobileToolbar(toolbarState, hiddenPanelIds, togglePanelVisibility))] }) }));
236
+ };
237
+ export default TMPanelManagerMatrix;
@@ -0,0 +1,69 @@
1
+ import { ITMPanelProps } from './TMPanel';
2
+ export declare const defaultTMPanelManagerToolbarStyles: {
3
+ container: {
4
+ backgroundColor: string;
5
+ padding: string;
6
+ };
7
+ items: {
8
+ width: string;
9
+ height: string;
10
+ inactiveBackgroundColor: string;
11
+ activeBackgroundColor: string;
12
+ borderRadius: string;
13
+ marginBottom: string;
14
+ iconFontSize: string;
15
+ iconColor: string;
16
+ };
17
+ };
18
+ export interface TMPanelManagerMatrixColumn {
19
+ rows: Array<TMPanelManagerMatrixRow>;
20
+ width?: string;
21
+ }
22
+ export interface ExtendedTMPanelProps extends ITMPanelProps {
23
+ showCustomMaximizeMinimizeButton?: boolean;
24
+ }
25
+ export interface TMPanelManagerMatrixRow {
26
+ id: string;
27
+ hidden: boolean;
28
+ content: JSX.Element | ((togglePanelVisibility: (toolbarItem: TMPanelManagerToolbarItem | undefined) => void, toggleToolbarItemDisabled: (toolbarItem: TMPanelManagerToolbarItem | undefined) => void, toggleToolbarItemVisibility: (toolbarItem: TMPanelManagerToolbarItem | undefined) => void) => JSX.Element);
29
+ height?: string;
30
+ width?: string;
31
+ panel?: ExtendedTMPanelProps;
32
+ }
33
+ export interface TMPanelManagerToolbarStyles {
34
+ container?: {
35
+ backgroundColor?: string;
36
+ padding?: string;
37
+ };
38
+ items?: {
39
+ width?: string;
40
+ height?: string;
41
+ inactiveBackgroundColor?: string;
42
+ activeBackgroundColor?: string;
43
+ borderRadius?: string;
44
+ marginBottom?: string;
45
+ iconFontSize?: string;
46
+ iconColor?: string;
47
+ };
48
+ }
49
+ export interface TMPanelManagerToolbarItem {
50
+ id: string;
51
+ icon: string | JSX.Element;
52
+ tooltipName: string;
53
+ panelManagerMatrixRowId: string;
54
+ alternativePanelManagerMatrixRowId?: Array<string>;
55
+ beginGroup?: boolean;
56
+ disabled?: boolean;
57
+ visible?: boolean;
58
+ }
59
+ export interface TMPanelManagerToolbar {
60
+ items: Array<TMPanelManagerToolbarItem>;
61
+ styles?: TMPanelManagerToolbarStyles;
62
+ }
63
+ export declare const calculatePanelSizes: (panelMatrixMap: Map<string, TMPanelManagerMatrixColumn>, hiddenIds: Set<string>) => Map<string, {
64
+ height: string;
65
+ }>;
66
+ export declare const getInitialMobilePanelID: (panelMatrixMap: Map<string, TMPanelManagerMatrixColumn>) => string | undefined;
67
+ export declare const DesktopToolbar: (toolbar: TMPanelManagerToolbar, hiddenPanelIds: Set<string>, togglePanelVisibility: (panel: TMPanelManagerToolbarItem) => void) => import("react/jsx-runtime").JSX.Element;
68
+ export declare const MobileToolbar: (toolbar: TMPanelManagerToolbar, hiddenPanelIds: Set<string>, togglePanelVisibility: (panel: TMPanelManagerToolbarItem) => void) => import("react/jsx-runtime").JSX.Element;
69
+ export declare const getDynamicColumnWidth: (col: TMPanelManagerMatrixColumn | undefined, hiddenPanelIds: Set<string>, allColumns: Array<TMPanelManagerMatrixColumn>) => string;
@@ -0,0 +1,155 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { ScrollView } from "devextreme-react";
3
+ import { SDKUI_Globals } from '../../helper';
4
+ import TMTooltip from './TMTooltip';
5
+ export const defaultTMPanelManagerToolbarStyles = {
6
+ container: {
7
+ backgroundColor: '#f0f0f0',
8
+ padding: '6px'
9
+ },
10
+ items: {
11
+ width: '35px',
12
+ height: '35px',
13
+ inactiveBackgroundColor: '#e57373',
14
+ activeBackgroundColor: '#81c784',
15
+ borderRadius: '50%',
16
+ marginBottom: '6px',
17
+ iconFontSize: "25px",
18
+ iconColor: '#ffffff'
19
+ }
20
+ };
21
+ ;
22
+ // Helper to calculate sizes based on hidden panel IDs
23
+ export const calculatePanelSizes = (panelMatrixMap, hiddenIds) => {
24
+ const sizes = new Map();
25
+ panelMatrixMap.forEach((column) => {
26
+ const visiblePanels = column.rows.filter(p => !hiddenIds.has(p.id));
27
+ const hiddenPanels = column.rows.filter(p => hiddenIds.has(p.id));
28
+ if (visiblePanels.length > 0) {
29
+ const totalVisibleHeight = visiblePanels.reduce((sum, panel) => {
30
+ return sum + parseFloat(panel.height || '0');
31
+ }, 0);
32
+ visiblePanels.forEach(panel => {
33
+ const originalHeight = parseFloat(panel.height || '0');
34
+ const newHeightPercent = (originalHeight / totalVisibleHeight) * 100;
35
+ sizes.set(panel.id, { height: `${newHeightPercent}%` });
36
+ });
37
+ }
38
+ hiddenPanels.forEach(panel => {
39
+ sizes.set(panel.id, { height: '0%' });
40
+ });
41
+ });
42
+ return sizes;
43
+ };
44
+ export const getInitialMobilePanelID = (panelMatrixMap) => {
45
+ const firstEntry = panelMatrixMap.values().next().value?.rows;
46
+ if (!firstEntry)
47
+ return undefined;
48
+ const visiblePanel = firstEntry.find((row) => !row.hidden);
49
+ return visiblePanel?.id;
50
+ };
51
+ export const DesktopToolbar = (toolbar, hiddenPanelIds, togglePanelVisibility) => {
52
+ return _jsx("div", { style: {
53
+ width: '40px',
54
+ display: 'flex',
55
+ flexDirection: 'column',
56
+ justifyContent: 'flex-start',
57
+ borderRadius: '8px',
58
+ alignItems: 'center',
59
+ marginLeft: SDKUI_Globals.userSettings.themeSettings.gutters,
60
+ // customizable properties
61
+ backgroundColor: toolbar.styles?.container?.backgroundColor ?? defaultTMPanelManagerToolbarStyles.container.backgroundColor,
62
+ padding: toolbar.styles?.container?.padding ?? defaultTMPanelManagerToolbarStyles.container.padding,
63
+ }, children: toolbar.items.filter(item => item.visible !== false).map((item, index) => {
64
+ return _jsxs("div", { children: [item.beginGroup && index !== 0 && (_jsx("hr", { style: { margin: '10px 0', borderTop: '1px solid #c6c6c6', width: '100%' } })), _jsx("button", { disabled: item.disabled ?? false, style: {
65
+ display: 'flex',
66
+ justifyContent: 'center',
67
+ alignItems: 'center',
68
+ border: 'none',
69
+ cursor: 'pointer',
70
+ transition: 'background-color 0.3s, transform 0.2s',
71
+ // customizable properties
72
+ width: toolbar.styles?.items?.width ?? defaultTMPanelManagerToolbarStyles.items.width,
73
+ height: toolbar.styles?.items?.height ?? defaultTMPanelManagerToolbarStyles.items.height,
74
+ backgroundColor: item.disabled ? '#cccccc'
75
+ : hiddenPanelIds.has(item.panelManagerMatrixRowId)
76
+ ? toolbar.styles?.items?.inactiveBackgroundColor ?? defaultTMPanelManagerToolbarStyles.items.inactiveBackgroundColor
77
+ : toolbar.styles?.items?.activeBackgroundColor ?? defaultTMPanelManagerToolbarStyles.items.activeBackgroundColor,
78
+ borderRadius: toolbar.styles?.items?.borderRadius ?? defaultTMPanelManagerToolbarStyles.items.borderRadius,
79
+ marginBottom: toolbar.styles?.items?.marginBottom ?? defaultTMPanelManagerToolbarStyles.items.marginBottom,
80
+ }, onMouseEnter: (e) => {
81
+ e.currentTarget.style.transform = 'scale(1.1)';
82
+ }, onMouseLeave: (e) => {
83
+ e.currentTarget.style.transform = 'scale(1)';
84
+ }, onClick: () => togglePanelVisibility(item), children: _jsx(TMTooltip, { content: item.tooltipName, children: typeof item.icon === 'string' ? _jsx("i", { className: `dx-icon dx-icon-${item.icon}`, style: { fontSize: toolbar.styles?.items?.iconFontSize ?? defaultTMPanelManagerToolbarStyles.items.iconFontSize, color: toolbar.styles?.items?.iconColor ?? defaultTMPanelManagerToolbarStyles.items.iconColor } }) : item.icon }) })] }, "TMPanelManagerMatrix-Desktop-Toolbar-Item-" + item.id);
85
+ }) }, "TMPanelManagerMatrix-Desktop-Toolbar");
86
+ };
87
+ export const MobileToolbar = (toolbar, hiddenPanelIds, togglePanelVisibility) => {
88
+ return _jsx("div", { style: {
89
+ width: '100%',
90
+ height: '60px',
91
+ background: 'linear-gradient(135deg, #e0eafc, #cfdef3)',
92
+ display: 'flex',
93
+ flexDirection: 'column',
94
+ justifyContent: 'center',
95
+ borderRadius: '12px',
96
+ boxShadow: '0 6px 10px rgba(0, 0, 0, 0.15)',
97
+ alignItems: 'center',
98
+ padding: '5px',
99
+ }, children: _jsx("div", { style: {
100
+ display: "flex",
101
+ overflow: "hidden",
102
+ borderRadius: "12px",
103
+ backgroundColor: "#ffffff",
104
+ boxShadow: "0 6px 12px rgba(0,0,0,0.1)",
105
+ width: "100%",
106
+ height: '100%',
107
+ }, children: _jsx(ScrollView, { direction: "horizontal", showScrollbar: "always", useNative: Number(SDKUI_Globals.userSettings?.themeSettings.gridSettings.useNativeScrollbar) === 1, style: { whiteSpace: "nowrap", width: "100%" }, children: _jsx("div", { style: { display: "flex", gap: "8px", justifyContent: "center", padding: "5px" }, children: toolbar.items.filter(item => item.visible !== false).map((item, index) => {
108
+ return _jsxs("div", { style: { display: "flex", flexDirection: "row", alignItems: "center" }, children: [item.beginGroup && index !== 0 && (_jsx("div", { style: { height: '35px', width: '1px', backgroundColor: '#c6c6c6', margin: '0 8px' } })), _jsx("button", { disabled: item.disabled ?? false, style: {
109
+ display: 'flex',
110
+ justifyContent: 'center',
111
+ alignItems: 'center',
112
+ border: 'none',
113
+ cursor: 'pointer',
114
+ transition: 'background-color 0.3s, transform 0.2s',
115
+ // customizable properties
116
+ width: toolbar.styles?.items?.width ?? defaultTMPanelManagerToolbarStyles.items.width,
117
+ height: toolbar.styles?.items?.height ?? defaultTMPanelManagerToolbarStyles.items.height,
118
+ backgroundColor: item.disabled ? '#cccccc'
119
+ : hiddenPanelIds.has(item.panelManagerMatrixRowId)
120
+ ? toolbar.styles?.items?.inactiveBackgroundColor ?? defaultTMPanelManagerToolbarStyles.items.inactiveBackgroundColor
121
+ : toolbar.styles?.items?.activeBackgroundColor ?? defaultTMPanelManagerToolbarStyles.items.activeBackgroundColor,
122
+ borderRadius: toolbar.styles?.items?.borderRadius ?? defaultTMPanelManagerToolbarStyles.items.borderRadius,
123
+ marginBottom: toolbar.styles?.items?.marginBottom ?? defaultTMPanelManagerToolbarStyles.items.marginBottom,
124
+ }, onMouseEnter: (e) => {
125
+ e.currentTarget.style.transform = 'scale(1.1)';
126
+ }, onMouseLeave: (e) => {
127
+ e.currentTarget.style.transform = 'scale(1)';
128
+ }, onClick: () => togglePanelVisibility(item), children: _jsx(TMTooltip, { content: item.tooltipName, children: typeof item.icon === 'string' ? _jsx("i", { className: `dx-icon dx-icon-${item.icon}`, style: { fontSize: toolbar.styles?.items?.iconFontSize ?? defaultTMPanelManagerToolbarStyles.items.iconFontSize, color: toolbar.styles?.items?.iconColor ?? defaultTMPanelManagerToolbarStyles.items.iconColor } }) : item.icon }) })] }, "TMPanelManagerMatrix-Mobile-Toolbar-Item-" + item.id);
129
+ }) }) }) }) }, "TMPanelManagerMatrix-Mobile-Toolbar");
130
+ };
131
+ export const getDynamicColumnWidth = (col, hiddenPanelIds, allColumns) => {
132
+ if (!col)
133
+ return '0%';
134
+ // If all rows in the column are hidden, return width 0%
135
+ const allRowsHidden = col.rows.every(row => hiddenPanelIds.has(row.id));
136
+ if (allRowsHidden)
137
+ return '0%';
138
+ // Calculate which columns are visible (at least one row not hidden)
139
+ const visibleColumns = allColumns.filter(c => c.rows.some(r => !hiddenPanelIds.has(r.id)));
140
+ const visibleCount = visibleColumns.length;
141
+ // If all columns are visible, use the original widths
142
+ if (visibleCount === allColumns.length) {
143
+ return col.width ?? `${100 / visibleCount}%`;
144
+ }
145
+ // If some columns are hidden, redistribute the 100% width among visible columns
146
+ // proportionally to their original widths
147
+ // First, sum the original widths (in percent) of the visible columns
148
+ const totalPercent = visibleColumns.reduce((sum, c) => {
149
+ const w = c.width ? parseFloat(c.width) : (100 / visibleCount);
150
+ return sum + w;
151
+ }, 0);
152
+ // Calculate the width percentage for this column based on its original width proportion
153
+ const thisPercent = col.width ? parseFloat(col.width) : (100 / visibleCount);
154
+ return `${(thisPercent / totalPercent) * 100}%`;
155
+ };
@@ -1,38 +1,36 @@
1
- import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
2
  import React, { useEffect, useState } from 'react';
3
3
  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, IconAdvanced, IconLightningFill, IconApply } from '../../../helper';
7
+ import { SDKUI_Localizator, Globalization, svgToString, IconStar, IconDelete, IconDashboard, IconApply } from '../../../helper';
8
8
  import { TMColors } from '../../../utils/theme';
9
9
  import ShowAlert from '../../base/TMAlert';
10
10
  import TMButton from '../../base/TMButton';
11
11
  import { TMMessageBoxManager, ButtonNames, TMExceptionBoxManager } from '../../base/TMPopUp';
12
12
  import TMSpinner from '../../base/TMSpinner';
13
- import TMTooltip from '../../base/TMTooltip';
14
13
  import { TMSearchBar } from '../../sidebar/TMHeader';
15
- const StyledSavedQueryListItem = styled.div `
14
+ const StyledSqdItem = styled.div `
16
15
  display: flex;
17
- flex-direction: row;
18
- align-items: center;
19
- background: ${(props) => props.$backgroundColor ?? undefined};
20
- border-radius: 8px;
21
- border: 1px solid;
22
- border-color: lightgray;
23
- box-shadow: 1px 1px 7px rgba(0,0,0,0.15);
24
- width: 100%;
25
- height: max-content;
26
- min-height: 45px;
27
- padding: 5px;
16
+ flex-direction: column;
17
+ align-items: stretch;
18
+ min-width: 0;
19
+ padding: 10px;
20
+ position: relative;
28
21
  white-space: nowrap;
29
22
  text-overflow: ellipsis;
30
23
 
31
24
  &:hover {
32
- background: ${(props) => props.$hoverColor ?? undefined};
33
25
  cursor: pointer;
34
26
  }
35
27
  `;
28
+ const StyledPipe = styled.div `
29
+ width: 90%;
30
+ height: 1px;
31
+ background: #00A99D;
32
+ margin: 4px auto;
33
+ `;
36
34
  const getSharingModeColor = (sharingMode) => {
37
35
  switch (sharingMode) {
38
36
  case SharingModes.Private: return 'rgb(185, 72, 57)';
@@ -119,23 +117,49 @@ const TMSavedQuerySelector = React.memo(({ items, selectedId, allowShowSearch =
119
117
  }
120
118
  };
121
119
  return (_jsxs("div", { style: { height: height ?? '100%', width: '100%', display: 'flex', flexDirection: 'column', gap: '5px', paddingTop: allowShowSearch ? '5px' : undefined }, children: [allowShowSearch &&
122
- _jsx("div", { style: { width: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '10px', paddingBottom: '10px', paddingTop: '10px' }, children: _jsx(TMSearchBar, { marginLeft: '0px', maxWidth: '300px', searchValue: searchText, onSearchValueChanged: (e) => setSearchText(e) }) }), _jsx("div", { style: { width: '100%', overflow: 'auto', display: 'flex', flexDirection: 'column', justifyContent: 'flex-start', padding: '5px', gap: '3px' }, children: dataSource.slice(0, showAllRoot || searchText.length > 0 ? dataSource.length : initialSQDsMaxItems).filter(o => searchText.length <= 0 || (searchText.length > 0 && o.name?.toLocaleLowerCase().includes(searchText.toLocaleLowerCase())) || o.description?.toLocaleLowerCase().includes(searchText.toLocaleLowerCase())).map((sqd, index) => (_jsxs(StyledSavedQueryListItem, { id: `sqd-item-${sqd.id}`, style: { position: 'relative', gap: '5px', paddingLeft: '5px' }, "$backgroundColor": 'white', "$hoverColor": 'rgba(243, 152, 119, .2)', "$selectedColor": 'rgb(237, 115, 72)', onClick: () => {
120
+ _jsx("div", { style: { width: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '10px', paddingBottom: '10px', paddingTop: '10px' }, children: _jsx(TMSearchBar, { marginLeft: '0px', maxWidth: '300px', searchValue: searchText, onSearchValueChanged: (e) => setSearchText(e) }) }), _jsx("div", { style: {
121
+ display: 'flex',
122
+ flexDirection: 'column',
123
+ width: '100%',
124
+ padding: '5px',
125
+ gap: '3px',
126
+ whiteSpace: 'nowrap',
127
+ overflow: 'hidden',
128
+ textOverflow: 'ellipsis'
129
+ }, children: dataSource.slice(0, showAllRoot || searchText.length > 0 ? dataSource.length : initialSQDsMaxItems).filter(o => searchText.length <= 0 || (searchText.length > 0 && o.name?.toLocaleLowerCase().includes(searchText.toLocaleLowerCase())) || o.description?.toLocaleLowerCase().includes(searchText.toLocaleLowerCase())).map((sqd, index) => (_jsxs(StyledSqdItem, { id: `sqd-item-${sqd.id}`, onClick: () => {
123
130
  setSelectedItem(sqd);
124
131
  onItemClick?.(sqd);
125
- }, children: [_jsx(TMTooltip, { content: getTooltipBySqd(sqd), children: _jsx("div", { style: { backgroundColor: 'white', minWidth: '24px', minHeight: '24px', borderRadius: '24px', display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: _jsx(IconSavedQuery, { fontSize: 22, color: getSharingModeColor(sqd.sharingMode) }) }) }), _jsxs("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', whiteSpace: 'nowrap',
132
+ }, children: [_jsxs("div", { style: {
133
+ display: 'flex',
134
+ flexDirection: 'row',
135
+ justifyContent: 'center',
136
+ width: '100%',
137
+ whiteSpace: 'nowrap',
126
138
  overflow: 'hidden',
127
- textOverflow: 'ellipsis' }, children: [_jsxs("div", { style: {
128
- display: 'flex', justifyContent: 'flex-start', width: '100%', whiteSpace: 'nowrap',
139
+ textOverflow: 'ellipsis',
140
+ gap: '5px'
141
+ }, children: [_jsx("p", { style: {
142
+ fontSize: '1rem',
143
+ fontWeight: sqd.id === 1 ? 600 : 'normal',
144
+ whiteSpace: 'nowrap',
129
145
  overflow: 'hidden',
130
- textOverflow: 'ellipsis'
131
- }, children: [_jsx("p", { style: {
132
- fontSize: '1rem', fontWeight: 600, whiteSpace: 'nowrap',
133
- overflow: 'hidden',
134
- textOverflow: 'ellipsis', alignItems: 'flex-end', display: 'flex'
135
- }, children: sqd.name }), manageDefault && sqd.isDefault == 1 && _jsx(IconStar, { fontSize: 16, color: 'rgb(248, 215, 117)' })] }), _jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'flex-start', width: '100%' }, children: _jsx("p", { style: { fontSize: '0.9rem', overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis' }, children: sqd.description }) })] }), _jsxs("div", { style: { height: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'flex-start' }, children: [_jsx("div", { style: { height: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: sqd.isEasyWhere != 1 ? _jsx(IconAdvanced, { fontSize: 20 }) : _jsx(_Fragment, {}) }), _jsx("div", { style: { height: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: sqd.runSearchWhenSelected ?
136
- _jsx("div", { style: { width: '16px', height: '16px', borderRadius: '16px', backgroundColor: TMColors.info, color: 'white', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '1rem', fontWeight: 'bold' }, children: _jsx(IconLightningFill, { fontSize: 12, color: 'rgb(224, 194, 43)' }) })
137
- : _jsx(_Fragment, {}) })] }), selectedItem?.id == sqd.id &&
138
- _jsx("div", { style: { width: '24px', height: '24px', borderRadius: '24px', backgroundColor: 'rgba(243, 152, 119, .8)', boxShadow: '1px 2px 2px #00000050', position: 'absolute', top: '-2px', right: '-5px', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '1rem', fontWeight: 'bold' }, 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 &&
146
+ textOverflow: 'ellipsis',
147
+ color: TMColors.primaryColor,
148
+ paddingRight: '18px'
149
+ }, children: sqd.name }), manageDefault && sqd.isDefault == 1 && _jsx(IconStar, { fontSize: 16, color: 'rgb(248, 215, 117)' })] }), selectedItem?.id == sqd.id &&
150
+ _jsx("div", { style: {
151
+ width: '24px',
152
+ height: '24px',
153
+ borderRadius: '24px',
154
+ position: 'absolute',
155
+ top: '-1px',
156
+ right: '0px',
157
+ display: 'flex',
158
+ alignItems: 'center',
159
+ justifyContent: 'center',
160
+ fontSize: '1rem',
161
+ fontWeight: 'bold'
162
+ }, children: _jsx(IconApply, { fontSize: 24, color: 'green' }) }), _jsx(StyledPipe, {}), _jsx(SavedQueryContexMenu, { sqd: sqd, manageDefault: manageDefault, setDefaultAsync: () => setDefaultSQDAsync(sqd), deleteAsync: () => deleteSQDAsync(sqd), favManageAsync: () => favManageSQDAsync(sqd) })] }, sqd.id))) }), dataSource.length > initialSQDsMaxItems && searchText.length <= 0 &&
139
163
  _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 ?
140
164
  _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}` }) }) :
141
165
  _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) })] }));
@@ -10,6 +10,7 @@ import TMDataGrid from '../../base/TMDataGrid';
10
10
  import TMLayoutContainer, { TMLayoutItem } from '../../base/TMLayout';
11
11
  import TMPanel from '../../base/TMPanel';
12
12
  import TMTidViewer from '../../viewers/TMTidViewer';
13
+ import { TMColors } from '../../../utils/theme';
13
14
  const TMTreeSelector = ({ layoutMode = LayoutModes.Update, onSelectedTIDChanged, onClose }) => {
14
15
  const [trees, setTrees] = useState([]);
15
16
  const [treeItems, setTreeItems] = useState([]);
@@ -60,7 +61,7 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, onSelectedTIDChanged,
60
61
  const renderCell = (data) => {
61
62
  let treeItem = data.data;
62
63
  if (treeItem.type == TreeItemTypes.DcmtType)
63
- return (_jsx(TMTidViewer, { tid: treeItem.tid, showIcon: true }));
64
+ return (_jsx(TMTidViewer, { tid: treeItem.tid, color: TMColors.primaryColor, showIcon: false }));
64
65
  else
65
66
  return (_jsxs(StyledDivHorizontal, { style: { gap: 5 }, children: [_jsx(IconFolder, { fontSize: 18 }), _jsx("p", { children: treeItem.nameLoc })] }));
66
67
  };
@@ -16,6 +16,7 @@ const StyledRecentTidItem = styled.div `
16
16
  min-width: 0;
17
17
  padding: 10px;
18
18
  position: relative;
19
+
19
20
  &:hover {
20
21
  cursor: pointer;
21
22
  }
@@ -29,8 +30,15 @@ const StyledPipe = styled.div `
29
30
  const iconDelete = () => ReactDOMServer.renderToString(_jsx(IconDelete, {}));
30
31
  const TMRecentsManager = ({ deviceType, mruTIDs, currentMruTID, onSelectedTID, onDeletedTID }) => {
31
32
  const [showDcmtTypeChooser, setShowDcmtTypeChooser] = useState(false);
32
- return (_jsxs(_Fragment, { children: [_jsxs("div", { style: { overflowY: deviceType === DeviceType.MOBILE ? 'auto' : undefined, display: 'flex', flexDirection: 'column', padding: '5px' }, children: [_jsxs(StyledRecentTidItem, { id: `tid-${0}`, onClick: () => { setShowDcmtTypeChooser(true); }, children: [_jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', width: '100%' }, children: _jsx("p", { style: { color: TMColors.primaryColor, fontSize: '1rem', fontWeight: 600, textOverflow: 'ellipsis' }, children: `${SDKUI_Localizator.AllDcmtTypes} (${DcmtTypeListCacheService.CacheCount(true)})` }) }), _jsx(StyledPipe, {})] }, 0), mruTIDs.map((tid) => {
33
- return (_jsxs(StyledRecentTidItem, { id: `tid-${tid}`, onClick: () => { onSelectedTID?.(tid); }, children: [_jsx("div", { style: { display: 'flex', justifyContent: 'center', width: '100%' }, children: _jsx(TMTidViewer, { tid: tid, color: TMColors.primaryColor }) }), _jsx(StyledPipe, {}), _jsx(ContextMenu, { dataSource: [{ text: SDKUI_Localizator.Remove, icon: iconDelete(), }], target: `#tid-${tid}`, onItemClick: () => { onDeletedTID?.(tid); } }), currentMruTID == tid &&
33
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { style: { overflowY: deviceType === DeviceType.MOBILE ? 'auto' : undefined, display: 'flex', flexDirection: 'column', padding: '5px' }, children: [_jsxs(StyledRecentTidItem, { id: `tid-${0}`, onClick: () => { setShowDcmtTypeChooser(true); }, children: [_jsx("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', width: '100%' }, children: _jsx("p", { style: {
34
+ color: TMColors.primaryColor,
35
+ fontSize: '1rem',
36
+ fontWeight: 600,
37
+ whiteSpace: 'nowrap',
38
+ overflow: 'hidden',
39
+ textOverflow: 'ellipsis'
40
+ }, children: `${SDKUI_Localizator.AllDcmtTypes} (${DcmtTypeListCacheService.CacheCount(true)})` }) }), _jsx(StyledPipe, {})] }, 0), mruTIDs.map((tid) => {
41
+ return (_jsxs(StyledRecentTidItem, { id: `tid-${tid}`, onClick: () => { onSelectedTID?.(tid); }, children: [_jsx("div", { style: { display: 'flex', justifyContent: 'center', width: '100%' }, children: _jsx(TMTidViewer, { tid: tid, color: TMColors.primaryColor, showIcon: false }) }), _jsx(StyledPipe, {}), _jsx(ContextMenu, { dataSource: [{ text: SDKUI_Localizator.Remove, icon: iconDelete(), }], target: `#tid-${tid}`, onItemClick: () => { onDeletedTID?.(tid); } }), currentMruTID == tid &&
34
42
  _jsx("div", { style: {
35
43
  width: '24px',
36
44
  height: '24px',