diff --git a/app/web/static/compare-select.js b/app/web/static/compare-select.js index 70a31c1..281f2d6 100644 --- a/app/web/static/compare-select.js +++ b/app/web/static/compare-select.js @@ -19,14 +19,11 @@ } function applyToDOM() { - const checkboxes = slot.querySelectorAll('.compare-cb'); - // Drop any selected stems that are no longer in the DOM (run aged out of list) - const present = new Set(); - checkboxes.forEach((cb) => present.add(cb.dataset.stem)); - for (const s of [...selected]) if (!present.has(s)) selected.delete(s); - + // Selections persist across swaps — with server-side filtering, rows + // leave the DOM when they don't match the current filter, but the user + // still has them "in the cart". const atCap = selected.size >= MAX; - checkboxes.forEach((cb) => { + slot.querySelectorAll('.compare-cb').forEach((cb) => { const stem = cb.dataset.stem; cb.checked = selected.has(stem); cb.disabled = atCap && !cb.checked; diff --git a/app/web/static/runs-filter.js b/app/web/static/runs-filter.js index 1786e55..ef11e7c 100644 --- a/app/web/static/runs-filter.js +++ b/app/web/static/runs-filter.js @@ -72,6 +72,19 @@ } } + function anyFilterActive() { + return AXES.some((ax) => ax.selected != null); + } + + function updateCounter() { + const count = slot.querySelectorAll('li.run').length; + const cap = anyFilterActive() ? 50 : 10; + const countEl = document.getElementById('runs-count'); + const capEl = document.getElementById('runs-cap'); + if (countEl) countEl.textContent = String(count); + if (capEl) capEl.textContent = String(cap); + } + function triggerRunsRefresh() { // Tell htmx to re-fetch /runs right now with the updated hx-vals. if (window.htmx && typeof window.htmx.trigger === 'function') { @@ -88,6 +101,7 @@ ax.selected = (ax.selected === v) ? null : v; paint(ax); syncHtmxVals(); + updateCounter(); triggerRunsRefresh(); }); } @@ -96,14 +110,14 @@ // current even between explicit refreshes. document.body.addEventListener('htmx:afterSwap', (e) => { if (e.target && e.target.id === 'runs-slot') { - // Nothing to re-apply in the DOM — the server already honored the - // filter. We just make sure selected chips stay marked. repaintAll(); + updateCounter(); } }); syncHtmxVals(); refreshUniverse(); + updateCounter(); // Periodically refresh the universe so newly-introduced values appear. setInterval(refreshUniverse, 30_000); })(); diff --git a/app/web/templates/index.html b/app/web/templates/index.html index 1e47d0c..dbf8f74 100644 --- a/app/web/templates/index.html +++ b/app/web/templates/index.html @@ -296,7 +296,7 @@