diff --git a/ccp/index.html b/ccp/index.html index 3f1f78c..1d9d6ee 100644 --- a/ccp/index.html +++ b/ccp/index.html @@ -7,6 +7,8 @@ + + @@ -20,7 +22,7 @@
- +
@@ -29,6 +31,9 @@
+
+ +
diff --git a/ccp/js/executionformcontroller.js b/ccp/js/executionformcontroller.js index 8fc9150..54cc4ee 100644 --- a/ccp/js/executionformcontroller.js +++ b/ccp/js/executionformcontroller.js @@ -4,10 +4,36 @@ class CCPExecutionForm extends HTMLElement{ #rootdoc; #data; #method; - #executionmonitor; - #serviceurl; - + #messages = { + "en" : { + "confirm_form_overwrite" : "Please confirm the overwrite of the previous execution form.", + "Inputs" : "Inputs", + "Options" : "Options", + "Outputs" : "Outputs", + "Execute" : "Execute", + "execute_help" : "Submit an execution request", + "generate_code" : "Generate code for", + "generate_code_help" : "Generate example code for a selectable programming language or runtime", + "direct_link" : "Direct link", + "direct_link_help" : "Navigate to the link for directly reopening this method in the execution form", + "automatic_archive_option" : "Select what you like to archive automatically when the execution is completed", + "automatic_archive_provenance" : "Automatically archive whole execution provenance", + "automatic_archive_provenance_help" : "Automatically archive the whole execution provenance to the workspace", + "automatic_archive_outputs" : "Automatically archive uncompressed outputs only", + "automatic_archive_outputs_help" : "Automatically archive only the outputs to the workspace", + "automatic_archive_none" : "Do not archive anything automatically", + "automatic_archive_none_help" : "Do not archive anything automatically", + "execution_accepted" : "Execution request accepted with id: ", + "drop_method_invitation" : "Drop a method here to request an execution", + "err_execution_not_accepted" : "Error. Execution has not been accepted by server", + "err_code_generation" : "Error while generating code", + "err_load_method" : "Error while loading method", + "err_no_runtimes" : "This method has no compatible runtimes available", + "err_execute" : "Error while sending execution request", + } + } + constructor(){ super() this.#boot = document.querySelector("d4s-boot-2") @@ -35,6 +61,13 @@ class CCPExecutionForm extends HTMLElement{ return ["method"]; } + getLabel(key, localehint){ + const locale = localehint ? localehint : navigator.language + const actlocale = this.#messages[locale] ? locale : "en" + const msg = this.#messages[actlocale][key] + return msg == null || msg == undefined ? key : this.#messages[actlocale][key] + } + attributeChangedCallback(name, oldValue, newValue) { //if((oldValue != newValue) && (name === "method")){ if(name === "method"){ @@ -45,9 +78,14 @@ class CCPExecutionForm extends HTMLElement{ connectNewExecutionRequest(){ document.addEventListener("newexecutionrequest", ev=>{ - if(window.confirm("Please confirm overwrite of execution form?")){ + if(this.#data){ + if(window.confirm(this.getLabel("confirm_form_overwrite"))){ + this.setAttribute("method", ev.detail) + this.parentElement.scrollIntoViewIfNeeded() + } + }else{ this.setAttribute("method", ev.detail) - this.parentElement.scrollIntoViewIfNeeded() + this.parentElement.scrollIntoViewIfNeeded() } }) } @@ -72,7 +110,7 @@ class CCPExecutionForm extends HTMLElement{
-
Inputs
+
${this.getLabel("Inputs")}
@@ -82,30 +120,22 @@ class CCPExecutionForm extends HTMLElement{
-
Options
+
${this.getLabel("Options")}
- +
-
-
Outputs
+
${this.getLabel("Outputs")}
@@ -115,11 +145,11 @@ class CCPExecutionForm extends HTMLElement{
- +
-
- +
+
-
@@ -150,7 +180,7 @@ class CCPExecutionForm extends HTMLElement{
@@ -184,7 +214,7 @@ class CCPExecutionForm extends HTMLElement{ (resp)=>{ if(resp.status === 200){ return resp.json() - }else throw "Error retrieving process" + }else throw this.getLabel("err_load_method") } ).then(data=>{ this.#data = data @@ -218,18 +248,18 @@ class CCPExecutionForm extends HTMLElement{ 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" + throw this.getLabel("err_execute") } return reply.json() }).then(data=>{ if(data.status !== "accepted"){ - throw "Execution has not been accepted by server" + throw this.getLabel("err_execution_not_accepted") } const event = new CustomEvent('newexecution', { detail: data.jobID }); document.dispatchEvent(event) - this.writeToPlexi("Execution request accepted with id: " + data.jobID) + this.writeToPlexi(this.getLabel("execution_accepted") + " " + data.jobID) window.setTimeout(()=>this.unlockRender(), 3000) - }).catch(err => {alert("Unable to call execute: " + err); this.unlockRender()}) + }).catch(err => {alert(this.getLabel("err_execute") + ": " + err); this.unlockRender()}) } generateCode(mime, filename){ @@ -238,7 +268,7 @@ class CCPExecutionForm extends HTMLElement{ this.#boot.secureFetch( url, { method : "POST", body : JSON.stringify(req), headers : { "Content-Type" : "application/json", "Accept" : mime}} ).then(reply=>{ - if(reply.status !== 200) throw "Error while requesting code:"; + if(reply.status !== 200) throw this.getLabel("err_code_generation"); return reply.blob() }).then(blob => { const objectURL = URL.createObjectURL(blob) @@ -266,13 +296,6 @@ class CCPExecutionForm extends HTMLElement{ if(o.enabled) request.outputs[o.name] = { transmissionMode : "value" }; }) - /*const autoarchiveoption = this.#rootdoc.querySelector("input[name='auto-archive']") - const autoarchiveoutputsoption = this.#rootdoc.querySelector("input[name='auto-archive-outputs']") - if (autoarchiveoption.checked || autoarchiveoutputsoption.checked){ - request.subscribers = [] - if(autoarchiveoption.checked) request.subscribers.push({ successUri : "http://registry:8080/executions/archive-to-folder" }) - if(autoarchiveoutputsoption.checked) request.subscribers.push({ successUri : "http://registry:8080/executions/outputs/archive-to-folder" }) - }*/ const archiveoption = this.#rootdoc.querySelector("select[name='archive-selector']").value switch(archiveoption){ case 'execution': @@ -304,10 +327,6 @@ class CCPExecutionForm extends HTMLElement{ }) } - //initOptionValues(request){ - // const autoarchiveoption = this.#rootdoc.querySelector("select[name='auto-archive-outputs']") - // autoarchiveoption.checked = request.subscribers && request.subscribers.filter(s=>s.successUri === "http://registry:8080/executions/archive-to-folder").length === 1 - //} initOptionValues(request){ const archiveselector = this.#rootdoc.querySelector("select[name='archive-selector']") if(request.subscribers){ @@ -329,7 +348,7 @@ class CCPExecutionForm extends HTMLElement{ .then(resp=>{ if(resp.status === 200){ return resp.json() - }else throw "Error retrieving process" + }else throw this.getLabel("err_load_method") } ).then(data=>data) @@ -338,7 +357,7 @@ class CCPExecutionForm extends HTMLElement{ .then(resp=>{ if(resp.status === 200){ return resp.json() - }else throw "Error retrieving process" + }else throw this.getLabel("err_load_method") } ).then(data=>data) @@ -455,7 +474,7 @@ class CCPExecutionForm extends HTMLElement{ ev.preventDefault() ev.stopPropagation() if(this.#data.executable) this.sendExecutionRequest(); - else alert("This method has no compatible runtimes available") + else alert(this.getLabel("err_no_runtimes")) return false; } }, diff --git a/ccp/js/executionhistorycontroller.js b/ccp/js/executionhistorycontroller.js index 8b0d7f5..c33b789 100644 --- a/ccp/js/executionhistorycontroller.js +++ b/ccp/js/executionhistorycontroller.js @@ -13,11 +13,47 @@ class CCPExecutionHistory extends HTMLElement { #searchfield = null; #fileupload = null; #archiveupload = null; + #messages = { + "en" : { + "search" : "Search", + "refresh_help" : "Refresh contents of Execution Monitor", + "paste_link" : "Paste your link here", + "execution_monitor" : "Execution Monitor", + "failed_count_help" : "Count of failed executions", + "successful_count_help" : "Count of successful executions", + "running_count_help" : "Count of running executions", + "accepted_count_help" : "Count of accepted executions", + "download_help" : "Click to download outputs to your local disk", + "archive_execution_help" : "Archive whole execution to workspace folder", + "archive_outputs_help" : "Archive only outputs to workspace folder", + "re-submit_help" : "Re submit this exact execution", + "delete_help" : "Delete this execution", + "generate_code" : "Generate code for", + "generate_code_help" : "Generate code that replicates this exact execution on a chosen programming language or runtime", + "direct_link" : "Direct link", + "import_file_help" : "Import from a previosusly exported file on your local disk", + "import_link_help" : "Import execution from a link in your workspace", + "direct_link_help" : "Navigate to the direct link for opening this exact execution in the exeuction form", + "confirm_import_link" : "Please confirm importing of execution from link", + "confirm_import_file" : "Please confirm importing of execution from file", + "confirm_delete_execution" : "Please confirm deletion of this execution" + } + } + getLabel(key, localehint){ + const locale = localehint ? localehint : navigator.language + const actlocale = this.#messages[locale] ? locale : "en" + const msg = this.#messages[actlocale][key] + return msg == null || msg == undefined ? key : this.#messages[actlocale][key] + } + constructor(){ super() this.#boot = document.querySelector("d4s-boot-2") this.#rootdoc = this.attachShadow({ "mode" : "open"}) + } + + connectedCallback(){ this.#serviceurl = this.getAttribute("serviceurl") this.#broadcasturl = this.getAttribute("broadcasturl") if(!this.#broadcasturl){ @@ -26,9 +62,6 @@ class CCPExecutionHistory extends HTMLElement { this.#broadcasturl = this.#broadcasturl + "/ws/notification" this.#archive = this.getAttribute("archive") this.connectNewExecution() - } - - connectedCallback(){ this.connectBroadcastWithSubject() this.render() this.refreshExecutions() @@ -64,10 +97,10 @@ class CCPExecutionHistory extends HTMLElement {
- Z - Y - Y - X + Z + Y + Y + X
    @@ -78,7 +111,7 @@ class CCPExecutionHistory extends HTMLElement {
    ${ this.#archive ? ` - ` : `` @@ -89,13 +122,13 @@ class CCPExecutionHistory extends HTMLElement { - - -
-
- +
+
- - - - + + +
@@ -403,29 +454,29 @@ class CCPMethodEditorController extends HTMLElement { ${this.renderContexts()}
-
- +
+
-
- +
+
-
- +
+
-
- +
+
${this.renderKeywords()}
-
- +
+ ${this.renderCategoryHints()}
@@ -433,8 +484,8 @@ class CCPMethodEditorController extends HTMLElement {
-
- +
+ @@ -448,7 +499,7 @@ class CCPMethodEditorController extends HTMLElement {
- Inputs + ${this.getLabel("inputs")}
${this.renderStandardInputButtons()} @@ -463,7 +514,7 @@ class CCPMethodEditorController extends HTMLElement {
- Outputs + ${this.getLabel("outputs")}
${this.renderStandardOutputButtons()} @@ -475,14 +526,14 @@ class CCPMethodEditorController extends HTMLElement {
-
+
- Scripts + ${this.getLabel("scripts")}
@@ -549,7 +600,7 @@ class CCPMethodEditorController extends HTMLElement { }) this.#rootdoc.querySelector("button[name=reset]").addEventListener("click", ev => { - if (window.confirm("All unsaved data will be lost. Proceed?")) { + if (window.confirm(this.getLabel("confirm_reset"))) { this.resetMethod() } ev.preventDefault() @@ -862,7 +913,7 @@ class CCPMethodEditorController extends HTMLElement { renderSaveButton() { return ` - ` @@ -870,7 +921,7 @@ class CCPMethodEditorController extends HTMLElement { renderDeleteButton() { return ` - ` @@ -878,7 +929,7 @@ class CCPMethodEditorController extends HTMLElement { renderResetButton() { return ` - ` @@ -896,7 +947,7 @@ class CCPMethodEditorController extends HTMLElement { renderStandardInputButtons() { return ` - ` @@ -904,10 +955,10 @@ class CCPMethodEditorController extends HTMLElement { renderStandardOutputButtons() { return ` - - ` diff --git a/ccp/js/methodlistcontroller.js b/ccp/js/methodlistcontroller.js index 67d450f..b00568a 100644 --- a/ccp/js/methodlistcontroller.js +++ b/ccp/js/methodlistcontroller.js @@ -4,15 +4,29 @@ class CCPMethodList extends HTMLElement{ #rootdoc; #data = null; #filtered; - #dragged = null; #searchfield = null; #allowedit = false; #allowexecute = false; #archive = false; - #fileupload = null; - #archiveupload = null; - + //#fileupload = null; + //#archiveupload = null; #serviceurl; + #messages = { + "en" : { + "Methods" : "Methods", + "refresh_help" : "Refresh the list of available methods", + "Search" : "Search", + "count_executable_help" : "Number of executable methods", + "count_not_executable_help" : "Number of non executable methods", + "export_category_help" : "Export all the methods in this category as JSON files", + "export_method_help" : "Export this method as JSON file", + "archive_method_help" : "Export this method as JSON file to your workspace", + "shared_help" : "This method is shared in this community", + "share_help" : "You can share this method in this community", + "execute_help" : "Open method's form to set inputs and execute", + "edit_help" : "Open method's form for cloning, deriving or editing" + } + } constructor(){ super() @@ -21,6 +35,13 @@ class CCPMethodList extends HTMLElement{ this.#archive = this.getAttribute("archive") } + getLabel(key, localehint){ + const locale = localehint ? localehint : navigator.language + const actlocale = this.#messages[locale] ? locale : "en" + const msg = this.#messages[actlocale][key] + return msg == null || msg == undefined ? key : this.#messages[actlocale][key] + } + render(){ this.#rootdoc.innerHTML = ` @@ -47,9 +68,9 @@ class CCPMethodList extends HTMLElement{
- - -
@@ -61,26 +82,26 @@ class CCPMethodList extends HTMLElement{
- - - ${ this.#archive ? ` - ` : `` } -
@@ -102,13 +123,13 @@ class CCPMethodList extends HTMLElement{
- Methods + ${this.getLabel("Methods")}
- -
- +
    @@ -141,24 +162,24 @@ class CCPMethodList extends HTMLElement{ this.updateList() }) - this.#fileupload = this.#rootdoc.querySelector("label[name=fileupload] > input[type=file]") - this.#fileupload.addEventListener("change", ev=>{ - const filelist = ev.target.files; - if (filelist.length > 0) { - const files = Array.prototype.slice.call(filelist) - this.importMethods(files) - } - }) + // this.#fileupload = this.#rootdoc.querySelector("label[name=fileupload] > input[type=file]") + // this.#fileupload.addEventListener("change", ev=>{ + // const filelist = ev.target.files; + // if (filelist.length > 0) { + // const files = Array.prototype.slice.call(filelist) + // this.importMethods(files) + // } + // }) - this.#archiveupload = this.#rootdoc.querySelector("button[name=archive]") - this.#archiveupload.addEventListener("click", ev=>{ - const link = ev.target.parentElement.querySelector("input").value - if(link){ - if(confirm("Please confirm importing of method from link?")){ - this.fromArchive(link) - } - } - }) + // this.#archiveupload = this.#rootdoc.querySelector("button[name=archive]") + // this.#archiveupload.addEventListener("click", ev=>{ + // const link = ev.target.parentElement.querySelector("input").value + // if(link){ + // if(confirm("Please confirm importing of method from link?")){ + // this.fromArchive(link) + // } + // } + // }) } connectedCallback(){ @@ -457,6 +478,7 @@ class CCPMethodList extends HTMLElement{ span.classList.add("badge") span.classList.add("badge-warning") span.textContent = "shared" + span.alt = span.title = this.getLabel("shared_help") e.replaceWith(span) }else if(!this.isAuthor(d)){ e.parentElement.removeChild(e) diff --git a/ccp/js/outputwidgeteditorcontroller.js b/ccp/js/outputwidgeteditorcontroller.js index 6561873..9b4d391 100644 --- a/ccp/js/outputwidgeteditorcontroller.js +++ b/ccp/js/outputwidgeteditorcontroller.js @@ -3,13 +3,32 @@ class CCPOutputWidgetEditorController extends HTMLElement { #output = null #index = null #type = null - + #messages = { + "en" : { + "output_id_help" : "The Id of the output. This has to be unique accross all the outputs the method", + "output_delete_help" : "Delete this output", + "output_title_help" : "Title of the output. This is how the output will appear in forms.", + "output_description_help" : "A description for this output", + "min_occurs_help" : "Minimum cardinality", + "max_occurs_help" : "Msximum cardinality", + "mimetype_help" : "Set MIME type of expected output", + "file_path" : "Path to file", + "file_path_help" : "Define the path to the file holding the output. This documents the location of the output in the zip archive returned by the execution. Paths in the execution runtime instead are infrastructure dependant." + } + } #delete_icon = ` ` + getLabel(key, localehint){ + const locale = localehint ? localehint : navigator.language + const actlocale = this.#messages[locale] ? locale : "en" + const msg = this.#messages[actlocale][key] + return msg == null || msg == undefined ? key : this.#messages[actlocale][key] + } + constructor(){ super() } @@ -29,38 +48,38 @@ class CCPOutputWidgetEditorController extends HTMLElement { this.innerHTML = `
    - -
    -
    +
    -
    +
    -
    +
    -
    +
    -
    +
    -
    +
    @@ -110,8 +129,9 @@ class CCPOutputWidgetEditorController extends HTMLElement { if(this.#output.metadata && this.#output.metadata.length > 0){ return `
    -
    - +
    + +
    `