fix(phase26): server trip delete persists across recompute + batch delete with checkboxes
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user