diff --git a/changes/add_external_projList.md b/changes/add_external_projList.md new file mode 100644 index 0000000..d41c4b9 --- /dev/null +++ b/changes/add_external_projList.md @@ -0,0 +1 @@ +External view of Projects list page diff --git a/src/main/java/ca/on/oicr/gsi/dimsum/controller/rest/external/ExternalAutocompleteRestController.java b/src/main/java/ca/on/oicr/gsi/dimsum/controller/rest/common/CommonAutocompleteRestController.java similarity index 89% rename from src/main/java/ca/on/oicr/gsi/dimsum/controller/rest/external/ExternalAutocompleteRestController.java rename to src/main/java/ca/on/oicr/gsi/dimsum/controller/rest/common/CommonAutocompleteRestController.java index 728fa09..f6cedad 100644 --- a/src/main/java/ca/on/oicr/gsi/dimsum/controller/rest/external/ExternalAutocompleteRestController.java +++ b/src/main/java/ca/on/oicr/gsi/dimsum/controller/rest/common/CommonAutocompleteRestController.java @@ -1,4 +1,4 @@ -package ca.on.oicr.gsi.dimsum.controller.rest.external; +package ca.on.oicr.gsi.dimsum.controller.rest.common; import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; @@ -9,8 +9,8 @@ import ca.on.oicr.gsi.dimsum.service.CaseService; @RestController -@RequestMapping("/rest/external/autocomplete") -public class ExternalAutocompleteRestController { +@RequestMapping("/rest/common/autocomplete") +public class CommonAutocompleteRestController { // Note: CaseService filters all below results based on the user's authorized projects diff --git a/src/main/java/ca/on/oicr/gsi/dimsum/controller/rest/external/ExternalProjectRestController.java b/src/main/java/ca/on/oicr/gsi/dimsum/controller/rest/external/ExternalProjectRestController.java new file mode 100644 index 0000000..1d1707a --- /dev/null +++ b/src/main/java/ca/on/oicr/gsi/dimsum/controller/rest/external/ExternalProjectRestController.java @@ -0,0 +1,34 @@ +package ca.on.oicr.gsi.dimsum.controller.rest.external; + +import static ca.on.oicr.gsi.dimsum.controller.mvc.MvcUtils.*; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import ca.on.oicr.gsi.dimsum.controller.rest.request.DataQuery; +import ca.on.oicr.gsi.dimsum.data.external.ExternalProjectSummary; +import ca.on.oicr.gsi.dimsum.service.CaseService; +import ca.on.oicr.gsi.dimsum.service.filtering.ProjectSummaryFilter; +import ca.on.oicr.gsi.dimsum.service.filtering.ProjectSummarySort; +import ca.on.oicr.gsi.dimsum.service.filtering.TableData; + + +@RestController +@RequestMapping("/rest/external/projects") +public class ExternalProjectRestController { + + @Autowired + private CaseService caseService; + + @PostMapping + public TableData query(@RequestBody DataQuery query) { + validateDataQuery(query); + ProjectSummarySort sort = parseSort(query, ProjectSummarySort::getByLabel); + boolean descending = parseDescending(query); + List filters = parseProjectSummaryFilters(query); + return caseService.getExternalProjects(query.getPageSize(), query.getPageNumber(), sort, + descending, filters); + } +} diff --git a/src/main/java/ca/on/oicr/gsi/dimsum/controller/rest/internal/AutocompleteRestController.java b/src/main/java/ca/on/oicr/gsi/dimsum/controller/rest/internal/AutocompleteRestController.java index e43204b..16da2c2 100644 --- a/src/main/java/ca/on/oicr/gsi/dimsum/controller/rest/internal/AutocompleteRestController.java +++ b/src/main/java/ca/on/oicr/gsi/dimsum/controller/rest/internal/AutocompleteRestController.java @@ -15,33 +15,8 @@ public class AutocompleteRestController { @Autowired private CaseService caseService; - @GetMapping("/assay-names") - public Set queryAssays(@RequestParam String q) { - return caseService.getMatchingAssayNames(q); - } - - @GetMapping("/requisition-names") - public Set queryRequisitions(@RequestParam String q) { - return caseService.getMatchingRequisitionNames(q); - } - - @GetMapping("/project-names") - public Set queryProjects(@RequestParam String q) { - return caseService.getMatchingProjectNames(q); - } - - @GetMapping("/donor-names") - public Set queryDonors(@RequestParam String q) { - return caseService.getMatchingDonorNames(q); - } - @GetMapping("/run-names") public Set queryRuns(@RequestParam String q) { return caseService.getMatchingRunNames(q); } - - @GetMapping("/test-names") - public Set queryTests(@RequestParam String q) { - return caseService.getMatchingTestNames(q); - } } diff --git a/src/main/java/ca/on/oicr/gsi/dimsum/data/external/ExternalProjectSummary.java b/src/main/java/ca/on/oicr/gsi/dimsum/data/external/ExternalProjectSummary.java new file mode 100644 index 0000000..2b27219 --- /dev/null +++ b/src/main/java/ca/on/oicr/gsi/dimsum/data/external/ExternalProjectSummary.java @@ -0,0 +1,23 @@ +package ca.on.oicr.gsi.dimsum.data.external; + +import ca.on.oicr.gsi.dimsum.data.ProjectSummary; + +public record ExternalProjectSummary(String name, String pipeline, int totalTestCount, + int receiptCompletedCount, int extractionCompletedCount, int libraryPrepCompletedCount, + int libraryQualCompletedCount, int fullDepthSeqCompletedCount, int analysisReviewCompletedCount, + int releaseApprovalCompletedCount, int releaseCompletedCount) { + + public ExternalProjectSummary(ProjectSummary from) { + this(from.getName(), + from.getPipeline(), + from.getTotalTestCount(), + from.getReceiptCompletedCount(), + from.getExtractionCompletedCount(), + from.getLibraryPrepCompletedCount(), + from.getLibraryQualCompletedCount(), + from.getFullDepthSeqCompletedCount(), + from.getAnalysisReviewCompletedCount(), + from.getReleaseApprovalCompletedCount(), + from.getReleaseCompletedCount()); + } +} diff --git a/src/main/java/ca/on/oicr/gsi/dimsum/service/CaseService.java b/src/main/java/ca/on/oicr/gsi/dimsum/service/CaseService.java index 55c7b34..d37b725 100644 --- a/src/main/java/ca/on/oicr/gsi/dimsum/service/CaseService.java +++ b/src/main/java/ca/on/oicr/gsi/dimsum/service/CaseService.java @@ -49,6 +49,7 @@ import ca.on.oicr.gsi.dimsum.data.RunAndLibraries; import ca.on.oicr.gsi.dimsum.data.TestTableView; import ca.on.oicr.gsi.dimsum.data.external.ExternalCase; +import ca.on.oicr.gsi.dimsum.data.external.ExternalProjectSummary; import ca.on.oicr.gsi.dimsum.data.external.ExternalSample; import ca.on.oicr.gsi.dimsum.data.external.ExternalTestTableView; import ca.on.oicr.gsi.dimsum.security.DimsumPrincipal; @@ -496,8 +497,8 @@ public TableData getOmittedSamples(int pageSize, int pageNumber, } public TableData getProjects(int pageSize, int pageNumber, - ProjectSummarySort sort, - boolean descending, Collection filters) { + ProjectSummarySort sort, boolean descending, Collection filters) { + authorizeInternalOnly(); List baseProjectSummaries = caseData.getProjectSummaries().stream().toList(); Stream stream = filterProjectSummaries(baseProjectSummaries, filters); @@ -517,6 +518,33 @@ public TableData getProjects(int pageSize, int pageNumber, return data; } + public TableData getExternalProjects(int pageSize, int pageNumber, + ProjectSummarySort sort, boolean descending, Collection filters) { + DimsumPrincipal principal = securityManager.getPrincipal(); + List baseProjectSummaries = caseData.getProjectSummaries().stream() + .filter(summary -> principal.getProjects().contains(summary.getName())) + .toList(); + Stream stream = filterProjectSummaries(baseProjectSummaries, filters); + + if (sort == null) { + sort = ProjectSummarySort.NAME; + descending = true; + } + stream = stream.sorted(descending ? sort.comparator().reversed() : sort.comparator()); + + List filteredProjectSummaries = + stream.skip(pageSize * (pageNumber - 1)) + .limit(pageSize) + .map(ExternalProjectSummary::new) + .collect(Collectors.toList()); + + TableData data = new TableData<>(); + data.setTotalCount(baseProjectSummaries.size()); + data.setFilteredCount(filterProjectSummaries(baseProjectSummaries, filters).count()); + data.setItems(filteredProjectSummaries); + return data; + } + public TableData getProjectSummaryRows(String projectName, Collection filters, LocalDate afterDate, LocalDate beforeDate) { DimsumPrincipal principal = securityManager.getPrincipal(); diff --git a/ts/util/urls.ts b/ts/util/urls.ts index 3dc7ac5..4bd6a2b 100644 --- a/ts/util/urls.ts +++ b/ts/util/urls.ts @@ -1,8 +1,10 @@ import { internalUser, siteConfig } from "./site-config"; import { Pair } from "./pair"; -function getRestBaseUrl() { - if (internalUser) { +function getRestBaseUrl(common?: boolean) { + if (common) { + return "/rest/common"; + } else if (internalUser) { return "/rest/internal"; } else { return "/rest/external"; @@ -40,12 +42,14 @@ export const urls = { list: `${getRestBaseUrl()}/runs`, }, autocomplete: { - assayNames: `${getRestBaseUrl()}/autocomplete/assay-names`, - requisitionNames: `${getRestBaseUrl()}/autocomplete/requisition-names`, - projectNames: `${getRestBaseUrl()}/autocomplete/project-names`, - donorNames: `${getRestBaseUrl()}/autocomplete/donor-names`, + assayNames: `${getRestBaseUrl(true)}/autocomplete/assay-names`, + requisitionNames: `${getRestBaseUrl( + true + )}/autocomplete/requisition-names`, + projectNames: `${getRestBaseUrl(true)}/autocomplete/project-names`, + donorNames: `${getRestBaseUrl(true)}/autocomplete/donor-names`, runNames: `${getRestBaseUrl()}/autocomplete/run-names`, - testNames: `${getRestBaseUrl()}/autocomplete/test-names`, + testNames: `${getRestBaseUrl(true)}/autocomplete/test-names`, }, notifications: `${getRestBaseUrl()}/notifications`, omissions: `${getRestBaseUrl()}/omissions`,