class CCPExecutionForm extends HTMLElement{ #boot; #rootdoc; #data; #method; #executionmonitor; #serviceurl = "https://nubis1.int.d4science.net:8080" #cdnurl = "https://cdn.dev.d4science.org/ccp/executionformfragment.html" //#cdnurl = "http://d4science-cdn-public:8984/resources/ccp/executionformfragment.html" constructor(){ super() this.#boot = document.querySelector("d4s-boot-2") this.#rootdoc = this.attachShadow({ "mode" : "open"}) this.fetchMarkup() } static get observedAttributes() { return ["method"]; } attributeChangedCallback(name, oldValue, newValue) { if((oldValue != newValue) && (name === "method")){ this.#method = newValue this.loadMethod() } } fetchMarkup(){ return fetch(this.#cdnurl).then( (reply)=>{ if(reply.status === 200){ return reply.text() }else{ throw new Exception("Unable to fetch markup") } }).then(data=>{ this.#rootdoc.innerHTML = data this.showMethod() }).catch(err=>{ console.error(err) }) } loadMethod(){ this.#boot.secureFetch(this.#serviceurl + "/processes/" + this.#method).then( (resp)=>{ if(resp.status === 200){ return resp.json() }else throw "Error retrieving process" } ).then(data=>{ this.#data = data const rts = this.#data.links .filter(l => l.rel === "compatibleWith") .map(l=>l.href.replace("runtimes/","")) .join(" ") return this.#boot.secureFetch(this.#serviceurl + "/infrastructures/runtimes?runtimes=" + rts) }).then(resp=>{ this.#data.executable = resp.status === 200 }).then(()=>{ this.showMethod() }).catch(err=>alert(err)) } showEmpty(resp){ BSS.apply(this.#empty_executionform_bss, this.#rootdoc) } showMethod(){ if(this.#method == null) this.showEmpty(); else{ console.log(this.#data) BSS.apply(this.#executionform_bss, this.#rootdoc) } } sendExecutionRequest(){ const url = this.#serviceurl + "/processes/" + this.#method + "/execution" const req = this.buildRequest() this.#boot.secureFetch( url, { method : "POST", body : JSON.stringify(req), headers : { "Content-Type" : "application/json"}} ).then(reply=>{ if(reply.status !== 200 && reply.status !== 201){ throw "Error while requesting resource" } return reply.json() }).then(data=>{ if(data.status !== "accepted"){ throw "Execution has not been accepted by server" } this.#executionmonitor = document.querySelector("d4s-ccp-executionmonitor") if(this.#executionmonitor){ this.#executionmonitor.addExecution( { self : data.links[0].href, events : [data], jobID : data.jobID, method : this.#data.title}) } }).catch(err => alert("Unable to call execute: " + err)) } buildRequest(){ let request = { inputs : {}, outputs : {}, response : "raw"} //fill inputs const inputs = this.getInputs() inputs.forEach(i=>{ request.inputs[i.name] = i.value }) //fill outputs const outputs = this.getOutputs() outputs.forEach(o=>{ if(o.enabled) request.outputs[o.name] = { transmissionMode : "value" }; }) return request } getInputs(){ return Array.prototype.slice.call(this.#rootdoc.querySelectorAll("d4s-ccp-input")) } getOutputs(){ return Array.prototype.slice.call(this.#rootdoc.querySelectorAll("d4s-ccp-output")) } #empty_executionform_bss = { template : "#EXECUTION_FORM_EMPTY_TEMPLATE", target : "div[name=execution_form]", on_drop : ev=>{ if(ev.dataTransfer && ev.dataTransfer.getData('text/plain+ccpmethod')){ const id = ev.dataTransfer.getData('text/plain+ccpmethod') this.setAttribute("method", id); ev.preventDefault() ev.stopPropagation() ev.currentTarget.style.backgroundColor = "white" } }, on_dragover : ev=>{ ev.preventDefault() }, } #executionform_bss = { template : "#EXECUTION_FORM_TEMPLATE", target : "div[name=execution_form]", in : ()=>this.#data, on_drop : ev=>{ if(ev.dataTransfer && ev.dataTransfer.getData('text/plain+ccpmethod')){ const id = ev.dataTransfer.getData('text/plain+ccpmethod'); this.setAttribute("method", id); ev.preventDefault() ev.stopPropagation() } }, on_dragover : ev=>{ ev.preventDefault() }, recurse : [ { target: ".ccp-method-title", apply : (e,d)=>e.textContent = d.title + " (v. " + d.version + ")" }, { target: "p.description", apply : (e,d)=>e.textContent = d.description }, { target: "div.ccp-inputs", in : (e,d)=>d, recurse : [ { "in" : (e,d)=>{ return Object.values(d.inputs) }, target : "div", apply : (e,d)=>{ e.innerHTML = `` } } ] }, { target: "div.ccp-outputs", in : (e,d)=>d, recurse : [ { "in" : (e,d)=>{ return Object.values(d.outputs) }, target : "div", apply : (e,d)=>{ e.innerHTML = `` } } ] }, { target: "div.ccp-runtimes *[name=refresh-runtimes]", on_click : ev=>{ BSS.apply(this.#executionform_bss) } }, { target: "#execute_method_button", on_click : ev=>{ ev.preventDefault() ev.stopPropagation() if(this.#data.executable) this.sendExecutionRequest(); else alert("This method has no compatible runtimes available") return false; } }, ] } } window.customElements.define('d4s-ccp-executionform', CCPExecutionForm); class CCPExecutionEnvironmentOption extends HTMLOptionElement{ #infrastructure; #runtime; constructor(runtime, infrastructure){ super(`${runtime.name} [${infrastructure.name}]`, runtime["descriptor-id"]) this.#runtime = runtime this.#infrastructure = infrastructure this.textContent = `${runtime.name} [${infrastructure.name}]` this.value = this.runtimeId } get infrastructureName(){ return this.#infrastructure.name } get infrastructureId(){ return this.#infrastructure.id } get runtimeName(){ return this.#runtime.name } get runtimeId(){ return this.#runtime["descriptor-id"] } } window.customElements.define('d4s-ccp-environment-option', CCPExecutionEnvironmentOption, {extends:'option'});