Skip to content

Commit

Permalink
Merge pull request I-TECH-UW#873 from parthnagdev/dashPage
Browse files Browse the repository at this point in the history
Adding API pagination to the Dashboard Order Lists I-TECH-UW#681
  • Loading branch information
mozzy11 authored Mar 25, 2024
2 parents b68f339 + efcc0d1 commit 592b234
Show file tree
Hide file tree
Showing 4 changed files with 304 additions and 6 deletions.
76 changes: 73 additions & 3 deletions frontend/src/components/home/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
ClickableTile,
Loading,
Grid,
Button,
Column,
DataTable,
TableContainer,
Expand Down Expand Up @@ -74,6 +75,16 @@ const HomeDashBoard: React.FC<DashBoardProps> = () => {
const [page, setPage] = useState(1);
const [pageSize, setPageSize] = useState(10);
const [selectedTile, setSelectedTile] = useState<Tile>(null);
const [nextPage, setNextPage] = useState(null);
const [previousPage, setPreviousPage] = useState(null);
const [pagination, setPagination] = useState(false);
const [url, setUrl] = useState("");

useEffect(() => {
setNextPage(null);
setPreviousPage(null);
setPagination(false);
}, []);

useEffect(() => {
getFromOpenElisServer("/rest/home-dashboard/metrics", loadCount);
Expand All @@ -86,6 +97,9 @@ const HomeDashBoard: React.FC<DashBoardProps> = () => {

useEffect(() => {
if (selectedTile != null) {
setNextPage(null);
setPreviousPage(null);
setPagination(false);
setLoading(true);
if (selectedTile.type == "AVERAGE_TURN_AROUND_TIME") {
getFromOpenElisServer(
Expand Down Expand Up @@ -114,19 +128,50 @@ const HomeDashBoard: React.FC<DashBoardProps> = () => {
};
}, [selectedTile]);

const loadNextResultsPage = () => {
setLoading(true);
getFromOpenElisServer("/rest/home-dashboard/" + selectedTile.type + "?page=" + nextPage, loadData);
};

const loadPreviousResultsPage = () => {
setLoading(true);
getFromOpenElisServer("/rest/home-dashboard/" + selectedTile.type + "?page=" + previousPage, loadData);
};

const loadCount = (data) => {
if (componentMounted.current) {
setCounts(data);
setLoading(false);
}
};

const loadData = (data) => {
if (data && data.length > 0) {
setData(data);
const loadData = (res) => {
// If the response object is not null and has displayItems array with length greater than 0 then set it as data.
if (res && res.displayItems && res.displayItems.length > 0) {
setData(res.displayItems);
} else {
setData([]);
}

// Sets next and previous page numbers based on the total pages and current page number.
if (res && res.paging) {
const { totalPages, currentPage } = res.paging;
if (totalPages > 1) {
setPagination(true);
if (parseInt(currentPage) < parseInt(totalPages)) {
setNextPage(parseInt(currentPage) + 1);
} else {
setNextPage(null);
}

if (parseInt(currentPage) > 1) {
setPreviousPage(parseInt(currentPage) - 1);
} else {
setPreviousPage(null);
}
}
}

setLoading(false);
};

Expand Down Expand Up @@ -408,6 +453,31 @@ const HomeDashBoard: React.FC<DashBoardProps> = () => {
) : (
<Grid>
<Column lg={16} md={8} sm={4}>
{pagination && (
<Grid>
<Column lg={11} />
<Column lg={2}>
<Button
type=""
id="loadpreviousresults"
onClick={loadPreviousResultsPage}
disabled={previousPage != null ? false : true}
>
<FormattedMessage id="button.label.loadprevious" />
</Button>
</Column>
<Column lg={2}>
<Button
type=""
id="loadnextresults"
onClick={loadNextResultsPage}
disabled={nextPage != null ? false : true}
>
<FormattedMessage id="button.label.loadnext" />
</Button>
</Column>
</Grid>
)}
<DataTable
rows={data.slice((page - 1) * pageSize, page * pageSize)}
headers={
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.openelisglobal.common.provider.query;

import org.openelisglobal.common.form.IPagingForm;
import org.openelisglobal.common.paging.PagingBean;
import org.openelisglobal.common.rest.provider.bean.homedashboard.OrderDisplayBean;

import java.util.List;

/**
* To be returned as a response to a request for a patient dashboard form.
* It contains display iteams of a page and paging information.
*/
public class PatientDashBoardForm implements IPagingForm {

private PagingBean paging;

private List<OrderDisplayBean> displayItems;

public void setOrderDisplayBeans(List<OrderDisplayBean> displayItems) {
this.displayItems = displayItems;
}

public List<OrderDisplayBean> getDisplayItems() {
return displayItems;
}

@Override
public void setPaging(PagingBean paging) {
this.paging = paging;
}

@Override
public PagingBean getPaging() {
return paging;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.openelisglobal.common.rest.provider;

import java.lang.reflect.InvocationTargetException;
import java.time.Duration;
import java.time.LocalDate;
import java.util.ArrayList;
Expand All @@ -9,15 +10,20 @@
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.validator.GenericValidator;
import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.ServiceRequest;
import org.openelisglobal.analysis.service.AnalysisService;
import org.openelisglobal.analysis.valueholder.Analysis;
import org.openelisglobal.common.provider.query.PatientDashBoardForm;
import org.openelisglobal.common.rest.provider.bean.homedashboard.AverageTimeDisplayBean;
import org.openelisglobal.common.rest.provider.bean.homedashboard.DashBoardMetrics;
import org.openelisglobal.common.rest.provider.bean.homedashboard.DashBoardTile;
import org.openelisglobal.common.rest.provider.bean.homedashboard.OrderDisplayBean;
import org.openelisglobal.common.rest.util.PatientDashBoardPaging;
import org.openelisglobal.common.services.IStatusService;
import org.openelisglobal.common.services.StatusService.AnalysisStatus;
import org.openelisglobal.common.services.StatusService.ExternalOrderStatus;
Expand Down Expand Up @@ -358,14 +364,43 @@ public DashBoardMetrics getDasBoardTiles() {

return metrics;
}


/**
* Get the list of orders to be displayed on the dashboard.
* It will returna a list of orders based on the type of the list in paginated manner.
*/
@GetMapping(value = "home-dashboard/{listType}", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public List<OrderDisplayBean> getDashBoardDisplayList(@PathVariable DashBoardTile.TileType listType,
@RequestParam(required = false) String systemUserId) {
public PatientDashBoardForm getDashBoardDisplayList(HttpServletRequest request, @PathVariable DashBoardTile.TileType listType,
@RequestParam(required = false) String systemUserId) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {

PatientDashBoardForm response = new PatientDashBoardForm();
PatientDashBoardPaging paging = new PatientDashBoardPaging();
List<OrderDisplayBean> orderDisplayBeans = new ArrayList<>();

String requestedPage = request.getParameter("page");
if (GenericValidator.isBlankOrNull(requestedPage)) {
orderDisplayBeans = retreiveOrders(listType, systemUserId);

// All the orders retreived are fed into paging to return the first page of the list.
paging.setDatabaseResults(request, response, orderDisplayBeans);
} else {
int requestedPageNumber = Integer.parseInt(requestedPage);

// Sets the requested page in the response.
paging.page(request, response, requestedPageNumber);
}

return response;
}

/**
* Returns the list of orders based on the type of the list provided by the getdashBoardDisplayList method.
*/
private List<OrderDisplayBean> retreiveOrders(DashBoardTile.TileType listType, String systemUserId) {
Set<Integer> statusIdSet;
List<Analysis> analyses;

switch (listType) {
case ORDERS_IN_PROGRESS:
analyses = analysisService.getAnalysesForStatusId(iStatusService.getStatusID(AnalysisStatus.NotStarted));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
package org.openelisglobal.common.rest.util;

/**
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations under
* the License.
*
* The Original Code is OpenELIS code.
*
* Copyright (C) CIRG, University of Washington, Seattle WA. All Rights Reserved.
*
*/

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.openelisglobal.common.action.IActionConstants;
import org.openelisglobal.common.paging.IPageDivider;
import org.openelisglobal.common.paging.IPageFlattener;
import org.openelisglobal.common.paging.IPageUpdater;
import org.openelisglobal.common.paging.PagingProperties;
import org.openelisglobal.common.paging.PagingUtility;
import org.openelisglobal.common.provider.query.PatientDashBoardForm;
import org.openelisglobal.common.rest.provider.bean.homedashboard.OrderDisplayBean;
import org.openelisglobal.common.util.IdValuePair;

import org.openelisglobal.spring.util.SpringContext;

/**
* Responsible for building a page by accepting all display and paging information.
* Based on the page size and the page number, it will return the appropriate page.
*/
public class PatientDashBoardPaging {

private final PagingUtility<List<OrderDisplayBean>> paging = new PagingUtility<>(); // Adjust type based on your data
private static final PatientDashboardPageHelper pagingHelper = new PatientDashboardPageHelper(); // Implement helper class

public void setDatabaseResults(HttpServletRequest request, PatientDashBoardForm form, List<OrderDisplayBean> orders)
throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {

paging.setDatabaseResults(request.getSession(), orders, pagingHelper);

List<OrderDisplayBean> resultPage = paging.getPage(1, request.getSession());
if (resultPage != null) {
form.setOrderDisplayBeans(resultPage);
form.setPaging(paging.getPagingBeanWithSearchMapping(1, request.getSession()));
}
}

public void page(HttpServletRequest request, PatientDashBoardForm form, int newPage)
throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {

request.getSession().setAttribute(IActionConstants.SAVE_DISABLED, IActionConstants.FALSE);

if (newPage < 0) {
newPage = 0;
}
List<OrderDisplayBean> resultPage = paging.getPage(newPage, request.getSession());
if (resultPage != null) {
form.setOrderDisplayBeans(resultPage);
//form.setTestSectionId("0");
form.setPaging(paging.getPagingBeanWithSearchMapping(newPage, request.getSession()));
}

}


public List<OrderDisplayBean> getResults(HttpServletRequest request) {
return paging.getAllResults(request.getSession(), pagingHelper);
}

private static class PatientDashboardPageHelper implements IPageDivider<List<OrderDisplayBean>>,
IPageUpdater<List<OrderDisplayBean>>, IPageFlattener<List<OrderDisplayBean>> {

@Override
public void createPages(List<OrderDisplayBean> orders, List<List<OrderDisplayBean>> pagedResults) {
List<OrderDisplayBean> page = new ArrayList<>();

Boolean createNewPage = false;
int resultCount = 0;

for (OrderDisplayBean item : orders) {
if (createNewPage) {
resultCount = 0;
createNewPage = false;
pagedResults.add(page);
page = new ArrayList<>();
}
if (resultCount >= SpringContext.getBean(PagingProperties.class).getResultsPageSize()) {
createNewPage = true;
}

page.add(item);
resultCount++;
}

if (!page.isEmpty() || pagedResults.isEmpty()) {
pagedResults.add(page);
}
}

@Override
public void updateCache(List<OrderDisplayBean> cacheItems, List<OrderDisplayBean> clientItems) {
for (int i = 0; i < clientItems.size(); i++) {
cacheItems.set(i, clientItems.get(i));
}

}

@Override
public List<OrderDisplayBean> flattenPages(List<List<OrderDisplayBean>> pages) {

List<OrderDisplayBean> allResults = new ArrayList<>();

for (List<OrderDisplayBean> page : pages) {
for (OrderDisplayBean item : page) {
allResults.add(item);
}
}

return allResults;

}

@Override
public List<IdValuePair> createSearchToPageMapping(List<List<OrderDisplayBean>> allPages) {
List<IdValuePair> mappingList = new ArrayList<>();

int page = 0;
for (List<OrderDisplayBean> resultList : allPages) {
page++;
String pageString = String.valueOf(page);

String orderID = null;

for (OrderDisplayBean resultItem : resultList) {
if (!resultItem.getId().equals(orderID)) {
orderID = resultItem.getId();
mappingList.add(new IdValuePair(orderID, pageString));
}
}

}

return mappingList;
}
}
}

0 comments on commit 592b234

Please sign in to comment.