From 84ed34d4f051c3d0b58f74238936ec4d2e0b6802 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Fri, 22 Dec 2017 12:27:09 +0200 Subject: [PATCH 01/19] UI: Introduce additionalParams for custom widget actions. --- .../widget/action/widget-action-dialog.tpl.html | 2 +- ui/src/app/components/widget/widget.controller.js | 9 ++++++--- ui/src/app/widget/lib/alarms-table-widget.js | 4 ++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/ui/src/app/components/widget/action/widget-action-dialog.tpl.html b/ui/src/app/components/widget/action/widget-action-dialog.tpl.html index ded4c969a6..aa0971a3ec 100644 --- a/ui/src/app/components/widget/action/widget-action-dialog.tpl.html +++ b/ui/src/app/components/widget/action/widget-action-dialog.tpl.html @@ -120,7 +120,7 @@ diff --git a/ui/src/app/components/widget/widget.controller.js b/ui/src/app/components/widget/widget.controller.js index 7d91aef114..a5faadaec5 100644 --- a/ui/src/app/components/widget/widget.controller.js +++ b/ui/src/app/components/widget/widget.controller.js @@ -444,7 +444,7 @@ export default function WidgetController($scope, $state, $timeout, $window, $ele } } - function handleWidgetAction($event, descriptor, entityId, entityName) { + function handleWidgetAction($event, descriptor, entityId, entityName, additionalParams) { var type = descriptor.type; var targetEntityParamName = descriptor.stateEntityParamName; var targetEntityId; @@ -485,8 +485,11 @@ export default function WidgetController($scope, $state, $timeout, $window, $ele var customFunction = descriptor.customFunction; if (angular.isDefined(customFunction) && customFunction.length > 0) { try { - var customActionFunction = new Function('$event', 'widgetContext', 'entityId', 'entityName', customFunction); - customActionFunction($event, widgetContext, entityId, entityName); + if (!additionalParams) { + additionalParams = {}; + } + var customActionFunction = new Function('$event', 'widgetContext', 'entityId', 'entityName', 'additionalParams', customFunction); + customActionFunction($event, widgetContext, entityId, entityName, additionalParams); } catch (e) { // } diff --git a/ui/src/app/widget/lib/alarms-table-widget.js b/ui/src/app/widget/lib/alarms-table-widget.js index 9e96d4d049..101c234152 100644 --- a/ui/src/app/widget/lib/alarms-table-widget.js +++ b/ui/src/app/widget/lib/alarms-table-widget.js @@ -298,7 +298,7 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia entityId = vm.currentAlarm.originator; entityName = vm.currentAlarm.originatorName; } - vm.ctx.actionsApi.handleWidgetAction($event, descriptors[0], entityId, entityName); + vm.ctx.actionsApi.handleWidgetAction($event, descriptors[0], entityId, entityName, { alarm: vm.currentAlarm }); } } @@ -312,7 +312,7 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia entityId = alarm.originator; entityName = alarm.originatorName; } - vm.ctx.actionsApi.handleWidgetAction($event, actionDescriptor, entityId, entityName); + vm.ctx.actionsApi.handleWidgetAction($event, actionDescriptor, entityId, entityName, { alarm: vm.currentAlarm }); } function isCurrent(alarm) { From 0b7754c1c06631f942eccd7e157a575b2ce90e03 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Fri, 22 Dec 2017 12:57:51 +0200 Subject: [PATCH 02/19] UI: Fix alarms table widget. --- ui/src/app/widget/lib/alarms-table-widget.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/src/app/widget/lib/alarms-table-widget.js b/ui/src/app/widget/lib/alarms-table-widget.js index 101c234152..00e499712e 100644 --- a/ui/src/app/widget/lib/alarms-table-widget.js +++ b/ui/src/app/widget/lib/alarms-table-widget.js @@ -124,7 +124,7 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia $scope.$on('alarms-table-data-updated', function(event, tableId) { if (vm.tableId == tableId) { if (vm.subscription) { - vm.allAlarms = vm.subscription.alarms; + vm.allAlarms = vm.subscription.alarms || []; updateAlarms(true); $scope.$digest(); } @@ -298,7 +298,7 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia entityId = vm.currentAlarm.originator; entityName = vm.currentAlarm.originatorName; } - vm.ctx.actionsApi.handleWidgetAction($event, descriptors[0], entityId, entityName, { alarm: vm.currentAlarm }); + vm.ctx.actionsApi.handleWidgetAction($event, descriptors[0], entityId, entityName, { alarm: alarm }); } } @@ -312,7 +312,7 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia entityId = alarm.originator; entityName = alarm.originatorName; } - vm.ctx.actionsApi.handleWidgetAction($event, actionDescriptor, entityId, entityName, { alarm: vm.currentAlarm }); + vm.ctx.actionsApi.handleWidgetAction($event, actionDescriptor, entityId, entityName, { alarm: alarm }); } function isCurrent(alarm) { From af7c811d0d3811aee3440fc5b6b33821a8c7cd90 Mon Sep 17 00:00:00 2001 From: Posi-Paka Date: Mon, 25 Dec 2017 14:59:53 -0800 Subject: [PATCH 03/19] Removal of Joda-Time library. --- application/pom.xml | 4 ---- .../security/model/token/JwtTokenFactory.java | 19 ++++++++++--------- pom.xml | 8 +------- 3 files changed, 11 insertions(+), 20 deletions(-) diff --git a/application/pom.xml b/application/pom.xml index c7d3240ef4..e5a4a4e614 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -125,10 +125,6 @@ io.jsonwebtoken jjwt - - joda-time - joda-time - org.apache.velocity velocity diff --git a/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java b/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java index 20de6d8e73..7e5fba5477 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java +++ b/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java @@ -20,7 +20,6 @@ import io.jsonwebtoken.Jws; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.apache.commons.lang3.StringUtils; -import org.joda.time.DateTime; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.id.CustomerId; @@ -31,7 +30,9 @@ import org.thingsboard.server.config.JwtSettings; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.UserPrincipal; -import java.util.Arrays; +import java.time.ZonedDateTime; +import java.util.Collections; +import java.util.Date; import java.util.List; import java.util.UUID; import java.util.stream.Collectors; @@ -81,13 +82,13 @@ public class JwtTokenFactory { claims.put(CUSTOMER_ID, securityUser.getCustomerId().getId().toString()); } - DateTime currentTime = new DateTime(); + ZonedDateTime currentTime = ZonedDateTime.now(); String token = Jwts.builder() .setClaims(claims) .setIssuer(settings.getTokenIssuer()) - .setIssuedAt(currentTime.toDate()) - .setExpiration(currentTime.plusSeconds(settings.getTokenExpirationTime()).toDate()) + .setIssuedAt(Date.from(currentTime.toInstant())) + .setExpiration(Date.from(currentTime.plusSeconds(settings.getTokenExpirationTime()).toInstant())) .signWith(SignatureAlgorithm.HS512, settings.getTokenSigningKey()) .compact(); @@ -129,11 +130,11 @@ public class JwtTokenFactory { throw new IllegalArgumentException("Cannot create JWT Token without username/email"); } - DateTime currentTime = new DateTime(); + ZonedDateTime currentTime = ZonedDateTime.now(); UserPrincipal principal = securityUser.getUserPrincipal(); Claims claims = Jwts.claims().setSubject(principal.getValue()); - claims.put(SCOPES, Arrays.asList(Authority.REFRESH_TOKEN.name())); + claims.put(SCOPES, Collections.singletonList(Authority.REFRESH_TOKEN.name())); claims.put(USER_ID, securityUser.getId().getId().toString()); claims.put(IS_PUBLIC, principal.getType() == UserPrincipal.Type.PUBLIC_ID); @@ -141,8 +142,8 @@ public class JwtTokenFactory { .setClaims(claims) .setIssuer(settings.getTokenIssuer()) .setId(UUID.randomUUID().toString()) - .setIssuedAt(currentTime.toDate()) - .setExpiration(currentTime.plusSeconds(settings.getRefreshTokenExpTime()).toDate()) + .setIssuedAt(Date.from(currentTime.toInstant())) + .setExpiration(Date.from(currentTime.plusSeconds(settings.getRefreshTokenExpTime()).toInstant())) .signWith(SignatureAlgorithm.HS512, settings.getTokenSigningKey()) .compact(); diff --git a/pom.xml b/pom.xml index e45fc3ea28..4b77abbd98 100755 --- a/pom.xml +++ b/pom.xml @@ -33,8 +33,7 @@ 4.3.4.RELEASE 4.2.0.RELEASE 0.7.0 - 2.4 - 2.2.0 + 2.2.0 4.12 1.7.7 1.2.3 @@ -483,11 +482,6 @@ jjwt ${jjwt.version} - - joda-time - joda-time - ${joda-time.version} - org.apache.velocity velocity From 29f217add8359235c5f1429479584546ea6da3b0 Mon Sep 17 00:00:00 2001 From: Dima Landiak Date: Wed, 27 Dec 2017 14:16:54 +0200 Subject: [PATCH 04/19] rest client added relation --- .../java/org/thingsboard/client/tools/RestClient.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tools/src/main/java/org/thingsboard/client/tools/RestClient.java b/tools/src/main/java/org/thingsboard/client/tools/RestClient.java index 7000496cdc..8ef51258ed 100644 --- a/tools/src/main/java/org/thingsboard/client/tools/RestClient.java +++ b/tools/src/main/java/org/thingsboard/client/tools/RestClient.java @@ -29,13 +29,12 @@ import org.springframework.web.client.RestTemplate; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.alarm.Alarm; -import org.thingsboard.server.common.data.alarm.AlarmSeverity; -import org.thingsboard.server.common.data.alarm.AlarmStatus; import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.id.AssetId; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.security.DeviceCredentials; import java.io.IOException; @@ -112,6 +111,14 @@ public class RestClient implements ClientHttpRequestInterceptor { customerId.toString(), assetId.toString()).getBody(); } + public EntityRelation makeRelation(String relationType, EntityId idFrom, EntityId idTo) { + EntityRelation relation = new EntityRelation(); + relation.setFrom(idFrom); + relation.setTo(idTo); + relation.setType(relationType); + return restTemplate.postForEntity(baseURL + "/api/relation", relation, EntityRelation.class).getBody(); + } + public DeviceCredentials getCredentials(DeviceId id) { return restTemplate.getForEntity(baseURL + "/api/device/" + id.getId().toString() + "/credentials", DeviceCredentials.class).getBody(); } From 34641d5395055b001b90e6cb6da0efab5016deda Mon Sep 17 00:00:00 2001 From: oleg Date: Wed, 27 Dec 2017 16:26:39 +0200 Subject: [PATCH 05/19] 'Timeseries table' widget improvements --- .../main/data/json/system/widget_bundles/cards.json | 4 ++-- ui/src/app/locale/locale.constant.js | 1 + ui/src/app/widget/lib/timeseries-table-widget.js | 6 +++++- .../app/widget/lib/timeseries-table-widget.tpl.html | 12 ++++++++---- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/application/src/main/data/json/system/widget_bundles/cards.json b/application/src/main/data/json/system/widget_bundles/cards.json index 0fc0085f12..ddb90dbaae 100644 --- a/application/src/main/data/json/system/widget_bundles/cards.json +++ b/application/src/main/data/json/system/widget_bundles/cards.json @@ -112,9 +112,9 @@ "templateHtml": "\n", "templateCss": "", "controllerScript": "self.onInit = function() {\n var scope = self.ctx.$scope;\n var id = self.ctx.$scope.$injector.get('utils').guid();\n scope.tableId = \"table-\"+id;\n scope.ctx = self.ctx;\n}\n\nself.onDataUpdated = function() {\n self.ctx.$scope.$broadcast('timeseries-table-data-updated', self.ctx.$scope.tableId);\n}\n\nself.onDestroy = function() {\n}", - "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"TimeseriesTableSettings\",\n \"properties\": {\n \"showTimestamp\": {\n \"title\": \"Display timestamp column\",\n \"type\": \"boolean\",\n \"default\": true\n }\n },\n \"required\": []\n },\n \"form\": [\n \"showTimestamp\"\n ]\n}", + "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"TimeseriesTableSettings\",\n \"properties\": {\n \"showTimestamp\": {\n \"title\": \"Display timestamp column\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"displayPagination\": {\n \"title\": \"Display pagination\",\n \"type\": \"boolean\",\n \"default\": true\n }, \n \"defaultPageSize\": {\n \"title\": \"Default page size\",\n \"type\": \"number\",\n \"default\": 10\n }\n },\n \"required\": []\n },\n \"form\": [\n \"showTimestamp\",\n \"displayPagination\",\n \"defaultPageSize\"\n ]\n}", "dataKeySettingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"DataKeySettings\",\n \"properties\": {\n \"useCellStyleFunction\": {\n \"title\": \"Use cell style function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"cellStyleFunction\": {\n \"title\": \"Cell style function: f(value)\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"useCellContentFunction\": {\n \"title\": \"Use cell content function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"cellContentFunction\": {\n \"title\": \"Cell content function: f(value, rowData, filter)\",\n \"type\": \"string\",\n \"default\": \"\"\n }\n },\n \"required\": []\n },\n \"form\": [\n \"useCellStyleFunction\",\n {\n \"key\": \"cellStyleFunction\",\n \"type\": \"javascript\"\n },\n \"useCellContentFunction\",\n {\n \"key\": \"cellContentFunction\",\n \"type\": \"javascript\"\n }\n ]\n}", - "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temperature °C\",\"color\":\"#2196f3\",\"settings\":{\"useCellStyleFunction\":true,\"cellStyleFunction\":\"if (value) {\\n var percent = (value + 60)/120 * 100;\\n var color = tinycolor.mix('blue', 'red', amount = percent);\\n color.setAlpha(.5);\\n return {\\n paddingLeft: '20px',\\n color: '#ffffff',\\n background: color.toRgbString(),\\n fontSize: '18px'\\n };\\n} else {\\n return {};\\n}\"},\"_hash\":0.8587686344902596,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nvar multiplier = Math.pow(10, 1 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Humidity, %\",\"color\":\"#ffc107\",\"settings\":{\"useCellStyleFunction\":true,\"cellStyleFunction\":\"if (value) {\\n var percent = value;\\n var backgroundColor = tinycolor('blue');\\n backgroundColor.setAlpha(value/100);\\n var color = 'blue';\\n if (value > 50) {\\n color = 'white';\\n }\\n \\n return {\\n paddingLeft: '20px',\\n color: color,\\n background: backgroundColor.toRgbString(),\\n fontSize: '18px'\\n };\\n} else {\\n return {};\\n}\",\"useCellContentFunction\":false},\"_hash\":0.12775350966079668,\"funcBody\":\"var value = prevValue + Math.random() * 20 - 10;\\nvar multiplier = Math.pow(10, 1 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < 5) {\\n\\tvalue = 5;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"interval\":1000,\"timewindowMs\":60000},\"aggregation\":{\"type\":\"NONE\",\"limit\":200}},\"showTitle\":true,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"showTimestamp\":true},\"title\":\"Timeseries table\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":false,\"showLegend\":false}" + "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temperature °C\",\"color\":\"#2196f3\",\"settings\":{\"useCellStyleFunction\":true,\"cellStyleFunction\":\"if (value) {\\n var percent = (value + 60)/120 * 100;\\n var color = tinycolor.mix('blue', 'red', amount = percent);\\n color.setAlpha(.5);\\n return {\\n paddingLeft: '20px',\\n color: '#ffffff',\\n background: color.toRgbString(),\\n fontSize: '18px'\\n };\\n} else {\\n return {};\\n}\"},\"_hash\":0.8587686344902596,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nvar multiplier = Math.pow(10, 1 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Humidity, %\",\"color\":\"#ffc107\",\"settings\":{\"useCellStyleFunction\":true,\"cellStyleFunction\":\"if (value) {\\n var percent = value;\\n var backgroundColor = tinycolor('blue');\\n backgroundColor.setAlpha(value/100);\\n var color = 'blue';\\n if (value > 50) {\\n color = 'white';\\n }\\n \\n return {\\n paddingLeft: '20px',\\n color: color,\\n background: backgroundColor.toRgbString(),\\n fontSize: '18px'\\n };\\n} else {\\n return {};\\n}\",\"useCellContentFunction\":false},\"_hash\":0.12775350966079668,\"funcBody\":\"var value = prevValue + Math.random() * 20 - 10;\\nvar multiplier = Math.pow(10, 1 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < 5) {\\n\\tvalue = 5;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"interval\":1000,\"timewindowMs\":60000},\"aggregation\":{\"type\":\"NONE\",\"limit\":200}},\"showTitle\":true,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"showTimestamp\":true,\"displayPagination\":true,\"defaultPageSize\":10},\"title\":\"Timeseries table\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":false,\"showLegend\":false,\"widgetStyle\":{},\"actions\":{}}" } } ] diff --git a/ui/src/app/locale/locale.constant.js b/ui/src/app/locale/locale.constant.js index ab672de30d..7769b3dbda 100644 --- a/ui/src/app/locale/locale.constant.js +++ b/ui/src/app/locale/locale.constant.js @@ -1213,6 +1213,7 @@ export default angular.module('thingsboard.locale', []) "remove-widget-title": "Are you sure you want to remove the widget '{{widgetTitle}}'?", "remove-widget-text": "After the confirmation the widget and all related data will become unrecoverable.", "timeseries": "Time series", + "search-data": "Search data", "latest-values": "Latest values", "rpc": "Control widget", "alarm": "Alarm widget", diff --git a/ui/src/app/widget/lib/timeseries-table-widget.js b/ui/src/app/widget/lib/timeseries-table-widget.js index 0c23e027fe..58a626cb9b 100644 --- a/ui/src/app/widget/lib/timeseries-table-widget.js +++ b/ui/src/app/widget/lib/timeseries-table-widget.js @@ -50,6 +50,8 @@ function TimeseriesTableWidgetController($element, $scope, $filter) { vm.sources = []; vm.sourceIndex = 0; + vm.defaultPageSize = 10; + vm.defaultSortOrder = '-0'; $scope.$watch('vm.ctx', function() { if (vm.ctx) { @@ -108,6 +110,8 @@ function TimeseriesTableWidgetController($element, $scope, $filter) { cssParser.createStyleElement(namespace, cssString); $element.addClass(namespace); + vm.displayPagination = angular.isDefined(vm.settings.displayPagination) ? vm.settings.displayPagination : true; + function hashCode(str) { var hash = 0; var i, char; @@ -211,7 +215,7 @@ function TimeseriesTableWidgetController($element, $scope, $filter) { source.data = []; source.rawData = []; source.query = { - limit: 5, + limit: vm.settings.defaultPageSize || 10, page: 1, order: '-0' } diff --git a/ui/src/app/widget/lib/timeseries-table-widget.tpl.html b/ui/src/app/widget/lib/timeseries-table-widget.tpl.html index 2b6d72c10a..32fb8e438c 100644 --- a/ui/src/app/widget/lib/timeseries-table-widget.tpl.html +++ b/ui/src/app/widget/lib/timeseries-table-widget.tpl.html @@ -28,16 +28,20 @@ - + - + \ No newline at end of file From f67a192e2bdb5eb99a91cb4425b4c301653cb71c Mon Sep 17 00:00:00 2001 From: Dima Landiak Date: Fri, 29 Dec 2017 10:42:56 +0200 Subject: [PATCH 06/19] rest client update --- .../server/controller/CustomerController.java | 16 ++++++++++++++-- .../server/dao/customer/CustomerService.java | 8 ++++++-- .../dao/customer/CustomerServiceImpl.java | 8 ++++++++ .../thingsboard/client/tools/RestClient.java | 19 +++++++++++++++++++ 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/CustomerController.java b/application/src/main/java/org/thingsboard/server/controller/CustomerController.java index c54973f0bc..d87ea5cfe0 100644 --- a/application/src/main/java/org/thingsboard/server/controller/CustomerController.java +++ b/application/src/main/java/org/thingsboard/server/controller/CustomerController.java @@ -82,7 +82,7 @@ public class CustomerController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer", method = RequestMethod.POST) - @ResponseBody + @ResponseBody public Customer saveCustomer(@RequestBody Customer customer) throws ThingsboardException { try { customer.setTenantId(getCurrentUser().getTenantId()); @@ -107,7 +107,7 @@ public class CustomerController extends BaseController { } @PreAuthorize("hasAuthority('TENANT_ADMIN')") - @RequestMapping(value = "/customers", params = { "limit" }, method = RequestMethod.GET) + @RequestMapping(value = "/customers", params = {"limit"}, method = RequestMethod.GET) @ResponseBody public TextPageData getCustomers(@RequestParam int limit, @RequestParam(required = false) String textSearch, @@ -122,4 +122,16 @@ public class CustomerController extends BaseController { } } + @PreAuthorize("hasAuthority('TENANT_ADMIN')") + @RequestMapping(value = "/tenant/customers", params = {"customerTitle"}, method = RequestMethod.GET) + @ResponseBody + public Customer getTenantCustomer( + @RequestParam String customerTitle) throws ThingsboardException { + try { + TenantId tenantId = getCurrentUser().getTenantId(); + return checkNotNull(customerService.findCustomerByTenantIdAndTitle(tenantId, customerTitle)); + } catch (Exception e) { + throw handleException(e); + } + } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerService.java b/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerService.java index 4600d9f048..1d1abda11f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerService.java @@ -22,20 +22,24 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.TextPageData; import org.thingsboard.server.common.data.page.TextPageLink; +import java.util.Optional; + public interface CustomerService { Customer findCustomerById(CustomerId customerId); + Optional findCustomerByTenantIdAndTitle(TenantId tenantId, String title); + ListenableFuture findCustomerByIdAsync(CustomerId customerId); Customer saveCustomer(Customer customer); - + void deleteCustomer(CustomerId customerId); Customer findOrCreatePublicCustomer(TenantId tenantId); TextPageData findCustomersByTenantId(TenantId tenantId, TextPageLink pageLink); - + void deleteCustomersByTenantId(TenantId tenantId); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java index e8ec21f3c0..f76d654bf9 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java @@ -52,6 +52,7 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom private static final String PUBLIC_CUSTOMER_TITLE = "Public"; public static final String INCORRECT_CUSTOMER_ID = "Incorrect customerId "; + public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; @Autowired private CustomerDao customerDao; @@ -78,6 +79,13 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom return customerDao.findById(customerId.getId()); } + @Override + public Optional findCustomerByTenantIdAndTitle(TenantId tenantId, String title) { + log.trace("Executing findCustomerByTenantIdAndTitle [{}] [{}]", tenantId, title); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); + return customerDao.findCustomersByTenantIdAndTitle(tenantId.getId(), title); + } + @Override public ListenableFuture findCustomerByIdAsync(CustomerId customerId) { log.trace("Executing findCustomerByIdAsync [{}]", customerId); diff --git a/tools/src/main/java/org/thingsboard/client/tools/RestClient.java b/tools/src/main/java/org/thingsboard/client/tools/RestClient.java index 8ef51258ed..e2a8e066f1 100644 --- a/tools/src/main/java/org/thingsboard/client/tools/RestClient.java +++ b/tools/src/main/java/org/thingsboard/client/tools/RestClient.java @@ -77,6 +77,21 @@ public class RestClient implements ClientHttpRequestInterceptor { } } + public Optional findAsset(String name) { + Map params = new HashMap(); + params.put("assetName", name); + try { + ResponseEntity assetEntity = restTemplate.getForEntity(baseURL + "/api/tenant/assets?assetName={assetName}", Asset.class, params); + return Optional.of(assetEntity.getBody()); + } catch (HttpClientErrorException exception) { + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) { + return Optional.empty(); + } else { + throw exception; + } + } + } + public Customer createCustomer(String title) { Customer customer = new Customer(); customer.setTitle(title); @@ -123,6 +138,10 @@ public class RestClient implements ClientHttpRequestInterceptor { return restTemplate.getForEntity(baseURL + "/api/device/" + id.getId().toString() + "/credentials", DeviceCredentials.class).getBody(); } + public Customer getCustomerByTitle(String title) { + return restTemplate.getForEntity(baseURL + "/api/tenant/customers?customerTitle=" + title, Customer.class).getBody(); + } + public RestTemplate getRestTemplate() { return restTemplate; } From 0aba2fcfe6dac3f0c5c6ffa386db5d8fddc3a5f3 Mon Sep 17 00:00:00 2001 From: Dima Landiak Date: Fri, 29 Dec 2017 11:07:43 +0200 Subject: [PATCH 07/19] fix rest client --- .../thingsboard/client/tools/RestClient.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/tools/src/main/java/org/thingsboard/client/tools/RestClient.java b/tools/src/main/java/org/thingsboard/client/tools/RestClient.java index e2a8e066f1..0baf1db508 100644 --- a/tools/src/main/java/org/thingsboard/client/tools/RestClient.java +++ b/tools/src/main/java/org/thingsboard/client/tools/RestClient.java @@ -77,6 +77,21 @@ public class RestClient implements ClientHttpRequestInterceptor { } } + public Optional findCustomer(String title) { + Map params = new HashMap(); + params.put("customerTitle", title); + try { + ResponseEntity customerEntity = restTemplate.getForEntity(baseURL + "/api/tenant/customers?customerTitle={customerTitle}", Customer.class, params); + return Optional.of(customerEntity.getBody()); + } catch (HttpClientErrorException exception) { + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) { + return Optional.empty(); + } else { + throw exception; + } + } + } + public Optional findAsset(String name) { Map params = new HashMap(); params.put("assetName", name); @@ -138,10 +153,6 @@ public class RestClient implements ClientHttpRequestInterceptor { return restTemplate.getForEntity(baseURL + "/api/device/" + id.getId().toString() + "/credentials", DeviceCredentials.class).getBody(); } - public Customer getCustomerByTitle(String title) { - return restTemplate.getForEntity(baseURL + "/api/tenant/customers?customerTitle=" + title, Customer.class).getBody(); - } - public RestTemplate getRestTemplate() { return restTemplate; } From 2dba7f52f5d74dd5e19dac94c13a07f47c874c77 Mon Sep 17 00:00:00 2001 From: oleg Date: Fri, 29 Dec 2017 15:24:31 +0200 Subject: [PATCH 08/19] "Timeseries - Flot" widget improvements (search) --- .../app/widget/lib/timeseries-table-widget.js | 52 +++++++++- .../widget/lib/timeseries-table-widget.scss | 4 + .../lib/timeseries-table-widget.tpl.html | 96 +++++++++++++------ 3 files changed, 122 insertions(+), 30 deletions(-) diff --git a/ui/src/app/widget/lib/timeseries-table-widget.js b/ui/src/app/widget/lib/timeseries-table-widget.js index 58a626cb9b..28ac811f1b 100644 --- a/ui/src/app/widget/lib/timeseries-table-widget.js +++ b/ui/src/app/widget/lib/timeseries-table-widget.js @@ -47,11 +47,37 @@ function TimeseriesTableWidget() { /*@ngInject*/ function TimeseriesTableWidgetController($element, $scope, $filter) { var vm = this; + let dateFormatFilter = 'yyyy-MM-dd HH:mm:ss'; vm.sources = []; vm.sourceIndex = 0; vm.defaultPageSize = 10; vm.defaultSortOrder = '-0'; + vm.query = { + "search": null + }; + + vm.enterFilterMode = enterFilterMode; + vm.exitFilterMode = exitFilterMode; + + function enterFilterMode () { + vm.query.search = ''; + vm.ctx.hideTitlePanel = true; + } + + function exitFilterMode () { + vm.query.search = null; + vm.ctx.hideTitlePanel = false; + } + + vm.searchAction = { + name: 'action.search', + show: true, + onAction: function() { + vm.enterFilterMode(); + }, + icon: 'search' + }; $scope.$watch('vm.ctx', function() { if (vm.ctx) { @@ -64,6 +90,7 @@ function TimeseriesTableWidgetController($element, $scope, $filter) { }); function initialize() { + vm.ctx.widgetActions = [ vm.searchAction ]; vm.showTimestamp = vm.settings.showTimestamp !== false; var origColor = vm.widgetConfig.color || 'rgba(0, 0, 0, 0.87)'; var defaultColor = tinycolor(origColor); @@ -167,7 +194,7 @@ function TimeseriesTableWidgetController($element, $scope, $filter) { vm.cellContent = function(source, index, row, value) { if (index === 0) { - return $filter('date')(value, 'yyyy-MM-dd HH:mm:ss'); + return $filter('date')(value, dateFormatFilter); } else { var strContent = ''; if (angular.isDefined(value)) { @@ -291,7 +318,30 @@ function TimeseriesTableWidgetController($element, $scope, $filter) { } function reorder(source) { + let searchRegExp = new RegExp(vm.query.search); + source.data = $filter('orderBy')(source.data, source.query.order); + if (vm.query.search !== null) { + source.data = source.data.filter(function(item){ + for (let i = 0; i < item.length; i++) { + if (vm.showTimestamp) { + if (i === 0) { + if (searchRegExp.test($filter('date')(item[i], dateFormatFilter))) { + return true; + } + } else { + if (searchRegExp.test(item[i])) { + return true; + } + } + } else { + if (searchRegExp.test(item[i])) { + return true; + } + } + } + }); + } } function convertData(data) { diff --git a/ui/src/app/widget/lib/timeseries-table-widget.scss b/ui/src/app/widget/lib/timeseries-table-widget.scss index 99a06537e9..da3ee81644 100644 --- a/ui/src/app/widget/lib/timeseries-table-widget.scss +++ b/ui/src/app/widget/lib/timeseries-table-widget.scss @@ -26,4 +26,8 @@ tb-timeseries-table-widget { .md-table-pagination>* { height: 46px; } + + .tb-data-table md-toolbar { + z-index: 10; + } } diff --git a/ui/src/app/widget/lib/timeseries-table-widget.tpl.html b/ui/src/app/widget/lib/timeseries-table-widget.tpl.html index 32fb8e438c..2e7286c163 100644 --- a/ui/src/app/widget/lib/timeseries-table-widget.tpl.html +++ b/ui/src/app/widget/lib/timeseries-table-widget.tpl.html @@ -15,33 +15,71 @@ limitations under the License. --> +
+
+ +
+ + search + + {{'entity.search' | translate}} + + + + + + + + close + + {{ 'action.close' | translate }} + + +
+
- - - - - - - - - - - - - - - -
Timestamp{{ h.dataKey.label }}
-
-
- - -
-
\ No newline at end of file + + + + + + + + + + + + + + + + +
+ Timestamp + + {{ h.dataKey.label }} +
+
+ + +
+
+
+
\ No newline at end of file From 20be8eba08ffee45561c7b835204ae0609e436b0 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Fri, 29 Dec 2017 19:09:34 +0200 Subject: [PATCH 09/19] UI: Access 'loading' property directly from rootScope. --- ui/src/app/admin/general-settings.tpl.html | 8 +- .../app/admin/outgoing-mail-settings.tpl.html | 14 ++-- .../app/alarm/alarm-details-dialog.tpl.html | 6 +- ui/src/app/alarm/alarm-table.tpl.html | 6 +- ui/src/app/api/asset.service.js | 4 +- ui/src/app/api/attribute.service.js | 4 +- ui/src/app/api/customer.service.js | 8 +- ui/src/app/api/dashboard.service.js | 16 ++-- ui/src/app/api/device.service.js | 4 +- ui/src/app/api/entity-relation.service.js | 4 +- ui/src/app/api/entity.service.js | 76 ++++++++++--------- ui/src/app/api/plugin.service.js | 24 +++--- ui/src/app/api/rule.service.js | 12 +-- ui/src/app/api/tenant.service.js | 8 +- ui/src/app/api/user.service.js | 8 +- ui/src/app/api/widget.service.js | 16 ++-- ui/src/app/asset/add-asset.tpl.html | 8 +- .../app/asset/add-assets-to-customer.tpl.html | 8 +- ui/src/app/asset/asset-fieldset.tpl.html | 4 +- ui/src/app/asset/assign-to-customer.tpl.html | 8 +- .../app/component/component-dialog.tpl.html | 14 ++-- ui/src/app/component/component.tpl.html | 4 +- .../dashboard-autocomplete.directive.js | 6 +- .../components/dashboard-select.directive.js | 4 +- .../datakey-config-dialog.controller.js | 2 +- .../components/datakey-config-dialog.tpl.html | 8 +- .../app/components/details-sidenav.tpl.html | 4 +- ui/src/app/components/grid.tpl.html | 14 ++-- .../components/legend-config-panel.tpl.html | 2 +- .../components/material-icons-dialog.tpl.html | 8 +- .../app/components/plugin-select.directive.js | 4 +- .../app/components/timewindow-panel.tpl.html | 6 +- .../action/widget-action-dialog.tpl.html | 10 +-- .../components/widget/widget-config.tpl.html | 4 +- .../widgets-bundle-select.directive.js | 2 +- ui/src/app/customer/add-customer.tpl.html | 8 +- .../app/customer/customer-fieldset.tpl.html | 2 +- ui/src/app/dashboard/add-dashboard.tpl.html | 8 +- .../add-dashboards-to-customer.tpl.html | 8 +- ui/src/app/dashboard/add-widget.controller.js | 2 +- ui/src/app/dashboard/add-widget.tpl.html | 10 +-- .../app/dashboard/assign-to-customer.tpl.html | 8 +- .../app/dashboard/dashboard-fieldset.tpl.html | 2 +- .../app/dashboard/dashboard-settings.tpl.html | 10 +-- ui/src/app/dashboard/dashboard.tpl.html | 16 ++-- ui/src/app/dashboard/edit-widget.directive.js | 2 +- ui/src/app/dashboard/edit-widget.tpl.html | 2 +- .../layouts/dashboard-layout.tpl.html | 2 +- .../layouts/manage-dashboard-layouts.tpl.html | 10 +-- .../layouts/select-target-layout.tpl.html | 6 +- .../states/dashboard-state-dialog.tpl.html | 10 +-- .../states/manage-dashboard-states.tpl.html | 10 +-- .../states/select-target-state.tpl.html | 10 +-- ui/src/app/device/add-device.tpl.html | 8 +- .../device/add-devices-to-customer.tpl.html | 8 +- ui/src/app/device/assign-to-customer.tpl.html | 8 +- ui/src/app/device/device-credentials.tpl.html | 12 +-- ui/src/app/device/device-fieldset.tpl.html | 6 +- .../entity/alias/entity-alias-dialog.tpl.html | 10 +-- .../app/entity/alias/entity-aliases.tpl.html | 16 ++-- .../attribute/add-attribute-dialog.tpl.html | 12 +-- .../add-widget-to-dashboard-dialog.tpl.html | 12 +-- .../entity/attribute/attribute-table.tpl.html | 2 +- .../entity/entity-autocomplete.directive.js | 2 +- ui/src/app/entity/entity-list.directive.js | 2 +- .../entity-subtype-autocomplete.directive.js | 4 +- .../entity/entity-subtype-list.directive.js | 4 +- .../entity/entity-subtype-select.directive.js | 4 +- .../entity/relation/relation-dialog.tpl.html | 12 +-- .../entity/relation/relation-filters.tpl.html | 4 +- .../entity/relation/relation-table.tpl.html | 2 +- .../app/event/event-content-dialog.tpl.html | 2 +- ui/src/app/event/event-table.tpl.html | 6 +- .../app/extension/extension-dialog.tpl.html | 8 +- .../app/import-export/import-dialog.tpl.html | 10 +-- ui/src/app/layout/home.tpl.html | 2 +- ui/src/app/login/create-password.tpl.html | 2 +- ui/src/app/login/login.tpl.html | 2 +- .../app/login/reset-password-request.tpl.html | 2 +- ui/src/app/login/reset-password.tpl.html | 2 +- ui/src/app/plugin/add-plugin.tpl.html | 8 +- ui/src/app/plugin/plugin-fieldset.tpl.html | 8 +- ui/src/app/profile/change-password.tpl.html | 8 +- ui/src/app/profile/profile.tpl.html | 10 +-- ui/src/app/rule/add-rule.tpl.html | 8 +- ui/src/app/rule/rule-fieldset.tpl.html | 10 +-- ui/src/app/tenant/add-tenant.tpl.html | 8 +- ui/src/app/tenant/tenant-fieldset.tpl.html | 2 +- ui/src/app/user/add-user.tpl.html | 8 +- ui/src/app/user/user-fieldset.tpl.html | 10 +-- ui/src/app/widget/add-widgets-bundle.tpl.html | 8 +- .../app/widget/save-widget-type-as.tpl.html | 8 +- ui/src/app/widget/select-widget-type.tpl.html | 8 +- ui/src/app/widget/widget-editor.tpl.html | 4 +- ui/src/app/widget/widget-library.tpl.html | 10 +-- .../widget/widgets-bundle-fieldset.tpl.html | 2 +- 96 files changed, 379 insertions(+), 369 deletions(-) diff --git a/ui/src/app/admin/general-settings.tpl.html b/ui/src/app/admin/general-settings.tpl.html index f6286511b6..50342d3afd 100644 --- a/ui/src/app/admin/general-settings.tpl.html +++ b/ui/src/app/admin/general-settings.tpl.html @@ -22,11 +22,11 @@ admin.general-settings - - + +
-
+
@@ -35,7 +35,7 @@
- {{'action.save' | translate}} + {{'action.save' | translate}}
diff --git a/ui/src/app/admin/outgoing-mail-settings.tpl.html b/ui/src/app/admin/outgoing-mail-settings.tpl.html index fd8476a499..3c59593ff7 100644 --- a/ui/src/app/admin/outgoing-mail-settings.tpl.html +++ b/ui/src/app/admin/outgoing-mail-settings.tpl.html @@ -24,11 +24,11 @@
- - + +
-
+
@@ -38,7 +38,7 @@ - + {{smtpProtocol.toUpperCase()}} @@ -78,7 +78,7 @@
admin.timeout-invalid
- {{ 'admin.enable-tls' | translate }} @@ -89,8 +89,8 @@
- {{'admin.send-test-mail' | translate}} - {{'action.save' | translate}} + {{'admin.send-test-mail' | translate}} + {{'action.save' | translate}}
diff --git a/ui/src/app/alarm/alarm-details-dialog.tpl.html b/ui/src/app/alarm/alarm-details-dialog.tpl.html index b090052228..cc213d1178 100644 --- a/ui/src/app/alarm/alarm-details-dialog.tpl.html +++ b/ui/src/app/alarm/alarm-details-dialog.tpl.html @@ -87,7 +87,7 @@ {{ 'alarm.acknowledge' | translate }} @@ -95,12 +95,12 @@ {{ 'alarm.clear' | translate }} - {{ 'action.close' | + {{ 'action.close' | translate }} diff --git a/ui/src/app/alarm/alarm-table.tpl.html b/ui/src/app/alarm/alarm-table.tpl.html index c32e39a2d2..98d42a2a93 100644 --- a/ui/src/app/alarm/alarm-table.tpl.html +++ b/ui/src/app/alarm/alarm-table.tpl.html @@ -19,7 +19,7 @@
- + {{ ('alarm.search-status.' + searchStatus) | translate }} @@ -31,8 +31,8 @@ - + tenantService.getTenant(id, config), entityIds); break; case types.entityType.customer: - promise = getEntitiesByIdsPromise(customerService.getCustomer, entityIds); + promise = getEntitiesByIdsPromise( + (id) => customerService.getCustomer(id, config), entityIds); break; case types.entityType.rule: - promise = getEntitiesByIdsPromise(ruleService.getRule, entityIds); + promise = getEntitiesByIdsPromise( + (id) => ruleService.getRule(id, config), entityIds); break; case types.entityType.plugin: - promise = getEntitiesByIdsPromise(pluginService.getPlugin, entityIds); + promise = getEntitiesByIdsPromise( + (id) => pluginService.getPlugin(id, config), entityIds); break; case types.entityType.dashboard: - promise = getEntitiesByIdsPromise(dashboardService.getDashboardInfo, entityIds); + promise = getEntitiesByIdsPromise( + (id) => dashboardService.getDashboardInfo(id, config), entityIds); break; case types.entityType.user: - promise = getEntitiesByIdsPromise(userService.getUser, entityIds); + promise = getEntitiesByIdsPromise( + (id) => userService.getUser(id, true, config), entityIds); break; case types.entityType.alarm: $log.error('Get Alarm Entity is not implemented!'); @@ -178,11 +184,11 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device return deferred.promise; } - function getSingleTenantByPageLinkPromise(pageLink) { + function getSingleTenantByPageLinkPromise(pageLink, config) { var user = userService.getCurrentUser(); var tenantId = user.tenantId; var deferred = $q.defer(); - tenantService.getTenant(tenantId).then( + tenantService.getTenant(tenantId, config).then( function success(tenant) { var tenantName = tenant.name; var result = { @@ -202,11 +208,11 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device return deferred.promise; } - function getSingleCustomerByPageLinkPromise(pageLink) { + function getSingleCustomerByPageLinkPromise(pageLink, config) { var user = userService.getCurrentUser(); var customerId = user.customerId; var deferred = $q.defer(); - customerService.getCustomer(customerId).then( + customerService.getCustomer(customerId, config).then( function success(customer) { var customerName = customer.name; var result = { @@ -247,29 +253,29 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device break; case types.entityType.tenant: if (user.authority === 'TENANT_ADMIN') { - promise = getSingleTenantByPageLinkPromise(pageLink); + promise = getSingleTenantByPageLinkPromise(pageLink, config); } else { - promise = tenantService.getTenants(pageLink); + promise = tenantService.getTenants(pageLink, config); } break; case types.entityType.customer: if (user.authority === 'CUSTOMER_USER') { - promise = getSingleCustomerByPageLinkPromise(pageLink); + promise = getSingleCustomerByPageLinkPromise(pageLink, config); } else { - promise = customerService.getCustomers(pageLink); + promise = customerService.getCustomers(pageLink, config); } break; case types.entityType.rule: - promise = ruleService.getAllRules(pageLink); + promise = ruleService.getAllRules(pageLink, config); break; case types.entityType.plugin: - promise = pluginService.getAllPlugins(pageLink); + promise = pluginService.getAllPlugins(pageLink, config); break; case types.entityType.dashboard: if (user.authority === 'CUSTOMER_USER') { - promise = dashboardService.getCustomerDashboards(customerId, pageLink, false); + promise = dashboardService.getCustomerDashboards(customerId, pageLink, false, config); } else { - promise = dashboardService.getTenantDashboards(pageLink, false); + promise = dashboardService.getTenantDashboards(pageLink, false, config); } break; case types.entityType.user: @@ -426,7 +432,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device var stateEntityId = getStateEntityId(filter, stateParams); switch (filter.type) { case types.aliasFilterType.singleEntity.value: - getEntity(filter.singleEntity.entityType, filter.singleEntity.id).then( + getEntity(filter.singleEntity.entityType, filter.singleEntity.id, {ignoreLoading: true}).then( function success(entity) { result.entities = entitiesToEntitiesInfo([entity]); deferred.resolve(result); @@ -437,7 +443,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device ); break; case types.aliasFilterType.entityList.value: - getEntities(filter.entityType, filter.entityList).then( + getEntities(filter.entityType, filter.entityList, {ignoreLoading: true}).then( function success(entities) { if (entities && entities.length || !failOnEmpty) { result.entities = entitiesToEntitiesInfo(entities); @@ -452,7 +458,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device ); break; case types.aliasFilterType.entityName.value: - getEntitiesByNameFilter(filter.entityType, filter.entityNameFilter, maxItems).then( + getEntitiesByNameFilter(filter.entityType, filter.entityNameFilter, maxItems, {ignoreLoading: true}).then( function success(entities) { if (entities && entities.length || !failOnEmpty) { result.entities = entitiesToEntitiesInfo(entities); @@ -469,7 +475,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device case types.aliasFilterType.stateEntity.value: result.stateEntity = true; if (stateEntityId) { - getEntity(stateEntityId.entityType, stateEntityId.id).then( + getEntity(stateEntityId.entityType, stateEntityId.id, {ignoreLoading: true}).then( function success(entity) { result.entities = entitiesToEntitiesInfo([entity]); deferred.resolve(result); @@ -483,7 +489,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device } break; case types.aliasFilterType.assetType.value: - getEntitiesByNameFilter(types.entityType.asset, filter.assetNameFilter, maxItems, null, filter.assetType).then( + getEntitiesByNameFilter(types.entityType.asset, filter.assetNameFilter, maxItems, {ignoreLoading: true}, filter.assetType).then( function success(entities) { if (entities && entities.length || !failOnEmpty) { result.entities = entitiesToEntitiesInfo(entities); @@ -498,7 +504,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device ); break; case types.aliasFilterType.deviceType.value: - getEntitiesByNameFilter(types.entityType.device, filter.deviceNameFilter, maxItems, null, filter.deviceType).then( + getEntitiesByNameFilter(types.entityType.device, filter.deviceNameFilter, maxItems, {ignoreLoading: true}, filter.deviceType).then( function success(entities) { if (entities && entities.length || !failOnEmpty) { result.entities = entitiesToEntitiesInfo(entities); @@ -533,7 +539,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device filters: filter.filters }; searchQuery.parameters.maxLevel = filter.maxLevel && filter.maxLevel > 0 ? filter.maxLevel : -1; - entityRelationService.findInfoByQuery(searchQuery).then( + entityRelationService.findInfoByQuery(searchQuery, {ignoreLoading: true}).then( function success(allRelations) { if (allRelations && allRelations.length || !failOnEmpty) { if (angular.isDefined(maxItems) && maxItems > 0 && allRelations) { @@ -577,10 +583,10 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device var findByQueryPromise; if (filter.type == types.aliasFilterType.assetSearchQuery.value) { searchQuery.assetTypes = filter.assetTypes; - findByQueryPromise = assetService.findByQuery(searchQuery, false); + findByQueryPromise = assetService.findByQuery(searchQuery, false, {ignoreLoading: true}); } else if (filter.type == types.aliasFilterType.deviceSearchQuery.value) { searchQuery.deviceTypes = filter.deviceTypes; - findByQueryPromise = deviceService.findByQuery(searchQuery, false); + findByQueryPromise = deviceService.findByQuery(searchQuery, false, {ignoreLoading: true}); } findByQueryPromise.then( function success(entities) { @@ -762,7 +768,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device return deferred.promise; } - function getEntityKeys(entityType, entityId, query, type) { + function getEntityKeys(entityType, entityId, query, type, config) { var deferred = $q.defer(); var url = '/api/plugins/telemetry/' + entityType + '/' + entityId + '/keys/'; if (type === types.dataKeyType.timeseries) { @@ -770,7 +776,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device } else if (type === types.dataKeyType.attribute) { url += 'attributes'; } - $http.get(url, null).then(function success(response) { + $http.get(url, config).then(function success(response) { var result = []; if (response.data) { if (query) { diff --git a/ui/src/app/api/plugin.service.js b/ui/src/app/api/plugin.service.js index 55429ce1cf..28f63def4e 100644 --- a/ui/src/app/api/plugin.service.js +++ b/ui/src/app/api/plugin.service.js @@ -50,11 +50,11 @@ function PluginService($http, $q, $rootScope, $filter, componentDescriptorServic tenantPlugins = undefined; } - function loadPluginsCache() { + function loadPluginsCache(config) { var deferred = $q.defer(); if (!allPlugins) { var url = '/api/plugins'; - $http.get(url, null).then(function success(response) { + $http.get(url, config).then(function success(response) { componentDescriptorService.getComponentDescriptorsByType(types.componentType.plugin).then( function success(pluginComponents) { allPlugins = response.data; @@ -93,9 +93,9 @@ function PluginService($http, $q, $rootScope, $filter, componentDescriptorServic return deferred.promise; } - function getSystemPlugins(pageLink) { + function getSystemPlugins(pageLink, config) { var deferred = $q.defer(); - loadPluginsCache().then( + loadPluginsCache(config).then( function success() { utils.filterSearchTextEntities(systemPlugins, 'name', pageLink, deferred); }, @@ -106,9 +106,9 @@ function PluginService($http, $q, $rootScope, $filter, componentDescriptorServic return deferred.promise; } - function getTenantPlugins(pageLink) { + function getTenantPlugins(pageLink, config) { var deferred = $q.defer(); - loadPluginsCache().then( + loadPluginsCache(config).then( function success() { utils.filterSearchTextEntities(tenantPlugins, 'name', pageLink, deferred); }, @@ -119,9 +119,9 @@ function PluginService($http, $q, $rootScope, $filter, componentDescriptorServic return deferred.promise; } - function getAllActionPlugins(pageLink) { + function getAllActionPlugins(pageLink, config) { var deferred = $q.defer(); - loadPluginsCache().then( + loadPluginsCache(config).then( function success() { utils.filterSearchTextEntities(allActionPlugins, 'name', pageLink, deferred); }, @@ -132,9 +132,9 @@ function PluginService($http, $q, $rootScope, $filter, componentDescriptorServic return deferred.promise; } - function getAllPlugins(pageLink) { + function getAllPlugins(pageLink, config) { var deferred = $q.defer(); - loadPluginsCache().then( + loadPluginsCache(config).then( function success() { utils.filterSearchTextEntities(allPlugins, 'name', pageLink, deferred); }, @@ -156,10 +156,10 @@ function PluginService($http, $q, $rootScope, $filter, componentDescriptorServic return deferred.promise; } - function getPlugin(pluginId) { + function getPlugin(pluginId, config) { var deferred = $q.defer(); var url = '/api/plugin/' + pluginId; - $http.get(url, null).then(function success(response) { + $http.get(url, config).then(function success(response) { deferred.resolve(response.data); }, function fail(response) { deferred.reject(response.data); diff --git a/ui/src/app/api/rule.service.js b/ui/src/app/api/rule.service.js index ee166f69ac..df37305ec5 100644 --- a/ui/src/app/api/rule.service.js +++ b/ui/src/app/api/rule.service.js @@ -47,11 +47,11 @@ function RuleService($http, $q, $rootScope, $filter, types, utils) { tenantRules = undefined; } - function loadRulesCache() { + function loadRulesCache(config) { var deferred = $q.defer(); if (!allRules) { var url = '/api/rules'; - $http.get(url, null).then(function success(response) { + $http.get(url, config).then(function success(response) { allRules = response.data; systemRules = []; tenantRules = []; @@ -100,9 +100,9 @@ function RuleService($http, $q, $rootScope, $filter, types, utils) { return deferred.promise; } - function getAllRules(pageLink) { + function getAllRules(pageLink, config) { var deferred = $q.defer(); - loadRulesCache().then( + loadRulesCache(config).then( function success() { utils.filterSearchTextEntities(allRules, 'name', pageLink, deferred); }, @@ -124,10 +124,10 @@ function RuleService($http, $q, $rootScope, $filter, types, utils) { return deferred.promise; } - function getRule(ruleId) { + function getRule(ruleId, config) { var deferred = $q.defer(); var url = '/api/rule/' + ruleId; - $http.get(url, null).then(function success(response) { + $http.get(url, config).then(function success(response) { deferred.resolve(response.data); }, function fail(response) { deferred.reject(response.data); diff --git a/ui/src/app/api/tenant.service.js b/ui/src/app/api/tenant.service.js index 594b543e7d..be04ae970d 100644 --- a/ui/src/app/api/tenant.service.js +++ b/ui/src/app/api/tenant.service.js @@ -29,7 +29,7 @@ function TenantService($http, $q) { return service; - function getTenants (pageLink) { + function getTenants (pageLink, config) { var deferred = $q.defer(); var url = '/api/tenants?limit=' + pageLink.limit; if (angular.isDefined(pageLink.textSearch)) { @@ -41,7 +41,7 @@ function TenantService($http, $q) { if (angular.isDefined(pageLink.textOffset)) { url += '&textOffset=' + pageLink.textOffset; } - $http.get(url, null).then(function success(response) { + $http.get(url, config).then(function success(response) { deferred.resolve(response.data); }, function fail() { deferred.reject(); @@ -49,10 +49,10 @@ function TenantService($http, $q) { return deferred.promise; } - function getTenant (tenantId) { + function getTenant (tenantId, config) { var deferred = $q.defer(); var url = '/api/tenant/' + tenantId; - $http.get(url, null).then(function success(response) { + $http.get(url, config).then(function success(response) { deferred.resolve(response.data); }, function fail(response) { deferred.reject(response.data); diff --git a/ui/src/app/api/user.service.js b/ui/src/app/api/user.service.js index d09387bda8..1a146b4e00 100644 --- a/ui/src/app/api/user.service.js +++ b/ui/src/app/api/user.service.js @@ -421,10 +421,14 @@ function UserService($http, $q, $rootScope, adminService, dashboardService, logi return deferred.promise; } - function getUser(userId, ignoreErrors) { + function getUser(userId, ignoreErrors, config) { var deferred = $q.defer(); var url = '/api/user/' + userId; - $http.get(url, { ignoreErrors: ignoreErrors }).then(function success(response) { + if (!config) { + config = {}; + } + config = Object.assign(config, { ignoreErrors: ignoreErrors }); + $http.get(url, config).then(function success(response) { deferred.resolve(response.data); }, function fail() { deferred.reject(); diff --git a/ui/src/app/api/widget.service.js b/ui/src/app/api/widget.service.js index 3c74ecbb4c..fe95729f3b 100644 --- a/ui/src/app/api/widget.service.js +++ b/ui/src/app/api/widget.service.js @@ -298,11 +298,11 @@ function WidgetService($rootScope, $http, $q, $filter, $ocLazyLoad, $window, $tr tenantWidgetsBundles = undefined; } - function loadWidgetsBundleCache() { + function loadWidgetsBundleCache(config) { var deferred = $q.defer(); if (!allWidgetsBundles) { var url = '/api/widgetsBundles'; - $http.get(url, null).then(function success(response) { + $http.get(url, config).then(function success(response) { allWidgetsBundles = response.data; systemWidgetsBundles = []; tenantWidgetsBundles = []; @@ -326,9 +326,9 @@ function WidgetService($rootScope, $http, $q, $filter, $ocLazyLoad, $window, $tr } - function getSystemWidgetsBundles() { + function getSystemWidgetsBundles(config) { var deferred = $q.defer(); - loadWidgetsBundleCache().then( + loadWidgetsBundleCache(config).then( function success() { deferred.resolve(systemWidgetsBundles); }, @@ -339,9 +339,9 @@ function WidgetService($rootScope, $http, $q, $filter, $ocLazyLoad, $window, $tr return deferred.promise; } - function getTenantWidgetsBundles() { + function getTenantWidgetsBundles(config) { var deferred = $q.defer(); - loadWidgetsBundleCache().then( + loadWidgetsBundleCache(config).then( function success() { deferred.resolve(tenantWidgetsBundles); }, @@ -352,9 +352,9 @@ function WidgetService($rootScope, $http, $q, $filter, $ocLazyLoad, $window, $tr return deferred.promise; } - function getAllWidgetsBundles() { + function getAllWidgetsBundles(config) { var deferred = $q.defer(); - loadWidgetsBundleCache().then( + loadWidgetsBundleCache(config).then( function success() { deferred.resolve(allWidgetsBundles); }, diff --git a/ui/src/app/asset/add-asset.tpl.html b/ui/src/app/asset/add-asset.tpl.html index ce22e4e674..71901e4b6a 100644 --- a/ui/src/app/asset/add-asset.tpl.html +++ b/ui/src/app/asset/add-asset.tpl.html @@ -27,8 +27,8 @@ - - + +
@@ -36,10 +36,10 @@ - + {{ 'action.add' | translate }} - {{ 'action.cancel' | translate }} + {{ 'action.cancel' | translate }} diff --git a/ui/src/app/asset/add-assets-to-customer.tpl.html b/ui/src/app/asset/add-assets-to-customer.tpl.html index 18e23ce0ca..64edcf817a 100644 --- a/ui/src/app/asset/add-assets-to-customer.tpl.html +++ b/ui/src/app/asset/add-assets-to-customer.tpl.html @@ -26,8 +26,8 @@
- - + +
@@ -65,11 +65,11 @@ - {{ 'action.assign' | translate }} - {{ 'action.cancel' | + {{ 'action.cancel' | translate }} diff --git a/ui/src/app/asset/asset-fieldset.tpl.html b/ui/src/app/asset/asset-fieldset.tpl.html index d921b2e6c4..afa14adc07 100644 --- a/ui/src/app/asset/asset-fieldset.tpl.html +++ b/ui/src/app/asset/asset-fieldset.tpl.html @@ -48,7 +48,7 @@ ng-show="!isEdit && isPublic && (assetScope === 'customer' || assetScope === 'tenant')"> {{ 'asset.asset-public' | translate }}
-
+
@@ -57,7 +57,7 @@ - - + +
@@ -65,10 +65,10 @@ - + {{ 'action.assign' | translate }} - {{ 'action.cancel' | + {{ 'action.cancel' | translate }} diff --git a/ui/src/app/component/component-dialog.tpl.html b/ui/src/app/component/component-dialog.tpl.html index 271d818555..841d7ef69a 100644 --- a/ui/src/app/component/component-dialog.tpl.html +++ b/ui/src/app/component/component-dialog.tpl.html @@ -27,11 +27,11 @@
- - + +
-
+
@@ -42,7 +42,7 @@ - + {{componentDescriptor.name}} @@ -57,7 +57,7 @@ @@ -67,11 +67,11 @@ - {{ (vm.isAdd ? 'action.add' : 'action.save') | translate }} - {{ 'action.cancel' | + {{ 'action.cancel' | translate }} diff --git a/ui/src/app/component/component.tpl.html b/ui/src/app/component/component.tpl.html index a9faa7f03f..d007ba6ccd 100644 --- a/ui/src/app/component/component.tpl.html +++ b/ui/src/app/component/component.tpl.html @@ -24,7 +24,7 @@ {{ componentTypeName }}
- @@ -43,7 +43,7 @@ edit - diff --git a/ui/src/app/components/dashboard-autocomplete.directive.js b/ui/src/app/components/dashboard-autocomplete.directive.js index ce7e4770fc..2235b82e95 100644 --- a/ui/src/app/components/dashboard-autocomplete.directive.js +++ b/ui/src/app/components/dashboard-autocomplete.directive.js @@ -48,19 +48,19 @@ function DashboardAutocomplete($compile, $templateCache, $q, dashboardService, u var promise; if (scope.dashboardsScope === 'customer' || userService.getAuthority() === 'CUSTOMER_USER') { if (scope.customerId) { - promise = dashboardService.getCustomerDashboards(scope.customerId, pageLink, false); + promise = dashboardService.getCustomerDashboards(scope.customerId, pageLink, false, {ignoreLoading: true}); } else { promise = $q.when({data: []}); } } else { if (userService.getAuthority() === 'SYS_ADMIN') { if (scope.tenantId) { - promise = dashboardService.getTenantDashboardsByTenantId(scope.tenantId, pageLink); + promise = dashboardService.getTenantDashboardsByTenantId(scope.tenantId, pageLink, {ignoreLoading: true}); } else { promise = $q.when({data: []}); } } else { - promise = dashboardService.getTenantDashboards(pageLink, false); + promise = dashboardService.getTenantDashboards(pageLink, false, {ignoreLoading: true}); } } diff --git a/ui/src/app/components/dashboard-select.directive.js b/ui/src/app/components/dashboard-select.directive.js index d7b32d8b06..ac5cd3d5b1 100644 --- a/ui/src/app/components/dashboard-select.directive.js +++ b/ui/src/app/components/dashboard-select.directive.js @@ -48,12 +48,12 @@ function DashboardSelect($compile, $templateCache, $q, $mdMedia, $mdPanel, $docu var promise; if (scope.dashboardsScope === 'customer' || userService.getAuthority() === 'CUSTOMER_USER') { if (scope.customerId && scope.customerId != types.id.nullUid) { - promise = dashboardService.getCustomerDashboards(scope.customerId, pageLink, false); + promise = dashboardService.getCustomerDashboards(scope.customerId, pageLink, false, {ignoreLoading: true}); } else { promise = $q.when({data: []}); } } else { - promise = dashboardService.getTenantDashboards(pageLink, false); + promise = dashboardService.getTenantDashboards(pageLink, false, {ignoreLoading: true}); } promise.then(function success(result) { diff --git a/ui/src/app/components/datakey-config-dialog.controller.js b/ui/src/app/components/datakey-config-dialog.controller.js index ccaac21235..c4e85946f9 100644 --- a/ui/src/app/components/datakey-config-dialog.controller.js +++ b/ui/src/app/components/datakey-config-dialog.controller.js @@ -43,7 +43,7 @@ function DatakeyConfigDialogController($scope, $mdDialog, $q, entityService, dat function success(aliasInfo) { var entity = aliasInfo.currentEntity; if (entity) { - entityService.getEntityKeys(entity.entityType, entity.id, query, type).then( + entityService.getEntityKeys(entity.entityType, entity.id, query, type, {ignoreLoading: true}).then( function success(keys) { deferred.resolve(keys); }, diff --git a/ui/src/app/components/datakey-config-dialog.tpl.html b/ui/src/app/components/datakey-config-dialog.tpl.html index a55c3161c1..574a7af3c8 100644 --- a/ui/src/app/components/datakey-config-dialog.tpl.html +++ b/ui/src/app/components/datakey-config-dialog.tpl.html @@ -26,8 +26,8 @@
- - + + - + {{ 'action.save' | translate }} - {{ 'action.cancel' | translate }} + {{ 'action.cancel' | translate }} diff --git a/ui/src/app/components/details-sidenav.tpl.html b/ui/src/app/components/details-sidenav.tpl.html index 24c22704d7..934aed37b2 100644 --- a/ui/src/app/components/details-sidenav.tpl.html +++ b/ui/src/app/components/details-sidenav.tpl.html @@ -35,7 +35,7 @@
- @@ -44,7 +44,7 @@ - diff --git a/ui/src/app/components/grid.tpl.html b/ui/src/app/components/grid.tpl.html index 24285d898a..b334567e5a 100644 --- a/ui/src/app/components/grid.tpl.html +++ b/ui/src/app/components/grid.tpl.html @@ -45,7 +45,7 @@ - {{ action.details( rowItem[n] ) }} @@ -81,28 +81,28 @@