Reservations page refreshes itself every 15 seconds

Online and last-seen times stay current. A newer draw (typing, a change)
wins over a slower older one; no refresh while the tab is hidden.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
abrown38andClaude Opus 5.5 committed 2026-10-18 18:03:06 +01:00
1 parent 5e6c61cc8e
commit 29fc991ce1
2 files changed
+10 -1

No files matched your search

@@ -2,6 +2,7 @@
import { h, mount, table, time, input, modal, errorBox, field, confirmDialog, select, debounce, badge, checkbox } from "../ui.js";
import { get, change, can } from "../api.js";
import { optionsEditor, subnetLabel } from "../widgets.js";
import { onLeave } from "../app.js";
// reservationsTable lists reservations with Edit and Delete.
export function reservationsTable(rs, done, opts = {}) {
@@ -87,19 +88,25 @@ export async function render(el, params, query) {
const subnetSel = select([["", "all subnets"], ...subnets.map((s) => [String(s.id), subnetLabel(s)])], query.get("subnet") || "");
const search = input({ type: "search", placeholder: "address, MAC or host name" });
const out = h("div");
let gen = 0;
const draw = async () => {
const my = ++gen;
const q = search.value.trim().toLowerCase();
const rs = (await get("/reservations", { subnet: subnetSel.value })).filter((r) =>
!q || r.ip.includes(q) || (r.mac || "").includes(q) || (r.hostname || "").toLowerCase().includes(q) || (r.client_id || "").includes(q));
if (my !== gen) return; // a newer draw (typing, a change) won
mount(out, reservationsTable(rs, draw, { empty: q || subnetSel.value ? "None match." : "No reservations yet." }));
};
subnetSel.addEventListener("change", draw);
search.addEventListener("input", debounce(draw, 200));
mount(el,
h("div", { class: "page-head" },
h("div", { class: "grow" }, h("h1", null, "Reservations"), h("div", { class: "muted" }, "Fixed addresses for clients, by MAC address or client identifier.")),
h("div", { class: "grow" }, h("h1", null, "Reservations"), h("div", { class: "muted" }, "Fixed addresses for clients, by MAC address or client identifier. Refreshed every 15 seconds.")),
can("config", true) ? h("div", { class: "actions" }, h("button", { class: "primary", onclick: () => reservationDialog(null, draw) }, "New reservation")) : null),
h("div", { class: "filter-row" }, subnetSel, search),
h("div", { class: "panel" }, out));
await draw();
// Online and last seen change as clients come and go.
const t = setInterval(() => { if (!document.hidden) draw().catch(() => {}); }, 15000);
onLeave(() => clearInterval(t));
}