From bbd4014f8ceacd98246b3d267a1ba04f3cd2f353 Mon Sep 17 00:00:00 2001 From: librelad Date: Thu, 28 May 2026 00:11:07 +0100 Subject: [PATCH] ui(backup): replace delete-location native confirm() with the backup-modal pattern MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The inline "Delete location" action was the last spot on the Backup page still using the native browser confirm() — the snapshot delete already uses the styled backup-modal, so the location delete sat out as the odd one. Adds a new #backup-delete-location-modal matching the existing modal shell (header / body / backup-danger-btn footer), swaps deleteInlineLocation() to open it instead of confirm(), and wires the confirm button to a new confirmDeleteLocation() that does the actual `libreportal backup location remove ` task. Behaviour is the same — confirm body text moves into the modal as a muted hint paragraph using backup-card-hint, location name bolded for scannability. expandedLocs cleanup also moves into the confirm handler so the row collapses only when the user actually deletes. Signed-off-by: librelad --- .../frontend/html/backup-content.html | 14 +++++++++++++ .../js/components/backup/backup-page.js | 20 +++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/containers/libreportal/frontend/html/backup-content.html b/containers/libreportal/frontend/html/backup-content.html index b8d2796..9149243 100644 --- a/containers/libreportal/frontend/html/backup-content.html +++ b/containers/libreportal/frontend/html/backup-content.html @@ -216,6 +216,20 @@ +
+
+
+

Delete backup location

+ +
+
+ +
+
+
diff --git a/containers/libreportal/frontend/js/components/backup/backup-page.js b/containers/libreportal/frontend/js/components/backup/backup-page.js index fa86c66..e77dd56 100644 --- a/containers/libreportal/frontend/js/components/backup/backup-page.js +++ b/containers/libreportal/frontend/js/components/backup/backup-page.js @@ -293,6 +293,7 @@ class BackupPage { if (e.target.closest('#backup-migrate-confirm')) { this.confirmMigrate(); return; } if (e.target.closest('#backup-restore-confirm')) { this.confirmRestore(); return; } if (e.target.closest('#backup-delete-confirm')) { this.confirmDelete(); return; } + if (e.target.closest('#backup-delete-location-confirm')) { this.confirmDeleteLocation(); return; } if (e.target.closest('#backup-add-location-confirm')) { this.confirmAddLocation(); return; } const engineBtn = e.target.closest('[data-action="open-engine-details"]'); if (engineBtn) { this.openEngineDetailsModal(engineBtn); return; } @@ -965,10 +966,25 @@ class BackupPage { await this.saveSection(`location-${idx}`); } - async deleteInlineLocation(idx) { + deleteInlineLocation(idx) { const loc = (this.locations?.locations || []).find(l => l.idx === idx); const name = loc?.name || `Location ${idx}`; - if (!confirm(`Delete location "${name}"?\n\nBackup data already stored at this location is not deleted — only LibrePortal's reference to it. The password file on disk also stays in place.`)) return; + const modal = document.getElementById('backup-delete-location-modal'); + const body = document.getElementById('backup-delete-location-modal-body'); + if (!modal || !body) return; + body.innerHTML = ` +

Delete location ${this.escape(name)}?

+

Backup data already stored at this location is not deleted — only LibrePortal's reference to it. The password file on disk also stays in place.

+ `; + modal.dataset.locIdx = String(idx); + modal.classList.add('open'); + } + + async confirmDeleteLocation() { + const modal = document.getElementById('backup-delete-location-modal'); + if (!modal) return; + const idx = parseInt(modal.dataset.locIdx, 10); + this.closeAllModals(); this.expandedLocs.delete(idx); await this.runTask(`libreportal backup location remove ${idx}`, 'backup', null); setTimeout(() => this.reloadAfterSave(), 2000);