From 39c421806d018c403a2d0bae613dadcec2779703 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 29 Mar 2026 08:53:51 -0500 Subject: [PATCH] Add mass selection in history: select-all, shift-click range, count badge Select All checkbox in header row: - Toggles all visible checkboxes at once - Shows indeterminate state when partially selected - Syncs with individual checkbox changes Shift-click range selection: - Hold Shift + click to select/deselect a range of rows - Tracks last clicked index for range calculation Selection count badge: - Shows "N selected / M runs" in the run count badge when items selected - Updates on every checkbox change Header updated to include Score column matching the data grid. Co-Authored-By: Claude Opus 4.6 (1M context) --- llm_team_ui.py | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/llm_team_ui.py b/llm_team_ui.py index 6f6dd91..072392b 100644 --- a/llm_team_ui.py +++ b/llm_team_ui.py @@ -6834,7 +6834,7 @@ h1 span{color:var(--accent)}
- IDModePromptModelsTagsDate + IDModePromptModelsScoreTagsDate
Loading...
@@ -7030,13 +7030,13 @@ function renderTable(runs) { var el = document.getElementById('run-list'); if (!runs.length) { el.textContent = ''; var e = document.createElement('div'); e.className = 'empty'; e.textContent = 'No runs found'; el.appendChild(e); return; } el.textContent = ''; - runs.forEach(function(r) { + runs.forEach(function(r, idx) { var row = document.createElement('div'); row.className = 'run-row' + (r.archived ? ' archived' : ''); // Checkbox var cb = document.createElement('input'); cb.type = 'checkbox'; cb.dataset.id = r.id; cb.style.cssText = 'width:14px;height:14px;accent-color:#e2b55a;cursor:pointer'; - cb.onclick = function(e){e.stopPropagation()}; + cb.onclick = function(e){e.stopPropagation(); handleRowCheck(this, idx);}; row.appendChild(cb); // ID var idEl = document.createElement('span'); idEl.className = 'run-id'; idEl.textContent = '#'+r.id; row.appendChild(idEl); @@ -7290,6 +7290,34 @@ async function saveTags(id, tags, notes) { if (tags !== null) loadRuns(); } +function toggleSelectAll(masterCb) { + var checked = masterCb.checked; + document.querySelectorAll('#run-list input[type=checkbox]').forEach(function(cb) { cb.checked = checked; }); + updateSelCount(); +} + +var _lastCheckedIdx = null; +function handleRowCheck(cb, idx) { + // Shift-click range selection + if (window.event && window.event.shiftKey && _lastCheckedIdx !== null) { + var cbs = Array.from(document.querySelectorAll('#run-list input[type=checkbox]')); + var start = Math.min(_lastCheckedIdx, idx); + var end = Math.max(_lastCheckedIdx, idx); + for (var i = start; i <= end; i++) { cbs[i].checked = cb.checked; } + } + _lastCheckedIdx = idx; + updateSelCount(); +} + +function updateSelCount() { + var count = document.querySelectorAll('#run-list input[type=checkbox]:checked').length; + var total = document.querySelectorAll('#run-list input[type=checkbox]').length; + var masterCb = document.getElementById('select-all-cb'); + if (masterCb) { masterCb.checked = count > 0 && count === total; masterCb.indeterminate = count > 0 && count < total; } + var badge = document.getElementById('run-count'); + if (badge && count > 0) badge.textContent = count + ' selected / ' + total + ' runs'; +} + function getSelectedIds() { var ids = []; document.querySelectorAll('#run-list input[type=checkbox]:checked').forEach(function(cb){ids.push(parseInt(cb.dataset.id))});