"use client"; import { IconAlertTriangle, IconCheck, IconCircleDashed, IconClockHour4, IconLoader2, type Icon as TablerIcon, } from "@tabler/icons-react"; import type { TFunction } from "i18next"; import { useTranslation } from "react-i18next"; import type { RemoteExecutorStatusData } from "@/hooks/domains/session/remote-executor-status-resource"; import { getExecutorLabel, getExecutorStatusIcon } from "@/lib/executor-icons"; import { cn, formatRelativeTime } from "@/lib/utils"; type StatusRow = { testId: string; label: string; value: string; Icon: TablerIcon; tone: string; technical?: boolean; tabular?: boolean; }; const DEFAULT_TONE = "text-foreground"; function statusPresentation(status: RemoteExecutorStatusData | null, loading: boolean) { if (status?.remote_status_error) { return { Icon: IconAlertTriangle, tone: "text-red-600 dark:text-red-400" }; } const state = status?.remote_state?.toLowerCase(); if (state === "running" || state === "ready" || state === "connected") { return { Icon: IconCheck, tone: "text-emerald-600 dark:text-emerald-400" }; } if ( state === "pending" || state === "starting" || state === "provisioning" || state === "waiting" ) { return { Icon: IconClockHour4, tone: "text-amber-600 dark:text-amber-400" }; } if (loading) return { Icon: IconLoader2, tone: "text-muted-foreground" }; return { Icon: IconCircleDashed, tone: "text-muted-foreground" }; } function SummaryRow({ row }: { row: StatusRow }) { const { Icon } = row; return (
{row.label}
); } function statusRows( status: RemoteExecutorStatusData | null, loading: boolean, t: TFunction, ): StatusRow[] { const presentation = statusPresentation(status, loading); const rows: StatusRow[] = [ { testId: "remote-executor-status-state", label: t("task:status"), value: status?.remote_state ?? (loading ? t("task:loadingStatus") : t("task:executorEnvironmentIsUnavailable")), ...presentation, }, ]; if (status?.remote_restarts !== undefined) { rows.push({ testId: "remote-executor-status-restarts", label: t("task:restarts"), value: String(status.remote_restarts), Icon: IconCircleDashed, tone: DEFAULT_TONE, tabular: true, }); } if (status?.remote_workspace_kind) { rows.push({ testId: "remote-executor-status-workspace", label: t("task:workspaceMode"), value: status.remote_workspace_kind, Icon: IconCircleDashed, tone: DEFAULT_TONE, technical: true, }); } if (status?.remote_created_at) { rows.push({ testId: "remote-executor-status-created", label: t("task:created"), value: formatRelativeTime(status.remote_created_at), Icon: IconClockHour4, tone: DEFAULT_TONE, }); } if (status?.remote_checked_at) { rows.push({ testId: "remote-executor-status-checked", label: t("task:remoteLastCheck"), value: formatRelativeTime(status.remote_checked_at), Icon: IconClockHour4, tone: DEFAULT_TONE, }); } if (status?.remote_status_error) { rows.push({ testId: "remote-executor-status-error", label: t("task:error"), value: status.remote_status_error, Icon: IconAlertTriangle, tone: "text-red-600 dark:text-red-400", }); } return rows; } export function RemoteExecutorTaskStatusSummary({ executorType, remoteName, status, loading, }: { executorType?: string | null; remoteName: string; status: RemoteExecutorStatusData | null; loading: boolean; }) { const { t } = useTranslation(); const icon = getExecutorStatusIcon(executorType, Boolean(status?.remote_status_error)); const Icon = icon.Icon; const rows = statusRows(status, loading, t); return (
{rows.map((row) => ( ))}
); }