Preserve tree scroll position
This commit is contained in:
+28
-10
@@ -375,6 +375,28 @@
|
||||
}
|
||||
}
|
||||
|
||||
function captureScrollState(root=document) {
|
||||
const trees=[...root.querySelectorAll('.bu-tree')].map((tree,index)=>({index,top:tree.scrollTop,left:tree.scrollLeft}));
|
||||
return {windowX:window.scrollX,windowY:window.scrollY,trees};
|
||||
}
|
||||
|
||||
function restoreScrollState(snapshot, root=document) {
|
||||
if(!snapshot) return;
|
||||
const apply=()=>{
|
||||
const trees=[...root.querySelectorAll('.bu-tree')];
|
||||
snapshot.trees.forEach(item=>{
|
||||
const tree=trees[item.index];
|
||||
if(tree) {
|
||||
tree.scrollTop=item.top;
|
||||
tree.scrollLeft=item.left;
|
||||
}
|
||||
});
|
||||
window.scrollTo(snapshot.windowX, snapshot.windowY);
|
||||
};
|
||||
apply();
|
||||
requestAnimationFrame(()=>{ apply(); setTimeout(apply, 0); });
|
||||
}
|
||||
|
||||
function renderDashboard() {
|
||||
const active = state.runs.filter(r => ['queued','running','paused'].includes(r.status)).length;
|
||||
const orderedRuns = newestRuns(state.runs);
|
||||
@@ -517,15 +539,13 @@
|
||||
function renderSourceBrowser() {
|
||||
const host=document.getElementById('bu-source-browser');
|
||||
if(!host) return;
|
||||
const windowX=window.scrollX, windowY=window.scrollY;
|
||||
const previousScroll=host.querySelector('.bu-tree')?.scrollTop || 0;
|
||||
const scrollSnapshot=captureScrollState(host);
|
||||
const chosen=state.backupSelections.length?state.backupSelections.map(path=>`<span class="bu-selection">${esc(path)}</span>`).join(''):'<span class="bu-muted">Keine Ordner ausgewählt.</span>';
|
||||
const tree=state.sourceTreeRoots.map(item=>sourceTreeNode(item,0)).join('');
|
||||
host.innerHTML=`<section class="bu-browser-card"><div class="bu-toolbar"><div><h3>Backup-Quellen auswählen</h3><span class="bu-muted">Ordner mit dem Dreieck aufklappen. Unterordner werden erst bei Bedarf geladen.</span></div><span class="bu-count">Ausgewählt: ${state.backupSelections.length}</span></div><div class="bu-selection-list">${chosen}</div><div class="bu-tree" role="tree">${tree||'<div class="bu-empty">Keine Ordner verfügbar.</div>'}</div></section>`;
|
||||
const treeElement=host.querySelector('.bu-tree'); if(treeElement) treeElement.scrollTop=previousScroll;
|
||||
host.querySelectorAll('.bu-source-select[data-partial="true"]').forEach(box=>{box.indeterminate=true;box.setAttribute('aria-checked','mixed');});
|
||||
enhanceTooltips(host);
|
||||
window.scrollTo(windowX, windowY);
|
||||
restoreScrollState(scrollSnapshot, host);
|
||||
}
|
||||
|
||||
async function toggleSourceTree(path, forceOpen=false) {
|
||||
@@ -569,13 +589,11 @@
|
||||
function renderDirectoryTree(key) {
|
||||
const tree=state.directoryTrees[key]; const host=document.getElementById(`bu-dir-tree-${key}`);
|
||||
if(!tree||!host) return;
|
||||
const windowX=window.scrollX, windowY=window.scrollY;
|
||||
const previousScroll=host.querySelector('.bu-tree')?.scrollTop || 0;
|
||||
const scrollSnapshot=captureScrollState(host);
|
||||
const html=tree.roots.map(item=>directoryTreeNode(key,item,0)).join('');
|
||||
host.innerHTML=`<section class="bu-browser-card"><div class="bu-toolbar"><div><h3>${esc(tree.title)}</h3><span class="bu-muted">Ordner mit dem Dreieck aufklappen und den gewünschten Zielordner auswählen.</span></div></div><div class="bu-tree" role="tree">${html||'<div class="bu-empty">Keine Ordner verfügbar.</div>'}</div></section>`;
|
||||
const treeElement=host.querySelector('.bu-tree'); if(treeElement) treeElement.scrollTop=previousScroll;
|
||||
enhanceTooltips(host);
|
||||
window.scrollTo(windowX, windowY);
|
||||
restoreScrollState(scrollSnapshot, host);
|
||||
}
|
||||
|
||||
async function toggleDirectoryTree(key, path, forceOpen=false) {
|
||||
@@ -755,9 +773,9 @@
|
||||
return state.config;
|
||||
}
|
||||
function renderPreservingScroll() {
|
||||
const windowX=window.scrollX, windowY=window.scrollY;
|
||||
const scrollSnapshot=captureScrollState(content);
|
||||
render();
|
||||
window.scrollTo(windowX, windowY);
|
||||
restoreScrollState(scrollSnapshot, content);
|
||||
}
|
||||
const lines = (value) => value.split('\n').map(v=>v.trim()).filter(Boolean);
|
||||
const runTime = run => new Date(run.createdAt || run.startedAt || run.finishedAt || 0).getTime() || 0;
|
||||
|
||||
Reference in New Issue
Block a user