mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-08-10 23:31:21 +02:00
Two fixes: 1. about_page edit was missing autosave-handler.js: the first if block (editType === 'page' || 'about_page') overrode $extraJs with only overtype.min.js, making the elseif that added autosave-handler.js unreachable for about_page. Added autosave-handler.js to the first block, removed dead 'about_page' from the elseif. 2. Deleting a contact group (Contacts 3/4/5) only removed the DOM element but never triggered htmx autosave. Dispatched a 'change' event on the form after removal+reindex so the hx-trigger fires. Also expanded autosave-handler.js URL filter to accept apropos.php so the status indicator (Enregistrement/Enregistré) works for contacts saves.
81 lines
2.8 KiB
JavaScript
81 lines
2.8 KiB
JavaScript
/**
|
|
* Shared HTMX after-request handler for autosave forms.
|
|
*
|
|
* Reads the JSON response, updates the CSRF token, and surfaces
|
|
* parse errors instead of silently swallowing them (unlike the
|
|
* old autosave.js .catch(() => {}) pattern).
|
|
*/
|
|
function handleAutosaveResponse(event) {
|
|
// Only handle responses from autosave endpoints (draft.php).
|
|
// The htmx:afterRequest event bubbles, so child elements'
|
|
// HTMX requests (e.g. licence fragment, pill-search) also
|
|
// reach this handler. We filter by URL to avoid mixing them.
|
|
const url = event.detail.requestConfig?.path || "";
|
|
if (!url.includes("draft.php") && !url.includes("apropos.php")) return;
|
|
|
|
const form = event.target.closest("form");
|
|
const status = form ? form.querySelector("[data-autosave-status]") : null;
|
|
|
|
if (!event.detail.successful) {
|
|
if (status) {
|
|
status.textContent = "Erreur !";
|
|
status.className = "autosave-status autosave-status--error";
|
|
}
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const data = JSON.parse(event.detail.xhr.responseText);
|
|
|
|
// Rotate CSRF token in the form, any share_link_token fields, and the meta tag
|
|
if (data.csrf_token) {
|
|
const csrfInput = form.querySelector('input[name="csrf_token"]');
|
|
if (csrfInput) csrfInput.value = data.csrf_token;
|
|
const shareTokenInput = form.querySelector(
|
|
'input[name="share_link_token"]',
|
|
);
|
|
if (shareTokenInput) shareTokenInput.value = data.csrf_token;
|
|
const meta = document.querySelector('meta[name="csrf-token"]');
|
|
if (meta) meta.content = data.csrf_token;
|
|
}
|
|
|
|
if (status) {
|
|
if (data.success) {
|
|
status.textContent = "Enregistré ✓";
|
|
status.className = "autosave-status autosave-status--saved";
|
|
} else {
|
|
status.textContent = "Erreur !";
|
|
status.className = "autosave-status autosave-status--error";
|
|
}
|
|
}
|
|
} catch {
|
|
// JSON parse failed (e.g. PHP warning in output) — surface it
|
|
if (status) {
|
|
status.textContent = "Erreur !";
|
|
status.className = "autosave-status autosave-status--error";
|
|
}
|
|
console.warn(
|
|
"Autosave: could not parse response",
|
|
event.detail.xhr.responseText,
|
|
);
|
|
}
|
|
}
|
|
|
|
// Expose globally for HTMX hx-on::after-request inlines (bundles wrap in IIFE)
|
|
window.handleAutosaveResponse = handleAutosaveResponse;
|
|
|
|
// Show saving indicator while request is in flight
|
|
document.body.addEventListener("htmx:beforeRequest", (e) => {
|
|
const url = e.detail.requestConfig?.path || "";
|
|
if (!url.includes("draft.php") && !url.includes("apropos.php")) return;
|
|
// The autosave request comes from the hidden probe div, so find
|
|
// the status indicator by searching the closest form.
|
|
const el = e.target;
|
|
const form = el?.closest?.("form");
|
|
const status = form?.querySelector?.("[data-autosave-status]");
|
|
if (status) {
|
|
status.textContent = "Enregistrement…";
|
|
status.className = "autosave-status autosave-status--saving";
|
|
}
|
|
});
|