114 lines
4.0 KiB
JavaScript
114 lines
4.0 KiB
JavaScript
(() => {
|
|
const perf = window.AssetPerf;
|
|
perf?.start('browser-state:gesamtes Modul');
|
|
const persistent = document.body?.dataset.persistBrowserState === 'true';
|
|
const storage = persistent ? window.localStorage : window.sessionStorage;
|
|
const prefix = 'assetmanager:';
|
|
|
|
const api = {
|
|
persistent,
|
|
get(key) {
|
|
try { return storage.getItem(prefix + key); } catch (_) { return null; }
|
|
},
|
|
set(key, value) {
|
|
try { storage.setItem(prefix + key, value); } catch (_) {}
|
|
},
|
|
remove(key) {
|
|
try { storage.removeItem(prefix + key); } catch (_) {}
|
|
}
|
|
};
|
|
window.AssetBrowserState = api;
|
|
|
|
function tableKey(table, index) {
|
|
return table.dataset.storageKey || table.id || `table-${location.pathname}-${index}`;
|
|
}
|
|
|
|
function filterControls(table) {
|
|
return [...table.querySelectorAll('thead input, thead select')].filter(control => {
|
|
const type = (control.type || '').toLowerCase();
|
|
return !['checkbox', 'radio', 'button', 'submit'].includes(type);
|
|
});
|
|
}
|
|
|
|
function controlKey(control, index) {
|
|
const cell = control.closest('th');
|
|
return control.name || control.dataset.field || cell?.dataset.field || `filter-${index}`;
|
|
}
|
|
|
|
function restoreTable(table, index) {
|
|
if (table.dataset.browserStateReady === '1') return;
|
|
if (table.dataset.serverFilters === '1') {
|
|
table.dataset.browserStateReady = '1';
|
|
return;
|
|
}
|
|
const restoreStarted = performance.now();
|
|
const controls = filterControls(table);
|
|
if (!controls.length) return;
|
|
|
|
table.dataset.browserStateReady = '1';
|
|
const key = `${tableKey(table, index)}:filters`;
|
|
let values = {};
|
|
try { values = JSON.parse(api.get(key) || '{}') || {}; } catch (_) {}
|
|
|
|
controls.forEach((control, controlIndex) => {
|
|
const field = controlKey(control, controlIndex);
|
|
if (Object.prototype.hasOwnProperty.call(values, field)) {
|
|
// Restore without dispatching one input/change pair per column.
|
|
control.value = values[field];
|
|
}
|
|
const save = () => {
|
|
const current = {};
|
|
filterControls(table).forEach((item, itemIndex) => {
|
|
current[controlKey(item, itemIndex)] = item.value;
|
|
});
|
|
api.set(key, JSON.stringify(current));
|
|
};
|
|
control.addEventListener('input', save);
|
|
control.addEventListener('change', save);
|
|
});
|
|
|
|
// One filtering pass after every stored value is in place.
|
|
if (typeof table.assetApplyFilters === 'function') {
|
|
table.assetApplyFilters();
|
|
}
|
|
table.dataset.browserStateRestored = '1';
|
|
window.dispatchEvent(new CustomEvent('asset-table-state-ready', { detail: { table } }));
|
|
const duration = performance.now() - restoreStarted;
|
|
const logger = duration >= 50 ? console.warn : console.debug;
|
|
logger('[AssetManager][Performance]', 'browser-state:restoreTable', {
|
|
dauer_ms: Math.round(duration * 10) / 10,
|
|
filter: controls.length,
|
|
gespeicherte_werte: Object.keys(values).length
|
|
});
|
|
}
|
|
|
|
function initializeTables() {
|
|
document.querySelectorAll('table').forEach(restoreTable);
|
|
}
|
|
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', initializeTables, { once: true });
|
|
} else {
|
|
initializeTables();
|
|
}
|
|
|
|
// Filter controls are added by table-tools.js. Initialize only on its explicit
|
|
// completion event instead of observing every DOM mutation in the document.
|
|
window.addEventListener('asset-table-structure-ready', initializeTables);
|
|
|
|
// A programmatic reset does not emit input/change events. Remove the
|
|
// corresponding persisted filter state explicitly so it cannot return after
|
|
// a page refresh.
|
|
window.addEventListener('asset-table-filters-cleared', event => {
|
|
const table = event.detail?.table;
|
|
if (!(table instanceof HTMLTableElement)) return;
|
|
|
|
const tables = [...document.querySelectorAll('table')];
|
|
const index = tables.indexOf(table);
|
|
const key = `${tableKey(table, index >= 0 ? index : 0)}:filters`;
|
|
api.remove(key);
|
|
});
|
|
|
|
perf?.end('browser-state:gesamtes Modul');
|
|
})();
|