import type { ReactNode } from "react"; import { MoreHorizontal, Play } from "lucide-react"; import { Link } from "@/lib/router"; import { AgentIcon } from "@/components/AgentIconPicker"; import { Button } from "@/components/ui/button"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { ToggleSwitch } from "@/components/ui/toggle-switch"; export type RoutineListProjectSummary = { name: string; color?: string | null; }; export type RoutineListAgentSummary = { name: string; icon?: string | null; }; export type RoutineListRowItem = { id: string; title: string; status: string; projectId: string | null; assigneeAgentId: string | null; lastRun?: { triggeredAt?: Date | string | null; status?: string | null; } | null; }; export function formatLastRunTimestamp(value: Date | string | null | undefined) { if (!value) return "Never"; return new Date(value).toLocaleString(); } export function formatRoutineRunStatus(value: string | null | undefined) { if (!value) return null; return value.replaceAll("_", " "); } export function nextRoutineStatus(currentStatus: string, enabled: boolean) { if (currentStatus === "archived" && enabled) return "active"; return enabled ? "active" : "paused"; } export function RoutineListRow({ routine, projectById, agentById, runningRoutineId, statusMutationRoutineId, href, configureLabel = "Edit", managedByLabel, secondaryDetails, runNowButton = false, disableRunNow = false, disableToggle = false, hideArchiveAction = false, onRunNow, onToggleEnabled, onToggleArchived, }: { routine: TRoutine; projectById: Map; agentById: Map; runningRoutineId: string | null; statusMutationRoutineId: string | null; href: string; configureLabel?: string; managedByLabel?: string | null; secondaryDetails?: ReactNode; runNowButton?: boolean; disableRunNow?: boolean; disableToggle?: boolean; hideArchiveAction?: boolean; onRunNow: (routine: TRoutine) => void; onToggleEnabled: (routine: TRoutine, enabled: boolean) => void; onToggleArchived?: (routine: TRoutine) => void; }) { const enabled = routine.status === "active"; const isArchived = routine.status === "archived"; const isStatusPending = statusMutationRoutineId === routine.id; const project = routine.projectId ? projectById.get(routine.projectId) ?? null : null; const agent = routine.assigneeAgentId ? agentById.get(routine.assigneeAgentId) ?? null : null; const isDraft = !isArchived && !routine.assigneeAgentId; const runDisabled = runningRoutineId === routine.id || isArchived || disableRunNow; return (
{routine.title} {(isArchived || routine.status === "paused" || isDraft) ? ( {isArchived ? "archived" : isDraft ? "draft" : "paused"} ) : null} {managedByLabel ? ( {managedByLabel} ) : null}
{routine.projectId ? (project?.name ?? "Unknown project") : "No project"} {agent?.icon ? : null} {routine.assigneeAgentId ? (agent?.name ?? "Unknown agent") : "No default agent"} {formatLastRunTimestamp(routine.lastRun?.triggeredAt)} {routine.lastRun ? ` ยท ${formatRoutineRunStatus(routine.lastRun.status)}` : ""}
{secondaryDetails ? (
{secondaryDetails}
) : null}
{ event.preventDefault(); event.stopPropagation(); }}> {runNowButton ? ( ) : null}
onToggleEnabled(routine, enabled)} disabled={isStatusPending || isArchived || disableToggle} aria-label={enabled ? `Disable ${routine.title}` : `Enable ${routine.title}`} /> {isArchived ? "Archived" : isDraft ? "Draft" : enabled ? "On" : "Off"}
{configureLabel} onRunNow(routine)} > {runningRoutineId === routine.id ? "Running..." : "Run now"} onToggleEnabled(routine, enabled)} disabled={isStatusPending || isArchived || disableToggle} > {enabled ? "Pause" : "Enable"} {!hideArchiveAction && onToggleArchived ? ( onToggleArchived(routine)} disabled={isStatusPending} > {routine.status === "archived" ? "Restore" : "Archive"} ) : null}
); }