From 5a00822294644e813332ca9fb8ca9bc66202b7fc Mon Sep 17 00:00:00 2001 From: x12sa Date: Sun, 5 Jul 2026 09:06:12 +0200 Subject: [PATCH] webpage_generator: tomo queue - don't reopen a manually collapsed running job renderTomoQueue auto-opened the running job whenever the open-state snapshot was empty, so collapsing the only open job (the running one) made the snapshot empty and re-opened it on the next refresh. Open-state was also keyed by positional index, which mis-assigns the flag when jobs are added/removed/ reordered. - Snapshot open jobs by stable key (added_at|label) via a data-key attribute instead of positional index. - Auto-open a running job only once, on first appearance, tracked in window.__tqAutoOpened; afterwards honor the DOM snapshot so a manual collapse sticks. Prune the set when jobs disappear. --- .../flomni/flomni_webpage_generator.py | 34 +++++++++++++++---- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni_webpage_generator.py b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni_webpage_generator.py index 8db13a1..a34ad90 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni_webpage_generator.py +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni_webpage_generator.py @@ -2764,22 +2764,39 @@ function calcProjections(params){{ function renderTomoQueue(jobs){{ const el=document.getElementById('tomo-queue-content'); if(!el) return; // setup has no tomo-queue card (HAS_TOMO_QUEUE=False) - // Snapshot which job indices are currently open before replacing innerHTML - const openIndices=new Set(); - el.querySelectorAll('details.tq-job').forEach((det,i)=>{{ - if(det.open) openIndices.add(i); + // Snapshot which jobs are currently open, keyed by a stable identity + // (added_at|label) rather than positional index, so add/remove/reorder + // does not carry the open flag onto the wrong job. This reflects the + // user's manual expand/collapse since the last render (the DOM persists + // across refreshes; only innerHTML is replaced). + const openKeys=new Set(); + el.querySelectorAll('details.tq-job').forEach(det=>{{ + if(det.open && det.dataset.key) openKeys.add(det.dataset.key); }}); if(!jobs||jobs.length===0){{ el.innerHTML='
No jobs queued
'; return; }} + // Running jobs are auto-opened once, on first appearance. We remember which + // we have already auto-opened so a manual collapse is not undone on the next + // refresh (previously, collapsing the only open job made the snapshot empty + // and re-triggered the auto-open). + const autoOpened=window.__tqAutoOpened||(window.__tqAutoOpened=new Set()); + const presentKeys=new Set(); let html=''; jobs.forEach((job,i)=>{{ const status=job.status||'pending'; const label=job.label||('Job '+(i+1)); const params=job.params||{{}}; - // Auto-open running jobs on first render; preserve user-opened state after that - const shouldOpen=openIndices.size>0?openIndices.has(i):(status==='running'); + const key=(job.added_at||'')+'|'+label; + presentKeys.add(key); + // Open if the user currently has it open, or it is a running job we have + // not auto-opened before (its first appearance). Auto-open fires once. + let shouldOpen=openKeys.has(key); + if(status==='running' && !autoOpened.has(key)){{ + shouldOpen=true; + autoOpened.add(key); + }} let paramRows=''; TQ_PARAM_DISPLAY.forEach(([key,dispLabel])=>{{ if(key in params){{ @@ -2797,7 +2814,7 @@ function renderTomoQueue(jobs){{ const addedAt=job.added_at ?'Added '+new Date(job.added_at).toLocaleString([],{{month:'short',day:'numeric',hour:'2-digit',minute:'2-digit'}}) :''; - html+='
' + html+='
' +'' +'#'+(i+1)+'' +''+esc(label)+'' @@ -2809,6 +2826,9 @@ function renderTomoQueue(jobs){{ +'' +'
'; }}); + // Drop remembered auto-open keys for jobs that are gone, so the set stays + // small and a job that later reappears is treated as new. + autoOpened.forEach(k=>{{ if(!presentKeys.has(k)) autoOpened.delete(k); }}); el.innerHTML=html; }}