Commit 69422fea0e98e1722ee25c1b6503b305c9b7341b
Merge branch 'master' of github.com:volodymyr-babak/thingsboard
Showing
100 changed files
with
532 additions
and
410 deletions
Too many changes to show.
To preserve performance only 100 of 129 files are displayed.
@@ -126,10 +126,6 @@ | @@ -126,10 +126,6 @@ | ||
126 | <artifactId>jjwt</artifactId> | 126 | <artifactId>jjwt</artifactId> |
127 | </dependency> | 127 | </dependency> |
128 | <dependency> | 128 | <dependency> |
129 | - <groupId>joda-time</groupId> | ||
130 | - <artifactId>joda-time</artifactId> | ||
131 | - </dependency> | ||
132 | - <dependency> | ||
133 | <groupId>org.apache.velocity</groupId> | 129 | <groupId>org.apache.velocity</groupId> |
134 | <artifactId>velocity</artifactId> | 130 | <artifactId>velocity</artifactId> |
135 | </dependency> | 131 | </dependency> |
@@ -112,9 +112,9 @@ | @@ -112,9 +112,9 @@ | ||
112 | "templateHtml": "<tb-timeseries-table-widget \n table-id=\"tableId\"\n ctx=\"ctx\">\n</tb-timeseries-table-widget>", | 112 | "templateHtml": "<tb-timeseries-table-widget \n table-id=\"tableId\"\n ctx=\"ctx\">\n</tb-timeseries-table-widget>", |
113 | "templateCss": "", | 113 | "templateCss": "", |
114 | "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}", | 114 | "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}", |
115 | - "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}", | 115 | + "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}", |
116 | "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}", | 116 | "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}", |
117 | - "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}" | 117 | + "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\":{}}" |
118 | } | 118 | } |
119 | } | 119 | } |
120 | ] | 120 | ] |
@@ -62,6 +62,7 @@ public final class PluginProcessingContext implements PluginContext { | @@ -62,6 +62,7 @@ public final class PluginProcessingContext implements PluginContext { | ||
62 | private static final Executor executor = Executors.newSingleThreadExecutor(); | 62 | private static final Executor executor = Executors.newSingleThreadExecutor(); |
63 | public static final String CUSTOMER_USER_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION = "Customer user is not allowed to perform this operation!"; | 63 | public static final String CUSTOMER_USER_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION = "Customer user is not allowed to perform this operation!"; |
64 | public static final String SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION = "System administrator is not allowed to perform this operation!"; | 64 | public static final String SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION = "System administrator is not allowed to perform this operation!"; |
65 | + public static final String DEVICE_WITH_REQUESTED_ID_NOT_FOUND = "Device with requested id wasn't found!"; | ||
65 | 66 | ||
66 | private final SharedPluginProcessingContext pluginCtx; | 67 | private final SharedPluginProcessingContext pluginCtx; |
67 | private final Optional<PluginApiCallSecurityContext> securityCtx; | 68 | private final Optional<PluginApiCallSecurityContext> securityCtx; |
@@ -309,7 +310,7 @@ public final class PluginProcessingContext implements PluginContext { | @@ -309,7 +310,7 @@ public final class PluginProcessingContext implements PluginContext { | ||
309 | ListenableFuture<Device> deviceFuture = pluginCtx.deviceService.findDeviceByIdAsync(new DeviceId(entityId.getId())); | 310 | ListenableFuture<Device> deviceFuture = pluginCtx.deviceService.findDeviceByIdAsync(new DeviceId(entityId.getId())); |
310 | Futures.addCallback(deviceFuture, getCallback(callback, device -> { | 311 | Futures.addCallback(deviceFuture, getCallback(callback, device -> { |
311 | if (device == null) { | 312 | if (device == null) { |
312 | - return ValidationResult.entityNotFound("Device with requested id wasn't found!"); | 313 | + return ValidationResult.entityNotFound(DEVICE_WITH_REQUESTED_ID_NOT_FOUND); |
313 | } else { | 314 | } else { |
314 | if (!device.getTenantId().equals(ctx.getTenantId())) { | 315 | if (!device.getTenantId().equals(ctx.getTenantId())) { |
315 | return ValidationResult.accessDenied("Device doesn't belong to the current Tenant!"); | 316 | return ValidationResult.accessDenied("Device doesn't belong to the current Tenant!"); |
@@ -47,8 +47,8 @@ public class WebSocketConfiguration implements WebSocketConfigurer { | @@ -47,8 +47,8 @@ public class WebSocketConfiguration implements WebSocketConfigurer { | ||
47 | @Bean | 47 | @Bean |
48 | public ServletServerContainerFactoryBean createWebSocketContainer() { | 48 | public ServletServerContainerFactoryBean createWebSocketContainer() { |
49 | ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean(); | 49 | ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean(); |
50 | - container.setMaxTextMessageBufferSize(8192); | ||
51 | - container.setMaxBinaryMessageBufferSize(8192); | 50 | + container.setMaxTextMessageBufferSize(32768); |
51 | + container.setMaxBinaryMessageBufferSize(32768); | ||
52 | return container; | 52 | return container; |
53 | } | 53 | } |
54 | 54 |
@@ -82,7 +82,7 @@ public class CustomerController extends BaseController { | @@ -82,7 +82,7 @@ public class CustomerController extends BaseController { | ||
82 | 82 | ||
83 | @PreAuthorize("hasAuthority('TENANT_ADMIN')") | 83 | @PreAuthorize("hasAuthority('TENANT_ADMIN')") |
84 | @RequestMapping(value = "/customer", method = RequestMethod.POST) | 84 | @RequestMapping(value = "/customer", method = RequestMethod.POST) |
85 | - @ResponseBody | 85 | + @ResponseBody |
86 | public Customer saveCustomer(@RequestBody Customer customer) throws ThingsboardException { | 86 | public Customer saveCustomer(@RequestBody Customer customer) throws ThingsboardException { |
87 | try { | 87 | try { |
88 | customer.setTenantId(getCurrentUser().getTenantId()); | 88 | customer.setTenantId(getCurrentUser().getTenantId()); |
@@ -107,7 +107,7 @@ public class CustomerController extends BaseController { | @@ -107,7 +107,7 @@ public class CustomerController extends BaseController { | ||
107 | } | 107 | } |
108 | 108 | ||
109 | @PreAuthorize("hasAuthority('TENANT_ADMIN')") | 109 | @PreAuthorize("hasAuthority('TENANT_ADMIN')") |
110 | - @RequestMapping(value = "/customers", params = { "limit" }, method = RequestMethod.GET) | 110 | + @RequestMapping(value = "/customers", params = {"limit"}, method = RequestMethod.GET) |
111 | @ResponseBody | 111 | @ResponseBody |
112 | public TextPageData<Customer> getCustomers(@RequestParam int limit, | 112 | public TextPageData<Customer> getCustomers(@RequestParam int limit, |
113 | @RequestParam(required = false) String textSearch, | 113 | @RequestParam(required = false) String textSearch, |
@@ -122,4 +122,16 @@ public class CustomerController extends BaseController { | @@ -122,4 +122,16 @@ public class CustomerController extends BaseController { | ||
122 | } | 122 | } |
123 | } | 123 | } |
124 | 124 | ||
125 | + @PreAuthorize("hasAuthority('TENANT_ADMIN')") | ||
126 | + @RequestMapping(value = "/tenant/customers", params = {"customerTitle"}, method = RequestMethod.GET) | ||
127 | + @ResponseBody | ||
128 | + public Customer getTenantCustomer( | ||
129 | + @RequestParam String customerTitle) throws ThingsboardException { | ||
130 | + try { | ||
131 | + TenantId tenantId = getCurrentUser().getTenantId(); | ||
132 | + return checkNotNull(customerService.findCustomerByTenantIdAndTitle(tenantId, customerTitle)); | ||
133 | + } catch (Exception e) { | ||
134 | + throw handleException(e); | ||
135 | + } | ||
136 | + } | ||
125 | } | 137 | } |
@@ -77,7 +77,6 @@ public class PluginWebSocketHandler extends TextWebSocketHandler implements Plug | @@ -77,7 +77,6 @@ public class PluginWebSocketHandler extends TextWebSocketHandler implements Plug | ||
77 | log.warn("[{}] Failed to find session", session.getId()); | 77 | log.warn("[{}] Failed to find session", session.getId()); |
78 | session.close(CloseStatus.SERVER_ERROR.withReason("Session not found!")); | 78 | session.close(CloseStatus.SERVER_ERROR.withReason("Session not found!")); |
79 | } | 79 | } |
80 | - session.sendMessage(message); | ||
81 | } catch (IOException e) { | 80 | } catch (IOException e) { |
82 | log.warn("IO error", e); | 81 | log.warn("IO error", e); |
83 | } | 82 | } |
@@ -96,7 +96,7 @@ public class DefaultMailService implements MailService { | @@ -96,7 +96,7 @@ public class DefaultMailService implements MailService { | ||
96 | javaMailProperties.put(MAIL_PROP + protocol + ".port", jsonConfig.get("smtpPort").asText()); | 96 | javaMailProperties.put(MAIL_PROP + protocol + ".port", jsonConfig.get("smtpPort").asText()); |
97 | javaMailProperties.put(MAIL_PROP + protocol + ".timeout", jsonConfig.get("timeout").asText()); | 97 | javaMailProperties.put(MAIL_PROP + protocol + ".timeout", jsonConfig.get("timeout").asText()); |
98 | javaMailProperties.put(MAIL_PROP + protocol + ".auth", String.valueOf(StringUtils.isNotEmpty(jsonConfig.get("username").asText()))); | 98 | javaMailProperties.put(MAIL_PROP + protocol + ".auth", String.valueOf(StringUtils.isNotEmpty(jsonConfig.get("username").asText()))); |
99 | - javaMailProperties.put(MAIL_PROP + protocol + ".starttls.enable", jsonConfig.get("enableTls")); | 99 | + javaMailProperties.put(MAIL_PROP + protocol + ".starttls.enable", jsonConfig.has("enableTls") ? jsonConfig.get("enableTls").asText() : "false"); |
100 | return javaMailProperties; | 100 | return javaMailProperties; |
101 | } | 101 | } |
102 | 102 |
@@ -20,7 +20,6 @@ import io.jsonwebtoken.Jws; | @@ -20,7 +20,6 @@ import io.jsonwebtoken.Jws; | ||
20 | import io.jsonwebtoken.Jwts; | 20 | import io.jsonwebtoken.Jwts; |
21 | import io.jsonwebtoken.SignatureAlgorithm; | 21 | import io.jsonwebtoken.SignatureAlgorithm; |
22 | import org.apache.commons.lang3.StringUtils; | 22 | import org.apache.commons.lang3.StringUtils; |
23 | -import org.joda.time.DateTime; | ||
24 | import org.springframework.beans.factory.annotation.Autowired; | 23 | import org.springframework.beans.factory.annotation.Autowired; |
25 | import org.springframework.stereotype.Component; | 24 | import org.springframework.stereotype.Component; |
26 | import org.thingsboard.server.common.data.id.CustomerId; | 25 | import org.thingsboard.server.common.data.id.CustomerId; |
@@ -31,7 +30,9 @@ import org.thingsboard.server.config.JwtSettings; | @@ -31,7 +30,9 @@ import org.thingsboard.server.config.JwtSettings; | ||
31 | import org.thingsboard.server.service.security.model.SecurityUser; | 30 | import org.thingsboard.server.service.security.model.SecurityUser; |
32 | import org.thingsboard.server.service.security.model.UserPrincipal; | 31 | import org.thingsboard.server.service.security.model.UserPrincipal; |
33 | 32 | ||
34 | -import java.util.Arrays; | 33 | +import java.time.ZonedDateTime; |
34 | +import java.util.Collections; | ||
35 | +import java.util.Date; | ||
35 | import java.util.List; | 36 | import java.util.List; |
36 | import java.util.UUID; | 37 | import java.util.UUID; |
37 | import java.util.stream.Collectors; | 38 | import java.util.stream.Collectors; |
@@ -81,13 +82,13 @@ public class JwtTokenFactory { | @@ -81,13 +82,13 @@ public class JwtTokenFactory { | ||
81 | claims.put(CUSTOMER_ID, securityUser.getCustomerId().getId().toString()); | 82 | claims.put(CUSTOMER_ID, securityUser.getCustomerId().getId().toString()); |
82 | } | 83 | } |
83 | 84 | ||
84 | - DateTime currentTime = new DateTime(); | 85 | + ZonedDateTime currentTime = ZonedDateTime.now(); |
85 | 86 | ||
86 | String token = Jwts.builder() | 87 | String token = Jwts.builder() |
87 | .setClaims(claims) | 88 | .setClaims(claims) |
88 | .setIssuer(settings.getTokenIssuer()) | 89 | .setIssuer(settings.getTokenIssuer()) |
89 | - .setIssuedAt(currentTime.toDate()) | ||
90 | - .setExpiration(currentTime.plusSeconds(settings.getTokenExpirationTime()).toDate()) | 90 | + .setIssuedAt(Date.from(currentTime.toInstant())) |
91 | + .setExpiration(Date.from(currentTime.plusSeconds(settings.getTokenExpirationTime()).toInstant())) | ||
91 | .signWith(SignatureAlgorithm.HS512, settings.getTokenSigningKey()) | 92 | .signWith(SignatureAlgorithm.HS512, settings.getTokenSigningKey()) |
92 | .compact(); | 93 | .compact(); |
93 | 94 | ||
@@ -129,11 +130,11 @@ public class JwtTokenFactory { | @@ -129,11 +130,11 @@ public class JwtTokenFactory { | ||
129 | throw new IllegalArgumentException("Cannot create JWT Token without username/email"); | 130 | throw new IllegalArgumentException("Cannot create JWT Token without username/email"); |
130 | } | 131 | } |
131 | 132 | ||
132 | - DateTime currentTime = new DateTime(); | 133 | + ZonedDateTime currentTime = ZonedDateTime.now(); |
133 | 134 | ||
134 | UserPrincipal principal = securityUser.getUserPrincipal(); | 135 | UserPrincipal principal = securityUser.getUserPrincipal(); |
135 | Claims claims = Jwts.claims().setSubject(principal.getValue()); | 136 | Claims claims = Jwts.claims().setSubject(principal.getValue()); |
136 | - claims.put(SCOPES, Arrays.asList(Authority.REFRESH_TOKEN.name())); | 137 | + claims.put(SCOPES, Collections.singletonList(Authority.REFRESH_TOKEN.name())); |
137 | claims.put(USER_ID, securityUser.getId().getId().toString()); | 138 | claims.put(USER_ID, securityUser.getId().getId().toString()); |
138 | claims.put(IS_PUBLIC, principal.getType() == UserPrincipal.Type.PUBLIC_ID); | 139 | claims.put(IS_PUBLIC, principal.getType() == UserPrincipal.Type.PUBLIC_ID); |
139 | 140 | ||
@@ -141,8 +142,8 @@ public class JwtTokenFactory { | @@ -141,8 +142,8 @@ public class JwtTokenFactory { | ||
141 | .setClaims(claims) | 142 | .setClaims(claims) |
142 | .setIssuer(settings.getTokenIssuer()) | 143 | .setIssuer(settings.getTokenIssuer()) |
143 | .setId(UUID.randomUUID().toString()) | 144 | .setId(UUID.randomUUID().toString()) |
144 | - .setIssuedAt(currentTime.toDate()) | ||
145 | - .setExpiration(currentTime.plusSeconds(settings.getRefreshTokenExpTime()).toDate()) | 145 | + .setIssuedAt(Date.from(currentTime.toInstant())) |
146 | + .setExpiration(Date.from(currentTime.plusSeconds(settings.getRefreshTokenExpTime()).toInstant())) | ||
146 | .signWith(SignatureAlgorithm.HS512, settings.getTokenSigningKey()) | 147 | .signWith(SignatureAlgorithm.HS512, settings.getTokenSigningKey()) |
147 | .compact(); | 148 | .compact(); |
148 | 149 |
@@ -107,6 +107,11 @@ public abstract class AbstractControllerTest { | @@ -107,6 +107,11 @@ public abstract class AbstractControllerTest { | ||
107 | protected static final String CUSTOMER_USER_EMAIL = "testcustomer@thingsboard.org"; | 107 | protected static final String CUSTOMER_USER_EMAIL = "testcustomer@thingsboard.org"; |
108 | private static final String CUSTOMER_USER_PASSWORD = "customer"; | 108 | private static final String CUSTOMER_USER_PASSWORD = "customer"; |
109 | 109 | ||
110 | + /** See {@link org.springframework.test.web.servlet.DefaultMvcResult#getAsyncResult(long)} | ||
111 | + * and {@link org.springframework.mock.web.MockAsyncContext#getTimeout()} | ||
112 | + */ | ||
113 | + private static final long DEFAULT_TIMEOUT = -1L; | ||
114 | + | ||
110 | protected MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(), | 115 | protected MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(), |
111 | MediaType.APPLICATION_JSON.getSubtype(), | 116 | MediaType.APPLICATION_JSON.getSubtype(), |
112 | Charset.forName("utf8")); | 117 | Charset.forName("utf8")); |
@@ -366,7 +371,7 @@ public abstract class AbstractControllerTest { | @@ -366,7 +371,7 @@ public abstract class AbstractControllerTest { | ||
366 | } | 371 | } |
367 | 372 | ||
368 | protected <T> T doPost(String urlTemplate, T content, Class<T> responseClass, ResultMatcher resultMatcher, String... params) throws Exception { | 373 | protected <T> T doPost(String urlTemplate, T content, Class<T> responseClass, ResultMatcher resultMatcher, String... params) throws Exception { |
369 | - return readResponse(doPost(urlTemplate, params).andExpect(resultMatcher), responseClass); | 374 | + return readResponse(doPost(urlTemplate, content, params).andExpect(resultMatcher), responseClass); |
370 | } | 375 | } |
371 | 376 | ||
372 | protected <T> T doPost(String urlTemplate, T content, Class<T> responseClass, String... params) throws Exception { | 377 | protected <T> T doPost(String urlTemplate, T content, Class<T> responseClass, String... params) throws Exception { |
@@ -374,7 +379,11 @@ public abstract class AbstractControllerTest { | @@ -374,7 +379,11 @@ public abstract class AbstractControllerTest { | ||
374 | } | 379 | } |
375 | 380 | ||
376 | protected <T> T doPostAsync(String urlTemplate, T content, Class<T> responseClass, ResultMatcher resultMatcher, String... params) throws Exception { | 381 | protected <T> T doPostAsync(String urlTemplate, T content, Class<T> responseClass, ResultMatcher resultMatcher, String... params) throws Exception { |
377 | - return readResponse(doPostAsync(urlTemplate, content, params).andExpect(resultMatcher), responseClass); | 382 | + return readResponse(doPostAsync(urlTemplate, content, DEFAULT_TIMEOUT, params).andExpect(resultMatcher), responseClass); |
383 | + } | ||
384 | + | ||
385 | + protected <T> T doPostAsync(String urlTemplate, T content, Class<T> responseClass, ResultMatcher resultMatcher, Long timeout, String... params) throws Exception { | ||
386 | + return readResponse(doPostAsync(urlTemplate, content, timeout, params).andExpect(resultMatcher), responseClass); | ||
378 | } | 387 | } |
379 | 388 | ||
380 | protected <T> T doDelete(String urlTemplate, Class<T> responseClass, String... params) throws Exception { | 389 | protected <T> T doDelete(String urlTemplate, Class<T> responseClass, String... params) throws Exception { |
@@ -396,12 +405,13 @@ public abstract class AbstractControllerTest { | @@ -396,12 +405,13 @@ public abstract class AbstractControllerTest { | ||
396 | return mockMvc.perform(postRequest); | 405 | return mockMvc.perform(postRequest); |
397 | } | 406 | } |
398 | 407 | ||
399 | - protected <T> ResultActions doPostAsync(String urlTemplate, T content, String... params) throws Exception { | 408 | + protected <T> ResultActions doPostAsync(String urlTemplate, T content, Long timeout, String... params) throws Exception { |
400 | MockHttpServletRequestBuilder postRequest = post(urlTemplate); | 409 | MockHttpServletRequestBuilder postRequest = post(urlTemplate); |
401 | setJwtToken(postRequest); | 410 | setJwtToken(postRequest); |
402 | String json = json(content); | 411 | String json = json(content); |
403 | postRequest.contentType(contentType).content(json); | 412 | postRequest.contentType(contentType).content(json); |
404 | MvcResult result = mockMvc.perform(postRequest).andReturn(); | 413 | MvcResult result = mockMvc.perform(postRequest).andReturn(); |
414 | + result.getAsyncResult(timeout); | ||
405 | return mockMvc.perform(asyncDispatch(result)); | 415 | return mockMvc.perform(asyncDispatch(result)); |
406 | } | 416 | } |
407 | 417 | ||
@@ -414,8 +424,8 @@ public abstract class AbstractControllerTest { | @@ -414,8 +424,8 @@ public abstract class AbstractControllerTest { | ||
414 | 424 | ||
415 | protected void populateParams(MockHttpServletRequestBuilder request, String... params) { | 425 | protected void populateParams(MockHttpServletRequestBuilder request, String... params) { |
416 | if (params != null && params.length > 0) { | 426 | if (params != null && params.length > 0) { |
417 | - Assert.assertEquals(params.length % 2, 0); | ||
418 | - MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<String, String>(); | 427 | + Assert.assertEquals(0, params.length % 2); |
428 | + MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>(); | ||
419 | for (int i = 0; i < params.length; i += 2) { | 429 | for (int i = 0; i < params.length; i += 2) { |
420 | paramsMap.add(params[i], params[i + 1]); | 430 | paramsMap.add(params[i], params[i + 1]); |
421 | } | 431 | } |
@@ -15,21 +15,23 @@ | @@ -15,21 +15,23 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.mqtt.rpc; | 16 | package org.thingsboard.server.mqtt.rpc; |
17 | 17 | ||
18 | +import java.util.Arrays; | ||
19 | + | ||
20 | +import com.datastax.driver.core.utils.UUIDs; | ||
21 | +import com.fasterxml.jackson.core.type.TypeReference; | ||
18 | import lombok.extern.slf4j.Slf4j; | 22 | import lombok.extern.slf4j.Slf4j; |
19 | import org.apache.commons.lang3.StringUtils; | 23 | import org.apache.commons.lang3.StringUtils; |
20 | import org.eclipse.paho.client.mqttv3.*; | 24 | import org.eclipse.paho.client.mqttv3.*; |
21 | import org.junit.*; | 25 | import org.junit.*; |
22 | -import org.springframework.http.HttpStatus; | ||
23 | -import org.springframework.web.client.HttpClientErrorException; | 26 | +import org.thingsboard.server.actors.plugin.PluginProcessingContext; |
24 | import org.thingsboard.server.common.data.Device; | 27 | import org.thingsboard.server.common.data.Device; |
25 | import org.thingsboard.server.common.data.Tenant; | 28 | import org.thingsboard.server.common.data.Tenant; |
26 | import org.thingsboard.server.common.data.User; | 29 | import org.thingsboard.server.common.data.User; |
30 | +import org.thingsboard.server.common.data.page.TextPageData; | ||
31 | +import org.thingsboard.server.common.data.plugin.PluginMetaData; | ||
27 | import org.thingsboard.server.common.data.security.Authority; | 32 | import org.thingsboard.server.common.data.security.Authority; |
28 | import org.thingsboard.server.common.data.security.DeviceCredentials; | 33 | import org.thingsboard.server.common.data.security.DeviceCredentials; |
29 | import org.thingsboard.server.controller.AbstractControllerTest; | 34 | import org.thingsboard.server.controller.AbstractControllerTest; |
30 | -import org.thingsboard.server.dao.service.DaoNoSqlTest; | ||
31 | - | ||
32 | -import java.util.UUID; | ||
33 | 35 | ||
34 | import static org.junit.Assert.assertEquals; | 36 | import static org.junit.Assert.assertEquals; |
35 | import static org.junit.Assert.assertNotNull; | 37 | import static org.junit.Assert.assertNotNull; |
@@ -42,15 +44,19 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. | @@ -42,15 +44,19 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. | ||
42 | public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractControllerTest { | 44 | public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractControllerTest { |
43 | 45 | ||
44 | private static final String MQTT_URL = "tcp://localhost:1883"; | 46 | private static final String MQTT_URL = "tcp://localhost:1883"; |
45 | - private static final String FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED = "HttpClientErrorException expected, but not encountered"; | 47 | + private static final Long TIME_TO_HANDLE_REQUEST = 500L; |
46 | 48 | ||
47 | private Tenant savedTenant; | 49 | private Tenant savedTenant; |
48 | private User tenantAdmin; | 50 | private User tenantAdmin; |
51 | + private Long asyncContextTimeoutToUseRpcPlugin; | ||
52 | + | ||
49 | 53 | ||
50 | @Before | 54 | @Before |
51 | public void beforeTest() throws Exception { | 55 | public void beforeTest() throws Exception { |
52 | loginSysAdmin(); | 56 | loginSysAdmin(); |
53 | 57 | ||
58 | + asyncContextTimeoutToUseRpcPlugin = getAsyncContextTimeoutToUseRpcPlugin(); | ||
59 | + | ||
54 | Tenant tenant = new Tenant(); | 60 | Tenant tenant = new Tenant(); |
55 | tenant.setTitle("My tenant"); | 61 | tenant.setTitle("My tenant"); |
56 | savedTenant = doPost("/api/tenant", tenant, Tenant.class); | 62 | savedTenant = doPost("/api/tenant", tenant, Tenant.class); |
@@ -70,8 +76,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | @@ -70,8 +76,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | ||
70 | public void afterTest() throws Exception { | 76 | public void afterTest() throws Exception { |
71 | loginSysAdmin(); | 77 | loginSysAdmin(); |
72 | if (savedTenant != null) { | 78 | if (savedTenant != null) { |
73 | - doDelete("/api/tenant/" + savedTenant.getId().getId().toString()) | ||
74 | - .andExpect(status().isOk()); | 79 | + doDelete("/api/tenant/" + savedTenant.getId().getId().toString()).andExpect(status().isOk()); |
75 | } | 80 | } |
76 | } | 81 | } |
77 | 82 | ||
@@ -102,7 +107,6 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | @@ -102,7 +107,6 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | ||
102 | } | 107 | } |
103 | 108 | ||
104 | @Test | 109 | @Test |
105 | - @Ignore // TODO: figure out the right error code for this case. Ignored due to failure: expected 408 but was: 200 | ||
106 | public void testServerMqttOneWayRpcDeviceOffline() throws Exception { | 110 | public void testServerMqttOneWayRpcDeviceOffline() throws Exception { |
107 | Device device = new Device(); | 111 | Device device = new Device(); |
108 | device.setName("Test One-Way Server-Side RPC Device Offline"); | 112 | device.setName("Test One-Way Server-Side RPC Device Offline"); |
@@ -115,29 +119,19 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | @@ -115,29 +119,19 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | ||
115 | 119 | ||
116 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; | 120 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; |
117 | String deviceId = savedDevice.getId().getId().toString(); | 121 | String deviceId = savedDevice.getId().getId().toString(); |
118 | - try { | ||
119 | - doPost("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().is(408)); | ||
120 | - Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED); | ||
121 | - } catch (HttpClientErrorException e) { | ||
122 | - log.error(e.getMessage(), e); | ||
123 | - Assert.assertEquals(HttpStatus.REQUEST_TIMEOUT, e.getStatusCode()); | ||
124 | - Assert.assertEquals("408 null", e.getMessage()); | ||
125 | - } | 122 | + |
123 | + doPostAsync("/api/plugins/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isRequestTimeout(), | ||
124 | + asyncContextTimeoutToUseRpcPlugin); | ||
126 | } | 125 | } |
127 | 126 | ||
128 | @Test | 127 | @Test |
129 | - @Ignore // TODO: figure out the right error code for this case. Ignored due to failure: expected 400 (404?) but was: 401 | ||
130 | public void testServerMqttOneWayRpcDeviceDoesNotExist() throws Exception { | 128 | public void testServerMqttOneWayRpcDeviceDoesNotExist() throws Exception { |
131 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; | 129 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; |
132 | - String nonExistentDeviceId = UUID.randomUUID().toString(); | ||
133 | - try { | ||
134 | - doPostAsync("/api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, status().is(400)); | ||
135 | - Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED); | ||
136 | - } catch (HttpClientErrorException e) { | ||
137 | - log.error(e.getMessage(), e); | ||
138 | - Assert.assertEquals(HttpStatus.BAD_REQUEST, e.getStatusCode()); | ||
139 | - Assert.assertEquals("400 null", e.getMessage()); | ||
140 | - } | 130 | + String nonExistentDeviceId = UUIDs.timeBased().toString(); |
131 | + | ||
132 | + String result = doPostAsync("/api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, | ||
133 | + status().isNotFound()); | ||
134 | + Assert.assertEquals(PluginProcessingContext.DEVICE_WITH_REQUESTED_ID_NOT_FOUND, result); | ||
141 | } | 135 | } |
142 | 136 | ||
143 | @Test | 137 | @Test |
@@ -168,7 +162,6 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | @@ -168,7 +162,6 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | ||
168 | } | 162 | } |
169 | 163 | ||
170 | @Test | 164 | @Test |
171 | - @Ignore // TODO: figure out the right error code for this case. Ignored due to failure: expected 408 but was: 200 | ||
172 | public void testServerMqttTwoWayRpcDeviceOffline() throws Exception { | 165 | public void testServerMqttTwoWayRpcDeviceOffline() throws Exception { |
173 | Device device = new Device(); | 166 | Device device = new Device(); |
174 | device.setName("Test Two-Way Server-Side RPC Device Offline"); | 167 | device.setName("Test Two-Way Server-Side RPC Device Offline"); |
@@ -181,29 +174,19 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | @@ -181,29 +174,19 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | ||
181 | 174 | ||
182 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; | 175 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; |
183 | String deviceId = savedDevice.getId().getId().toString(); | 176 | String deviceId = savedDevice.getId().getId().toString(); |
184 | - try { | ||
185 | - doPost("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().is(408)); | ||
186 | - Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED); | ||
187 | - } catch (HttpClientErrorException e) { | ||
188 | - log.error(e.getMessage(), e); | ||
189 | - Assert.assertEquals(HttpStatus.REQUEST_TIMEOUT, e.getStatusCode()); | ||
190 | - Assert.assertEquals("408 null", e.getMessage()); | ||
191 | - } | 177 | + |
178 | + doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isRequestTimeout(), | ||
179 | + asyncContextTimeoutToUseRpcPlugin); | ||
192 | } | 180 | } |
193 | 181 | ||
194 | @Test | 182 | @Test |
195 | - @Ignore // TODO: figure out the right error code for this case. Ignored due to failure: expected 400 (404?) but was: 401 | ||
196 | public void testServerMqttTwoWayRpcDeviceDoesNotExist() throws Exception { | 183 | public void testServerMqttTwoWayRpcDeviceDoesNotExist() throws Exception { |
197 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; | 184 | String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; |
198 | - String nonExistentDeviceId = UUID.randomUUID().toString(); | ||
199 | - try { | ||
200 | - doPostAsync("/api/plugins/rpc/oneway/" + nonExistentDeviceId, setGpioRequest, String.class, status().is(400)); | ||
201 | - Assert.fail(FAIL_MSG_IF_HTTP_CLIENT_ERROR_NOT_ENCOUNTERED); | ||
202 | - } catch (HttpClientErrorException e) { | ||
203 | - log.error(e.getMessage(), e); | ||
204 | - Assert.assertEquals(HttpStatus.BAD_REQUEST, e.getStatusCode()); | ||
205 | - Assert.assertEquals("400 null", e.getMessage()); | ||
206 | - } | 185 | + String nonExistentDeviceId = UUIDs.timeBased().toString(); |
186 | + | ||
187 | + String result = doPostAsync("/api/plugins/rpc/twoway/" + nonExistentDeviceId, setGpioRequest, String.class, | ||
188 | + status().isNotFound()); | ||
189 | + Assert.assertEquals(PluginProcessingContext.DEVICE_WITH_REQUESTED_ID_NOT_FOUND, result); | ||
207 | } | 190 | } |
208 | 191 | ||
209 | private Device getSavedDevice(Device device) throws Exception { | 192 | private Device getSavedDevice(Device device) throws Exception { |
@@ -214,6 +197,13 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | @@ -214,6 +197,13 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | ||
214 | return doGet("/api/device/" + savedDevice.getId().getId().toString() + "/credentials", DeviceCredentials.class); | 197 | return doGet("/api/device/" + savedDevice.getId().getId().toString() + "/credentials", DeviceCredentials.class); |
215 | } | 198 | } |
216 | 199 | ||
200 | + private Long getAsyncContextTimeoutToUseRpcPlugin() throws Exception { | ||
201 | + TextPageData<PluginMetaData> plugins = doGetTyped("/api/plugin/system?limit=1&textSearch=system rpc plugin", | ||
202 | + new TypeReference<TextPageData<PluginMetaData>>(){}); | ||
203 | + Long systemRpcPluginTimeout = plugins.getData().iterator().next().getConfiguration().get("defaultTimeout").asLong(); | ||
204 | + return systemRpcPluginTimeout + TIME_TO_HANDLE_REQUEST; | ||
205 | + } | ||
206 | + | ||
217 | private static class TestMqttCallback implements MqttCallback { | 207 | private static class TestMqttCallback implements MqttCallback { |
218 | 208 | ||
219 | private final MqttAsyncClient client; | 209 | private final MqttAsyncClient client; |
@@ -228,10 +218,10 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | @@ -228,10 +218,10 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractC | ||
228 | 218 | ||
229 | @Override | 219 | @Override |
230 | public void messageArrived(String requestTopic, MqttMessage mqttMessage) throws Exception { | 220 | public void messageArrived(String requestTopic, MqttMessage mqttMessage) throws Exception { |
231 | - log.info("Message Arrived: " + mqttMessage.getPayload().toString()); | 221 | + log.info("Message Arrived: " + Arrays.toString(mqttMessage.getPayload())); |
232 | MqttMessage message = new MqttMessage(); | 222 | MqttMessage message = new MqttMessage(); |
233 | String responseTopic = requestTopic.replace("request", "response"); | 223 | String responseTopic = requestTopic.replace("request", "response"); |
234 | - message.setPayload("{\"value1\":\"A\", \"value2\":\"B\"}".getBytes()); | 224 | + message.setPayload("{\"value1\":\"A\", \"value2\":\"B\"}".getBytes("UTF-8")); |
235 | client.publish(responseTopic, message); | 225 | client.publish(responseTopic, message); |
236 | } | 226 | } |
237 | 227 |
@@ -22,20 +22,24 @@ import org.thingsboard.server.common.data.id.TenantId; | @@ -22,20 +22,24 @@ import org.thingsboard.server.common.data.id.TenantId; | ||
22 | import org.thingsboard.server.common.data.page.TextPageData; | 22 | import org.thingsboard.server.common.data.page.TextPageData; |
23 | import org.thingsboard.server.common.data.page.TextPageLink; | 23 | import org.thingsboard.server.common.data.page.TextPageLink; |
24 | 24 | ||
25 | +import java.util.Optional; | ||
26 | + | ||
25 | public interface CustomerService { | 27 | public interface CustomerService { |
26 | 28 | ||
27 | Customer findCustomerById(CustomerId customerId); | 29 | Customer findCustomerById(CustomerId customerId); |
28 | 30 | ||
31 | + Optional<Customer> findCustomerByTenantIdAndTitle(TenantId tenantId, String title); | ||
32 | + | ||
29 | ListenableFuture<Customer> findCustomerByIdAsync(CustomerId customerId); | 33 | ListenableFuture<Customer> findCustomerByIdAsync(CustomerId customerId); |
30 | 34 | ||
31 | Customer saveCustomer(Customer customer); | 35 | Customer saveCustomer(Customer customer); |
32 | - | 36 | + |
33 | void deleteCustomer(CustomerId customerId); | 37 | void deleteCustomer(CustomerId customerId); |
34 | 38 | ||
35 | Customer findOrCreatePublicCustomer(TenantId tenantId); | 39 | Customer findOrCreatePublicCustomer(TenantId tenantId); |
36 | 40 | ||
37 | TextPageData<Customer> findCustomersByTenantId(TenantId tenantId, TextPageLink pageLink); | 41 | TextPageData<Customer> findCustomersByTenantId(TenantId tenantId, TextPageLink pageLink); |
38 | - | 42 | + |
39 | void deleteCustomersByTenantId(TenantId tenantId); | 43 | void deleteCustomersByTenantId(TenantId tenantId); |
40 | 44 | ||
41 | } | 45 | } |
@@ -52,6 +52,7 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom | @@ -52,6 +52,7 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom | ||
52 | 52 | ||
53 | private static final String PUBLIC_CUSTOMER_TITLE = "Public"; | 53 | private static final String PUBLIC_CUSTOMER_TITLE = "Public"; |
54 | public static final String INCORRECT_CUSTOMER_ID = "Incorrect customerId "; | 54 | public static final String INCORRECT_CUSTOMER_ID = "Incorrect customerId "; |
55 | + public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; | ||
55 | 56 | ||
56 | @Autowired | 57 | @Autowired |
57 | private CustomerDao customerDao; | 58 | private CustomerDao customerDao; |
@@ -79,6 +80,13 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom | @@ -79,6 +80,13 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom | ||
79 | } | 80 | } |
80 | 81 | ||
81 | @Override | 82 | @Override |
83 | + public Optional<Customer> findCustomerByTenantIdAndTitle(TenantId tenantId, String title) { | ||
84 | + log.trace("Executing findCustomerByTenantIdAndTitle [{}] [{}]", tenantId, title); | ||
85 | + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
86 | + return customerDao.findCustomersByTenantIdAndTitle(tenantId.getId(), title); | ||
87 | + } | ||
88 | + | ||
89 | + @Override | ||
82 | public ListenableFuture<Customer> findCustomerByIdAsync(CustomerId customerId) { | 90 | public ListenableFuture<Customer> findCustomerByIdAsync(CustomerId customerId) { |
83 | log.trace("Executing findCustomerByIdAsync [{}]", customerId); | 91 | log.trace("Executing findCustomerByIdAsync [{}]", customerId); |
84 | validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); | 92 | validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); |
@@ -33,8 +33,7 @@ | @@ -33,8 +33,7 @@ | ||
33 | <spring.version>4.3.4.RELEASE</spring.version> | 33 | <spring.version>4.3.4.RELEASE</spring.version> |
34 | <spring-security.version>4.2.0.RELEASE</spring-security.version> | 34 | <spring-security.version>4.2.0.RELEASE</spring-security.version> |
35 | <jjwt.version>0.7.0</jjwt.version> | 35 | <jjwt.version>0.7.0</jjwt.version> |
36 | - <joda-time.version>2.4</joda-time.version> | ||
37 | - <json-path.version>2.2.0</json-path.version> | 36 | + <json-path.version>2.2.0</json-path.version> |
38 | <junit.version>4.12</junit.version> | 37 | <junit.version>4.12</junit.version> |
39 | <slf4j.version>1.7.7</slf4j.version> | 38 | <slf4j.version>1.7.7</slf4j.version> |
40 | <logback.version>1.2.3</logback.version> | 39 | <logback.version>1.2.3</logback.version> |
@@ -484,11 +483,6 @@ | @@ -484,11 +483,6 @@ | ||
484 | <version>${jjwt.version}</version> | 483 | <version>${jjwt.version}</version> |
485 | </dependency> | 484 | </dependency> |
486 | <dependency> | 485 | <dependency> |
487 | - <groupId>joda-time</groupId> | ||
488 | - <artifactId>joda-time</artifactId> | ||
489 | - <version>${joda-time.version}</version> | ||
490 | - </dependency> | ||
491 | - <dependency> | ||
492 | <groupId>org.apache.velocity</groupId> | 486 | <groupId>org.apache.velocity</groupId> |
493 | <artifactId>velocity</artifactId> | 487 | <artifactId>velocity</artifactId> |
494 | <version>${velocity.version}</version> | 488 | <version>${velocity.version}</version> |
@@ -29,13 +29,12 @@ import org.springframework.web.client.RestTemplate; | @@ -29,13 +29,12 @@ import org.springframework.web.client.RestTemplate; | ||
29 | import org.thingsboard.server.common.data.Customer; | 29 | import org.thingsboard.server.common.data.Customer; |
30 | import org.thingsboard.server.common.data.Device; | 30 | import org.thingsboard.server.common.data.Device; |
31 | import org.thingsboard.server.common.data.alarm.Alarm; | 31 | import org.thingsboard.server.common.data.alarm.Alarm; |
32 | -import org.thingsboard.server.common.data.alarm.AlarmSeverity; | ||
33 | -import org.thingsboard.server.common.data.alarm.AlarmStatus; | ||
34 | import org.thingsboard.server.common.data.asset.Asset; | 32 | import org.thingsboard.server.common.data.asset.Asset; |
35 | import org.thingsboard.server.common.data.id.AssetId; | 33 | import org.thingsboard.server.common.data.id.AssetId; |
36 | import org.thingsboard.server.common.data.id.CustomerId; | 34 | import org.thingsboard.server.common.data.id.CustomerId; |
37 | import org.thingsboard.server.common.data.id.DeviceId; | 35 | import org.thingsboard.server.common.data.id.DeviceId; |
38 | import org.thingsboard.server.common.data.id.EntityId; | 36 | import org.thingsboard.server.common.data.id.EntityId; |
37 | +import org.thingsboard.server.common.data.relation.EntityRelation; | ||
39 | import org.thingsboard.server.common.data.security.DeviceCredentials; | 38 | import org.thingsboard.server.common.data.security.DeviceCredentials; |
40 | 39 | ||
41 | import java.io.IOException; | 40 | import java.io.IOException; |
@@ -78,6 +77,36 @@ public class RestClient implements ClientHttpRequestInterceptor { | @@ -78,6 +77,36 @@ public class RestClient implements ClientHttpRequestInterceptor { | ||
78 | } | 77 | } |
79 | } | 78 | } |
80 | 79 | ||
80 | + public Optional<Customer> findCustomer(String title) { | ||
81 | + Map<String, String> params = new HashMap<String, String>(); | ||
82 | + params.put("customerTitle", title); | ||
83 | + try { | ||
84 | + ResponseEntity<Customer> customerEntity = restTemplate.getForEntity(baseURL + "/api/tenant/customers?customerTitle={customerTitle}", Customer.class, params); | ||
85 | + return Optional.of(customerEntity.getBody()); | ||
86 | + } catch (HttpClientErrorException exception) { | ||
87 | + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) { | ||
88 | + return Optional.empty(); | ||
89 | + } else { | ||
90 | + throw exception; | ||
91 | + } | ||
92 | + } | ||
93 | + } | ||
94 | + | ||
95 | + public Optional<Asset> findAsset(String name) { | ||
96 | + Map<String, String> params = new HashMap<String, String>(); | ||
97 | + params.put("assetName", name); | ||
98 | + try { | ||
99 | + ResponseEntity<Asset> assetEntity = restTemplate.getForEntity(baseURL + "/api/tenant/assets?assetName={assetName}", Asset.class, params); | ||
100 | + return Optional.of(assetEntity.getBody()); | ||
101 | + } catch (HttpClientErrorException exception) { | ||
102 | + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) { | ||
103 | + return Optional.empty(); | ||
104 | + } else { | ||
105 | + throw exception; | ||
106 | + } | ||
107 | + } | ||
108 | + } | ||
109 | + | ||
81 | public Customer createCustomer(String title) { | 110 | public Customer createCustomer(String title) { |
82 | Customer customer = new Customer(); | 111 | Customer customer = new Customer(); |
83 | customer.setTitle(title); | 112 | customer.setTitle(title); |
@@ -112,6 +141,14 @@ public class RestClient implements ClientHttpRequestInterceptor { | @@ -112,6 +141,14 @@ public class RestClient implements ClientHttpRequestInterceptor { | ||
112 | customerId.toString(), assetId.toString()).getBody(); | 141 | customerId.toString(), assetId.toString()).getBody(); |
113 | } | 142 | } |
114 | 143 | ||
144 | + public EntityRelation makeRelation(String relationType, EntityId idFrom, EntityId idTo) { | ||
145 | + EntityRelation relation = new EntityRelation(); | ||
146 | + relation.setFrom(idFrom); | ||
147 | + relation.setTo(idTo); | ||
148 | + relation.setType(relationType); | ||
149 | + return restTemplate.postForEntity(baseURL + "/api/relation", relation, EntityRelation.class).getBody(); | ||
150 | + } | ||
151 | + | ||
115 | public DeviceCredentials getCredentials(DeviceId id) { | 152 | public DeviceCredentials getCredentials(DeviceId id) { |
116 | return restTemplate.getForEntity(baseURL + "/api/device/" + id.getId().toString() + "/credentials", DeviceCredentials.class).getBody(); | 153 | return restTemplate.getForEntity(baseURL + "/api/device/" + id.getId().toString() + "/credentials", DeviceCredentials.class).getBody(); |
117 | } | 154 | } |
@@ -74,13 +74,13 @@ echo "Generating SSL Key Pair..." | @@ -74,13 +74,13 @@ echo "Generating SSL Key Pair..." | ||
74 | 74 | ||
75 | keytool -genkeypair -v \ | 75 | keytool -genkeypair -v \ |
76 | -alias $CLIENT_KEY_ALIAS \ | 76 | -alias $CLIENT_KEY_ALIAS \ |
77 | - -dname "CN=$DOMAIN_SUFFIX, OU=$ORGANIZATIONAL_UNIT, O=$ORGANIZATION, L=$CITY, ST=$STATE_OR_PROVINCE, C=$TWO_LETTER_COUNTRY_CODE" \ | ||
78 | -keystore $CLIENT_FILE_PREFIX.jks \ | 77 | -keystore $CLIENT_FILE_PREFIX.jks \ |
79 | -keypass $CLIENT_KEY_PASSWORD \ | 78 | -keypass $CLIENT_KEY_PASSWORD \ |
80 | -storepass $CLIENT_KEYSTORE_PASSWORD \ | 79 | -storepass $CLIENT_KEYSTORE_PASSWORD \ |
81 | -keyalg RSA \ | 80 | -keyalg RSA \ |
82 | -keysize 2048 \ | 81 | -keysize 2048 \ |
83 | - -validity 9999 | 82 | + -validity 9999 \ |
83 | + -dname "CN=$DOMAIN_SUFFIX, OU=$ORGANIZATIONAL_UNIT, O=$ORGANIZATION, L=$CITY, ST=$STATE_OR_PROVINCE, C=$TWO_LETTER_COUNTRY_CODE" | ||
84 | 84 | ||
85 | echo "Converting keystore to pkcs12" | 85 | echo "Converting keystore to pkcs12" |
86 | keytool -importkeystore \ | 86 | keytool -importkeystore \ |
@@ -17,7 +17,7 @@ | @@ -17,7 +17,7 @@ | ||
17 | DOMAIN_SUFFIX="$(hostname)" | 17 | DOMAIN_SUFFIX="$(hostname)" |
18 | ORGANIZATIONAL_UNIT=Thingsboard | 18 | ORGANIZATIONAL_UNIT=Thingsboard |
19 | ORGANIZATION=Thingsboard | 19 | ORGANIZATION=Thingsboard |
20 | -CITY=San Francisco | 20 | +CITY=SF |
21 | STATE_OR_PROVINCE=CA | 21 | STATE_OR_PROVINCE=CA |
22 | TWO_LETTER_COUNTRY_CODE=US | 22 | TWO_LETTER_COUNTRY_CODE=US |
23 | 23 |
@@ -22,11 +22,11 @@ | @@ -22,11 +22,11 @@ | ||
22 | <span translate class="md-headline">admin.general-settings</span> | 22 | <span translate class="md-headline">admin.general-settings</span> |
23 | </md-card-title-text> | 23 | </md-card-title-text> |
24 | </md-card-title> | 24 | </md-card-title> |
25 | - <md-progress-linear md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
26 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 25 | + <md-progress-linear md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
26 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
27 | <md-card-content> | 27 | <md-card-content> |
28 | <form name="vm.settingsForm" ng-submit="vm.save()" tb-confirm-on-exit confirm-form="vm.settingsForm"> | 28 | <form name="vm.settingsForm" ng-submit="vm.save()" tb-confirm-on-exit confirm-form="vm.settingsForm"> |
29 | - <fieldset ng-disabled="loading"> | 29 | + <fieldset ng-disabled="$root.loading"> |
30 | <md-input-container class="md-block"> | 30 | <md-input-container class="md-block"> |
31 | <label translate>admin.base-url</label> | 31 | <label translate>admin.base-url</label> |
32 | <input required name="baseUrl" ng-model="vm.settings.jsonValue.baseUrl"> | 32 | <input required name="baseUrl" ng-model="vm.settings.jsonValue.baseUrl"> |
@@ -35,7 +35,7 @@ | @@ -35,7 +35,7 @@ | ||
35 | </div> | 35 | </div> |
36 | </md-input-container> | 36 | </md-input-container> |
37 | <div layout="row" layout-align="end center" width="100%" layout-wrap> | 37 | <div layout="row" layout-align="end center" width="100%" layout-wrap> |
38 | - <md-button ng-disabled="loading || vm.settingsForm.$invalid || !vm.settingsForm.$dirty" type="submit" class="md-raised md-primary">{{'action.save' | translate}}</md-button> | 38 | + <md-button ng-disabled="$root.loading || vm.settingsForm.$invalid || !vm.settingsForm.$dirty" type="submit" class="md-raised md-primary">{{'action.save' | translate}}</md-button> |
39 | </div> | 39 | </div> |
40 | </fieldset> | 40 | </fieldset> |
41 | </form> | 41 | </form> |
@@ -24,11 +24,11 @@ | @@ -24,11 +24,11 @@ | ||
24 | <div id="help-container"></div> | 24 | <div id="help-container"></div> |
25 | </md-card-title-text> | 25 | </md-card-title-text> |
26 | </md-card-title> | 26 | </md-card-title> |
27 | - <md-progress-linear md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
28 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 27 | + <md-progress-linear md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
28 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
29 | <md-card-content> | 29 | <md-card-content> |
30 | <form name="vm.settingsForm" ng-submit="vm.save()" tb-confirm-on-exit confirm-form="vm.settingsForm"> | 30 | <form name="vm.settingsForm" ng-submit="vm.save()" tb-confirm-on-exit confirm-form="vm.settingsForm"> |
31 | - <fieldset ng-disabled="loading"> | 31 | + <fieldset ng-disabled="$root.loading"> |
32 | <md-input-container class="md-block"> | 32 | <md-input-container class="md-block"> |
33 | <label translate>admin.mail-from</label> | 33 | <label translate>admin.mail-from</label> |
34 | <input required name="mailFrom" ng-model="vm.settings.jsonValue.mailFrom"> | 34 | <input required name="mailFrom" ng-model="vm.settings.jsonValue.mailFrom"> |
@@ -38,7 +38,7 @@ | @@ -38,7 +38,7 @@ | ||
38 | </md-input-container> | 38 | </md-input-container> |
39 | <md-input-container class="md-block"> | 39 | <md-input-container class="md-block"> |
40 | <label translate>admin.smtp-protocol</label> | 40 | <label translate>admin.smtp-protocol</label> |
41 | - <md-select ng-disabled="loading" ng-model="vm.settings.jsonValue.smtpProtocol"> | 41 | + <md-select ng-disabled="$root.loading" ng-model="vm.settings.jsonValue.smtpProtocol"> |
42 | <md-option ng-repeat="smtpProtocol in vm.smtpProtocols" value="{{smtpProtocol}}"> | 42 | <md-option ng-repeat="smtpProtocol in vm.smtpProtocols" value="{{smtpProtocol}}"> |
43 | {{smtpProtocol.toUpperCase()}} | 43 | {{smtpProtocol.toUpperCase()}} |
44 | </md-option> | 44 | </md-option> |
@@ -78,7 +78,7 @@ | @@ -78,7 +78,7 @@ | ||
78 | <div translate ng-message="md-maxlength">admin.timeout-invalid</div> | 78 | <div translate ng-message="md-maxlength">admin.timeout-invalid</div> |
79 | </div> | 79 | </div> |
80 | </md-input-container> | 80 | </md-input-container> |
81 | - <md-checkbox ng-disabled="loading" ng-true-value="'true'" ng-false-value="'false'" | 81 | + <md-checkbox ng-disabled="$root.loading" ng-true-value="'true'" ng-false-value="'false'" |
82 | aria-label="{{ 'admin.enable-tls' | translate }}" ng-model="vm.settings.jsonValue.enableTls">{{ 'admin.enable-tls' | translate }}</md-checkbox> | 82 | aria-label="{{ 'admin.enable-tls' | translate }}" ng-model="vm.settings.jsonValue.enableTls">{{ 'admin.enable-tls' | translate }}</md-checkbox> |
83 | <md-input-container class="md-block"> | 83 | <md-input-container class="md-block"> |
84 | <label translate>common.username</label> | 84 | <label translate>common.username</label> |
@@ -89,8 +89,8 @@ | @@ -89,8 +89,8 @@ | ||
89 | <input name="password" placeholder="{{ 'common.enter-password' | translate }}" type="password" ng-model="vm.settings.jsonValue.password"> | 89 | <input name="password" placeholder="{{ 'common.enter-password' | translate }}" type="password" ng-model="vm.settings.jsonValue.password"> |
90 | </md-input-container> | 90 | </md-input-container> |
91 | <div layout="row" layout-align="end center" width="100%" layout-wrap> | 91 | <div layout="row" layout-align="end center" width="100%" layout-wrap> |
92 | - <md-button ng-disabled="loading || vm.settingsForm.$invalid" ng-click="vm.sendTestMail()" class="md-raised">{{'admin.send-test-mail' | translate}}</md-button> | ||
93 | - <md-button ng-disabled="loading || vm.settingsForm.$invalid || !vm.settingsForm.$dirty" type="submit" class="md-raised md-primary">{{'action.save' | translate}}</md-button> | 92 | + <md-button ng-disabled="$root.loading || vm.settingsForm.$invalid" ng-click="vm.sendTestMail()" class="md-raised">{{'admin.send-test-mail' | translate}}</md-button> |
93 | + <md-button ng-disabled="$root.loading || vm.settingsForm.$invalid || !vm.settingsForm.$dirty" type="submit" class="md-raised md-primary">{{'action.save' | translate}}</md-button> | ||
94 | </div> | 94 | </div> |
95 | </fieldset> | 95 | </fieldset> |
96 | </form> | 96 | </form> |
@@ -87,7 +87,7 @@ | @@ -87,7 +87,7 @@ | ||
87 | <md-button ng-if="vm.allowAcknowledgment && (vm.alarm.status==vm.types.alarmStatus.activeUnack || | 87 | <md-button ng-if="vm.allowAcknowledgment && (vm.alarm.status==vm.types.alarmStatus.activeUnack || |
88 | vm.alarm.status==vm.types.alarmStatus.clearedUnack)" | 88 | vm.alarm.status==vm.types.alarmStatus.clearedUnack)" |
89 | class="md-raised md-primary" | 89 | class="md-raised md-primary" |
90 | - ng-disabled="loading" | 90 | + ng-disabled="$root.loading" |
91 | ng-click="vm.acknowledge()" | 91 | ng-click="vm.acknowledge()" |
92 | style="margin-right:20px;">{{ 'alarm.acknowledge' | | 92 | style="margin-right:20px;">{{ 'alarm.acknowledge' | |
93 | translate }} | 93 | translate }} |
@@ -95,12 +95,12 @@ | @@ -95,12 +95,12 @@ | ||
95 | <md-button ng-if="vm.allowClear && (vm.alarm.status==vm.types.alarmStatus.activeAck || | 95 | <md-button ng-if="vm.allowClear && (vm.alarm.status==vm.types.alarmStatus.activeAck || |
96 | vm.alarm.status==vm.types.alarmStatus.activeUnack)" | 96 | vm.alarm.status==vm.types.alarmStatus.activeUnack)" |
97 | class="md-raised md-primary" | 97 | class="md-raised md-primary" |
98 | - ng-disabled="loading" | 98 | + ng-disabled="$root.loading" |
99 | ng-click="vm.clear()">{{ 'alarm.clear' | | 99 | ng-click="vm.clear()">{{ 'alarm.clear' | |
100 | translate }} | 100 | translate }} |
101 | </md-button> | 101 | </md-button> |
102 | <span flex></span> | 102 | <span flex></span> |
103 | - <md-button ng-disabled="loading" ng-click="vm.close()" style="margin-right:20px;">{{ 'action.close' | | 103 | + <md-button ng-disabled="$root.loading" ng-click="vm.close()" style="margin-right:20px;">{{ 'action.close' | |
104 | translate }} | 104 | translate }} |
105 | </md-button> | 105 | </md-button> |
106 | </md-dialog-actions> | 106 | </md-dialog-actions> |
@@ -19,7 +19,7 @@ | @@ -19,7 +19,7 @@ | ||
19 | <section layout="row"> | 19 | <section layout="row"> |
20 | <md-input-container class="md-block" style="width: 200px;"> | 20 | <md-input-container class="md-block" style="width: 200px;"> |
21 | <label translate>alarm.alarm-status</label> | 21 | <label translate>alarm.alarm-status</label> |
22 | - <md-select ng-model="alarmSearchStatus" ng-disabled="loading()"> | 22 | + <md-select ng-model="alarmSearchStatus" ng-disabled="$root.loading"> |
23 | <md-option ng-repeat="searchStatus in types.alarmSearchStatus" ng-value="searchStatus"> | 23 | <md-option ng-repeat="searchStatus in types.alarmSearchStatus" ng-value="searchStatus"> |
24 | {{ ('alarm.search-status.' + searchStatus) | translate }} | 24 | {{ ('alarm.search-status.' + searchStatus) | translate }} |
25 | </md-option> | 25 | </md-option> |
@@ -31,8 +31,8 @@ | @@ -31,8 +31,8 @@ | ||
31 | <md-list flex layout="column" class="tb-alarm-table"> | 31 | <md-list flex layout="column" class="tb-alarm-table"> |
32 | <md-list class="tb-row tb-header" layout="row" tb-alarm-header> | 32 | <md-list class="tb-row tb-header" layout="row" tb-alarm-header> |
33 | </md-list> | 33 | </md-list> |
34 | - <md-progress-linear style="max-height: 0px;" md-mode="indeterminate" ng-disabled="!loading()" | ||
35 | - ng-show="loading()"></md-progress-linear> | 34 | + <md-progress-linear style="max-height: 0px;" md-mode="indeterminate" ng-disabled="!$root.loading" |
35 | + ng-show="$root.loading"></md-progress-linear> | ||
36 | <md-divider></md-divider> | 36 | <md-divider></md-divider> |
37 | <span translate layout-align="center center" | 37 | <span translate layout-align="center center" |
38 | style="margin-top: 25px;" | 38 | style="margin-top: 25px;" |
@@ -265,10 +265,10 @@ function AssetService($http, $q, customerService, userService) { | @@ -265,10 +265,10 @@ function AssetService($http, $q, customerService, userService) { | ||
265 | return deferred.promise; | 265 | return deferred.promise; |
266 | } | 266 | } |
267 | 267 | ||
268 | - function getAssetTypes() { | 268 | + function getAssetTypes(config) { |
269 | var deferred = $q.defer(); | 269 | var deferred = $q.defer(); |
270 | var url = '/api/asset/types'; | 270 | var url = '/api/asset/types'; |
271 | - $http.get(url).then(function success(response) { | 271 | + $http.get(url, config).then(function success(response) { |
272 | deferred.resolve(response.data); | 272 | deferred.resolve(response.data); |
273 | }, function fail() { | 273 | }, function fail() { |
274 | deferred.reject(); | 274 | deferred.reject(); |
@@ -35,7 +35,7 @@ function AttributeService($http, $q, $filter, types, telemetryWebsocketService) | @@ -35,7 +35,7 @@ function AttributeService($http, $q, $filter, types, telemetryWebsocketService) | ||
35 | 35 | ||
36 | return service; | 36 | return service; |
37 | 37 | ||
38 | - function getEntityKeys(entityType, entityId, query, type) { | 38 | + function getEntityKeys(entityType, entityId, query, type, config) { |
39 | var deferred = $q.defer(); | 39 | var deferred = $q.defer(); |
40 | var url = '/api/plugins/telemetry/' + entityType + '/' + entityId + '/keys/'; | 40 | var url = '/api/plugins/telemetry/' + entityType + '/' + entityId + '/keys/'; |
41 | if (type === types.dataKeyType.timeseries) { | 41 | if (type === types.dataKeyType.timeseries) { |
@@ -43,7 +43,7 @@ function AttributeService($http, $q, $filter, types, telemetryWebsocketService) | @@ -43,7 +43,7 @@ function AttributeService($http, $q, $filter, types, telemetryWebsocketService) | ||
43 | } else if (type === types.dataKeyType.attribute) { | 43 | } else if (type === types.dataKeyType.attribute) { |
44 | url += 'attributes'; | 44 | url += 'attributes'; |
45 | } | 45 | } |
46 | - $http.get(url, null).then(function success(response) { | 46 | + $http.get(url, config).then(function success(response) { |
47 | var result = []; | 47 | var result = []; |
48 | if (response.data) { | 48 | if (response.data) { |
49 | if (query) { | 49 | if (query) { |
@@ -32,7 +32,7 @@ function CustomerService($http, $q, types) { | @@ -32,7 +32,7 @@ function CustomerService($http, $q, types) { | ||
32 | 32 | ||
33 | return service; | 33 | return service; |
34 | 34 | ||
35 | - function getCustomers(pageLink) { | 35 | + function getCustomers(pageLink, config) { |
36 | var deferred = $q.defer(); | 36 | var deferred = $q.defer(); |
37 | var url = '/api/customers?limit=' + pageLink.limit; | 37 | var url = '/api/customers?limit=' + pageLink.limit; |
38 | if (angular.isDefined(pageLink.textSearch)) { | 38 | if (angular.isDefined(pageLink.textSearch)) { |
@@ -44,7 +44,7 @@ function CustomerService($http, $q, types) { | @@ -44,7 +44,7 @@ function CustomerService($http, $q, types) { | ||
44 | if (angular.isDefined(pageLink.textOffset)) { | 44 | if (angular.isDefined(pageLink.textOffset)) { |
45 | url += '&textOffset=' + pageLink.textOffset; | 45 | url += '&textOffset=' + pageLink.textOffset; |
46 | } | 46 | } |
47 | - $http.get(url, null).then(function success(response) { | 47 | + $http.get(url, config).then(function success(response) { |
48 | deferred.resolve(response.data); | 48 | deferred.resolve(response.data); |
49 | }, function fail() { | 49 | }, function fail() { |
50 | deferred.reject(); | 50 | deferred.reject(); |
@@ -52,10 +52,10 @@ function CustomerService($http, $q, types) { | @@ -52,10 +52,10 @@ function CustomerService($http, $q, types) { | ||
52 | return deferred.promise; | 52 | return deferred.promise; |
53 | } | 53 | } |
54 | 54 | ||
55 | - function getCustomer(customerId) { | 55 | + function getCustomer(customerId, config) { |
56 | var deferred = $q.defer(); | 56 | var deferred = $q.defer(); |
57 | var url = '/api/customer/' + customerId; | 57 | var url = '/api/customer/' + customerId; |
58 | - $http.get(url, null).then(function success(response) { | 58 | + $http.get(url, config).then(function success(response) { |
59 | deferred.resolve(response.data); | 59 | deferred.resolve(response.data); |
60 | }, function fail(response) { | 60 | }, function fail(response) { |
61 | deferred.reject(response.data); | 61 | deferred.reject(response.data); |
@@ -43,7 +43,7 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | @@ -43,7 +43,7 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | ||
43 | 43 | ||
44 | return service; | 44 | return service; |
45 | 45 | ||
46 | - function getTenantDashboardsByTenantId(tenantId, pageLink) { | 46 | + function getTenantDashboardsByTenantId(tenantId, pageLink, config) { |
47 | var deferred = $q.defer(); | 47 | var deferred = $q.defer(); |
48 | var url = '/api/tenant/' + tenantId + '/dashboards?limit=' + pageLink.limit; | 48 | var url = '/api/tenant/' + tenantId + '/dashboards?limit=' + pageLink.limit; |
49 | if (angular.isDefined(pageLink.textSearch)) { | 49 | if (angular.isDefined(pageLink.textSearch)) { |
@@ -55,7 +55,7 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | @@ -55,7 +55,7 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | ||
55 | if (angular.isDefined(pageLink.textOffset)) { | 55 | if (angular.isDefined(pageLink.textOffset)) { |
56 | url += '&textOffset=' + pageLink.textOffset; | 56 | url += '&textOffset=' + pageLink.textOffset; |
57 | } | 57 | } |
58 | - $http.get(url, null).then(function success(response) { | 58 | + $http.get(url, config).then(function success(response) { |
59 | deferred.resolve(response.data); | 59 | deferred.resolve(response.data); |
60 | }, function fail() { | 60 | }, function fail() { |
61 | deferred.reject(); | 61 | deferred.reject(); |
@@ -63,7 +63,7 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | @@ -63,7 +63,7 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | ||
63 | return deferred.promise; | 63 | return deferred.promise; |
64 | } | 64 | } |
65 | 65 | ||
66 | - function getTenantDashboards(pageLink, applyCustomersInfo) { | 66 | + function getTenantDashboards(pageLink, applyCustomersInfo, config) { |
67 | var deferred = $q.defer(); | 67 | var deferred = $q.defer(); |
68 | var url = '/api/tenant/dashboards?limit=' + pageLink.limit; | 68 | var url = '/api/tenant/dashboards?limit=' + pageLink.limit; |
69 | if (angular.isDefined(pageLink.textSearch)) { | 69 | if (angular.isDefined(pageLink.textSearch)) { |
@@ -75,7 +75,7 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | @@ -75,7 +75,7 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | ||
75 | if (angular.isDefined(pageLink.textOffset)) { | 75 | if (angular.isDefined(pageLink.textOffset)) { |
76 | url += '&textOffset=' + pageLink.textOffset; | 76 | url += '&textOffset=' + pageLink.textOffset; |
77 | } | 77 | } |
78 | - $http.get(url, null).then(function success(response) { | 78 | + $http.get(url, config).then(function success(response) { |
79 | if (applyCustomersInfo) { | 79 | if (applyCustomersInfo) { |
80 | customerService.applyAssignedCustomersInfo(response.data.data).then( | 80 | customerService.applyAssignedCustomersInfo(response.data.data).then( |
81 | function success(data) { | 81 | function success(data) { |
@@ -95,7 +95,7 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | @@ -95,7 +95,7 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | ||
95 | return deferred.promise; | 95 | return deferred.promise; |
96 | } | 96 | } |
97 | 97 | ||
98 | - function getCustomerDashboards(customerId, pageLink, applyCustomersInfo) { | 98 | + function getCustomerDashboards(customerId, pageLink, applyCustomersInfo, config) { |
99 | var deferred = $q.defer(); | 99 | var deferred = $q.defer(); |
100 | var url = '/api/customer/' + customerId + '/dashboards?limit=' + pageLink.limit; | 100 | var url = '/api/customer/' + customerId + '/dashboards?limit=' + pageLink.limit; |
101 | if (angular.isDefined(pageLink.textSearch)) { | 101 | if (angular.isDefined(pageLink.textSearch)) { |
@@ -107,7 +107,7 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | @@ -107,7 +107,7 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | ||
107 | if (angular.isDefined(pageLink.textOffset)) { | 107 | if (angular.isDefined(pageLink.textOffset)) { |
108 | url += '&textOffset=' + pageLink.textOffset; | 108 | url += '&textOffset=' + pageLink.textOffset; |
109 | } | 109 | } |
110 | - $http.get(url, null).then(function success(response) { | 110 | + $http.get(url, config).then(function success(response) { |
111 | if (applyCustomersInfo) { | 111 | if (applyCustomersInfo) { |
112 | customerService.applyAssignedCustomerInfo(response.data.data, customerId).then( | 112 | customerService.applyAssignedCustomerInfo(response.data.data, customerId).then( |
113 | function success(data) { | 113 | function success(data) { |
@@ -158,10 +158,10 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | @@ -158,10 +158,10 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | ||
158 | return deferred.promise; | 158 | return deferred.promise; |
159 | } | 159 | } |
160 | 160 | ||
161 | - function getDashboardInfo(dashboardId) { | 161 | + function getDashboardInfo(dashboardId, config) { |
162 | var deferred = $q.defer(); | 162 | var deferred = $q.defer(); |
163 | var url = '/api/dashboard/info/' + dashboardId; | 163 | var url = '/api/dashboard/info/' + dashboardId; |
164 | - $http.get(url, null).then(function success(response) { | 164 | + $http.get(url, config).then(function success(response) { |
165 | deferred.resolve(response.data); | 165 | deferred.resolve(response.data); |
166 | }, function fail() { | 166 | }, function fail() { |
167 | deferred.reject(); | 167 | deferred.reject(); |
@@ -293,10 +293,10 @@ function DeviceService($http, $q, attributeService, customerService, types) { | @@ -293,10 +293,10 @@ function DeviceService($http, $q, attributeService, customerService, types) { | ||
293 | return deferred.promise; | 293 | return deferred.promise; |
294 | } | 294 | } |
295 | 295 | ||
296 | - function getDeviceTypes() { | 296 | + function getDeviceTypes(config) { |
297 | var deferred = $q.defer(); | 297 | var deferred = $q.defer(); |
298 | var url = '/api/device/types'; | 298 | var url = '/api/device/types'; |
299 | - $http.get(url).then(function success(response) { | 299 | + $http.get(url, config).then(function success(response) { |
300 | deferred.resolve(response.data); | 300 | deferred.resolve(response.data); |
301 | }, function fail() { | 301 | }, function fail() { |
302 | deferred.reject(); | 302 | deferred.reject(); |
@@ -175,10 +175,10 @@ function EntityRelationService($http, $q) { | @@ -175,10 +175,10 @@ function EntityRelationService($http, $q) { | ||
175 | return deferred.promise; | 175 | return deferred.promise; |
176 | } | 176 | } |
177 | 177 | ||
178 | - function findInfoByQuery(query) { | 178 | + function findInfoByQuery(query, config) { |
179 | var deferred = $q.defer(); | 179 | var deferred = $q.defer(); |
180 | var url = '/api/relations/info'; | 180 | var url = '/api/relations/info'; |
181 | - $http.post(url, query).then(function success(response) { | 181 | + $http.post(url, query, config).then(function success(response) { |
182 | deferred.resolve(response.data); | 182 | deferred.resolve(response.data); |
183 | }, function fail() { | 183 | }, function fail() { |
184 | deferred.reject(); | 184 | deferred.reject(); |
@@ -56,22 +56,22 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -56,22 +56,22 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
56 | promise = assetService.getAsset(entityId, true, config); | 56 | promise = assetService.getAsset(entityId, true, config); |
57 | break; | 57 | break; |
58 | case types.entityType.tenant: | 58 | case types.entityType.tenant: |
59 | - promise = tenantService.getTenant(entityId); | 59 | + promise = tenantService.getTenant(entityId, config); |
60 | break; | 60 | break; |
61 | case types.entityType.customer: | 61 | case types.entityType.customer: |
62 | - promise = customerService.getCustomer(entityId); | 62 | + promise = customerService.getCustomer(entityId, config); |
63 | break; | 63 | break; |
64 | case types.entityType.rule: | 64 | case types.entityType.rule: |
65 | - promise = ruleService.getRule(entityId); | 65 | + promise = ruleService.getRule(entityId, config); |
66 | break; | 66 | break; |
67 | case types.entityType.plugin: | 67 | case types.entityType.plugin: |
68 | - promise = pluginService.getPlugin(entityId); | 68 | + promise = pluginService.getPlugin(entityId, config); |
69 | break; | 69 | break; |
70 | case types.entityType.dashboard: | 70 | case types.entityType.dashboard: |
71 | - promise = dashboardService.getDashboardInfo(entityId); | 71 | + promise = dashboardService.getDashboardInfo(entityId, config); |
72 | break; | 72 | break; |
73 | case types.entityType.user: | 73 | case types.entityType.user: |
74 | - promise = userService.getUser(entityId); | 74 | + promise = userService.getUser(entityId, true, config); |
75 | break; | 75 | break; |
76 | case types.entityType.alarm: | 76 | case types.entityType.alarm: |
77 | $log.error('Get Alarm Entity is not implemented!'); | 77 | $log.error('Get Alarm Entity is not implemented!'); |
@@ -136,22 +136,28 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -136,22 +136,28 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
136 | promise = assetService.getAssets(entityIds, config); | 136 | promise = assetService.getAssets(entityIds, config); |
137 | break; | 137 | break; |
138 | case types.entityType.tenant: | 138 | case types.entityType.tenant: |
139 | - promise = getEntitiesByIdsPromise(tenantService.getTenant, entityIds); | 139 | + promise = getEntitiesByIdsPromise( |
140 | + (id) => tenantService.getTenant(id, config), entityIds); | ||
140 | break; | 141 | break; |
141 | case types.entityType.customer: | 142 | case types.entityType.customer: |
142 | - promise = getEntitiesByIdsPromise(customerService.getCustomer, entityIds); | 143 | + promise = getEntitiesByIdsPromise( |
144 | + (id) => customerService.getCustomer(id, config), entityIds); | ||
143 | break; | 145 | break; |
144 | case types.entityType.rule: | 146 | case types.entityType.rule: |
145 | - promise = getEntitiesByIdsPromise(ruleService.getRule, entityIds); | 147 | + promise = getEntitiesByIdsPromise( |
148 | + (id) => ruleService.getRule(id, config), entityIds); | ||
146 | break; | 149 | break; |
147 | case types.entityType.plugin: | 150 | case types.entityType.plugin: |
148 | - promise = getEntitiesByIdsPromise(pluginService.getPlugin, entityIds); | 151 | + promise = getEntitiesByIdsPromise( |
152 | + (id) => pluginService.getPlugin(id, config), entityIds); | ||
149 | break; | 153 | break; |
150 | case types.entityType.dashboard: | 154 | case types.entityType.dashboard: |
151 | - promise = getEntitiesByIdsPromise(dashboardService.getDashboardInfo, entityIds); | 155 | + promise = getEntitiesByIdsPromise( |
156 | + (id) => dashboardService.getDashboardInfo(id, config), entityIds); | ||
152 | break; | 157 | break; |
153 | case types.entityType.user: | 158 | case types.entityType.user: |
154 | - promise = getEntitiesByIdsPromise(userService.getUser, entityIds); | 159 | + promise = getEntitiesByIdsPromise( |
160 | + (id) => userService.getUser(id, true, config), entityIds); | ||
155 | break; | 161 | break; |
156 | case types.entityType.alarm: | 162 | case types.entityType.alarm: |
157 | $log.error('Get Alarm Entity is not implemented!'); | 163 | $log.error('Get Alarm Entity is not implemented!'); |
@@ -178,11 +184,11 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -178,11 +184,11 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
178 | return deferred.promise; | 184 | return deferred.promise; |
179 | } | 185 | } |
180 | 186 | ||
181 | - function getSingleTenantByPageLinkPromise(pageLink) { | 187 | + function getSingleTenantByPageLinkPromise(pageLink, config) { |
182 | var user = userService.getCurrentUser(); | 188 | var user = userService.getCurrentUser(); |
183 | var tenantId = user.tenantId; | 189 | var tenantId = user.tenantId; |
184 | var deferred = $q.defer(); | 190 | var deferred = $q.defer(); |
185 | - tenantService.getTenant(tenantId).then( | 191 | + tenantService.getTenant(tenantId, config).then( |
186 | function success(tenant) { | 192 | function success(tenant) { |
187 | var tenantName = tenant.name; | 193 | var tenantName = tenant.name; |
188 | var result = { | 194 | var result = { |
@@ -202,11 +208,11 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -202,11 +208,11 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
202 | return deferred.promise; | 208 | return deferred.promise; |
203 | } | 209 | } |
204 | 210 | ||
205 | - function getSingleCustomerByPageLinkPromise(pageLink) { | 211 | + function getSingleCustomerByPageLinkPromise(pageLink, config) { |
206 | var user = userService.getCurrentUser(); | 212 | var user = userService.getCurrentUser(); |
207 | var customerId = user.customerId; | 213 | var customerId = user.customerId; |
208 | var deferred = $q.defer(); | 214 | var deferred = $q.defer(); |
209 | - customerService.getCustomer(customerId).then( | 215 | + customerService.getCustomer(customerId, config).then( |
210 | function success(customer) { | 216 | function success(customer) { |
211 | var customerName = customer.name; | 217 | var customerName = customer.name; |
212 | var result = { | 218 | var result = { |
@@ -247,29 +253,29 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -247,29 +253,29 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
247 | break; | 253 | break; |
248 | case types.entityType.tenant: | 254 | case types.entityType.tenant: |
249 | if (user.authority === 'TENANT_ADMIN') { | 255 | if (user.authority === 'TENANT_ADMIN') { |
250 | - promise = getSingleTenantByPageLinkPromise(pageLink); | 256 | + promise = getSingleTenantByPageLinkPromise(pageLink, config); |
251 | } else { | 257 | } else { |
252 | - promise = tenantService.getTenants(pageLink); | 258 | + promise = tenantService.getTenants(pageLink, config); |
253 | } | 259 | } |
254 | break; | 260 | break; |
255 | case types.entityType.customer: | 261 | case types.entityType.customer: |
256 | if (user.authority === 'CUSTOMER_USER') { | 262 | if (user.authority === 'CUSTOMER_USER') { |
257 | - promise = getSingleCustomerByPageLinkPromise(pageLink); | 263 | + promise = getSingleCustomerByPageLinkPromise(pageLink, config); |
258 | } else { | 264 | } else { |
259 | - promise = customerService.getCustomers(pageLink); | 265 | + promise = customerService.getCustomers(pageLink, config); |
260 | } | 266 | } |
261 | break; | 267 | break; |
262 | case types.entityType.rule: | 268 | case types.entityType.rule: |
263 | - promise = ruleService.getAllRules(pageLink); | 269 | + promise = ruleService.getAllRules(pageLink, config); |
264 | break; | 270 | break; |
265 | case types.entityType.plugin: | 271 | case types.entityType.plugin: |
266 | - promise = pluginService.getAllPlugins(pageLink); | 272 | + promise = pluginService.getAllPlugins(pageLink, config); |
267 | break; | 273 | break; |
268 | case types.entityType.dashboard: | 274 | case types.entityType.dashboard: |
269 | if (user.authority === 'CUSTOMER_USER') { | 275 | if (user.authority === 'CUSTOMER_USER') { |
270 | - promise = dashboardService.getCustomerDashboards(customerId, pageLink, false); | 276 | + promise = dashboardService.getCustomerDashboards(customerId, pageLink, false, config); |
271 | } else { | 277 | } else { |
272 | - promise = dashboardService.getTenantDashboards(pageLink, false); | 278 | + promise = dashboardService.getTenantDashboards(pageLink, false, config); |
273 | } | 279 | } |
274 | break; | 280 | break; |
275 | case types.entityType.user: | 281 | case types.entityType.user: |
@@ -426,7 +432,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -426,7 +432,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
426 | var stateEntityId = getStateEntityId(filter, stateParams); | 432 | var stateEntityId = getStateEntityId(filter, stateParams); |
427 | switch (filter.type) { | 433 | switch (filter.type) { |
428 | case types.aliasFilterType.singleEntity.value: | 434 | case types.aliasFilterType.singleEntity.value: |
429 | - getEntity(filter.singleEntity.entityType, filter.singleEntity.id).then( | 435 | + getEntity(filter.singleEntity.entityType, filter.singleEntity.id, {ignoreLoading: true}).then( |
430 | function success(entity) { | 436 | function success(entity) { |
431 | result.entities = entitiesToEntitiesInfo([entity]); | 437 | result.entities = entitiesToEntitiesInfo([entity]); |
432 | deferred.resolve(result); | 438 | deferred.resolve(result); |
@@ -437,7 +443,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -437,7 +443,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
437 | ); | 443 | ); |
438 | break; | 444 | break; |
439 | case types.aliasFilterType.entityList.value: | 445 | case types.aliasFilterType.entityList.value: |
440 | - getEntities(filter.entityType, filter.entityList).then( | 446 | + getEntities(filter.entityType, filter.entityList, {ignoreLoading: true}).then( |
441 | function success(entities) { | 447 | function success(entities) { |
442 | if (entities && entities.length || !failOnEmpty) { | 448 | if (entities && entities.length || !failOnEmpty) { |
443 | result.entities = entitiesToEntitiesInfo(entities); | 449 | result.entities = entitiesToEntitiesInfo(entities); |
@@ -452,7 +458,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -452,7 +458,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
452 | ); | 458 | ); |
453 | break; | 459 | break; |
454 | case types.aliasFilterType.entityName.value: | 460 | case types.aliasFilterType.entityName.value: |
455 | - getEntitiesByNameFilter(filter.entityType, filter.entityNameFilter, maxItems).then( | 461 | + getEntitiesByNameFilter(filter.entityType, filter.entityNameFilter, maxItems, {ignoreLoading: true}).then( |
456 | function success(entities) { | 462 | function success(entities) { |
457 | if (entities && entities.length || !failOnEmpty) { | 463 | if (entities && entities.length || !failOnEmpty) { |
458 | result.entities = entitiesToEntitiesInfo(entities); | 464 | result.entities = entitiesToEntitiesInfo(entities); |
@@ -469,7 +475,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -469,7 +475,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
469 | case types.aliasFilterType.stateEntity.value: | 475 | case types.aliasFilterType.stateEntity.value: |
470 | result.stateEntity = true; | 476 | result.stateEntity = true; |
471 | if (stateEntityId) { | 477 | if (stateEntityId) { |
472 | - getEntity(stateEntityId.entityType, stateEntityId.id).then( | 478 | + getEntity(stateEntityId.entityType, stateEntityId.id, {ignoreLoading: true}).then( |
473 | function success(entity) { | 479 | function success(entity) { |
474 | result.entities = entitiesToEntitiesInfo([entity]); | 480 | result.entities = entitiesToEntitiesInfo([entity]); |
475 | deferred.resolve(result); | 481 | deferred.resolve(result); |
@@ -483,7 +489,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -483,7 +489,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
483 | } | 489 | } |
484 | break; | 490 | break; |
485 | case types.aliasFilterType.assetType.value: | 491 | case types.aliasFilterType.assetType.value: |
486 | - getEntitiesByNameFilter(types.entityType.asset, filter.assetNameFilter, maxItems, null, filter.assetType).then( | 492 | + getEntitiesByNameFilter(types.entityType.asset, filter.assetNameFilter, maxItems, {ignoreLoading: true}, filter.assetType).then( |
487 | function success(entities) { | 493 | function success(entities) { |
488 | if (entities && entities.length || !failOnEmpty) { | 494 | if (entities && entities.length || !failOnEmpty) { |
489 | result.entities = entitiesToEntitiesInfo(entities); | 495 | result.entities = entitiesToEntitiesInfo(entities); |
@@ -498,7 +504,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -498,7 +504,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
498 | ); | 504 | ); |
499 | break; | 505 | break; |
500 | case types.aliasFilterType.deviceType.value: | 506 | case types.aliasFilterType.deviceType.value: |
501 | - getEntitiesByNameFilter(types.entityType.device, filter.deviceNameFilter, maxItems, null, filter.deviceType).then( | 507 | + getEntitiesByNameFilter(types.entityType.device, filter.deviceNameFilter, maxItems, {ignoreLoading: true}, filter.deviceType).then( |
502 | function success(entities) { | 508 | function success(entities) { |
503 | if (entities && entities.length || !failOnEmpty) { | 509 | if (entities && entities.length || !failOnEmpty) { |
504 | result.entities = entitiesToEntitiesInfo(entities); | 510 | result.entities = entitiesToEntitiesInfo(entities); |
@@ -533,7 +539,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -533,7 +539,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
533 | filters: filter.filters | 539 | filters: filter.filters |
534 | }; | 540 | }; |
535 | searchQuery.parameters.maxLevel = filter.maxLevel && filter.maxLevel > 0 ? filter.maxLevel : -1; | 541 | searchQuery.parameters.maxLevel = filter.maxLevel && filter.maxLevel > 0 ? filter.maxLevel : -1; |
536 | - entityRelationService.findInfoByQuery(searchQuery).then( | 542 | + entityRelationService.findInfoByQuery(searchQuery, {ignoreLoading: true}).then( |
537 | function success(allRelations) { | 543 | function success(allRelations) { |
538 | if (allRelations && allRelations.length || !failOnEmpty) { | 544 | if (allRelations && allRelations.length || !failOnEmpty) { |
539 | if (angular.isDefined(maxItems) && maxItems > 0 && allRelations) { | 545 | if (angular.isDefined(maxItems) && maxItems > 0 && allRelations) { |
@@ -577,10 +583,10 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -577,10 +583,10 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
577 | var findByQueryPromise; | 583 | var findByQueryPromise; |
578 | if (filter.type == types.aliasFilterType.assetSearchQuery.value) { | 584 | if (filter.type == types.aliasFilterType.assetSearchQuery.value) { |
579 | searchQuery.assetTypes = filter.assetTypes; | 585 | searchQuery.assetTypes = filter.assetTypes; |
580 | - findByQueryPromise = assetService.findByQuery(searchQuery, false); | 586 | + findByQueryPromise = assetService.findByQuery(searchQuery, false, {ignoreLoading: true}); |
581 | } else if (filter.type == types.aliasFilterType.deviceSearchQuery.value) { | 587 | } else if (filter.type == types.aliasFilterType.deviceSearchQuery.value) { |
582 | searchQuery.deviceTypes = filter.deviceTypes; | 588 | searchQuery.deviceTypes = filter.deviceTypes; |
583 | - findByQueryPromise = deviceService.findByQuery(searchQuery, false); | 589 | + findByQueryPromise = deviceService.findByQuery(searchQuery, false, {ignoreLoading: true}); |
584 | } | 590 | } |
585 | findByQueryPromise.then( | 591 | findByQueryPromise.then( |
586 | function success(entities) { | 592 | function success(entities) { |
@@ -762,7 +768,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -762,7 +768,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
762 | return deferred.promise; | 768 | return deferred.promise; |
763 | } | 769 | } |
764 | 770 | ||
765 | - function getEntityKeys(entityType, entityId, query, type) { | 771 | + function getEntityKeys(entityType, entityId, query, type, config) { |
766 | var deferred = $q.defer(); | 772 | var deferred = $q.defer(); |
767 | var url = '/api/plugins/telemetry/' + entityType + '/' + entityId + '/keys/'; | 773 | var url = '/api/plugins/telemetry/' + entityType + '/' + entityId + '/keys/'; |
768 | if (type === types.dataKeyType.timeseries) { | 774 | if (type === types.dataKeyType.timeseries) { |
@@ -770,7 +776,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -770,7 +776,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
770 | } else if (type === types.dataKeyType.attribute) { | 776 | } else if (type === types.dataKeyType.attribute) { |
771 | url += 'attributes'; | 777 | url += 'attributes'; |
772 | } | 778 | } |
773 | - $http.get(url, null).then(function success(response) { | 779 | + $http.get(url, config).then(function success(response) { |
774 | var result = []; | 780 | var result = []; |
775 | if (response.data) { | 781 | if (response.data) { |
776 | if (query) { | 782 | if (query) { |
@@ -50,11 +50,11 @@ function PluginService($http, $q, $rootScope, $filter, componentDescriptorServic | @@ -50,11 +50,11 @@ function PluginService($http, $q, $rootScope, $filter, componentDescriptorServic | ||
50 | tenantPlugins = undefined; | 50 | tenantPlugins = undefined; |
51 | } | 51 | } |
52 | 52 | ||
53 | - function loadPluginsCache() { | 53 | + function loadPluginsCache(config) { |
54 | var deferred = $q.defer(); | 54 | var deferred = $q.defer(); |
55 | if (!allPlugins) { | 55 | if (!allPlugins) { |
56 | var url = '/api/plugins'; | 56 | var url = '/api/plugins'; |
57 | - $http.get(url, null).then(function success(response) { | 57 | + $http.get(url, config).then(function success(response) { |
58 | componentDescriptorService.getComponentDescriptorsByType(types.componentType.plugin).then( | 58 | componentDescriptorService.getComponentDescriptorsByType(types.componentType.plugin).then( |
59 | function success(pluginComponents) { | 59 | function success(pluginComponents) { |
60 | allPlugins = response.data; | 60 | allPlugins = response.data; |
@@ -93,9 +93,9 @@ function PluginService($http, $q, $rootScope, $filter, componentDescriptorServic | @@ -93,9 +93,9 @@ function PluginService($http, $q, $rootScope, $filter, componentDescriptorServic | ||
93 | return deferred.promise; | 93 | return deferred.promise; |
94 | } | 94 | } |
95 | 95 | ||
96 | - function getSystemPlugins(pageLink) { | 96 | + function getSystemPlugins(pageLink, config) { |
97 | var deferred = $q.defer(); | 97 | var deferred = $q.defer(); |
98 | - loadPluginsCache().then( | 98 | + loadPluginsCache(config).then( |
99 | function success() { | 99 | function success() { |
100 | utils.filterSearchTextEntities(systemPlugins, 'name', pageLink, deferred); | 100 | utils.filterSearchTextEntities(systemPlugins, 'name', pageLink, deferred); |
101 | }, | 101 | }, |
@@ -106,9 +106,9 @@ function PluginService($http, $q, $rootScope, $filter, componentDescriptorServic | @@ -106,9 +106,9 @@ function PluginService($http, $q, $rootScope, $filter, componentDescriptorServic | ||
106 | return deferred.promise; | 106 | return deferred.promise; |
107 | } | 107 | } |
108 | 108 | ||
109 | - function getTenantPlugins(pageLink) { | 109 | + function getTenantPlugins(pageLink, config) { |
110 | var deferred = $q.defer(); | 110 | var deferred = $q.defer(); |
111 | - loadPluginsCache().then( | 111 | + loadPluginsCache(config).then( |
112 | function success() { | 112 | function success() { |
113 | utils.filterSearchTextEntities(tenantPlugins, 'name', pageLink, deferred); | 113 | utils.filterSearchTextEntities(tenantPlugins, 'name', pageLink, deferred); |
114 | }, | 114 | }, |
@@ -119,9 +119,9 @@ function PluginService($http, $q, $rootScope, $filter, componentDescriptorServic | @@ -119,9 +119,9 @@ function PluginService($http, $q, $rootScope, $filter, componentDescriptorServic | ||
119 | return deferred.promise; | 119 | return deferred.promise; |
120 | } | 120 | } |
121 | 121 | ||
122 | - function getAllActionPlugins(pageLink) { | 122 | + function getAllActionPlugins(pageLink, config) { |
123 | var deferred = $q.defer(); | 123 | var deferred = $q.defer(); |
124 | - loadPluginsCache().then( | 124 | + loadPluginsCache(config).then( |
125 | function success() { | 125 | function success() { |
126 | utils.filterSearchTextEntities(allActionPlugins, 'name', pageLink, deferred); | 126 | utils.filterSearchTextEntities(allActionPlugins, 'name', pageLink, deferred); |
127 | }, | 127 | }, |
@@ -132,9 +132,9 @@ function PluginService($http, $q, $rootScope, $filter, componentDescriptorServic | @@ -132,9 +132,9 @@ function PluginService($http, $q, $rootScope, $filter, componentDescriptorServic | ||
132 | return deferred.promise; | 132 | return deferred.promise; |
133 | } | 133 | } |
134 | 134 | ||
135 | - function getAllPlugins(pageLink) { | 135 | + function getAllPlugins(pageLink, config) { |
136 | var deferred = $q.defer(); | 136 | var deferred = $q.defer(); |
137 | - loadPluginsCache().then( | 137 | + loadPluginsCache(config).then( |
138 | function success() { | 138 | function success() { |
139 | utils.filterSearchTextEntities(allPlugins, 'name', pageLink, deferred); | 139 | utils.filterSearchTextEntities(allPlugins, 'name', pageLink, deferred); |
140 | }, | 140 | }, |
@@ -156,10 +156,10 @@ function PluginService($http, $q, $rootScope, $filter, componentDescriptorServic | @@ -156,10 +156,10 @@ function PluginService($http, $q, $rootScope, $filter, componentDescriptorServic | ||
156 | return deferred.promise; | 156 | return deferred.promise; |
157 | } | 157 | } |
158 | 158 | ||
159 | - function getPlugin(pluginId) { | 159 | + function getPlugin(pluginId, config) { |
160 | var deferred = $q.defer(); | 160 | var deferred = $q.defer(); |
161 | var url = '/api/plugin/' + pluginId; | 161 | var url = '/api/plugin/' + pluginId; |
162 | - $http.get(url, null).then(function success(response) { | 162 | + $http.get(url, config).then(function success(response) { |
163 | deferred.resolve(response.data); | 163 | deferred.resolve(response.data); |
164 | }, function fail(response) { | 164 | }, function fail(response) { |
165 | deferred.reject(response.data); | 165 | deferred.reject(response.data); |
@@ -47,11 +47,11 @@ function RuleService($http, $q, $rootScope, $filter, types, utils) { | @@ -47,11 +47,11 @@ function RuleService($http, $q, $rootScope, $filter, types, utils) { | ||
47 | tenantRules = undefined; | 47 | tenantRules = undefined; |
48 | } | 48 | } |
49 | 49 | ||
50 | - function loadRulesCache() { | 50 | + function loadRulesCache(config) { |
51 | var deferred = $q.defer(); | 51 | var deferred = $q.defer(); |
52 | if (!allRules) { | 52 | if (!allRules) { |
53 | var url = '/api/rules'; | 53 | var url = '/api/rules'; |
54 | - $http.get(url, null).then(function success(response) { | 54 | + $http.get(url, config).then(function success(response) { |
55 | allRules = response.data; | 55 | allRules = response.data; |
56 | systemRules = []; | 56 | systemRules = []; |
57 | tenantRules = []; | 57 | tenantRules = []; |
@@ -100,9 +100,9 @@ function RuleService($http, $q, $rootScope, $filter, types, utils) { | @@ -100,9 +100,9 @@ function RuleService($http, $q, $rootScope, $filter, types, utils) { | ||
100 | return deferred.promise; | 100 | return deferred.promise; |
101 | } | 101 | } |
102 | 102 | ||
103 | - function getAllRules(pageLink) { | 103 | + function getAllRules(pageLink, config) { |
104 | var deferred = $q.defer(); | 104 | var deferred = $q.defer(); |
105 | - loadRulesCache().then( | 105 | + loadRulesCache(config).then( |
106 | function success() { | 106 | function success() { |
107 | utils.filterSearchTextEntities(allRules, 'name', pageLink, deferred); | 107 | utils.filterSearchTextEntities(allRules, 'name', pageLink, deferred); |
108 | }, | 108 | }, |
@@ -124,10 +124,10 @@ function RuleService($http, $q, $rootScope, $filter, types, utils) { | @@ -124,10 +124,10 @@ function RuleService($http, $q, $rootScope, $filter, types, utils) { | ||
124 | return deferred.promise; | 124 | return deferred.promise; |
125 | } | 125 | } |
126 | 126 | ||
127 | - function getRule(ruleId) { | 127 | + function getRule(ruleId, config) { |
128 | var deferred = $q.defer(); | 128 | var deferred = $q.defer(); |
129 | var url = '/api/rule/' + ruleId; | 129 | var url = '/api/rule/' + ruleId; |
130 | - $http.get(url, null).then(function success(response) { | 130 | + $http.get(url, config).then(function success(response) { |
131 | deferred.resolve(response.data); | 131 | deferred.resolve(response.data); |
132 | }, function fail(response) { | 132 | }, function fail(response) { |
133 | deferred.reject(response.data); | 133 | deferred.reject(response.data); |
@@ -23,6 +23,8 @@ export default angular.module('thingsboard.api.telemetryWebsocket', [thingsboard | @@ -23,6 +23,8 @@ export default angular.module('thingsboard.api.telemetryWebsocket', [thingsboard | ||
23 | const RECONNECT_INTERVAL = 2000; | 23 | const RECONNECT_INTERVAL = 2000; |
24 | const WS_IDLE_TIMEOUT = 90000; | 24 | const WS_IDLE_TIMEOUT = 90000; |
25 | 25 | ||
26 | +const MAX_PUBLISH_COMMANDS = 10; | ||
27 | + | ||
26 | /*@ngInject*/ | 28 | /*@ngInject*/ |
27 | function TelemetryWebsocketService($rootScope, $websocket, $timeout, $window, types, userService) { | 29 | function TelemetryWebsocketService($rootScope, $websocket, $timeout, $window, types, userService) { |
28 | 30 | ||
@@ -75,19 +77,40 @@ function TelemetryWebsocketService($rootScope, $websocket, $timeout, $window, ty | @@ -75,19 +77,40 @@ function TelemetryWebsocketService($rootScope, $websocket, $timeout, $window, ty | ||
75 | return service; | 77 | return service; |
76 | 78 | ||
77 | function publishCommands () { | 79 | function publishCommands () { |
78 | - if (isOpened && (cmdsWrapper.tsSubCmds.length > 0 || | ||
79 | - cmdsWrapper.historyCmds.length > 0 || | ||
80 | - cmdsWrapper.attrSubCmds.length > 0)) { | ||
81 | - dataStream.send(angular.copy(cmdsWrapper)).then(function () { | 80 | + while(isOpened && hasCommands()) { |
81 | + dataStream.send(preparePublishCommands()).then(function () { | ||
82 | checkToClose(); | 82 | checkToClose(); |
83 | }); | 83 | }); |
84 | - cmdsWrapper.tsSubCmds = []; | ||
85 | - cmdsWrapper.historyCmds = []; | ||
86 | - cmdsWrapper.attrSubCmds = []; | ||
87 | } | 84 | } |
88 | tryOpenSocket(); | 85 | tryOpenSocket(); |
89 | } | 86 | } |
90 | 87 | ||
88 | + function hasCommands() { | ||
89 | + return cmdsWrapper.tsSubCmds.length > 0 || | ||
90 | + cmdsWrapper.historyCmds.length > 0 || | ||
91 | + cmdsWrapper.attrSubCmds.length > 0; | ||
92 | + } | ||
93 | + | ||
94 | + function preparePublishCommands() { | ||
95 | + var preparedWrapper = {}; | ||
96 | + var leftCount = MAX_PUBLISH_COMMANDS; | ||
97 | + preparedWrapper.tsSubCmds = popCmds(cmdsWrapper.tsSubCmds, leftCount); | ||
98 | + leftCount -= preparedWrapper.tsSubCmds.length; | ||
99 | + preparedWrapper.historyCmds = popCmds(cmdsWrapper.historyCmds, leftCount); | ||
100 | + leftCount -= preparedWrapper.historyCmds.length; | ||
101 | + preparedWrapper.attrSubCmds = popCmds(cmdsWrapper.attrSubCmds, leftCount); | ||
102 | + return preparedWrapper; | ||
103 | + } | ||
104 | + | ||
105 | + function popCmds(cmds, leftCount) { | ||
106 | + var toPublish = Math.min(cmds.length, leftCount); | ||
107 | + if (toPublish > 0) { | ||
108 | + return cmds.splice(0, toPublish); | ||
109 | + } else { | ||
110 | + return []; | ||
111 | + } | ||
112 | + } | ||
113 | + | ||
91 | function onError (/*message*/) { | 114 | function onError (/*message*/) { |
92 | isOpening = false; | 115 | isOpening = false; |
93 | } | 116 | } |
@@ -29,7 +29,7 @@ function TenantService($http, $q) { | @@ -29,7 +29,7 @@ function TenantService($http, $q) { | ||
29 | 29 | ||
30 | return service; | 30 | return service; |
31 | 31 | ||
32 | - function getTenants (pageLink) { | 32 | + function getTenants (pageLink, config) { |
33 | var deferred = $q.defer(); | 33 | var deferred = $q.defer(); |
34 | var url = '/api/tenants?limit=' + pageLink.limit; | 34 | var url = '/api/tenants?limit=' + pageLink.limit; |
35 | if (angular.isDefined(pageLink.textSearch)) { | 35 | if (angular.isDefined(pageLink.textSearch)) { |
@@ -41,7 +41,7 @@ function TenantService($http, $q) { | @@ -41,7 +41,7 @@ function TenantService($http, $q) { | ||
41 | if (angular.isDefined(pageLink.textOffset)) { | 41 | if (angular.isDefined(pageLink.textOffset)) { |
42 | url += '&textOffset=' + pageLink.textOffset; | 42 | url += '&textOffset=' + pageLink.textOffset; |
43 | } | 43 | } |
44 | - $http.get(url, null).then(function success(response) { | 44 | + $http.get(url, config).then(function success(response) { |
45 | deferred.resolve(response.data); | 45 | deferred.resolve(response.data); |
46 | }, function fail() { | 46 | }, function fail() { |
47 | deferred.reject(); | 47 | deferred.reject(); |
@@ -49,10 +49,10 @@ function TenantService($http, $q) { | @@ -49,10 +49,10 @@ function TenantService($http, $q) { | ||
49 | return deferred.promise; | 49 | return deferred.promise; |
50 | } | 50 | } |
51 | 51 | ||
52 | - function getTenant (tenantId) { | 52 | + function getTenant (tenantId, config) { |
53 | var deferred = $q.defer(); | 53 | var deferred = $q.defer(); |
54 | var url = '/api/tenant/' + tenantId; | 54 | var url = '/api/tenant/' + tenantId; |
55 | - $http.get(url, null).then(function success(response) { | 55 | + $http.get(url, config).then(function success(response) { |
56 | deferred.resolve(response.data); | 56 | deferred.resolve(response.data); |
57 | }, function fail(response) { | 57 | }, function fail(response) { |
58 | deferred.reject(response.data); | 58 | deferred.reject(response.data); |
@@ -421,10 +421,14 @@ function UserService($http, $q, $rootScope, adminService, dashboardService, logi | @@ -421,10 +421,14 @@ function UserService($http, $q, $rootScope, adminService, dashboardService, logi | ||
421 | return deferred.promise; | 421 | return deferred.promise; |
422 | } | 422 | } |
423 | 423 | ||
424 | - function getUser(userId, ignoreErrors) { | 424 | + function getUser(userId, ignoreErrors, config) { |
425 | var deferred = $q.defer(); | 425 | var deferred = $q.defer(); |
426 | var url = '/api/user/' + userId; | 426 | var url = '/api/user/' + userId; |
427 | - $http.get(url, { ignoreErrors: ignoreErrors }).then(function success(response) { | 427 | + if (!config) { |
428 | + config = {}; | ||
429 | + } | ||
430 | + config = Object.assign(config, { ignoreErrors: ignoreErrors }); | ||
431 | + $http.get(url, config).then(function success(response) { | ||
428 | deferred.resolve(response.data); | 432 | deferred.resolve(response.data); |
429 | }, function fail() { | 433 | }, function fail() { |
430 | deferred.reject(); | 434 | deferred.reject(); |
@@ -298,11 +298,11 @@ function WidgetService($rootScope, $http, $q, $filter, $ocLazyLoad, $window, $tr | @@ -298,11 +298,11 @@ function WidgetService($rootScope, $http, $q, $filter, $ocLazyLoad, $window, $tr | ||
298 | tenantWidgetsBundles = undefined; | 298 | tenantWidgetsBundles = undefined; |
299 | } | 299 | } |
300 | 300 | ||
301 | - function loadWidgetsBundleCache() { | 301 | + function loadWidgetsBundleCache(config) { |
302 | var deferred = $q.defer(); | 302 | var deferred = $q.defer(); |
303 | if (!allWidgetsBundles) { | 303 | if (!allWidgetsBundles) { |
304 | var url = '/api/widgetsBundles'; | 304 | var url = '/api/widgetsBundles'; |
305 | - $http.get(url, null).then(function success(response) { | 305 | + $http.get(url, config).then(function success(response) { |
306 | allWidgetsBundles = response.data; | 306 | allWidgetsBundles = response.data; |
307 | systemWidgetsBundles = []; | 307 | systemWidgetsBundles = []; |
308 | tenantWidgetsBundles = []; | 308 | tenantWidgetsBundles = []; |
@@ -326,9 +326,9 @@ function WidgetService($rootScope, $http, $q, $filter, $ocLazyLoad, $window, $tr | @@ -326,9 +326,9 @@ function WidgetService($rootScope, $http, $q, $filter, $ocLazyLoad, $window, $tr | ||
326 | } | 326 | } |
327 | 327 | ||
328 | 328 | ||
329 | - function getSystemWidgetsBundles() { | 329 | + function getSystemWidgetsBundles(config) { |
330 | var deferred = $q.defer(); | 330 | var deferred = $q.defer(); |
331 | - loadWidgetsBundleCache().then( | 331 | + loadWidgetsBundleCache(config).then( |
332 | function success() { | 332 | function success() { |
333 | deferred.resolve(systemWidgetsBundles); | 333 | deferred.resolve(systemWidgetsBundles); |
334 | }, | 334 | }, |
@@ -339,9 +339,9 @@ function WidgetService($rootScope, $http, $q, $filter, $ocLazyLoad, $window, $tr | @@ -339,9 +339,9 @@ function WidgetService($rootScope, $http, $q, $filter, $ocLazyLoad, $window, $tr | ||
339 | return deferred.promise; | 339 | return deferred.promise; |
340 | } | 340 | } |
341 | 341 | ||
342 | - function getTenantWidgetsBundles() { | 342 | + function getTenantWidgetsBundles(config) { |
343 | var deferred = $q.defer(); | 343 | var deferred = $q.defer(); |
344 | - loadWidgetsBundleCache().then( | 344 | + loadWidgetsBundleCache(config).then( |
345 | function success() { | 345 | function success() { |
346 | deferred.resolve(tenantWidgetsBundles); | 346 | deferred.resolve(tenantWidgetsBundles); |
347 | }, | 347 | }, |
@@ -352,9 +352,9 @@ function WidgetService($rootScope, $http, $q, $filter, $ocLazyLoad, $window, $tr | @@ -352,9 +352,9 @@ function WidgetService($rootScope, $http, $q, $filter, $ocLazyLoad, $window, $tr | ||
352 | return deferred.promise; | 352 | return deferred.promise; |
353 | } | 353 | } |
354 | 354 | ||
355 | - function getAllWidgetsBundles() { | 355 | + function getAllWidgetsBundles(config) { |
356 | var deferred = $q.defer(); | 356 | var deferred = $q.defer(); |
357 | - loadWidgetsBundleCache().then( | 357 | + loadWidgetsBundleCache(config).then( |
358 | function success() { | 358 | function success() { |
359 | deferred.resolve(allWidgetsBundles); | 359 | deferred.resolve(allWidgetsBundles); |
360 | }, | 360 | }, |
@@ -27,8 +27,8 @@ | @@ -27,8 +27,8 @@ | ||
27 | </md-button> | 27 | </md-button> |
28 | </div> | 28 | </div> |
29 | </md-toolbar> | 29 | </md-toolbar> |
30 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
31 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 30 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
31 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
32 | <md-dialog-content> | 32 | <md-dialog-content> |
33 | <div class="md-dialog-content"> | 33 | <div class="md-dialog-content"> |
34 | <tb-asset asset="vm.item" is-edit="true" the-form="theForm"></tb-asset> | 34 | <tb-asset asset="vm.item" is-edit="true" the-form="theForm"></tb-asset> |
@@ -36,10 +36,10 @@ | @@ -36,10 +36,10 @@ | ||
36 | </md-dialog-content> | 36 | </md-dialog-content> |
37 | <md-dialog-actions layout="row"> | 37 | <md-dialog-actions layout="row"> |
38 | <span flex></span> | 38 | <span flex></span> |
39 | - <md-button ng-disabled="loading || theForm.$invalid || !theForm.$dirty" type="submit" class="md-raised md-primary"> | 39 | + <md-button ng-disabled="$root.loading || theForm.$invalid || !theForm.$dirty" type="submit" class="md-raised md-primary"> |
40 | {{ 'action.add' | translate }} | 40 | {{ 'action.add' | translate }} |
41 | </md-button> | 41 | </md-button> |
42 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> | 42 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> |
43 | </md-dialog-actions> | 43 | </md-dialog-actions> |
44 | </form> | 44 | </form> |
45 | </md-dialog> | 45 | </md-dialog> |
@@ -26,8 +26,8 @@ | @@ -26,8 +26,8 @@ | ||
26 | </md-button> | 26 | </md-button> |
27 | </div> | 27 | </div> |
28 | </md-toolbar> | 28 | </md-toolbar> |
29 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
30 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 29 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
30 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
31 | <md-dialog-content> | 31 | <md-dialog-content> |
32 | <div class="md-dialog-content"> | 32 | <div class="md-dialog-content"> |
33 | <fieldset> | 33 | <fieldset> |
@@ -65,11 +65,11 @@ | @@ -65,11 +65,11 @@ | ||
65 | </md-dialog-content> | 65 | </md-dialog-content> |
66 | <md-dialog-actions layout="row"> | 66 | <md-dialog-actions layout="row"> |
67 | <span flex></span> | 67 | <span flex></span> |
68 | - <md-button ng-disabled="loading || vm.assets.selectedCount == 0" type="submit" | 68 | + <md-button ng-disabled="$root.loading || vm.assets.selectedCount == 0" type="submit" |
69 | class="md-raised md-primary"> | 69 | class="md-raised md-primary"> |
70 | {{ 'action.assign' | translate }} | 70 | {{ 'action.assign' | translate }} |
71 | </md-button> | 71 | </md-button> |
72 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | | 72 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | |
73 | translate }} | 73 | translate }} |
74 | </md-button> | 74 | </md-button> |
75 | </md-dialog-actions> | 75 | </md-dialog-actions> |
@@ -48,7 +48,7 @@ | @@ -48,7 +48,7 @@ | ||
48 | ng-show="!isEdit && isPublic && (assetScope === 'customer' || assetScope === 'tenant')"> | 48 | ng-show="!isEdit && isPublic && (assetScope === 'customer' || assetScope === 'tenant')"> |
49 | {{ 'asset.asset-public' | translate }} | 49 | {{ 'asset.asset-public' | translate }} |
50 | </div> | 50 | </div> |
51 | - <fieldset ng-disabled="loading || !isEdit"> | 51 | + <fieldset ng-disabled="$root.loading || !isEdit"> |
52 | <md-input-container class="md-block"> | 52 | <md-input-container class="md-block"> |
53 | <label translate>asset.name</label> | 53 | <label translate>asset.name</label> |
54 | <input required name="name" ng-model="asset.name"> | 54 | <input required name="name" ng-model="asset.name"> |
@@ -57,7 +57,7 @@ | @@ -57,7 +57,7 @@ | ||
57 | </div> | 57 | </div> |
58 | </md-input-container> | 58 | </md-input-container> |
59 | <tb-entity-subtype-autocomplete | 59 | <tb-entity-subtype-autocomplete |
60 | - ng-disabled="loading || !isEdit" | 60 | + ng-disabled="$root.loading || !isEdit" |
61 | tb-required="true" | 61 | tb-required="true" |
62 | the-form="theForm" | 62 | the-form="theForm" |
63 | ng-model="asset.type" | 63 | ng-model="asset.type" |
@@ -26,8 +26,8 @@ | @@ -26,8 +26,8 @@ | ||
26 | </md-button> | 26 | </md-button> |
27 | </div> | 27 | </div> |
28 | </md-toolbar> | 28 | </md-toolbar> |
29 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
30 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 29 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
30 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
31 | <md-dialog-content> | 31 | <md-dialog-content> |
32 | <div class="md-dialog-content"> | 32 | <div class="md-dialog-content"> |
33 | <fieldset> | 33 | <fieldset> |
@@ -65,10 +65,10 @@ | @@ -65,10 +65,10 @@ | ||
65 | </md-dialog-content> | 65 | </md-dialog-content> |
66 | <md-dialog-actions layout="row"> | 66 | <md-dialog-actions layout="row"> |
67 | <span flex></span> | 67 | <span flex></span> |
68 | - <md-button ng-disabled="loading || vm.customers.selection==null" type="submit" class="md-raised md-primary"> | 68 | + <md-button ng-disabled="$root.loading || vm.customers.selection==null" type="submit" class="md-raised md-primary"> |
69 | {{ 'action.assign' | translate }} | 69 | {{ 'action.assign' | translate }} |
70 | </md-button> | 70 | </md-button> |
71 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | | 71 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | |
72 | translate }} | 72 | translate }} |
73 | </md-button> | 73 | </md-button> |
74 | </md-dialog-actions> | 74 | </md-dialog-actions> |
@@ -134,6 +134,8 @@ function Utils($mdColorPalette, $rootScope, $window, $translate, $q, $timeout, t | @@ -134,6 +134,8 @@ function Utils($mdColorPalette, $rootScope, $window, $translate, $q, $timeout, t | ||
134 | defaultAlarmDataKeys.push(dataKey); | 134 | defaultAlarmDataKeys.push(dataKey); |
135 | } | 135 | } |
136 | 136 | ||
137 | + var imageAspectMap = {}; | ||
138 | + | ||
137 | var service = { | 139 | var service = { |
138 | getDefaultDatasource: getDefaultDatasource, | 140 | getDefaultDatasource: getDefaultDatasource, |
139 | generateObjectFromJsonSchema: generateObjectFromJsonSchema, | 141 | generateObjectFromJsonSchema: generateObjectFromJsonSchema, |
@@ -159,7 +161,8 @@ function Utils($mdColorPalette, $rootScope, $window, $translate, $q, $timeout, t | @@ -159,7 +161,8 @@ function Utils($mdColorPalette, $rootScope, $window, $translate, $q, $timeout, t | ||
159 | insertVariable: insertVariable, | 161 | insertVariable: insertVariable, |
160 | customTranslation: customTranslation, | 162 | customTranslation: customTranslation, |
161 | objToBase64: objToBase64, | 163 | objToBase64: objToBase64, |
162 | - base64toObj: base64toObj | 164 | + base64toObj: base64toObj, |
165 | + loadImageAspect: loadImageAspect | ||
163 | } | 166 | } |
164 | 167 | ||
165 | return service; | 168 | return service; |
@@ -543,4 +546,34 @@ function Utils($mdColorPalette, $rootScope, $window, $translate, $q, $timeout, t | @@ -543,4 +546,34 @@ function Utils($mdColorPalette, $rootScope, $window, $translate, $q, $timeout, t | ||
543 | return obj; | 546 | return obj; |
544 | } | 547 | } |
545 | 548 | ||
549 | + function loadImageAspect(imageUrl) { | ||
550 | + var deferred = $q.defer(); | ||
551 | + if (imageUrl && imageUrl.length) { | ||
552 | + var urlHashCode = hashCode(imageUrl); | ||
553 | + var aspect = imageAspectMap[urlHashCode]; | ||
554 | + if (angular.isUndefined(aspect)) { | ||
555 | + var testImage = document.createElement('img'); // eslint-disable-line | ||
556 | + testImage.style.visibility = 'hidden'; | ||
557 | + testImage.onload = function() { | ||
558 | + aspect = testImage.width / testImage.height; | ||
559 | + document.body.removeChild(testImage); //eslint-disable-line | ||
560 | + imageAspectMap[urlHashCode] = aspect; | ||
561 | + deferred.resolve(aspect); | ||
562 | + }; | ||
563 | + testImage.onerror = function() { | ||
564 | + aspect = 0; | ||
565 | + imageAspectMap[urlHashCode] = aspect; | ||
566 | + deferred.resolve(aspect); | ||
567 | + }; | ||
568 | + document.body.appendChild(testImage); //eslint-disable-line | ||
569 | + testImage.src = imageUrl; | ||
570 | + } else { | ||
571 | + deferred.resolve(aspect); | ||
572 | + } | ||
573 | + } else { | ||
574 | + deferred.resolve(0); | ||
575 | + } | ||
576 | + return deferred.promise; | ||
577 | + } | ||
578 | + | ||
546 | } | 579 | } |
@@ -27,11 +27,11 @@ | @@ -27,11 +27,11 @@ | ||
27 | </md-button> | 27 | </md-button> |
28 | </div> | 28 | </div> |
29 | </md-toolbar> | 29 | </md-toolbar> |
30 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
31 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 30 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
31 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
32 | <md-dialog-content> | 32 | <md-dialog-content> |
33 | <div class="md-dialog-content tb-filter"> | 33 | <div class="md-dialog-content tb-filter"> |
34 | - <fieldset ng-disabled="loading || vm.isReadOnly"> | 34 | + <fieldset ng-disabled="$root.loading || vm.isReadOnly"> |
35 | <section flex layout="row"> | 35 | <section flex layout="row"> |
36 | <md-input-container flex class="md-block"> | 36 | <md-input-container flex class="md-block"> |
37 | <label translate>rule.component-name</label> | 37 | <label translate>rule.component-name</label> |
@@ -42,7 +42,7 @@ | @@ -42,7 +42,7 @@ | ||
42 | </md-input-container> | 42 | </md-input-container> |
43 | <md-input-container flex class="md-block"> | 43 | <md-input-container flex class="md-block"> |
44 | <label translate>rule.component-type</label> | 44 | <label translate>rule.component-type</label> |
45 | - <md-select required name="componentType" ng-model="vm.componentInfo.component.clazz" ng-disabled="loading || vm.isReadOnly"> | 45 | + <md-select required name="componentType" ng-model="vm.componentInfo.component.clazz" ng-disabled="$root.loading || vm.isReadOnly"> |
46 | <md-option ng-repeat="componentDescriptor in vm.componentDescriptors" ng-value="componentDescriptor.clazz"> | 46 | <md-option ng-repeat="componentDescriptor in vm.componentDescriptors" ng-value="componentDescriptor.clazz"> |
47 | {{componentDescriptor.name}} | 47 | {{componentDescriptor.name}} |
48 | </md-option> | 48 | </md-option> |
@@ -57,7 +57,7 @@ | @@ -57,7 +57,7 @@ | ||
57 | <tb-json-form schema="vm.componentDescriptor.configurationDescriptor.schema" | 57 | <tb-json-form schema="vm.componentDescriptor.configurationDescriptor.schema" |
58 | form="vm.componentDescriptor.configurationDescriptor.form" | 58 | form="vm.componentDescriptor.configurationDescriptor.form" |
59 | model="vm.componentInfo.component.configuration" | 59 | model="vm.componentInfo.component.configuration" |
60 | - readonly="loading || vm.isReadOnly" | 60 | + readonly="$root.loading || vm.isReadOnly" |
61 | form-control="theForm"> | 61 | form-control="theForm"> |
62 | </tb-json-form> | 62 | </tb-json-form> |
63 | </md-card-content> | 63 | </md-card-content> |
@@ -67,11 +67,11 @@ | @@ -67,11 +67,11 @@ | ||
67 | </md-dialog-content> | 67 | </md-dialog-content> |
68 | <md-dialog-actions layout="row"> | 68 | <md-dialog-actions layout="row"> |
69 | <span flex></span> | 69 | <span flex></span> |
70 | - <md-button ng-if="!vm.isReadOnly" ng-disabled="loading || theForm.$invalid || !theForm.$dirty" type="submit" | 70 | + <md-button ng-if="!vm.isReadOnly" ng-disabled="$root.loading || theForm.$invalid || !theForm.$dirty" type="submit" |
71 | class="md-raised md-primary"> | 71 | class="md-raised md-primary"> |
72 | {{ (vm.isAdd ? 'action.add' : 'action.save') | translate }} | 72 | {{ (vm.isAdd ? 'action.add' : 'action.save') | translate }} |
73 | </md-button> | 73 | </md-button> |
74 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | | 74 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | |
75 | translate }} | 75 | translate }} |
76 | </md-button> | 76 | </md-button> |
77 | </md-dialog-actions> | 77 | </md-dialog-actions> |
@@ -24,7 +24,7 @@ | @@ -24,7 +24,7 @@ | ||
24 | {{ componentTypeName }} | 24 | {{ componentTypeName }} |
25 | </span> | 25 | </span> |
26 | <span ng-if="readOnly" style="min-width: 40px; min-height: 40px; margin: 0 6px;"></br></span> | 26 | <span ng-if="readOnly" style="min-width: 40px; min-height: 40px; margin: 0 6px;"></br></span> |
27 | - <md-button ng-disabled="loading" class="md-icon-button md-primary" | 27 | + <md-button ng-disabled="$root.loading" class="md-icon-button md-primary" |
28 | style="min-width: 40px;" | 28 | style="min-width: 40px;" |
29 | ng-click="openComponent($event)" | 29 | ng-click="openComponent($event)" |
30 | aria-label="{{ (readOnly ? 'action.view' : 'action.edit') | translate }}"> | 30 | aria-label="{{ (readOnly ? 'action.view' : 'action.edit') | translate }}"> |
@@ -43,7 +43,7 @@ | @@ -43,7 +43,7 @@ | ||
43 | edit | 43 | edit |
44 | </md-icon> | 44 | </md-icon> |
45 | </md-button> | 45 | </md-button> |
46 | - <md-button ng-if="!readOnly" ng-disabled="loading" class="md-icon-button md-primary" | 46 | + <md-button ng-if="!readOnly" ng-disabled="$root.loading" class="md-icon-button md-primary" |
47 | style="min-width: 40px;" | 47 | style="min-width: 40px;" |
48 | ng-click="onRemoveComponent({event: $event})" | 48 | ng-click="onRemoveComponent({event: $event})" |
49 | aria-label="{{ 'action.remove' | translate }}"> | 49 | aria-label="{{ 'action.remove' | translate }}"> |
@@ -48,19 +48,19 @@ function DashboardAutocomplete($compile, $templateCache, $q, dashboardService, u | @@ -48,19 +48,19 @@ function DashboardAutocomplete($compile, $templateCache, $q, dashboardService, u | ||
48 | var promise; | 48 | var promise; |
49 | if (scope.dashboardsScope === 'customer' || userService.getAuthority() === 'CUSTOMER_USER') { | 49 | if (scope.dashboardsScope === 'customer' || userService.getAuthority() === 'CUSTOMER_USER') { |
50 | if (scope.customerId) { | 50 | if (scope.customerId) { |
51 | - promise = dashboardService.getCustomerDashboards(scope.customerId, pageLink, false); | 51 | + promise = dashboardService.getCustomerDashboards(scope.customerId, pageLink, false, {ignoreLoading: true}); |
52 | } else { | 52 | } else { |
53 | promise = $q.when({data: []}); | 53 | promise = $q.when({data: []}); |
54 | } | 54 | } |
55 | } else { | 55 | } else { |
56 | if (userService.getAuthority() === 'SYS_ADMIN') { | 56 | if (userService.getAuthority() === 'SYS_ADMIN') { |
57 | if (scope.tenantId) { | 57 | if (scope.tenantId) { |
58 | - promise = dashboardService.getTenantDashboardsByTenantId(scope.tenantId, pageLink); | 58 | + promise = dashboardService.getTenantDashboardsByTenantId(scope.tenantId, pageLink, {ignoreLoading: true}); |
59 | } else { | 59 | } else { |
60 | promise = $q.when({data: []}); | 60 | promise = $q.when({data: []}); |
61 | } | 61 | } |
62 | } else { | 62 | } else { |
63 | - promise = dashboardService.getTenantDashboards(pageLink, false); | 63 | + promise = dashboardService.getTenantDashboards(pageLink, false, {ignoreLoading: true}); |
64 | } | 64 | } |
65 | } | 65 | } |
66 | 66 |
@@ -48,12 +48,12 @@ function DashboardSelect($compile, $templateCache, $q, $mdMedia, $mdPanel, $docu | @@ -48,12 +48,12 @@ function DashboardSelect($compile, $templateCache, $q, $mdMedia, $mdPanel, $docu | ||
48 | var promise; | 48 | var promise; |
49 | if (scope.dashboardsScope === 'customer' || userService.getAuthority() === 'CUSTOMER_USER') { | 49 | if (scope.dashboardsScope === 'customer' || userService.getAuthority() === 'CUSTOMER_USER') { |
50 | if (scope.customerId && scope.customerId != types.id.nullUid) { | 50 | if (scope.customerId && scope.customerId != types.id.nullUid) { |
51 | - promise = dashboardService.getCustomerDashboards(scope.customerId, pageLink, false); | 51 | + promise = dashboardService.getCustomerDashboards(scope.customerId, pageLink, false, {ignoreLoading: true}); |
52 | } else { | 52 | } else { |
53 | promise = $q.when({data: []}); | 53 | promise = $q.when({data: []}); |
54 | } | 54 | } |
55 | } else { | 55 | } else { |
56 | - promise = dashboardService.getTenantDashboards(pageLink, false); | 56 | + promise = dashboardService.getTenantDashboards(pageLink, false, {ignoreLoading: true}); |
57 | } | 57 | } |
58 | 58 | ||
59 | promise.then(function success(result) { | 59 | promise.then(function success(result) { |
@@ -43,7 +43,7 @@ function DatakeyConfigDialogController($scope, $mdDialog, $q, entityService, dat | @@ -43,7 +43,7 @@ function DatakeyConfigDialogController($scope, $mdDialog, $q, entityService, dat | ||
43 | function success(aliasInfo) { | 43 | function success(aliasInfo) { |
44 | var entity = aliasInfo.currentEntity; | 44 | var entity = aliasInfo.currentEntity; |
45 | if (entity) { | 45 | if (entity) { |
46 | - entityService.getEntityKeys(entity.entityType, entity.id, query, type).then( | 46 | + entityService.getEntityKeys(entity.entityType, entity.id, query, type, {ignoreLoading: true}).then( |
47 | function success(keys) { | 47 | function success(keys) { |
48 | deferred.resolve(keys); | 48 | deferred.resolve(keys); |
49 | }, | 49 | }, |
@@ -26,8 +26,8 @@ | @@ -26,8 +26,8 @@ | ||
26 | </md-button> | 26 | </md-button> |
27 | </div> | 27 | </div> |
28 | </md-toolbar> | 28 | </md-toolbar> |
29 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
30 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 29 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
30 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
31 | <md-dialog-content> | 31 | <md-dialog-content> |
32 | <tb-datakey-config ng-model="vm.dataKey" | 32 | <tb-datakey-config ng-model="vm.dataKey" |
33 | fetch-entity-keys="vm.fetchEntityKeys(entityAliasId, query, type)" | 33 | fetch-entity-keys="vm.fetchEntityKeys(entityAliasId, query, type)" |
@@ -37,10 +37,10 @@ | @@ -37,10 +37,10 @@ | ||
37 | </md-dialog-content> | 37 | </md-dialog-content> |
38 | <md-dialog-actions layout="row"> | 38 | <md-dialog-actions layout="row"> |
39 | <span flex></span> | 39 | <span flex></span> |
40 | - <md-button ng-disabled="loading || theForm.$invalid || !theForm.$dirty" type="submit" class="md-raised md-primary"> | 40 | + <md-button ng-disabled="$root.loading || theForm.$invalid || !theForm.$dirty" type="submit" class="md-raised md-primary"> |
41 | {{ 'action.save' | translate }} | 41 | {{ 'action.save' | translate }} |
42 | </md-button> | 42 | </md-button> |
43 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> | 43 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> |
44 | </md-dialog-actions> | 44 | </md-dialog-actions> |
45 | </form> | 45 | </form> |
46 | </md-dialog> | 46 | </md-dialog> |
@@ -35,7 +35,7 @@ | @@ -35,7 +35,7 @@ | ||
35 | </div> | 35 | </div> |
36 | <section ng-if="!isReadOnly" layout="row" layout-wrap | 36 | <section ng-if="!isReadOnly" layout="row" layout-wrap |
37 | class="tb-header-buttons md-fab"> | 37 | class="tb-header-buttons md-fab"> |
38 | - <md-button ng-show="isEdit" ng-disabled="loading || theForm.$invalid || !theForm.$dirty" | 38 | + <md-button ng-show="isEdit" ng-disabled="$root.loading || theForm.$invalid || !theForm.$dirty" |
39 | class="tb-btn-header md-accent md-hue-2 md-fab md-fab-bottom-right" | 39 | class="tb-btn-header md-accent md-hue-2 md-fab md-fab-bottom-right" |
40 | aria-label="{{ 'action.apply' | translate }}" | 40 | aria-label="{{ 'action.apply' | translate }}" |
41 | ng-click="detailsApply()"> | 41 | ng-click="detailsApply()"> |
@@ -44,7 +44,7 @@ | @@ -44,7 +44,7 @@ | ||
44 | </md-tooltip> | 44 | </md-tooltip> |
45 | <ng-md-icon icon="done"></ng-md-icon> | 45 | <ng-md-icon icon="done"></ng-md-icon> |
46 | </md-button> | 46 | </md-button> |
47 | - <md-button ng-disabled="loading || (isAlwaysEdit && !theForm.$dirty)" class="tb-btn-header md-accent md-hue-2 md-fab md-fab-bottom-right" | 47 | + <md-button ng-disabled="$root.loading || (isAlwaysEdit && !theForm.$dirty)" class="tb-btn-header md-accent md-hue-2 md-fab md-fab-bottom-right" |
48 | aria-label="{{ 'details.edit-mode' | translate }}" | 48 | aria-label="{{ 'details.edit-mode' | translate }}" |
49 | ng-click="toggleDetailsEditMode()"> | 49 | ng-click="toggleDetailsEditMode()"> |
50 | <md-tooltip md-direction="top"> | 50 | <md-tooltip md-direction="top"> |
@@ -45,7 +45,7 @@ | @@ -45,7 +45,7 @@ | ||
45 | <tb-grid-card-content flex grid-ctl="vm" parent-ctl="vm.parentCtl" item-controller="vm.itemCardController" item-template="vm.itemCardTemplate" item="rowItem[n]"></tb-grid-card-content> | 45 | <tb-grid-card-content flex grid-ctl="vm" parent-ctl="vm.parentCtl" item-controller="vm.itemCardController" item-template="vm.itemCardTemplate" item="rowItem[n]"></tb-grid-card-content> |
46 | </md-card-content> | 46 | </md-card-content> |
47 | <md-card-actions layout="row" layout-align="end end"> | 47 | <md-card-actions layout="row" layout-align="end end"> |
48 | - <md-button ng-if="action.isEnabled(rowItem[n])" ng-disabled="loading" class="md-icon-button md-primary" ng-repeat="action in vm.actionsList" | 48 | + <md-button ng-if="action.isEnabled(rowItem[n])" ng-disabled="$root.loading" class="md-icon-button md-primary" ng-repeat="action in vm.actionsList" |
49 | ng-click="action.onAction($event, rowItem[n])" aria-label="{{ action.name() }}"> | 49 | ng-click="action.onAction($event, rowItem[n])" aria-label="{{ action.name() }}"> |
50 | <md-tooltip md-direction="top"> | 50 | <md-tooltip md-direction="top"> |
51 | {{ action.details( rowItem[n] ) }} | 51 | {{ action.details( rowItem[n] ) }} |
@@ -81,28 +81,28 @@ | @@ -81,28 +81,28 @@ | ||
81 | </section> | 81 | </section> |
82 | 82 | ||
83 | <section layout="row" layout-wrap class="tb-footer-buttons md-fab " layout-align="start end"> | 83 | <section layout="row" layout-wrap class="tb-footer-buttons md-fab " layout-align="start end"> |
84 | - <md-button ng-disabled="loading" ng-show="vm.items.selectedCount > 0" class="tb-btn-footer md-accent md-hue-2 md-fab" ng-repeat="groupAction in vm.groupActionsList" | 84 | + <md-button ng-disabled="$root.loading" ng-show="vm.items.selectedCount > 0" class="tb-btn-footer md-accent md-hue-2 md-fab" ng-repeat="groupAction in vm.groupActionsList" |
85 | ng-click="groupAction.onAction($event, vm.items)" aria-label="{{ groupAction.name() }}"> | 85 | ng-click="groupAction.onAction($event, vm.items)" aria-label="{{ groupAction.name() }}"> |
86 | <md-tooltip md-direction="top"> | 86 | <md-tooltip md-direction="top"> |
87 | {{ groupAction.details(vm.items.selectedCount) }} | 87 | {{ groupAction.details(vm.items.selectedCount) }} |
88 | </md-tooltip> | 88 | </md-tooltip> |
89 | <ng-md-icon icon="{{groupAction.icon}}"></ng-md-icon> | 89 | <ng-md-icon icon="{{groupAction.icon}}"></ng-md-icon> |
90 | </md-button> | 90 | </md-button> |
91 | - <md-button ng-disabled="loading" ng-show="vm.topIndex > 0" class="tb-btn-footer md-primary md-hue-1 md-fab" ng-click="vm.moveToTop()" aria-label="{{'grid.scroll-to-top' | translate}}" > | 91 | + <md-button ng-disabled="$root.loading" ng-show="vm.topIndex > 0" class="tb-btn-footer md-primary md-hue-1 md-fab" ng-click="vm.moveToTop()" aria-label="{{'grid.scroll-to-top' | translate}}" > |
92 | <md-tooltip md-direction="top"> | 92 | <md-tooltip md-direction="top"> |
93 | {{'grid.scroll-to-top' | translate}} | 93 | {{'grid.scroll-to-top' | translate}} |
94 | </md-tooltip> | 94 | </md-tooltip> |
95 | <ng-md-icon icon="arrow_drop_up"></ng-md-icon> | 95 | <ng-md-icon icon="arrow_drop_up"></ng-md-icon> |
96 | </md-button> | 96 | </md-button> |
97 | - <md-button ng-disabled="loading" ng-if="vm.addItemAction.name() && vm.addItemActions.length == 0" class="tb-btn-footer md-accent md-hue-2 md-fab" ng-click="vm.addItemAction.onAction($event)" aria-label="{{ vm.addItemAction.name() }}" > | 97 | + <md-button ng-disabled="$root.loading" ng-if="vm.addItemAction.name() && vm.addItemActions.length == 0" class="tb-btn-footer md-accent md-hue-2 md-fab" ng-click="vm.addItemAction.onAction($event)" aria-label="{{ vm.addItemAction.name() }}" > |
98 | <md-tooltip md-direction="top"> | 98 | <md-tooltip md-direction="top"> |
99 | {{ vm.addItemAction.details() }} | 99 | {{ vm.addItemAction.details() }} |
100 | </md-tooltip> | 100 | </md-tooltip> |
101 | <ng-md-icon icon="{{ vm.addItemAction.icon }}"></ng-md-icon> | 101 | <ng-md-icon icon="{{ vm.addItemAction.icon }}"></ng-md-icon> |
102 | </md-button> | 102 | </md-button> |
103 | - <md-fab-speed-dial ng-disabled="loading" ng-if="vm.addItemAction.name() && vm.addItemActions.length > 0" md-open="vm.addItemActionsOpen" class="md-scale" md-direction="up" ng-if="vm.addItemAction.name()"> | 103 | + <md-fab-speed-dial ng-disabled="$root.loading" ng-if="vm.addItemAction.name() && vm.addItemActions.length > 0" md-open="vm.addItemActionsOpen" class="md-scale" md-direction="up" ng-if="vm.addItemAction.name()"> |
104 | <md-fab-trigger> | 104 | <md-fab-trigger> |
105 | - <md-button ng-disabled="loading" class="tb-btn-footer md-accent md-hue-2 md-fab" aria-label="{{ vm.addItemAction.name() }}" > | 105 | + <md-button ng-disabled="$root.loading" class="tb-btn-footer md-accent md-hue-2 md-fab" aria-label="{{ vm.addItemAction.name() }}" > |
106 | <md-tooltip md-direction="top"> | 106 | <md-tooltip md-direction="top"> |
107 | {{ vm.addItemAction.details() }} | 107 | {{ vm.addItemAction.details() }} |
108 | </md-tooltip> | 108 | </md-tooltip> |
@@ -110,7 +110,7 @@ | @@ -110,7 +110,7 @@ | ||
110 | </md-button> | 110 | </md-button> |
111 | </md-fab-trigger> | 111 | </md-fab-trigger> |
112 | <md-fab-actions> | 112 | <md-fab-actions> |
113 | - <md-button ng-disabled="loading" class="md-accent md-hue-2 md-fab" ng-repeat="addItemAction in vm.addItemActions" | 113 | + <md-button ng-disabled="$root.loading" class="md-accent md-hue-2 md-fab" ng-repeat="addItemAction in vm.addItemActions" |
114 | ng-click="addItemAction.onAction($event)" aria-label="{{ addItemAction.name() }}" > | 114 | ng-click="addItemAction.onAction($event)" aria-label="{{ addItemAction.name() }}" > |
115 | <md-tooltip md-direction="top"> | 115 | <md-tooltip md-direction="top"> |
116 | {{ addItemAction.details() }} | 116 | {{ addItemAction.details() }} |
@@ -16,7 +16,7 @@ | @@ -16,7 +16,7 @@ | ||
16 | 16 | ||
17 | --> | 17 | --> |
18 | <form name="theForm" ng-submit="vm.update()"> | 18 | <form name="theForm" ng-submit="vm.update()"> |
19 | - <fieldset ng-disabled="loading"> | 19 | + <fieldset ng-disabled="$root.loading"> |
20 | <md-content style="height: 100%" flex layout="column"> | 20 | <md-content style="height: 100%" flex layout="column"> |
21 | <section layout="column"> | 21 | <section layout="column"> |
22 | <md-content class="md-padding" layout="column"> | 22 | <md-content class="md-padding" layout="column"> |
@@ -32,15 +32,15 @@ | @@ -32,15 +32,15 @@ | ||
32 | </md-button> | 32 | </md-button> |
33 | </div> | 33 | </div> |
34 | </md-toolbar> | 34 | </md-toolbar> |
35 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
36 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 35 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
36 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
37 | <div class="tb-absolute-fill tb-icons-load" ng-show="vm.loadingIcons" layout="column" layout-align="center center"> | 37 | <div class="tb-absolute-fill tb-icons-load" ng-show="vm.loadingIcons" layout="column" layout-align="center center"> |
38 | <md-progress-circular md-mode="indeterminate" ng-disabled="!vm.loadingIcons" class="md-accent" md-diameter="40"></md-progress-circular> | 38 | <md-progress-circular md-mode="indeterminate" ng-disabled="!vm.loadingIcons" class="md-accent" md-diameter="40"></md-progress-circular> |
39 | </div> | 39 | </div> |
40 | <md-dialog-content> | 40 | <md-dialog-content> |
41 | <div class="md-dialog-content"> | 41 | <div class="md-dialog-content"> |
42 | <md-content class="md-padding" layout="column"> | 42 | <md-content class="md-padding" layout="column"> |
43 | - <fieldset ng-disabled="loading"> | 43 | + <fieldset ng-disabled="$root.loading"> |
44 | <md-button ng-class="{'md-primary md-raised': icon == vm.selectedIcon}" class="tb-select-icon-button md-icon-button" | 44 | <md-button ng-class="{'md-primary md-raised': icon == vm.selectedIcon}" class="tb-select-icon-button md-icon-button" |
45 | ng-repeat="icon in vm.icons" ng-click="vm.selectIcon($event, icon)" tb-on-finish-render="iconsLoadFinished"> | 45 | ng-repeat="icon in vm.icons" ng-click="vm.selectIcon($event, icon)" tb-on-finish-render="iconsLoadFinished"> |
46 | <md-icon class="material-icons">{{icon}}</md-icon> | 46 | <md-icon class="material-icons">{{icon}}</md-icon> |
@@ -54,7 +54,7 @@ | @@ -54,7 +54,7 @@ | ||
54 | </md-dialog-content> | 54 | </md-dialog-content> |
55 | <md-dialog-actions layout="row"> | 55 | <md-dialog-actions layout="row"> |
56 | <span flex></span> | 56 | <span flex></span> |
57 | - <md-button ng-disabled="loading" ng-click="vm.cancel()"> | 57 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()"> |
58 | {{ 'action.cancel' | translate }} | 58 | {{ 'action.cancel' | translate }} |
59 | </md-button> | 59 | </md-button> |
60 | </md-dialog-actions> | 60 | </md-dialog-actions> |
@@ -56,7 +56,7 @@ function PluginSelect($compile, $templateCache, $q, pluginService, types) { | @@ -56,7 +56,7 @@ function PluginSelect($compile, $templateCache, $q, pluginService, types) { | ||
56 | 56 | ||
57 | var deferred = $q.defer(); | 57 | var deferred = $q.defer(); |
58 | 58 | ||
59 | - scope.pluginFetchFunction(pageLink).then(function success(result) { | 59 | + scope.pluginFetchFunction(pageLink, {ignoreLoading: true}).then(function success(result) { |
60 | deferred.resolve(result.data); | 60 | deferred.resolve(result.data); |
61 | }, function fail() { | 61 | }, function fail() { |
62 | deferred.reject(); | 62 | deferred.reject(); |
@@ -89,7 +89,7 @@ function PluginSelect($compile, $templateCache, $q, pluginService, types) { | @@ -89,7 +89,7 @@ function PluginSelect($compile, $templateCache, $q, pluginService, types) { | ||
89 | 89 | ||
90 | if (scope.selectFirstPlugin) { | 90 | if (scope.selectFirstPlugin) { |
91 | var pageLink = {limit: 1, textSearch: ''}; | 91 | var pageLink = {limit: 1, textSearch: ''}; |
92 | - scope.pluginFetchFunction(pageLink).then(function success(result) { | 92 | + scope.pluginFetchFunction(pageLink, {ignoreLoading: true}).then(function success(result) { |
93 | var plugins = result.data; | 93 | var plugins = result.data; |
94 | if (plugins.length > 0) { | 94 | if (plugins.length > 0) { |
95 | scope.plugin = plugins[0]; | 95 | scope.plugin = plugins[0]; |
@@ -16,7 +16,7 @@ | @@ -16,7 +16,7 @@ | ||
16 | 16 | ||
17 | --> | 17 | --> |
18 | <form name="theForm" ng-submit="vm.update()"> | 18 | <form name="theForm" ng-submit="vm.update()"> |
19 | - <fieldset ng-disabled="loading"> | 19 | + <fieldset ng-disabled="$root.loading"> |
20 | <md-content style="height: 100%" flex layout="column"> | 20 | <md-content style="height: 100%" flex layout="column"> |
21 | <section layout="column"> | 21 | <section layout="column"> |
22 | <md-tabs ng-class="{'tb-headless': vm.historyOnly}" md-dynamic-height md-selected="vm.timewindow.selectedTab" md-border-bottom> | 22 | <md-tabs ng-class="{'tb-headless': vm.historyOnly}" md-dynamic-height md-selected="vm.timewindow.selectedTab" md-border-bottom> |
@@ -81,10 +81,10 @@ | @@ -81,10 +81,10 @@ | ||
81 | <span flex></span> | 81 | <span flex></span> |
82 | <section layout="row" layout-alignment="start center"> | 82 | <section layout="row" layout-alignment="start center"> |
83 | <span flex></span> | 83 | <span flex></span> |
84 | - <md-button ng-disabled="loading || theForm.$invalid || !theForm.$dirty" type="submit" class="md-raised md-primary"> | 84 | + <md-button ng-disabled="$root.loading || theForm.$invalid || !theForm.$dirty" type="submit" class="md-raised md-primary"> |
85 | {{ 'action.update' | translate }} | 85 | {{ 'action.update' | translate }} |
86 | </md-button> | 86 | </md-button> |
87 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;"> | 87 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;"> |
88 | {{ 'action.cancel' | translate }} | 88 | {{ 'action.cancel' | translate }} |
89 | </md-button> | 89 | </md-button> |
90 | </section> | 90 | </section> |
@@ -26,12 +26,12 @@ | @@ -26,12 +26,12 @@ | ||
26 | </md-button> | 26 | </md-button> |
27 | </div> | 27 | </div> |
28 | </md-toolbar> | 28 | </md-toolbar> |
29 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
30 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 29 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
30 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
31 | <md-dialog-content> | 31 | <md-dialog-content> |
32 | <div class="md-dialog-content"> | 32 | <div class="md-dialog-content"> |
33 | <md-content class="md-padding" layout="column"> | 33 | <md-content class="md-padding" layout="column"> |
34 | - <fieldset ng-disabled="loading" layout="column"> | 34 | + <fieldset ng-disabled="$root.loading" layout="column"> |
35 | <md-input-container class="md-block"> | 35 | <md-input-container class="md-block"> |
36 | <label translate>widget-config.action-source</label> | 36 | <label translate>widget-config.action-source</label> |
37 | <md-select name="actionSource" required aria-label="{{ 'widget-config.action-source' | translate }}" ng-model="vm.action.actionSourceId"> | 37 | <md-select name="actionSource" required aria-label="{{ 'widget-config.action-source' | translate }}" ng-model="vm.action.actionSourceId"> |
@@ -120,7 +120,7 @@ | @@ -120,7 +120,7 @@ | ||
120 | </div> | 120 | </div> |
121 | <tb-js-func ng-if="vm.action.type == vm.types.widgetActionTypes.custom.value" | 121 | <tb-js-func ng-if="vm.action.type == vm.types.widgetActionTypes.custom.value" |
122 | ng-model="vm.action.customFunction" | 122 | ng-model="vm.action.customFunction" |
123 | - function-args="{{ ['$event', 'widgetContext', 'entityId'] }}" | 123 | + function-args="{{ ['$event', 'widgetContext', 'entityId', 'entityName', 'additionalParams'] }}" |
124 | validation-args="{{ [] }}"> | 124 | validation-args="{{ [] }}"> |
125 | </tb-js-func> | 125 | </tb-js-func> |
126 | </fieldset> | 126 | </fieldset> |
@@ -129,11 +129,11 @@ | @@ -129,11 +129,11 @@ | ||
129 | </md-dialog-content> | 129 | </md-dialog-content> |
130 | <md-dialog-actions layout="row"> | 130 | <md-dialog-actions layout="row"> |
131 | <span flex></span> | 131 | <span flex></span> |
132 | - <md-button ng-disabled="loading || theForm.$invalid || !theForm.$dirty" type="submit" | 132 | + <md-button ng-disabled="$root.loading || theForm.$invalid || !theForm.$dirty" type="submit" |
133 | class="md-raised md-primary"> | 133 | class="md-raised md-primary"> |
134 | {{ (vm.isAdd ? 'action.add' : 'action.save') | translate }} | 134 | {{ (vm.isAdd ? 'action.add' : 'action.save') | translate }} |
135 | </md-button> | 135 | </md-button> |
136 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;"> | 136 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;"> |
137 | {{ 'action.cancel' | translate }} | 137 | {{ 'action.cancel' | translate }} |
138 | </md-button> | 138 | </md-button> |
139 | </md-dialog-actions> | 139 | </md-dialog-actions> |
@@ -104,7 +104,7 @@ | @@ -104,7 +104,7 @@ | ||
104 | generate-data-key="generateDataKey(chip,type)" | 104 | generate-data-key="generateDataKey(chip,type)" |
105 | fetch-entity-keys="fetchEntityKeys({entityAliasId: entityAliasId, query: query, type: type})" | 105 | fetch-entity-keys="fetchEntityKeys({entityAliasId: entityAliasId, query: query, type: type})" |
106 | on-create-entity-alias="onCreateEntityAlias({event: event, alias: alias})"></tb-datasource> | 106 | on-create-entity-alias="onCreateEntityAlias({event: event, alias: alias})"></tb-datasource> |
107 | - <md-button ng-disabled="loading" class="md-icon-button md-primary" | 107 | + <md-button ng-disabled="$root.loading" class="md-icon-button md-primary" |
108 | style="min-width: 40px;" | 108 | style="min-width: 40px;" |
109 | ng-click="removeDatasource($event, datasource)" | 109 | ng-click="removeDatasource($event, datasource)" |
110 | aria-label="{{ 'action.remove' | translate }}"> | 110 | aria-label="{{ 'action.remove' | translate }}"> |
@@ -121,7 +121,7 @@ | @@ -121,7 +121,7 @@ | ||
121 | </div> | 121 | </div> |
122 | </div> | 122 | </div> |
123 | <div flex layout="row" layout-align="start center"> | 123 | <div flex layout="row" layout-align="start center"> |
124 | - <md-button ng-show="typeParameters.maxDatasources == -1 || datasources.length < typeParameters.maxDatasources" ng-disabled="loading" class="md-primary md-raised" | 124 | + <md-button ng-show="typeParameters.maxDatasources == -1 || datasources.length < typeParameters.maxDatasources" ng-disabled="$root.loading" class="md-primary md-raised" |
125 | ng-click="addDatasource($event)" aria-label="{{ 'action.add' | translate }}"> | 125 | ng-click="addDatasource($event)" aria-label="{{ 'action.add' | translate }}"> |
126 | <md-tooltip md-direction="top"> | 126 | <md-tooltip md-direction="top"> |
127 | {{ 'widget-config.add-datasource' | translate }} | 127 | {{ 'widget-config.add-datasource' | translate }} |
@@ -444,7 +444,7 @@ export default function WidgetController($scope, $state, $timeout, $window, $ele | @@ -444,7 +444,7 @@ export default function WidgetController($scope, $state, $timeout, $window, $ele | ||
444 | } | 444 | } |
445 | } | 445 | } |
446 | 446 | ||
447 | - function handleWidgetAction($event, descriptor, entityId, entityName) { | 447 | + function handleWidgetAction($event, descriptor, entityId, entityName, additionalParams) { |
448 | var type = descriptor.type; | 448 | var type = descriptor.type; |
449 | var targetEntityParamName = descriptor.stateEntityParamName; | 449 | var targetEntityParamName = descriptor.stateEntityParamName; |
450 | var targetEntityId; | 450 | var targetEntityId; |
@@ -485,8 +485,11 @@ export default function WidgetController($scope, $state, $timeout, $window, $ele | @@ -485,8 +485,11 @@ export default function WidgetController($scope, $state, $timeout, $window, $ele | ||
485 | var customFunction = descriptor.customFunction; | 485 | var customFunction = descriptor.customFunction; |
486 | if (angular.isDefined(customFunction) && customFunction.length > 0) { | 486 | if (angular.isDefined(customFunction) && customFunction.length > 0) { |
487 | try { | 487 | try { |
488 | - var customActionFunction = new Function('$event', 'widgetContext', 'entityId', 'entityName', customFunction); | ||
489 | - customActionFunction($event, widgetContext, entityId, entityName); | 488 | + if (!additionalParams) { |
489 | + additionalParams = {}; | ||
490 | + } | ||
491 | + var customActionFunction = new Function('$event', 'widgetContext', 'entityId', 'entityName', 'additionalParams', customFunction); | ||
492 | + customActionFunction($event, widgetContext, entityId, entityName, additionalParams); | ||
490 | } catch (e) { | 493 | } catch (e) { |
491 | // | 494 | // |
492 | } | 495 | } |
@@ -48,7 +48,7 @@ function WidgetsBundleSelect($compile, $templateCache, widgetService, types) { | @@ -48,7 +48,7 @@ function WidgetsBundleSelect($compile, $templateCache, widgetService, types) { | ||
48 | } | 48 | } |
49 | } | 49 | } |
50 | 50 | ||
51 | - widgetsBundleFetchFunction().then( | 51 | + widgetsBundleFetchFunction({ignoreLoading: true}).then( |
52 | function success(widgetsBundles) { | 52 | function success(widgetsBundles) { |
53 | scope.widgetsBundles = widgetsBundles; | 53 | scope.widgetsBundles = widgetsBundles; |
54 | if (scope.selectFirstBundle) { | 54 | if (scope.selectFirstBundle) { |
@@ -27,8 +27,8 @@ | @@ -27,8 +27,8 @@ | ||
27 | </md-button> | 27 | </md-button> |
28 | </div> | 28 | </div> |
29 | </md-toolbar> | 29 | </md-toolbar> |
30 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
31 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 30 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
31 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
32 | <md-dialog-content> | 32 | <md-dialog-content> |
33 | <div class="md-dialog-content"> | 33 | <div class="md-dialog-content"> |
34 | <tb-customer customer="vm.item" is-edit="true" the-form="theForm"></tb-customer> | 34 | <tb-customer customer="vm.item" is-edit="true" the-form="theForm"></tb-customer> |
@@ -36,10 +36,10 @@ | @@ -36,10 +36,10 @@ | ||
36 | </md-dialog-content> | 36 | </md-dialog-content> |
37 | <md-dialog-actions layout="row"> | 37 | <md-dialog-actions layout="row"> |
38 | <span flex></span> | 38 | <span flex></span> |
39 | - <md-button ng-disabled="loading || theForm.$invalid || !theForm.$dirty" type="submit" class="md-raised md-primary"> | 39 | + <md-button ng-disabled="$root.loading || theForm.$invalid || !theForm.$dirty" type="submit" class="md-raised md-primary"> |
40 | {{ 'action.add' | translate }} | 40 | {{ 'action.add' | translate }} |
41 | </md-button> | 41 | </md-button> |
42 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> | 42 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> |
43 | </md-dialog-actions> | 43 | </md-dialog-actions> |
44 | </form> | 44 | </form> |
45 | </md-dialog> | 45 | </md-dialog> |
@@ -32,7 +32,7 @@ | @@ -32,7 +32,7 @@ | ||
32 | </div> | 32 | </div> |
33 | 33 | ||
34 | <md-content class="md-padding" layout="column"> | 34 | <md-content class="md-padding" layout="column"> |
35 | - <fieldset ng-show="!isPublic" ng-disabled="loading || !isEdit"> | 35 | + <fieldset ng-show="!isPublic" ng-disabled="$root.loading || !isEdit"> |
36 | <md-input-container class="md-block"> | 36 | <md-input-container class="md-block"> |
37 | <label translate>customer.title</label> | 37 | <label translate>customer.title</label> |
38 | <input required name="title" ng-model="customer.title"> | 38 | <input required name="title" ng-model="customer.title"> |
@@ -27,8 +27,8 @@ | @@ -27,8 +27,8 @@ | ||
27 | </md-button> | 27 | </md-button> |
28 | </div> | 28 | </div> |
29 | </md-toolbar> | 29 | </md-toolbar> |
30 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
31 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 30 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
31 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
32 | <md-dialog-content> | 32 | <md-dialog-content> |
33 | <div class="md-dialog-content"> | 33 | <div class="md-dialog-content"> |
34 | <tb-dashboard-details dashboard="vm.item" is-edit="true" the-form="theForm"></tb-dashboard-details> | 34 | <tb-dashboard-details dashboard="vm.item" is-edit="true" the-form="theForm"></tb-dashboard-details> |
@@ -36,10 +36,10 @@ | @@ -36,10 +36,10 @@ | ||
36 | </md-dialog-content> | 36 | </md-dialog-content> |
37 | <md-dialog-actions layout="row"> | 37 | <md-dialog-actions layout="row"> |
38 | <span flex></span> | 38 | <span flex></span> |
39 | - <md-button ng-disabled="loading || theForm.$invalid || !theForm.$dirty" type="submit" class="md-raised md-primary"> | 39 | + <md-button ng-disabled="$root.loading || theForm.$invalid || !theForm.$dirty" type="submit" class="md-raised md-primary"> |
40 | {{ 'action.add' | translate }} | 40 | {{ 'action.add' | translate }} |
41 | </md-button> | 41 | </md-button> |
42 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> | 42 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> |
43 | </md-dialog-actions> | 43 | </md-dialog-actions> |
44 | </form> | 44 | </form> |
45 | </md-dialog> | 45 | </md-dialog> |
@@ -26,8 +26,8 @@ | @@ -26,8 +26,8 @@ | ||
26 | </md-button> | 26 | </md-button> |
27 | </div> | 27 | </div> |
28 | </md-toolbar> | 28 | </md-toolbar> |
29 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
30 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 29 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
30 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
31 | <md-dialog-content> | 31 | <md-dialog-content> |
32 | <div class="md-dialog-content"> | 32 | <div class="md-dialog-content"> |
33 | <fieldset> | 33 | <fieldset> |
@@ -65,11 +65,11 @@ | @@ -65,11 +65,11 @@ | ||
65 | </md-dialog-content> | 65 | </md-dialog-content> |
66 | <md-dialog-actions layout="row"> | 66 | <md-dialog-actions layout="row"> |
67 | <span flex></span> | 67 | <span flex></span> |
68 | - <md-button ng-disabled="loading || vm.dashboards.selectedCount == 0" type="submit" | 68 | + <md-button ng-disabled="$root.loading || vm.dashboards.selectedCount == 0" type="submit" |
69 | class="md-raised md-primary"> | 69 | class="md-raised md-primary"> |
70 | {{ 'action.assign' | translate }} | 70 | {{ 'action.assign' | translate }} |
71 | </md-button> | 71 | </md-button> |
72 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | | 72 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | |
73 | translate }} | 73 | translate }} |
74 | </md-button> | 74 | </md-button> |
75 | </md-dialog-actions> | 75 | </md-dialog-actions> |
@@ -110,7 +110,7 @@ export default function AddWidgetController($scope, widgetService, entityService | @@ -110,7 +110,7 @@ export default function AddWidgetController($scope, widgetService, entityService | ||
110 | function success(aliasInfo) { | 110 | function success(aliasInfo) { |
111 | var entity = aliasInfo.currentEntity; | 111 | var entity = aliasInfo.currentEntity; |
112 | if (entity) { | 112 | if (entity) { |
113 | - entityService.getEntityKeys(entity.entityType, entity.id, query, type).then( | 113 | + entityService.getEntityKeys(entity.entityType, entity.id, query, type, {ignoreLoading: true}).then( |
114 | function success(keys) { | 114 | function success(keys) { |
115 | deferred.resolve(keys); | 115 | deferred.resolve(keys); |
116 | }, | 116 | }, |
@@ -27,11 +27,11 @@ | @@ -27,11 +27,11 @@ | ||
27 | </md-button> | 27 | </md-button> |
28 | </div> | 28 | </div> |
29 | </md-toolbar> | 29 | </md-toolbar> |
30 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
31 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 30 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
31 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
32 | <md-dialog-content> | 32 | <md-dialog-content> |
33 | <div class="md-dialog-content" style="padding-top: 0px;"> | 33 | <div class="md-dialog-content" style="padding-top: 0px;"> |
34 | - <fieldset ng-disabled="loading" style="position: relative; height: 600px;"> | 34 | + <fieldset ng-disabled="$root.loading" style="position: relative; height: 600px;"> |
35 | <tb-widget-config widget-type="vm.widget.type" | 35 | <tb-widget-config widget-type="vm.widget.type" |
36 | type-parameters="vm.widgetInfo.typeParameters" | 36 | type-parameters="vm.widgetInfo.typeParameters" |
37 | action-sources="vm.widgetInfo.actionSources" | 37 | action-sources="vm.widgetInfo.actionSources" |
@@ -50,11 +50,11 @@ | @@ -50,11 +50,11 @@ | ||
50 | </md-dialog-content> | 50 | </md-dialog-content> |
51 | <md-dialog-actions layout="row"> | 51 | <md-dialog-actions layout="row"> |
52 | <span flex></span> | 52 | <span flex></span> |
53 | - <md-button ng-disabled="loading || theForm.$invalid" type="submit" | 53 | + <md-button ng-disabled="$root.loading || theForm.$invalid" type="submit" |
54 | class="md-raised md-primary"> | 54 | class="md-raised md-primary"> |
55 | {{ 'action.add' | translate }} | 55 | {{ 'action.add' | translate }} |
56 | </md-button> | 56 | </md-button> |
57 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | | 57 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | |
58 | translate }} | 58 | translate }} |
59 | </md-button> | 59 | </md-button> |
60 | </md-dialog-actions> | 60 | </md-dialog-actions> |
@@ -26,8 +26,8 @@ | @@ -26,8 +26,8 @@ | ||
26 | </md-button> | 26 | </md-button> |
27 | </div> | 27 | </div> |
28 | </md-toolbar> | 28 | </md-toolbar> |
29 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
30 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 29 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
30 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
31 | <md-dialog-content> | 31 | <md-dialog-content> |
32 | <div class="md-dialog-content"> | 32 | <div class="md-dialog-content"> |
33 | <fieldset> | 33 | <fieldset> |
@@ -65,10 +65,10 @@ | @@ -65,10 +65,10 @@ | ||
65 | </md-dialog-content> | 65 | </md-dialog-content> |
66 | <md-dialog-actions layout="row"> | 66 | <md-dialog-actions layout="row"> |
67 | <span flex></span> | 67 | <span flex></span> |
68 | - <md-button ng-disabled="loading || vm.customers.selection==null" type="submit" class="md-raised md-primary"> | 68 | + <md-button ng-disabled="$root.loading || vm.customers.selection==null" type="submit" class="md-raised md-primary"> |
69 | {{ 'action.assign' | translate }} | 69 | {{ 'action.assign' | translate }} |
70 | </md-button> | 70 | </md-button> |
71 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | | 71 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | |
72 | translate }} | 72 | translate }} |
73 | </md-button> | 73 | </md-button> |
74 | </md-dialog-actions> | 74 | </md-dialog-actions> |
@@ -59,7 +59,7 @@ | @@ -59,7 +59,7 @@ | ||
59 | </md-button> | 59 | </md-button> |
60 | </div> | 60 | </div> |
61 | </div> | 61 | </div> |
62 | - <fieldset ng-disabled="loading || !isEdit"> | 62 | + <fieldset ng-disabled="$root.loading || !isEdit"> |
63 | <md-input-container class="md-block"> | 63 | <md-input-container class="md-block"> |
64 | <label translate>dashboard.title</label> | 64 | <label translate>dashboard.title</label> |
65 | <input required name="title" ng-model="dashboard.title"> | 65 | <input required name="title" ng-model="dashboard.title"> |
@@ -26,11 +26,11 @@ | @@ -26,11 +26,11 @@ | ||
26 | </md-button> | 26 | </md-button> |
27 | </div> | 27 | </div> |
28 | </md-toolbar> | 28 | </md-toolbar> |
29 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
30 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 29 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
30 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
31 | <md-dialog-content> | 31 | <md-dialog-content> |
32 | <div class="md-dialog-content"> | 32 | <div class="md-dialog-content"> |
33 | - <fieldset ng-disabled="loading"> | 33 | + <fieldset ng-disabled="$root.loading"> |
34 | <div ng-show="vm.settings"> | 34 | <div ng-show="vm.settings"> |
35 | <md-input-container class="md-block"> | 35 | <md-input-container class="md-block"> |
36 | <label translate>dashboard.state-controller</label> | 36 | <label translate>dashboard.state-controller</label> |
@@ -194,10 +194,10 @@ | @@ -194,10 +194,10 @@ | ||
194 | </md-dialog-content> | 194 | </md-dialog-content> |
195 | <md-dialog-actions layout="row"> | 195 | <md-dialog-actions layout="row"> |
196 | <span flex></span> | 196 | <span flex></span> |
197 | - <md-button ng-disabled="loading || !theForm.$dirty || !theForm.$valid" type="submit" class="md-raised md-primary"> | 197 | + <md-button ng-disabled="$root.loading || !theForm.$dirty || !theForm.$valid" type="submit" class="md-raised md-primary"> |
198 | {{ 'action.save' | translate }} | 198 | {{ 'action.save' | translate }} |
199 | </md-button> | 199 | </md-button> |
200 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> | 200 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> |
201 | </md-dialog-actions> | 201 | </md-dialog-actions> |
202 | </form> | 202 | </form> |
203 | </md-dialog> | 203 | </md-dialog> |
@@ -110,7 +110,7 @@ | @@ -110,7 +110,7 @@ | ||
110 | </section> | 110 | </section> |
111 | <section class="tb-dashboard-container tb-absolute-fill" | 111 | <section class="tb-dashboard-container tb-absolute-fill" |
112 | ng-class="{ 'is-fullscreen': forceFullscreen, 'tb-dashboard-toolbar-opened': vm.toolbarOpened, 'tb-dashboard-toolbar-closed': !vm.toolbarOpened }"> | 112 | ng-class="{ 'is-fullscreen': forceFullscreen, 'tb-dashboard-toolbar-opened': vm.toolbarOpened, 'tb-dashboard-toolbar-closed': !vm.toolbarOpened }"> |
113 | - <section ng-show="!loading && vm.dashboardConfigurationError()" layout-align="center center" | 113 | + <section ng-show="!$root.loading && vm.dashboardConfigurationError()" layout-align="center center" |
114 | ng-style="{'color': vm.dashboard.configuration.settings.titleColor}" | 114 | ng-style="{'color': vm.dashboard.configuration.settings.titleColor}" |
115 | ng-class="{'tb-padded' : !vm.widgetEditMode}" | 115 | ng-class="{'tb-padded' : !vm.widgetEditMode}" |
116 | style="text-transform: uppercase; display: flex; z-index: 1;" | 116 | style="text-transform: uppercase; display: flex; z-index: 1;" |
@@ -277,10 +277,10 @@ | @@ -277,10 +277,10 @@ | ||
277 | </div> | 277 | </div> |
278 | </tb-details-sidenav> | 278 | </tb-details-sidenav> |
279 | <section layout="row" layout-wrap class="tb-footer-buttons md-fab" layout-align="start end"> | 279 | <section layout="row" layout-wrap class="tb-footer-buttons md-fab" layout-align="start end"> |
280 | - <md-fab-speed-dial ng-disabled="loading" ng-show="!vm.isAddingWidget && vm.isEdit && !vm.widgetEditMode" | 280 | + <md-fab-speed-dial ng-disabled="$root.loading" ng-show="!vm.isAddingWidget && vm.isEdit && !vm.widgetEditMode" |
281 | md-open="vm.addItemActionsOpen" class="md-scale" md-direction="up"> | 281 | md-open="vm.addItemActionsOpen" class="md-scale" md-direction="up"> |
282 | <md-fab-trigger> | 282 | <md-fab-trigger> |
283 | - <md-button ng-disabled="loading" | 283 | + <md-button ng-disabled="$root.loading" |
284 | class="tb-btn-footer md-accent md-hue-2 md-fab" | 284 | class="tb-btn-footer md-accent md-hue-2 md-fab" |
285 | aria-label="{{ 'dashboard.add-widget' | translate }}"> | 285 | aria-label="{{ 'dashboard.add-widget' | translate }}"> |
286 | <md-tooltip md-direction="top"> | 286 | <md-tooltip md-direction="top"> |
@@ -290,7 +290,7 @@ | @@ -290,7 +290,7 @@ | ||
290 | </md-button> | 290 | </md-button> |
291 | </md-fab-trigger> | 291 | </md-fab-trigger> |
292 | <md-fab-actions> | 292 | <md-fab-actions> |
293 | - <md-button ng-disabled="loading" | 293 | + <md-button ng-disabled="$root.loading" |
294 | class="tmd-accent md-hue-2 md-fab" ng-click="vm.addWidget($event)" | 294 | class="tmd-accent md-hue-2 md-fab" ng-click="vm.addWidget($event)" |
295 | aria-label="{{ 'action.create' | translate }}"> | 295 | aria-label="{{ 'action.create' | translate }}"> |
296 | <md-tooltip md-direction="top"> | 296 | <md-tooltip md-direction="top"> |
@@ -298,7 +298,7 @@ | @@ -298,7 +298,7 @@ | ||
298 | </md-tooltip> | 298 | </md-tooltip> |
299 | <ng-md-icon icon="insert_drive_file"></ng-md-icon> | 299 | <ng-md-icon icon="insert_drive_file"></ng-md-icon> |
300 | </md-button> | 300 | </md-button> |
301 | - <md-button ng-disabled="loading" | 301 | + <md-button ng-disabled="$root.loading" |
302 | class="tmd-accent md-hue-2 md-fab" ng-click="vm.importWidget($event)" | 302 | class="tmd-accent md-hue-2 md-fab" ng-click="vm.importWidget($event)" |
303 | aria-label="{{ 'action.import' | translate }}"> | 303 | aria-label="{{ 'action.import' | translate }}"> |
304 | <md-tooltip md-direction="top"> | 304 | <md-tooltip md-direction="top"> |
@@ -308,7 +308,7 @@ | @@ -308,7 +308,7 @@ | ||
308 | </md-button> | 308 | </md-button> |
309 | </md-fab-actions> | 309 | </md-fab-actions> |
310 | </md-fab-speed-dial> | 310 | </md-fab-speed-dial> |
311 | - <md-button ng-if="(vm.isTenantAdmin() || vm.isSystemAdmin()) && !forceFullscreen" ng-show="vm.isEdit && !vm.isAddingWidget && !loading" ng-disabled="loading" | 311 | + <md-button ng-if="(vm.isTenantAdmin() || vm.isSystemAdmin()) && !forceFullscreen" ng-show="vm.isEdit && !vm.isAddingWidget && !$root.loading" ng-disabled="$root.loading" |
312 | class="tb-btn-footer md-accent md-hue-2 md-fab" | 312 | class="tb-btn-footer md-accent md-hue-2 md-fab" |
313 | aria-label="{{ 'action.apply' | translate }}" | 313 | aria-label="{{ 'action.apply' | translate }}" |
314 | ng-click="vm.saveDashboard()"> | 314 | ng-click="vm.saveDashboard()"> |
@@ -317,8 +317,8 @@ | @@ -317,8 +317,8 @@ | ||
317 | </md-tooltip> | 317 | </md-tooltip> |
318 | <ng-md-icon icon="done"></ng-md-icon> | 318 | <ng-md-icon icon="done"></ng-md-icon> |
319 | </md-button> | 319 | </md-button> |
320 | - <md-button ng-show="!vm.isAddingWidget && !loading" | ||
321 | - ng-if="(vm.isTenantAdmin() || vm.isSystemAdmin()) && !forceFullscreen" ng-disabled="loading" | 320 | + <md-button ng-show="!vm.isAddingWidget && !$root.loading" |
321 | + ng-if="(vm.isTenantAdmin() || vm.isSystemAdmin()) && !forceFullscreen" ng-disabled="$root.loading" | ||
322 | class="tb-btn-footer md-accent md-hue-2 md-fab" | 322 | class="tb-btn-footer md-accent md-hue-2 md-fab" |
323 | aria-label="{{ 'action.edit-mode' | translate }}" | 323 | aria-label="{{ 'action.edit-mode' | translate }}" |
324 | ng-click="vm.toggleDashboardEditMode()"> | 324 | ng-click="vm.toggleDashboardEditMode()"> |
@@ -75,7 +75,7 @@ export default function EditWidgetDirective($compile, $templateCache, types, wid | @@ -75,7 +75,7 @@ export default function EditWidgetDirective($compile, $templateCache, types, wid | ||
75 | function success(aliasInfo) { | 75 | function success(aliasInfo) { |
76 | var entity = aliasInfo.currentEntity; | 76 | var entity = aliasInfo.currentEntity; |
77 | if (entity) { | 77 | if (entity) { |
78 | - entityService.getEntityKeys(entity.entityType, entity.id, query, type).then( | 78 | + entityService.getEntityKeys(entity.entityType, entity.id, query, type, {ignoreLoading: true}).then( |
79 | function success(keys) { | 79 | function success(keys) { |
80 | deferred.resolve(keys); | 80 | deferred.resolve(keys); |
81 | }, | 81 | }, |
@@ -15,7 +15,7 @@ | @@ -15,7 +15,7 @@ | ||
15 | limitations under the License. | 15 | limitations under the License. |
16 | 16 | ||
17 | --> | 17 | --> |
18 | -<fieldset ng-disabled="loading"> | 18 | +<fieldset ng-disabled="$root.loading"> |
19 | <tb-widget-config widget-type="widget.type" | 19 | <tb-widget-config widget-type="widget.type" |
20 | type-parameters="typeParameters" | 20 | type-parameters="typeParameters" |
21 | action-sources="actionSources" | 21 | action-sources="actionSources" |
@@ -22,7 +22,7 @@ | @@ -22,7 +22,7 @@ | ||
22 | 'background-attachment': 'scroll', | 22 | 'background-attachment': 'scroll', |
23 | 'background-size': vm.layoutCtx.gridSettings.backgroundSizeMode || '100%', | 23 | 'background-size': vm.layoutCtx.gridSettings.backgroundSizeMode || '100%', |
24 | 'background-position': '0% 0%'}"> | 24 | 'background-position': '0% 0%'}"> |
25 | - <section ng-show="!loading && vm.noData()" layout-align="center center" | 25 | + <section ng-show="!$root.loading && vm.noData()" layout-align="center center" |
26 | ng-style="{'color': vm.layoutCtx.gridSettings.color}" | 26 | ng-style="{'color': vm.layoutCtx.gridSettings.color}" |
27 | style="text-transform: uppercase; display: flex; z-index: 1; pointer-events: none;" | 27 | style="text-transform: uppercase; display: flex; z-index: 1; pointer-events: none;" |
28 | class="md-headline tb-absolute-fill"> | 28 | class="md-headline tb-absolute-fill"> |
@@ -26,11 +26,11 @@ | @@ -26,11 +26,11 @@ | ||
26 | </md-button> | 26 | </md-button> |
27 | </div> | 27 | </div> |
28 | </md-toolbar> | 28 | </md-toolbar> |
29 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
30 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 29 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
30 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
31 | <md-dialog-content> | 31 | <md-dialog-content> |
32 | <div class="md-dialog-content"> | 32 | <div class="md-dialog-content"> |
33 | - <fieldset ng-disabled="loading"> | 33 | + <fieldset ng-disabled="$root.loading"> |
34 | <div layout="row" layout-align="start center"> | 34 | <div layout="row" layout-align="start center"> |
35 | <md-checkbox ng-disabled="true" flex aria-label="{{ 'layout.main' | translate }}" | 35 | <md-checkbox ng-disabled="true" flex aria-label="{{ 'layout.main' | translate }}" |
36 | ng-model="vm.displayLayouts.main">{{ 'layout.main' | translate }} | 36 | ng-model="vm.displayLayouts.main">{{ 'layout.main' | translate }} |
@@ -56,10 +56,10 @@ | @@ -56,10 +56,10 @@ | ||
56 | </md-dialog-content> | 56 | </md-dialog-content> |
57 | <md-dialog-actions layout="row"> | 57 | <md-dialog-actions layout="row"> |
58 | <span flex></span> | 58 | <span flex></span> |
59 | - <md-button ng-disabled="loading || !theForm.$dirty || !theForm.$valid" type="submit" class="md-raised md-primary"> | 59 | + <md-button ng-disabled="$root.loading || !theForm.$dirty || !theForm.$valid" type="submit" class="md-raised md-primary"> |
60 | {{ 'action.save' | translate }} | 60 | {{ 'action.save' | translate }} |
61 | </md-button> | 61 | </md-button> |
62 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> | 62 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> |
63 | </md-dialog-actions> | 63 | </md-dialog-actions> |
64 | </form> | 64 | </form> |
65 | </md-dialog> | 65 | </md-dialog> |
@@ -26,11 +26,11 @@ | @@ -26,11 +26,11 @@ | ||
26 | </md-button> | 26 | </md-button> |
27 | </div> | 27 | </div> |
28 | </md-toolbar> | 28 | </md-toolbar> |
29 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
30 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 29 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
30 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
31 | <md-dialog-content> | 31 | <md-dialog-content> |
32 | <div class="md-dialog-content"> | 32 | <div class="md-dialog-content"> |
33 | - <fieldset ng-disabled="loading"> | 33 | + <fieldset ng-disabled="$root.loading"> |
34 | <div layout="row" layout-align="start center"> | 34 | <div layout="row" layout-align="start center"> |
35 | <md-button flex class="tb-layout-button md-raised md-primary" layout="column" | 35 | <md-button flex class="tb-layout-button md-raised md-primary" layout="column" |
36 | ng-click="vm.selectLayout($event, 'main')"> | 36 | ng-click="vm.selectLayout($event, 'main')"> |
@@ -26,12 +26,12 @@ | @@ -26,12 +26,12 @@ | ||
26 | </md-button> | 26 | </md-button> |
27 | </div> | 27 | </div> |
28 | </md-toolbar> | 28 | </md-toolbar> |
29 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
30 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 29 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
30 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
31 | <md-dialog-content> | 31 | <md-dialog-content> |
32 | <div class="md-dialog-content"> | 32 | <div class="md-dialog-content"> |
33 | <md-content class="md-padding" layout="column"> | 33 | <md-content class="md-padding" layout="column"> |
34 | - <fieldset ng-disabled="loading"> | 34 | + <fieldset ng-disabled="$root.loading"> |
35 | <md-input-container class="md-block"> | 35 | <md-input-container class="md-block"> |
36 | <label translate>dashboard.state-name</label> | 36 | <label translate>dashboard.state-name</label> |
37 | <input name="name" required ng-model="vm.state.name"> | 37 | <input name="name" required ng-model="vm.state.name"> |
@@ -57,11 +57,11 @@ | @@ -57,11 +57,11 @@ | ||
57 | </md-dialog-content> | 57 | </md-dialog-content> |
58 | <md-dialog-actions layout="row"> | 58 | <md-dialog-actions layout="row"> |
59 | <span flex></span> | 59 | <span flex></span> |
60 | - <md-button ng-disabled="loading || theForm.$invalid || !theForm.$dirty" type="submit" | 60 | + <md-button ng-disabled="$root.loading || theForm.$invalid || !theForm.$dirty" type="submit" |
61 | class="md-raised md-primary"> | 61 | class="md-raised md-primary"> |
62 | {{ (vm.isAdd ? 'action.add' : 'action.save') | translate }} | 62 | {{ (vm.isAdd ? 'action.add' : 'action.save') | translate }} |
63 | </md-button> | 63 | </md-button> |
64 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;"> | 64 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;"> |
65 | {{ 'action.cancel' | translate }} | 65 | {{ 'action.cancel' | translate }} |
66 | </md-button> | 66 | </md-button> |
67 | </md-dialog-actions> | 67 | </md-dialog-actions> |
@@ -26,11 +26,11 @@ | @@ -26,11 +26,11 @@ | ||
26 | </md-button> | 26 | </md-button> |
27 | </div> | 27 | </div> |
28 | </md-toolbar> | 28 | </md-toolbar> |
29 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
30 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 29 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
30 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
31 | <md-dialog-content> | 31 | <md-dialog-content> |
32 | <div class="md-dialog-content"> | 32 | <div class="md-dialog-content"> |
33 | - <fieldset ng-disabled="loading"> | 33 | + <fieldset ng-disabled="$root.loading"> |
34 | <div class="manage-dashboard-states" layout="column"> | 34 | <div class="manage-dashboard-states" layout="column"> |
35 | <md-toolbar class="md-table-toolbar md-default" ng-show="vm.query.search === null"> | 35 | <md-toolbar class="md-table-toolbar md-default" ng-show="vm.query.search === null"> |
36 | <div class="md-toolbar-tools"> | 36 | <div class="md-toolbar-tools"> |
@@ -118,10 +118,10 @@ | @@ -118,10 +118,10 @@ | ||
118 | </md-dialog-content> | 118 | </md-dialog-content> |
119 | <md-dialog-actions layout="row"> | 119 | <md-dialog-actions layout="row"> |
120 | <span flex></span> | 120 | <span flex></span> |
121 | - <md-button ng-disabled="loading || !theForm.$dirty || !theForm.$valid" type="submit" class="md-raised md-primary"> | 121 | + <md-button ng-disabled="$root.loading || !theForm.$dirty || !theForm.$valid" type="submit" class="md-raised md-primary"> |
122 | {{ 'action.save' | translate }} | 122 | {{ 'action.save' | translate }} |
123 | </md-button> | 123 | </md-button> |
124 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> | 124 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> |
125 | </md-dialog-actions> | 125 | </md-dialog-actions> |
126 | </form> | 126 | </form> |
127 | </md-dialog> | 127 | </md-dialog> |
@@ -26,11 +26,11 @@ | @@ -26,11 +26,11 @@ | ||
26 | </md-button> | 26 | </md-button> |
27 | </div> | 27 | </div> |
28 | </md-toolbar> | 28 | </md-toolbar> |
29 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
30 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 29 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
30 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
31 | <md-dialog-content> | 31 | <md-dialog-content> |
32 | <div class="md-dialog-content"> | 32 | <div class="md-dialog-content"> |
33 | - <fieldset ng-disabled="loading"> | 33 | + <fieldset ng-disabled="$root.loading"> |
34 | <md-select required aria-label="{{ 'dashboard.state' | translate }}" ng-model="vm.stateId"> | 34 | <md-select required aria-label="{{ 'dashboard.state' | translate }}" ng-model="vm.stateId"> |
35 | <md-option ng-repeat="(stateId, state) in vm.states" ng-value="stateId"> | 35 | <md-option ng-repeat="(stateId, state) in vm.states" ng-value="stateId"> |
36 | {{state.name}} | 36 | {{state.name}} |
@@ -41,10 +41,10 @@ | @@ -41,10 +41,10 @@ | ||
41 | </md-dialog-content> | 41 | </md-dialog-content> |
42 | <md-dialog-actions layout="row"> | 42 | <md-dialog-actions layout="row"> |
43 | <span flex></span> | 43 | <span flex></span> |
44 | - <md-button ng-disabled="loading || !theForm.$dirty || !theForm.$valid" type="submit" class="md-raised md-primary"> | 44 | + <md-button ng-disabled="$root.loading || !theForm.$dirty || !theForm.$valid" type="submit" class="md-raised md-primary"> |
45 | {{ 'action.save' | translate }} | 45 | {{ 'action.save' | translate }} |
46 | </md-button> | 46 | </md-button> |
47 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> | 47 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> |
48 | </md-dialog-actions> | 48 | </md-dialog-actions> |
49 | </form> | 49 | </form> |
50 | </md-dialog> | 50 | </md-dialog> |
@@ -27,8 +27,8 @@ | @@ -27,8 +27,8 @@ | ||
27 | </md-button> | 27 | </md-button> |
28 | </div> | 28 | </div> |
29 | </md-toolbar> | 29 | </md-toolbar> |
30 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
31 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 30 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
31 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
32 | <md-dialog-content> | 32 | <md-dialog-content> |
33 | <div class="md-dialog-content"> | 33 | <div class="md-dialog-content"> |
34 | <tb-device device="vm.item" is-edit="true" the-form="theForm"></tb-device> | 34 | <tb-device device="vm.item" is-edit="true" the-form="theForm"></tb-device> |
@@ -36,10 +36,10 @@ | @@ -36,10 +36,10 @@ | ||
36 | </md-dialog-content> | 36 | </md-dialog-content> |
37 | <md-dialog-actions layout="row"> | 37 | <md-dialog-actions layout="row"> |
38 | <span flex></span> | 38 | <span flex></span> |
39 | - <md-button ng-disabled="loading || theForm.$invalid || !theForm.$dirty" type="submit" class="md-raised md-primary"> | 39 | + <md-button ng-disabled="$root.loading || theForm.$invalid || !theForm.$dirty" type="submit" class="md-raised md-primary"> |
40 | {{ 'action.add' | translate }} | 40 | {{ 'action.add' | translate }} |
41 | </md-button> | 41 | </md-button> |
42 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> | 42 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> |
43 | </md-dialog-actions> | 43 | </md-dialog-actions> |
44 | </form> | 44 | </form> |
45 | </md-dialog> | 45 | </md-dialog> |
@@ -26,8 +26,8 @@ | @@ -26,8 +26,8 @@ | ||
26 | </md-button> | 26 | </md-button> |
27 | </div> | 27 | </div> |
28 | </md-toolbar> | 28 | </md-toolbar> |
29 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
30 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 29 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
30 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
31 | <md-dialog-content> | 31 | <md-dialog-content> |
32 | <div class="md-dialog-content"> | 32 | <div class="md-dialog-content"> |
33 | <fieldset> | 33 | <fieldset> |
@@ -65,11 +65,11 @@ | @@ -65,11 +65,11 @@ | ||
65 | </md-dialog-content> | 65 | </md-dialog-content> |
66 | <md-dialog-actions layout="row"> | 66 | <md-dialog-actions layout="row"> |
67 | <span flex></span> | 67 | <span flex></span> |
68 | - <md-button ng-disabled="loading || vm.devices.selectedCount == 0" type="submit" | 68 | + <md-button ng-disabled="$root.loading || vm.devices.selectedCount == 0" type="submit" |
69 | class="md-raised md-primary"> | 69 | class="md-raised md-primary"> |
70 | {{ 'action.assign' | translate }} | 70 | {{ 'action.assign' | translate }} |
71 | </md-button> | 71 | </md-button> |
72 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | | 72 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | |
73 | translate }} | 73 | translate }} |
74 | </md-button> | 74 | </md-button> |
75 | </md-dialog-actions> | 75 | </md-dialog-actions> |
@@ -26,8 +26,8 @@ | @@ -26,8 +26,8 @@ | ||
26 | </md-button> | 26 | </md-button> |
27 | </div> | 27 | </div> |
28 | </md-toolbar> | 28 | </md-toolbar> |
29 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
30 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 29 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
30 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
31 | <md-dialog-content> | 31 | <md-dialog-content> |
32 | <div class="md-dialog-content"> | 32 | <div class="md-dialog-content"> |
33 | <fieldset> | 33 | <fieldset> |
@@ -65,10 +65,10 @@ | @@ -65,10 +65,10 @@ | ||
65 | </md-dialog-content> | 65 | </md-dialog-content> |
66 | <md-dialog-actions layout="row"> | 66 | <md-dialog-actions layout="row"> |
67 | <span flex></span> | 67 | <span flex></span> |
68 | - <md-button ng-disabled="loading || vm.customers.selection==null" type="submit" class="md-raised md-primary"> | 68 | + <md-button ng-disabled="$root.loading || vm.customers.selection==null" type="submit" class="md-raised md-primary"> |
69 | {{ 'action.assign' | translate }} | 69 | {{ 'action.assign' | translate }} |
70 | </md-button> | 70 | </md-button> |
71 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | | 71 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | |
72 | translate }} | 72 | translate }} |
73 | </md-button> | 73 | </md-button> |
74 | </md-dialog-actions> | 74 | </md-dialog-actions> |
@@ -26,14 +26,14 @@ | @@ -26,14 +26,14 @@ | ||
26 | </md-button> | 26 | </md-button> |
27 | </div> | 27 | </div> |
28 | </md-toolbar> | 28 | </md-toolbar> |
29 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
30 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 29 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
30 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
31 | <md-dialog-content> | 31 | <md-dialog-content> |
32 | <div class="md-dialog-content"> | 32 | <div class="md-dialog-content"> |
33 | - <fieldset ng-disabled="loading || vm.isReadOnly"> | 33 | + <fieldset ng-disabled="$root.loading || vm.isReadOnly"> |
34 | <md-input-container class="md-block"> | 34 | <md-input-container class="md-block"> |
35 | <label translate>device.credentials-type</label> | 35 | <label translate>device.credentials-type</label> |
36 | - <md-select ng-disabled="loading || vm.isReadOnly" ng-model="vm.deviceCredentials.credentialsType" | 36 | + <md-select ng-disabled="$root.loading || vm.isReadOnly" ng-model="vm.deviceCredentials.credentialsType" |
37 | ng-change="vm.clear()"> | 37 | ng-change="vm.clear()"> |
38 | <md-option ng-repeat="credentialsType in vm.credentialsTypes" value="{{credentialsType.value}}"> | 38 | <md-option ng-repeat="credentialsType in vm.credentialsTypes" value="{{credentialsType.value}}"> |
39 | {{credentialsType.name}} | 39 | {{credentialsType.name}} |
@@ -62,10 +62,10 @@ | @@ -62,10 +62,10 @@ | ||
62 | </md-dialog-content> | 62 | </md-dialog-content> |
63 | <md-dialog-actions layout="row"> | 63 | <md-dialog-actions layout="row"> |
64 | <span flex></span> | 64 | <span flex></span> |
65 | - <md-button ng-if="!vm.isReadOnly" ng-disabled="loading || theForm.$invalid || !theForm.$dirty || !vm.valid()" type="submit" class="md-raised md-primary"> | 65 | + <md-button ng-if="!vm.isReadOnly" ng-disabled="$root.loading || theForm.$invalid || !theForm.$dirty || !vm.valid()" type="submit" class="md-raised md-primary"> |
66 | {{ 'action.save' | translate }} | 66 | {{ 'action.save' | translate }} |
67 | </md-button> | 67 | </md-button> |
68 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ (vm.isReadOnly ? 'action.close' : 'action.cancel') | translate }}</md-button> | 68 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ (vm.isReadOnly ? 'action.close' : 'action.cancel') | translate }}</md-button> |
69 | </md-dialog-actions> | 69 | </md-dialog-actions> |
70 | </form> | 70 | </form> |
71 | </md-dialog> | 71 | </md-dialog> |
@@ -58,7 +58,7 @@ | @@ -58,7 +58,7 @@ | ||
58 | ng-show="!isEdit && isPublic && (deviceScope === 'customer' || deviceScope === 'tenant')"> | 58 | ng-show="!isEdit && isPublic && (deviceScope === 'customer' || deviceScope === 'tenant')"> |
59 | {{ 'device.device-public' | translate }} | 59 | {{ 'device.device-public' | translate }} |
60 | </div> | 60 | </div> |
61 | - <fieldset ng-disabled="loading || !isEdit"> | 61 | + <fieldset ng-disabled="$root.loading || !isEdit"> |
62 | <md-input-container class="md-block"> | 62 | <md-input-container class="md-block"> |
63 | <label translate>device.name</label> | 63 | <label translate>device.name</label> |
64 | <input required name="name" ng-model="device.name"> | 64 | <input required name="name" ng-model="device.name"> |
@@ -67,14 +67,14 @@ | @@ -67,14 +67,14 @@ | ||
67 | </div> | 67 | </div> |
68 | </md-input-container> | 68 | </md-input-container> |
69 | <tb-entity-subtype-autocomplete | 69 | <tb-entity-subtype-autocomplete |
70 | - ng-disabled="loading || !isEdit" | 70 | + ng-disabled="$root.loading || !isEdit" |
71 | tb-required="true" | 71 | tb-required="true" |
72 | the-form="theForm" | 72 | the-form="theForm" |
73 | ng-model="device.type" | 73 | ng-model="device.type" |
74 | entity-type="types.entityType.device"> | 74 | entity-type="types.entityType.device"> |
75 | </tb-entity-subtype-autocomplete> | 75 | </tb-entity-subtype-autocomplete> |
76 | <md-input-container class="md-block"> | 76 | <md-input-container class="md-block"> |
77 | - <md-checkbox ng-disabled="loading || !isEdit" flex aria-label="{{ 'device.is-gateway' | translate }}" | 77 | + <md-checkbox ng-disabled="$root.loading || !isEdit" flex aria-label="{{ 'device.is-gateway' | translate }}" |
78 | ng-model="device.additionalInfo.gateway">{{ 'device.is-gateway' | translate }} | 78 | ng-model="device.additionalInfo.gateway">{{ 'device.is-gateway' | translate }} |
79 | </md-checkbox> | 79 | </md-checkbox> |
80 | </md-input-container> | 80 | </md-input-container> |
@@ -26,11 +26,11 @@ | @@ -26,11 +26,11 @@ | ||
26 | </md-button> | 26 | </md-button> |
27 | </div> | 27 | </div> |
28 | </md-toolbar> | 28 | </md-toolbar> |
29 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
30 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 29 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
30 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
31 | <md-dialog-content> | 31 | <md-dialog-content> |
32 | <div class="md-dialog-content"> | 32 | <div class="md-dialog-content"> |
33 | - <fieldset ng-disabled="loading"> | 33 | + <fieldset ng-disabled="$root.loading"> |
34 | <div flex layout="column"> | 34 | <div flex layout="column"> |
35 | <div layout="row"> | 35 | <div layout="row"> |
36 | <md-input-container flex class="md-block"> | 36 | <md-input-container flex class="md-block"> |
@@ -64,10 +64,10 @@ | @@ -64,10 +64,10 @@ | ||
64 | </md-dialog-content> | 64 | </md-dialog-content> |
65 | <md-dialog-actions layout="row"> | 65 | <md-dialog-actions layout="row"> |
66 | <span flex></span> | 66 | <span flex></span> |
67 | - <md-button ng-disabled="loading || theForm.$invalid || !theForm.$dirty" type="submit" class="md-raised md-primary"> | 67 | + <md-button ng-disabled="$root.loading || theForm.$invalid || !theForm.$dirty" type="submit" class="md-raised md-primary"> |
68 | {{ (vm.isAdd ? 'action.add' : 'action.save') | translate }} | 68 | {{ (vm.isAdd ? 'action.add' : 'action.save') | translate }} |
69 | </md-button> | 69 | </md-button> |
70 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> | 70 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> |
71 | </md-dialog-actions> | 71 | </md-dialog-actions> |
72 | </form> | 72 | </form> |
73 | </md-dialog> | 73 | </md-dialog> |
@@ -26,8 +26,8 @@ | @@ -26,8 +26,8 @@ | ||
26 | </md-button> | 26 | </md-button> |
27 | </div> | 27 | </div> |
28 | </md-toolbar> | 28 | </md-toolbar> |
29 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
30 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 29 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
30 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
31 | <div class="tb-aliases-header" flex layout="row" layout-align="start center"> | 31 | <div class="tb-aliases-header" flex layout="row" layout-align="start center"> |
32 | <span flex="5"></span> | 32 | <span flex="5"></span> |
33 | <div flex layout="row" layout-align="start center"> | 33 | <div flex layout="row" layout-align="start center"> |
@@ -40,7 +40,7 @@ | @@ -40,7 +40,7 @@ | ||
40 | <md-divider></md-divider> | 40 | <md-divider></md-divider> |
41 | <md-dialog-content> | 41 | <md-dialog-content> |
42 | <div class="md-dialog-content"> | 42 | <div class="md-dialog-content"> |
43 | - <fieldset ng-disabled="loading"> | 43 | + <fieldset ng-disabled="$root.loading"> |
44 | <div ng-form name="aliasForm" flex layout="row" layout-align="start center" ng-repeat="entityAlias in vm.entityAliases track by $index"> | 44 | <div ng-form name="aliasForm" flex layout="row" layout-align="start center" ng-repeat="entityAlias in vm.entityAliases track by $index"> |
45 | <span flex="5">{{$index + 1}}.</span> | 45 | <span flex="5">{{$index + 1}}.</span> |
46 | <di class="md-whiteframe-4dp tb-alias" flex layout="row" layout-align="start center"> | 46 | <di class="md-whiteframe-4dp tb-alias" flex layout="row" layout-align="start center"> |
@@ -63,7 +63,7 @@ | @@ -63,7 +63,7 @@ | ||
63 | aria-label="resolve-multiple-switcher"> | 63 | aria-label="resolve-multiple-switcher"> |
64 | </md-switch> | 64 | </md-switch> |
65 | </section> | 65 | </section> |
66 | - <md-button ng-disabled="loading" class="md-icon-button md-primary" style="min-width: 40px;" | 66 | + <md-button ng-disabled="$root.loading" class="md-icon-button md-primary" style="min-width: 40px;" |
67 | ng-click="vm.editAlias($event, entityAlias)" aria-label="{{ 'action.edit' | translate }}"> | 67 | ng-click="vm.editAlias($event, entityAlias)" aria-label="{{ 'action.edit' | translate }}"> |
68 | <md-tooltip md-direction="top"> | 68 | <md-tooltip md-direction="top"> |
69 | {{ 'alias.edit' | translate }} | 69 | {{ 'alias.edit' | translate }} |
@@ -72,7 +72,7 @@ | @@ -72,7 +72,7 @@ | ||
72 | edit | 72 | edit |
73 | </md-icon> | 73 | </md-icon> |
74 | </md-button> | 74 | </md-button> |
75 | - <md-button ng-disabled="loading" class="md-icon-button md-primary" style="min-width: 40px;" | 75 | + <md-button ng-disabled="$root.loading" class="md-icon-button md-primary" style="min-width: 40px;" |
76 | ng-click="vm.removeAlias($event, entityAlias)" aria-label="{{ 'action.remove' | translate }}"> | 76 | ng-click="vm.removeAlias($event, entityAlias)" aria-label="{{ 'action.remove' | translate }}"> |
77 | <md-tooltip md-direction="top"> | 77 | <md-tooltip md-direction="top"> |
78 | {{ 'entity.remove-alias' | translate }} | 78 | {{ 'entity.remove-alias' | translate }} |
@@ -87,7 +87,7 @@ | @@ -87,7 +87,7 @@ | ||
87 | </div> | 87 | </div> |
88 | </md-dialog-content> | 88 | </md-dialog-content> |
89 | <md-dialog-actions layout="row"> | 89 | <md-dialog-actions layout="row"> |
90 | - <md-button ng-show="!vm.disableAdd" ng-disabled="loading" class="md-primary md-raised" | 90 | + <md-button ng-show="!vm.disableAdd" ng-disabled="$root.loading" class="md-primary md-raised" |
91 | ng-click="vm.addAlias($event)" | 91 | ng-click="vm.addAlias($event)" |
92 | aria-label="{{ 'alias.add' | translate }}"> | 92 | aria-label="{{ 'alias.add' | translate }}"> |
93 | <md-tooltip md-direction="top"> | 93 | <md-tooltip md-direction="top"> |
@@ -96,10 +96,10 @@ | @@ -96,10 +96,10 @@ | ||
96 | <span translate>alias.add</span> | 96 | <span translate>alias.add</span> |
97 | </md-button> | 97 | </md-button> |
98 | <span flex></span> | 98 | <span flex></span> |
99 | - <md-button ng-disabled="loading || theForm.$invalid || !theForm.$dirty" type="submit" class="md-raised md-primary"> | 99 | + <md-button ng-disabled="$root.loading || theForm.$invalid || !theForm.$dirty" type="submit" class="md-raised md-primary"> |
100 | {{ 'action.save' | translate }} | 100 | {{ 'action.save' | translate }} |
101 | </md-button> | 101 | </md-button> |
102 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> | 102 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> |
103 | </md-dialog-actions> | 103 | </md-dialog-actions> |
104 | </form> | 104 | </form> |
105 | </md-dialog> | 105 | </md-dialog> |
@@ -26,12 +26,12 @@ | @@ -26,12 +26,12 @@ | ||
26 | </md-button> | 26 | </md-button> |
27 | </div> | 27 | </div> |
28 | </md-toolbar> | 28 | </md-toolbar> |
29 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
30 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 29 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
30 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
31 | <md-dialog-content> | 31 | <md-dialog-content> |
32 | <div class="md-dialog-content"> | 32 | <div class="md-dialog-content"> |
33 | <md-content class="md-padding" layout="column"> | 33 | <md-content class="md-padding" layout="column"> |
34 | - <fieldset ng-disabled="loading"> | 34 | + <fieldset ng-disabled="$root.loading"> |
35 | <md-input-container class="md-block"> | 35 | <md-input-container class="md-block"> |
36 | <label translate>attribute.key</label> | 36 | <label translate>attribute.key</label> |
37 | <input required name="key" ng-model="vm.attribute.key"> | 37 | <input required name="key" ng-model="vm.attribute.key"> |
@@ -42,7 +42,7 @@ | @@ -42,7 +42,7 @@ | ||
42 | <section layout="row"> | 42 | <section layout="row"> |
43 | <md-input-container flex="40" class="md-block" style="width: 200px;"> | 43 | <md-input-container flex="40" class="md-block" style="width: 200px;"> |
44 | <label translate>value.type</label> | 44 | <label translate>value.type</label> |
45 | - <md-select ng-model="vm.valueType" ng-disabled="loading()"> | 45 | + <md-select ng-model="vm.valueType" ng-disabled="$root.loading"> |
46 | <md-option ng-repeat="type in vm.valueTypes" ng-value="type"> | 46 | <md-option ng-repeat="type in vm.valueTypes" ng-value="type"> |
47 | <md-icon md-svg-icon="{{ type.icon }}"></md-icon> | 47 | <md-icon md-svg-icon="{{ type.icon }}"></md-icon> |
48 | <span>{{type.name | translate}}</span> | 48 | <span>{{type.name | translate}}</span> |
@@ -83,11 +83,11 @@ | @@ -83,11 +83,11 @@ | ||
83 | </md-dialog-content> | 83 | </md-dialog-content> |
84 | <md-dialog-actions layout="row"> | 84 | <md-dialog-actions layout="row"> |
85 | <span flex></span> | 85 | <span flex></span> |
86 | - <md-button ng-disabled="loading || theForm.$invalid || !theForm.$dirty" type="submit" | 86 | + <md-button ng-disabled="$root.loading || theForm.$invalid || !theForm.$dirty" type="submit" |
87 | class="md-raised md-primary"> | 87 | class="md-raised md-primary"> |
88 | {{ 'action.add' | translate }} | 88 | {{ 'action.add' | translate }} |
89 | </md-button> | 89 | </md-button> |
90 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | | 90 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | |
91 | translate }} | 91 | translate }} |
92 | </md-button> | 92 | </md-button> |
93 | </md-dialog-actions> | 93 | </md-dialog-actions> |
@@ -26,18 +26,18 @@ | @@ -26,18 +26,18 @@ | ||
26 | </md-button> | 26 | </md-button> |
27 | </div> | 27 | </div> |
28 | </md-toolbar> | 28 | </md-toolbar> |
29 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
30 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 29 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
30 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
31 | <md-dialog-content> | 31 | <md-dialog-content> |
32 | <div class="md-dialog-content"> | 32 | <div class="md-dialog-content"> |
33 | <md-content class="md-padding" layout="column"> | 33 | <md-content class="md-padding" layout="column"> |
34 | - <fieldset ng-disabled="loading"> | 34 | + <fieldset ng-disabled="$root.loading"> |
35 | <md-radio-group ng-model="vm.addToDashboardType" class="md-primary"> | 35 | <md-radio-group ng-model="vm.addToDashboardType" class="md-primary"> |
36 | <md-radio-button flex ng-value=0 class="md-primary md-align-top-left md-radio-interactive"> | 36 | <md-radio-button flex ng-value=0 class="md-primary md-align-top-left md-radio-interactive"> |
37 | <section flex layout="column" style="width: 300px;"> | 37 | <section flex layout="column" style="width: 300px;"> |
38 | <span translate style="padding-bottom: 10px;">dashboard.select-existing</span> | 38 | <span translate style="padding-bottom: 10px;">dashboard.select-existing</span> |
39 | <tb-dashboard-autocomplete the-form="theForm" | 39 | <tb-dashboard-autocomplete the-form="theForm" |
40 | - ng-disabled="loading || vm.addToDashboardType != 0" | 40 | + ng-disabled="$root.loading || vm.addToDashboardType != 0" |
41 | tb-required="vm.addToDashboardType === 0" | 41 | tb-required="vm.addToDashboardType === 0" |
42 | ng-model="vm.dashboardId" | 42 | ng-model="vm.dashboardId" |
43 | select-first-dashboard="false"> | 43 | select-first-dashboard="false"> |
@@ -69,11 +69,11 @@ | @@ -69,11 +69,11 @@ | ||
69 | style="margin-bottom: 0px; padding-right: 20px;"> | 69 | style="margin-bottom: 0px; padding-right: 20px;"> |
70 | {{ 'dashboard.open-dashboard' | translate }} | 70 | {{ 'dashboard.open-dashboard' | translate }} |
71 | </md-checkbox> | 71 | </md-checkbox> |
72 | - <md-button ng-disabled="loading || theForm.$invalid || !theForm.$dirty" type="submit" | 72 | + <md-button ng-disabled="$root.loading || theForm.$invalid || !theForm.$dirty" type="submit" |
73 | class="md-raised md-primary"> | 73 | class="md-raised md-primary"> |
74 | {{ 'action.add' | translate }} | 74 | {{ 'action.add' | translate }} |
75 | </md-button> | 75 | </md-button> |
76 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | | 76 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | |
77 | translate }} | 77 | translate }} |
78 | </md-button> | 78 | </md-button> |
79 | </md-dialog-actions> | 79 | </md-dialog-actions> |
@@ -47,7 +47,7 @@ md-toolbar.md-table-toolbar.alternate { | @@ -47,7 +47,7 @@ md-toolbar.md-table-toolbar.alternate { | ||
47 | .widgets-carousel { | 47 | .widgets-carousel { |
48 | position: relative; | 48 | position: relative; |
49 | margin: 0px; | 49 | margin: 0px; |
50 | - | 50 | + height: calc(100% - 100px); |
51 | min-height: 150px !important; | 51 | min-height: 150px !important; |
52 | 52 | ||
53 | tb-dashboard { | 53 | tb-dashboard { |
@@ -19,7 +19,7 @@ | @@ -19,7 +19,7 @@ | ||
19 | <section ng-show="!disableAttributeScopeSelection"> | 19 | <section ng-show="!disableAttributeScopeSelection"> |
20 | <md-input-container class="md-block" style="width: 200px;"> | 20 | <md-input-container class="md-block" style="width: 200px;"> |
21 | <label translate>attribute.attributes-scope</label> | 21 | <label translate>attribute.attributes-scope</label> |
22 | - <md-select ng-model="attributeScope" ng-disabled="loading() || attributeScopeSelectionReadonly"> | 22 | + <md-select ng-model="attributeScope" ng-disabled="$root.loading || attributeScopeSelectionReadonly"> |
23 | <md-option ng-repeat="scope in attributeScopes" ng-value="scope"> | 23 | <md-option ng-repeat="scope in attributeScopes" ng-value="scope"> |
24 | {{scope.name | translate}} | 24 | {{scope.name | translate}} |
25 | </md-option> | 25 | </md-option> |
@@ -38,7 +38,7 @@ export default function EntityAutocomplete($compile, $templateCache, $q, $filter | @@ -38,7 +38,7 @@ export default function EntityAutocomplete($compile, $templateCache, $q, $filter | ||
38 | if (scope.excludeEntityIds && scope.excludeEntityIds.length) { | 38 | if (scope.excludeEntityIds && scope.excludeEntityIds.length) { |
39 | limit += scope.excludeEntityIds.length; | 39 | limit += scope.excludeEntityIds.length; |
40 | } | 40 | } |
41 | - entityService.getEntitiesByNameFilter(scope.entityType, searchText, limit, null, scope.entitySubtype).then(function success(result) { | 41 | + entityService.getEntitiesByNameFilter(scope.entityType, searchText, limit, {ignoreLoading: true}, scope.entitySubtype).then(function success(result) { |
42 | if (result) { | 42 | if (result) { |
43 | if (scope.excludeEntityIds && scope.excludeEntityIds.length) { | 43 | if (scope.excludeEntityIds && scope.excludeEntityIds.length) { |
44 | var entities = []; | 44 | var entities = []; |
@@ -38,7 +38,7 @@ export default function EntityListDirective($compile, $templateCache, $q, $mdUti | @@ -38,7 +38,7 @@ export default function EntityListDirective($compile, $templateCache, $q, $mdUti | ||
38 | 38 | ||
39 | scope.fetchEntities = function(searchText, limit) { | 39 | scope.fetchEntities = function(searchText, limit) { |
40 | var deferred = $q.defer(); | 40 | var deferred = $q.defer(); |
41 | - entityService.getEntitiesByNameFilter(scope.entityType, searchText, limit).then( | 41 | + entityService.getEntitiesByNameFilter(scope.entityType, searchText, limit, {ignoreLoading: true}).then( |
42 | function success(result) { | 42 | function success(result) { |
43 | if (result) { | 43 | if (result) { |
44 | deferred.resolve(result); | 44 | deferred.resolve(result); |
@@ -93,9 +93,9 @@ export default function EntitySubtypeAutocomplete($compile, $templateCache, $q, | @@ -93,9 +93,9 @@ export default function EntitySubtypeAutocomplete($compile, $templateCache, $q, | ||
93 | if (!scope.entitySubtypes) { | 93 | if (!scope.entitySubtypes) { |
94 | var entitySubtypesPromise; | 94 | var entitySubtypesPromise; |
95 | if (scope.entityType == types.entityType.asset) { | 95 | if (scope.entityType == types.entityType.asset) { |
96 | - entitySubtypesPromise = assetService.getAssetTypes(); | 96 | + entitySubtypesPromise = assetService.getAssetTypes({ignoreLoading: true}); |
97 | } else if (scope.entityType == types.entityType.device) { | 97 | } else if (scope.entityType == types.entityType.device) { |
98 | - entitySubtypesPromise = deviceService.getDeviceTypes(); | 98 | + entitySubtypesPromise = deviceService.getDeviceTypes({ignoreLoading: true}); |
99 | } | 99 | } |
100 | if (entitySubtypesPromise) { | 100 | if (entitySubtypesPromise) { |
101 | entitySubtypesPromise.then( | 101 | entitySubtypesPromise.then( |
@@ -95,9 +95,9 @@ export default function EntitySubtypeListDirective($compile, $templateCache, $q, | @@ -95,9 +95,9 @@ export default function EntitySubtypeListDirective($compile, $templateCache, $q, | ||
95 | if (!scope.entitySubtypes) { | 95 | if (!scope.entitySubtypes) { |
96 | var entitySubtypesPromise; | 96 | var entitySubtypesPromise; |
97 | if (scope.entityType == types.entityType.asset) { | 97 | if (scope.entityType == types.entityType.asset) { |
98 | - entitySubtypesPromise = assetService.getAssetTypes(); | 98 | + entitySubtypesPromise = assetService.getAssetTypes({ignoreLoading: true}); |
99 | } else if (scope.entityType == types.entityType.device) { | 99 | } else if (scope.entityType == types.entityType.device) { |
100 | - entitySubtypesPromise = deviceService.getDeviceTypes(); | 100 | + entitySubtypesPromise = deviceService.getDeviceTypes({ignoreLoading: true}); |
101 | } | 101 | } |
102 | if (entitySubtypesPromise) { | 102 | if (entitySubtypesPromise) { |
103 | entitySubtypesPromise.then( | 103 | entitySubtypesPromise.then( |
@@ -73,9 +73,9 @@ export default function EntitySubtypeSelect($compile, $templateCache, $translate | @@ -73,9 +73,9 @@ export default function EntitySubtypeSelect($compile, $templateCache, $translate | ||
73 | scope.entitySubtypes = []; | 73 | scope.entitySubtypes = []; |
74 | var entitySubtypesPromise; | 74 | var entitySubtypesPromise; |
75 | if (scope.entityType == types.entityType.asset) { | 75 | if (scope.entityType == types.entityType.asset) { |
76 | - entitySubtypesPromise = assetService.getAssetTypes(); | 76 | + entitySubtypesPromise = assetService.getAssetTypes({ignoreLoading: true}); |
77 | } else if (scope.entityType == types.entityType.device) { | 77 | } else if (scope.entityType == types.entityType.device) { |
78 | - entitySubtypesPromise = deviceService.getDeviceTypes(); | 78 | + entitySubtypesPromise = deviceService.getDeviceTypes({ignoreLoading: true}); |
79 | } | 79 | } |
80 | if (entitySubtypesPromise) { | 80 | if (entitySubtypesPromise) { |
81 | entitySubtypesPromise.then( | 81 | entitySubtypesPromise.then( |
@@ -26,16 +26,16 @@ | @@ -26,16 +26,16 @@ | ||
26 | </md-button> | 26 | </md-button> |
27 | </div> | 27 | </div> |
28 | </md-toolbar> | 28 | </md-toolbar> |
29 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
30 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 29 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
30 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
31 | <md-dialog-content> | 31 | <md-dialog-content> |
32 | <div class="md-dialog-content"> | 32 | <div class="md-dialog-content"> |
33 | <md-content class="md-padding" layout="column"> | 33 | <md-content class="md-padding" layout="column"> |
34 | - <fieldset ng-disabled="loading"> | 34 | + <fieldset ng-disabled="$root.loading"> |
35 | <tb-relation-type-autocomplete ng-disabled="!vm.isAdd" | 35 | <tb-relation-type-autocomplete ng-disabled="!vm.isAdd" |
36 | ng-model="vm.relation.type" | 36 | ng-model="vm.relation.type" |
37 | tb-required="true" | 37 | tb-required="true" |
38 | - ng-disabled="loading"> | 38 | + ng-disabled="$root.loading"> |
39 | </tb-relation-type-autocomplete> | 39 | </tb-relation-type-autocomplete> |
40 | <small>{{(vm.direction == vm.types.entitySearchDirection.from ? | 40 | <small>{{(vm.direction == vm.types.entitySearchDirection.from ? |
41 | 'relation.to-entity' : 'relation.from-entity') | translate}}</small> | 41 | 'relation.to-entity' : 'relation.from-entity') | translate}}</small> |
@@ -61,11 +61,11 @@ | @@ -61,11 +61,11 @@ | ||
61 | </md-dialog-content> | 61 | </md-dialog-content> |
62 | <md-dialog-actions layout="row"> | 62 | <md-dialog-actions layout="row"> |
63 | <span flex></span> | 63 | <span flex></span> |
64 | - <md-button ng-disabled="loading || theForm.$invalid || !theForm.$dirty" type="submit" | 64 | + <md-button ng-disabled="$root.loading || theForm.$invalid || !theForm.$dirty" type="submit" |
65 | class="md-raised md-primary"> | 65 | class="md-raised md-primary"> |
66 | {{ (vm.isAdd ? 'action.add' : 'action.save') | translate }} | 66 | {{ (vm.isAdd ? 'action.add' : 'action.save') | translate }} |
67 | </md-button> | 67 | </md-button> |
68 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | | 68 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | |
69 | translate }} | 69 | translate }} |
70 | </md-button> | 70 | </md-button> |
71 | </md-dialog-actions> | 71 | </md-dialog-actions> |
@@ -37,7 +37,7 @@ | @@ -37,7 +37,7 @@ | ||
37 | allowed-entity-types="allowedEntityTypes" | 37 | allowed-entity-types="allowedEntityTypes" |
38 | tb-required="false"> | 38 | tb-required="false"> |
39 | </tb-entity-type-list> | 39 | </tb-entity-type-list> |
40 | - <md-button ng-disabled="loading" class="md-icon-button md-primary" style="width: 40px; min-width: 40px;" | 40 | + <md-button ng-disabled="$root.loading" class="md-icon-button md-primary" style="width: 40px; min-width: 40px;" |
41 | ng-click="removeFilter($event, filter)" aria-label="{{ 'action.remove' | translate }}"> | 41 | ng-click="removeFilter($event, filter)" aria-label="{{ 'action.remove' | translate }}"> |
42 | <md-tooltip md-direction="top"> | 42 | <md-tooltip md-direction="top"> |
43 | {{ 'relation.remove-relation-filter' | translate }} | 43 | {{ 'relation.remove-relation-filter' | translate }} |
@@ -54,7 +54,7 @@ | @@ -54,7 +54,7 @@ | ||
54 | class="tb-prompt" translate>relation.any-relation</span> | 54 | class="tb-prompt" translate>relation.any-relation</span> |
55 | </div> | 55 | </div> |
56 | <div> | 56 | <div> |
57 | - <md-button ng-disabled="loading" class="md-primary md-raised" ng-click="addFilter($event)" aria-label="{{ 'action.add' | translate }}"> | 57 | + <md-button ng-disabled="$root.loading" class="md-primary md-raised" ng-click="addFilter($event)" aria-label="{{ 'action.add' | translate }}"> |
58 | <md-tooltip md-direction="top"> | 58 | <md-tooltip md-direction="top"> |
59 | {{ 'relation.add-relation-filter' | translate }} | 59 | {{ 'relation.add-relation-filter' | translate }} |
60 | </md-tooltip> | 60 | </md-tooltip> |
@@ -19,7 +19,7 @@ | @@ -19,7 +19,7 @@ | ||
19 | <section layout="row"> | 19 | <section layout="row"> |
20 | <md-input-container class="md-block" style="width: 200px;"> | 20 | <md-input-container class="md-block" style="width: 200px;"> |
21 | <label translate>relation.direction</label> | 21 | <label translate>relation.direction</label> |
22 | - <md-select ng-model="vm.direction" ng-disabled="loading"> | 22 | + <md-select ng-model="vm.direction" ng-disabled="$root.loading"> |
23 | <md-option ng-repeat="direction in vm.types.entitySearchDirection" ng-value="direction"> | 23 | <md-option ng-repeat="direction in vm.types.entitySearchDirection" ng-value="direction"> |
24 | {{ ('relation.search-direction.' + direction) | translate}} | 24 | {{ ('relation.search-direction.' + direction) | translate}} |
25 | </md-option> | 25 | </md-option> |
@@ -35,7 +35,7 @@ | @@ -35,7 +35,7 @@ | ||
35 | </md-dialog-content> | 35 | </md-dialog-content> |
36 | <md-dialog-actions layout="row"> | 36 | <md-dialog-actions layout="row"> |
37 | <span flex></span> | 37 | <span flex></span> |
38 | - <md-button ng-disabled="loading" ng-click="vm.close()" style="margin-right:20px;">{{ 'action.close' | | 38 | + <md-button ng-disabled="$root.loading" ng-click="vm.close()" style="margin-right:20px;">{{ 'action.close' | |
39 | translate }} | 39 | translate }} |
40 | </md-button> | 40 | </md-button> |
41 | </md-dialog-actions> | 41 | </md-dialog-actions> |
@@ -19,7 +19,7 @@ | @@ -19,7 +19,7 @@ | ||
19 | <section layout="row"> | 19 | <section layout="row"> |
20 | <md-input-container class="md-block" style="width: 200px;"> | 20 | <md-input-container class="md-block" style="width: 200px;"> |
21 | <label translate>event.event-type</label> | 21 | <label translate>event.event-type</label> |
22 | - <md-select ng-model="eventType" ng-disabled="loading()"> | 22 | + <md-select ng-model="eventType" ng-disabled="$root.loading"> |
23 | <md-option ng-repeat="type in eventTypes" ng-value="type.value"> | 23 | <md-option ng-repeat="type in eventTypes" ng-value="type.value"> |
24 | {{type.name | translate}} | 24 | {{type.name | translate}} |
25 | </md-option> | 25 | </md-option> |
@@ -30,8 +30,8 @@ | @@ -30,8 +30,8 @@ | ||
30 | <md-list flex layout="column" class="md-whiteframe-z1 tb-event-table"> | 30 | <md-list flex layout="column" class="md-whiteframe-z1 tb-event-table"> |
31 | <md-list class="tb-row tb-header" layout="row" tb-event-header event-type="{{eventType}}"> | 31 | <md-list class="tb-row tb-header" layout="row" tb-event-header event-type="{{eventType}}"> |
32 | </md-list> | 32 | </md-list> |
33 | - <md-progress-linear style="max-height: 0px;" md-mode="indeterminate" ng-disabled="!loading()" | ||
34 | - ng-show="loading()"></md-progress-linear> | 33 | + <md-progress-linear style="max-height: 0px;" md-mode="indeterminate" ng-disabled="!$root.loading" |
34 | + ng-show="$root.loading"></md-progress-linear> | ||
35 | <md-divider></md-divider> | 35 | <md-divider></md-divider> |
36 | <span translate layout-align="center center" | 36 | <span translate layout-align="center center" |
37 | style="margin-top: 25px;" | 37 | style="margin-top: 25px;" |
@@ -27,14 +27,14 @@ | @@ -27,14 +27,14 @@ | ||
27 | </div> | 27 | </div> |
28 | </md-toolbar> | 28 | </md-toolbar> |
29 | 29 | ||
30 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | 30 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
31 | 31 | ||
32 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 32 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> |
33 | 33 | ||
34 | <md-dialog-content> | 34 | <md-dialog-content> |
35 | <div class="md-dialog-content"> | 35 | <div class="md-dialog-content"> |
36 | <md-content class="md-padding" layout="column"> | 36 | <md-content class="md-padding" layout="column"> |
37 | - <fieldset ng-disabled="loading"> | 37 | + <fieldset ng-disabled="$root.loading"> |
38 | <section flex layout="row"> | 38 | <section flex layout="row"> |
39 | <md-input-container flex="60" class="md-block" md-is-error="theForm.extensionId.$touched && theForm.extensionId.$invalid"> | 39 | <md-input-container flex="60" class="md-block" md-is-error="theForm.extensionId.$touched && theForm.extensionId.$invalid"> |
40 | <label translate>extension.extension-id</label> | 40 | <label translate>extension.extension-id</label> |
@@ -74,7 +74,7 @@ | @@ -74,7 +74,7 @@ | ||
74 | {{ (vm.isAdd ? 'action.add' : 'action.save') | translate }} | 74 | {{ (vm.isAdd ? 'action.add' : 'action.save') | translate }} |
75 | </md-button> | 75 | </md-button> |
76 | 76 | ||
77 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }} | 77 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }} |
78 | </md-button> | 78 | </md-button> |
79 | </md-dialog-actions> | 79 | </md-dialog-actions> |
80 | </form> | 80 | </form> |
@@ -26,11 +26,11 @@ | @@ -26,11 +26,11 @@ | ||
26 | </md-button> | 26 | </md-button> |
27 | </div> | 27 | </div> |
28 | </md-toolbar> | 28 | </md-toolbar> |
29 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | ||
30 | - <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | 29 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
30 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
31 | <md-dialog-content> | 31 | <md-dialog-content> |
32 | <div class="md-dialog-content"> | 32 | <div class="md-dialog-content"> |
33 | - <fieldset ng-disabled="loading"> | 33 | + <fieldset ng-disabled="$root.loading"> |
34 | <div layout="column" layout-padding> | 34 | <div layout="column" layout-padding> |
35 | <div class="tb-container"> | 35 | <div class="tb-container"> |
36 | <label class="tb-label" translate>{{ vm.importFileLabel }}</label> | 36 | <label class="tb-label" translate>{{ vm.importFileLabel }}</label> |
@@ -63,10 +63,10 @@ | @@ -63,10 +63,10 @@ | ||
63 | </md-dialog-content> | 63 | </md-dialog-content> |
64 | <md-dialog-actions layout="row"> | 64 | <md-dialog-actions layout="row"> |
65 | <span flex></span> | 65 | <span flex></span> |
66 | - <md-button ng-disabled="loading || !theForm.$dirty || !theForm.$valid || !vm.importData" type="submit" class="md-raised md-primary"> | 66 | + <md-button ng-disabled="$root.loading || !theForm.$dirty || !theForm.$valid || !vm.importData" type="submit" class="md-raised md-primary"> |
67 | {{ 'action.import' | translate }} | 67 | {{ 'action.import' | translate }} |
68 | </md-button> | 68 | </md-button> |
69 | - <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> | 69 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> |
70 | </md-dialog-actions> | 70 | </md-dialog-actions> |
71 | </form> | 71 | </form> |
72 | </md-dialog> | 72 | </md-dialog> |
@@ -76,7 +76,7 @@ | @@ -76,7 +76,7 @@ | ||
76 | </tb-user-menu> | 76 | </tb-user-menu> |
77 | </div> | 77 | </div> |
78 | </md-toolbar> | 78 | </md-toolbar> |
79 | - <md-progress-linear class="md-warn" style="z-index: 10; max-height: 0px; width: 100%;" md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | 79 | + <md-progress-linear class="md-warn" style="z-index: 10; max-height: 0px; width: 100%;" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
80 | 80 | ||
81 | <div flex layout="column" id="toast-parent" style="position: relative;"> | 81 | <div flex layout="column" id="toast-parent" style="position: relative;"> |
82 | <md-content ng-cloak flex layout="column" class="page-content" ui-view name="content"></md-content> | 82 | <md-content ng-cloak flex layout="column" class="page-content" ui-view name="content"></md-content> |
@@ -1213,6 +1213,7 @@ export default angular.module('thingsboard.locale', []) | @@ -1213,6 +1213,7 @@ export default angular.module('thingsboard.locale', []) | ||
1213 | "remove-widget-title": "Are you sure you want to remove the widget '{{widgetTitle}}'?", | 1213 | "remove-widget-title": "Are you sure you want to remove the widget '{{widgetTitle}}'?", |
1214 | "remove-widget-text": "After the confirmation the widget and all related data will become unrecoverable.", | 1214 | "remove-widget-text": "After the confirmation the widget and all related data will become unrecoverable.", |
1215 | "timeseries": "Time series", | 1215 | "timeseries": "Time series", |
1216 | + "search-data": "Search data", | ||
1216 | "latest-values": "Latest values", | 1217 | "latest-values": "Latest values", |
1217 | "rpc": "Control widget", | 1218 | "rpc": "Control widget", |
1218 | "alarm": "Alarm widget", | 1219 | "alarm": "Alarm widget", |
@@ -23,7 +23,7 @@ | @@ -23,7 +23,7 @@ | ||
23 | </md-card-title-text> | 23 | </md-card-title-text> |
24 | </md-card-title> | 24 | </md-card-title> |
25 | <md-progress-linear class="md-warn" style="z-index: 1; max-height: 5px; width: inherit; position: absolute" | 25 | <md-progress-linear class="md-warn" style="z-index: 1; max-height: 5px; width: inherit; position: absolute" |
26 | - md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | 26 | + md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
27 | <md-card-content> | 27 | <md-card-content> |
28 | <form class="create-password-form" ng-submit="vm.createPassword()"> | 28 | <form class="create-password-form" ng-submit="vm.createPassword()"> |
29 | <div layout="column" layout-padding="" id="toast-parent"> | 29 | <div layout="column" layout-padding="" id="toast-parent"> |
@@ -23,7 +23,7 @@ | @@ -23,7 +23,7 @@ | ||
23 | </md-card-title-text> | 23 | </md-card-title-text> |
24 | </md-card-title> | 24 | </md-card-title> |
25 | <md-progress-linear class="md-warn" style="z-index: 1; max-height: 5px; width: inherit; position: absolute" | 25 | <md-progress-linear class="md-warn" style="z-index: 1; max-height: 5px; width: inherit; position: absolute" |
26 | - md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | 26 | + md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
27 | <md-card-content> | 27 | <md-card-content> |
28 | <form class="login-form" ng-submit="vm.login()"> | 28 | <form class="login-form" ng-submit="vm.login()"> |
29 | <div layout="column" layout-padding="" id="toast-parent"> | 29 | <div layout="column" layout-padding="" id="toast-parent"> |
@@ -23,7 +23,7 @@ | @@ -23,7 +23,7 @@ | ||
23 | </md-card-title-text> | 23 | </md-card-title-text> |
24 | </md-card-title> | 24 | </md-card-title> |
25 | <md-progress-linear class="md-warn" style="z-index: 1; max-height: 5px; width: inherit; position: absolute" | 25 | <md-progress-linear class="md-warn" style="z-index: 1; max-height: 5px; width: inherit; position: absolute" |
26 | - md-mode="indeterminate" ng-disabled="!loading" ng-show="loading"></md-progress-linear> | 26 | + md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> |
27 | <md-card-content> | 27 | <md-card-content> |
28 | <form class="request-password-reset-form" ng-submit="vm.sendResetPasswordLink()"> | 28 | <form class="request-password-reset-form" ng-submit="vm.sendResetPasswordLink()"> |
29 | <div layout="column" layout-padding="" id="toast-parent"> | 29 | <div layout="column" layout-padding="" id="toast-parent"> |