diff --git a/pom.xml b/pom.xml index 1a8fda392..d5e77f101 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ com.gw geoweaver - 1.4.3 + 1.4.5 geoweaver A lightweight workflow management software for organizing data analysis workflows, preserving history of every workflow run, and improving scientist producitvity and workflow FAIRness, diff --git a/src/main/resources/static/js/gw.about.js b/src/main/resources/static/js/gw.about.js index a223a80b3..87e8fcde5 100644 --- a/src/main/resources/static/js/gw.about.js +++ b/src/main/resources/static/js/gw.about.js @@ -1,35 +1,32 @@ /** - * + * * About Geoweaver Page - * + * */ GW.about = { - - dependency: "d3.js, bootstrap, jquery, codemirror, directed-graph-creator, dmuploader", - - content: "thanks to Colorado Reed (https://github.com/cjrd) for making the fantastic D3.js graph creator.", - - showDialog: function(){ - - var content = '
'+ - '

Geoweaver is a web system to allow users to easily compose and execute full-stack deep learning workflows in web browsers by ad hoc integrating the distributed spatial data facilities, high-performance computation platforms, and open-source deep learning libraries.

'+ - - '

Geoweaver (version '+ GW.version+') is currently supported by ESIPLab, NSF geoinformatics program #1947893 and #1947875 and '+ - 'NASA ACCESS-19. The source code is on Github.

'+ - - '

Geoweaver logo is designed by Dr. Annie Burgess contact.

'+ - - '

Geoweaver is a community effort and welcome all contributors. If you have any questions, please create a new issue in GitHub or directly contact us

'; - - - GW.process.createJSFrameDialog(720, 640, content, "About"); - - }, - - showTerms: function(){ - - var content = ` + dependency: + "d3.js, bootstrap, jquery, codemirror, directed-graph-creator, dmuploader", + + content: + "thanks to Colorado Reed (https://github.com/cjrd) for making the fantastic D3.js graph creator.", + + showDialog: function () { + var content = + '
' + + '

Geoweaver is a web system to allow users to easily compose and execute full-stack deep learning workflows in web browsers by ad hoc integrating the distributed spatial data facilities, high-performance computation platforms, and open-source deep learning libraries.

' + + '

Geoweaver (version ' + + GW.version + + ') is currently supported by ESIPLab, NSF geoinformatics program #1947893 and #1947875 and ' + + 'NASA ACCESS-19. The source code is on Github.

' + + '

Geoweaver logo is designed by Dr. Annie Burgess contact.

' + + '

Geoweaver is a community effort and welcome all contributors. If you have any questions, please create a new issue in GitHub or directly contact us

'; + + GW.process.createJSFrameDialog(720, 640, content, "About"); + }, + + showTerms: function () { + var content = `

1. Scope

@@ -103,10 +100,8 @@ GW.about = {

12.1. Any supplementary agreement requires the written form.

12.2. The individual pages of the Geoweaver software are normally self operated and administered by Geoweaver users. The pages comply with the law applicable in the country where the responsible company has its business residence. Geoweaver provider makes no representation that information, software and/or documentation on the Geoweaver software are appropriate or available for viewing or downloading at locations outside such country. If Users access Geoweaver software from outside such country, they are exclusively responsible for compliance with all applicable local laws. Access to Geoweaver software's information, software and/or documentation from countries where such content is unlawful is prohibited. In this case and where User seeks to do business with Geoweaver provider, the User should contact the Geoweaver provider representative for the particular country for country specific business.

12.3. These Terms of Use shall be governed by - and all disputes relating to or in connection with these Terms of Use or their subject matter shall be resolved in accordance with - the laws of U.S.A, to the exclusion of its conflict of laws rules. The application of the United Nations Convention on Contracts for the International Sales of Goods (CISG) of 11 April 1980 is excluded.

-
]` - - GW.process.createJSFrameDialog(720, 640, content, "User Terms"); + ]`; - } - -} \ No newline at end of file + GW.process.createJSFrameDialog(720, 640, content, "User Terms"); + }, +}; diff --git a/src/main/resources/static/js/gw.chart.js b/src/main/resources/static/js/gw.chart.js index 146ed0f0b..2fba773bf 100644 --- a/src/main/resources/static/js/gw.chart.js +++ b/src/main/resources/static/js/gw.chart.js @@ -1,441 +1,402 @@ +GW.chart = { + history_chart: {}, + chartColors: { + red: "rgb(255, 99, 132)", + orange: "rgb(255, 159, 64)", + yellow: "rgb(255, 205, 86)", + green: "rgb(75, 192, 192)", + blue: "rgb(54, 162, 235)", + purple: "rgb(153, 102, 255)", + grey: "rgb(201, 203, 207)", + }, -GW.chart = { - - history_chart: {}, - - chartColors : { - red: 'rgb(255, 99, 132)', - orange: 'rgb(255, 159, 64)', - yellow: 'rgb(255, 205, 86)', - green: 'rgb(75, 192, 192)', - blue: 'rgb(54, 162, 235)', - purple: 'rgb(153, 102, 255)', - grey: 'rgb(201, 203, 207)' - }, - - MONTHS : [ - 'January', - 'February', - 'March', - 'April', - 'May', - 'June', - 'July', - 'August', - 'September', - 'October', - 'November', - 'December' - ], - - COLORS : [ - '#4dc9f6', - '#f67019', - '#f53794', - '#537bc4', - '#acc236', - '#166a8f', - '#00a950', - '#58595b', - '#8549ba' - ], - - utils : { - // Adapted from http://indiegamr.com/generate-repeatable-random-numbers-in-js/ - srand: function(seed) { - this._seed = seed; - }, - - rand: function(min, max) { - var seed = this._seed; - min = min === undefined ? 0 : min; - max = max === undefined ? 1 : max; - this._seed = (seed * 9301 + 49297) % 233280; - var res = min + (this._seed / 233280) * (max - min); - return res; - }, - - numbers: function(config) { - var cfg = config || {}; - var min = cfg.min || 0; - var max = cfg.max || 1; - var from = cfg.from || []; - var count = cfg.count || 8; - var decimals = cfg.decimals || 8; - var continuity = cfg.continuity || 1; - var dfactor = Math.pow(10, decimals) || 0; - var data = []; - var i, value; - - for (i = 0; i < count; ++i) { - value = (from[i] || 0) + this.rand(min, max); - if (this.rand() <= continuity) { - data.push(Math.round(dfactor * value) / dfactor); - } else { - data.push(null); - } - } - - return data; - }, - - labels: function(config) { - var cfg = config || {}; - var min = cfg.min || 0; - var max = cfg.max || 100; - var count = cfg.count || 8; - var step = (max - min) / count; - var decimals = cfg.decimals || 8; - var dfactor = Math.pow(10, decimals) || 0; - var prefix = cfg.prefix || ''; - var values = []; - var i; - - for (i = min; i < max; i += step) { - values.push(prefix + Math.round(dfactor * i) / dfactor); - } - - return values; - }, - - months: function(config) { - var cfg = config || {}; - var count = cfg.count || 12; - var section = cfg.section; - var values = []; - var i, value; - - for (i = 0; i < count; ++i) { - value = MONTHS[Math.ceil(i) % 12]; - values.push(value.substring(0, section)); - } - - return values; - }, - - color: function(index) { - return COLORS[index % COLORS.length]; - }, - - transparentize: function(color, opacity) { - var alpha = opacity === undefined ? 0.5 : 1 - opacity; - return Color(color).alpha(alpha).rgbString(); - } - }, - - randomScalingFactor : function() { - var num = Math.round(this.utils.rand(-100, 100)); -// console.log("numbers: " + num) - return num - }, - - getYYYYMMDD: function(date){ - - var yyyy = date.getFullYear(); - - var mm = date.getMonth() + 1; - - var mm = (mm>9 ? '' : '0') + mm; - - var dd = date.getDate(); - - var dd = (dd>9 ? '' : '0') + dd; - - return yyyy + mm + dd; - - }, - - isInSameDay: function(date1, date2){ - - var day1 = this.getYYYYMMDD(date1); - - var day2 = this.getYYYYMMDD(date2); - - var isin = false; - - if(day1==day2){ - - isin =true; - - } - - return isin; - - }, - - renderUtil: function(type, msg, process_history_container_id){ - - this.utils.srand(Date.now()); - - var labels = [], succeed = [], failed = [], running = [], unknown = []; - - // { - // "history_id":"BSoARJLDm5cD", - // "history_input":"\n", - // "history_output":"3.9.7 \n", - // "history_begin_time":1641022884104, - // "history_end_time":1641022889227, - // "history_notes":null, - // "history_process":"beqbtr", - // "host_id":null, - // "indicator":"Done" - // } - - //sort the array ascending from early to later - - for(var i=0;i next_time.getTime()){ - - var swap = msg[i]; - msg[i] = msg[j]; - msg[j] = swap; - current_time = new Date(msg[i].begin_time); - - } - - } - - } - - console.log("Sorted Array: ", msg); - - //count how many runs on each day - - var previous = null; - - var suc_times = 0, fail_times = 0, running_times = 0, unknown_times = 0; - - for(var i=0;i 9 ? "" : "0") + mm; + + var dd = date.getDate(); + + var dd = (dd > 9 ? "" : "0") + dd; + + return yyyy + mm + dd; + }, + + isInSameDay: function (date1, date2) { + var day1 = this.getYYYYMMDD(date1); + + var day2 = this.getYYYYMMDD(date2); + + var isin = false; + + if (day1 == day2) { + isin = true; + } + + return isin; + }, + + renderUtil: function (type, msg, process_history_container_id) { + this.utils.srand(Date.now()); + + var labels = [], + succeed = [], + failed = [], + running = [], + unknown = []; + + // { + // "history_id":"BSoARJLDm5cD", + // "history_input":"\n", + // "history_output":"3.9.7 \n", + // "history_begin_time":1641022884104, + // "history_end_time":1641022889227, + // "history_notes":null, + // "history_process":"beqbtr", + // "host_id":null, + // "indicator":"Done" + // } + + //sort the array ascending from early to later + + for (var i = 0; i < msg.length; i += 1) { + var current_time = new Date(msg[i].history_begin_time); + + for (var j = i + 1; j < msg.length; j += 1) { + var next_time = new Date(msg[j].history_begin_time); + + if (current_time.getTime() > next_time.getTime()) { + var swap = msg[i]; + msg[i] = msg[j]; + msg[j] = swap; + current_time = new Date(msg[i].begin_time); + } + } + } + + console.log("Sorted Array: ", msg); + + //count how many runs on each day + + var previous = null; + + var suc_times = 0, + fail_times = 0, + running_times = 0, + unknown_times = 0; + + for (var i = 0; i < msg.length; i += 1) { + var current = new Date(msg[i].history_begin_time); + + if (previous == null) { + previous = current; + + labels.push(this.getYYYYMMDD(current)); + + if (msg[i].indicator == "Done") { + suc_times += 1; + } else if (msg[i].indicator == "Failed") { + fail_times += 1; + } else if (msg[i].indicator == "Running") { + running_times += 1; + } else { + unknown_times += 1; + } + + if (msg.length == 1) { + succeed.push(suc_times); + + failed.push(fail_times); + + running.push(running_times); + + unknown.push(unknown_times); + } + } else if (this.isInSameDay(current, previous)) { + if (msg[i].indicator == "Done") { + suc_times += 1; + } else if (msg[i].indicator == "Failed") { + fail_times += 1; + } else if (msg[i].indicator == "Running") { + running_times += 1; + } else { + unknown_times += 1; + } + + if (i == msg.length - 1) { + succeed.push(suc_times); + + failed.push(fail_times); + + running.push(running_times); + + unknown.push(unknown_times); + } + } else if (!this.isInSameDay(current, previous)) { + previous = current; + + succeed.push(suc_times); + + failed.push(fail_times); + + running.push(running_times); + + unknown.push(unknown_times); + + labels.push(this.getYYYYMMDD(current)); + + (suc_times = 0), + (fail_times = 0), + (running_times = 0), + (unknown_times = 0); + + if (msg[i].indicator == "Done") { + suc_times += 1; + } else if (msg[i].indicator == "Failed") { + fail_times += 1; + } else if (msg[i].indicator == "Running") { + running_times += 1; + } else { + unknown_times += 1; + } + + if (i == msg.length - 1) { + succeed.push(suc_times); + + failed.push(fail_times); + + running.push(running_times); + + unknown.push(unknown_times); + } + } + } + + console.log(labels); + + console.log(succeed); + + $("#" + type + "-history-chart").html(""); + + var ctx = document.getElementById(type + "-history-chart").getContext("2d"); + + // if the type is process then getting the right history chart from the right parent container + if (type == "process" && process_history_container_id !== null) { + let chart_parent_container = document.querySelector( + process_history_container_id, + ); + ctx = chart_parent_container + .querySelector("#" + type + "-history-chart") + .getContext("2d"); + } + var config = { + type: "line", + data: { + labels: labels, + datasets: [ + { + label: "Running", + fill: false, + backgroundColor: this.chartColors.blue, + borderColor: this.chartColors.blue, + borderDash: [5, 5], + data: running, + }, + { + label: "Done", + fill: false, + backgroundColor: this.chartColors.green, + borderColor: this.chartColors.green, + borderDash: [5, 5], + data: succeed, + }, + { + label: "Failed", + backgroundColor: this.chartColors.red, + borderColor: this.chartColors.red, + borderDash: [5, 5], + data: failed, + }, + { + label: "Unknown", + backgroundColor: this.chartColors.grey, + borderColor: this.chartColors.grey, + borderDash: [5, 5], + data: unknown, + }, + ], + }, + options: { + responsive: true, + title: { + display: true, + text: type + " Execution History Chart", + }, + tooltips: { + mode: "index", + intersect: false, + }, + hover: { + mode: "nearest", + intersect: true, + }, + scales: { + xAxes: [ + { + display: true, + scaleLabel: { + display: true, + labelString: "Date", + }, + }, + ], + yAxes: [ + { + display: true, + scaleLabel: { + display: true, + labelString: "Number of Runs", + }, + }, + ], + }, + }, + }; + + this.history_chart[type] = new Chart(ctx, config); + }, + + renderProcessHistoryChart: function (msg, process_history_container_id) { + msg = msg.sort(function (x, y) { + return x["history_begin_time"] - y["history_begin_time"]; + }); + this.renderUtil("process", msg, process_history_container_id); + }, + + renderWorkflowHistoryChart: function (msg) { + this.renderUtil("workflow", msg); + }, + + renderHostHistoryChart: function (msg) { + this.renderUtil("host", msg); + }, +}; diff --git a/src/main/resources/static/js/gw.comparison.js b/src/main/resources/static/js/gw.comparison.js index 6c505cd94..f29d0898d 100644 --- a/src/main/resources/static/js/gw.comparison.js +++ b/src/main/resources/static/js/gw.comparison.js @@ -1,148 +1,120 @@ /** - * + * * This class is for comparing two historical version of one process/notebook/script - * + * */ GW.comparison = { - - list_hist_ids: [], - - list_history: [], - - compare_frame: null, - - show: function(){ - - this.list_hist_ids = []; - - this.list_history = []; //clear the current comparison - - var count = 0; - - $(".hist-checkbox:checked").each(function() { - - var histid = $(this).attr('id').substring(9); - - count+=1; - - if(count > 2) { - - return; - - } - -// console.log("Removing "+histid); - -// GW.host.deleteJupyterDirectly(histid.substring(9)); - - $.ajax({ - - url: "log", - - method: "POST", - - data: "type=host&id=" + histid - - }).done(function(msg){ - - if(msg==""){ - - alert("Cannot find the host history in the database."); - - return; - - } - - msg = $.parseJSON(msg); - - var code = msg.output; - - if(code!=null && typeof code != 'undefined'){ - - if(typeof code != 'object'){ - - code = $.parseJSON(code); - - } - - GW.comparison.list_history.push(code); - - GW.comparison.list_hist_ids.push(histid); - - if (GW.comparison.list_history.length==2) { - - GW.comparison.showDialog(); - - } - - } - - - }).fail(function(e){ - - console.error(e); - - }); - - }); - - }, - - showDialog: function(){ - - var notebook1 = nb.parse(GW.comparison.list_history[0].content); - - var notebook2 = nb.parse(GW.comparison.list_history[1].content); - - var rendered1 = notebook1.render(); - - var rendered2 = notebook2.render(); - - var content = ''; - - content += ''; - -// console.log(content); - - GW.comparison.compare_frame = GW.process.createJSFrameDialog(800, 600, content, "History Comparison " + GW.comparison.list_hist_ids[0] + - " vs " + GW.comparison.list_hist_ids[1]); - - $("#compare-download-btn").click(function(){ - - GW.host.downloadJupyter(GW.comparison.list_hist_ids[0]); - GW.host.downloadJupyter(GW.comparison.list_hist_ids[1]); - - }) - - $("#compare-cancel-btn").click(function(){ - - GW.comparison.compare_frame.closeFrame(); - - }); - - } - - -} + list_hist_ids: [], + + list_history: [], + + compare_frame: null, + + show: function () { + this.list_hist_ids = []; + + this.list_history = []; //clear the current comparison + + var count = 0; + + $(".hist-checkbox:checked").each(function () { + var histid = $(this).attr("id").substring(9); + + count += 1; + + if (count > 2) { + return; + } + + // console.log("Removing "+histid); + + // GW.host.deleteJupyterDirectly(histid.substring(9)); + + $.ajax({ + url: "log", + + method: "POST", + + data: "type=host&id=" + histid, + }) + .done(function (msg) { + if (msg == "") { + alert("Cannot find the host history in the database."); + + return; + } + + msg = $.parseJSON(msg); + + var code = msg.output; + + if (code != null && typeof code != "undefined") { + if (typeof code != "object") { + code = $.parseJSON(code); + } + + GW.comparison.list_history.push(code); + + GW.comparison.list_hist_ids.push(histid); + + if (GW.comparison.list_history.length == 2) { + GW.comparison.showDialog(); + } + } + }) + .fail(function (e) { + console.error(e); + }); + }); + }, + + showDialog: function () { + var notebook1 = nb.parse(GW.comparison.list_history[0].content); + + var notebook2 = nb.parse(GW.comparison.list_history[1].content); + + var rendered1 = notebook1.render(); + + var rendered2 = notebook2.render(); + + var content = + '"; + + content += + '"; + + // console.log(content); + + GW.comparison.compare_frame = GW.process.createJSFrameDialog( + 800, + 600, + content, + "History Comparison " + + GW.comparison.list_hist_ids[0] + + " vs " + + GW.comparison.list_hist_ids[1], + ); + + $("#compare-download-btn").click(function () { + GW.host.downloadJupyter(GW.comparison.list_hist_ids[0]); + GW.host.downloadJupyter(GW.comparison.list_hist_ids[1]); + }); + + $("#compare-cancel-btn").click(function () { + GW.comparison.compare_frame.closeFrame(); + }); + }, +}; diff --git a/src/main/resources/static/js/gw.dashboard.js b/src/main/resources/static/js/gw.dashboard.js index 7a6e0f2c4..62c2f1f61 100644 --- a/src/main/resources/static/js/gw.dashboard.js +++ b/src/main/resources/static/js/gw.dashboard.js @@ -1,340 +1,326 @@ /** - * + * * Dashboard tab - * + * */ GW.board = { + real_time_status_chart: null, + time_cost_chart: null, + /** + * Initialize the tab panel, this function should be only called when app is loaded + * after that, call refresh() directly. + */ + init: function () { + this.display(); + + this.refresh(); + }, + + /** + * Add values to those charts and tables + */ + refresh: function () { + $.ajax({ + url: "dashboard", + + method: "POST", + + data: "", + }) + .done(function (msg) { + if (!msg.length) { + console.error("no dashboard info found"); + + return; + } - real_time_status_chart: null, - time_cost_chart: null, - /** - * Initialize the tab panel, this function should be only called when app is loaded - * after that, call refresh() directly. - */ - init: function(){ - - this.display(); - - this.refresh(); - - }, - - /** - * Add values to those charts and tables - */ - refresh: function(){ - - $.ajax({ - - url: "dashboard", - - method: "POST", - - data: "" - - }).done(function(msg){ - - if(!msg.length){ - - console.error("no dashboard info found"); - - return; - - } - - msg = $.parseJSON(msg); - - console.log(msg); - - // { "process_num":12,"history_num":99,"host_num":1,"workflow_num":4,"environment_num":39,"process_shell_num":3,"process_notebook_num":0,"process_python_num":4,"process_builtin_num":3,"host_ssh_num":1,"host_jupyter_num":0,"host_jupyterlab_num":0,"host_jupyterhub_num":0,"host_gee_num":0,"running_process_num":2,"failed_process_num":15,"success_process_num":47,"running_workflow_num":0,"failed_workflow_num":0,"success_workflow_num":0} - - $("#host_num").html(msg.host_num) - - $("#host_ssh_num").html(msg.host_ssh_num) - - $("#host_jupyter_num").html(msg.host_jupyter_num) - - $("#host_jupyterlab_num").html(msg.host_jupyterlab_num) - - $("#host_jupyterhub_num").html(msg.host_jupyterhub_num) - - $("#host_gee_num").html(msg.host_gee_num) - - $("#process_num").html(msg.process_num) - - $("#process_shell_num").html(msg.process_shell_num) - - $("#process_notebook_num").html(msg.process_notebook_num) - - $("#process_python_num").html(msg.process_python_num) - - $("#process_builtin_num").html(msg.process_builtin_num) - - $("#workflow_num").html(msg.workflow_num); - - $("#running_workflow_num").html(msg.running_workflow_num) - - $("#failed_workflow_num").html(msg.failed_workflow_num) - - $("#success_workflow_num").html(msg.success_workflow_num) - - GW.board.real_time_status_chart.data.datasets[0].data = [ - msg.running_process_num, msg.failed_process_num, msg.success_process_num, - msg.running_workflow_num, msg.failed_workflow_num, msg.success_workflow_num - ] - - GW.board.real_time_status_chart.update(); + msg = $.parseJSON(msg); - var time_costs = msg.time_costs.map(x=>+x); + console.log(msg); - time_costs = GW.board.removeMinusOne(time_costs); + // { "process_num":12,"history_num":99,"host_num":1,"workflow_num":4,"environment_num":39,"process_shell_num":3,"process_notebook_num":0,"process_python_num":4,"process_builtin_num":3,"host_ssh_num":1,"host_jupyter_num":0,"host_jupyterlab_num":0,"host_jupyterhub_num":0,"host_gee_num":0,"running_process_num":2,"failed_process_num":15,"success_process_num":47,"running_workflow_num":0,"failed_workflow_num":0,"success_workflow_num":0} - var maxmin = GW.board.findMaxMin(time_costs); + $("#host_num").html(msg.host_num); - var max_value = maxmin[0].toFixed(); + $("#host_ssh_num").html(msg.host_ssh_num); - var min_value = maxmin[1].toFixed(); + $("#host_jupyter_num").html(msg.host_jupyter_num); - var first_splitter = (max_value-min_value)/3 + min_value; first_splitter = Number(first_splitter).toFixed(); + $("#host_jupyterlab_num").html(msg.host_jupyterlab_num); - var second_splitter = (max_value-min_value)*2/3 + min_value;second_splitter = Number(second_splitter).toFixed(); + $("#host_jupyterhub_num").html(msg.host_jupyterhub_num); - GW.board.time_cost_chart.data.labels = [min_value + " - " + first_splitter + " ms", first_splitter + - " - " + second_splitter + " ms", second_splitter + " - " + max_value + " ms"] + $("#host_gee_num").html(msg.host_gee_num); - GW.board.time_cost_chart.data.datasets[0].data = GW.board.calculateFrequency(time_costs, first_splitter, second_splitter); + $("#process_num").html(msg.process_num); - // GW.board.time_cost_chart.title.text = "Time Cost (unit: milliseconds)"; + $("#process_shell_num").html(msg.process_shell_num); - GW.board.time_cost_chart.update(); + $("#process_notebook_num").html(msg.process_notebook_num); - }).fail(function(jxr, status){ - - console.error(status); - - });; + $("#process_python_num").html(msg.process_python_num); - }, + $("#process_builtin_num").html(msg.process_builtin_num); - calculateFrequency: function(thearr, first_splitter, second_splitter){ + $("#workflow_num").html(msg.workflow_num); - var lvl1 = 0; - var lvl2 = 0; - var lvl3 = 0; + $("#running_workflow_num").html(msg.running_workflow_num); - for(var i=0;ifirst_splitter && thearr[i]<=second_splitter){ + GW.board.real_time_status_chart.update(); - lvl2 += 1 + var time_costs = msg.time_costs.map((x) => +x); - }else if(thearr[i]>second_splitter){ + time_costs = GW.board.removeMinusOne(time_costs); - lvl3 += 1 + var maxmin = GW.board.findMaxMin(time_costs); - } + var max_value = maxmin[0].toFixed(); - } + var min_value = maxmin[1].toFixed(); - return [lvl1, lvl2, lvl3] + var first_splitter = (max_value - min_value) / 3 + min_value; + first_splitter = Number(first_splitter).toFixed(); - }, + var second_splitter = ((max_value - min_value) * 2) / 3 + min_value; + second_splitter = Number(second_splitter).toFixed(); - findMaxMin: function(thearr){ + GW.board.time_cost_chart.data.labels = [ + min_value + " - " + first_splitter + " ms", + first_splitter + " - " + second_splitter + " ms", + second_splitter + " - " + max_value + " ms", + ]; - var maxv = thearr[0], minv = thearr[0]; + GW.board.time_cost_chart.data.datasets[0].data = + GW.board.calculateFrequency( + time_costs, + first_splitter, + second_splitter, + ); - for(var i=0;i thearr[i]) minv = thearr[i]; + calculateFrequency: function (thearr, first_splitter, second_splitter) { + var lvl1 = 0; + var lvl2 = 0; + var lvl3 = 0; - } + for (var i = 0; i < thearr.length; i += 1) { + if (thearr[i] <= first_splitter) { + lvl1 += 1; + } else if (thearr[i] > first_splitter && thearr[i] <= second_splitter) { + lvl2 += 1; + } else if (thearr[i] > second_splitter) { + lvl3 += 1; + } + } - return [maxv, minv]; + return [lvl1, lvl2, lvl3]; + }, - }, + findMaxMin: function (thearr) { + var maxv = thearr[0], + minv = thearr[0]; - removeMinusOne: function(thearr){ + for (var i = 0; i < thearr.length; i += 1) { + if (maxv < thearr[i]) maxv = thearr[i]; - var newarr = [] + if (minv > thearr[i]) minv = thearr[i]; + } - for (var i = 0; i < thearr.length; i++) { + return [maxv, minv]; + }, - if (Number(thearr[i]) != -1) { - newarr.push(Number(thearr[i])) - } - } - - - return newarr; - - }, - - renderRealTimeStatusChart: function(){ - - var ctx = document.getElementById('real_time_status_canvas').getContext('2d'); - this.real_time_status_chart = new Chart(ctx, { - type: 'bar', - data: { - labels: ['Running Process', 'Failed Process', 'Done Process', 'Running Workflow', 'Failed Workflow', 'Done Workflow'], - datasets: [{ - label: '# of Processes/Workflows', - data: [0, 0, 0, 0, 0, 0], - backgroundColor: [ - 'rgba(255, 99, 132, 0.2)', - 'rgba(54, 162, 235, 0.2)', - 'rgba(255, 206, 86, 0.2)', - 'rgba(75, 192, 192, 0.2)', - 'rgba(153, 102, 255, 0.2)', - 'rgba(255, 159, 64, 0.2)' - ], - borderColor: [ - 'rgba(255, 99, 132, 1)', - 'rgba(54, 162, 235, 1)', - 'rgba(255, 206, 86, 1)', - 'rgba(75, 192, 192, 1)', - 'rgba(153, 102, 255, 1)', - 'rgba(255, 159, 64, 1)' - ], - borderWidth: 1 - }] - }, - options: { - scales: { - y: { - beginAtZero: true - } - } - } - }); - - - }, - - renderTimeCostChart: function(){ - - var ctx = document.getElementById('time_cost_canvas').getContext('2d'); - this.time_cost_chart = new Chart(ctx, { - type: 'doughnut', - data: { - labels: [ - 'Red', - 'Blue', - 'Yellow' - ], - datasets: [{ - label: 'My First Dataset', - data: [300, 50, 100], - backgroundColor: [ - 'rgb(255, 99, 132)', - 'rgb(54, 162, 235)', - 'rgb(255, 205, 86)' - ], - hoverOffset: 4 - }] - } - }); - - }, - - /** - * Show all the charts and tables (empty) - */ - display: function(){ - - var cont = ""; - - //list the number of hosts, processes, and workflows - cont += '
'+ - '
'+ - '
'+ - '
'+ - '

Host

'+ - '
'+ - '
    '+ - '
  • hosts

  • '+ - '
  • SSH hosts

  • '+ - '
  • Jupyter Notebook hosts

  • '+ - '
  • JupyterHub hosts

  • '+ - '
  • JupyterLab hosts

  • '+ - '
  • Earth Engine hosts

  • '+ - '
'+ - '
'+ - '
'+ - - '
'+ - '
'+ - '
'+ - '

Process

'+ - '
'+ - '
    '+ - '
  • processes

  • '+ - '
  • Shell processes

  • '+ - '
  • Jupyter notebooks

  • '+ - '
  • builtin processes

  • '+ - '
  • python processes

  • '+ - '
'+ - '
'+ - '
'+ - '
'+ - '
'+ - '
'+ - '

Workflows

'+ - '
'+ - '
    '+ - '
  • workflows

  • '+ - '
  • pending workflow runs

  • '+ - '
  • failed workflow runs

  • '+ - '
  • successful workflow runs

  • '+ - '
'+ - '
'+ - '
'+ - - '
'; - - //list the statistics of each categories of hosts, processes, and workflows - cont += '
'+ - '
'+ - '
'+ - '
'+ - '

Real Time Status

'+ - '
'+ - '
'+ - ' '+ - '
'+ - '
'+ - '
'+ - '
'+ - '
'+ - '
'+ - '

Time Cost

'+ - '
'+ - '
'+ - ' '+ - '
'+ - '
'+ - '
'+ - '
'; - - //list the status of processes and workflows - cont += ""; - - //show the average time cost and history recorded - - - $("#main-dashboard-content").html(cont); - - this.renderRealTimeStatusChart(); - - this.renderTimeCostChart(); + removeMinusOne: function (thearr) { + var newarr = []; + for (var i = 0; i < thearr.length; i++) { + if (Number(thearr[i]) != -1) { + newarr.push(Number(thearr[i])); + } } -} \ No newline at end of file + return newarr; + }, + + renderRealTimeStatusChart: function () { + var ctx = document + .getElementById("real_time_status_canvas") + .getContext("2d"); + this.real_time_status_chart = new Chart(ctx, { + type: "bar", + data: { + labels: [ + "Running Process", + "Failed Process", + "Done Process", + "Running Workflow", + "Failed Workflow", + "Done Workflow", + ], + datasets: [ + { + label: "# of Processes/Workflows", + data: [0, 0, 0, 0, 0, 0], + backgroundColor: [ + "rgba(255, 99, 132, 0.2)", + "rgba(54, 162, 235, 0.2)", + "rgba(255, 206, 86, 0.2)", + "rgba(75, 192, 192, 0.2)", + "rgba(153, 102, 255, 0.2)", + "rgba(255, 159, 64, 0.2)", + ], + borderColor: [ + "rgba(255, 99, 132, 1)", + "rgba(54, 162, 235, 1)", + "rgba(255, 206, 86, 1)", + "rgba(75, 192, 192, 1)", + "rgba(153, 102, 255, 1)", + "rgba(255, 159, 64, 1)", + ], + borderWidth: 1, + }, + ], + }, + options: { + scales: { + y: { + beginAtZero: true, + }, + }, + }, + }); + }, + + renderTimeCostChart: function () { + var ctx = document.getElementById("time_cost_canvas").getContext("2d"); + this.time_cost_chart = new Chart(ctx, { + type: "doughnut", + data: { + labels: ["Red", "Blue", "Yellow"], + datasets: [ + { + label: "My First Dataset", + data: [300, 50, 100], + backgroundColor: [ + "rgb(255, 99, 132)", + "rgb(54, 162, 235)", + "rgb(255, 205, 86)", + ], + hoverOffset: 4, + }, + ], + }, + }); + }, + + /** + * Show all the charts and tables (empty) + */ + display: function () { + var cont = ""; + + //list the number of hosts, processes, and workflows + cont += + '
' + + '
' + + '
' + + '
' + + '

Host

' + + "
" + + '
    ' + + '
  • hosts

  • ' + + '
  • SSH hosts

  • ' + + '
  • Jupyter Notebook hosts

  • ' + + '
  • JupyterHub hosts

  • ' + + '
  • JupyterLab hosts

  • ' + + '
  • Earth Engine hosts

  • ' + + "
" + + "
" + + "
" + + '
' + + '
' + + '
' + + '

Process

' + + "
" + + '
    ' + + '
  • processes

  • ' + + '
  • Shell processes

  • ' + + '
  • Jupyter notebooks

  • ' + + '
  • builtin processes

  • ' + + '
  • python processes

  • ' + + "
" + + "
" + + "
" + + '
' + + '
' + + '
' + + '

Workflows

' + + "
" + + '
    ' + + '
  • workflows

  • ' + + '
  • pending workflow runs

  • ' + + '
  • failed workflow runs

  • ' + + '
  • successful workflow runs

  • ' + + "
" + + "
" + + "
" + + "
"; + + //list the statistics of each categories of hosts, processes, and workflows + cont += + '
' + + '
' + + '
' + + '
' + + '

Real Time Status

' + + "
" + + '
' + + ' ' + + "
" + + "
" + + "
" + + '
' + + '
' + + '
' + + '

Time Cost

' + + "
" + + '
' + + ' ' + + "
" + + "
" + + "
" + + "
"; + + //list the status of processes and workflows + cont += ""; + + //show the average time cost and history recorded + + $("#main-dashboard-content").html(cont); + + this.renderRealTimeStatusChart(); + + this.renderTimeCostChart(); + }, +}; diff --git a/src/main/resources/static/js/gw.editor.js b/src/main/resources/static/js/gw.editor.js index d10a47984..91d298d81 100644 --- a/src/main/resources/static/js/gw.editor.js +++ b/src/main/resources/static/js/gw.editor.js @@ -1,78 +1,75 @@ - - GW.editor = { - - beforeFullscreen: {}, - - isfullscreen: false, - - switchSidePanelFullScreen: function(){ - - var sidepanel = $('.cd-panel__container') //.cd-panel__container - if (!sidepanel.hasClass('fullscreen')) { - // this.beforeFullscreen = { height: sidepanel.height(), width: sidepanel.width() } - sidepanel.addClass('fullscreen'); - sidepanel.height('100vh'); - sidepanel.width('100vw'); - sidepanel.css('top', '0'); - $('#prompt-panel-main').height('calc(100% - 55px)') - $('#prompt-panel-main-process-info-code').height('100%') - $('#prompt-panel-main-process-info-history').height('100%') - GW.process.sidepanel.leftDock() - this.isfullscreen = true; - }else { - sidepanel.removeClass('fullscreen'); - // sidepanel.height(this.beforeFullscreen.height); - // sidepanel.width(this.beforeFullscreen.width); - sidepanel.css('top', '52px'); - // subtabCodeDiv.height('calc(100% - 150px)'); - // subtabHistoryDiv.height('calc(100% - 150px)'); - sidepanel.height('100%') - sidepanel.width('40%') - $('#prompt-panel-main').height('calc(100% - 105px)') - $('#prompt-panel-main-process-info-code').height('100%') - $('#prompt-panel-main-process-info-history').height('100%') - GW.process.sidepanel.bottomDock() - // editor.refresh(); - this.isfullscreen = false; - } - - GW.process.util.refreshCodeEditor(); - - }, - - switchFullScreen: function(){ - - this.switchFullScreenUtil('#editor-history-tab-panel', - '#main-process-info-code', - '#main-process-info-history') - - }, - - switchFullScreenUtil: function(editor_history_tab_panel_id, main_process_info_code_id, main_process_info_history_id){ - - var editorDiv = $(editor_history_tab_panel_id); - var subtabCodeDiv = $(main_process_info_code_id); - var subtabHistoryDiv = $(main_process_info_history_id); - if (!editorDiv.hasClass('fullscreen')) { - this.beforeFullscreen = { height: editorDiv.height(), width: editorDiv.width() } - editorDiv.addClass('fullscreen'); - editorDiv.height('100vh'); - editorDiv.width('100vw'); - subtabCodeDiv.height('calc(100% - 40px)'); - subtabHistoryDiv.height('calc(100% - 40px)'); - this.isfullscreen = true; - } - else { - editorDiv.removeClass('fullscreen'); - editorDiv.height(this.beforeFullscreen.height); - editorDiv.width(this.beforeFullscreen.width); - subtabCodeDiv.height('calc(100% - 150px)'); - subtabHistoryDiv.height('calc(100% - 150px)'); - this.isfullscreen = false; - } - + beforeFullscreen: {}, + + isfullscreen: false, + + switchSidePanelFullScreen: function () { + var sidepanel = $(".cd-panel__container"); //.cd-panel__container + if (!sidepanel.hasClass("fullscreen")) { + // this.beforeFullscreen = { height: sidepanel.height(), width: sidepanel.width() } + sidepanel.addClass("fullscreen"); + sidepanel.height("100vh"); + sidepanel.width("100vw"); + sidepanel.css("top", "0"); + $("#prompt-panel-main").height("calc(100% - 55px)"); + $("#prompt-panel-main-process-info-code").height("100%"); + $("#prompt-panel-main-process-info-history").height("100%"); + GW.process.sidepanel.leftDock(); + this.isfullscreen = true; + } else { + sidepanel.removeClass("fullscreen"); + // sidepanel.height(this.beforeFullscreen.height); + // sidepanel.width(this.beforeFullscreen.width); + sidepanel.css("top", "52px"); + // subtabCodeDiv.height('calc(100% - 150px)'); + // subtabHistoryDiv.height('calc(100% - 150px)'); + sidepanel.height("100%"); + sidepanel.width("40%"); + $("#prompt-panel-main").height("calc(100% - 105px)"); + $("#prompt-panel-main-process-info-code").height("100%"); + $("#prompt-panel-main-process-info-history").height("100%"); + GW.process.sidepanel.bottomDock(); + // editor.refresh(); + this.isfullscreen = false; } - -} \ No newline at end of file + GW.process.util.refreshCodeEditor(); + }, + + switchFullScreen: function () { + this.switchFullScreenUtil( + "#editor-history-tab-panel", + "#main-process-info-code", + "#main-process-info-history", + ); + }, + + switchFullScreenUtil: function ( + editor_history_tab_panel_id, + main_process_info_code_id, + main_process_info_history_id, + ) { + var editorDiv = $(editor_history_tab_panel_id); + var subtabCodeDiv = $(main_process_info_code_id); + var subtabHistoryDiv = $(main_process_info_history_id); + if (!editorDiv.hasClass("fullscreen")) { + this.beforeFullscreen = { + height: editorDiv.height(), + width: editorDiv.width(), + }; + editorDiv.addClass("fullscreen"); + editorDiv.height("100vh"); + editorDiv.width("100vw"); + subtabCodeDiv.height("calc(100% - 40px)"); + subtabHistoryDiv.height("calc(100% - 40px)"); + this.isfullscreen = true; + } else { + editorDiv.removeClass("fullscreen"); + editorDiv.height(this.beforeFullscreen.height); + editorDiv.width(this.beforeFullscreen.width); + subtabCodeDiv.height("calc(100% - 150px)"); + subtabHistoryDiv.height("calc(100% - 150px)"); + this.isfullscreen = false; + } + }, +}; diff --git a/src/main/resources/static/js/gw.feedback.js b/src/main/resources/static/js/gw.feedback.js index 5ca4deb27..972d33b0e 100644 --- a/src/main/resources/static/js/gw.feedback.js +++ b/src/main/resources/static/js/gw.feedback.js @@ -1,15 +1,11 @@ GW.feedback = { - - showDialog: function () { - - var content = `
+ showDialog: function () { + var content = `

Have feedback? We'd love to hear it!

Let us know what you think of Geoweaver and how we can improve your Geoweaver experience.



Get Started

`; - - GW.process.createJSFrameDialog(460, 320, content, "Feedback"); - - }, -} \ No newline at end of file + GW.process.createJSFrameDialog(460, 320, content, "Feedback"); + }, +}; diff --git a/src/main/resources/static/js/gw.filebrowser.js b/src/main/resources/static/js/gw.filebrowser.js index e12f46099..e23549fa4 100644 --- a/src/main/resources/static/js/gw.filebrowser.js +++ b/src/main/resources/static/js/gw.filebrowser.js @@ -1,532 +1,487 @@ - GW.filebrowser = { - - current_path: null, - - current_hid: null, - - editor: null, - - edit_file: 0, - - openFileEditor: function(file_name){ - - $.ajax({ - - url: "retrievefile", - - method: "POST", - - data: { "filepath" : GW.filebrowser.current_path + file_name} - - }).done(function(msg){ - - msg = $.parseJSON(msg); - - if(msg.ret == "success"){ - - GW.filebrowser.edit_file = 1; - - var content = "
"+ - "
" + - '' - - var frame = GW.process.createJSFrameDialog(800, 640, content, 'File Editor') - - $("#codearea").append(''); - - GW.filebrowser.editor = CodeMirror.fromTextArea(document.getElementById("code_editor"), { - - lineNumbers: true, - lineWrapping: true - }); - - var url_path = msg.path; - - //prevent it loading from cache - $.ajaxSetup ({ - // Disable caching of AJAX responses - cache: false - }); - - $.get( "../" + url_path, function( data ) { - - GW.filebrowser.editor.setValue(data); - - $("#loading_btn").hide(); - - }); - - $.ajaxSetup ({ - // Enable caching of AJAX responses - cache: true - }); - - frame.on('closeButton', 'click', (_frame, evt) => { - - $.ajax({ - - url: "closefilebrowser", - - method: "POST" - - }).done(function(msg){ - - console.log(msg); - - }); - - _frame.closeFrame(); - - }); - - $("#browser-save").click(function(){ - - $.ajax({ - - url: "updatefile", - - method: "POST", - - data: { filepath: GW.filebrowser.current_path + file_name, - content: GW.filebrowser.editor.getValue()} - - }).done(function(msg){ - - msg = $.parseJSON(msg); - - if(msg.ret == "success"){ - - console.log("file updated"); - - alert("Saved!!"); - - }else{ - - alert("Failed!!" + msg.reason); - } - - }); - - - }); - - $("#browser-run").click(function(){ - - var patt1 = /\.([0-9a-z]+)(?:[\?#]|$)/i; - - var suffix = file_name.match(patt1); - - if(GW.filebrowser.isIn(suffix[1],["py", "sh"])){ - - //step 1: add the file as a new process - - //step 2: pop-up the run dialog of the process - - var type = "shell"; - - if("py"==suffix[1]){ - - type = "python"; - - } - - var req = { - - name: file_name, - - filepath: GW.filebrowser.current_path + file_name, - - hid: GW.filebrowser.current_hid, - - type: type, - - content: GW.filebrowser.editor.getValue() - - }; - - $.ajax({ - - url: "addLocalFile", - - method: "POST", - - data: req - - }).done(function(msg){ - - msg = $.parseJSON(msg); - - var pid = msg.id; - - GW.process.addMenuItem(msg, type); - - GW.process.executeProcess(pid, GW.filebrowser.current_hid, type); - - GW.ssh.addlog("The process " + msg.name + " is added to the process list."); - GW.ssh.addlog("Pop up authorization dialog to initiate the run of the process : " + pid); - - }); - - }else{ - - alert("Only Python and Shell script can run!"); - - } - - - }); - - - }else{ - - alert("Fail to retrieve file: " + msg.reason); - - } - - }); - - }, - - downloadFile: function(file_name){ - - var path = GW.filebrowser.current_path + file_name; - - var req = {filepath : path}; - - $.ajax({ - - url: "retrievefile", - - data: req, - - method: "POST" - - }).done(function(msg){ - - msg = $.parseJSON(msg); - - if(msg.ret == "success"){ - - var fileurl = msg.path; - - GW.result.download_path("../" + fileurl, file_name); //remove web from Geoweaver/web - - }else{ - - alert("Fail to download!"); - - } - - }).fail(function(jqXHR, textStatus, errorThrown){ - - console.error(textStatus + errorThrown); - - }); - - }, - - isIn: function(target, array) { - for(var i=0; i '+parentfolder+' '+ - ' '+ - ' '+ - ' '+ - ' '; - - for(var i=0;i' +msg.array[i].name+''; - - }else{ - - cont += ' ' +msg.array[i].name+''; - - } - - cont += ' '+GW.filebrowser.s2Date(msg.array[i].mtime)+''+ - ' '+msg.array[i].size+''+ - ' '+msg.array[i].mode+''+ - ' '; - - } - - $("#directory_table > tbody").html(cont); - - }, - - sortTable: function (n) { - - var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0; - table = document.getElementById("directory_table"); - switching = true; - // Set the sorting direction to ascending: - dir = "asc"; - /* Make a loop that will continue until + current_path: null, + + current_hid: null, + + editor: null, + + edit_file: 0, + + openFileEditor: function (file_name) { + $.ajax({ + url: "retrievefile", + + method: "POST", + + data: { filepath: GW.filebrowser.current_path + file_name }, + }).done(function (msg) { + msg = $.parseJSON(msg); + + if (msg.ret == "success") { + GW.filebrowser.edit_file = 1; + + var content = + '' + + '"; + + var frame = GW.process.createJSFrameDialog( + 800, + 640, + content, + "File Editor", + ); + + $("#codearea").append( + '', + ); + + GW.filebrowser.editor = CodeMirror.fromTextArea( + document.getElementById("code_editor"), + { + lineNumbers: true, + lineWrapping: true, + }, + ); + + var url_path = msg.path; + + //prevent it loading from cache + $.ajaxSetup({ + // Disable caching of AJAX responses + cache: false, + }); + + $.get("../" + url_path, function (data) { + GW.filebrowser.editor.setValue(data); + + $("#loading_btn").hide(); + }); + + $.ajaxSetup({ + // Enable caching of AJAX responses + cache: true, + }); + + frame.on("closeButton", "click", (_frame, evt) => { + $.ajax({ + url: "closefilebrowser", + + method: "POST", + }).done(function (msg) { + console.log(msg); + }); + + _frame.closeFrame(); + }); + + $("#browser-save").click(function () { + $.ajax({ + url: "updatefile", + + method: "POST", + + data: { + filepath: GW.filebrowser.current_path + file_name, + content: GW.filebrowser.editor.getValue(), + }, + }).done(function (msg) { + msg = $.parseJSON(msg); + + if (msg.ret == "success") { + console.log("file updated"); + + alert("Saved!!"); + } else { + alert("Failed!!" + msg.reason); + } + }); + }); + + $("#browser-run").click(function () { + var patt1 = /\.([0-9a-z]+)(?:[\?#]|$)/i; + + var suffix = file_name.match(patt1); + + if (GW.filebrowser.isIn(suffix[1], ["py", "sh"])) { + //step 1: add the file as a new process + + //step 2: pop-up the run dialog of the process + + var type = "shell"; + + if ("py" == suffix[1]) { + type = "python"; + } + + var req = { + name: file_name, + + filepath: GW.filebrowser.current_path + file_name, + + hid: GW.filebrowser.current_hid, + + type: type, + + content: GW.filebrowser.editor.getValue(), + }; + + $.ajax({ + url: "addLocalFile", + + method: "POST", + + data: req, + }).done(function (msg) { + msg = $.parseJSON(msg); + + var pid = msg.id; + + GW.process.addMenuItem(msg, type); + + GW.process.executeProcess(pid, GW.filebrowser.current_hid, type); + + GW.ssh.addlog( + "The process " + msg.name + " is added to the process list.", + ); + GW.ssh.addlog( + "Pop up authorization dialog to initiate the run of the process : " + + pid, + ); + }); + } else { + alert("Only Python and Shell script can run!"); + } + }); + } else { + alert("Fail to retrieve file: " + msg.reason); + } + }); + }, + + downloadFile: function (file_name) { + var path = GW.filebrowser.current_path + file_name; + + var req = { filepath: path }; + + $.ajax({ + url: "retrievefile", + + data: req, + + method: "POST", + }) + .done(function (msg) { + msg = $.parseJSON(msg); + + if (msg.ret == "success") { + var fileurl = msg.path; + + GW.result.download_path("../" + fileurl, file_name); //remove web from Geoweaver/web + } else { + alert("Fail to download!"); + } + }) + .fail(function (jqXHR, textStatus, errorThrown) { + console.error(textStatus + errorThrown); + }); + }, + + isIn: function (target, array) { + for (var i = 0; i < array.length; i++) { + if (array[i] == target) return true; + } + return false; + }, + + operatefile: function (file_name, file_size) { + GW.general.showToasts("Preparing the file, please wait.."); + + var patt1 = /\.([0-9a-z]+)(?:[\?#]|$)/i; + + var suffix = file_name.match(patt1); + + if (suffix !== null) { + if ( + Number(file_size) < 10 * 1024 * 1024 && + GW.filebrowser.isIn(suffix[1], [ + "txt", + "py", + "sh", + "java", + "log", + "js", + "r", + "c", + "cpp", + "f", + "go", + "sql", + "php", + "perl", + "js", + ]) + ) { + //edit the file + GW.filebrowser.openFileEditor(file_name); + } else { + //directly download the file + GW.filebrowser.downloadFile(file_name); + } + } else { + //directly download the file + GW.filebrowser.downloadFile(file_name); + } + }, + + continuebrowser: function (file_name) { + $.ajax({ + url: "openfilebrowser", + + data: { init_path: GW.filebrowser.current_path + file_name + "/" }, + + method: "POST", + }) + .done(function (msg) { + msg = $.parseJSON(msg); + + if (msg.ret != "failure") GW.filebrowser.updateBrowser(msg); + else alert("Fail to open the directory: " + msg.msg); + }) + .fail(function (error) { + alert("Fail to send request to continue file browser" + error); + }); + }, + + s2Date: function (seconds) { + var m = new Date(Number(seconds) * 1000); + + var dateString = + m.getUTCFullYear() + + "/" + + ("0" + (m.getUTCMonth() + 1)).slice(-2) + + "/" + + ("0" + m.getUTCDate()).slice(-2) + + " " + + ("0" + m.getUTCHours()).slice(-2) + + ":" + + ("0" + m.getUTCMinutes()).slice(-2) + + ":" + + ("0" + m.getUTCSeconds()).slice(-2); + + return dateString; + }, + + updateBrowser: function (msg) { + GW.filebrowser.current_path = msg.current; + + var parentfolder = ".."; + + if (GW.filebrowser.current_path == "/") parentfolder = "."; + + var cont = + "" + + ' " + + parentfolder + + " " + + " " + + " " + + " " + + " "; + + for (var i = 0; i < msg.array.length; i++) { + cont += ""; + + if (msg.array[i].isdirectory) { + cont += + ' " + + msg.array[i].name + + ""; + } else { + cont += + ' " + + msg.array[i].name + + ""; + } + + cont += + " " + + GW.filebrowser.s2Date(msg.array[i].mtime) + + "" + + " " + + msg.array[i].size + + "" + + " " + + msg.array[i].mode + + "" + + " "; + } + + $("#directory_table > tbody").html(cont); + }, + + sortTable: function (n) { + var table, + rows, + switching, + i, + x, + y, + shouldSwitch, + dir, + switchcount = 0; + table = document.getElementById("directory_table"); + switching = true; + // Set the sorting direction to ascending: + dir = "asc"; + /* Make a loop that will continue until no switching has been done: */ - while (switching) { - // Start by saying: no switching is done: - switching = false; - rows = table.rows; - /* Loop through all table rows (except the + while (switching) { + // Start by saying: no switching is done: + switching = false; + rows = table.rows; + /* Loop through all table rows (except the first, which contains table headers): */ - for (i = 1; i < (rows.length - 1); i++) { - // Start by saying there should be no switching: - shouldSwitch = false; - /* Get the two elements you want to compare, + for (i = 1; i < rows.length - 1; i++) { + // Start by saying there should be no switching: + shouldSwitch = false; + /* Get the two elements you want to compare, one from current row and one from the next: */ - x = rows[i].getElementsByTagName("TD")[n]; - y = rows[i + 1].getElementsByTagName("TD")[n]; - /* Check if the two rows should switch place, + x = rows[i].getElementsByTagName("TD")[n]; + y = rows[i + 1].getElementsByTagName("TD")[n]; + /* Check if the two rows should switch place, based on the direction, asc or desc: */ - if (dir == "asc") { - if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) { - // If so, mark as a switch and break the loop: - shouldSwitch = true; - break; - } - } else if (dir == "desc") { - if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) { - // If so, mark as a switch and break the loop: - shouldSwitch = true; - break; - } - } - } - if (shouldSwitch) { - /* If a switch has been marked, make the switch + if (dir == "asc") { + if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) { + // If so, mark as a switch and break the loop: + shouldSwitch = true; + break; + } + } else if (dir == "desc") { + if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) { + // If so, mark as a switch and break the loop: + shouldSwitch = true; + break; + } + } + } + if (shouldSwitch) { + /* If a switch has been marked, make the switch and mark that a switch has been done: */ - rows[i].parentNode.insertBefore(rows[i + 1], rows[i]); - switching = true; - // Each time a switch is done, increase this count by 1: - switchcount ++; - } else { - /* If no switching has been done AND the direction is "asc", + rows[i].parentNode.insertBefore(rows[i + 1], rows[i]); + switching = true; + // Each time a switch is done, increase this count by 1: + switchcount++; + } else { + /* If no switching has been done AND the direction is "asc", set the direction to "desc" and run the while loop again. */ - if (switchcount == 0 && dir == "asc") { - dir = "desc"; - switching = true; - } - } - } - }, - - closeBrowser: function(){ - - if(GW.filebrowser.edit_file==0){ - - //only close connection when the file editor is not present - $.ajax({ - - url: "closefilebrowser", - - method: "POST" - - }).done(function(msg){ - - console.log(msg); - - }); - - } - - $("#host-file-browser").html(""); - - }, - - showFolderBrowserDialog: function(msg){ - - var cont = ''; - - cont ="

File Browser Section

"+ cont; - - -// var frame = GW.process.createJSFrameDialog(800, 640, cont, 'File Browser') - - $("#host-file-browser").html(cont); - - GW.filebrowser.updateBrowser(msg); - - GW.filebrowser.edit_file = 0; - - $("#closeFileBrowser").click(this.closeBrowser); - - }, - - connect_folder: function(encrypt, req, dialog, button){ - - req.pswd = encrypt; - - $.ajax({ - - url: "openfilebrowser", - - data: req, - - method: "POST" - - }).done(function(msg){ - - msg = $.parseJSON(msg); - - if(msg.current.length){ - - GW.filebrowser.showFolderBrowserDialog(msg); - - }else{ - - alert("Fail to open file browser"); - - } - - dialog.closeFrame(); - - }).fail(function(error){ - - alert("Fail to send folder open request"); - - button.enable(); - - button.stopSpin(); - - }); - - }, - - start: function(hid){ - - var req = { hid: hid, init_path: "/home/"} - - if(this.current_hid == hid){ - - req.init_path = this.current_path; - - } - - this.current_hid = hid; - - GW.host.start_auth_single(hid, req, GW.filebrowser.connect_folder); - - } - -} + if (switchcount == 0 && dir == "asc") { + dir = "desc"; + switching = true; + } + } + } + }, + + closeBrowser: function () { + if (GW.filebrowser.edit_file == 0) { + //only close connection when the file editor is not present + $.ajax({ + url: "closefilebrowser", + + method: "POST", + }).done(function (msg) { + console.log(msg); + }); + } + + $("#host-file-browser").html(""); + }, + + showFolderBrowserDialog: function (msg) { + var cont = + '"; + + cont = + '

File Browser Section

' + + cont; + + // var frame = GW.process.createJSFrameDialog(800, 640, cont, 'File Browser') + + $("#host-file-browser").html(cont); + + GW.filebrowser.updateBrowser(msg); + + GW.filebrowser.edit_file = 0; + + $("#closeFileBrowser").click(this.closeBrowser); + }, + + connect_folder: function (encrypt, req, dialog, button) { + req.pswd = encrypt; + + $.ajax({ + url: "openfilebrowser", + + data: req, + + method: "POST", + }) + .done(function (msg) { + msg = $.parseJSON(msg); + + if (msg.current.length) { + GW.filebrowser.showFolderBrowserDialog(msg); + } else { + alert("Fail to open file browser"); + } + + dialog.closeFrame(); + }) + .fail(function (error) { + alert("Fail to send folder open request"); + + button.enable(); + + button.stopSpin(); + }); + }, + + start: function (hid) { + var req = { hid: hid, init_path: "/home/" }; + + if (this.current_hid == hid) { + req.init_path = this.current_path; + } + + this.current_hid = hid; + + GW.host.start_auth_single(hid, req, GW.filebrowser.connect_folder); + }, +}; diff --git a/src/main/resources/static/js/gw.fileupload.js b/src/main/resources/static/js/gw.fileupload.js index af79e0b55..a99fe6840 100644 --- a/src/main/resources/static/js/gw.fileupload.js +++ b/src/main/resources/static/js/gw.fileupload.js @@ -1,557 +1,543 @@ /** * Plugin for uploading files to the remote host - * + * * Code comes from https://danielmg.org/demo/java-script/uploader/no-queue (by Daniel Morales) MIT license */ GW.fileupload = { - - uploader: null, - - hid : null, - - password: null, - - password_frame: null, - - clean: function(){ - - console.log("clean everything"); - - hid = null; - - encrypted = null; - - }, - - uploadfile: function(hid){ - - //it is divided into two steps - //let users input credentials of the selected host - - GW.fileupload.hid = hid; - - $.ajax({ - - url: "detail", - - method: "POST", - - data: "type=host&id=" + hid - - }).done(function(msg){ - - //open the login page - - msg = $.parseJSON(msg); - - if(GW.host.findCache(hid)==null){ - - if(GW.fileupload.password_frame != null){ - - try{ - - GW.fileupload.password_frame.closeFrame(); - - }catch(e){ - - console.error("Fail to close the frame. Probably it is already closed."); - - } - - GW.fileupload.password_frame = null; - - } - - var content = '"; - - content += ''; - - GW.fileupload.password_frame = GW.process.createJSFrameDialog(350, 250, content, "Authorization") - - GW.fileupload.password_frame.on('closeButton', 'click', (_frame, evt) => { - - _frame.closeFrame(); - - }); - - //Show the window -// GW.fileupload.password_frame.show(); -// -// GW.fileupload.password_frame.setPosition((window.innerWidth - width) / 2, (window.innerHeight -height) / 2, 'LEFT_TOP'); - - $("#pswd-confirm-btn").click(function(){ - -// var $button = this; -// -// $button.spin(); - -// GW.fileupload.password_frame.enableButtons(false); - - GW.fileupload.password = $('#inputpswd').val() - - if(GW.fileupload.password == ""){ - - alert("Please input correct password."); - - return; - - } - - if(document.getElementById('upload-remember').checked) { - - GW.host.setCache(hid, GW.fileupload.password); - - } - - GW.fileupload.showUploadDialog(); - - GW.fileupload.password_frame.closeFrame(); - - }); - - $("#pswd-cancel-btn").click(function(){ - - GW.fileupload.password_frame.closeFrame(); - - }); - - - }else{ - - GW.fileupload.password = GW.host.findCache(hid); - - if(GW.fileupload.password == ""){ - - alert("Please clean the cache and try again."); - - return; - - } - - GW.fileupload.showUploadDialog(); - - GW.fileupload.password_frame.closeFrame(); - - } - - - }); - - }, - - getUploadDialogContent: function(hasdebug){ - - var content = "
"+ - "
"+ - "
"+ - " "+ - "
"+ - "

Drag & drop files here

"+ - - "
"+ - " Open the file Browser "+ - " "+ - "
"+ - "
"+ - "
"+ - "
"+ - "
"+ - "
"+ - " File List "+ - "
"+ - "
    "+ - "
  • No files uploaded.
  • "+ - "
"+ - "
"+ - "
"+ - "
"; - - if(hasdebug) - content += "
"+ - "
"+ - "
"+ - "
"+ - " Debug Messages "+ - "
"+ - "
    "+ - "
  • Loading plugin....
  • "+ - "
"+ - "
"+ - "
"+ - "
"; - - content += " "+ - " "+ - "
"; - - content += ''; - - - - return content; - - }, - - closeUploaderJSFrame: function(){ - - if(this.uploader!=null){ - - try{ this.uploader.closeFrame(); }catch(e){ console.error("Probably it is already closed."); } - - this.uploader = null; - - } - - }, - - showUploadWorkflowDialog: function(){ - - this.closeUploaderJSFrame(); - - let content = GW.fileupload.getUploadDialogContent(false); - - this.uploader = GW.process.createJSFrameDialog(550, 450, content, "Upload Workflow"); - - this.listenUploadButtons(false, true); - - }, - - showUploadDialog: function(){ - - //once validated, show a dialog for users to select a file or multiple files to upload - //click the submit button, the files are first uploaded to Geoweaver host - //once received the complete response, send another request to upload the files to remote host - - let content = GW.fileupload.getUploadDialogContent(true); - - content = "

File Uploader Section

"+content; - - $("#host-file-uploader").html(content); - - $("#closeFileUploader").click(function(){ - - $("#host-file-uploader").html(""); - - }); - - this.listenUploadButtons(true, false); - - }, - - listenUploadButtons: function(iftransfer, ifworkflow){ - - $('#drag-and-drop-zone').dmUploader({ - url: '../FileUploadServlet', - maxFileSize: 3000000000, // 3000 Megs max - auto: false, - queue: true, - onDragEnter: function(){ - // Happens when dragging something over the DnD area - this.addClass('active'); - }, - onDragLeave: function(){ - // Happens when dragging something OUT of the DnD area - this.removeClass('active'); - }, - onInit: function(){ - // Plugin is ready to use - GW.fileupload.ui_add_log('Uploader initialized :)', 'info'); - }, - onComplete: function(){ - // All files in the queue are processed (success or error) -// GW.fileupload.ui_add_log('All pending tranfers finished'); - }, - onNewFile: function(id, file){ - // When a new file is added using the file selector or the DnD area - GW.fileupload.ui_add_log('New file added #' + id); - GW.fileupload.ui_multi_add_file(id, file); - }, - onBeforeUpload: function(id){ - // about tho start uploading a file - GW.fileupload.ui_add_log('Starting the upload of #' + id); - GW.fileupload.ui_multi_update_file_progress(id, 0, '', true); - GW.fileupload.ui_multi_update_file_status(id, 'uploading', 'Uploading...'); - }, - onUploadProgress: function(id, percent){ - // Updating file progress - GW.fileupload.ui_multi_update_file_progress(id, percent); - }, - onUploadSuccess: function(id, data){ - // A file was successfully uploaded - GW.fileupload.ui_add_log('Server Response for file #' + id + ': ' + data); - GW.fileupload.ui_add_log('Upload of file #' + id + ' COMPLETED', 'success'); - data = $.parseJSON(data); - if(iftransfer){ - GW.fileupload.ui_multi_update_file_progress(id, 90, '', true); - GW.fileupload.transfer(id, data.url); - } - - if(ifworkflow){ - GW.fileupload.closeUploaderJSFrame(); - GW.workflow.parseUploadedWorkflow(id, data.filename); - } - - }, - onUploadError: function(id, xhr, status, message){ - GW.fileupload.ui_multi_update_file_status(id, 'danger', message); - GW.fileupload.ui_multi_update_file_progress(id, 0, 'danger', false); - }, - onFallbackMode: function(){ - // When the browser doesn't support this plugin :( - GW.fileupload.ui_add_log('Plugin cant be used here, running Fallback callback', 'danger'); - }, - onFileSizeError: function(file){ - GW.fileupload.ui_add_log('File \'' + file.name + '\' cannot be added: size excess limit', 'danger'); - } - }); - - $("#upload-start").click(function(){ - - $('#drag-and-drop-zone').dmUploader('start'); - - var $button = $("#upload-start"); // 'this' here is a jQuery object that wrapping the ' + + ' ' + + "
"; + + GW.fileupload.password_frame = GW.process.createJSFrameDialog( + 350, + 250, + content, + "Authorization", + ); + + GW.fileupload.password_frame.on( + "closeButton", + "click", + (_frame, evt) => { + _frame.closeFrame(); + }, + ); + + //Show the window + // GW.fileupload.password_frame.show(); + // + // GW.fileupload.password_frame.setPosition((window.innerWidth - width) / 2, (window.innerHeight -height) / 2, 'LEFT_TOP'); + + $("#pswd-confirm-btn").click(function () { + // var $button = this; + // + // $button.spin(); + + // GW.fileupload.password_frame.enableButtons(false); + + GW.fileupload.password = $("#inputpswd").val(); + + if (GW.fileupload.password == "") { + alert("Please input correct password."); + + return; + } + + if (document.getElementById("upload-remember").checked) { + GW.host.setCache(hid, GW.fileupload.password); + } + + GW.fileupload.showUploadDialog(); + + GW.fileupload.password_frame.closeFrame(); + }); + + $("#pswd-cancel-btn").click(function () { + GW.fileupload.password_frame.closeFrame(); + }); + } else { + GW.fileupload.password = GW.host.findCache(hid); + + if (GW.fileupload.password == "") { + alert("Please clean the cache and try again."); + + return; + } + + GW.fileupload.showUploadDialog(); + + GW.fileupload.password_frame.closeFrame(); + } + }); + }, + + getUploadDialogContent: function (hasdebug) { + var content = + '
'; - - content += ''; - - this.password_frame = GW.process.createJSFrameDialog(520, 340, content, "Host Password") - - $("#inputpswd").on('keypress',function(e) { - - if(e.which == 13) { - - $("#pswd-confirm-btn").click(); - - } - - }); - - $("#pswd-confirm-btn").click(function(){ - - $('#pswd-confirm-btn').prop('disabled', true); - -// dialogItself.enableButtons(false); - - if(document.getElementById('remember').checked) { - - GW.host.setCache(hid, $('#inputpswd').val()); //remember s - - } - - GW.host.encrypt(hid, $('#inputpswd').val(), req, GW.host.password_frame, $('#pswd-confirm-btn'), business_callback); - - }); - - $("#pswd-cancel-btn").click(function(){ - - GW.host.password_frame.closeFrame(); - - }); - - }, - - start_auth_single: function(hid, req, business_callback){ - - var s = GW.host.findCache(hid); - - // if(hid == GW.host.local_hid){ - - // GW.host.encrypt(hid, "local", req, null, null, business_callback); - - // }else - if(s==null){ - - GW.host.enter_password(hid, req, business_callback); - - }else{ - - GW.host.encrypt(hid, s, req, null, null, business_callback); - - } - - }, - - encrypt_m : function(hosts, pswds, req, dialogItself, button, business_callback){ - - //Two-step encryption is applied here. - //First, get public key from server. - //Second, encrypt the password and sent the encypted string to server. - $.ajax({ - - url: "key", - - type: "POST", - - data: "" - - }).done(function(msg){ - - //encrypt the password using the received rsa key - - msg = $.parseJSON(msg); - - var encrypt = new JSEncrypt(); - - encrypt.setPublicKey(msg.rsa_public); - - var encrypt_passwds = []; - - for(var i=0; iHost '+newhosts[i].name+' Password: '+ - '
'+ - ' '+ - '
'+ - '
'; - } - - content += '
'+ - ' '+ - ' '+ - '
'; - - content += ''; - - var frame = GW.process.createJSFrameDialog(360, 360, content, "Host Password"); - - frame.on('#pswd-cancel', 'click', (_frame, evt) => { - - _frame.closeFrame() - - }) - - frame.on('#pswd-confirm', 'click', (_frame, evt) => { - - var filled = true; - - $.each( $( "input[type='password']" ), function() { - if(!$(this).val()){ - - filled = false; - - alert("Please input password. "); - - return; - - } - }); - - if(!filled) return; - - var $button = $(this); -// -// $button.spin(); - - var shortpasswds = []; - - for(var i=0;i0){ - - GW.host.enter_pswd_m(newhosts, hosts, req, business_callback); - - }else{ - - var passwds = GW.host.extendList([], newhosts, hosts); - - GW.host.encrypt_m(hosts, passwds, req, null, null, business_callback); - } - - }, - - turnHosts2Ids: function(hosts){ - - var ids = []; - - for(var i=0; i", "SSH Command Line") - - var frame = "

SSH Terminal Section

"+ - - "" - - $("#ssh-terminal-iframe").html(frame); - - $("#closeSSHTerminal").click(function(){ - - GW.host.closeSSH(token); - - $("#ssh-terminal-iframe").html(""); //double remove to make sure it clears every time - - }) - - }, - - /** - * Open the SSH Connection Dialog if the host is a remote server - */ - openssh: function(hostid){ - - //get the host information - - $.ajax({ - - url: "detail", - - method: "POST", - - data: "type=host&id=" + hostid - - }).done(function(msg){ - - //open the login page - - hostmsg = $.parseJSON(msg); - - if(GW.host.ssh_password_frame != null){ - - try{ - - GW.host.ssh_password_frame.closeFrame(); - - }catch(e){ - - console.log("Probably it is closed already."); - - } - - GW.host.ssh_password_frame = null; - - } - - if(GW.host.findCache(hostid)==null){ - - var cont = '"; - - cont += ''; - - GW.host.ssh_password_frame = GW.process.createJSFrameDialog(500, 340, cont, "Open SSH session") - - $("#ssh-connect-btn").click(function(){ - - $("#ssh-connect-btn").prop("disabled", true); - - $.ajax({ - - url: "key", - - type: "POST", - - data: "" - - }).done(function(msg){ - - //encrypt the password using the received rsa key - msg = $.parseJSON(msg); - - var encrypt = new JSEncrypt(); - - encrypt.setPublicKey(msg.rsa_public); - - var encrypted = encrypt.encrypt($("#passwd").val()); - - var req = { - host: hostmsg.ip, - port: hostmsg.port, - username: hostmsg.username, - password: encrypted - } - - $.ajax({ - - url: "geoweaver-ssh-login-inbox", - - method: "POST", - - data: req - - }).done(function(msg){ - - msg = $.parseJSON(msg); - - if(msg.token!=null){ - - //open a dialog to show the SSH command line interface - - GW.host.showSSHCmd(msg.token); - - if(document.getElementById('ssh-remember').checked) { - - GW.host.setCache(hostid, $('#passwd').val()); //only remember password if users check the box the the login is successful. - - } - - }else{ - - alert("Username or Password is wrong or the server is not accessible"); - - } - try{ - GW.host.ssh_password_frame.closeFrame(); - }catch(e){console.log(e)} - - - }).fail(function(status){ - - alert("Username or Password is wrong or the server is not accessible" + status); - - $("#ssh-connect-btn").prop("disabled", false); - - }); - - - }); - - }); - - $("#ssh-cancel-btn").click(function(){ - - GW.host.ssh_password_frame.closeFrame(); - - }); - - }else{ - - //if the login attempt failed once, the password will be removed and users need input again. - var pswd = GW.host.findCache(hostid); - - $.ajax({ - - url: "key", - - type: "POST", - - data: "" - - }).done(function(msg){ - - //encrypt the password using the received rsa key - msg = $.parseJSON(msg); - - var encrypt = new JSEncrypt(); - - encrypt.setPublicKey(msg.rsa_public); - - var encrypted = encrypt.encrypt(pswd); - - var req = { - host: hostmsg.ip, - port: hostmsg.port, - username: hostmsg.username, - password: encrypted - } - - $.ajax({ - - url: "geoweaver-ssh-login-inbox", - - method: "POST", - - data: req - - }).done(function(msg){ - - msg = $.parseJSON(msg); - - if(msg.token!=null){ - - //open a dialog to show the SSH command line interface - - GW.host.showSSHCmd(msg.token); - - }else{ - - alert("Username or Password is wrong or the server is not accessible"); - - GW.host.setCache(hostid, null); - - } - - }).fail(function(status){ - - alert("Username or Password is wrong or the server is not accessible" + status); - - GW.host.setCache(hostid, null); - //$("#ssh-connect-btn").prop("disabled", false); - - }); - - }); - - } - - }); - - }, - - cleanMenu: function(){ - - $("#host_folder_ssh_target").html(""); - - $("#host_folder_jupyter_target").html(""); - - $("#host_folder_jupyterhub_target").html(""); - - $("#host_folder_gee_target").html(""); - - }, - - refreshHostListForExecution:function(){ - - $.ajax({ - - url: "listhostwithenvironments", - - method: "POST", - - data: "type=host" - - }).done(function(msg){ - - msg = $.parseJSON(msg); - - GW.host.host_environment_list_cache = msg; - - console.log("Start to refresh the host list.."); - - GW.host.list(msg); - - if($(".hostselector")) { - - for(var i=0;i"+msg[i].name+""); - - } - - } - - //show the environment of the first host - if($(".environmentselector")){ - - $(".environmentselector").append(''); - - var envs = msg[0].envs - - for(var i=0;i"+envs[i].name+""); - - } - - } - - $(".hostselector").change(function(){ - - //get the corresponding environmentselector - // var corenvelelist = $(this).closest('div').next().find('.environmentselector'); - var hostselectid = $(this).attr("id"); - - var envselectid = "environmentforprocess_" + hostselectid.split("_")[1]; - - //change the environment selector options - var envselect = $("#" + envselectid); - - var selectedhostid = $(this).children("option:selected").attr("id"); - - envselect.empty().append(''); - - //add new options to the environment selector - var theenv = GW.host.findEnvironmentByHostId(selectedhostid); - - if(theenv != null){ - - for(var i=0;i"+theenv[i].name+""); - - } - - } - - }); - - } - - }).fail(function(jxr, status){ - - console.error("fail to list host"); - - }); - - }, - - findEnvironmentByHostId: function(hostid){ - - var theenv = null; - - if(GW.host.host_environment_list_cache!=null){ - - for(var i=0;i   ` + - - one.name + ``; - - $("#host_folder_"+one.type+"_target").append(one_item); - - }, - - expand: function(one){ - - console.log("EXPAND host type") - - $("#host_folder_"+one.type+"_target").collapse("show"); - }, - - list: function(msg){ - - GW.host.cleanMenu(); - - for(var i=0;i"; - - if( hosttype=="ssh" || hosttype == null || hosttype == "null" ){ - - // ""+ //this is a problematic function - -// ""+ - - content += ""+ - - ""+ - - " "; - - }else if(hosttype=="jupyter" || hosttype=="jupyterhub" || hosttype=="jupyterlab" ){ - - content += "" + - - ""; - - }else if(hosttype=="gee"){ - - content += "" + - - ""; - - } - - return content; - - }, - - - - showEnvironmentTable: function(msg){ - - var content = "

Environment List

"+ - "
"+ - " "+ - " "+ - " "+ - " "+ - " "+ - " "+ - " "+ - " "+ - " "+ - " "+ - " "; - - - for(var i=0;i"+msg[i].name+" "+ - " "+ - " "+ - " "+ - " "+ - " "; - - } - - content += ""+ - "
NameBin PathPyEnvBase DirectorySettings
"+msg[i].bin+""+msg[i].pyenv+""+msg[i].basedir+""+msg[i].settings+"
"+ - "
"; - - $("#environment-iframe").html(content); - - $("#closeEnvironmentPanel").click(function(){ - - $("#environment-iframe").html(""); - - }); - - }, - - readEnvironmentCallback: function(encrypt, req, dialogItself, button){ - - req.pswd = encrypt; - - req.token = GW.general.CLIENT_TOKEN; - - $.ajax({ - - url: "readEnvironment", - - type: "POST", - - data: req - - }).done(function(msg){ - - if(msg){ - - msg = GW.general.parseResponse(msg); - - if(msg.status == "failed"){ - - alert("Fail to read python environment."); - - console.error("fail to execute the process " + msg.reason); - - }else{ - - GW.host.showEnvironmentTable(msg); - - } - - - - }else{ - - console.warn("Return Response is Empty"); - - GW.host.showEnvironmentTable([]); - - } - - if(dialogItself) { - - try{dialogItself.closeFrame(); }catch(e){} - - } - - - }).fail(function(jxr, status){ - - alert("Error: unable to log on. Check if your password or the configuration of host is correct."); - - if($("#inputpswd").length) $("#inputpswd").val(""); - - if ($("#pswd-confirm-btn").prop("disabled")) { - $("#pswd-confirm-btn").prop("disabled", false); - } - - console.error("fail to execute the process " + req.processId); - - }); - }, - - readEnvironment: function(hid){ - - var req = { - - hostid: hid, - - } - - GW.host.start_auth_single(hid, req, GW.host.readEnvironmentCallback ); - - }, - - display: function(msg){ - - GW.process.editOn = false; - - var content = "
"; - - content += "
"; - content += "
" - content += "

Host Details


" - var hostid = null, hostip = null, hosttype = null, confidential = null, owner = null, envs = null; - - jQuery.each(msg, function(i, val) { - - if(val!=null&&val!="null"&&val!=""){ - - if(typeof val =='object') - { - val = JSON.stringify(val); - } - - if(i=="id"){ - - hostid = val; - - } - - if(i=="ip"){ - - hostip = val; - - } - - if(i=="type"){ - - hosttype = val; - - } - - if(i=="confidential"){ - - confidential = val; - return; - - }else if(i=="owner"){ - - owner = val; - return; - - }else if(i=="envs"){ - - envs = val; - return; - - } - - content += `
`; - - if(i=="id" || i=="ip" || i=="type" || i=="url"){ - - if(i=="ip"){ - - content += "
"+"IP Address"+"
"; - - }else if (i=="id") { - - content += "
"+i.toUpperCase()+"
"; - - }else if (i=="url") { - - content += "
"+"URL"+"
"; - - }else { - - content += "
"+i.charAt(0).toUpperCase()+ i.slice(1)+"
"; - - } - - }else { - - content += "
"+i.charAt(0).toUpperCase()+ i.slice(1)+"
"; - } - - - if(i=="id" || i=="type"){ - - content += "
"+val+"
"; - - }else{ - - if (i=='name'){ - - content += "
"+ - "
"; - - - } else if (i=="ip") { - - content += "
"+ - "
"; - - } else if (i=="port") { - - content += "
"+ - "
"; - - }else if (i=="username") { - - content += "
"+ - "
"; - - }else { - - content += "
"+ - "
"; - - } - - } - - content += `
`; - - } - - }); - - content += `
`; - - content += "
Confidential
"+ - "
"; - - if(confidential=="FALSE"){ - - content += ' '+ - ' '; - - if(GW.user.current_userid==owner && GW.user.current_userid != "111111") - content += ' '+ - ' '; - - }else{ - - content += ' '+ - ' '; - - if(GW.user.current_userid==owner&& GW.user.current_userid != "111111") - content += ' '+ - ' '; - - } - - content += `
`; - - content += "
" - - var delbtn = ""; - -// if(hostip!="127.0.0.1") - if(msg.id!="100001") - delbtn = ""; - - content += "
"+ - - "
"+ - - "

"+ - - this.getToolbar(hostid, hosttype) + - - delbtn + - - "

"+ - - "
"+ - - "
"+ - - "
"+ - - "
"+ - - "
"+ - - "
"+ - - "
"+ - - "
"+ - - "
"+ - - "
"+ - - "
"+ - - "
"; - - - $("#main-host-content").html(content); - - GW.ssh.current_process_log_length = 0; - - GW.general.switchTab("host"); - - - }, - - viewJupyter: function(history_id){ - - $.ajax({ - - url: "log", - - method: "POST", - - data: "type=host&id=" + history_id - - }).done(function(msg){ - - if(msg==""){ - - alert("Cannot find the host history in the database."); - - return; - - } - - msg = $.parseJSON(msg); - - var code = msg.output; - - if(code!=null && typeof code != 'undefined'){ - - if(typeof code != 'object'){ - - code = $.parseJSON(code); - - } - - var notebook = nb.parse(code.content); - - var rendered = notebook.render(); - - var content = ''; - - content += ''; - -// console.log(content); - - GW.host.his_frame = GW.process.createJSFrameDialog(800, 600, content, "History Jupyter Notebook " + history_id); - - $("#host-history-download-btn").click(function(){ - - GW.host.downloadJupyter(history_id); - - }) - - $("#host-history-cancel-btn").click(function(){ - - GW.host.his_frame.closeFrame(); - - }); - - } - - }).fail(function(e){ - - console.error(e); - - }); - - }, - - - deleteSelectedJupyter: function(){ - - if(confirm("Are you sure to remove all the selected history? This is permanent.")){ - - $(".hist-checkbox:checked").each(function() { - - var histid = $(this).attr('id'); - - console.log("Removing "+histid); - - GW.host.deleteJupyterDirectly(histid.substring(9)); - - }); - - } - - }, - - deleteJupyterDirectly: function(history_id){ - - $.ajax({ - - url: "del", - - method: "POST", - - data: "type=history&id=" + history_id - - }).done(function(msg){ - - if(msg==""){ - - alert("Cannot find the host history in the database."); - - return; - - }else if(msg=="done"){ - - console.log("The history " + history_id + " is removed") - - $("#host_history_row_" + history_id).remove() - - }else{ - - alert("Fail to delete the jupyter notebook") - - console.error("Fail to delete jupyter: " + msg); - - } - - }) - - }, - - deleteJupyter: function(history_id){ - - if(confirm("Are you sure to remove this history? This is permanent.")){ - - this.deleteJupyterDirectly(history_id); - - } - - }, - - downloadJupyter: function(history_id){ - - $.ajax({ - - url: "log", - - method: "POST", - - data: "type=host&id=" + history_id - - }).done(function(msg){ - - if(msg==""){ - - alert("Cannot find the host history in the database."); - - return; - - } - - msg = $.parseJSON(msg); - - var code = msg.output; - - if(code!=null && typeof code != 'undefined'){ - - if(typeof code != 'object'){ - - code = $.parseJSON(code); - - } - -// function download(content, fileName, contentType) { - - var a = document.createElement("a"); - - var file = new Blob([JSON.stringify(code.content)], {type: "application/json"}); - - a.href = URL.createObjectURL(file); - - a.target = "_blank" - - a.download = "jupyter-"+history_id + ".ipynb"; - - a.click(); - -// } - - } - -// download(jsonData, 'json.txt', 'text/plain'); - - - - }) - - }, - - historyTableCellUpdateCallBack: function(updatedCell, updatedRow, oldValue){ - - console.log("The new value for the cell is: " + updatedCell.data()); - console.log("The old value for that cell was: " + oldValue); - console.log("The values for each cell in that row are: " + updatedRow.data()); - - // The values for each cell in that row are: ,http://localhost:8888/api/contents/work/GMU%20workspace/COVID/covid_win_laptop.ipynb,xyz,2021-03-03 22:00:32.913,View Download Delete - - var thecheckbox = updatedRow.data()[0] - - var hisid = $(thecheckbox).attr("id").substring(9) - - console.log("history id: " + hisid) - - var newvalue = updatedRow.data()[2] - - GW.history.updateNotesOfAHistory(hisid, newvalue); - - }, - - - recent: function(hid){ - - console.log("Show the history of all previously executed scripts/jupyter notebok"); - - $.ajax({ - - url: "recent", - - method: "POST", - - data: "type=host&hostid=" + hid + "&number=100" - - }).done(function(msg){ - - if(!msg.length){ - - alert("no history found"); - - return; - - } - - msg = $.parseJSON(msg); - - var content = "

Recent History

"+ - "
"+ - - "
"+ - " "+ - " "+ - " "+ - "
"+ - - " "+ - " "+ - " "+ - " "+ - " "+ - " "+ - " "+ - " "+ -// " "+ - " "+ - " "+ - " "+ - " "; - - for(var i=0;iView Download Delete "; - - content += " "+ - " "+ - " "+ - " "+ - " "+ - " "+ -// status_col + - detailbtn + - " "; - - } - - content += ""; - - $("#host-history-browser").html(content); - - // initialize the tab with editable cells - - var table = $('.host_history_table').DataTable(); - - table.MakeCellsEditable({ - "onUpdate": GW.host.historyTableCellUpdateCallBack, - "columns": [3], - "allowNulls": { - "columns": [3], - "errorClass": 'error' - }, - "confirmationButton": { // could also be true - "confirmCss": 'my-confirm-class', - "cancelCss": 'my-cancel-class' - }, - "inputTypes": [ - { - "column": 3, - "type": "text", - "options": null - }] - }); - -// $("#all-selected").on("click", function(){}); - - $('#all-selected').change(function(){ - if ($(this).is(':checked')) { - //check all the rows - $(".hist-checkbox").prop('checked', true); - - }else { - $(".hist-checkbox").prop('checked', false); - - } - }); - - $("#closeHostHistoryBtn").on("click", function(){ - - $("#host-history-browser").html(""); - - }); - - $("#deleteHostHistoryBtn").on("click", function(){ - - GW.host.deleteSelectedJupyter(); - - }); - - $("#deleteHostHistoryNoNoteBtn").on("click", function(){ - - GW.history.deleteNoNotesJupyter(hid, GW.host.recent); - - }) - - $("#deleteHostHistoryAllBtn").on("click", function(){ - - GW.history.deleteAllJupyter(hid, GW.host.recent); - - }) - - $("#compareHistoryBtn").on("click", function(){ - - GW.comparison.show(); - - }); - - $("#refreshHostHistoryBtn").on("click", function(){ - - GW.host.recent(hid); - - }); - -// var frame = GW.process.createJSFrameDialog(720, 480, content, 'History of ' + msg.name) - - }).fail(function(jxr, status){ - - console.error(status); - - }); - - - }, - - getNewDialogContentByHostType: function(host_type){ - - var content = "" - - if(host_type=="jupyter") { - - content = '
'+ - ' '+ - '
'+ - ' '+ - '
'+ - '
'+ - '
'+ - ' '+ - '
'+ - ' '+ - '
'+ - '
'; - - }else if(host_type=="jupyterhub"){ - - content = '
'+ - ' '+ - '
'+ - ' '+ - '
'+ - '
'+ - '
'+ - ' '+ - '
'+ - ' '+ - '
'+ - '
'; - - }else if(host_type=="jupyterlab"){ - - content = '
'+ - ' '+ - '
'+ - ' '+ - '
'+ - '
'+ - '
'+ - ' '+ - '
'+ - ' '+ - '
'+ - '
'; - - }else if(host_type == "ssh") { - - content = '
'+ - ' '+ - '
'+ - ' '+ - '
'+ - '
'+ - '
'+ - ' '+ - '
'+ - ' '+ - '
'+ - '
'+ - '
'+ - ' '+ - '
'+ - ' '+ - '
'+ - '
'+ - '
'+ - ' '+ - '
'+ - ' '+ - '
'+ - '
'; - - }else if(host_type == "gee") { - - content = '
'+ - ' '+ - '
'+ - ' '+ - '
'+ - '
'+ - '
'+ - ' '+ - '
'+ - ' '+ - '
'+ - '
'; - - } - - content += '
'+ - ' '+ - '
'+ - ' '+ - ' '; - - if(GW.user.current_userid!=null && GW.user.current_userid!="111111") - content += ' '+ - ' '; - - content += '
'+ - '
'; - - return content; - - }, - - newDialog: function(category){ - - if(GW.host.new_host_frame!=null){ - - try{ - - GW.host.new_host_frame.closeFrame(); - - }catch(e){ - - console.error("Fail to close old frame. Maybe it is already closed."); - - } - - GW.host.new_host_frame = null; - - } - - var content = ''; - - content += ''; - - GW.host.new_host_frame = GW.process.createJSFrameDialog(500, 450, content, "Add new host") - - $("#hosttype").change(function(){ - - var op = $( "#hosttype option:selected" ).val() - - $("#host_dynamic_form").html(GW.host.getNewDialogContentByHostType(op)); - - }) - - $("#host-add-btn").click(function(){ - - GW.host.add(function(){ - - try{GW.host.new_host_frame.closeFrame();}catch(e){} - - }); - - }); - - $("#host-cancel-btn").click(function(){ - - GW.host.new_host_frame.closeFrame(); - - }); - - if(category) - $("#hosttype").val(category).trigger('change'); - }, - -} + cred_cache: [ + { h: "xxxx", s: "yyyyy", env: { bin: "python3", pyenv: "cdl" } }, + ], + + host_environment_list_cache: null, + + password_frame: null, + + ssh_password_frame: null, + + new_host_frame: null, + + local_hid: null, + + editOn: false, + + clearCache: function () { + this.cred_cache = []; + + this.host_environment_list_cache = []; + }, + + checkIfHostPanelActive: function () { + return document.getElementById("main-host-info").style.display == "flex"; + }, + + setEnvCache: function (hid, env) { + var is = false; + + for (var i = 0; i < GW.host.cred_cache.length; i++) { + if (GW.host.cred_cache[i].h == hid) { + GW.host.cred_cache[i].env = env; + + is = true; + + break; + } + } + + if (!is) { + GW.host.cred_cache.push({ h: hid, env: env }); + } + }, + + setCache: function (hid, s) { + var is = false; + + for (var i = 0; i < GW.host.cred_cache.length; i++) { + if (GW.host.cred_cache[i].h == hid) { + GW.host.cred_cache[i].s = s; + + is = true; + + break; + } + } + + if (!is) { + GW.host.cred_cache.push({ h: hid, s: s }); + } + }, + + findEnvCache: function (hid) { + var env = null; + + for (var i = 0; i < GW.host.cred_cache.length; i++) { + if (GW.host.cred_cache[i].h == hid) { + env = GW.host.cred_cache[i].env; + + break; + } + } + + return env; + }, + + findCache: function (hid) { + var s = null; + + for (var i = 0; i < GW.host.cred_cache.length; i++) { + if (GW.host.cred_cache[i].h == hid) { + s = GW.host.cred_cache[i].s; + + break; + } + } + + return s; + }, + + isLocal: function (msg) { + var is = false; + + if (msg.ip == "127.0.0.1") { + is = true; + } + + return is; + }, + + encrypt: function (hid, pstext, req, dialog, button, business_callback) { + //Two-step encryption is applied here. + //First, get public key from server. + //Second, encrypt the password and sent the encypted string to server. + $.ajax({ + url: "key", + + type: "POST", + + data: "", + }) + .done(function (msg) { + //encrypt the password using the received rsa key + + msg = $.parseJSON(msg); + + var encrypt = new JSEncrypt(); + + encrypt.setPublicKey(msg.rsa_public); + + var encrypted = encrypt.encrypt(pstext); + + // msg.pswd = encrypted; + + business_callback(encrypted, req, dialog, button); + }) + .fail(function (jxr, status) {}); + }, + + enter_password: function (hid, req, business_callback) { + if (this.password_frame != null) { + try { + this.password_frame.closeFrame(); + } catch (e) {} + + this.password_frame = null; + } + + var content = + '"; + + content += + '"; + + this.password_frame = GW.process.createJSFrameDialog( + 520, + 340, + content, + "Host Password", + ); + + $("#inputpswd").on("keypress", function (e) { + if (e.which == 13) { + $("#pswd-confirm-btn").click(); + } + }); + + $("#pswd-confirm-btn").click(function () { + $("#pswd-confirm-btn").prop("disabled", true); + + // dialogItself.enableButtons(false); + + if (document.getElementById("remember").checked) { + GW.host.setCache(hid, $("#inputpswd").val()); //remember s + } + + GW.host.encrypt( + hid, + $("#inputpswd").val(), + req, + GW.host.password_frame, + $("#pswd-confirm-btn"), + business_callback, + ); + }); + + $("#pswd-cancel-btn").click(function () { + GW.host.password_frame.closeFrame(); + }); + }, + + start_auth_single: function (hid, req, business_callback) { + var s = GW.host.findCache(hid); + + // if(hid == GW.host.local_hid){ + + // GW.host.encrypt(hid, "local", req, null, null, business_callback); + + // }else + if (s == null) { + GW.host.enter_password(hid, req, business_callback); + } else { + GW.host.encrypt(hid, s, req, null, null, business_callback); + } + }, + + encrypt_m: function ( + hosts, + pswds, + req, + dialogItself, + button, + business_callback, + ) { + //Two-step encryption is applied here. + //First, get public key from server. + //Second, encrypt the password and sent the encypted string to server. + $.ajax({ + url: "key", + + type: "POST", + + data: "", + }) + .done(function (msg) { + //encrypt the password using the received rsa key + + msg = $.parseJSON(msg); + + var encrypt = new JSEncrypt(); + + encrypt.setPublicKey(msg.rsa_public); + + var encrypt_passwds = []; + + for (var i = 0; i < hosts.length; i++) { + var encrypted = encrypt.encrypt(pswds[i]); //$('#inputpswd_' + i).val()); + + encrypt_passwds.push(encrypted); + } + + var ids = GW.host.turnHosts2Ids(hosts); + + var envs = GW.host.turnHosts2EnvIds(hosts); + + req.hosts = ids; + + req.passwords = encrypt_passwds; + + req.envs = envs; + + business_callback(req, dialogItself, button); + }) + .fail(function (jxr, status) { + console.error("fail to get encrypted key"); + }); + }, + + enter_pswd_m: function (newhosts, hosts, req, business_callback) { + var content = '"; + + content += + '"; + + var frame = GW.process.createJSFrameDialog( + 360, + 360, + content, + "Host Password", + ); + + frame.on("#pswd-cancel", "click", (_frame, evt) => { + _frame.closeFrame(); + }); + + frame.on("#pswd-confirm", "click", (_frame, evt) => { + var filled = true; + + $.each($("input[type='password']"), function () { + if (!$(this).val()) { + filled = false; + + alert("Please input password. "); + + return; + } + }); + + if (!filled) return; + + var $button = $(this); + // + // $button.spin(); + + var shortpasswds = []; + + for (var i = 0; i < newhosts.length; i++) { + shortpasswds.push($("#inputpswd_" + i).val()); + + if (document.getElementById("remember").checked) { + GW.host.setCache(newhosts[i].id, $("#inputpswd_" + i).val()); + } + } + + var passwds = GW.host.extendList(shortpasswds, newhosts, hosts); + + GW.host.encrypt_m( + hosts, + passwds, + req, + _frame, + $button, + business_callback, + ); + + _frame.closeFrame(); + }); + }, + + start_auth_multiple: function (hosts, req, business_callback) { + var newhosts = this.shrinkList(hosts); + + if (newhosts.length > 0) { + GW.host.enter_pswd_m(newhosts, hosts, req, business_callback); + } else { + var passwds = GW.host.extendList([], newhosts, hosts); + + GW.host.encrypt_m(hosts, passwds, req, null, null, business_callback); + } + }, + + turnHosts2Ids: function (hosts) { + var ids = []; + + for (var i = 0; i < hosts.length; i++) { + ids.push(hosts[i].id); + } + + return ids; + }, + + turnHosts2EnvIds: function (hosts) { + var ids = []; + + for (var i = 0; i < hosts.length; i++) { + ids.push(hosts[i].env); + } + + return ids; + }, + + /** + * Extend the list to original size + */ + extendList: function (shortpasswds, newhosts, hosts) { + var fullpasswdslist = []; + + for (var i = 0; i < hosts.length; i++) { + var passwd = null; + + for (var j = 0; j < newhosts.length; j++) { + if (newhosts[j].id == hosts[i].id) { + passwd = shortpasswds[j]; + + break; + } + } + + if (passwd != null) fullpasswdslist.push(passwd); + else fullpasswdslist.push(GW.host.findCache(hosts[i].id)); + } + + return fullpasswdslist; + }, + + shrinkList: function (hosts) { + var newhosts = []; + + for (var i = 0; i < hosts.length; i++) { + var exist = false; + + for (var j = 0; j < newhosts.length; j++) { + if (hosts[i].id == newhosts[j].id) { + exist = true; + + break; + } + } + + if (!exist && GW.host.findCache(hosts[i].id) == null) { + //the p is not cached + + newhosts.push(hosts[i]); + } + } + + return newhosts; + }, + + /** + * Close the SSH Terminal and Connection + */ + closeSSH: function (token) { + $.ajax({ + url: "geoweaver-ssh-logout-inbox", + + method: "POST", + + data: "token=" + token, + }) + .done(function (msg) { + if (msg == "done") { + console.log("SSH session is closed."); + + $("#ssh-terminal-iframe").html(""); + } else { + console.error("Fail to close SSH."); + } + }) + .fail(function () { + console.error("Fail to close SSH."); + }); + }, + + /** + * Show the SSH Terminal Section + */ + showSSHCmd: function (token) { + // var frame = GW.process.createJSFrameDialog(600, 540, "", "SSH Command Line") + + var frame = + '

SSH Terminal Section

' + + ''; + + $("#ssh-terminal-iframe").html(frame); + + $("#closeSSHTerminal").click(function () { + GW.host.closeSSH(token); + + $("#ssh-terminal-iframe").html(""); //double remove to make sure it clears every time + }); + }, + + /** + * Open the SSH Connection Dialog if the host is a remote server + */ + openssh: function (hostid) { + //get the host information + + $.ajax({ + url: "detail", + + method: "POST", + + data: "type=host&id=" + hostid, + }).done(function (msg) { + //open the login page + + hostmsg = $.parseJSON(msg); + + if (GW.host.ssh_password_frame != null) { + try { + GW.host.ssh_password_frame.closeFrame(); + } catch (e) { + console.log("Probably it is closed already."); + } + + GW.host.ssh_password_frame = null; + } + + if (GW.host.findCache(hostid) == null) { + var cont = + '"; + + cont += + '"; + + GW.host.ssh_password_frame = GW.process.createJSFrameDialog( + 500, + 340, + cont, + "Open SSH session", + ); + + $("#ssh-connect-btn").click(function () { + $("#ssh-connect-btn").prop("disabled", true); + + $.ajax({ + url: "key", + + type: "POST", + + data: "", + }).done(function (msg) { + //encrypt the password using the received rsa key + msg = $.parseJSON(msg); + + var encrypt = new JSEncrypt(); + + encrypt.setPublicKey(msg.rsa_public); + + var encrypted = encrypt.encrypt($("#passwd").val()); + + var req = { + host: hostmsg.ip, + port: hostmsg.port, + username: hostmsg.username, + password: encrypted, + }; + + $.ajax({ + url: "geoweaver-ssh-login-inbox", + + method: "POST", + + data: req, + }) + .done(function (msg) { + msg = $.parseJSON(msg); + + if (msg.token != null) { + //open a dialog to show the SSH command line interface + + GW.host.showSSHCmd(msg.token); + + if (document.getElementById("ssh-remember").checked) { + GW.host.setCache(hostid, $("#passwd").val()); //only remember password if users check the box the the login is successful. + } + } else { + alert( + "Username or Password is wrong or the server is not accessible", + ); + } + try { + GW.host.ssh_password_frame.closeFrame(); + } catch (e) { + console.log(e); + } + }) + .fail(function (status) { + alert( + "Username or Password is wrong or the server is not accessible" + + status, + ); + + $("#ssh-connect-btn").prop("disabled", false); + }); + }); + }); + + $("#ssh-cancel-btn").click(function () { + GW.host.ssh_password_frame.closeFrame(); + }); + } else { + //if the login attempt failed once, the password will be removed and users need input again. + var pswd = GW.host.findCache(hostid); + + $.ajax({ + url: "key", + + type: "POST", + + data: "", + }).done(function (msg) { + //encrypt the password using the received rsa key + msg = $.parseJSON(msg); + + var encrypt = new JSEncrypt(); + + encrypt.setPublicKey(msg.rsa_public); + + var encrypted = encrypt.encrypt(pswd); + + var req = { + host: hostmsg.ip, + port: hostmsg.port, + username: hostmsg.username, + password: encrypted, + }; + + $.ajax({ + url: "geoweaver-ssh-login-inbox", + + method: "POST", + + data: req, + }) + .done(function (msg) { + msg = $.parseJSON(msg); + + if (msg.token != null) { + //open a dialog to show the SSH command line interface + + GW.host.showSSHCmd(msg.token); + } else { + alert( + "Username or Password is wrong or the server is not accessible", + ); + + GW.host.setCache(hostid, null); + } + }) + .fail(function (status) { + alert( + "Username or Password is wrong or the server is not accessible" + + status, + ); + + GW.host.setCache(hostid, null); + //$("#ssh-connect-btn").prop("disabled", false); + }); + }); + } + }); + }, + + cleanMenu: function () { + $("#host_folder_ssh_target").html(""); + + $("#host_folder_jupyter_target").html(""); + + $("#host_folder_jupyterhub_target").html(""); + + $("#host_folder_gee_target").html(""); + }, + + refreshHostListForExecution: function () { + $.ajax({ + url: "listhostwithenvironments", + + method: "POST", + + data: "type=host", + }) + .done(function (msg) { + msg = $.parseJSON(msg); + + GW.host.host_environment_list_cache = msg; + + console.log("Start to refresh the host list.."); + + GW.host.list(msg); + + if ($(".hostselector")) { + for (var i = 0; i < msg.length; i++) { + //right now only SSH host can run processes + if (msg[i].type == "ssh") { + $(".hostselector").append( + '", + ); + } + } + + //show the environment of the first host + if ($(".environmentselector")) { + $(".environmentselector").append( + '', + ); + + var envs = msg[0].envs; + + for (var i = 0; i < envs.length; i++) { + $(".environmentselector").append( + '", + ); + } + } + + $(".hostselector").change(function () { + //get the corresponding environmentselector + // var corenvelelist = $(this).closest('div').next().find('.environmentselector'); + var hostselectid = $(this).attr("id"); + + var envselectid = + "environmentforprocess_" + hostselectid.split("_")[1]; + + //change the environment selector options + var envselect = $("#" + envselectid); + + var selectedhostid = $(this).children("option:selected").attr("id"); + + envselect + .empty() + .append(''); + + //add new options to the environment selector + var theenv = GW.host.findEnvironmentByHostId(selectedhostid); + + if (theenv != null) { + for (var i = 0; i < theenv.length; i++) { + envselect.append( + '", + ); + } + } + }); + } + }) + .fail(function (jxr, status) { + console.error("fail to list host"); + }); + }, + + findEnvironmentByHostId: function (hostid) { + var theenv = null; + + if (GW.host.host_environment_list_cache != null) { + for (var i = 0; i < GW.host.host_environment_list_cache.length; i++) { + var value = GW.host.host_environment_list_cache[i]; + if (hostid == value.id) { + theenv = value.envs; + break; + } + } + } + + return theenv; + }, + + refreshSearchList: function () { + GW.search.filterMenuListUtil("host_folder_ssh_target", "hosts", "host"); + }, + + //refresh host list for the menu + refreshHostList: function () { + $.ajax({ + url: "list", + + method: "POST", + + data: "type=host", + }) + .done(function (msg) { + msg = $.parseJSON(msg); + + console.log("Start to refresh the host list.."); + + GW.host.list(msg); + }) + .fail(function (jxr, status) { + console.error("fail to list host"); + }); + }, + + addMenuItem: function (one) { + console.log("Add host to the tree"); + + var one_item = + `
  •    ` + + one.name + + `
  • `; + + $("#host_folder_" + one.type + "_target").append(one_item); + }, + + expand: function (one) { + console.log("EXPAND host type"); + + $("#host_folder_" + one.type + "_target").collapse("show"); + }, + + list: function (msg) { + GW.host.cleanMenu(); + + for (var i = 0; i < msg.length; i++) { + this.addMenuItem(msg[i]); + } + + $("#hosts").collapse("show"); + }, + + validateIP: function (ipaddress) { + var valid = false; + + if ( + /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test( + ipaddress, + ) + ) { + valid = true; + } else { + alert("You have entered an invalid IP address!"); + } + + return valid; + }, + + preEditcheck: function () { + console.log("Check if the input valid"); + + var valid = false; + + var hosttype = $("#_host_type").text(); + + if (hosttype == "ssh" || hosttype == "") { + if ( + $("#_host_name").val() && + $("#_host_ip").val() && + $("#_host_port").val() && + $("#_host_username").val() && + this.validateIP($("#_host_ip").val()) && + $.isNumeric($("#_host_port").val()) + ) { + valid = true; + } + } else if (hosttype == "jupyter") { + if ($("#_host_name").val() && $("#_host_url").val()) { + valid = true; + } + } else if (hosttype == "gee") { + if ($("#_host_name").val() && $("#_host_client_id").val()) { + valid = true; + } + } + + return valid; + }, + + precheck: function () { + var valid = false; + + var hosttype = $("#hosttype option:selected").val(); + + if (hosttype == "ssh") { + if ( + $("#hostname").val() && + $("#hostip").val() && + $("#hostport").val() && + $("#username").val() && + this.validateIP($("#hostip").val()) && + $.isNumeric($("#hostport").val()) + ) { + valid = true; + } + } else if ( + hosttype == "jupyter" || + hosttype == "jupyterhub" || + hosttype == "jupyterlab" + ) { + if ($("#hostname").val() && $("#jupyter_home_url").val()) { + valid = true; + } + } else if (hosttype == "gee") { + if ($("#hostname").val() && $("#client_id").val()) { + valid = true; + } + } + + return valid; + }, + + add: function (callback) { + if (this.precheck()) { + var hostport = ""; + + if (typeof $("#hostport").val() != "undefined") { + hostport = $("#hostport").val(); + } + + var hostip = ""; + + if (typeof $("#hostip").val() != "undefined") { + hostip = $("#hostip").val(); + } + + var hosttype = $("#hosttype option:selected").val(); + + var jupyter_url = ""; + + if (typeof $("#jupyter_home_url").val() != "undefined") { + jupyter_url = $("#jupyter_home_url").val(); + } + + var confidential = "FALSE"; //default is public + + var confidential_field_value = $( + '#host_dynamic_form input[name="confidential"]:checked', + ).val(); + + if (typeof confidential_field_value != "undefined") { + confidential = confidential_field_value; + } + + var req = { + type: "host", + + hostname: $("#hostname").val(), + + hostip: hostip, + + hostport: hostport, + + url: jupyter_url, + + hosttype: hosttype, + + username: $("#username").val(), + + confidential: confidential, + + ownerid: GW.user.current_userid, + }; + + $.ajax({ + url: "add", + + method: "POST", + + data: req, + }) + .done(function (msg) { + msg = $.parseJSON(msg); + + GW.host.addMenuItem(msg); + + GW.host.expand(msg); + + callback(); + }) + .fail(function (jqXHR, textStatus) { + alert("Fail to add the host."); + }); + } else { + alert("Invalid input"); + } + }, + + edit: function () { + if (this.preEditcheck()) { + var hostid = $("#_host_id").text(); + + var hostname = $("#_host_name").val(); + + var hostusername = $("#_host_username").val(); + + var hostip = ""; + + if (typeof $("#_host_ip").val() != "undefined") { + hostip = $("#_host_ip").val(); + } + + var hostport = ""; + + if (typeof $("#_host_port").val() != "undefined") { + hostport = $("#_host_port").val(); + } + + var hosttype = $("#_host_type").text(); + + var jupyter_url = ""; + + if (typeof $("#_host_url").val() != "undefined") { + jupyter_url = $("#_host_url").val(); + } + + var confidential = "FALSE"; //default is public + + if (typeof $('input[name="confidential"]:checked').val() != "undefined") { + confidential = $('input[name="confidential"]:checked').val(); + } + + var req = { + type: "host", + + hostname: hostname, + + hostip: hostip, + + hostport: hostport, + + url: jupyter_url, + + hosttype: hosttype, + + username: hostusername, + + hostid: hostid, + + confidential: confidential, + }; + + $.ajax({ + url: "edit", + + method: "POST", + + data: req, + }) + .done(function (msg) { + msg = $.parseJSON(msg); + + GW.general.showToasts("Host updated."); + + GW.host.refreshHostList(); + }) + .fail(function (jqXHR, textStatus) { + alert("Fail to add the host."); + }); + } else { + alert("Invalid input"); + } + }, + + editSwitch: function () { + if (GW.host.checkIfHostPanelActive()) { + console.log("Turn on/off the fields"); + + $(".host-value-field").prop("disabled", GW.process.editOn); + + GW.process.editOn = !GW.process.editOn; + + if (!GW.process.editOn) { + console.log("Save the changes if any"); + + this.edit(); + } + } + }, + + openJupyter: function (hostid) { + window.open("/Geoweaver/jupyter-proxy/" + hostid + "/", "_blank"); + }, + + openGoogleEarth: function (hostid) { + window.open("/Geoweaver/GoogleEarth-proxy/" + hostid + "/", "_blank"); + }, + + getToolbar: function (hostid, hosttype) { + var content = + ''; + + if (hosttype == "ssh" || hosttype == null || hosttype == "null") { + // ""+ //this is a problematic function + + // ""+ + + content += + '' + + '' + + ' '; + } else if ( + hosttype == "jupyter" || + hosttype == "jupyterhub" || + hosttype == "jupyterlab" + ) { + content += + '' + + ''; + } else if (hosttype == "gee") { + content += + '' + + ''; + } + + return content; + }, + + showEnvironmentTable: function (msg) { + var content = + '

    Environment List

    ' + + '
    ProcessNotes (Click to Edit)Begin TimeEnd TimeStatusAction
    "+msg[i].name+""+msg[i].notes+""+msg[i].begin_time+""+msg[i].end_time+"
    ' + + ' ' + + " " + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + " " + + " " + + " "; + + for (var i = 0; i < msg.length; i++) { + content += + " " + + " " + + " " + + " " + + " " + + " " + + " "; + } + + content += "" + "
    NameBin PathPyEnvBase DirectorySettings
    " + + msg[i].name + + "" + + msg[i].bin + + "" + + msg[i].pyenv + + "" + + msg[i].basedir + + "" + + msg[i].settings + + "
    " + "
    "; + + $("#environment-iframe").html(content); + + $("#closeEnvironmentPanel").click(function () { + $("#environment-iframe").html(""); + }); + }, + + readEnvironmentCallback: function (encrypt, req, dialogItself, button) { + req.pswd = encrypt; + + req.token = GW.general.CLIENT_TOKEN; + + $.ajax({ + url: "readEnvironment", + + type: "POST", + + data: req, + }) + .done(function (msg) { + if (msg) { + msg = GW.general.parseResponse(msg); + + if (msg.status == "failed") { + alert("Fail to read python environment."); + + console.error("fail to execute the process " + msg.reason); + } else { + GW.host.showEnvironmentTable(msg); + } + } else { + console.warn("Return Response is Empty"); + + GW.host.showEnvironmentTable([]); + } + + if (dialogItself) { + try { + dialogItself.closeFrame(); + } catch (e) {} + } + }) + .fail(function (jxr, status) { + alert( + "Error: unable to log on. Check if your password or the configuration of host is correct.", + ); + + if ($("#inputpswd").length) $("#inputpswd").val(""); + + if ($("#pswd-confirm-btn").prop("disabled")) { + $("#pswd-confirm-btn").prop("disabled", false); + } + + console.error("fail to execute the process " + req.processId); + }); + }, + + readEnvironment: function (hid) { + var req = { + hostid: hid, + }; + + GW.host.start_auth_single(hid, req, GW.host.readEnvironmentCallback); + }, + + display: function (msg) { + GW.process.editOn = false; + + var content = '"; + + $("#main-host-content").html(content); + + GW.ssh.current_process_log_length = 0; + + GW.general.switchTab("host"); + }, + + viewJupyter: function (history_id) { + $.ajax({ + url: "log", + + method: "POST", + + data: "type=host&id=" + history_id, + }) + .done(function (msg) { + if (msg == "") { + alert("Cannot find the host history in the database."); + + return; + } + + msg = $.parseJSON(msg); + + var code = msg.output; + + if (code != null && typeof code != "undefined") { + if (typeof code != "object") { + code = $.parseJSON(code); + } + + var notebook = nb.parse(code.content); + + var rendered = notebook.render(); + + var content = + '"; + + content += + '"; + + // console.log(content); + + GW.host.his_frame = GW.process.createJSFrameDialog( + 800, + 600, + content, + "History Jupyter Notebook " + history_id, + ); + + $("#host-history-download-btn").click(function () { + GW.host.downloadJupyter(history_id); + }); + + $("#host-history-cancel-btn").click(function () { + GW.host.his_frame.closeFrame(); + }); + } + }) + .fail(function (e) { + console.error(e); + }); + }, + + deleteSelectedJupyter: function () { + if ( + confirm( + "Are you sure to remove all the selected history? This is permanent.", + ) + ) { + $(".hist-checkbox:checked").each(function () { + var histid = $(this).attr("id"); + + console.log("Removing " + histid); + + GW.host.deleteJupyterDirectly(histid.substring(9)); + }); + } + }, + + deleteJupyterDirectly: function (history_id) { + $.ajax({ + url: "del", + + method: "POST", + + data: "type=history&id=" + history_id, + }).done(function (msg) { + if (msg == "") { + alert("Cannot find the host history in the database."); + + return; + } else if (msg == "done") { + console.log("The history " + history_id + " is removed"); + + $("#host_history_row_" + history_id).remove(); + } else { + alert("Fail to delete the jupyter notebook"); + + console.error("Fail to delete jupyter: " + msg); + } + }); + }, + + deleteJupyter: function (history_id) { + if (confirm("Are you sure to remove this history? This is permanent.")) { + this.deleteJupyterDirectly(history_id); + } + }, + + downloadJupyter: function (history_id) { + $.ajax({ + url: "log", + + method: "POST", + + data: "type=host&id=" + history_id, + }).done(function (msg) { + if (msg == "") { + alert("Cannot find the host history in the database."); + + return; + } + + msg = $.parseJSON(msg); + + var code = msg.output; + + if (code != null && typeof code != "undefined") { + if (typeof code != "object") { + code = $.parseJSON(code); + } + + // function download(content, fileName, contentType) { + + var a = document.createElement("a"); + + var file = new Blob([JSON.stringify(code.content)], { + type: "application/json", + }); + + a.href = URL.createObjectURL(file); + + a.target = "_blank"; + + a.download = "jupyter-" + history_id + ".ipynb"; + + a.click(); + + // } + } + + // download(jsonData, 'json.txt', 'text/plain'); + }); + }, + + historyTableCellUpdateCallBack: function (updatedCell, updatedRow, oldValue) { + console.log("The new value for the cell is: " + updatedCell.data()); + console.log("The old value for that cell was: " + oldValue); + console.log( + "The values for each cell in that row are: " + updatedRow.data(), + ); + + // The values for each cell in that row are: ,http://localhost:8888/api/contents/work/GMU%20workspace/COVID/covid_win_laptop.ipynb,xyz,2021-03-03 22:00:32.913,View Download Delete + + var thecheckbox = updatedRow.data()[0]; + + var hisid = $(thecheckbox).attr("id").substring(9); + + console.log("history id: " + hisid); + + var newvalue = updatedRow.data()[2]; + + GW.history.updateNotesOfAHistory(hisid, newvalue); + }, + + recent: function (hid) { + console.log( + "Show the history of all previously executed scripts/jupyter notebok", + ); + + $.ajax({ + url: "recent", + + method: "POST", + + data: "type=host&hostid=" + hid + "&number=100", + }) + .done(function (msg) { + if (!msg.length) { + alert("no history found"); + + return; + } + + msg = $.parseJSON(msg); + + var content = + '

    Recent History

    ' + + '"; - - var frame = GW.process.createJSFrameDialog(800, 500, content, "Search Results") - - }, - - send: function(keywords, type){ - - $.ajax({ - - url: "search", - - type: "POST", - - data: { keywords: keywords, type: type} - - }).success(function(data){ - - data = $.parseJSON(data); - - GW.search.showResults(data); - - }).fail(function(){ - - alert("Fail to send search request."); - - }); - - }, - - selectType: function(){ - - $("#resource-type-select").text($(this).text()); - - }, - - showDialog: function(){ - - var content = "
    "+ - " "+ - "
    "+ - "
    "; - - content += ''; - - var frame = GW.process.createJSFrameDialog(500, 200, content, "Search") - - $("#search").click(function(){ - - GW.search.send($("#keywords").val(), $("#resource-type-select").val()); - - }); - - } - -} + keywords: "", + + init: function () { + $("#instant_search_bar").on("input", function () { + GW.search.keywords = $(this).val(); + + console.log("search string changed to: " + GW.search.keywords); + + GW.menu.refreshSearchResults(); + + if (GW.search.keywords != "") { + $("#clean_search_field").css("visibility", "visible"); + } else { + $("#clean_search_field").css("visibility", "hidden"); + } + }); + + $("#clean_search_field").click(function () { + $("#instant_search_bar").val(""); + + GW.search.keywords = ""; + + $("#clean_search_field").css("visibility", "hidden"); + + GW.menu.refreshSearchResults(); + }); + }, + + filterMenuListUtil: function ( + folder_div_name, + parent_div_name, + li_class_name, + ) { + $("#" + parent_div_name).collapse("show"); + + $("#" + folder_div_name).collapse("show"); + + $("#" + parent_div_name) + .find("li." + li_class_name) + .each(function (index) { + host_name_div = $(this).find("div.col-md-8").first(); + + if (host_name_div.length == 0) host_name_div = $(this); //workflow doesn't have second level div + + host_name = host_name_div.text(); + + if (GW.search.keywords != "") { + if ( + host_name.toLowerCase().includes(GW.search.keywords.toLowerCase()) + ) { + // $(this).css("background-color", "yellow") + var re = new RegExp(GW.search.keywords, "g"); + new_host_name = host_name.replace( + re, + "" + + GW.search.keywords + + "", + ); + host_name_div.html(new_host_name); + + $(this).show(); + } else { + var re = new RegExp( + "" + + GW.search.keywords + + "", + "g", + ); + new_host_name = host_name.replace(re, GW.search.keywords); + + host_name_div.html(new_host_name); + + $(this).hide(); + } + } else { + var re = new RegExp( + "" + + GW.search.keywords + + "", + "g", + ); + + new_host_name = host_name.replace(re, GW.search.keywords); + + host_name_div.html(new_host_name); + + $(this).show(); + + $("#" + folder_div_name).collapse("hide"); + + $("#" + parent_div_name).collapse("hide"); + } + }); + }, + + showResults: function (data) { + var content = + '"; + + var frame = GW.process.createJSFrameDialog( + 800, + 500, + content, + "Search Results", + ); + }, + + send: function (keywords, type) { + $.ajax({ + url: "search", + + type: "POST", + + data: { keywords: keywords, type: type }, + }) + .success(function (data) { + data = $.parseJSON(data); + + GW.search.showResults(data); + }) + .fail(function () { + alert("Fail to send search request."); + }); + }, + + selectType: function () { + $("#resource-type-select").text($(this).text()); + }, + + showDialog: function () { + var content = + '"; + + content += + '"; + + var frame = GW.process.createJSFrameDialog(500, 200, content, "Search"); + + $("#search").click(function () { + GW.search.send($("#keywords").val(), $("#resource-type-select").val()); + }); + }, +}; diff --git a/src/main/resources/static/js/gw.settings.js b/src/main/resources/static/js/gw.settings.js index e48a0be1f..760c011be 100644 --- a/src/main/resources/static/js/gw.settings.js +++ b/src/main/resources/static/js/gw.settings.js @@ -1,169 +1,162 @@ - GW.settings = { - - clearCache: function(){ - - if(confirm("Do you want to clear all the cached information (including passwords, the connection between process/workflow and host)?")){ - - GW.host.clearCache(); - - GW.process.clearCache(); - - GW.workflow.clearCache(); - - alert("Cache cleared."); - - } - - }, - - clearPasswords: function(){ - - if(confirm("Do you want to clear the remembered passwords?")){ - - GW.host.clearCache(); + clearCache: function () { + if ( + confirm( + "Do you want to clear all the cached information (including passwords, the connection between process/workflow and host)?", + ) + ) { + GW.host.clearCache(); + + GW.process.clearCache(); + + GW.workflow.clearCache(); + + alert("Cache cleared."); + } + }, + + clearPasswords: function () { + if (confirm("Do you want to clear the remembered passwords?")) { + GW.host.clearCache(); + + alert("Cache cleared."); + } + }, + + clearConnections: function () { + if ( + confirm( + "Do you want to clear the remembered mappings between processes/workflows and hosts?", + ) + ) { + GW.process.clearCache(); + + GW.workflow.clearCache(); + + alert("Cache cleared."); + } + }, + + clearProcessConnections: function () { + if ( + confirm( + "Do you want to clear the remembered mappings between processes and hosts?", + ) + ) { + GW.process.clearCache(); + + alert("Cache cleared."); + } + }, + + clearWorkflowConnections: function () { + if ( + confirm( + "Do you want to clear the remembered mappings between workflows and hosts?", + ) + ) { + GW.workflow.clearCache(); + + alert("Cache cleared."); + } + }, - alert("Cache cleared."); - - } - - }, - - clearConnections: function(){ - - if(confirm("Do you want to clear the remembered mappings between processes/workflows and hosts?")){ - - GW.process.clearCache(); - - GW.workflow.clearCache(); + showDialog: function () { + var content = + '
    "; - alert("Cache cleared."); - - } - - }, - - clearProcessConnections: function(){ - - if(confirm("Do you want to clear the remembered mappings between processes and hosts?")){ - - GW.process.clearCache(); + var frame = GW.process.createJSFrameDialog(360, 320, content, "Settings"); - alert("Cache cleared."); - } - - }, - - clearWorkflowConnections: function(){ - - if(confirm("Do you want to clear the remembered mappings between workflows and hosts?")){ - - GW.workflow.clearCache(); - - alert("Cache cleared."); - - } - - }, - - showDialog: function(){ - - var content = ""; - - var frame = GW.process.createJSFrameDialog(360, 320, content, "Settings"); - -// BootstrapDialog.show({ -// -// title: "Settings", -// -// message: function(){ -// -// var content = ""; -// -// return content; -// -// }, -// -// buttons: [{ -// -// label: "Close", -// -// action: function(dialogItself){ -// -// dialogItself.close(); -// -// } -// -// }] -// -// }); - - } - -} \ No newline at end of file + // BootstrapDialog.show({ + // + // title: "Settings", + // + // message: function(){ + // + // var content = ""; + // + // return content; + // + // }, + // + // buttons: [{ + // + // label: "Close", + // + // action: function(dialogItself){ + // + // dialogItself.close(); + // + // } + // + // }] + // + // }); + }, +}; diff --git a/src/main/resources/static/js/gw.sidenav.js b/src/main/resources/static/js/gw.sidenav.js index 5a508eb67..7b728323a 100644 --- a/src/main/resources/static/js/gw.sidenav.js +++ b/src/main/resources/static/js/gw.sidenav.js @@ -1,48 +1,59 @@ window.sidenavContext = undefined; GW.sidenav = { + setSidenavWindowObjects: ( + code, + owner, + confidentialField, + category, + codeType, + processId, + processName, + ) => { + window.sidenavContext.code = code; + window.sidenavContext.confidentialField = confidentialField; + window.sidenavContext.category = category; + window.sidenavContext.codeType = codeType; + window.sidenavContext.processId = processId; + window.sidenavContext.processName = processName; + }, - setSidenavWindowObjects: ( - code, owner, confidentialField, category, codeType, processId, processName - ) => { - window.sidenavContext.code = code; - window.sidenavContext.confidentialField = confidentialField; - window.sidenavContext.category = category; - window.sidenavContext.codeType = codeType; - window.sidenavContext.processId = processId; - window.sidenavContext.processName = processName; - }, + getData: (id) => { + const TYPE = "process"; + let code, + owner, + confidentialField, + category, + codeType, + processId, + processName; - getData: (id) => { - const TYPE = "process"; - let code, owner, confidentialField, category, codeType, processId, processName; + $.ajax({ + url: "detail", + method: "POST", + data: "type=" + TYPE + "&id=" + id, + }).done((response) => { + let parsedMessage = GW.general.parseResponse(response); + codeType = parsedMessage.lang.equals(null) + ? parsedMessage.description + : parsedMessage.lang; + code = parsedMessage.code; + if (code && code.includes('\\"')) { + code = GW.process.unescape(code); + } + processId = parsedMessage.id; + processName = parsedMessage.name; + owner = parsedMessage.owner; + confidentialField = parsedMessage.confidential !== "FALSE"; - $.ajax({ - url: "detail", - method: "POST", - data: "type=" + TYPE + "&id=" + id - }).done((response) => { - let parsedMessage = GW.general.parseResponse(response); - codeType = parsedMessage.lang.equals(null) ? parsedMessage.description : parsedMessage.lang - code = parsedMessage.code; - if (code && code.includes("\\\"")) { - code = GW.process.unescape(code); - } - processId = parsedMessage.id; - processName = parsedMessage.name; - owner = parsedMessage.owner; - confidentialField = parsedMessage.confidential !== "FALSE"; - - this.setSidenavWindowObjects( - code, - owner, - confidentialField, - category, - codeType, - processId, - processName - ) - - }) - } - -} \ No newline at end of file + this.setSidenavWindowObjects( + code, + owner, + confidentialField, + category, + codeType, + processId, + processName, + ); + }); + }, +}; diff --git a/src/main/resources/static/js/gw.ssh.js b/src/main/resources/static/js/gw.ssh.js index 7c5e30eec..f8c0ff75d 100644 --- a/src/main/resources/static/js/gw.ssh.js +++ b/src/main/resources/static/js/gw.ssh.js @@ -1,414 +1,344 @@ - /** - * + * * SSH client - * - * Create a shared websocket shell to stream all the results from server to the client. - * + * + * Create a shared websocket shell to stream all the results from server to the client. + * * Distinguish the outputs of different sessions using tokens. - * - * Only one ssh session is allowed at one time. - * - * Only one running workflow is allowed at one time. - * + * + * Only one ssh session is allowed at one time. + * + * Only one running workflow is allowed at one time. + * */ GW.ssh = { - - shell: null, - - sshConnected : false, - - passwordPhase : false, - - user : null, - - host : null, - - port : null, - - token : null, - - output_div_id: null, - - process_output_id: "process-log-window", - - ws: null, - - all_ws: null, //future websocket session for all the traffic between client and server - - last_prompt: null, - - password_cout: 0, - - key : '', - - checker_swich: false, - - current_log_length: 0, // length of log in log-window - - current_process_log_length: 0, // length of log in process and prompt log-window - - username : '', - - special : { - black: "\x1b[1;30m", - red: "\x1b[1;31m", - green: "\x1b[1;32m", - yellow: "\x1b[1;33m", - blue: "\x1b[1;34m", - magenta: "\x1b[1;35m", - cyan: "\x1b[1;36m", - white: "\x1b[1;37m", - reset: "\x1b[0m", - ready: "]0;", - prompt: "$" - }, - - echo: function(content){ - - if(content!=null){ - - content = content.replace(/\n/g,'
    ') - - this.addlog(content); - - // trigger the builtin process - - if(GW.general.isJSON(content)){ - - try{ - - var returnmsg = $.parseJSON(content); - - console.log(returnmsg); - - if(returnmsg.ret == "success"){ - - setTimeout(function (){ - - GW.process.callback(returnmsg); - - }, 2000); - - - } - - if(returnmsg.builtin){ - - GW.process.callback(returnmsg); - - }else{ - - // GW.workspace.updateStatus(returnmsg); // the workflow status message should only come from the workflow-socket - - } - - }catch(errors){ - - console.error(errors) - - } - - } - - } - - }, - - error: function(content){ - - content = content.replace(/\n/g,'
    ') - - this.addlog(content); - - }, - - send: function (data) { - - if(this.ws != null){ - - this.ws.send(data); - - } else { - - if(data!=this.token){ - - this.error('not connected!'); - - } - - } - }, - - checkSessionStatus: function(){ - // console.log("Current WS status: " + GW.ssh.all_ws.readyState); - // return GW.ssh.all_ws.readyState; - - GW.ssh.checker_swich = true; - - GW.ssh.send("token:"+GW.general.CLIENT_TOKEN); - - setTimeout(() => { - - if(GW.ssh.checker_swich){ - - //restart the websocket if the switch is still true two seconds later - GW.ssh.startLogSocket(GW.ssh.token); - GW.ssh.checker_swich = false; - - } - - }, 2000); - - }, - - ws_onopen: function (e) { - - console.log("WebSocket Channel is Openned"); - - this.echo("connected"); - - setTimeout(() => { GW.ssh.send("token:" + GW.general.CLIENT_TOKEN) }, 1000); //create a chance for the server side to register the session if it didn't when it is openned - - }, - - - ws_onclose: function (e) { - - try{ - - this.echo("disconnected"); - - GW.ssh.all_ws = null; - GW.ssh.ws = null; - GW.ssh.token = null; - - }catch(e){ - - console.error(e); - - this.echo("Reconnection failed. " + e) - - } - - console.log("the logging out websocket has been closed"); - - }, - - ws_onerror: function (e) { - - this.error("The process execution failed.") - - this.error("Reason: " + e); - - }, - - ws_onmessage: function (e) { - - try { - if(e.data.indexOf("Session_Status:Active")!=-1){ - GW.ssh.checker_swich = false; - }else if(e.data.indexOf(this.special.prompt) == -1 && - - e.data.indexOf(this.special.ready) == -1 && - - e.data.indexOf("No SSH connection is active") == -1) { - - this.echo(e.data); - - }else{ - - //the websocket is already closed. try the history query - - // this.echo("It ends too quickly. Go to history to check the logs out."); - - } - - - - //if (e.data.indexOf(special.ready) != -1) { - - // shell.resume(); - - //} - - } catch(err) { - - console.log(err); - - this.error("** Invalid server response : " + e.data); - - } - - }, - - addlog: function(content){ - var dt = new Date(); - var time = dt.getHours() + ":" + dt.getMinutes() + ":" + dt.getSeconds(); - - cont_splits = content.split("*_*") - - log_history_id = null - - if(cont_splits.length>1){ - log_history_id = cont_splits[0] - let newArray = cont_splits.slice(1); - content = newArray.join(" ") - } - - var style1 = ""; - if(content.includes("Start to execute")){ - - style1 = "color: blue; font-weight: bold; text-decoration: underline;"; - - $(".dot-flashing").removeClass("invisible") - $(".dot-flashing").addClass("visible") - - }else if(content.includes("===== Process")){ - - style1 = "color: blue; font-weight: bold; text-decoration: underline;"; - - $(".dot-flashing").removeClass("visible") - $(".dot-flashing").addClass("invisible") - - }else if(content=="disconnected"){ - $(".dot-flashing").removeClass("visible") - $(".dot-flashing").addClass("invisible") - }else if(log_history_id == GW.process.history_id){ - $(".dot-flashing").removeClass("invisible") - $(".dot-flashing").addClass("visible") - }else{ - $(".dot-flashing").removeClass("visible") - $(".dot-flashing").addClass("invisible") - } - - var newline = `

    ` + content + `

    `; - - this.current_log_length += 1 //line number plus 1 - - if(this.current_log_length > 5000){ - $("#log-window").find('p:first').remove(); - this.current_log_length -= 1 - } - - $("#log-window").append(newline); - - //don't output log to process log if the current executed is workflow - if(GW.process.last_executed_process_id==GW.process.process_id){ - - if($("#"+GW.ssh.process_output_id).length){ - - if(this.current_process_log_length > 5000){ - - $("#"+GW.ssh.process_output_id).find('p:first').remove(); - - this.current_process_log_length -= 1 - - } - - if(GW.process.history_id == log_history_id){ - - // only display the log if the current history id is the correct one - $("#"+GW.ssh.process_output_id).append(newline); - - } - - - this.current_process_log_length += 1 - - } - - } - - - }, - - clearProcessLog: function(){ - - $("#"+GW.ssh.process_output_id).html(""); - - }, - - clearMain: function(){ - - $("#log-window").html(""); - - }, - - getWsPrefixURL: function(){ - - var s = ((window.location.protocol === "https:") ? "wss://" : "ws://") + window.location.host + "/Geoweaver/"; - -// s += "Geoweaver/"; //this is gone in spring boot - - console.log("Ws URL Prefix: ", s) - - return s; - - }, - - startLogSocket: function(token){ - - if(GW.ssh.all_ws) GW.ssh.all_ws.close(); - - GW.ssh.all_ws = new WebSocket(this.getWsPrefixURL() + "command-socket"); - - GW.ssh.ws = GW.ssh.all_ws; - - GW.ssh.output_div_id = "log_box_id"; - - GW.ssh.token = token; //token is the jsession id - -// this.echo("Running process " + token) - - GW.ssh.all_ws.onopen = function(e) { GW.ssh.ws_onopen(e) }; - - GW.ssh.all_ws.onclose = function(e) { GW.ssh.ws_onclose(e) }; - - GW.ssh.all_ws.onmessage = function(e) { GW.ssh.ws_onmessage(e) }; - - GW.ssh.all_ws.onerror = function(e) { GW.ssh.ws_onerror(e) }; - - }, - - connectWsSessionWithExecution: function(msg){ - - - - }, - - openLog: function(msg){ - - //check if the websocket session is alive, otherwise, restore the connection - - if (GW.ssh.all_ws!=null && (GW.ssh.all_ws.readyState === WebSocket.CLOSED || GW.ssh.all_ws.readyState === WebSocket.CLOSING) ) { - - // GW.ssh.all_ws.close(); - - console.log("The command websocket connection is detected to be closed. Try to reconnect..."); - - GW.ssh.startLogSocket(msg.token); - - console.log("The console websocket connection is restored.."); - - }else{ - - GW.ssh.checkSessionStatus(); - - } - - if(msg.history_id.length==12) - this.addlog("=======\nStart to execute Process " + msg.history_id); - else - this.addlog("=======\nStart to execute Workflow " + msg.history_id); - - }, - - openTerminal: function(token, terminal_div_id){ - - } - -} \ No newline at end of file + shell: null, + + sshConnected: false, + + passwordPhase: false, + + user: null, + + host: null, + + port: null, + + token: null, + + output_div_id: null, + + process_output_id: "process-log-window", + + ws: null, + + all_ws: null, //future websocket session for all the traffic between client and server + + last_prompt: null, + + password_cout: 0, + + key: "", + + checker_swich: false, + + current_log_length: 0, // length of log in log-window + + current_process_log_length: 0, // length of log in process and prompt log-window + + username: '', + + special: { + black: "\x1b[1;30m", + red: "\x1b[1;31m", + green: "\x1b[1;32m", + yellow: "\x1b[1;33m", + blue: "\x1b[1;34m", + magenta: "\x1b[1;35m", + cyan: "\x1b[1;36m", + white: "\x1b[1;37m", + reset: "\x1b[0m", + ready: "]0;", + prompt: "$", + }, + + echo: function (content) { + if (content != null) { + content = content.replace(/\n/g, "
    "); + + this.addlog(content); + + // trigger the builtin process + + if (GW.general.isJSON(content)) { + try { + var returnmsg = $.parseJSON(content); + + console.log(returnmsg); + + if (returnmsg.ret == "success") { + setTimeout(function () { + GW.process.callback(returnmsg); + }, 2000); + } + + if (returnmsg.builtin) { + GW.process.callback(returnmsg); + } else { + // GW.workspace.updateStatus(returnmsg); // the workflow status message should only come from the workflow-socket + } + } catch (errors) { + console.error(errors); + } + } + } + }, + + error: function (content) { + content = content.replace(/\n/g, "
    "); + + this.addlog(content); + }, + + send: function (data) { + if (this.ws != null) { + this.ws.send(data); + } else { + if (data != this.token) { + this.error("not connected!"); + } + } + }, + + checkSessionStatus: function () { + // console.log("Current WS status: " + GW.ssh.all_ws.readyState); + // return GW.ssh.all_ws.readyState; + + GW.ssh.checker_swich = true; + + GW.ssh.send("token:" + GW.general.CLIENT_TOKEN); + + setTimeout(() => { + if (GW.ssh.checker_swich) { + //restart the websocket if the switch is still true two seconds later + GW.ssh.startLogSocket(GW.ssh.token); + GW.ssh.checker_swich = false; + } + }, 2000); + }, + + ws_onopen: function (e) { + console.log("WebSocket Channel is Openned"); + + this.echo("connected"); + + setTimeout(() => { + GW.ssh.send("token:" + GW.general.CLIENT_TOKEN); + }, 1000); //create a chance for the server side to register the session if it didn't when it is openned + }, + + ws_onclose: function (e) { + try { + this.echo("disconnected"); + + GW.ssh.all_ws = null; + GW.ssh.ws = null; + GW.ssh.token = null; + } catch (e) { + console.error(e); + + this.echo("Reconnection failed. " + e); + } + + console.log("the logging out websocket has been closed"); + }, + + ws_onerror: function (e) { + this.error("The process execution failed."); + + this.error("Reason: " + e); + }, + + ws_onmessage: function (e) { + try { + if (e.data.indexOf("Session_Status:Active") != -1) { + GW.ssh.checker_swich = false; + } else if ( + e.data.indexOf(this.special.prompt) == -1 && + e.data.indexOf(this.special.ready) == -1 && + e.data.indexOf("No SSH connection is active") == -1 + ) { + this.echo(e.data); + } else { + //the websocket is already closed. try the history query + // this.echo("It ends too quickly. Go to history to check the logs out."); + } + + //if (e.data.indexOf(special.ready) != -1) { + + // shell.resume(); + + //} + } catch (err) { + console.log(err); + + this.error("** Invalid server response : " + e.data); + } + }, + + addlog: function (content) { + var dt = new Date(); + var time = dt.getHours() + ":" + dt.getMinutes() + ":" + dt.getSeconds(); + + cont_splits = content.split("*_*"); + + log_history_id = null; + + if (cont_splits.length > 1) { + log_history_id = cont_splits[0]; + let newArray = cont_splits.slice(1); + content = newArray.join(" "); + } + + var style1 = ""; + if (content.includes("Start to execute")) { + style1 = "color: blue; font-weight: bold; text-decoration: underline;"; + + $(".dot-flashing").removeClass("invisible"); + $(".dot-flashing").addClass("visible"); + } else if (content.includes("===== Process")) { + style1 = "color: blue; font-weight: bold; text-decoration: underline;"; + + $(".dot-flashing").removeClass("visible"); + $(".dot-flashing").addClass("invisible"); + } else if (content == "disconnected") { + $(".dot-flashing").removeClass("visible"); + $(".dot-flashing").addClass("invisible"); + } else if (log_history_id == GW.process.history_id) { + $(".dot-flashing").removeClass("invisible"); + $(".dot-flashing").addClass("visible"); + } else { + $(".dot-flashing").removeClass("visible"); + $(".dot-flashing").addClass("invisible"); + } + + var newline = + `

    ` + + content + + `

    `; + + this.current_log_length += 1; //line number plus 1 + + if (this.current_log_length > 5000) { + $("#log-window").find("p:first").remove(); + this.current_log_length -= 1; + } + + $("#log-window").append(newline); + + //don't output log to process log if the current executed is workflow + if (GW.process.last_executed_process_id == GW.process.process_id) { + if ($("#" + GW.ssh.process_output_id).length) { + if (this.current_process_log_length > 5000) { + $("#" + GW.ssh.process_output_id) + .find("p:first") + .remove(); + + this.current_process_log_length -= 1; + } + + if (GW.process.history_id == log_history_id) { + // only display the log if the current history id is the correct one + $("#" + GW.ssh.process_output_id).append(newline); + } + + this.current_process_log_length += 1; + } + } + }, + + clearProcessLog: function () { + $("#" + GW.ssh.process_output_id).html(""); + }, + + clearMain: function () { + $("#log-window").html(""); + }, + + getWsPrefixURL: function () { + var s = + (window.location.protocol === "https:" ? "wss://" : "ws://") + + window.location.host + + "/Geoweaver/"; + + // s += "Geoweaver/"; //this is gone in spring boot + + console.log("Ws URL Prefix: ", s); + + return s; + }, + + startLogSocket: function (token) { + if (GW.ssh.all_ws) GW.ssh.all_ws.close(); + + GW.ssh.all_ws = new WebSocket(this.getWsPrefixURL() + "command-socket"); + + GW.ssh.ws = GW.ssh.all_ws; + + GW.ssh.output_div_id = "log_box_id"; + + GW.ssh.token = token; //token is the jsession id + + // this.echo("Running process " + token) + + GW.ssh.all_ws.onopen = function (e) { + GW.ssh.ws_onopen(e); + }; + + GW.ssh.all_ws.onclose = function (e) { + GW.ssh.ws_onclose(e); + }; + + GW.ssh.all_ws.onmessage = function (e) { + GW.ssh.ws_onmessage(e); + }; + + GW.ssh.all_ws.onerror = function (e) { + GW.ssh.ws_onerror(e); + }; + }, + + connectWsSessionWithExecution: function (msg) {}, + + openLog: function (msg) { + //check if the websocket session is alive, otherwise, restore the connection + + if ( + GW.ssh.all_ws != null && + (GW.ssh.all_ws.readyState === WebSocket.CLOSED || + GW.ssh.all_ws.readyState === WebSocket.CLOSING) + ) { + // GW.ssh.all_ws.close(); + + console.log( + "The command websocket connection is detected to be closed. Try to reconnect...", + ); + + GW.ssh.startLogSocket(msg.token); + + console.log("The console websocket connection is restored.."); + } else { + GW.ssh.checkSessionStatus(); + } + + if (msg.history_id.length == 12) + this.addlog("=======\nStart to execute Process " + msg.history_id); + else this.addlog("=======\nStart to execute Workflow " + msg.history_id); + }, + + openTerminal: function (token, terminal_div_id) {}, +}; diff --git a/src/main/resources/static/js/gw.sshterm.js b/src/main/resources/static/js/gw.sshterm.js index add901068..74ab35e0d 100644 --- a/src/main/resources/static/js/gw.sshterm.js +++ b/src/main/resources/static/js/gw.sshterm.js @@ -9,118 +9,96 @@ var password_cout = 0; var port = window.location.port; var pcol = window.location.protocol; */ var root = getContextURLPath(); -var key = '${key}'; +var key = "${key}"; var completable = false; var username = ''; //alert('ID:' + key + ',USERNAME:' + username); var special = { - black: "\x1b[1;30m", - red: "\x1b[1;31m", - green: "\x1b[1;32m", - yellow: "\x1b[1;33m", - blue: "\x1b[1;34m", + black: "\x1b[1;30m", + red: "\x1b[1;31m", + green: "\x1b[1;32m", + yellow: "\x1b[1;33m", + blue: "\x1b[1;34m", magenta: "\x1b[1;35m", - cyan: "\x1b[1;36m", - white: "\x1b[1;37m", - reset: "\x1b[0m", - ready: "]0;", - prompt: "$" + cyan: "\x1b[1;36m", + white: "\x1b[1;37m", + reset: "\x1b[0m", + ready: "]0;", + prompt: "$", }; - + function ws_onopen(e) { - //shell.echo(special.white + "connected" + special.reset); shell.echo("socket connected"); // link the SSH session established with spring security logon to the websocket session... send(token); send("\n"); shell.resume(); - } function send(data) { - - shell.pause(); - - if(ws != null){ - - ws.send(data); - - } else { - - shell.error('not connected!'); - - } + shell.pause(); + + if (ws != null) { + ws.send(data); + } else { + shell.error("not connected!"); + } } function ws_onclose(e) { - - try{ - - shell.echo(special.white + "disconnected" + special.reset); - - shell.destroy(); - - shell.purge(); - - }catch(e){ - - console.error(e); - } - - document.forms['logout'].submit(); + try { + shell.echo(special.white + "disconnected" + special.reset); + + shell.destroy(); + + shell.purge(); + } catch (e) { + console.error(e); + } + + document.forms["logout"].submit(); } function ws_onerror(e) { - - shell.echo(special.red + e + special.reset); - - shell.resume(); - + shell.echo(special.red + e + special.reset); + + shell.resume(); } -function resumeTerm(message){ - - var breaks; - - if(message.indexOf("$ ")!=-1){ - - breaks = message.split("$ "); - - last_prompt = breaks[0] + "$ "; - - shell.set_prompt(last_prompt); - - }else if(message.indexOf("# ")!=-1){ - - breaks = message.split("# "); - - last_prompt = breaks[0] + "# "; - - shell.set_prompt(last_prompt); - - } - - if(breaks != null && breaks[1].startsWith("sudo")){ - - shell.set_prompt("[sudo] password for " + user + ": "); - - //one try failed - //shell.set_prompt("[sudo] password for " + user + ": "); - - //passwordPhase = true; - - }else if(message.startsWith("[sudo] password")){ - - /*passwordPhase = true;*/ - - send("\n"); - - shell.set_mask(false); - - } - - /*else if(passwordPhase && (message.startsWith("[sudo] password for") || message.startsWith("Sorry"))){ +function resumeTerm(message) { + var breaks; + + if (message.indexOf("$ ") != -1) { + breaks = message.split("$ "); + + last_prompt = breaks[0] + "$ "; + + shell.set_prompt(last_prompt); + } else if (message.indexOf("# ") != -1) { + breaks = message.split("# "); + + last_prompt = breaks[0] + "# "; + + shell.set_prompt(last_prompt); + } + + if (breaks != null && breaks[1].startsWith("sudo")) { + shell.set_prompt("[sudo] password for " + user + ": "); + + //one try failed + //shell.set_prompt("[sudo] password for " + user + ": "); + + //passwordPhase = true; + } else if (message.startsWith("[sudo] password")) { + /*passwordPhase = true;*/ + + send("\n"); + + shell.set_mask(false); + } + + /*else if(passwordPhase && (message.startsWith("[sudo] password for") || message.startsWith("Sorry"))){ //one try failed shell.set_prompt("[sudo] password for " + user + ": "); @@ -131,29 +109,26 @@ function resumeTerm(message){ passwordPhase = false; }*/ - - shell.resume(); - + + shell.resume(); } function ws_onmessage(e) { - try { - - //if(e.data.indexOf(special.prompt) == -1 && e.data.indexOf(special.ready) == -1) { - - console.log(e.data); + //if(e.data.indexOf(special.prompt) == -1 && e.data.indexOf(special.ready) == -1) { + + console.log(e.data); - /*if(completable){ + /*if(completable){ completable = false; }else{*/ - - var match = /\r|\n/.exec(e.data); - - /*if(passwordPhase){ + + var match = /\r|\n/.exec(e.data); + + /*if(passwordPhase){ if(e.data.startsWith("[sudo] password for") || e.data.startsWith("Sorry")){ @@ -180,119 +155,108 @@ function ws_onmessage(e) { } }else */ - - if(!match && e.data.indexOf("@")!=-1 && e.data.indexOf(special.prompt)){ - - /*var breaks = e.data.split("$ "); + + if (!match && e.data.indexOf("@") != -1 && e.data.indexOf(special.prompt)) { + /*var breaks = e.data.split("$ "); var last_prompt = breaks[0] + "$ "; shell.set_prompt(last_prompt); shell.resume();*/ - - resumeTerm(e.data); - - }else if(e.data.startsWith("[sudo] password")){ - - //passwordPhase = true; - - resumeTerm(e.data); - - }else{ - - shell.echo(e.data); - - } - - - /*}*/ - + + resumeTerm(e.data); + } else if (e.data.startsWith("[sudo] password")) { + //passwordPhase = true; + + resumeTerm(e.data); + } else { + shell.echo(e.data); + } + + /*}*/ + //} - + //if (e.data.indexOf(special.ready) != -1) { - - + //} - - } catch(err) { - - shell.error("** Invalid server response : " + e.data + " - " + err); - - if(last_prompt) { - - shell.set_prompt(last_prompt); - - } - + } catch (err) { + shell.error("** Invalid server response : " + e.data + " - " + err); + + if (last_prompt) { + shell.set_prompt(last_prompt); + } } - + //shell.resume(); - } function getContextURLPath() { - var rootUrl = location.protocol; - rootUrl = rootUrl+"//"+location.host; - var path = location.pathname; - var tempStr = path.split('/'); - rootUrl = rootUrl+"/"+tempStr[1]; - return rootUrl; + var rootUrl = location.protocol; + rootUrl = rootUrl + "//" + location.host; + var path = location.pathname; + var tempStr = path.split("/"); + rootUrl = rootUrl + "/" + tempStr[1]; + return rootUrl; } - -function getWsPrefixURL (){ - - var s = ((window.location.protocol === "https:") ? "wss://" : "ws://") + window.location.host + "/"; - -// s += "Geoweaver/"; - - console.log("Ws URL Prefix: ", s) - - return s - + +function getWsPrefixURL() { + var s = + (window.location.protocol === "https:" ? "wss://" : "ws://") + + window.location.host + + "/"; + + // s += "Geoweaver/"; + + console.log("Ws URL Prefix: ", s); + + return s; } $(document).ready(function ($) { - -// ws = new SockJS("shell"); - - ws = new WebSocket(getWsPrefixURL() + "Geoweaver/terminal-socket") - - ws.onopen = function(e) { ws_onopen(e) }; - - ws.onclose = function(e) { ws_onclose(e) }; - - ws.onmessage = function(e) { ws_onmessage(e) }; - - ws.onerror = function(e) { ws_onerror(e) }; - - shell = $('#content').terminal(function (command, term) { - - if(command.startsWith("cd")){ - - command += "\n"; - - } - - if(command.startsWith("sudo")){ - - shell.set_mask(true); - - } - - send(command); - - }, { - - prompt: '['+user+'@'+host+': ~]# ', - name: 'Geoweaver SSH on Web', - scrollOnEcho: true, - exit: false, - clear: true, - wrap: true, - greetings: "SSH on Web started. Type 'exit' to quit. \n", - - /*completion: function (command, callback) { + // ws = new SockJS("shell"); + + ws = new WebSocket(getWsPrefixURL() + "Geoweaver/terminal-socket"); + + ws.onopen = function (e) { + ws_onopen(e); + }; + + ws.onclose = function (e) { + ws_onclose(e); + }; + + ws.onmessage = function (e) { + ws_onmessage(e); + }; + + ws.onerror = function (e) { + ws_onerror(e); + }; + + shell = $("#content").terminal( + function (command, term) { + if (command.startsWith("cd")) { + command += "\n"; + } + + if (command.startsWith("sudo")) { + shell.set_mask(true); + } + + send(command); + }, + { + prompt: "[" + user + "@" + host + ": ~]# ", + name: "Geoweaver SSH on Web", + scrollOnEcho: true, + exit: false, + clear: true, + wrap: true, + greetings: "SSH on Web started. Type 'exit' to quit. \n", + + /*completion: function (command, callback) { console.log("Complete command is entered - " + command + ":") @@ -302,53 +266,43 @@ $(document).ready(function ($) { },*/ - /*keypress:{ + /*keypress:{ "" },*/ - - /*onCommandChange: function(command, terminal){ + + /*onCommandChange: function(command, terminal){ console.log("Command is changed: ", command); },*/ - keymap: { - - "CTRL+D": function(e, original){ - - console.log("ctrl+d is presesed"); - - send("\u0003"); - - original(); - - }, - - "CTRL+C": function(e, original){ - - console.log("ctrl+c is presesed"); - - send("\u0003"); - - original(); - - }, - - "CTRL+ALT+C": function(e, original){ - - console.log("ctrl+alt+c is presesed"); - - send("\u0003"); - - original(); - - } - - } - } - - ); - -}); \ No newline at end of file + keymap: { + "CTRL+D": function (e, original) { + console.log("ctrl+d is presesed"); + + send("\u0003"); + + original(); + }, + + "CTRL+C": function (e, original) { + console.log("ctrl+c is presesed"); + + send("\u0003"); + + original(); + }, + + "CTRL+ALT+C": function (e, original) { + console.log("ctrl+alt+c is presesed"); + + send("\u0003"); + + original(); + }, + }, + }, + ); +}); diff --git a/src/main/resources/static/js/gw.test.js b/src/main/resources/static/js/gw.test.js index 0ce79c28b..f93c8cc11 100644 --- a/src/main/resources/static/js/gw.test.js +++ b/src/main/resources/static/js/gw.test.js @@ -5,129 +5,200 @@ */ GW.test = { + run: function () { + GW.test.initHTML(); - run: function(){ + describe("Geoweaver", function () { + describe(".general()", function () { + it("process", function () { + GW.process.addMenuItem( + { id: "xyzxyz", name: "testProcess" }, + "process", + ); + GW.process.refreshProcessList(); + GW.process.checkIfProcessPanelActive(); + GW.process.clearCache(); + GW.process.clearProcessLogging(); + GW.process.clearCodeEditorListener(); + GW.process.displayToolbar(); + $("body").append('
    '); + GW.process.display({ + id: "7uvu8x", + name: "testshell1", + description: null, + code: '#!/bin/bash\nsudo pacman-mirrors --country United_States\nsudo pacman-mirrors -f 0\nsudo pacman -S yay pamac --noconfirm\nsudo pacman -Syyu --noconfirm\nyay -Syyua --noconfirm\n\nyay -S timeshift gnome-disk-utility stacer-bin --noconfirm\n\nsudo mkdir -p /media/hdd\nsudo chmod -R 777 /media/hdd\necho "mount hard drive to /media/hdd using gnome-disk-utility"\n\necho "Installing arc-kde theme:"\npkgs="arc-kde papirus-icon-theme papirus-maia-icon-theme latte-dock"\necho $pkgs\nyay -S $pkgs --noconfirm\n\necho "System Settings - Workspace Theme -- Look And Feel - Arc Dark"\necho "Backup system using timeshift"\n\nyay -Sy base-devel --noconfirm\nyay -S linux59 linux59-headers --noconfirm\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n', + lang: "shell", + owner: "111111", + confidential: "FALSE", + }); - GW.test.initHTML(); - - describe('Geoweaver', function(){ - describe('.general()', function(){ - it('process', function(){ - GW.process.addMenuItem({id:"xyzxyz", name:"testProcess"}, "process"); - GW.process.refreshProcessList(); - GW.process.checkIfProcessPanelActive(); - GW.process.clearCache(); - GW.process.clearProcessLogging(); - GW.process.clearCodeEditorListener(); - GW.process.displayToolbar(); + expect(true).to.equal(true); + }); - $("body").append("
    "); - GW.process.display({"id":"7uvu8x","name":"testshell1","description":null,"code":"#!/bin/bash\nsudo pacman-mirrors --country United_States\nsudo pacman-mirrors -f 0\nsudo pacman -S yay pamac --noconfirm\nsudo pacman -Syyu --noconfirm\nyay -Syyua --noconfirm\n\nyay -S timeshift gnome-disk-utility stacer-bin --noconfirm\n\nsudo mkdir -p /media/hdd\nsudo chmod -R 777 /media/hdd\necho \"mount hard drive to /media/hdd using gnome-disk-utility\"\n\necho \"Installing arc-kde theme:\"\npkgs=\"arc-kde papirus-icon-theme papirus-maia-icon-theme latte-dock\"\necho $pkgs\nyay -S $pkgs --noconfirm\n\necho \"System Settings - Workspace Theme -- Look And Feel - Arc Dark\"\necho \"Backup system using timeshift\"\n\nyay -Sy base-devel --noconfirm\nyay -S linux59 linux59-headers --noconfirm\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","lang":"shell","owner":"111111","confidential":"FALSE"}); - - - expect(true).to.equal(true); - }) + it("host", function () { + GW.host.addMenuItem({ id: "xyzxyz", name: "testProcess" }, "process"); + GW.host.refreshHostList(); + GW.host.checkIfHostPanelActive(); + GW.host.clearCache(); + GW.host.expand({ type: "ssh" }); - it('host', function(){ - GW.host.addMenuItem({id:"xyzxyz", name:"testProcess"}, "process"); - GW.host.refreshHostList(); - GW.host.checkIfHostPanelActive(); - GW.host.clearCache(); - GW.host.expand({"type": "ssh"}); + GW.host.newDialog(); + GW.host.new_host_frame.closeFrame(); - GW.host.newDialog(); - GW.host.new_host_frame.closeFrame(); - - GW.host.list([{"id":"oy1pa5","name":"localhost","ip":"127.0.0.1","port":"22","username":"test","owner":"111111","type":"ssh","url":"","confidential":"FALSE"},{"id":"h8avme","name":"New Host","ip":"","port":"","username":null,"owner":"111111","type":"jupyterhub","url":"sdfds","confidential":"FALSE"},{"id":"hocqgp","name":"Geobrain","ip":"129.174.131.222","port":"22","username":"zsun","owner":"111111","type":"ssh","url":"","confidential":"FALSE"}]); - GW.host.validateIP("127.0.0.1"); - GW.host.display({"id":"oy1pa5","name":"localhost","ip":"127.0.0.1","port":"22","username":"test","owner":"111111","type":"ssh","url":"","confidential":"FALSE"}); - - expect(true).to.equal(true); - }) - - it('workflow', function(){ - GW.workflow.addMenuItem({id:"wfxyzxyz", name:"test workflow"}); - GW.workflow.refreshWorkflowList(); - - GW.workflow.list([{"id":"8mfoowf5jdgfcrf1rubt","name":"Test2","description":null,"owner":"111111","confidential":"FALSE","edges":"[{\"source\":{\"title\":\"test.sh\",\"id\":\"j3gk83-ksEM6\",\"x\":516,\"y\":124,\"color\":\"red\"},\"target\":{\"title\":\"sdfdsf\",\"id\":\"1nadu8-eMUf6\",\"x\":846,\"y\":309,\"color\":\"red\"}},{\"source\":{\"title\":\"test.sh\",\"id\":\"j3gk83-ksEM6\",\"x\":516,\"y\":124,\"color\":\"red\"},\"target\":{\"title\":\"sdfdsf\",\"id\":\"1nadu8-f2GUH\",\"x\":486.3621826171875,\"y\":446.6592025756836,\"color\":\"red\"}},{\"source\":{\"title\":\"test.sh\",\"id\":\"j3gk83-ksEM6\",\"x\":516,\"y\":124,\"color\":\"red\"},\"target\":{\"title\":\"sdfdsf\",\"id\":\"1nadu8-hYYyQ\",\"x\":720,\"y\":559,\"color\":\"red\"}},{\"source\":{\"title\":\"sdfds\",\"id\":\"jsff21-HQa0e\",\"x\":201.05120849609375,\"y\":263.98046875,\"color\":\"green\"},\"target\":{\"title\":\"sdfdsf\",\"id\":\"1nadu8-f2GUH\",\"x\":486.3621826171875,\"y\":446.6592025756836,\"color\":\"red\"}},{\"source\":{\"title\":\"sdfdsf\",\"id\":\"1nadu8-f2GUH\",\"x\":486.3621826171875,\"y\":446.6592025756836,\"color\":\"red\"},\"target\":{\"title\":\"sdfds\",\"id\":\"jsff21-80Ruu\",\"x\":663.7502670288086,\"y\":761.33251953125,\"color\":\"green\"}},{\"source\":{\"title\":\"sdfdsf\",\"id\":\"1nadu8-hYYyQ\",\"x\":720,\"y\":559,\"color\":\"red\"},\"target\":{\"title\":\"sdfds\",\"id\":\"jsff21-80Ruu\",\"x\":663.7502670288086,\"y\":761.33251953125,\"color\":\"green\"}},{\"source\":{\"title\":\"sdfdsf\",\"id\":\"1nadu8-hYYyQ\",\"x\":720,\"y\":559,\"color\":\"red\"},\"target\":{\"title\":\"sdfds\",\"id\":\"jsff21-kJasL\",\"x\":1031.091796875,\"y\":486.306396484375,\"color\":\"green\"}},{\"source\":{\"title\":\"sdfdsf\",\"id\":\"1nadu8-eMUf6\",\"x\":846,\"y\":309,\"color\":\"red\"},\"target\":{\"title\":\"sdfds\",\"id\":\"jsff21-kJasL\",\"x\":1031.091796875,\"y\":486.306396484375,\"color\":\"green\"}},{\"source\":{\"title\":\"sdfds\",\"id\":\"jsff21-kJasL\",\"x\":1031.091796875,\"y\":486.306396484375,\"color\":\"green\"},\"target\":{\"title\":\"very_long_process\",\"id\":\"jdzilo-RY9DE\",\"x\":1092.4887084960938,\"y\":739.0208740234375,\"color\":\"green\"}},{\"source\":{\"title\":\"sdfds\",\"id\":\"jsff21-80Ruu\",\"x\":663.7502670288086,\"y\":761.33251953125,\"color\":\"green\"},\"target\":{\"title\":\"very_long_process\",\"id\":\"jdzilo-RY9DE\",\"x\":1092.4887084960938,\"y\":739.0208740234375,\"color\":\"green\"}},{\"source\":{\"title\":\"test.sh\",\"id\":\"j3gk83-ksEM6\",\"x\":516,\"y\":124,\"color\":\"red\"},\"target\":{\"title\":\"very_long_process\",\"id\":\"jdzilo-1q0Rp\",\"x\":700,\"y\":72,\"color\":\"green\"}},{\"source\":{\"title\":\"sdfds\",\"id\":\"jsff21-HQa0e\",\"x\":201.05120849609375,\"y\":263.98046875,\"color\":\"green\"},\"target\":{\"title\":\"very_long_process\",\"id\":\"jdzilo-9vBkB\",\"x\":109.91619873046875,\"y\":489.175048828125,\"color\":\"green\"}},{\"source\":{\"title\":\"sdfds\",\"id\":\"jsff21-HQa0e\",\"x\":201.05120849609375,\"y\":263.98046875,\"color\":\"green\"},\"target\":{\"title\":\"very_long_process\",\"id\":\"jdzilo-1FgbC\",\"x\":323.335205078125,\"y\":550.1676025390625,\"color\":\"green\"}},{\"source\":{\"title\":\"sdfdsf\",\"id\":\"1nadu8-eMUf6\",\"x\":846,\"y\":309,\"color\":\"red\"},\"target\":{\"title\":\"very_long_process\",\"id\":\"jdzilo-rGUgx\",\"x\":732,\"y\":432,\"color\":\"green\"}},{\"source\":{\"title\":\"sdfds\",\"id\":\"jsff21-HQa0e\",\"x\":201.05120849609375,\"y\":263.98046875,\"color\":\"green\"},\"target\":{\"title\":\"complexity_learning\",\"id\":\"eqa0ae-iRSio\",\"x\":204.61265563964844,\"y\":664.52978515625,\"color\":\"orange\"}},{\"source\":{\"title\":\"sdfdsf\",\"id\":\"1nadu8-hYYyQ\",\"x\":720,\"y\":559,\"color\":\"red\"},\"target\":{\"title\":\"sdfdsf\",\"id\":\"1nadu8-nAyaL\",\"x\":913.4776306152344,\"y\":664.4720458984375,\"color\":\"red\"}},{\"source\":{\"title\":\"sdfdsf\",\"id\":\"1nadu8-eMUf6\",\"x\":846,\"y\":309,\"color\":\"red\"},\"target\":{\"title\":\"sdggkkk\",\"id\":\"j0uraj-V5nKX\",\"x\":1134.1107788085938,\"y\":346.7290344238281,\"color\":\"green\"}},{\"source\":{\"title\":\"test.sh\",\"id\":\"j3gk83-ksEM6\",\"x\":516,\"y\":124,\"color\":\"red\"},\"target\":{\"title\":\"sdggkkk\",\"id\":\"j0uraj-gQFzf\",\"x\":938.4860534667969,\"y\":196.58752822875977,\"color\":\"green\"}},{\"source\":{\"title\":\"test.sh\",\"id\":\"j3gk83-ksEM6\",\"x\":516,\"y\":124,\"color\":\"red\"},\"target\":{\"title\":\"test1\",\"id\":\"2zh7so-0uA9W\",\"x\":393.49322509765625,\"y\":256.5926818847656}},{\"source\":{\"title\":\"sdfdsf\",\"id\":\"1nadu8-f2GUH\",\"x\":486.3621826171875,\"y\":446.6592025756836,\"color\":\"red\"},\"target\":{\"title\":\"test1\",\"id\":\"2zh7so-nnZrJ\",\"x\":469.376708984375,\"y\":637.949951171875}}]","nodes":"[{\"title\":\"test.sh\",\"id\":\"j3gk83-ksEM6\",\"x\":516,\"y\":124,\"color\":\"red\"},{\"title\":\"sdfdsf\",\"id\":\"1nadu8-eMUf6\",\"x\":846,\"y\":309,\"color\":\"red\"},{\"title\":\"sdfdsf\",\"id\":\"1nadu8-hYYyQ\",\"x\":720,\"y\":559,\"color\":\"red\"},{\"title\":\"sdfdsf\",\"id\":\"1nadu8-f2GUH\",\"x\":486.3621826171875,\"y\":446.6592025756836,\"color\":\"red\"},{\"title\":\"sdfds\",\"id\":\"jsff21-HQa0e\",\"x\":201.05120849609375,\"y\":263.98046875,\"color\":\"green\"},{\"title\":\"sdfds\",\"id\":\"jsff21-kJasL\",\"x\":1031.091796875,\"y\":486.306396484375,\"color\":\"green\"},{\"title\":\"sdfds\",\"id\":\"jsff21-80Ruu\",\"x\":663.7502670288086,\"y\":761.33251953125,\"color\":\"green\"},{\"title\":\"very_long_process\",\"id\":\"jdzilo-RY9DE\",\"x\":1092.4887084960938,\"y\":739.0208740234375,\"color\":\"green\"},{\"title\":\"very_long_process\",\"id\":\"jdzilo-9vBkB\",\"x\":109.91619873046875,\"y\":489.175048828125,\"color\":\"green\"},{\"title\":\"very_long_process\",\"id\":\"jdzilo-1FgbC\",\"x\":323.335205078125,\"y\":550.1676025390625,\"color\":\"green\"},{\"title\":\"very_long_process\",\"id\":\"jdzilo-rGUgx\",\"x\":732,\"y\":432,\"color\":\"green\"},{\"title\":\"very_long_process\",\"id\":\"jdzilo-1q0Rp\",\"x\":700,\"y\":72,\"color\":\"green\"},{\"title\":\"complexity_learning\",\"id\":\"eqa0ae-iRSio\",\"x\":204.61265563964844,\"y\":664.52978515625,\"color\":\"orange\"},{\"title\":\"sdfdsf\",\"id\":\"1nadu8-nAyaL\",\"x\":913.4776306152344,\"y\":664.4720458984375,\"color\":\"red\"},{\"title\":\"sdggkkk\",\"id\":\"j0uraj-gQFzf\",\"x\":938.4860534667969,\"y\":196.58752822875977,\"color\":\"green\"},{\"title\":\"sdggkkk\",\"id\":\"j0uraj-V5nKX\",\"x\":1134.1107788085938,\"y\":346.7290344238281,\"color\":\"green\"},{\"title\":\"test1\",\"id\":\"2zh7so-0uA9W\",\"x\":393.49322509765625,\"y\":256.5926818847656},{\"title\":\"test1\",\"id\":\"2zh7so-nnZrJ\",\"x\":469.376708984375,\"y\":637.949951171875}]"}]); + GW.host.list([ + { + id: "oy1pa5", + name: "localhost", + ip: "127.0.0.1", + port: "22", + username: "test", + owner: "111111", + type: "ssh", + url: "", + confidential: "FALSE", + }, + { + id: "h8avme", + name: "New Host", + ip: "", + port: "", + username: null, + owner: "111111", + type: "jupyterhub", + url: "sdfds", + confidential: "FALSE", + }, + { + id: "hocqgp", + name: "Geobrain", + ip: "129.174.131.222", + port: "22", + username: "zsun", + owner: "111111", + type: "ssh", + url: "", + confidential: "FALSE", + }, + ]); + GW.host.validateIP("127.0.0.1"); + GW.host.display({ + id: "oy1pa5", + name: "localhost", + ip: "127.0.0.1", + port: "22", + username: "test", + owner: "111111", + type: "ssh", + url: "", + confidential: "FALSE", + }); - GW.workflow.display({"id":"zv9gez8e3qdtultn9i6c","name":"t3","description":"sdfdsf","owner":"111111","confidential":"FALSE","edges":"[{\"source\":{\"title\":\"testpython2\",\"id\":\"nq1huz-iWizg\",\"x\":580.8966674804688,\"y\":187.61172485351562},\"target\":{\"title\":\"sdggkkk\",\"id\":\"j0uraj-lNCK0\",\"x\":897,\"y\":8}}]","nodes":"[{\"title\":\"testpython2\",\"id\":\"nq1huz-iWizg\",\"x\":580.8966674804688,\"y\":187.61172485351562},{\"title\":\"sdggkkk\",\"id\":\"j0uraj-lNCK0\",\"x\":897,\"y\":8}]"}); + expect(true).to.equal(true); + }); - expect(true).to.equal(true); - }) + it("workflow", function () { + GW.workflow.addMenuItem({ id: "wfxyzxyz", name: "test workflow" }); + GW.workflow.refreshWorkflowList(); - it('workspace', function(){ - // GW.workflow.newDialog(); //this should be tested in the workspace - // if(GW.workflow.new_frame!=null) GW.workflow.new_frame.closeFrame(); - expect(true).to.equal(true); - }) + GW.workflow.list([ + { + id: "8mfoowf5jdgfcrf1rubt", + name: "Test2", + description: null, + owner: "111111", + confidential: "FALSE", + edges: + '[{"source":{"title":"test.sh","id":"j3gk83-ksEM6","x":516,"y":124,"color":"red"},"target":{"title":"sdfdsf","id":"1nadu8-eMUf6","x":846,"y":309,"color":"red"}},{"source":{"title":"test.sh","id":"j3gk83-ksEM6","x":516,"y":124,"color":"red"},"target":{"title":"sdfdsf","id":"1nadu8-f2GUH","x":486.3621826171875,"y":446.6592025756836,"color":"red"}},{"source":{"title":"test.sh","id":"j3gk83-ksEM6","x":516,"y":124,"color":"red"},"target":{"title":"sdfdsf","id":"1nadu8-hYYyQ","x":720,"y":559,"color":"red"}},{"source":{"title":"sdfds","id":"jsff21-HQa0e","x":201.05120849609375,"y":263.98046875,"color":"green"},"target":{"title":"sdfdsf","id":"1nadu8-f2GUH","x":486.3621826171875,"y":446.6592025756836,"color":"red"}},{"source":{"title":"sdfdsf","id":"1nadu8-f2GUH","x":486.3621826171875,"y":446.6592025756836,"color":"red"},"target":{"title":"sdfds","id":"jsff21-80Ruu","x":663.7502670288086,"y":761.33251953125,"color":"green"}},{"source":{"title":"sdfdsf","id":"1nadu8-hYYyQ","x":720,"y":559,"color":"red"},"target":{"title":"sdfds","id":"jsff21-80Ruu","x":663.7502670288086,"y":761.33251953125,"color":"green"}},{"source":{"title":"sdfdsf","id":"1nadu8-hYYyQ","x":720,"y":559,"color":"red"},"target":{"title":"sdfds","id":"jsff21-kJasL","x":1031.091796875,"y":486.306396484375,"color":"green"}},{"source":{"title":"sdfdsf","id":"1nadu8-eMUf6","x":846,"y":309,"color":"red"},"target":{"title":"sdfds","id":"jsff21-kJasL","x":1031.091796875,"y":486.306396484375,"color":"green"}},{"source":{"title":"sdfds","id":"jsff21-kJasL","x":1031.091796875,"y":486.306396484375,"color":"green"},"target":{"title":"very_long_process","id":"jdzilo-RY9DE","x":1092.4887084960938,"y":739.0208740234375,"color":"green"}},{"source":{"title":"sdfds","id":"jsff21-80Ruu","x":663.7502670288086,"y":761.33251953125,"color":"green"},"target":{"title":"very_long_process","id":"jdzilo-RY9DE","x":1092.4887084960938,"y":739.0208740234375,"color":"green"}},{"source":{"title":"test.sh","id":"j3gk83-ksEM6","x":516,"y":124,"color":"red"},"target":{"title":"very_long_process","id":"jdzilo-1q0Rp","x":700,"y":72,"color":"green"}},{"source":{"title":"sdfds","id":"jsff21-HQa0e","x":201.05120849609375,"y":263.98046875,"color":"green"},"target":{"title":"very_long_process","id":"jdzilo-9vBkB","x":109.91619873046875,"y":489.175048828125,"color":"green"}},{"source":{"title":"sdfds","id":"jsff21-HQa0e","x":201.05120849609375,"y":263.98046875,"color":"green"},"target":{"title":"very_long_process","id":"jdzilo-1FgbC","x":323.335205078125,"y":550.1676025390625,"color":"green"}},{"source":{"title":"sdfdsf","id":"1nadu8-eMUf6","x":846,"y":309,"color":"red"},"target":{"title":"very_long_process","id":"jdzilo-rGUgx","x":732,"y":432,"color":"green"}},{"source":{"title":"sdfds","id":"jsff21-HQa0e","x":201.05120849609375,"y":263.98046875,"color":"green"},"target":{"title":"complexity_learning","id":"eqa0ae-iRSio","x":204.61265563964844,"y":664.52978515625,"color":"orange"}},{"source":{"title":"sdfdsf","id":"1nadu8-hYYyQ","x":720,"y":559,"color":"red"},"target":{"title":"sdfdsf","id":"1nadu8-nAyaL","x":913.4776306152344,"y":664.4720458984375,"color":"red"}},{"source":{"title":"sdfdsf","id":"1nadu8-eMUf6","x":846,"y":309,"color":"red"},"target":{"title":"sdggkkk","id":"j0uraj-V5nKX","x":1134.1107788085938,"y":346.7290344238281,"color":"green"}},{"source":{"title":"test.sh","id":"j3gk83-ksEM6","x":516,"y":124,"color":"red"},"target":{"title":"sdggkkk","id":"j0uraj-gQFzf","x":938.4860534667969,"y":196.58752822875977,"color":"green"}},{"source":{"title":"test.sh","id":"j3gk83-ksEM6","x":516,"y":124,"color":"red"},"target":{"title":"test1","id":"2zh7so-0uA9W","x":393.49322509765625,"y":256.5926818847656}},{"source":{"title":"sdfdsf","id":"1nadu8-f2GUH","x":486.3621826171875,"y":446.6592025756836,"color":"red"},"target":{"title":"test1","id":"2zh7so-nnZrJ","x":469.376708984375,"y":637.949951171875}}]', + nodes: + '[{"title":"test.sh","id":"j3gk83-ksEM6","x":516,"y":124,"color":"red"},{"title":"sdfdsf","id":"1nadu8-eMUf6","x":846,"y":309,"color":"red"},{"title":"sdfdsf","id":"1nadu8-hYYyQ","x":720,"y":559,"color":"red"},{"title":"sdfdsf","id":"1nadu8-f2GUH","x":486.3621826171875,"y":446.6592025756836,"color":"red"},{"title":"sdfds","id":"jsff21-HQa0e","x":201.05120849609375,"y":263.98046875,"color":"green"},{"title":"sdfds","id":"jsff21-kJasL","x":1031.091796875,"y":486.306396484375,"color":"green"},{"title":"sdfds","id":"jsff21-80Ruu","x":663.7502670288086,"y":761.33251953125,"color":"green"},{"title":"very_long_process","id":"jdzilo-RY9DE","x":1092.4887084960938,"y":739.0208740234375,"color":"green"},{"title":"very_long_process","id":"jdzilo-9vBkB","x":109.91619873046875,"y":489.175048828125,"color":"green"},{"title":"very_long_process","id":"jdzilo-1FgbC","x":323.335205078125,"y":550.1676025390625,"color":"green"},{"title":"very_long_process","id":"jdzilo-rGUgx","x":732,"y":432,"color":"green"},{"title":"very_long_process","id":"jdzilo-1q0Rp","x":700,"y":72,"color":"green"},{"title":"complexity_learning","id":"eqa0ae-iRSio","x":204.61265563964844,"y":664.52978515625,"color":"orange"},{"title":"sdfdsf","id":"1nadu8-nAyaL","x":913.4776306152344,"y":664.4720458984375,"color":"red"},{"title":"sdggkkk","id":"j0uraj-gQFzf","x":938.4860534667969,"y":196.58752822875977,"color":"green"},{"title":"sdggkkk","id":"j0uraj-V5nKX","x":1134.1107788085938,"y":346.7290344238281,"color":"green"},{"title":"test1","id":"2zh7so-0uA9W","x":393.49322509765625,"y":256.5926818847656},{"title":"test1","id":"2zh7so-nnZrJ","x":469.376708984375,"y":637.949951171875}]', + }, + ]); - it('history', function(){ - - expect(true).to.equal(true); - }) - - // describe('with many arguments', function(){ - // it('should add the values', function(){ - // var arr = []; - // arr.push('foo', 'bar'); - // expect(arr[0]).to.equal('foo'); - // expect(arr[1]).to.equal('bar'); - // }) - // }) - // }) - - // describe('.unshift()', function(){ - // it('should prepend a value', function(){ - // var arr = [1,2,3]; - // arr.unshift('foo'); - // expect(arr[0]).to.equal('foo'); - // expect(arr[1]).to.equal(1); - // }) - - // it('should return the length', function(){ - // var arr = []; - // var n = arr.unshift('foo'); - // expect(n).to.equal(1); - // n = arr.unshift('bar'); - // expect(n).to.equal(2); - // }) - - // describe('with many arguments', function(){ - // it('should add the values', function(){ - // var arr = []; - // arr.unshift('foo', 'bar'); - // expect(arr[0]).to.equal('foo'); - // expect(arr[1]).to.equal('bar'); - // }) - // }) - // }) - - // describe('.pop()', function(){ - // it('should remove and return the last value', function(){ - // var arr = [1,2,3]; - // expect(arr.pop()).to.equal(3); - // expect(arr.pop()).to.equal(2); - // expect(arr).to.have.length(1); - // }) - // }) - - // describe('.shift()', function(){ - // it('should remove and return the first value', function(){ - // var arr = [1,2,3]; - // expect(arr.shift()).to.equal(1); - // expect(arr.shift()).to.equal(2); - // expect(arr).to.have.length(1); - // }) - }) + GW.workflow.display({ + id: "zv9gez8e3qdtultn9i6c", + name: "t3", + description: "sdfdsf", + owner: "111111", + confidential: "FALSE", + edges: + '[{"source":{"title":"testpython2","id":"nq1huz-iWizg","x":580.8966674804688,"y":187.61172485351562},"target":{"title":"sdggkkk","id":"j0uraj-lNCK0","x":897,"y":8}}]', + nodes: + '[{"title":"testpython2","id":"nq1huz-iWizg","x":580.8966674804688,"y":187.61172485351562},{"title":"sdggkkk","id":"j0uraj-lNCK0","x":897,"y":8}]', + }); + + expect(true).to.equal(true); + }); + + it("workspace", function () { + // GW.workflow.newDialog(); //this should be tested in the workspace + // if(GW.workflow.new_frame!=null) GW.workflow.new_frame.closeFrame(); + expect(true).to.equal(true); + }); + + it("history", function () { + expect(true).to.equal(true); }); - }, + // describe('with many arguments', function(){ + // it('should add the values', function(){ + // var arr = []; + // arr.push('foo', 'bar'); + // expect(arr[0]).to.equal('foo'); + // expect(arr[1]).to.equal('bar'); + // }) + // }) + // }) - initHTML: function(){ + // describe('.unshift()', function(){ + // it('should prepend a value', function(){ + // var arr = [1,2,3]; + // arr.unshift('foo'); + // expect(arr[0]).to.equal('foo'); + // expect(arr[1]).to.equal(1); + // }) - $("body").append(`