fix: paginate operational list pages
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Fragment, useEffect, useMemo, useState } from 'react';
|
||||
import { Fragment, useEffect, useState } from 'react';
|
||||
import { Clock3, Eye, FileText, Search, StopCircle } from 'lucide-react';
|
||||
import {
|
||||
Button,
|
||||
@@ -99,6 +99,8 @@ export function ClientBatchTasksPage() {
|
||||
const [tasks, setTasks] = useState<BatchTask[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState('');
|
||||
const [total, setTotal] = useState(0);
|
||||
const [applications, setApplications] = useState<Array<{ id: string; name: string }>>([]);
|
||||
const [keyword, setKeyword] = useState('');
|
||||
const [application, setApplication] = useState('all');
|
||||
const [submittedDateRange, setSubmittedDateRange] = useState<DateRangeValue>({});
|
||||
@@ -106,11 +108,21 @@ export function ClientBatchTasksPage() {
|
||||
const [page, setPage] = useState(1);
|
||||
const [selectedTask, setSelectedTask] = useState<BatchTask | null>(null);
|
||||
|
||||
function loadTasks() {
|
||||
const pageSize = 10;
|
||||
|
||||
function loadTasks(targetPage = page) {
|
||||
setLoading(true);
|
||||
clientApi.listBatchTasks()
|
||||
.then((items) => {
|
||||
setTasks(items.map(mapTask));
|
||||
clientApi.listBatchTasksPage({
|
||||
keyword: keyword.trim() || undefined,
|
||||
applicationKeyword: application === 'all' ? undefined : application,
|
||||
createdAtFrom: submittedDateRange.start,
|
||||
createdAtTo: submittedDateRange.end,
|
||||
page: targetPage,
|
||||
pageSize,
|
||||
})
|
||||
.then((result) => {
|
||||
setTasks(result.items.map(mapTask));
|
||||
setTotal(result.total);
|
||||
setError('');
|
||||
})
|
||||
.catch((reason: Error) => setError(reason.message || '批量任务加载失败'))
|
||||
@@ -118,39 +130,28 @@ export function ClientBatchTasksPage() {
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
loadTasks();
|
||||
}, []);
|
||||
|
||||
const applicationOptions = useMemo(() => {
|
||||
const names = Array.from(new Set(tasks.map((item) => item.applicationName)));
|
||||
return [
|
||||
{ label: '全部应用', value: 'all' },
|
||||
...names.map((name) => ({ label: name, value: name })),
|
||||
];
|
||||
}, [tasks]);
|
||||
|
||||
const filteredTasks = tasks.filter((item) => {
|
||||
const matchesKeyword = !keyword || item.id.includes(keyword);
|
||||
const matchesApplication = application === 'all' || item.applicationName === application;
|
||||
const submittedDate = item.submittedAt.slice(0, 10);
|
||||
const matchesStartDate = !submittedDateRange.start || submittedDate >= submittedDateRange.start;
|
||||
const matchesEndDate = !submittedDateRange.end || submittedDate <= submittedDateRange.end;
|
||||
return matchesKeyword && matchesApplication && matchesStartDate && matchesEndDate;
|
||||
});
|
||||
const pageSize = 10;
|
||||
const totalPages = Math.max(1, Math.ceil(filteredTasks.length / pageSize));
|
||||
const currentPage = Math.min(page, totalPages);
|
||||
const visibleTasks = filteredTasks.slice((currentPage - 1) * pageSize, currentPage * pageSize);
|
||||
loadTasks(page);
|
||||
}, [page]);
|
||||
|
||||
useEffect(() => {
|
||||
setPage(1);
|
||||
}, [application, keyword, submittedDateRange.end, submittedDateRange.start, tasks.length]);
|
||||
clientApi.listApplicationOptions()
|
||||
.then((items) => setApplications(items.map((item) => ({ id: item.id, name: item.name }))))
|
||||
.catch(() => undefined);
|
||||
}, []);
|
||||
|
||||
const applicationOptions = [
|
||||
{ label: '全部应用', value: 'all' },
|
||||
...applications.map((item) => ({ label: item.name, value: item.name })),
|
||||
];
|
||||
const totalPages = Math.max(1, Math.ceil(total / pageSize));
|
||||
const currentPage = Math.min(page, totalPages);
|
||||
const visibleTasks = tasks;
|
||||
|
||||
function terminateTask(id: string) {
|
||||
const source = tasks.find((item) => item.id === id);
|
||||
if (!source) return;
|
||||
clientApi.cancelBatchTask(source.backendId)
|
||||
.then(loadTasks)
|
||||
.then(() => loadTasks(page))
|
||||
.catch((reason: Error) => setError(reason.message || '发送批次终止失败'));
|
||||
}
|
||||
|
||||
@@ -236,17 +237,24 @@ export function ClientBatchTasksPage() {
|
||||
|
||||
<QueryPanel
|
||||
title="查询条件"
|
||||
summary={<>共找到 <strong>{filteredTasks.length}</strong> 个发送批次</>}
|
||||
summary={<>共找到 <strong>{total}</strong> 个发送批次</>}
|
||||
>
|
||||
<Input
|
||||
label="发送批次号"
|
||||
onChange={(event) => setKeyword(event.target.value)}
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === 'Enter') {
|
||||
setPage(1);
|
||||
loadTasks(1);
|
||||
}
|
||||
}}
|
||||
placeholder="输入发送批次号搜索"
|
||||
prefix={<Search size={16} />}
|
||||
value={keyword}
|
||||
/>
|
||||
<Select label="选择应用" onChange={(event) => setApplication(event.target.value)} options={applicationOptions} value={application} />
|
||||
<DateRangeInput label="提交时间" onChange={setSubmittedDateRange} value={submittedDateRange} />
|
||||
<Button onClick={() => { setPage(1); loadTasks(1); }} variant="primary">查询</Button>
|
||||
</QueryPanel>
|
||||
|
||||
<div className="surface batch-table-card">
|
||||
@@ -301,7 +309,7 @@ export function ClientBatchTasksPage() {
|
||||
totalPages={totalPages}
|
||||
onPageChange={setPage}
|
||||
previousDisabled={currentPage <= 1}
|
||||
total={filteredTasks.length}
|
||||
total={total}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user