Initialer Import des AssetManagers
This commit is contained in:
@@ -0,0 +1,238 @@
|
||||
(() => {
|
||||
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();
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user