// Adapted from the original A2A ProgressPage's ledger summary, table and detail rail. // Counts describe persisted local tasks and records, with no inferred discovery/coverage states. import { useMemo, useState } from 'react'; import { Button, Select } from 'antd'; import { RefreshCw } from 'lucide-react'; import { EmptyState, ResourceState } from '../components/States'; import { platformLabels, StatusTag, formatTime, useResource } from '../components/common'; import type { LearningTask, Overview, PageResult } from '../types'; export function ProgressPage({ navigate }: { navigate: (path: string) => void }) { const resource = useResource('/learning/overview'); const taskResource = useResource>('/learning/tasks'); const [selected, setSelected] = useState('all'); const campaigns = taskResource.data?.items || []; const platforms = useMemo(() => [...new Set(campaigns.map(item => item.platform))], [campaigns]); const filtered = selected === 'all' ? campaigns : campaigns.filter(item => item.platform === selected); const data = resource.data; const refresh = () => { void resource.reload(); void taskResource.reload(); }; return

账本总览

{data ? `${data.tasks} 个批次 · ${data.candidates} 个候选 · ${data.validations} 条验证` : '查看持久化的学习与验证记录'}

{data && taskResource.data && !resource.error && !taskResource.error && <>

各平台学习批次

按实际任务状态统计
{platforms.map(platform => { const rows = campaigns.filter(item => item.platform === platform); return ; })}
来源平台批次总数待开始观察中等待人工登录会话关闭 / 暂停
{platformLabels[platform]}{rows.length}{rows.filter(item => ['draft', 'created'].includes(item.status)).length}{rows.filter(item => ['observing', 'ready'].includes(item.status)).length}{rows.filter(item => ['awaiting_user', 'waiting_login'].includes(item.status)).length}{rows.filter(item => ['closed', 'paused'].includes(item.status)).length}

学习入口