From 23bd42a69707c64ab5fb919c4508251b0ca627e8 Mon Sep 17 00:00:00 2001 From: oussamasic <oussamazerouali42@gmail.com> Date: Mon, 6 Sep 2021 18:33:42 +0200 Subject: [PATCH] Create Dip Request --- .../common/dto/ExportDipCriteriaDto.java | 60 ++++++++ .../ArchiveSearchExternalRestClient.java | 5 +- .../ArchivesSearchExternalController.java | 11 +- .../ArchivesSearchExternalService.java | 5 +- .../client/ArchiveInternalRestClient.java | 7 +- .../ArchiveSearchInternalServerConfig.java | 7 + .../rest/ArchiveSearchInternalController.java | 11 +- .../service/ArchiveSearchInternalService.java | 56 ++++++-- ...ArchiveSearchInternalServerConfigTest.java | 4 + ...iteriaHistoryInternalServerConfigTest.java | 4 + .../ArchiveSearchInternalServiceTest.java | 6 +- .../server/config/ApiIamServerConfigTest.java | 4 + .../InitCustomerServiceIntegrationTest.java | 4 + .../ApiIngestInternalServerConfigTest.java | 4 + .../vitam/api/access/ExportDipV2Service.java | 75 ++++++++++ .../commons/vitam/api/access/UnitService.java | 6 +- .../vitam/api/config/VitamAccessConfig.java | 6 + .../vitam/api/config/VitamClientConfig.java | 11 ++ .../api/access/ExportDipV2ServiceTest.java | 73 ++++++++++ .../search/rest/ArchivesSearchController.java | 7 +- .../search/service/ArchivesSearchService.java | 7 +- .../modules/security/has-role.directive.ts | 20 +-- .../archive-search.component.html | 6 +- .../archive-search.component.ts | 74 ++++++---- .../dip-request-create.component.css | 15 ++ .../dip-request-create.component.html | 124 ++++++++++++++++ .../dip-request-create.component.spec.ts | 77 ++++++++++ .../dip-request-create.component.ts | 135 ++++++++++++++++++ .../src/app/archive/archive.module.ts | 2 + .../src/app/archive/archive.service.ts | 23 ++- .../models/dip-request-detail.interface.ts | 54 +++++++ .../vitamui-snack-bar.component.html | 7 +- .../vitamui-snack-bar.component.scss | 19 +-- .../src/app/core/api/archive-api.service.ts | 5 +- .../archive-search/src/assets/i18n/en.json | 23 ++- .../archive-search/src/assets/i18n/fr.json | 23 ++- 36 files changed, 874 insertions(+), 106 deletions(-) create mode 100644 api/api-archive-search/archive-search-commons/src/main/java/fr/gouv/vitamui/archives/search/common/dto/ExportDipCriteriaDto.java create mode 100644 commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/access/ExportDipV2Service.java create mode 100644 commons/commons-vitam/src/test/java/fr/gouv/vitamui/commons/vitam/api/access/ExportDipV2ServiceTest.java create mode 100644 ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/dip-request-create/dip-request-create.component.css create mode 100644 ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/dip-request-create/dip-request-create.component.html create mode 100644 ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/dip-request-create/dip-request-create.component.spec.ts create mode 100644 ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/dip-request-create/dip-request-create.component.ts create mode 100644 ui/ui-frontend/projects/archive-search/src/app/archive/models/dip-request-detail.interface.ts diff --git a/api/api-archive-search/archive-search-commons/src/main/java/fr/gouv/vitamui/archives/search/common/dto/ExportDipCriteriaDto.java b/api/api-archive-search/archive-search-commons/src/main/java/fr/gouv/vitamui/archives/search/common/dto/ExportDipCriteriaDto.java new file mode 100644 index 000000000..0badfde3e --- /dev/null +++ b/api/api-archive-search/archive-search-commons/src/main/java/fr/gouv/vitamui/archives/search/common/dto/ExportDipCriteriaDto.java @@ -0,0 +1,60 @@ +/** + * 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.archives.search.common.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; +import fr.gouv.vitam.common.model.export.dip.DipRequestParameters; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.io.Serializable; +import java.util.Set; + +@ToString +@JsonInclude(JsonInclude.Include.NON_NULL) +@Setter +@Getter +public class ExportDipCriteriaDto implements Serializable { + + private DipRequestParameters dipRequestParameters; + private SearchCriteriaDto exportDIPSearchCriteria; + private Set<String> dataObjectVersions ; + private boolean lifeCycleLogs; + +} diff --git a/api/api-archive-search/archive-search-external-client/src/main/java/fr/gouv/vitamui/archives/search/external/client/ArchiveSearchExternalRestClient.java b/api/api-archive-search/archive-search-external-client/src/main/java/fr/gouv/vitamui/archives/search/external/client/ArchiveSearchExternalRestClient.java index daf3ec591..467a14233 100644 --- a/api/api-archive-search/archive-search-external-client/src/main/java/fr/gouv/vitamui/archives/search/external/client/ArchiveSearchExternalRestClient.java +++ b/api/api-archive-search/archive-search-external-client/src/main/java/fr/gouv/vitamui/archives/search/external/client/ArchiveSearchExternalRestClient.java @@ -28,6 +28,7 @@ package fr.gouv.vitamui.archives.search.external.client; import fr.gouv.vitamui.archives.search.common.dto.ArchiveUnitsDto; +import fr.gouv.vitamui.archives.search.common.dto.ExportDipCriteriaDto; import fr.gouv.vitamui.archives.search.common.dto.SearchCriteriaDto; import fr.gouv.vitamui.archives.search.common.rest.RestApi; import fr.gouv.vitamui.commons.api.CommonConstants; @@ -158,10 +159,10 @@ public class ArchiveSearchExternalRestClient return response; } - public ResponseEntity<String> exportDIPCriteria(SearchCriteriaDto query, ExternalHttpContext context) { + public ResponseEntity<String> exportDIPCriteria(ExportDipCriteriaDto exportDipCriteriaDto, ExternalHttpContext context) { LOGGER.debug("Calling export DIP by criteria"); MultiValueMap<String, String> headers = buildSearchHeaders(context); - final HttpEntity<SearchCriteriaDto> request = new HttpEntity<>(query, headers); + final HttpEntity<ExportDipCriteriaDto> request = new HttpEntity<>(exportDipCriteriaDto, headers); final ResponseEntity<String> response = restTemplate.exchange(getUrl() + RestApi.EXPORT_DIP, HttpMethod.POST, request, String.class); diff --git a/api/api-archive-search/archive-search-external/src/main/java/fr/gouv/vitamui/archives/search/external/server/rest/ArchivesSearchExternalController.java b/api/api-archive-search/archive-search-external/src/main/java/fr/gouv/vitamui/archives/search/external/server/rest/ArchivesSearchExternalController.java index f3da19f5a..5c6143852 100644 --- a/api/api-archive-search/archive-search-external/src/main/java/fr/gouv/vitamui/archives/search/external/server/rest/ArchivesSearchExternalController.java +++ b/api/api-archive-search/archive-search-external/src/main/java/fr/gouv/vitamui/archives/search/external/server/rest/ArchivesSearchExternalController.java @@ -29,6 +29,7 @@ package fr.gouv.vitamui.archives.search.external.server.rest; import fr.gouv.vitamui.archives.search.common.dto.ArchiveUnitsDto; +import fr.gouv.vitamui.archives.search.common.dto.ExportDipCriteriaDto; import fr.gouv.vitamui.archives.search.common.dto.SearchCriteriaDto; import fr.gouv.vitamui.archives.search.common.rest.RestApi; import fr.gouv.vitamui.archives.search.external.server.service.ArchivesSearchExternalService; @@ -125,11 +126,11 @@ public class ArchivesSearchExternalController { @PostMapping(RestApi.EXPORT_DIP) @Secured(ServicesData.ROLE_EXPORT_DIP) - public String exportDIPByCriteria(final @RequestBody SearchCriteriaDto query) { - LOGGER.info("Calling export DIP By Criteria {} ", query); - ParameterChecker.checkParameter("The query is a mandatory parameter: ", query); - SanityChecker.sanitizeCriteria(query); - return archivesSearchExternalService.exportDIPByCriteria(query); + public String exportDIPByCriteria(final @RequestBody ExportDipCriteriaDto exportDipCriteriaDto) { + LOGGER.info("Calling export DIP By Criteria {} ", exportDipCriteriaDto); + ParameterChecker.checkParameter("The query is a mandatory parameter: ", exportDipCriteriaDto); + SanityChecker.sanitizeCriteria(exportDipCriteriaDto); + return archivesSearchExternalService.exportDIPByCriteria(exportDipCriteriaDto); } } diff --git a/api/api-archive-search/archive-search-external/src/main/java/fr/gouv/vitamui/archives/search/external/server/service/ArchivesSearchExternalService.java b/api/api-archive-search/archive-search-external/src/main/java/fr/gouv/vitamui/archives/search/external/server/service/ArchivesSearchExternalService.java index b85dd6786..bfc43abe8 100644 --- a/api/api-archive-search/archive-search-external/src/main/java/fr/gouv/vitamui/archives/search/external/server/service/ArchivesSearchExternalService.java +++ b/api/api-archive-search/archive-search-external/src/main/java/fr/gouv/vitamui/archives/search/external/server/service/ArchivesSearchExternalService.java @@ -30,6 +30,7 @@ package fr.gouv.vitamui.archives.search.external.server.service; import fr.gouv.archive.internal.client.ArchiveInternalRestClient; import fr.gouv.archive.internal.client.ArchiveInternalWebClient; import fr.gouv.vitamui.archives.search.common.dto.ArchiveUnitsDto; +import fr.gouv.vitamui.archives.search.common.dto.ExportDipCriteriaDto; import fr.gouv.vitamui.archives.search.common.dto.SearchCriteriaDto; import fr.gouv.vitamui.commons.vitam.api.dto.ResultsDto; import fr.gouv.vitamui.commons.vitam.api.dto.VitamUISearchResponseDto; @@ -95,7 +96,7 @@ public class ArchivesSearchExternalService extends AbstractResourceClientService return archiveInternalRestClient.exportCsvArchiveUnitsByCriteria(query, getInternalHttpContext()); } - public String exportDIPByCriteria(final SearchCriteriaDto query) { - return archiveInternalRestClient.exportDIPByCriteria(query, getInternalHttpContext()); + public String exportDIPByCriteria(final ExportDipCriteriaDto exportDipCriteriaDto) { + return archiveInternalRestClient.exportDIPByCriteria(exportDipCriteriaDto, getInternalHttpContext()); } } diff --git a/api/api-archive-search/archive-search-internal-client/src/main/java/fr/gouv/archive/internal/client/ArchiveInternalRestClient.java b/api/api-archive-search/archive-search-internal-client/src/main/java/fr/gouv/archive/internal/client/ArchiveInternalRestClient.java index 2ad3a66ad..d16119f02 100644 --- a/api/api-archive-search/archive-search-internal-client/src/main/java/fr/gouv/archive/internal/client/ArchiveInternalRestClient.java +++ b/api/api-archive-search/archive-search-internal-client/src/main/java/fr/gouv/archive/internal/client/ArchiveInternalRestClient.java @@ -28,6 +28,7 @@ package fr.gouv.archive.internal.client; import com.fasterxml.jackson.databind.JsonNode; import fr.gouv.vitamui.archives.search.common.dto.ArchiveUnitsDto; +import fr.gouv.vitamui.archives.search.common.dto.ExportDipCriteriaDto; import fr.gouv.vitamui.archives.search.common.dto.SearchCriteriaDto; import fr.gouv.vitamui.archives.search.common.rest.RestApi; import fr.gouv.vitamui.commons.api.CommonConstants; @@ -159,11 +160,11 @@ public class ArchiveInternalRestClient } - public String exportDIPByCriteria(final SearchCriteriaDto query, + public String exportDIPByCriteria(final ExportDipCriteriaDto exportDipCriteriaDto, final InternalHttpContext context) { - LOGGER.info("Calling exportDIPByCriteria with query {} ", query); + LOGGER.info("Calling exportDIPByCriteria with query {} ", exportDipCriteriaDto); MultiValueMap<String, String> headers = buildSearchHeaders(context); - final HttpEntity<SearchCriteriaDto> request = new HttpEntity<>(query, headers); + final HttpEntity<ExportDipCriteriaDto> request = new HttpEntity<>(exportDipCriteriaDto, headers); final ResponseEntity<String> response = restTemplate.exchange(getUrl() + RestApi.EXPORT_DIP, HttpMethod.POST, request, String.class); diff --git a/api/api-archive-search/archive-search-internal/src/main/java/fr/gouv/vitamui/archive/internal/server/config/ArchiveSearchInternalServerConfig.java b/api/api-archive-search/archive-search-internal/src/main/java/fr/gouv/vitamui/archive/internal/server/config/ArchiveSearchInternalServerConfig.java index 4e06129ca..894b814ae 100644 --- a/api/api-archive-search/archive-search-internal/src/main/java/fr/gouv/vitamui/archive/internal/server/config/ArchiveSearchInternalServerConfig.java +++ b/api/api-archive-search/archive-search-internal/src/main/java/fr/gouv/vitamui/archive/internal/server/config/ArchiveSearchInternalServerConfig.java @@ -27,6 +27,7 @@ package fr.gouv.vitamui.archive.internal.server.config; import fr.gouv.vitam.access.external.client.AccessExternalClient; +import fr.gouv.vitam.access.external.client.v2.AccessExternalClientV2; import fr.gouv.vitamui.archive.internal.server.searchcriteria.converter.SearchCriteriaHistoryConverter; import fr.gouv.vitamui.archive.internal.server.searchcriteria.dao.SearchCriteriaHistoryRepository; import fr.gouv.vitamui.archive.internal.server.searchcriteria.service.SearchCriteriaHistoryInternalService; @@ -35,6 +36,7 @@ import fr.gouv.vitamui.commons.mongo.dao.CustomSequenceRepository; import fr.gouv.vitamui.commons.rest.RestExceptionHandler; import fr.gouv.vitamui.commons.rest.client.configuration.RestClientConfiguration; import fr.gouv.vitamui.commons.rest.configuration.SwaggerConfiguration; +import fr.gouv.vitamui.commons.vitam.api.access.ExportDipV2Service; import fr.gouv.vitamui.commons.vitam.api.access.UnitService; import fr.gouv.vitamui.commons.vitam.api.config.VitamAccessConfig; import fr.gouv.vitamui.commons.vitam.api.config.VitamAdministrationConfig; @@ -96,6 +98,11 @@ public class ArchiveSearchInternalServerConfig extends AbstractContextConfigurat return new UnitService(client); } + @Bean + public ExportDipV2Service exportDipV2Service(final AccessExternalClientV2 accessExternalClientV2) { + return new ExportDipV2Service(accessExternalClientV2); + } + @Bean public SearchCriteriaHistoryInternalService searchCriteriaHistoryInternalService( final CustomSequenceRepository sequenceRepository, diff --git a/api/api-archive-search/archive-search-internal/src/main/java/fr/gouv/vitamui/archive/internal/server/rest/ArchiveSearchInternalController.java b/api/api-archive-search/archive-search-internal/src/main/java/fr/gouv/vitamui/archive/internal/server/rest/ArchiveSearchInternalController.java index 383bfb94f..3d578caea 100644 --- a/api/api-archive-search/archive-search-internal/src/main/java/fr/gouv/vitamui/archive/internal/server/rest/ArchiveSearchInternalController.java +++ b/api/api-archive-search/archive-search-internal/src/main/java/fr/gouv/vitamui/archive/internal/server/rest/ArchiveSearchInternalController.java @@ -36,6 +36,7 @@ import fr.gouv.vitam.common.exception.InvalidParseOperationException; import fr.gouv.vitam.common.exception.VitamClientException; import fr.gouv.vitamui.archive.internal.server.service.ArchiveSearchInternalService; import fr.gouv.vitamui.archives.search.common.dto.ArchiveUnitsDto; +import fr.gouv.vitamui.archives.search.common.dto.ExportDipCriteriaDto; import fr.gouv.vitamui.archives.search.common.dto.SearchCriteriaDto; import fr.gouv.vitamui.archives.search.common.rest.RestApi; import fr.gouv.vitamui.common.security.SanityChecker; @@ -210,15 +211,15 @@ public class ArchiveSearchInternalController { public ResponseEntity<String> exportDIPByCriteria( @RequestHeader(value = CommonConstants.X_TENANT_ID_HEADER) final Integer tenantId, @RequestHeader(value = CommonConstants.X_ACCESS_CONTRACT_ID_HEADER) final String accessContractId, - @RequestBody final SearchCriteriaDto searchQuery) + @RequestBody final ExportDipCriteriaDto exportDipCriteriaDto) throws VitamClientException { - LOGGER.info("Export DIP by criteria {}", searchQuery); - SanityChecker.sanitizeCriteria(searchQuery); + LOGGER.info("Export DIP by criteria {}", exportDipCriteriaDto); + SanityChecker.sanitizeCriteria(exportDipCriteriaDto); ParameterChecker .checkParameter("The tenant Id, the accessContract Id and the SearchCriteria are mandatory parameters: ", - tenantId, accessContractId, searchQuery); + tenantId, accessContractId, exportDipCriteriaDto); final VitamContext vitamContext = securityService.buildVitamContext(tenantId, accessContractId); - String result = archiveInternalService.exportDIP(searchQuery, vitamContext); + String result = archiveInternalService.requestToExportDIP(exportDipCriteriaDto, vitamContext); return new ResponseEntity<>(result, HttpStatus.OK); } diff --git a/api/api-archive-search/archive-search-internal/src/main/java/fr/gouv/vitamui/archive/internal/server/service/ArchiveSearchInternalService.java b/api/api-archive-search/archive-search-internal/src/main/java/fr/gouv/vitamui/archive/internal/server/service/ArchiveSearchInternalService.java index fad77307e..7d218e44a 100644 --- a/api/api-archive-search/archive-search-internal/src/main/java/fr/gouv/vitamui/archive/internal/server/service/ArchiveSearchInternalService.java +++ b/api/api-archive-search/archive-search-internal/src/main/java/fr/gouv/vitamui/archive/internal/server/service/ArchiveSearchInternalService.java @@ -42,11 +42,15 @@ import fr.gouv.vitam.common.database.facet.model.FacetOrder; import fr.gouv.vitam.common.exception.InvalidParseOperationException; import fr.gouv.vitam.common.exception.VitamClientException; import fr.gouv.vitam.common.model.RequestResponse; +import fr.gouv.vitam.common.model.dip.DataObjectVersions; +import fr.gouv.vitam.common.model.export.dip.DipExportType; +import fr.gouv.vitam.common.model.export.dip.DipRequest; import fr.gouv.vitamui.archives.search.common.common.ArchiveSearchConsts; import fr.gouv.vitamui.archives.search.common.dto.ArchiveUnit; import fr.gouv.vitamui.archives.search.common.dto.ArchiveUnitCsv; import fr.gouv.vitamui.archives.search.common.dto.ArchiveUnitsDto; import fr.gouv.vitamui.archives.search.common.dto.CriteriaValue; +import fr.gouv.vitamui.archives.search.common.dto.ExportDipCriteriaDto; import fr.gouv.vitamui.archives.search.common.dto.ExportSearchResultParam; import fr.gouv.vitamui.archives.search.common.dto.SearchCriteriaDto; import fr.gouv.vitamui.archives.search.common.dto.SearchCriteriaEltDto; @@ -58,6 +62,7 @@ import fr.gouv.vitamui.commons.api.exception.InternalServerException; import fr.gouv.vitamui.commons.api.exception.RequestEntityTooLargeException; import fr.gouv.vitamui.commons.api.logger.VitamUILogger; import fr.gouv.vitamui.commons.api.logger.VitamUILoggerFactory; +import fr.gouv.vitamui.commons.vitam.api.access.ExportDipV2Service; import fr.gouv.vitamui.commons.vitam.api.access.UnitService; import fr.gouv.vitamui.commons.vitam.api.dto.ResultsDto; import fr.gouv.vitamui.commons.vitam.api.dto.VitamUISearchResponseDto; @@ -107,6 +112,7 @@ public class ArchiveSearchInternalService { public static final String NEW_LINE = "\n"; public static final String NEW_TAB = "\t"; public static final String NEW_LINE_1 = "\r\n"; + public static final String OPERATION_IDENTIFIER = "itemId"; public static final String SPACE = " "; @@ -116,6 +122,7 @@ public class ArchiveSearchInternalService { private final ArchiveSearchRulesInternalService archiveSearchRulesInternalService; private final ArchivesSearchAppraisalQueryBuilderService archivesSearchAppraisalQueryBuilderService; private final ArchivesSearchFieldsQueryBuilderService archivesSearchFieldsQueryBuilderService; + private final ExportDipV2Service exportDipV2Service; @Autowired @@ -123,7 +130,8 @@ public class ArchiveSearchInternalService { final ArchiveSearchAgenciesInternalService archiveSearchAgenciesInternalService, final ArchiveSearchRulesInternalService archiveSearchRulesInternalService, final ArchivesSearchFieldsQueryBuilderService archivesSearchFieldsQueryBuilderService, - final ArchivesSearchAppraisalQueryBuilderService archivesSearchAppraisalQueryBuilderService + final ArchivesSearchAppraisalQueryBuilderService archivesSearchAppraisalQueryBuilderService, + final ExportDipV2Service exportDipV2Service ) { this.unitService = unitService; @@ -132,6 +140,7 @@ public class ArchiveSearchInternalService { this.archiveSearchRulesInternalService = archiveSearchRulesInternalService; this.archivesSearchFieldsQueryBuilderService = archivesSearchFieldsQueryBuilderService; this.archivesSearchAppraisalQueryBuilderService = archivesSearchAppraisalQueryBuilderService; + this.exportDipV2Service = exportDipV2Service; } public ArchiveUnitsDto searchArchiveUnitsByCriteria(final SearchCriteriaDto searchQuery, @@ -509,21 +518,44 @@ public class ArchiveSearchInternalService { return select.getFinalSelect(); } - public String exportDIP(final SearchCriteriaDto searchQuery, + public String requestToExportDIP(final ExportDipCriteriaDto exportDipCriteriaDto, final VitamContext vitamContext) throws VitamClientException { - LOGGER.debug("Export DIP by criteria {} ", searchQuery.toString()); - searchQuery.setPageNumber(0); - searchQuery.setSize(EXPORT_DIP_MAX_ELEMENTS); - archiveSearchAgenciesInternalService.mapAgenciesNameToCodes(searchQuery, vitamContext); - archiveSearchRulesInternalService.mapAppraisalRulesTitlesToCodes(searchQuery, vitamContext); - JsonNode dslQuery = mapRequestToDslQuery(searchQuery); - JsonNode vitamResponse = searchArchiveUnits(dslQuery, vitamContext); - return vitamResponse.toString(); - } - private void test() { + LOGGER.debug("Export DIP by criteria {} ", exportDipCriteriaDto); + exportDipCriteriaDto.getExportDIPSearchCriteria().setPageNumber(0); + exportDipCriteriaDto.getExportDIPSearchCriteria().setSize(EXPORT_DIP_MAX_ELEMENTS); + archiveSearchAgenciesInternalService.mapAgenciesNameToCodes(exportDipCriteriaDto.getExportDIPSearchCriteria(), vitamContext); + archiveSearchRulesInternalService.mapAppraisalRulesTitlesToCodes(exportDipCriteriaDto.getExportDIPSearchCriteria(), vitamContext); + JsonNode dslQuery = mapRequestToDslQuery(exportDipCriteriaDto.getExportDIPSearchCriteria()); + DataObjectVersions dataObjectVersionToExport = new DataObjectVersions(); + dataObjectVersionToExport.setDataObjectVersions(exportDipCriteriaDto.getDataObjectVersions()); + DipRequest dipRequest = prepareDipRequestBody(exportDipCriteriaDto, dslQuery); + JsonNode response = exportDIP(vitamContext,dipRequest); + return response.findValue(OPERATION_IDENTIFIER).textValue(); } + + public DipRequest prepareDipRequestBody(final ExportDipCriteriaDto exportDipCriteriaDto, JsonNode dslQuery) { + DipRequest dipRequest = new DipRequest(); + + if(exportDipCriteriaDto != null) { + DataObjectVersions dataObjectVersionToExport = new DataObjectVersions(); + dataObjectVersionToExport.setDataObjectVersions(exportDipCriteriaDto.getDataObjectVersions()); + dipRequest.setExportWithLogBookLFC(exportDipCriteriaDto.isLifeCycleLogs()); + dipRequest.setDslRequest(dslQuery); + dipRequest.setDipExportType(DipExportType.FULL); + dipRequest.setDataObjectVersionToExport(dataObjectVersionToExport); + dipRequest.setDipRequestParameters(exportDipCriteriaDto.getDipRequestParameters()); + } + return dipRequest; + } + + public JsonNode exportDIP( final VitamContext vitamContext, DipRequest dipRequest) + throws VitamClientException { + RequestResponse<JsonNode> response = exportDipV2Service.exportDip( vitamContext, dipRequest); + return response.toJsonNode(); + } + } diff --git a/api/api-archive-search/archive-search-internal/src/test/java/fr/gouv/vitamui/archive/internal/server/config/ApiArchiveSearchInternalServerConfigTest.java b/api/api-archive-search/archive-search-internal/src/test/java/fr/gouv/vitamui/archive/internal/server/config/ApiArchiveSearchInternalServerConfigTest.java index a8efdef52..ca53f8661 100644 --- a/api/api-archive-search/archive-search-internal/src/test/java/fr/gouv/vitamui/archive/internal/server/config/ApiArchiveSearchInternalServerConfigTest.java +++ b/api/api-archive-search/archive-search-internal/src/test/java/fr/gouv/vitamui/archive/internal/server/config/ApiArchiveSearchInternalServerConfigTest.java @@ -28,6 +28,7 @@ package fr.gouv.vitamui.archive.internal.server.config; import fr.gouv.vitam.access.external.client.AccessExternalClient; import fr.gouv.vitam.access.external.client.AdminExternalClient; +import fr.gouv.vitam.access.external.client.v2.AccessExternalClientV2; import fr.gouv.vitam.ingest.external.client.IngestExternalClient; import fr.gouv.vitamui.archive.internal.server.service.ArchiveSearchAgenciesInternalService; import fr.gouv.vitamui.archive.internal.server.service.ArchiveSearchInternalService; @@ -56,6 +57,9 @@ public class ApiArchiveSearchInternalServerConfigTest extends AbstractContextCon @MockBean(name = "accessExternalClient") private AccessExternalClient accessExternalClient; + @MockBean(name = "accessExternalClientV2") + private AccessExternalClientV2 accessExternalClientV2; + @MockBean(name = "ingestExternalClient") private IngestExternalClient ingestExternalClient; diff --git a/api/api-archive-search/archive-search-internal/src/test/java/fr/gouv/vitamui/archive/internal/server/config/SearchCriteriaHistoryInternalServerConfigTest.java b/api/api-archive-search/archive-search-internal/src/test/java/fr/gouv/vitamui/archive/internal/server/config/SearchCriteriaHistoryInternalServerConfigTest.java index a96be83b5..0897dc483 100644 --- a/api/api-archive-search/archive-search-internal/src/test/java/fr/gouv/vitamui/archive/internal/server/config/SearchCriteriaHistoryInternalServerConfigTest.java +++ b/api/api-archive-search/archive-search-internal/src/test/java/fr/gouv/vitamui/archive/internal/server/config/SearchCriteriaHistoryInternalServerConfigTest.java @@ -39,6 +39,7 @@ package fr.gouv.vitamui.archive.internal.server.config; import fr.gouv.vitam.access.external.client.AccessExternalClient; import fr.gouv.vitam.access.external.client.AdminExternalClient; +import fr.gouv.vitam.access.external.client.v2.AccessExternalClientV2; import fr.gouv.vitam.ingest.external.client.IngestExternalClient; import fr.gouv.vitamui.archive.internal.server.searchcriteria.service.SearchCriteriaHistoryInternalService; import org.junit.jupiter.api.Assertions; @@ -67,6 +68,9 @@ public class SearchCriteriaHistoryInternalServerConfigTest { @MockBean(name = "ingestExternalClient") private IngestExternalClient ingestExternalClient; + @MockBean(name = "accessExternalClientV2") + private AccessExternalClientV2 accessExternalClientV2; + @Autowired private SearchCriteriaHistoryInternalService searchCriteriaHistoryInternalService; diff --git a/api/api-archive-search/archive-search-internal/src/test/java/fr/gouv/vitamui/archive/internal/server/service/ArchiveSearchInternalServiceTest.java b/api/api-archive-search/archive-search-internal/src/test/java/fr/gouv/vitamui/archive/internal/server/service/ArchiveSearchInternalServiceTest.java index d852002e1..ab03237d3 100644 --- a/api/api-archive-search/archive-search-internal/src/test/java/fr/gouv/vitamui/archive/internal/server/service/ArchiveSearchInternalServiceTest.java +++ b/api/api-archive-search/archive-search-internal/src/test/java/fr/gouv/vitamui/archive/internal/server/service/ArchiveSearchInternalServiceTest.java @@ -48,6 +48,7 @@ import fr.gouv.vitam.common.model.RequestResponseOK; import fr.gouv.vitamui.commons.api.logger.VitamUILogger; import fr.gouv.vitamui.commons.api.logger.VitamUILoggerFactory; import fr.gouv.vitamui.commons.test.utils.ServerIdentityConfigurationBuilder; +import fr.gouv.vitamui.commons.vitam.api.access.ExportDipV2Service; import fr.gouv.vitamui.commons.vitam.api.access.UnitService; import fr.gouv.vitamui.commons.vitam.api.administration.AgencyService; import fr.gouv.vitamui.commons.vitam.api.dto.VitamUISearchResponseDto; @@ -94,6 +95,9 @@ public class ArchiveSearchInternalServiceTest { @InjectMocks private ArchiveSearchInternalService archiveSearchInternalService; + @MockBean(name = "exportDipV2Service") + private ExportDipV2Service exportDipV2Service; + public final String FILING_HOLDING_SCHEME_RESULTS = "data/vitam_filing_holding_units_response.json"; @BeforeEach @@ -102,7 +106,7 @@ public class ArchiveSearchInternalServiceTest { archiveSearchInternalService = new ArchiveSearchInternalService(objectMapper, unitService, archiveSearchAgenciesInternalService, archiveSearchRulesInternalService, archivesSearchFieldsQueryBuilderService, - archivesSearchAppraisalQueryBuilderService); + archivesSearchAppraisalQueryBuilderService, exportDipV2Service); } @Test diff --git a/api/api-iam/iam-internal/src/test/java/fr/gouv/vitamui/iam/internal/server/config/ApiIamServerConfigTest.java b/api/api-iam/iam-internal/src/test/java/fr/gouv/vitamui/iam/internal/server/config/ApiIamServerConfigTest.java index c460fb837..259d89ac8 100644 --- a/api/api-iam/iam-internal/src/test/java/fr/gouv/vitamui/iam/internal/server/config/ApiIamServerConfigTest.java +++ b/api/api-iam/iam-internal/src/test/java/fr/gouv/vitamui/iam/internal/server/config/ApiIamServerConfigTest.java @@ -2,6 +2,7 @@ package fr.gouv.vitamui.iam.internal.server.config; import static org.assertj.core.api.Assertions.assertThat; +import fr.gouv.vitam.access.external.client.v2.AccessExternalClientV2; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -31,6 +32,9 @@ public class ApiIamServerConfigTest { @MockBean(name = "ingestExternalClient") private IngestExternalClient ingestExternalClient; + @MockBean(name = "accessExternalClientV2") + private AccessExternalClientV2 accessExternalClientV2; + @Autowired private EventService logbookService; diff --git a/api/api-iam/iam-internal/src/test/java/fr/gouv/vitamui/iam/internal/server/customer/service/InitCustomerServiceIntegrationTest.java b/api/api-iam/iam-internal/src/test/java/fr/gouv/vitamui/iam/internal/server/customer/service/InitCustomerServiceIntegrationTest.java index 719054cdc..876c45add 100644 --- a/api/api-iam/iam-internal/src/test/java/fr/gouv/vitamui/iam/internal/server/customer/service/InitCustomerServiceIntegrationTest.java +++ b/api/api-iam/iam-internal/src/test/java/fr/gouv/vitamui/iam/internal/server/customer/service/InitCustomerServiceIntegrationTest.java @@ -2,6 +2,7 @@ package fr.gouv.vitamui.iam.internal.server.customer.service; import fr.gouv.vitam.access.external.client.AccessExternalClient; import fr.gouv.vitam.access.external.client.AdminExternalClient; +import fr.gouv.vitam.access.external.client.v2.AccessExternalClientV2; import fr.gouv.vitam.ingest.external.client.IngestExternalClient; import fr.gouv.vitamui.commons.api.domain.AddressDto; import fr.gouv.vitamui.commons.api.domain.ExternalParametersDto; @@ -128,6 +129,9 @@ public class InitCustomerServiceIntegrationTest { @MockBean(name = "ingestExternalClient") private IngestExternalClient ingestExternalClient; + @MockBean(name = "accessExternalClientV2") + private AccessExternalClientV2 accessExternalClientV2; + @MockBean private InternalSecurityService internalSecurityService; diff --git a/api/api-ingest/ingest-internal/src/test/java/fr/gouv/vitamui/ingest/internal/server/config/ApiIngestInternalServerConfigTest.java b/api/api-ingest/ingest-internal/src/test/java/fr/gouv/vitamui/ingest/internal/server/config/ApiIngestInternalServerConfigTest.java index aa87cc184..9d2c74987 100644 --- a/api/api-ingest/ingest-internal/src/test/java/fr/gouv/vitamui/ingest/internal/server/config/ApiIngestInternalServerConfigTest.java +++ b/api/api-ingest/ingest-internal/src/test/java/fr/gouv/vitamui/ingest/internal/server/config/ApiIngestInternalServerConfigTest.java @@ -38,6 +38,7 @@ package fr.gouv.vitamui.ingest.internal.server.config; import fr.gouv.vitam.access.external.client.AccessExternalClient; import fr.gouv.vitam.access.external.client.AdminExternalClient; +import fr.gouv.vitam.access.external.client.v2.AccessExternalClientV2; import fr.gouv.vitam.ingest.external.client.IngestExternalClient; import fr.gouv.vitamui.commons.vitam.api.ingest.IngestService; import fr.gouv.vitamui.ingest.internal.server.service.IngestInternalService; @@ -67,6 +68,9 @@ public class ApiIngestInternalServerConfigTest { @MockBean(name = "ingestExternalClient") private IngestExternalClient ingestExternalClient; + @MockBean(name = "accessExternalClientV2") + private AccessExternalClientV2 accessExternalClientV2; + @MockBean(name = "ingestService") private IngestService ingestService; diff --git a/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/access/ExportDipV2Service.java b/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/access/ExportDipV2Service.java new file mode 100644 index 000000000..a20a18657 --- /dev/null +++ b/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/access/ExportDipV2Service.java @@ -0,0 +1,75 @@ +/** + * 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.access; + +import com.fasterxml.jackson.databind.JsonNode; +import fr.gouv.vitam.access.external.client.v2.AccessExternalClientV2; +import fr.gouv.vitam.common.client.VitamContext; +import fr.gouv.vitam.common.exception.VitamClientException; +import fr.gouv.vitam.common.model.RequestResponse; +import fr.gouv.vitam.common.model.export.dip.DipRequest; +import fr.gouv.vitamui.commons.api.logger.VitamUILogger; +import fr.gouv.vitamui.commons.api.logger.VitamUILoggerFactory; +import fr.gouv.vitamui.commons.vitam.api.util.VitamRestUtils; +import org.apache.http.HttpStatus; + +public class ExportDipV2Service { + + @SuppressWarnings("unused") + private static final VitamUILogger LOGGER = VitamUILoggerFactory.getInstance(ExportDipV2Service.class); + + private final AccessExternalClientV2 accessExternalClientV2; + + public ExportDipV2Service(final AccessExternalClientV2 accessExternalClientV2) { + this.accessExternalClientV2 = accessExternalClientV2; + } + + /** + * Starts the export of the files of the selected unit archives. + * @param dipRequest DipRequest used to select units to export as DIP + * @param vitamContext The vitam context + * @return + * @throws VitamClientException + */ + + public RequestResponse<JsonNode> exportDip( final VitamContext vitamContext, final DipRequest dipRequest) throws VitamClientException { + final RequestResponse<JsonNode> response = accessExternalClientV2.exportDIP(vitamContext, dipRequest); + VitamRestUtils.checkResponse(response, HttpStatus.SC_OK, HttpStatus.SC_ACCEPTED); + return response; + } +} diff --git a/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/access/UnitService.java b/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/access/UnitService.java index 908e260a1..970c95dee 100644 --- a/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/access/UnitService.java +++ b/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/access/UnitService.java @@ -87,7 +87,7 @@ public class UnitService { return result; } - public RequestResponse<JsonNode> searchUnitsWithErrors(final Optional<String> unitId, final JsonNode dslQuery, final VitamContext vitamContext) + public RequestResponse<JsonNode> searchUnitsWithErrors(final Optional<String> unitId, final JsonNode dslQuery, final VitamContext vitamContext) throws VitamClientException { final RequestResponse<JsonNode> result; if (unitId.isPresent()) { @@ -97,7 +97,7 @@ public class UnitService { } return result; } - + public RequestResponse<JsonNode> searchUnitsWithInheritedRules(final JsonNode dslQuery, final VitamContext vitamContext) throws VitamClientException { final RequestResponse<JsonNode> result = @@ -114,7 +114,7 @@ public class UnitService { VitamRestUtils.checkResponse(result); return result; } - + public RequestResponse<JsonNode> findObjectMetadataById(final String unitId, final JsonNode dslQuery, final VitamContext vitamContext) throws VitamClientException { final RequestResponse<JsonNode> result = accessExternalClient.selectObjectMetadatasByUnitId(vitamContext, dslQuery, unitId); VitamRestUtils.checkResponse(result); diff --git a/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/config/VitamAccessConfig.java b/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/config/VitamAccessConfig.java index 850069bdf..bfc7db7ed 100644 --- a/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/config/VitamAccessConfig.java +++ b/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/config/VitamAccessConfig.java @@ -36,6 +36,7 @@ */ package fr.gouv.vitamui.commons.vitam.api.config; +import fr.gouv.vitamui.commons.vitam.api.access.ExportDipV2Service; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -67,4 +68,9 @@ public class VitamAccessConfig extends VitamClientConfig { return new ExportDipService(accessExternalClient()); } + @Bean + public ExportDipV2Service getExportDipV2Service() { + return new ExportDipV2Service(accessExternalClientV2()); + } + } diff --git a/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/config/VitamClientConfig.java b/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/config/VitamClientConfig.java index be9789fa8..a62830f27 100644 --- a/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/config/VitamClientConfig.java +++ b/commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/config/VitamClientConfig.java @@ -36,6 +36,8 @@ */ package fr.gouv.vitamui.commons.vitam.api.config; +import fr.gouv.vitam.access.external.client.v2.AccessExternalClientV2; +import fr.gouv.vitam.access.external.client.v2.AccessExternalClientV2Factory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Profile; @@ -79,4 +81,13 @@ public abstract class VitamClientConfig { } return factory.getClient(); } + + @Bean + public AccessExternalClientV2 accessExternalClientV2() { + final AccessExternalClientV2Factory factory = AccessExternalClientV2Factory.getInstance(); + if (VitamClientType.MOCK.equals(factory.getVitamClientType())) { + throw new InternalServerException("Failed to load Vitam configuration: Vitam client is in MOCK mode"); + } + return factory.getClient(); + } } diff --git a/commons/commons-vitam/src/test/java/fr/gouv/vitamui/commons/vitam/api/access/ExportDipV2ServiceTest.java b/commons/commons-vitam/src/test/java/fr/gouv/vitamui/commons/vitam/api/access/ExportDipV2ServiceTest.java new file mode 100644 index 000000000..a6b37f6af --- /dev/null +++ b/commons/commons-vitam/src/test/java/fr/gouv/vitamui/commons/vitam/api/access/ExportDipV2ServiceTest.java @@ -0,0 +1,73 @@ +/* + * * + * * 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.access; + +import fr.gouv.vitam.access.external.client.v2.AccessExternalClientV2; +import fr.gouv.vitamui.commons.api.logger.VitamUILogger; +import fr.gouv.vitamui.commons.test.utils.FieldUtils; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class ExportDipV2ServiceTest { + + @InjectMocks + private ExportDipV2Service exportDipV2Service; + + @Mock + private AccessExternalClientV2 accessExternalClientV2; + + @Mock + private VitamUILogger logger; + + @Before + public void setUp() throws NoSuchFieldException, SecurityException, Exception { + FieldUtils.setFinalStatic(ExportDipV2Service.class.getDeclaredField("LOGGER"), logger); + } + + @Test + public void toImplement() { + // TODO implement + } +} diff --git a/ui/ui-archive-search/src/main/java/fr/gouv/vitamui/archives/search/rest/ArchivesSearchController.java b/ui/ui-archive-search/src/main/java/fr/gouv/vitamui/archives/search/rest/ArchivesSearchController.java index e2ba0564b..4aaee3d53 100644 --- a/ui/ui-archive-search/src/main/java/fr/gouv/vitamui/archives/search/rest/ArchivesSearchController.java +++ b/ui/ui-archive-search/src/main/java/fr/gouv/vitamui/archives/search/rest/ArchivesSearchController.java @@ -28,6 +28,7 @@ package fr.gouv.vitamui.archives.search.rest; import fr.gouv.vitamui.archives.search.common.common.ArchiveSearchConsts; import fr.gouv.vitamui.archives.search.common.dto.ArchiveUnitsDto; +import fr.gouv.vitamui.archives.search.common.dto.ExportDipCriteriaDto; import fr.gouv.vitamui.archives.search.common.dto.ObjectData; import fr.gouv.vitamui.archives.search.common.dto.SearchCriteriaDto; import fr.gouv.vitamui.archives.search.common.dto.VitamUIArchiveUnitResponseDto; @@ -175,9 +176,9 @@ public class ArchivesSearchController extends AbstractUiRestController { @ApiOperation(value = "export DIP by criteria") @PostMapping(RestApi.EXPORT_DIP) @ResponseStatus(HttpStatus.OK) - public String exportDIPByCriteria(@RequestBody final SearchCriteriaDto searchQuery) { - LOGGER.debug("Export DIP with criteria {}", searchQuery); - String result = archivesSearchService.exportDIPByCriteria(searchQuery, buildUiHttpContext()).getBody(); + public String exportDIPByCriteria(@RequestBody final ExportDipCriteriaDto exportDipCriteriaDto) { + LOGGER.debug("Export DIP with criteria {}", exportDipCriteriaDto); + String result = archivesSearchService.exportDIPByCriteria(exportDipCriteriaDto, buildUiHttpContext()).getBody(); return result; } } diff --git a/ui/ui-archive-search/src/main/java/fr/gouv/vitamui/archives/search/service/ArchivesSearchService.java b/ui/ui-archive-search/src/main/java/fr/gouv/vitamui/archives/search/service/ArchivesSearchService.java index faadb4e45..b8e0ee2a7 100644 --- a/ui/ui-archive-search/src/main/java/fr/gouv/vitamui/archives/search/service/ArchivesSearchService.java +++ b/ui/ui-archive-search/src/main/java/fr/gouv/vitamui/archives/search/service/ArchivesSearchService.java @@ -27,6 +27,7 @@ package fr.gouv.vitamui.archives.search.service; import fr.gouv.vitamui.archives.search.common.dto.ArchiveUnitsDto; +import fr.gouv.vitamui.archives.search.common.dto.ExportDipCriteriaDto; import fr.gouv.vitamui.archives.search.common.dto.SearchCriteriaDto; import fr.gouv.vitamui.archives.search.common.dto.ObjectData; import fr.gouv.vitamui.archives.search.external.client.ArchiveSearchExternalRestClient; @@ -160,8 +161,8 @@ public class ArchivesSearchService extends AbstractPaginateService<ArchiveUnitsD return Integer.parseInt(versions.get(0).getDataObjectVersion().split("_")[1]); } - public ResponseEntity<String> exportDIPByCriteria(final SearchCriteriaDto searchQuery,ExternalHttpContext context) { - LOGGER.info("export DIP with criteria {}", searchQuery); - return archiveSearchExternalRestClient.exportDIPCriteria(searchQuery, context); + public ResponseEntity<String> exportDIPByCriteria(final ExportDipCriteriaDto exportDipCriteriaDto,ExternalHttpContext context) { + LOGGER.info("export DIP with criteria {}", exportDipCriteriaDto); + return archiveSearchExternalRestClient.exportDIPCriteria(exportDipCriteriaDto, context); } } diff --git a/ui/ui-frontend-common/src/app/modules/security/has-role.directive.ts b/ui/ui-frontend-common/src/app/modules/security/has-role.directive.ts index 517ef7e62..801a9ac31 100644 --- a/ui/ui-frontend-common/src/app/modules/security/has-role.directive.ts +++ b/ui/ui-frontend-common/src/app/modules/security/has-role.directive.ts @@ -36,27 +36,19 @@ */ import { Directive, Input, OnDestroy, OnInit, TemplateRef, ViewContainerRef } from '@angular/core'; import { Subscription } from 'rxjs'; - import { SecurityService } from './security.service'; @Directive({ - selector: '[vitamuiCommonHasRole]' + selector: '[vitamuiCommonHasRole]', }) export class HasRoleDirective implements OnInit, OnDestroy { - roleSubscription: Subscription; private viewEmbedded = false; - constructor( - private templateRef: TemplateRef<any>, - private viewContainer: ViewContainerRef, - private securityService: SecurityService - ) { - } + constructor(private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef, private securityService: SecurityService) {} - ngOnInit(): void { - } + ngOnInit(): void {} ngOnDestroy(): void { if (this.roleSubscription) { @@ -65,13 +57,12 @@ export class HasRoleDirective implements OnInit, OnDestroy { } @Input() - set vitamuiCommonHasRole(data: { appId: string, tenantIdentifier: number, role: string }) { + set vitamuiCommonHasRole(data: { appId: string; tenantIdentifier: number; role: string }) { if (this.roleSubscription) { this.roleSubscription.unsubscribe(); } - this.roleSubscription = this.securityService.hasRole(data.appId, data.tenantIdentifier, data.role) - .subscribe((allowed) => { + this.roleSubscription = this.securityService.hasRole(data.appId, data.tenantIdentifier, data.role).subscribe((allowed) => { if (allowed && !this.viewEmbedded) { this.viewEmbedded = true; this.viewContainer.createEmbeddedView(this.templateRef); @@ -81,5 +72,4 @@ export class HasRoleDirective implements OnInit, OnDestroy { } }); } - } diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/archive-search.component.html b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/archive-search.component.html index 73be1a829..3c20c9cdd 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/archive-search.component.html +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/archive-search.component.html @@ -173,7 +173,11 @@ </div> <div class="col-1"> <vitamui-common-menu-button [overlayPos]="'end'" [icon]="'vitamui-icon-more-horiz'"> - <button mat-menu-item (click)="exportDIPService()" [disabled]="(itemSelected === 0 && hasDipExportRole) || !hasDipExportRole"> + <button + mat-menu-item + (click)="openExportDIPRequestCreateDialog()" + [disabled]="(itemSelected === 0 && hasDipExportRole) || !hasDipExportRole" + > {{ 'ARCHIVE_SEARCH.DIP.EXPORT_DIP' | translate }} </button> </vitamui-common-menu-button> 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 438a2c2cc..c0c1f636c 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 @@ -35,7 +35,7 @@ * knowledge of the CeCILL-C license and that you accept its terms. */ import { HttpErrorResponse } from '@angular/common/http'; -import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core'; +import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core'; import { FormGroup } from '@angular/forms'; import { MatDialog, MatDialogConfig } from '@angular/material/dialog'; import { MatSnackBar } from '@angular/material/snack-bar'; @@ -43,7 +43,7 @@ import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; import { merge, Subject, Subscription } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; -import { Direction, StartupService } from 'ui-frontend-common'; +import { Direction } from 'ui-frontend-common'; import { ArchiveSharedDataServiceService } from '../../core/archive-shared-data-service.service'; import { ArchiveService } from '../archive.service'; import { FilingHoldingSchemeNode } from '../models/node.interface'; @@ -60,8 +60,10 @@ import { } 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'; import { SearchCriteriaSaverComponent } from './search-criteria-saver/search-criteria-saver.component'; +const MAX_DIP_EXPORT_THRESHOLD = 10000; const BUTTON_MAX_TEXT = 40; const DESCRIPTION_MAX_TEXT = 60; const PAGE_SIZE = 10; @@ -72,13 +74,12 @@ const FILTER_DEBOUNCE_TIME_MS = 400; templateUrl: './archive-search.component.html', styleUrls: ['./archive-search.component.scss'], }) -export class ArchiveSearchComponent implements OnInit, OnChanges { +export class ArchiveSearchComponent implements OnInit, OnChanges, OnDestroy { constructor( private archiveService: ArchiveService, private translateService: TranslateService, private route: ActivatedRoute, private archiveExchangeDataService: ArchiveSharedDataServiceService, - private startupService: StartupService, public snackBar: MatSnackBar, public dialog: MatDialog ) { @@ -220,6 +221,7 @@ export class ArchiveSearchComponent implements OnInit, OnChanges { hasDipExportRole = false; hasEliminationActionRole = false; hasEliminationAnalysisRole = false; + openDialogSubscription: Subscription; selectedCategoryChange(selectedCategoryIndex: number) { this.additionalSearchCriteriaCategoryIndex = selectedCategoryIndex; @@ -860,6 +862,7 @@ export class ArchiveSearchComponent implements OnInit, OnChanges { this.subscriptionEntireNodes.unsubscribe(); this.subscriptionFilingHoldingSchemeNodes.unsubscribe(); this.subscriptionSimpleSearchCriteriaAdd.unsubscribe(); + this.openDialogSubscription.unsubscribe(); } exportArchiveUnitsToCsvFile() { @@ -954,32 +957,6 @@ export class ArchiveSearchComponent implements OnInit, OnChanges { } } - exportDIPService() { - this.listOfUACriteriaSearch = this.prepareUAIdList(this.criteriaSearchList, this.listOfUAIdToInclude, this.listOfUAIdToExclude); - const sortingCriteria = { criteria: this.orderBy, sorting: this.direction }; - const exportDIPSearchCriteria = { - criteriaList: this.listOfUACriteriaSearch, - pageNumber: this.currentPage, - size: PAGE_SIZE, - sortingCriteria, - language: this.translateService.currentLang, - }; - this.archiveService.exportDIP(exportDIPSearchCriteria, this.accessContract).subscribe((data) => { - console.log('response', JSON.parse(data)); - const guid = 'aeeaaaaaaggtywctaanl4al3rxsbxziaaaaq'; - const message = 'custom message for different workflows'; - const index = this.startupService.getReferentialUrl().lastIndexOf('/'); - const serviceUrl = - this.startupService.getReferentialUrl().substring(0, index) + - '/logbook-operation/tenant/' + - this.tenantIdentifier + - '?guid=' + - guid; - - this.openSnackBarForWorkflow(message, serviceUrl + ''); - }); - } - prepareUAIdList(criteriaSearchList: SearchCriteriaEltDto[], listOfUAIdToInclude: CriteriaValue[], listOfUAIdToExclude: CriteriaValue[]) { const listOfUACriteriaSearch = []; if (criteriaSearchList && criteriaSearchList.length > 0) { @@ -1049,4 +1026,41 @@ export class ArchiveSearchComponent implements OnInit, OnChanges { } }); } + + openExportDIPRequestCreateDialog() { + if (this.itemSelected > MAX_DIP_EXPORT_THRESHOLD) { + this.snackBar.openFromComponent(VitamUISnackBarComponent, { + panelClass: 'vitamui-snack-bar', + data: { type: 'exportDIPLimitReached' }, + duration: 10000, + }); + return; + } + + this.listOfUACriteriaSearch = this.prepareUAIdList(this.criteriaSearchList, this.listOfUAIdToInclude, this.listOfUAIdToExclude); + const sortingCriteria = { criteria: this.orderBy, sorting: this.direction }; + const exportDIPSearchCriteria = { + criteriaList: this.listOfUACriteriaSearch, + pageNumber: this.currentPage, + size: PAGE_SIZE, + sortingCriteria, + language: this.translateService.currentLang, + }; + + const dialogRef = this.dialog.open(DipRequestCreateComponent, { + panelClass: 'vitamui-modal', + disableClose: false, + data: { + itemSelected: this.itemSelected, + exportDIPSearchCriteria, + accessContract: this.accessContract, + tenantIdentifier: this.tenantIdentifier, + }, + }); + this.openDialogSubscription = dialogRef.afterClosed().subscribe((result) => { + if (result) { + return; + } + }); + } } diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/dip-request-create/dip-request-create.component.css b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/dip-request-create/dip-request-create.component.css new file mode 100644 index 000000000..9614aa2e6 --- /dev/null +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/dip-request-create/dip-request-create.component.css @@ -0,0 +1,15 @@ +.text-title { +font-family: Mulish; +font-style: normal; +font-weight: normal; +font-size: 16px; +line-height: 24px; + +display: flex; +align-items: center; + +color: #757575; +} +.text-center { + text-align: center; +} \ No newline at end of file diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/dip-request-create/dip-request-create.component.html b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/dip-request-create/dip-request-create.component.html new file mode 100644 index 000000000..6db0f60ee --- /dev/null +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/dip-request-create/dip-request-create.component.html @@ -0,0 +1,124 @@ +<br /> + +<form [formGroup]="exportDIPform" (ngSubmit)="onSubmit()"> + <div class="content vitamui-form"> + <div class="text-title">{{ 'ARCHIVE_SEARCH.DIP.REQUEST_DIP' | translate }}</div> + <div class="text large bold">{{ 'ARCHIVE_SEARCH.DIP.DIP_PARAMS' | translate }}</div> + <div class="text-title" *ngIf="itemSelected > 1">{{ itemSelected }} {{ 'ARCHIVE_SEARCH.DIP.ITEMS_SELECTED' | translate }}</div> + <div class="text-title" *ngIf="itemSelected === 1">{{ itemSelected }} {{ 'ARCHIVE_SEARCH.DIP.ONE_ITEM_SELECTED' | translate }}</div> + <br /> + + <vitamui-common-input + class="col-10 px-0" + formControlName="messageRequestIdentifier" + minlength="2" + maxlength="100" + required + placeholder="{{ 'ARCHIVE_SEARCH.DIP.REQUEST_ID' | translate }}" + > + <vitamui-common-input-error + *ngIf=" + exportDIPform?.get('messageRequestIdentifier')?.touched && exportDIPform?.get('messageRequestIdentifier')?.hasError('required') + " + >{{ 'ARCHIVE_SEARCH.DIP.REQUIRED' | translate }}</vitamui-common-input-error + > + </vitamui-common-input> + + <vitamui-common-input + class="col-10 px-0" + formControlName="requesterIdentifier" + minlength="2" + maxlength="100" + required + placeholder="{{ 'ARCHIVE_SEARCH.DIP.REQUESTER_ID' | translate }}" + > + <vitamui-common-input-error + *ngIf="exportDIPform?.get('requesterIdentifier')?.touched && exportDIPform?.get('requesterIdentifier')?.hasError('required')" + >{{ 'ARCHIVE_SEARCH.DIP.REQUIRED' | translate }}</vitamui-common-input-error + > + </vitamui-common-input> + + <vitamui-common-input + class="col-10 px-0" + formControlName="archivalAgencyIdentifier" + minlength="2" + maxlength="300" + required + placeholder="{{ 'ARCHIVE_SEARCH.DIP.ARCHIVAL_AGENCY' | translate }}" + > + <vitamui-common-input-error + *ngIf=" + exportDIPform?.get('archivalAgencyIdentifier')?.touched && exportDIPform?.get('archivalAgencyIdentifier')?.hasError('required') + " + >{{ 'ARCHIVE_SEARCH.DIP.REQUIRED' | translate }}</vitamui-common-input-error + > + </vitamui-common-input> + + <vitamui-common-input + class="col-10 px-0" + [required]="false" + formControlName="authorizationRequestReplyIdentifier" + maxlength="300" + placeholder="{{ 'ARCHIVE_SEARCH.DIP.AUTHORISATION_REQUEST_REPLY' | translate }}" + > + <vitamui-common-input-error + *ngIf=" + exportDIPform?.get('authorizationRequestReplyIdentifier')?.touched && + exportDIPform?.get('authorizationRequestReplyIdentifier')?.hasError('required') + " + >{{ 'ARCHIVE_SEARCH.DIP.REQUIRED' | translate }}</vitamui-common-input-error + > + </vitamui-common-input> + + <vitamui-common-input + class="col-10 px-0" + [required]="false" + formControlName="submissionAgencyIdentifier" + maxlength="100" + placeholder="{{ 'ARCHIVE_SEARCH.DIP.SUBMISSION_AGENCY_ID' | translate }}" + > + <vitamui-common-input-error + *ngIf=" + exportDIPform?.get('submissionAgencyIdentifier')?.touched && + exportDIPform?.get('submissionAgencyIdentifier')?.hasError('required') + " + >{{ 'ARCHIVE_SEARCH.DIP.REQUIRED' | translate }}</vitamui-common-input-error + > + </vitamui-common-input> + + <vitamui-common-input + class="col-10 px-0" + [required]="false" + formControlName="comment" + maxlength="300" + placeholder="{{ 'ARCHIVE_SEARCH.DIP.COMMENT' | translate }}" + > + <vitamui-common-input-error *ngIf="exportDIPform?.get('comment')?.touched && exportDIPform?.get('comment')?.hasError('required')">{{ + 'ARCHIVE_SEARCH.DIP.REQUIRED' | translate + }}</vitamui-common-input-error> + </vitamui-common-input> + + <div class="row"> + <label for="lifeCycleLogs" class="col-3 text-center"> {{ 'ARCHIVE_SEARCH.DIP.LOGS' | translate }} </label> + <mat-button-toggle-group + formControlName="lifeCycleLogs" + class="col-8" + #group="matButtonToggleGroup" + class="vitamui-button-toggle-group" + > + <mat-button-toggle value="Inclure"> {{ 'ARCHIVE_SEARCH.DIP.INCLUDE' | translate }}</mat-button-toggle> + <mat-button-toggle value="Exclure">{{ 'ARCHIVE_SEARCH.DIP.EXCLUDE' | translate }} </mat-button-toggle> + </mat-button-toggle-group> + </div> + <br /> + + <div class="d-flex mt-4"> + <button type="submit" class="btn primary mr-4" [disabled]="exportDIPform.invalid"> + {{ 'ARCHIVE_SEARCH.DIP.EXPORT_DIP' | translate }} + </button> + <button type="button" class="btn link cancel" (click)="onCancel()"> + {{ 'ARCHIVE_SEARCH.DIP.CANCEL' | translate }} + </button> + </div> + </div> +</form> diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/dip-request-create/dip-request-create.component.spec.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/dip-request-create/dip-request-create.component.spec.ts new file mode 100644 index 000000000..35fbb1b32 --- /dev/null +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/dip-request-create/dip-request-create.component.spec.ts @@ -0,0 +1,77 @@ +/* + * 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 { ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormBuilder } from '@angular/forms'; +import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { DipRequestCreateComponent } from './dip-request-create.component'; + +describe('DipRequestCreateComponent', () => { + let component: DipRequestCreateComponent; + let fixture: ComponentFixture<DipRequestCreateComponent>; + + const matDialogRefSpy = jasmine.createSpyObj('MatDialogRef', ['close']); + const matDialogSpy = jasmine.createSpyObj('MatDialog', ['open']); + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [DipRequestCreateComponent], + providers: [ + FormBuilder, + { provide: MatDialogRef, useValue: matDialogRefSpy }, + { provide: MatDialog, useValue: matDialogSpy }, + { provide: MAT_DIALOG_DATA, useValue: {} }, + ], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(DipRequestCreateComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + it('items Selected should be grather than 0 ', () => { + expect(component.itemSelected).toBeGreaterThan(0); + }); + it('Should have an accessContract ', () => { + expect(component.data.accessContract).not.toBeNull(); + }); +}); diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/dip-request-create/dip-request-create.component.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/dip-request-create/dip-request-create.component.ts new file mode 100644 index 000000000..c791cecc8 --- /dev/null +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive-search/dip-request-create/dip-request-create.component.ts @@ -0,0 +1,135 @@ +/* + * 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 { Component, Inject, OnDestroy, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { TranslateService } from '@ngx-translate/core'; +import { Subscription } from 'rxjs'; +import { ConfirmDialogService, Logger, StartupService } from 'ui-frontend-common'; +import * as uuid from 'uuid'; +import { ArchiveService } from '../../archive.service'; +import { ExportDIPCriteriaList, ExportDIPRequestDetail } from '../../models/dip-request-detail.interface'; +import { SearchCriteriaEltDto } from '../../models/search.criteria'; + +@Component({ + selector: 'app-dip-request-create', + templateUrl: './dip-request-create.component.html', + styleUrls: ['./dip-request-create.component.css'], +}) +export class DipRequestCreateComponent implements OnInit, OnDestroy { + constructor( + private translate: TranslateService, + public dialogRef: MatDialogRef<DipRequestCreateComponent>, + private formBuilder: FormBuilder, + private archiveService: ArchiveService, + private startupService: StartupService, + private confirmDialogService: ConfirmDialogService, + private logger: Logger, + @Inject(MAT_DIALOG_DATA) + public data: { itemSelected: number; exportDIPSearchCriteria: SearchCriteriaEltDto[]; accessContract: string; tenantIdentifier: string } + ) {} + exportDIPform: FormGroup; + exportDIPIncludeform: FormGroup; + itemSelected: number; + keyPressSubscription: Subscription; + dataObjectVersions = ['BinaryMaster', 'Dissemination', 'Thumbnail', 'TextContent', 'PhysicalMaster']; + + ngOnInit(): void { + this.itemSelected = this.data.itemSelected; + this.initExportForm(); + this.keyPressSubscription = this.confirmDialogService.listenToEscapeKeyPress(this.dialogRef).subscribe(() => this.onCancel()); + } + + ngOnDestroy() { + this.keyPressSubscription.unsubscribe(); + } + + onCancel() { + if (this.exportDIPform.dirty) { + this.confirmDialogService.confirmBeforeClosing(this.dialogRef); + } else { + this.dialogRef.close(); + } + } + + private initExportForm() { + const messageRequestIdentifier = uuid.v4(); + this.exportDIPform = this.formBuilder.group({ + lifeCycleLogs: [this.translate.instant('ARCHIVE_SEARCH.DIP.INCLUDE')], + messageRequestIdentifier: [{ value: messageRequestIdentifier, disabled: true }, Validators.required], + requesterIdentifier: [null, Validators.required], + archivalAgencyIdentifier: [null, Validators.required], + authorizationRequestReplyIdentifier: [null], + submissionAgencyIdentifier: [null], + comment: [null], + archivalAgreement: [this.data.accessContract], + }); + } + + onSubmit() { + if (this.exportDIPform.invalid) { + return; + } + + const exportDIPformDetail: ExportDIPRequestDetail = this.exportDIPform.getRawValue(); + const exportDIPCriteriaList: ExportDIPCriteriaList = { + dipRequestParameters: exportDIPformDetail, + exportDIPSearchCriteria: this.data.exportDIPSearchCriteria, + dataObjectVersions: this.dataObjectVersions, + lifeCycleLogs: this.exportDIPform.get('lifeCycleLogs').value === this.translate.instant('ARCHIVE_SEARCH.DIP.INCLUDE'), + }; + + this.archiveService.exportDIPService(exportDIPCriteriaList, this.data.accessContract).subscribe( + (response) => { + this.dialogRef.close(true); + const index = this.startupService.getReferentialUrl().lastIndexOf('/'); + const serviceUrl = + this.startupService.getReferentialUrl().substring(0, index) + + '/logbook-operation/tenant/' + + this.data.tenantIdentifier + + '?guid=' + + response; + + this.archiveService.openSnackBarForWorkflow(this.translate.instant('ARCHIVE_SEARCH.DIP.REQUEST_MESSAGE'), serviceUrl); + }, + (error: any) => { + this.logger.error('Error message :', error); + } + ); + } +} 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 6ccf43016..050221407 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 @@ -74,6 +74,7 @@ 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: [ @@ -124,6 +125,7 @@ import { SharedModule } from './shared/shared.module'; AppraisalRuleSearchComponent, SimpleCriteriaSearchComponent, TitleAndDescriptionCriteriaSearchComponent, + DipRequestCreateComponent, ], schemas: [CUSTOM_ELEMENTS_SCHEMA], }) diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/archive.service.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/archive.service.ts index 6c41603c4..bf2ff649f 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/archive.service.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/archive.service.ts @@ -41,6 +41,7 @@ import { Observable, of, throwError, TimeoutError } from 'rxjs'; import { catchError, map, tap } from 'rxjs/operators'; import { SearchService, SecurityService } from 'ui-frontend-common'; import { ArchiveApiService } from '../core/api/archive-api.service'; +import { ExportDIPCriteriaList } from './models/dip-request-detail.interface'; import { FilingHoldingSchemeNode } from './models/node.interface'; import { SearchResponse } from './models/search-response.interface'; import { PagedResult, ResultFacet, SearchCriteriaDto } from './models/search.criteria'; @@ -215,15 +216,27 @@ export class ArchiveService extends SearchService<any> { return this.archiveApiService.getObjectById(id, headers); } - exportDIP(criteriaDto: SearchCriteriaDto, accessContract: string) { + hasArchiveSearcheRole(role: string, tenantIdentifier: number): Observable<boolean> { + const applicationIdentifier = 'ARCHIVE_SEARCH_MANAGEMENT_APP'; + return this.securityService.hasRole(applicationIdentifier, tenantIdentifier, role); + } + + exportDIPService(exportDIPCriteriaList: ExportDIPCriteriaList, accessContract: string): Observable<string> { let headers = new HttpHeaders().append('Content-Type', 'application/json'); headers = headers.append('X-Access-Contract-Id', accessContract); - return this.archiveApiService.exportDIP(criteriaDto, headers); + return this.archiveApiService.exportDipApiService(exportDIPCriteriaList, headers); } - hasArchiveSearcheRole(role: string, tenantIdentifier: number): Observable<boolean> { - const applicationIdentifier = 'ARCHIVE_SEARCH_MANAGEMENT_APP'; - return this.securityService.hasRole(applicationIdentifier, tenantIdentifier, role); + openSnackBarForWorkflow(message: string, serviceUrl?: string) { + this.snackBar.openFromComponent(VitamUISnackBarComponent, { + panelClass: 'vitamui-snack-bar', + data: { + type: 'WorkflowSuccessSnackBar', + message, + serviceUrl, + }, + duration: 100000, + }); } } diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/models/dip-request-detail.interface.ts b/ui/ui-frontend/projects/archive-search/src/app/archive/models/dip-request-detail.interface.ts new file mode 100644 index 000000000..de3d0246a --- /dev/null +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/models/dip-request-detail.interface.ts @@ -0,0 +1,54 @@ +/* + * 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 { SearchCriteriaEltDto } from './search.criteria'; + +export interface ExportDIPRequestDetail { + messageRequestIdentifier: string; + requesterIdentifier: string; + archivalAgencyIdentifier: string; + authorizationRequestReplyIdentifier: string; + submissionAgencyIdentifier: string; + comment: string; +} + +export interface ExportDIPCriteriaList { + dipRequestParameters: ExportDIPRequestDetail; + exportDIPSearchCriteria: SearchCriteriaEltDto[]; + dataObjectVersions: string[]; + lifeCycleLogs: boolean; +} diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/shared/vitamui-snack-bar/vitamui-snack-bar.component.html b/ui/ui-frontend/projects/archive-search/src/app/archive/shared/vitamui-snack-bar/vitamui-snack-bar.component.html index 089920707..97ac3ba92 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/shared/vitamui-snack-bar/vitamui-snack-bar.component.html +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/shared/vitamui-snack-bar/vitamui-snack-bar.component.html @@ -18,11 +18,14 @@ {{ 'ARCHIVE_SEARCH.SEARCH_CRITERIA_SAVER.DELETED_WITH_SUCCESS_2' | translate }} </ng-container> <ng-container *ngSwitchCase="'WorkflowSuccessSnackBar'"> - {{ data?.message }} + <span class="space-style">{{ data?.message }}</span> <button type="button" class="btn white" (click)="goToLogbook(data?.serviceUrl)"> - VOIR LE JOURNAL DES OPÉRATIONS + {{ 'ARCHIVE_SEARCH.DIP.TO_OPERATION_APP' | translate }} </button> </ng-container> + <ng-container *ngSwitchCase="'exportDIPLimitReached'"> + {{ 'ARCHIVE_SEARCH.DIP.EXPORT_LIMITS' | translate }} + </ng-container> </span> <button class="close-btn" (click)="close()"><i class="material-icons">clear</i></button> diff --git a/ui/ui-frontend/projects/archive-search/src/app/archive/shared/vitamui-snack-bar/vitamui-snack-bar.component.scss b/ui/ui-frontend/projects/archive-search/src/app/archive/shared/vitamui-snack-bar/vitamui-snack-bar.component.scss index 271075ea5..34207cea0 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/archive/shared/vitamui-snack-bar/vitamui-snack-bar.component.scss +++ b/ui/ui-frontend/projects/archive-search/src/app/archive/shared/vitamui-snack-bar/vitamui-snack-bar.component.scss @@ -1,13 +1,16 @@ :host { - display: flex; - align-items: center; - justify-content: space-between; - height: 100%; - width: 100%; + display: flex; + align-items: center; + justify-content: space-between; + height: 100%; + width: 100%; } .btn-link { - color: white; - font-weight: bold; - margin-left: 10px; + color: white; + font-weight: bold; + margin-left: 10px; +} +.space-style { + margin-right: 30px; } diff --git a/ui/ui-frontend/projects/archive-search/src/app/core/api/archive-api.service.ts b/ui/ui-frontend/projects/archive-search/src/app/core/api/archive-api.service.ts index 6ad90c7ee..451379cdc 100644 --- a/ui/ui-frontend/projects/archive-search/src/app/core/api/archive-api.service.ts +++ b/ui/ui-frontend/projects/archive-search/src/app/core/api/archive-api.service.ts @@ -39,6 +39,7 @@ import { Inject, Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { tap } from 'rxjs/operators'; import { BaseHttpClient, BASE_URL, PageRequest, PaginatedResponse } from 'ui-frontend-common'; +import { ExportDIPCriteriaList } from '../../archive/models/dip-request-detail.interface'; import { SearchCriteriaHistory } from '../../archive/models/search-criteria-history.interface'; import { SearchResponse } from '../../archive/models/search-response.interface'; import { SearchCriteriaDto } from '../../archive/models/search.criteria'; @@ -111,8 +112,8 @@ export class ArchiveApiService extends BaseHttpClient<any> { return this.http.get(`${this.apiUrl}/object/${id}`, { headers, responseType: 'text' }); } - exportDIP(criteriaDto: SearchCriteriaDto, headers?: HttpHeaders): Observable<any> { - return this.http.post(`${this.apiUrl}/export-dip`, criteriaDto, { + exportDipApiService(exportDIPCriteriaList: ExportDIPCriteriaList, headers?: HttpHeaders): Observable<string> { + return this.http.post(`${this.apiUrl}/export-dip`, exportDIPCriteriaList, { responseType: 'text', headers, }); 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 a9d8c1972..f7c279844 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,9 +1,28 @@ { "ARCHIVE_SEARCH": { - "DIP" : { + "DIP" : { "EXPORT_DIP" : "Export a DIP", "SELECTED" :"Selected", - "ONE_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", + "EXPORT_LIMITS": "DIP export cannot be performed. Please restrict your selection to a maximum of 10,000 archival units" }, "ACCESS_CONTRACT_NOT_FOUND": "No contract associated with current user", "SHOW_TREES_PLANS": "Show trees and plans", 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 f3cd5cea4..896c878f5 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,9 +1,28 @@ { "ARCHIVE_SEARCH": { - "DIP" : { + "DIP" : { "EXPORT_DIP" : "Exporter un DIP", "SELECTED" :"Sélectionnés", - "ONE_SELECTED" :"Sélectionné" + "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." }, "ACCESS_CONTRACT_NOT_FOUND": "Aucun contrat d'accès n'est associé à l'utiisateur", -- GitLab