fix: html-router modals and add insta snapshot tests.

Avoid nested forms in the scratchpad editor, centralize modal lifecycle in modal.js, return HTMX partials from archive, and add template compile plus layout snapshots.
This commit is contained in:
Per Stark
2026-06-03 20:20:43 +02:00
parent d2c1ea7d2a
commit 5cca8dee01
29 changed files with 1426 additions and 217 deletions
+19
View File
@@ -0,0 +1,19 @@
/**
* Shared "Reset to Default" handler for the admin prompt-edit modals
* (templates/admin/edit_*_prompt_modal.html).
*
* Each reset button carries data-reset-target with a selector for the prompt
* textarea to repopulate from the modal's hidden #default_prompt_content.
*/
(function () {
'use strict';
document.body.addEventListener('click', function (e) {
const btn = e.target.closest('[data-reset-target]');
if (!btn) return;
const scope = btn.closest('dialog') || document;
const source = scope.querySelector('#default_prompt_content');
const target = scope.querySelector(btn.dataset.resetTarget);
if (source && target) target.value = source.value;
});
})();
+33
View File
@@ -0,0 +1,33 @@
/**
* Modal lifecycle for markup injected into #modal (see templates/modal_base.html).
*
* Uses delegated listeners so we do not rely on inline <script> re-execution on
* each hx-swap="innerHTML". Successful submit close is per-form via hx-on in the template.
*/
(function () {
'use strict';
function getDialog() {
return document.getElementById('body_modal');
}
// Auto-open the dialog whenever new modal markup is swapped into #modal.
document.body.addEventListener('htmx:afterSwap', function (e) {
if (!e.detail.target || e.detail.target.id !== 'modal') return;
const dialog = getDialog();
if (dialog && typeof dialog.showModal === 'function' && !dialog.open) {
dialog.showModal();
}
});
// Submit success → close: hx-on::after-request on #modal_form (modal_base.html)
// and on scratchpad ingest-form; not handled here.
// Clear modal content on close so browser back/forward can't reopen it.
// The dialog 'close' event does not bubble, so listen in the capture phase.
document.body.addEventListener('close', function (e) {
if (e.target && e.target.id === 'body_modal') {
e.target.innerHTML = '';
}
}, true);
})();