Add delete with confirmation for trips and dashcam
- Confirmation modal in server base.html (window.confirmDelete promise helper) - Trip delete: trash button in Replay column (server-only via data-deletable on trip-list div), DELETE /api/v1/portal/trip/<id>, removes computed trip only (raw tracking_points kept) - Dashcam delete: trash button next to download, DELETE /api/v1/portal/dashcam/<id>, removes from DB + disk (best-effort file removal) - history.js: delete button gated on data-deletable='1' attribute; click handler intercepts before replay logic - db.py: delete_trip(), delete_dashcam_file() helpers Co-authored-by: Copilot <[email protected]>
This commit is contained in:
+29
-1
@@ -179,6 +179,9 @@
|
||||
initializeTimeline(result.points);
|
||||
}
|
||||
|
||||
const tripList = document.getElementById("trip-list");
|
||||
const deletable = tripList && tripList.dataset.deletable === "1";
|
||||
|
||||
function renderTrips(trips) {
|
||||
body.replaceChildren();
|
||||
trips.forEach(function (trip) {
|
||||
@@ -189,6 +192,11 @@
|
||||
row.dataset.maxSpeed = trip.max_speed_kmh;
|
||||
row.dataset.tripId = trip.id;
|
||||
row.style.cursor = "pointer";
|
||||
const deleteBtn = deletable
|
||||
? `<button class="btn btn-sm btn-outline-danger ms-1" type="button" data-delete-trip-id="${trip.id}" title="Delete trip">
|
||||
<i class="fas fa-trash fa-fw" aria-hidden="true"></i>
|
||||
</button>`
|
||||
: "";
|
||||
row.innerHTML = `
|
||||
<td>${formatDate(trip.start_datetime)}</td>
|
||||
<td>${formatDistance(trip.distance_km)}</td>
|
||||
@@ -199,13 +207,33 @@
|
||||
<button class="btn btn-sm btn-primary" type="button" data-trip-id="${trip.id}">
|
||||
Replay
|
||||
</button>
|
||||
${deleteBtn}
|
||||
</td>`;
|
||||
body.appendChild(row);
|
||||
});
|
||||
}
|
||||
|
||||
body.addEventListener("click", function (event) {
|
||||
// Button click (desktop) or row click (mobile)
|
||||
// Delete button
|
||||
const deleteBtn = event.target.closest("[data-delete-trip-id]");
|
||||
if (deleteBtn) {
|
||||
event.stopPropagation();
|
||||
const tripId = deleteBtn.dataset.deleteTripId;
|
||||
const date = deleteBtn.closest("tr").querySelector("td").textContent;
|
||||
window.confirmDelete(`Delete trip from ${date}? The raw GPS data is kept — only the computed trip record is removed.`)
|
||||
.then(function(confirmed) {
|
||||
if (!confirmed) return;
|
||||
return fetch(`/api/v1/portal/trip/${tripId}`, { method: "DELETE" })
|
||||
.then(function(res) {
|
||||
if (!res.ok) throw new Error("Delete failed");
|
||||
deleteBtn.closest("tr").remove();
|
||||
})
|
||||
.catch(function(e) { showError(e.message); });
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Replay button click (desktop) or row click (mobile)
|
||||
const button = event.target.closest("[data-trip-id]");
|
||||
const row = event.target.closest("tr[data-trip-id]");
|
||||
const tripId = button ? button.dataset.tripId : (row ? row.dataset.tripId : null);
|
||||
|
||||
Reference in New Issue
Block a user