mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
- The Orchestrator card showed red 'Stopped' whenever zero agents were running, even though the service was healthy (it read total_agents > 0). Base Running/Stopped on whether the status query resolves; agent count is already shown in its own card. - The human CEO leaked into the Board agent grid (its record carries team=board). Exclude the ceo role from getBoardAgents — the CEO is the operator, not a spawnable agent.
81 lines
3.1 KiB
TypeScript
81 lines
3.1 KiB
TypeScript
import { OrchestratorStatus as OrchestratorStatusType } from "@/types";
|
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
import { Badge } from "@/components/ui/badge";
|
|
import { Skeleton } from "@/components/ui/skeleton";
|
|
import { Server, Users, Clock, Activity } from "lucide-react";
|
|
|
|
interface OrchestratorStatusCardsProps {
|
|
status: OrchestratorStatusType | undefined;
|
|
isLoading: boolean;
|
|
}
|
|
|
|
export function OrchestratorStatusCards({ status, isLoading }: OrchestratorStatusCardsProps) {
|
|
// Calculate running agents from by_state
|
|
const runningCount = status?.by_state?.running || 0;
|
|
const readyCount = status?.by_state?.ready || 0;
|
|
const activeCount = runningCount + readyCount;
|
|
// The orchestrator service is up whenever its status query resolves — agent
|
|
// count is shown separately in the cards below. (Previously this read
|
|
// `total_agents > 0`, so an idle-but-healthy orchestrator showed "Stopped".)
|
|
const isRunning = status !== undefined;
|
|
|
|
return (
|
|
<div className="grid gap-4 md:grid-cols-4">
|
|
<Card>
|
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
|
<CardTitle className="text-sm font-medium">Orchestrator</CardTitle>
|
|
<Server className="h-4 w-4 text-muted-foreground" />
|
|
</CardHeader>
|
|
<CardContent>
|
|
{isLoading ? (
|
|
<Skeleton className="h-8 w-24" />
|
|
) : (
|
|
<Badge className={isRunning ? "bg-green-500" : "bg-red-500"}>
|
|
{isRunning ? "Running" : "Stopped"}
|
|
</Badge>
|
|
)}
|
|
</CardContent>
|
|
</Card>
|
|
<Card>
|
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
|
<CardTitle className="text-sm font-medium">Total Agents</CardTitle>
|
|
<Users className="h-4 w-4 text-muted-foreground" />
|
|
</CardHeader>
|
|
<CardContent>
|
|
{isLoading ? (
|
|
<Skeleton className="h-8 w-12" />
|
|
) : (
|
|
<div className="text-2xl font-bold">{status?.total_agents || 0}</div>
|
|
)}
|
|
</CardContent>
|
|
</Card>
|
|
<Card>
|
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
|
<CardTitle className="text-sm font-medium">Active</CardTitle>
|
|
<Activity className="h-4 w-4 text-muted-foreground" />
|
|
</CardHeader>
|
|
<CardContent>
|
|
{isLoading ? (
|
|
<Skeleton className="h-8 w-12" />
|
|
) : (
|
|
<div className="text-2xl font-bold">{activeCount}</div>
|
|
)}
|
|
</CardContent>
|
|
</Card>
|
|
<Card>
|
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
|
<CardTitle className="text-sm font-medium">Waiting</CardTitle>
|
|
<Clock className="h-4 w-4 text-muted-foreground" />
|
|
</CardHeader>
|
|
<CardContent>
|
|
{isLoading ? (
|
|
<Skeleton className="h-8 w-12" />
|
|
) : (
|
|
<div className="text-2xl font-bold">{status?.waiting_count || 0}</div>
|
|
)}
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|