From 360287972109d6c691a6cb6ee55337f0f07fb388 Mon Sep 17 00:00:00 2001 From: Ivo Oskamp Date: Thu, 1 Jan 2026 16:54:45 +0100 Subject: [PATCH] Auto-commit local changes before build (2026-01-01 16:54:45) --- .last-branch | 2 +- .../src/templates/main/run_checks.html | 49 +++++++++++++++++++ docs/changelog.md | 8 +++ 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/.last-branch b/.last-branch index b9f1354..5372076 100644 --- a/.last-branch +++ b/.last-branch @@ -1 +1 @@ -v20260101-04-run-checks-guide-layout-fix +v20260101-05-run-checks-shift-multiselect diff --git a/containers/backupchecks/src/templates/main/run_checks.html b/containers/backupchecks/src/templates/main/run_checks.html index 1cd5276..d3ecbf8 100644 --- a/containers/backupchecks/src/templates/main/run_checks.html +++ b/containers/backupchecks/src/templates/main/run_checks.html @@ -286,6 +286,11 @@ var btnMarkAllReviewed = document.getElementById('rcm_mark_all_reviewed'); + // Shift multi-select support for the overview table. + // Works like file explorers: click a checkbox, then Shift+click another checkbox + // to toggle the full range in between. + var lastClickedIndex = null; + function statusClass(status) { var s = (status || "").toString().toLowerCase(); @@ -343,27 +348,71 @@ return ids.filter(function (x) { return Number.isFinite(x); }); } + function updateSelectAllState() { + if (!selectAll) return; + var cbs = table.querySelectorAll('tbody .rc_row_cb'); + var total = cbs.length; + var checked = 0; + cbs.forEach(function (cb) { if (cb.checked) checked++; }); + + if (total === 0) { + selectAll.checked = false; + selectAll.indeterminate = false; + return; + } + + selectAll.checked = checked === total; + selectAll.indeterminate = checked > 0 && checked < total; + } + function updateButtons() { var ids = getSelectedJobIds(); if (btnMark) btnMark.disabled = ids.length === 0; if (btnUnmark) btnUnmark.disabled = ids.length === 0; if (statusEl) statusEl.textContent = ids.length ? (ids.length + ' selected') : ''; + + updateSelectAllState(); } if (selectAll) { selectAll.addEventListener('change', function () { var cbs = table.querySelectorAll('tbody .rc_row_cb'); cbs.forEach(function (cb) { cb.checked = selectAll.checked; }); + selectAll.indeterminate = false; updateButtons(); }); } + // Handle Shift+click range selection on checkboxes. + table.addEventListener('click', function (e) { + if (!e.target || !e.target.classList || !e.target.classList.contains('rc_row_cb')) return; + + var cbs = Array.prototype.slice.call(table.querySelectorAll('tbody .rc_row_cb')); + var idx = cbs.indexOf(e.target); + if (idx === -1) return; + + if (e.shiftKey && lastClickedIndex !== null) { + var start = Math.min(lastClickedIndex, idx); + var end = Math.max(lastClickedIndex, idx); + var newState = e.target.checked; + for (var i = start; i <= end; i++) { + cbs[i].checked = newState; + } + } + + lastClickedIndex = idx; + updateButtons(); + }); + table.addEventListener('change', function (e) { if (e.target && e.target.classList && e.target.classList.contains('rc_row_cb')) { updateButtons(); } }); + // Initialize select-all state on page load. + updateButtons(); + function postJson(url, body) { return fetch(url, { method: 'POST', diff --git a/docs/changelog.md b/docs/changelog.md index d588425..e09cd54 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -125,6 +125,14 @@ - Ensured the guide follows the same layout and alignment as the existing Run Checks page elements. - Applied layout-only changes without modifying any functional behavior. +--- + +## v20260101-05-run-checks-shift-multiselect + +- Added support for selecting multiple rows on the Run Checks page using Shift-click. +- Users can now select a continuous range of checkboxes by holding Shift and clicking another row. +- Improves efficiency when reviewing or updating multiple checks at once. + ================================================================================================================================================ ## v0.1.14