diff --git a/ui/src/pages/Inbox.tsx b/ui/src/pages/Inbox.tsx index a34747ad..6c5c86a8 100644 --- a/ui/src/pages/Inbox.tsx +++ b/ui/src/pages/Inbox.tsx @@ -35,7 +35,6 @@ import { ArrowUpRight, XCircle, X, - UserCheck, RotateCcw, } from "lucide-react"; import { Identity } from "../components/Identity"; @@ -137,6 +136,19 @@ function runFailureMessage(run: HeartbeatRun): string { return firstNonEmptyLine(run.error) ?? firstNonEmptyLine(run.stderrExcerpt) ?? "Run exited with an error."; } +function normalizeTimestamp(value: string | Date | null | undefined): number { + if (!value) return 0; + const timestamp = new Date(value).getTime(); + return Number.isFinite(timestamp) ? timestamp : 0; +} + +function issueLastActivityTimestamp(issue: Issue): number { + return Math.max( + normalizeTimestamp(issue.updatedAt), + normalizeTimestamp(issue.lastExternalCommentAt), + ); +} + function readIssueIdFromRun(run: HeartbeatRun): string | null { const context = run.contextSnapshot; if (!context) return null; @@ -357,7 +369,7 @@ export function Inbox() { queryFn: () => issuesApi.list(selectedCompanyId!, { touchedByUserId: "me", - status: "backlog,todo,in_progress,in_review,blocked", + status: "backlog,todo,in_progress,in_review,blocked,done", }), enabled: !!selectedCompanyId, }); @@ -372,16 +384,14 @@ export function Inbox() { () => (issues ? getStaleIssues(issues) : []).filter((i) => !dismissed.has(`stale:${i.id}`)), [issues, dismissed], ); - const sortByRecentExternalComment = useCallback((a: Issue, b: Issue) => { - const aExternal = a.lastExternalCommentAt ? new Date(a.lastExternalCommentAt).getTime() : 0; - const bExternal = b.lastExternalCommentAt ? new Date(b.lastExternalCommentAt).getTime() : 0; - if (aExternal !== bExternal) return bExternal - aExternal; - return new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime(); - }, []); + const sortByMostRecentActivity = useCallback( + (a: Issue, b: Issue) => issueLastActivityTimestamp(b) - issueLastActivityTimestamp(a), + [], + ); const touchedIssues = useMemo( - () => [...touchedIssuesRaw].sort(sortByRecentExternalComment), - [sortByRecentExternalComment, touchedIssuesRaw], + () => [...touchedIssuesRaw].sort(sortByMostRecentActivity), + [sortByMostRecentActivity, touchedIssuesRaw], ); const agentById = useMemo(() => { @@ -642,22 +652,22 @@ export function Inbox() { to={`/issues/${issue.identifier ?? issue.id}`} className="flex cursor-pointer items-center gap-3 px-4 py-3 transition-colors hover:bg-accent/50 no-underline text-inherit" > - + + + {issue.identifier ?? issue.id.slice(0, 8)} {issue.title} - - {issue.isUnreadForMe ? "Unread" : "Read"} - {issue.lastExternalCommentAt ? `commented ${timeAgo(issue.lastExternalCommentAt)}`