(() => { const perf = window.AssetPerf; perf?.start('list-tools:gesamtes Modul'); const tables = new Map(); function isDataRow(row) { if (!row || row.closest('thead')) return false; if (row.classList.contains('column-filter-row') || row.classList.contains('filter-row')) return false; if (row.querySelector('.empty-state')) return false; return true; } function isVisible(row) { if (row.hidden || row.classList.contains('hidden')) return false; return true; } function countTarget(table, index) { const toolbar = table.closest('main')?.querySelector('.toolbar'); if (!toolbar) return null; let actions = toolbar.querySelector('.toolbar-actions'); if (!actions) { actions = document.createElement('div'); actions.className = 'toolbar-actions'; toolbar.appendChild(actions); } let target = actions.querySelector(`[data-table-count-for="${index}"]`); if (!target) { target = document.createElement('span'); target.className = 'record-count'; target.dataset.tableCountFor = String(index); actions.insertBefore(target, actions.firstChild); } return target; } function update(table, index) { const updateStarted = performance.now(); const rows = [...table.querySelectorAll('tbody tr')].filter(isDataRow); const visible = rows.filter(isVisible).length; const target = countTarget(table, index); if (target) { const template = document.body.dataset.recordCountTemplate || 'Angezeigt: {visible} von {total} Datensätzen'; target.textContent = template .replace('{visible}', String(visible)) .replace('{total}', String(rows.length)); target.title = document.body.dataset.recordCountTitle || ''; } window.dispatchEvent(new CustomEvent('asset-list-count-updated', { detail: { table, visible, total: rows.length } })); const duration = performance.now() - updateStarted; const logger = duration >= 50 ? console.warn : console.debug; logger('[AssetManager][Performance]', 'list-tools:update', { dauer_ms: Math.round(duration * 10) / 10, sichtbar: visible, gesamt: rows.length }); } function schedule(table, index) { const state = tables.get(table) || {}; if (state.frame) cancelAnimationFrame(state.frame); state.frame = requestAnimationFrame(() => { state.frame = null; update(table, index); }); tables.set(table, state); } function initialize() { document.querySelectorAll('table.data-table').forEach((table, index) => { if (table.dataset.listToolsReady === '1') { schedule(table, index); return; } table.dataset.listToolsReady = '1'; schedule(table, index); table.addEventListener('input', () => setTimeout(() => schedule(table, index), 0)); table.addEventListener('change', () => setTimeout(() => schedule(table, index), 0)); const body = table.tBodies[0]; if (body) { const observer = new MutationObserver(mutations => { const started = performance.now(); schedule(table, index); const duration = performance.now() - started; console.debug('[AssetManager][Performance]', 'list-tools:MutationObserver', { dauer_ms: Math.round(duration * 10) / 10, mutationen: mutations.length }); }); observer.observe(body, { subtree: true, childList: true, attributes: true, attributeFilter: ['hidden', 'style', 'class'] }); } }); if (document.getElementById('asset-table')) { document.body.classList.add('single-scroll-list'); } else { document.body.classList.remove('single-scroll-list'); } } document.addEventListener('input', () => { document.querySelectorAll('table.data-table').forEach((table, index) => { setTimeout(() => schedule(table, index), 0); }); }); document.addEventListener('change', () => { document.querySelectorAll('table.data-table').forEach((table, index) => { setTimeout(() => schedule(table, index), 0); }); }); window.addEventListener('asset-table-filter-changed', initialize); window.addEventListener('asset-table-content-reloaded', initialize); if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initialize); } else { initialize(); } perf?.end('list-tools:gesamtes Modul'); })();