Skip to content

Commit f93ae9a

Browse files
authored
fix: Job uses server's pagination (#315)
1 parent 9d74dd2 commit f93ae9a

File tree

2 files changed

+42
-26
lines changed

2 files changed

+42
-26
lines changed

src/components/job/preheats/index.tsx

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,20 @@ import AddIcon from '@mui/icons-material/Add';
2222
import MoreTimeIcon from '@mui/icons-material/MoreTime';
2323
import { useNavigate, Link } from 'react-router-dom';
2424
import { useEffect, useState } from 'react';
25-
import { getJobs, getJobsResponse } from '../../../lib/api';
26-
import { DEFAULT_PAGE_SIZE, MAX_PAGE_SIZE } from '../../../lib/constants';
27-
import { getDatetime, getPaginatedList } from '../../../lib/utils';
25+
import { getJobs, JobsResponse } from '../../../lib/api';
26+
import { DEFAULT_PAGE_SIZE } from '../../../lib/constants';
27+
import { getDatetime } from '../../../lib/utils';
2828

2929
export default function Preheats() {
3030
const [errorMessage, setErrorMessage] = useState(false);
3131
const [errorMessageText, setErrorMessageText] = useState('');
3232
const [preheatPage, setPreheatPage] = useState(1);
33+
const [preheatTotalPages, setPreheatTotalPages] = useState(1);
3334
const [isLoading, setIsLoading] = useState(false);
3435
const [status, setStatus] = useState<string>('ALL');
3536
const [shouldPoll, setShouldPoll] = useState(false);
3637
const [openStatusSelect, setOpenStatusSelect] = useState(false);
37-
const [allPreheats, setAllPreheats] = useState<getJobsResponse[]>([]);
38+
const [allPreheats, setAllPreheats] = useState<JobsResponse[]>([]);
3839

3940
const navigate = useNavigate();
4041

@@ -55,14 +56,18 @@ export default function Preheats() {
5556
setIsLoading(true);
5657

5758
const jobs = await getJobs({
58-
page: 1,
59-
per_page: MAX_PAGE_SIZE,
59+
page: preheatPage,
60+
per_page: DEFAULT_PAGE_SIZE,
6061
state: status === 'ALL' ? undefined : status,
6162
});
6263

63-
setAllPreheats(jobs.sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime()));
64+
setAllPreheats(jobs.data);
65+
setPreheatTotalPages(jobs.total_page || 1);
66+
67+
const states = jobs.data.filter(
68+
(obj) => obj.result.State !== 'SUCCESS' && obj.result.State !== 'FAILURE',
69+
).length;
6470

65-
const states = jobs.filter((obj) => obj.result.State !== 'SUCCESS' && obj.result.State !== 'FAILURE').length;
6671
states === 0 ? setShouldPoll(false) : setShouldPoll(true);
6772

6873
setIsLoading(false);
@@ -73,23 +78,26 @@ export default function Preheats() {
7378
}
7479
}
7580
})();
76-
}, [status]);
81+
}, [status, preheatPage]);
7782

7883
useEffect(() => {
7984
if (shouldPoll) {
8085
const pollingInterval = setInterval(() => {
8186
const pollPreheat = async () => {
8287
try {
8388
const jobs = await getJobs({
84-
page: 1,
85-
per_page: MAX_PAGE_SIZE,
89+
page: preheatPage,
90+
per_page: DEFAULT_PAGE_SIZE,
8691
state: status === 'ALL' ? undefined : status,
8792
});
88-
setAllPreheats(jobs.sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime()));
8993

90-
const states = jobs.filter(
94+
setAllPreheats(jobs.data);
95+
setPreheatTotalPages(jobs.total_page || 1);
96+
97+
const states = jobs.data.filter(
9198
(obj) => obj.result.State !== 'SUCCESS' && obj.result.State !== 'FAILURE',
9299
).length;
100+
93101
states === 0 ? setShouldPoll(false) : setShouldPoll(true);
94102
} catch (error) {
95103
if (error instanceof Error) {
@@ -106,7 +114,7 @@ export default function Preheats() {
106114
clearInterval(pollingInterval);
107115
};
108116
}
109-
}, [status, shouldPoll]);
117+
}, [status, shouldPoll, preheatPage]);
110118

111119
const statusList = [
112120
{ lable: 'Pending', name: 'PENDING' },
@@ -115,9 +123,6 @@ export default function Preheats() {
115123
{ lable: 'Failure', name: 'FAILURE' },
116124
];
117125

118-
const totalPage = Math.ceil(allPreheats.length / DEFAULT_PAGE_SIZE);
119-
const currentPageData = getPaginatedList(allPreheats, preheatPage, DEFAULT_PAGE_SIZE);
120-
121126
const changeStatus = (event: any) => {
122127
setStatus(event.target.value);
123128
setShouldPoll(true);
@@ -209,15 +214,15 @@ export default function Preheats() {
209214
</FormControl>
210215
</Box>
211216
<Divider />
212-
{currentPageData.length === 0 ? (
217+
{allPreheats.length === 0 ? (
213218
<Box sx={{ height: '4rem', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
214219
You don't have any preheat tasks.
215220
</Box>
216221
) : (
217222
<>
218-
{Array.isArray(currentPageData) &&
219-
currentPageData.map((item, index) => {
220-
return index !== currentPageData.length - 1 ? (
223+
{Array.isArray(allPreheats) &&
224+
allPreheats.map((item, index) => {
225+
return index !== allPreheats.length - 1 ? (
221226
<Box key={item.id}>
222227
<Box sx={{ display: 'flex', p: '0.8rem', alignItems: 'center' }}>
223228
<Box sx={{ display: 'flex', alignItems: 'flex-start', width: '60%' }}>
@@ -365,10 +370,10 @@ export default function Preheats() {
365370
</>
366371
)}
367372
</Paper>
368-
{totalPage > 1 ? (
373+
{preheatTotalPages > 1 ? (
369374
<Box display="flex" justifyContent="flex-end" sx={{ marginTop: theme.spacing(2) }}>
370375
<Pagination
371-
count={totalPage}
376+
count={preheatTotalPages}
372377
onChange={(_event: any, newPage: number) => {
373378
setPreheatPage(newPage);
374379
}}

src/lib/api.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import queryString from 'query-string';
2+
import { parseLinkHeader } from '@web3-storage/parse-link-header';
23

34
const API_URL = process.env.REACT_APP_API_URL || window.location.href;
45

@@ -655,7 +656,7 @@ interface getJobsParams {
655656
state?: string;
656657
}
657658

658-
export interface getJobsResponse {
659+
export interface JobsResponse {
659660
id: number;
660661
created_at: string;
661662
updated_at: string;
@@ -689,13 +690,23 @@ export interface getJobsResponse {
689690
};
690691
}
691692

692-
export async function getJobs(params?: getJobsParams): Promise<getJobsResponse[]> {
693+
interface getJobsResponse {
694+
data: JobsResponse[];
695+
total_page?: number;
696+
}
697+
698+
export async function getJobs(params?: getJobsParams): Promise<getJobsResponse> {
693699
const url = params
694700
? new URL(`/api/v1/jobs?${queryString.stringify(params)}`, API_URL)
695701
: new URL('/api/v1/jobs', API_URL);
696702

697703
const response = await get(url);
698-
return await response.json();
704+
const data = await response.json();
705+
const linkHeader = response.headers.get('link');
706+
const links = parseLinkHeader(linkHeader || null);
707+
const totalPage = Number(links?.last?.page);
708+
const responses = { data: data, total_page: totalPage };
709+
return responses;
699710
}
700711

701712
interface getJobResponse {

0 commit comments

Comments
 (0)