From 8bc55afa6304edc17708ab7f25068aa3f97f045f Mon Sep 17 00:00:00 2001 From: Tamas Levente Kiss <tamas.levente.kiss@ericsson.com> Date: Fri, 24 May 2019 14:48:08 +0200 Subject: [PATCH] [internal #1720434] Minor bugfixes + SVG displays Signed-off-by: Tamas Levente Kiss <tamas.levente.kiss@ericsson.com> --- htdocs/Utils/DsRestAPI/DsRestAPIComm.js | 16 +- htdocs/Utils/DsRestAPI/RequestSchema.json | 6 + htdocs/Utils/DsRestAPI/openapi.yaml | 4 + htdocs/Utils/FileHandler.js | 1 + htdocs/Utils/Utilities.js | 8 +- htdocs/WebApplicationFramework/Res/Main.css | 10 +- .../Views/View_ElementTable_blue.css | 178 ++++++++++++++++++ .../Views/View_MultipliedViewAligner.js | 8 + .../Views/View_SVGDisplay.css | 26 +++ .../Views/View_SVGDisplay.js | 126 +++++++++++++ .../Views/View_TextArea.js | 153 +++++++++++++++ .../WebApplications/CustomizableApp/Main.js | 38 +++- .../WebApplications/CustomizableApp/View.html | 2 +- .../WebApplications/CustomizableApp/View.js | 12 +- .../CustomizableApp/ViewModel.js | 107 ++++++++++- .../ViewModels/ViewModel_Condition.js | 2 +- .../ViewModels/ViewModel_ElementRelay.js | 37 +++- .../ViewModels/ViewModel_FSM_SVG.js | 128 +++++++++++++ .../ViewModels/ViewModel_Multiplier.js | 26 ++- .../ViewModels/ViewModel_SanityChecker.js | 23 +-- .../GuiEditor/Views/View_ElementEditor.js | 7 +- .../Views/View_ElementEditor.js | 7 +- 22 files changed, 873 insertions(+), 52 deletions(-) create mode 100644 htdocs/WebApplicationFramework/Views/View_ElementTable_blue.css create mode 100644 htdocs/WebApplicationFramework/Views/View_SVGDisplay.css create mode 100644 htdocs/WebApplicationFramework/Views/View_SVGDisplay.js create mode 100644 htdocs/WebApplicationFramework/Views/View_TextArea.js create mode 100644 htdocs/WebApplications/CustomizableApp/ViewModels/ViewModel_FSM_SVG.js diff --git a/htdocs/Utils/DsRestAPI/DsRestAPIComm.js b/htdocs/Utils/DsRestAPI/DsRestAPIComm.js index e610427..9741189 100644 --- a/htdocs/Utils/DsRestAPI/DsRestAPIComm.js +++ b/htdocs/Utils/DsRestAPI/DsRestAPIComm.js @@ -56,17 +56,19 @@ function CDsRestAPIComm(p_extension) { $('#cll_DsRestAPI_error').addClass("hidden"); if (data && data !== "" && data !== " ") { + var contentlist; try { - var contentlist = JSON.parse(data).contentList; - if (contentlist.length == 1 && contentlist[0].node != undefined && contentlist[0].node.val == "timeout") - { - mThis.handleError("Timeout received from server", "Overload", aHandler, end, start); - } - else - aHandler(contentlist); + contentlist = JSON.parse(data).contentList; } catch (e) { mThis.handleError("Badly encoded response received from server", e.message, aHandler, end, start); + return; } + if (contentlist.length == 1 && contentlist[0].node != undefined && contentlist[0].node.val == "timeout") + { + mThis.handleError("Timeout received from server", "Overload", aHandler, end, start); + } + else + aHandler(contentlist); } else aHandler(mNoAnswer); diff --git a/htdocs/Utils/DsRestAPI/RequestSchema.json b/htdocs/Utils/DsRestAPI/RequestSchema.json index 7ab295c..58bb5ef 100644 --- a/htdocs/Utils/DsRestAPI/RequestSchema.json +++ b/htdocs/Utils/DsRestAPI/RequestSchema.json @@ -105,6 +105,9 @@ "ptcname": { "type": "string" }, + "clientSideCache": { + "type": "boolean" + }, "element": { "type": "string" }, @@ -194,6 +197,9 @@ "ptcname": { "type": "string" }, + "clientSideCache": { + "type": "boolean" + }, "element": { "type": "string" }, diff --git a/htdocs/Utils/DsRestAPI/openapi.yaml b/htdocs/Utils/DsRestAPI/openapi.yaml index fc1a445..ecfe9f2 100644 --- a/htdocs/Utils/DsRestAPI/openapi.yaml +++ b/htdocs/Utils/DsRestAPI/openapi.yaml @@ -71,6 +71,8 @@ components: type: string ptcname: type: string + clientSideCache: + type: boolean element: type: string params: @@ -125,6 +127,8 @@ components: type: string ptcname: type: string + clientSideCache: + type: boolean element: type: string content: diff --git a/htdocs/Utils/FileHandler.js b/htdocs/Utils/FileHandler.js index 2682094..3a13066 100644 --- a/htdocs/Utils/FileHandler.js +++ b/htdocs/Utils/FileHandler.js @@ -39,6 +39,7 @@ function FileHandler() { url: url, type: 'LSDIR', success: function(aData) {callback(JSON.parse(aData).fileList.sort());}, + error: function(aData) {callback(0);}, data: "", dataType: 'text', contentType: 'text', diff --git a/htdocs/Utils/Utilities.js b/htdocs/Utils/Utilities.js index 68b463e..a996844 100644 --- a/htdocs/Utils/Utilities.js +++ b/htdocs/Utils/Utilities.js @@ -33,7 +33,7 @@ function uniq(list) { window.jsErrors = []; -if (!window.onerror) { +/*if (!window.onerror) { window.onerror = function(error, url, line, ch, ex) { "use strict"; var errorMessage = 'Error caught in global context: "{0}", URL: {1}, Line {2}, char index {3} (w/o indent, usually).'.format(error, url, line, ch); @@ -46,7 +46,7 @@ if (!window.onerror) { window.jsErrors[window.jsErrors.length] = stack; return true; // handled. }; -} +}*/ /** mpad - converts a number to string and pads it with leading zeroes */ function mpad(num, size) { @@ -295,4 +295,8 @@ function a2hex(str) { return arr.join(''); } +function replaceAt(str, index, replacement) { + return str.substr(0, index) + replacement+ str.substr(index + replacement.length); +} + //# sourceURL=Utils\Utilities.js diff --git a/htdocs/WebApplicationFramework/Res/Main.css b/htdocs/WebApplicationFramework/Res/Main.css index 6d9ce1d..09fba4d 100644 --- a/htdocs/WebApplicationFramework/Res/Main.css +++ b/htdocs/WebApplicationFramework/Res/Main.css @@ -49,10 +49,8 @@ button::-moz-focus-inner { .line { clear: both; width: 100%; - margin-top: 6px; - border-top: 1px solid #C4C4C3; - border-bottom: 1px solid #ffffff; - margin-bottom: 6px; + margin-top: 7px; + margin-bottom: 7px; } .tabs { @@ -85,9 +83,9 @@ button::-moz-focus-inner { } #webapps BUTTON, #hiddenWebapps BUTTON, #webappToggleButton { - height: 30px; + height: 26px; color: #000; - border: 2px solid #c5c5c5; + border: 0px solid #c5c5c5; background-color: #c5c5c5; text-align: center; text-decoration: none; diff --git a/htdocs/WebApplicationFramework/Views/View_ElementTable_blue.css b/htdocs/WebApplicationFramework/Views/View_ElementTable_blue.css new file mode 100644 index 0000000..856eb8e --- /dev/null +++ b/htdocs/WebApplicationFramework/Views/View_ElementTable_blue.css @@ -0,0 +1,178 @@ +.ElementTable, +.TableBlue { + font-weight: normal; + width: 100%; + height: 100%; + white-space: nowrap; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.ElementTable_HeaderBar, +.TableBlue_HeaderBar { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + width: 100%; + overflow: hidden; + padding-left: 2px; + white-space: nowrap; + /*border-bottom: 1px solid black;*/ +} + +.ElementTable_HeaderBar { + background-color: #55BAD4; +} + +.TableBlue_HeaderBar { + background-color: #6494e9; +} + +.ElementTable_HeaderBar > *, +.TableBlue_HeaderBar > * { + display: inline-block; + vertical-align: middle; + overflow: hidden; + white-space: nowrap; +} + +.ElementTable_Name{ + width: 50%; + font-weight: bold; +} + +.TableBlue_Name { + width: 50%; + font-weight: bold; +} + +.ElementTable_SearchLabel, +.TableBlue_SearchLabel { + width: 15%; + text-align: right; +} + +.ElementTable_SearchInput, +.TableBlue_SearchInput { + width: 35%; +} + +.ElementTable_TableWrapper, +.TableBlue_TableWrapper { + overflow-y: auto; +} + +.ElementTable table, +.TableBlue table { + width: 100%; +} + +.ElementTable table tr.ElementTable_Selected { + background-color: #66a19f; +} + +.TableBlue table tr.TableBlue_Selected { + background-color: #6494e9; + color: white; +} + +.ElementTable table, +.TableBlue table { + border: none; + border-collapse: collapse; +} + +.ElementTable table tr.ElementTable_Header, +.TableBlue table tr.TableBlue_Header { + border-bottom: 1px solid black; + color: black; + font-weight: bold; + /*font-size: 14px;*/ + text-align: left; + padding: 2px; +} + +.ElementTable table tr.ElementTable_Header { + background-color: #66CBE5; +} + +.TableBlue table tr.TableBlue_Header { + background-color: #6494e9; +} + +.ElementTable_Sort_No, +.ElementTable_Sort_Asc, +.ElementTable_Sort_Desc, +.TableBlue_Sort_No, +.TableBlue_Sort_Asc, +.TableBlue_Sort_Desc { + background-position: right center; + background-repeat: no-repeat; +} +.ElementTable_Sort_Asc, +.TableBlue_Sort_Asc { + background-image: url("WebApplicationFramework/Res/sort_asc.png"); +} +.ElementTable_Sort_Desc, +.TableBlue_Sort_Desc { + background-image: url("WebApplicationFramework/Res/sort_desc.png"); +} +.ElementTable_Sort_No, +.TableBlue_Sort_No { + background-image: url("WebApplicationFramework/Res/sort_both.png"); +} + +.ElementTable td, +.ElementTable th, +.TableBlue th, +.TableBlue td { + padding: 2px 2px; + font-weight: normal; +} + +.ElementTable tr:nth-child(odd) { + background-color: #D4F0F8; + color: black; +} + +.ElementTable tr.ElementTable_Odd { + background-color: #D4F0F8; +} + +.ElementTable tr:nth-child(even) { + background-color: #F2FBFD; + color: black; +} + +.ElementTable tr.ElementTable_Even { + background-color: #F2FBFD; +} + +.ElementTable tr:hover { + background-color: #0066b3; + color: white; +} + +.TableBlue tr:nth-child(odd) { + color: black; + background-color: #c5c5c5; +} + +.TableBlue tr.TableBlue_Odd { + background-color: #c5c5c5; +} + +.TableBlue tr:nth-child(even) { + color: black; + background-color: #c5c5c5; +} + +.TableBlue tr.TableBlue_Even { + background-color: #c5c5c5; +} + +.TableBlue tr:hover { + background-color: #6494e9; + color: white; +} \ No newline at end of file diff --git a/htdocs/WebApplicationFramework/Views/View_MultipliedViewAligner.js b/htdocs/WebApplicationFramework/Views/View_MultipliedViewAligner.js index a34478f..e05c64b 100644 --- a/htdocs/WebApplicationFramework/Views/View_MultipliedViewAligner.js +++ b/htdocs/WebApplicationFramework/Views/View_MultipliedViewAligner.js @@ -103,6 +103,14 @@ function CView_MultipliedViewAligner(p_viewmodels, p_mainId, p_parentId, p_data) subview.applicationCreated(); ViewUtils.applyCss(customData, id); ViewUtils.processCss(customData, parentId); + $("#" + parentId).on("click", function(a) { + + var index = $(this).index(); + if (index >= 0) { + v_dataViewmodel.select(index); + } + }); + v_multipliedSubviews.push(subview); subview.refresh(true); diff --git a/htdocs/WebApplicationFramework/Views/View_SVGDisplay.css b/htdocs/WebApplicationFramework/Views/View_SVGDisplay.css new file mode 100644 index 0000000..ad1d4b2 --- /dev/null +++ b/htdocs/WebApplicationFramework/Views/View_SVGDisplay.css @@ -0,0 +1,26 @@ +.BasicSVGDisplay, +.HeaderSVGDisplay, +.StripedSVGDisplay { + width: 100%; + height: 100%; + box-sizing: border-box; + padding-right: 5px; +} + +.StripedSVGDisplay { + background: repeating-linear-gradient(144deg, #F1F1F1, #F1F1F1 5px, #E8E8E8 5px, #E8E8E8 10px); + background: -moz-repeating-linear-gradient(144deg, #F1F1F1, #F1F1F1 5px, #E8E8E8 5px, #E8E8E8 10px); +} + +.HeaderSVGDisplay { + background-color: #bbbbbb; + /*font-size: 12px;*/ +} + +.BasicSVGDisplay > DIV, +.StripedSVGDisplay > DIV { + width: 0px; + height: 25px; + display: inline-block; + vertical-align: middle; +} \ No newline at end of file diff --git a/htdocs/WebApplicationFramework/Views/View_SVGDisplay.js b/htdocs/WebApplicationFramework/Views/View_SVGDisplay.js new file mode 100644 index 0000000..512fe7a --- /dev/null +++ b/htdocs/WebApplicationFramework/Views/View_SVGDisplay.js @@ -0,0 +1,126 @@ +// Copyright (c) 2000-2019 Ericsson Telecom AB Telecom AB // +// All rights reserved. This program and the accompanying materials are made available under the // +// terms of the Eclipse Public License v2.0 which accompanies this distribution, and is available at // +// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html // +/////////////////////////////////////////////////////////////////////////////////////////////////////// + +function CView_SVGDisplay(p_viewmodels, p_objId, p_parentId, p_data) { + "use strict"; + + /** constructor */ + var v_viewmodels = ViewUtils.getViewmodelsFromExpectedInterface(p_viewmodels, CView_SVGDisplay); + var v_viewmodel = v_viewmodels[0]; + var v_conditionViewmodel = v_viewmodels[1]; + var v_writableViewmodel = v_viewmodels[2]; + + var v_objId = p_objId; + var v_parentId = p_parentId; + var v_customData = p_data; + + var v_SVGDisplayLabel; + var v_currentSVG = ""; + + /** public functions */ + this.applicationCreated = function() { + $("#" + v_parentId).append(getHtml()); + if (v_customData.isElementLabelPresent) { + v_SVGDisplayLabel = ViewUtils.addLabel(v_objId, v_customData.elementText); + } + if (v_customData.class != undefined) { + $("#" + v_objId).addClass(v_customData.class); + } else { + $("#" + v_objId).addClass("BasicSVGDisplay"); + } + + ViewUtils.addTooltip(v_objId, v_customData); + }; + + this.refresh = function(p_fullRefresh) { + if (ViewUtils.checkVisibility(v_conditionViewmodel, v_objId) && v_viewmodel != undefined) { + var dataObject = v_viewmodel.getListWithElementInfo(); + if (v_customData.text != undefined || dataObject == undefined || dataObject.values[0] == undefined) { + return; + } + + if (p_fullRefresh && v_customData.isElementLabelPresent && v_customData.elementText == undefined) { + v_SVGDisplayLabel.text(dataObject.values[0].element); + } + + if (v_customData.text == undefined) { + var text = ""; + //console.log(dataObject) + if(dataObject.values[0].val != undefined) { + $("#" + v_objId + " > *").css("display", ""); + $("#" + v_objId).removeClass("NoData"); + text = dataObject.values[0].val; + } else { + $("#" + v_objId + " > *").css("display", "none"); + $("#" + v_objId).addClass("NoData"); + } + if (text != v_currentSVG) + { + v_currentSVG = text; + try { + var dectext = window.atob(text); + dectext = dectext.replace("style=\"", "style=\"transform:scale(0.75);"); + $("#" + v_objId).html(dectext); + } catch (e) { + text = text.replace("style=\"", "style=\"transform:scale(0.75);"); + $("#" + v_objId).html(text); + } + } + } + + if (v_customData.disabled !== true && dataObject.values[0] != undefined && dataObject.values[0].isWritable && (v_writableViewmodel == undefined || v_writableViewmodel.isWritable())) { + } else { + } + } + }; + + /** private functions */ + function getHtml() { + return '<div id="' + v_objId + '"></div>'; + } +} + +CView_SVGDisplay.getHelp = function() { + return "Simple SVG display. Expected interface: \n" + JSON.stringify(CView_SVGDisplay.expectsInterface(), null, 4); +} + +CView_SVGDisplay.expectsInterface = function() { + return [ + { + "optional": ["getListWithElementInfo"] + }, + { + "optional": ["getState"] + }, + { + "optional": ["isWritable"] + } + ]; +}; + +CView_SVGDisplay.getCustomDataSchema = function() { + var schema = { + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Custom data for CView_SVGDisplay", + "type": "object", + "properties": { + "class": { + "type": "string", + "description": "the css class of the view", + "default": "BasicSVGDisplay" + }, + "text": { + "type": "string", + "description": "the SVGDisplay text" + } + }, + "additionalProperties": false + }; + $.extend(true, schema, ViewUtils.commonViewSchema, ViewUtils.commonElementSchema); + return schema; +}; + +//# sourceURL=WebApplicationFramework\Views\View_SVGDisplay.js \ No newline at end of file diff --git a/htdocs/WebApplicationFramework/Views/View_TextArea.js b/htdocs/WebApplicationFramework/Views/View_TextArea.js new file mode 100644 index 0000000..1d575e0 --- /dev/null +++ b/htdocs/WebApplicationFramework/Views/View_TextArea.js @@ -0,0 +1,153 @@ +// Copyright (c) 2000-2019 Ericsson Telecom AB Telecom AB // +// All rights reserved. This program and the accompanying materials are made available under the // +// terms of the Eclipse Public License v2.0 which accompanies this distribution, and is available at // +// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html // +/////////////////////////////////////////////////////////////////////////////////////////////////////// +function CView_TextArea(p_viewmodels, p_mainId, p_parentId, p_data) { + "use strict"; + + /** constructor */ + + var v_viewmodels = ViewUtils.getViewmodelsFromExpectedInterface(p_viewmodels, CView_TextArea); + var v_viewmodel = v_viewmodels[0]; + var v_conditionViewmodel = v_viewmodels[1]; + var v_writableViewmodel = v_viewmodels[2]; + + var v_mainId = p_mainId; + var v_parentId = p_parentId; + var v_customData = p_data; + + var v_textArea; + var v_selected = false; + var v_currentValue = ""; + + var v_this = this; + + /** public functions */ + + this.applicationCreated = function() { + $("#" + v_parentId).append(getHtml()); + if (v_customData.isElementLabelPresent) { + v_label = ViewUtils.addLabel(v_mainId, v_customData.elementText); + } + if (v_customData.class != undefined) { + $("#" + v_mainId).addClass(v_customData.class); + } else { + $("#" + v_mainId).addClass("BasicLabel"); + } + + var lTextArea = $("#" + v_mainId + " textArea"); + + if (v_customData.disabled !== true && v_customData.text == undefined && v_viewmodel != undefined) { + lTextArea.on({ + focus: function() { + v_selected = true; + }, + blur: function() { + var newValue = $(this).val(); + if (newValue != v_currentValue) { + v_viewmodel.setValue(0, newValue); + } + v_selected = false; + }, + keydown: function(event) { + if (event.keyCode == 13) { + $(this).blur(); + } + } + }); + } + + if (v_viewmodel == undefined || v_customData.text != undefined) { + $("#" + v_mainId + " > textArea").prop('disabled', true); + } + + ViewUtils.addTooltip(v_mainId, v_customData); + }; + + this.refresh = function(p_fullRefresh) { + if (ViewUtils.checkVisibility(v_conditionViewmodel, v_mainId) && v_viewmodel != undefined) { + var dataObject = v_viewmodel.getListWithElementInfo(); + if (v_customData.text != undefined || dataObject == undefined || dataObject.values[0] == undefined) { + return; + } + + var lTextArea = $("#" + v_mainId + " textArea"); + + if (p_fullRefresh && v_customData.isElementLabelPresent && v_customData.elementText == undefined) { + v_label.text(dataObject.values[0].element); + } + + if (!v_selected && v_customData.text == undefined) { + var text = ""; + if(dataObject.values[0].val != undefined) { + $("#" + v_mainId + " > *").css("display", ""); + $("#" + v_mainId).removeClass("NoData"); + text = dataObject.values[0].val; + } else { + $("#" + v_mainId + " > *").css("display", "none"); + $("#" + v_mainId).addClass("NoData"); + } + // we need both... + lTextArea.val(text); + lTextArea[0].setAttribute('value', text); + v_currentValue = text; + } + + if (v_customData.disabled !== true && dataObject.values[0] != undefined && dataObject.values[0].isWritable && (v_writableViewmodel == undefined || v_writableViewmodel.isWritable())) { + $("#" + v_mainId + " > textArea").prop('disabled', false); + } else { + $("#" + v_mainId + " > textArea").prop('disabled', true); + } + } + }; + + /** private functions */ + + function getHtml() { + return '<div id="' + v_mainId + '">' + + '<div></div><textarea spellcheck="false" rows="50" cols="40" >' + (v_customData.text != undefined ? v_customData.text : '') + '</textarea>' + + '</div>'; + } +} + +CView_TextArea.getHelp = function() { + return "A single text area that can also be used for input."; +} + +CView_TextArea.expectsInterface = function() { + return [ + { + "optional": ["setValue", "getListWithElementInfo"] + }, + { + "optional": ["getState"] + }, + { + "optional": ["isWritable"] + } + ]; +}; + +CView_TextArea.getCustomDataSchema = function() { + var schema = { + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Custom data for CView_TextArea", + "type": "object", + "properties": { + "class": { + "type": "string", + "description": "the css class of the view", + "default": "BasicLabel" + }, + "text": { + "type": "string", + "description": "the text area text" + } + }, + "additionalProperties": false + }; + $.extend(true, schema, ViewUtils.commonViewSchema, ViewUtils.commonElementSchema); + return schema; +}; +//# sourceURL=WebApplicationFramework\Views\View_TextArea.js \ No newline at end of file diff --git a/htdocs/WebApplications/CustomizableApp/Main.js b/htdocs/WebApplications/CustomizableApp/Main.js index 509ecb7..f207795 100644 --- a/htdocs/WebApplications/CustomizableApp/Main.js +++ b/htdocs/WebApplications/CustomizableApp/Main.js @@ -1,8 +1,8 @@ -// Copyright (c) 2000-2019 Ericsson Telecom AB Telecom AB // -// All rights reserved. This program and the accompanying materials are made available under the // -// terms of the Eclipse Public License v2.0 which accompanies this distribution, and is available at // -// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html // -/////////////////////////////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2000-2019 Ericsson Telecom AB Telecom AB // +// All rights reserved. This program and the accompanying materials are made available under the // +// terms of the Eclipse Public License v2.0 which accompanies this distribution, and is available at // +// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html // +/////////////////////////////////////////////////////////////////////////////////////////////////////// /** Common functionality for applications, such as - mainLoop, - request issuing @@ -178,8 +178,31 @@ function CBinder(aViewModel, aView, aDataSourceUtils) mInterval = undefined; }; - this.notifyChange = function(aDisableViews, aFiredFromLoop) + function searchObjecForValue(obj, query) { + for (var key in obj) + { + var value = obj[key]; + if (typeof value === 'object') + return searchObjecForValue(value, query); + if (typeof value == "string" && value.startsWith(query)) + return value; + } + return false; + } + + this.notifyChange = function(aDisableViews, aFiredFromLoop, aResponseInCaseOfSetData) + { + if (aResponseInCaseOfSetData) + { + var val = searchObjecForValue(aResponseInCaseOfSetData, "GoodbyeMessage:"); + if (val) + { + mView.destroy(); + mView.displayGoodbyeMessage(val.substring(val.indexOf(':') + 1)); + mThis.stop(); + } + } function dataArrived(aData) { if (aDisableViews && mViewModel.getUIConfig().overlayEnabledOnSelect) { mView.enableViews(); @@ -224,7 +247,8 @@ function CBinder(aViewModel, aView, aDataSourceUtils) }; this.disableViews = function(aDoNotShowSpinningCircle) { - mView.disableViews(aDoNotShowSpinningCircle); + if (mRunning == ERunningState.ERunning) + mView.disableViews(aDoNotShowSpinningCircle); }; this.isRunning = function() { diff --git a/htdocs/WebApplications/CustomizableApp/View.html b/htdocs/WebApplications/CustomizableApp/View.html index edc1953..0fcb9d2 100644 --- a/htdocs/WebApplications/CustomizableApp/View.html +++ b/htdocs/WebApplications/CustomizableApp/View.html @@ -1,7 +1,7 @@ <style id="WebAppStyle" type="text/css"></style> <style id="SetupStyle" type="text/css"></style> -<div class="applications_header_class" style="position:relative;"> +<div class="applications_header_class" style="position:relative;left:160px"> <table id="ajaxstats" class="DsRestAPIStatisticsTable"> <tbody> <tr> diff --git a/htdocs/WebApplications/CustomizableApp/View.js b/htdocs/WebApplications/CustomizableApp/View.js index 23aaa36..0b1e953 100644 --- a/htdocs/WebApplications/CustomizableApp/View.js +++ b/htdocs/WebApplications/CustomizableApp/View.js @@ -167,15 +167,19 @@ function CView(a_viewModel, a_ID, a_parentID) if (aDoNotShowSpinningCircle) { html = '<div class="ui-widget-overlay ui-front" style="z-index: 1000; opacity: ' + opacity + ';"></div>'; } else { - html = '<div class="ui-widget-overlay ui-front" style="z-index: 1000; opacity: ' + opacity + ';"></div><img src="WebApplicationFramework/Res/waiting.gif" class="waitingImage">'; + html = '<div class="ui-widget-overlay ui-front" style="z-index: 1000; opacity: ' + opacity + ';"></div><center><img src="WebApplicationFramework/Res/waiting.gif" class="waitingImage"></center>'; } $(m_parentDiv).append(html); } }; - this.enableViews = function() { - $(".ui-widget-overlay").remove(); - $(".waitingImage").remove(); + this.enableViews = function() { + $(".ui-widget-overlay").remove(); + $(".waitingImage").remove(); + }; + + this.displayGoodbyeMessage = function(aMessage) { + $(m_parentDiv).html('<div style="height: 100px;"></div> <div style="height: 100px; line-height: 100px; text-align: center; font-size: 20px;background-color: #6494e9;">' + aMessage + '</div>'); }; /** private functions */ diff --git a/htdocs/WebApplications/CustomizableApp/ViewModel.js b/htdocs/WebApplications/CustomizableApp/ViewModel.js index eb69298..ba0bd56 100644 --- a/htdocs/WebApplications/CustomizableApp/ViewModel.js +++ b/htdocs/WebApplications/CustomizableApp/ViewModel.js @@ -22,6 +22,7 @@ function CViewModel(aModel, aDataSourceUtils) var mResponse; var mModel = aModel; var mThis = this; + var mRequestCache = {}; var mSelectionToChangeToValue = []; @@ -201,7 +202,7 @@ function CViewModel(aModel, aDataSourceUtils) mBinder.enableViews(); if (aCallback != undefined) aCallback(response); - mBinder.notifyChange(); + mBinder.notifyChange(false, false, response); } if (aAdditionalData == undefined) { @@ -278,6 +279,7 @@ function CViewModel(aModel, aDataSourceUtils) mViewIsDisabledBecauseConnectionWasInterrupted = false; mBinder.enableViews(); } + processStaticResponses(aResponse, mRequest, []); mResponse = aResponse; } else { mViewIsDisabledBecauseConnectionWasInterrupted = true; @@ -286,6 +288,7 @@ function CViewModel(aModel, aDataSourceUtils) } aHandler(aResponse); } + processStaticRequests(mRequest, []); mDsRestAPI.getList(mRequest, saveResponse); }; @@ -376,6 +379,24 @@ function CViewModel(aModel, aDataSourceUtils) } } + function getRequestKeyVMS(p_path) { + var key = ''; + var currentPath = []; + for (var i = 0; i < p_path.length - 1; ++i) { + currentPath.push(p_path[i]); + var request = mThis.getRequestFromPath(currentPath); + if (request.getData.selectionValues != undefined) { + key += request.getData.selectionValues + "SV_"; + } else if (request.getData.selection != undefined) { + key += request.getData.selection[0] + 'S_'; + } + } + + key += JSON.stringify(p_path) + 'P_'; + + return key; + } + function getRequestKey(p_path, p_type) { var key = ''; var currentPath = []; @@ -512,5 +533,89 @@ function CViewModel(aModel, aDataSourceUtils) p_path.pop(i); } } + + function processStaticResponses(p_contentList, p_requests, p_path, indxInList) + { + for (var i = 0; i < p_requests.length; ++i) + { + var request = p_requests[i].getData; + var response = p_contentList[i]; + p_path.push(i); + if (request.clientSideCache != undefined && request.clientSideCache) + { + var key = getRequestKeyVMS(p_path); + if (mRequestCache[key] == undefined && indxInList == undefined) + { + if (response.node != undefined && response.node.val.includes('Unhandled request')) + {} + else + mRequestCache[key] = response; + } + else if (indxInList != undefined) + { + if (mRequestCache[key] == undefined) + mRequestCache[key] = {}; + if (mRequestCache[key][indxInList] == undefined) + { + if (response.node != undefined && response.node.val.includes('Unhandled request')) + mRequestCache[key] = undefined; + else + mRequestCache[key][indxInList] = response; + } + } + + if (mRequestCache[key] != undefined) + { + if (indxInList == undefined) + p_contentList[i] = mRequestCache[key]; + else + p_contentList[i] = mRequestCache[key][indxInList]; + } + } + + if (response.node != undefined) + { + if (request.children != undefined && response.node.childVals != undefined) + processStaticResponses(response.node.childVals, request.children, p_path); + } + else if (response.list != undefined) + { + for (var j = 0; j < response.list.length; ++j) + { + var responseNode = response.list[j]; + if (responseNode.node.childVals != undefined && responseNode.node.childVals.length > 0) + processStaticResponses(responseNode.node.childVals, request.children, p_path, j); + } + } + p_path.pop(i); + } + } + + function processStaticRequests(p_requests, p_path) + { + for (var i = 0; i < p_requests.length; ++i) + { + var request = p_requests[i].getData; + p_path.push(i); + if (request.clientSideCache != undefined && request.clientSideCache) + { + var key = getRequestKeyVMS(p_path, "selection"); + if (mRequestCache[key] != undefined) + { + if (request.element != "") + { + request.StoredRqElement = request.element; + request.element = ""; + } + } + else if (request.element == "") + request.element = request.StoredRqElement; + } + + if (request.children != undefined) + processStaticRequests(request.children, p_path); + p_path.pop(i); + } + } } //# sourceURL=CustomizableApp\ViewModel.js diff --git a/htdocs/WebApplications/CustomizableApp/ViewModels/ViewModel_Condition.js b/htdocs/WebApplications/CustomizableApp/ViewModels/ViewModel_Condition.js index 4af5dac..a3d4b5a 100644 --- a/htdocs/WebApplications/CustomizableApp/ViewModels/ViewModel_Condition.js +++ b/htdocs/WebApplications/CustomizableApp/ViewModels/ViewModel_Condition.js @@ -38,7 +38,7 @@ function CViewModel_Condition(p_viewmodel, p_options) { if (response != undefined && response.node != undefined) { if (response.node.tp == 0) { returnValue = false; - } else if (response.node.tp == 3 && request.getData.filter == undefined) { + } else if ((response.node.tp == 3 || response.node.tp == -3) && request.getData.filter == undefined) { returnValue = response.node.val === "true"; } else { returnValue = true; diff --git a/htdocs/WebApplications/CustomizableApp/ViewModels/ViewModel_ElementRelay.js b/htdocs/WebApplications/CustomizableApp/ViewModels/ViewModel_ElementRelay.js index b897c16..af92ed0 100644 --- a/htdocs/WebApplications/CustomizableApp/ViewModels/ViewModel_ElementRelay.js +++ b/htdocs/WebApplications/CustomizableApp/ViewModels/ViewModel_ElementRelay.js @@ -89,6 +89,23 @@ function CViewModel_ElementRelay(aViewModel, aOptions) }; } + function getEncodedVal(aVal) + { + if (mOptions.decodeBase64) + { + try + { + return window.atob(aVal); + } + catch (e) + { + return aVal; + console.log("Base64 decode error", aVal); + } + } + else + return aVal; + } function getRow(node) { @@ -101,13 +118,15 @@ function CViewModel_ElementRelay(aViewModel, aOptions) { if (node.childVals[j].node) { - lChildren.push(node.childVals[j].node.val); + lChildren.push(getEncodedVal(node.childVals[j].node.val)); } else if (node.childVals[j].list) { var lList = []; for (var i = 0; i < node.childVals[j].list.length; ++i) - lList.push(node.childVals[j].list[i].node.val); + { + lList.push(getEncodedVal(node.childVals[j].list[i].node.val)); + } lChildren.push(lList); //console.log ("lListVM::", lList); } @@ -184,7 +203,7 @@ function CViewModel_ElementRelay(aViewModel, aOptions) lData.error = lElement.error; else if (lElement.node) { - lData.val = lElement.node.val; + lData.val = getEncodedVal(lElement.node.val); lData.isWritable = lElement.node.tp > 0; lData.children = getChildren(lElement.node, aRq.getData)[1]; } @@ -201,7 +220,7 @@ function CViewModel_ElementRelay(aViewModel, aOptions) node = lElement.list[aRq.getData.selection[0]].node; } - lData.val = node.val; + lData.val = getEncodedVal(node.val); if (aRq.getData.children) { var lChildren = getChildren(node); if (aRq.getData.children) { @@ -224,7 +243,7 @@ function CViewModel_ElementRelay(aViewModel, aOptions) var lChildList = []; for (var i = 0; i < lElement.list.length; ++i) { - lList.push(lElement.list[i].node.val); + lList.push(getEncodedVal(lElement.list[i].node.val)); var lChildren = getChildren(lElement.list[i].node); if (aRq.getData.children) { @@ -277,7 +296,13 @@ CViewModel_ElementRelay.getCustomDataSchema = function() { "showOnlySelected": { "type": "boolean", "format": "checkbox", - "description": "whther we only show the selected element from an iterator", + "description": "whether we only show the selected element from an iterator", + "default": true + }, + "decodeBase64": { + "type": "boolean", + "format": "checkbox", + "description": "if true, the returned data will be base64 decoded", "default": true } } diff --git a/htdocs/WebApplications/CustomizableApp/ViewModels/ViewModel_FSM_SVG.js b/htdocs/WebApplications/CustomizableApp/ViewModels/ViewModel_FSM_SVG.js new file mode 100644 index 0000000..38e4af7 --- /dev/null +++ b/htdocs/WebApplications/CustomizableApp/ViewModels/ViewModel_FSM_SVG.js @@ -0,0 +1,128 @@ +// Copyright (c) 2000-2019 Ericsson Telecom AB Telecom AB // +// All rights reserved. This program and the accompanying materials are made available under the // +// terms of the Eclipse Public License v2.0 which accompanies this distribution, and is available at // +// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html // +/////////////////////////////////////////////////////////////////////////////////////////////////////// + +function CViewModel_FSM_SVG(p_viewmodel, p_options) { + "use strict"; + + /** constructor */ + + var v_viewmodel = p_viewmodel; + var v_options = p_options; + var v_dataPaths = []; + var mDecodedSVGs = {}; + + /** public functions - interface for parent */ + + this.setSelectionToControl = function(p_selection) {}; + this.setBinder = function(p_binder) {}; + this.setReponseDataPath = function(p_index, p_path) { + v_dataPaths[p_index] = p_path; + }; + + /** public functions - interface for views */ + + this.getListWithElementInfo = function() { + var lValues = []; + var svgenc = v_viewmodel.getResponseElement(v_dataPaths[0]); + var state; + if (v_dataPaths[1] != undefined) + state = v_viewmodel.getResponseElement(v_dataPaths[1]); + + var lKey = getRequestKeyS(v_dataPaths[0]); + + if (svgenc != undefined) + { + if (mDecodedSVGs[lKey] == undefined) + { + try + { + mDecodedSVGs[lKey] = window.atob(svgenc.node.val); + } + catch (e) + { + console.log("svg base64 decode error", svgenc); + } + } + + var svgdec = mDecodedSVGs[lKey]; + if (svgdec != undefined) + { + var lsvgdec = mcopy(svgdec); + if (state != undefined) + { + state = state.node.val; + var activeIndx = lsvgdec.indexOf(state); + var colorindx = lsvgdec.lastIndexOf("<rect fill=\"#FEFECE\"", activeIndx); + lsvgdec = replaceAt(lsvgdec, colorindx, "<rect fill=\"#ffafaf\""); + } + lValues[0] = {val: lsvgdec}; + } + } + return {values: lValues}; + }; + + /** private functions */ + + function getRequestKeyS(p_path) { + var key = ''; + var currentPath = []; + for (var i = 0; i < p_path.length - 1; ++i) { + currentPath.push(p_path[i]); + var request = v_viewmodel.getRequestFromPath(currentPath); + if (request.getData.selectionValues != undefined) { + key += request.getData.selectionValues + "SV_"; + } else if (request.getData.selection != undefined) { + key += request.getData.selection[0] + 'S_'; + } + } + key += JSON.stringify(p_path) + 'P_'; + return key; + } +} + +CViewModel_FSM_SVG.getHelp = function() { + return "A viewmodel that can be used to display FSMs with colored active state."; +} + +CViewModel_FSM_SVG.providesInterface = function() { + return ["getListWithElementInfo"]; +}; + +CViewModel_FSM_SVG.getCustomDataSchema = function() { + return { + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Custom data for CViewModel_FSM_SVG", + "type": "object", + "properties": { + "schema": { + "description": "The json schema that the FSM SVG will use if a second data connection is not present.", + "type": "object" + } + }, + "additionalProperties": false + }; +}; + +CViewModel_FSM_SVG.expectsConnection = function() { + var dataConnections = [ + { + "valueType": ["charstringType", "octetstringType"] + }, + { + "valueType": ["charstringType"], + "optional": true + } + ]; + + var selectionConnections = []; + + return { + "dataConnections": dataConnections, + "selectionConnections": selectionConnections + }; +}; + +//# sourceURL=CustomizableApp\ViewModels\ViewModel_FSM_SVG.js \ No newline at end of file diff --git a/htdocs/WebApplications/CustomizableApp/ViewModels/ViewModel_Multiplier.js b/htdocs/WebApplications/CustomizableApp/ViewModels/ViewModel_Multiplier.js index 7408508..1ca73d4 100644 --- a/htdocs/WebApplications/CustomizableApp/ViewModels/ViewModel_Multiplier.js +++ b/htdocs/WebApplications/CustomizableApp/ViewModels/ViewModel_Multiplier.js @@ -13,14 +13,17 @@ function CViewModel_Multiplier(p_viewmodel, p_options) { var v_binder; var v_dataPaths = []; - + var v_selections = []; + var v_currentBundle = []; var v_this = this; /** public functions - interface for parent */ - this.setSelectionToControl = function() {}; + this.setSelectionToControl = function(p_selection) { + v_selections.push(p_selection); + }; this.setReponseDataPath = function(p_index, p_path) { v_dataPaths[p_index] = p_path; @@ -32,6 +35,15 @@ function CViewModel_Multiplier(p_viewmodel, p_options) { /** public functions - interface for views */ + this.select = function(p_index) { + for (var i = 0; i < v_selections.length; ++i) { + v_viewmodel.select(v_selections[i], p_index); + } + if (v_selections.length > 0) { + v_binder.notifyChange(true); + } + }; + this.getViewmodelBundle = function() { var response = v_viewmodel.getResponseElement(v_dataPaths[0]); var numberOfBundles = 0; @@ -207,8 +219,14 @@ CViewModel_Multiplier.expectsConnection = function() { } ]; - var selectionConnections = []; - + var selectionConnections = [ + { + "dataElementOfDataConnection": 0, + "multiple": true, + "optional": true + } + ]; + return { "dataConnections": dataConnections, "selectionConnections": selectionConnections diff --git a/htdocs/WebApplications/GuiEditor/ViewModels/ViewModel_SanityChecker.js b/htdocs/WebApplications/GuiEditor/ViewModels/ViewModel_SanityChecker.js index 99151a7..bebc980 100644 --- a/htdocs/WebApplications/GuiEditor/ViewModels/ViewModel_SanityChecker.js +++ b/htdocs/WebApplications/GuiEditor/ViewModels/ViewModel_SanityChecker.js @@ -281,20 +281,21 @@ function GuiEditor_SanityChecker_ViewModel(p_model, p_parent) { var bestIndex; var bestScore = 0; var source = request.getData.source; - for (var i = 0; i < v_help.sources.length; ++i) { - if (v_help.sources[i].source == source) { - for (var j = 0; j < v_help.sources[i].dataElements.length; ++j) { - var score = isCorrectElementForRequest(v_help.sources[i].dataElements[j].dataElement, request); - if (score > bestScore) { - result = { - "index": j, - "dataElement": v_help.sources[i].dataElements[j].dataElement - }; - bestScore = score; + if (v_help) + for (var i = 0; i < v_help.sources.length; ++i) { + if (v_help.sources[i].source == source) { + for (var j = 0; j < v_help.sources[i].dataElements.length; ++j) { + var score = isCorrectElementForRequest(v_help.sources[i].dataElements[j].dataElement, request); + if (score > bestScore) { + result = { + "index": j, + "dataElement": v_help.sources[i].dataElements[j].dataElement + }; + bestScore = score; + } } } } - } if (bestScore == 0) { result = { diff --git a/htdocs/WebApplications/GuiEditor/Views/View_ElementEditor.js b/htdocs/WebApplications/GuiEditor/Views/View_ElementEditor.js index a160496..673063f 100644 --- a/htdocs/WebApplications/GuiEditor/Views/View_ElementEditor.js +++ b/htdocs/WebApplications/GuiEditor/Views/View_ElementEditor.js @@ -97,7 +97,8 @@ function GuiEditor_ElementEditor_View(p_viewmodel, p_parentId, p_viewId, p_paren v_request.getData.source = newRequest.source; v_request.getData.element = newRequest.element; v_parentView.requestRenamed(v_path, newRequest.element); - v_request.getData.ptcname = newRequest.ptcname; + v_request.getData.ptcname = newRequest.ptcname; + v_request.getData.clientSideCache = newRequest.clientSideCache; v_request.getData.params = newRequest.params; v_request.getData.selection = newRequest.selection; v_request.getData.selectionValues = newRequest.selectionValues; @@ -126,6 +127,10 @@ function ElementEditorViewmodel(p_data, p_save) { "ptcname": { "description": "The ptc name", "type": "string" + }, + "clientSideCache": { + "description": "Set to true, the data is get only once from the server.", + "type": "boolean" }, "params": { "type": "array", diff --git a/htdocs/WebApplications/RequestConsole/Views/View_ElementEditor.js b/htdocs/WebApplications/RequestConsole/Views/View_ElementEditor.js index 911985b..738b597 100644 --- a/htdocs/WebApplications/RequestConsole/Views/View_ElementEditor.js +++ b/htdocs/WebApplications/RequestConsole/Views/View_ElementEditor.js @@ -101,7 +101,8 @@ function RequestConsole_ElementEditor_View(p_viewmodel, p_parentId, p_viewId, p_ v_request[lGetOrSetData].source = newRequest.source; v_request[lGetOrSetData].element = newRequest.element; v_parentView.requestRenamed(v_path, newRequest.element); - v_request[lGetOrSetData].ptcname = newRequest.ptcname; + v_request[lGetOrSetData].ptcname = newRequest.ptcname; + v_request[lGetOrSetData].clientSideCache = newRequest.clientSideCache; v_request[lGetOrSetData].params = newRequest.params; v_request[lGetOrSetData].selection = newRequest.selection; v_request[lGetOrSetData].selectionValues = newRequest.selectionValues; @@ -222,6 +223,10 @@ function ElementEditorViewmodel(p_data, p_save, p_request) { "ptcname": { "description": "The ptc name", "type": "string" + }, + "clientSideCache": { + "description": "Set to true, the data is get only once from the server.", + "type": "boolean" }, "params": { "type": "array", -- GitLab