diff --git a/apps/admin-web/src/api/adminApiClient.ts b/apps/admin-web/src/api/adminApiClient.ts index 5155a2470..6673b98be 100644 --- a/apps/admin-web/src/api/adminApiClient.ts +++ b/apps/admin-web/src/api/adminApiClient.ts @@ -280,6 +280,7 @@ export function listAdminErrorReports( fingerprint?: string; source?: string; limit?: number; + offset?: number; } = {}, ) { return request( @@ -866,6 +867,7 @@ function buildErrorReportQueryString(query: { fingerprint?: string; source?: string; limit?: number; + offset?: number; }) { const params = new URLSearchParams(); appendQueryParam(params, 'status', query.status); @@ -874,6 +876,9 @@ function buildErrorReportQueryString(query: { if (typeof query.limit === 'number' && Number.isFinite(query.limit)) { params.set('limit', String(query.limit)); } + if (typeof query.offset === 'number' && Number.isFinite(query.offset)) { + params.set('offset', String(query.offset)); + } const queryString = params.toString(); return queryString ? `?${queryString}` : ''; } diff --git a/apps/admin-web/src/api/adminApiTypes.ts b/apps/admin-web/src/api/adminApiTypes.ts index c2f9b3b52..b911a6e8b 100644 --- a/apps/admin-web/src/api/adminApiTypes.ts +++ b/apps/admin-web/src/api/adminApiTypes.ts @@ -116,6 +116,10 @@ export interface AdminErrorReportEntry { export interface AdminErrorReportListResponse { reports: AdminErrorReportEntry[]; + total: number; + offset: number; + limit: number; + hasMore: boolean; } export interface AdminErrorReportDetail extends AdminErrorReportEntry { diff --git a/apps/admin-web/src/pages/AdminErrorReportsPage.tsx b/apps/admin-web/src/pages/AdminErrorReportsPage.tsx index 0ac7f508c..4c2f323e8 100644 --- a/apps/admin-web/src/pages/AdminErrorReportsPage.tsx +++ b/apps/admin-web/src/pages/AdminErrorReportsPage.tsx @@ -16,6 +16,7 @@ import type { type Props = { token: string; onUnauthorized: (message?: string) => void }; const ADMIN_ERROR_REPORT_STATUSES = ['new', 'in-progress', 'resolved'] as const; +const ERROR_REPORT_PAGE_SIZE = 50; export function AdminErrorReportsPage({ token, onUnauthorized }: Props) { const [reports, setReports] = useState([]); @@ -23,6 +24,8 @@ export function AdminErrorReportsPage({ token, onUnauthorized }: Props) { const [status, setStatus] = useState(''); const [busy, setBusy] = useState(false); const [filterStatus, setFilterStatus] = useState(''); + const [pageOffset, setPageOffset] = useState(0); + const [pageInfo, setPageInfo] = useState({ total: 0, hasMore: false }); const openReportRequestId = useRef(0); const loadRequestId = useRef(0); @@ -32,15 +35,20 @@ export function AdminErrorReportsPage({ token, onUnauthorized }: Props) { try { const response = await listAdminErrorReports(token, { status: filterStatus || undefined, + limit: ERROR_REPORT_PAGE_SIZE, + offset: pageOffset, }); - if (requestId === loadRequestId.current) setReports(response.reports); + if (requestId === loadRequestId.current) { + setReports(response.reports); + setPageInfo({ total: response.total, hasMore: response.hasMore }); + } } catch (error) { if (requestId !== loadRequestId.current) return; if (isAdminApiError(error) && error.status === 401) return onUnauthorized(); setStatus(formatAdminApiError(error)); } - }, [filterStatus, onUnauthorized, token]); + }, [filterStatus, onUnauthorized, pageOffset, token]); useEffect(() => { void load(); @@ -109,7 +117,10 @@ export function AdminErrorReportsPage({ token, onUnauthorized }: Props) { 状态{' '}