From 41a5ed9cbf348f4fe6d14deb997710cd75a87737 Mon Sep 17 00:00:00 2001 From: Katherine Thiessen Date: Tue, 31 Jan 2023 11:01:23 -0600 Subject: [PATCH 1/3] updating sample modified date when metadata is deleted --- .../web/samples/SamplesAjaxController.java | 58 +++----- .../ria/web/services/UISampleService.java | 135 +++++++++--------- .../resources/js/apis/samples/samples.ts | 4 +- .../samples/components/SampleMetadata.tsx | 3 +- 4 files changed, 93 insertions(+), 107 deletions(-) diff --git a/src/main/java/ca/corefacility/bioinformatics/irida/ria/web/samples/SamplesAjaxController.java b/src/main/java/ca/corefacility/bioinformatics/irida/ria/web/samples/SamplesAjaxController.java index 5bc98e39c70..e3b4aaa90d5 100644 --- a/src/main/java/ca/corefacility/bioinformatics/irida/ria/web/samples/SamplesAjaxController.java +++ b/src/main/java/ca/corefacility/bioinformatics/irida/ria/web/samples/SamplesAjaxController.java @@ -2,18 +2,14 @@ import java.io.IOException; import java.security.Principal; -import java.util.*; +import java.util.List; +import java.util.Locale; +import java.util.Set; import javax.servlet.http.HttpServletResponse; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; -import ca.corefacility.bioinformatics.irida.exceptions.ConcatenateException; -import ca.corefacility.bioinformatics.irida.exceptions.EntityExistsException; -import ca.corefacility.bioinformatics.irida.exceptions.EntityNotFoundException; -import ca.corefacility.bioinformatics.irida.model.sequenceFile.SequencingObject; -import ca.corefacility.bioinformatics.irida.ria.web.samples.dto.*; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -22,16 +18,17 @@ import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; +import ca.corefacility.bioinformatics.irida.exceptions.ConcatenateException; +import ca.corefacility.bioinformatics.irida.exceptions.EntityExistsException; +import ca.corefacility.bioinformatics.irida.exceptions.EntityNotFoundException; import ca.corefacility.bioinformatics.irida.model.sample.Sample; import ca.corefacility.bioinformatics.irida.model.sequenceFile.SequenceFile; - +import ca.corefacility.bioinformatics.irida.model.sequenceFile.SequencingObject; import ca.corefacility.bioinformatics.irida.ria.web.ajax.dto.ajax.AjaxErrorResponse; import ca.corefacility.bioinformatics.irida.ria.web.ajax.dto.ajax.AjaxResponse; import ca.corefacility.bioinformatics.irida.ria.web.ajax.dto.ajax.AjaxSuccessResponse; +import ca.corefacility.bioinformatics.irida.ria.web.samples.dto.*; import ca.corefacility.bioinformatics.irida.ria.web.services.UIAnalysesService; - -import ca.corefacility.bioinformatics.irida.ria.web.samples.dto.SampleDetails; - import ca.corefacility.bioinformatics.irida.ria.web.services.UISampleService; /** @@ -62,8 +59,7 @@ public ResponseEntity> uploadSequenceFiles try { return ResponseEntity.ok(uiSampleService.uploadSequenceFiles(sampleId, request)); } catch (IOException e) { - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) - .body(null); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); } } @@ -80,8 +76,7 @@ public ResponseEntity> uploadFast5Files(@P try { return ResponseEntity.ok(uiSampleService.uploadFast5Files(sampleId, request)); } catch (IOException e) { - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) - .body(null); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); } } @@ -98,8 +93,7 @@ public ResponseEntity> uploadAssemblies(@Pat try { return ResponseEntity.ok(uiSampleService.uploadAssemblies(sampleId, request)); } catch (IOException e) { - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) - .body(null); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); } } @@ -145,8 +139,7 @@ public ResponseEntity updateSampleDetails(@PathVariable Long id, for (ConstraintViolation a : e.getConstraintViolations()) { constraintViolations += a.getMessage() + "\n"; } - return ResponseEntity.status(HttpStatus.BAD_REQUEST) - .body(new AjaxErrorResponse(constraintViolations)); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new AjaxErrorResponse(constraintViolations)); } } @@ -165,17 +158,16 @@ public ResponseEntity updateDefaultSequencingObjectForSample(@Path return ResponseEntity.ok(new AjaxSuccessResponse( uiSampleService.updateDefaultSequencingObjectForSample(id, sequencingObjectId, locale))); } catch (EntityNotFoundException e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST) - .body(new AjaxErrorResponse(e.getMessage())); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new AjaxErrorResponse(e.getMessage())); } } /** * Update the default genome assembly for the sample * - * @param id {@link Long} identifier for the sample + * @param id {@link Long} identifier for the sample * @param genomeAssemblyId The genome assembly identifier - * @param locale {@link Locale} for the currently logged in user + * @param locale {@link Locale} for the currently logged in user * @return {@link ResponseEntity} explaining to the user the results of the update. */ @PutMapping(value = "/{id}/default-genome-assembly") @@ -185,8 +177,7 @@ public ResponseEntity updateDefaultGenomeAssemblyForSample(@PathVa return ResponseEntity.ok(new AjaxSuccessResponse( uiSampleService.updateDefaultGenomeAssemblyForSample(id, genomeAssemblyId, locale))); } catch (EntityNotFoundException e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST) - .body(new AjaxErrorResponse(e.getMessage())); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new AjaxErrorResponse(e.getMessage())); } } @@ -204,8 +195,7 @@ public ResponseEntity> getSampleAnalyses(@PathVariable Long try { return ResponseEntity.ok(uiAnalysesService.getSampleAnalyses(sampleId, principal, locale)); } catch (Exception e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST) - .body(null); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null); } } @@ -227,16 +217,17 @@ public ResponseEntity addSampleMetadata(@PathVariable * Remove metadata field and entry from {@link Sample} * * @param projectId The project identifier - * @param metadataFieldId The metadata field id + * @param sampleId The sample identifier + * @param metadataFieldId The metadata field id * @param metadataEntryId The metadata entry identifier * @param locale {@link Locale} for the currently logged in user * @return {@link ResponseEntity} explaining to the user the results of the deletion. */ @DeleteMapping(value = "/metadata") - public ResponseEntity removeSampleMetadata(@RequestParam Long projectId, + public ResponseEntity removeSampleMetadata(@RequestParam Long projectId, @RequestParam Long sampleId, @RequestParam Long metadataFieldId, @RequestParam Long metadataEntryId, Locale locale) { return ResponseEntity.ok(new AjaxSuccessResponse( - uiSampleService.removeSampleMetadata(projectId, metadataFieldId, metadataEntryId, locale))); + uiSampleService.removeSampleMetadata(projectId, sampleId, metadataFieldId, metadataEntryId, locale))); } /** @@ -254,8 +245,7 @@ public ResponseEntity updateSampleMetadata(@PathVariable Long id, return ResponseEntity.ok(new AjaxSuccessResponse( uiSampleService.updateSampleMetadata(id, updateSampleMetadataRequest, locale))); } catch (EntityExistsException e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST) - .body(new AjaxErrorResponse(e.getMessage())); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new AjaxErrorResponse(e.getMessage())); } } @@ -273,7 +263,6 @@ public ResponseEntity getFilesForSample(@PathVariable Long id, } /** - * Get updated sample sequencing objects for given sequencing object ids * * @param id Identifier for a sample @@ -341,8 +330,7 @@ public ResponseEntity> concatenateSequence return ResponseEntity.ok(uiSampleService.concatenateSequenceFiles(sampleId, sequenceObjectIds, newFileName, removeOriginals)); } catch (ConcatenateException e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST) - .body(null); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null); } } diff --git a/src/main/java/ca/corefacility/bioinformatics/irida/ria/web/services/UISampleService.java b/src/main/java/ca/corefacility/bioinformatics/irida/ria/web/services/UISampleService.java index dac2668bab1..c19feeacc3c 100644 --- a/src/main/java/ca/corefacility/bioinformatics/irida/ria/web/services/UISampleService.java +++ b/src/main/java/ca/corefacility/bioinformatics/irida/ria/web/services/UISampleService.java @@ -300,20 +300,20 @@ public String updateDefaultGenomeAssemblyForSample(Long sampleId, Long genomeAss public AddSampleMetadataResponse addSampleMetadata(Long sampleId, AddSampleMetadataRequest addSampleMetadataRequest, Locale locale) { Sample sample = sampleService.read(sampleId); - ProjectMetadataRole metadataRole = ProjectMetadataRole - .fromString(addSampleMetadataRequest.getMetadataRestriction()); + ProjectMetadataRole metadataRole = ProjectMetadataRole.fromString( + addSampleMetadataRequest.getMetadataRestriction()); Project project = projectService.read(addSampleMetadataRequest.getProjectId()); - MetadataTemplateField existingTemplateField = metadataTemplateService - .readMetadataFieldByLabel(addSampleMetadataRequest.getMetadataField()); + MetadataTemplateField existingTemplateField = metadataTemplateService.readMetadataFieldByLabel( + addSampleMetadataRequest.getMetadataField()); MetadataTemplateField templateField; if (existingTemplateField != null) { templateField = existingTemplateField; } else { - templateField = metadataTemplateService - .saveMetadataField(new MetadataTemplateField(addSampleMetadataRequest.getMetadataField(), "text")); + templateField = metadataTemplateService.saveMetadataField( + new MetadataTemplateField(addSampleMetadataRequest.getMetadataField(), "text")); } MetadataRestriction metadataRestriction = null; @@ -347,15 +347,12 @@ public AddSampleMetadataResponse addSampleMetadata(Long sampleId, AddSampleMetad metadataRole); metadataRestrictionRepository.save(metadataRestriction); } - String metadataRestrictionString = messageSource - .getMessage("metadataRole." + metadataRestriction.getLevel(), new Object[] {}, locale); - - message = messageSource.getMessage("server.sample.metadata.add.success", - new Object[] { - addSampleMetadataRequest.getMetadataField(), - addSampleMetadataRequest.getMetadataEntry(), - metadataRestrictionString }, - locale); + String metadataRestrictionString = messageSource.getMessage( + "metadataRole." + metadataRestriction.getLevel(), new Object[] {}, locale); + + message = messageSource.getMessage("server.sample.metadata.add.success", new Object[] { + addSampleMetadataRequest.getMetadataField(), addSampleMetadataRequest.getMetadataEntry(), + metadataRestrictionString }, locale); } return new AddSampleMetadataResponse(metadataTemplateField.getId(), metadataTemplateField.getLabel(), @@ -367,12 +364,15 @@ public AddSampleMetadataResponse addSampleMetadata(Long sampleId, AddSampleMetad * Remove metadata from the sample * * @param projectId The project id + * @param sampleId The sample id * @param metadataFieldId The metadata field id * @param metadataEntryId The metadata entry id * @param locale {@link Locale} for the currently logged in user * @return message indicating deletion status */ - public String removeSampleMetadata(Long projectId, Long metadataFieldId, Long metadataEntryId, Locale locale) { + public String removeSampleMetadata(Long projectId, Long sampleId, Long metadataFieldId, Long metadataEntryId, + Locale locale) { + Sample sample = sampleService.read(sampleId); Project project = projectService.read(projectId); List sampleList = sampleService.getSamplesForProject(project) .stream() @@ -389,13 +389,16 @@ public String removeSampleMetadata(Long projectId, Long metadataFieldId, Long me where the field is in use within the project */ if (fieldUsageCount == 1) { - MetadataRestriction restrictionToDelete = metadataTemplateService - .getMetadataRestrictionForFieldAndProject(project, metadataTemplateField); + MetadataRestriction restrictionToDelete = metadataTemplateService.getMetadataRestrictionForFieldAndProject( + project, metadataTemplateField); if (restrictionToDelete != null) { metadataRestrictionRepository.delete(restrictionToDelete); } } + sample.setModifiedDate(new Date()); + sampleService.update(sample); + return messageSource.getMessage("server.sample.metadata.remove.success", new Object[] { metadataTemplateField.getLabel() }, locale); } @@ -415,19 +418,19 @@ public String updateSampleMetadata(Long sampleId, UpdateSampleMetadataRequest up boolean sampleUpdated = false; MetadataTemplateField metadataTemplateField = null; // Existing field with the updated field label - MetadataTemplateField existingField = metadataTemplateService - .readMetadataFieldByLabel(updateSampleMetadataRequest.getMetadataField()); + MetadataTemplateField existingField = metadataTemplateService.readMetadataFieldByLabel( + updateSampleMetadataRequest.getMetadataField()); // Get the existing entry if it exists - MetadataTemplateField existingFieldById = metadataTemplateService - .readMetadataField(updateSampleMetadataRequest.getMetadataFieldId()); + MetadataTemplateField existingFieldById = metadataTemplateService.readMetadataField( + updateSampleMetadataRequest.getMetadataFieldId()); MetadataEntry existingEntry = metadataEntryRepository.getMetadataEntryBySampleAndField(existingFieldById, sample); Set metadataEntrySet = new HashSet<>(); - ProjectMetadataRole projectMetadataRole = ProjectMetadataRole - .fromString(updateSampleMetadataRequest.getMetadataRestriction()); + ProjectMetadataRole projectMetadataRole = ProjectMetadataRole.fromString( + updateSampleMetadataRequest.getMetadataRestriction()); if (existingField != null) { metadataTemplateField = existingField; @@ -494,8 +497,8 @@ get the existing entry of the previous metadata field label (for the sample) Get the metadata restriction for the field and update if there is no previous restriction on the field or a user modifies the restriction for the field */ - MetadataRestriction currentRestriction = metadataTemplateService - .getMetadataRestrictionForFieldAndProject(project, metadataTemplateField); + MetadataRestriction currentRestriction = metadataTemplateService.getMetadataRestrictionForFieldAndProject( + project, metadataTemplateField); if (currentRestriction == null) { metadataTemplateService.setMetadataRestriction(project, metadataTemplateField, projectMetadataRole); @@ -1045,8 +1048,8 @@ public List uploadAssemblies(Long sampleId, Multi GenomeAssembly genomeAssembly = genomeAssemblyService.createAssemblyInSample(sample, uploadedAssembly) .getObject(); - sampleGenomeAssemblyFileModels - .add(new SampleGenomeAssemblyFileModel(genomeAssembly, uploadedAssembly.getFileSize())); + sampleGenomeAssemblyFileModels.add( + new SampleGenomeAssemblyFileModel(genomeAssembly, uploadedAssembly.getFileSize())); } return sampleGenomeAssemblyFileModels; @@ -1072,13 +1075,14 @@ public List concatenateSequenceFiles(Long sampl Iterable readMultiple = sequencingObjectService.readMultiple(objectIds); try { - SampleSequencingObjectJoin concatenatedSequencingObjects = sequencingObjectService - .concatenateSequences(Lists.newArrayList(readMultiple), filename, sample, removeOriginals); + SampleSequencingObjectJoin concatenatedSequencingObjects = sequencingObjectService.concatenateSequences( + Lists.newArrayList(readMultiple), filename, sample, removeOriginals); if (removeOriginals) { for (SequencingObject sequencingObject : readMultiple) { - if (sample.getDefaultSequencingObject() != null - && sample.getDefaultSequencingObject().getId().equals(sequencingObject.getId())) { + if (sample.getDefaultSequencingObject() != null && sample.getDefaultSequencingObject() + .getId() + .equals(sequencingObject.getId())) { sample.setDefaultSequencingObject(null); sampleService.update(sample); break; @@ -1096,8 +1100,9 @@ public List concatenateSequenceFiles(Long sampl firstFileSize = s.getForwardSequenceFile().getFileSize(); secondFileSize = s.getReverseSequenceFile().getFileSize(); } - sampleSequencingObjectFileModels.add(new SampleSequencingObjectFileModel(sequencingObject, firstFileSize, - secondFileSize, sequencingObject.getQcEntries())); + sampleSequencingObjectFileModels.add( + new SampleSequencingObjectFileModel(sequencingObject, firstFileSize, secondFileSize, + sequencingObject.getQcEntries())); return sampleSequencingObjectFileModels; } catch (ConcatenateException ex) { throw new ConcatenateException(ex.getMessage()); @@ -1113,10 +1118,10 @@ public List concatenateSequenceFiles(Long sampl */ private ProjectMetadataRole getMetadataFieldRestriction(Long projectId, Long metadataTemplateFieldId) { Project project = projectService.read(projectId); - MetadataTemplateField metadataTemplateField = metadataTemplateService - .readMetadataField(metadataTemplateFieldId); - MetadataRestriction metadataRestriction = metadataRestrictionRepository - .getRestrictionForFieldAndProject(project, metadataTemplateField); + MetadataTemplateField metadataTemplateField = metadataTemplateService.readMetadataField( + metadataTemplateFieldId); + MetadataRestriction metadataRestriction = metadataRestrictionRepository.getRestrictionForFieldAndProject( + project, metadataTemplateField); if (metadataRestriction != null) { return metadataRestriction.getLevel(); } @@ -1136,9 +1141,8 @@ private SampleSequencingObjectFileModel createSequenceFilePairsInSample(List sampleId try { for (Sample sample : samples) { - Collection sequencingObjectsForSample = sequencingObjectService - .getSequencingObjectsForSample(sample); + Collection sequencingObjectsForSample = sequencingObjectService.getSequencingObjectsForSample( + sample); for (SampleSequencingObjectJoin join : sequencingObjectsForSample) { for (SequenceFile file : join.getObject().getFiles()) { Path path = file.getFile(); - String fileName = project.getName() + "/" + sample.getSampleName() + "/" - + path.getFileName().toString(); + String fileName = + project.getName() + "/" + sample.getSampleName() + "/" + path.getFileName() + .toString(); if (usedFileNames.contains(fileName)) { fileName = handleDuplicate(fileName, usedFileNames); } @@ -1349,8 +1352,8 @@ public void downloadSamplesSpreadsheet(Long projectId, String type, ProjectSampl * @return list of paired end sequence files */ public List getPairedSequenceFilesForExportSample(Sample sample, Project project) { - Collection filePairJoins = sequencingObjectService - .getSequencesForSampleOfType(sample, SequenceFilePair.class); + Collection filePairJoins = sequencingObjectService.getSequencesForSampleOfType( + sample, SequenceFilePair.class); // add project to qc entries and filter any unavailable entries List filePairs = new ArrayList<>(); for (SampleSequencingObjectJoin join : filePairJoins) { @@ -1370,8 +1373,8 @@ public List getPairedSequenceFilesForExportSample(Sample sampl * @return list of single end sequence files */ public List getSingleEndSequenceFilesForExportSample(Sample sample, Project project) { - Collection singleFileJoins = sequencingObjectService - .getSequencesForSampleOfType(sample, SingleEndSequenceFile.class); + Collection singleFileJoins = sequencingObjectService.getSequencesForSampleOfType( + sample, SingleEndSequenceFile.class); List singles = new ArrayList<>(); for (SampleSequencingObjectJoin join : singleFileJoins) { @@ -1390,8 +1393,8 @@ public List getSingleEndSequenceFilesForExportSample(Sample sa * @return list of fast5 sequence files */ public List getFast5FilesForExportSample(Sample sample) { - Collection fast5FileJoins = sequencingObjectService - .getSequencesForSampleOfType(sample, Fast5Object.class); + Collection fast5FileJoins = sequencingObjectService.getSequencesForSampleOfType( + sample, Fast5Object.class); return fast5FileJoins.stream().map(SampleSequencingObjectJoin::getObject).collect(Collectors.toList()); } @@ -1432,8 +1435,8 @@ private List formatSamplesForTable(Page ({ - url: `${URL}/metadata?projectId=${projectId}&metadataFieldId=${fieldId}&metadataEntryId=${entryId}`, + query: ({ fieldId, entryId, projectId, sampleId }) => ({ + url: `${URL}/metadata?projectId=${projectId}&sampleId=${sampleId}&metadataFieldId=${fieldId}&metadataEntryId=${entryId}`, method: "DELETE", }), invalidatesTags: ["SampleMetadata"], diff --git a/src/main/webapp/resources/js/components/samples/components/SampleMetadata.tsx b/src/main/webapp/resources/js/components/samples/components/SampleMetadata.tsx index 9cc0d9286dd..c157b65b2ab 100644 --- a/src/main/webapp/resources/js/components/samples/components/SampleMetadata.tsx +++ b/src/main/webapp/resources/js/components/samples/components/SampleMetadata.tsx @@ -24,7 +24,7 @@ import { removeSampleMetadataField, setEditSampleMetadata, } from "../sampleSlice"; -import { HEADER_HEIGHT, HEADER_HEIGHT_WITH_PADDING } from "./ViewerHeader"; +import { HEADER_HEIGHT_WITH_PADDING } from "./ViewerHeader"; const { Text } = Typography; @@ -58,6 +58,7 @@ export default function SampleMetadata() { const removeMetadata = (fieldId: number, entryId: number) => { removeSampleMetadata({ projectId, + sampleId: sample.identifier, fieldId, entryId, }) From 36dfa9af8261c3f278c53c7e17a2d5c80a03fb37 Mon Sep 17 00:00:00 2001 From: Katherine Thiessen Date: Tue, 31 Jan 2023 11:17:09 -0600 Subject: [PATCH 2/3] fixing linting error --- .../js/components/samples/components/SampleMetadata.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/webapp/resources/js/components/samples/components/SampleMetadata.tsx b/src/main/webapp/resources/js/components/samples/components/SampleMetadata.tsx index c157b65b2ab..c04234268f6 100644 --- a/src/main/webapp/resources/js/components/samples/components/SampleMetadata.tsx +++ b/src/main/webapp/resources/js/components/samples/components/SampleMetadata.tsx @@ -53,7 +53,7 @@ export default function SampleMetadata() { projectId, }) ); - }, []); + }, [dispatch, projectId, sample.identifier]); const removeMetadata = (fieldId: number, entryId: number) => { removeSampleMetadata({ From 5556c62688c317a6ffc75b4dffb01201a1350e3f Mon Sep 17 00:00:00 2001 From: Katherine Thiessen Date: Tue, 31 Jan 2023 11:19:55 -0600 Subject: [PATCH 3/3] updating changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dace2fbf4cf..58f2a1d5ea8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ * [UI]: Fixed bug where the `User` column was named `User Group` on the admin User Groups page. [See PR 1450](https://github.com/phac-nml/irida/pull/1450) * [Developer]: Replaced Apache OLTU with Nimbusds for performing OAuth2 authentication flow during syncing and Galaxy exporting. See [PR 1432](https://github.com/phac-nml/irida/pull/1432) * [Developer/UI]: Performance enhancements to the metadata uploader. See [PR 1445](https://github.com/phac-nml/irida/pull/1445). +* [Developer/UI]: Fix for updating sample modified date when metadata is deleted. See [PR 1457](https://github.com/phac-nml/irida/pull/1457). ## [22.09.7] - 2022/01/24 * [UI]: Fixed bugs on NCBI Export page preventing the NCBI `submission.xml` file from being properly written. See [PR 1451](https://github.com/phac-nml/irida/pull/1451)