function http(method, remote, callback, body) { var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == XMLHttpRequest.DONE) { callback(xmlhttp.responseText, xmlhttp.status) } }; xmlhttp.open(method, remote, true); if (typeof body == "undefined") { body = null } xmlhttp.send(body); } function upsert() { function cb(body, status) { if (status == 200) { init() } else { console.log("error upserting:", status, body) } } console.log("to upsert", jsonifyForm("upsert")) http("POST", "/api/job/upsert", cb, jsonifyForm("upsert")) } function jsonifyForm(id) { var form = document.getElementById(id) var entries = new FormData(form).entries(); var json = Object.assign(...Array.from(entries, ([x,y]) => ({[x]:y}))); json.disabled = json.disabled == "false" var s = JSON.stringify(json) return s } function init() { var table = document.getElementById("jobs").getElementsByTagName("tbody")[0] function cb(body, status) { var jobs = JSON.parse(body) getJobsTable().innerHTML = "" jobs.forEach(function(job) { var s = format(job) inject(s) }) } http("GET", "/api/job/list", cb, null) } function format(job) { var pause = "⏸" var passing = "9711" if (job.last.status != 0) { passing = "129314" passing = "129324" } passing = `&#${passing};` var buttons = "" var btns = [ {"name":"refresh", "icon":"8635"}, {"name":"run", "icon":"9654"}, {"name":"modify", "icon":"9999"}, {"name":"delete", "icon":"10006"} ] btns.forEach(function(e) { buttons += ` ` }) var strikethrough = "initial" if (job.disabled) strikethrough = "line-through" strikethrough = "text-decoration: "+strikethrough return `
${job.title} ${passing} ${buttons}
${job.cron} ${job.language}
${job.last.run} ${job.last.runtime}
${job.script}
${job.last.output}
` } function inject(s) { getJobsTable().innerHTML += s } function getJobsTable() { return document.getElementById("jobs").getElementsByTagName("tbody")[0] } init() function jobdisable(input) { jobmodify(input) getField("disabled").checked = true } function jobenable(input) { jobmodify(input) getField("disabled").checked = false } function jobrun(input) { var job = jobFromInput(input) function cb(body, status) { if (status != 200) { console.log("failed to run job: ", status, body) } } http("GET", "/api/job/run/"+job.id, cb, null) } function jobmodify(input) { var form = getForm() var job = jobFromInput(input) var fields = ["id", "language", "cron", "script", "disabled", "title"] fields.forEach(function(field) { var e = getField(field) e.checked = job[field] e.value = job[field] }) var details = form.parentElement details.setAttribute("open", "") } function jobdelete(input) { var job = jobFromInput(input) if (!confirm(`Delete the job "${job.title}"?`)) return function cb(body, status) { var tr = getJobElement(job.id) tr.parentNode.removeChild(tr) } http("DELETE", "/api/job/delete/"+job.id, cb, null) } function jobrefresh(input) { var job = jobFromInput(input) function cb(body, status) { var table = getJobsTable() var summaries = Array.from(table.getElementsByTagName("summary")) summaries.forEach(function(e) { if (e.getAttribute("name") == job.id) { e = e.parentElement var showing = false if (e.getAttribute("open") != null) { showing = true } e = e.parentElement.parentElement var table = document.createElement("table") table.innerHTML = format(JSON.parse(body)) if (showing) { table.getElementsByTagName("details")[0].setAttribute("open", "") } e.innerHTML = table.innerHTML } }) } http("GET", "/api/job/get/"+job.id, cb, null) } function getJobElement(id) { var table = getJobsTable() var summaries = Array.from(table.getElementsByTagName("summary")) var target = null summaries.forEach(function(e) { if (e.getAttribute("name") == id) { e = e.parentElement e = e.parentElement.parentElement target = e } }) return target } function jobFromInput(input) { var b64 = input.getAttribute("job") var encoded = atob(b64) var json = decodeURIComponent(encoded) return JSON.parse(json) } function getForm() { return document.getElementById("upsert") } getForm().reset() function getField(name) { var form = getForm() var matches = form.elements[name] return matches }