import { useNavigate } from "react-router-dom"; import { Play, PencilSimple, X } from "@phosphor-icons/react"; import paths from "@/utils/paths"; import { humanizeCron } from "../utils/cron"; import { useTranslation } from "react-i18next"; // One row of the scheduled-jobs list. Clicking the name navigates to the // run history; CRUD callbacks come from the parent. export default function JobRow({ job, onTrigger, onToggle, onEdit, onDelete }) { const navigate = useNavigate(); const { t, i18n } = useTranslation(); // A job has at most one in-flight run; disable "Run now" while it's queued // or running so users get visible feedback that their click registered and // so the backend dedup never has to drop a manual trigger silently. const inFlight = job.latestRun?.status === "running" || job.latestRun?.status === "queued"; const statusText = job.latestRun ? t(`scheduledJobs.status.${job.latestRun.status}`, job.latestRun.status) : t("scheduledJobs.row.neverRun"); const stop = (handler) => (e) => { e.stopPropagation(); handler(); }; return (
navigate(paths.settings.scheduledJobRuns(job.id))} onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); navigate(paths.settings.scheduledJobRuns(job.id)); } }} className="flex items-center justify-between px-4 h-14 hover:bg-white/5 light:hover:bg-slate-200 transition-colors cursor-pointer" title={t("scheduledJobs.row.viewRuns")} > {job.name} {humanizeCron(job.schedule, i18n.language)} {statusText} {job.lastRunAt ? new Date(job.lastRunAt).toLocaleString() : "—"} {job.enabled && job.nextRunAt ? new Date(job.nextRunAt).toLocaleString() : "—"}
); }