auto-sync: 2026-05-19 15:32:44

This commit is contained in:
cfdaily
2026-05-19 15:32:44 +08:00
parent 3b7fa354b1
commit e51a6e0d3a
+21 -10
View File
@@ -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>