diff --git a/application/src/main/data/json/system/oauth2_config_templates/github_config.json b/application/src/main/data/json/system/oauth2_config_templates/github_config.json index 0a1ae5779b..439043d961 100644 --- a/application/src/main/data/json/system/oauth2_config_templates/github_config.json +++ b/application/src/main/data/json/system/oauth2_config_templates/github_config.json @@ -10,6 +10,7 @@ "mapperConfig": { "type": "GITHUB", "basic": { + "firstNameAttributeKey": "name", "tenantNameStrategy": "DOMAIN" } }, diff --git a/application/src/main/java/org/thingsboard/server/controller/OAuth2Controller.java b/application/src/main/java/org/thingsboard/server/controller/OAuth2Controller.java index 323eb19bcd..fc5e0a1426 100644 --- a/application/src/main/java/org/thingsboard/server/controller/OAuth2Controller.java +++ b/application/src/main/java/org/thingsboard/server/controller/OAuth2Controller.java @@ -16,6 +16,7 @@ package org.thingsboard.server.controller; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; @@ -23,6 +24,7 @@ import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo; import org.thingsboard.server.common.data.oauth2.OAuth2ClientsParams; import org.thingsboard.server.common.data.oauth2.SchemeType; +import org.thingsboard.server.dao.oauth2.OAuth2Configuration; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; @@ -36,6 +38,10 @@ import java.util.List; @RequestMapping("/api") @Slf4j public class OAuth2Controller extends BaseController { + + @Autowired + private OAuth2Configuration oAuth2Configuration; + @RequestMapping(value = "/noauth/oauth2Clients", method = RequestMethod.POST) @ResponseBody public List getOAuth2Clients(HttpServletRequest request) throws ThingsboardException { @@ -70,4 +76,16 @@ public class OAuth2Controller extends BaseController { throw handleException(e); } } + + @PreAuthorize("hasAnyAuthority('SYS_ADMIN')") + @RequestMapping(value = "/oauth2/loginProcessingUrl", method = RequestMethod.GET) + @ResponseBody + public String getLoginProcessingUrl() throws ThingsboardException { + try { + accessControlService.checkPermission(getCurrentUser(), Resource.OAUTH2_CONFIGURATION_INFO, Operation.READ); + return "\"" + oAuth2Configuration.getLoginProcessingUrl() + "\""; + } catch (Exception e) { + throw handleException(e); + } + } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientsDomainParams.java b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientsDomainParams.java index d93401f5cc..4e932fad85 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientsDomainParams.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientsDomainParams.java @@ -27,6 +27,6 @@ import java.util.Set; @NoArgsConstructor @AllArgsConstructor public class OAuth2ClientsDomainParams { - private Set domainInfos; - private Set clientRegistrations; -} \ No newline at end of file + private List domainInfos; + private List clientRegistrations; +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientsParams.java b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientsParams.java index ee20021aca..ad5d5305bd 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientsParams.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientsParams.java @@ -16,6 +16,8 @@ package org.thingsboard.server.common.data.oauth2; import lombok.*; + +import java.util.List; import java.util.Set; @EqualsAndHashCode @@ -26,5 +28,5 @@ import java.util.Set; @AllArgsConstructor public class OAuth2ClientsParams { private boolean enabled; - private Set domainsParams; -} \ No newline at end of file + private List domainsParams; +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2Utils.java b/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2Utils.java index a96a0d36c8..00b4f7e941 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2Utils.java +++ b/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2Utils.java @@ -32,19 +32,19 @@ public class OAuth2Utils { } public static OAuth2ClientsParams toOAuth2Params(List extendedOAuth2ClientRegistrationInfos) { - Map> domainsByInfoId = new HashMap<>(); - Map infoById = new HashMap<>(); + Map> domainsByInfoId = new LinkedHashMap<>(); + Map infoById = new LinkedHashMap<>(); for (ExtendedOAuth2ClientRegistrationInfo extendedClientRegistrationInfo : extendedOAuth2ClientRegistrationInfos) { String domainName = extendedClientRegistrationInfo.getDomainName(); SchemeType domainScheme = extendedClientRegistrationInfo.getDomainScheme(); - domainsByInfoId.computeIfAbsent(extendedClientRegistrationInfo.getId(), key -> new HashSet<>()) + domainsByInfoId.computeIfAbsent(extendedClientRegistrationInfo.getId(), key -> new ArrayList<>()) .add(new DomainInfo(domainScheme, domainName)); infoById.put(extendedClientRegistrationInfo.getId(), extendedClientRegistrationInfo); } - Map, OAuth2ClientsDomainParams> domainParamsMap = new HashMap<>(); + Map, OAuth2ClientsDomainParams> domainParamsMap = new LinkedHashMap<>(); domainsByInfoId.forEach((clientRegistrationInfoId, domainInfos) -> { domainParamsMap.computeIfAbsent(domainInfos, - key -> new OAuth2ClientsDomainParams(key, new HashSet<>()) + key -> new OAuth2ClientsDomainParams(key, new ArrayList<>()) ) .getClientRegistrations() .add(toClientRegistrationDto(infoById.get(clientRegistrationInfoId))); @@ -52,7 +52,7 @@ public class OAuth2Utils { boolean enabled = extendedOAuth2ClientRegistrationInfos.stream() .map(OAuth2ClientRegistrationInfo::isEnabled) .findFirst().orElse(false); - return new OAuth2ClientsParams(enabled, new HashSet<>(domainParamsMap.values())); + return new OAuth2ClientsParams(enabled, new ArrayList<>(domainParamsMap.values())); } public static ClientRegistrationDto toClientRegistrationDto(OAuth2ClientRegistrationInfo oAuth2ClientRegistrationInfo) { diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseOAuth2ServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseOAuth2ServiceTest.java index b54505a3d7..a927f1e78c 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseOAuth2ServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseOAuth2ServiceTest.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.dao.service; +import com.google.common.collect.Lists; import com.google.common.collect.Sets; import org.junit.After; import org.junit.Assert; @@ -29,7 +30,7 @@ import java.util.*; import java.util.stream.Collectors; public class BaseOAuth2ServiceTest extends AbstractServiceTest { - private static final OAuth2ClientsParams EMPTY_PARAMS = new OAuth2ClientsParams(false, new HashSet<>()); + private static final OAuth2ClientsParams EMPTY_PARAMS = new OAuth2ClientsParams(false, new ArrayList<>()); @Autowired protected OAuth2Service oAuth2Service; @@ -48,14 +49,14 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { @Test(expected = DataValidationException.class) public void testSaveHttpAndMixedDomainsTogether() { - OAuth2ClientsParams clientsParams = new OAuth2ClientsParams(true, Sets.newHashSet( + OAuth2ClientsParams clientsParams = new OAuth2ClientsParams(true, Lists.newArrayList( OAuth2ClientsDomainParams.builder() - .domainInfos(Sets.newHashSet( + .domainInfos(Lists.newArrayList( DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(), DomainInfo.builder().name("first-domain").scheme(SchemeType.MIXED).build(), DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build() )) - .clientRegistrations(Sets.newHashSet( + .clientRegistrations(Lists.newArrayList( validClientRegistrationDto(), validClientRegistrationDto(), validClientRegistrationDto() @@ -67,14 +68,14 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { @Test(expected = DataValidationException.class) public void testSaveHttpsAndMixedDomainsTogether() { - OAuth2ClientsParams clientsParams = new OAuth2ClientsParams(true, Sets.newHashSet( + OAuth2ClientsParams clientsParams = new OAuth2ClientsParams(true, Lists.newArrayList( OAuth2ClientsDomainParams.builder() - .domainInfos(Sets.newHashSet( + .domainInfos(Lists.newArrayList( DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTPS).build(), DomainInfo.builder().name("first-domain").scheme(SchemeType.MIXED).build(), DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build() )) - .clientRegistrations(Sets.newHashSet( + .clientRegistrations(Lists.newArrayList( validClientRegistrationDto(), validClientRegistrationDto(), validClientRegistrationDto() @@ -131,20 +132,20 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { Assert.assertNotNull(foundClientsParams); Assert.assertEquals(clientsParams, foundClientsParams); - OAuth2ClientsParams newClientsParams = new OAuth2ClientsParams(true, Sets.newHashSet( + OAuth2ClientsParams newClientsParams = new OAuth2ClientsParams(true, Lists.newArrayList( OAuth2ClientsDomainParams.builder() - .domainInfos(Sets.newHashSet( + .domainInfos(Lists.newArrayList( DomainInfo.builder().name("another-domain").scheme(SchemeType.HTTPS).build() )) - .clientRegistrations(Sets.newHashSet( + .clientRegistrations(Lists.newArrayList( validClientRegistrationDto() )) .build(), OAuth2ClientsDomainParams.builder() - .domainInfos(Sets.newHashSet( + .domainInfos(Lists.newArrayList( DomainInfo.builder().name("test-domain").scheme(SchemeType.MIXED).build() )) - .clientRegistrations(Sets.newHashSet( + .clientRegistrations(Lists.newArrayList( validClientRegistrationDto() )) .build() @@ -157,22 +158,22 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { @Test public void testGetOAuth2Clients() { - Set firstGroup = Sets.newHashSet( + List firstGroup = Lists.newArrayList( validClientRegistrationDto(), validClientRegistrationDto(), validClientRegistrationDto(), validClientRegistrationDto() ); - Set secondGroup = Sets.newHashSet( + List secondGroup = Lists.newArrayList( validClientRegistrationDto(), validClientRegistrationDto() ); - Set thirdGroup = Sets.newHashSet( + List thirdGroup = Lists.newArrayList( validClientRegistrationDto() ); - OAuth2ClientsParams clientsParams = new OAuth2ClientsParams(true, Sets.newHashSet( + OAuth2ClientsParams clientsParams = new OAuth2ClientsParams(true, Lists.newArrayList( OAuth2ClientsDomainParams.builder() - .domainInfos(Sets.newHashSet( + .domainInfos(Lists.newArrayList( DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(), DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(), DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build() @@ -180,14 +181,14 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { .clientRegistrations(firstGroup) .build(), OAuth2ClientsDomainParams.builder() - .domainInfos(Sets.newHashSet( + .domainInfos(Lists.newArrayList( DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTP).build(), DomainInfo.builder().name("fourth-domain").scheme(SchemeType.MIXED).build() )) .clientRegistrations(secondGroup) .build(), OAuth2ClientsDomainParams.builder() - .domainInfos(Sets.newHashSet( + .domainInfos(Lists.newArrayList( DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTPS).build(), DomainInfo.builder().name("fifth-domain").scheme(SchemeType.HTTP).build() )) @@ -285,15 +286,15 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { @Test public void testGetOAuth2ClientsForHttpAndHttps() { - Set firstGroup = Sets.newHashSet( + List firstGroup = Lists.newArrayList( validClientRegistrationDto(), validClientRegistrationDto(), validClientRegistrationDto(), validClientRegistrationDto() ); - OAuth2ClientsParams clientsParams = new OAuth2ClientsParams(true, Sets.newHashSet( + OAuth2ClientsParams clientsParams = new OAuth2ClientsParams(true, Lists.newArrayList( OAuth2ClientsDomainParams.builder() - .domainInfos(Sets.newHashSet( + .domainInfos(Lists.newArrayList( DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(), DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(), DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTPS).build() @@ -335,25 +336,25 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { @Test public void testGetDisabledOAuth2Clients() { - OAuth2ClientsParams clientsParams = new OAuth2ClientsParams(true, Sets.newHashSet( + OAuth2ClientsParams clientsParams = new OAuth2ClientsParams(true, Lists.newArrayList( OAuth2ClientsDomainParams.builder() - .domainInfos(Sets.newHashSet( + .domainInfos(Lists.newArrayList( DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(), DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(), DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build() )) - .clientRegistrations(Sets.newHashSet( + .clientRegistrations(Lists.newArrayList( validClientRegistrationDto(), validClientRegistrationDto(), validClientRegistrationDto() )) .build(), OAuth2ClientsDomainParams.builder() - .domainInfos(Sets.newHashSet( + .domainInfos(Lists.newArrayList( DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTP).build(), DomainInfo.builder().name("fourth-domain").scheme(SchemeType.MIXED).build() )) - .clientRegistrations(Sets.newHashSet( + .clientRegistrations(Lists.newArrayList( validClientRegistrationDto(), validClientRegistrationDto() )) @@ -374,35 +375,35 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { @Test public void testFindAllClientRegistrationInfos() { - OAuth2ClientsParams clientsParams = new OAuth2ClientsParams(true, Sets.newHashSet( + OAuth2ClientsParams clientsParams = new OAuth2ClientsParams(true, Lists.newArrayList( OAuth2ClientsDomainParams.builder() - .domainInfos(Sets.newHashSet( + .domainInfos(Lists.newArrayList( DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(), DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(), DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build() )) - .clientRegistrations(Sets.newHashSet( + .clientRegistrations(Lists.newArrayList( validClientRegistrationDto(), validClientRegistrationDto(), validClientRegistrationDto() )) .build(), OAuth2ClientsDomainParams.builder() - .domainInfos(Sets.newHashSet( + .domainInfos(Lists.newArrayList( DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTP).build(), DomainInfo.builder().name("fourth-domain").scheme(SchemeType.MIXED).build() )) - .clientRegistrations(Sets.newHashSet( + .clientRegistrations(Lists.newArrayList( validClientRegistrationDto(), validClientRegistrationDto() )) .build(), OAuth2ClientsDomainParams.builder() - .domainInfos(Sets.newHashSet( + .domainInfos(Lists.newArrayList( DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTPS).build(), DomainInfo.builder().name("fifth-domain").scheme(SchemeType.HTTP).build() )) - .clientRegistrations(Sets.newHashSet( + .clientRegistrations(Lists.newArrayList( validClientRegistrationDto() )) .build() @@ -423,35 +424,35 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { @Test public void testFindClientRegistrationById() { - OAuth2ClientsParams clientsParams = new OAuth2ClientsParams(true, Sets.newHashSet( + OAuth2ClientsParams clientsParams = new OAuth2ClientsParams(true, Lists.newArrayList( OAuth2ClientsDomainParams.builder() - .domainInfos(Sets.newHashSet( + .domainInfos(Lists.newArrayList( DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(), DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(), DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build() )) - .clientRegistrations(Sets.newHashSet( + .clientRegistrations(Lists.newArrayList( validClientRegistrationDto(), validClientRegistrationDto(), validClientRegistrationDto() )) .build(), OAuth2ClientsDomainParams.builder() - .domainInfos(Sets.newHashSet( + .domainInfos(Lists.newArrayList( DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTP).build(), DomainInfo.builder().name("fourth-domain").scheme(SchemeType.MIXED).build() )) - .clientRegistrations(Sets.newHashSet( + .clientRegistrations(Lists.newArrayList( validClientRegistrationDto(), validClientRegistrationDto() )) .build(), OAuth2ClientsDomainParams.builder() - .domainInfos(Sets.newHashSet( + .domainInfos(Lists.newArrayList( DomainInfo.builder().name("second-domain").scheme(SchemeType.HTTPS).build(), DomainInfo.builder().name("fifth-domain").scheme(SchemeType.HTTP).build() )) - .clientRegistrations(Sets.newHashSet( + .clientRegistrations(Lists.newArrayList( validClientRegistrationDto() )) .build() @@ -466,14 +467,14 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { } private OAuth2ClientsParams createDefaultClientsParams() { - return new OAuth2ClientsParams(true, Sets.newHashSet( + return new OAuth2ClientsParams(true, Lists.newArrayList( OAuth2ClientsDomainParams.builder() - .domainInfos(Sets.newHashSet( + .domainInfos(Lists.newArrayList( DomainInfo.builder().name("first-domain").scheme(SchemeType.HTTP).build(), DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(), DomainInfo.builder().name("third-domain").scheme(SchemeType.HTTPS).build() )) - .clientRegistrations(Sets.newHashSet( + .clientRegistrations(Lists.newArrayList( validClientRegistrationDto(), validClientRegistrationDto(), validClientRegistrationDto(), @@ -481,11 +482,11 @@ public class BaseOAuth2ServiceTest extends AbstractServiceTest { )) .build(), OAuth2ClientsDomainParams.builder() - .domainInfos(Sets.newHashSet( + .domainInfos(Lists.newArrayList( DomainInfo.builder().name("second-domain").scheme(SchemeType.MIXED).build(), DomainInfo.builder().name("fourth-domain").scheme(SchemeType.MIXED).build() )) - .clientRegistrations(Sets.newHashSet( + .clientRegistrations(Lists.newArrayList( validClientRegistrationDto(), validClientRegistrationDto() )) diff --git a/ui-ngx/src/app/core/http/oauth2.service.ts b/ui-ngx/src/app/core/http/oauth2.service.ts index a8f890223d..2eff9fa339 100644 --- a/ui-ngx/src/app/core/http/oauth2.service.ts +++ b/ui-ngx/src/app/core/http/oauth2.service.ts @@ -41,4 +41,8 @@ export class OAuth2Service { return this.http.post('/api/oauth2/config', OAuth2Setting, defaultHttpOptionsFromConfig(config)); } + + public getLoginProcessingUrl(config?: RequestConfig): Observable { + return this.http.get(`/api/oauth2/loginProcessingUrl`, defaultHttpOptionsFromConfig(config)); + } } diff --git a/ui-ngx/src/app/core/services/menu.service.ts b/ui-ngx/src/app/core/services/menu.service.ts index e44c3c6ec2..4e98f375c2 100644 --- a/ui-ngx/src/app/core/services/menu.service.ts +++ b/ui-ngx/src/app/core/services/menu.service.ts @@ -191,6 +191,11 @@ export class MenuService { name: 'admin.security-settings', icon: 'security', path: '/settings/security-settings' + }, + { + name: 'admin.oauth2.oauth2', + icon: 'security', + path: '/settings/oauth2' } ] } diff --git a/ui-ngx/src/app/modules/home/components/alarm/alarm-details-dialog.component.html b/ui-ngx/src/app/modules/home/components/alarm/alarm-details-dialog.component.html index 47c9ef8645..64d40df581 100644 --- a/ui-ngx/src/app/modules/home/components/alarm/alarm-details-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/alarm/alarm-details-dialog.component.html @@ -88,14 +88,20 @@
-
+ + +
@@ -109,12 +115,5 @@ {{ 'alarm.clear' | translate }}
- -
diff --git a/ui-ngx/src/app/modules/home/components/alias/entity-alias-dialog.component.html b/ui-ngx/src/app/modules/home/components/alias/entity-alias-dialog.component.html index b7f0ff21fc..bb89ff479e 100644 --- a/ui-ngx/src/app/modules/home/components/alias/entity-alias-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/alias/entity-alias-dialog.component.html @@ -59,16 +59,16 @@
- +
diff --git a/ui-ngx/src/app/modules/home/components/alias/entity-aliases-dialog.component.html b/ui-ngx/src/app/modules/home/components/alias/entity-aliases-dialog.component.html index f817762f95..18f3e1a795 100644 --- a/ui-ngx/src/app/modules/home/components/alias/entity-aliases-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/alias/entity-aliases-dialog.component.html @@ -95,11 +95,6 @@ {{ 'alias.add' | translate }} - + diff --git a/ui-ngx/src/app/modules/home/components/attribute/add-attribute-dialog.component.html b/ui-ngx/src/app/modules/home/components/attribute/add-attribute-dialog.component.html index 072858455c..f815da49e7 100644 --- a/ui-ngx/src/app/modules/home/components/attribute/add-attribute-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/attribute/add-attribute-dialog.component.html @@ -44,16 +44,16 @@
- +
diff --git a/ui-ngx/src/app/modules/home/components/attribute/add-widget-to-dashboard-dialog.component.html b/ui-ngx/src/app/modules/home/components/attribute/add-widget-to-dashboard-dialog.component.html index 60fe5e30d7..4899a893e5 100644 --- a/ui-ngx/src/app/modules/home/components/attribute/add-widget-to-dashboard-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/attribute/add-widget-to-dashboard-dialog.component.html @@ -55,21 +55,22 @@ -
+
+ style="margin-bottom: 0;"> {{ 'dashboard.open-dashboard' | translate }} - + +
diff --git a/ui-ngx/src/app/modules/home/components/attribute/edit-attribute-value-panel.component.html b/ui-ngx/src/app/modules/home/components/attribute/edit-attribute-value-panel.component.html index 8e2264fae1..fe48694983 100644 --- a/ui-ngx/src/app/modules/home/components/attribute/edit-attribute-value-panel.component.html +++ b/ui-ngx/src/app/modules/home/components/attribute/edit-attribute-value-panel.component.html @@ -26,7 +26,6 @@
- +
diff --git a/ui-ngx/src/app/modules/home/components/event/event-content-dialog.component.html b/ui-ngx/src/app/modules/home/components/event/event-content-dialog.component.html index 29ee7364eb..e4ee790806 100644 --- a/ui-ngx/src/app/modules/home/components/event/event-content-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/event/event-content-dialog.component.html @@ -31,7 +31,6 @@
- +
diff --git a/ui-ngx/src/app/modules/home/components/filter/filter-dialog.component.html b/ui-ngx/src/app/modules/home/components/filter/filter-dialog.component.html index ab49dae445..717e8765de 100644 --- a/ui-ngx/src/app/modules/home/components/filter/filter-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/filter/filter-dialog.component.html @@ -55,16 +55,16 @@
- +
diff --git a/ui-ngx/src/app/modules/home/components/filter/filter-user-info-dialog.component.html b/ui-ngx/src/app/modules/home/components/filter/filter-user-info-dialog.component.html index a8d205479f..587504da45 100644 --- a/ui-ngx/src/app/modules/home/components/filter/filter-user-info-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/filter/filter-user-info-dialog.component.html @@ -46,12 +46,6 @@
- +
diff --git a/ui-ngx/src/app/modules/home/components/filter/filters-dialog.component.html b/ui-ngx/src/app/modules/home/components/filter/filters-dialog.component.html index 91bbc11425..c573267d2a 100644 --- a/ui-ngx/src/app/modules/home/components/filter/filters-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/filter/filters-dialog.component.html @@ -88,11 +88,6 @@ {{ 'filter.add' | translate }} - + diff --git a/ui-ngx/src/app/modules/home/components/filter/key-filter-dialog.component.html b/ui-ngx/src/app/modules/home/components/filter/key-filter-dialog.component.html index f601814920..5a9f8858c3 100644 --- a/ui-ngx/src/app/modules/home/components/filter/key-filter-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/filter/key-filter-dialog.component.html @@ -79,12 +79,6 @@
- +
diff --git a/ui-ngx/src/app/modules/home/components/filter/user-filter-dialog.component.html b/ui-ngx/src/app/modules/home/components/filter/user-filter-dialog.component.html index 2a0cf0be24..bf38483244 100644 --- a/ui-ngx/src/app/modules/home/components/filter/user-filter-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/filter/user-filter-dialog.component.html @@ -65,16 +65,16 @@
- +
diff --git a/ui-ngx/src/app/modules/home/components/import-export/import-dialog.component.html b/ui-ngx/src/app/modules/home/components/import-export/import-dialog.component.html index e53ff360ca..a8fe3a1f46 100644 --- a/ui-ngx/src/app/modules/home/components/import-export/import-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/import-export/import-dialog.component.html @@ -43,16 +43,16 @@
- +
diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-rule-condition-dialog.component.html b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-rule-condition-dialog.component.html index 7be952c68d..493763756b 100644 --- a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-rule-condition-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-rule-condition-dialog.component.html @@ -108,17 +108,17 @@
- +
diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule-dialog.component.html b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule-dialog.component.html index abe511fc3f..64a808fe98 100644 --- a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule-dialog.component.html @@ -37,17 +37,17 @@
- +
diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/create-alarm-rules.component.html b/ui-ngx/src/app/modules/home/components/profile/alarm/create-alarm-rules.component.html index 8eee1d980e..5c992d9e04 100644 --- a/ui-ngx/src/app/modules/home/components/profile/alarm/create-alarm-rules.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/alarm/create-alarm-rules.component.html @@ -47,9 +47,9 @@ remove_circle_outline -
+
device-profile.no-create-alarm-rules + class="tb-prompt required">device-profile.add-create-alarm-rule-prompt
- +
diff --git a/ui-ngx/src/app/modules/home/components/profile/device-profile.component.html b/ui-ngx/src/app/modules/home/components/profile/device-profile.component.html index 4fbc413d98..f74b19891e 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device-profile.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/device-profile.component.html @@ -41,7 +41,7 @@
-
+
device-profile.name diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant-profile-dialog.component.html b/ui-ngx/src/app/modules/home/components/profile/tenant-profile-dialog.component.html index 79bf7983a7..75f75906d0 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant-profile-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/tenant-profile-dialog.component.html @@ -15,7 +15,7 @@ limitations under the License. --> - +

{{ (isAdd ? 'tenant-profile.add' : 'tenant-profile.edit' ) | translate }}

@@ -37,11 +37,6 @@
- +
diff --git a/ui-ngx/src/app/modules/home/components/relation/relation-dialog.component.html b/ui-ngx/src/app/modules/home/components/relation/relation-dialog.component.html index 2d637c4066..f1d6790ae8 100644 --- a/ui-ngx/src/app/modules/home/components/relation/relation-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/relation/relation-dialog.component.html @@ -53,17 +53,16 @@
- +
diff --git a/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.html b/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.html index a61b3a80c6..46a0d213a4 100644 --- a/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.html @@ -147,16 +147,16 @@
- +
diff --git a/ui-ngx/src/app/modules/home/components/widget/data-key-config-dialog.component.html b/ui-ngx/src/app/modules/home/components/widget/data-key-config-dialog.component.html index d09b7aae24..8127b77e5d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/data-key-config-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/data-key-config-dialog.component.html @@ -38,16 +38,16 @@
- +
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/alarm-filter-panel.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/alarm-filter-panel.component.html index b150110fca..3a834621e6 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/alarm-filter-panel.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/alarm-filter-panel.component.html @@ -50,17 +50,16 @@
+ -
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/date-range-navigator/date-range-navigator-panel.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/date-range-navigator/date-range-navigator-panel.component.html index 2ee1222168..05aabbb7a7 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/date-range-navigator/date-range-navigator-panel.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/date-range-navigator/date-range-navigator-panel.component.html @@ -28,7 +28,6 @@
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/entities-table-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/entities-table-widget.component.ts index dae33f3cfe..b9791b5ae9 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/entities-table-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/entities-table-widget.component.ts @@ -352,7 +352,8 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni } dataKeys.push(dataKey); - dataKey.title = this.utils.customTranslation(dataKey.label, dataKey.label); + dataKey.label = this.utils.customTranslation(dataKey.label, dataKey.label); + dataKey.title = dataKey.label; dataKey.def = 'def' + this.columns.length; const keySettings: TableWidgetDataKeySettings = dataKey.settings; if (dataKey.type === DataKeyType.entityField && @@ -374,7 +375,7 @@ export class EntitiesTableWidgetComponent extends PageComponent implements OnIni } if (this.settings.defaultSortOrder && this.settings.defaultSortOrder.length) { - this.defaultSortOrder = this.settings.defaultSortOrder; + this.defaultSortOrder = this.utils.customTranslation(this.settings.defaultSortOrder, this.settings.defaultSortOrder); } this.pageLink.sortOrder = entityDataSortOrderFromString(this.defaultSortOrder, this.columns); diff --git a/ui-ngx/src/app/modules/home/dialogs/add-entities-to-customer-dialog.component.html b/ui-ngx/src/app/modules/home/dialogs/add-entities-to-customer-dialog.component.html index 0b33828bc4..2fcc346477 100644 --- a/ui-ngx/src/app/modules/home/dialogs/add-entities-to-customer-dialog.component.html +++ b/ui-ngx/src/app/modules/home/dialogs/add-entities-to-customer-dialog.component.html @@ -40,17 +40,17 @@
- +
diff --git a/ui-ngx/src/app/modules/home/dialogs/assign-to-customer-dialog.component.html b/ui-ngx/src/app/modules/home/dialogs/assign-to-customer-dialog.component.html index 5c98c02fa1..18d71968fd 100644 --- a/ui-ngx/src/app/modules/home/dialogs/assign-to-customer-dialog.component.html +++ b/ui-ngx/src/app/modules/home/dialogs/assign-to-customer-dialog.component.html @@ -39,17 +39,17 @@
- +
diff --git a/ui-ngx/src/app/modules/home/pages/admin/admin-routing.module.ts b/ui-ngx/src/app/modules/home/pages/admin/admin-routing.module.ts index af7dc98e19..7fefbfb521 100644 --- a/ui-ngx/src/app/modules/home/pages/admin/admin-routing.module.ts +++ b/ui-ngx/src/app/modules/home/pages/admin/admin-routing.module.ts @@ -14,8 +14,8 @@ /// limitations under the License. /// -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; +import { Injectable, NgModule } from '@angular/core'; +import { Resolve, RouterModule, Routes } from '@angular/router'; import { MailServerComponent } from '@modules/home/pages/admin/mail-server.component'; import { ConfirmOnExitGuard } from '@core/guards/confirm-on-exit.guard'; @@ -23,6 +23,25 @@ import { Authority } from '@shared/models/authority.enum'; import { GeneralSettingsComponent } from '@modules/home/pages/admin/general-settings.component'; import { SecuritySettingsComponent } from '@modules/home/pages/admin/security-settings.component'; import { OAuth2SettingsComponent } from '@home/pages/admin/oauth2-settings.component'; +import { User } from '@shared/models/user.model'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { UserService } from '@core/http/user.service'; +import { Observable } from 'rxjs'; +import { getCurrentAuthUser } from '@core/auth/auth.selectors'; +import { OAuth2Service } from '@core/http/oauth2.service'; +import { UserProfileResolver } from '@home/pages/profile/profile-routing.module'; + +@Injectable() +export class OAuth2LoginProcessingUrlResolver implements Resolve { + + constructor(private oauth2Service: OAuth2Service) { + } + + resolve(): Observable { + return this.oauth2Service.getLoginProcessingUrl(); + } +} const routes: Routes = [ { @@ -90,6 +109,9 @@ const routes: Routes = [ label: 'admin.oauth2.oauth2', icon: 'security' } + }, + resolve: { + loginProcessingUrl: OAuth2LoginProcessingUrlResolver } } ] @@ -98,6 +120,9 @@ const routes: Routes = [ @NgModule({ imports: [RouterModule.forChild(routes)], - exports: [RouterModule] + exports: [RouterModule], + providers: [ + OAuth2LoginProcessingUrlResolver + ] }) export class AdminRoutingModule { } diff --git a/ui-ngx/src/app/modules/home/pages/admin/oauth2-settings.component.ts b/ui-ngx/src/app/modules/home/pages/admin/oauth2-settings.component.ts index 58cbe536d7..37ae0433d3 100644 --- a/ui-ngx/src/app/modules/home/pages/admin/oauth2-settings.component.ts +++ b/ui-ngx/src/app/modules/home/pages/admin/oauth2-settings.component.ts @@ -43,6 +43,7 @@ import { DialogService } from '@core/services/dialog.service'; import { TranslateService } from '@ngx-translate/core'; import { isDefined, isDefinedAndNotNull } from '@core/utils'; import { OAuth2Service } from '@core/http/oauth2.service'; +import { ActivatedRoute } from '@angular/router'; @Component({ selector: 'tb-oauth2-settings', @@ -87,7 +88,10 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha templateProvider = ['Custom']; + private loginProcessingUrl: string = this.route.snapshot.data.loginProcessingUrl; + constructor(protected store: Store, + private route: ActivatedRoute, private oauth2Service: OAuth2Service, private fb: FormBuilder, private dialogService: DialogService, @@ -130,7 +134,7 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha return this.oauth2SettingsForm.get('domainsParams') as FormArray; } - private formBasicGroup(mapperConfigBasic?: MapperConfigBasic): FormGroup { + private formBasicGroup(type: MapperConfigType, mapperConfigBasic?: MapperConfigBasic): FormGroup { let tenantNamePattern; if (mapperConfigBasic?.tenantNamePattern) { tenantNamePattern = mapperConfigBasic.tenantNamePattern; @@ -138,16 +142,20 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha tenantNamePattern = {value: null, disabled: true}; } const basicGroup = this.fb.group({ - emailAttributeKey: [mapperConfigBasic?.emailAttributeKey ? mapperConfigBasic.emailAttributeKey : 'email', Validators.required], firstNameAttributeKey: [mapperConfigBasic?.firstNameAttributeKey ? mapperConfigBasic.firstNameAttributeKey : ''], lastNameAttributeKey: [mapperConfigBasic?.lastNameAttributeKey ? mapperConfigBasic.lastNameAttributeKey : ''], tenantNameStrategy: [mapperConfigBasic?.tenantNameStrategy ? mapperConfigBasic.tenantNameStrategy : TenantNameStrategy.DOMAIN], tenantNamePattern: [tenantNamePattern, Validators.required], customerNamePattern: [mapperConfigBasic?.customerNamePattern ? mapperConfigBasic.customerNamePattern : null], defaultDashboardName: [mapperConfigBasic?.defaultDashboardName ? mapperConfigBasic.defaultDashboardName : null], - alwaysFullScreen: [mapperConfigBasic?.alwaysFullScreen ? mapperConfigBasic.alwaysFullScreen : false] + alwaysFullScreen: [isDefinedAndNotNull(mapperConfigBasic?.alwaysFullScreen) ? mapperConfigBasic.alwaysFullScreen : false] }); + if (MapperConfigType.GITHUB !== type) { + basicGroup.addControl('emailAttributeKey', + this.fb.control( mapperConfigBasic?.emailAttributeKey ? mapperConfigBasic.emailAttributeKey : 'email', Validators.required)); + } + this.subscriptions.push(basicGroup.get('tenantNameStrategy').valueChanges.subscribe((domain) => { if (domain === 'CUSTOM') { basicGroup.get('tenantNamePattern').enable(); @@ -279,9 +287,12 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha clientRegistration?.userNameAttributeName ? clientRegistration.userNameAttributeName : 'email', Validators.required], mapperConfig: this.fb.group({ allowUserCreation: [ - clientRegistration?.mapperConfig?.allowUserCreation ? clientRegistration.mapperConfig.allowUserCreation : true + isDefinedAndNotNull(clientRegistration?.mapperConfig?.allowUserCreation) ? + clientRegistration.mapperConfig.allowUserCreation : true + ], + activateUser: [ + isDefinedAndNotNull(clientRegistration?.mapperConfig?.activateUser) ? clientRegistration.mapperConfig.activateUser : false ], - activateUser: [clientRegistration?.mapperConfig?.activateUser ? clientRegistration.mapperConfig.activateUser : false], type: [ clientRegistration?.mapperConfig?.type ? clientRegistration.mapperConfig.type : MapperConfigType.BASIC, Validators.required ] @@ -308,7 +319,7 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha return clientRegistrationFormGroup; } - private validateScope (control: AbstractControl): ValidationErrors | null { + private validateScope(control: AbstractControl): ValidationErrors | null { const scope: string[] = control.value; if (!scope || !scope.length) { return { @@ -347,7 +358,11 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha mapperConfig.addControl('custom', this.formCustomGroup(predefinedValue?.custom)); } else { mapperConfig.removeControl('custom'); - mapperConfig.addControl('basic', this.formBasicGroup(predefinedValue?.basic)); + if (mapperConfig.get('basic')) { + mapperConfig.setControl('basic', this.formBasicGroup(type, predefinedValue?.basic)); + } else { + mapperConfig.addControl('basic', this.formBasicGroup(type, predefinedValue?.basic)); + } } } @@ -490,7 +505,7 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha } else { protocol = domainInfo.scheme === DomainSchema.MIXED ? DomainSchema.HTTPS.toLowerCase() : domainInfo.scheme.toLowerCase(); } - return `${protocol}://${domainInfo.name}/login/oauth2/code/`; + return `${protocol}://${domainInfo.name}${this.loginProcessingUrl}`; } return ''; } diff --git a/ui-ngx/src/app/modules/home/pages/dashboard/add-widget-dialog.component.html b/ui-ngx/src/app/modules/home/pages/dashboard/add-widget-dialog.component.html index 614c63d980..fb0d17e73a 100644 --- a/ui-ngx/src/app/modules/home/pages/dashboard/add-widget-dialog.component.html +++ b/ui-ngx/src/app/modules/home/pages/dashboard/add-widget-dialog.component.html @@ -41,11 +41,6 @@
- +
diff --git a/ui-ngx/src/app/modules/home/pages/dashboard/dashboard-settings-dialog.component.html b/ui-ngx/src/app/modules/home/pages/dashboard/dashboard-settings-dialog.component.html index 082ff62633..80d5412226 100644 --- a/ui-ngx/src/app/modules/home/pages/dashboard/dashboard-settings-dialog.component.html +++ b/ui-ngx/src/app/modules/home/pages/dashboard/dashboard-settings-dialog.component.html @@ -152,17 +152,17 @@
- +
diff --git a/ui-ngx/src/app/modules/home/pages/dashboard/layout/manage-dashboard-layouts-dialog.component.html b/ui-ngx/src/app/modules/home/pages/dashboard/layout/manage-dashboard-layouts-dialog.component.html index 8c539a8cb8..0014fcb0cb 100644 --- a/ui-ngx/src/app/modules/home/pages/dashboard/layout/manage-dashboard-layouts-dialog.component.html +++ b/ui-ngx/src/app/modules/home/pages/dashboard/layout/manage-dashboard-layouts-dialog.component.html @@ -54,11 +54,6 @@
- +
diff --git a/ui-ngx/src/app/modules/home/pages/dashboard/make-dashboard-public-dialog.component.html b/ui-ngx/src/app/modules/home/pages/dashboard/make-dashboard-public-dialog.component.html index 0a20f6a48e..3097e0e303 100644 --- a/ui-ngx/src/app/modules/home/pages/dashboard/make-dashboard-public-dialog.component.html +++ b/ui-ngx/src/app/modules/home/pages/dashboard/make-dashboard-public-dialog.component.html @@ -54,7 +54,6 @@
- +
diff --git a/ui-ngx/src/app/modules/home/pages/dashboard/states/dashboard-state-dialog.component.html b/ui-ngx/src/app/modules/home/pages/dashboard/states/dashboard-state-dialog.component.html index cc27d98d9a..52788ca0e8 100644 --- a/ui-ngx/src/app/modules/home/pages/dashboard/states/dashboard-state-dialog.component.html +++ b/ui-ngx/src/app/modules/home/pages/dashboard/states/dashboard-state-dialog.component.html @@ -52,16 +52,16 @@
- +
diff --git a/ui-ngx/src/app/modules/home/pages/dashboard/states/manage-dashboard-states-dialog.component.html b/ui-ngx/src/app/modules/home/pages/dashboard/states/manage-dashboard-states-dialog.component.html index d75b4f41c3..7f4f486278 100644 --- a/ui-ngx/src/app/modules/home/pages/dashboard/states/manage-dashboard-states-dialog.component.html +++ b/ui-ngx/src/app/modules/home/pages/dashboard/states/manage-dashboard-states-dialog.component.html @@ -136,16 +136,16 @@
- +
diff --git a/ui-ngx/src/app/modules/home/pages/device-profile/device-profile-tabs.component.html b/ui-ngx/src/app/modules/home/pages/device-profile/device-profile-tabs.component.html index d927e5222c..a803d35b1d 100644 --- a/ui-ngx/src/app/modules/home/pages/device-profile/device-profile-tabs.component.html +++ b/ui-ngx/src/app/modules/home/pages/device-profile/device-profile-tabs.component.html @@ -70,7 +70,7 @@ - diff --git a/ui-ngx/src/app/modules/home/pages/device/device-credentials-dialog.component.html b/ui-ngx/src/app/modules/home/pages/device/device-credentials-dialog.component.html index 0c99fd7040..2936b60911 100644 --- a/ui-ngx/src/app/modules/home/pages/device/device-credentials-dialog.component.html +++ b/ui-ngx/src/app/modules/home/pages/device/device-credentials-dialog.component.html @@ -36,17 +36,17 @@
- +
diff --git a/ui-ngx/src/app/modules/home/pages/profile/change-password-dialog.component.html b/ui-ngx/src/app/modules/home/pages/profile/change-password-dialog.component.html index 9cd30ab768..926c4d7bcc 100644 --- a/ui-ngx/src/app/modules/home/pages/profile/change-password-dialog.component.html +++ b/ui-ngx/src/app/modules/home/pages/profile/change-password-dialog.component.html @@ -46,16 +46,16 @@
- +
diff --git a/ui-ngx/src/app/modules/home/pages/rulechain/add-rule-node-dialog.component.html b/ui-ngx/src/app/modules/home/pages/rulechain/add-rule-node-dialog.component.html index e8df333ecd..75ccbb764e 100644 --- a/ui-ngx/src/app/modules/home/pages/rulechain/add-rule-node-dialog.component.html +++ b/ui-ngx/src/app/modules/home/pages/rulechain/add-rule-node-dialog.component.html @@ -40,16 +40,16 @@
- +
diff --git a/ui-ngx/src/app/modules/home/pages/rulechain/add-rule-node-link-dialog.component.html b/ui-ngx/src/app/modules/home/pages/rulechain/add-rule-node-link-dialog.component.html index 3016ab6d70..12de2706f5 100644 --- a/ui-ngx/src/app/modules/home/pages/rulechain/add-rule-node-link-dialog.component.html +++ b/ui-ngx/src/app/modules/home/pages/rulechain/add-rule-node-link-dialog.component.html @@ -39,16 +39,16 @@
- +
diff --git a/ui-ngx/src/app/modules/home/pages/user/add-user-dialog.component.html b/ui-ngx/src/app/modules/home/pages/user/add-user-dialog.component.html index 52ac55275c..a66a3ab995 100644 --- a/ui-ngx/src/app/modules/home/pages/user/add-user-dialog.component.html +++ b/ui-ngx/src/app/modules/home/pages/user/add-user-dialog.component.html @@ -41,11 +41,6 @@
- +
diff --git a/ui-ngx/src/app/modules/home/pages/widget/save-widget-type-as-dialog.component.html b/ui-ngx/src/app/modules/home/pages/widget/save-widget-type-as-dialog.component.html index 8af9a379d9..0ae1e24a07 100644 --- a/ui-ngx/src/app/modules/home/pages/widget/save-widget-type-as-dialog.component.html +++ b/ui-ngx/src/app/modules/home/pages/widget/save-widget-type-as-dialog.component.html @@ -46,17 +46,17 @@
- +
diff --git a/ui-ngx/src/app/shared/components/dialog/color-picker-dialog.component.html b/ui-ngx/src/app/shared/components/dialog/color-picker-dialog.component.html index 8e1b64381d..4de07b1f80 100644 --- a/ui-ngx/src/app/shared/components/dialog/color-picker-dialog.component.html +++ b/ui-ngx/src/app/shared/components/dialog/color-picker-dialog.component.html @@ -34,7 +34,6 @@ diff --git a/ui-ngx/src/app/shared/components/dialog/json-object-edit-dialog.component.html b/ui-ngx/src/app/shared/components/dialog/json-object-edit-dialog.component.html index 8dc4f5b1d2..9d5ee6c6ef 100644 --- a/ui-ngx/src/app/shared/components/dialog/json-object-edit-dialog.component.html +++ b/ui-ngx/src/app/shared/components/dialog/json-object-edit-dialog.component.html @@ -41,17 +41,16 @@
- +
diff --git a/ui-ngx/src/app/shared/components/dialog/node-script-test-dialog.component.html b/ui-ngx/src/app/shared/components/dialog/node-script-test-dialog.component.html index 698ecb75ae..365445ed02 100644 --- a/ui-ngx/src/app/shared/components/dialog/node-script-test-dialog.component.html +++ b/ui-ngx/src/app/shared/components/dialog/node-script-test-dialog.component.html @@ -109,18 +109,17 @@ {{ 'rulenode.test' | translate }} - + diff --git a/ui-ngx/src/app/shared/components/time/timewindow-panel.component.html b/ui-ngx/src/app/shared/components/time/timewindow-panel.component.html index c462c150c0..398d5dd9d1 100644 --- a/ui-ngx/src/app/shared/components/time/timewindow-panel.component.html +++ b/ui-ngx/src/app/shared/components/time/timewindow-panel.component.html @@ -140,19 +140,18 @@
+ -
diff --git a/ui-ngx/src/app/shared/models/device.models.ts b/ui-ngx/src/app/shared/models/device.models.ts index 9e92defa45..f6850dbc57 100644 --- a/ui-ngx/src/app/shared/models/device.models.ts +++ b/ui-ngx/src/app/shared/models/device.models.ts @@ -26,7 +26,7 @@ import { EntityInfoData } from '@shared/models/entity.models'; import { KeyFilter } from '@shared/models/query/query.models'; import { TimeUnit } from '@shared/models/time/time.models'; import * as _moment from 'moment-timezone'; -import { AbstractControl, FormGroup } from '@angular/forms'; +import { AbstractControl, FormGroup, ValidationErrors } from '@angular/forms'; export enum DeviceProfileType { DEFAULT = 'DEFAULT' @@ -87,7 +87,7 @@ export const deviceProvisionTypeTranslationMap = new Map( [ @@ -303,6 +303,18 @@ export interface AlarmRule { schedule?: AlarmSchedule; } +export function alarmRuleValidator(control: AbstractControl): ValidationErrors | null { + const alarmRule: AlarmRule = control.value; + return alarmRuleValid(alarmRule) ? null : {alarmRule: true}; +} + +function alarmRuleValid(alarmRule: AlarmRule): boolean { + if (!alarmRule || !alarmRule.condition || !alarmRule.condition.condition || !alarmRule.condition.condition.length) { + return false; + } + return true; +} + export interface DeviceProfileAlarm { id: string; alarmType: string; @@ -312,6 +324,34 @@ export interface DeviceProfileAlarm { propagateRelationTypes?: Array; } +export function deviceProfileAlarmValidator(control: AbstractControl): ValidationErrors | null { + const deviceProfileAlarm: DeviceProfileAlarm = control.value; + if (deviceProfileAlarm && deviceProfileAlarm.id && deviceProfileAlarm.alarmType && + deviceProfileAlarm.createRules) { + const severities = Object.keys(deviceProfileAlarm.createRules); + if (severities.length) { + let alarmRulesValid = true; + for (const severity of severities) { + const alarmRule = deviceProfileAlarm.createRules[severity]; + if (!alarmRuleValid(alarmRule)) { + alarmRulesValid = false; + break; + } + } + if (alarmRulesValid) { + if (deviceProfileAlarm.clearRule && !alarmRuleValid(deviceProfileAlarm.clearRule)) { + alarmRulesValid = false; + } + } + if (alarmRulesValid) { + return null; + } + } + } + return {deviceProfileAlarm: true}; +} + + export interface DeviceProfileData { configuration: DeviceProfileConfiguration; transportConfiguration: DeviceProfileTransportConfiguration; diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index b5b34f8fe5..453d5d2abd 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -908,6 +908,7 @@ "create-alarm-pattern": "Create {{alarmType}} alarm", "create-alarm-rules": "Create alarm rules", "no-create-alarm-rules": "No create conditions configured", + "add-create-alarm-rule-prompt": "Please add create alarm rule", "clear-alarm-rule": "Clear alarm rule", "no-clear-alarm-rule": "No clear condition configured", "add-create-alarm-rule": "Add create condition", diff --git a/ui-ngx/src/styles.scss b/ui-ngx/src/styles.scss index ac717e783e..190fbb1ba7 100644 --- a/ui-ngx/src/styles.scss +++ b/ui-ngx/src/styles.scss @@ -331,6 +331,9 @@ pre.tb-highlight { font-weight: 400; line-height: 18px; color: rgba(0, 0, 0, .38); + &.required { + color: rgb(221, 44, 0); + } } .tb-fullscreen {