import { Link } from "@/lib/router"; import { Identity } from "./Identity"; import { IssueReferenceActivitySummary } from "./IssueReferenceActivitySummary"; import { timeAgo } from "../lib/timeAgo"; import { cn } from "../lib/utils"; import { formatActivityVerb } from "../lib/activity-format"; import { deriveProjectUrlKey, type ActivityEvent, type Agent } from "@paperclipai/shared"; import type { CompanyUserProfile } from "../lib/company-members"; function entityLink(entityType: string, entityId: string, name?: string | null): string | null { switch (entityType) { case "issue": return `/issues/${name ?? entityId}`; case "agent": return `/agents/${entityId}`; case "project": return `/projects/${deriveProjectUrlKey(name, entityId)}`; case "goal": return `/goals/${entityId}`; case "approval": return `/approvals/${entityId}`; default: return null; } } interface ActivityRowProps { event: ActivityEvent; agentMap: Map; userProfileMap?: Map; entityNameMap: Map; entityTitleMap?: Map; className?: string; } export function ActivityRow({ event, agentMap, userProfileMap, entityNameMap, entityTitleMap, className }: ActivityRowProps) { const verb = formatActivityVerb(event.action, event.details, { agentMap, userProfileMap }); const isHeartbeatEvent = event.entityType === "heartbeat_run"; const heartbeatAgentId = isHeartbeatEvent ? (event.details as Record | null)?.agentId as string | undefined : undefined; const name = isHeartbeatEvent ? (heartbeatAgentId ? entityNameMap.get(`agent:${heartbeatAgentId}`) : null) : entityNameMap.get(`${event.entityType}:${event.entityId}`); const entityTitle = entityTitleMap?.get(`${event.entityType}:${event.entityId}`); const link = isHeartbeatEvent && heartbeatAgentId ? `/agents/${heartbeatAgentId}/runs/${event.entityId}` : entityLink(event.entityType, event.entityId, name); const actor = event.actorType === "agent" ? agentMap.get(event.actorId) : null; const userProfile = event.actorType === "user" ? userProfileMap?.get(event.actorId) : null; const actorName = actor?.name ?? (event.actorType === "system" ? "System" : userProfile?.label ?? (event.actorType === "user" ? "Board" : event.actorId || "Unknown")); const actorAvatarUrl = userProfile?.image ?? null; const inner = (

{verb} {name && {name}} {entityTitle && — {entityTitle}}

{timeAgo(event.createdAt)}
); const classes = cn( "px-4 py-2 text-sm", link && "cursor-pointer hover:bg-accent/50 transition-colors", className, ); if (link) { return ( {inner} ); } return (
{inner}
); }