overall fixes and refactorings for alpha testers
This commit is contained in:
parent
b2b1caf9db
commit
c91a3dbdfe
|
@ -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 = `
|
||||
<div>
|
||||
<link rel="stylesheet" href="https://cdn.dev.d4science.org/ccp/css/common.css"></link>
|
||||
<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">
|
||||
<style>
|
||||
|
||||
</style>
|
||||
<template id="EXECUTION_FORM_TEMPLATE">
|
||||
<div class="ccp-execution-form" name="execution_form">
|
||||
<h5 class="ccp-method-title"></h5>
|
||||
<p class="description font-italic font-weight-lighter"></p>
|
||||
<div name="plexiglass" class="ccp-invisible">
|
||||
<span name="status"></span>
|
||||
<span class="fas fa-spinner fa-spin"></span>
|
||||
</div>
|
||||
<form name="execution_form" class="d-flex flex-column gap-3" style="gap:5px">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5>Inputs</h5>
|
||||
</div>
|
||||
<div class="card-body ccp-inputs">
|
||||
<div class="card-body">
|
||||
<div class="form-group"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5>Outputs</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="form-row ccp-outputs">
|
||||
<div class="col form-group"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--div class="card">
|
||||
<div class="card-header">
|
||||
<h5>Runtimes <span alt="refresh" title="refresh" style="cursor:pointer" name="refresh-runtimes" class="text-info">↺</span></h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="ccp-runtimes">
|
||||
<div class="form-row">
|
||||
<select class="form-control">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div-->
|
||||
<button id="execute_method_button" class="btn btn-info">Execute</button>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
<template id="EXECUTION_FORM_EMPTY_TEMPLATE">
|
||||
<div name="execution_form">
|
||||
<i style="padding:3rem">Select a method</i>
|
||||
</div>
|
||||
</template>
|
||||
<div name="execution_form"></div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
loadMethod(){
|
||||
|
|
|
@ -49,12 +49,18 @@ class CCPInfrastructureList extends HTMLElement{
|
|||
</style>
|
||||
`;
|
||||
|
||||
#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"})
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ class CCPInputWidgetEditorController extends HTMLElement{
|
|||
this.innerHTML = `
|
||||
<details>
|
||||
<summary class="mb-3">
|
||||
<input class="form-control" style="width:auto;display:inline" required="required" name="id" value="${this.#input.id}"/>
|
||||
<input class="form-control" style="width:auto;display:inline" required="required" name="id" value="${this.#input.id}" title="Id of input"/>
|
||||
<button data-index="${this.#index}" name="delete-input" title="Delete" class="btn btn-danger ccp-toolbar-button">
|
||||
${this.#delete_icon}
|
||||
</button>
|
||||
|
@ -38,19 +38,19 @@ class CCPInputWidgetEditorController extends HTMLElement{
|
|||
<div style="padding-left: 1rem;border-left: 1px solid gray;">
|
||||
<div class="row mb-3">
|
||||
<div class="col">
|
||||
<div class="form-field">
|
||||
<div class="form-field" title="Title">
|
||||
<input name="title" class="form-control" placeholder="title" value="${this.#input.title}" required="required"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="form-field">
|
||||
<div class="form-field" title="description">
|
||||
<input name="description" class="form-control" placeholder="description" value="${this.#input.description}" required="required"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-3">
|
||||
<div class="form-field">
|
||||
<div class="form-field" title="Type">
|
||||
<label>Type</label>
|
||||
<select name="type" class="form-control" placeholder="type" value="${this.#input.schema.type}">
|
||||
<option value="string">String</option>
|
||||
|
@ -59,13 +59,13 @@ class CCPInputWidgetEditorController extends HTMLElement{
|
|||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="form-field">
|
||||
<div class="form-field" title="Minimum">
|
||||
<label>Min</label>
|
||||
<input value="${this.#input.minOccurs}" type="number" min="0" step="1" name="minOccurs" value="${this.#input.minOccurs}" required="required" class="form-control" placeholder="minOccurs"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="form-field">
|
||||
<div class="form-field" title="Maximum">
|
||||
<label>Max</label>
|
||||
<input value="${this.#input.maxOccurs}" type="number" min="0" step="1" name="maxOccurs" value="${this.#input.maxOccurs}" required="required" class="form-control" placeholder="maxOccurs"/>
|
||||
</div>
|
||||
|
@ -73,9 +73,9 @@ class CCPInputWidgetEditorController extends HTMLElement{
|
|||
</div>
|
||||
<div name="string-input" class="${this.#type === 'enum' ? 'd-none' : ''} row mb-3">
|
||||
<div class="col-3">
|
||||
<div class="form-field">
|
||||
<div class="form-field" title="Format">
|
||||
<label>Format</label>
|
||||
<select value="${this.#input.schema.format}" name="format" class="form-control" value="${this.#input.schema.format}">
|
||||
<select value="${this.#input.schema.format}" name="format" class="form-control">
|
||||
<option value="none">None</option>
|
||||
<option value="date">Date</option>
|
||||
<option value="time">Time</option>
|
||||
|
@ -84,7 +84,7 @@ class CCPInputWidgetEditorController extends HTMLElement{
|
|||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="col" title="Mime type">
|
||||
<label>Mime</label>
|
||||
<div class="form-field">
|
||||
<input value="${this.#input.schema.contentMediaType}" name="contentMediaType" class="form-control" placeholder="mime"/>
|
||||
|
@ -92,13 +92,13 @@ class CCPInputWidgetEditorController extends HTMLElement{
|
|||
</div>
|
||||
</div>
|
||||
<div name="enum-input" class="${this.#type !== 'enum' ? 'd-none' : ''} mb-3">
|
||||
<div class="form-field">
|
||||
<div class="form-field" title="options">
|
||||
<input name="options" class="form-control" type="text" placeholder="option"/>
|
||||
<small class="form-text text-muted">Comma separated list of options</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="form-field">
|
||||
<div class="form-field" title="Default value">
|
||||
<input value="${this.#input.schema.default}" name="default" class="form-control" placeholder="default"/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -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{
|
|||
<path d="M23,12L19,8V11H10V13H19V16M1,18V6C1,4.89 1.9,4 3,4H15A2,2 0 0,1 17,6V9H15V6H3V18H15V15H17V18A2,2 0 0,1 15,20H3A2,2 0 0,1 1,18Z" />
|
||||
</svg>
|
||||
`
|
||||
#delete_icon = `
|
||||
<svg style="width:24px;height:24px;pointer-events: none;" viewBox="0 0 24 24">
|
||||
<path d="M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z" />
|
||||
</svg>
|
||||
`
|
||||
|
||||
#ansible_icon = `
|
||||
<svg viewBox="0 0 24 24"><path fill="currentColor" d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10s10-4.5 10-10S17.5 2 12 2m4.1 15c-.19 0-.34-.1-.55-.27l-5.16-4.17l-1.73 4.34H7.17l4.37-10.51c.11-.28.35-.42.63-.42s.5.14.62.42l3.98 9.58c.04.11.07.22.07.29c-.01.42-.34.74-.74.74m-3.93-8.89l2.59 6.39l-3.91-3.08l1.32-3.31Z"></path>
|
||||
|
@ -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 = `
|
||||
<div class="ccp-method-editor">
|
||||
<div class="d-none plexiglass">
|
||||
|
@ -258,10 +357,15 @@ class CCPMethodEditorController extends HTMLElement{
|
|||
<div class="ccp-method-editor-form">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div>
|
||||
<span class="mr-2">${this.#current.title}</span>
|
||||
${this.renderSaveButton()}
|
||||
${this.renderResetButton()}
|
||||
<div class="ccp-toolbar-header">
|
||||
<div>
|
||||
<span name="header" class="mr-2">${this.#current.title}</span>
|
||||
</div>
|
||||
<div class="ccp-toolbar-right">
|
||||
${this.renderSaveButton()}
|
||||
${this.renderResetButton()}
|
||||
${ this.#isupdate ? this.renderDeleteButton() : "" }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
@ -299,17 +403,29 @@ class CCPMethodEditorController extends HTMLElement{
|
|||
</div>
|
||||
<details class="card">
|
||||
<summary class="card-header">
|
||||
<span class="mr-2">Inputs</span>
|
||||
${this.renderPlusButton("add-input")}
|
||||
<div class="ccp-toolbar-header">
|
||||
<div>
|
||||
<span class="mr-2">Inputs</span>
|
||||
</div>
|
||||
<div class="ccp-toolbar-right">
|
||||
${this.renderPlusButton("add-input")}
|
||||
</div>
|
||||
</div>
|
||||
</summary>
|
||||
<div class="card-body" name="input-list">
|
||||
</div>
|
||||
</details>
|
||||
<details class="card">
|
||||
<summary class="card-header" name="output-buttons">
|
||||
<span class="mr-2">Outputs</span>
|
||||
${this.renderStandardOutputButtons()}
|
||||
${this.renderPlusButton("add-output")}
|
||||
<div class="ccp-toolbar-header">
|
||||
<div>
|
||||
<span class="mr-2">Outputs</span>
|
||||
</div>
|
||||
<div class="ccp-toolbar-right">
|
||||
${this.renderStandardOutputButtons()}
|
||||
${this.renderPlusButton("add-output")}
|
||||
</div>
|
||||
</div>
|
||||
</summary>
|
||||
<div class="card-body" name="output-list">
|
||||
<d4s-ccp-output-editor></d4s-ccp-output-editor>
|
||||
|
@ -317,15 +433,22 @@ class CCPMethodEditorController extends HTMLElement{
|
|||
</div>
|
||||
<details class="card" name="script-list">
|
||||
<summary class="card-header">
|
||||
<span>Scripts</span>
|
||||
<select name="script-selector" style="border:none; padding:.3rem">
|
||||
<option value="deploy-script">Deploy</option>
|
||||
<option value="execute-script">Execute</option>
|
||||
<option value="fetch-output-script">Fetch output</option>
|
||||
<option value="undeploy-script">Undeploy</option>
|
||||
<option value="cancel-script">Cancel</option>
|
||||
</select>
|
||||
${ this.renderAnsibleIcon() }
|
||||
<div class="ccp-toolbar-header">
|
||||
<div>
|
||||
<span>Scripts</span>
|
||||
<select name="script-selector" style="border:none; padding:.3rem">
|
||||
<option value=""></option>
|
||||
<option value="deploy-script">Deploy</option>
|
||||
<option value="execute-script">Execute</option>
|
||||
<option value="fetch-output-script">Fetch output</option>
|
||||
<option value="undeploy-script">Undeploy</option>
|
||||
<option value="cancel-script">Cancel</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
${ this.renderAnsibleIcon() }
|
||||
</div>
|
||||
</div>
|
||||
</summary>
|
||||
<div class="card-body" name="input_container">
|
||||
${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 `
|
||||
<div title="Ansible" style="width:2rem;height:2rem;display:inline-block;vertical-align:middle;position:absolute;right:0;margin-right:1rem;opacity:0.4;">
|
||||
<div title="Ansible" style="width:2rem;height:2rem;position:absolute;right:5px;top:30%;opacity:0.4;">
|
||||
${ this.#ansible_icon }
|
||||
</div>
|
||||
`
|
||||
|
@ -557,6 +705,14 @@ class CCPMethodEditorController extends HTMLElement{
|
|||
`
|
||||
}
|
||||
|
||||
renderDeleteButton(){
|
||||
return `
|
||||
<button title="Delete" name="delete" class="btn btn-danger ccp-toolbar-button">
|
||||
${this.#delete_icon}
|
||||
</button>
|
||||
`
|
||||
}
|
||||
|
||||
renderResetButton(){
|
||||
return `
|
||||
<button name="reset" title="Reset" class="btn btn-primary ccp-toolbar-button">
|
||||
|
@ -658,7 +814,7 @@ class CCPMethodEditorController extends HTMLElement{
|
|||
|
||||
renderScripts(){
|
||||
return this.#current.additionalParameters.parameters.map(
|
||||
(script, i) => `<textarea rows="5" class="script-area form-control ${ i > 0 ? 'd-none' : ''}" name="${script.name}">${script.value[0]}</textarea>`
|
||||
(script, i) => `<textarea rows="5" class="script-area form-control d-none" name="${script.name}">${script.value[0]}</textarea>`
|
||||
).join("\n")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,29 +6,107 @@ class CCPMethodList extends HTMLElement{
|
|||
#filtered;
|
||||
#dragged = null;
|
||||
|
||||
#serviceurl = "https://nubis1.int.d4science.net:8080"
|
||||
#cdnurl = "https://cdn.dev.d4science.org/ccp/methodlistfragment.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.fetchProcesses()
|
||||
}
|
||||
|
||||
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
|
||||
console.log(this.#boot)
|
||||
this.fetchProcesses()
|
||||
}).catch(err=>{
|
||||
console.error(err)
|
||||
})
|
||||
render(){
|
||||
this.#rootdoc.innerHTML = `
|
||||
<div>
|
||||
<style>
|
||||
.process_container{
|
||||
display: flex;
|
||||
flex-direction:column;
|
||||
}
|
||||
input[name=search]{
|
||||
display: block;
|
||||
padding: 0.375rem 0.75rem;
|
||||
color: #495057;
|
||||
background-color: #fff;
|
||||
background-clip: padding-box;
|
||||
border: 1px solid #ced4da;
|
||||
border-radius: 0.25rem;
|
||||
transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out;
|
||||
}
|
||||
input:focus{
|
||||
border-color: #80bdff;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.2rem rgb(0 123 255 / 25%);
|
||||
}
|
||||
ul.process_list{
|
||||
list-style: none;
|
||||
padding-left: 0;
|
||||
color: #495057;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: .25rem;
|
||||
user-select: none;
|
||||
}
|
||||
li.process_list_item{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
cursor: pointer;
|
||||
border: solid 1px rgba(0,0,0,.3);
|
||||
padding: 0.3rem;
|
||||
border-radius: 0.3rem;
|
||||
box-shadow: #333333 1px 1px 4px;
|
||||
background: #eeeeee;
|
||||
transition: background .3s;
|
||||
}
|
||||
li.process_list_item:hover{
|
||||
background: #ffffff;
|
||||
}
|
||||
ul.keyword_list{
|
||||
list-style: none;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap:2px;
|
||||
padding-left: 0;
|
||||
font-size: x-small;
|
||||
font-weight: 300;
|
||||
}
|
||||
li.keyword_list_item{
|
||||
display: inline-block;
|
||||
padding: 0.25em 0.4em;
|
||||
line-height: 1;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
vertical-align: baseline;
|
||||
border-radius: 0.25rem;
|
||||
background-color: #eeffff;
|
||||
color: #0099CC;
|
||||
border: solid 1px #0099CC;
|
||||
}
|
||||
.process_list_item_header{
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
<template id="PROCESS_LIST_TEMPLATE">
|
||||
<ul class="process_list" name="process_list">
|
||||
<li class="process_list_item" draggable="true">
|
||||
<h4 class="process_list_item_header"></h4>
|
||||
<ul name="keywords" class="keyword_list">
|
||||
<li class="keyword_list_item"></li>
|
||||
</ul>
|
||||
<i></i>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
<div class="process_container">
|
||||
<input name="search" type="text"/>
|
||||
<ul name="process_list"></ul>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
connectedCallback(){
|
||||
|
@ -51,7 +129,6 @@ class CCPMethodList extends HTMLElement{
|
|||
}
|
||||
|
||||
showList(){
|
||||
//this.#data = JSON.parse(resp)
|
||||
this.enableSearch()
|
||||
this.updateList()
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ class CCPOutputWidgetEditorController extends HTMLElement {
|
|||
this.innerHTML = `
|
||||
<details>
|
||||
<summary class="mb-3">
|
||||
<input class="form-control" style="width:auto;display:inline" required="required" name="id" value="${this.#output.id}"/>
|
||||
<input class="form-control" style="width:auto;display:inline" required="required" name="id" value="${this.#output.id}" title="Id of output"/>
|
||||
<button data-index="${this.#index}" name="delete-output" title="Delete" class="btn btn-danger ccp-toolbar-button">
|
||||
${this.#delete_icon}
|
||||
</button>
|
||||
|
@ -37,38 +37,38 @@ class CCPOutputWidgetEditorController extends HTMLElement {
|
|||
<div style="padding-left: 1rem;border-left: 1px solid gray;">
|
||||
<div class="row mb-3">
|
||||
<div class="col">
|
||||
<div class="form-field">
|
||||
<div class="form-field" title="Title">
|
||||
<input name="title" class="form-control" placeholder="title" value="${this.#output.title}" required="required"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="form-field">
|
||||
<div class="form-field" title="Description">
|
||||
<input name="description" class="form-control" placeholder="description" value="${this.#output.description}" required="required"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col">
|
||||
<div class="form-field">
|
||||
<div class="form-field" title="Mininum cardinality">
|
||||
<input value="${this.#output.minOccurs}" type="number" min="0" step="1" name="minOccurs" class="form-control" placeholder="minOccurs"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="form-field">
|
||||
<div class="form-field" title="Maximum cardinality">
|
||||
<input value="${this.#output.maxOccurs}" type="number" min="0" step="1" name="maxOccurs" class="form-control" placeholder="maxOccurs"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-3">
|
||||
<div class="form-field">
|
||||
<div class="form-field" title="Type">
|
||||
<select name="type" class="form-control" placeholder="type">
|
||||
<option value="string">String</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="form-field">
|
||||
<div class="form-field" title="Mime type">
|
||||
<input value="${this.#output.schema.contentMediaType}" name="contentMediaType" class="form-control" placeholder="mime"/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue