aboutsummaryrefslogtreecommitdiffstats
path: root/static/app.js
blob: 7a9ff403906b477f0cafd7c2d74376a77498c5b9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// The shell: discover modules, mount each panel, poll its state.
// A module is static/modules/<name>.js exporting default {title, interval,
// mount(el), update(state, el)}. A missing or broken panel is skipped.

const grid = document.getElementById("grid");

async function mountModule(name) {
  let panel;
  try {
    panel = (await import(`./modules/${name}.js`)).default;
  } catch {
    return;
  }
  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() {
  const r = await fetch("/api/modules");
  if (!r.ok) return;
  for (const { name } of await r.json()) await mountModule(name);
}

boot();