fix(pct/eml): bouton 'Telecharger .eml' via delegation document-level

Bug: le handler etait attache via getElementById('pct-btn-eml') au moment du <script>
mais la modal HTML est plus bas dans le DOM -> element pas encore parse -> bind silencieux KO.

Fix: utilise document.addEventListener('click', ...) avec delegation
(closest('button') + check sur t.id). Marche meme si la modal est ajoutee/retiree.
Inclus aussi pct-btn-cancel et pct-modal-bg dans la delegation pour coherence.
This commit is contained in:
Pierre & Lumière 2026-05-07 22:40:41 +02:00
parent abfb1bec7f
commit 69ea7aa09a

View File

@ -541,14 +541,20 @@
document.addEventListener('keydown', e => { document.addEventListener('keydown', e => {
if (e.key === 'Escape') closePctModal(); if (e.key === 'Escape') closePctModal();
}); });
document.getElementById('pct-btn-cancel')?.addEventListener('click', closePctModal); // Délégation document-level pour les boutons modaux (bind robuste même si
document.getElementById('pct-modal-bg')?.addEventListener('click', closePctModal); // la modal HTML est parsée APRÈS ce script).
document.addEventListener('click', async (ev) => {
// Bouton "Télécharger .eml" : génère un fichier mail prêt à ouvrir dans Outlook web/New const t = ev.target.closest('button');
document.getElementById('pct-btn-eml')?.addEventListener('click', async () => { if (!t) return;
if (t.id === 'pct-btn-cancel' || t.id === 'pct-modal-bg') {
closePctModal();
return;
}
if (t.id === 'pct-btn-eml') {
const checkedAny = Array.from(tbody.querySelectorAll('input.row-cb:checked')); const checkedAny = Array.from(tbody.querySelectorAll('input.row-cb:checked'));
const ids = checkedAny.map(cb => cb.dataset.id); const ids = checkedAny.map(cb => cb.dataset.id);
if (!ids.length) { alert('Sélection vide'); return; } if (!ids.length) { alert('Sélection vide'); return; }
t.disabled = true; const orig = t.textContent; t.textContent = '⏳ Génération .eml…';
try { try {
const r = await fetch('/patching/import/pct-prevenance/download-eml', { const r = await fetch('/patching/import/pct-prevenance/download-eml', {
method: 'POST', headers: {'Content-Type':'application/json'}, method: 'POST', headers: {'Content-Type':'application/json'},
@ -560,13 +566,11 @@
alert('Erreur génération .eml : ' + (j.msg || r.status)); alert('Erreur génération .eml : ' + (j.msg || r.status));
return; return;
} }
// Récupère le nom de fichier depuis Content-Disposition
let filename = 'prevenance_pct.eml'; let filename = 'prevenance_pct.eml';
const cd = r.headers.get('Content-Disposition') || ''; const cd = r.headers.get('Content-Disposition') || '';
const m = cd.match(/filename="?([^"]+)"?/i); const m = cd.match(/filename="?([^"]+)"?/i);
if (m) filename = m[1]; if (m) filename = m[1];
const blob = await r.blob(); const blob = await r.blob();
// Force download
const url = URL.createObjectURL(blob); const url = URL.createObjectURL(blob);
const a = document.createElement('a'); const a = document.createElement('a');
a.href = url; a.download = filename; a.href = url; a.download = filename;
@ -575,7 +579,14 @@
setTimeout(() => URL.revokeObjectURL(url), 1000); setTimeout(() => URL.revokeObjectURL(url), 1000);
} catch (e) { } catch (e) {
alert('Erreur réseau : ' + e); alert('Erreur réseau : ' + e);
} finally {
t.disabled = false; t.textContent = orig;
} }
}
});
// Click hors modal sur le BG ferme la modal (delegation aussi)
document.addEventListener('click', (ev) => {
if (ev.target && ev.target.id === 'pct-modal-bg') closePctModal();
}); });
})(); })();
</script> </script>