import { Button } from "@agent-native/toolkit/ui/button"; import { IconBolt, IconCalendarEvent, IconClock, IconEye, IconLoader2, IconPlayerPause, IconPlayerPlay, IconTrash, } from "@tabler/icons-react"; import { useState } from "react"; import { AgentAskPopover } from "../AgentAskPopover.js"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "../components/ui/dialog.js"; import { useFormatters, useT } from "../i18n.js"; import { automationCreationContext, AutomationsList, } from "../settings/AutomationsSection.js"; import { AgentEmptyState } from "./AgentEmptyState.js"; import { AgentTabFrame } from "./AgentTabFrame.js"; import type { AgentPageTabProps } from "./types.js"; import { useManageRecurringJob, useRecurringJobs, type RecurringJob, } from "./use-jobs.js"; export function AgentJobsTab({ canManageOrg = false }: AgentPageTabProps) { const t = useT(); const { formatDate } = useFormatters(); const personalQuery = useRecurringJobs("user"); const organizationQuery = useRecurringJobs("org"); const personalMutation = useManageRecurringJob("user"); const organizationMutation = useManageRecurringJob("org"); const [deleteTarget, setDeleteTarget] = useState(null); const [detailsTarget, setDetailsTarget] = useState(null); const formatDateTime = (value: string | null) => { if (!value || Number.isNaN(new Date(value).getTime())) return null; return formatDate(value, { month: "short", day: "numeric", hour: "numeric", minute: "2-digit", }); }; const renderRecurringSection = ( title: string, scope: "user" | "org", query: ReturnType, mutation: ReturnType, ) => { const jobs = query.data ?? []; return (

{title}

{scope === "org" ? t("jobs.organizationRecurringDescription", { defaultValue: "Jobs shared with this organization. Members can view them; creators and admins can manage them.", }) : t("jobs.recurringDescription", { defaultValue: "Scheduled prompts that ask the agent to do work automatically.", })}

{scope === "org" && !canManageOrg ? ( {t("jobs.organizationMemberNote", { defaultValue: "You can manage jobs you created.", })} ) : null}
{query.isLoading ? (
{t("jobs.loading", { defaultValue: "Loading…" })}
) : query.error ? (

{t("jobs.recurringLoadError", { defaultValue: "Could not load recurring jobs.", })}

) : jobs.length === 0 ? ( } /> ) : (
{jobs.map((job) => { const lastRun = formatDateTime(job.lastRun); const nextRun = formatDateTime(job.nextRun); return (

{job.name.replace(/-/g, " ")}

{job.enabled ? t("jobs.enabled", { defaultValue: "Enabled" }) : t("jobs.paused", { defaultValue: "Paused" })} {job.lastStatus ? ( {job.lastStatus} ) : null}

{job.scheduleDescription || job.schedule}

{job.instructions}

{lastRun || nextRun ? (
{nextRun ? ( {t("jobs.nextRun", { defaultValue: "Next run" })}:{" "} {nextRun} ) : null} {lastRun ? ( {t("jobs.lastRun", { defaultValue: "Last run" })}:{" "} {lastRun} ) : null}
) : null}
{job.canUpdate ? ( <> ) : null}
); })}
)} {mutation.error ? (

{mutation.error.message || t("jobs.recurringUpdateError", { defaultValue: "Could not update recurring job.", })}

) : null}
); }; const mutationPending = personalMutation.isPending || organizationMutation.isPending; const deleteMutation = deleteTarget?.scope === "organization" ? organizationMutation : personalMutation; return (
{renderRecurringSection( "Personal", "user", personalQuery, personalMutation, )} {renderRecurringSection( "Organization", "org", organizationQuery, organizationMutation, )}

{t("jobs.automationsTitle", { defaultValue: "Automations" })}

{t("jobs.automationsDescription", { defaultValue: "Event-triggered and scheduled agent tasks managed from one place.", })}

} /> } />
{ if (!open && !mutationPending) setDeleteTarget(null); }} > {t("jobs.deleteRecurringTitle", { defaultValue: "Delete recurring job?", })} {t("jobs.deleteRecurringDescription", { defaultValue: "This permanently removes the job and cannot be undone.", })} { if (!open) setDetailsTarget(null); }} > {detailsTarget?.name.replace(/-/g, " ") ?? t("jobs.recurringDetails", { defaultValue: "Recurring job details", })} {detailsTarget?.scheduleDescription || detailsTarget?.schedule} {detailsTarget ? (

{t("jobs.instructions", { defaultValue: "Instructions" })}

{detailsTarget.instructions}

{detailsTarget.mcpTools.length > 0 ? (

{t("jobs.mcpTools", { defaultValue: "Connected MCP tools", })}

{detailsTarget.mcpTools.map((toolName) => ( {toolName} ))}
) : null}
) : null}
); }