Optimize table view and export for software lists added. excelexport fixed - first line

This commit is contained in:
2026-09-24 11:38:40 +02:00
parent 80f6136399
commit 8de15f223c
16 changed files with 320 additions and 24 deletions
+68 -6
View File
@@ -165,14 +165,69 @@
return collator.compare(String(left.value), String(right.value));
}
function ensureStandardTableShell(table) {
table.classList.add('standard-data-table');
const shellSelector = '.standard-data-table-scroll, .table-scroll, .table-wrap, .sticky-table, .management-table-scroll';
const directParent = table.parentElement;
let shell = directParent?.matches(shellSelector) ? directParent : null;
if (!shell) {
const parent = table.parentNode;
if (!parent) return null;
shell = document.createElement('div');
shell.className = 'table-scroll standard-data-table-scroll';
parent.insertBefore(shell, table);
shell.appendChild(table);
} else {
shell.classList.add('standard-data-table-scroll');
}
return shell;
}
function ensureStableTableStorageKey(table) {
if (table.dataset.storageKey) return table.dataset.storageKey;
if (table.id) {
table.dataset.storageKey = table.id;
return table.id;
}
const tables = [...document.querySelectorAll('main table.data-table')];
const index = Math.max(0, tables.indexOf(table));
const key = `${window.location.pathname}:data-table-${index}`;
table.dataset.storageKey = key;
return key;
}
function initTable(table) {
const thead = table.tHead;
const tbody = table.tBodies[0];
if (!thead || !tbody || !thead.rows.length) return;
const tableShell = ensureStandardTableShell(table);
ensureStableTableStorageKey(table);
if (table.dataset.tableToolsReady === '1') return;
const headerRow = thead.rows[0];
// Sticky title/filter rows and resizable columns must coexist. Sticky is
// applied to the TH cells in CSS; this custom property supplies the exact
// offset for the filter row from the rendered title-row height.
function updateStickyHeaderMetrics() {
const measured = headerRow.getBoundingClientRect().height || headerRow.offsetHeight || 0;
if (measured > 0) {
table.style.setProperty('--table-title-row-height', `${Math.ceil(measured)}px`);
}
}
if (typeof ResizeObserver === 'function') {
const observer = new ResizeObserver(() => updateStickyHeaderMetrics());
observer.observe(headerRow);
table._stickyHeaderResizeObserver = observer;
}
window.addEventListener('resize', updateStickyHeaderMetrics);
// Add a purely visual row-number column before every real table column.
// It is recalculated after filtering, sorting and partial server reloads and
// therefore never represents a database identifier.
@@ -188,7 +243,7 @@
}
const numberHeader = headerRow.querySelector('th[data-row-number-column="1"]');
const rowNumberStoragePart = table.dataset.storageKey || table.id || window.location.pathname;
const rowNumberStoragePart = ensureStableTableStorageKey(table);
const rowNumberWidthKey = `table:${rowNumberStoragePart}:row-number-width`;
const defaultRowNumberWidth = 64;
const minimumRowNumberWidth = 48;
@@ -1189,10 +1244,15 @@
});
thead.appendChild(filterRow);
if (isAssetTable) {
installColumnResizers();
applyStoredColumnWidths();
}
updateStickyHeaderMetrics();
requestAnimationFrame(updateStickyHeaderMetrics);
// All AssetManager data tables use the same resize implementation.
// This keeps width changes, table growth and user-state persistence
// identical across Assets, Software, Jobs, Settings and detail lists.
installColumnResizers();
applyStoredColumnWidths();
requestAnimationFrame(updateStickyHeaderMetrics);
// Editable cells are always read live, so changed values immediately
// participate in filtering without a stale cache.
@@ -1210,6 +1270,7 @@
table.assetUpdateRowNumbers = updateRowNumbers;
table.assetRebuildFilterCache = rebuildMissingCellKeys;
table.assetApplyStoredColumnWidths = applyStoredColumnWidths;
table.assetUpdateStickyHeaderMetrics = updateStickyHeaderMetrics;
table.dataset.tableToolsReady = '1';
ensureFilterStatus();
@@ -1352,7 +1413,7 @@
const initializeTableTools = () => {
document.querySelectorAll('table.data-table').forEach(initTable);
document.querySelectorAll('main table:not(#asset-table):not([data-column-resize="off"])').forEach(initUniversalTableResize);
document.querySelectorAll('main table:not(.data-table):not([data-column-resize="off"])').forEach(initUniversalTableResize);
};
if (uiState?.ready) uiState.ready.finally(initializeTableTools);
else initializeTableTools();
@@ -1369,6 +1430,7 @@
}
table.assetUpdateRowNumbers?.();
table.assetApplyStoredColumnWidths?.();
requestAnimationFrame(() => table.assetUpdateStickyHeaderMetrics?.());
}
});
})();