treefmt: apply prettier
Pure `nix fmt` output from the commit before this one — no hand edits. 203 files: 52 md, 42 tsx, 32 js, 32 css, 21 ts, 13 html, 8 json, 3 mjs. Reproduce with `nix develop -c nix fmt` on the parent commit; the result should be byte-identical to this tree. None of the 13 `.prettierignore` entries appears here — verified by intersecting the changed-file list against the ignore file, with a control proving the intersection finds a match when one exists.
This commit is contained in:
parent
5d24bedd60
commit
39b95c2ede
203 changed files with 10090 additions and 6085 deletions
|
|
@ -51,30 +51,37 @@ export function asyncBtn(btn, fn) {
|
|||
// `data-prompt-field`) are surfaced via the themed dialogs in `modal.js`
|
||||
// rather than native `confirm()`/`prompt()`, and errors via `themedToast`
|
||||
// rather than `alert()`, so every page gets the same in-theme experience.
|
||||
import { themedConfirm, themedPrompt, themedToast } from './modal.js';
|
||||
import { themedConfirm, themedPrompt, themedToast } from "./modal.js";
|
||||
|
||||
export function bindAsyncForms(onSuccess) {
|
||||
document.addEventListener('submit', async (e) => {
|
||||
document.addEventListener("submit", async (e) => {
|
||||
const f = e.target;
|
||||
if (!(f instanceof HTMLFormElement) || !f.hasAttribute('data-async')) return;
|
||||
if (!(f instanceof HTMLFormElement) || !f.hasAttribute("data-async"))
|
||||
return;
|
||||
e.preventDefault();
|
||||
if (f.dataset.confirm && !(await themedConfirm({ message: f.dataset.confirm }))) return;
|
||||
if (
|
||||
f.dataset.confirm &&
|
||||
!(await themedConfirm({ message: f.dataset.confirm }))
|
||||
)
|
||||
return;
|
||||
if (f.dataset.prompt) {
|
||||
const ans = await themedPrompt({ message: f.dataset.prompt });
|
||||
if (ans === null) return; // operator hit Cancel
|
||||
// Drop into a hidden input named after `data-prompt-field` (or
|
||||
// 'note' by default) so the value rides along on the POST.
|
||||
const field = f.dataset.promptField || 'note';
|
||||
const field = f.dataset.promptField || "note";
|
||||
let input = f.querySelector(`input[name="${field}"]`);
|
||||
if (!input) {
|
||||
input = document.createElement('input');
|
||||
input.type = 'hidden';
|
||||
input = document.createElement("input");
|
||||
input.type = "hidden";
|
||||
input.name = field;
|
||||
f.append(input);
|
||||
}
|
||||
input.value = ans;
|
||||
}
|
||||
const btn = f.querySelector('button[type="submit"], button:not([type]), .btn-inline');
|
||||
const btn = f.querySelector(
|
||||
'button[type="submit"], button:not([type]), .btn-inline',
|
||||
);
|
||||
// Inner action: POST, clear inputs, call onSuccess.
|
||||
// Errors are surfaced via themedToast; the caller does not re-throw
|
||||
// so asyncBtn's finally always runs (restoring the button).
|
||||
|
|
@ -82,25 +89,37 @@ export function bindAsyncForms(onSuccess) {
|
|||
let resp;
|
||||
try {
|
||||
resp = await fetch(f.action, {
|
||||
method: f.method || 'POST',
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
method: f.method || "POST",
|
||||
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
||||
body: new URLSearchParams(new FormData(f)),
|
||||
redirect: 'manual',
|
||||
redirect: "manual",
|
||||
});
|
||||
} catch (err) {
|
||||
themedToast('action failed: ' + err, { type: 'error' });
|
||||
themedToast("action failed: " + err, { type: "error" });
|
||||
return;
|
||||
}
|
||||
const ok = resp.ok || resp.type === 'opaqueredirect'
|
||||
|| (resp.status >= 200 && resp.status < 400);
|
||||
const ok =
|
||||
resp.ok ||
|
||||
resp.type === "opaqueredirect" ||
|
||||
(resp.status >= 200 && resp.status < 400);
|
||||
if (!ok) {
|
||||
const text = await resp.text().catch(() => '');
|
||||
themedToast('action failed: ' + resp.status + (text ? '\n\n' + text : ''), { type: 'error' });
|
||||
const text = await resp.text().catch(() => "");
|
||||
themedToast(
|
||||
"action failed: " + resp.status + (text ? "\n\n" + text : ""),
|
||||
{ type: "error" },
|
||||
);
|
||||
return;
|
||||
}
|
||||
// Clear text inputs whose value was just submitted.
|
||||
f.querySelectorAll('input[type="text"], input:not([type]), textarea').forEach((i) => { i.value = ''; });
|
||||
if (!f.hasAttribute('data-no-refresh') && typeof onSuccess === 'function') {
|
||||
f.querySelectorAll(
|
||||
'input[type="text"], input:not([type]), textarea',
|
||||
).forEach((i) => {
|
||||
i.value = "";
|
||||
});
|
||||
if (
|
||||
!f.hasAttribute("data-no-refresh") &&
|
||||
typeof onSuccess === "function"
|
||||
) {
|
||||
onSuccess();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue