import { useState } from "react"; import { ChevronRight } from "lucide-react"; import type { ActivityEvent } from "@paperclipai/shared"; import { cn } from "@/lib/utils"; export type RoutineActivityEvent = Pick; function formatTime(value: string | Date): string { try { return new Date(value).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }); } catch { return String(value); } } function summarizeEvent(event: RoutineActivityEvent): string { const details = event.details; if (event.action === "routine.webhook_test_received") return "Connection working · No run or task created"; if (event.action === "routine.webhook_test_rejected") return "Update the key in your app and resend"; if (event.action === "routine.webhook_received") return "Authentication passed"; if (event.action === "routine.webhook_rejected") return "Check the key in your sending app"; if (!details) return ""; if (typeof details.changeSummary === "string") return details.changeSummary; if (event.action === "routine.run_triggered") return `${details.source === "webhook" ? "Webhook" : details.source === "schedule" ? "Schedule" : "Manual"} · ${details.status === "issue_created" ? "Task created" : String(details.status ?? "").replaceAll("_", " ")}`; return Object.entries(details).filter(([key]) => !/id$/i.test(key)).slice(0, 3) .map(([key, value]) => `${key.replace(/([a-z])([A-Z])/g, "$1 $2").replaceAll("_", " ").toLowerCase()}: ${formatDetailValue(value)}`) .join(" · "); } function formatDetailValue(value: unknown): string { if (value === null) return "null"; if (typeof value === "string") return value; if (typeof value === "number" || typeof value === "boolean") return String(value); if (Array.isArray(value)) return value.length === 0 ? "[]" : value.map(formatDetailValue).join(", "); try { return JSON.stringify(value); } catch { return "[unserializable]"; } } const actionLabels: Record = { "routine.webhook_test_received": "Connection test passed", "routine.webhook_test_rejected": "Connection test rejected", "routine.webhook_received": "Webhook event received", "routine.webhook_rejected": "Webhook authentication failed", "routine.created": "Routine created", "routine.updated": "Routine updated", "routine.trigger_created": "Trigger added", "routine.trigger_updated": "Trigger updated", "routine.trigger_deleted": "Trigger removed", "routine.trigger_removed": "Trigger removed", "routine.trigger_restored": "Trigger restored", "routine.trigger_setup_finished": "Webhook setup finished", "routine.trigger_secret_rotated": "Webhook key replaced", "routine.run_triggered": "Routine started", "routine.run_created": "Run created", }; function actionLabel(action: string) { return actionLabels[action] ?? action.replace(/^routine[._]/, "").replaceAll("_", " ").replaceAll(".", " ").replace(/^./, (char) => char.toUpperCase()); } /** Activity log row with an expandable JSON payload (§3.7). */ export function RoutineActivityRow({ event }: { event: RoutineActivityEvent }) { const [expanded, setExpanded] = useState(false); const hasPayload = event.details != null && Object.keys(event.details).length > 0; return (
{expanded && hasPayload ? (
          {JSON.stringify(event.details, null, 2)}
        
) : null}
); }