fix(phase26): server trip delete persists across recompute + batch delete with checkboxes

This commit is contained in:
Mathieu Moran
2026-08-11 04:18:58 -04:00
parent e6bc488e84
commit bdc7a9afb7
6 changed files with 133 additions and 5 deletions
+57
View File
@@ -232,6 +232,53 @@
const tripList = document.getElementById("trip-list");
const deletable = tripList && tripList.dataset.deletable === "1";
const deleteUrl = (tripList && tripList.dataset.deleteUrl) || "/api/trip/";
const batchDeleteUrl = tripList && tripList.dataset.batchDeleteUrl;
const deleteSelectedBtn = document.getElementById("delete-selected-btn");
function getCheckedIds() {
return Array.from(body.querySelectorAll("input.trip-checkbox:checked"))
.map(cb => parseInt(cb.value));
}
function updateDeleteSelectedBtn() {
if (!deleteSelectedBtn) return;
const count = getCheckedIds().length;
deleteSelectedBtn.hidden = count === 0;
deleteSelectedBtn.textContent = `Delete selected (${count})`;
}
function selectAllTrips() {
const cbs = body.querySelectorAll("input.trip-checkbox");
const allChecked = cbs.length > 0 && Array.from(cbs).every(cb => cb.checked);
cbs.forEach(cb => { cb.checked = !allChecked; });
updateDeleteSelectedBtn();
}
async function deleteSelected() {
const ids = getCheckedIds();
if (!ids.length || !batchDeleteUrl) return;
const confirmed = await window.confirmDelete(
`Delete ${ids.length} selected trip(s)?\n\nRaw GPS data is kept — only computed trip records are removed.`
);
if (!confirmed) return;
try {
const res = await fetch(batchDeleteUrl, {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({ids: ids}),
});
if (!res.ok) throw new Error("Delete failed");
ids.forEach(id => {
const row = body.querySelector(`tr[data-trip-id="${id}"]`);
if (row) row.remove();
});
updateDeleteSelectedBtn();
} catch(e) { showError(e.message); }
}
if (deleteSelectedBtn) {
deleteSelectedBtn.addEventListener("click", deleteSelected);
}
function renderTrips(trips) {
body.replaceChildren();
@@ -248,7 +295,11 @@
<i class="fas fa-trash fa-fw" aria-hidden="true"></i>
</button>`
: "";
const checkboxCol = batchDeleteUrl
? `<td class="text-center" onclick="event.stopPropagation()"><input type="checkbox" class="trip-checkbox form-check-input" value="${trip.id}"></td>`
: "";
row.innerHTML = `
${checkboxCol}
<td>${formatDate(trip.start_datetime)}</td>
<td>${formatDistance(trip.distance_km)}</td>
<td>${formatDuration(trip.duration_seconds)}</td>
@@ -261,6 +312,12 @@
</td>`;
body.appendChild(row);
});
// Wire checkbox listeners
body.querySelectorAll("input.trip-checkbox").forEach(cb => {
cb.addEventListener("change", updateDeleteSelectedBtn);
});
updateDeleteSelectedBtn();
}
body.addEventListener("click", function (event) {