aboutsummaryrefslogtreecommitdiffstats
path: root/static/app.js
diff options
context:
space:
mode:
Diffstat (limited to 'static/app.js')
-rw-r--r--static/app.js47
1 files changed, 27 insertions, 20 deletions
diff --git a/static/app.js b/static/app.js
index 7a9ff40..ed19c60 100644
--- a/static/app.js
+++ b/static/app.js
@@ -3,31 +3,34 @@
// mount(el), update(state, el)}. A missing or broken panel is skipped.
const grid = document.getElementById("grid");
+const refreshers = [];
async function mountModule(name) {
- let panel;
try {
- panel = (await import(`./modules/${name}.js`)).default;
+ const panel = (await import(`./modules/${name}.js`)).default;
+ const el = document.createElement("section");
+ el.className = "panel";
+ el.dataset.module = name;
+ const title = document.createElement("h2");
+ title.textContent = panel.title ?? name;
+ el.append(title);
+ grid.append(el);
+ panel.mount?.(el);
+
+ const poll = async () => {
+ try {
+ const r = await fetch(`/api/${name}`);
+ if (r.ok) panel.update?.(await r.json(), el);
+ } catch {
+ // keep the last state; the next tick retries
+ }
+ };
+ refreshers.push(poll);
+ await poll();
+ setInterval(poll, (panel.interval ?? 1) * 1000);
} catch {
- return;
+ // a broken panel must not take down the rest of the dashboard
}
- const el = document.createElement("section");
- el.className = "panel";
- el.dataset.module = name;
- el.innerHTML = `<h2>${panel.title ?? name}</h2>`;
- grid.append(el);
- panel.mount?.(el);
-
- const poll = async () => {
- try {
- const r = await fetch(`/api/${name}`);
- if (r.ok) panel.update?.(await r.json(), el);
- } catch {
- // keep the last state; the next tick retries
- }
- };
- await poll();
- setInterval(poll, (panel.interval ?? 1) * 1000);
}
async function boot() {
@@ -36,4 +39,8 @@ async function boot() {
for (const { name } of await r.json()) await mountModule(name);
}
+document.addEventListener("visibilitychange", () => {
+ if (document.visibilityState === "visible") refreshers.forEach((fn) => fn());
+});
+
boot();