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;
}}