-
Notifications
You must be signed in to change notification settings - Fork 545
Expand file tree
/
Copy pathPRStatus.tsx
More file actions
135 lines (120 loc) · 4.72 KB
/
PRStatus.tsx
File metadata and controls
135 lines (120 loc) · 4.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
"use client";
import { type DashboardPR, isPRRateLimited } from "@/lib/types";
import { CIBadge } from "./CIBadge";
function getSizeLabel(additions: number, deletions: number): string {
const size = additions + deletions;
return size > 1000 ? "XL" : size > 500 ? "L" : size > 200 ? "M" : size > 50 ? "S" : "XS";
}
interface PRStatusProps {
pr: DashboardPR;
}
export function PRStatus({ pr }: PRStatusProps) {
const sizeLabel = getSizeLabel(pr.additions, pr.deletions);
const rateLimited = isPRRateLimited(pr);
return (
<div className="flex flex-wrap items-center gap-1.5">
{/* PR number */}
<a
href={pr.url}
target="_blank"
rel="noopener noreferrer"
className="text-[11px] font-medium text-[var(--color-accent)] underline-offset-2 hover:underline"
onClick={(e) => e.stopPropagation()}
>
#{pr.number}
</a>
{/* Size — hide when rate limited (would show +0 -0 XS) */}
{!rateLimited && (
<span className="inline-flex items-center rounded-full bg-[rgba(125,133,144,0.08)] px-2 py-0.5 text-[10px] font-semibold text-[var(--color-text-muted)]">
+{pr.additions} -{pr.deletions} {sizeLabel}
</span>
)}
{rateLimited && (
<span className="inline-flex items-center rounded-full bg-[rgba(210,153,34,0.1)] px-2 py-0.5 text-[10px] font-semibold text-[var(--color-accent-yellow)]">
stale
</span>
)}
{/* Merged badge */}
{pr.state === "merged" && (
<span className="inline-flex items-center rounded-full bg-[rgba(163,113,247,0.1)] px-2 py-0.5 text-[10px] font-semibold text-[var(--color-accent-violet)]">
merged
</span>
)}
{/* Draft badge */}
{pr.isDraft && pr.state === "open" && (
<span className="inline-flex items-center rounded-full bg-[rgba(125,133,144,0.08)] px-2 py-0.5 text-[10px] font-semibold text-[var(--color-text-muted)]">
draft
</span>
)}
{/* CI status — only when we have real data */}
{pr.state === "open" && !pr.isDraft && !rateLimited && (
<CIBadge status={pr.ciStatus} checks={pr.ciChecks} />
)}
{/* Review decision (only for open PRs with real data) */}
{pr.state === "open" && pr.reviewDecision === "approved" && !rateLimited && (
<span className="inline-flex items-center rounded-full bg-[rgba(63,185,80,0.1)] px-2 py-0.5 text-[10px] font-semibold text-[var(--color-accent-green)]">
approved
</span>
)}
</div>
);
}
interface PRTableRowProps {
pr: DashboardPR;
}
export function PRTableRow({ pr }: PRTableRowProps) {
const sizeLabel = getSizeLabel(pr.additions, pr.deletions);
const rateLimited = isPRRateLimited(pr);
const reviewLabel = rateLimited
? "—"
: pr.isDraft
? "draft"
: pr.reviewDecision === "approved"
? "approved"
: pr.reviewDecision === "changes_requested"
? "changes requested"
: "needs review";
const reviewClass = rateLimited
? "text-[var(--color-text-tertiary)]"
: pr.isDraft
? "text-[var(--color-text-muted)]"
: pr.reviewDecision === "approved"
? "text-[var(--color-accent-green)]"
: pr.reviewDecision === "changes_requested"
? "text-[var(--color-accent-red)]"
: "text-[var(--color-accent-yellow)]";
return (
<tr className="border-b border-[var(--color-border-muted)] hover:bg-[rgba(88,166,255,0.03)]">
<td className="px-3 py-2.5 text-sm">
<a href={pr.url} target="_blank" rel="noopener noreferrer" className="hover:underline">
#{pr.number}
</a>
</td>
<td className="max-w-[420px] truncate px-3 py-2.5 text-sm font-medium">{pr.title}</td>
<td className="px-3 py-2.5 text-sm">
{rateLimited ? (
<span className="text-[var(--color-text-tertiary)]">—</span>
) : (
<>
<span className="text-[var(--color-accent-green)]">+{pr.additions}</span>{" "}
<span className="text-[var(--color-accent-red)]">-{pr.deletions}</span>{" "}
<span className="text-[var(--color-text-muted)]">{sizeLabel}</span>
</>
)}
</td>
<td className="px-3 py-2.5">
{rateLimited ? (
<span className="text-[var(--color-text-tertiary)]">—</span>
) : (
<CIBadge status={pr.ciStatus} checks={pr.ciChecks} compact />
)}
</td>
<td className={`px-3 py-2.5 text-xs font-semibold ${reviewClass}`}>{reviewLabel}</td>
<td
className={`px-3 py-2.5 text-center text-sm font-bold ${pr.unresolvedThreads > 0 ? "text-[var(--color-accent-red)]" : "text-[var(--color-border-default)]"}`}
>
{pr.unresolvedThreads}
</td>
</tr>
);
}