From f93ae9add0e77116a17bf1e65a0acd63a4b3a948 Mon Sep 17 00:00:00 2001 From: Zhaoxinxin <107842350+Liam-Zhao@users.noreply.github.com> Date: Tue, 31 Oct 2023 16:42:02 +0800 Subject: [PATCH] fix: Job uses server's pagination (#315) --- src/components/job/preheats/index.tsx | 51 +++++++++++++++------------ src/lib/api.ts | 17 +++++++-- 2 files changed, 42 insertions(+), 26 deletions(-) diff --git a/src/components/job/preheats/index.tsx b/src/components/job/preheats/index.tsx index d8e45b59..d83d7be4 100644 --- a/src/components/job/preheats/index.tsx +++ b/src/components/job/preheats/index.tsx @@ -22,19 +22,20 @@ import AddIcon from '@mui/icons-material/Add'; import MoreTimeIcon from '@mui/icons-material/MoreTime'; import { useNavigate, Link } from 'react-router-dom'; import { useEffect, useState } from 'react'; -import { getJobs, getJobsResponse } from '../../../lib/api'; -import { DEFAULT_PAGE_SIZE, MAX_PAGE_SIZE } from '../../../lib/constants'; -import { getDatetime, getPaginatedList } from '../../../lib/utils'; +import { getJobs, JobsResponse } from '../../../lib/api'; +import { DEFAULT_PAGE_SIZE } from '../../../lib/constants'; +import { getDatetime } from '../../../lib/utils'; export default function Preheats() { const [errorMessage, setErrorMessage] = useState(false); const [errorMessageText, setErrorMessageText] = useState(''); const [preheatPage, setPreheatPage] = useState(1); + const [preheatTotalPages, setPreheatTotalPages] = useState(1); const [isLoading, setIsLoading] = useState(false); const [status, setStatus] = useState('ALL'); const [shouldPoll, setShouldPoll] = useState(false); const [openStatusSelect, setOpenStatusSelect] = useState(false); - const [allPreheats, setAllPreheats] = useState([]); + const [allPreheats, setAllPreheats] = useState([]); const navigate = useNavigate(); @@ -55,14 +56,18 @@ export default function Preheats() { setIsLoading(true); const jobs = await getJobs({ - page: 1, - per_page: MAX_PAGE_SIZE, + page: preheatPage, + per_page: DEFAULT_PAGE_SIZE, state: status === 'ALL' ? undefined : status, }); - setAllPreheats(jobs.sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime())); + setAllPreheats(jobs.data); + setPreheatTotalPages(jobs.total_page || 1); + + const states = jobs.data.filter( + (obj) => obj.result.State !== 'SUCCESS' && obj.result.State !== 'FAILURE', + ).length; - const states = jobs.filter((obj) => obj.result.State !== 'SUCCESS' && obj.result.State !== 'FAILURE').length; states === 0 ? setShouldPoll(false) : setShouldPoll(true); setIsLoading(false); @@ -73,7 +78,7 @@ export default function Preheats() { } } })(); - }, [status]); + }, [status, preheatPage]); useEffect(() => { if (shouldPoll) { @@ -81,15 +86,18 @@ export default function Preheats() { const pollPreheat = async () => { try { const jobs = await getJobs({ - page: 1, - per_page: MAX_PAGE_SIZE, + page: preheatPage, + per_page: DEFAULT_PAGE_SIZE, state: status === 'ALL' ? undefined : status, }); - setAllPreheats(jobs.sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime())); - const states = jobs.filter( + setAllPreheats(jobs.data); + setPreheatTotalPages(jobs.total_page || 1); + + const states = jobs.data.filter( (obj) => obj.result.State !== 'SUCCESS' && obj.result.State !== 'FAILURE', ).length; + states === 0 ? setShouldPoll(false) : setShouldPoll(true); } catch (error) { if (error instanceof Error) { @@ -106,7 +114,7 @@ export default function Preheats() { clearInterval(pollingInterval); }; } - }, [status, shouldPoll]); + }, [status, shouldPoll, preheatPage]); const statusList = [ { lable: 'Pending', name: 'PENDING' }, @@ -115,9 +123,6 @@ export default function Preheats() { { lable: 'Failure', name: 'FAILURE' }, ]; - const totalPage = Math.ceil(allPreheats.length / DEFAULT_PAGE_SIZE); - const currentPageData = getPaginatedList(allPreheats, preheatPage, DEFAULT_PAGE_SIZE); - const changeStatus = (event: any) => { setStatus(event.target.value); setShouldPoll(true); @@ -209,15 +214,15 @@ export default function Preheats() { - {currentPageData.length === 0 ? ( + {allPreheats.length === 0 ? ( You don't have any preheat tasks. ) : ( <> - {Array.isArray(currentPageData) && - currentPageData.map((item, index) => { - return index !== currentPageData.length - 1 ? ( + {Array.isArray(allPreheats) && + allPreheats.map((item, index) => { + return index !== allPreheats.length - 1 ? ( @@ -365,10 +370,10 @@ export default function Preheats() { )} - {totalPage > 1 ? ( + {preheatTotalPages > 1 ? ( { setPreheatPage(newPage); }} diff --git a/src/lib/api.ts b/src/lib/api.ts index db49b1b9..0c0c2718 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -1,4 +1,5 @@ import queryString from 'query-string'; +import { parseLinkHeader } from '@web3-storage/parse-link-header'; const API_URL = process.env.REACT_APP_API_URL || window.location.href; @@ -655,7 +656,7 @@ interface getJobsParams { state?: string; } -export interface getJobsResponse { +export interface JobsResponse { id: number; created_at: string; updated_at: string; @@ -689,13 +690,23 @@ export interface getJobsResponse { }; } -export async function getJobs(params?: getJobsParams): Promise { +interface getJobsResponse { + data: JobsResponse[]; + total_page?: number; +} + +export async function getJobs(params?: getJobsParams): Promise { const url = params ? new URL(`/api/v1/jobs?${queryString.stringify(params)}`, API_URL) : new URL('/api/v1/jobs', API_URL); const response = await get(url); - return await response.json(); + const data = await response.json(); + const linkHeader = response.headers.get('link'); + const links = parseLinkHeader(linkHeader || null); + const totalPage = Number(links?.last?.page); + const responses = { data: data, total_page: totalPage }; + return responses; } interface getJobResponse {