diff --git a/htdocs/Utils/Utilities.js b/htdocs/Utils/Utilities.js index eea9d4fbb42918c9ab90e512d8d3585ae6d3ec85..23d7f60899e0c2f9e0cfd0e3e003866397876e76 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 @@ function getLocationParam(p_key) { 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 0000000000000000000000000000000000000000..7e90e66f9137840b5e5e50ff0c5ff338f94372a3 --- /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 0000000000000000000000000000000000000000..bec489869a26ea04ee4dbe3f4b65ea982fefdea2 --- /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 0000000000000000000000000000000000000000..9350bbaff7a3b4f79866445ca7d88ee5ca90157d --- /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 eec5f697cd9a03c4ada6bc8f3159a8c31f36fe5e..a8159e5dc315385900c85c1c072ca2e5665ec70a 100644 --- a/htdocs/WebApplications/CustomizableApp/ViewModel.js +++ b/htdocs/WebApplications/CustomizableApp/ViewModel.js @@ -494,7 +494,15 @@ function CViewModel(aModel, aDataSourceUtils) 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 04e9a41fc5d719aefdbe54eca3a17d80a11ecc7c..00fb327421a2d5e6a93a3637f145887d1ef1be65 100644 --- a/htdocs/WebApplications/CustomizableApp/ViewModels/Viewmodel_ScrollForRangeFilter.js +++ b/htdocs/WebApplications/CustomizableApp/ViewModels/Viewmodel_ScrollForRangeFilter.js @@ -22,10 +22,10 @@ function CViewModel_ScrollForRangeFilter(p_viewmodel, p_options) { /** 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.providesInterface = function() { 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 @@ CViewModel_ScrollForRangeFilter.expectsConnection = function() { return CViewModel_Paging.expectsConnection(); }; -//# sourceURL=CustomizableApp\ViewModels\ViewModel_Scroll.js \ No newline at end of file +//# sourceURL=CustomizableApp\ViewModels\ViewModel_ScrollForRangeFilter.js