(() => { function init() { const table = document.getElementById('asset-table'); if (!table || table.dataset.columnManagerReady === '1') return; table.dataset.columnManagerReady = '1'; const scroll = document.getElementById('asset-table-scroll'); const topScroll = document.getElementById('asset-table-scroll-top'); const topInner = topScroll?.firstElementChild; const dialog = document.getElementById('column-settings-dialog'); const list = document.getElementById('column-settings-list'); const openButton = document.getElementById('column-settings-button'); const showAllButton = document.getElementById('show-all-columns'); const resetButton = document.getElementById('reset-columns'); const menu = document.getElementById('column-context-menu'); const hideMenuButton = document.getElementById('context-hide-column'); const openMenuButton = document.getElementById('context-open-columns'); const keyBase = table.dataset.storageKey || 'asset-columns-all'; const hiddenKey = `${keyBase}-hidden`; const styleId = `asset-column-visibility-${keyBase.replace(/[^a-zA-Z0-9_-]/g, '-')}`; let contextField = null; let resizeFrame = 0; let lastContainerWidth = -1; const headers = () => [...table.querySelectorAll('thead tr:first-child th[data-field]')]; const fieldLabel = field => { const th = table.querySelector( `thead tr:first-child th[data-field="${CSS.escape(field)}"]` ); return th?.dataset.label || th?.textContent?.trim() || field; }; const allFields = () => headers().map(th => th.dataset.field); function getHidden() { try { const value = JSON.parse(window.AssetBrowserState?.get(hiddenKey) || '[]'); return Array.isArray(value) ? value : []; } catch (_) { return []; } } function setHidden(fields) { window.AssetBrowserState?.set(hiddenKey, JSON.stringify([...new Set(fields)])); } function columnWidth(header) { const configured = Number.parseInt(header.dataset.columnWidth || '', 10); return Number.isFinite(configured) && configured > 0 ? configured : 180; } function visibleTableWidth(hidden) { const fieldWidth = headers().reduce( (sum, header) => hidden.has(header.dataset.field) ? sum : sum + columnWidth(header), 0 ); const fixedWidth = Number.parseInt(table.dataset.fixedColumnWidth || '224', 10); return Math.max(640, fieldWidth + fixedWidth); } function updateTopScrollbar(tableWidth) { if (!scroll || !topScroll || !topInner) return; topInner.style.width = `${tableWidth}px`; topScroll.hidden = tableWidth <= scroll.clientWidth + 1; } function buildList() { if (!list) return; const hidden = new Set(getHidden()); const fragment = document.createDocumentFragment(); allFields().forEach(field => { const label = document.createElement('label'); label.className = 'checkbox-option'; const input = document.createElement('input'); input.type = 'checkbox'; input.checked = !hidden.has(field); input.addEventListener('change', () => input.checked ? showField(field) : hideField(field) ); const span = document.createElement('span'); span.textContent = fieldLabel(field); label.append(input, span); fragment.appendChild(label); }); list.replaceChildren(fragment); } function applyHidden() { const hidden = new Set(getHidden()); let style = document.getElementById(styleId); if (!style) { style = document.createElement('style'); style.id = styleId; document.head.appendChild(style); } style.textContent = [...hidden] .map(field => `#asset-table [data-field="${CSS.escape(field)}"]{display:none!important}` ) .join('\n'); const tableWidth = visibleTableWidth(hidden); table.style.width = `${tableWidth}px`; table.style.minWidth = `${tableWidth}px`; table.dataset.calculatedWidth = String(tableWidth); buildList(); requestAnimationFrame(() => updateTopScrollbar(tableWidth)); window.dispatchEvent(new Event('asset-table-columns-changed')); } function hideField(field) { if (!field) return; const hidden = getHidden(); const visibleFields = allFields().filter(item => !hidden.includes(item)); if (visibleFields.length <= 1 || hidden.includes(field)) return; hidden.push(field); setHidden(hidden); applyHidden(); } function showField(field) { setHidden(getHidden().filter(item => item !== field)); applyHidden(); } let syncing = false; scroll?.addEventListener('scroll', () => { if (syncing || !topScroll) return; syncing = true; topScroll.scrollLeft = scroll.scrollLeft; syncing = false; }, { passive: true }); topScroll?.addEventListener('scroll', () => { if (syncing || !scroll) return; syncing = true; scroll.scrollLeft = topScroll.scrollLeft; syncing = false; }, { passive: true }); headers().forEach(th => { th.addEventListener('contextmenu', event => { event.preventDefault(); contextField = th.dataset.field; if (!menu) return; menu.hidden = false; const maxX = window.innerWidth - menu.offsetWidth - 8; const maxY = window.innerHeight - menu.offsetHeight - 8; menu.style.left = `${Math.max(8, Math.min(event.clientX, maxX))}px`; menu.style.top = `${Math.max(8, Math.min(event.clientY, maxY))}px`; }); }); hideMenuButton?.addEventListener('click', () => { hideField(contextField); menu.hidden = true; }); openMenuButton?.addEventListener('click', () => { menu.hidden = true; buildList(); dialog?.showModal(); }); document.addEventListener('click', event => { if (menu && !menu.contains(event.target)) menu.hidden = true; }); document.addEventListener('keydown', event => { if (event.key === 'Escape' && menu) menu.hidden = true; }); openButton?.addEventListener('click', () => { buildList(); dialog?.showModal(); }); showAllButton?.addEventListener('click', () => { setHidden([]); applyHidden(); }); resetButton?.addEventListener('click', () => { setHidden([]); window.AssetBrowserState?.remove?.(keyBase); applyHidden(); window.location.reload(); }); function scheduleScrollbarUpdate() { cancelAnimationFrame(resizeFrame); resizeFrame = requestAnimationFrame(() => { const tableWidth = Number.parseInt(table.dataset.calculatedWidth || '0', 10); if (tableWidth) updateTopScrollbar(tableWidth); }); } window.addEventListener('resize', scheduleScrollbarUpdate, { passive: true }); if ('ResizeObserver' in window && scroll) { const resizeObserver = new ResizeObserver(entries => { const width = Math.round(entries[0]?.contentRect?.width || 0); if (width === lastContainerWidth) return; lastContainerWidth = width; scheduleScrollbarUpdate(); }); resizeObserver.observe(scroll); } window.addEventListener('asset-table-content-reloaded', event => { if (!event.detail?.table || event.detail.table === table) { applyHidden(); } }); applyHidden(); window.dispatchEvent(new CustomEvent('asset-table-columns-ready', { detail: { table } })); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init, { once: true }); } else { init(); } })();