From fd992d7e3c03f37fbcafe9d3f26c72a2ead3b2a7 Mon Sep 17 00:00:00 2001 From: Toby Vincent Date: Thu, 26 Sep 2024 17:31:16 -0500 Subject: feat!: impl full api --- assets/index.js | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 assets/index.js (limited to 'assets/index.js') diff --git a/assets/index.js b/assets/index.js new file mode 100644 index 0000000..173ed72 --- /dev/null +++ b/assets/index.js @@ -0,0 +1,87 @@ +/** + * @typedef {Object} Check + * @property {String} status - 'pass'|'fail'|'warn' + * @property {String} output - Details. Not present if 'pass' + */ + +/** + * @typedef {Check} HealthCheck + * @property {Map} checks + */ + +async function getHealthCheck() { + const url = "api/healthcheck"; + 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(check) { + const statusElm = document.getElementById("status"); + const issuesElm = document.getElementById("issues"); + switch (check.status) { + case "pass": + issuesElm.textContent = "No issues detected"; + statusElm.setAttribute("class", "ok"); + break; + case "fail": + issuesElm.textContent = `${check.output} issues detected`; + statusElm.setAttribute("class", "error"); + break; + case "warn": + issuesElm.textContent = `${check.output} warnings detected`; + statusElm.setAttribute("class", "warning"); + break; + default: + issuesElm.textContent = "Unknown"; + statusElm.setAttribute("class", "warning"); + } +} + +getHealthCheck().then((healthCheck) => { + const table = document.getElementById("services"); + const evtSource = new EventSource("sse"); + updateStatus(healthCheck); + + for (const [service, check] of Object.entries(healthCheck.checks)) { + const row = table.insertRow(); + + const nameNode = row.insertCell(); + nameNode.textContent = service; + + const stateNode = row.insertCell(); + switch (check.status) { + case "pass": + stateNode.textContent = "Operational"; + stateNode.setAttribute("class", "ok"); + break; + case "fail": + stateNode.textContent = "Down"; + stateNode.title = check.output; + stateNode.setAttribute("class", "error"); + break; + case "warn": + stateNode.textContent = "Warning"; + stateNode.title = check.output; + stateNode.setAttribute("class", "warning"); + break; + default: + stateNode.textContent = "Unknown"; + statusElm.setAttribute("class", "warning"); + } + + evtSource.addEventListener(service, (event) => { + const status = JSON.parse(event.data); + stateNode.textContent = status.state; + stateNode.title = status.output; + }); + } +}); -- cgit v1.2.3-70-g09d2