summaryrefslogtreecommitdiffstats
path: root/dmt/script.js
diff options
context:
space:
mode:
Diffstat (limited to 'dmt/script.js')
-rw-r--r--dmt/script.js154
1 files changed, 154 insertions, 0 deletions
diff --git a/dmt/script.js b/dmt/script.js
new file mode 100644
index 0000000..66e2d31
--- /dev/null
+++ b/dmt/script.js
@@ -0,0 +1,154 @@
+const ICON_VIEW = "⬇";
+const ICON_MAINT = "↻";
+const ICON_EVENT = "ϟ";
+const ICON_PASS = "✔";
+const ICON_FAIL = "✖";
+
+let version = null;
+let latest_job = -1;
+
+async function api(x) {
+ let r = await fetch(x);
+ return r.json();
+}
+
+function icon_progress() {
+ // Use random braille glyphs to create a moving progress effect.
+ let i = Math.floor(Math.random() * (0x28ff - 0x2801)) + 0x2801;
+ return `&#${i};`;
+}
+
+function set_progress(element, x) {
+ if (x !== null || element.className == "") {
+ element.className = (x === null ? "progress" : "");
+ element.innerHTML = (x === null ? icon_progress() : x);
+ }
+}
+
+function set_time(element) {
+ let timestamp = element.dataset.timestamp;
+ let seconds = Math.floor((Date.now() / 1000) - timestamp);
+ let minutes = Math.floor(seconds / 60);
+ let hours = Math.floor(minutes / 60);
+ let days = Math.floor(hours / 24);
+
+ if (seconds < 120) {
+ element.innerText = `${seconds} seconds ago`;
+ } else if (minutes < 120) {
+ element.innerText = `${minutes} minutes ago`;
+ } else if (hours < 48) {
+ element.innerText = `${hours} hours ago`;
+ } else {
+ element.innerText = `${days} days ago`;
+ }
+}
+
+function touch_job(list, job) {
+ // New job, new <div>
+ if (document.getElementById(`${job.job}`) === null) {
+ let abv_hash = job.hash.substring(0, 16);
+ let reason = (job.reason == "event" ? ICON_EVENT : ICON_MAINT);
+
+ let element = document.createElement("div");
+ list.insertBefore(element, list.childNodes[0]);
+
+ element.innerHTML = `
+ <div class="box" id="${job.job}">
+ <div class="box-title">
+ <a href="/api/log/${job.job}/%($CYCHE_LOG_FILENAME%)">
+ <span class="button">${ICON_VIEW}</span>
+ </a>
+ #${job.job}
+ ${job.service}
+ <small><i>${abv_hash}</i></small>
+
+ <span class="right">
+ <span class="time" id="${job.job}_time"
+ data-timestamp="${job.time}"></span>
+ <span id="${job.job}_result"></span>
+ ${reason}
+ </span>
+ </div>
+
+ <div class="box-text">
+ <pre id="${job.job}_log"></pre>
+ </div>
+ </div>`;
+
+ let time = document.getElementById(`${job.job}_time`);
+ set_time(time);
+ }
+
+ // Update existing
+ let box = document.getElementById(`${job.job}`);
+ let result = document.getElementById(`${job.job}_result`);
+ let log = document.getElementById(`${job.job}_log`);
+
+ let cn = (job.reason == "remove" ? "remove" : job.result);
+ box.className = `box ${cn}`;
+
+ switch (job.result) {
+ case "active": set_progress(result, null); break;
+ case "fail": set_progress(result, ICON_FAIL); break;
+ case "pass": set_progress(result, ICON_PASS); break;
+ }
+
+ log.innerText = job.log;
+}
+
+async function update_jobs() {
+ let nav_progress = document.getElementById("nav_progress");
+ let no_server = document.getElementById("no_server");
+ let no_jobs = document.getElementById("no_jobs");
+ let list = document.getElementById("list");
+
+ let timeout = %($CYCHE_IDLE_UPDATE%);
+
+ try {
+ let status = await api("/api/status");
+
+ if (version === null) { version = status.version; }
+ if (version != status.version) { location.reload(); }
+ if (status.active) { timeout = %($CYCHE_ACTIVE_UPDATE%); }
+ set_progress(nav_progress, (status.active ? null : ""));
+
+ for (let i = status.oldest; i <= status.newest; i++) {
+ if (i >= latest_job) {
+ let job = await api(`/api/job/${i}`);
+ touch_job(list, job);
+ latest_job = i;
+ }
+ }
+
+ if (list.childElementCount > 0) {
+ list.classList.remove("hidden");
+ no_jobs.classList.add("hidden");
+ }
+
+ no_server.classList.add("hidden");
+ } catch (ex) {
+ no_server.classList.remove("hidden");
+ console.log(ex);
+ }
+
+ setTimeout(update_jobs, timeout);
+}
+
+function update_times() {
+ let elements = document.getElementsByClassName("time");
+ for (let e of elements) {
+ set_time(e);
+ }
+}
+
+function update_progress() {
+ let elements = document.getElementsByClassName("progress");
+ for (let e of elements) {
+ e.innerHTML = icon_progress();
+ }
+}
+
+update_jobs();
+update_progress();
+setInterval(update_times, 1000);
+setInterval(update_progress, %($CYCHE_PROGRESS_ANIM_SPEED%));