Merge "[master] IFrame view added, minor fixes in rangeFilter handling - WebGUI_Improvements"
diff --git a/htdocs/Utils/Utilities.js b/htdocs/Utils/Utilities.js
index eea9d4f..23d7f60 100644
--- a/htdocs/Utils/Utilities.js
+++ b/htdocs/Utils/Utilities.js
@@ -1,8 +1,8 @@
-// Copyright (c) 2000-2017 Ericsson Telecom AB //
-// All rights reserved. This program and the accompanying materials are made available under the //
-// terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at //
-// http://www.eclipse.org/legal/epl-v10.html //
-///////////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2017 Ericsson Telecom AB //
+// All rights reserved. This program and the accompanying materials are made available under the //
+// terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at //
+// http://www.eclipse.org/legal/epl-v10.html //
+///////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* printf() clone - String.prototype.format(formatStr, args...)
@@ -245,6 +245,38 @@
return undefined;
}
+// No modification if ip has http prefix and no port is given.
+// Adds http prefix if there isn't one.
+// Joins ip and port if both are given.
+// If there is an url with a trailing slash and a port is given, the trailing slash will be removed and the port will be added on.
+// If relativeURL is true, current hostname and port is used as the base address
+function urlifier(ip, port, relativeURL) {
+ var httpPrefix = 'http://';
+ if (ip == undefined) {
+ ip = '';
+ }
+ if (ip != '' && relativeURL != undefined && relativeURL == true) {
+ currentAddress=window.location.hostname;
+ if (window.location.port != undefined && window.location.port != '') {
+ currentAddress = currentAddress + ":" + window.location.port;
+ }
+ ip = currentAddress + '/' + ip;
+ port=undefined;
+ }
+ if (ip != '' && ip.substr(0, httpPrefix.length).toLowerCase() !== httpPrefix) {
+ ip = httpPrefix + ip;
+ }
+ if (port != undefined) {
+ port = ':' + port;
+ if (ip.substr(ip.length - 1) === '/') {
+ ip = ip.substring(0, ip.length - 1);
+ }
+ } else {
+ port = '';
+ }
+ return ip + port;
+}
+
// string.encode("hex")
function hex2a(hex) {
var str = '';
diff --git a/htdocs/WebApplicationFramework/Views/View_Iframe.js b/htdocs/WebApplicationFramework/Views/View_Iframe.js
new file mode 100644
index 0000000..7e90e66
--- /dev/null
+++ b/htdocs/WebApplicationFramework/Views/View_Iframe.js
@@ -0,0 +1,100 @@
+function CView_Iframe(p_viewmodels, p_mainId, p_parentId, p_data) {
+ "use strict";
+
+ /** constructor */
+
+ var v_mainId = p_mainId;
+ var v_parentId = p_parentId;
+ var v_customData = p_data;
+
+ var v_viewmodel = ViewUtils.getViewmodelsFromExpectedInterface(p_viewmodels, CView_Iframe)[0];
+ var v_conditionViewmodel = ViewUtils.getViewmodelsFromExpectedInterface(p_viewmodels, CView_Iframe)[1];
+
+ var v_currentUrl = urlifier(v_customData.ip, v_customData.port, v_customData.relativeURL);
+ var v_this = this;
+
+ /** public functions */
+
+ this.applicationCreated = function() {
+ $("#" + v_parentId).append(getHtml());
+ if (v_customData.isElementLabelPresent) {
+ ViewUtils.addLabel(v_mainId, v_customData.elementText);
+ }
+ if (v_customData.class != undefined) {
+ $("#" + v_mainId).addClass(v_customData.class);
+ }
+ };
+
+ this.refresh = function() {
+ if (ViewUtils.checkVisibility(v_conditionViewmodel, v_mainId) && v_viewmodel != undefined && v_viewmodel.getList() != undefined) {
+ var dataObject = v_viewmodel.getList().values;
+ var vl_ip;
+ if (dataObject == undefined || dataObject[0] == undefined) {
+ return;
+ }
+ if (dataObject.length>0 && dataObject[0].length>0 && dataObject[0][0].length>0) {
+ vl_ip = dataObject[0][0][0];
+ }
+ var vl_port;
+ if (dataObject.length>1 && dataObject[1].length>0 && dataObject[1][0].length>0) {
+ vl_port=dataObject[1][0][0]
+ }
+ var refreshedUrl = urlifier(vl_ip, vl_port, v_customData.relativeURL);
+
+ if (v_currentUrl != refreshedUrl) {
+ v_currentUrl = refreshedUrl;
+ $("#" + v_mainId).replaceWith(getHtml());
+ }
+ }
+ };
+
+ /** private functions */
+
+ function getHtml() {
+ return '<iframe id="' + v_mainId + '" src="' + v_currentUrl + '"></iframe>';
+ }
+}
+
+CView_Iframe.getHelp = function() {
+ return "An iframe element. Any kind of locally avaliable url can be inserted as an iframe, by using a list input with the ip or url as the first member and port as optional second member.";
+}
+
+CView_Iframe.expectsInterface = function() {
+ return [
+ {
+ "optional": ["getList"]
+ }
+ ];
+};
+
+CView_Iframe.getCustomDataSchema = function() {
+ var schema = {
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "title": "Custom data for CView_Iframe",
+ "type": "object",
+ "properties": {
+ "class": {
+ "type": "string",
+ "description": "the css class of the iframe"
+ },
+ "ip": {
+ "type": "string",
+ "description": "the address (ip or url) of the iframe"
+ },
+ "port": {
+ "type": "string",
+ "description": "the optional port of the iframe"
+ },
+ "relativeURL": {
+ "description": "If true: current address is used as the base URL. Effective only when ip/port is not specified (default true)",
+ "type": "boolean",
+ "format": "checkbox",
+ "default": true
+ }
+ },
+ "additionalProperties": false
+ };
+ $.extend(true, schema, ViewUtils.commonViewSchema, ViewUtils.commonElementLabelSchema);
+ return schema;
+};
+//# sourceURL=WebApplicationFramework\Views\View_Iframe.js
\ No newline at end of file
diff --git a/htdocs/WebApplicationFramework/Views/View_ValueScale.css b/htdocs/WebApplicationFramework/Views/View_ValueScale.css
new file mode 100644
index 0000000..bec4898
--- /dev/null
+++ b/htdocs/WebApplicationFramework/Views/View_ValueScale.css
@@ -0,0 +1,4 @@
+.ValueScale svg {
+ width: 100%;
+ height: 100%;
+}
diff --git a/htdocs/WebApplicationFramework/Views/View_ValueScale.js b/htdocs/WebApplicationFramework/Views/View_ValueScale.js
new file mode 100644
index 0000000..9350bba
--- /dev/null
+++ b/htdocs/WebApplicationFramework/Views/View_ValueScale.js
@@ -0,0 +1,177 @@
+function CView_ValueScale(p_viewmodels, p_mainId, p_parentId, p_data) {
+ "use strict";
+
+ /** constructor */
+
+ var v_mainId = p_mainId;
+ var v_parentId = p_parentId;
+ var v_customData = p_data;
+
+ var defaultData = {
+ stroke : "#4CAF50",
+ strokeWidth : 7,
+ radius : 28
+ }
+ if (v_customData.minimumValue == undefined) {
+ v_customData.minimumValue = 0;
+ }
+ if (v_customData.maximumValue == undefined) {
+ v_customData.maximumValue = 100;
+ }
+ if (v_customData.yellowZone == undefined) {
+ v_customData.yellowZone = 60;
+ }
+ if (v_customData.redZone == undefined) {
+ v_customData.redZone = 80;
+ }
+
+ var v_viewmodel = ViewUtils.getViewmodelsFromExpectedInterface(p_viewmodels, CView_ValueScale)[0];
+ var v_this = this;
+
+ /** public functions */
+
+ this.applicationCreated = function() {
+ $("#" + v_parentId).append(getHtml());
+ if (v_customData.isElementLabelPresent) {
+ ViewUtils.addLabel(v_mainId, v_customData.elementText);
+ }
+ if (v_customData.class != undefined) {
+ $("#" + v_mainId).addClass(v_customData.class);
+ } else {
+ $("#" + v_mainId).addClass("ValueScale");
+ }
+
+ };
+
+ this.refresh = function() {
+ if (v_viewmodel != undefined) {
+ var list = v_viewmodel.getList();
+ list.values[0][0] = (list.values[0][0]) / 100 * Math.random() + 20;
+ updateCircle(list.values[0][0]);
+ }
+ };
+
+ /** private functions */
+
+ function getHtml() {
+ return '<div id="' + v_mainId + '"><svg><path fill="none"' + defaultData.stroke + '" stroke-width="' + defaultData.strokeWidth + '"></path><text class="scalePercentage" x="0" y="21" fill="black"></text></svg><label class="scaleText"></label></div>';
+ }
+
+ function updateCircle(value) {
+ var percent = getPercetageFromValue(value);
+ $("#" + v_mainId + " path").attr("d", getArc(percent));
+ $("#" + v_mainId + " path").attr("stroke", calculateColor(percent));
+ if (isNaN(percent)) {
+ $("#" + v_mainId + " .scalePercentage").text("--%");
+ } else {
+ $("#" + v_mainId + " .scalePercentage").text(Math.floor(percent) + "%");
+ var currentWidth = $("#" + v_mainId).width() / 2 - 12;
+ $("#" + v_mainId + " text").attr("x", currentWidth);
+ }
+ }
+
+ function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
+ var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;
+
+ return {
+ x: centerX + (radius * Math.cos(angleInRadians)),
+ y: centerY + (radius * Math.sin(angleInRadians))
+ };
+ }
+
+ function getPercetageFromValue(value) {
+ var maxValue = v_customData.maximumValue;
+ if (v_customData.maximumValue > v_customData.minimumValue && v_customData.minimumValue >= 0 && v_customData.maximumValue >= 0 && v_customData.maximumValue >= value && v_customData.minimumValue <= value) {
+ value = value - v_customData.minimumValue;
+ maxValue = maxValue - v_customData.minimumValue
+ return (value / maxValue) * 100;
+ }
+ }
+
+ function getArc(percent){
+ if (percent == 100.0) {
+ percent = 99.99;
+ }
+
+ var radius = defaultData.radius;
+ var startAngle = -60;
+ var endAngle = 240.0 * percent / 100.0 / 2 - 60;
+
+ var centerY = 33;
+ var centerX = $("#" + v_mainId).width() / 2;
+
+ var start = polarToCartesian(centerX, centerY, radius, endAngle);
+ var end = polarToCartesian(centerX, centerY, radius, startAngle);
+
+ var arcSweep = endAngle - startAngle <= 180 ? "0" : "1";
+ var d = [
+ "M", start.x, start.y,
+ "A", radius, radius, 0, arcSweep, 0, end.x, end.y
+ ].join(" ");
+
+ return d;
+ }
+
+ function calculateColor(percent){
+ var color;
+ if (percent != undefined) {
+ color = "#4CAF50";
+ if (percent > v_customData.redZone) {
+ color = "#DC143C";
+ } else if (percent > v_customData.yellowZone) {
+ color = "#FFD700";
+ }
+ }
+ return color;
+ }
+}
+
+CView_ValueScale.getHelp = function() {
+ return "A value scale view. Requires a list whose first element is a percentage. Optionally, non percentage numbers can be given, but minimum and maximum range should be defined in custom data. Defaults are minimum 0 and maximum 100.";
+}
+
+CView_ValueScale.expectsInterface = function() {
+ return [
+ {
+ "mandatory": ["getList"]
+ }
+ ];
+};
+
+CView_ValueScale.getCustomDataSchema = function() {
+ var schema = {
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "title": "Custom data for CView_ValueScale",
+ "type": "object",
+ "properties": {
+ "class": {
+ "type": "string",
+ "description": "the css class of the value scale bar"
+ },
+ "minimumValue": {
+ "type": "integer",
+ "description": "the value that will serve as the minimum on the scale",
+ "default": 0
+ },
+ "maximumValue": {
+ "type": "integer",
+ "description": "the value that will serve as the maximum on the scale",
+ "default": 100
+ },
+ "yellowZone": {
+ "type": "integer",
+ "description": "value in percent where the scale will turn yellow",
+ "default": 60
+ },
+ "redZone": {
+ "type": "integer",
+ "description": "value in percent where the scale will turn red",
+ "default": 80
+ }
+ },
+ "additionalProperties": false
+ };
+ $.extend(true, schema, ViewUtils.commonViewSchema);
+ return schema;
+};
+//# sourceURL=WebApplicationFramework\Views\View_ValueScale.js
\ No newline at end of file
diff --git a/htdocs/WebApplications/CustomizableApp/ViewModel.js b/htdocs/WebApplications/CustomizableApp/ViewModel.js
index eec5f69..a8159e5 100644
--- a/htdocs/WebApplications/CustomizableApp/ViewModel.js
+++ b/htdocs/WebApplications/CustomizableApp/ViewModel.js
@@ -494,7 +494,15 @@
if (rangeFilter != undefined) {
p_requests[i].getData.rangeFilter = JSON.parse(rangeFilter);
} else {
- p_requests[i].getData.rangeFilter.offset = 0;
+ var origKey = JSON.stringify(p_path)+"origRangeFilter"+mWebAppModel.getSetupModel().getSetup().name;
+ rangeFilter = sessionStorage.getItem(origKey);
+ if (rangeFilter == undefined) {
+ sessionStorage.setItem(origKey, JSON.stringify(p_requests[i].getData.rangeFilter));
+ rangeFilter = p_requests[i].getData.rangeFilter;
+ } else {
+ rangeFilter = JSON.parse(rangeFilter);
+ }
+ p_requests[i].getData.rangeFilter = rangeFilter;
}
}
diff --git a/htdocs/WebApplications/CustomizableApp/ViewModels/Viewmodel_ScrollForRangeFilter.js b/htdocs/WebApplications/CustomizableApp/ViewModels/Viewmodel_ScrollForRangeFilter.js
index 04e9a41..00fb327 100644
--- a/htdocs/WebApplications/CustomizableApp/ViewModels/Viewmodel_ScrollForRangeFilter.js
+++ b/htdocs/WebApplications/CustomizableApp/ViewModels/Viewmodel_ScrollForRangeFilter.js
@@ -22,10 +22,10 @@
/** public functions - interface for views */
this.getRange = function() {
- var size = paging.getSize();
+ var size = base.getSize();
var max = size;
if (v_options.allowScrollBelow == false) {
- max = max - paging.getRangeFilter().count + 1;
+ max = max - base.getRangeFilter().count + 1;
}
return {
"min": 0,
@@ -56,7 +56,7 @@
CViewModel_ScrollForRangeFilter.getCustomDataSchema = function() {
var schema = CViewModel_Paging.getCustomDataSchema();
- scema.title = "Custom data for CViewModel_ScrollForRangeFilter";
+ schema.title = "Custom data for CViewModel_ScrollForRangeFilter";
return schema;
};
@@ -64,4 +64,4 @@
return CViewModel_Paging.expectsConnection();
};
-//# sourceURL=CustomizableApp\ViewModels\ViewModel_Scroll.js
\ No newline at end of file
+//# sourceURL=CustomizableApp\ViewModels\ViewModel_ScrollForRangeFilter.js