diff --git a/backend/app/api/v1/commons/constants.py b/backend/app/api/v1/commons/constants.py index 650e9b8c..4d049387 100644 --- a/backend/app/api/v1/commons/constants.py +++ b/backend/app/api/v1/commons/constants.py @@ -21,3 +21,4 @@ "infraNodesCount", "totalNodesCount", ) +MAX_PAGE = 10000 diff --git a/backend/app/api/v1/commons/utils.py b/backend/app/api/v1/commons/utils.py index bfefa013..a2276124 100644 --- a/backend/app/api/v1/commons/utils.py +++ b/backend/app/api/v1/commons/utils.py @@ -2,6 +2,7 @@ from fastapi import HTTPException, status import re import app.api.v1.commons.constants as constants +from typing import Optional async def getMetadata(uuid: str, configpath: str): @@ -98,3 +99,18 @@ def build_sort_terms(sort_string: str) -> list[dict[str, str]]: ) sort_terms.append({f"{key}": {"order": dir}}) return sort_terms + + +def normalize_pagination(offset: Optional[int], size: Optional[int]) -> tuple[int, int]: + if offset and not size: + raise HTTPException(400, f"offset {offset} specified without size") + elif not offset and not size: + size = constants.MAX_PAGE + offset = 0 + elif not offset: + offset = 0 + elif offset >= constants.MAX_PAGE: + raise HTTPException( + 400, f"offset {offset} is too big (>= {constants.MAX_PAGE})" + ) + return offset, size diff --git a/backend/app/api/v1/endpoints/cpt/cptJobs.py b/backend/app/api/v1/endpoints/cpt/cptJobs.py index 3c9839cb..08228488 100644 --- a/backend/app/api/v1/endpoints/cpt/cptJobs.py +++ b/backend/app/api/v1/endpoints/cpt/cptJobs.py @@ -2,7 +2,7 @@ import asyncio from concurrent.futures import ProcessPoolExecutor, as_completed from multiprocessing import cpu_count -from fastapi import Response +from fastapi import Response, HTTPException import pandas as pd from datetime import datetime, timedelta, date from fastapi import APIRouter @@ -13,6 +13,7 @@ from .maps.ocm import ocmMapper from ...commons.example_responses import cpt_200_response, response_422 from fastapi.param_functions import Query +from app.api.v1.commons.utils import normalize_pagination router = APIRouter() @@ -68,6 +69,8 @@ async def jobs( status_code=422, ) + offset, size = normalize_pagination(offset, size) + results_df = pd.DataFrame() total_dict = {} total = 0 diff --git a/backend/app/api/v1/endpoints/ocm/ocmJobs.py b/backend/app/api/v1/endpoints/ocm/ocmJobs.py index bbcc39c7..6c9a43ae 100644 --- a/backend/app/api/v1/endpoints/ocm/ocmJobs.py +++ b/backend/app/api/v1/endpoints/ocm/ocmJobs.py @@ -69,8 +69,8 @@ async def jobs( "startDate": start_date.__str__(), "endDate": end_date.__str__(), "results": jobs, - "total": 0, - "offset": 0, + "total": results["total"], + "offset": (offset + size) if size != 10000 else 0, } if pretty: diff --git a/backend/app/api/v1/endpoints/ocp/ocpJobs.py b/backend/app/api/v1/endpoints/ocp/ocpJobs.py index 07b689a5..b6721858 100644 --- a/backend/app/api/v1/endpoints/ocp/ocpJobs.py +++ b/backend/app/api/v1/endpoints/ocp/ocpJobs.py @@ -5,6 +5,7 @@ from ...commons.ocp import getData from ...commons.example_responses import ocp_200_response, response_422 from fastapi.param_functions import Query +from app.api.v1.commons.utils import normalize_pagination router = APIRouter() @@ -52,13 +53,7 @@ async def jobs( status_code=422, ) - if offset and not size: - raise HTTPException(400, f"offset {offset} specified without size") - elif not offset and not size: - size = 10000 - offset = 0 - elif not offset: - offset = 0 + offset, size = normalize_pagination(offset, size) results = await getData( start_date, end_date, size, offset, sort, "ocp.elasticsearch" diff --git a/backend/app/api/v1/endpoints/quay/quayJobs.py b/backend/app/api/v1/endpoints/quay/quayJobs.py index 0a86db56..f25ccb54 100644 --- a/backend/app/api/v1/endpoints/quay/quayJobs.py +++ b/backend/app/api/v1/endpoints/quay/quayJobs.py @@ -5,6 +5,7 @@ from ...commons.quay import getData from ...commons.example_responses import quay_200_response, response_422 from fastapi.param_functions import Query +from app.api.v1.commons.utils import normalize_pagination router = APIRouter() @@ -52,13 +53,7 @@ async def jobs( status_code=422, ) - if offset and not size: - raise HTTPException(400, f"offset {offset} specified without size") - elif not offset and not size: - size = 10000 - offset = 0 - elif not offset: - offset = 0 + offset, size = normalize_pagination(offset, size) results = await getData( start_date, end_date, size, offset, sort, "quay.elasticsearch" @@ -72,8 +67,8 @@ async def jobs( "startDate": start_date.__str__(), "endDate": end_date.__str__(), "results": jobs, - "total": 0, - "offset": 0, + "total": results["total"], + "offset": offset + size, } if pretty: diff --git a/backend/app/api/v1/endpoints/telco/telcoJobs.py b/backend/app/api/v1/endpoints/telco/telcoJobs.py index c9a2d18f..892cd15d 100644 --- a/backend/app/api/v1/endpoints/telco/telcoJobs.py +++ b/backend/app/api/v1/endpoints/telco/telcoJobs.py @@ -1,10 +1,11 @@ import json from fastapi import Response from datetime import datetime, timedelta, date -from fastapi import APIRouter +from fastapi import APIRouter, HTTPException from ...commons.telco import getData from ...commons.example_responses import telco_200_response, response_422 from fastapi.param_functions import Query +from app.api.v1.commons.utils import normalize_pagination router = APIRouter() @@ -50,6 +51,7 @@ async def jobs( ), status_code=422, ) + offset, size = normalize_pagination(offset, size) results = await getData(start_date, end_date, size, offset, "telco.splunk") jobs = [] @@ -60,8 +62,8 @@ async def jobs( "startDate": start_date.__str__(), "endDate": end_date.__str__(), "results": jobs, - "total": 0, - "offset": 0, + "total": results["total"], + "offset": offset + size, } if pretty: diff --git a/frontend/src/actions/commonActions.js b/frontend/src/actions/commonActions.js index 0eec4c94..ce2846e3 100644 --- a/frontend/src/actions/commonActions.js +++ b/frontend/src/actions/commonActions.js @@ -140,12 +140,12 @@ export const getSelectedFilter = }; export const getRequestParams = (type) => (dispatch, getState) => { - const { start_date, end_date, size, offset, sort } = getState()[type]; + const { start_date, end_date, perPage, offset, sort } = getState()[type]; const params = { pretty: true, ...(start_date && { start_date }), ...(end_date && { end_date }), - size: size, + size: perPage, offset: offset, ...(sort && { sort }), }; diff --git a/frontend/src/actions/paginationActions.js b/frontend/src/actions/paginationActions.js index 09416cc8..7f2bd081 100644 --- a/frontend/src/actions/paginationActions.js +++ b/frontend/src/actions/paginationActions.js @@ -6,6 +6,7 @@ import { } from "./ocpActions"; import { fetchOCPJobsData, + setCPTOffset, setCPTPage, setCPTPageOptions, sliceCPTTableRows, @@ -47,36 +48,37 @@ const calculateOffset = (pageNumber, itemsPerPage) => { return (pageNumber - 1) * itemsPerPage; }; +const fetchActions = { + ocp: fetchOCPJobs, + quay: fetchQuayJobsData, + telco: fetchTelcoJobsData, + cpt: fetchOCPJobsData, +}; +const offsetActions = { + ocp: setOCPOffset, + quay: setQuayOffset, + telco: setTelcoOffset, + cpt: setCPTOffset, +}; + export const checkTableData = (newPage, currType) => (dispatch, getState) => { const { results, totalJobs, perPage, page } = getState()[currType]; - const fetchActions = { - ocp: fetchOCPJobs, - quay: fetchQuayJobsData, - telco: fetchTelcoJobsData, - }; - const offsetActions = { - ocp: setOCPOffset, - quay: setQuayOffset, - telco: setTelcoOffset, - }; + const hasPageData = results.length >= newPage * perPage; const offset = calculateOffset(newPage, perPage); - if (results.length < totalJobs && !hasPageData) { - if (currType === "cpt") { - const startIdx = (page - 1) * perPage; - const endIdx = startIdx + perPage - 1; + + if (currType === "cpt") { + const startIdx = (page - 1) * perPage; + const endIdx = startIdx + perPage - 1; + if (results.length < totalJobs && !hasPageData) { if (results[startIdx] === undefined || results[endIdx] === undefined) { dispatch(fetchOCPJobsData()); } } else { - dispatch(offsetActions[currType](offset)); - dispatch(fetchActions[currType]()); - } - } else { - if (currType === "cpt") { - const startIdx = (page - 1) * perPage; - const endIdx = startIdx + perPage - 1; dispatch(sliceCPTTableRows(startIdx, endIdx)); } + } else if (results.length < totalJobs) { + dispatch(offsetActions[currType](offset)); + dispatch(fetchActions[currType]()); } }; diff --git a/frontend/src/components/organisms/Pagination/index.jsx b/frontend/src/components/organisms/Pagination/index.jsx index 5b6454b3..32373a64 100644 --- a/frontend/src/components/organisms/Pagination/index.jsx +++ b/frontend/src/components/organisms/Pagination/index.jsx @@ -27,6 +27,7 @@ const RenderPagination = (props) => { const onPerPageSelect = useCallback( (_evt, newPerPage, newPage, startIdx, endIdx) => { dispatch(setPageOptions(newPage, newPerPage, props.type)); + dispatch(checkTableData(newPage, props.type)); }, [dispatch, props.type] ); @@ -51,8 +52,11 @@ const RenderPagination = (props) => { perPageOptions={perPageOptions} onSetPage={onSetPage} onPerPageSelect={onPerPageSelect} + onPreviousClick={onNextClick} onNextClick={onNextClick} onPageInput={onNextClick} + onFirstClick={onNextClick} + onLastClick={onNextClick} isCompact={props.type === "cpt" ? true : false} /> ); diff --git a/frontend/src/reducers/homeReducer.js b/frontend/src/reducers/homeReducer.js index 716c4d47..f4929a4d 100644 --- a/frontend/src/reducers/homeReducer.js +++ b/frontend/src/reducers/homeReducer.js @@ -46,7 +46,6 @@ const initialState = { filteredResults: [], page: START_PAGE, perPage: DEFAULT_PER_PAGE, - size: DEFAULT_PER_PAGE, offset: INITAL_OFFSET, totalJobs: 0, summary: {}, diff --git a/frontend/src/reducers/ocpReducer.js b/frontend/src/reducers/ocpReducer.js index 5e93b8b6..61ce4ac9 100644 --- a/frontend/src/reducers/ocpReducer.js +++ b/frontend/src/reducers/ocpReducer.js @@ -45,7 +45,6 @@ const initialState = { sort: "", page: START_PAGE, perPage: DEFAULT_PER_PAGE, - size: DEFAULT_PER_PAGE, offset: INITAL_OFFSET, totalJobs: 0, filterData: [], diff --git a/frontend/src/reducers/quayReducer.js b/frontend/src/reducers/quayReducer.js index db7f4551..ea45329b 100644 --- a/frontend/src/reducers/quayReducer.js +++ b/frontend/src/reducers/quayReducer.js @@ -65,7 +65,6 @@ const initialState = { graphData: [], page: START_PAGE, perPage: DEFAULT_PER_PAGE, - size: DEFAULT_PER_PAGE, offset: INITAL_OFFSET, totalJobs: 0, summary: {}, diff --git a/frontend/src/reducers/telcoReducer.js b/frontend/src/reducers/telcoReducer.js index 1637f131..e0c262d5 100644 --- a/frontend/src/reducers/telcoReducer.js +++ b/frontend/src/reducers/telcoReducer.js @@ -62,7 +62,6 @@ const initialState = { graphData: [], page: START_PAGE, perPage: DEFAULT_PER_PAGE, - size: DEFAULT_PER_PAGE, offset: INITAL_OFFSET, totalJobs: 0, summary: {},