@schneideress/dashboardframework 20.0.29 → 20.0.31
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.
|
@@ -4977,29 +4977,38 @@ class RADashboardArea {
|
|
|
4977
4977
|
this.initialWidgetCount++ : null;
|
|
4978
4978
|
}
|
|
4979
4979
|
/**
|
|
4980
|
-
* Whether expanded view is active.
|
|
4981
|
-
* Handles bulkActionData as string (from API) or object (from event).
|
|
4980
|
+
* Whether expanded view is active. URL `?expanded=true` is checked first; then bulk action (works in normal browser and kiosk).
|
|
4981
|
+
* Handles bulkActionData as string (from API) or object (from event).
|
|
4982
4982
|
*/
|
|
4983
4983
|
isExpandedView() {
|
|
4984
|
-
|
|
4985
|
-
|
|
4986
|
-
const
|
|
4987
|
-
|
|
4988
|
-
: this.bulkActionData;
|
|
4989
|
-
if (data?.allSelections?.expandedView === true)
|
|
4984
|
+
try {
|
|
4985
|
+
if (typeof window !== 'undefined' && window.location?.search) {
|
|
4986
|
+
const fromUrl = new URLSearchParams(window.location.search).get('expanded') === 'true';
|
|
4987
|
+
if (fromUrl) {
|
|
4990
4988
|
return true;
|
|
4989
|
+
}
|
|
4991
4990
|
}
|
|
4992
|
-
catch (_) {
|
|
4993
|
-
// ignore parse errors
|
|
4994
|
-
}
|
|
4995
4991
|
}
|
|
4996
|
-
|
|
4992
|
+
catch (_) {
|
|
4993
|
+
// ignore URL parse errors
|
|
4994
|
+
}
|
|
4995
|
+
if (!this.bulkActionData)
|
|
4996
|
+
return false;
|
|
4997
|
+
try {
|
|
4998
|
+
const data = typeof this.bulkActionData === 'string'
|
|
4999
|
+
? JSON.parse(this.bulkActionData)
|
|
5000
|
+
: this.bulkActionData;
|
|
5001
|
+
return data?.allSelections?.expandedView === true;
|
|
5002
|
+
}
|
|
5003
|
+
catch (_) {
|
|
5004
|
+
return false;
|
|
5005
|
+
}
|
|
4997
5006
|
}
|
|
4998
5007
|
dataLoaded(widgetInfo) {
|
|
4999
5008
|
setTimeout(() => {
|
|
5000
5009
|
this.currentLoadingCount--;
|
|
5001
5010
|
}, 100);
|
|
5002
|
-
// For expanded view, override widget dimensions after data loads (from bulk action
|
|
5011
|
+
// For expanded view, override widget dimensions after data loads (from bulk action)
|
|
5003
5012
|
if (this.isExpandedView() && widgetInfo && widgetInfo.widgetInstanceId) {
|
|
5004
5013
|
this.overrideWidgetDimensions(widgetInfo);
|
|
5005
5014
|
}
|
|
@@ -5040,49 +5049,59 @@ class RADashboardArea {
|
|
|
5040
5049
|
}
|
|
5041
5050
|
return;
|
|
5042
5051
|
}
|
|
5043
|
-
//
|
|
5044
|
-
const
|
|
5045
|
-
|
|
5052
|
+
// Prefer the real data table (ra-grid) so we do not pick unrelated tables when present
|
|
5053
|
+
const dataTable = element.querySelector('table.ra-grid')
|
|
5054
|
+
?? element.querySelector('table');
|
|
5055
|
+
const tbody = dataTable?.querySelector('tbody')
|
|
5056
|
+
?? element.querySelector('tbody');
|
|
5057
|
+
const table = dataTable;
|
|
5046
5058
|
const wcBody = element.querySelector('.wcBody');
|
|
5047
5059
|
const wc = element.querySelector('.wc');
|
|
5048
5060
|
const kendoGridContent = element.querySelector('.k-grid-content');
|
|
5049
5061
|
const kendoGridTable = element.querySelector('.k-grid-table');
|
|
5062
|
+
const addVisibleFilterHeights = (base) => {
|
|
5063
|
+
let h = base;
|
|
5064
|
+
element.querySelectorAll('.ra-widget-filter').forEach((node) => {
|
|
5065
|
+
const fe = node;
|
|
5066
|
+
if (fe.offsetHeight > 0) {
|
|
5067
|
+
h += fe.offsetHeight;
|
|
5068
|
+
}
|
|
5069
|
+
});
|
|
5070
|
+
return h;
|
|
5071
|
+
};
|
|
5050
5072
|
// Measure the actual content height - try multiple strategies to get accurate measurement
|
|
5051
5073
|
let contentHeight = 0;
|
|
5052
5074
|
let measuredElement = null;
|
|
5053
|
-
// Strategy 1:
|
|
5054
|
-
if (
|
|
5075
|
+
// Strategy 1: HTML table / ra-grid — use full table box (thead + tbody), not tbody only (avoids clipping header row)
|
|
5076
|
+
if (table && table.offsetHeight > 0) {
|
|
5077
|
+
measuredElement = table;
|
|
5078
|
+
contentHeight = addVisibleFilterHeights(table.offsetHeight);
|
|
5079
|
+
}
|
|
5080
|
+
// Strategy 2: tbody only (fallback if table not measurable)
|
|
5081
|
+
else if (tbody) {
|
|
5055
5082
|
measuredElement = tbody;
|
|
5056
|
-
// Count actual rows and calculate height
|
|
5057
5083
|
const rows = tbody.querySelectorAll('tr');
|
|
5058
5084
|
if (rows.length > 0) {
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
// Use scrollHeight if available, otherwise use estimated
|
|
5065
|
-
contentHeight = Math.max(tbody.scrollHeight, estimatedHeight);
|
|
5085
|
+
let totalRowHeight = 0;
|
|
5086
|
+
rows.forEach((row) => {
|
|
5087
|
+
totalRowHeight += row.offsetHeight || 30;
|
|
5088
|
+
});
|
|
5089
|
+
contentHeight = addVisibleFilterHeights(totalRowHeight);
|
|
5066
5090
|
}
|
|
5067
5091
|
else {
|
|
5068
|
-
contentHeight = tbody.scrollHeight;
|
|
5092
|
+
contentHeight = addVisibleFilterHeights(tbody.scrollHeight);
|
|
5069
5093
|
}
|
|
5070
5094
|
}
|
|
5071
|
-
// Strategy
|
|
5095
|
+
// Strategy 3: Measure Kendo grid content
|
|
5072
5096
|
else if (kendoGridContent) {
|
|
5073
5097
|
measuredElement = kendoGridContent;
|
|
5074
|
-
contentHeight = kendoGridContent.scrollHeight;
|
|
5098
|
+
contentHeight = addVisibleFilterHeights(kendoGridContent.scrollHeight);
|
|
5075
5099
|
// Also check the table inside
|
|
5076
5100
|
if (kendoGridTable) {
|
|
5077
5101
|
const tableHeight = kendoGridTable.scrollHeight;
|
|
5078
|
-
contentHeight = Math.max(contentHeight, tableHeight);
|
|
5102
|
+
contentHeight = Math.max(contentHeight, addVisibleFilterHeights(tableHeight));
|
|
5079
5103
|
}
|
|
5080
5104
|
}
|
|
5081
|
-
// Strategy 3: Measure table
|
|
5082
|
-
else if (table) {
|
|
5083
|
-
measuredElement = table;
|
|
5084
|
-
contentHeight = table.scrollHeight;
|
|
5085
|
-
}
|
|
5086
5105
|
// Strategy 4: Measure widget content
|
|
5087
5106
|
else if (wc) {
|
|
5088
5107
|
measuredElement = wc;
|
|
@@ -5109,16 +5128,22 @@ class RADashboardArea {
|
|
|
5109
5128
|
// Try offsetHeight
|
|
5110
5129
|
contentHeight = Math.max(contentHeight, offsetH);
|
|
5111
5130
|
}
|
|
5112
|
-
//
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5131
|
+
// Sum of tr heights often exceeds table.offsetHeight for many rows (borders/spacing), which grows extra whitespace.
|
|
5132
|
+
// When the table already laid out with a real box height, trust that measurement only.
|
|
5133
|
+
const tableBoxHeightTrusted = !!(table && table.offsetHeight > 0);
|
|
5134
|
+
if (!tableBoxHeightTrusted) {
|
|
5135
|
+
const rowHost = table || tbody;
|
|
5136
|
+
if (rowHost) {
|
|
5137
|
+
const hostEl = rowHost;
|
|
5138
|
+
const allRows = hostEl.querySelectorAll('tr');
|
|
5139
|
+
if (allRows.length > 0) {
|
|
5140
|
+
let totalRowHeight = 0;
|
|
5141
|
+
allRows.forEach((row) => {
|
|
5142
|
+
totalRowHeight += row.offsetHeight || 30;
|
|
5143
|
+
});
|
|
5144
|
+
const withFilters = addVisibleFilterHeights(totalRowHeight);
|
|
5145
|
+
contentHeight = Math.max(contentHeight, withFilters);
|
|
5146
|
+
}
|
|
5122
5147
|
}
|
|
5123
5148
|
}
|
|
5124
5149
|
}
|
|
@@ -5126,8 +5151,8 @@ class RADashboardArea {
|
|
|
5126
5151
|
const header = element.querySelector('.wcheader');
|
|
5127
5152
|
const headerHeight = header ? header.offsetHeight : 46;
|
|
5128
5153
|
// Calculate total height needed (content + header + padding)
|
|
5129
|
-
//
|
|
5130
|
-
const padding =
|
|
5154
|
+
// Slightly less vertical slack for tall tables (grid ceil already adds a partial row).
|
|
5155
|
+
const padding = contentHeight > 380 ? 28 : 36;
|
|
5131
5156
|
const totalHeight = contentHeight + headerHeight + padding;
|
|
5132
5157
|
// Check if content is loaded (reasonable height)
|
|
5133
5158
|
// For expanded view, we expect significant content
|
|
@@ -5137,13 +5162,12 @@ class RADashboardArea {
|
|
|
5137
5162
|
this.measureAndUpdateWidgetDimensions(gridsterItem, attempt + 1, maxAttempts);
|
|
5138
5163
|
return;
|
|
5139
5164
|
}
|
|
5140
|
-
// Calculate rows needed based on grid cell height
|
|
5141
|
-
//
|
|
5142
|
-
const
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
const
|
|
5146
|
-
const newRows = Math.max(Math.ceil(bufferedRows), 4);
|
|
5165
|
+
// Calculate rows needed based on grid cell height.
|
|
5166
|
+
// Blend pixel + fractional cell buffer; keep a bit more for short content to avoid last-row clipping.
|
|
5167
|
+
const bufferPx = contentHeight > 380
|
|
5168
|
+
? Math.max(12, this.gridcellHeight * 0.35)
|
|
5169
|
+
: Math.max(16, this.gridcellHeight * 0.5);
|
|
5170
|
+
const newRows = Math.max(Math.ceil((totalHeight + bufferPx) / this.gridcellHeight), 2);
|
|
5147
5171
|
// For expanded view, use full available width (no spacing needed since widgets stack vertically)
|
|
5148
5172
|
const maxCols = this.responsiveService.maxColsDesktop || 12;
|
|
5149
5173
|
const newCols = maxCols; // Full width
|
|
@@ -5184,8 +5208,12 @@ class RADashboardArea {
|
|
|
5184
5208
|
}
|
|
5185
5209
|
if (el) {
|
|
5186
5210
|
const wcBody = el.querySelector('.wcBody');
|
|
5211
|
+
const tableContainer = el.querySelector('.table-container');
|
|
5212
|
+
const verifyTable = el.querySelector('table.ra-grid')
|
|
5213
|
+
?? el.querySelector('table');
|
|
5187
5214
|
const tbody = el.querySelector('tbody');
|
|
5188
|
-
|
|
5215
|
+
// ra-grid scrolls inside .table-container; measuring tbody alone can miss real overflow
|
|
5216
|
+
const contentEl = tableContainer || verifyTable || tbody || wcBody || el;
|
|
5189
5217
|
// Check if there's scrolling (scrollHeight > clientHeight)
|
|
5190
5218
|
if (contentEl && contentEl.scrollHeight > contentEl.clientHeight + 10) {
|
|
5191
5219
|
// Still has scrolling, need more height
|
|
@@ -5203,6 +5231,23 @@ class RADashboardArea {
|
|
|
5203
5231
|
setTimeout(() => this.setAreaHeight(), 100);
|
|
5204
5232
|
}
|
|
5205
5233
|
}
|
|
5234
|
+
else if (contentEl) {
|
|
5235
|
+
// If there is clear spare space, shrink one row to avoid oversized blank area.
|
|
5236
|
+
// Keep this conservative to prevent oscillation/flapping.
|
|
5237
|
+
const spareHeight = contentEl.clientHeight - contentEl.scrollHeight;
|
|
5238
|
+
const canShrink = spareHeight > (this.gridcellHeight * 0.8) && gridsterItem.rows > 2;
|
|
5239
|
+
if (canShrink) {
|
|
5240
|
+
gridsterItem.rows = gridsterItem.rows - 1;
|
|
5241
|
+
if (gridsterItem.widgetInfo) {
|
|
5242
|
+
gridsterItem.widgetInfo.height = gridsterItem.rows;
|
|
5243
|
+
}
|
|
5244
|
+
this.widgetList = [...this.widgetList];
|
|
5245
|
+
if (this.options && this.options.api) {
|
|
5246
|
+
this.options.api?.optionsChanged();
|
|
5247
|
+
}
|
|
5248
|
+
setTimeout(() => this.setAreaHeight(), 100);
|
|
5249
|
+
}
|
|
5250
|
+
}
|
|
5206
5251
|
}
|
|
5207
5252
|
// Continue with normal retry logic
|
|
5208
5253
|
this.measureAndUpdateWidgetDimensions(gridsterItem, attempt + 1, maxAttempts);
|