const values = {}; for (const k of dirty) { const inp = $(`#rows [data-key="${CSS.escape(k)}"]`); values[k] = inp.value; } try { const d = await POST("/settings/save-batch", { values }); const errs = d.errors || {}; const nApplied = Object.keys(d.applied || {}).length; if (nApplied) toast(`Saved ${nApplied} setting(s)`, "ok"); if (Object.keys(errs).length) toast("Some values rejected: " + JSON.stringify(errs), "err", 8000); await load(); } catch (err) { toast("Save failed: " + err.message, "err"); } }); $("#rows").addEventListener("click", (e) => { const b = e.target.closest("button"); if (!b || !b.dataset.reset) return; confirmedAction(`Reset “${b.dataset.reset}” to its default value?`, async () => { await POST("/settings/reset", { key: b.dataset.reset, value: "" }); toast("Reset to default", "ok"); await load(); }); }); $("#btnResetCat").addEventListener("click", () => { const keys = settings.filter(s => s.category === cat && !s.is_default).map(s => s.key); if (!keys.length) { toast("All settings in this category already use defaults"); return; } confirmedAction(`Reset all customized settings in “${cat}”?`, async () => { for (const k of keys) await POST("/settings/reset", { key: k, value: "" }); toast(`Reset ${keys.length} setting(s)`, "ok"); await load(); }); }); $("#btnResetAll").addEventListener("click", () => confirmedAction( "Reset ALL settings to defaults across every category?", async () => { const d = await POST("/settings/reset-all"); toast(`Reset ${d.reset} settings`, "ok"); await load(); })); await load(); }; === settings list === financial | amount_min | float | True financial | amount_max | float | True financial | shipping_min | float | True financial | shipping_max | float | True financial | invoice_format | str | True financial | invoice_prefix | str | True limits | default_daily_limit | int | True limits | default_campaign_limit | int | True limits | default_max_per_account | int | True limits | default_send_interval | float | True limits | default_rate_per_minute | int | True attachments | attachment_kind | str | True compliance | unsubscribe_enabled | bool | True compliance | unsubscribe_base_url | str | True general | company_name | str | True general | test_email_default | str | True