From c91a3dbdfe4ec05d1fa128300a74eba0d3f24a13 Mon Sep 17 00:00:00 2001 From: dcore94 Date: Mon, 18 Jul 2022 18:08:53 +0200 Subject: [PATCH] overall fixes and refactorings for alpha testers --- ccp/js/executionformcontroller.js | 82 +++++++-- ccp/js/infrastructurelistcontroller.js | 10 +- ccp/js/inputwidgetcontroller.js | 9 +- ccp/js/inputwidgeteditorcontroller.js | 22 +-- ccp/js/methodeditorcontroller.js | 228 +++++++++++++++++++++---- ccp/js/methodlistcontroller.js | 113 ++++++++++-- ccp/js/outputwidgeteditorcontroller.js | 14 +- 7 files changed, 386 insertions(+), 92 deletions(-) diff --git a/ccp/js/executionformcontroller.js b/ccp/js/executionformcontroller.js index 592550f..dbe4291 100644 --- a/ccp/js/executionformcontroller.js +++ b/ccp/js/executionformcontroller.js @@ -6,15 +6,15 @@ class CCPExecutionForm extends HTMLElement{ #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" + #serviceurl; constructor(){ super() this.#boot = document.querySelector("d4s-boot-2") + this.#serviceurl = this.getAttribute("serviceurl") this.#rootdoc = this.attachShadow({ "mode" : "open"}) - this.fetchMarkup() + this.render() + this.showMethod() } static get observedAttributes() { @@ -28,18 +28,68 @@ class CCPExecutionForm extends HTMLElement{ } } - 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) - }) + render(){ + this.#rootdoc.innerHTML = ` +
+ + + + + +
+
+ ` } loadMethod(){ diff --git a/ccp/js/infrastructurelistcontroller.js b/ccp/js/infrastructurelistcontroller.js index bb2b9b8..aba0474 100644 --- a/ccp/js/infrastructurelistcontroller.js +++ b/ccp/js/infrastructurelistcontroller.js @@ -49,12 +49,18 @@ class CCPInfrastructureList extends HTMLElement{ `; - #serviceurl = "https://nubis1.int.d4science.net:8080" - #broadcasturl = "ws://nubis1.int.d4science.net:8989/ws/notification" + #serviceurl; + #broadcasturl; constructor(){ super() this.#boot = document.querySelector("d4s-boot-2") + 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.#rootdoc = this.attachShadow({ "mode" : "open"}) } diff --git a/ccp/js/inputwidgetcontroller.js b/ccp/js/inputwidgetcontroller.js index d91d9e8..8aa15b4 100644 --- a/ccp/js/inputwidgetcontroller.js +++ b/ccp/js/inputwidgetcontroller.js @@ -79,11 +79,16 @@ class Renderer{ } static isCode(input){ - return (input.schema.type === "string") && ("format" in input.schema) && (input.schema.format.toLowerCase() === "code") + return (input.schema.type === "string") && + ("format" in input.schema) && + (input.schema.format != null) && + (input.schema.format.toLowerCase() === "code") } static isDateTime(input){ - return (input.schema.type === "string") && ("format" in input.schema) && + return (input.schema.type === "string") && + ("format" in input.schema) && + (input.schema.format != null) && (["date", "time", "datetime"].indexOf(input.schema.format.toLowerCase()) !== -1) } } diff --git a/ccp/js/inputwidgeteditorcontroller.js b/ccp/js/inputwidgeteditorcontroller.js index b4ed2e3..6be7eb2 100644 --- a/ccp/js/inputwidgeteditorcontroller.js +++ b/ccp/js/inputwidgeteditorcontroller.js @@ -30,7 +30,7 @@ class CCPInputWidgetEditorController extends HTMLElement{ this.innerHTML = `
- + @@ -38,19 +38,19 @@ class CCPInputWidgetEditorController extends HTMLElement{
-
+
-
+
-
+
-
+
@@ -73,9 +73,9 @@ class CCPInputWidgetEditorController extends HTMLElement{
-
+
- @@ -84,7 +84,7 @@ class CCPInputWidgetEditorController extends HTMLElement{
-
+
@@ -92,13 +92,13 @@ class CCPInputWidgetEditorController extends HTMLElement{
-
+
Comma separated list of options
-
+
diff --git a/ccp/js/methodeditorcontroller.js b/ccp/js/methodeditorcontroller.js index 7eee553..b949df8 100644 --- a/ccp/js/methodeditorcontroller.js +++ b/ccp/js/methodeditorcontroller.js @@ -3,10 +3,12 @@ class CCPMethodEditorController extends HTMLElement{ #boot; #rootdoc; - #serviceurl = "https://nubis1.int.d4science.net:8080" + #serviceurl; #runtimes; #locked = false; + #isupdate = false; + #tmp_inputs = [] #tmp_outputs = [] #current = null; @@ -103,6 +105,18 @@ class CCPMethodEditorController extends HTMLElement{ position: relative; } + .ccp-toolbar-header { + display: inline-flex; + align-items: center; + gap: 5px; + padding: .2rem; + } + + .ccp-toolbar-right { + position:absolute; + right: 1rem; + } + .ccp-toolbar-button { font-weight: bold; padding:.3rem; @@ -151,6 +165,11 @@ class CCPMethodEditorController extends HTMLElement{ ` + #delete_icon = ` + + + + ` #ansible_icon = ` @@ -161,6 +180,8 @@ class CCPMethodEditorController extends HTMLElement{ super(); this.#boot = document.querySelector("d4s-boot-2") this.#rootdoc = this.attachShadow({ "mode" : "open"}) + this.#serviceurl = this.getAttribute("serviceurl") + this.initMethod() this.fetchRuntimes() } @@ -181,13 +202,72 @@ class CCPMethodEditorController extends HTMLElement{ }) } - saveCurrent(){ + saveMethod(){ + if(this.#locked) return; if(this.#current != null){ this.adoptTemporaries() - console.log(this.#current) + const text = `Confirm ${this.#isupdate ? "updating" : "creation"} of ${this.#current.title} version ${this.#current.version}` + if(window.confirm(text)){ + this.lockRender() + const url = this.#serviceurl + "/methods" + const args = { + body : JSON.stringify(this.#current), + method : this.#isupdate ? "PUT" : "POST", + headers : {"Content-type" : "application/json"} + } + this.#boot.secureFetch(url, args).then( + (resp)=>{ + if(resp.status === 201 || resp.status === 204){ + return resp.text() + }else throw "Error saving process" + }).then(data=>{ + if(!this.#isupdate) this.#isupdate = true; + this.unlockRender() + }).catch(err=>{ + alert(err) + this.unlockRender() + }) + } } } + deleteMethod(){ + if(this.#locked) return; + if(this.#current != null){ + const text = `Confirm deletion of ${this.#current.title} version ${this.#current.version}` + if(window.confirm(text)){ + this.lockRender() + const url = this.#serviceurl + "/methods/" + this.#current.id + const args = { + method : "DELETE" + } + this.#boot.secureFetch(url, args).then( + (resp)=>{ + if(resp.status === 404 || resp.status === 204){ + return null + }else throw "Error deleting method" + }).then(data=>{ + this.unlockRender() + }).catch(err=>{ + alert(err) + this.unlockRender() + }) + } + } + } + + initMethod(){ + this.#current = JSON.parse(JSON.stringify(this.#method_template)) + this.#current.id = Math.abs((Math.random() * 10e11)|0) + this.#tmp_inputs = [] + this.#tmp_outputs = [] + } + + resetMethod(){ + this.initMethod() + this.render() + } + cloneMethod(method){ if(this.#locked) return; this.lockRender() @@ -199,7 +279,30 @@ class CCPMethodEditorController extends HTMLElement{ } ).then(data=>{ this.#current = data - this.#current.id = "" + this.#current.id = Math.abs((Math.random() * 10e11)|0) + this.#isupdate = false + this.#current.title = "Clone of " + this.#current.title + this.#current.description = "[Clone of] " + this.#current.description + this.#tmp_inputs = Object.keys(this.#current.inputs).map(k=>this.#current.inputs[k]) + this.#tmp_outputs = Object.keys(this.#current.outputs).map(k=>this.#current.outputs[k]) + this.unlockRender() + }).catch(err=>{ + this.unlockRender() + }) + } + + editMethod(method){ + if(this.#locked) return; + this.lockRender() + this.#boot.secureFetch(this.#serviceurl + "/processes/" + method).then( + (resp)=>{ + if(resp.status === 200){ + return resp.json() + }else throw "Error retrieving process" + } + ).then(data=>{ + this.#current = data + this.#isupdate = true this.#tmp_inputs = Object.keys(this.#current.inputs).map(k=>this.#current.inputs[k]) this.#tmp_outputs = Object.keys(this.#current.outputs).map(k=>this.#current.outputs[k]) this.unlockRender() @@ -243,10 +346,6 @@ class CCPMethodEditorController extends HTMLElement{ } render(){ - if(this.#current == null){ - this.#current = JSON.parse(JSON.stringify(this.#method_template)) - this.#current.id = Math.random(10e6)|0 - } this.#rootdoc.innerHTML = `
@@ -258,10 +357,15 @@ class CCPMethodEditorController extends HTMLElement{
-
- ${this.#current.title} - ${this.renderSaveButton()} - ${this.renderResetButton()} +
+
+ ${this.#current.title} +
+
+ ${this.renderSaveButton()} + ${this.renderResetButton()} + ${ this.#isupdate ? this.renderDeleteButton() : "" } +
@@ -299,17 +403,29 @@ class CCPMethodEditorController extends HTMLElement{
- Inputs - ${this.renderPlusButton("add-input")} +
+
+ Inputs +
+
+ ${this.renderPlusButton("add-input")} +
+
- Outputs - ${this.renderStandardOutputButtons()} - ${this.renderPlusButton("add-output")} +
+
+ Outputs +
+
+ ${this.renderStandardOutputButtons()} + ${this.renderPlusButton("add-output")} +
+
@@ -317,15 +433,22 @@ class CCPMethodEditorController extends HTMLElement{
- Scripts - - ${ this.renderAnsibleIcon() } +
+
+ Scripts + +
+
+ ${ this.renderAnsibleIcon() } +
+
${this.renderScripts()} @@ -337,12 +460,30 @@ class CCPMethodEditorController extends HTMLElement{ this.renderInputs() this.renderOutputs() + this.#rootdoc.querySelector("input[name=title]").addEventListener("input", ev=>{ + this.#current.title = ev.currentTarget.value + this.#rootdoc.querySelector("span[name=header]").innerText = this.#current.title + }) + + this.#rootdoc.querySelector("input[name=version]").addEventListener("input", ev=>{ + this.#current.version = ev.currentTarget.value + }) + + this.#rootdoc.querySelector("input[name=description]").addEventListener("input", ev=>{ + this.#current.description = ev.currentTarget.value + }) + this.#rootdoc.addEventListener("drop", ev=>{ if(ev.dataTransfer && ev.dataTransfer.getData('text/plain+ccpmethod')){ const id = ev.dataTransfer.getData('text/plain+ccpmethod') + ev.stopImmediatePropagation() ev.preventDefault() ev.stopPropagation() - this.cloneMethod(id) + if(window.confirm("Do you want to create a new clone?")){ + this.cloneMethod(id) + } else { + this.editMethod(id) + } } }) @@ -351,10 +492,9 @@ class CCPMethodEditorController extends HTMLElement{ }) this.#rootdoc.querySelector("button[name=reset]").addEventListener("click", ev=>{ - this.#current = this.#method_template - this.#tmp_inputs = [] - this.#tmp_outputs = [] - this.render() + if(window.confirm("All unsaved data will be lost. Proceed?")){ + this.resetMethod() + } ev.preventDefault() ev.stopPropagation() }) @@ -362,9 +502,17 @@ class CCPMethodEditorController extends HTMLElement{ this.#rootdoc.querySelector("button[name=save]").addEventListener("click", ev=>{ ev.preventDefault() ev.stopPropagation() - this.saveCurrent() + this.saveMethod() }) + if(this.#isupdate){ + this.#rootdoc.querySelector("button[name=delete]").addEventListener("click", ev=>{ + ev.preventDefault() + ev.stopPropagation() + this.deleteMethod() + }) + } + this.#rootdoc.querySelector("input[name=keyword-input]").addEventListener("keypress", ev=>{ if(ev.key === "Enter" || ev.which === 13){ ev.preventDefault() @@ -432,7 +580,7 @@ class CCPMethodEditorController extends HTMLElement{ schema : { type : "string", format : null, - contentMediaType : null, + contentMediaType : "text/plain", default : "" } } @@ -464,7 +612,7 @@ class CCPMethodEditorController extends HTMLElement{ maxOccurs : 1, schema : { type : "string", - contentMediaType : null + contentMediaType : "text/plain" } } ) @@ -543,7 +691,7 @@ class CCPMethodEditorController extends HTMLElement{ renderAnsibleIcon(){ return ` -
+
${ this.#ansible_icon }
` @@ -557,6 +705,14 @@ class CCPMethodEditorController extends HTMLElement{ ` } + renderDeleteButton(){ + return ` + + ` + } + renderResetButton(){ return ` @@ -37,38 +37,38 @@ class CCPOutputWidgetEditorController extends HTMLElement {
-
+
-
+
-
+
-
+
-
+
-
+