// The audit log: logins, users, tokens, changes, lease deletions. import { h, mount, table, time, input, debounce, badge } from "../ui.js"; import { get } from "../api.js"; export async function render(el) { const search = input({ type: "search", placeholder: "user, action, object or detail" }); const out = h("div"); const draw = async () => { const q = search.value.trim(); const evs = await get("/audit", { q, limit: 300 }); mount(out, table([ { label: "When", render: (e) => time(e.time) }, { label: "User", render: (e) => [e.username || "–", e.auth ? h("span", { class: "muted small" }, " " + e.auth) : null] }, { label: "From", render: (e) => h("span", { class: "mono small" }, e.ip || "") }, { label: "Action", render: (e) => h("span", { class: "mono" }, e.action) }, { label: "Object", render: (e) => e.object }, { label: "Result", render: (e) => badge(e.result, e.result === "success" ? "ok" : "err") }, { label: "Detail", render: (e) => h("span", { class: "small" }, e.detail) }, ], evs, { empty: "Nothing logged" + (q ? " that matches." : " yet.") })); }; search.addEventListener("input", debounce(draw, 300)); mount(el, h("div", { class: "page-head" }, h("div", { class: "grow" }, h("h1", null, "Audit log"))), h("div", { class: "filter-row" }, search), h("div", { class: "panel" }, out)); await draw(); }