@topconsultnpm/sdkui-react-beta 6.13.13 → 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,9 @@
1
+ import { TMPanelManagerMatrixColumn, TMPanelManagerToolbar } from './TMPanelManagerMatrixUtils';
2
+ export interface TMPanelManagerMatrixProps {
3
+ panelMatrixMap: Map<string, TMPanelManagerMatrixColumn>;
4
+ toolbar?: TMPanelManagerToolbar;
5
+ initialMobilePanelID?: string;
6
+ gutters?: number;
7
+ }
8
+ declare const TMPanelManagerMatrix: (props: TMPanelManagerMatrixProps) => import("react/jsx-runtime").JSX.Element;
9
+ export default TMPanelManagerMatrix;
@@ -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
+ };
@@ -14,6 +14,8 @@ export * from './base/TMToolbarCard';
14
14
  export * from './base/TMRightSidebar';
15
15
  export * from './base/TMTreeView';
16
16
  export * from './base/TMPanel';
17
+ export { default as TMPanelManagerMatrix } from './base/TMPanelManagerMatrix';
18
+ export * from './base/TMPanelManagerMatrixUtils';
17
19
  export { default as CounterBar } from './base/TMCounterBar';
18
20
  export { default as TMProgressBar } from './base/TMProgressBar';
19
21
  export { default as TMSpinner } from './base/TMSpinner';
@@ -15,6 +15,8 @@ export * from './base/TMToolbarCard';
15
15
  export * from './base/TMRightSidebar';
16
16
  export * from './base/TMTreeView';
17
17
  export * from './base/TMPanel';
18
+ export { default as TMPanelManagerMatrix } from './base/TMPanelManagerMatrix';
19
+ export * from './base/TMPanelManagerMatrixUtils';
18
20
  export { default as CounterBar } from './base/TMCounterBar';
19
21
  export { default as TMProgressBar } from './base/TMProgressBar';
20
22
  export { default as TMSpinner } from './base/TMSpinner';
@@ -242,6 +242,7 @@ export declare class SDKUI_Localizator {
242
242
  static get NoDcmtFound(): "Kein Dokument gefunden" | "No documents found" | "Ningún documento encontrado" | "Pas de documents trouvés" | "Nenhum documento encontrado" | "Nessun documento trovato";
243
243
  static get NoMessages(): string;
244
244
  static get NoMessagesFound(): string;
245
+ static get NoPanelSelected(): string;
245
246
  static get NoResultsFound(): string;
246
247
  static get NoneSelection(): "Keine Auswahl" | "No selection" | "Ninguna selección" | "Pas de sélections" | "Nenhuma seleção" | "Nessuna selezione";
247
248
  static get OfSystem(): "Des Systems" | "Of system" | "Del sistema" | "Du système" | "Do sistema" | "Di sistema";
@@ -2371,6 +2371,16 @@ export class SDKUI_Localizator {
2371
2371
  default: return "Nessun messaggio trovato";
2372
2372
  }
2373
2373
  }
2374
+ static get NoPanelSelected() {
2375
+ switch (this._cultureID) {
2376
+ case CultureIDs.De_DE: return "Kein Panel ausgewählt";
2377
+ case CultureIDs.En_US: return "No panel selected";
2378
+ case CultureIDs.Es_ES: return "Ningún panel seleccionado";
2379
+ case CultureIDs.Fr_FR: return "Aucun panneau sélectionné";
2380
+ case CultureIDs.Pt_PT: return "Nenhum painel selecionado";
2381
+ default: return "Nessun pannello selezionato";
2382
+ }
2383
+ }
2374
2384
  static get NoResultsFound() {
2375
2385
  switch (this._cultureID) {
2376
2386
  case CultureIDs.De_DE: return "Kein Ergebnis gefunden";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react-beta",
3
- "version": "6.13.13",
3
+ "version": "6.13.14",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",