auto-sync: 2026-05-19 14:00:04
This commit is contained in:
@@ -282,33 +282,46 @@ function ActionCheckpoint({
|
||||
|
||||
export default function CheckpointPanel({
|
||||
taskId,
|
||||
checkpoints,
|
||||
onDone,
|
||||
}: {
|
||||
taskId: string;
|
||||
checkpoints: CheckpointInfo[];
|
||||
onDone: () => void;
|
||||
}) {
|
||||
const [checkpoints, setCheckpoints] = useState<Checkpoint[]>([]);
|
||||
const [activeIdx, setActiveIdx] = useState(0);
|
||||
const info = checkpoints[activeIdx];
|
||||
if (!info) return null;
|
||||
|
||||
const cp = info.checkpoint;
|
||||
const typeIcon = cp.type === 'verify' ? '🔍' : cp.type === 'decision' ? '🎯' : '🔧';
|
||||
const typeColor = cp.type === 'verify' ? '#6a9eff' : cp.type === 'decision' ? '#818cf8' : '#f59e0b';
|
||||
const typeLabel = cp.type === 'verify' ? '验证 Checkpoint' : cp.type === 'decision' ? '决策 Checkpoint' : '执行 Checkpoint';
|
||||
useEffect(() => {
|
||||
const pid = api._getProjectId();
|
||||
if (!pid) return;
|
||||
fetch(`/api/projects/${pid}/tasks/${taskId}/checkpoints`)
|
||||
.then(r => r.json())
|
||||
.then(d => setCheckpoints(d.checkpoints || []))
|
||||
.catch(() => {});
|
||||
}, [taskId]);
|
||||
|
||||
const cp = checkpoints[activeIdx];
|
||||
if (!cp) return null;
|
||||
|
||||
// 只显示 pending 的
|
||||
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>;
|
||||
|
||||
const typeIcon = activeCp.type === 'verify' ? '🔍' : activeCp.type === 'decision' ? '🎯' : '🔧';
|
||||
const typeColor = activeCp.type === 'verify' ? '#6a9eff' : activeCp.type === 'decision' ? '#818cf8' : '#f59e0b';
|
||||
const typeLabel = activeCp.type === 'verify' ? '验证 Checkpoint' : activeCp.type === 'decision' ? '决策 Checkpoint' : '执行 Checkpoint';
|
||||
|
||||
return (
|
||||
<div>
|
||||
{/* 多节点 Tab */}
|
||||
{checkpoints.length > 1 && (
|
||||
{/* 多 checkpoint Tab */}
|
||||
{pendingCps.length > 1 && (
|
||||
<div style={{ display: 'flex', borderBottom: '1px solid var(--line)', marginBottom: 12 }}>
|
||||
{checkpoints.map((c, i) => (
|
||||
<button key={c.node_id}
|
||||
className={`tab-btn ${i === activeIdx ? 'active' : ''}`}
|
||||
{pendingCps.map((c, i) => (
|
||||
<button key={c.id}
|
||||
onClick={() => setActiveIdx(i)}
|
||||
style={{ fontSize: 12, color: i === activeIdx ? typeColor : 'var(--muted)', borderBottomColor: i === activeIdx ? typeColor : 'transparent' }}
|
||||
>🛐 {c.node_name}</button>
|
||||
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>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
@@ -318,17 +331,16 @@ export default function CheckpointPanel({
|
||||
<div style={{ width: 36, height: 36, borderRadius: '50%', background: `${typeColor}22`, display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 16 }}>{typeIcon}</div>
|
||||
<div>
|
||||
<div style={{ fontSize: 14, fontWeight: 700, color: typeColor }}>{typeLabel}</div>
|
||||
<div style={{ fontSize: 11, color: 'var(--muted)' }}>节点 {info.node_name}({AGENT_EMOJI[info.agent_id] || ''} {info.agent_id})</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 标题 */}
|
||||
<div style={{ fontSize: 15, fontWeight: 700, marginBottom: 6 }}>{cp.title}</div>
|
||||
<div style={{ fontSize: 15, fontWeight: 700, marginBottom: 6 }}>{activeCp.title}</div>
|
||||
|
||||
{/* 按类型渲染 */}
|
||||
{cp.type === 'verify' && <VerifyCheckpoint taskId={taskId} info={info} onDone={onDone} />}
|
||||
{cp.type === 'decision' && <DecisionCheckpoint taskId={taskId} info={info} onDone={onDone} />}
|
||||
{cp.type === 'action' && <ActionCheckpoint taskId={taskId} info={info} onDone={onDone} />}
|
||||
{activeCp.type === 'verify' && <VerifyCheckpoint taskId={taskId} cp={activeCp} onDone={onDone} />}
|
||||
{activeCp.type === 'decision' && <DecisionCheckpoint taskId={taskId} cp={activeCp} onDone={onDone} />}
|
||||
{activeCp.type === 'action' && <ActionCheckpoint taskId={taskId} cp={activeCp} onDone={onDone} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user