Files
folio/public/assets/js/admin.js
T
cedricAbonnel 5ce91da06a perf & ux : cache getAll, fingerprint assets, Last-Modified, 404 log, row-click bulk (v1.6.19)
- getAll() : cache fichier articles_list.json, invalidé à chaque écriture (#16)
- layout.php : fingerprinting ?v=<hash> sur CSS/JS pour invalidation navigateur (#18)
- case 'view' : Last-Modified + 304 Not Modified pour les articles publiés (#18)
- case 'not_found' : logging JSON des 404 dans _logs/not_found.jsonl (#52)
- case 'view' : echo nu → templates/404.php pour brouillons/privés (#52)
- admin.js : clic sur ligne tableau → toggle bulk-check (#86)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 10:44:08 +02:00

90 lines
3.9 KiB
JavaScript

document.addEventListener('DOMContentLoaded', function () {
// Confirmation data-confirm sur les formulaires (evite confirm() inline bloqué par CSP)
document.querySelectorAll('form[data-confirm]').forEach(function (form) {
form.addEventListener('submit', function (e) {
var msg = form.getAttribute('data-confirm') || 'Confirmer ?';
if (!window.confirm(msg)) {
e.preventDefault();
}
});
});
// Sélection globale articles
var checkAll = document.getElementById('check-all');
if (checkAll) {
checkAll.addEventListener('change', function () {
document.querySelectorAll('.bulk-check').forEach(function (cb) {
cb.checked = checkAll.checked;
});
});
}
// Clic sur la ligne entière pour cocher/décocher la case de sélection
document.querySelectorAll('table tbody tr').forEach(function (tr) {
var cb = tr.querySelector('.bulk-check');
if (!cb) { return; }
tr.style.cursor = 'pointer';
tr.addEventListener('click', function (e) {
if (e.target.closest('a, button, input, label')) { return; }
cb.checked = !cb.checked;
if (checkAll) {
var total = document.querySelectorAll('.bulk-check').length;
var checked = document.querySelectorAll('.bulk-check:checked').length;
checkAll.checked = total > 0 && checked === total;
checkAll.indeterminate = checked > 0 && checked < total;
}
});
});
// Indicateurs de traitement formulaire SMTP (config + tester connexion)
var smtpForm = document.getElementById('smtp-config-form');
if (smtpForm) {
smtpForm.addEventListener('submit', function (e) {
var clicked = e.submitter;
if (!clicked) return;
smtpForm.querySelectorAll('button[type="submit"]').forEach(function (btn) {
btn.disabled = true;
});
var isSave = clicked.id === 'smtp-save-btn';
clicked.innerHTML = '<span class="spinner-border spinner-border-sm me-1" role="status" aria-hidden="true"></span>'
+ (isSave ? 'Enregistrement…' : 'En cours…');
});
}
// Indicateur de traitement envoi email de test
var smtpTestForm = document.getElementById('smtp-test-form');
if (smtpTestForm) {
smtpTestForm.addEventListener('submit', function () {
var btn = document.getElementById('smtp-send-btn');
if (btn) {
btn.disabled = true;
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-1" role="status" aria-hidden="true"></span>En cours…';
}
});
}
// Suppression groupée avec confirmation (remplace onclick inline)
var bulkDeleteBtn = document.getElementById('bulk-delete-btn');
if (bulkDeleteBtn) {
bulkDeleteBtn.addEventListener('click', function (e) {
var checked = document.querySelectorAll('.bulk-check:checked').length;
if (checked === 0) { e.preventDefault(); return; }
var msg = bulkDeleteBtn.getAttribute('data-confirm-bulk') || 'Confirmer ?';
if (!window.confirm(msg)) { e.preventDefault(); }
});
}
// Ajout d'un article à un livre (remplace onchange="bookAddArticle(this)")
var bookArticleSel = document.getElementById('book-article-select');
if (bookArticleSel) {
bookArticleSel.addEventListener('change', function () {
var slug = bookArticleSel.value;
if (!slug) { return; }
var ta = document.getElementById('book-articles-ta');
var lines = ta.value.split('\n').map(function (s) { return s.trim(); }).filter(Boolean);
if (lines.indexOf(slug) === -1) { lines.push(slug); ta.value = lines.join('\n'); }
bookArticleSel.value = '';
});
}
});