Skip to content

Commit 791b504

Browse files
authored
UI - Fixes & Improvements from M20 Demo (#170)
* Fix deployments download * Add "none" to process table if no in/out vars * Fix state for "Show stats for last ..." * Fix null exception for input variables * Fix error where worker status was opposite * Update default order on proc page * Update model to include more examples of imgs * Fix deleting process resulting in ajax error * When model is suspended, grey out line * Process details table now changes size * Adjust sizing * Add message re: popup permission for open all * Moved output var to local filter * Make default for logs page to be "ERROR" * Search on enter key press * Add support for image urls, other file support * Update to add support for other files, image urls * Only show input vars (not vars during proc run) * Update nested table on logs - make same font size * Make hide all suspended processes check stateful * Make warning hidden by default * Add 3-way toggle: show all, log lines only, no log * Update input var detection * Add copy button to long stderr/stdout * Searchbuilder is now encoded in url * Update history test to be compat. with new btns * Update caching behavior * Update test model with relative paths
1 parent 6c175c7 commit 791b504

File tree

15 files changed

+479
-186
lines changed

15 files changed

+479
-186
lines changed

cws-service/src/main/java/jpl/cws/controller/RestService.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -815,18 +815,18 @@ public ModelAndView validateAndSaveSnippets(
815815
throw new Exception(restCallResult.getResponse());
816816
}
817817

818-
response.setStatus(HttpServletResponse.SC_OK);
819-
820-
return new JsonResponse(JsonResponse.Status.SUCCESS, restCallResult.getResponse()).toString();
818+
String strResponse = "{\"status\": \"SUCCESS\"}";
819+
820+
return strResponse;
821821
}
822822
catch (Exception e) {
823823

824824
String message = "A problem occurred while trying to delete log data (url=" + urlString + ", data=" + data + ", error=" + e.getMessage() + ")";
825825
log.error(message, e);
826-
827-
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
828-
829-
return new JsonResponse(JsonResponse.Status.FAIL, e.getMessage()).toString();
826+
827+
String strResponse = "{\"status\": \"ERROR\"}";
828+
829+
return strResponse;
830830
}
831831
}
832832

cws-service/src/main/java/jpl/cws/service/CwsConsoleService.java

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -611,31 +611,43 @@ public Map<String, String> getInputVariablesForProcess(String processInstanceId)
611611
if (varType == null || !varType.equals("file")) {
612612
Object objValue = historicVariableInstance.getValue();
613613
if (objValue == null) {
614-
inputVarMap.put(varName + " (" + varType + ")", null);
614+
inputVarMap.put("[" + historicVariableInstance.getCreateTime().toString() + "]" + varName + " (" + varType + ")", null);
615615
} else {
616616
String varValue = historicVariableInstance.getValue().toString();
617-
inputVarMap.put(varName + " (" + varType + ")", varValue);
617+
inputVarMap.put("[" + historicVariableInstance.getCreateTime().toString() + "]" + varName + " (" + varType + ")", varValue);
618618
}
619619
} else {
620620
//the variable is a file.
621-
//we need to get the file name and the contents of the file and put them in the outputVarMap
621+
//we need to get the file name and the contents of the file and put them in the inputVarMap
622622
TypedValue typedValue = historicVariableInstance.getTypedValue();
623623
if (typedValue instanceof FileValue) {
624624
FileValue fileValue = (FileValue) typedValue;
625625
String fileName = fileValue.getFilename();
626626
String mimeType = fileValue.getMimeType();
627-
if (mimeType.contains("image")) {
627+
if (mimeType != null) {
628+
if (mimeType.contains("image")) {
629+
InputStream fileInputStream = fileValue.getValue();
630+
String encodedString = "data:" + mimeType + ";base64, ";
631+
try {
632+
byte[] sourceBytes = IOUtils.toByteArray(fileInputStream);
633+
encodedString += Base64.getEncoder().encodeToString(sourceBytes);
634+
} catch (IOException e) {
635+
log.error("Error converting image to Base64");
636+
}
637+
inputVarMap.put("[" + historicVariableInstance.getCreateTime().toString() + "]" + varName + " (" + varType + ", " + mimeType + ")", encodedString);
638+
} else {
639+
inputVarMap.put("[" + historicVariableInstance.getCreateTime().toString() + "]" + varName + " (" + varType + ")", fileName);
640+
}
641+
} else {
628642
InputStream fileInputStream = fileValue.getValue();
629-
String encodedString = "data:" + mimeType + ";base64, ";
643+
String encodedString = "";
630644
try {
631645
byte[] sourceBytes = IOUtils.toByteArray(fileInputStream);
632646
encodedString += Base64.getEncoder().encodeToString(sourceBytes);
633647
} catch (IOException e) {
634-
throw new RuntimeException(e);
648+
log.error("Error converting file to Base64");
635649
}
636-
inputVarMap.put(varName + " (" + varType + ", image)", encodedString);
637-
} else {
638-
inputVarMap.put(varName + " (" + varType + ")", fileName);
650+
inputVarMap.put("[" + historicVariableInstance.getCreateTime().toString() + "]" + varName + "(" + varType + ") {" + fileName + "}", encodedString);
639651
}
640652
}
641653
}
@@ -683,15 +695,22 @@ public Map<String, String> getOutputVariablesForProcess(String processInstanceId
683695
byte[] sourceBytes = IOUtils.toByteArray(fileInputStream);
684696
encodedString += Base64.getEncoder().encodeToString(sourceBytes);
685697
} catch (IOException e) {
686-
throw new RuntimeException(e);
698+
log.error("Error converting image to Base64");
687699
}
688700
outputVarMap.put(varName + " (" + varType + ", " + mimeType + ")", encodedString);
689701
} else {
690702
outputVarMap.put(varName + " (" + varType + ")", fileName);
691703
}
692704
} else {
693-
log.error("PROCESSES PAGE: Encountered an error when trying to detect the mime type of an image. Did you add a mimeType to the file when creating it?");
694-
outputVarMap.put(varName + "(" + varType + ")", "ERROR: File does not have a mime type.");
705+
InputStream fileInputStream = fileValue.getValue();
706+
String encodedString = "";
707+
try {
708+
byte[] sourceBytes = IOUtils.toByteArray(fileInputStream);
709+
encodedString += Base64.getEncoder().encodeToString(sourceBytes);
710+
} catch (IOException e) {
711+
log.error("Error converting file to Base64");
712+
}
713+
outputVarMap.put(varName + "(" + varType + ") {" + fileName + "}", encodedString);
695714
}
696715
}
697716
}

cws-test/src/test/java/jpl/cws/test/integration/ui/HistoryTestIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public void runResultsTest() throws IOException {
8282

8383
findOnPage("CWS - History");
8484

85-
WebElement hideLineCheckbox = findElByXPath("//input[@id='hide-log-lines-checkbox']");
85+
WebElement hideLineCheckbox = findElByXPath("//input[@id='showall']");
8686
waitForElement(hideLineCheckbox);
8787

8888
sleep(10000);

cws-ui/src/main/webapp/css/deployments.css

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,16 +195,15 @@
195195
justify-content: flex-start;
196196
align-content: space-between;
197197
align-items: center;
198-
gap: 15px;
199198
}
200199

201200
.proc-name-btns {
202201
display: flex;
203-
flex-direction: column;
202+
flex-direction: row;
204203
justify-content: center;
205204
align-items: stretch;
206205
align-content: space-between;
207-
gap: 5px;
206+
gap: 10px;
208207
}
209208

210209
.status-div-flex {
@@ -218,5 +217,9 @@
218217
}
219218

220219
.glyphicon-pause {
221-
scale: 1.5;
220+
scale: 1.25;
221+
}
222+
223+
.disabled td {
224+
font-style: italic;
222225
}

cws-ui/src/main/webapp/css/history.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,8 @@ summary {
7373
align-self: start;
7474
margin-top: auto;
7575
margin-bottom: auto;
76+
}
77+
78+
#logDataNest {
79+
font-size: 95%;
7680
}
Lines changed: 30 additions & 0 deletions
Loading

install/cws-ui/deployments.ftl

Lines changed: 69 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,9 @@
264264
refreshing = true;
265265
//grab the value here so we don't have to do it multiple times
266266
var statsCookieValue = parseInt(localStorage.getItem(lastNumHoursVar));
267+
if (statsCookieValue == -1) {
268+
statsCookieValue = null;
269+
}
267270
268271
$.ajax({
269272
url: "/${base}/rest/stats/processInstanceStatsJSON",
@@ -371,17 +374,30 @@
371374
$("#process-table").DataTable({
372375
columns: [
373376
{
374-
data: { id: "id", key: "key" },
377+
data: { suspended: "suspended", id: "id", key: "key" },
375378
render: function(data, type) {
376379
if (type !== 'display') {
377-
return "";
380+
return data.id;
378381
} else {
379-
return `<div class="proc-name-btns">`
380-
+ `<a href="/${base}/modeler?procDefKey=` + data.key + `" target="_blank">`
382+
383+
var returnVal = `<div class="proc-name-btns">`;
384+
if (data.suspended == "true") {
385+
returnVal += `<a id="btn-suspend-` + data.key + `" data-proc-id="` + data.key + `" onClick="resumeProcDef('` + data.id + `', '` + data.key + `')">`
386+
+ `<span style="cursor: pointer; float: right; color: green;" id="suspend-`
387+
+ data.key + `" class="glyphicon glyphicon-play"></span></a>`;
388+
} else {
389+
returnVal += `<a id="btn-suspend-` + data.key + `" data-proc-id="` + data.key + `" onClick="suspendProcDef('` + data.id + `', '` + data.key + `')">`
390+
+ `<span style="cursor: pointer; float: right; color: #d9534f;" id="suspend-`
391+
+ data.key + `" class="glyphicon glyphicon-pause"></span></a>`;
392+
}
393+
394+
returnVal += `<a href="/${base}/modeler?procDefKey=` + data.key + `" target="_blank">`
381395
+ `<span style="float: right;" id="edit-` + data.key + `" class="glyphicon glyphicon-pencil"></span></a>`
382-
+ `<a data-proc-key="` + data.key + `" onClick="handleDeleteProcDef('` + data.key + `')"><span style="cursor: pointer; float: right; color: #d9534f; padding-left: 7;" id="delete-`
383-
+ data.key + `" class="glyphicon glyphicon-remove-sign"></span></a>`
384-
+ `</div>`;
396+
+ `<a data-proc-key="` + data.key + `" onClick="handleDeleteProcDef('` + data.key + `')"><span style="cursor: pointer; float: right; color: #d9534f;" id="delete-`
397+
+ data.key + `" class="glyphicon glyphicon-trash"></span></a>`;
398+
399+
returnVal += `</div>`;
400+
return returnVal;
385401
}
386402
}
387403
},
@@ -439,7 +455,7 @@
439455
}
440456
},
441457
{
442-
data: { suspended: "suspended", key: "key", id: "id" },
458+
data: { suspended: "suspended", key: "key" },
443459
render: function (data, type) {
444460
if (type !== 'display') {
445461
if (data.suspended === "true") {
@@ -452,16 +468,10 @@
452468
var status = "";
453469
var html = "";
454470
if (data.suspended == "true") {
455-
html = `<div class="status-div-flex"><div class="pause-btn-div"><a id="btn-suspend-` + data.key + `" data-proc-id="` + data.key + `" onClick="resumeProcDef('` + data.id + `', '` + data.key + `')">`
456-
+ `<span style="cursor: pointer; float: right; padding-left: 7; color: green;" id="suspend-`
457-
+ data.key + `" class="glyphicon glyphicon-play"></span></a></div>`
458-
+ `<div class="status-div-text" id="status-txt-` + data.key + `">Suspended</div></div>`;
471+
html =`<div class="status-div-text" id="status-txt-` + data.key + `"><i style="color: dimgray;">Suspended</i></div>`;
459472
}
460473
else {
461-
html = `<div class="status-div-flex"><div class="pause-btn-div"><a id="btn-suspend-` + data.key + `" data-proc-id="` + data.key + `" onClick="suspendProcDef('` + data.id + `', '` + data.key + `')">`
462-
+ `<span style="cursor: pointer; float: right; padding-left: 7; color: #d9534f;" id="suspend-`
463-
+ data.key + `" class="glyphicon glyphicon-pause"></span></a></div>`
464-
+ `<div class="status-div-text" id="status-txt-` + data.key + `">Active</div></div>`;
474+
html = `<div class="status-div-text" id="status-txt-` + data.key + `">Active</div></div>`;
465475
}
466476
return html;
467477
}
@@ -510,6 +520,7 @@
510520
}
511521
}
512522
],
523+
rowId: "key",
513524
columnDefs: [
514525
{ orderable: false, targets: 0},
515526
{ orderable: false, targets: 6 },
@@ -539,10 +550,37 @@
539550
if ($(this).prop("checked")) {
540551
$("#process-table").DataTable().column(5).search("Active", false, true).draw();
541552
localStorage.setItem(hideSuspendedProcVar, "1");
553+
refreshStats();
542554
}
543555
else {
544556
$("#process-table").DataTable().column(5).search("").draw();
557+
localStorage.setItem(hideSuspendedProcVar, "0");
558+
refreshStats();
545559
}
560+
$("#process-table").DataTable().rows().every(function () {
561+
$("#process-table").DataTable().rows().every( function (rowIdx, tableLoop, rowLoop) {
562+
var status = this.data()["suspended"];
563+
var procDefKey = this.data()["key"];
564+
var procDefId = this.data()["id"];
565+
if (status == "false") {
566+
$("#suspend-" + procDefKey).removeClass("glyphicon-play");
567+
$("#suspend-" + procDefKey).addClass("glyphicon-pause");
568+
$("#suspend-" + procDefKey).css("color", "#d9534f");
569+
$("#btn-suspend-" + procDefKey).attr("onclick", "suspendProcDef('" + procDefId + "', '" + procDefKey + "')");
570+
$("#status-txt-" + procDefKey).html("Active");
571+
$("#" + procDefKey).removeClass("disabled");
572+
$("#pv-" + procDefKey).removeClass("disabled");
573+
} else {
574+
$("#suspend-" + procDefKey).removeClass("glyphicon-pause");
575+
$("#suspend-" + procDefKey).addClass("glyphicon-play");
576+
$("#suspend-" + procDefKey).css("color", "green");
577+
$("#btn-suspend-" + procDefKey).attr("onclick", "resumeProcDef('" + procDefId + "', '" + procDefKey + "')");
578+
$("#status-txt-" + procDefKey).html("Suspended");
579+
$("#" + procDefKey).addClass("disabled");
580+
$("#pv-" + procDefKey).addClass("disabled");
581+
}
582+
});
583+
});
546584
});
547585
548586
if (parseInt(localStorage.getItem(hideSuspendedProcVar)) == 0) {
@@ -684,6 +722,8 @@
684722
$("#suspend-" + procDefKey).css("color", "green");
685723
$("#btn-suspend-" + procDefKey).attr("onclick", "resumeProcDef('" + procDefId + "', '" + procDefKey + "')");
686724
$("#status-txt-" + procDefKey).html("Suspended");
725+
$("#" + procDefKey).addClass("disabled");
726+
$("#pv-" + procDefKey).addClass("disabled");
687727
},
688728
error: function(data) {
689729
console.log("error suspending");
@@ -708,6 +748,8 @@
708748
$("#suspend-" + procDefKey).css("color", "#d9534f");
709749
$("#btn-suspend-" + procDefKey).attr("onclick", "suspendProcDef('" + procDefId + "', '" + procDefKey + "')");
710750
$("#status-txt-" + procDefKey).html("Active");
751+
$("#" + procDefKey).removeClass("disabled");
752+
$("#pv-" + procDefKey).removeClass("disabled");
711753
},
712754
error: function(data) {
713755
console.log("error activating");
@@ -786,7 +828,7 @@
786828
<option value="72">Show stats for last 3 Days</option>
787829
<option value="168">Show stats for last 1 Week</option>
788830
<option value="336">Show stats for last 2 Weeks</option>
789-
<option value="null">Show stats for All Time</option>
831+
<option value="-1">Show stats for All Time</option>
790832
</select>
791833
</div>
792834
</div>
@@ -1041,7 +1083,7 @@
10411083
});
10421084
10431085
$("#stats-last-num-hours").on('change', function () {
1044-
lastNumHours = parseInt($(this).val()) | null;
1086+
lastNumHours = parseInt($(this).val());
10451087
localStorage.setItem(lastNumHoursVar, lastNumHours.toString());
10461088
refreshStats();
10471089
});
@@ -1111,25 +1153,23 @@
11111153
11121154
dt.rows().every(function (rowIdx, tableLoop, rowLoop) {
11131155
var thisModelJson = {};
1114-
var modelName = this.data()[0].replace(/<a.*?>/g, '');
1115-
modelName = modelName.substring(0, modelName.indexOf("</a>"));
1116-
1117-
var modelId = this.data()[1];
1156+
this.data().get
1157+
var modelName = this.data()["name"];
1158+
console.log(this.data());
1159+
var modelId = this.data()["key"];
11181160
//modelId = modelId.substring(modelId.indexOf("id=\"") + 4);
11191161
//modelId = modelId.substring(0, modelId.indexOf("\""));
11201162
1121-
var version = this.data()[2];
1163+
var version = this.data()["version"];
11221164
1123-
var status = this.data()[4];
1124-
//check if active is in str
1125-
if (status.indexOf("active") > -1) {
1126-
status = "active";
1165+
if (this.data["suspended"] == "true") {
1166+
status = "Suspended";
11271167
}
11281168
else {
1129-
status = "inactive";
1169+
status = "Active";
11301170
}
11311171
1132-
var hasAssignedWorkers = $("#pv-" + modelId).hasClass("btn-danger") ? "false" : "true";
1172+
var hasAssignedWorkers = !$("#pv-" + modelId).hasClass("btn-danger");
11331173
11341174
var statPending = 0;
11351175
var statDisabled = 0;

0 commit comments

Comments
 (0)