diff --git a/src/main/java/fr/inra/oresing/rest/OreSiResources.java b/src/main/java/fr/inra/oresing/rest/OreSiResources.java index ecac70390a96d1726ae276e323f03656b1595389..6d2c184763f11a6ac2e6e6642fad00601e2e098a 100644 --- a/src/main/java/fr/inra/oresing/rest/OreSiResources.java +++ b/src/main/java/fr/inra/oresing/rest/OreSiResources.java @@ -181,6 +181,8 @@ public class OreSiResources { @PathVariable("refType") String refType, @RequestParam MultiValueMap<String, String> params) { List<ReferenceValue> list = service.findReference(nameOrId, refType, params); + + ImmutableSet<GetReferenceResult.ReferenceValue> referenceValues = list.stream() .map(referenceValue -> new GetReferenceResult.ReferenceValue( @@ -193,6 +195,15 @@ public class OreSiResources { return ResponseEntity.ok(new GetReferenceResult(referenceValues)); } + @GetMapping(value = "/applications/{nameOrId}/references/{refType}/csv", produces = MediaType.TEXT_PLAIN_VALUE) + public ResponseEntity<String> listReferencesCsv( + @PathVariable("nameOrId") String nameOrId, + @PathVariable("refType") String refType, + @RequestParam MultiValueMap<String, String> params) { + String csv = service.getReferenceValuesCsv(nameOrId, refType, params); + return ResponseEntity.ok(csv); + } + @GetMapping(value = "/applications/{nameOrId}/references/{refType}/{column}", produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<List<String>> listReferences(@PathVariable("nameOrId") String nameOrId, @PathVariable("refType") String refType, @PathVariable("column") String column) { Application application = service.getApplication(nameOrId); diff --git a/src/main/java/fr/inra/oresing/rest/OreSiService.java b/src/main/java/fr/inra/oresing/rest/OreSiService.java index 65e632538fd492d61e1971622b2ba2b69e27981f..7f06aa49dd565c47b5d991b3cb9b718e1390023d 100644 --- a/src/main/java/fr/inra/oresing/rest/OreSiService.java +++ b/src/main/java/fr/inra/oresing/rest/OreSiService.java @@ -919,6 +919,34 @@ public class OreSiService { return list; } + public String getReferenceValuesCsv(String applicationNameOrId, String referenceType, MultiValueMap<String, String> params) { + Configuration.ReferenceDescription referenceDescription = getApplication(applicationNameOrId) + .getConfiguration() + .getReferences() + .get(referenceType); + ImmutableMap<String, Function<ReferenceValue, String>> model = referenceDescription.getColumns().keySet().stream() + .collect(ImmutableMap.toImmutableMap(Function.identity(), column -> referenceValue -> referenceValue.getRefValues().get(column))); + CSVFormat csvFormat = CSVFormat.DEFAULT + .withDelimiter(referenceDescription.getSeparator()) + .withSkipHeaderRecord(); + StringWriter out = new StringWriter(); + try { + CSVPrinter csvPrinter = new CSVPrinter(out, csvFormat); + csvPrinter.printRecord(model.keySet()); + List<ReferenceValue> list = repo.getRepository(applicationNameOrId).referenceValue().findAllByReferenceType(referenceType, params); + for (ReferenceValue referenceValue : list) { + ImmutableList<String> rowAsRecord = model.values().stream() + .map(getCellContentFn -> getCellContentFn.apply(referenceValue)) + .collect(ImmutableList.toImmutableList()); + csvPrinter.printRecord(rowAsRecord); + } + } catch (IOException e) { + throw new OreSiTechnicalException("erreur lors de la génération du fichier CSV", e); + } + String csv = out.toString(); + return csv; + } + public Optional<BinaryFile> getFile(String name, UUID id) { authenticationService.setRoleForClient(); Optional<BinaryFile> optionalBinaryFile = repo.getRepository(name).binaryFile().tryFindById(id); diff --git a/src/test/java/fr/inra/oresing/rest/OreSiResourcesTest.java b/src/test/java/fr/inra/oresing/rest/OreSiResourcesTest.java index b03a2350ea5ce6d4dc393d4eefb43b8eed38df43..a0896039f5ac849464cda6737d2887e0cb81d769 100644 --- a/src/test/java/fr/inra/oresing/rest/OreSiResourcesTest.java +++ b/src/test/java/fr/inra/oresing/rest/OreSiResourcesTest.java @@ -415,6 +415,14 @@ public class OreSiResourcesTest { refs = objectMapper.readValue(getReferenceResponse, GetReferenceResult.class); Assert.assertEquals(103, refs.getReferenceValues().size()); + String getReferenceCsvResponse = mockMvc.perform(get("/api/v1/applications/acbb/references/parcelles/csv") + .cookie(authCookie) + .accept(MediaType.TEXT_PLAIN)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + + Assert.assertEquals(31, StringUtils.countMatches(getReferenceCsvResponse, "theix")); + // ajout de data try (InputStream in = getClass().getResourceAsStream(fixtures.getFluxToursDataResourceName())) { MockMultipartFile file = new MockMultipartFile("file", "Flux_tours.csv", "text/plain", in); diff --git a/ui2/src/services/rest/ReferenceService.js b/ui2/src/services/rest/ReferenceService.js index 36c03c4469ebf9e489a4ef49f6c4d493c98575d1..c3211dbe3414b48d0f1932f6dd9d5f612ace7688 100644 --- a/ui2/src/services/rest/ReferenceService.js +++ b/ui2/src/services/rest/ReferenceService.js @@ -11,6 +11,10 @@ export class ReferenceService extends Fetcher { return this.get(`applications/${applicationName}/references/${referenceId}`); } + async getReferenceCsv(applicationName, referenceId) { + return this.downloadFile(`applications/${applicationName}/references/${referenceId}/csv`); + } + async createReference(applicationName, referenceId, refFile) { return this.post(`applications/${applicationName}/references/${referenceId}`, { file: refFile, diff --git a/ui2/src/views/references/ReferencesManagementView.vue b/ui2/src/views/references/ReferencesManagementView.vue index 295a39a5fa032b429389ca06d9e7e0e4948d6593..5ca7120131aa64447dcfc396ae9c9ca6cf7cdcbb 100644 --- a/ui2/src/views/references/ReferencesManagementView.vue +++ b/ui2/src/views/references/ReferencesManagementView.vue @@ -61,7 +61,9 @@ export default class ReferencesManagementView extends Vue { (label) => this.consultReference(label), "is-primary" ), - new Button(this.$t("referencesManagement.download"), "download"), + new Button(this.$t("referencesManagement.download"), "download", (label) => + this.downloadReference(label) + ), ]; created() { @@ -90,18 +92,25 @@ export default class ReferencesManagementView extends Vue { openRefDetails(event, label) { event.stopPropagation(); this.openPanel = this.chosenRef && this.chosenRef.label === label ? !this.openPanel : true; - this.chosenRef = Object.values(this.application.references).find((ref) => ref.label === label); + this.chosenRef = this.findReferenceByLabel(label); } consultReference(label) { - const ref = Object.values(this.application.references).find((ref) => ref.label === label); + const ref = this.findReferenceByLabel(label); if (ref) { this.$router.push(`/applications/${this.applicationName}/references/${ref.id}`); } } + downloadReference(label) { + const reference = this.findReferenceByLabel(label); + if (reference) { + this.referenceService.getReferenceCsv(this.applicationName, reference.id); + } + } + async uploadReferenceCsv(label, refFile) { - const reference = Object.values(this.application.references).find((ref) => ref.label === label); + const reference = this.findReferenceByLabel(label); try { await this.referenceService.createReference(this.applicationName, reference.id, refFile); this.alertService.toastSuccess(this.$t("alert.reference-updated")); @@ -109,5 +118,9 @@ export default class ReferencesManagementView extends Vue { this.alertService.toastError(this.$t("alert.reference-csv-upload-error"), error); } } + + findReferenceByLabel(label) { + return Object.values(this.application.references).find((ref) => ref.label === label); + } } </script>