"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}
{row.value}
);
}
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 (
{getExecutorLabel(executorType ?? "")}
{remoteName}
{loading ? (
) : null}
{rows.map((row) => (
))}
);
}