Merge pull request 'ccp-features' (#8) from ccp-features into master

Reviewed-on: #8
This commit is contained in:
Marco Lettere 2023-06-28 19:18:25 +02:00
commit 6f50029859
2 changed files with 158 additions and 3 deletions

View File

@ -26,10 +26,10 @@ class CCPExecutionHistory extends HTMLElement {
this.#broadcasturl = this.#broadcasturl + "/ws/notification" this.#broadcasturl = this.#broadcasturl + "/ws/notification"
this.#archive = this.getAttribute("archive") this.#archive = this.getAttribute("archive")
this.connectNewExecution() this.connectNewExecution()
this.connectBroadcast()
} }
connectedCallback(){ connectedCallback(){
this.connectBroadcastWithSubject()
this.render() this.render()
this.refreshExecutions() this.refreshExecutions()
} }
@ -114,6 +114,8 @@ class CCPExecutionHistory extends HTMLElement {
<span style="text-overflow:ellipsis" class="badge badge-light text-info border border-info" name="infrastructure" alt="Infrastructure" title="Infrastructure"></span> <span style="text-overflow:ellipsis" class="badge badge-light text-info border border-info" name="infrastructure" alt="Infrastructure" title="Infrastructure"></span>
<span class="badge" name="runtime" alt="Runtime" title="Runtime"></span> <span class="badge" name="runtime" alt="Runtime" title="Runtime"></span>
</div> </div>
<div name="logterminalcontainer" style="margin:5px 0 5px 0">
</div>
<ul> <ul>
<li></li> <li></li>
</ul> </ul>
@ -270,10 +272,26 @@ class CCPExecutionHistory extends HTMLElement {
}) })
} }
connectBroadcastWithSubject(){
var interval = window.setInterval( ()=>{
if(this.#boot.subject){
window.clearInterval(interval)
this.connectBroadcast()
}
}, 1000)
}
connectBroadcast(){ connectBroadcast(){
this.#socket = new WebSocket(this.#broadcasturl + "/executions"); this.#socket = new WebSocket(`${this.#broadcasturl}/unified?subject=${this.#boot.subject}`);
this.#socket.onmessage = event=>{ this.#socket.onmessage = event=>{
const data = JSON.parse(event.data) const data = JSON.parse(event.data)
if(data[0] && data[0].source){
//has to be logs
this.appendLogs(data)
return
}
let exec = this.#data.filter(e=>e.id === data.jobID)[0] let exec = this.#data.filter(e=>e.id === data.jobID)[0]
if(exec){ if(exec){
this.refreshExecution(exec.id) this.refreshExecution(exec.id)
@ -299,6 +317,17 @@ class CCPExecutionHistory extends HTMLElement {
}, 30000) }, 30000)
} }
appendLogs(data){
if(!data.length) return;
const exid = data[0]["attrs"]["execution"]
const lt = this.#rootdoc.querySelector(`d4s-ccp-logterminal[index='${exid}']`)
if(!lt){
console.error("No terminal found for adding logs of " + exid)
}else{
lt.addLines(data)
}
}
download(url, name) { download(url, name) {
this.#boot.secureFetch(url).then(reply => { this.#boot.secureFetch(url).then(reply => {
if (!reply.ok) { if (!reply.ok) {
@ -627,6 +656,12 @@ class CCPExecutionHistory extends HTMLElement {
this.generateCode(id, lang, `${id}.${ext}`) this.generateCode(id, lang, `${id}.${ext}`)
} }
}, },
{
target : "div[name=logterminalcontainer]",
apply : (e,d)=>{
e.innerHTML = `<d4s-ccp-logterminal index="${d.id}" maxstoredlines="100" maxlines="10"></d4s-ccp-logterminal>`
}
},
{ {
target : "ul", target : "ul",
recurse : [ recurse : [

View File

@ -0,0 +1,120 @@
class LogTerminal extends HTMLElement {
#maxlines = 10;
#maxstoredlines = 100;
#rootdoc = null;
#lines = [];
#index = null;
static get observedAttributes() { return ['index']; }
constructor(){
super()
this.#maxlines = this.getAttribute("maxlines")
this.#rootdoc = this.attachShadow({ "mode" : "open"})
this.render()
}
connectedCallback(){
this.reloadLines()
this.refresh()
}
attributeChangedCallback(name, oldValue, newValue) {
if(name === "index"){
this.#index = newValue
this.reloadLines()
}
}
get lines(){
return this.#lines
}
addLines(lines){
this.#lines = this.#lines.concat(lines)
this.refresh()
this.storeLines()
}
reloadLines(){
if(this.#index == null) return;
if(sessionStorage.getItem("logs-" + this.#index)){
this.#lines = JSON.parse(sessionStorage.getItem("logs-" + this.#index))
}else{
this.#lines = []
}
}
storeLines(){
if(this.#lines.length > this.#maxstoredlines){
this.#lines.splice(0, this.#lines.length - this.#maxstoredlines)
}
sessionStorage.setItem("logs-" + this.#index, JSON.stringify(this.#lines))
}
render(){
this.#rootdoc.innerHTML = `
<link href="https://fonts.googleapis.com/css2?family=VT323&display=swap" rel="stylesheet">
<style>
.terminal-container{
overflow: hidden;
}
.terminal{
background-color: black;
max-height: 10rem;
height: 10rem;
min-height:10rem;
padding: 5px;
overflow:auto;
font-size: x-small;
line-height: 0.9rem;
}
.terminal > .line {
font-family: 'VT323', monospace;
color: #88ff00;
}
.terminal > .line.error {
color: #ff3300;
}
.terminal > .line.infrastructure {
color: rgba(255,255,255,0.8);
}
</style>
<template id="TERMINAL_TEMPLATE">
<div name="terminal" class="container">
<div class="terminal" id="t">
<div class="line"></div>
</div>
</div>
</template>
<div name="terminal" class="container"></div>
`
}
refresh(){
BSS.apply(this.#terminal_bss, this.#rootdoc)
const lt = this.#rootdoc.querySelector("div.terminal")
lt.scrollTop = lt.scrollHeight;
}
#terminal_bss = {
template : "#TERMINAL_TEMPLATE",
target : "div[name=terminal]",
in : ()=>this,
recurse : {
target : "div.line",
in: (e,d)=>d.lines,
apply: (e,d,i)=>{
if(d.source === "stderr") e.classList.add("error");
if(d.source === "infrastructure") e.classList.add("infrastructure");
e.innerHTML = `<span>${d.line}</span>`
}
}
}
}
window.customElements.define('d4s-ccp-logterminal', LogTerminal);