const serviceMap = new Map(); async function getServices() { const url = "api/services"; try { const response = await fetch(url); if (!response.ok) { throw new Error(`Response status: ${response.status}`); } const json = await response.json(); return json; } catch (error) { console.error(error.message); } } function updateStatus() { const statusElm = document.getElementById("status"); const issuesElm = document.getElementById("issues"); const issues = [...serviceMap.values()].filter((s) => !s).length; issuesElm.textContent = `${issues} issue(s) detected`; if (issues) { statusElm.setAttribute("class", "error"); } else { statusElm.setAttribute("class", "ok"); } } function updateService(name, node, status) { switch (status.status) { case "pass": node.textContent = "Operational"; node.setAttribute("class", "ok"); break; case "fail": node.textContent = "Down"; node.title = status.output; node.setAttribute("class", "error"); break; case "warn": node.textContent = "Warning"; node.title = status.output; node.setAttribute("class", "warning"); break; case "unknown": node.textContent = "Unknown"; node.setAttribute("class", "warning"); } serviceMap.set(name, status.status === "pass"); updateStatus(); } getServices().then((services) => { for (const [service] of Object.entries(services)) { const table = document.getElementById("services"); const row = table.insertRow(); const nameNode = row.insertCell(); nameNode.textContent = service; const node = row.insertCell(); const evtSource = new EventSource(`sse/${service}`); evtSource.onmessage = (event) => { const status = JSON.parse(event.data); updateService(service, node, status); }; } });