From b262e446d1b3e3fc168954f57a1ef86cc4f1a0bf Mon Sep 17 00:00:00 2001 From: Bhavya Gupta Date: Thu, 25 Jun 2026 08:04:53 +0530 Subject: [PATCH] feat: add Merged/Open/Closed status filter controls to PR Analytics chart (#1488) --- src/components/PRBreakdownChart.tsx | 42 ++++++++++++++-------- src/components/PRMetrics.tsx | 56 ++++++++++++++++++----------- 2 files changed, 63 insertions(+), 35 deletions(-) diff --git a/src/components/PRBreakdownChart.tsx b/src/components/PRBreakdownChart.tsx index e5be6dbe6..c2b202ae1 100644 --- a/src/components/PRBreakdownChart.tsx +++ b/src/components/PRBreakdownChart.tsx @@ -10,6 +10,9 @@ interface PRBreakdown { merged: number; closed: number; } +interface PRBreakdownChartProps { + filter?: "all" | "merged" | "open" | "closed"; +} const SLICES: { key: keyof PRBreakdown; label: string; color: string }[] = [ { key: "open", label: "Open", color: "var(--accent)" }, @@ -18,7 +21,7 @@ const SLICES: { key: keyof PRBreakdown; label: string; color: string }[] = [ { key: "draft", label: "Draft", color: "var(--muted-foreground)" }, ]; -export default function PRBreakdownChart() { +export default function PRBreakdownChart({ filter = "all" }: PRBreakdownChartProps) { const { selectedAccount } = useAccount(); const [breakdown, setBreakdown] = useState(null); const [loading, setLoading] = useState(true); @@ -89,11 +92,16 @@ export default function PRBreakdownChart() { } const total = breakdown ? SLICES.reduce((sum, s) => sum + (breakdown[s.key] ?? 0), 0) : 0; - const chartData = breakdown - ? SLICES.map((s) => ({ name: s.label, value: breakdown[s.key] ?? 0, color: s.color })).filter( - (d) => d.value > 0 - ) - : []; + const chartData = breakdown + ? SLICES.map((s) => ({ + name: s.label, + value: + filter === "all" || s.key === filter + ? (breakdown[s.key] ?? 0) + : 0, + color: s.color, + })).filter((d) => d.value > 0) + : []; return (
@@ -136,15 +144,19 @@ export default function PRBreakdownChart() {
- {SLICES.map((s) => ( -
- - {s.label}: {breakdown?.[s.key] ?? 0} -
- ))} + {SLICES.filter((s) => filter === "all" || s.key === filter).map((s) => ( +
+ + {s.label}: {breakdown?.[s.key] ?? 0} +
+))}
)} diff --git a/src/components/PRMetrics.tsx b/src/components/PRMetrics.tsx index fb40d8461..a88661871 100644 --- a/src/components/PRMetrics.tsx +++ b/src/components/PRMetrics.tsx @@ -7,6 +7,7 @@ import { useDashboardWidgetA11y } from "@/components/dashboard/DashboardWidgetA1 import { LineChart, Line, XAxis, YAxis, Tooltip, ResponsiveContainer } from "recharts"; import PRStatusDonutChart from "./PRStatusDonutChart"; import MiniPRTrendChart from "./MiniPRTrendChart"; +import PRBreakdownChart from "./PRBreakdownChart"; interface PRMetricsSummary { open: number; @@ -54,7 +55,7 @@ export default function PRMetrics() { const [minutesAgo, setMinutesAgo] = useState(0); const [error, setError] = useState(null); const [activeTab, setActiveTab] = useState<"authored" | "reviews">("authored"); - const [prFilter, setPrFilter] = useState<"all" | "merged" | "open">("all"); + const [prFilter, setPrFilter] = useState<"all" | "merged" | "open" | "closed">("all"); const [range, setRange] = useState<"7d" | "30d" | "90d">("30d"); const [staleThresholdDays, setStaleThresholdDays] = useState(14); @@ -274,16 +275,28 @@ export default function PRMetrics() {

GitHub PRs

- {(["all", "merged", "open"] as const).map((filter) => ( - - ))} + {(["all", "merged", "open", "closed"] as const).map((filter) => { + const colors: Record = { + all: "bg-[var(--accent)] text-white", + merged: "bg-green-600 text-white", + open: "bg-blue-600 text-white", + closed: "bg-orange-500 text-white", + }; + return ( + + ); +})}
@@ -302,15 +315,18 @@ export default function PRMetrics() { {/* PR Status Donut Chart */} {metrics && ( -
-

PR Status Distribution

- -
- )} +
+

PR Status Distribution

+ +
+ +
+
+)} {/* Cycle Time Features */}