diff --git a/app/templates/snapshots.html b/app/templates/snapshots.html
index 5fcf759..830c920 100644
--- a/app/templates/snapshots.html
+++ b/app/templates/snapshots.html
@@ -18,8 +18,32 @@
.badge-age-warn { background: rgba(245,158,11,.20); color: #f59e0b; border: 1px solid #f59e0b; }
.badge-age-fresh { background: rgba(34,197,94,.20); color: #22c55e; border: 1px solid #22c55e; }
.filters-card label { display: flex; align-items: center; gap: 0.5rem; }
+ /* Overlay plein page pendant les actions async */
+ #busy-overlay {
+ position: fixed; inset: 0; z-index: 9999;
+ background: rgba(10,14,23,0.75); backdrop-filter: blur(2px);
+ display: none; align-items: center; justify-content: center;
+ flex-direction: column; gap: 1rem;
+ }
+ #busy-overlay.active { display: flex; }
+ .spinner {
+ width: 64px; height: 64px;
+ border: 4px solid rgba(245,158,11,0.2);
+ border-top-color: #f59e0b;
+ border-radius: 50%;
+ animation: spin 0.9s linear infinite;
+ }
+ @keyframes spin { to { transform: rotate(360deg); } }
+ #busy-text { color: #f59e0b; font-size: 1.05rem; font-weight: 600; text-shadow: 0 0 12px rgba(245,158,11,0.6); }
+ #busy-sub { color: #9ca3af; font-size: 0.85rem; }
+
+
+
Action en cours…
+
Ne ferme pas la page, ne navigue pas ailleurs.
+
+
@@ -199,8 +223,19 @@
btnDelete.textContent = n > 0 ? `✕ SUPPRIMER ${n} SNAPSHOT${n>1?'S':''}` : '✕ SUPPRIMER LA SÉLECTION';
}
- function setBusy(msg, btn) {
+ // Overlay plein page : bloque toute interaction pendant les actions async.
+ // Empêche aussi la navigation accidentelle via beforeunload.
+ const overlay = document.getElementById('busy-overlay');
+ const busyText = document.getElementById('busy-text');
+ const busySub = document.getElementById('busy-sub');
+ let busyActive = false;
+
+ function setBusy(msg, btn, sub) {
status.innerHTML = '⏳ ' + escapeHTML(msg) + '';
+ busyText.textContent = '⏳ ' + msg;
+ busySub.textContent = sub || 'Ne ferme pas la page, ne navigue pas ailleurs.';
+ overlay.classList.add('active');
+ busyActive = true;
if (btn) {
btn.disabled = true;
btn._origText = btn._origText || btn.textContent;
@@ -208,11 +243,21 @@
}
}
function clearBusy(btn) {
+ overlay.classList.remove('active');
+ busyActive = false;
if (btn && btn._origText) {
btn.disabled = false;
btn.textContent = btn._origText;
}
}
+ // Avertit si l'utilisateur tente de quitter la page pendant une action
+ window.addEventListener('beforeunload', (e) => {
+ if (busyActive) {
+ e.preventDefault();
+ e.returnValue = 'Une action est en cours. Quitter maintenant peut interrompre la requête.';
+ return e.returnValue;
+ }
+ });
btnRefresh.addEventListener('click', async () => {
setBusy('Recherche en cours… (peut prendre 10-30 s selon les vCenters)', btnRefresh);