cdn-experiments/ccp/js/executionmonitorcontroller.js

175 lines
5.5 KiB
JavaScript

class CCPExecutionMonitor extends HTMLElement {
#boot = null;
#rootdoc = null;
#serviceurl = null;
#broadcasturl = null;
#executions = [];
#socket = null;
constructor(){
super()
this.#boot = document.querySelector("d4s-boot-2")
this.#rootdoc = this.attachShadow({ "mode" : "open"})
this.#serviceurl = this.getAttribute("serviceurl")
this.#broadcasturl = this.getAttribute("broadcasturl")
if(!this.#broadcasturl){
this.#broadcasturl = this.#serviceurl.replace(/^http/, "ws")
}
this.#broadcasturl = this.#broadcasturl + "/ws/notification"
this.connectBroadcast()
}
connectedCallback(){
this.#rootdoc.innerHTML = this.renderDeprecated()
}
renderDeprecated(){
return `
<div>
<span style="color:red;font-weight:bolder">DEPRECATED!<span>
<div>
`
}
render(){
return `
<template id="EXECUTIOM_LIST_TEMPLATE">
<ol name="ccp_execution_list" class="ccp-execution-list list-group">
<li class="ccp-execution-item list-group-item" style="border: none">
<details open>
<summary>
<h5 style="display:inline"></h5>
<span name="status" class="badge"></span>
</summary>
<p name="message" class="status-message font-weight-light font-italic" style="margin-top:revert"></span>
<ul class="list-group">
<li class="list-group-item" style="border: none"></li>
</ul>
</details>
</li>
</ol>
</template>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<ol name="ccp_execution_list" style="display:none"></ol>
`
}
addExecution(execution){
this.#executions.push(execution)
this.refreshExecution(execution)
}
refreshExecution(execution){
this.#boot.secureFetch(`${this.#serviceurl}/executions/${execution.jobID}`).then(reply =>{
if(reply.status === 200) return reply.json();
else throw "Unable to load job links"
}).then(data=>{
execution.links = data
BSS.apply(this.execution_list_bss, this.#rootdoc)
}).catch(err=>{ console.error(err)})
}
connectBroadcast(){
this.#socket = new WebSocket(this.#broadcasturl + "/executions");
this.#socket.onmessage = event=>{
const data = JSON.parse(event.data)
let exec = this.#executions.filter(e=>e.jobID === data.jobID)[0]
if(exec){
exec.events.push(data)
if(!exec.self) exec.self = data.links[0].href;
this.refreshExecution(exec)
}
}
window.setInterval( ()=>this.#socket.send("ping"), 30000)
}
download(url, name) {
this.#boot.secureFetch(url).then(reply => {
if (reply.status !== 200) {
throw "Unable to download"
}
return reply.blob()
}).then(blob => {
const objectURL = URL.createObjectURL(blob)
var tmplnk = document.createElement("a")
tmplnk.download = name
tmplnk.href = objectURL
//tmplnk.target="_blank"
document.body.appendChild(tmplnk)
tmplnk.click()
document.body.removeChild(tmplnk)
}).catch(err => console.error(err))
}
execution_list_bss = {
template : "#EXECUTIOM_LIST_TEMPLATE",
target : "ol[name=ccp_execution_list]",
in : ()=>{ return {executions : this.#executions} },
recurse:[
{
target : "li",
in : (e,d)=>d.executions,
apply: (e,d)=>{
if(d.events && d.events.length > 0){
e.alt = e.title = (new Date(d.events[d.events.length - 1].updated)).toLocaleString()
}
},
recurse : [
{
target : "h5",
apply : (e,d)=>{
e.textContent = d.method
}
},
{
target : "span[name=status]",
apply : (e,d)=>{
if(d.events && d.events.length > 0){
const status = d.events[d.events.length - 1].status
e.textContent = status
if (status === "running") e.classList.add("badge-primary");
else if (status === "successful") e.classList.add("badge-success");
else if (status === "failure") e.classList.add("badge-danger");
else e.classList.add("badge-secondary");
}
}
},
{
target : ".status-message",
apply : (e,d)=>{
if(d.events && d.events.length > 0){
e.textContent = d.events[d.events.length - 1].message
}
}
},
{
target : "ul",
recurse : [
{
target : "li",
"in" : (e,d)=>{
return d.links.map(l=>{
return { href : this.#serviceurl + "/executions/" + d.jobID + "/" + l.path, path : l.path}
})
},
on_click : ev=>{
const href = ev.currentTarget.bss_input.data.href
const name = ev.currentTarget.bss_input.data.path
this.download(href, name)
},
apply : (e,d)=>{
e.innerHTML = `<a href="${d.href}" onclick="event.preventDefault()">${d.path}</a>`
}
}
]
}
]
}
]
}
}
window.customElements.define('d4s-ccp-executionmonitor', CCPExecutionMonitor);