import { ExternalLink } from "lucide-react"; import { Link } from "react-router"; import type { TimelineEvent, TimelineStage } from "~/api/tasks.ts"; import { LoadingState } from "~/components/console/empty-state.tsx"; import { StatusBadge } from "~/components/console/status-badge.tsx"; import { Timeline } from "~/components/console/timeline.tsx"; // 业务时间线(参考 MovieClaw task-activity):把观察 → 计划 → 下载 → 整理 → Agent 串成一个业务过程, // 阶段计数与首页/侧栏同口径;每条事件都有文字说明,不只靠颜色。 export const STAGE_LABEL: Record = { observation: "发现", plan: "准备", download: "下载", organization: "整理", agent: "智能体", engine: "任务", }; const ORDER: TimelineStage[] = ["observation", "plan", "download", "organization", "agent", "engine"]; export function BusinessTimeline({ events, loading }: { events: TimelineEvent[]; loading?: boolean }) { const counts = new Map(); for (const e of events) counts.set(e.stage, (counts.get(e.stage) ?? 0) + 1); const ongoing = events.filter((e) => e.ongoing); return (
{ORDER.filter((s) => counts.get(s)).map((s) => { const bad = events.some((e) => e.stage === s && e.tone === "destructive"); return ( {STAGE_LABEL[s]} · {counts.get(s)} ); })}
{ongoing.length ? (

当前:{ongoing.map((e) => e.title).join(";")}

) : null} {loading && !events.length ? ( ) : ( ({ id: e.key, at: e.at, tone: e.tone, meta: STAGE_LABEL[e.stage], title: e.href ? ( {e.title} ) : ( e.title ), description: e.detail ?? undefined, }))} /> )} {loading && events.length ? (

加载整理记录和引擎运行…

) : null}
); }