From cd95dd1d8317464e7c335020532636119ec8f89c Mon Sep 17 00:00:00 2001 From: EL HAJJIOUI Nabil <nabil.elhajjioui@smile.fr> Date: Fri, 29 Oct 2021 12:42:36 +0200 Subject: [PATCH] [VAS] Item 8585 Check rules for archive search (#516) --- .../server/config/ApiIamServerConfig.java | 25 ++- .../client/IamInternalRestClientFactory.java | 1 - .../common/utils/ReferentialDtoBuilder.java | 13 +- .../client/RuleExternalRestClient.java | 38 ++-- .../server/config/ConverterConfig.java | 7 - .../server/rest/RuleInternalController.java | 51 +++-- .../server/rule/RuleInternalService.java | 41 ++-- ...sionRegisterDetailInternalServiceTest.java | 7 +- .../vitamui/commons/rest}/dto/RuleDto.java | 45 +++-- .../api/config/VitamAdministrationConfig.java | 6 + .../api/config/converter}/RuleConverter.java | 10 +- .../api/dto/InheritedRuleCategoryDto.java | 9 +- .../vitam/api/dto/RuleCategoryDto.java | 9 +- .../commons/vitam/api/dto/UnitRuleDto.java | 67 ++++++ .../ui-archive-search/application.yml.j2 | 15 ++ .../ui-identity-admin/application.yml.j2 | 15 ++ .../templates/ui-identity/application.yml.j2 | 15 ++ .../templates/ui-ingest/application.yml.j2 | 15 ++ .../templates/ui-portal/application.yml.j2 | 15 ++ ...ve_search_profile_to_add_rule_access.js.j2 | 50 +++++ ...ve_search_context_to_add_rule_access.js.j2 | 18 ++ .../ApiReferentialExternalRuleCheckSteps.java | 2 +- ...iReferentialExternalRuleCreationSteps.java | 30 ++- ...ApiReferentialExternalRuleDeleteSteps.java | 9 +- .../ApiReferentialExternalRuleGetSteps.java | 6 +- .../ApiReferentialExternalRulePatchSteps.java | 10 +- .../cucumber/common/context/TestContext.java | 2 +- .../fr/gouv/vitamui/utils/FactoryDto.java | 33 ++- .../src/main/resources/application-dev.yml | 16 ++ .../resources/dev/keystore_ui-referential.jks | Bin 0 -> 3865 bytes .../src/test/resources/application.yml | 13 ++ ui/ui-commons/pom.xml | 10 +- .../AutoConfigurationRestController.java | 26 ++- .../config/AutoConfigurationService.java | 13 +- .../config/UICommonsAutoConfiguration.java | 17 ++ .../ui/commons/config/UIPropertiesImpl.java | 2 + .../ui/commons/property/UIProperties.java | 6 +- .../ui/commons/rest/RuleController.java | 191 ++++++++++++++++++ .../ui/commons/service/RuleService.java | 118 +++++++++++ .../UICommonsAutoConfigurationTest.java | 28 ++- .../rest/ApplicationControllerTest.java | 1 + .../commons/rest/SecurityControllerTest.java | 3 +- .../rest/SubrogationControllerTest.java | 28 +-- .../ui/commons/rest/UserControllerTest.java | 41 ++-- .../src/app/modules/api/rule-api.service.ts | 99 +++++++++ .../vitamui-snack-bar.component.html | 51 ++++- .../src/app/modules/index.ts | 2 + .../src/app/modules/models/index.ts | 11 +- .../src/app/modules/models/rule/index.ts | 37 ++++ .../app/modules/models/rule/rule.interface.ts | 52 +++++ .../src/app/modules/rule/index.ts | 37 ++++ .../src/app/modules/rule/rule.service.ts | 181 +++++++++++++++++ .../src/assets/shared-i18n/en.json | 14 +- .../src/assets/shared-i18n/fr.json | 14 +- .../appraisal-rule-search.component.css | 5 + .../appraisal-rule-search.component.html | 37 +++- .../appraisal-rule-search.component.ts | 73 ++++--- .../appraisal-rule-search/rule.validator.ts | 74 +++++++ .../archive-search.component.ts | 11 +- .../src/app/archive/archive.module.ts | 10 +- .../archive-search/src/assets/i18n/en.json | 58 +++--- .../archive-search/src/assets/i18n/fr.json | 60 +++--- .../src/app/core/api/rule-api.service.ts | 37 ++-- .../rule-create/rule-create.component.spec.ts | 110 +++++----- .../rule/rule-create/rule-create.component.ts | 31 ++- .../rule-create/rule-create.validators.ts | 25 +-- .../rule-list/rule-list.component.spec.ts | 42 ++-- .../app/rule/rule-list/rule-list.component.ts | 77 +++---- .../rule-information-tab.component.spec.ts | 33 ++- .../rule-information-tab.component.ts | 74 +++---- .../rule-preview/rule-preview.component.html | 49 +++-- .../rule-preview.component.spec.ts | 27 ++- .../rule-preview/rule-preview.component.ts | 40 ++-- .../src/app/rule/rule.component.ts | 56 +++-- .../referential/src/app/rule/rule.service.ts | 43 ++-- .../src/test/resources/application.yml | 13 ++ .../src/test/resources/application.yml | 13 ++ .../src/main/resources/application-dev.yml | 16 ++ .../resources/dev/keystore_ui-referential.jks | Bin 0 -> 3865 bytes .../src/test/resources/application.yml | 14 +- .../referential/rest/RuleController.java | 63 +++--- .../referential/service/RuleService.java | 31 ++- 82 files changed, 1941 insertions(+), 756 deletions(-) rename commons/{commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api => commons-rest/src/main/java/fr/gouv/vitamui/commons/rest}/dto/RuleDto.java (76%) rename {api/api-referential/referential-internal/src/main/java/fr/gouv/vitamui/referential/internal/server/rule => commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/config/converter}/RuleConverter.java (96%) create mode 100644 commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/dto/UnitRuleDto.java create mode 100644 deployment/scripts/mongod/2.0.0/42_new_update_archive_search_profile_to_add_rule_access.js.j2 create mode 100644 deployment/scripts/mongod/2.0.0/43_new_update_archive_search_context_to_add_rule_access.js.j2 create mode 100644 ui/ui-archive-search/src/main/resources/dev/keystore_ui-referential.jks create mode 100644 ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/rest/RuleController.java create mode 100644 ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/service/RuleService.java create mode 100644 ui/ui-frontend-common/src/app/modules/api/rule-api.service.ts create mode 100644 ui/ui-frontend-common/src/app/modules/models/rule/index.ts create mode 100644 ui/ui-frontend-common/src/app/modules/models/rule/rule.interface.ts create mode 100644 ui/ui-frontend-common/src/app/modules/rule/index.ts create mode 100644 ui/ui-frontend-common/src/app/modules/rule/rule.service.ts create mode 100644 ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/appraisal-rule-search/appraisal-rule-search.component.css create mode 100644 ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/appraisal-rule-search/rule.validator.ts create mode 100644 ui/ui-portal/src/main/resources/dev/keystore_ui-referential.jks diff --git a/api/api-iam/iam-external/src/main/java/fr/gouv/vitamui/iam/external/server/config/ApiIamServerConfig.java b/api/api-iam/iam-external/src/main/java/fr/gouv/vitamui/iam/external/server/config/ApiIamServerConfig.java index 4dacc74c9..a03dd793c 100644 --- a/api/api-iam/iam-external/src/main/java/fr/gouv/vitamui/iam/external/server/config/ApiIamServerConfig.java +++ b/api/api-iam/iam-external/src/main/java/fr/gouv/vitamui/iam/external/server/config/ApiIamServerConfig.java @@ -36,28 +36,17 @@ */ package fr.gouv.vitamui.iam.external.server.config; -import fr.gouv.vitamui.commons.rest.client.accesscontract.AccessContractInternalRestClient; -import fr.gouv.vitamui.iam.internal.client.ExternalParamProfileInternalRestClient; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.web.multipart.MultipartResolver; -import org.springframework.web.multipart.commons.CommonsMultipartResolver; -import org.springframework.web.multipart.support.MultipartFilter; -import org.springframework.web.reactive.function.client.WebClient; - import fr.gouv.vitamui.commons.api.application.AbstractContextConfiguration; import fr.gouv.vitamui.commons.rest.RestExceptionHandler; import fr.gouv.vitamui.commons.rest.client.InternalHttpContext; +import fr.gouv.vitamui.commons.rest.client.accesscontract.AccessContractInternalRestClient; import fr.gouv.vitamui.commons.rest.client.logbook.LogbookInternalRestClient; import fr.gouv.vitamui.commons.rest.configuration.SwaggerConfiguration; import fr.gouv.vitamui.iam.internal.client.ApplicationInternalRestClient; import fr.gouv.vitamui.iam.internal.client.CasInternalRestClient; import fr.gouv.vitamui.iam.internal.client.CustomerInternalRestClient; import fr.gouv.vitamui.iam.internal.client.CustomerInternalWebClient; +import fr.gouv.vitamui.iam.internal.client.ExternalParamProfileInternalRestClient; import fr.gouv.vitamui.iam.internal.client.ExternalParametersInternalRestClient; import fr.gouv.vitamui.iam.internal.client.GroupInternalRestClient; import fr.gouv.vitamui.iam.internal.client.IamInternalRestClientFactory; @@ -73,6 +62,16 @@ import fr.gouv.vitamui.iam.security.service.ExternalAuthentificationService; import fr.gouv.vitamui.iam.security.service.ExternalSecurityService; import fr.gouv.vitamui.security.client.ContextRestClient; import fr.gouv.vitamui.security.client.SecurityRestClientFactory; +import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.web.multipart.MultipartResolver; +import org.springframework.web.multipart.commons.CommonsMultipartResolver; +import org.springframework.web.multipart.support.MultipartFilter; +import org.springframework.web.reactive.function.client.WebClient; @Configuration @Import({ RestExceptionHandler.class, SwaggerConfiguration.class, HttpMessageConvertersAutoConfiguration.class }) diff --git a/api/api-iam/iam-internal-client/src/main/java/fr/gouv/vitamui/iam/internal/client/IamInternalRestClientFactory.java b/api/api-iam/iam-internal-client/src/main/java/fr/gouv/vitamui/iam/internal/client/IamInternalRestClientFactory.java index 19b494327..0d78f9611 100644 --- a/api/api-iam/iam-internal-client/src/main/java/fr/gouv/vitamui/iam/internal/client/IamInternalRestClientFactory.java +++ b/api/api-iam/iam-internal-client/src/main/java/fr/gouv/vitamui/iam/internal/client/IamInternalRestClientFactory.java @@ -122,5 +122,4 @@ public class IamInternalRestClientFactory extends BaseRestClientFactory { public AccessContractInternalRestClient<InternalHttpContext> getAccessContractInternalRestClient() { return new AccessContractInternalRestClient<>(getRestTemplate(), getBaseUrl()); } - } diff --git a/api/api-referential/referential-commons/src/test/java/fr/gouv/vitamui/referential/common/utils/ReferentialDtoBuilder.java b/api/api-referential/referential-commons/src/test/java/fr/gouv/vitamui/referential/common/utils/ReferentialDtoBuilder.java index b3b399877..1c67ac0ce 100644 --- a/api/api-referential/referential-commons/src/test/java/fr/gouv/vitamui/referential/common/utils/ReferentialDtoBuilder.java +++ b/api/api-referential/referential-commons/src/test/java/fr/gouv/vitamui/referential/common/utils/ReferentialDtoBuilder.java @@ -36,12 +36,17 @@ */ package fr.gouv.vitamui.referential.common.utils; -import java.util.HashSet; -import java.util.Set; - import fr.gouv.vitam.common.model.administration.ActivationStatus; import fr.gouv.vitam.common.model.administration.ContextStatus; -import fr.gouv.vitamui.referential.common.dto.*; +import fr.gouv.vitamui.commons.rest.dto.RuleDto; +import fr.gouv.vitamui.referential.common.dto.AccessContractDto; +import fr.gouv.vitamui.referential.common.dto.ContextDto; +import fr.gouv.vitamui.referential.common.dto.IngestContractDto; +import fr.gouv.vitamui.referential.common.dto.PermissionDto; +import fr.gouv.vitamui.referential.common.dto.SecurityProfileDto; + +import java.util.HashSet; +import java.util.Set; public class ReferentialDtoBuilder { diff --git a/api/api-referential/referential-external-client/src/main/java/fr/gouv/vitamui/referential/external/client/RuleExternalRestClient.java b/api/api-referential/referential-external-client/src/main/java/fr/gouv/vitamui/referential/external/client/RuleExternalRestClient.java index d7ea532c6..a4cfd7447 100644 --- a/api/api-referential/referential-external-client/src/main/java/fr/gouv/vitamui/referential/external/client/RuleExternalRestClient.java +++ b/api/api-referential/referential-external-client/src/main/java/fr/gouv/vitamui/referential/external/client/RuleExternalRestClient.java @@ -36,12 +36,15 @@ */ package fr.gouv.vitamui.referential.external.client; -import java.util.List; -import java.util.Map; - import fr.gouv.vitamui.common.security.SanityChecker; import fr.gouv.vitamui.commons.api.CommonConstants; - +import fr.gouv.vitamui.commons.api.domain.PaginatedValuesDto; +import fr.gouv.vitamui.commons.api.logger.VitamUILogger; +import fr.gouv.vitamui.commons.api.logger.VitamUILoggerFactory; +import fr.gouv.vitamui.commons.rest.client.BasePaginatingAndSortingRestClient; +import fr.gouv.vitamui.commons.rest.client.ExternalHttpContext; +import fr.gouv.vitamui.commons.rest.dto.RuleDto; +import fr.gouv.vitamui.referential.common.rest.RestApi; import org.apache.commons.lang3.StringUtils; import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.io.Resource; @@ -51,20 +54,13 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.util.Assert; import org.springframework.web.client.RestTemplate; - -import fr.gouv.vitamui.commons.api.domain.PaginatedValuesDto; -import fr.gouv.vitamui.commons.api.logger.VitamUILogger; -import fr.gouv.vitamui.commons.api.logger.VitamUILoggerFactory; -import fr.gouv.vitamui.commons.api.utils.ApiUtils; -import fr.gouv.vitamui.commons.rest.client.BasePaginatingAndSortingRestClient; -import fr.gouv.vitamui.commons.rest.client.ExternalHttpContext; -import fr.gouv.vitamui.referential.common.dto.RuleDto; -import fr.gouv.vitamui.referential.common.rest.RestApi; - import org.springframework.web.util.UriComponentsBuilder; +import java.util.List; +import java.util.Map; + public class RuleExternalRestClient extends BasePaginatingAndSortingRestClient<RuleDto, ExternalHttpContext> { - + private static final VitamUILogger LOGGER = VitamUILoggerFactory.getInstance(RuleExternalRestClient.class); public RuleExternalRestClient(final RestTemplate restTemplate, final String baseUrl) { @@ -96,11 +92,11 @@ public class RuleExternalRestClient extends BasePaginatingAndSortingRestClient<R request, Boolean.class); return response.getStatusCode() == HttpStatus.OK; } - + public boolean createRule(final ExternalHttpContext context, final RuleDto dto) { LOGGER.debug("Create {}", dto); final HttpEntity<RuleDto> request = new HttpEntity<>(dto, buildHeaders(context)); - + final ResponseEntity<Boolean> response = restTemplate.exchange(getUrl(), HttpMethod.POST, request, Boolean.class); checkResponse(response, 200, 201, 202, 204); return response.getStatusCode() == HttpStatus.OK | response.getStatusCode() == HttpStatus.CREATED; @@ -110,16 +106,16 @@ public class RuleExternalRestClient extends BasePaginatingAndSortingRestClient<R LOGGER.debug("Patch {}", partialDto); SanityChecker.check(id); Assert.isTrue(StringUtils.equals(id, (String) partialDto.get("id")), "The DTO identifier must match the path identifier for patch."); - + final UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(getUrl()); uriBuilder.path(CommonConstants.PATH_ID); - + final HttpEntity<Map<String, Object>> request = new HttpEntity<>(partialDto, buildHeaders(context)); - final ResponseEntity<Boolean> response = restTemplate.exchange(uriBuilder.build(id), HttpMethod.PATCH, request, Boolean.class); + final ResponseEntity<Boolean> response = restTemplate.exchange(uriBuilder.build(id), HttpMethod.PATCH, request, Boolean.class); checkResponse(response, 200, 201, 202, 204); return response.getStatusCode() == HttpStatus.OK; } - + public boolean deleteRule(ExternalHttpContext context, String id) { LOGGER.debug("Delete {}", id); SanityChecker.check(id); diff --git a/api/api-referential/referential-internal/src/main/java/fr/gouv/vitamui/referential/internal/server/config/ConverterConfig.java b/api/api-referential/referential-internal/src/main/java/fr/gouv/vitamui/referential/internal/server/config/ConverterConfig.java index 640e1efec..3258e1bf4 100644 --- a/api/api-referential/referential-internal/src/main/java/fr/gouv/vitamui/referential/internal/server/config/ConverterConfig.java +++ b/api/api-referential/referential-internal/src/main/java/fr/gouv/vitamui/referential/internal/server/config/ConverterConfig.java @@ -44,7 +44,6 @@ import fr.gouv.vitamui.referential.internal.server.ingestcontract.IngestContract import fr.gouv.vitamui.referential.internal.server.managementcontract.ManagementContractConverter; import fr.gouv.vitamui.referential.internal.server.ontology.OntologyConverter; import fr.gouv.vitamui.referential.internal.server.profile.ProfileConverter; -import fr.gouv.vitamui.referential.internal.server.rule.RuleConverter; import fr.gouv.vitamui.referential.internal.server.securityprofile.SecurityProfileConverter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -96,10 +95,4 @@ public class ConverterConfig { public ProfileConverter profileConverter() { return new ProfileConverter(); } - - @Bean - public RuleConverter ruleConverter() { - return new RuleConverter(); - } - } diff --git a/api/api-referential/referential-internal/src/main/java/fr/gouv/vitamui/referential/internal/server/rest/RuleInternalController.java b/api/api-referential/referential-internal/src/main/java/fr/gouv/vitamui/referential/internal/server/rest/RuleInternalController.java index bbc7606a5..7ab2dc83a 100644 --- a/api/api-referential/referential-internal/src/main/java/fr/gouv/vitamui/referential/internal/server/rest/RuleInternalController.java +++ b/api/api-referential/referential-internal/src/main/java/fr/gouv/vitamui/referential/internal/server/rest/RuleInternalController.java @@ -36,43 +36,50 @@ */ package fr.gouv.vitamui.referential.internal.server.rest; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; -import java.util.Collection; -import java.util.Map; -import java.util.Optional; - import com.fasterxml.jackson.databind.JsonNode; +import fr.gouv.vitam.common.client.VitamContext; import fr.gouv.vitam.common.exception.VitamClientException; import fr.gouv.vitamui.commons.api.CommonConstants; import fr.gouv.vitamui.commons.api.ParameterChecker; -import fr.gouv.vitamui.referential.common.dto.RuleDto; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.io.InputStreamResource; -import org.springframework.core.io.Resource; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.util.Assert; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; - -import fr.gouv.vitam.common.client.VitamContext; import fr.gouv.vitamui.commons.api.domain.DirectionDto; import fr.gouv.vitamui.commons.api.domain.PaginatedValuesDto; import fr.gouv.vitamui.commons.api.logger.VitamUILogger; import fr.gouv.vitamui.commons.api.logger.VitamUILoggerFactory; +import fr.gouv.vitamui.commons.rest.dto.RuleDto; import fr.gouv.vitamui.commons.rest.util.RestUtils; import fr.gouv.vitamui.iam.security.service.InternalSecurityService; import fr.gouv.vitamui.referential.common.rest.RestApi; import fr.gouv.vitamui.referential.internal.server.rule.RuleInternalService; import lombok.Getter; import lombok.Setter; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.InputStreamResource; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.util.Assert; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; import javax.validation.Valid; import javax.ws.rs.core.Response; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.util.Collection; +import java.util.Map; +import java.util.Optional; @RestController @RequestMapping(RestApi.RULES_URL) @@ -167,11 +174,11 @@ public class RuleInternalController { } return null; } - + @PostMapping(CommonConstants.PATH_IMPORT) public JsonNode importAgencies(@RequestParam("fileName") String fileName, @RequestParam("file") MultipartFile file) { LOGGER.debug("import rule file {}", fileName); - final VitamContext vitamContext = securityService.buildVitamContext(securityService.getTenantIdentifier()); + final VitamContext vitamContext = securityService.buildVitamContext(securityService.getTenantIdentifier()); return ruleInternalService.importRules(vitamContext, fileName, file); } } diff --git a/api/api-referential/referential-internal/src/main/java/fr/gouv/vitamui/referential/internal/server/rule/RuleInternalService.java b/api/api-referential/referential-internal/src/main/java/fr/gouv/vitamui/referential/internal/server/rule/RuleInternalService.java index 8a95ae77b..b06f08430 100644 --- a/api/api-referential/referential-internal/src/main/java/fr/gouv/vitamui/referential/internal/server/rule/RuleInternalService.java +++ b/api/api-referential/referential-internal/src/main/java/fr/gouv/vitamui/referential/internal/server/rule/RuleInternalService.java @@ -36,31 +36,10 @@ */ package fr.gouv.vitamui.referential.internal.server.rule; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -import javax.ws.rs.core.Response; -import javax.xml.bind.JAXBException; - -import fr.gouv.vitamui.commons.vitam.api.dto.RuleNodeResponseDto; -import org.apache.commons.beanutils.BeanUtilsBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Service; -import org.springframework.web.multipart.MultipartFile; - import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; - -import fr.gouv.vitam.access.external.api.AdminCollections; import fr.gouv.vitam.access.external.common.exception.AccessExternalClientException; import fr.gouv.vitam.common.client.VitamContext; import fr.gouv.vitam.common.database.builder.request.exception.InvalidCreateOperationException; @@ -76,10 +55,26 @@ import fr.gouv.vitamui.commons.api.exception.InternalServerException; import fr.gouv.vitamui.commons.api.exception.VitamUIException; import fr.gouv.vitamui.commons.api.logger.VitamUILogger; import fr.gouv.vitamui.commons.api.logger.VitamUILoggerFactory; +import fr.gouv.vitamui.commons.rest.dto.RuleDto; import fr.gouv.vitamui.commons.vitam.api.access.LogbookService; +import fr.gouv.vitamui.commons.vitam.api.config.converter.RuleConverter; +import fr.gouv.vitamui.commons.vitam.api.dto.RuleNodeResponseDto; import fr.gouv.vitamui.referential.common.dsl.VitamQueryHelper; -import fr.gouv.vitamui.referential.common.dto.RuleDto; import fr.gouv.vitamui.referential.common.service.VitamRuleService; +import org.apache.commons.beanutils.BeanUtilsBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import javax.ws.rs.core.Response; +import javax.xml.bind.JAXBException; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; @Service public class RuleInternalService { @@ -247,7 +242,7 @@ public class RuleInternalService { throw new InternalServerException("Unable to fetch history", e); } } - + public JsonNode importRules(VitamContext context, String fileName, MultipartFile file) { try { return ruleService.importRules(context, fileName, file).toJsonNode(); diff --git a/api/api-referential/referential-internal/src/test/java/fr/gouv/vitamui/referential/internal/server/service/AccessionRegisterDetailInternalServiceTest.java b/api/api-referential/referential-internal/src/test/java/fr/gouv/vitamui/referential/internal/server/service/AccessionRegisterDetailInternalServiceTest.java index f1b11dc33..3c4df5b73 100644 --- a/api/api-referential/referential-internal/src/test/java/fr/gouv/vitamui/referential/internal/server/service/AccessionRegisterDetailInternalServiceTest.java +++ b/api/api-referential/referential-internal/src/test/java/fr/gouv/vitamui/referential/internal/server/service/AccessionRegisterDetailInternalServiceTest.java @@ -53,8 +53,8 @@ import fr.gouv.vitamui.commons.vitam.api.administration.AgencyService; import fr.gouv.vitamui.referential.common.dsl.VitamQueryHelper; import fr.gouv.vitamui.referential.common.dto.AccessionRegisterDetailResponseDto; import fr.gouv.vitamui.referential.internal.server.accessionregister.details.AccessionRegisterDetailInternalService; +import org.junit.Test; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -99,8 +99,9 @@ class AccessionRegisterDetailInternalServiceTest { doNothing().when(vitamUILogger).info(any()); } - @Test - void should_call_appropriate_api_once_when_get_paginated_is_invoked() throws IOException, InvalidCreateOperationException, InvalidParseOperationException, VitamClientException { + @Test + void should_call_appropriate_api_once_when_get_paginated_is_invoked() throws IOException, + InvalidCreateOperationException, InvalidParseOperationException, VitamClientException { //Given VitamContext vitamContext = new VitamContext(0); Map<String, Object> vitamCriteria = new HashMap<>(); diff --git a/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/dto/RuleDto.java b/commons/commons-rest/src/main/java/fr/gouv/vitamui/commons/rest/dto/RuleDto.java similarity index 76% rename from commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/dto/RuleDto.java rename to commons/commons-rest/src/main/java/fr/gouv/vitamui/commons/rest/dto/RuleDto.java index 6f87768db..90f7f8a6e 100644 --- a/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/dto/RuleDto.java +++ b/commons/commons-rest/src/main/java/fr/gouv/vitamui/commons/rest/dto/RuleDto.java @@ -34,34 +34,39 @@ * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. */ -package fr.gouv.vitamui.commons.vitam.api.dto; - -import com.fasterxml.jackson.annotation.JsonProperty; +package fr.gouv.vitamui.commons.rest.dto; +import com.fasterxml.jackson.annotation.JsonInclude; +import fr.gouv.vitamui.commons.api.domain.IdDto; import lombok.Getter; import lombok.Setter; import lombok.ToString; +import java.io.Serializable; + +@ToString +@JsonInclude(JsonInclude.Include.NON_NULL) @Getter @Setter -@ToString -public class RuleDto { +public class RuleDto extends IdDto implements Serializable { + + private Integer tenant; + + private Integer version; + + private String creationDate; + + private String updateDate; + + private String ruleId; + + private String ruleType; + + private String ruleValue; - /** - * Rule id - */ - @JsonProperty("Rule") - private String rule; + private String ruleDescription; - /** - * Start date - */ - @JsonProperty("StartDate") - private String startDate; + private String ruleDuration; - /** - * End date - */ - @JsonProperty("EndDate") - private String endDate; + private String ruleMeasurement; } diff --git a/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/config/VitamAdministrationConfig.java b/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/config/VitamAdministrationConfig.java index cc1edcd4d..7089e3192 100644 --- a/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/config/VitamAdministrationConfig.java +++ b/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/config/VitamAdministrationConfig.java @@ -36,6 +36,7 @@ */ package fr.gouv.vitamui.commons.vitam.api.config; +import fr.gouv.vitamui.commons.vitam.api.config.converter.RuleConverter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -78,4 +79,9 @@ public class VitamAdministrationConfig extends VitamClientConfig { public IngestContractService geIngestContractService() { return new IngestContractService(adminExternalClient()); } + + @Bean + public RuleConverter rulesConverter() { + return new RuleConverter(); + } } diff --git a/api/api-referential/referential-internal/src/main/java/fr/gouv/vitamui/referential/internal/server/rule/RuleConverter.java b/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/config/converter/RuleConverter.java similarity index 96% rename from api/api-referential/referential-internal/src/main/java/fr/gouv/vitamui/referential/internal/server/rule/RuleConverter.java rename to commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/config/converter/RuleConverter.java index b63de7f07..81a2c6dac 100644 --- a/api/api-referential/referential-internal/src/main/java/fr/gouv/vitamui/referential/internal/server/rule/RuleConverter.java +++ b/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/config/converter/RuleConverter.java @@ -34,14 +34,14 @@ * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. */ -package fr.gouv.vitamui.referential.internal.server.rule; - -import java.util.List; -import java.util.stream.Collectors; +package fr.gouv.vitamui.commons.vitam.api.config.converter; import fr.gouv.vitam.common.model.administration.FileRulesModel; +import fr.gouv.vitamui.commons.rest.dto.RuleDto; import fr.gouv.vitamui.commons.utils.VitamUIUtils; -import fr.gouv.vitamui.referential.common.dto.RuleDto; + +import java.util.List; +import java.util.stream.Collectors; public class RuleConverter { diff --git a/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/dto/InheritedRuleCategoryDto.java b/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/dto/InheritedRuleCategoryDto.java index b63988c78..77cdfb32c 100644 --- a/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/dto/InheritedRuleCategoryDto.java +++ b/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/dto/InheritedRuleCategoryDto.java @@ -36,22 +36,21 @@ */ package fr.gouv.vitamui.commons.vitam.api.dto; -import java.util.ArrayList; -import java.util.List; - import com.fasterxml.jackson.annotation.JsonProperty; - import lombok.Getter; import lombok.Setter; import lombok.ToString; +import java.util.ArrayList; +import java.util.List; + @Getter @Setter @ToString public class InheritedRuleCategoryDto { @JsonProperty("Rules") - private List<RuleDto> rules = new ArrayList<>(); + private List<UnitRuleDto> rules = new ArrayList<>(); @JsonProperty("Properties") private List<InheritedPropertyDto> properties = new ArrayList<>(); diff --git a/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/dto/RuleCategoryDto.java b/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/dto/RuleCategoryDto.java index 6282458f3..55f1c8d21 100644 --- a/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/dto/RuleCategoryDto.java +++ b/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/dto/RuleCategoryDto.java @@ -36,22 +36,21 @@ */ package fr.gouv.vitamui.commons.vitam.api.dto; -import java.util.ArrayList; -import java.util.List; - import com.fasterxml.jackson.annotation.JsonProperty; - import lombok.Getter; import lombok.Setter; import lombok.ToString; +import java.util.ArrayList; +import java.util.List; + @Getter @Setter @ToString public class RuleCategoryDto { @JsonProperty("Rules") - private List<RuleDto> rules = new ArrayList<>(); + private List<UnitRuleDto> rules = new ArrayList<>(); @JsonProperty("FinalAction") private String finalAction; diff --git a/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/dto/UnitRuleDto.java b/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/dto/UnitRuleDto.java new file mode 100644 index 000000000..bf79e628d --- /dev/null +++ b/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/dto/UnitRuleDto.java @@ -0,0 +1,67 @@ +/** + * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2020) + * and the signatories of the "VITAM - Accord du Contributeur" agreement. + * + * contact@programmevitam.fr + * + * This software is a computer program whose purpose is to implement + * implement a digital archiving front-office system for the secure and + * efficient high volumetry VITAM solution. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-C license and that you accept its terms. + */ +package fr.gouv.vitamui.commons.vitam.api.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString +public class UnitRuleDto { + + /** + * Rule id + */ + @JsonProperty("Rule") + private String rule; + + /** + * Start date + */ + @JsonProperty("StartDate") + private String startDate; + + /** + * End date + */ + @JsonProperty("EndDate") + private String endDate; +} diff --git a/deployment/roles/vitamui/templates/ui-archive-search/application.yml.j2 b/deployment/roles/vitamui/templates/ui-archive-search/application.yml.j2 index 858a4c763..542863149 100644 --- a/deployment/roles/vitamui/templates/ui-archive-search/application.yml.j2 +++ b/deployment/roles/vitamui/templates/ui-archive-search/application.yml.j2 @@ -82,6 +82,21 @@ ui-archive-search: key-path: {{ vitamui_folder_conf }}/truststore_{{ vitamui_certificate_type }}.jks key-password: {{ password_truststore }} hostname-verification: false +{%endif %} + referential-external-client: + server-host: {{ vitamui.referential_external.host }} + server-port: {{ vitamui.referential_external.port_service }} +{% if vitamui.referential_external.secure | lower == "true" %} + secure: {{ vitamui.referential_external.secure | lower }} + ssl-configuration: + keystore: + key-path: {{ vitamui_folder_conf }}/keystore_{{ vitamui_struct.package_name }}.jks + key-password: {{ password_keystore }} + type: JKS + truststore: + key-path: {{ vitamui_folder_conf }}/truststore_{{ vitamui_certificate_type }}.jks + key-password: {{ password_truststore }} + hostname-verification: false {%endif %} assets: "{{ vitamui_defaults.folder.root_path }}/conf/assets" portal-logo: "{{ vitamui_platform_informations.theme.portal_logo }}" diff --git a/deployment/roles/vitamui/templates/ui-identity-admin/application.yml.j2 b/deployment/roles/vitamui/templates/ui-identity-admin/application.yml.j2 index 8e8b28a5f..1231450cd 100644 --- a/deployment/roles/vitamui/templates/ui-identity-admin/application.yml.j2 +++ b/deployment/roles/vitamui/templates/ui-identity-admin/application.yml.j2 @@ -77,6 +77,21 @@ ui-identity: key-password: {{ password_truststore }} # TODO OMA : revoir hostname-verification: false {% endif %} + referential-external-client: + server-host: {{ vitamui.referential_external.host }} + server-port: {{ vitamui.referential_external.port_service }} +{% if vitamui.referential_external.secure | lower == "true" %} + secure: {{ vitamui.referential_external.secure | lower }} + ssl-configuration: + keystore: + key-path: {{ vitamui_folder_conf }}/keystore_{{ vitamui_struct.package_name }}.jks + key-password: {{ password_keystore }} + type: JKS + truststore: + key-path: {{ vitamui_folder_conf }}/truststore_{{ vitamui_certificate_type }}.jks + key-password: {{ password_truststore }} + hostname-verification: false +{%endif %} assets: "{{ vitamui_defaults.folder.root_path }}/conf/assets" portal-logo: "{{ vitamui_platform_informations.theme.portal_logo }}" header-logo: "{{ vitamui_platform_informations.theme.header_logo }}" diff --git a/deployment/roles/vitamui/templates/ui-identity/application.yml.j2 b/deployment/roles/vitamui/templates/ui-identity/application.yml.j2 index c340938b3..27410383b 100644 --- a/deployment/roles/vitamui/templates/ui-identity/application.yml.j2 +++ b/deployment/roles/vitamui/templates/ui-identity/application.yml.j2 @@ -89,6 +89,21 @@ ui-identity: key-path: {{ vitamui_folder_conf }}/truststore_{{ vitamui_certificate_type }}.jks key-password: {{ password_truststore }} hostname-verification: false +{%endif %} + referential-external-client: + server-host: {{ vitamui.referential_external.host }} + server-port: {{ vitamui.referential_external.port_service }} +{% if vitamui.referential_external.secure | lower == "true" %} + secure: {{ vitamui.referential_external.secure | lower }} + ssl-configuration: + keystore: + key-path: {{ vitamui_folder_conf }}/keystore_{{ vitamui_struct.package_name }}.jks + key-password: {{ password_keystore }} + type: JKS + truststore: + key-path: {{ vitamui_folder_conf }}/truststore_{{ vitamui_certificate_type }}.jks + key-password: {{ password_truststore }} + hostname-verification: false {%endif %} base-url: {% if vitamui.portal.base_url is defined %} diff --git a/deployment/roles/vitamui/templates/ui-ingest/application.yml.j2 b/deployment/roles/vitamui/templates/ui-ingest/application.yml.j2 index 99b7b6a09..e54ba952e 100644 --- a/deployment/roles/vitamui/templates/ui-ingest/application.yml.j2 +++ b/deployment/roles/vitamui/templates/ui-ingest/application.yml.j2 @@ -84,6 +84,21 @@ ui-ingest: key-path: {{ vitamui_folder_conf }}/truststore_{{ vitamui_certificate_type }}.jks key-password: {{ password_truststore }} hostname-verification: false +{%endif %} + referential-external-client: + server-host: {{ vitamui.referential_external.host }} + server-port: {{ vitamui.referential_external.port_service }} +{% if vitamui.referential_external.secure | lower == "true" %} + secure: {{ vitamui.referential_external.secure | lower }} + ssl-configuration: + keystore: + key-path: {{ vitamui_folder_conf }}/keystore_{{ vitamui_struct.package_name }}.jks + key-password: {{ password_keystore }} + type: JKS + truststore: + key-path: {{ vitamui_folder_conf }}/truststore_{{ vitamui_certificate_type }}.jks + key-password: {{ password_truststore }} + hostname-verification: false {%endif %} assets: "{{ vitamui_defaults.folder.root_path }}/conf/assets" portal-logo: "{{ vitamui_platform_informations.theme.portal_logo }}" diff --git a/deployment/roles/vitamui/templates/ui-portal/application.yml.j2 b/deployment/roles/vitamui/templates/ui-portal/application.yml.j2 index a813708d8..4312baf4a 100644 --- a/deployment/roles/vitamui/templates/ui-portal/application.yml.j2 +++ b/deployment/roles/vitamui/templates/ui-portal/application.yml.j2 @@ -68,6 +68,21 @@ ui-portal: key-password: {{ password_truststore }} # TODO OMA : revoir hostname-verification: false {% endif %} + referential-external-client: + server-host: {{ vitamui.referential_external.host }} + server-port: {{ vitamui.referential_external.port_service }} +{% if vitamui.referential_external.secure | lower == "true" %} + secure: {{ vitamui.referential_external.secure | lower }} + ssl-configuration: + keystore: + key-path: {{ vitamui_folder_conf }}/keystore_{{ vitamui_struct.package_name }}.jks + key-password: {{ password_keystore }} + type: JKS + truststore: + key-path: {{ vitamui_folder_conf }}/truststore_{{ vitamui_certificate_type }}.jks + key-password: {{ password_truststore }} + hostname-verification: false +{%endif %} assets: "{{ vitamui_defaults.folder.root_path }}/conf/assets" portal-logo: "{{ vitamui_platform_informations.theme.portal_logo }}" header-logo: "{{ vitamui_platform_informations.theme.header_logo }}" diff --git a/deployment/scripts/mongod/2.0.0/42_new_update_archive_search_profile_to_add_rule_access.js.j2 b/deployment/scripts/mongod/2.0.0/42_new_update_archive_search_profile_to_add_rule_access.js.j2 new file mode 100644 index 000000000..d77a503c3 --- /dev/null +++ b/deployment/scripts/mongod/2.0.0/42_new_update_archive_search_profile_to_add_rule_access.js.j2 @@ -0,0 +1,50 @@ +db = db.getSiblingDB('iam') + +print("42_new_update_archive_search_profile_to_add_rule_access.js"); + +db.profiles.updateOne({ + "_id":"system_archive_search_profile_archiviste_administrator" +}, +{ + $addToSet:{ + "roles":{ + $each:[ + { + "name" : "ROLE_GET_RULES" + } + ] + } + } +}); + +db.profiles.updateOne({ + "_id":"system_archive_search_profile_consultation" +}, +{ + $addToSet:{ + "roles":{ + $each:[ + { + "name" : "ROLE_GET_RULES" + } + ] + } + } +}); + +db.profiles.updateOne({ + "_id":"system_archive_search_profile_archiviste" +}, +{ + $addToSet:{ + "roles":{ + $each:[ + { + "name" : "ROLE_GET_RULES" + } + ] + } + } +}); + +print("42_new_update_archive_search_profile_to_add_rule_access.js"); diff --git a/deployment/scripts/mongod/2.0.0/43_new_update_archive_search_context_to_add_rule_access.js.j2 b/deployment/scripts/mongod/2.0.0/43_new_update_archive_search_context_to_add_rule_access.js.j2 new file mode 100644 index 000000000..6a0789e49 --- /dev/null +++ b/deployment/scripts/mongod/2.0.0/43_new_update_archive_search_context_to_add_rule_access.js.j2 @@ -0,0 +1,18 @@ +db = db.getSiblingDB('security') + +print("43_new_update_archive_search_context_to_add_rule_access.js"); + +db.contexts.updateOne({ + "_id":"ui_archive_search_context" +}, +{ + $addToSet:{ + "roleNames":{ + $each:[ + "ROLE_GET_RULES" + ] + } + } +}); + +print("43_new_update_archive_search_context_to_add_rule_access.js"); diff --git a/integration-tests/src/test/java/fr/gouv/vitamui/cucumber/back/steps/referential/rule/ApiReferentialExternalRuleCheckSteps.java b/integration-tests/src/test/java/fr/gouv/vitamui/cucumber/back/steps/referential/rule/ApiReferentialExternalRuleCheckSteps.java index 3d50bf36e..6df65d86b 100644 --- a/integration-tests/src/test/java/fr/gouv/vitamui/cucumber/back/steps/referential/rule/ApiReferentialExternalRuleCheckSteps.java +++ b/integration-tests/src/test/java/fr/gouv/vitamui/cucumber/back/steps/referential/rule/ApiReferentialExternalRuleCheckSteps.java @@ -36,8 +36,8 @@ */ package fr.gouv.vitamui.cucumber.back.steps.referential.rule; +import fr.gouv.vitamui.commons.rest.dto.RuleDto; import fr.gouv.vitamui.cucumber.common.CommonSteps; -import fr.gouv.vitamui.referential.common.dto.RuleDto; import fr.gouv.vitamui.referential.common.utils.ReferentialDtoBuilder; import io.cucumber.java.en.Given; import io.cucumber.java.en.When; diff --git a/integration-tests/src/test/java/fr/gouv/vitamui/cucumber/back/steps/referential/rule/ApiReferentialExternalRuleCreationSteps.java b/integration-tests/src/test/java/fr/gouv/vitamui/cucumber/back/steps/referential/rule/ApiReferentialExternalRuleCreationSteps.java index 2de92ace4..f60aa5ae5 100644 --- a/integration-tests/src/test/java/fr/gouv/vitamui/cucumber/back/steps/referential/rule/ApiReferentialExternalRuleCreationSteps.java +++ b/integration-tests/src/test/java/fr/gouv/vitamui/cucumber/back/steps/referential/rule/ApiReferentialExternalRuleCreationSteps.java @@ -36,27 +36,21 @@ */ package fr.gouv.vitamui.cucumber.back.steps.referential.rule; +import com.fasterxml.jackson.databind.JsonNode; +import fr.gouv.vitamui.commons.rest.dto.RuleDto; import fr.gouv.vitamui.cucumber.common.CommonSteps; -import fr.gouv.vitamui.referential.common.dto.ContextDto; -import fr.gouv.vitamui.referential.common.dto.RuleDto; import fr.gouv.vitamui.referential.common.utils.ReferentialDtoBuilder; -import fr.gouv.vitamui.utils.FactoryDto; -import fr.gouv.vitamui.utils.TestConstants; -import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; import io.cucumber.java.en.When; - -import static org.assertj.core.api.Assertions.assertThat; +import org.apache.commons.io.IOUtils; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.FileInputStream; import java.io.IOException; -import org.apache.commons.io.IOUtils; -import org.springframework.mock.web.MockMultipartFile; -import org.springframework.web.multipart.MultipartFile; - -import com.fasterxml.jackson.databind.JsonNode; +import static org.assertj.core.api.Assertions.assertThat; /** * Teste l'API Rules dans Referential admin : operations de creation. @@ -65,7 +59,7 @@ import com.fasterxml.jackson.databind.JsonNode; */ public class ApiReferentialExternalRuleCreationSteps extends CommonSteps { - + private JsonNode response; @When("^un utilisateur avec le role ROLE_CREATE_RULES ajoute une nouvelle regle en utilisant un certificat full access avec le role ROLE_CREATE_RULES$") @@ -78,22 +72,22 @@ public class ApiReferentialExternalRuleCreationSteps extends CommonSteps { public void le_serveur_retourne_la_regle_creee() { assertThat(testContext.savedRuleDto).overridingErrorMessage("la reponse retournee est null").isNotNull(); } - + @When("^un utilisateur importe des règles à partir d'un fichier csv valide$") public void un_utilisateur_importe_des_regles_à _partir_d_un_fichier_csv_valide() throws IOException { File file = new File("src/test/resources/data/import_rules_valid.csv"); FileInputStream input = new FileInputStream(file); MultipartFile multipartFile = new MockMultipartFile("import_rules_valid.csv", - file.getName(), "application/csv", IOUtils.toByteArray(input)); + file.getName(), "application/csv", IOUtils.toByteArray(input)); response = getFileFormatWebClient().importFileFormats(getSystemTenantUserAdminContext(), multipartFile); } - + @Then("^l'import des règles a réussi$") public void l_import_règles_a_réussi() { assertThat(response).isNotNull(); assertThat(response.get("httpCode").asInt()).isEqualTo(200); } - + @When("^un utilisateur importe des règles à partir d'un fichier csv invalide$") public void un_utilisateur_importe_des_formats_de_fichier_à _partir_d_un_fichier_csv_invalide() throws IOException { File file = new File("src/test/resources/data/import_rules_invalid.csv"); @@ -102,7 +96,7 @@ public class ApiReferentialExternalRuleCreationSteps extends CommonSteps { file.getName(), "application/csv", IOUtils.toByteArray(input)); response = getFileFormatWebClient().importFileFormats(getSystemTenantUserAdminContext(), multipartFile); } - + @Then("^l'import des règles a échoué$") public void l_import_des_règles_a_échoué() { assertThat(response).isNotNull(); diff --git a/integration-tests/src/test/java/fr/gouv/vitamui/cucumber/back/steps/referential/rule/ApiReferentialExternalRuleDeleteSteps.java b/integration-tests/src/test/java/fr/gouv/vitamui/cucumber/back/steps/referential/rule/ApiReferentialExternalRuleDeleteSteps.java index 7027caba3..2aae4df92 100644 --- a/integration-tests/src/test/java/fr/gouv/vitamui/cucumber/back/steps/referential/rule/ApiReferentialExternalRuleDeleteSteps.java +++ b/integration-tests/src/test/java/fr/gouv/vitamui/cucumber/back/steps/referential/rule/ApiReferentialExternalRuleDeleteSteps.java @@ -36,17 +36,10 @@ */ package fr.gouv.vitamui.cucumber.back.steps.referential.rule; -import com.fasterxml.jackson.databind.JsonNode; +import fr.gouv.vitamui.commons.rest.dto.RuleDto; import fr.gouv.vitamui.cucumber.common.CommonSteps; -import fr.gouv.vitamui.referential.common.dto.RuleDto; -import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; import io.cucumber.java.en.When; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import static org.assertj.core.api.Assertions.assertThat; /** diff --git a/integration-tests/src/test/java/fr/gouv/vitamui/cucumber/back/steps/referential/rule/ApiReferentialExternalRuleGetSteps.java b/integration-tests/src/test/java/fr/gouv/vitamui/cucumber/back/steps/referential/rule/ApiReferentialExternalRuleGetSteps.java index 6bed501ed..112cc6dfb 100644 --- a/integration-tests/src/test/java/fr/gouv/vitamui/cucumber/back/steps/referential/rule/ApiReferentialExternalRuleGetSteps.java +++ b/integration-tests/src/test/java/fr/gouv/vitamui/cucumber/back/steps/referential/rule/ApiReferentialExternalRuleGetSteps.java @@ -36,15 +36,11 @@ */ package fr.gouv.vitamui.cucumber.back.steps.referential.rule; -import com.fasterxml.jackson.databind.JsonNode; import fr.gouv.vitamui.commons.api.domain.CriterionOperator; import fr.gouv.vitamui.commons.api.domain.PaginatedValuesDto; import fr.gouv.vitamui.commons.api.domain.QueryDto; -import fr.gouv.vitamui.commons.api.domain.QueryOperator; +import fr.gouv.vitamui.commons.rest.dto.RuleDto; import fr.gouv.vitamui.cucumber.common.CommonSteps; -import fr.gouv.vitamui.referential.common.dto.ContextDto; -import fr.gouv.vitamui.referential.common.dto.RuleDto; -import fr.gouv.vitamui.utils.TestConstants; import io.cucumber.java.en.Then; import io.cucumber.java.en.When; diff --git a/integration-tests/src/test/java/fr/gouv/vitamui/cucumber/back/steps/referential/rule/ApiReferentialExternalRulePatchSteps.java b/integration-tests/src/test/java/fr/gouv/vitamui/cucumber/back/steps/referential/rule/ApiReferentialExternalRulePatchSteps.java index 4ddf1de8e..07daa70d8 100644 --- a/integration-tests/src/test/java/fr/gouv/vitamui/cucumber/back/steps/referential/rule/ApiReferentialExternalRulePatchSteps.java +++ b/integration-tests/src/test/java/fr/gouv/vitamui/cucumber/back/steps/referential/rule/ApiReferentialExternalRulePatchSteps.java @@ -36,18 +36,14 @@ */ package fr.gouv.vitamui.cucumber.back.steps.referential.rule; -import com.fasterxml.jackson.databind.JsonNode; -import fr.gouv.vitamui.commons.api.domain.CriterionOperator; -import fr.gouv.vitamui.commons.api.domain.PaginatedValuesDto; -import fr.gouv.vitamui.commons.api.domain.QueryDto; +import fr.gouv.vitamui.commons.rest.dto.RuleDto; import fr.gouv.vitamui.cucumber.common.CommonSteps; -import fr.gouv.vitamui.referential.common.dto.RuleDto; -import fr.gouv.vitamui.referential.common.utils.ReferentialDtoBuilder; import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; import io.cucumber.java.en.When; -import java.util.*; +import java.util.HashMap; +import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; diff --git a/integration-tests/src/test/java/fr/gouv/vitamui/cucumber/common/context/TestContext.java b/integration-tests/src/test/java/fr/gouv/vitamui/cucumber/common/context/TestContext.java index 467cf1cf9..7e7aa83a8 100644 --- a/integration-tests/src/test/java/fr/gouv/vitamui/cucumber/common/context/TestContext.java +++ b/integration-tests/src/test/java/fr/gouv/vitamui/cucumber/common/context/TestContext.java @@ -7,12 +7,12 @@ import fr.gouv.vitamui.commons.api.domain.OwnerDto; import fr.gouv.vitamui.commons.api.domain.ProfileDto; import fr.gouv.vitamui.commons.api.domain.TenantDto; import fr.gouv.vitamui.commons.api.domain.UserDto; +import fr.gouv.vitamui.commons.rest.dto.RuleDto; import fr.gouv.vitamui.commons.security.client.dto.AuthUserDto; import fr.gouv.vitamui.iam.common.dto.CustomerDto; import fr.gouv.vitamui.iam.common.dto.IdentityProviderDto; import fr.gouv.vitamui.iam.common.dto.SubrogationDto; import fr.gouv.vitamui.referential.common.dto.ContextDto; -import fr.gouv.vitamui.referential.common.dto.RuleDto; import fr.gouv.vitamui.referential.common.dto.AccessContractDto; import fr.gouv.vitamui.referential.common.dto.IngestContractDto; import fr.gouv.vitamui.referential.common.dto.SecurityProfileDto; diff --git a/integration-tests/src/test/java/fr/gouv/vitamui/utils/FactoryDto.java b/integration-tests/src/test/java/fr/gouv/vitamui/utils/FactoryDto.java index f2c485733..2eb22c5e7 100644 --- a/integration-tests/src/test/java/fr/gouv/vitamui/utils/FactoryDto.java +++ b/integration-tests/src/test/java/fr/gouv/vitamui/utils/FactoryDto.java @@ -1,24 +1,7 @@ package fr.gouv.vitamui.utils; -import static fr.gouv.vitamui.utils.TestConstants.ADMIN_LEVEL; -import static fr.gouv.vitamui.utils.TestConstants.SYSTEM_CUSTOMER_ID; -import static fr.gouv.vitamui.utils.TestConstants.SYSTEM_USER_PROFILE_ID; - -import java.util.Arrays; -import java.util.concurrent.ThreadLocalRandom; - import fr.gouv.vitamui.archives.search.common.dto.SearchCriteriaHistoryDto; import fr.gouv.vitamui.commons.api.domain.ExternalParametersDto; -import fr.gouv.vitamui.referential.common.dto.AccessContractDto; -import fr.gouv.vitamui.referential.common.dto.ContextDto; -import fr.gouv.vitamui.referential.common.dto.IngestContractDto; -import fr.gouv.vitamui.referential.common.dto.RuleDto; -import fr.gouv.vitamui.referential.common.dto.SecurityProfileDto; -import org.apache.commons.lang3.RandomStringUtils; -import org.openqa.selenium.InvalidArgumentException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.env.Environment; - import fr.gouv.vitamui.commons.api.domain.GroupDto; import fr.gouv.vitamui.commons.api.domain.OwnerDto; import fr.gouv.vitamui.commons.api.domain.ProfileDto; @@ -26,10 +9,26 @@ import fr.gouv.vitamui.commons.api.domain.Role; import fr.gouv.vitamui.commons.api.domain.ServicesData; import fr.gouv.vitamui.commons.api.domain.TenantDto; import fr.gouv.vitamui.commons.api.domain.UserDto; +import fr.gouv.vitamui.commons.rest.dto.RuleDto; import fr.gouv.vitamui.iam.common.dto.CustomerDto; import fr.gouv.vitamui.iam.common.dto.IdentityProviderDto; import fr.gouv.vitamui.iam.commons.utils.IamDtoBuilder; +import fr.gouv.vitamui.referential.common.dto.AccessContractDto; +import fr.gouv.vitamui.referential.common.dto.ContextDto; +import fr.gouv.vitamui.referential.common.dto.IngestContractDto; +import fr.gouv.vitamui.referential.common.dto.SecurityProfileDto; import fr.gouv.vitamui.referential.common.utils.ReferentialDtoBuilder; +import org.apache.commons.lang3.RandomStringUtils; +import org.openqa.selenium.InvalidArgumentException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; + +import java.util.Arrays; +import java.util.concurrent.ThreadLocalRandom; + +import static fr.gouv.vitamui.utils.TestConstants.ADMIN_LEVEL; +import static fr.gouv.vitamui.utils.TestConstants.SYSTEM_CUSTOMER_ID; +import static fr.gouv.vitamui.utils.TestConstants.SYSTEM_USER_PROFILE_ID; public class FactoryDto { diff --git a/ui/ui-archive-search/src/main/resources/application-dev.yml b/ui/ui-archive-search/src/main/resources/application-dev.yml index d63c0a46d..f2f0796f5 100644 --- a/ui/ui-archive-search/src/main/resources/application-dev.yml +++ b/ui/ui-archive-search/src/main/resources/application-dev.yml @@ -70,6 +70,22 @@ ui-archive-search: key-path: src/main/resources/dev/truststore_server.jks key-password: changeme hostname-verification: false + referential-external-client: + server-host: localhost + server-port: 8087 + connect-time-out: 30 + read-time-out: 30 + write-time-out: 30 + secure: true + ssl-configuration: + keystore: + key-path: src/main/resources/dev/keystore_ui-referential.jks + key-password: changeme + type: JKS + truststore: + key-path: src/main/resources/dev/truststore_server.jks + key-password: changeme + hostname-verification: false base-url: portal: "https://dev.vitamui.com:4200" archives-search: "https://dev.vitamui.com:4209/archive-search" diff --git a/ui/ui-archive-search/src/main/resources/dev/keystore_ui-referential.jks b/ui/ui-archive-search/src/main/resources/dev/keystore_ui-referential.jks new file mode 100644 index 0000000000000000000000000000000000000000..6a435ca4cb27e75cf6ad522732f18d6f2afe3797 GIT binary patch literal 3865 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 Z3<S3|p(zl&yvmuEINq8zwY&F5{|{)J{hI&) literal 0 HcmV?d00001 diff --git a/ui/ui-archive-search/src/test/resources/application.yml b/ui/ui-archive-search/src/test/resources/application.yml index 11a57f6ac..5f471b063 100644 --- a/ui/ui-archive-search/src/test/resources/application.yml +++ b/ui/ui-archive-search/src/test/resources/application.yml @@ -43,6 +43,19 @@ ui-archive-search: key-path: src/main/resources/dev/truststore_server.jks key-password: changeme hostname-verification: false + referential-external-client: + server-host: localhost + server-port: 8087 + secure: true + ssl-configuration: + keystore: + key-path: src/main/resources/dev/keystore_ui-archive-search.jks + key-password: changeme + type: JKS + truststore: + key-path: src/main/resources/dev/truststore_server.jks + key-password: changeme + hostname-verification: false ui-prefix: archive-search-api diff --git a/ui/ui-commons/pom.xml b/ui/ui-commons/pom.xml index 7d3460ff2..9bcf6d805 100644 --- a/ui/ui-commons/pom.xml +++ b/ui/ui-commons/pom.xml @@ -48,6 +48,10 @@ <groupId>fr.gouv.vitamui</groupId> <artifactId>iam-external-client</artifactId> </dependency> + <dependency> + <groupId>fr.gouv.vitamui</groupId> + <artifactId>referential-external-client</artifactId> + </dependency> <!-- Utils --> <dependency> <groupId>org.apache.commons</groupId> @@ -130,7 +134,11 @@ <groupId>org.owasp.antisamy</groupId> <artifactId>antisamy</artifactId> </dependency> - </dependencies> + <dependency> + <groupId>fr.gouv.vitamui</groupId> + <artifactId>referential-commons</artifactId> + </dependency> + </dependencies> <build> <plugins> diff --git a/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/config/AutoConfigurationRestController.java b/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/config/AutoConfigurationRestController.java index 1e2d4ef88..29d7d3a57 100644 --- a/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/config/AutoConfigurationRestController.java +++ b/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/config/AutoConfigurationRestController.java @@ -37,28 +37,29 @@ package fr.gouv.vitamui.ui.commons.config; import fr.gouv.vitamui.ui.commons.rest.AccessContractController; -import fr.gouv.vitamui.ui.commons.rest.ExternalParamProfileController; -import fr.gouv.vitamui.ui.commons.service.ExternalParamProfileService; -import fr.gouv.vitamui.ui.commons.service.AccessContractService; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.DependsOn; - import fr.gouv.vitamui.ui.commons.rest.AccountController; import fr.gouv.vitamui.ui.commons.rest.ApplicationController; +import fr.gouv.vitamui.ui.commons.rest.ExternalParamProfileController; import fr.gouv.vitamui.ui.commons.rest.ExternalParametersController; import fr.gouv.vitamui.ui.commons.rest.LogbookController; +import fr.gouv.vitamui.ui.commons.rest.RuleController; import fr.gouv.vitamui.ui.commons.rest.SecurityController; import fr.gouv.vitamui.ui.commons.rest.SubrogationController; import fr.gouv.vitamui.ui.commons.rest.UserController; +import fr.gouv.vitamui.ui.commons.service.AccessContractService; import fr.gouv.vitamui.ui.commons.service.AccountService; import fr.gouv.vitamui.ui.commons.service.ApplicationService; +import fr.gouv.vitamui.ui.commons.service.ExternalParamProfileService; import fr.gouv.vitamui.ui.commons.service.ExternalParametersService; import fr.gouv.vitamui.ui.commons.service.LogbookService; +import fr.gouv.vitamui.ui.commons.service.RuleService; import fr.gouv.vitamui.ui.commons.service.SubrogationService; import fr.gouv.vitamui.ui.commons.service.UserService; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.DependsOn; @Configuration public class AutoConfigurationRestController { @@ -121,4 +122,11 @@ public class AutoConfigurationRestController { public AccessContractController accessContractController(final AccessContractService accessContractService) { return new AccessContractController(accessContractService); } + + @Bean("CommonRuleController") + @DependsOn("CommonRuleService") + @ConditionalOnMissingBean + public RuleController ruleService(final RuleService ruleService) { + return new RuleController(ruleService); + } } diff --git a/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/config/AutoConfigurationService.java b/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/config/AutoConfigurationService.java index eebd7e190..ce023a345 100644 --- a/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/config/AutoConfigurationService.java +++ b/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/config/AutoConfigurationService.java @@ -38,14 +38,17 @@ package fr.gouv.vitamui.ui.commons.config; import fr.gouv.vitamui.commons.security.client.logout.CasLogoutUrl; import fr.gouv.vitamui.iam.external.client.IamExternalRestClientFactory; +import fr.gouv.vitamui.referential.external.client.ReferentialExternalRestClientFactory; +import fr.gouv.vitamui.referential.external.client.ReferentialExternalWebClientFactory; import fr.gouv.vitamui.ui.commons.property.UIProperties; -import fr.gouv.vitamui.ui.commons.service.ExternalParamProfileService; import fr.gouv.vitamui.ui.commons.service.AccessContractService; import fr.gouv.vitamui.ui.commons.service.AccountService; import fr.gouv.vitamui.ui.commons.service.ApplicationService; import fr.gouv.vitamui.ui.commons.service.CommonService; +import fr.gouv.vitamui.ui.commons.service.ExternalParamProfileService; import fr.gouv.vitamui.ui.commons.service.ExternalParametersService; import fr.gouv.vitamui.ui.commons.service.LogbookService; +import fr.gouv.vitamui.ui.commons.service.RuleService; import fr.gouv.vitamui.ui.commons.service.SubrogationService; import fr.gouv.vitamui.ui.commons.service.UserService; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -123,4 +126,12 @@ public class AutoConfigurationService { public AccessContractService accessContractService(final IamExternalRestClientFactory factory) { return new AccessContractService(factory.getAccessContractExternalRestClient()); } + + @Bean("CommonRuleService") + @DependsOn("referentialRestClientFactory") + @ConditionalOnMissingBean + public RuleService ruleService(final CommonService commonService, final ReferentialExternalRestClientFactory factoryRest, final + ReferentialExternalWebClientFactory dactoryWeb) { + return new RuleService(commonService ,factoryRest.getRuleExternalRestClient(), dactoryWeb.getRuleExternalWebClient()); + } } diff --git a/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/config/UICommonsAutoConfiguration.java b/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/config/UICommonsAutoConfiguration.java index bd7e43cbd..5b149f50d 100644 --- a/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/config/UICommonsAutoConfiguration.java +++ b/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/config/UICommonsAutoConfiguration.java @@ -36,6 +36,8 @@ */ package fr.gouv.vitamui.ui.commons.config; +import fr.gouv.vitamui.referential.external.client.ReferentialExternalRestClientFactory; +import fr.gouv.vitamui.referential.external.client.ReferentialExternalWebClientFactory; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.web.client.RestTemplateBuilder; @@ -68,4 +70,19 @@ public class UICommonsAutoConfiguration { public IamExternalRestClientFactory iamRestClientFactory(final UIProperties uiProperties, final RestTemplateBuilder restTemplateBuilder) { return new IamExternalRestClientFactory(uiProperties.getIamExternalClient(), restTemplateBuilder); } + + @Bean + @ConditionalOnMissingBean + @DependsOn("uiProperties") + public ReferentialExternalRestClientFactory referentialRestClientFactory(final UIProperties uiProperties, final RestTemplateBuilder restTemplateBuilder) { + return new ReferentialExternalRestClientFactory(uiProperties.getReferentialExternalClient(), restTemplateBuilder); + } + + @Bean + @ConditionalOnMissingBean + @DependsOn("uiProperties") + public ReferentialExternalWebClientFactory referentialWebClientFactory(final UIProperties uiProperties) { + return new ReferentialExternalWebClientFactory(uiProperties.getReferentialExternalClient()); + } + } diff --git a/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/config/UIPropertiesImpl.java b/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/config/UIPropertiesImpl.java index 971b4b4f0..bc89dd1d8 100644 --- a/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/config/UIPropertiesImpl.java +++ b/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/config/UIPropertiesImpl.java @@ -88,4 +88,6 @@ public class UIPropertiesImpl implements UIProperties { private Map<String, Map<String,Object>> portalCategories; private String versionRelease; + + private RestClientConfiguration referentialExternalClient; } diff --git a/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/property/UIProperties.java b/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/property/UIProperties.java index f9fa15323..59436627b 100644 --- a/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/property/UIProperties.java +++ b/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/property/UIProperties.java @@ -36,10 +36,10 @@ */ package fr.gouv.vitamui.ui.commons.property; -import java.util.Map; - import fr.gouv.vitamui.commons.rest.client.configuration.RestClientConfiguration; +import java.util.Map; + public interface UIProperties { public String getPrefix(); @@ -48,6 +48,8 @@ public interface UIProperties { public RestClientConfiguration getIamExternalClient(); + public RestClientConfiguration getReferentialExternalClient(); + public Integer getLimitPagination(); public String getPortalLogo(); diff --git a/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/rest/RuleController.java b/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/rest/RuleController.java new file mode 100644 index 000000000..76e149d22 --- /dev/null +++ b/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/rest/RuleController.java @@ -0,0 +1,191 @@ +/** + * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2020) + * and the signatories of the "VITAM - Accord du Contributeur" agreement. + * + * contact@programmevitam.fr + * + * This software is a computer program whose purpose is to implement + * implement a digital archiving front-office system for the secure and + * efficient high volumetry VITAM solution. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-C license and that you accept its terms. + */ +package fr.gouv.vitamui.ui.commons.rest; + +import com.fasterxml.jackson.databind.JsonNode; +import fr.gouv.vitamui.commons.api.CommonConstants; +import fr.gouv.vitamui.commons.api.ParameterChecker; +import fr.gouv.vitamui.commons.api.domain.DirectionDto; +import fr.gouv.vitamui.commons.api.domain.PaginatedValuesDto; +import fr.gouv.vitamui.commons.api.logger.VitamUILogger; +import fr.gouv.vitamui.commons.api.logger.VitamUILoggerFactory; +import fr.gouv.vitamui.commons.rest.AbstractUiRestController; +import fr.gouv.vitamui.commons.rest.dto.RuleDto; +import fr.gouv.vitamui.commons.rest.util.RestUtils; +import fr.gouv.vitamui.commons.vitam.api.dto.LogbookOperationsResponseDto; +import fr.gouv.vitamui.referential.common.rest.RestApi; +import fr.gouv.vitamui.ui.commons.service.RuleService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.util.Assert; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import javax.ws.rs.Consumes; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.Collection; +import java.util.Map; +import java.util.Optional; + +@Api(tags = "rule") +@RestController +@RequestMapping("${ui-prefix}/rules") +@Consumes("application/json") +@Produces("application/json") +public class RuleController extends AbstractUiRestController { + + protected final RuleService service; + + private static final VitamUILogger LOGGER = VitamUILoggerFactory.getInstance(RuleController.class); + + @Autowired + public RuleController(final RuleService service) { + this.service = service; + } + + @ApiOperation(value = "Get entities paginated") + @GetMapping(params = { "page", "size" }) + @ResponseStatus(HttpStatus.OK) + public PaginatedValuesDto<RuleDto> getAllPaginated(@RequestParam final Integer page, @RequestParam final Integer size, + @RequestParam final Optional<String> criteria, @RequestParam final Optional<String> orderBy, @RequestParam final Optional<DirectionDto> direction) { + LOGGER.debug("getAllPaginated page={}, size={}, criteria={}, orderBy={}, ascendant={}", page, size, criteria, orderBy, direction); + return service.getAllPaginated(page, size, criteria, orderBy, direction, buildUiHttpContext()); + } + + @ApiOperation(value = "Get entity") + @GetMapping + @ResponseStatus(HttpStatus.OK) + public Collection<RuleDto> getAll(final Optional<String> criteria) { + LOGGER.debug("Get all with criteria={}", criteria); + RestUtils.checkCriteria(criteria); + return service.getAll(buildUiHttpContext(), criteria); + } + + @ApiOperation(value = "Get rule by ID") + @GetMapping(path = RestApi.PATH_REFERENTIAL_ID) + @ResponseStatus(HttpStatus.OK) + public RuleDto getById(final @PathVariable("identifier") String identifier) throws UnsupportedEncodingException { + LOGGER.debug("getById {} / {}", identifier, URLEncoder.encode(identifier, StandardCharsets.UTF_8.toString())); + ParameterChecker.checkParameter("The Identifier is a mandatory parameter: ", identifier); + return service.getOne(buildUiHttpContext(), URLEncoder.encode(identifier, StandardCharsets.UTF_8.toString())); + } + + @ApiOperation(value = "Check ability to create rule") + @PostMapping(path = CommonConstants.PATH_CHECK) + public ResponseEntity<Void> check(@RequestBody RuleDto ruleDto) { + LOGGER.debug("check ability to create rule={}", ruleDto); + final boolean exist = service.check(buildUiHttpContext(), ruleDto); + LOGGER.debug("response value={}" + exist); + return RestUtils.buildBooleanResponse(exist); + } + + @ApiOperation(value = "Create rule") + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + public ResponseEntity<Void> create(@Valid @RequestBody RuleDto ruleDto) { + LOGGER.debug("create rule={}", ruleDto); + return RestUtils.buildBooleanResponse( + service.createRule(buildUiHttpContext(), ruleDto) + ); + } + + @ApiOperation(value = "Patch entity") + @PatchMapping(CommonConstants.PATH_ID) + @ResponseStatus(HttpStatus.OK) + public ResponseEntity<Void> patch(final @PathVariable("id") String id, @RequestBody final Map<String, Object> partialDto) { + LOGGER.debug("Patch User {} with {}", id, partialDto); + ParameterChecker.checkParameter("The Identifier, the partialEntity are mandatory parameters: ", id, partialDto); + Assert.isTrue(StringUtils.equals(id, (String) partialDto.get("id")), "Unable to patch rule : the DTO id must match the path id."); + return RestUtils.buildBooleanResponse( + service.patchRule(buildUiHttpContext(), partialDto, id) + ); + } + + @ApiOperation(value = "get history by rule's id") + @GetMapping(CommonConstants.PATH_LOGBOOK) + public LogbookOperationsResponseDto findHistoryById(final @PathVariable String id) { + LOGGER.debug("get logbook for rule with id :{}", id); + ParameterChecker.checkParameter("The Identifier is a mandatory parameter: ", id); + return service.findHistoryById(buildUiHttpContext(), id); + } + + @ApiOperation(value = "delete rule") + @DeleteMapping(CommonConstants.PATH_ID) + public ResponseEntity<Void> delete(final @PathVariable String id) { + LOGGER.debug("delete rule with id :{}", id); + ParameterChecker.checkParameter("The Identifier is a mandatory parameter: ", id); + return RestUtils.buildBooleanResponse( + service.deleteRule(buildUiHttpContext(), id) + ); + } + + @ApiOperation(value = "get exported csv for rules") + @GetMapping("/export") + @Produces(MediaType.APPLICATION_OCTET_STREAM_VALUE) + public ResponseEntity<Resource> export() { + LOGGER.debug("export rules"); + return service.export(buildUiHttpContext()); + } + + @ApiOperation(value = "import a rule file") + @PostMapping(CommonConstants.PATH_IMPORT) + public JsonNode importRules(@Context HttpServletRequest request, MultipartFile file) { + LOGGER.debug("Import rule file {}", file != null ? file.getOriginalFilename() : null); + return service.importRules(buildUiHttpContext(), file); + } +} diff --git a/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/service/RuleService.java b/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/service/RuleService.java new file mode 100644 index 000000000..facbb03e9 --- /dev/null +++ b/ui/ui-commons/src/main/java/fr/gouv/vitamui/ui/commons/service/RuleService.java @@ -0,0 +1,118 @@ +/** + * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2020) + * and the signatories of the "VITAM - Accord du Contributeur" agreement. + * + * contact@programmevitam.fr + * + * This software is a computer program whose purpose is to implement + * implement a digital archiving front-office system for the secure and + * efficient high volumetry VITAM solution. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-C license and that you accept its terms. + */ +package fr.gouv.vitamui.ui.commons.service; + +import com.fasterxml.jackson.databind.JsonNode; +import fr.gouv.vitamui.commons.api.domain.DirectionDto; +import fr.gouv.vitamui.commons.api.domain.PaginatedValuesDto; +import fr.gouv.vitamui.commons.api.logger.VitamUILogger; +import fr.gouv.vitamui.commons.api.logger.VitamUILoggerFactory; +import fr.gouv.vitamui.commons.rest.client.BasePaginatingAndSortingRestClient; +import fr.gouv.vitamui.commons.rest.client.ExternalHttpContext; +import fr.gouv.vitamui.commons.rest.dto.RuleDto; +import fr.gouv.vitamui.referential.external.client.RuleExternalRestClient; +import fr.gouv.vitamui.referential.external.client.RuleExternalWebClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.Resource; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +@Service +public class RuleService extends AbstractPaginateService<RuleDto>{ + static final VitamUILogger LOGGER = VitamUILoggerFactory.getInstance(RuleService.class); + + private RuleExternalRestClient client; + + private RuleExternalWebClient webClient; + + private CommonService commonService; + + @Autowired + public RuleService(final CommonService commonService, final RuleExternalRestClient client, final RuleExternalWebClient webClient) { + this.commonService = commonService; + this.client = client; + this.webClient = webClient; + } + + @Override + public PaginatedValuesDto<RuleDto> getAllPaginated(final Integer page, final Integer size, final Optional<String> criteria, + final Optional<String> orderBy, final Optional<DirectionDto> direction, final ExternalHttpContext context) { + return super.getAllPaginated(page, size, criteria, orderBy, direction, context); + } + + @Override + protected Integer beforePaginate(final Integer page, final Integer size) { + return commonService.checkPagination(page, size); + } + + @Override public BasePaginatingAndSortingRestClient<RuleDto, ExternalHttpContext> getClient() { + return client; + } + + public List<RuleDto> getAll(final ExternalHttpContext context, final Optional<String> criteria) { + return client.getAll(context, criteria); + } + + public boolean check(ExternalHttpContext context, RuleDto ruleDto) { + return client.check(context,ruleDto); + } + + public boolean createRule(ExternalHttpContext context, RuleDto ruleDto) { + return client.createRule(context, ruleDto); + } + + public boolean patchRule(ExternalHttpContext context, Map<String, Object> partialDto, String id) { + return client.patchRule(context, partialDto, id); + } + + public boolean deleteRule(ExternalHttpContext context, String id) { + return client.deleteRule(context, id); + } + + public ResponseEntity<Resource> export(ExternalHttpContext context) { + return client.export(context); + } + + public JsonNode importRules(ExternalHttpContext context, MultipartFile file) { + return webClient.importRules(context, file); + } +} diff --git a/ui/ui-commons/src/test/java/fr/gouv/vitamui/ui/commons/config/UICommonsAutoConfigurationTest.java b/ui/ui-commons/src/test/java/fr/gouv/vitamui/ui/commons/config/UICommonsAutoConfigurationTest.java index 5a60b4a99..9410143bf 100644 --- a/ui/ui-commons/src/test/java/fr/gouv/vitamui/ui/commons/config/UICommonsAutoConfigurationTest.java +++ b/ui/ui-commons/src/test/java/fr/gouv/vitamui/ui/commons/config/UICommonsAutoConfigurationTest.java @@ -1,23 +1,26 @@ package fr.gouv.vitamui.ui.commons.config; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - import fr.gouv.vitamui.commons.rest.client.configuration.RestClientConfiguration; import fr.gouv.vitamui.commons.security.client.logout.CasLogoutUrl; import fr.gouv.vitamui.iam.external.client.IamExternalRestClientFactory; +import fr.gouv.vitamui.referential.external.client.ReferentialExternalRestClientFactory; +import fr.gouv.vitamui.referential.external.client.ReferentialExternalWebClientFactory; import fr.gouv.vitamui.ui.commons.property.UIProperties; import fr.gouv.vitamui.ui.commons.rest.AccountController; import fr.gouv.vitamui.ui.commons.rest.ApplicationController; +import fr.gouv.vitamui.ui.commons.rest.RuleController; import fr.gouv.vitamui.ui.commons.rest.SubrogationController; import fr.gouv.vitamui.ui.commons.service.ApplicationService; +import fr.gouv.vitamui.ui.commons.service.RuleService; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.assertj.core.api.Assertions.assertThat; @RunWith(SpringJUnit4ClassRunner.class) public class UICommonsAutoConfigurationTest { @@ -36,6 +39,10 @@ public class UICommonsAutoConfigurationTest { assertThat(context).hasSingleBean(IamExternalRestClientFactory.class); assertThat(context).hasSingleBean(SubrogationController.class); assertThat(context).hasSingleBean(AccountController.class); + assertThat(context).hasSingleBean(ReferentialExternalRestClientFactory.class); + assertThat(context).hasSingleBean(ReferentialExternalWebClientFactory.class); + assertThat(context).hasSingleBean(RuleService.class); + assertThat(context).hasSingleBean(RuleController.class); }); } @@ -47,6 +54,7 @@ public class UICommonsAutoConfigurationTest { public UIProperties uiProperties() { final UIPropertiesImpl properties = new UIPropertiesImpl(); properties.setIamExternalClient(new RestClientConfiguration()); + properties.setReferentialExternalClient(new RestClientConfiguration()); return properties; } diff --git a/ui/ui-commons/src/test/java/fr/gouv/vitamui/ui/commons/rest/ApplicationControllerTest.java b/ui/ui-commons/src/test/java/fr/gouv/vitamui/ui/commons/rest/ApplicationControllerTest.java index 7903f420e..e7008add8 100644 --- a/ui/ui-commons/src/test/java/fr/gouv/vitamui/ui/commons/rest/ApplicationControllerTest.java +++ b/ui/ui-commons/src/test/java/fr/gouv/vitamui/ui/commons/rest/ApplicationControllerTest.java @@ -37,6 +37,7 @@ public class ApplicationControllerTest extends UIControllerTest<ApplicationDto> public UIProperties uiProperties() { final UIPropertiesImpl properties = new UIPropertiesImpl(); properties.setIamExternalClient(new RestClientConfiguration()); + properties.setReferentialExternalClient(new RestClientConfiguration()); return properties; } } diff --git a/ui/ui-commons/src/test/java/fr/gouv/vitamui/ui/commons/rest/SecurityControllerTest.java b/ui/ui-commons/src/test/java/fr/gouv/vitamui/ui/commons/rest/SecurityControllerTest.java index 728df921d..0f11dd19d 100644 --- a/ui/ui-commons/src/test/java/fr/gouv/vitamui/ui/commons/rest/SecurityControllerTest.java +++ b/ui/ui-commons/src/test/java/fr/gouv/vitamui/ui/commons/rest/SecurityControllerTest.java @@ -23,8 +23,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import java.util.Properties; - @RunWith(SpringJUnit4ClassRunner.class) @ImportAutoConfiguration(classes = { UICommonsAutoConfiguration.class, UICommonsAutoSpringMockConfiguration.class }) @WebMvcTest(controllers = { SecurityController.class }) @@ -38,6 +36,7 @@ public class SecurityControllerTest extends UIControllerTest<UserDto> { public UIProperties uiProperties() { final UIPropertiesImpl properties = new UIPropertiesImpl(); properties.setIamExternalClient(new RestClientConfiguration()); + properties.setReferentialExternalClient(new RestClientConfiguration()); return properties; } } diff --git a/ui/ui-commons/src/test/java/fr/gouv/vitamui/ui/commons/rest/SubrogationControllerTest.java b/ui/ui-commons/src/test/java/fr/gouv/vitamui/ui/commons/rest/SubrogationControllerTest.java index d8e8b0025..f6ed2a851 100644 --- a/ui/ui-commons/src/test/java/fr/gouv/vitamui/ui/commons/rest/SubrogationControllerTest.java +++ b/ui/ui-commons/src/test/java/fr/gouv/vitamui/ui/commons/rest/SubrogationControllerTest.java @@ -1,8 +1,16 @@ package fr.gouv.vitamui.ui.commons.rest; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; - +import fr.gouv.vitamui.commons.api.identity.ServerIdentityConfiguration; +import fr.gouv.vitamui.commons.api.logger.VitamUILogger; +import fr.gouv.vitamui.commons.api.logger.VitamUILoggerFactory; +import fr.gouv.vitamui.commons.rest.client.configuration.RestClientConfiguration; +import fr.gouv.vitamui.iam.common.dto.SubrogationDto; +import fr.gouv.vitamui.ui.commons.config.UICommonsAutoConfiguration; +import fr.gouv.vitamui.ui.commons.config.UICommonsAutoSpringMockConfiguration; +import fr.gouv.vitamui.ui.commons.config.UIPropertiesImpl; +import fr.gouv.vitamui.ui.commons.property.UIProperties; +import fr.gouv.vitamui.ui.commons.security.SecurityConfig; +import fr.gouv.vitamui.ui.commons.service.SubrogationService; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; @@ -16,17 +24,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import fr.gouv.vitamui.commons.api.identity.ServerIdentityConfiguration; -import fr.gouv.vitamui.commons.api.logger.VitamUILogger; -import fr.gouv.vitamui.commons.api.logger.VitamUILoggerFactory; -import fr.gouv.vitamui.commons.rest.client.configuration.RestClientConfiguration; -import fr.gouv.vitamui.iam.common.dto.SubrogationDto; -import fr.gouv.vitamui.ui.commons.config.UICommonsAutoConfiguration; -import fr.gouv.vitamui.ui.commons.config.UICommonsAutoSpringMockConfiguration; -import fr.gouv.vitamui.ui.commons.config.UIPropertiesImpl; -import fr.gouv.vitamui.ui.commons.property.UIProperties; -import fr.gouv.vitamui.ui.commons.security.SecurityConfig; -import fr.gouv.vitamui.ui.commons.service.SubrogationService; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; @RunWith(SpringJUnit4ClassRunner.class) @ImportAutoConfiguration(classes = {UICommonsAutoConfiguration.class, UICommonsAutoSpringMockConfiguration.class}) @@ -41,6 +40,7 @@ public class SubrogationControllerTest extends UIControllerTest<SubrogationDto> public UIProperties uiProperties() { final UIPropertiesImpl properties = new UIPropertiesImpl(); properties.setIamExternalClient(new RestClientConfiguration()); + properties.setReferentialExternalClient(new RestClientConfiguration()); return properties; } diff --git a/ui/ui-commons/src/test/java/fr/gouv/vitamui/ui/commons/rest/UserControllerTest.java b/ui/ui-commons/src/test/java/fr/gouv/vitamui/ui/commons/rest/UserControllerTest.java index 962f3cd0e..09b9c4492 100644 --- a/ui/ui-commons/src/test/java/fr/gouv/vitamui/ui/commons/rest/UserControllerTest.java +++ b/ui/ui-commons/src/test/java/fr/gouv/vitamui/ui/commons/rest/UserControllerTest.java @@ -1,12 +1,19 @@ package fr.gouv.vitamui.ui.commons.rest; -import static fr.gouv.vitamui.commons.api.CommonConstants.APPLICATION_ID; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import java.util.Map; - +import com.google.common.collect.ImmutableMap; +import fr.gouv.vitamui.commons.api.CommonConstants; +import fr.gouv.vitamui.commons.api.domain.UserDto; +import fr.gouv.vitamui.commons.api.identity.ServerIdentityConfiguration; +import fr.gouv.vitamui.commons.api.logger.VitamUILogger; +import fr.gouv.vitamui.commons.api.logger.VitamUILoggerFactory; +import fr.gouv.vitamui.commons.rest.client.ExternalHttpContext; +import fr.gouv.vitamui.commons.rest.client.configuration.RestClientConfiguration; +import fr.gouv.vitamui.ui.commons.config.UICommonsAutoConfiguration; +import fr.gouv.vitamui.ui.commons.config.UICommonsAutoSpringMockConfiguration; +import fr.gouv.vitamui.ui.commons.config.UIPropertiesImpl; +import fr.gouv.vitamui.ui.commons.property.UIProperties; +import fr.gouv.vitamui.ui.commons.security.SecurityConfig; +import fr.gouv.vitamui.ui.commons.service.UserService; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; @@ -21,21 +28,12 @@ import org.springframework.context.annotation.Import; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.web.servlet.ResultActions; -import com.google.common.collect.ImmutableMap; +import java.util.Map; -import fr.gouv.vitamui.commons.api.CommonConstants; -import fr.gouv.vitamui.commons.api.domain.UserDto; -import fr.gouv.vitamui.commons.api.identity.ServerIdentityConfiguration; -import fr.gouv.vitamui.commons.api.logger.VitamUILogger; -import fr.gouv.vitamui.commons.api.logger.VitamUILoggerFactory; -import fr.gouv.vitamui.commons.rest.client.ExternalHttpContext; -import fr.gouv.vitamui.commons.rest.client.configuration.RestClientConfiguration; -import fr.gouv.vitamui.ui.commons.config.UICommonsAutoConfiguration; -import fr.gouv.vitamui.ui.commons.config.UICommonsAutoSpringMockConfiguration; -import fr.gouv.vitamui.ui.commons.config.UIPropertiesImpl; -import fr.gouv.vitamui.ui.commons.property.UIProperties; -import fr.gouv.vitamui.ui.commons.security.SecurityConfig; -import fr.gouv.vitamui.ui.commons.service.UserService; +import static fr.gouv.vitamui.commons.api.CommonConstants.APPLICATION_ID; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @RunWith(SpringJUnit4ClassRunner.class) @ImportAutoConfiguration(classes = {UICommonsAutoConfiguration.class, UICommonsAutoSpringMockConfiguration.class}) @@ -60,6 +58,7 @@ public class UserControllerTest extends UIControllerTest<UserDto> { public UIProperties uiProperties() { final UIPropertiesImpl properties = new UIPropertiesImpl(); properties.setIamExternalClient(new RestClientConfiguration()); + properties.setReferentialExternalClient(new RestClientConfiguration()); return properties; } diff --git a/ui/ui-frontend-common/src/app/modules/api/rule-api.service.ts b/ui/ui-frontend-common/src/app/modules/api/rule-api.service.ts new file mode 100644 index 000000000..8df7ee78e --- /dev/null +++ b/ui/ui-frontend-common/src/app/modules/api/rule-api.service.ts @@ -0,0 +1,99 @@ +/* + * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2020) + * and the signatories of the "VITAM - Accord du Contributeur" agreement. + * + * contact@programmevitam.fr + * + * This software is a computer program whose purpose is to implement + * implement a digital archiving front-office system for the secure and + * efficient high volumetry VITAM solution. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-C license and that you accept its terms. + */ +import { HttpClient, HttpHeaders, HttpParams, HttpResponse } from '@angular/common/http'; +import { Inject, Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; +import { BaseHttpClient } from '../base-http-client'; +import { BASE_URL } from '../injection-tokens'; +import { Rule } from '../models/rule/rule.interface'; +import { PageRequest, PaginatedResponse } from '../vitamui-table'; + +const HTTP_STATUS_OK = 200; + +@Injectable({ + providedIn: 'root' +}) +export class RuleApiService extends BaseHttpClient<Rule> { + constructor(http: HttpClient, @Inject(BASE_URL) baseUrl: string) { + super(http, baseUrl + '/rules'); + } + + getAllByParams(params: HttpParams, headers?: HttpHeaders) { + return super.getAllByParams(params, headers); + } + + getAllPaginated(pageRequest: PageRequest, embedded?: string, headers?: HttpHeaders): Observable<PaginatedResponse<Rule>> { + return super.getAllPaginated(pageRequest, embedded, headers); + } + + getOne(id: string, headers?: HttpHeaders): Observable<Rule> { + return super.getOne(id, headers); + } + + createRule(rule: Rule, headers?: HttpHeaders): Observable<boolean> { + return super + .getHttp() + .post<any>(super.getApiUrl(), rule, { observe: 'response', headers }) + .pipe(map((response: HttpResponse<void>) => response.status === HTTP_STATUS_OK)); + } + + patchRule(partialRule: { id: string; [key: string]: any }, headers?: HttpHeaders): Observable<boolean> { + return super + .getHttp() + .patch<any>(super.getApiUrl() + '/' + partialRule.id, partialRule, { observe: 'response', headers }) + .pipe(map((response: HttpResponse<void>) => response.status === HTTP_STATUS_OK)); + } + + deleteRule(id: string, headers?: HttpHeaders): Observable<boolean> { + return super + .getHttp() + .delete<any>(super.getApiUrl() + '/' + id, { observe: 'response', headers }) + .pipe(map((response: HttpResponse<void>) => response.status === HTTP_STATUS_OK)); + } + + check(rule: Rule, headers?: HttpHeaders): Observable<boolean> { + return super + .getHttp() + .post<any>(super.getApiUrl() + '/check', rule, { observe: 'response', headers }) + .pipe(map((response: HttpResponse<void>) => response.status === HTTP_STATUS_OK)); + } + + export(headers?: HttpHeaders): Observable<any> { + return super.getHttp().get(super.getApiUrl() + '/export', { headers, responseType: 'text' }); + } +} diff --git a/ui/ui-frontend-common/src/app/modules/components/vitamui-snack-bar/vitamui-snack-bar.component.html b/ui/ui-frontend-common/src/app/modules/components/vitamui-snack-bar/vitamui-snack-bar.component.html index 9f1f18887..3bc74d5d6 100644 --- a/ui/ui-frontend-common/src/app/modules/components/vitamui-snack-bar/vitamui-snack-bar.component.html +++ b/ui/ui-frontend-common/src/app/modules/components/vitamui-snack-bar/vitamui-snack-bar.component.html @@ -1,20 +1,59 @@ <div class="vitamui-snack-bar-container"> - <span class="vitamui-snack-bar-content" [ngSwitch]="data?.type"> - <ng-container *ngSwitchCase="'accountUpdate'"> - <i class="vitamui-icon vitamui-icon-user"></i> {{'SNACKBAR.UPDATED_ACCOUNT' | translate}} + <i class="vitamui-icon vitamui-icon-user"></i> {{ 'SNACKBAR.UPDATED_ACCOUNT' | translate }} </ng-container> <ng-container *ngSwitchCase="'subrogationFinish'"> - <i class="vitamui-icon vitamui-icon-link banner-icon"></i> {{'SNACKBAR.FINISHED_SUBROGATION' | translate}} + <i class="vitamui-icon vitamui-icon-link banner-icon"></i> {{ 'SNACKBAR.FINISHED_SUBROGATION' | translate }} </ng-container> <ng-container *ngSwitchCase="'subrogationActivated'"> - <i class="vitamui-icon vitamui-icon-link banner-icon"></i> {{'SNACKBAR.ACTIVATED_SUBROGATION' | translate : { duration: data.duration, hours: data.endTime | date:'H', minutes: data.endTime | date: 'mm' } }} + <i class="vitamui-icon vitamui-icon-link banner-icon"></i> + {{ + 'SNACKBAR.ACTIVATED_SUBROGATION' + | translate: { duration: data.duration, hours: data.endTime | date: 'H', minutes: data.endTime | date: 'mm' } + }} + </ng-container> + + <ng-container *ngSwitchCase="'ruleCreateSuccess'"> + <i class="vitamui-icon vitamui-icon-rules"></i> {{ 'APPLICATION.RULES_APP.MESSAGES.COMMON_RULE_MESSAGE' | translate }} + {{ data?.name }} {{ 'APPLICATION.RULES_APP.MESSAGES.CREATION_SUCCESS' | translate }} + </ng-container> + + <ng-container *ngSwitchCase="'ruleCreateFailed'"> + <i class="vitamui-icon vitamui-icon-rules"></i> {{ 'APPLICATION.RULES_APP.MESSAGES.COMMON_RULE_MESSAGE' | translate }} + {{ data?.name }} {{ 'APPLICATION.RULES_APP.MESSAGES.CREATION_FAILED' | translate }} + </ng-container> + + <ng-container *ngSwitchCase="'ruleUpdateSuccess'"> + <i class="vitamui-icon vitamui-icon-admin-rules"></i> {{ 'APPLICATION.RULES_APP.MESSAGES.COMMON_RULE_MESSAGE' | translate }} + {{ data?.name }} {{ 'APPLICATION.RULES_APP.MESSAGES.UPDATE_SUCCESS' | translate }} + </ng-container> + + <ng-container *ngSwitchCase="'ruleUpdateFailed'"> + <i class="vitamui-icon vitamui-icon-admin-rules"></i> {{ 'APPLICATION.RULES_APP.MESSAGES.COMMON_RULE_MESSAGE' | translate }} + {{ data?.name }} {{ 'APPLICATION.RULES_APP.MESSAGES.UPDATE_FAILED' | translate }} + </ng-container> + + <ng-container *ngSwitchCase="'ruleDeleteSuccess'"> + <i class="vitamui-icon vitamui-icon-admin-rules"></i> {{ 'APPLICATION.RULES_APP.MESSAGES.COMMON_RULE_MESSAGE' | translate }} + {{ data?.name }} {{ 'APPLICATION.RULES_APP.MESSAGES.DELETION_SUCCESS' | translate }} + </ng-container> + + <ng-container *ngSwitchCase="'ruleDeleteFailed'"> + <i class="vitamui-icon vitamui-icon-admin-rules"></i> {{ 'APPLICATION.RULES_APP.MESSAGES.COMMON_RULE_MESSAGE' | translate }} + {{ data?.name }} {{ 'APPLICATION.RULES_APP.MESSAGES.DELETION_FAILED' | translate }} </ng-container> + <ng-container *ngSwitchCase="'ruleDeleteStart'"> + <i class="vitamui-icon vitamui-icon-admin-rules"></i> {{ 'APPLICATION.RULES_APP.MESSAGES.DELETION' | translate }} {{ data?.name }} + {{ 'APPLICATION.RULES_APP.MESSAGES.OPERATION_IN_PROGRESS' | translate }} + </ng-container> + + <ng-container *ngSwitchCase="'ruleExportAll'"> + <i class="vitamui-icon vitamui-icon-rules"></i> {{ 'APPLICATION.RULES_APP.MESSAGES.EXPORT_IN_PROGRESS' | translate }} + </ng-container> </span> <button class="close-btn" (click)="close()"><i class="material-icons">clear</i></button> - </div> diff --git a/ui/ui-frontend-common/src/app/modules/index.ts b/ui/ui-frontend-common/src/app/modules/index.ts index 3b1d4a82d..9f2197f1a 100644 --- a/ui/ui-frontend-common/src/app/modules/index.ts +++ b/ui/ui-frontend-common/src/app/modules/index.ts @@ -43,6 +43,7 @@ export * from './api/application-api.service'; export * from './api/external-param-profile-api.service'; export * from './api/logbook-api.service'; export * from './api/profile-api.service'; +export * from './api/rule-api.service'; export * from './api/subrogation-api.service'; export * from './api/user-api.service'; export * from './app-root-component.class'; @@ -95,6 +96,7 @@ export * from './models/index'; export * from './module-import-guard'; export * from './paginated-api.interface'; export * from './pipes/index'; +export * from './rule/index'; export * from './security/security.service'; export * from './services/index'; export * from './sidenav-page.class'; diff --git a/ui/ui-frontend-common/src/app/modules/models/index.ts b/ui/ui-frontend-common/src/app/modules/models/index.ts index b40db41df..b87b9fd96 100644 --- a/ui/ui-frontend-common/src/app/modules/models/index.ts +++ b/ui/ui-frontend-common/src/app/modules/models/index.ts @@ -34,23 +34,24 @@ * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. */ -export * from './application/index'; +export * from './access-register/index'; export * from './app.configuration.interface'; +export * from './application/index'; +export * from './breadcrumb/breadcrumb.interface'; export * from './content-disposition.enum'; +export * from './criteria/criteria.enums'; export * from './criteria/criteria.interface'; export * from './criteria/criterion.interface'; -export * from './criteria/criteria.enums'; export * from './customer/index'; +export * from './externalparamprofile/index'; export * from './group/index'; export * from './id.interface'; export * from './logbook/index'; export * from './operation/index'; export * from './position/index'; export * from './profile/index'; -export * from './externalparamprofile/index'; +export * from './rule/index'; export * from './subrogation/index'; export * from './tree-node.interface'; export * from './user/index'; export * from './vitam/index'; -export * from './breadcrumb/breadcrumb.interface'; -export * from './access-register/index'; diff --git a/ui/ui-frontend-common/src/app/modules/models/rule/index.ts b/ui/ui-frontend-common/src/app/modules/models/rule/index.ts new file mode 100644 index 000000000..1df94d130 --- /dev/null +++ b/ui/ui-frontend-common/src/app/modules/models/rule/index.ts @@ -0,0 +1,37 @@ +/* + * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2020) + * and the signatories of the "VITAM - Accord du Contributeur" agreement. + * + * contact@programmevitam.fr + * + * This software is a computer program whose purpose is to implement + * implement a digital archiving front-office system for the secure and + * efficient high volumetry VITAM solution. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-C license and that you accept its terms. + */ +export * from './rule.interface'; diff --git a/ui/ui-frontend-common/src/app/modules/models/rule/rule.interface.ts b/ui/ui-frontend-common/src/app/modules/models/rule/rule.interface.ts new file mode 100644 index 000000000..722375912 --- /dev/null +++ b/ui/ui-frontend-common/src/app/modules/models/rule/rule.interface.ts @@ -0,0 +1,52 @@ +import { Id } from '../id.interface'; + +/* + * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2020) + * and the signatories of the "VITAM - Accord du Contributeur" agreement. + * + * contact@programmevitam.fr + * + * This software is a computer program whose purpose is to implement + * implement a digital archiving front-office system for the secure and + * efficient high volumetry VITAM solution. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-C license and that you accept its terms. + */ + +export interface Rule extends Id { + id: string; + tenant: number; + version: number; + ruleId: string; + ruleType: string; + ruleValue: string; + ruleDescription: string; + ruleDuration: string; + ruleMeasurement: string; + creationDate: string; + updateDate: string; +} diff --git a/ui/ui-frontend-common/src/app/modules/rule/index.ts b/ui/ui-frontend-common/src/app/modules/rule/index.ts new file mode 100644 index 000000000..65b5021de --- /dev/null +++ b/ui/ui-frontend-common/src/app/modules/rule/index.ts @@ -0,0 +1,37 @@ +/* + * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2020) + * and the signatories of the "VITAM - Accord du Contributeur" agreement. + * + * contact@programmevitam.fr + * + * This software is a computer program whose purpose is to implement + * implement a digital archiving front-office system for the secure and + * efficient high volumetry VITAM solution. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-C license and that you accept its terms. + */ +export * from './rule.service'; diff --git a/ui/ui-frontend-common/src/app/modules/rule/rule.service.ts b/ui/ui-frontend-common/src/app/modules/rule/rule.service.ts new file mode 100644 index 000000000..90e62e734 --- /dev/null +++ b/ui/ui-frontend-common/src/app/modules/rule/rule.service.ts @@ -0,0 +1,181 @@ +/* + * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2020) + * and the signatories of the "VITAM - Accord du Contributeur" agreement. + * + * contact@programmevitam.fr + * + * This software is a computer program whose purpose is to implement + * implement a digital archiving front-office system for the secure and + * efficient high volumetry VITAM solution. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-C license and that you accept its terms. + */ +import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Observable, Subject } from 'rxjs'; +import { tap } from 'rxjs/operators'; +import { RuleApiService } from '../api/rule-api.service'; +import { VitamUISnackBar } from '../components/vitamui-snack-bar'; +import { VitamUISnackBarComponent } from '../components/vitamui-snack-bar/vitamui-snack-bar.component'; +import { Rule } from '../models/rule/rule.interface'; +import { SearchService } from '../vitamui-table'; + +@Injectable({ + providedIn: 'root' +}) +export class RuleService extends SearchService<Rule> { + updated = new Subject<Rule>(); + + constructor(private ruleApiService: RuleApiService, private snackBar: VitamUISnackBar, http: HttpClient) { + super(http, ruleApiService, 'ALL'); + } + + get(ruleId: string): Observable<Rule> { + return this.ruleApiService.getOne(encodeURI(ruleId)); + } + + getAllForTenant(tenantId: string): Observable<Rule[]> { + // TODO: Check add of tenantId + const params = new HttpParams().set('embedded', 'ALL'); + const headers = new HttpHeaders().append('X-Tenant-Id', tenantId); + return this.ruleApiService.getAllByParams(params, headers); + } + + existsProperties(properties: { name?: string; ruleId?: string }): Observable<any> { + const rule: any = {}; + if (properties.ruleId) { + rule.ruleId = properties.ruleId; + } + + const objectRule = rule as Rule; + return this.ruleApiService.check(objectRule, this.headers); + } + + create(rule: Rule): Observable<boolean> { + return this.ruleApiService.createRule(rule, this.headers).pipe( + tap( + (success) => { + const message = success ? 'ruleCreateSuccess' : 'ruleCreateFailed'; + + this.snackBar.openFromComponent(VitamUISnackBarComponent, { + panelClass: 'vitamui-snack-bar', + duration: 10000, + data: { + type: message, + name: rule.ruleId + } + }); + }, + (error) => { + this.snackBar.open(error.error.message, null, { + panelClass: 'vitamui-snack-bar', + duration: 10000 + }); + } + ) + ); + } + + patch(data: { id: string; [key: string]: any }): Observable<boolean> { + return this.ruleApiService.patchRule(data).pipe( + tap( + (success) => { + const message = success ? 'ruleUpdateSuccess' : 'ruleUpdateFailed'; + + this.snackBar.openFromComponent(VitamUISnackBarComponent, { + panelClass: 'vitamui-snack-bar', + duration: 10000, + data: { + type: message, + name: data.id + } + }); + }, + (error) => { + this.snackBar.open(error.error.message, null, { + panelClass: 'vitamui-snack-bar', + duration: 10000 + }); + } + ) + ); + } + + delete(rule: Rule): Observable<boolean> { + return this.ruleApiService.deleteRule(rule.ruleId).pipe( + tap( + (success) => { + const message = success ? 'ruleDeleteSuccess' : 'ruleDeleteFailed'; + + this.snackBar.openFromComponent(VitamUISnackBarComponent, { + panelClass: 'vitamui-snack-bar', + duration: 10000, + data: { + type: message, + name: rule.ruleId + } + }); + }, + (error) => { + this.snackBar.open(error.error.message, null, { + panelClass: 'vitamui-snack-bar', + duration: 10000 + }); + } + ) + ); + } + + export() { + this.snackBar.openFromComponent(VitamUISnackBarComponent, { + panelClass: 'vitamui-snack-bar', + duration: 10000, + data: { type: 'ruleExportAll' } + }); + + this.ruleApiService.export().subscribe( + (response) => { + const a = document.createElement('a'); + document.body.appendChild(a); + a.style.display = 'none'; + + const blob = new Blob([response], { type: 'octet/stream' }); + const url = window.URL.createObjectURL(blob); + a.href = url; + a.download = 'rules.csv'; + a.click(); + window.URL.revokeObjectURL(url); + }, + (error) => { + this.snackBar.open(error.error.message, null, { + panelClass: 'vitamui-snack-bar', + duration: 10000 + }); + } + ); + } +} diff --git a/ui/ui-frontend-common/src/assets/shared-i18n/en.json b/ui/ui-frontend-common/src/assets/shared-i18n/en.json index 846ac6459..6aa668e45 100644 --- a/ui/ui-frontend-common/src/assets/shared-i18n/en.json +++ b/ui/ui-frontend-common/src/assets/shared-i18n/en.json @@ -208,7 +208,19 @@ }, "RULES_APP": { "NAME": "Management rules", - "TOOLTIP": "Management rules" + "TOOLTIP": "Management rules", + "MESSAGES": { + "COMMON_RULE_MESSAGE": "The Rule", + "CREATION_SUCCESS": "succussfully created.", + "DELETION": "rule deletion", + "CREATION_FAILED": "didn't created.", + "UPDATE_SUCCESS": "successfully uodated", + "UPDATE_FAILED": "didn't updated", + "DELETION_SUCCESS": "successfully deleted", + "DELETION_FAILED": "didn't deleted", + "OPERATION_IN_PROGRESS": "in progress...", + "EXPORT_IN_PROGRESS": "Rule export in progress..." + } }, "FILE_FORMATS_APP": { "NAME": "Files formats", diff --git a/ui/ui-frontend-common/src/assets/shared-i18n/fr.json b/ui/ui-frontend-common/src/assets/shared-i18n/fr.json index acfa6d039..10d370e77 100644 --- a/ui/ui-frontend-common/src/assets/shared-i18n/fr.json +++ b/ui/ui-frontend-common/src/assets/shared-i18n/fr.json @@ -256,7 +256,19 @@ }, "RULES_APP": { "NAME": "Règles de gestion", - "TOOLTIP": "Accéder, Créer, Modifier ou Supprimer les règles de gestion" + "TOOLTIP": "Accéder, Créer, Modifier ou Supprimer les règles de gestion", + "MESSAGES": { + "COMMON_RULE_MESSAGE": "La règle de gestion ", + "CREATION_SUCCESS": "a bien été créée", + "DELETION": "Suppression de la règle de gestion ", + "CREATION_FAILED": "n'a pu être créée.", + "UPDATE_SUCCESS": "a bien été mise à jour.", + "UPDATE_FAILED": "n'a pu être mise à jour.", + "DELETION_SUCCESS": "a bien été supprimée.", + "DELETION_FAILED": "n'a pu être supprimée.", + "OPERATION_IN_PROGRESS": "en cours...", + "EXPORT_IN_PROGRESS": "Export des règles de gestion en cours..." + } }, "FILE_FORMATS_APP": { "NAME": "Formats de fichiers", diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/appraisal-rule-search/appraisal-rule-search.component.css b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/appraisal-rule-search/appraisal-rule-search.component.css new file mode 100644 index 000000000..d15586fe1 --- /dev/null +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/appraisal-rule-search/appraisal-rule-search.component.css @@ -0,0 +1,5 @@ +.check-rule { + margin-right: 25%; + margin-left: -15%; + margin-top: 5px; +} diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/appraisal-rule-search/appraisal-rule-search.component.html b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/appraisal-rule-search/appraisal-rule-search.component.html index 5f5e88556..5b027940a 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/appraisal-rule-search/appraisal-rule-search.component.html +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/appraisal-rule-search/appraisal-rule-search.component.html @@ -8,14 +8,41 @@ <div class="row justify-content-start"> <div class="col-5 form-control"> - <vitamui-common-editable-input + <vitamui-common-input + class="field-ruleId" formControlName="appraisalRuleIdentifier" - [validator]="appraisalRuleCriteriaForm?.get('appraisalRuleIdentifier')?.validator" - label="{{ 'ARCHIVE_SEARCH.SEARCH_CRITERIA_FILTER.FIELDS.ID_DUA' | translate }}" + minlength="2" + maxlength="100" + required + placeholder="{{ 'ARCHIVE_SEARCH.SEARCH_CRITERIA_FILTER.FIELDS.ID_DUA' | translate }}" > - </vitamui-common-editable-input> + <ng-container *ngIf="appraisalRuleCriteriaForm.get('appraisalRuleIdentifier')?.touched"> + <vitamui-common-input-error *ngIf="!!appraisalRuleCriteriaForm?.get('appraisalRuleIdentifier')?.errors?.ruleIdExists" + >{{ 'ARCHIVE_SEARCH.RULE.CODE_NOT_EXIST' | translate }} + </vitamui-common-input-error> + <vitamui-common-input-error *ngIf="!!appraisalRuleCriteriaForm?.get('appraisalRuleIdentifier')?.errors?.ruleIdPattern" + >{{ 'ARCHIVE_SEARCH.RULE.WRONG_FORMAT' | translate }} + </vitamui-common-input-error> + </ng-container> + </vitamui-common-input> </div> - <div class="col-1 form-control"></div> + + <div class="check-rule"> + <button + [ngStyle]="{ 'background-color': 'green', width: '30', height: '30' }" + *ngIf="appraisalRuleCriteriaForm.get('appraisalRuleIdentifier').value" + type="button" + mat-mini-fab + [disabled]=" + appraisalRuleCriteriaForm.get('appraisalRuleIdentifier')?.touched && + !!appraisalRuleCriteriaForm?.get('appraisalRuleIdentifier')?.errors?.ruleIdExists + " + (click)="addCriteriaRulePostCheck()" + > + <i class="material-icons">check</i> + </button> + </div> + <div class="col-4 form-control"> <vitamui-common-editable-input formControlName="appraisalRuleTitle" diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/appraisal-rule-search/appraisal-rule-search.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/appraisal-rule-search/appraisal-rule-search.component.ts index 02d2866de..68433d302 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/appraisal-rule-search/appraisal-rule-search.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/appraisal-rule-search/appraisal-rule-search.component.ts @@ -6,6 +6,7 @@ import { debounceTime, filter, map } from 'rxjs/operators'; import { diff } from 'ui-frontend-common'; import { ArchiveSharedDataServiceService } from '../../../core/archive-shared-data-service.service'; import { CriteriaValue, SearchCriteriaEltDto, SearchCriteriaTypeEnum } from '../../models/search.criteria'; +import { RuleValidator } from './rule.validator'; const UPDATE_DEBOUNCE_TIME = 200; @@ -33,6 +34,7 @@ const ELIMINATION_TECHNICAL_ID = 'ELIMINATION_TECHNICAL_ID'; @Component({ selector: 'appraisal-rule-search', templateUrl: './appraisal-rule-search.component.html', + styleUrls: ['./appraisal-rule-search.component.css'] }) export class AppraisalRuleSearchComponent implements OnInit, OnDestroy { appraisalRuleCriteriaForm: FormGroup; @@ -73,7 +75,7 @@ export class AppraisalRuleSearchComponent implements OnInit, OnDestroy { notSpecifiedFinalActionType: false, appraisalRuleFinalActionHasFinalAction: false, appraisalRuleFinalActionInheriteFinalAction: false, - appraisalRuleEliminationIdentifier: '', + appraisalRuleEliminationIdentifier: '' }; showUnitPreviewBlock = false; @@ -81,15 +83,16 @@ export class AppraisalRuleSearchComponent implements OnInit, OnDestroy { constructor( private formBuilder: FormBuilder, public dialog: MatDialog, - private archiveExchangeDataService: ArchiveSharedDataServiceService + private archiveExchangeDataService: ArchiveSharedDataServiceService, + private ruleValidator: RuleValidator ) { this.appraisalRuleCriteriaForm = this.formBuilder.group({ - appraisalRuleIdentifier: ['', []], + appraisalRuleIdentifier: [null, [this.ruleValidator.ruleIdPattern()], this.ruleValidator.uniqueRuleId()], appraisalRuleTitle: ['', []], appraisalRuleStartDate: ['', []], appraisalRuleEndDate: ['', []], - appraisalRuleEliminationIdentifier: ['', []], + appraisalRuleEliminationIdentifier: ['', []] }); merge(this.appraisalRuleCriteriaForm.statusChanges, this.appraisalRuleCriteriaForm.valueChanges) .pipe( @@ -137,7 +140,7 @@ export class AppraisalRuleSearchComponent implements OnInit, OnDestroy { } else { this.emitRemoveCriteriaEvent(APPRAISAL_RULE_ORIGIN, { id: APPRAISAL_RULE_ORIGIN_INHERITE_AT_LEAST_ONE, - value: APPRAISAL_RULE_ORIGIN_INHERITE_AT_LEAST_ONE, + value: APPRAISAL_RULE_ORIGIN_INHERITE_AT_LEAST_ONE }); } this.previousAppraisalCriteriaValue.appraisalRuleOriginInheriteAtLeastOne = action; @@ -157,7 +160,7 @@ export class AppraisalRuleSearchComponent implements OnInit, OnDestroy { } else { this.emitRemoveCriteriaEvent(APPRAISAL_RULE_ORIGIN, { id: APPRAISAL_RULE_ORIGIN_HAS_NO_ONE, - value: APPRAISAL_RULE_ORIGIN_HAS_NO_ONE, + value: APPRAISAL_RULE_ORIGIN_HAS_NO_ONE }); } this.previousAppraisalCriteriaValue.appraisalRuleOriginHasNoOne = action; @@ -177,7 +180,7 @@ export class AppraisalRuleSearchComponent implements OnInit, OnDestroy { } else { this.emitRemoveCriteriaEvent(APPRAISAL_RULE_ORIGIN, { id: APPRAISAL_RULE_ORIGIN_WAITING_RECALCULATE, - value: APPRAISAL_RULE_ORIGIN_WAITING_RECALCULATE, + value: APPRAISAL_RULE_ORIGIN_WAITING_RECALCULATE }); } this.previousAppraisalCriteriaValue.appraisalRuleOriginWaitingRecalculate = action; @@ -197,7 +200,7 @@ export class AppraisalRuleSearchComponent implements OnInit, OnDestroy { } else { this.emitRemoveCriteriaEvent(APPRAISAL_RULE_ORIGIN, { id: APPRAISAL_RULE_ORIGIN_HAS_AT_LEAST_ONE, - value: APPRAISAL_RULE_ORIGIN_HAS_AT_LEAST_ONE, + value: APPRAISAL_RULE_ORIGIN_HAS_AT_LEAST_ONE }); } this.previousAppraisalCriteriaValue.appraisalRuleOriginHasAtLeastOne = action; @@ -217,7 +220,7 @@ export class AppraisalRuleSearchComponent implements OnInit, OnDestroy { } else { this.emitRemoveCriteriaEvent(APPRAISAL_RULE_FINAL_ACTION_TYPE, { id: APPRAISAL_RULE_FINAL_ACTION_TYPE_ELIMINATION, - value: APPRAISAL_RULE_FINAL_ACTION_TYPE_ELIMINATION, + value: APPRAISAL_RULE_FINAL_ACTION_TYPE_ELIMINATION }); } this.previousAppraisalCriteriaValue.eliminationFinalActionType = action; @@ -237,7 +240,7 @@ export class AppraisalRuleSearchComponent implements OnInit, OnDestroy { } else { this.emitRemoveCriteriaEvent(APPRAISAL_RULE_FINAL_ACTION_TYPE, { id: APPRAISAL_RULE_FINAL_ACTION_TYPE_KEEP, - value: APPRAISAL_RULE_FINAL_ACTION_TYPE_KEEP, + value: APPRAISAL_RULE_FINAL_ACTION_TYPE_KEEP }); } this.previousAppraisalCriteriaValue.keepFinalActionType = action; @@ -257,7 +260,7 @@ export class AppraisalRuleSearchComponent implements OnInit, OnDestroy { } else { this.emitRemoveCriteriaEvent(APPRAISAL_RULE_FINAL_ACTION_TYPE, { id: APPRAISAL_RULE_FINAL_ACTION_TYPE_NOT_SPECIFIED, - value: APPRAISAL_RULE_FINAL_ACTION_TYPE_NOT_SPECIFIED, + value: APPRAISAL_RULE_FINAL_ACTION_TYPE_NOT_SPECIFIED }); } this.previousAppraisalCriteriaValue.notSpecifiedFinalActionType = action; @@ -277,7 +280,7 @@ export class AppraisalRuleSearchComponent implements OnInit, OnDestroy { } else { this.emitRemoveCriteriaEvent(APPRAISAL_RULE_FINAL_ACTION, { id: APPRAISAL_RULE_FINAL_ACTION_HAS_FINAL_ACTION, - value: APPRAISAL_RULE_FINAL_ACTION_HAS_FINAL_ACTION, + value: APPRAISAL_RULE_FINAL_ACTION_HAS_FINAL_ACTION }); } this.previousAppraisalCriteriaValue.appraisalRuleFinalActionHasFinalAction = action; @@ -297,7 +300,7 @@ export class AppraisalRuleSearchComponent implements OnInit, OnDestroy { } else { this.emitRemoveCriteriaEvent(APPRAISAL_RULE_FINAL_ACTION, { id: APPRAISAL_RULE_FINAL_ACTION_INHERITE_FINAL_ACTION, - value: APPRAISAL_RULE_FINAL_ACTION_INHERITE_FINAL_ACTION, + value: APPRAISAL_RULE_FINAL_ACTION_INHERITE_FINAL_ACTION }); } this.previousAppraisalCriteriaValue.appraisalRuleFinalActionInheriteFinalAction = action; @@ -315,7 +318,7 @@ export class AppraisalRuleSearchComponent implements OnInit, OnDestroy { { id: this.appraisalRuleCriteriaForm.value.appraisalRuleStartDate + '-', beginInterval: '', - endInterval: this.appraisalRuleCriteriaForm.value.appraisalRuleStartDate, + endInterval: this.appraisalRuleCriteriaForm.value.appraisalRuleStartDate }, this.appraisalRuleCriteriaForm.value.appraisalRuleStartDate, true, @@ -328,6 +331,26 @@ export class AppraisalRuleSearchComponent implements OnInit, OnDestroy { } } + addCriteriaRulePostCheck() { + if (this.appraisalRuleCriteriaForm.value.appraisalRuleIdentifier) { + this.addCriteria( + APPRAISAL_RULE_IDENTIFIER, + { + id: this.appraisalRuleCriteriaForm.value.appraisalRuleIdentifier.trim(), + value: this.appraisalRuleCriteriaForm.value.appraisalRuleIdentifier.trim() + }, + + this.appraisalRuleCriteriaForm.value.appraisalRuleIdentifier.trim(), + true, + 'EQ', + false, + 'STRING', + SearchCriteriaTypeEnum.APPRAISAL_RULE + ); + this.appraisalRuleCriteriaForm.controls.appraisalRuleIdentifier.setValue(null); + } + } + addIntervalDtDuaCriteria() { if (this.appraisalRuleCriteriaForm.value.appraisalRuleStartDate && this.appraisalRuleCriteriaForm.value.appraisalRuleEndDate) { this.addCriteria( @@ -335,7 +358,7 @@ export class AppraisalRuleSearchComponent implements OnInit, OnDestroy { { id: this.appraisalRuleCriteriaForm.value.appraisalRuleStartDate + '-' + this.appraisalRuleCriteriaForm.value.appraisalRuleEndDate, beginInterval: this.appraisalRuleCriteriaForm.value.appraisalRuleStartDate, - endInterval: this.appraisalRuleCriteriaForm.value.appraisalRuleEndDate, + endInterval: this.appraisalRuleCriteriaForm.value.appraisalRuleEndDate }, this.appraisalRuleCriteriaForm.value.appraisalRuleStartDate, true, @@ -351,21 +374,7 @@ export class AppraisalRuleSearchComponent implements OnInit, OnDestroy { isEmpty(formData: any): boolean { if (formData) { - if (formData.appraisalRuleIdentifier) { - this.addCriteria( - APPRAISAL_RULE_IDENTIFIER, - { id: formData.appraisalRuleIdentifier.trim(), value: formData.appraisalRuleIdentifier.trim() }, - - formData.appraisalRuleIdentifier.trim(), - true, - 'EQ', - false, - 'STRING', - SearchCriteriaTypeEnum.APPRAISAL_RULE - ); - - return true; - } else if (formData.appraisalRuleTitle) { + if (formData.appraisalRuleTitle) { this.addCriteria( APPRAISAL_RULE_TITLE, { id: formData.appraisalRuleTitle.trim(), value: formData.appraisalRuleTitle.trim() }, @@ -435,7 +444,7 @@ export class AppraisalRuleSearchComponent implements OnInit, OnDestroy { appraisalRuleFinalActionHasFinalAction: false, appraisalRuleFinalActionInheriteFinalAction: false, - appraisalRuleEliminationIdentifier: '', + appraisalRuleEliminationIdentifier: '' }; this.addCriteria( @@ -485,7 +494,7 @@ export class AppraisalRuleSearchComponent implements OnInit, OnDestroy { operator, category, valueTranslated, - dataType, + dataType }); } } diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/appraisal-rule-search/rule.validator.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/appraisal-rule-search/rule.validator.ts new file mode 100644 index 000000000..1984aa2b9 --- /dev/null +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/appraisal-rule-search/rule.validator.ts @@ -0,0 +1,74 @@ +/* + * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2020) + * and the signatories of the "VITAM - Accord du Contributeur" agreement. + * + * contact@programmevitam.fr + * + * This software is a computer program whose purpose is to implement + * implement a digital archiving front-office system for the secure and + * efficient high volumetry VITAM solution. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-C license and that you accept its terms. + */ +import { Injectable } from '@angular/core'; +import { AbstractControl, AsyncValidatorFn, ValidationErrors, ValidatorFn } from '@angular/forms'; +import { of, timer } from 'rxjs'; +import { map, switchMap, take } from 'rxjs/operators'; +import { RuleService } from 'ui-frontend-common'; + +@Injectable() +export class RuleValidator { + private debounceTime = 400; + + constructor(private ruleService: RuleService) {} + + uniqueRuleId = (ruleIdToIgnore?: string): AsyncValidatorFn => { + return this.uniqueFields('ruleId', 'ruleIdExists', ruleIdToIgnore); + }; + + ruleIdPattern = (): ValidatorFn => { + return (control: AbstractControl): ValidationErrors | null => { + const regexp = /[À-ÖØ-öø-ÿ ]/; + return regexp.test(control.value) ? { ruleIdPattern: true } : null; + }; + }; + + private uniqueFields(field: string, existTag: string, valueToIgnore?: string) { + return (control: AbstractControl) => { + const properties: any = {}; + properties[field] = control.value; + const existField: any = {}; + existField[existTag] = true; + + return timer(this.debounceTime).pipe( + switchMap(() => (control.value !== valueToIgnore ? this.ruleService.existsProperties(properties) : of(false))), + take(1), + map((exists: boolean) => (exists ? null : existField)) + ); + }; + } +} diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/archive-search.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/archive-search.component.ts index 726b0a499..a58c27f5e 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/archive-search.component.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/archive-search.component.ts @@ -50,16 +50,7 @@ import { ArchiveService } from '../archive.service'; import { FilingHoldingSchemeNode } from '../models/node.interface'; import { NodeData } from '../models/nodedata.interface'; import { SearchCriteriaEltements, SearchCriteriaHistory } from '../models/search-criteria-history.interface'; -import { - CriteriaValue, - PagedResult, - SearchCriteria, - SearchCriteriaCategory, - SearchCriteriaEltDto, - SearchCriteriaStatusEnum, - SearchCriteriaTypeEnum, - SearchCriteriaValue, -} from '../models/search.criteria'; +import { CriteriaValue, PagedResult, SearchCriteria, SearchCriteriaCategory, SearchCriteriaEltDto, SearchCriteriaStatusEnum, SearchCriteriaTypeEnum, SearchCriteriaValue } from '../models/search.criteria'; import { Unit } from '../models/unit.interface'; import { VitamUISnackBarComponent } from '../shared/vitamui-snack-bar'; import { DipRequestCreateComponent } from './dip-request-create/dip-request-create.component'; diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive.module.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive.module.ts index 050221407..1840652b7 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive.module.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive.module.ts @@ -63,7 +63,9 @@ import { ArchiveSearchPopupComponent } from './archive-preview/archive-search-po import { ArchiveRoutingModule } from './archive-routing.module'; import { ArchiveSearchResolverService } from './archive-search-resolver.service'; import { AppraisalRuleSearchComponent } from './archive-search/appraisal-rule-search/appraisal-rule-search.component'; +import { RuleValidator } from './archive-search/appraisal-rule-search/rule.validator'; import { ArchiveSearchComponent } from './archive-search/archive-search.component'; +import { DipRequestCreateComponent } from './archive-search/dip-request-create/dip-request-create.component'; import { SearchCriteriaListComponent } from './archive-search/search-criteria-list/search-criteria-list.component'; import { SearchCriteriaSaverComponent } from './archive-search/search-criteria-saver/search-criteria-saver.component'; import { SearchCriteriaSaverService } from './archive-search/search-criteria-saver/search-criteria-saver.service'; @@ -74,7 +76,6 @@ import { CriteriaSearchComponent } from './criteria-search/criteria-search.compo import { FilingHoldingSchemeComponent } from './filing-holding-scheme/filing-holding-scheme.component'; import { FilingHoldingNodeComponent } from './filing-holding-scheme/tree-node/filing-holding-node.component'; import { SharedModule } from './shared/shared.module'; -import { DipRequestCreateComponent } from './archive-search/dip-request-create/dip-request-create.component'; @NgModule({ imports: [ @@ -102,7 +103,7 @@ import { DipRequestCreateComponent } from './archive-search/dip-request-create/d TableFilterModule, VitamUILibraryModule, MatIconModule, - MatTabsModule, + MatTabsModule ], providers: [ ArchiveApiService, @@ -111,6 +112,7 @@ import { DipRequestCreateComponent } from './archive-search/dip-request-create/d ArchiveSearchResolverService, TranslateService, SearchCriteriaSaverService, + RuleValidator ], declarations: [ ArchiveComponent, @@ -125,8 +127,8 @@ import { DipRequestCreateComponent } from './archive-search/dip-request-create/d AppraisalRuleSearchComponent, SimpleCriteriaSearchComponent, TitleAndDescriptionCriteriaSearchComponent, - DipRequestCreateComponent, + DipRequestCreateComponent ], - schemas: [CUSTOM_ELEMENTS_SCHEMA], + schemas: [CUSTOM_ELEMENTS_SCHEMA] }) export class ArchiveModule {} diff --git a/ui/ui-frontend/projects/archive-search/src/assets/i18n/en.json b/ui/ui-frontend/projects/archive-search/src/assets/i18n/en.json index b424fb013..6976d29ca 100644 --- a/ui/ui-frontend/projects/archive-search/src/assets/i18n/en.json +++ b/ui/ui-frontend/projects/archive-search/src/assets/i18n/en.json @@ -1,39 +1,39 @@ { "ARCHIVE_SEARCH": { - "DIP" : { - "EXPORT_DIP" : "Export a DIP", - "SELECTED" :"Selected", - "ONE_SELECTED" :"Selected", - "CANCEL" : "Cancel", - "REQUEST_ID" :"Request identifier", - "REQUESTER_ID":"Requester identifier", - "COMMENT" : "Comment(s)", - "ARCHIVAL_AGENCY" :"Archive service identifier", - "AUTHORISATION_REQUEST_REPLY" : "Identifier of the response to an authorization request", - "SUBMISSION_AGENCY_ID" : "Submission agency identifier ", + "DIP": { + "EXPORT_DIP": "Export a DIP", + "SELECTED": "Selected", + "ONE_SELECTED": "Selected", + "CANCEL": "Cancel", + "REQUEST_ID": "Request identifier", + "REQUESTER_ID": "Requester identifier", + "COMMENT": "Comment(s)", + "ARCHIVAL_AGENCY": "Archive service identifier", + "AUTHORISATION_REQUEST_REPLY": "Identifier of the response to an authorization request", + "SUBMISSION_AGENCY_ID": "Submission agency identifier ", "REQUIRED": "Required field", - "REQUEST_DIP" : "Request to export a DIP", - "DIP_PARAMS" : "Define the DIP parameters", - "ITEMS_SELECTED" : "Items selected", - "ONE_ITEM_SELECTED" : "Item selected", - "LOGS" : "Life cycle logs :", - "INCLUDE" : "Include", - "EXCLUDE" :"Exclude", - "OBJECT_GROUPS" : "groups of objects :", - "REQUEST_MESSAGE" : "Your DIP request has been taken into account ", - "TO_OPERATION_APP" : "SEE OPERATIONS LOG", + "REQUEST_DIP": "Request to export a DIP", + "DIP_PARAMS": "Define the DIP parameters", + "ITEMS_SELECTED": "Items selected", + "ONE_ITEM_SELECTED": "Item selected", + "LOGS": "Life cycle logs :", + "INCLUDE": "Include", + "EXCLUDE": "Exclude", + "OBJECT_GROUPS": "groups of objects :", + "REQUEST_MESSAGE": "Your DIP request has been taken into account ", + "TO_OPERATION_APP": "SEE OPERATIONS LOG", "EXPORT_LIMITS": "DIP export cannot be performed. Please restrict your selection to a maximum of 10,000 archival units" }, "ELIMINATION": { "ANALYSIS": "Launch elimination analysis", "ELIMINATION_LAUNCHED": "Your request for elimination has been taken into account", "THRESHOLD_EXCEEDED": "The elimination analysis cannot be started. Please restrict your selection to a maximum of 10,000 archival units.", - "EXECUTION" : "Delete archives", - "TO_ELIMINATE" : "Do you want to eliminate", - "SELECTED_ITEMS" : "selected items?", - "ONE_SELECTED" : " Do you want to delete the selected item ?", - "EXECUTE" : "Delete the archives", - "EXECUTE_ONE" : "Delete the archive" + "EXECUTION": "Delete archives", + "TO_ELIMINATE": "Do you want to eliminate", + "SELECTED_ITEMS": "selected items?", + "ONE_SELECTED": " Do you want to delete the selected item ?", + "EXECUTE": "Delete the archives", + "EXECUTE_ONE": "Delete the archive" }, "RULE" : { "UPDATE_RULE" : "Update a rule" @@ -207,6 +207,10 @@ "DIFFUSION": "Diffusion", "CLASSIFICATION": "Classification", "GEL": "Freezing" + }, + "RULE": { + "CODE_NOT_EXIST": "Rule not found", + "WRONG_FORMAT": "Wrong rule format" } } } diff --git a/ui/ui-frontend/projects/archive-search/src/assets/i18n/fr.json b/ui/ui-frontend/projects/archive-search/src/assets/i18n/fr.json index 24842d004..825f1c8c8 100644 --- a/ui/ui-frontend/projects/archive-search/src/assets/i18n/fr.json +++ b/ui/ui-frontend/projects/archive-search/src/assets/i18n/fr.json @@ -1,39 +1,39 @@ { "ARCHIVE_SEARCH": { - "DIP" : { - "EXPORT_DIP" : "Exporter un DIP", - "SELECTED" :"Sélectionnés", - "ONE_SELECTED" :"Sélectionné", - "CANCEL" : "Annuler", - "REQUEST_ID" :"Identifiant de la demande", - "REQUESTER_ID":"Identifiant du demandeur", - "COMMENT" : "Commentaire(s)", - "ARCHIVAL_AGENCY" :"Identifiant du service d’archives", - "AUTHORISATION_REQUEST_REPLY" : "Identifiant de la réponse à une demande d’autorisation ", - "SUBMISSION_AGENCY_ID" : "Identifiant du service versant ", + "DIP": { + "EXPORT_DIP": "Exporter un DIP", + "SELECTED": "Sélectionnés", + "ONE_SELECTED": "Sélectionné", + "CANCEL": "Annuler", + "REQUEST_ID": "Identifiant de la demande", + "REQUESTER_ID": "Identifiant du demandeur", + "COMMENT": "Commentaire(s)", + "ARCHIVAL_AGENCY": "Identifiant du service d’archives", + "AUTHORISATION_REQUEST_REPLY": "Identifiant de la réponse à une demande d’autorisation ", + "SUBMISSION_AGENCY_ID": "Identifiant du service versant ", "REQUIRED": "Champ requis", - "REQUEST_DIP" : "Demande d'export d'un DIP", - "DIP_PARAMS" : "Définir les paramètres du DIP", - "ITEMS_SELECTED" : "éléments sélectionnés", - "ONE_ITEM_SELECTED" : "élément sélectionné", - "LOGS" : "Journaux :", - "INCLUDE" : "Inclure", - "EXCLUDE" :"Exclure", - "OBJECT_GROUPS" : "Groupes d'objets :", - "REQUEST_MESSAGE" : "Votre demande de DIP a bien été prise en compte ", - "TO_OPERATION_APP" : "VOIR LE JOURNAL DES OPÉRATIONS", - "EXPORT_LIMITS" : "L’export de DIP ne peut être réalisé. Merci de restreindre votre sélection à 10 000 unités archivistiques maximum." + "REQUEST_DIP": "Demande d'export d'un DIP", + "DIP_PARAMS": "Définir les paramètres du DIP", + "ITEMS_SELECTED": "éléments sélectionnés", + "ONE_ITEM_SELECTED": "élément sélectionné", + "LOGS": "Journaux :", + "INCLUDE": "Inclure", + "EXCLUDE": "Exclure", + "OBJECT_GROUPS": "Groupes d'objets :", + "REQUEST_MESSAGE": "Votre demande de DIP a bien été prise en compte ", + "TO_OPERATION_APP": "VOIR LE JOURNAL DES OPÉRATIONS", + "EXPORT_LIMITS": "L’export de DIP ne peut être réalisé. Merci de restreindre votre sélection à 10 000 unités archivistiques maximum." }, "ELIMINATION": { "ANALYSIS": "Lancer une analyse d'élimination", "ELIMINATION_LAUNCHED": "Votre demande d'élimination a bien été prise en compte", "THRESHOLD_EXCEEDED": "L’analyse d’élimination ne peut être lancée. Merci de restreindre votre sélection à 10 000 unités archivistiques maximum.", - "EXECUTION" : "Eliminer des archives", - "TO_ELIMINATE" : "Voulez-vous éliminer les", - "SELECTED_ITEMS" : "éléments séléctionnés ?", - "ONE_SELECTED" : "Voulez-vous éliminer l'élément séléctionné ?" , - "EXECUTE" : "Eliminer les archives", - "EXECUTE_ONE" : "Eliminer l'archive" + "EXECUTION": "Eliminer des archives", + "TO_ELIMINATE": "Voulez-vous éliminer les", + "SELECTED_ITEMS": "éléments séléctionnés ?", + "ONE_SELECTED": "Voulez-vous éliminer l'élément séléctionné ?", + "EXECUTE": "Eliminer les archives", + "EXECUTE_ONE": "Eliminer l'archive" }, "RULE" : { "UPDATE_RULE" : "Modifier une règle" @@ -235,6 +235,10 @@ "DIFFUSION": "Diffusion", "CLASSIFICATION": "Classification", "GEL": "Gel" + }, + "RULE": { + "CODE_NOT_EXIST": "La Règle n'existe pas", + "WRONG_FORMAT": "Mauvais format de règle" } } } diff --git a/ui/ui-frontend/projects/referential/src/app/core/api/rule-api.service.ts b/ui/ui-frontend/projects/referential/src/app/core/api/rule-api.service.ts index d54264c5a..3b7b416b7 100644 --- a/ui/ui-frontend/projects/referential/src/app/core/api/rule-api.service.ts +++ b/ui/ui-frontend/projects/referential/src/app/core/api/rule-api.service.ts @@ -34,20 +34,22 @@ * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. */ -import {HttpClient, HttpHeaders, HttpParams, HttpResponse} from '@angular/common/http'; -import {Inject, Injectable} from '@angular/core'; -import {Observable} from 'rxjs'; -import {map} from 'rxjs/operators'; -import {BASE_URL, BaseHttpClient, PageRequest, PaginatedResponse} from 'ui-frontend-common'; -import {Rule} from '../../../../../vitamui-library/src/lib/models/rule'; +import { HttpClient, HttpHeaders, HttpParams, HttpResponse } from '@angular/common/http'; +import { Inject, Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; +import { BaseHttpClient, BASE_URL, PageRequest, PaginatedResponse } from 'ui-frontend-common'; +import { Rule } from '../../../../../vitamui-library/src/lib/models/rule'; const HTTP_STATUS_OK = 200; @Injectable({ providedIn: 'root' }) +/** + * @deprecated This class is deprecated since 5.0.2, and it will be removed in the next minor version, use RuleApiService of ui-frontend-commons instead! + */ export class RuleApiService extends BaseHttpClient<Rule> { - constructor(http: HttpClient, @Inject(BASE_URL) baseUrl: string) { super(http, baseUrl + '/rule'); } @@ -65,27 +67,34 @@ export class RuleApiService extends BaseHttpClient<Rule> { } createRule(rule: Rule, headers?: HttpHeaders): Observable<boolean> { - return super.getHttp().post<any>(super.getApiUrl(), rule, {observe: 'response', headers}) + return super + .getHttp() + .post<any>(super.getApiUrl(), rule, { observe: 'response', headers }) .pipe(map((response: HttpResponse<void>) => response.status === HTTP_STATUS_OK)); } - patchRule(partialRule: {id: string, [key: string]: any}, headers?: HttpHeaders): Observable<boolean> { - return super.getHttp().patch<any>(super.getApiUrl() + '/' + partialRule.id, partialRule, {observe: 'response', headers}) + patchRule(partialRule: { id: string; [key: string]: any }, headers?: HttpHeaders): Observable<boolean> { + return super + .getHttp() + .patch<any>(super.getApiUrl() + '/' + partialRule.id, partialRule, { observe: 'response', headers }) .pipe(map((response: HttpResponse<void>) => response.status === HTTP_STATUS_OK)); } deleteRule(id: string, headers?: HttpHeaders): Observable<boolean> { - return super.getHttp().delete<any>(super.getApiUrl() + '/' + id, {observe: 'response', headers}) + return super + .getHttp() + .delete<any>(super.getApiUrl() + '/' + id, { observe: 'response', headers }) .pipe(map((response: HttpResponse<void>) => response.status === HTTP_STATUS_OK)); } check(rule: Rule, headers?: HttpHeaders): Observable<boolean> { - return super.getHttp().post<any>(super.getApiUrl() + '/check', rule, {observe: 'response', headers}) + return super + .getHttp() + .post<any>(super.getApiUrl() + '/check', rule, { observe: 'response', headers }) .pipe(map((response: HttpResponse<void>) => response.status === HTTP_STATUS_OK)); } export(headers?: HttpHeaders): Observable<any> { - return super.getHttp().get(super.getApiUrl() + '/export', {headers, responseType: 'text'}); + return super.getHttp().get(super.getApiUrl() + '/export', { headers, responseType: 'text' }); } - } diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule-create/rule-create.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/rule/rule-create/rule-create.component.spec.ts index 7225bdeec..b8c9f2157 100644 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule-create/rule-create.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/rule/rule-create/rule-create.component.spec.ts @@ -35,24 +35,22 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ /* tslint:disable: max-classes-per-file directive-selector */ -import {NO_ERRORS_SCHEMA} from '@angular/core'; -import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing'; -import {ReactiveFormsModule} from '@angular/forms'; -import {MatButtonToggleModule} from '@angular/material/button-toggle'; -import {MAT_DIALOG_DATA, MatDialogModule, MatDialogRef} from '@angular/material/dialog'; -import {MatFormFieldModule} from '@angular/material/form-field'; -import {MatProgressBarModule} from '@angular/material/progress-bar'; -import {MatProgressSpinnerModule} from '@angular/material/progress-spinner'; -import {MatSelectModule} from '@angular/material/select'; -import {NoopAnimationsModule} from '@angular/platform-browser/animations'; -import {EMPTY, of} from 'rxjs'; -import {ConfirmDialogService} from 'ui-frontend-common'; -import {VitamUICommonTestModule} from 'ui-frontend-common/testing'; - -import {RuleService} from '../rule.service'; -import {RULE_MEASUREMENTS, RULE_TYPES} from '../rules.constants'; -import {RuleCreateComponent} from './rule-create.component'; -import {RuleCreateValidators} from './rule-create.validators'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatButtonToggleModule } from '@angular/material/button-toggle'; +import { MatDialogModule, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { MatSelectModule } from '@angular/material/select'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { EMPTY, of } from 'rxjs'; +import { ConfirmDialogService, RuleService } from 'ui-frontend-common'; +import { VitamUICommonTestModule } from 'ui-frontend-common/testing'; +import { RULE_MEASUREMENTS, RULE_TYPES } from '../rules.constants'; +import { RuleCreateComponent } from './rule-create.component'; +import { RuleCreateValidators } from './rule-create.validators'; const expectedRule = { ruleId: '424242', @@ -67,7 +65,6 @@ let component: RuleCreateComponent; let fixture: ComponentFixture<RuleCreateComponent>; class Page { - get submit() { return fixture.nativeElement.querySelector('button[type=submit]'); } @@ -75,53 +72,48 @@ class Page { control(name: string) { return fixture.nativeElement.querySelector('[formControlName=' + name + ']'); } - } let page: Page; describe('RuleCreateComponent', () => { - - beforeEach(waitForAsync(() => { - const matDialogRefSpy = jasmine.createSpyObj('MatDialogRef', ['close']); - const ruleServiceSpy = jasmine.createSpyObj('RuleService', { - create: of({}), - existsProperties: of(false) - }); - const ruleCreateValidators: RuleCreateValidators = new RuleCreateValidators(null); - const ruleCreateValidatorsSpy = jasmine.createSpyObj( - 'RuleCreateValidators', { + beforeEach( + waitForAsync(() => { + const matDialogRefSpy = jasmine.createSpyObj('MatDialogRef', ['close']); + const ruleServiceSpy = jasmine.createSpyObj('RuleService', { + create: of({}), + existsProperties: of(false) + }); + const ruleCreateValidators: RuleCreateValidators = new RuleCreateValidators(null); + const ruleCreateValidatorsSpy = jasmine.createSpyObj('RuleCreateValidators', { uniqueRuleId: () => of(null), ruleIdPattern: ruleCreateValidators.ruleIdPattern() - } - ); - - TestBed.configureTestingModule({ - declarations: [ - RuleCreateComponent - ], - imports: [ - ReactiveFormsModule, - NoopAnimationsModule, - MatFormFieldModule, - MatSelectModule, - MatButtonToggleModule, - MatProgressBarModule, - MatProgressSpinnerModule, - MatDialogModule, - VitamUICommonTestModule, - ], - providers: [ - {provide: RuleService, useValue: ruleServiceSpy}, - {provide: RuleCreateValidators, useValue: ruleCreateValidatorsSpy}, - {provide: ConfirmDialogService, useValue: {listenToEscapeKeyPress: () => EMPTY}}, - {provide: MatDialogRef, useValue: matDialogRefSpy}, - {provide: MAT_DIALOG_DATA, useValue: {}} - ], - schemas: [NO_ERRORS_SCHEMA] + }); + + TestBed.configureTestingModule({ + declarations: [RuleCreateComponent], + imports: [ + ReactiveFormsModule, + NoopAnimationsModule, + MatFormFieldModule, + MatSelectModule, + MatButtonToggleModule, + MatProgressBarModule, + MatProgressSpinnerModule, + MatDialogModule, + VitamUICommonTestModule + ], + providers: [ + { provide: RuleService, useValue: ruleServiceSpy }, + { provide: RuleCreateValidators, useValue: ruleCreateValidatorsSpy }, + { provide: ConfirmDialogService, useValue: { listenToEscapeKeyPress: () => EMPTY } }, + { provide: MatDialogRef, useValue: matDialogRefSpy }, + { provide: MAT_DIALOG_DATA, useValue: {} } + ], + schemas: [NO_ERRORS_SCHEMA] + }).compileComponents(); }) - .compileComponents(); - })); + ); beforeEach(() => { fixture = TestBed.createComponent(RuleCreateComponent); @@ -168,7 +160,6 @@ describe('RuleCreateComponent', () => { }); describe('Validators', () => { - describe('fields', () => { it('should be required', () => { expect(setControlValue('ruleId', '').invalid).toBeTruthy('empty ruleId invalid'); @@ -223,5 +214,4 @@ describe('RuleCreateComponent', () => { expect(matDialogRef.close).toHaveBeenCalledTimes(1); }); }); - }); diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule-create/rule-create.component.ts b/ui/ui-frontend/projects/referential/src/app/rule/rule-create/rule-create.component.ts index 77b42cac8..ff196ab60 100644 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule-create/rule-create.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/rule/rule-create/rule-create.component.ts @@ -34,16 +34,13 @@ * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. */ -import {Component, Inject, OnDestroy, OnInit, ViewChild} from '@angular/core'; -import {FormBuilder, FormGroup, Validators} from '@angular/forms'; -import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; -import {Rule} from 'projects/vitamui-library/src/public-api'; -import {Subscription} from 'rxjs'; -import {ConfirmDialogService} from 'ui-frontend-common'; - -import {RuleService} from '../rule.service'; -import {RULE_MEASUREMENTS, RULE_TYPES} from '../rules.constants'; -import {RuleCreateValidators} from './rule-create.validators'; +import { Component, Inject, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { Subscription } from 'rxjs'; +import { ConfirmDialogService, Rule, RuleService } from 'ui-frontend-common'; +import { RULE_MEASUREMENTS, RULE_TYPES } from '../rules.constants'; +import { RuleCreateValidators } from './rule-create.validators'; const PROGRESS_BAR_MULTIPLICATOR = 100; @@ -53,7 +50,6 @@ const PROGRESS_BAR_MULTIPLICATOR = 100; styleUrls: ['./rule-create.component.scss'] }) export class RuleCreateComponent implements OnInit, OnDestroy { - form: FormGroup; stepIndex = 0; hasCustomGraphicIdentity = false; @@ -70,7 +66,7 @@ export class RuleCreateComponent implements OnInit, OnDestroy { ruleTypes = RULE_TYPES; ruleMeasurements = RULE_MEASUREMENTS; - @ViewChild('fileSearch', {static: false}) fileSearch: any; + @ViewChild('fileSearch', { static: false }) fileSearch: any; tenantIdentifier: number; constructor( @@ -80,8 +76,7 @@ export class RuleCreateComponent implements OnInit, OnDestroy { private confirmDialogService: ConfirmDialogService, private ruleService: RuleService, private ruleCreateValidator: RuleCreateValidators - ) { - } + ) {} ngOnInit() { this.form = this.formBuilder.group({ @@ -117,16 +112,16 @@ export class RuleCreateComponent implements OnInit, OnDestroy { this.ruleService.create(format).subscribe( () => { - this.dialogRef.close({success: true}); + this.dialogRef.close({ success: true }); }, (error: any) => { - this.dialogRef.close({success: false}); + this.dialogRef.close({ success: false }); console.error(error); - }); + } + ); } get stepProgress() { return ((this.stepIndex + 1) / this.stepCount) * PROGRESS_BAR_MULTIPLICATOR; } - } diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule-create/rule-create.validators.ts b/ui/ui-frontend/projects/referential/src/app/rule/rule-create/rule-create.validators.ts index 8b41a8b8b..92508de7a 100644 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule-create/rule-create.validators.ts +++ b/ui/ui-frontend/projects/referential/src/app/rule/rule-create/rule-create.validators.ts @@ -34,43 +34,40 @@ * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. */ -import {Injectable} from '@angular/core'; -import {AbstractControl, AsyncValidatorFn, ValidationErrors, ValidatorFn} from '@angular/forms'; - -import {of, timer} from 'rxjs'; -import {map, switchMap, take} from 'rxjs/operators'; -import {RuleService} from '../rule.service'; +import { Injectable } from '@angular/core'; +import { AbstractControl, AsyncValidatorFn, ValidationErrors, ValidatorFn } from '@angular/forms'; +import { of, timer } from 'rxjs'; +import { map, switchMap, take } from 'rxjs/operators'; +import { RuleService } from 'ui-frontend-common'; @Injectable() export class RuleCreateValidators { private debounceTime = 400; - constructor(private ruleService: RuleService) { - } + constructor(private ruleService: RuleService) {} uniqueRuleId = (ruleIdToIgnore?: string): AsyncValidatorFn => { return this.uniqueFields('ruleId', 'ruleIdExists', ruleIdToIgnore); - } + }; ruleIdPattern = (): ValidatorFn => { return (control: AbstractControl): ValidationErrors | null => { const regexp = /[À-ÖØ-öø-ÿ ]/; - return regexp.test(control.value) ? {ruleIdPattern: true} : null; + return regexp.test(control.value) ? { ruleIdPattern: true } : null; }; - } + }; private uniqueFields(field: string, existTag: string, valueToIgnore?: string) { return (control: AbstractControl) => { - const properties: any = {}; properties[field] = control.value; const existField: any = {}; existField[existTag] = true; return timer(this.debounceTime).pipe( - switchMap(() => control.value !== valueToIgnore ? this.ruleService.existsProperties(properties) : of(false)), + switchMap(() => (control.value !== valueToIgnore ? this.ruleService.existsProperties(properties) : of(false))), take(1), - map((exists: boolean) => exists ? existField : null) + map((exists: boolean) => (exists ? existField : null)) ); }; } diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule-list/rule-list.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/rule/rule-list/rule-list.component.spec.ts index 1d6516535..70e14352c 100644 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule-list/rule-list.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/rule/rule-list/rule-list.component.spec.ts @@ -34,16 +34,12 @@ * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. */ -import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing'; - -import {NO_ERRORS_SCHEMA} from '@angular/core'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { MatDialog } from '@angular/material/dialog'; -import {Rule} from 'projects/vitamui-library/src/public-api'; -import {of} from 'rxjs'; -import {AuthService, BASE_URL, VitamUISnackBar} from 'ui-frontend-common'; -import {RuleService} from '../rule.service'; -import {RuleListComponent} from './rule-list.component'; - +import { of } from 'rxjs'; +import { AuthService, BASE_URL, Rule, RuleService, VitamUISnackBar } from 'ui-frontend-common'; +import { RuleListComponent } from './rule-list.component'; describe('RuleListComponent', () => { let component: RuleListComponent; @@ -55,19 +51,21 @@ describe('RuleListComponent', () => { search: () => of(null) }; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [RuleListComponent], - providers: [ - {provide: BASE_URL, useValue: ''}, - {provide: RuleService, useValue: ruleServiceMock}, - {provide: AuthService, useValue: {user: {proofTenantIdentifier: '1'}}}, - {provide: VitamUISnackBar, useValue: {}}, - {provide: MatDialog, useValue: {}} - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [RuleListComponent], + providers: [ + { provide: BASE_URL, useValue: '' }, + { provide: RuleService, useValue: ruleServiceMock }, + { provide: AuthService, useValue: { user: { proofTenantIdentifier: '1' } } }, + { provide: VitamUISnackBar, useValue: {} }, + { provide: MatDialog, useValue: {} } + ], + schemas: [NO_ERRORS_SCHEMA] + }).compileComponents(); + }) + ); beforeEach(() => { fixture = TestBed.createComponent(RuleListComponent); diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule-list/rule-list.component.ts b/ui/ui-frontend/projects/referential/src/app/rule/rule-list/rule-list.component.ts index 37111094f..c2e4b27a6 100644 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule-list/rule-list.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/rule/rule-list/rule-list.component.ts @@ -34,22 +34,11 @@ * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. */ -import { - Component, - ElementRef, - EventEmitter, - Input, - OnDestroy, - OnInit, - Output, - TemplateRef, - ViewChild -} from '@angular/core'; -import {MatDialog} from '@angular/material/dialog'; -import {Rule} from 'projects/vitamui-library/src/lib/models/rule'; -import {ConfirmActionComponent} from 'projects/vitamui-library/src/public-api'; -import {merge, Subject} from 'rxjs'; -import {debounceTime, filter} from 'rxjs/operators'; +import { Component, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output, TemplateRef, ViewChild } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { ConfirmActionComponent } from 'projects/vitamui-library/src/public-api'; +import { merge, Subject } from 'rxjs'; +import { debounceTime, filter } from 'rxjs/operators'; import { AdminUserProfile, ApplicationId, @@ -59,12 +48,13 @@ import { InfiniteScrollTable, PageRequest, Role, + Rule, + RuleService, User, VitamUISnackBar } from 'ui-frontend-common'; -import {VitamUISnackBarComponent} from '../../shared/vitamui-snack-bar'; -import {RuleService} from '../rule.service'; -import {RULE_MEASUREMENTS, RULE_TYPES} from '../rules.constants'; +import { VitamUISnackBarComponent } from '../../shared/vitamui-snack-bar'; +import { RULE_MEASUREMENTS, RULE_TYPES } from '../rules.constants'; const FILTER_DEBOUNCE_TIME_MS = 400; @@ -98,16 +88,16 @@ export class RuleListComponent extends InfiniteScrollTable<Rule> implements OnDe @Output() ruleClick = new EventEmitter<Rule>(); - @ViewChild('filterTemplate', {static: false}) filterTemplate: TemplateRef<RuleListComponent>; - @ViewChild('filterButton', {static: false}) filterButton: ElementRef; + @ViewChild('filterTemplate', { static: false }) filterTemplate: TemplateRef<RuleListComponent>; + @ViewChild('filterButton', { static: false }) filterButton: ElementRef; overridePendingChange: true; loaded = false; orderBy = 'RuleId'; direction = Direction.ASCENDANT; - genericUserRole: Readonly<{appId: ApplicationId, tenantIdentifier: number, roles: Role[]}>; + genericUserRole: Readonly<{ appId: ApplicationId; tenantIdentifier: number; roles: Role[] }>; - private groups: Array<{id: string, group: any}> = []; + private groups: Array<{ id: string; group: any }> = []; private readonly filterChange = new Subject<string>(); private readonly searchChange = new Subject<string>(); private readonly orderChange = new Subject<string>(); @@ -139,13 +129,11 @@ export class RuleListComponent extends InfiniteScrollTable<Rule> implements OnDe } ngOnInit() { - this.ruleService.search(new PageRequest(0, DEFAULT_PAGE_SIZE, this.orderBy, Direction.ASCENDANT)) - .subscribe((data: Rule[]) => { - this.dataSource = data; - }); + this.ruleService.search(new PageRequest(0, DEFAULT_PAGE_SIZE, this.orderBy, Direction.ASCENDANT)).subscribe((data: Rule[]) => { + this.dataSource = data; + }); - const searchCriteriaChange = merge(this.searchChange, this.orderChange, this.filterChange) - .pipe(debounceTime(FILTER_DEBOUNCE_TIME_MS)); + const searchCriteriaChange = merge(this.searchChange, this.orderChange, this.filterChange).pipe(debounceTime(FILTER_DEBOUNCE_TIME_MS)); searchCriteriaChange.subscribe(() => { const query: any = this.buildRuleCriteriaFromSearch(); @@ -188,7 +176,7 @@ export class RuleListComponent extends InfiniteScrollTable<Rule> implements OnDe getRuleType(input: string) { if (input) { - const result = this.ruleTypes.find(x => x.key.toLowerCase() === input.toLowerCase()); + const result = this.ruleTypes.find((x) => x.key.toLowerCase() === input.toLowerCase()); return result ? result.label : input; } else { return ''; @@ -197,7 +185,7 @@ export class RuleListComponent extends InfiniteScrollTable<Rule> implements OnDe getRuleMeasurement(input: string) { if (input) { - const result = this.ruleMeasurements.find(x => x.key.toLowerCase() === input.toLowerCase()); + const result = this.ruleMeasurements.find((x) => x.key.toLowerCase() === input.toLowerCase()); return result ? result.label : input; } else { return ''; @@ -205,23 +193,22 @@ export class RuleListComponent extends InfiniteScrollTable<Rule> implements OnDe } deleteRuleDialog(rule: Rule) { - const dialog = this.matDialog.open(ConfirmActionComponent, {panelClass: 'vitamui-confirm-dialog'}); + const dialog = this.matDialog.open(ConfirmActionComponent, { panelClass: 'vitamui-confirm-dialog' }); dialog.componentInstance.objectType = 'format de fichier'; dialog.componentInstance.objectName = rule.ruleId; - dialog.afterClosed().pipe( - filter((result) => !!result) - ).subscribe(() => { - this.snackBar.openFromComponent(VitamUISnackBarComponent, { - panelClass: 'vitamui-snack-bar', - duration: 5000, - data: {type: 'ruleDeleteStart', name: rule.ruleId} - }); - this.ruleService.delete(rule).subscribe(() => { - this.searchRuleOrdered(); + dialog + .afterClosed() + .pipe(filter((result) => !!result)) + .subscribe(() => { + this.snackBar.openFromComponent(VitamUISnackBarComponent, { + panelClass: 'vitamui-snack-bar', + duration: 5000, + data: { type: 'ruleDeleteStart', name: rule.ruleId } + }); + this.ruleService.delete(rule).subscribe(() => { + this.searchRuleOrdered(); + }); }); - }); - } - } diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-information-tab/rule-information-tab.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-information-tab/rule-information-tab.component.spec.ts index d33b68529..d8721e62c 100644 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-information-tab/rule-information-tab.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-information-tab/rule-information-tab.component.spec.ts @@ -34,14 +34,13 @@ * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. */ -import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing'; - -import {NO_ERRORS_SCHEMA} from '@angular/core'; -import {FormBuilder} from '@angular/forms'; -import {Rule} from 'projects/vitamui-library/src/public-api'; -import {of} from 'rxjs'; -import {RuleService} from '../../rule.service'; -import {RuleInformationTabComponent} from './rule-information-tab.component'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { FormBuilder } from '@angular/forms'; +import { Rule } from 'projects/vitamui-library/src/public-api'; +import { of } from 'rxjs'; +import { RuleService } from 'ui-frontend-common'; +import { RuleInformationTabComponent } from './rule-information-tab.component'; describe('RuleInformationTabComponent', () => { let component: RuleInformationTabComponent; @@ -74,17 +73,15 @@ describe('RuleInformationTabComponent', () => { updateDate: '20/02/2020' }; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [RuleInformationTabComponent], - providers: [ - FormBuilder, - {provide: RuleService, useValue: ruleServiceMock} - ], - schemas: [NO_ERRORS_SCHEMA] + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [RuleInformationTabComponent], + providers: [FormBuilder, { provide: RuleService, useValue: ruleServiceMock }], + schemas: [NO_ERRORS_SCHEMA] + }).compileComponents(); }) - .compileComponents(); - })); + ); beforeEach(() => { fixture = TestBed.createComponent(RuleInformationTabComponent); diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-information-tab/rule-information-tab.component.ts b/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-information-tab/rule-information-tab.component.ts index b12c5d4cd..9baa6c718 100644 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-information-tab/rule-information-tab.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-information-tab/rule-information-tab.component.ts @@ -34,16 +34,13 @@ * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. */ -import {Component, EventEmitter, Input, Output} from '@angular/core'; -import {FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms'; -import {Rule} from 'projects/vitamui-library/src/public-api'; -import {Observable, of} from 'rxjs'; -import {catchError, filter, map, switchMap} from 'rxjs/operators'; -import {diff} from 'ui-frontend-common'; -import {extend, isEmpty} from 'underscore'; -import {RuleService} from '../../rule.service'; -import {RULE_MEASUREMENTS, RULE_TYPES} from '../../rules.constants'; - +import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; +import { Observable, of } from 'rxjs'; +import { catchError, filter, map, switchMap } from 'rxjs/operators'; +import { diff, Rule, RuleService } from 'ui-frontend-common'; +import { extend, isEmpty } from 'underscore'; +import { RULE_MEASUREMENTS, RULE_TYPES } from '../../rules.constants'; @Component({ selector: 'app-rule-information-tab', @@ -51,7 +48,6 @@ import {RULE_MEASUREMENTS, RULE_TYPES} from '../../rules.constants'; styleUrls: ['./rule-information-tab.component.scss'] }) export class RuleInformationTabComponent { - @Output() updated: EventEmitter<boolean> = new EventEmitter<boolean>(); form: FormGroup; @@ -68,7 +64,7 @@ export class RuleInformationTabComponent { previousValue = (): Rule => { return this._rule; - } + }; @Input() set rule(rule: Rule) { @@ -84,17 +80,14 @@ export class RuleInformationTabComponent { @Input() set readOnly(readOnly: boolean) { if (readOnly && this.form.enabled) { - this.form.disable({emitEvent: false}); + this.form.disable({ emitEvent: false }); } else if (this.form.disabled) { - this.form.enable({emitEvent: false}); - this.form.get('identifier').disable({emitEvent: false}); + this.form.enable({ emitEvent: false }); + this.form.get('identifier').disable({ emitEvent: false }); } } - constructor( - private formBuilder: FormBuilder, - private ruleService: RuleService - ) { + constructor(private formBuilder: FormBuilder, private ruleService: RuleService) { this.form = this.formBuilder.group({ ruleType: [null, Validators.required], ruleValue: [null, Validators.required], @@ -114,18 +107,26 @@ export class RuleInformationTabComponent { } isInvalid(): boolean { - return this.form.get('ruleType').invalid || this.form.get('ruleType').pending || - this.form.get('ruleValue').invalid || this.form.get('ruleValue').pending || - this.form.get('ruleDescription').invalid || this.form.get('ruleDescription').pending || - this.form.get('ruleDuration').invalid || this.form.get('ruleDuration').pending || - this.form.get('ruleMeasurement').invalid || this.form.get('ruleMeasurement').pending; + return ( + this.form.get('ruleType').invalid || + this.form.get('ruleType').pending || + this.form.get('ruleValue').invalid || + this.form.get('ruleValue').pending || + this.form.get('ruleDescription').invalid || + this.form.get('ruleDescription').pending || + this.form.get('ruleDuration').invalid || + this.form.get('ruleDuration').pending || + this.form.get('ruleMeasurement').invalid || + this.form.get('ruleMeasurement').pending + ); } prepareSubmit(): Observable<Rule> { return of(diff(this.form.getRawValue(), this.previousValue())).pipe( filter((formData) => !isEmpty(formData)), - map((formData) => extend({id: this.previousValue().ruleId, ruleId: this.previousValue().ruleId}, formData)), - switchMap((formData: {id: string, [key: string]: any}) => this.ruleService.patch(formData).pipe(catchError(() => of(null))))); + map((formData) => extend({ id: this.previousValue().ruleId, ruleId: this.previousValue().ruleId }, formData)), + switchMap((formData: { id: string; [key: string]: any }) => this.ruleService.patch(formData).pipe(catchError(() => of(null)))) + ); } onSubmit() { @@ -134,26 +135,27 @@ export class RuleInformationTabComponent { return; } - this.prepareSubmit().subscribe(() => { - this.ruleService.get(this._rule.ruleId).subscribe( - response => { + this.prepareSubmit().subscribe( + () => { + this.ruleService.get(this._rule.ruleId).subscribe((response) => { this.submited = false; this.rule = response; - } - ); - }, () => { - this.submited = false; - }); + }); + }, + () => { + this.submited = false; + } + ); } resetForm(rule: Rule) { - this.form.reset(rule, {emitEvent: false}); + this.form.reset(rule, { emitEvent: false }); } getRuleTypeLabel(): string { const formControl = this.form.get('ruleType'); if (formControl) { - const ruleType = this.ruleTypes.find(item => item.key === formControl.value); + const ruleType = this.ruleTypes.find((item) => item.key === formControl.value); if (ruleType) { return ruleType.label; } diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-preview.component.html b/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-preview.component.html index a4952b82f..78e748c0b 100644 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-preview.component.html +++ b/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-preview.component.html @@ -1,30 +1,29 @@ <div class="vitamui-sidepanel"> - <div class="vitamui-sidepanel-header"> - <div class="d-flex justify-content-end"> - <button class="btn link cancel" (click)="emitClose()"> - <i class="vitamui-icon vitamui-icon-close"></i> - </button> - </div> - - <div class="title"> - <div matTooltipClass="vitamui-tooltip"> - <h5 class="m-0 text-primary">{{rule?.ruleValue.substr(0,33)}} <small>({{rule?.ruleId}})</small></h5> - </div> - </div> + <div class="vitamui-sidepanel-header"> + <div class="d-flex justify-content-end"> + <button class="btn link cancel" (click)="emitClose()"> + <i class="vitamui-icon vitamui-icon-close"></i> + </button> </div> - <div class="vitamui-sidepanel-body"> - <mat-tab-group class="preview-tab-group" #tabs> - - <mat-tab label="Informations" i18n-label="Information tab@@rulePreviewTabInformation"> - <app-rule-information-tab [rule]="rule" (updated)="updatedChange($event, 0)" #infoTab> - </app-rule-information-tab> - </mat-tab> - <mat-tab label="Historique" i18n-label="History tab@@rulePreviewTabHistory"> - <vitamui-common-operation-history-tab [id]="rule?.id" [identifier]="rule?.id" collectionName="rule" - [filter]="filterEvents"> - </vitamui-common-operation-history-tab> - </mat-tab> - </mat-tab-group> + <div class="title"> + <div matTooltipClass="vitamui-tooltip"> + <h5 class="m-0 text-primary"> + {{ rule?.ruleValue.substr(0, 33) }} <small>({{ rule?.ruleId }})</small> + </h5> + </div> </div> + </div> + <div class="vitamui-sidepanel-body"> + <mat-tab-group class="preview-tab-group" #tabs> + <mat-tab label="Informations" i18n-label="Information tab@@rulePreviewTabInformation"> + <app-rule-information-tab [rule]="rule" (updated)="updatedChange($event, 0)" #infoTab> </app-rule-information-tab> + </mat-tab> + + <mat-tab label="Historique" i18n-label="History tab@@rulePreviewTabHistory"> + <vitamui-common-operation-history-tab [id]="rule?.id" [identifier]="rule?.id" collectionName="rules" [filter]="filterEvents"> + </vitamui-common-operation-history-tab> + </mat-tab> + </mat-tab-group> + </div> </div> diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-preview.component.spec.ts b/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-preview.component.spec.ts index 326100b1b..4bd38b02d 100644 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-preview.component.spec.ts +++ b/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-preview.component.spec.ts @@ -34,28 +34,25 @@ * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. */ -import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing'; - -import {CUSTOM_ELEMENTS_SCHEMA} from '@angular/core'; +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { MatDialog } from '@angular/material/dialog'; -import {RuleService} from '../rule.service'; -import {RulePreviewComponent} from './rule-preview.component'; +import { RuleService } from 'ui-frontend-common'; +import { RulePreviewComponent } from './rule-preview.component'; describe('RulePreviewComponent', () => { let component: RulePreviewComponent; let fixture: ComponentFixture<RulePreviewComponent>; - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [RulePreviewComponent], - providers: [ - {provide: MatDialog, useValue: {}}, - {provide: RuleService, useValue: {}} - ], - schemas: [CUSTOM_ELEMENTS_SCHEMA] + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [RulePreviewComponent], + providers: [{ provide: MatDialog, useValue: {} }, { provide: RuleService, useValue: {} }], + schemas: [CUSTOM_ELEMENTS_SCHEMA] + }).compileComponents(); }) - .compileComponents(); - })); + ); beforeEach(() => { fixture = TestBed.createComponent(RulePreviewComponent); diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-preview.component.ts b/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-preview.component.ts index cda8d2a43..48b2ca242 100644 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-preview.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/rule/rule-preview/rule-preview.component.ts @@ -34,14 +34,13 @@ * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. */ -import {Component, EventEmitter, HostListener, Input, Output, ViewChild, AfterViewInit} from '@angular/core'; -import {MatDialog} from '@angular/material/dialog'; -import {MatTab, MatTabGroup, MatTabHeader} from '@angular/material/tabs'; -import {Rule} from 'projects/vitamui-library/src/lib/models/rule'; -import {ConfirmActionComponent} from 'projects/vitamui-library/src/public-api'; -import {Observable} from 'rxjs'; -import {RuleService} from '../rule.service'; -import {RuleInformationTabComponent} from './rule-information-tab/rule-information-tab.component'; +import { AfterViewInit, Component, EventEmitter, HostListener, Input, Output, ViewChild } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { MatTab, MatTabGroup, MatTabHeader } from '@angular/material/tabs'; +import { ConfirmActionComponent } from 'projects/vitamui-library/src/public-api'; +import { Observable } from 'rxjs'; +import { Rule, RuleService } from 'ui-frontend-common'; +import { RuleInformationTabComponent } from './rule-information-tab/rule-information-tab.component'; @Component({ selector: 'app-rule-preview', @@ -49,15 +48,14 @@ import {RuleInformationTabComponent} from './rule-information-tab/rule-informati styleUrls: ['./rule-preview.component.scss'] }) export class RulePreviewComponent implements AfterViewInit { - @Output() previewClose: EventEmitter<any> = new EventEmitter(); @Input() rule: Rule; tabUpdated: boolean[] = [false, false]; - @ViewChild('tabs', {static: false}) tabs: MatTabGroup; + @ViewChild('tabs', { static: false }) tabs: MatTabGroup; tabLinks: Array<RuleInformationTabComponent> = []; - @ViewChild('infoTab', {static: false}) infoTab: RuleInformationTabComponent; + @ViewChild('infoTab', { static: false }) infoTab: RuleInformationTabComponent; @HostListener('window:beforeunload', ['$event']) beforeunloadHandler(event: any) { @@ -68,8 +66,7 @@ export class RulePreviewComponent implements AfterViewInit { } } - constructor(private matDialog: MatDialog, private ruleService: RuleService) { - } + constructor(private matDialog: MatDialog, private ruleService: RuleService) {} ngAfterViewInit() { this.tabs._handleClick = this.interceptTabChange.bind(this); @@ -85,11 +82,9 @@ export class RulePreviewComponent implements AfterViewInit { const submitAccessContractUpdate: Observable<Rule> = this.infoTab.prepareSubmit(); submitAccessContractUpdate.subscribe(() => { - this.ruleService.get(this.rule.ruleId).subscribe( - response => { - this.rule = response; - } - ); + this.ruleService.get(this.rule.ruleId).subscribe((response) => { + this.rule = response; + }); }); } else { this.infoTab.resetForm(this.rule); @@ -106,15 +101,15 @@ export class RulePreviewComponent implements AfterViewInit { } async confirmAction(): Promise<boolean> { - const dialog = this.matDialog.open(ConfirmActionComponent, {panelClass: 'vitamui-confirm-dialog'}); + const dialog = this.matDialog.open(ConfirmActionComponent, { panelClass: 'vitamui-confirm-dialog' }); dialog.componentInstance.dialogType = 'changeTab'; return await dialog.afterClosed().toPromise(); } filterEvents(event: any): boolean { - return event.outDetail && ( - event.outDetail.includes('EXT_VITAMUI_UPDATE_FILE_FORMAT') || - event.outDetail.includes('EXT_VITAMUI_CREATE_FILE_FORMAT') + return ( + event.outDetail && + (event.outDetail.includes('EXT_VITAMUI_UPDATE_FILE_FORMAT') || event.outDetail.includes('EXT_VITAMUI_CREATE_FILE_FORMAT')) ); } @@ -124,5 +119,4 @@ export class RulePreviewComponent implements AfterViewInit { } this.previewClose.emit(); } - } diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule.component.ts b/ui/ui-frontend/projects/referential/src/app/rule/rule.component.ts index 7a9867b6d..35701c061 100644 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule.component.ts +++ b/ui/ui-frontend/projects/referential/src/app/rule/rule.component.ts @@ -34,28 +34,24 @@ * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. */ -import {Component, OnInit, ViewChild} from '@angular/core'; -import {FormBuilder, FormGroup} from '@angular/forms'; -import {MatDialog} from '@angular/material/dialog'; -import {ActivatedRoute, Router} from '@angular/router'; -import {Rule} from 'projects/vitamui-library/src/lib/models/rule'; -import {GlobalEventService, SidenavPage} from 'ui-frontend-common'; +import { Component, OnInit, ViewChild } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; +import { ActivatedRoute, Router } from '@angular/router'; +import { GlobalEventService, Rule, RuleService, SidenavPage } from 'ui-frontend-common'; import { Referential } from '../shared/vitamui-import-dialog/referential.enum'; import { VitamUIImportDialogComponent } from '../shared/vitamui-import-dialog/vitamui-import-dialog.component'; -import {RuleCreateComponent} from './rule-create/rule-create.component'; -import {RuleListComponent} from './rule-list/rule-list.component'; -import {RuleService} from './rule.service'; -import {NULL_TYPE, RULE_TYPES} from './rules.constants'; +import { RuleCreateComponent } from './rule-create/rule-create.component'; +import { RuleListComponent } from './rule-list/rule-list.component'; +import { NULL_TYPE, RULE_TYPES } from './rules.constants'; @Component({ selector: 'app-rules', templateUrl: './rule.component.html', styleUrls: ['./rule.component.scss'] }) - export class RuleComponent extends SidenavPage<Rule> implements OnInit { - - @ViewChild(RuleListComponent, {static: true}) ruleListComponentListComponent: RuleListComponent; + @ViewChild(RuleListComponent, { static: true }) ruleListComponentListComponent: RuleListComponent; search = ''; typeFilterForm: FormGroup; @@ -70,14 +66,14 @@ export class RuleComponent extends SidenavPage<Rule> implements OnInit { private route: ActivatedRoute, private router: Router, globalEventService: GlobalEventService, - private formBuilder: FormBuilder) { - + private formBuilder: FormBuilder + ) { super(route, globalEventService); globalEventService.tenantEvent.subscribe(() => { this.refreshList(); }); - this.route.params.subscribe(params => { + this.route.params.subscribe((params) => { if (params.tenantIdentifier) { this.tenantId = params.tenantIdentifier; } @@ -87,12 +83,10 @@ export class RuleComponent extends SidenavPage<Rule> implements OnInit { ruleTypes: null }); - this.typeFilterForm - .controls.ruleTypes.valueChanges.subscribe(value => { - this.filters = value; - this.ruleListComponentListComponent.filters = this.filters; - }); - + this.typeFilterForm.controls.ruleTypes.valueChanges.subscribe((value) => { + this.filters = value; + this.ruleListComponentListComponent.filters = this.filters; + }); } openCreateRuleDialog() { @@ -108,7 +102,6 @@ export class RuleComponent extends SidenavPage<Rule> implements OnInit { }); } - private refreshList() { if (!this.ruleListComponentListComponent) { return; @@ -118,15 +111,14 @@ export class RuleComponent extends SidenavPage<Rule> implements OnInit { changeTenant(tenantIdentifier: number) { this.tenantId = tenantIdentifier; - this.router.navigate(['..', tenantIdentifier], {relativeTo: this.route}); + this.router.navigate(['..', tenantIdentifier], { relativeTo: this.route }); } onSearchSubmit(search: string) { this.search = search || ''; } - ngOnInit() { - } + ngOnInit() {} showRule(item: Rule) { this.openPanel(item); @@ -137,17 +129,15 @@ export class RuleComponent extends SidenavPage<Rule> implements OnInit { } openRuleImportDialog() { - const dialogRef = this.dialog.open( - VitamUIImportDialogComponent, { - panelClass: 'vitamui-modal', - data: Referential.RULE, - disableClose: true - }); + const dialogRef = this.dialog.open(VitamUIImportDialogComponent, { + panelClass: 'vitamui-modal', + data: Referential.RULE, + disableClose: true + }); dialogRef.afterClosed().subscribe((result) => { if (result && result.success) { this.refreshList(); } }); } - } diff --git a/ui/ui-frontend/projects/referential/src/app/rule/rule.service.ts b/ui/ui-frontend/projects/referential/src/app/rule/rule.service.ts index bd6865a10..9a771e197 100644 --- a/ui/ui-frontend/projects/referential/src/app/rule/rule.service.ts +++ b/ui/ui-frontend/projects/referential/src/app/rule/rule.service.ts @@ -34,27 +34,24 @@ * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. */ -import {HttpClient, HttpHeaders, HttpParams} from '@angular/common/http'; -import {Injectable} from '@angular/core'; -import {Rule} from 'projects/vitamui-library/src/lib/models/rule'; -import {Observable, Subject} from 'rxjs'; -import {tap} from 'rxjs/operators'; -import {SearchService, VitamUISnackBar} from 'ui-frontend-common'; -import {RuleApiService} from '../core/api/rule-api.service'; -import {VitamUISnackBarComponent} from '../shared/vitamui-snack-bar'; +import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Observable, Subject } from 'rxjs'; +import { tap } from 'rxjs/operators'; +import { Rule, SearchService, VitamUISnackBar } from 'ui-frontend-common'; +import { RuleApiService } from '../core/api/rule-api.service'; +import { VitamUISnackBarComponent } from '../shared/vitamui-snack-bar'; @Injectable({ providedIn: 'root' }) - +/** + * @deprecated This class is deprecated since 5.0.2, and it will be removed in the next minor version, use commonized service RuleService instead + */ export class RuleService extends SearchService<Rule> { - updated = new Subject<Rule>(); - constructor( - private ruleApiService: RuleApiService, - private snackBar: VitamUISnackBar, - http: HttpClient) { + constructor(private ruleApiService: RuleApiService, private snackBar: VitamUISnackBar, http: HttpClient) { super(http, ruleApiService, 'ALL'); } @@ -69,7 +66,7 @@ export class RuleService extends SearchService<Rule> { return this.ruleApiService.getAllByParams(params, headers); } - existsProperties(properties: {name?: string, ruleId?: string}): Observable<any> { + existsProperties(properties: { name?: string; ruleId?: string }): Observable<any> { const rule: any = {}; if (properties.ruleId) { rule.ruleId = properties.ruleId; @@ -89,7 +86,7 @@ export class RuleService extends SearchService<Rule> { panelClass: 'vitamui-snack-bar', duration: 10000, data: { - type: message, + type: message, name: rule.ruleId } }); @@ -104,7 +101,7 @@ export class RuleService extends SearchService<Rule> { ); } - patch(data: {id: string, [key: string]: any}): Observable<boolean> { + patch(data: { id: string; [key: string]: any }): Observable<boolean> { return this.ruleApiService.patchRule(data).pipe( tap( (success) => { @@ -114,7 +111,7 @@ export class RuleService extends SearchService<Rule> { panelClass: 'vitamui-snack-bar', duration: 10000, data: { - type: message, + type: message, name: data.id } }); @@ -139,7 +136,7 @@ export class RuleService extends SearchService<Rule> { panelClass: 'vitamui-snack-bar', duration: 10000, data: { - type: message, + type: message, name: rule.ruleId } }); @@ -158,7 +155,7 @@ export class RuleService extends SearchService<Rule> { this.snackBar.openFromComponent(VitamUISnackBarComponent, { panelClass: 'vitamui-snack-bar', duration: 10000, - data: {type: 'ruleExportAll'} + data: { type: 'ruleExportAll' } }); this.ruleApiService.export().subscribe( @@ -167,13 +164,14 @@ export class RuleService extends SearchService<Rule> { document.body.appendChild(a); a.style.display = 'none'; - const blob = new Blob([response], {type: 'octet/stream'}); + const blob = new Blob([response], { type: 'octet/stream' }); const url = window.URL.createObjectURL(blob); a.href = url; a.download = 'rules.csv'; a.click(); window.URL.revokeObjectURL(url); - }, (error) => { + }, + (error) => { this.snackBar.open(error.error.message, null, { panelClass: 'vitamui-snack-bar', duration: 10000 @@ -181,5 +179,4 @@ export class RuleService extends SearchService<Rule> { } ); } - } diff --git a/ui/ui-identity/src/test/resources/application.yml b/ui/ui-identity/src/test/resources/application.yml index 950c52f91..a6157612e 100644 --- a/ui/ui-identity/src/test/resources/application.yml +++ b/ui/ui-identity/src/test/resources/application.yml @@ -30,6 +30,19 @@ ui-identity: key-path: "@project.build.testOutputDirectory@/truststore_sae-app.jks" key-password: azerty hostname-verification: true + referential-external-client: + server-host: localhost + server-port: 8087 + secure: true + ssl-configuration: + keystore: + key-path: src/main/resources/dev/keystore_ui-identity-admin.jks + key-password: changeme + type: JKS + truststore: + key-path: src/main/resources/dev/truststore_server.jks + key-password: changeme + hostname-verification: false base-url: portal: "https://localhost:4200" admin-identity: "${ui.url}" diff --git a/ui/ui-ingest/src/test/resources/application.yml b/ui/ui-ingest/src/test/resources/application.yml index 2e81fb91d..2d76e0de2 100644 --- a/ui/ui-ingest/src/test/resources/application.yml +++ b/ui/ui-ingest/src/test/resources/application.yml @@ -43,6 +43,19 @@ ui-ingest: key-path: src/test/resources/certs/truststore.jks key-password: jkspasswd hostname-verification: false + referential-external-client: + server-host: localhost + server-port: 8087 + secure: true + ssl-configuration: + keystore: + key-path: src/main/resources/dev/keystore_ui-ingest.jks + key-password: changeme + type: JKS + truststore: + key-path: src/main/resources/dev/truststore_server.jks + key-password: changeme + hostname-verification: false ui-prefix: ingest-api server-identity: diff --git a/ui/ui-portal/src/main/resources/application-dev.yml b/ui/ui-portal/src/main/resources/application-dev.yml index 4b660db6c..6d4fb2dd1 100644 --- a/ui/ui-portal/src/main/resources/application-dev.yml +++ b/ui/ui-portal/src/main/resources/application-dev.yml @@ -61,6 +61,22 @@ ui-portal: key-path: src/main/resources/dev/truststore_server.jks key-password: changeme hostname-verification: false + referential-external-client: + server-host: localhost + server-port: 8087 + connect-time-out: 30 + read-time-out: 30 + write-time-out: 30 + secure: true + ssl-configuration: + keystore: + key-path: src/main/resources/dev/keystore_ui-portal.jks + key-password: changeme + type: JKS + truststore: + key-path: src/main/resources/dev/truststore_server.jks + key-password: changeme + hostname-verification: false base-url: portal: "https://dev.vitamui.com:4200" admin-identity: "https://dev.vitamui.com:4201/identity" diff --git a/ui/ui-portal/src/main/resources/dev/keystore_ui-referential.jks b/ui/ui-portal/src/main/resources/dev/keystore_ui-referential.jks new file mode 100644 index 0000000000000000000000000000000000000000..6a435ca4cb27e75cf6ad522732f18d6f2afe3797 GIT binary patch literal 3865 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 Z3<S3|p(zl&yvmuEINq8zwY&F5{|{)J{hI&) literal 0 HcmV?d00001 diff --git a/ui/ui-portal/src/test/resources/application.yml b/ui/ui-portal/src/test/resources/application.yml index a5ecd2b48..f993a1a99 100644 --- a/ui/ui-portal/src/test/resources/application.yml +++ b/ui/ui-portal/src/test/resources/application.yml @@ -32,7 +32,19 @@ ui-portal: key-path: src/main/resources/dev/truststore_server.jks key-password: changeme hostname-verification: false - + referential-external-client: + server-host: localhost + server-port: 8087 + secure: true + ssl-configuration: + keystore: + key-path: src/main/resources/dev/keystore_ui-portal.jks + key-password: changeme + type: JKS + truststore: + key-path: src/main/resources/dev/truststore_server.jks + key-password: changeme + hostname-verification: false ui-prefix: portal-api controller: diff --git a/ui/ui-referential/src/main/java/fr/gouv/vitamui/referential/rest/RuleController.java b/ui/ui-referential/src/main/java/fr/gouv/vitamui/referential/rest/RuleController.java index ba596dc35..047bc1652 100644 --- a/ui/ui-referential/src/main/java/fr/gouv/vitamui/referential/rest/RuleController.java +++ b/ui/ui-referential/src/main/java/fr/gouv/vitamui/referential/rest/RuleController.java @@ -36,46 +36,53 @@ */ package fr.gouv.vitamui.referential.rest; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.util.Collection; -import java.util.Map; -import java.util.Optional; - -import javax.servlet.http.HttpServletRequest; -import javax.validation.Valid; -import javax.ws.rs.Consumes; -import javax.ws.rs.Produces; -import javax.ws.rs.core.Context; - +import com.fasterxml.jackson.databind.JsonNode; import fr.gouv.vitamui.commons.api.CommonConstants; import fr.gouv.vitamui.commons.api.ParameterChecker; -import fr.gouv.vitamui.commons.vitam.api.dto.LogbookOperationsResponseDto; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.io.Resource; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.util.Assert; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; - -import com.fasterxml.jackson.databind.JsonNode; - import fr.gouv.vitamui.commons.api.domain.DirectionDto; import fr.gouv.vitamui.commons.api.domain.PaginatedValuesDto; import fr.gouv.vitamui.commons.api.logger.VitamUILogger; import fr.gouv.vitamui.commons.api.logger.VitamUILoggerFactory; import fr.gouv.vitamui.commons.rest.AbstractUiRestController; +import fr.gouv.vitamui.commons.rest.dto.RuleDto; import fr.gouv.vitamui.commons.rest.util.RestUtils; -import fr.gouv.vitamui.referential.common.dto.RuleDto; +import fr.gouv.vitamui.commons.vitam.api.dto.LogbookOperationsResponseDto; import fr.gouv.vitamui.referential.common.rest.RestApi; import fr.gouv.vitamui.referential.service.RuleService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.util.Assert; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import javax.ws.rs.Consumes; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.Collection; +import java.util.Map; +import java.util.Optional; +@Deprecated(since = "5.0.2", forRemoval = true) @Api(tags = "rule") @RestController @RequestMapping("${ui-referential.prefix}/rule") @@ -175,7 +182,7 @@ public class RuleController extends AbstractUiRestController { LOGGER.debug("export rules"); return service.export(buildUiHttpContext()); } - + /*** * Import rules from a csv file * @param request HTTP request diff --git a/ui/ui-referential/src/main/java/fr/gouv/vitamui/referential/service/RuleService.java b/ui/ui-referential/src/main/java/fr/gouv/vitamui/referential/service/RuleService.java index 54fe94c5a..9c7960c96 100644 --- a/ui/ui-referential/src/main/java/fr/gouv/vitamui/referential/service/RuleService.java +++ b/ui/ui-referential/src/main/java/fr/gouv/vitamui/referential/service/RuleService.java @@ -36,36 +36,35 @@ */ package fr.gouv.vitamui.referential.service; -import java.util.Collection; -import java.util.Map; -import java.util.Optional; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.io.Resource; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Service; -import org.springframework.web.multipart.MultipartFile; - import com.fasterxml.jackson.databind.JsonNode; - import fr.gouv.vitamui.commons.api.domain.DirectionDto; import fr.gouv.vitamui.commons.api.domain.PaginatedValuesDto; import fr.gouv.vitamui.commons.api.logger.VitamUILogger; import fr.gouv.vitamui.commons.api.logger.VitamUILoggerFactory; import fr.gouv.vitamui.commons.rest.client.BasePaginatingAndSortingRestClient; import fr.gouv.vitamui.commons.rest.client.ExternalHttpContext; -import fr.gouv.vitamui.referential.common.dto.RuleDto; +import fr.gouv.vitamui.commons.rest.dto.RuleDto; import fr.gouv.vitamui.referential.external.client.RuleExternalRestClient; import fr.gouv.vitamui.referential.external.client.RuleExternalWebClient; import fr.gouv.vitamui.ui.commons.service.AbstractPaginateService; import fr.gouv.vitamui.ui.commons.service.CommonService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.Resource; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.util.Collection; +import java.util.Map; +import java.util.Optional; +@Deprecated(since = "5.0.2", forRemoval = true) @Service public class RuleService extends AbstractPaginateService<RuleDto> { static final VitamUILogger LOGGER = VitamUILoggerFactory.getInstance(RuleService.class); private RuleExternalRestClient client; - + private RuleExternalWebClient webClient; private CommonService commonService; @@ -99,15 +98,15 @@ public class RuleService extends AbstractPaginateService<RuleDto> { public boolean check(ExternalHttpContext context, RuleDto ruleDto) { return client.check(context,ruleDto); } - + public boolean createRule(ExternalHttpContext context, RuleDto ruleDto) { return client.createRule(context, ruleDto); } - + public boolean patchRule(ExternalHttpContext context, Map<String, Object> partialDto, String id) { return client.patchRule(context, partialDto, id); } - + public boolean deleteRule(ExternalHttpContext context, String id) { return client.deleteRule(context, id); } -- GitLab