auto-sync: 2026-05-19 15:32:44
This commit is contained in:
@@ -288,24 +288,35 @@ export default function CheckpointPanel({
|
||||
onDone: () => void;
|
||||
}) {
|
||||
const [checkpoints, setCheckpoints] = useState<Checkpoint[]>([]);
|
||||
const [activeIdx, setActiveIdx] = useState(0);
|
||||
const [pendingIdx, setPendingIdx] = useState(0);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const pid = getProjectId();
|
||||
if (!pid) return;
|
||||
if (!pid) { setLoading(false); return; }
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
fetch(`/api/projects/${pid}/tasks/${taskId}/checkpoints`)
|
||||
.then(r => r.json())
|
||||
.then(d => setCheckpoints(d.checkpoints || []))
|
||||
.catch(() => {});
|
||||
.then(d => { setCheckpoints(d.checkpoints || []); setLoading(false); })
|
||||
.catch(() => { setError('加载失败'); setLoading(false); });
|
||||
}, [taskId]);
|
||||
|
||||
const cp = checkpoints[activeIdx];
|
||||
if (!cp) return null;
|
||||
if (loading) return <div style={{ fontSize: 12, color: 'var(--muted)', textAlign: 'center', padding: 20 }}>加载中...</div>;
|
||||
if (error) return (
|
||||
<div style={{ fontSize: 12, color: '#ef4444', textAlign: 'center', padding: 20 }}>
|
||||
<div>{error}</div>
|
||||
<button onClick={() => setCheckpoints([]) || setLoading(true)} style={{ marginTop: 8, fontSize: 11, padding: '4px 12px', borderRadius: 4, border: '1px solid var(--line)', background: 'transparent', color: 'var(--fg)', cursor: 'pointer' }}>重试</button>
|
||||
</div>
|
||||
);
|
||||
|
||||
// 只显示 pending 的
|
||||
// 只显示 pending 的(BUG-34: 直接基于 pendingCps 管理索引)
|
||||
const pendingCps = checkpoints.filter(c => c.status === 'pending');
|
||||
const activeCp = pendingCps[activeIdx] || pendingCps[0];
|
||||
if (!activeCp) return <div style={{ fontSize: 12, color: 'var(--muted)', textAlign: 'center', padding: 20 }}>所有 Checkpoint 已处理</div>;
|
||||
if (pendingCps.length === 0) return <div style={{ fontSize: 12, color: 'var(--muted)', textAlign: 'center', padding: 20 }}>所有 Checkpoint 已处理</div>;
|
||||
|
||||
const activeCp = pendingCps[pendingIdx] || pendingCps[0];
|
||||
const activeIdx = pendingCps.indexOf(activeCp);
|
||||
|
||||
const typeIcon = activeCp.type === 'verify' ? '🔍' : activeCp.type === 'decision' ? '🎯' : '🔧';
|
||||
const typeColor = activeCp.type === 'verify' ? '#6a9eff' : activeCp.type === 'decision' ? '#818cf8' : '#f59e0b';
|
||||
@@ -318,7 +329,7 @@ export default function CheckpointPanel({
|
||||
<div style={{ display: 'flex', borderBottom: '1px solid var(--line)', marginBottom: 12 }}>
|
||||
{pendingCps.map((c, i) => (
|
||||
<button key={c.id}
|
||||
onClick={() => setActiveIdx(i)}
|
||||
onClick={() => setPendingIdx(i)}
|
||||
style={{ fontSize: 12, padding: '6px 12px', border: 'none', background: 'transparent', cursor: 'pointer',
|
||||
color: i === activeIdx ? typeColor : 'var(--muted)', borderBottom: `2px solid ${i === activeIdx ? typeColor : 'transparent'}` }}
|
||||
>{typeIcon} {c.title}</button>
|
||||
|
||||
Reference in New Issue
Block a user