diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetDaoImpl.java index 1be6557ae..2bf712760 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetDaoImpl.java @@ -58,8 +58,11 @@ public class DatasetDaoImpl extends DatabaseAccess implements DatasetDa @Override public QueryableList getAuthenticated(QueryableList query, UserInfo principal) { - query.where((builder, root) -> builder.or(builder.equal(root.get("dmp").get("creator"), principal), builder.isMember(principal, root.get("dmp").get("users")) - , builder.equal(root.get("isPublic"), true))); + if (principal.getId() == null) query.where((builder, root) -> builder.equal(root.get("isPublic"), true)); + else { + query.where((builder, root) -> builder.or(builder.equal(root.get("dmp").get("creator"), principal), builder.isMember(principal, root.get("dmp").get("users")) + , builder.equal(root.get("isPublic"), true))); + } return query; } diff --git a/dmp-backend/logging/src/main/java/eu/eudat/core/logger/common/AbstractBatchLogger.java b/dmp-backend/logging/src/main/java/eu/eudat/core/logger/common/AbstractBatchLogger.java index e9938a5ff..baf14718a 100644 --- a/dmp-backend/logging/src/main/java/eu/eudat/core/logger/common/AbstractBatchLogger.java +++ b/dmp-backend/logging/src/main/java/eu/eudat/core/logger/common/AbstractBatchLogger.java @@ -19,9 +19,9 @@ public abstract class AbstractBatchLogger { private Map concurrentHashMap = new ConcurrentHashMap(); public AbstractBatchLogger(Environment environment) { - ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); + //ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); - executor.scheduleAtFixedRate(() -> this.outputData(), Long.parseLong(environment.getProperty("http-logger.initial-delay")), Long.parseLong(environment.getProperty("http-logger.delay")), TimeUnit.SECONDS); + //executor.scheduleAtFixedRate(() -> this.outputData(), Long.parseLong(environment.getProperty("http-logger.initial-delay")), Long.parseLong(environment.getProperty("http-logger.delay")), TimeUnit.SECONDS); } public abstract LoggingOutputType logOutputType(); diff --git a/dmp-backend/queryengine/src/main/java/Main.java b/dmp-backend/queryengine/src/main/java/Main.java index 1d2da52a3..00364e090 100644 --- a/dmp-backend/queryengine/src/main/java/Main.java +++ b/dmp-backend/queryengine/src/main/java/Main.java @@ -15,5 +15,9 @@ public class Main { queryBuilder.where((comparisonExpression) -> comparisonExpression.field("id").greaterThan(5) ); queryBuilder.where((comparisonExpression) -> comparisonExpression.field("label").equal("mitsos") ); queryBuilder.toList(); + + QueryBuilder queryBuilder2 = new QueryBuilderImpl<>(DataRepository.class); + queryBuilder2.where((comparisonExpression) -> comparisonExpression.field("id").lessOrEqualThan(11111) ); + queryBuilder2.toList(); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetWizardController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetWizardController.java index 3d111f234..9e2cfec16 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetWizardController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetWizardController.java @@ -1,17 +1,18 @@ package eu.eudat.controllers; -import eu.eudat.logic.utilities.documents.helpers.FileEnvelope; import eu.eudat.data.entities.Dataset; +import eu.eudat.data.query.items.item.dataset.DatasetWizardAutocompleteRequest; +import eu.eudat.data.query.items.item.datasetprofile.DatasetProfileWizardAutocompleteRequest; import eu.eudat.logic.managers.DatasetManager; import eu.eudat.logic.managers.DatasetWizardManager; +import eu.eudat.logic.security.claims.ClaimedAuthorities; +import eu.eudat.logic.services.ApiContext; +import eu.eudat.logic.utilities.documents.helpers.FileEnvelope; import eu.eudat.models.data.datasetwizard.DataManagentPlanListingModel; -import eu.eudat.data.query.items.item.datasetprofile.DatasetProfileWizardAutocompleteRequest; -import eu.eudat.data.query.items.item.dataset.DatasetWizardAutocompleteRequest; import eu.eudat.models.data.datasetwizard.DatasetWizardModel; import eu.eudat.models.data.dmp.AssociatedProfile; import eu.eudat.models.data.helpers.responses.ResponseItem; import eu.eudat.models.data.security.Principal; -import eu.eudat.logic.services.ApiContext; import eu.eudat.types.ApiMessageCode; import org.apache.poi.util.IOUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -30,6 +31,8 @@ import java.io.IOException; import java.io.InputStream; import java.util.List; +import static eu.eudat.types.Authorities.ANONYMOUS; + @RestController @CrossOrigin @@ -59,7 +62,7 @@ public class DatasetWizardController extends BaseController { @RequestMapping(method = RequestMethod.POST, value = {"/getAvailableProfiles"}, produces = "application/json") public @ResponseBody - ResponseEntity>> getAvailableProfiles(@RequestBody DatasetProfileWizardAutocompleteRequest datasetProfileWizardAutocompleteRequest, Principal principal) { + ResponseEntity>> getAvailableProfiles(@RequestBody DatasetProfileWizardAutocompleteRequest datasetProfileWizardAutocompleteRequest, @ClaimedAuthorities(claims = {ANONYMOUS}) Principal principal) { try { List dataManagementPlans = DatasetWizardManager.getAvailableProfiles(this.getApiContext().getOperationsContext().getDatabaseRepository().getDmpDao(), datasetProfileWizardAutocompleteRequest); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dataManagementPlans)); @@ -72,10 +75,10 @@ public class DatasetWizardController extends BaseController { @RequestMapping(method = RequestMethod.GET, value = {"/getSingle/{id}"}, produces = "application/json") public @ResponseBody - ResponseEntity> getSingle(@PathVariable String id, Principal principal) { + ResponseEntity> getSingle(@PathVariable String id, @ClaimedAuthorities(claims = {ANONYMOUS}) Principal principal) { try { - DatasetWizardModel dataset = new DatasetManager().getSingle(this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetDao(),this.getApiContext().getOperationsContext().getDatasetRepository() - ,id); + DatasetWizardModel dataset = new DatasetManager().getSingle(this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetDao(), this.getApiContext().getOperationsContext().getDatasetRepository() + , id); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataset)); } catch (Exception ex) { ex.printStackTrace(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java index 589a488f8..fe57b22f4 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java @@ -1,14 +1,16 @@ package eu.eudat.controllers; import eu.eudat.data.entities.Dataset; -import eu.eudat.logic.managers.DatasetManager; import eu.eudat.data.query.items.table.dataset.DatasetTableRequest; +import eu.eudat.logic.managers.DatasetManager; +import eu.eudat.logic.security.claims.ClaimedAuthorities; +import eu.eudat.logic.services.ApiContext; import eu.eudat.models.data.helpers.common.DataTableData; import eu.eudat.models.data.helpers.responses.ResponseItem; import eu.eudat.models.data.listingmodels.DatasetListingModel; import eu.eudat.models.data.security.Principal; -import eu.eudat.logic.services.ApiContext; import eu.eudat.types.ApiMessageCode; +import eu.eudat.types.Authorities; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -31,7 +33,7 @@ public class Datasets extends BaseController { @RequestMapping(method = RequestMethod.POST, value = {"/datasets/getPaged"}, consumes = "application/json", produces = "application/json") public @ResponseBody - ResponseEntity>> getPaged(@RequestBody DatasetTableRequest datasetTableRequest, Principal principal) { + ResponseEntity>> getPaged(@RequestBody DatasetTableRequest datasetTableRequest, @ClaimedAuthorities(claims = {Authorities.ANONYMOUS}) Principal principal) { try { DataTableData dataTable = new DatasetManager().getPaged(this.getApiContext(), datasetTableRequest, principal); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dataTable)); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Users.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Users.java index 36c84eac6..06803b7fa 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Users.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Users.java @@ -1,13 +1,13 @@ package eu.eudat.controllers; +import eu.eudat.data.query.items.table.userinfo.UserInfoTableRequestItem; import eu.eudat.logic.managers.UserManager; +import eu.eudat.logic.security.claims.ClaimedAuthorities; +import eu.eudat.logic.services.ApiContext; import eu.eudat.models.data.helpers.common.DataTableData; import eu.eudat.models.data.helpers.responses.ResponseItem; import eu.eudat.models.data.security.Principal; -import eu.eudat.data.query.items.table.userinfo.UserInfoTableRequestItem; import eu.eudat.models.data.userinfo.UserListingModel; -import eu.eudat.logic.security.claims.ClaimedAuthorities; -import eu.eudat.logic.services.ApiContext; import eu.eudat.models.data.userinfo.UserProfile; import eu.eudat.types.ApiMessageCode; import org.springframework.beans.factory.annotation.Autowired; @@ -17,7 +17,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; - +import java.util.Map; import java.util.UUID; import static eu.eudat.types.Authorities.ADMIN; @@ -70,6 +70,19 @@ public class Users extends BaseController { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.DEFAULT_ERROR_MESSAGE).message(ex.getMessage())); } } + + @Transactional + @RequestMapping(method = RequestMethod.POST, value = {"/settings"}, produces = "application/json") + public @ResponseBody + ResponseEntity> saveSettings(@RequestBody Map settings, Principal principal) { + try { + UserManager.updateSettings(this.getApiContext(), settings, principal); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE)); + } catch (Exception ex) { + ex.printStackTrace(); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.DEFAULT_ERROR_MESSAGE).message(ex.getMessage())); + } + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/builders/model/models/PrincipalBuilder.java b/dmp-backend/web/src/main/java/eu/eudat/logic/builders/model/models/PrincipalBuilder.java index 12bc35b6b..133d5e179 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/builders/model/models/PrincipalBuilder.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/builders/model/models/PrincipalBuilder.java @@ -19,6 +19,9 @@ public class PrincipalBuilder extends Builder { private Date expiresAt; private String avatarUrl; private Set authorities; + private String culture; + private String language; + private String timezone; public PrincipalBuilder id(UUID id) { this.id = id; @@ -50,6 +53,21 @@ public class PrincipalBuilder extends Builder { return this; } + public PrincipalBuilder culture(String culture) { + this.culture = culture; + return this; + } + + public PrincipalBuilder language(String language) { + this.language = language; + return this; + } + + public PrincipalBuilder timezone(String timezone) { + this.timezone = timezone; + return this; + } + @Override public Principal build() { Principal principal = new Principal(); @@ -59,6 +77,9 @@ public class PrincipalBuilder extends Builder { principal.setToken(token); principal.setId(id); principal.setAvatarUrl(avatarUrl); + principal.setCulture(culture); + principal.setLanguage(language); + principal.setTimezone(timezone); return principal; } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/handlers/PrincipalArgumentResolver.java b/dmp-backend/web/src/main/java/eu/eudat/logic/handlers/PrincipalArgumentResolver.java index 47c2798e6..4ff940353 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/handlers/PrincipalArgumentResolver.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/handlers/PrincipalArgumentResolver.java @@ -32,7 +32,7 @@ public final class PrincipalArgumentResolver implements HandlerMethodArgumentRes String token = nativeWebRequest.getHeader("AuthToken"); Optional claimsAnnotation = Arrays.stream(methodParameter.getParameterAnnotations()).filter(annotation -> annotation.annotationType().equals(ClaimedAuthorities.class)).findAny(); List claimList = claimsAnnotation.map(annotation -> Arrays.asList(((ClaimedAuthorities) annotation).claims())).orElse(Authorities.all()); - if(claimList.size() == 0 && claimList.get(0).equals(Authorities.ANONYMOUS)) return new Principal(); + if(token == null && claimList.size() == 1 && claimList.get(0).equals(Authorities.ANONYMOUS)) return new Principal(); if (token == null) throw new UnauthorisedException("Authentication Information Is Missing"); UUID authToken; try { @@ -43,7 +43,7 @@ public final class PrincipalArgumentResolver implements HandlerMethodArgumentRes Principal principal = this.authenticationService.Touch(authToken); if (principal == null) throw new UnauthorisedException("Authentication Information Missing"); - if (!principal.isAuthorized(claimList)) + if (!claimList.contains(Authorities.ANONYMOUS) && !principal.isAuthorized(claimList)) throw new UnauthorisedException("You are not Authorized For this Action"); return principal; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java index be46cb222..27c0c06be 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java @@ -1,5 +1,6 @@ package eu.eudat.logic.managers; +import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.data.entities.DMP; import eu.eudat.data.entities.UserRole; import eu.eudat.data.query.items.table.userinfo.UserInfoTableRequestItem; @@ -16,10 +17,14 @@ import eu.eudat.models.data.security.Principal; import eu.eudat.models.data.userinfo.UserListingModel; import eu.eudat.models.data.userinfo.UserProfile; import eu.eudat.queryable.QueryableList; +import org.json.JSONObject; import org.w3c.dom.Document; import org.w3c.dom.Element; +import java.io.IOException; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.UUID; import java.util.stream.Collectors; @@ -60,6 +65,17 @@ public class UserManager { } } + public static void updateSettings(ApiContext apiContext, Map settings, Principal principal) throws IOException { + eu.eudat.data.entities.UserInfo userInfo = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId()); + apiContext.getOperationsContext().getDatabaseRepository().detachEntity(userInfo); + HashMap result = + new ObjectMapper().readValue(userInfo.getAdditionalinfo(), HashMap.class); + result.putAll(settings); + userInfo.setAdditionalinfo(new JSONObject(result).toString()); + apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao() + .createOrUpdate(userInfo); + } + public static Principal authenticate(AuthenticationServiceImpl authenticationServiceImpl, Credentials credentials) { Principal principal = authenticationServiceImpl.Touch(credentials); if (principal == null) throw new UnauthorisedException("Could not Sign In User"); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/TokenValidatorFactoryImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/TokenValidatorFactoryImpl.java index 080c27977..d145da466 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/TokenValidatorFactoryImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/TokenValidatorFactoryImpl.java @@ -1,11 +1,16 @@ package eu.eudat.logic.security.validators; +import eu.eudat.logic.security.customproviders.B2AccessCustomProvider; import eu.eudat.logic.security.validators.b2access.B2AccessTokenValidator; import eu.eudat.logic.security.validators.facebook.FacebookTokenValidator; import eu.eudat.logic.security.validators.google.GoogleTokenValidator; import eu.eudat.logic.security.validators.linkedin.LinkedInTokenValidator; import eu.eudat.logic.security.validators.twitter.TwitterTokenValidator; +import eu.eudat.logic.services.ApiContext; +import eu.eudat.logic.services.operations.AuthenticationService; +import eu.eudat.logic.services.operations.AuthenticationServiceImpl; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; @@ -44,34 +49,31 @@ public class TokenValidatorFactoryImpl implements TokenValidatorFactory { } } - private GoogleTokenValidator googleTokenValidator; - private FacebookTokenValidator facebookTokenValidator; - private LinkedInTokenValidator linkedInTokenValidator; - private TwitterTokenValidator twitterTokenValidator; - private B2AccessTokenValidator b2AccessTokenValidator; + private ApiContext apiContext; + private Environment environment; + private AuthenticationServiceImpl authenticationService; + private B2AccessCustomProvider b2AccessCustomProvider; @Autowired - public TokenValidatorFactoryImpl(GoogleTokenValidator googleTokenValidator, FacebookTokenValidator facebookTokenValidator, - LinkedInTokenValidator linkedInTokenValidator, TwitterTokenValidator twitterTokenValidator, B2AccessTokenValidator b2AccessTokenValidator) { - this.googleTokenValidator = googleTokenValidator; - this.facebookTokenValidator = facebookTokenValidator; - this.linkedInTokenValidator = linkedInTokenValidator; - this.twitterTokenValidator = twitterTokenValidator; - this.b2AccessTokenValidator = b2AccessTokenValidator; + public TokenValidatorFactoryImpl(ApiContext apiContext, Environment environment, AuthenticationServiceImpl authenticationService, B2AccessCustomProvider b2AccessCustomProvider) { + this.apiContext = apiContext; + this.environment = environment; + this.authenticationService = authenticationService; + this.b2AccessCustomProvider = b2AccessCustomProvider; } public TokenValidator getProvider(LoginProvider provider) { switch (provider) { case GOOGLE: - return this.googleTokenValidator; + return new GoogleTokenValidator(this.apiContext, this.environment, this.authenticationService); case FACEBOOK: - return this.facebookTokenValidator; + return new FacebookTokenValidator(this.apiContext, this.environment, this.authenticationService); case LINKEDIN: - return this.linkedInTokenValidator; + return new LinkedInTokenValidator(this.apiContext, this.environment, this.authenticationService); case TWITTER: - return this.twitterTokenValidator; + return new TwitterTokenValidator(this.apiContext, this.environment, this.authenticationService); case B2_ACCESS: - return this.b2AccessTokenValidator; + return new B2AccessTokenValidator(this.environment, this.authenticationService, this.b2AccessCustomProvider); default: throw new RuntimeException("Login Provider Not Implemented"); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/b2access/B2AccessTokenValidator.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/b2access/B2AccessTokenValidator.java index f6b28fd0c..f11b53728 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/b2access/B2AccessTokenValidator.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/b2access/B2AccessTokenValidator.java @@ -28,7 +28,7 @@ public class B2AccessTokenValidator implements TokenValidator { private Environment environment; @Autowired - public B2AccessTokenValidator(AuthenticationServiceImpl authenticationServiceImpl, Environment environment, B2AccessCustomProvider b2AccessCustomProvider) { + public B2AccessTokenValidator(Environment environment, AuthenticationServiceImpl authenticationServiceImpl, B2AccessCustomProvider b2AccessCustomProvider) { this.authenticationServiceImpl = authenticationServiceImpl; this.environment = environment; this.b2AccessCustomProvider = b2AccessCustomProvider; diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/facebook/FacebookTokenValidator.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/facebook/FacebookTokenValidator.java index adc93ef3e..ae3a733ce 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/facebook/FacebookTokenValidator.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/facebook/FacebookTokenValidator.java @@ -31,7 +31,7 @@ public class FacebookTokenValidator implements TokenValidator { private FacebookServiceProvider facebookServiceProvider; @Autowired - public FacebookTokenValidator(Environment environment, ApiContext apiContext, AuthenticationServiceImpl authenticationServiceImpl) { + public FacebookTokenValidator(ApiContext apiContext, Environment environment, AuthenticationServiceImpl authenticationServiceImpl) { this.environment = environment; this.apiContext = apiContext; this.authenticationServiceImpl = authenticationServiceImpl; diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/linkedin/LinkedInTokenValidator.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/linkedin/LinkedInTokenValidator.java index 16f4ae071..b31cb532e 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/linkedin/LinkedInTokenValidator.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/linkedin/LinkedInTokenValidator.java @@ -2,13 +2,13 @@ package eu.eudat.logic.security.validators.linkedin; import eu.eudat.exceptions.security.NonValidTokenException; import eu.eudat.exceptions.security.UnauthorisedException; -import eu.eudat.models.data.login.LoginInfo; -import eu.eudat.models.data.loginprovider.LoginProviderUser; -import eu.eudat.models.data.security.Principal; import eu.eudat.logic.security.validators.TokenValidator; import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.operations.AuthenticationServiceImpl; +import eu.eudat.models.data.login.LoginInfo; +import eu.eudat.models.data.loginprovider.LoginProviderUser; +import eu.eudat.models.data.security.Principal; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.social.linkedin.api.LinkedIn; @@ -30,7 +30,7 @@ public class LinkedInTokenValidator implements TokenValidator { private LinkedInServiceProvider linkedInServiceProvider; @Autowired - public LinkedInTokenValidator(Environment environment, ApiContext apiContext, AuthenticationServiceImpl authenticationServiceImpl) { + public LinkedInTokenValidator(ApiContext apiContext, Environment environment, AuthenticationServiceImpl authenticationServiceImpl) { this.environment = environment; this.apiContext = apiContext; this.authenticationServiceImpl = authenticationServiceImpl; diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/twitter/TwitterTokenValidator.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/twitter/TwitterTokenValidator.java index 70849f2ca..989a5dcc6 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/twitter/TwitterTokenValidator.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/twitter/TwitterTokenValidator.java @@ -2,13 +2,13 @@ package eu.eudat.logic.security.validators.twitter; import eu.eudat.exceptions.security.NonValidTokenException; import eu.eudat.exceptions.security.UnauthorisedException; -import eu.eudat.models.data.login.LoginInfo; -import eu.eudat.models.data.loginprovider.LoginProviderUser; -import eu.eudat.models.data.security.Principal; import eu.eudat.logic.security.validators.TokenValidator; import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.operations.AuthenticationServiceImpl; +import eu.eudat.models.data.login.LoginInfo; +import eu.eudat.models.data.loginprovider.LoginProviderUser; +import eu.eudat.models.data.security.Principal; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.social.oauth1.AuthorizedRequestToken; @@ -32,7 +32,7 @@ public class TwitterTokenValidator implements TokenValidator { private TwitterServiceProvider twitterServiceProvider; @Autowired - public TwitterTokenValidator(Environment environment, ApiContext apiContext, AuthenticationServiceImpl authenticationServiceImpl) { + public TwitterTokenValidator(ApiContext apiContext, Environment environment, AuthenticationServiceImpl authenticationServiceImpl) { this.environment = environment; this.apiContext = apiContext; this.authenticationServiceImpl = authenticationServiceImpl; @@ -55,7 +55,7 @@ public class TwitterTokenValidator implements TokenValidator { user.setEmail((String) values.get("email")); user.setAvatarUrl(profile.getProfileImageUrl()); user.setIsVerified(true); //TODO - user.setId(""+profile.getId()); + user.setId("" + profile.getId()); user.setName(profile.getName()); user.setProvider(TokenValidatorFactoryImpl.LoginProvider.TWITTER); user.setSecret(finalOauthToken.getValue()); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/AuthenticationServiceImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/AuthenticationServiceImpl.java index f591e72ff..2ae675891 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/AuthenticationServiceImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/AuthenticationServiceImpl.java @@ -1,21 +1,22 @@ package eu.eudat.logic.services.operations; import com.fasterxml.jackson.databind.ObjectMapper; -import eu.eudat.logic.builders.entity.CredentialBuilder; -import eu.eudat.logic.builders.entity.UserInfoBuilder; -import eu.eudat.logic.builders.entity.UserTokenBuilder; -import eu.eudat.logic.builders.model.models.PrincipalBuilder; import eu.eudat.data.dao.criteria.UserInfoCriteria; import eu.eudat.data.entities.Credential; import eu.eudat.data.entities.UserInfo; import eu.eudat.data.entities.UserRole; import eu.eudat.data.entities.UserToken; +import eu.eudat.logic.builders.entity.CredentialBuilder; +import eu.eudat.logic.builders.entity.UserInfoBuilder; +import eu.eudat.logic.builders.entity.UserTokenBuilder; +import eu.eudat.logic.builders.model.models.PrincipalBuilder; +import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl; +import eu.eudat.logic.services.ApiContext; import eu.eudat.models.data.login.Credentials; import eu.eudat.models.data.loginprovider.LoginProviderUser; import eu.eudat.models.data.security.Principal; -import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl; -import eu.eudat.logic.services.ApiContext; import eu.eudat.types.Authorities; +import org.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; @@ -53,17 +54,39 @@ public class AuthenticationServiceImpl implements AuthenticationService { UserInfo user = this.apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(token.getUser().getId()); if (user == null) return null; - String json; + String avatarUrl; try { - json = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("data").get("avatar").get("url").asText() : ""; - } catch (IOException e) { - json = ""; + avatarUrl = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("avatarUrl").asText() : ""; + } catch (Exception e) { + avatarUrl = ""; + } + String culture; + try { + culture = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("culture").get("name").asText() : ""; + } catch (Exception e) { + culture = ""; + } + String language; + try { + language = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("language").get("value").asText() : ""; + } catch (Exception e) { + language = ""; + } + String timezone; + try { + timezone = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("timezone").asText() : ""; + } catch (Exception e) { + timezone = ""; } Principal principal = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(PrincipalBuilder.class) .id(user.getId()).token(token.getToken()) .expiresAt(token.getExpiresAt()).name(user.getName()) - .avatarUrl(json) + .avatarUrl(avatarUrl) + .culture(culture) + .language(language) + .timezone(timezone) .build(); + List userRoles = apiContext.getOperationsContext().getDatabaseRepository().getUserRoleDao().getUserRoles(user); for (UserRole item : userRoles) { if (principal.getAuthz() == null) principal.setAuthorities(new HashSet<>()); @@ -120,7 +143,7 @@ public class AuthenticationServiceImpl implements AuthenticationService { userInfo = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserInfoBuilder.class) .name(profile.getName()).verified_email(profile.getIsVerified()) .email(profile.getEmail()).created(new Date()).lastloggedin(new Date()) - .additionalinfo("{\"data\":{\"avatar\":{\"url\":\""+profile.getAvatarUrl()+"\"}}}") + .additionalinfo("{\"data\":{\"avatar\":{\"url\":\"" + profile.getAvatarUrl() + "\"}}}") .authorization_level((short) 1).usertype((short) 1) .build(); @@ -135,8 +158,11 @@ public class AuthenticationServiceImpl implements AuthenticationService { apiContext.getOperationsContext().getDatabaseRepository().getUserRoleDao().createOrUpdate(role); } else { + Map additionalInfo = userInfo.getAdditionalinfo() != null ? + new JSONObject(userInfo.getAdditionalinfo()).toMap() : new HashMap<>(); + additionalInfo.put("avatarUrl", profile.getAvatarUrl()); userInfo.setLastloggedin(new Date()); - userInfo.setAdditionalinfo("{\"data\":{\"avatar\":{\"url\":\""+profile.getAvatarUrl()+"\"}}}"); + userInfo.setAdditionalinfo(new JSONObject(additionalInfo).toString()); Set credentials = userInfo.getCredentials(); if (credentials.contains(credential)) { Credential oldCredential = credentials.stream().filter(item -> credential.getProvider().equals(item.getProvider())).findFirst().get(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java index 6cd4470ff..ee0b24cee 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java @@ -45,4 +45,6 @@ public interface DatabaseRepository { DatasetExternalDatasetDao getDatasetExternalDatasetDao(); DatasetServiceDao getDatasetServiceDao(); + + void detachEntity(T entity); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java index 8fe94d43d..44ac7c426 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java @@ -239,4 +239,8 @@ public class DatabaseRepositoryImpl implements DatabaseRepository { public void setDatasetServiceDao(DatasetServiceDao datasetServiceDao) { this.datasetServiceDao = datasetServiceDao; } + + public void detachEntity(T entity) { + this.entityManager.detach(entity); + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/OperationsContextImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/OperationsContextImpl.java index bd1ffd04c..47894d017 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/OperationsContextImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/OperationsContextImpl.java @@ -23,7 +23,7 @@ public class OperationsContextImpl implements OperationsContext { @Autowired public OperationsContextImpl(DatabaseRepository databaseRepository, ApplicationContext applicationContext, RemoteFetcher remoteFetcher - , BuilderFactory builderFactory, FileStorageService fileStorageService,DatasetRepository datasetRepository) { + , BuilderFactory builderFactory, FileStorageService fileStorageService, DatasetRepository datasetRepository) { this.databaseRepository = databaseRepository; this.applicationContext = applicationContext; this.remoteFetcher = remoteFetcher; diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/InvitationService.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/InvitationService.java index 336987267..968da7850 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/InvitationService.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/InvitationService.java @@ -6,6 +6,7 @@ import eu.eudat.data.dao.entities.InvitationDao; import eu.eudat.data.entities.DMP; import eu.eudat.data.entities.Invitation; +import javax.mail.MessagingException; import java.util.List; @@ -14,7 +15,7 @@ public interface InvitationService { void assignToDmp(DMPDao dmpDao, eu.eudat.data.entities.UserInfo user, DMP dmp); - void createInvitations(InvitationDao invitationDao, MailService mailService, List users, DMP dmp, eu.eudat.data.entities.UserInfo creator); + void createInvitations(InvitationDao invitationDao, MailService mailService, List users, DMP dmp, eu.eudat.data.entities.UserInfo creator) throws MessagingException; - void sendInvitation(DMP dmp, Invitation invitation, MailService mailService); + void sendInvitation(DMP dmp, Invitation invitation, String recipient, MailService mailService) throws MessagingException; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/InvitationServiceImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/InvitationServiceImpl.java index 601978a28..6bc055b95 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/InvitationServiceImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/InvitationServiceImpl.java @@ -7,6 +7,7 @@ import eu.eudat.data.entities.Invitation; import eu.eudat.models.data.mail.SimpleMail; import org.springframework.stereotype.Service; +import javax.mail.MessagingException; import java.util.List; import java.util.UUID; @@ -28,7 +29,7 @@ public class InvitationServiceImpl implements InvitationService { } @Override - public void createInvitations(InvitationDao invitationDao, MailService mailService, List users, DMP dmp, eu.eudat.data.entities.UserInfo creator) { + public void createInvitations(InvitationDao invitationDao, MailService mailService, List users, DMP dmp, eu.eudat.data.entities.UserInfo creator) throws MessagingException { for (eu.eudat.data.entities.UserInfo userInfo : users) { Invitation invitation = new Invitation(); invitation.setDmp(dmp); @@ -37,15 +38,15 @@ public class InvitationServiceImpl implements InvitationService { invitation.setToken(UUID.randomUUID()); invitation.setAcceptedInvitation(false); invitationDao.createOrUpdate(invitation); - sendInvitation(dmp, invitation, mailService); + sendInvitation(dmp, invitation, userInfo.getName(), mailService); } } @Override - public void sendInvitation(DMP dmp, Invitation invitation, MailService mailService) { + public void sendInvitation(DMP dmp, Invitation invitation, String recipient, MailService mailService) throws MessagingException { SimpleMail mail = new SimpleMail(); mail.setSubject(createSubject(dmp, mailService.getMailTemplateSubject())); - mail.setContent(createContent(invitation.getId(), dmp, mailService.getMailTemplateContent())); + mail.setContent(createContent(invitation.getId(), dmp, recipient, mailService.getMailTemplateContent())); mail.setTo(invitation.getInvitationEmail()); mailService.sendSimpleMail(mail); } @@ -55,9 +56,11 @@ public class InvitationServiceImpl implements InvitationService { return subject; } - private String createContent(UUID invitationID, DMP dmp, String templateContent) { + private String createContent(UUID invitationID, DMP dmp, String recipient, String templateContent) { String content = templateContent.replace("{dmpname}", dmp.getLabel()); content = content.replace("{invitationID}", invitationID.toString()); + content = content.replace("{recipient}", recipient); + return content; } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/MailService.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/MailService.java index c2fd28558..84ec2d3ec 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/MailService.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/MailService.java @@ -2,9 +2,11 @@ package eu.eudat.logic.services.utilities; import eu.eudat.models.data.mail.SimpleMail; +import javax.mail.MessagingException; + public interface MailService { - void sendSimpleMail(SimpleMail mail); + void sendSimpleMail(SimpleMail mail) throws MessagingException; String getMailTemplateContent(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/MailServiceImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/MailServiceImpl.java index 5340ec671..6fa552ad8 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/MailServiceImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/MailServiceImpl.java @@ -1,27 +1,42 @@ package eu.eudat.logic.services.utilities; import eu.eudat.models.data.mail.SimpleMail; +import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; import org.springframework.core.env.Environment; -import org.springframework.mail.SimpleMailMessage; +import org.springframework.core.io.Resource; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.stereotype.Service; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.internet.MimeMessage; +import java.io.*; + @Service("mailService") public class MailServiceImpl implements MailService { - @Autowired + private Environment env; - @Autowired private JavaMailSender emailSender; + private ApplicationContext applicationContext; + + @Autowired + public MailServiceImpl(Environment env, JavaMailSender emailSender, ApplicationContext applicationContext) { + this.env = env; + this.emailSender = emailSender; + this.applicationContext = applicationContext; + } + @Override - public void sendSimpleMail(SimpleMail mail) { - SimpleMailMessage message = new SimpleMailMessage(); + public void sendSimpleMail(SimpleMail mail) throws MessagingException { + MimeMessage message = this.emailSender.createMimeMessage(); message.setSubject(mail.getSubject()); - message.setText(mail.getContent()); - message.setTo(mail.getTo()); + message.setText(mail.getContent(), "utf-8", "html"); + message.addRecipients(Message.RecipientType.TO, mail.getTo()); message.setFrom(env.getProperty("mail.from")); this.emailSender.send(message); } @@ -31,8 +46,17 @@ public class MailServiceImpl implements MailService { } @Override - public String getMailTemplateContent() { - return env.getProperty("mail.content"); + public String getMailTemplateContent() { + Resource resource = applicationContext.getResource("classpath:email.html"); + try { + InputStream inputStream = resource.getInputStream(); + StringWriter writer = new StringWriter(); + IOUtils.copy(inputStream, writer, "UTF-8"); + return writer.toString(); + } catch (IOException e) { + e.printStackTrace(); + } + return ""; } @Override diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/security/Principal.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/security/Principal.java index 55674294b..5399b5466 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/security/Principal.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/security/Principal.java @@ -14,6 +14,9 @@ public class Principal { private Date expiresAt; private String avatarUrl; private Set authorities; + private String culture; + private String language; + private String timezone; public UUID getId() { return id; @@ -59,6 +62,30 @@ public class Principal { return authorities.stream().map(authz -> authz.getValue()).collect(Collectors.toSet()); } + public String getCulture() { + return culture; + } + + public void setCulture(String culture) { + this.culture = culture; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public String getTimezone() { + return timezone; + } + + public void setTimezone(String timezone) { + this.timezone = timezone; + } + @JsonIgnore public Set getAuthz() { return this.authorities; diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/validators/fluentvalidator/FluentValidator.java b/dmp-backend/web/src/main/java/eu/eudat/models/validators/fluentvalidator/FluentValidator.java new file mode 100644 index 000000000..f10c376c8 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/validators/fluentvalidator/FluentValidator.java @@ -0,0 +1,28 @@ +package eu.eudat.models.validators.fluentvalidator; + +import eu.eudat.models.validators.fluentvalidator.predicates.FieldSelector; +import org.springframework.validation.Errors; +import org.springframework.validation.Validator; + +/** + * Created by ikalyvas on 8/28/2018. + */ +public class FluentValidator implements Validator { + + private T item; + + public void ruleFor(FieldSelector selector) { + selector.apply(this.item); + } + + @Override + public boolean supports(Class clazz) { + return this.item.getClass().equals(clazz); + } + + @Override + public void validate(Object target, Errors errors) { + this.item = (T) target; + + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/validators/fluentvalidator/predicates/FieldSelector.java b/dmp-backend/web/src/main/java/eu/eudat/models/validators/fluentvalidator/predicates/FieldSelector.java new file mode 100644 index 000000000..66d743f2b --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/validators/fluentvalidator/predicates/FieldSelector.java @@ -0,0 +1,8 @@ +package eu.eudat.models.validators.fluentvalidator.predicates; + +/** + * Created by ikalyvas on 8/28/2018. + */ +public interface FieldSelector { + R apply(T item); +} diff --git a/dmp-backend/web/src/main/resources/application.properties b/dmp-backend/web/src/main/resources/application.properties index 100a05014..ed1996337 100644 --- a/dmp-backend/web/src/main/resources/application.properties +++ b/dmp-backend/web/src/main/resources/application.properties @@ -30,7 +30,7 @@ spring.mail.test-connection=false spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.starttls.enable=true mail.subject=Invitation to DMP Plan {dmpname} -mail.content=You have been invited to {dmpname} data management plan.Follow the link http://dl043.madgik.di.uoa.gr/invitation/{invitationID} to submit it +mail.content=You have been invited to {dmpname} data management plan.Follow the link http://dl043.madgik.di.uoa.gr/dmps/invitation/{invitationID} to submit it mail.from=citesagrdev@gmail.com ########################FACEBOOK LOGIN Properties############################# facebook.login.clientId=110586756143149 diff --git a/dmp-backend/web/src/main/resources/email.html b/dmp-backend/web/src/main/resources/email.html new file mode 100644 index 000000000..069f78218 --- /dev/null +++ b/dmp-backend/web/src/main/resources/email.html @@ -0,0 +1,305 @@ + + + + + + Simple Transactional Email + + + + + + + + + +
  +
+ + + This is preheader text. Some clients will show this text as a preview. + + + + + + + + +
+ + + + +
+

Dear {recipient},

+

You have been invited to collaborate to Data Management plan {dmpname}.

+

Click the button to redirect to {dmpname}.

+ + + + + + + +
+ + + + + + +
Join
+
+ +
+
+ + + + + + +
+
 
+ + \ No newline at end of file diff --git a/dmp-frontend/package-lock.json b/dmp-frontend/package-lock.json index 63f69444f..cf9b2b988 100644 --- a/dmp-frontend/package-lock.json +++ b/dmp-frontend/package-lock.json @@ -587,9 +587,26 @@ "dev": true }, "@angular/material": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@angular/material/-/material-6.1.0.tgz", - "integrity": "sha512-9FLWjVnHFzAoGSWU5dz8X/QYeBtZGijMJIp1k94QDYz+2xA10IbesEgnv8I5Ri3EPnjV/gCspeSkt1ClLc95CA==", + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-6.4.6.tgz", + "integrity": "sha512-SUSg9MhLv4IZj6Nh8qoCLDImZugCQ+Jvvt+/cDIaTn6TrT6ZenDHc6jOhbGFesU6FuBDBFIXMiuBPD9kBr7vaA==", + "requires": { + "parse5": "^5.0.0", + "tslib": "^1.7.1" + }, + "dependencies": { + "parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", + "optional": true + } + } + }, + "@angular/material-moment-adapter": { + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/@angular/material-moment-adapter/-/material-moment-adapter-6.4.6.tgz", + "integrity": "sha512-Bvj/zwtEjF1bqOF1z/M0VcWYOwlRjmCBjvPVmNZ1Bxf7HE8yyRf8B+AAv46sn/EhhAv/eMNU9bzFcxrR/vEHAg==", "requires": { "tslib": "^1.7.1" } @@ -716,9 +733,9 @@ "dev": true }, "@types/selenium-webdriver": { - "version": "2.53.43", - "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-2.53.43.tgz", - "integrity": "sha512-UBYHWph6P3tutkbXpW6XYg9ZPbTKjw/YC2hGG1/GEvWwTbvezBUv3h+mmUFw79T3RFPnmedpiXdOBbXX+4l0jg==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.10.tgz", + "integrity": "sha512-ikB0JHv6vCR1KYUQAzTO4gi/lXLElT4Tx+6De2pc/OZwizE9LRNiTa+U8TBFKBD/nntPnr/MPSHSnOTybjhqNA==", "dev": true }, "@types/strip-bom": { @@ -1027,9 +1044,9 @@ "optional": true }, "adm-zip": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.4.tgz", - "integrity": "sha1-ph7VrmkFw66lizplfSUDMJEFJzY=", + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.11.tgz", + "integrity": "sha512-L8vcjDTCOIJk7wFvmlEUN7AsSb8T+2JrdP7KINBjzr24TJ5Mwj590sLu3BC7zNZowvJWa/JtPmD8eJCzdtDWjA==", "dev": true }, "after": { @@ -1953,6 +1970,15 @@ "electron-to-chromium": "^1.3.47" } }, + "browserstack": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.5.1.tgz", + "integrity": "sha512-O8VMT64P9NOLhuIoD4YngyxBURefaSdR4QdhG8l6HZ9VxtU7jc3m6jLufFwKA5gaf7fetfB2TnRJnMxyob+heg==", + "dev": true, + "requires": { + "https-proxy-agent": "^2.2.1" + } + }, "buffer": { "version": "4.9.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", @@ -4065,8 +4091,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -4087,14 +4112,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4109,20 +4132,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -4239,8 +4259,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -4252,7 +4271,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -4267,7 +4285,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -4275,14 +4292,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -4301,7 +4316,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -4382,8 +4396,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -4395,7 +4408,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -4481,8 +4493,7 @@ "safe-buffer": { "version": "5.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -4518,7 +4529,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -4538,7 +4548,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -4582,14 +4591,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, @@ -7903,6 +7910,19 @@ "minimist": "0.0.8" } }, + "moment": { + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", + "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=" + }, + "moment-timezone": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.21.tgz", + "integrity": "sha512-j96bAh4otsgj3lKydm3K7kdtA3iKf2m6MY2iSYCzCm5a1zmHo1g+aK3068dDEeocLZQIS9kU8bsdQHLqEvgW0A==", + "requires": { + "moment": ">= 2.9.0" + } + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -8597,12 +8617,6 @@ } } }, - "options": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", - "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=", - "dev": true - }, "original": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/original/-/original-1.0.1.tgz", @@ -9147,15 +9161,16 @@ } }, "protractor": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/protractor/-/protractor-5.3.2.tgz", - "integrity": "sha512-pw4uwwiy5lHZjIguxNpkEwJJa7hVz+bJsvaTI+IbXlfn2qXwzbF8eghW/RmrZwE2sGx82I8etb8lVjQ+JrjejA==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/protractor/-/protractor-5.4.0.tgz", + "integrity": "sha512-6TSYqMhUUzxr4/wN0ttSISqPMKvcVRXF4k8jOEpGWD8OioLak4KLgfzHK9FJ49IrjzRrZ+Mx1q2Op8Rk0zEcnQ==", "dev": true, "requires": { "@types/node": "^6.0.46", "@types/q": "^0.0.32", - "@types/selenium-webdriver": "~2.53.39", + "@types/selenium-webdriver": "^3.0.0", "blocking-proxy": "^1.0.0", + "browserstack": "^1.5.1", "chalk": "^1.1.3", "glob": "^7.0.3", "jasmine": "2.8.0", @@ -9165,15 +9180,21 @@ "saucelabs": "^1.5.0", "selenium-webdriver": "3.6.0", "source-map-support": "~0.4.0", - "webdriver-js-extender": "^1.0.0", + "webdriver-js-extender": "2.0.0", "webdriver-manager": "^12.0.6" }, "dependencies": { - "adm-zip": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.11.tgz", - "integrity": "sha512-L8vcjDTCOIJk7wFvmlEUN7AsSb8T+2JrdP7KINBjzr24TJ5Mwj590sLu3BC7zNZowvJWa/JtPmD8eJCzdtDWjA==", - "dev": true + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "dev": true, + "requires": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } }, "ansi-styles": { "version": "2.2.1", @@ -9181,6 +9202,24 @@ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true + }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", @@ -9209,6 +9248,23 @@ "rimraf": "^2.2.8" } }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "form-data": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", + "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "1.0.6", + "mime-types": "^2.1.12" + } + }, "globby": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", @@ -9223,38 +9279,148 @@ "pinkie-promise": "^2.0.0" } }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", + "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", + "dev": true, + "requires": { + "ajv": "^5.3.0", + "har-schema": "^2.0.0" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "mime-db": { + "version": "1.36.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz", + "integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw==", + "dev": true + }, + "mime-types": { + "version": "2.1.20", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz", + "integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==", + "dev": true, + "requires": { + "mime-db": "~1.36.0" + } + }, "minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true }, - "webdriver-manager": { - "version": "12.0.6", - "resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.0.6.tgz", - "integrity": "sha1-PfGkgZdwELTL+MnYXHpXeCjA5ws=", + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", "dev": true, "requires": { - "adm-zip": "^0.4.7", + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "webdriver-manager": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.1.0.tgz", + "integrity": "sha512-oEc5fmkpz6Yh6udhwir5m0eN5mgRPq9P/NU5YWuT3Up5slt6Zz+znhLU7q4+8rwCZz/Qq3Fgpr/4oao7NPCm2A==", + "dev": true, + "requires": { + "adm-zip": "^0.4.9", "chalk": "^1.1.1", "del": "^2.2.0", "glob": "^7.0.3", "ini": "^1.3.4", "minimist": "^1.2.0", "q": "^1.4.1", - "request": "^2.78.0", + "request": "^2.87.0", "rimraf": "^2.5.2", "semver": "^5.3.0", "xml2js": "^0.4.17" @@ -9320,6 +9486,12 @@ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, + "psl": { + "version": "1.1.29", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", + "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==", + "dev": true + }, "public-encrypt": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz", @@ -12170,66 +12342,13 @@ } }, "webdriver-js-extender": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-1.0.0.tgz", - "integrity": "sha1-gcUzqeM9W/tZe05j4s2yW1R3dRU=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-2.0.0.tgz", + "integrity": "sha512-fbyKiVu3azzIc5d4+26YfuPQcFTlgFQV5yQ/0OQj4Ybkl4g1YQuIPskf5v5wqwRJhHJnPHthB6tqCjWHOKLWag==", "dev": true, "requires": { - "@types/selenium-webdriver": "^2.53.35", - "selenium-webdriver": "^2.53.2" - }, - "dependencies": { - "sax": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-0.6.1.tgz", - "integrity": "sha1-VjsZx8HeiS4Jv8Ty/DDjwn8JUrk=", - "dev": true - }, - "selenium-webdriver": { - "version": "2.53.3", - "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-2.53.3.tgz", - "integrity": "sha1-0p/1qVff8aG0ncRXdW5OS/vc4IU=", - "dev": true, - "requires": { - "adm-zip": "0.4.4", - "rimraf": "^2.2.8", - "tmp": "0.0.24", - "ws": "^1.0.1", - "xml2js": "0.4.4" - } - }, - "tmp": { - "version": "0.0.24", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.24.tgz", - "integrity": "sha1-1qXhmNFKmDXMby18PZ4wJCjIzxI=", - "dev": true - }, - "ultron": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", - "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=", - "dev": true - }, - "ws": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", - "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", - "dev": true, - "requires": { - "options": ">=0.0.5", - "ultron": "1.0.x" - } - }, - "xml2js": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.4.tgz", - "integrity": "sha1-MREBAAMAiuGSQOuhdJe1fHKcVV0=", - "dev": true, - "requires": { - "sax": "0.6.x", - "xmlbuilder": ">=1.0.0" - } - } + "@types/selenium-webdriver": "^3.0.0", + "selenium-webdriver": "^3.0.1" } }, "webpack": { diff --git a/dmp-frontend/package.json b/dmp-frontend/package.json index 86fbe7dea..df10047e6 100644 --- a/dmp-frontend/package.json +++ b/dmp-frontend/package.json @@ -20,7 +20,8 @@ "@angular/flex-layout": "6.0.0-beta.16", "@angular/forms": "6.0.7", "@angular/http": "6.0.7", - "@angular/material": "6.1.0", + "@angular/material": "6.4.6", + "@angular/material-moment-adapter": "6.4.6", "@angular/platform-browser": "6.0.7", "@angular/platform-browser-dynamic": "6.0.7", "@angular/router": "6.0.7", @@ -32,6 +33,8 @@ "bootstrap": "^4.1.2", "core-js": "^2.4.1", "file-saver": "1.3.3", + "moment": "^2.22.2", + "moment-timezone": "^0.5.21", "rxjs": "^6.2.1", "rxjs-compat": "^6.1.0", "zone.js": "^0.8.26" @@ -51,7 +54,7 @@ "karma-coverage-istanbul-reporter": "^1.2.1", "karma-jasmine": "~1.1.0", "karma-jasmine-html-reporter": "^0.2.2", - "protractor": "^5.3.2", + "protractor": "5.4.0", "ts-node": "~4.1.0", "tslint": "~5.9.1", "typescript": "2.7.2", diff --git a/dmp-frontend/src/app/app-routing.module.ts b/dmp-frontend/src/app/app-routing.module.ts index a767b1eb3..ed97b22db 100644 --- a/dmp-frontend/src/app/app-routing.module.ts +++ b/dmp-frontend/src/app/app-routing.module.ts @@ -12,7 +12,7 @@ const appRoutes: Routes = [ data: { breadcrumb: true }, - canActivate: [AuthGuard] + //canActivate: [AuthGuard] }, { path: 'about', diff --git a/dmp-frontend/src/app/app.component.ts b/dmp-frontend/src/app/app.component.ts index c5ed6a64a..f67d2bb2c 100644 --- a/dmp-frontend/src/app/app.component.ts +++ b/dmp-frontend/src/app/app.component.ts @@ -5,6 +5,8 @@ import { LanguageResolverService } from './services/language-resolver/language-r import { BreadCrumbResolverService } from './services/breadcrumb/breadcrumb-resolver.service'; import { Observable } from 'rxjs/Observable'; import { AuthService } from './services/auth/auth.service'; +import { CultureService } from './utilities/culture/culture-service'; +import { environment } from '../environments/environment'; declare const gapi: any; @@ -28,12 +30,10 @@ export class AppComponent implements OnInit { private authentication: AuthService, private translate: TranslateService, private languageService: LanguageResolverService, - private breadCrumbResolverService: BreadCrumbResolverService + private breadCrumbResolverService: BreadCrumbResolverService, + private cultureService: CultureService ) { - // this language will be used as a fallback when a translation isn't found in the current language - translate.setDefaultLang('en'); - // the lang to use, if the lang isn't available, it will use the current loader to get them - translate.use('en'); + this.initializeServices() } onActivate(event: any) { @@ -73,5 +73,14 @@ export class AppComponent implements OnInit { goToProjects() { this.router.navigate(['/projects'], { queryParams: { /*refresh : Math.random() ,returnUrl: this.state.url*/ } }); } + + initializeServices() { + // this language will be used as a fallback when a translation isn't found in the current language + this.translate.setDefaultLang('en'); + + this.cultureService.cultureSelected(environment.defaultCulture); + + //this.setupChangeListeners(); + } } diff --git a/dmp-frontend/src/app/app.module.ts b/dmp-frontend/src/app/app.module.ts index 0b6ac0021..e01fcfabf 100644 --- a/dmp-frontend/src/app/app.module.ts +++ b/dmp-frontend/src/app/app.module.ts @@ -21,7 +21,7 @@ import { BrowserModule } from '@angular/platform-browser'; import { HomepageComponent } from './homepage/homepage.component'; import { PageNotFoundComponent } from './not-found.component'; import { AppComponent } from './app.component'; -import { NgModule } from '@angular/core'; +import { NgModule, LOCALE_ID } from '@angular/core'; import { WelcomepageComponent } from './welcomepage/welcomepage.component'; import { HelpContentService } from './services/help-content/help-content.service'; import { B2AccessLoginComponent } from './user-management/login/b2access/b2access-login.component'; @@ -32,6 +32,8 @@ import { HelpContentComponent, AsideHelpContentComponent } from './shared/help-c import { AuthGuard } from './shared/guards/auth.guard'; import { UrlUtilities } from './utilities/UrlUtilities'; import { BreadCrumbResolverService } from './services/breadcrumb/breadcrumb-resolver.service'; +import { MAT_DATE_LOCALE } from '@angular/material'; +import { CultureService } from './utilities/culture/culture-service'; @NgModule({ declarations: [ @@ -103,7 +105,18 @@ import { BreadCrumbResolverService } from './services/breadcrumb/breadcrumb-reso HelpContentService, LanguageService, LanguageResolverService, - BreadCrumbResolverService + BreadCrumbResolverService, + CultureService, + { + provide: MAT_DATE_LOCALE, + deps: [CultureService], + useFactory: (cultureService) => cultureService.getCurrentCulture().name + }, + { + provide: LOCALE_ID, + deps: [CultureService], + useFactory: (cultureService) => cultureService.getCurrentCulture().name + }, ], bootstrap: [AppComponent] }) diff --git a/dmp-frontend/src/app/datasets/dataset-public/dataset-public-listing.component.html b/dmp-frontend/src/app/datasets/dataset-public/dataset-public-listing.component.html new file mode 100644 index 000000000..5cabc997f --- /dev/null +++ b/dmp-frontend/src/app/datasets/dataset-public/dataset-public-listing.component.html @@ -0,0 +1,84 @@ +
+

{{'DATASET-LISTING.TITLE' | translate}} {{titlePrefix}}

+ + + + + + + + + + + + {{'DATASET-LISTING.COLUMNS.NAME' | translate}} + {{row.label}} + + + + + {{'DATASET-LISTING.COLUMNS.DMP' | translate}} + {{row.dmp}} + + + + + {{'DATASET-LISTING.COLUMNS.PROFILE' | translate}} + {{row.profile}} + + + + + {{'DATASET-LISTING.COLUMNS.STATUS' | translate}} + {{row.status}} + + + + + + + + + + + + + + + + + {{'DATASET-LISTING.COLUMNS.DESCRIPTION' | translate}} + {{row.description}} + + + + + {{'DATASET-LISTING.COLUMNS.CREATED' | translate}} + {{row.created | date:'shortDate'}} + + + + + + + + + + + + + +
diff --git a/dmp-frontend/src/app/datasets/dataset-public/dataset-public-listing.component.scss b/dmp-frontend/src/app/datasets/dataset-public/dataset-public-listing.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/dmp-frontend/src/app/datasets/dataset-public/dataset-public-listing.component.ts b/dmp-frontend/src/app/datasets/dataset-public/dataset-public-listing.component.ts new file mode 100644 index 000000000..eb7d5882b --- /dev/null +++ b/dmp-frontend/src/app/datasets/dataset-public/dataset-public-listing.component.ts @@ -0,0 +1,151 @@ +import { OnInit, Component, ViewChild } from "@angular/core"; +import { MatSort, MatPaginator, PageEvent, MatSnackBar } from "@angular/material"; +import { DatasetCriteriaComponent } from "../../shared/components/criteria/datasets/datasets-criteria.component"; +import { Observable } from "rxjs"; +import { BreadcrumbItem } from "../../shared/components/breadcrumb/definition/breadcrumb-item"; +import { DatasetService } from "../../services/dataset/dataset.service"; +import { Router, ActivatedRoute, Params } from "@angular/router"; +import { TranslateService } from "@ngx-translate/core"; +import { DataManagementPlanService } from "../../services/data-management-plan/data-management-plan.service"; +import { DatasetCriteria } from "../../models/criteria/dataset/DatasetCriteria"; +import { DataSource } from "@angular/cdk/table"; +import { DatasetListingModel } from "../../models/datasets/DatasetListingModel"; +import { DataTableRequest } from "../../models/data-table/DataTableRequest"; + + +@Component({ + selector: 'app-dataset-public-listing-component', + templateUrl: 'dataset-public-listing.component.html', + styleUrls: ['./dataset-public-listing.component.scss'], +}) +export class DatasetPublicListingComponent implements OnInit { + + + @ViewChild(MatPaginator) _paginator: MatPaginator; + @ViewChild(MatSort) sort: MatSort; + @ViewChild(DatasetCriteriaComponent) criteria: DatasetCriteriaComponent; + + dataSource: DatasetDataSource | null; + displayedColumns: String[] = ['label', 'dmp', 'profile', 'status', 'description', 'created']; + pageEvent: PageEvent; + titlePrefix: String; + dmpId: string; + + statuses = [ + { value: '0', viewValue: 'Active' }, + { value: '1', viewValue: 'Inactive' } + ]; + + constructor( + private datasetService: DatasetService, + private router: Router, + private languageService: TranslateService, + public snackBar: MatSnackBar, + public route: ActivatedRoute, + public dataManagementPlanService: DataManagementPlanService + ) { + + } + + + ngOnInit() { + + this.route.params.subscribe(async (params: Params) => { + this.dmpId = params['dmpId']; + this.criteria.setCriteria(this.getDefaultCriteria(this.dmpId)); + this.refresh(); + this.criteria.setRefreshCallback(() => this.refresh()); + if (this.dmpId != null) { + let dmp = await this.dataManagementPlanService.getSingle(this.dmpId).toPromise() + if (params['dmpLabel'] != undefined) + this.titlePrefix = "for " + params['dmpLabel']; + } + }); + } + + refresh() { + this.dataSource = new DatasetDataSource(this.datasetService, this._paginator, this.sort, this.languageService, this.snackBar, this.criteria, this.dmpId); + } + + rowClick(rowId: String) { + this.router.navigate(['/datasets/edit/' + rowId]); + } + + getDefaultCriteria(dmpId: String): DatasetCriteria { + const defaultCriteria = new DatasetCriteria(); + if (dmpId != null) { + defaultCriteria.dmpIds.push(dmpId); + } + return defaultCriteria; + } + + makeItPublic(id: String) { + this.datasetService.makeDatasetPublic(id).subscribe(); + } + +} + +export class DatasetDataSource extends DataSource { + + totalCount = 0; + isLoadingResults = false; + constructor( + private _service: DatasetService, + private _paginator: MatPaginator, + private _sort: MatSort, + private _languageService: TranslateService, + private _snackBar: MatSnackBar, + private _criteria: DatasetCriteriaComponent, + private dmpId: String + ) { + super(); + + } + + connect(): Observable { + const displayDataChanges = [ + this._paginator.page + //this._sort.matSortChange + ]; + + + return Observable.merge(...displayDataChanges) + .startWith(null) + .switchMap(() => { + setTimeout(() => { + this.isLoadingResults = true; + }); + const startIndex = this._paginator.pageIndex * this._paginator.pageSize; + let fields: Array = new Array() + if (this._sort.active) fields = this._sort.direction === "asc" ? ["+" + this._sort.active] : ["-" + this._sort.active]; + const request = new DataTableRequest(startIndex, this._paginator.pageSize, { fields: fields }); + request.criteria = this._criteria.criteria; + if (this.dmpId) request.criteria.allVersions = true; + return this._service.getPaged(request); + }) + /*.catch((error: any) => { + this._snackBar.openFromComponent(SnackBarNotificationComponent, { + data: { message: 'GENERAL.SNACK-BAR.FORMS-BAD-REQUEST', language: this._languageService }, + duration: 3000, + extraClasses: ['snackbar-warning'] + }); + //this._criteria.criteria.onCallbackError(error); + return Observable.of(null); + })*/ + .map(result => { + setTimeout(() => { + this.isLoadingResults = false; + }); + return result; + }) + .map(result => { + if (!result) { return []; } + if (this._paginator.pageIndex === 0) { this.totalCount = result.totalCount; } + return result.data; + }); + } + + disconnect() { + // No-op + } +} diff --git a/dmp-frontend/src/app/datasets/dataset.module.ts b/dmp-frontend/src/app/datasets/dataset.module.ts index 6fa36b18e..2b0f4c451 100644 --- a/dmp-frontend/src/app/datasets/dataset.module.ts +++ b/dmp-frontend/src/app/datasets/dataset.module.ts @@ -20,6 +20,7 @@ import { DataManagementPlanService } from '../services/data-management-plan/data import { DatasetWizardService } from '../services/dataset-wizard/dataset-wizard.service'; import { ExternalSourcesService } from '../services/external-sources/external-sources.service'; import { ExternalSourcesConfigurationService } from '../services/external-sources/external-sources-configuration.service'; +import { DatasetPublicListingComponent } from './dataset-public/dataset-public-listing.component'; @NgModule({ imports: [ CommonModule, @@ -43,13 +44,15 @@ import { ExternalSourcesConfigurationService } from '../services/external-source declarations: [ DatasetListingComponent, DatasetEditorComponent, - DatasetWizardComponent + DatasetWizardComponent, + DatasetPublicListingComponent ], exports: [ DatasetListingComponent, DatasetEditorComponent, DatasetWizardComponent, + DatasetPublicListingComponent, RouterModule ], providers: [ diff --git a/dmp-frontend/src/app/datasets/dataset.routes.ts b/dmp-frontend/src/app/datasets/dataset.routes.ts index bf9958fc9..2381287dd 100644 --- a/dmp-frontend/src/app/datasets/dataset.routes.ts +++ b/dmp-frontend/src/app/datasets/dataset.routes.ts @@ -2,6 +2,7 @@ import { DatasetWizardComponent } from './dataset-wizard/dataset-wizard.componen import { DatasetListingComponent } from './listing/dataset-listing.component'; import { RouterModule, Routes } from '@angular/router'; import { AuthGuard } from '../shared/guards/auth.guard'; +import { DatasetPublicListingComponent } from './dataset-public/dataset-public-listing.component'; export const DatasetRoutes: Routes = [ { @@ -15,7 +16,7 @@ export const DatasetRoutes: Routes = [ { path: "edit/:id", component: DatasetWizardComponent, - canActivate: [AuthGuard], + //canActivate: [AuthGuard], data: { breadcrumb: true }, @@ -31,15 +32,20 @@ export const DatasetRoutes: Routes = [ { path: '', component: DatasetListingComponent, - canActivate: [AuthGuard], + //canActivate: [AuthGuard], data: { breadcrumb: true }, }, + { + path: 'public', + component: DatasetPublicListingComponent, + //canActivate: [AuthGuard], + }, { path: "dmp/:dmpId", component: DatasetListingComponent, - canActivate: [AuthGuard], + //canActivate: [AuthGuard], data: { breadcrumb: true }, diff --git a/dmp-frontend/src/app/dmps/editor/dmp-editor.component.html b/dmp-frontend/src/app/dmps/editor/dmp-editor.component.html index 1e34fa63e..bd422c4d3 100644 --- a/dmp-frontend/src/app/dmps/editor/dmp-editor.component.html +++ b/dmp-frontend/src/app/dmps/editor/dmp-editor.component.html @@ -21,6 +21,8 @@ queue{{'DMP-LISTING.ACTIONS.NEW-VERSION' | translate}} +
--> -
+
{{baseErrorModel['Criteria.like']}}
-
- +
+ @@ -38,7 +38,7 @@ {{baseErrorModel['Criteria.status']}}
-
+
diff --git a/dmp-frontend/src/app/shared/components/criteria/datasets/datasets-criteria.component.ts b/dmp-frontend/src/app/shared/components/criteria/datasets/datasets-criteria.component.ts index f1e8adf93..4c1fd42cb 100644 --- a/dmp-frontend/src/app/shared/components/criteria/datasets/datasets-criteria.component.ts +++ b/dmp-frontend/src/app/shared/components/criteria/datasets/datasets-criteria.component.ts @@ -1,5 +1,5 @@ import { TranslateService } from '@ngx-translate/core'; -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, Input } from '@angular/core'; import { FormControl, FormGroup, FormBuilder, Validators } from '@angular/forms'; import { BaseCriteriaComponent } from '../base/base-criteria.component'; import { ValidationContext, Validation } from '../../../../utilities/validators/ValidationContext'; @@ -25,6 +25,8 @@ export class DatasetCriteriaComponent extends BaseCriteriaComponent implements O // public form: ProjectType; // public formStatus: ProjectStatus; + @Input() + public isPublic = false; public criteria: DatasetCriteria = new DatasetCriteria(); public filteringTagsAsync: boolean = false; public filteredTags: ExternalSourcesItemModel[]; diff --git a/dmp-frontend/src/app/shared/components/figurecard/figurecard.component.html b/dmp-frontend/src/app/shared/components/figurecard/figurecard.component.html index 4577acc87..762fdb8d6 100644 --- a/dmp-frontend/src/app/shared/components/figurecard/figurecard.component.html +++ b/dmp-frontend/src/app/shared/components/figurecard/figurecard.component.html @@ -1,5 +1,5 @@
-
+
{{ headerIcon }}
diff --git a/dmp-frontend/src/app/shared/components/figurecard/figurecard.component.css b/dmp-frontend/src/app/shared/components/figurecard/figurecard.component.scss similarity index 97% rename from dmp-frontend/src/app/shared/components/figurecard/figurecard.component.css rename to dmp-frontend/src/app/shared/components/figurecard/figurecard.component.scss index ff0859704..3b7eed15a 100644 --- a/dmp-frontend/src/app/shared/components/figurecard/figurecard.component.css +++ b/dmp-frontend/src/app/shared/components/figurecard/figurecard.component.scss @@ -19,7 +19,10 @@ border-radius: 3px; padding: 15px; position: relative; - cursor: pointer; +} + +.clickable{ + cursor: pointer; } .card-header i { diff --git a/dmp-frontend/src/app/shared/components/figurecard/figurecard.component.ts b/dmp-frontend/src/app/shared/components/figurecard/figurecard.component.ts index a9c4fb87f..32c325d53 100644 --- a/dmp-frontend/src/app/shared/components/figurecard/figurecard.component.ts +++ b/dmp-frontend/src/app/shared/components/figurecard/figurecard.component.ts @@ -5,7 +5,7 @@ import { AuthService } from '../../../services/auth/auth.service'; @Component({ selector: 'app-figurecard', templateUrl: './figurecard.component.html', - styleUrls: ['./figurecard.component.css'] + styleUrls: ['./figurecard.component.scss'] }) export class FigurecardComponent implements OnInit { @Input() headerIcon: string; @@ -26,6 +26,7 @@ export class FigurecardComponent implements OnInit { } navigateToUrl() { + if(!this.isAuthenticated()) return; this.router.navigate([this.routelLink]); } diff --git a/dmp-frontend/src/app/shared/components/navigation/navigation.component.html b/dmp-frontend/src/app/shared/components/navigation/navigation.component.html index 60567fcc9..15160dcc8 100644 --- a/dmp-frontend/src/app/shared/components/navigation/navigation.component.html +++ b/dmp-frontend/src/app/shared/components/navigation/navigation.component.html @@ -8,7 +8,11 @@ - + +
+
+
diff --git a/dmp-frontend/src/app/shared/material/material.module.ts b/dmp-frontend/src/app/shared/material/material.module.ts index 3789899d6..4f067a2be 100644 --- a/dmp-frontend/src/app/shared/material/material.module.ts +++ b/dmp-frontend/src/app/shared/material/material.module.ts @@ -1,92 +1,97 @@ -import { NgModule } from '@angular/core'; +import { NgModule, LOCALE_ID } from '@angular/core'; import { - MatToolbarModule, - MatIconModule, - MatSidenavModule, - MatButtonModule, - MatTableModule, - MatPaginatorModule, - MatSortModule, - MatDialogModule, - MatDatepickerModule, - MatNativeDateModule, - MatInputModule, - MatFormFieldModule, - MatSnackBarModule, - MatAutocompleteModule, - MatExpansionModule, - MatSelectModule, - MatOptionModule, - MatCardModule, - MatProgressBarModule, - MatProgressSpinnerModule, - DateAdapter, - MatTooltipModule, - MatCheckboxModule, - MatTabsModule, - MatStepperModule, - MatRadioModule, - MatMenuModule, - MatListModule, - MatChipsModule, - MatBadgeModule + MatToolbarModule, + MatIconModule, + MatSidenavModule, + MatButtonModule, + MatTableModule, + MatPaginatorModule, + MatSortModule, + MatDialogModule, + MatDatepickerModule, + MatNativeDateModule, + MatInputModule, + MatFormFieldModule, + MatSnackBarModule, + MatAutocompleteModule, + MatExpansionModule, + MatSelectModule, + MatOptionModule, + MatCardModule, + MatProgressBarModule, + MatProgressSpinnerModule, + DateAdapter, + MatTooltipModule, + MatCheckboxModule, + MatTabsModule, + MatStepperModule, + MatRadioModule, + MatMenuModule, + MatListModule, + MatChipsModule, + MatBadgeModule, + MAT_DATE_LOCALE, + MAT_DATE_FORMATS } from '@angular/material'; import { CdkTableModule } from '@angular/cdk/table'; import { SnackBarNotificationComponent } from '../components/notificaiton/snack-bar-notification.component'; import { CovalentLayoutModule, CovalentChipsModule, CovalentDialogsModule, CovalentFileModule } from '@covalent/core'; +import { CultureService } from '../../utilities/culture/culture-service'; +import { MomentDateAdapter } from '@angular/material-moment-adapter'; @NgModule({ - imports: [ - ], + imports: [ + ], - exports: [ - MatToolbarModule, - MatIconModule, - MatSidenavModule, - MatButtonModule, - MatTableModule, - MatPaginatorModule, - CdkTableModule, - MatSortModule, - MatDialogModule, - MatDatepickerModule, - MatNativeDateModule, - MatInputModule, - MatFormFieldModule, - MatSnackBarModule, - MatAutocompleteModule, - MatExpansionModule, - MatSelectModule, - MatOptionModule, - MatCardModule, - MatProgressBarModule, - MatProgressSpinnerModule, - MatTooltipModule, - MatCheckboxModule, - MatTabsModule, - CovalentLayoutModule, - CovalentChipsModule, - CovalentDialogsModule, - CovalentFileModule, - MatStepperModule, - MatRadioModule, - MatMenuModule, - MatListModule, + exports: [ + MatToolbarModule, + MatIconModule, + MatSidenavModule, + MatButtonModule, + MatTableModule, + MatPaginatorModule, + CdkTableModule, + MatSortModule, + MatDialogModule, + MatDatepickerModule, + MatNativeDateModule, + MatInputModule, + MatFormFieldModule, + MatSnackBarModule, + MatAutocompleteModule, + MatExpansionModule, + MatSelectModule, + MatOptionModule, + MatCardModule, + MatProgressBarModule, + MatProgressSpinnerModule, + MatTooltipModule, + MatCheckboxModule, + MatTabsModule, + CovalentLayoutModule, + CovalentChipsModule, + CovalentDialogsModule, + CovalentFileModule, + MatStepperModule, + MatRadioModule, + MatMenuModule, + MatListModule, MatChipsModule, - MatBadgeModule - ], + MatBadgeModule, - providers: [ - //{ provide: DateAdapter, useClass: LocalizedDateAdapter }, - ], + ], - entryComponents: [ - SnackBarNotificationComponent - ] + providers: [ + + ], + + entryComponents: [ + SnackBarNotificationComponent + ] }) export class MaterialModule { - // constructor(dateAdapter: DateAdapter) { - // dateAdapter.setLocale('el-GR'); - // } + // constructor(dateAdapter: DateAdapter) { + // dateAdapter.setLocale('el-GR'); + // } } diff --git a/dmp-frontend/src/app/shared/shared.module.ts b/dmp-frontend/src/app/shared/shared.module.ts index 44264aee9..e909bef36 100644 --- a/dmp-frontend/src/app/shared/shared.module.ts +++ b/dmp-frontend/src/app/shared/shared.module.ts @@ -25,6 +25,7 @@ import { SingleAutoCompleteComponent } from './components/autocompletes/single/s import { MultipleAutoCompleteComponent } from './components/autocompletes/multiple/multiple-auto-complete.component'; import { UserDialogComponent } from './components/user-dialog/user-dialog.component'; import { SearchBarComponent } from './components/search-bar/search-bar.component'; +import { TimezoneInfoDisplayPipe } from '../utilities/culture/pipes/TimezoneInfoDisplayPipe'; @NgModule({ imports: [ diff --git a/dmp-frontend/src/app/user-management/login/login.component.html b/dmp-frontend/src/app/user-management/login/login.component.html index 43287c763..63dcb2465 100644 --- a/dmp-frontend/src/app/user-management/login/login.component.html +++ b/dmp-frontend/src/app/user-management/login/login.component.html @@ -19,7 +19,7 @@
- diff --git a/dmp-frontend/src/app/user-management/utilties/login-service.ts b/dmp-frontend/src/app/user-management/utilties/login-service.ts index f8cb479c7..327275aaa 100644 --- a/dmp-frontend/src/app/user-management/utilties/login-service.ts +++ b/dmp-frontend/src/app/user-management/utilties/login-service.ts @@ -12,6 +12,7 @@ import { SnackBarNotificationComponent } from '../../shared/components/notificai import { Router, ActivatedRoute, Params } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { CultureService } from '../../utilities/culture/culture-service'; declare const gapi: any; declare const FB: any; @@ -30,6 +31,7 @@ export class LoginService { public language: TranslateService, private zone: NgZone, private httpClient: HttpClient, + private cultureService: CultureService, @Optional() private config: LoginServiceConfiguration ) { if (config) { @@ -218,6 +220,7 @@ export class LoginService { data: { message: 'GENERAL.SNACK-BAR.SUCCESSFUL-LOGIN', language: this.language }, duration: 3000, }); + this.cultureService.cultureSelected(this.authService.current().culture) let params = this.router["rawUrlTree"].queryParams; let redirectUrl = params['returnUrl'] ? params['returnUrl'] : '/'; this.zone.run(() => this.router.navigate([redirectUrl])); diff --git a/dmp-frontend/src/app/users/profile/user-profile.component.html b/dmp-frontend/src/app/users/profile/user-profile.component.html index db524e48e..48336ea72 100644 --- a/dmp-frontend/src/app/users/profile/user-profile.component.html +++ b/dmp-frontend/src/app/users/profile/user-profile.component.html @@ -3,7 +3,7 @@
- +
{{userProfile.name}} {{userProfile.email}} @@ -18,7 +18,8 @@
- +
{{ dmp.label }}
@@ -35,15 +36,55 @@ + + +

{{ 'USER-PROFILE.SETTINGS.TITLE' | translate}}

+ + +
+
-
-
-

{{ 'USER-PROFILE.SETTINGS' | translate}}

+
+
+
+ + + + + {{ timezone | timezoneInfoDisplay }} + + + +
+
+ + + + + {{ culture.displayName }} - {{ culture.nativeName }} + + + +
+
+ + + + {{ language.label }} + + + +
- Loading stuff... diff --git a/dmp-frontend/src/app/users/profile/user-profile.component.scss b/dmp-frontend/src/app/users/profile/user-profile.component.scss index a33508507..90a030730 100644 --- a/dmp-frontend/src/app/users/profile/user-profile.component.scss +++ b/dmp-frontend/src/app/users/profile/user-profile.component.scss @@ -1,3 +1,10 @@ .clickable{ cursor: pointer; } +.two-line-mat-option { + height: 3.5em; + line-height: 1.2em; +} +.full-width{ + width: 100% +} diff --git a/dmp-frontend/src/app/users/profile/user-profile.component.ts b/dmp-frontend/src/app/users/profile/user-profile.component.ts index 16c907b46..0ada5237d 100644 --- a/dmp-frontend/src/app/users/profile/user-profile.component.ts +++ b/dmp-frontend/src/app/users/profile/user-profile.component.ts @@ -16,34 +16,62 @@ import { DataSource } from '@angular/cdk/table'; import { RecentActivityTypes } from '../../users/activity/RecentActivityTypes'; import { AuthService } from '../../services/auth/auth.service'; import { DataManagementPlanModel } from '../../models/data-managemnt-plans/DataManagementPlanModel'; +import { CultureInfo } from '../../utilities/culture/models/culture-info'; +import { CultureService } from '../../utilities/culture/culture-service'; +import { FormControl, FormBuilder, FormGroup } from '@angular/forms'; +import * as moment from 'moment-timezone'; +import { User } from '../../models/invitation/User'; +const availableLanguages: any[] = require('../../../assets/resources/language.json'); @Component({ selector: 'app-user-profile', templateUrl: './user-profile.component.html', styleUrls: ['./user-profile.component.scss'], providers: [ - UserReferenceService + UserReferenceService, + CultureService ] }) export class UserProfileComponent implements OnInit { user: Observable; currentUserId: string; + cultures: Observable; + timezones: Observable; + editMode = false; + languages = availableLanguages; + + formGroup: FormGroup; constructor( private userReferenceService: UserReferenceService, private route: ActivatedRoute, private router: Router, private authService: AuthService, - private language: TranslateService + private language: TranslateService, + private cultureService: CultureService, + private translate: TranslateService, ) { } ngOnInit() { this.route.params.subscribe((params: Params) => { this.currentUserId = params['id']; let userId = params['id'] === this.authService.current().id ? 'me' : params['id'] - this.user = this.userReferenceService.getUser(userId).map(result => { result["additionalinfo"] = JSON.parse(result["additionalinfo"]); return result }) + this.user = this.userReferenceService.getUser(userId).map(result => { + result["additionalinfo"] = JSON.parse(result["additionalinfo"]); + this.formGroup = new FormBuilder().group({ + language: new FormControl(result["additionalinfo"]["language"] ? availableLanguages.filter(x => x.value === result["additionalinfo"]["language"]["value"]).pop() : ''), + timezone: new FormControl(result["additionalinfo"]["timezone"]), + culture: new FormControl(result["additionalinfo"]["culture"]) + }) + this.formGroup.get('language').valueChanges.subscribe(x => { if (x) this.translate.use(x.value) }) + this.formGroup.get('timezone').valueChanges.subscribe(x => { if (x) this.timezones = this._filterTimezone(x) }); + this.formGroup.get('culture').valueChanges.subscribe(x => { if (x) this.cultures = this._filterCulture(x) }); + this.formGroup.disable() + return result; + }) }) + } getUserRole(dmp: DataManagementPlanModel) { @@ -60,4 +88,46 @@ export class UserProfileComponent implements OnInit { this.router.navigate(["/dmps/edit/" + dmp.id]) } + private _filterTimezone(value: string): Observable { + if (value && typeof value === 'string') { + const filterValue = value.toLowerCase(); + return Observable.of(moment.tz.names().filter(option => option.toLowerCase().includes(filterValue))); + } else { + return Observable.of(moment.tz.names()); + } + } + + private _filterCulture(value: string): Observable { + if (value && typeof value === 'string') { + const filterValue = value.toLowerCase(); + return Observable.of(this.cultureService.getCultureValues().filter(option => option.displayName.toLowerCase().includes(filterValue))); + } else { + return Observable.of(this.cultureService.getCultureValues()); + } + } + + displayFn(culture?: CultureInfo): string | undefined { + return culture ? culture.displayName + '-' + culture.nativeName : undefined; + } + + save() { + + } + + public unlock() { + this.editMode = true; + this.formGroup.enable() + } + + public lock() { + this.userReferenceService.updateUserSettings(this.formGroup.value).subscribe( + x => { + this.editMode = false; + this.formGroup.disable(); + }, + error => { + console.log(error) + }) + } + } diff --git a/dmp-frontend/src/app/users/users.module.ts b/dmp-frontend/src/app/users/users.module.ts index 8862eaf61..e945776ac 100644 --- a/dmp-frontend/src/app/users/users.module.ts +++ b/dmp-frontend/src/app/users/users.module.ts @@ -17,6 +17,7 @@ import { UsersRoutes } from './users.routes'; import { BaseHttpModule } from '../utilities/cite-http-service-module/cite-http.module'; import { BaseHttpService } from '../utilities/cite-http-service-module/base-http.service'; import { UserProfileComponent } from './profile/user-profile.component'; +import { TimezoneInfoDisplayPipe } from '../utilities/culture/pipes/TimezoneInfoDisplayPipe'; @NgModule({ imports: [ @@ -40,12 +41,12 @@ import { UserProfileComponent } from './profile/user-profile.component'; UsersComponent, UsersCriteriaComponent, UserRoleEditorComponent, - UserProfileComponent + UserProfileComponent, + TimezoneInfoDisplayPipe ], providers: [ BaseHttpService, UserReferenceService - ], exports: [ UsersComponent diff --git a/dmp-frontend/src/app/utilities/culture/culture-service.ts b/dmp-frontend/src/app/utilities/culture/culture-service.ts new file mode 100644 index 000000000..05e688083 --- /dev/null +++ b/dmp-frontend/src/app/utilities/culture/culture-service.ts @@ -0,0 +1,69 @@ +import { Injectable } from '@angular/core'; +import { Observable, Subject } from 'rxjs'; +import { CultureInfo } from './models/culture-info'; +import { registerLocaleData } from '@angular/common'; + +const availableCultures: CultureInfo[] = require('../../../assets/resources/available-cultures.json'); + +@Injectable() +export class CultureService { + + private cultureValues = new Map(); // cultures by name + private cultureChangeSubject = new Subject(); + private currentCulture: CultureInfo; + + constructor( + ) { + if (availableCultures) { + this.cultureValues = new Map(); + availableCultures.forEach(culture => { + this.cultureValues.set(culture.name, culture); + }); + } + } + + getCultureValues(): CultureInfo[] { + const values: CultureInfo[] = []; + this.cultureValues.forEach((value) => values.push(value)); + return values; + } + + getCultureValue(culture: string): CultureInfo | undefined { + return this.cultureValues.get(culture); + } + + cultureSelected(culture: string | CultureInfo) { + let newCultureName: string; + if (typeof culture == 'string') { + if (this.currentCulture && this.currentCulture.name === culture) { return; } + newCultureName = culture; + } else { + if (this.currentCulture && this.currentCulture.name === culture.name) { return; } + newCultureName = culture.name; + } + + const newCulture = this.cultureValues.get(newCultureName); + if (!newCulture) { + console.error(`unsupported culture given: ${newCultureName}`); //TODO: throw error? + return; + } + this.currentCulture = newCulture; + this.cultureChangeSubject.next(newCulture); + + // Set angular locale based on user selection. + const locale = newCulture.name.split('-')[0]; + import(`@angular/common/locales/${locale}.js`).catch(reason => { + console.error('Could not load locale: ' + locale); + }).then(selectedLocale => { + registerLocaleData(selectedLocale.default); + }); + } + + getCultureChangeObservable(): Observable { + return this.cultureChangeSubject.asObservable(); + } + + getCurrentCulture(): CultureInfo { + return this.currentCulture; + } +} diff --git a/dmp-frontend/src/app/utilities/culture/models/culture-info.ts b/dmp-frontend/src/app/utilities/culture/models/culture-info.ts new file mode 100644 index 000000000..c3afee24a --- /dev/null +++ b/dmp-frontend/src/app/utilities/culture/models/culture-info.ts @@ -0,0 +1,5 @@ +export class CultureInfo { + public name: string; + public displayName: string; + public nativeName: string; +} diff --git a/dmp-frontend/src/app/utilities/culture/pipes/TimezoneInfoDisplayPipe.ts b/dmp-frontend/src/app/utilities/culture/pipes/TimezoneInfoDisplayPipe.ts new file mode 100644 index 000000000..aa88e27e1 --- /dev/null +++ b/dmp-frontend/src/app/utilities/culture/pipes/TimezoneInfoDisplayPipe.ts @@ -0,0 +1,12 @@ +import { Pipe, PipeTransform } from '@angular/core'; +import * as moment from 'moment'; +import 'moment-timezone'; + +@Pipe({ name: 'timezoneInfoDisplay' }) +export class TimezoneInfoDisplayPipe implements PipeTransform { + constructor() { } + + public transform(value): any { + return value + ' (GMT' + moment["tz"](value).format('Z') + ')'; + } +} diff --git a/dmp-frontend/src/assets/lang/en.json b/dmp-frontend/src/assets/lang/en.json index be4cb147a..6257e720d 100644 --- a/dmp-frontend/src/assets/lang/en.json +++ b/dmp-frontend/src/assets/lang/en.json @@ -26,6 +26,7 @@ "PROJECTS": "Projects", "DMPS": "DMPs", "DATASETS": "Datasets", + "PUBLIC-DATASETS": "Public Datasets", "USERS": "Users", "DATASETS-ADMIN": "Dataset Profiles", "DMP-PROFILES": "DMP Profiles", @@ -181,7 +182,7 @@ "PERIOD-TO": "Project End", "PROJECT-STATE-TYPE": "Project Status", "TYPES": { - "ON-GOING": "OnGoing", + "ON-GOING": "On Going", "FINISHED": "Finished" } }, @@ -324,7 +325,12 @@ "EXIT": "Exit " }, "USER-PROFILE": { - "SETTINGS": "Settings", + "SETTINGS": { + "TITLE": "Settings", + "TIMEZONE": "Time Zone", + "CULTURE": "Culture", + "LANGUAGE": "Language" + }, "ASSOCIATED-DMPS": "Associated DMPs", "DMPS": { "SHOW-ALL": "Show All", diff --git a/dmp-frontend/src/assets/lang/gr.json b/dmp-frontend/src/assets/lang/gr.json new file mode 100644 index 000000000..0d5810d52 --- /dev/null +++ b/dmp-frontend/src/assets/lang/gr.json @@ -0,0 +1,21 @@ +{ + "GENERAL": { + "VALIDATION": { + "REQUIRED": "Required" + } + }, + "USER-PROFILE": { + "SETTINGS": { + "TITLE": "Ρυθμίσεις", + "TIMEZONE": "Ζώνη Ώρας", + "CULTURE": "Κουλτούρα", + "LANGUAGE": "Γλώσσα" + }, + "ASSOCIATED-DMPS": "Συσχετιζόμενα DMPs", + "DMPS": { + "SHOW-ALL": "Όλα", + "CREATOR": "Δημιουργός", + "MEMBER": "Μέλος" + } + } +} diff --git a/dmp-frontend/src/assets/resources/available-cultures.json b/dmp-frontend/src/assets/resources/available-cultures.json new file mode 100644 index 000000000..102b0d38a --- /dev/null +++ b/dmp-frontend/src/assets/resources/available-cultures.json @@ -0,0 +1,2816 @@ +[{ + "name": "aa-DJ", + "displayName": "Qafar (Yabuuti)", + "nativeName": "Qafar (Yabuuti)" + }, + { + "name": "aa-ER", + "displayName": "Qafar (Eretria)", + "nativeName": "Qafar (Eretria)" + }, + { + "name": "aa-ET", + "displayName": "Qafar (Otobbia)", + "nativeName": "Qafar (Otobbia)" + }, + { + "name": "af-NA", + "displayName": "Afrikaans (Namibië)", + "nativeName": "Afrikaans (Namibië)" + }, + { + "name": "af-ZA", + "displayName": "Afrikaans (South Africa)", + "nativeName": "Afrikaans (Suid-Afrika)" + }, + { + "name": "agq-CM", + "displayName": "Aghem (Kàmàlûŋ)", + "nativeName": "Aghem (Kàmàlûŋ)" + }, + { + "name": "ak-GH", + "displayName": "Akan (Gaana)", + "nativeName": "Akan (Gaana)" + }, + { + "name": "am-ET", + "displayName": "Amharic (Ethiopia)", + "nativeName": "አማርኛ (ኢትዮጵያ)" + }, + { + "name": "ar-001", + "displayName": "العربية (العالم)", + "nativeName": "العربية (العالم)" + }, + { + "name": "ar-AE", + "displayName": "Arabic (United Arab Emirates)", + "nativeName": "العربية (الإمارات العربية المتحدة)" + }, + { + "name": "ar-BH", + "displayName": "Arabic (Bahrain)", + "nativeName": "العربية (البحرين)" + }, + { + "name": "ar-DJ", + "displayName": "العربية (جيبوتي)", + "nativeName": "العربية (جيبوتي)" + }, + { + "name": "ar-DZ", + "displayName": "Arabic (Algeria)", + "nativeName": "العربية (الجزائر)" + }, + { + "name": "ar-EG", + "displayName": "Arabic (Egypt)", + "nativeName": "العربية (مصر)" + }, + { + "name": "ar-ER", + "displayName": "العربية (إريتريا)", + "nativeName": "العربية (إريتريا)" + }, + { + "name": "ar-IL", + "displayName": "العربية (إسرائيل)", + "nativeName": "العربية (إسرائيل)" + }, + { + "name": "ar-IQ", + "displayName": "Arabic (Iraq)", + "nativeName": "العربية (العراق)" + }, + { + "name": "ar-JO", + "displayName": "Arabic (Jordan)", + "nativeName": "العربية (الأردن)" + }, + { + "name": "ar-KM", + "displayName": "العربية (جزر القمر)", + "nativeName": "العربية (جزر القمر)" + }, + { + "name": "ar-KW", + "displayName": "Arabic (Kuwait)", + "nativeName": "العربية (الكويت)" + }, + { + "name": "ar-LB", + "displayName": "Arabic (Lebanon)", + "nativeName": "العربية (لبنان)" + }, + { + "name": "ar-LY", + "displayName": "Arabic (Libya)", + "nativeName": "العربية (ليبيا)" + }, + { + "name": "ar-MA", + "displayName": "Arabic (Morocco)", + "nativeName": "العربية (المملكة المغربية)" + }, + { + "name": "ar-MR", + "displayName": "العربية (موريتانيا)", + "nativeName": "العربية (موريتانيا)" + }, + { + "name": "ar-OM", + "displayName": "Arabic (Oman)", + "nativeName": "العربية (عمان)" + }, + { + "name": "ar-PS", + "displayName": "العربية (السلطة الفلسطينية)", + "nativeName": "العربية (السلطة الفلسطينية)" + }, + { + "name": "ar-QA", + "displayName": "Arabic (Qatar)", + "nativeName": "العربية (قطر)" + }, + { + "name": "ar-SA", + "displayName": "Arabic (Saudi Arabia)", + "nativeName": "العربية (المملكة العربية السعودية)" + }, + { + "name": "ar-SD", + "displayName": "العربية (السودان)", + "nativeName": "العربية (السودان)" + }, + { + "name": "ar-SO", + "displayName": "العربية (الصومال)", + "nativeName": "العربية (الصومال)" + }, + { + "name": "ar-SS", + "displayName": "العربية (جنوب السودان)", + "nativeName": "العربية (جنوب السودان)" + }, + { + "name": "ar-SY", + "displayName": "Arabic (Syria)", + "nativeName": "العربية (سوريا)" + }, + { + "name": "ar-TD", + "displayName": "العربية (تشاد)", + "nativeName": "العربية (تشاد)" + }, + { + "name": "ar-TN", + "displayName": "Arabic (Tunisia)", + "nativeName": "العربية (تونس)" + }, + { + "name": "ar-YE", + "displayName": "Arabic (Yemen)", + "nativeName": "العربية (اليمن)" + }, + { + "name": "arn-CL", + "displayName": "Mapudungun (Chile)", + "nativeName": "Mapudungun (Chile)" + }, + { + "name": "as-IN", + "displayName": "Assamese (India)", + "nativeName": "অসমীয়া (ভাৰত)" + }, + { + "name": "asa-TZ", + "displayName": "Kipare (Tadhania)", + "nativeName": "Kipare (Tadhania)" + }, + { + "name": "ast-ES", + "displayName": "asturianu (España)", + "nativeName": "asturianu (España)" + }, + { + "name": "az-Cyrl-AZ", + "displayName": "Azerbaijani (Cyrillic, Azerbaijan)", + "nativeName": "азәрбајҹан (Азәрбајҹан)" + }, + { + "name": "az-Latn-AZ", + "displayName": "Azerbaijani (Latin, Azerbaijan)", + "nativeName": "azərbaycan (Azərbaycan)" + }, + { + "name": "ba-RU", + "displayName": "Bashkir (Russia)", + "nativeName": "Башҡорт (Рәсәй)" + }, + { + "name": "bas-CM", + "displayName": "Ɓàsàa (Kàmɛ̀rûn)", + "nativeName": "Ɓàsàa (Kàmɛ̀rûn)" + }, + { + "name": "be-BY", + "displayName": "Belarusian (Belarus)", + "nativeName": "Беларуская (Беларусь)" + }, + { + "name": "bem-ZM", + "displayName": "Ichibemba (Zambia)", + "nativeName": "Ichibemba (Zambia)" + }, + { + "name": "bez-TZ", + "displayName": "Hibena (Hutanzania)", + "nativeName": "Hibena (Hutanzania)" + }, + { + "name": "bg-BG", + "displayName": "Bulgarian (Bulgaria)", + "nativeName": "български (България)" + }, + { + "name": "bin-NG", + "displayName": "Edo (Nigeria)", + "nativeName": "Ẹ̀dó (Nigeria)" + }, + { + "name": "bm-Latn-ML", + "displayName": "bamanakan (Mali)", + "nativeName": "bamanakan (Mali)" + }, + { + "name": "bn-BD", + "displayName": "Bangla (Bangladesh)", + "nativeName": "বাংলা (বাংলাদেশ)" + }, + { + "name": "bn-IN", + "displayName": "Bangla (India)", + "nativeName": "বাংলা (ভারত)" + }, + { + "name": "bo-CN", + "displayName": "Tibetan (China)", + "nativeName": "བོད་ཡིག (ཀྲུང་ཧྭ་མི་དམངས་སྤྱི་མཐུན་རྒྱལ་ཁབ།)" + }, + { + "name": "bo-IN", + "displayName": "བོད་སྐད་ (རྒྱ་གར་)", + "nativeName": "བོད་སྐད་ (རྒྱ་གར་)" + }, + { + "name": "br-FR", + "displayName": "Breton (France)", + "nativeName": "brezhoneg (Frañs)" + }, + { + "name": "brx-IN", + "displayName": "बड़ो (भारत)", + "nativeName": "बड़ो (भारत)" + }, + { + "name": "bs-Cyrl-BA", + "displayName": "Bosnian (Cyrillic, Bosnia and Herzegovina)", + "nativeName": "босански (Босна и Херцеговина)" + }, + { + "name": "bs-Latn-BA", + "displayName": "Bosnian (Latin, Bosnia and Herzegovina)", + "nativeName": "bosanski (Bosna i Hercegovina)" + }, + { + "name": "byn-ER", + "displayName": "ብሊን (ኤርትራ)", + "nativeName": "ብሊን (ኤርትራ)" + }, + { + "name": "ca-AD", + "displayName": "català (Andorra)", + "nativeName": "català (Andorra)" + }, + { + "name": "ca-ES", + "displayName": "Catalan (Catalan)", + "nativeName": "català (català)" + }, + { + "name": "ca-ES-valencia", + "displayName": "Valencian (Spain)", + "nativeName": "valencià (Espanya)" + }, + { + "name": "ca-FR", + "displayName": "català (França)", + "nativeName": "català (França)" + }, + { + "name": "ca-IT", + "displayName": "català (Itàlia)", + "nativeName": "català (Itàlia)" + }, + { + "name": "ce-RU", + "displayName": "нохчийн (Росси)", + "nativeName": "нохчийн (Росси)" + }, + { + "name": "cgg-UG", + "displayName": "Rukiga (Uganda)", + "nativeName": "Rukiga (Uganda)" + }, + { + "name": "chr-Cher-US", + "displayName": "Cherokee (Cherokee, United States)", + "nativeName": "ᏣᎳᎩ (ᏌᏊ ᎢᏳᎾᎵᏍᏔᏅ ᏍᎦᏚᎩ)" + }, + { + "name": "co-FR", + "displayName": "Corsican (France)", + "nativeName": "Corsu (Francia)" + }, + { + "name": "cs-CZ", + "displayName": "Czech (Czechia)", + "nativeName": "čeština (Česko)" + }, + { + "name": "cu-RU", + "displayName": "церковнослове́нскїй (рѡссі́а)", + "nativeName": "церковнослове́нскїй (рѡссі́а)" + }, + { + "name": "cy-GB", + "displayName": "Welsh (United Kingdom)", + "nativeName": "Cymraeg (Y Deyrnas Unedig)" + }, + { + "name": "da-DK", + "displayName": "Danish (Denmark)", + "nativeName": "dansk (Danmark)" + }, + { + "name": "da-GL", + "displayName": "dansk (Grønland)", + "nativeName": "dansk (Grønland)" + }, + { + "name": "dav-KE", + "displayName": "Kitaita (Kenya)", + "nativeName": "Kitaita (Kenya)" + }, + { + "name": "de-AT", + "displayName": "German (Austria)", + "nativeName": "Deutsch (Österreich)" + }, + { + "name": "de-BE", + "displayName": "Deutsch (Belgien)", + "nativeName": "Deutsch (Belgien)" + }, + { + "name": "de-CH", + "displayName": "German (Switzerland)", + "nativeName": "Deutsch (Schweiz)" + }, + { + "name": "de-DE", + "displayName": "German (Germany)", + "nativeName": "Deutsch (Deutschland)" + }, + { + "name": "de-IT", + "displayName": "Deutsch (Italien)", + "nativeName": "Deutsch (Italien)" + }, + { + "name": "de-LI", + "displayName": "German (Liechtenstein)", + "nativeName": "Deutsch (Liechtenstein)" + }, + { + "name": "de-LU", + "displayName": "German (Luxembourg)", + "nativeName": "Deutsch (Luxemburg)" + }, + { + "name": "dje-NE", + "displayName": "Zarmaciine (Nižer)", + "nativeName": "Zarmaciine (Nižer)" + }, + { + "name": "dsb-DE", + "displayName": "Lower Sorbian (Germany)", + "nativeName": "dolnoserbšćina (Nimska)" + }, + { + "name": "dua-CM", + "displayName": "duálá (Cameroun)", + "nativeName": "duálá (Cameroun)" + }, + { + "name": "dv-MV", + "displayName": "Divehi (Maldives)", + "nativeName": "ދިވެހިބަސް (ދިވެހި ރާއްޖެ)" + }, + { + "name": "dyo-SN", + "displayName": "joola (Senegal)", + "nativeName": "joola (Senegal)" + }, + { + "name": "dz-BT", + "displayName": "Dzongkha (Bhutan)", + "nativeName": "རྫོང་ཁ (འབྲུག)" + }, + { + "name": "ebu-KE", + "displayName": "Kĩembu (Kenya)", + "nativeName": "Kĩembu (Kenya)" + }, + { + "name": "ee-GH", + "displayName": "Eʋegbe (Ghana nutome)", + "nativeName": "Eʋegbe (Ghana nutome)" + }, + { + "name": "ee-TG", + "displayName": "Eʋegbe (Togo nutome)", + "nativeName": "Eʋegbe (Togo nutome)" + }, + { + "name": "el-CY", + "displayName": "Ελληνικά (Κύπρος)", + "nativeName": "Ελληνικά (Κύπρος)" + }, + { + "name": "el-GR", + "displayName": "Greek (Greece)", + "nativeName": "Ελληνικά (Ελλάδα)" + }, + { + "name": "en-001", + "displayName": "English (World)", + "nativeName": "English (World)" + }, + { + "name": "en-029", + "displayName": "English (Caribbean)", + "nativeName": "English (Caribbean)" + }, + { + "name": "en-150", + "displayName": "English (Europe)", + "nativeName": "English (Europe)" + }, + { + "name": "en-AG", + "displayName": "English (Antigua and Barbuda)", + "nativeName": "English (Antigua and Barbuda)" + }, + { + "name": "en-AI", + "displayName": "English (Anguilla)", + "nativeName": "English (Anguilla)" + }, + { + "name": "en-AS", + "displayName": "English (American Samoa)", + "nativeName": "English (American Samoa)" + }, + { + "name": "en-AT", + "displayName": "English (Austria)", + "nativeName": "English (Austria)" + }, + { + "name": "en-AU", + "displayName": "English (Australia)", + "nativeName": "English (Australia)" + }, + { + "name": "en-BB", + "displayName": "English (Barbados)", + "nativeName": "English (Barbados)" + }, + { + "name": "en-BE", + "displayName": "English (Belgium)", + "nativeName": "English (Belgium)" + }, + { + "name": "en-BI", + "displayName": "English (Burundi)", + "nativeName": "English (Burundi)" + }, + { + "name": "en-BM", + "displayName": "English (Bermuda)", + "nativeName": "English (Bermuda)" + }, + { + "name": "en-BS", + "displayName": "English (Bahamas)", + "nativeName": "English (Bahamas)" + }, + { + "name": "en-BW", + "displayName": "English (Botswana)", + "nativeName": "English (Botswana)" + }, + { + "name": "en-BZ", + "displayName": "English (Belize)", + "nativeName": "English (Belize)" + }, + { + "name": "en-CA", + "displayName": "English (Canada)", + "nativeName": "English (Canada)" + }, + { + "name": "en-CC", + "displayName": "English (Cocos (Keeling) Islands)", + "nativeName": "English (Cocos (Keeling) Islands)" + }, + { + "name": "en-CH", + "displayName": "English (Switzerland)", + "nativeName": "English (Switzerland)" + }, + { + "name": "en-CK", + "displayName": "English (Cook Islands)", + "nativeName": "English (Cook Islands)" + }, + { + "name": "en-CM", + "displayName": "English (Cameroon)", + "nativeName": "English (Cameroon)" + }, + { + "name": "en-CX", + "displayName": "English (Christmas Island)", + "nativeName": "English (Christmas Island)" + }, + { + "name": "en-CY", + "displayName": "English (Cyprus)", + "nativeName": "English (Cyprus)" + }, + { + "name": "en-DE", + "displayName": "English (Germany)", + "nativeName": "English (Germany)" + }, + { + "name": "en-DK", + "displayName": "English (Denmark)", + "nativeName": "English (Denmark)" + }, + { + "name": "en-DM", + "displayName": "English (Dominica)", + "nativeName": "English (Dominica)" + }, + { + "name": "en-ER", + "displayName": "English (Eritrea)", + "nativeName": "English (Eritrea)" + }, + { + "name": "en-FI", + "displayName": "English (Finland)", + "nativeName": "English (Finland)" + }, + { + "name": "en-FJ", + "displayName": "English (Fiji)", + "nativeName": "English (Fiji)" + }, + { + "name": "en-FK", + "displayName": "English (Falkland Islands)", + "nativeName": "English (Falkland Islands)" + }, + { + "name": "en-FM", + "displayName": "English (Micronesia)", + "nativeName": "English (Micronesia)" + }, + { + "name": "en-GB", + "displayName": "English (United Kingdom)", + "nativeName": "English (United Kingdom)" + }, + { + "name": "en-GD", + "displayName": "English (Grenada)", + "nativeName": "English (Grenada)" + }, + { + "name": "en-GG", + "displayName": "English (Guernsey)", + "nativeName": "English (Guernsey)" + }, + { + "name": "en-GH", + "displayName": "English (Ghana)", + "nativeName": "English (Ghana)" + }, + { + "name": "en-GI", + "displayName": "English (Gibraltar)", + "nativeName": "English (Gibraltar)" + }, + { + "name": "en-GM", + "displayName": "English (Gambia)", + "nativeName": "English (Gambia)" + }, + { + "name": "en-GU", + "displayName": "English (Guam)", + "nativeName": "English (Guam)" + }, + { + "name": "en-GY", + "displayName": "English (Guyana)", + "nativeName": "English (Guyana)" + }, + { + "name": "en-HK", + "displayName": "English (Hong Kong SAR)", + "nativeName": "English (Hong Kong SAR)" + }, + { + "name": "en-ID", + "displayName": "English (Indonesia)", + "nativeName": "English (Indonesia)" + }, + { + "name": "en-IE", + "displayName": "English (Ireland)", + "nativeName": "English (Ireland)" + }, + { + "name": "en-IL", + "displayName": "English (Israel)", + "nativeName": "English (Israel)" + }, + { + "name": "en-IM", + "displayName": "English (Isle of Man)", + "nativeName": "English (Isle of Man)" + }, + { + "name": "en-IN", + "displayName": "English (India)", + "nativeName": "English (India)" + }, + { + "name": "en-IO", + "displayName": "English (British Indian Ocean Territory)", + "nativeName": "English (British Indian Ocean Territory)" + }, + { + "name": "en-JE", + "displayName": "English (Jersey)", + "nativeName": "English (Jersey)" + }, + { + "name": "en-JM", + "displayName": "English (Jamaica)", + "nativeName": "English (Jamaica)" + }, + { + "name": "en-KE", + "displayName": "English (Kenya)", + "nativeName": "English (Kenya)" + }, + { + "name": "en-KI", + "displayName": "English (Kiribati)", + "nativeName": "English (Kiribati)" + }, + { + "name": "en-KN", + "displayName": "English (Saint Kitts and Nevis)", + "nativeName": "English (Saint Kitts and Nevis)" + }, + { + "name": "en-KY", + "displayName": "English (Cayman Islands)", + "nativeName": "English (Cayman Islands)" + }, + { + "name": "en-LC", + "displayName": "English (Saint Lucia)", + "nativeName": "English (Saint Lucia)" + }, + { + "name": "en-LR", + "displayName": "English (Liberia)", + "nativeName": "English (Liberia)" + }, + { + "name": "en-LS", + "displayName": "English (Lesotho)", + "nativeName": "English (Lesotho)" + }, + { + "name": "en-MG", + "displayName": "English (Madagascar)", + "nativeName": "English (Madagascar)" + }, + { + "name": "en-MH", + "displayName": "English (Marshall Islands)", + "nativeName": "English (Marshall Islands)" + }, + { + "name": "en-MO", + "displayName": "English (Macao SAR)", + "nativeName": "English (Macao SAR)" + }, + { + "name": "en-MP", + "displayName": "English (Northern Mariana Islands)", + "nativeName": "English (Northern Mariana Islands)" + }, + { + "name": "en-MS", + "displayName": "English (Montserrat)", + "nativeName": "English (Montserrat)" + }, + { + "name": "en-MT", + "displayName": "English (Malta)", + "nativeName": "English (Malta)" + }, + { + "name": "en-MU", + "displayName": "English (Mauritius)", + "nativeName": "English (Mauritius)" + }, + { + "name": "en-MW", + "displayName": "English (Malawi)", + "nativeName": "English (Malawi)" + }, + { + "name": "en-MY", + "displayName": "English (Malaysia)", + "nativeName": "English (Malaysia)" + }, + { + "name": "en-NA", + "displayName": "English (Namibia)", + "nativeName": "English (Namibia)" + }, + { + "name": "en-NF", + "displayName": "English (Norfolk Island)", + "nativeName": "English (Norfolk Island)" + }, + { + "name": "en-NG", + "displayName": "English (Nigeria)", + "nativeName": "English (Nigeria)" + }, + { + "name": "en-NL", + "displayName": "English (Netherlands)", + "nativeName": "English (Netherlands)" + }, + { + "name": "en-NR", + "displayName": "English (Nauru)", + "nativeName": "English (Nauru)" + }, + { + "name": "en-NU", + "displayName": "English (Niue)", + "nativeName": "English (Niue)" + }, + { + "name": "en-NZ", + "displayName": "English (New Zealand)", + "nativeName": "English (New Zealand)" + }, + { + "name": "en-PG", + "displayName": "English (Papua New Guinea)", + "nativeName": "English (Papua New Guinea)" + }, + { + "name": "en-PH", + "displayName": "English (Philippines)", + "nativeName": "English (Philippines)" + }, + { + "name": "en-PK", + "displayName": "English (Pakistan)", + "nativeName": "English (Pakistan)" + }, + { + "name": "en-PN", + "displayName": "English (Pitcairn Islands)", + "nativeName": "English (Pitcairn Islands)" + }, + { + "name": "en-PR", + "displayName": "English (Puerto Rico)", + "nativeName": "English (Puerto Rico)" + }, + { + "name": "en-PW", + "displayName": "English (Palau)", + "nativeName": "English (Palau)" + }, + { + "name": "en-RW", + "displayName": "English (Rwanda)", + "nativeName": "English (Rwanda)" + }, + { + "name": "en-SB", + "displayName": "English (Solomon Islands)", + "nativeName": "English (Solomon Islands)" + }, + { + "name": "en-SC", + "displayName": "English (Seychelles)", + "nativeName": "English (Seychelles)" + }, + { + "name": "en-SD", + "displayName": "English (Sudan)", + "nativeName": "English (Sudan)" + }, + { + "name": "en-SE", + "displayName": "English (Sweden)", + "nativeName": "English (Sweden)" + }, + { + "name": "en-SG", + "displayName": "English (Singapore)", + "nativeName": "English (Singapore)" + }, + { + "name": "en-SH", + "displayName": "English (St Helena, Ascension, Tristan da Cunha)", + "nativeName": "English (St Helena, Ascension, Tristan da Cunha)" + }, + { + "name": "en-SI", + "displayName": "English (Slovenia)", + "nativeName": "English (Slovenia)" + }, + { + "name": "en-SL", + "displayName": "English (Sierra Leone)", + "nativeName": "English (Sierra Leone)" + }, + { + "name": "en-SS", + "displayName": "English (South Sudan)", + "nativeName": "English (South Sudan)" + }, + { + "name": "en-SX", + "displayName": "English (Sint Maarten)", + "nativeName": "English (Sint Maarten)" + }, + { + "name": "en-SZ", + "displayName": "English (Swaziland)", + "nativeName": "English (Swaziland)" + }, + { + "name": "en-TC", + "displayName": "English (Turks and Caicos Islands)", + "nativeName": "English (Turks and Caicos Islands)" + }, + { + "name": "en-TK", + "displayName": "English (Tokelau)", + "nativeName": "English (Tokelau)" + }, + { + "name": "en-TO", + "displayName": "English (Tonga)", + "nativeName": "English (Tonga)" + }, + { + "name": "en-TT", + "displayName": "English (Trinidad and Tobago)", + "nativeName": "English (Trinidad and Tobago)" + }, + { + "name": "en-TV", + "displayName": "English (Tuvalu)", + "nativeName": "English (Tuvalu)" + }, + { + "name": "en-TZ", + "displayName": "English (Tanzania)", + "nativeName": "English (Tanzania)" + }, + { + "name": "en-UG", + "displayName": "English (Uganda)", + "nativeName": "English (Uganda)" + }, + { + "name": "en-UM", + "displayName": "English (U.S. Outlying Islands)", + "nativeName": "English (U.S. Outlying Islands)" + }, + { + "name": "en-US", + "displayName": "English (United States)", + "nativeName": "English (United States)" + }, + { + "name": "en-VC", + "displayName": "English (Saint Vincent and the Grenadines)", + "nativeName": "English (Saint Vincent and the Grenadines)" + }, + { + "name": "en-VG", + "displayName": "English (British Virgin Islands)", + "nativeName": "English (British Virgin Islands)" + }, + { + "name": "en-VI", + "displayName": "English (U.S. Virgin Islands)", + "nativeName": "English (U.S. Virgin Islands)" + }, + { + "name": "en-VU", + "displayName": "English (Vanuatu)", + "nativeName": "English (Vanuatu)" + }, + { + "name": "en-WS", + "displayName": "English (Samoa)", + "nativeName": "English (Samoa)" + }, + { + "name": "en-ZA", + "displayName": "English (South Africa)", + "nativeName": "English (South Africa)" + }, + { + "name": "en-ZM", + "displayName": "English (Zambia)", + "nativeName": "English (Zambia)" + }, + { + "name": "en-ZW", + "displayName": "English (Zimbabwe)", + "nativeName": "English (Zimbabwe)" + }, + { + "name": "eo-001", + "displayName": "esperanto (World)", + "nativeName": "esperanto (World)" + }, + { + "name": "es-419", + "displayName": "Spanish (Latin America)", + "nativeName": "español (Latinoamérica)" + }, + { + "name": "es-AR", + "displayName": "Spanish (Argentina)", + "nativeName": "español (Argentina)" + }, + { + "name": "es-BO", + "displayName": "Spanish (Bolivia)", + "nativeName": "español (Bolivia)" + }, + { + "name": "es-BR", + "displayName": "español (Brasil)", + "nativeName": "español (Brasil)" + }, + { + "name": "es-BZ", + "displayName": "español (Belice)", + "nativeName": "español (Belice)" + }, + { + "name": "es-CL", + "displayName": "Spanish (Chile)", + "nativeName": "español (Chile)" + }, + { + "name": "es-CO", + "displayName": "Spanish (Colombia)", + "nativeName": "español (Colombia)" + }, + { + "name": "es-CR", + "displayName": "Spanish (Costa Rica)", + "nativeName": "español (Costa Rica)" + }, + { + "name": "es-CU", + "displayName": "Spanish (Cuba)", + "nativeName": "español (Cuba)" + }, + { + "name": "es-DO", + "displayName": "Spanish (Dominican Republic)", + "nativeName": "español (República Dominicana)" + }, + { + "name": "es-EC", + "displayName": "Spanish (Ecuador)", + "nativeName": "español (Ecuador)" + }, + { + "name": "es-ES", + "displayName": "Spanish (Spain, International Sort)", + "nativeName": "español (España, alfabetización internacional)" + }, + { + "name": "es-GQ", + "displayName": "español (Guinea Ecuatorial)", + "nativeName": "español (Guinea Ecuatorial)" + }, + { + "name": "es-GT", + "displayName": "Spanish (Guatemala)", + "nativeName": "español (Guatemala)" + }, + { + "name": "es-HN", + "displayName": "Spanish (Honduras)", + "nativeName": "español (Honduras)" + }, + { + "name": "es-MX", + "displayName": "Spanish (Mexico)", + "nativeName": "español (México)" + }, + { + "name": "es-NI", + "displayName": "Spanish (Nicaragua)", + "nativeName": "español (Nicaragua)" + }, + { + "name": "es-PA", + "displayName": "Spanish (Panama)", + "nativeName": "español (Panamá)" + }, + { + "name": "es-PE", + "displayName": "Spanish (Peru)", + "nativeName": "español (Perú)" + }, + { + "name": "es-PH", + "displayName": "español (Filipinas)", + "nativeName": "español (Filipinas)" + }, + { + "name": "es-PR", + "displayName": "Spanish (Puerto Rico)", + "nativeName": "español (Puerto Rico)" + }, + { + "name": "es-PY", + "displayName": "Spanish (Paraguay)", + "nativeName": "español (Paraguay)" + }, + { + "name": "es-SV", + "displayName": "Spanish (El Salvador)", + "nativeName": "español (El Salvador)" + }, + { + "name": "es-US", + "displayName": "Spanish (United States)", + "nativeName": "español (Estados Unidos)" + }, + { + "name": "es-UY", + "displayName": "Spanish (Uruguay)", + "nativeName": "español (Uruguay)" + }, + { + "name": "es-VE", + "displayName": "Spanish (Venezuela)", + "nativeName": "español (Venezuela)" + }, + { + "name": "et-EE", + "displayName": "Estonian (Estonia)", + "nativeName": "eesti (Eesti)" + }, + { + "name": "eu-ES", + "displayName": "Basque (Basque)", + "nativeName": "euskara (euskara)" + }, + { + "name": "ewo-CM", + "displayName": "ewondo (Kamərún)", + "nativeName": "ewondo (Kamərún)" + }, + { + "name": "fa-IR", + "displayName": "Persian (Iran)", + "nativeName": "فارسى (ایران)" + }, + { + "name": "ff-CM", + "displayName": "Pulaar (Kameruun)", + "nativeName": "Pulaar (Kameruun)" + }, + { + "name": "ff-GN", + "displayName": "Pulaar (Gine)", + "nativeName": "Pulaar (Gine)" + }, + { + "name": "ff-Latn-SN", + "displayName": "Fulah (Latin, Senegal)", + "nativeName": "Fulah (Sénégal)" + }, + { + "name": "ff-MR", + "displayName": "Pulaar (Muritani)", + "nativeName": "Pulaar (Muritani)" + }, + { + "name": "ff-NG", + "displayName": "Fulah (Nigeria)", + "nativeName": "Pulaar (Nigeria)" + }, + { + "name": "fi-FI", + "displayName": "Finnish (Finland)", + "nativeName": "suomi (Suomi)" + }, + { + "name": "fil-PH", + "displayName": "Filipino (Philippines)", + "nativeName": "Filipino (Pilipinas)" + }, + { + "name": "fo-DK", + "displayName": "føroyskt (Danmark)", + "nativeName": "føroyskt (Danmark)" + }, + { + "name": "fo-FO", + "displayName": "Faroese (Faroe Islands)", + "nativeName": "føroyskt (Føroyar)" + }, + { + "name": "fr-029", + "displayName": "French (Caribbean)", + "nativeName": "français (caraïbes)" + }, + { + "name": "fr-BE", + "displayName": "French (Belgium)", + "nativeName": "français (Belgique)" + }, + { + "name": "fr-BF", + "displayName": "français (Burkina Faso)", + "nativeName": "français (Burkina Faso)" + }, + { + "name": "fr-BI", + "displayName": "français (Burundi)", + "nativeName": "français (Burundi)" + }, + { + "name": "fr-BJ", + "displayName": "français (Bénin)", + "nativeName": "français (Bénin)" + }, + { + "name": "fr-BL", + "displayName": "français (Saint-Barthélemy)", + "nativeName": "français (Saint-Barthélemy)" + }, + { + "name": "fr-CA", + "displayName": "French (Canada)", + "nativeName": "français (Canada)" + }, + { + "name": "fr-CD", + "displayName": "French Congo (DRC)", + "nativeName": "français (Congo, République démocratique du)" + }, + { + "name": "fr-CF", + "displayName": "français (République centrafricaine)", + "nativeName": "français (République centrafricaine)" + }, + { + "name": "fr-CG", + "displayName": "français (Congo)", + "nativeName": "français (Congo)" + }, + { + "name": "fr-CH", + "displayName": "French (Switzerland)", + "nativeName": "français (Suisse)" + }, + { + "name": "fr-CI", + "displayName": "French (Côte d’Ivoire)", + "nativeName": "français (Côte d’Ivoire)" + }, + { + "name": "fr-CM", + "displayName": "French (Cameroon)", + "nativeName": "français (Cameroun)" + }, + { + "name": "fr-DJ", + "displayName": "français (Djibouti)", + "nativeName": "français (Djibouti)" + }, + { + "name": "fr-DZ", + "displayName": "français (Algérie)", + "nativeName": "français (Algérie)" + }, + { + "name": "fr-FR", + "displayName": "French (France)", + "nativeName": "français (France)" + }, + { + "name": "fr-GA", + "displayName": "français (Gabon)", + "nativeName": "français (Gabon)" + }, + { + "name": "fr-GF", + "displayName": "français (Guyane française)", + "nativeName": "français (Guyane française)" + }, + { + "name": "fr-GN", + "displayName": "français (Guinée)", + "nativeName": "français (Guinée)" + }, + { + "name": "fr-GP", + "displayName": "français (Guadeloupe)", + "nativeName": "français (Guadeloupe)" + }, + { + "name": "fr-GQ", + "displayName": "français (Guinée équatoriale)", + "nativeName": "français (Guinée équatoriale)" + }, + { + "name": "fr-HT", + "displayName": "French (Haiti)", + "nativeName": "français (Haïti)" + }, + { + "name": "fr-KM", + "displayName": "français (Comores)", + "nativeName": "français (Comores)" + }, + { + "name": "fr-LU", + "displayName": "French (Luxembourg)", + "nativeName": "français (Luxembourg)" + }, + { + "name": "fr-MA", + "displayName": "French (Morocco)", + "nativeName": "français (Maroc)" + }, + { + "name": "fr-MC", + "displayName": "French (Monaco)", + "nativeName": "français (Monaco)" + }, + { + "name": "fr-MF", + "displayName": "français (Saint-Martin)", + "nativeName": "français (Saint-Martin)" + }, + { + "name": "fr-MG", + "displayName": "français (Madagascar)", + "nativeName": "français (Madagascar)" + }, + { + "name": "fr-ML", + "displayName": "French (Mali)", + "nativeName": "français (Mali)" + }, + { + "name": "fr-MQ", + "displayName": "français (Martinique)", + "nativeName": "français (Martinique)" + }, + { + "name": "fr-MR", + "displayName": "français (Mauritanie)", + "nativeName": "français (Mauritanie)" + }, + { + "name": "fr-MU", + "displayName": "français (Maurice)", + "nativeName": "français (Maurice)" + }, + { + "name": "fr-NC", + "displayName": "français (Nouvelle-Calédonie)", + "nativeName": "français (Nouvelle-Calédonie)" + }, + { + "name": "fr-NE", + "displayName": "français (Niger)", + "nativeName": "français (Niger)" + }, + { + "name": "fr-PF", + "displayName": "français (Polynésie française)", + "nativeName": "français (Polynésie française)" + }, + { + "name": "fr-PM", + "displayName": "français (Saint-Pierre-et-Miquelon)", + "nativeName": "français (Saint-Pierre-et-Miquelon)" + }, + { + "name": "fr-RE", + "displayName": "French (Réunion)", + "nativeName": "français (La Réunion)" + }, + { + "name": "fr-RW", + "displayName": "français (Rwanda)", + "nativeName": "français (Rwanda)" + }, + { + "name": "fr-SC", + "displayName": "français (Seychelles)", + "nativeName": "français (Seychelles)" + }, + { + "name": "fr-SN", + "displayName": "French (Senegal)", + "nativeName": "français (Sénégal)" + }, + { + "name": "fr-SY", + "displayName": "français (Syrie)", + "nativeName": "français (Syrie)" + }, + { + "name": "fr-TD", + "displayName": "français (Tchad)", + "nativeName": "français (Tchad)" + }, + { + "name": "fr-TG", + "displayName": "français (Togo)", + "nativeName": "français (Togo)" + }, + { + "name": "fr-TN", + "displayName": "français (Tunisie)", + "nativeName": "français (Tunisie)" + }, + { + "name": "fr-VU", + "displayName": "français (Vanuatu)", + "nativeName": "français (Vanuatu)" + }, + { + "name": "fr-WF", + "displayName": "français (Wallis-et-Futuna)", + "nativeName": "français (Wallis-et-Futuna)" + }, + { + "name": "fr-YT", + "displayName": "français (Mayotte)", + "nativeName": "français (Mayotte)" + }, + { + "name": "fur-IT", + "displayName": "furlan (Italie)", + "nativeName": "furlan (Italie)" + }, + { + "name": "fy-NL", + "displayName": "Western Frisian (Netherlands)", + "nativeName": "Frysk (Nederlân)" + }, + { + "name": "ga-IE", + "displayName": "Irish (Ireland)", + "nativeName": "Gaeilge (Éire)" + }, + { + "name": "gd-GB", + "displayName": "Scottish Gaelic (United Kingdom)", + "nativeName": "Gàidhlig (An Rìoghachd Aonaichte)" + }, + { + "name": "gl-ES", + "displayName": "Galician (Galician)", + "nativeName": "galego (galego)" + }, + { + "name": "gn-PY", + "displayName": "Guarani (Paraguay)", + "nativeName": "Avañe’ẽ (Paraguái)" + }, + { + "name": "gsw-CH", + "displayName": "Schwiizertüütsch (Schwiiz)", + "nativeName": "Schwiizertüütsch (Schwiiz)" + }, + { + "name": "gsw-FR", + "displayName": "Alsatian (France)", + "nativeName": "Elsässisch (Frànkrisch)" + }, + { + "name": "gsw-LI", + "displayName": "Schwiizertüütsch (Liächteschtäi)", + "nativeName": "Schwiizertüütsch (Liächteschtäi)" + }, + { + "name": "gu-IN", + "displayName": "Gujarati (India)", + "nativeName": "ગુજરાતી (ભારત)" + }, + { + "name": "guz-KE", + "displayName": "Ekegusii (Kenya)", + "nativeName": "Ekegusii (Kenya)" + }, + { + "name": "gv-IM", + "displayName": "Gaelg (Ellan Vannin)", + "nativeName": "Gaelg (Ellan Vannin)" + }, + { + "name": "ha-Latn-GH", + "displayName": "Hausa (Gana)", + "nativeName": "Hausa (Gana)" + }, + { + "name": "ha-Latn-NE", + "displayName": "Hausa (Nijar)", + "nativeName": "Hausa (Nijar)" + }, + { + "name": "ha-Latn-NG", + "displayName": "Hausa (Latin, Nigeria)", + "nativeName": "Hausa (Najeriya)" + }, + { + "name": "haw-US", + "displayName": "Hawaiian (United States)", + "nativeName": "ʻŌlelo Hawaiʻi (ʻAmelika Hui Pū ʻIa)" + }, + { + "name": "he-IL", + "displayName": "Hebrew (Israel)", + "nativeName": "עברית (ישראל)" + }, + { + "name": "hi-IN", + "displayName": "Hindi (India)", + "nativeName": "हिंदी (भारत)" + }, + { + "name": "hr-BA", + "displayName": "Croatian (Bosnia and Herzegovina)", + "nativeName": "hrvatski (Bosna i Hercegovina)" + }, + { + "name": "hr-HR", + "displayName": "Croatian (Croatia)", + "nativeName": "hrvatski (Hrvatska)" + }, + { + "name": "hsb-DE", + "displayName": "Upper Sorbian (Germany)", + "nativeName": "hornjoserbšćina (Němska)" + }, + { + "name": "hu-HU", + "displayName": "Hungarian (Hungary)", + "nativeName": "magyar (Magyarország)" + }, + { + "name": "hy-AM", + "displayName": "Armenian (Armenia)", + "nativeName": "Հայերեն (Հայաստան)" + }, + { + "name": "ia-001", + "displayName": "interlingua (World)", + "nativeName": "interlingua (World)" + }, + { + "name": "ia-FR", + "displayName": "interlingua (Francia)", + "nativeName": "interlingua (Francia)" + }, + { + "name": "ibb-NG", + "displayName": "Ibibio (Nigeria)", + "nativeName": "Ibibio-Efik (Nigeria)" + }, + { + "name": "id-ID", + "displayName": "Indonesian (Indonesia)", + "nativeName": "Indonesia (Indonesia)" + }, + { + "name": "ig-NG", + "displayName": "Igbo (Nigeria)", + "nativeName": "Igbo (Nigeria)" + }, + { + "name": "ii-CN", + "displayName": "Yi (China)", + "nativeName": "ꆈꌠꁱꂷ (ꍏꉸꏓꂱꇭꉼꇩ)" + }, + { + "name": "is-IS", + "displayName": "Icelandic (Iceland)", + "nativeName": "íslenska (Ísland)" + }, + { + "name": "it-CH", + "displayName": "Italian (Switzerland)", + "nativeName": "italiano (Svizzera)" + }, + { + "name": "it-IT", + "displayName": "Italian (Italy)", + "nativeName": "italiano (Italia)" + }, + { + "name": "it-SM", + "displayName": "italiano (San Marino)", + "nativeName": "italiano (San Marino)" + }, + { + "name": "it-VA", + "displayName": "italiano (Città del Vaticano)", + "nativeName": "italiano (Città del Vaticano)" + }, + { + "name": "iu-Cans-CA", + "displayName": "Inuktitut (Syllabics, Canada)", + "nativeName": "ᐃᓄᒃᑎᑐᑦ (ᑲᓇᑕᒥ)" + }, + { + "name": "iu-Latn-CA", + "displayName": "Inuktitut (Latin, Canada)", + "nativeName": "Inuktitut (Kanatami)" + }, + { + "name": "ja-JP", + "displayName": "Japanese (Japan)", + "nativeName": "日本語 (日本)" + }, + { + "name": "jgo-CM", + "displayName": "Ndaꞌa (Kamɛlûn)", + "nativeName": "Ndaꞌa (Kamɛlûn)" + }, + { + "name": "jmc-TZ", + "displayName": "Kimachame (Tanzania)", + "nativeName": "Kimachame (Tanzania)" + }, + { + "name": "jv-Java-ID", + "displayName": "ꦧꦱꦗꦮ (Indonesia)", + "nativeName": "ꦧꦱꦗꦮ (Indonesia)" + }, + { + "name": "jv-Latn-ID", + "displayName": "Basa Jawa (Indonesia)", + "nativeName": "Basa Jawa (Indonesia)" + }, + { + "name": "ka-GE", + "displayName": "Georgian (Georgia)", + "nativeName": "ქართული (საქართველო)" + }, + { + "name": "kab-DZ", + "displayName": "Taqbaylit (Lezzayer)", + "nativeName": "Taqbaylit (Lezzayer)" + }, + { + "name": "kam-KE", + "displayName": "Kikamba (Kenya)", + "nativeName": "Kikamba (Kenya)" + }, + { + "name": "kde-TZ", + "displayName": "Chimakonde (Tanzania)", + "nativeName": "Chimakonde (Tanzania)" + }, + { + "name": "kea-CV", + "displayName": "kabuverdianu (Kabu Verdi)", + "nativeName": "kabuverdianu (Kabu Verdi)" + }, + { + "name": "khq-ML", + "displayName": "Koyra ciini (Maali)", + "nativeName": "Koyra ciini (Maali)" + }, + { + "name": "ki-KE", + "displayName": "Gikuyu (Kenya)", + "nativeName": "Gikuyu (Kenya)" + }, + { + "name": "kk-KZ", + "displayName": "Kazakh (Kazakhstan)", + "nativeName": "қазақ тілі (Қазақстан)" + }, + { + "name": "kkj-CM", + "displayName": "kakɔ (Kamɛrun)", + "nativeName": "kakɔ (Kamɛrun)" + }, + { + "name": "kl-GL", + "displayName": "Greenlandic (Greenland)", + "nativeName": "kalaallisut (Kalaallit Nunaat)" + }, + { + "name": "kln-KE", + "displayName": "Kalenjin (Emetab Kenya)", + "nativeName": "Kalenjin (Emetab Kenya)" + }, + { + "name": "km-KH", + "displayName": "Khmer (Cambodia)", + "nativeName": "ភាសាខ្មែរ (កម្ពុជា)" + }, + { + "name": "kn-IN", + "displayName": "Kannada (India)", + "nativeName": "ಕನ್ನಡ (ಭಾರತ)" + }, + { + "name": "ko-KP", + "displayName": "한국어 (조선민주주의인민공화국)", + "nativeName": "한국어 (조선민주주의인민공화국)" + }, + { + "name": "ko-KR", + "displayName": "Korean (Korea)", + "nativeName": "한국어(대한민국)" + }, + { + "name": "kok-IN", + "displayName": "Konkani (India)", + "nativeName": "कोंकणी (भारत)" + }, + { + "name": "kr-NG", + "displayName": "Kanuri (Nigeria)", + "nativeName": "Kanuri (Nigeria)" + }, + { + "name": "ks-Arab-IN", + "displayName": "کٲشُر (اَربی)", + "nativeName": "کٲشُر (اَربی)" + }, + { + "name": "ks-Deva-IN", + "displayName": "Kashmiri (Devanagari)", + "nativeName": "कॉशुर" + }, + { + "name": "ksb-TZ", + "displayName": "Kishambaa (Tanzania)", + "nativeName": "Kishambaa (Tanzania)" + }, + { + "name": "ksf-CM", + "displayName": "rikpa (kamɛrún)", + "nativeName": "rikpa (kamɛrún)" + }, + { + "name": "ksh-DE", + "displayName": "Kölsch (Doütschland)", + "nativeName": "Kölsch (Doütschland)" + }, + { + "name": "ku-Arab-IQ", + "displayName": "Central Kurdish (Iraq)", + "nativeName": "کوردیی ناوەڕاست (عێراق)" + }, + { + "name": "ku-Arab-IR", + "displayName": "کوردی (ئێران)", + "nativeName": "کوردی (ئێران)" + }, + { + "name": "kw-GB", + "displayName": "kernewek (Rywvaneth Unys)", + "nativeName": "kernewek (Rywvaneth Unys)" + }, + { + "name": "ky-KG", + "displayName": "Kyrgyz (Kyrgyzstan)", + "nativeName": "Кыргыз (Кыргызстан)" + }, + { + "name": "la-001", + "displayName": "Latin (World)", + "nativeName": "lingua latīna (World)" + }, + { + "name": "lag-TZ", + "displayName": "Kɨlaangi (Taansanía)", + "nativeName": "Kɨlaangi (Taansanía)" + }, + { + "name": "lb-LU", + "displayName": "Luxembourgish (Luxembourg)", + "nativeName": "Lëtzebuergesch (Lëtzebuerg)" + }, + { + "name": "lg-UG", + "displayName": "Luganda (Yuganda)", + "nativeName": "Luganda (Yuganda)" + }, + { + "name": "lkt-US", + "displayName": "Lakȟólʼiyapi (Mílahaŋska Tȟamákȟočhe)", + "nativeName": "Lakȟólʼiyapi (Mílahaŋska Tȟamákȟočhe)" + }, + { + "name": "ln-AO", + "displayName": "lingála (Angóla)", + "nativeName": "lingála (Angóla)" + }, + { + "name": "ln-CD", + "displayName": "lingála (Republíki ya Kongó Demokratíki)", + "nativeName": "lingála (Republíki ya Kongó Demokratíki)" + }, + { + "name": "ln-CF", + "displayName": "lingála (Repibiki ya Afríka ya Káti)", + "nativeName": "lingála (Repibiki ya Afríka ya Káti)" + }, + { + "name": "ln-CG", + "displayName": "lingála (Kongo)", + "nativeName": "lingála (Kongo)" + }, + { + "name": "lo-LA", + "displayName": "Lao (Laos)", + "nativeName": "ລາວ (ລາວ)" + }, + { + "name": "lrc-IQ", + "displayName": "لۊری شومالی (Iraq)", + "nativeName": "لۊری شومالی (Iraq)" + }, + { + "name": "lrc-IR", + "displayName": "لۊری شومالی (Iran)", + "nativeName": "لۊری شومالی (Iran)" + }, + { + "name": "lt-LT", + "displayName": "Lithuanian (Lithuania)", + "nativeName": "lietuvių (Lietuva)" + }, + { + "name": "lu-CD", + "displayName": "Tshiluba (Ditunga wa Kongu)", + "nativeName": "Tshiluba (Ditunga wa Kongu)" + }, + { + "name": "luo-KE", + "displayName": "Dholuo (Kenya)", + "nativeName": "Dholuo (Kenya)" + }, + { + "name": "luy-KE", + "displayName": "Luluhia (Kenya)", + "nativeName": "Luluhia (Kenya)" + }, + { + "name": "lv-LV", + "displayName": "Latvian (Latvia)", + "nativeName": "latviešu (Latvija)" + }, + { + "name": "mas-KE", + "displayName": "Maa (Kenya)", + "nativeName": "Maa (Kenya)" + }, + { + "name": "mas-TZ", + "displayName": "Maa (Tansania)", + "nativeName": "Maa (Tansania)" + }, + { + "name": "mer-KE", + "displayName": "Kĩmĩrũ (Kenya)", + "nativeName": "Kĩmĩrũ (Kenya)" + }, + { + "name": "mfe-MU", + "displayName": "kreol morisien (Moris)", + "nativeName": "kreol morisien (Moris)" + }, + { + "name": "mg-MG", + "displayName": "Malagasy (Madagasikara)", + "nativeName": "Malagasy (Madagasikara)" + }, + { + "name": "mgh-MZ", + "displayName": "Makua (Umozambiki)", + "nativeName": "Makua (Umozambiki)" + }, + { + "name": "mgo-CM", + "displayName": "metaʼ (Kamalun)", + "nativeName": "metaʼ (Kamalun)" + }, + { + "name": "mi-NZ", + "displayName": "Maori (New Zealand)", + "nativeName": "Reo Māori (Aotearoa)" + }, + { + "name": "mk-MK", + "displayName": "Macedonian (Macedonia, FYRO)", + "nativeName": "македонски (Република Македонија)" + }, + { + "name": "ml-IN", + "displayName": "Malayalam (India)", + "nativeName": "മലയാളം (ഇന്ത്യ)" + }, + { + "name": "mn-MN", + "displayName": "Mongolian (Mongolia)", + "nativeName": "монгол (Монгол)" + }, + { + "name": "mn-Mong-CN", + "displayName": "Mongolian (Traditional Mongolian, China)", + "nativeName": "ᠮᠣᠩᠭᠣᠤᠯ ᠬᠡᠯᠡ (ᠪᠦᠭᠦᠳᠡ ᠨᠠᠢᠷᠠᠮᠳᠠᠬᠤ ᠳᠤᠮᠳᠠᠳᠤ ᠠᠷᠠᠳ ᠣᠯᠣᠰ)" + }, + { + "name": "mn-Mong-MN", + "displayName": "Mongolian (Traditional Mongolian, Mongolia)", + "nativeName": "ᠮᠣᠩᠭᠣᠯ ᠬᠡᠯᠡ (ᠮᠣᠩᠭᠣᠯ ᠣᠯᠣᠰ)" + }, + { + "name": "mni-IN", + "displayName": "Manipuri (India)", + "nativeName": "মৈতৈলোন্ (India)" + }, + { + "name": "moh-CA", + "displayName": "Mohawk (Mohawk)", + "nativeName": "Kanien'kéha" + }, + { + "name": "mr-IN", + "displayName": "Marathi (India)", + "nativeName": "मराठी (भारत)" + }, + { + "name": "ms-BN", + "displayName": "Malay (Brunei)", + "nativeName": "Bahasa Melayu (Brunei)" + }, + { + "name": "ms-MY", + "displayName": "Malay (Malaysia)", + "nativeName": "Bahasa Melayu (Malaysia)" + }, + { + "name": "ms-SG", + "displayName": "Bahasa Melayu (Singapura)", + "nativeName": "Bahasa Melayu (Singapura)" + }, + { + "name": "mt-MT", + "displayName": "Maltese (Malta)", + "nativeName": "Malti (Malta)" + }, + { + "name": "mua-CM", + "displayName": "MUNDAŊ (kameruŋ)", + "nativeName": "MUNDAŊ (kameruŋ)" + }, + { + "name": "my-MM", + "displayName": "Burmese (Myanmar)", + "nativeName": "မြန်မာ (မြန်မာ)" + }, + { + "name": "mzn-IR", + "displayName": "مازرونی (ایران)", + "nativeName": "مازرونی (ایران)" + }, + { + "name": "naq-NA", + "displayName": "Khoekhoegowab (Namibiab)", + "nativeName": "Khoekhoegowab (Namibiab)" + }, + { + "name": "nb-NO", + "displayName": "Norwegian Bokmål (Norway)", + "nativeName": "norsk bokmål (Norge)" + }, + { + "name": "nb-SJ", + "displayName": "norsk bokmål (Svalbard og Jan Mayen)", + "nativeName": "norsk bokmål (Svalbard og Jan Mayen)" + }, + { + "name": "nd-ZW", + "displayName": "isiNdebele (Zimbabwe)", + "nativeName": "isiNdebele (Zimbabwe)" + }, + { + "name": "nds-DE", + "displayName": "Neddersass’sch (Düütschland)", + "nativeName": "Neddersass’sch (Düütschland)" + }, + { + "name": "nds-NL", + "displayName": "Neddersass’sch (Nedderlannen)", + "nativeName": "Neddersass’sch (Nedderlannen)" + }, + { + "name": "ne-IN", + "displayName": "Nepali (India)", + "nativeName": "नेपाली (भारत)" + }, + { + "name": "ne-NP", + "displayName": "Nepali (Nepal)", + "nativeName": "नेपाली (नेपाल)" + }, + { + "name": "nl-AW", + "displayName": "Nederlands (Aruba)", + "nativeName": "Nederlands (Aruba)" + }, + { + "name": "nl-BE", + "displayName": "Dutch (Belgium)", + "nativeName": "Nederlands (België)" + }, + { + "name": "nl-BQ", + "displayName": "Nederlands (Bonaire, Sint Eustatius en Saba)", + "nativeName": "Nederlands (Bonaire, Sint Eustatius en Saba)" + }, + { + "name": "nl-CW", + "displayName": "Nederlands (Curaçao)", + "nativeName": "Nederlands (Curaçao)" + }, + { + "name": "nl-NL", + "displayName": "Dutch (Netherlands)", + "nativeName": "Nederlands (Nederland)" + }, + { + "name": "nl-SR", + "displayName": "Nederlands (Suriname)", + "nativeName": "Nederlands (Suriname)" + }, + { + "name": "nl-SX", + "displayName": "Nederlands (Sint-Maarten)", + "nativeName": "Nederlands (Sint-Maarten)" + }, + { + "name": "nmg-CM", + "displayName": "Kwasio (Kamerun)", + "nativeName": "Kwasio (Kamerun)" + }, + { + "name": "nn-NO", + "displayName": "Norwegian Nynorsk (Norway)", + "nativeName": "nynorsk (Noreg)" + }, + { + "name": "nnh-CM", + "displayName": "Shwóŋò ngiembɔɔn (Kàmalûm)", + "nativeName": "Shwóŋò ngiembɔɔn (Kàmalûm)" + }, + { + "name": "nqo-GN", + "displayName": "ߒߞߏ (ߖߌ߬ߣߍ߬ ߞߊ߲ߓߍ߲)", + "nativeName": "ߒߞߏ (ߖߌ߬ߣߍ߬ ߞߊ߲ߓߍ߲)" + }, + { + "name": "nr-ZA", + "displayName": "isiNdebele (South Africa)", + "nativeName": "isiNdebele (South Africa)" + }, + { + "name": "nso-ZA", + "displayName": "Sesotho sa Leboa (South Africa)", + "nativeName": "Sesotho sa Leboa (Afrika Borwa)" + }, + { + "name": "nus-SS", + "displayName": "Thok Nath (South Sudan)", + "nativeName": "Thok Nath (South Sudan)" + }, + { + "name": "nyn-UG", + "displayName": "Runyankore (Uganda)", + "nativeName": "Runyankore (Uganda)" + }, + { + "name": "oc-FR", + "displayName": "Occitan (France)", + "nativeName": "Occitan (França)" + }, + { + "name": "om-ET", + "displayName": "Oromo (Ethiopia)", + "nativeName": "Oromoo (Itoophiyaa)" + }, + { + "name": "om-KE", + "displayName": "Oromoo (Keeniyaa)", + "nativeName": "Oromoo (Keeniyaa)" + }, + { + "name": "or-IN", + "displayName": "Odia (India)", + "nativeName": "ଓଡ଼ିଆ (ଭାରତ)" + }, + { + "name": "os-GE", + "displayName": "ирон (Гуырдзыстон)", + "nativeName": "ирон (Гуырдзыстон)" + }, + { + "name": "os-RU", + "displayName": "ирон (Уӕрӕсе)", + "nativeName": "ирон (Уӕрӕсе)" + }, + { + "name": "pa-Arab-PK", + "displayName": "Punjabi (Pakistan)", + "nativeName": "پنجابی (پاکستان)" + }, + { + "name": "pa-IN", + "displayName": "Punjabi (India)", + "nativeName": "ਪੰਜਾਬੀ (ਭਾਰਤ)" + }, + { + "name": "pap-029", + "displayName": "Papiamento (Caribbean)", + "nativeName": "Papiamentu (Caribbean)" + }, + { + "name": "pl-PL", + "displayName": "Polish (Poland)", + "nativeName": "polski (Polska)" + }, + { + "name": "prg-001", + "displayName": "prūsiskan (swītai)", + "nativeName": "prūsiskan (swītai)" + }, + { + "name": "prs-AF", + "displayName": "Dari (Afghanistan)", + "nativeName": "درى (افغانستان)" + }, + { + "name": "ps-AF", + "displayName": "Pashto (Afghanistan)", + "nativeName": "پښتو (افغانستان)" + }, + { + "name": "pt-AO", + "displayName": "português (Angola)", + "nativeName": "português (Angola)" + }, + { + "name": "pt-BR", + "displayName": "Portuguese (Brazil)", + "nativeName": "português (Brasil)" + }, + { + "name": "pt-CH", + "displayName": "português (Suíça)", + "nativeName": "português (Suíça)" + }, + { + "name": "pt-CV", + "displayName": "português (Cabo Verde)", + "nativeName": "português (Cabo Verde)" + }, + { + "name": "pt-GQ", + "displayName": "português (Guiné Equatorial)", + "nativeName": "português (Guiné Equatorial)" + }, + { + "name": "pt-GW", + "displayName": "português (Guiné-Bissau)", + "nativeName": "português (Guiné-Bissau)" + }, + { + "name": "pt-LU", + "displayName": "português (Luxemburgo)", + "nativeName": "português (Luxemburgo)" + }, + { + "name": "pt-MO", + "displayName": "português (RAE de Macau)", + "nativeName": "português (RAE de Macau)" + }, + { + "name": "pt-MZ", + "displayName": "português (Moçambique)", + "nativeName": "português (Moçambique)" + }, + { + "name": "pt-PT", + "displayName": "Portuguese (Portugal)", + "nativeName": "português (Portugal)" + }, + { + "name": "pt-ST", + "displayName": "português (São Tomé e Príncipe)", + "nativeName": "português (São Tomé e Príncipe)" + }, + { + "name": "pt-TL", + "displayName": "português (Timor-Leste)", + "nativeName": "português (Timor-Leste)" + }, + { + "name": "quc-Latn-GT", + "displayName": "K'iche' (Guatemala)", + "nativeName": "K'iche' (Guatemala)" + }, + { + "name": "quz-BO", + "displayName": "Quechua (Bolivia)", + "nativeName": "Runasimi (Bolivia)" + }, + { + "name": "quz-EC", + "displayName": "Quichua (Ecuador)", + "nativeName": "Runasimi (Ecuador)" + }, + { + "name": "quz-PE", + "displayName": "Quechua (Peru)", + "nativeName": "Runasimi (Perú)" + }, + { + "name": "rm-CH", + "displayName": "Romansh (Switzerland)", + "nativeName": "rumantsch (Svizra)" + }, + { + "name": "rn-BI", + "displayName": "Ikirundi (Uburundi)", + "nativeName": "Ikirundi (Uburundi)" + }, + { + "name": "ro-MD", + "displayName": "Romanian (Moldova)", + "nativeName": "română (Republica Moldova)" + }, + { + "name": "ro-RO", + "displayName": "Romanian (Romania)", + "nativeName": "română (România)" + }, + { + "name": "rof-TZ", + "displayName": "Kihorombo (Tanzania)", + "nativeName": "Kihorombo (Tanzania)" + }, + { + "name": "ru-BY", + "displayName": "русский (Беларусь)", + "nativeName": "русский (Беларусь)" + }, + { + "name": "ru-KG", + "displayName": "русский (Киргизия)", + "nativeName": "русский (Киргизия)" + }, + { + "name": "ru-KZ", + "displayName": "русский (Казахстан)", + "nativeName": "русский (Казахстан)" + }, + { + "name": "ru-MD", + "displayName": "Russian (Moldova)", + "nativeName": "русский (Молдова)" + }, + { + "name": "ru-RU", + "displayName": "Russian (Russia)", + "nativeName": "русский (Россия)" + }, + { + "name": "ru-UA", + "displayName": "русский (Украина)", + "nativeName": "русский (Украина)" + }, + { + "name": "rw-RW", + "displayName": "Kinyarwanda (Rwanda)", + "nativeName": "Kinyarwanda (Rwanda)" + }, + { + "name": "rwk-TZ", + "displayName": "Kiruwa (Tanzania)", + "nativeName": "Kiruwa (Tanzania)" + }, + { + "name": "sa-IN", + "displayName": "Sanskrit (India)", + "nativeName": "संस्कृत (भारतम्)" + }, + { + "name": "sah-RU", + "displayName": "Sakha (Russia)", + "nativeName": "Саха (Россия)" + }, + { + "name": "saq-KE", + "displayName": "Kisampur (Kenya)", + "nativeName": "Kisampur (Kenya)" + }, + { + "name": "sbp-TZ", + "displayName": "Ishisangu (Tansaniya)", + "nativeName": "Ishisangu (Tansaniya)" + }, + { + "name": "sd-Arab-PK", + "displayName": "Sindhi (Pakistan)", + "nativeName": "سنڌي (پاکستان)" + }, + { + "name": "sd-Deva-IN", + "displayName": "Sindhi (Devanagari, India)", + "nativeName": "सिन्धी (India)" + }, + { + "name": "se-FI", + "displayName": "Sami, Northern (Finland)", + "nativeName": "davvisámegiella (Suopma)" + }, + { + "name": "se-NO", + "displayName": "Sami, Northern (Norway)", + "nativeName": "davvisámegiella (Norga)" + }, + { + "name": "se-SE", + "displayName": "Sami, Northern (Sweden)", + "nativeName": "davvisámegiella (Ruoŧŧa)" + }, + { + "name": "seh-MZ", + "displayName": "sena (Moçambique)", + "nativeName": "sena (Moçambique)" + }, + { + "name": "ses-ML", + "displayName": "Koyraboro senni (Maali)", + "nativeName": "Koyraboro senni (Maali)" + }, + { + "name": "sg-CF", + "displayName": "Sängö (Ködörösêse tî Bêafrîka)", + "nativeName": "Sängö (Ködörösêse tî Bêafrîka)" + }, + { + "name": "shi-Latn-MA", + "displayName": "Tashelḥiyt (lmɣrib)", + "nativeName": "Tashelḥiyt (lmɣrib)" + }, + { + "name": "shi-Tfng-MA", + "displayName": "ⵜⴰⵛⵍⵃⵉⵜ (ⵍⵎⵖⵔⵉⴱ)", + "nativeName": "ⵜⴰⵛⵍⵃⵉⵜ (ⵍⵎⵖⵔⵉⴱ)" + }, + { + "name": "si-LK", + "displayName": "Sinhala (Sri Lanka)", + "nativeName": "සිංහල (ශ්‍රී ලංකාව)" + }, + { + "name": "sk-SK", + "displayName": "Slovak (Slovakia)", + "nativeName": "slovenčina (Slovensko)" + }, + { + "name": "sl-SI", + "displayName": "Slovenian (Slovenia)", + "nativeName": "slovenščina (Slovenija)" + }, + { + "name": "sma-NO", + "displayName": "Sami, Southern (Norway)", + "nativeName": "åarjelsaemiengïele (Nöörje)" + }, + { + "name": "sma-SE", + "displayName": "Sami, Southern (Sweden)", + "nativeName": "åarjelsaemiengïele (Sveerje)" + }, + { + "name": "smj-NO", + "displayName": "Sami, Lule (Norway)", + "nativeName": "julevusámegiella (Vuodna)" + }, + { + "name": "smj-SE", + "displayName": "Sami, Lule (Sweden)", + "nativeName": "julevusámegiella (Svierik)" + }, + { + "name": "smn-FI", + "displayName": "Sami, Inari (Finland)", + "nativeName": "anarâškielâ (Suomâ)" + }, + { + "name": "sms-FI", + "displayName": "Sami, Skolt (Finland)", + "nativeName": "sää´mǩiõll (Lää´ddjânnam)" + }, + { + "name": "sn-Latn-ZW", + "displayName": "chiShona (Zimbabwe)", + "nativeName": "chiShona (Zimbabwe)" + }, + { + "name": "so-DJ", + "displayName": "Soomaali (Jabuuti)", + "nativeName": "Soomaali (Jabuuti)" + }, + { + "name": "so-ET", + "displayName": "Soomaali (Itoobiya)", + "nativeName": "Soomaali (Itoobiya)" + }, + { + "name": "so-KE", + "displayName": "Soomaali (Kiiniya)", + "nativeName": "Soomaali (Kiiniya)" + }, + { + "name": "so-SO", + "displayName": "Somali (Somalia)", + "nativeName": "Soomaali (Soomaaliya)" + }, + { + "name": "sq-AL", + "displayName": "Albanian (Albania)", + "nativeName": "shqip (Shqipëri)" + }, + { + "name": "sq-MK", + "displayName": "shqip (Republika e Maqedonisë)", + "nativeName": "shqip (Republika e Maqedonisë)" + }, + { + "name": "sq-XK", + "displayName": "shqip (Kosovë)", + "nativeName": "shqip (Kosovë)" + }, + { + "name": "sr-Cyrl-BA", + "displayName": "Serbian (Cyrillic, Bosnia and Herzegovina)", + "nativeName": "српски (Босна и Херцеговина)" + }, + { + "name": "sr-Cyrl-ME", + "displayName": "Serbian (Cyrillic, Montenegro)", + "nativeName": "српски (Црна Гора)" + }, + { + "name": "sr-Cyrl-RS", + "displayName": "Serbian (Cyrillic, Serbia)", + "nativeName": "српски (Србија)" + }, + { + "name": "sr-Cyrl-XK", + "displayName": "српски (Косово)", + "nativeName": "српски (Косово)" + }, + { + "name": "sr-Latn-BA", + "displayName": "Serbian (Latin, Bosnia and Herzegovina)", + "nativeName": "srpski (Bosna i Hercegovina)" + }, + { + "name": "sr-Latn-ME", + "displayName": "Serbian (Latin, Montenegro)", + "nativeName": "srpski (Crna Gora)" + }, + { + "name": "sr-Latn-RS", + "displayName": "Serbian (Latin, Serbia)", + "nativeName": "srpski (Srbija)" + }, + { + "name": "sr-Latn-XK", + "displayName": "srpski (Kosovo)", + "nativeName": "srpski (Kosovo)" + }, + { + "name": "ss-SZ", + "displayName": "siSwati (Swaziland)", + "nativeName": "siSwati (Swaziland)" + }, + { + "name": "ss-ZA", + "displayName": "siSwati (South Africa)", + "nativeName": "siSwati (South Africa)" + }, + { + "name": "ssy-ER", + "displayName": "Saho (Eretria)", + "nativeName": "Saho (Eretria)" + }, + { + "name": "st-LS", + "displayName": "Sesotho (Lesotho)", + "nativeName": "Sesotho (Lesotho)" + }, + { + "name": "st-ZA", + "displayName": "Sesotho (South Africa)", + "nativeName": "Sesotho (South Africa)" + }, + { + "name": "sv-AX", + "displayName": "svenska (Åland)", + "nativeName": "svenska (Åland)" + }, + { + "name": "sv-FI", + "displayName": "Swedish (Finland)", + "nativeName": "svenska (Finland)" + }, + { + "name": "sv-SE", + "displayName": "Swedish (Sweden)", + "nativeName": "svenska (Sverige)" + }, + { + "name": "sw-CD", + "displayName": "Kiswahili (Jamhuri ya Kidemokrasia ya Kongo)", + "nativeName": "Kiswahili (Jamhuri ya Kidemokrasia ya Kongo)" + }, + { + "name": "sw-KE", + "displayName": "Kiswahili (Kenya)", + "nativeName": "Kiswahili (Kenya)" + }, + { + "name": "sw-TZ", + "displayName": "Kiswahili (Tanzania)", + "nativeName": "Kiswahili (Tanzania)" + }, + { + "name": "sw-UG", + "displayName": "Kiswahili (Uganda)", + "nativeName": "Kiswahili (Uganda)" + }, + { + "name": "syr-SY", + "displayName": "Syriac (Syria)", + "nativeName": "ܣܘܪܝܝܐ (ܣܘܪܝܐ)" + }, + { + "name": "ta-IN", + "displayName": "Tamil (India)", + "nativeName": "தமிழ் (இந்தியா)" + }, + { + "name": "ta-LK", + "displayName": "Tamil (Sri Lanka)", + "nativeName": "தமிழ் (இலங்கை)" + }, + { + "name": "ta-MY", + "displayName": "தமிழ் (மலேசியா)", + "nativeName": "தமிழ் (மலேசியா)" + }, + { + "name": "ta-SG", + "displayName": "தமிழ் (சிங்கப்பூர்)", + "nativeName": "தமிழ் (சிங்கப்பூர்)" + }, + { + "name": "te-IN", + "displayName": "Telugu (India)", + "nativeName": "తెలుగు (భారత దేశం)" + }, + { + "name": "teo-KE", + "displayName": "Kiteso (Kenia)", + "nativeName": "Kiteso (Kenia)" + }, + { + "name": "teo-UG", + "displayName": "Kiteso (Uganda)", + "nativeName": "Kiteso (Uganda)" + }, + { + "name": "tg-Cyrl-TJ", + "displayName": "Tajik (Cyrillic, Tajikistan)", + "nativeName": "тоҷикӣ (Тоҷикистон)" + }, + { + "name": "th-TH", + "displayName": "Thai (Thailand)", + "nativeName": "ไทย (ไทย)" + }, + { + "name": "ti-ER", + "displayName": "Tigrinya (Eritrea)", + "nativeName": "ትግርኛ (ኤርትራ)" + }, + { + "name": "ti-ET", + "displayName": "Tigrinya (Ethiopia)", + "nativeName": "ትግርኛ (ኢትዮጵያ)" + }, + { + "name": "tig-ER", + "displayName": "ትግረ (ኤርትራ)", + "nativeName": "ትግረ (ኤርትራ)" + }, + { + "name": "tk-TM", + "displayName": "Turkmen (Turkmenistan)", + "nativeName": "Türkmen dili (Türkmenistan)" + }, + { + "name": "tn-BW", + "displayName": "Setswana (Botswana)", + "nativeName": "Setswana (Botswana)" + }, + { + "name": "tn-ZA", + "displayName": "Setswana (South Africa)", + "nativeName": "Setswana (Aforika Borwa)" + }, + { + "name": "to-TO", + "displayName": "lea fakatonga (Tonga)", + "nativeName": "lea fakatonga (Tonga)" + }, + { + "name": "tr-CY", + "displayName": "Türkçe (Kıbrıs)", + "nativeName": "Türkçe (Kıbrıs)" + }, + { + "name": "tr-TR", + "displayName": "Turkish (Turkey)", + "nativeName": "Türkçe (Türkiye)" + }, + { + "name": "ts-ZA", + "displayName": "Xitsonga (South Africa)", + "nativeName": "Xitsonga (South Africa)" + }, + { + "name": "tt-RU", + "displayName": "Tatar (Russia)", + "nativeName": "Татар (Россия)" + }, + { + "name": "twq-NE", + "displayName": "Tasawaq senni (Nižer)", + "nativeName": "Tasawaq senni (Nižer)" + }, + { + "name": "tzm-Arab-MA", + "displayName": "Central Atlas Tamazight (Arabic, Morocco)", + "nativeName": "أطلس المركزية التامازيتية (Morocco)" + }, + { + "name": "tzm-Latn-DZ", + "displayName": "Central Atlas Tamazight (Latin, Algeria)", + "nativeName": "Tamaziɣt n laṭlaṣ (Djazaïr)" + }, + { + "name": "tzm-Latn-MA", + "displayName": "Tamaziɣt n laṭlaṣ (Meṛṛuk)", + "nativeName": "Tamaziɣt n laṭlaṣ (Meṛṛuk)" + }, + { + "name": "tzm-Tfng-MA", + "displayName": "Central Atlas Tamazight (Tifinagh, Morocco)", + "nativeName": "ⵜⴰⵎⴰⵣⵉⵖⵜ (ⵍⵎⵖⵔⵉⴱ)" + }, + { + "name": "ug-CN", + "displayName": "Uyghur (China)", + "nativeName": "ئۇيغۇرچە (جۇڭخۇا خەلق جۇمھۇرىيىتى)" + }, + { + "name": "uk-UA", + "displayName": "Ukrainian (Ukraine)", + "nativeName": "українська (Україна)" + }, + { + "name": "ur-IN", + "displayName": "Urdu (India)", + "nativeName": "اردو (بھارت)" + }, + { + "name": "ur-PK", + "displayName": "Urdu (Pakistan)", + "nativeName": "اُردو (پاکستان)" + }, + { + "name": "uz-Arab-AF", + "displayName": "اوزبیک (افغانستان)", + "nativeName": "اوزبیک (افغانستان)" + }, + { + "name": "uz-Cyrl-UZ", + "displayName": "Uzbek (Cyrillic, Uzbekistan)", + "nativeName": "ўзбекча (Ўзбекистон)" + }, + { + "name": "uz-Latn-UZ", + "displayName": "Uzbek (Latin, Uzbekistan)", + "nativeName": "o‘zbek (Oʻzbekiston)" + }, + { + "name": "vai-Latn-LR", + "displayName": "Vai (Laibhiya)", + "nativeName": "Vai (Laibhiya)" + }, + { + "name": "vai-Vaii-LR", + "displayName": "ꕙꔤ (ꕞꔤꔫꕩ)", + "nativeName": "ꕙꔤ (ꕞꔤꔫꕩ)" + }, + { + "name": "ve-ZA", + "displayName": "Venda (South Africa)", + "nativeName": "Tshivenḓa (South Africa)" + }, + { + "name": "vi-VN", + "displayName": "Vietnamese (Vietnam)", + "nativeName": "Tiếng Việt (Việt Nam)" + }, + { + "name": "vo-001", + "displayName": "Volapük (World)", + "nativeName": "Volapük (World)" + }, + { + "name": "vun-TZ", + "displayName": "Kyivunjo (Tanzania)", + "nativeName": "Kyivunjo (Tanzania)" + }, + { + "name": "wae-CH", + "displayName": "Walser (Schwiz)", + "nativeName": "Walser (Schwiz)" + }, + { + "name": "wal-ET", + "displayName": "ወላይታቱ (ኢትዮጵያ)", + "nativeName": "ወላይታቱ (ኢትዮጵያ)" + }, + { + "name": "wo-SN", + "displayName": "Wolof (Senegal)", + "nativeName": "Wolof (Senegaal)" + }, + { + "name": "xh-ZA", + "displayName": "isiXhosa (South Africa)", + "nativeName": "isiXhosa (eMzantsi Afrika)" + }, + { + "name": "xog-UG", + "displayName": "Olusoga (Yuganda)", + "nativeName": "Olusoga (Yuganda)" + }, + { + "name": "yav-CM", + "displayName": "nuasue (Kemelún)", + "nativeName": "nuasue (Kemelún)" + }, + { + "name": "yi-001", + "displayName": "Yiddish (World)", + "nativeName": "ייִדיש (וועלט)" + }, + { + "name": "yo-BJ", + "displayName": "Èdè Yorùbá (Orílɛ́ède Bɛ̀nɛ̀)", + "nativeName": "Èdè Yorùbá (Orílɛ́ède Bɛ̀nɛ̀)" + }, + { + "name": "yo-NG", + "displayName": "Yoruba (Nigeria)", + "nativeName": "Èdè Yorùbá (Orílẹ́ède Nàìjíríà)" + }, + { + "name": "zgh-Tfng-MA", + "displayName": "ⵜⴰⵎⴰⵣⵉⵖⵜ (ⵍⵎⵖⵔⵉⴱ)", + "nativeName": "ⵜⴰⵎⴰⵣⵉⵖⵜ (ⵍⵎⵖⵔⵉⴱ)" + }, + { + "name": "zh-CN", + "displayName": "Chinese (Simplified, China)", + "nativeName": "中文(中国)" + }, + { + "name": "zh-Hans-HK", + "displayName": "中文 (香港特别行政区)", + "nativeName": "中文 (香港特别行政区)" + }, + { + "name": "zh-Hans-MO", + "displayName": "中文 (澳门特别行政区)", + "nativeName": "中文 (澳门特别行政区)" + }, + { + "name": "zh-HK", + "displayName": "Chinese (Traditional, Hong Kong SAR)", + "nativeName": "中文(香港特別行政區)" + }, + { + "name": "zh-MO", + "displayName": "Chinese (Traditional, Macao SAR)", + "nativeName": "中文(澳門特別行政區)" + }, + { + "name": "zh-SG", + "displayName": "Chinese (Simplified, Singapore)", + "nativeName": "中文(新加坡)" + }, + { + "name": "zh-TW", + "displayName": "Chinese (Traditional, Taiwan)", + "nativeName": "中文(台灣)" + }, + { + "name": "zu-ZA", + "displayName": "isiZulu (South Africa)", + "nativeName": "isiZulu (i-South Africa)" + } +] diff --git a/dmp-frontend/src/assets/resources/language.json b/dmp-frontend/src/assets/resources/language.json new file mode 100644 index 000000000..4bbfac0ab --- /dev/null +++ b/dmp-frontend/src/assets/resources/language.json @@ -0,0 +1,10 @@ +[ + { + "label": "English", + "value": "en" + }, + { + "label": "Greek", + "value": "gr" + } +] diff --git a/dmp-frontend/src/assets/resources/locales.json b/dmp-frontend/src/assets/resources/locales.json new file mode 100644 index 000000000..e69de29bb diff --git a/dmp-frontend/src/environments/environment.prod.ts b/dmp-frontend/src/environments/environment.prod.ts index 7f6a04de0..d22151c52 100644 --- a/dmp-frontend/src/environments/environment.prod.ts +++ b/dmp-frontend/src/environments/environment.prod.ts @@ -1,6 +1,6 @@ export const environment = { production: true, - Server: 'http://localhost:8080/api/', + Server: 'http://dl043.madgik.di.uoa.gr:8080/api/', App: 'http://dl043.madgik.di.uoa.gr/', HelpServiceUrl: 'http://dl043.madgik.di.uoa.gr:5555/' }; diff --git a/dmp-frontend/src/environments/environment.ts b/dmp-frontend/src/environments/environment.ts index 05a577f68..1bcb935b3 100644 --- a/dmp-frontend/src/environments/environment.ts +++ b/dmp-frontend/src/environments/environment.ts @@ -7,5 +7,6 @@ export const environment = { production: false, Server: 'http://devel-21.local.cite.gr:8080/api/', App: 'http://localhost:4200/', - HelpServiceUrl: 'localhost:5000/' + HelpServiceUrl: 'localhost:5000/', + defaultCulture: "en-GB" }; diff --git a/dmp-frontend/src/tsconfig.app.json b/dmp-frontend/src/tsconfig.app.json index 33aace051..d9b21b2b4 100644 --- a/dmp-frontend/src/tsconfig.app.json +++ b/dmp-frontend/src/tsconfig.app.json @@ -3,7 +3,6 @@ "compilerOptions": { "outDir": "../out-tsc/app", "baseUrl": "./", - "module": "es2015", "types": ["node"], "typeRoots": [ "../node_modules/@types" ] },