Files
openclaw-taskboard/components/failure-queue.tsx

50 lines
1.8 KiB
TypeScript

import { Badge } from "@/components/ui/badge";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import type { TaskRecord } from "@/lib/types";
export function FailureQueue({
failedTasks,
}: {
failedTasks: TaskRecord[];
}) {
return (
<Card>
<CardHeader>
<CardTitle>Failure Queue</CardTitle>
<CardDescription>
Tasks with failed dispatch state that still need operator review or retry.
</CardDescription>
</CardHeader>
<CardContent className="space-y-3">
{failedTasks.length === 0 ? (
<p className="text-sm text-slate-400">No failed dispatches recorded.</p>
) : (
failedTasks.map((task) => (
<div className="rounded-xl border border-amber-400/20 bg-amber-400/5 p-4" key={task.id}>
<div className="flex flex-wrap items-center justify-between gap-3">
<div className="min-w-0">
<p className="font-medium text-white">{task.title}</p>
<p className="text-sm text-slate-400">
{task.assignee || "Unassigned"} {task.target_host || "n/a"}
</p>
</div>
<Badge variant="warning">{task.dispatch_state}</Badge>
</div>
<p className="mt-2 break-words text-sm text-slate-300">
{task.last_error || "No error text captured."}
</p>
<div className="mt-3 flex flex-wrap gap-2">
{task.tags.map((tag) => (
<Badge key={tag} variant="outline">
{tag}
</Badge>
))}
</div>
</div>
))
)}
</CardContent>
</Card>
);
}