From 1c6342d8b33454bdda49e70019c52fcd726d8a74 Mon Sep 17 00:00:00 2001 From: RuoJi6 <79234113+RuoJi6@users.noreply.github.com> Date: Wed, 16 Sep 2026 22:13:08 +0800 Subject: [PATCH] fix(approvals): load pending requests independently of history pagination (#133) --- web/src/components/approval-records.tsx | 46 ++++++++++++++++++++----- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/web/src/components/approval-records.tsx b/web/src/components/approval-records.tsx index c4b2d34..eff3902 100644 --- a/web/src/components/approval-records.tsx +++ b/web/src/components/approval-records.tsx @@ -24,7 +24,7 @@ import { Empty, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "@/ import { Skeleton } from "@/components/ui/skeleton"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { api } from "@/lib/api"; -import type { InterceptApprovalRow, InterceptAudit, InterceptDetail, InterceptReviewInput } from "@/lib/types"; +import type { InterceptApprovalRow, InterceptAudit, InterceptDetail, InterceptPending, InterceptReviewInput } from "@/lib/types"; import { cn } from "@/lib/utils"; function fmtTime(value?: string) { @@ -640,12 +640,14 @@ function ApprovalTable({ export function ApprovalRecords({ taskId }: { taskId?: string }) { const [rows, setRows] = React.useState([]); + const [pendingRows, setPendingRows] = React.useState([]); const [page, setPage] = React.useState(1); const [pageSize, setPageSize] = React.useState(20); const [total, setTotal] = React.useState(0); const [loading, setLoading] = React.useState(true); const [refreshing, setRefreshing] = React.useState(false); const [error, setError] = React.useState(""); + const [pendingError, setPendingError] = React.useState(""); const [deciding, setDeciding] = React.useState(false); const [revision, setRevision] = React.useState(0); const request = React.useRef(0); @@ -663,13 +665,26 @@ export function ApprovalRecords({ taskId }: { taskId?: string }) { const id = ++request.current; if (manual) setRefreshing(true); try { - const result = taskId - ? await api.interceptTaskPage(taskId, page, pageSize) - : await api.interceptHistoryPage(page, pageSize); + // The approval queue is independent of the current history page. Older + // requests must remain actionable even when newer decisions fill it. + const [history, pending] = await Promise.allSettled([ + taskId ? api.interceptTaskPage(taskId, page, pageSize) : api.interceptHistoryPage(page, pageSize), + api.interceptPending(), + ]); if (id !== request.current) return; - setRows(result.items); - setTotal(result.total); - setError(""); + if (history.status === "fulfilled") { + setRows(history.value.items); + setTotal(history.value.total); + setError(""); + } else { + setError((history.reason as Error).message || "加载失败"); + } + if (pending.status === "fulfilled") { + setPendingRows(pending.value); + setPendingError(""); + } else { + setPendingError((pending.reason as Error).message || "加载失败"); + } if (manual) setRevision((v) => v + 1); } catch (e) { if (id === request.current) setError((e as Error).message || "加载失败"); @@ -708,6 +723,7 @@ export function ApprovalRecords({ taskId }: { taskId?: string }) { setRows((prev) => prev.map((row) => (row.id === id ? { ...row, status: decision, decided_at: new Date().toISOString() } : row)), ); + setPendingRows((prev) => prev.filter((row) => row.id !== id)); setRevision((v) => v + 1); toast.success(decision === "allowed" ? "已允许执行" : "已拒绝执行"); } catch (e) { @@ -719,7 +735,16 @@ export function ApprovalRecords({ taskId }: { taskId?: string }) { } }; - const pending = rows.filter((row) => row.status === "pending"); + const historyById = new Map(rows.map((row) => [row.id, row])); + const pending: InterceptApprovalRow[] = pendingRows + .filter((row) => !taskId || row.task_id === taskId) + .map((row) => ({ + conv_title: "", + conv_agent_key: "", + rule_name: row.rule_id ? `规则 #${row.rule_id}` : "", + ...historyById.get(row.id), + ...row, + })); const title = taskId ? "拦截审批" : "审批记录"; return (
@@ -740,6 +765,11 @@ export function ApprovalRecords({ taskId }: { taskId?: string }) { 记录加载失败:{error}。请点击刷新重试。 ) : null} + {pendingError ? ( + + 待审批加载失败:{pendingError}。请点击刷新重试。 + + ) : null} {pending.length ? (