import { useState } from 'react'; import { ChevronDown, ChevronRight, FileText } from './Icons'; import { CATEGORY_LABEL, STATUS_LABEL, type LearnedEntry, type Task } from '../types'; function screenshotUrl(path: string): string { return `file:///${path.replace(/\\/g, '/')}?t=${Date.now()}`; } export function TaskCard({ task, timeline, learned, operatorMode, embedded, onOpenDoc, onLearned }: { task: Task; timeline: string[]; learned: LearnedEntry[]; operatorMode: boolean; embedded: boolean; onOpenDoc: () => void; onLearned: (id: number, action: 'verify' | 'reject') => void; }) { const [showTimeline, setShowTimeline] = useState(false); const tracking = task.artifacts.tracking; const last = tracking?.history?.[tracking.history.length - 1]; const reasonLabel = task.status === 'failed' ? '原因' : task.status === 'blocked' ? '阻断' : task.status === 'rejected' ? '驳回' : null; return (
{task.business_name ?? '任务'} {STATUS_LABEL[task.status] ?? task.status}
步骤
{task.current_step ?? '-'}
创建
{task.created_at}
{task.status === 'submitted' && (
审批
{last ? `${last.status}(${last.at})` : '待回查'}{task.next_check_at ? `,下次回查 ${task.next_check_at}` : ''}
)} {reasonLabel && task.pause_reason &&
{reasonLabel}
{task.pause_reason.slice(0, 240)}
}
{!embedded && task.latest_screenshot && ( Agent 最近一步的页面截图 )}
{showTimeline && (
    {timeline.slice(-12).map((line, index) =>
  1. {line}
  2. )}
)} {operatorMode && learned.length > 0 && (
沉淀草稿 · 运维模式
)}
); }