import { Clock, RefreshCw, ChevronRight, Check, X, Minus } from 'lucide-react'; import type { SchedulerJobSummary, SchedulerJobSessionLookup } from '../../types/protocol'; interface SchedulerJobListProps { jobs: SchedulerJobSummary[]; onRefresh: () => void; onViewJob: (lookup: SchedulerJobSessionLookup, jobId: string, description: string) => void; sessionId: string | null; } function kindLabel(kind: string): string { const map: Record = { internal_event: '内部事件', outbound_message: '外发消息', agent_task: '智能体', silent_agent_task: '静默智能体', }; return map[kind] ?? kind; } function stateBadge(state: string): { label: string; color: string; pulse: boolean } { switch (state) { case 'running': return { label: '执行中', color: 'bg-[var(--accent-amber)]/15 text-[var(--accent-amber)] border-[var(--accent-amber)]/30', pulse: true, }; case 'scheduled': return { label: '已调度', color: 'bg-[var(--accent-amber)]/10 text-[var(--accent-amber)] border-[var(--accent-amber)]/20', pulse: false, }; case 'paused': return { label: '已暂停', color: 'bg-[var(--overlay-dim)] text-[var(--text-muted)] border-[var(--border-color)]', pulse: false, }; case 'completed': return { label: '已完成', color: 'bg-[var(--accent-green)]/15 text-[var(--accent-green)] border-[var(--accent-green)]/30', pulse: false, }; default: return { label: state, color: 'bg-[var(--overlay-dim)] text-[var(--text-muted)] border-[var(--border-color)]', pulse: false, }; } } function formatTime(tsMillis: number | undefined): string { if (tsMillis == null) return '--'; const d = new Date(tsMillis); return d.toLocaleString('zh-CN', { month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', }); } function scheduleDescription(schedule: unknown): string { if (!schedule || typeof schedule !== 'object') return '--'; const s = schedule as Record; switch (s.type) { case 'cron': return `Cron: ${s.expression}`; case 'interval': return `每 ${s.seconds} 秒`; case 'delay': return `延迟 ${s.seconds} 秒`; case 'at': return `定时: ${s.timestamp}`; default: return JSON.stringify(s); } } function lastStatusIcon(lastStatus: string | undefined) { switch (lastStatus) { case 'ok': return ; case 'error': return ; default: return ; } } export function SchedulerJobList({ jobs, onRefresh, onViewJob, sessionId }: SchedulerJobListProps) { return (
{/* Header */}

定时任务 {jobs.length > 0 && ( ({jobs.length}) )}

{/* Job List */}
{!sessionId ? (

等待连接...

) : jobs.length === 0 ? (

暂无定时任务

) : (
{jobs.map((job) => { const badge = stateBadge(job.state); const hasLookup = !!job.session_lookup; return ( ); })}
)}
); }