mirror of
https://github.com/LittleQuartZ/addmon.git
synced 2026-02-07 02:45:28 +07:00
feat(monitor): add alert monitoring page with KPI dashboard, alert list, and incident management
- Add Tauri plugins for file dialog and filesystem access - Create Rust backend for processing Grafana alerts (pairing, KPI calculation) - Add virtualized alert list with invalid toggle and incident attachment - Add incident manager with create, attach, and detach functionality - Add KPI dashboard showing coverage ratio, downtime, and invalid rate - Add date-fns for date formatting
This commit is contained in:
parent
ee3c0c156b
commit
ea1c9105a7
15 changed files with 1757 additions and 19 deletions
117
apps/web/src/components/monitor/kpi-dashboard.tsx
Normal file
117
apps/web/src/components/monitor/kpi-dashboard.tsx
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { KpiMetrics } from "@/lib/types/alerts";
|
||||
|
||||
interface KpiDashboardProps {
|
||||
kpis: KpiMetrics | null;
|
||||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
export function KpiDashboard({ kpis, isLoading = false }: KpiDashboardProps) {
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="grid gap-4 md:grid-cols-3">
|
||||
<Card className="rounded-none">
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">
|
||||
Error Coverage
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Skeleton className="h-7 w-20 rounded-none" />
|
||||
<Skeleton className="mt-1 h-4 w-32 rounded-none" />
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card className="rounded-none">
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">
|
||||
Total Downtime
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Skeleton className="h-7 w-20 rounded-none" />
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card className="rounded-none">
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">
|
||||
Invalid Alerts
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Skeleton className="h-7 w-20 rounded-none" />
|
||||
<Skeleton className="mt-1 h-4 w-32 rounded-none" />
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!kpis) {
|
||||
return (
|
||||
<Card className="rounded-none">
|
||||
<CardContent className="pt-6 text-center text-xs text-muted-foreground">
|
||||
No KPI data available
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
const coverageColor =
|
||||
kpis.errorCoverageRatio > 80
|
||||
? "text-green-500"
|
||||
: kpis.errorCoverageRatio > 50
|
||||
? "text-yellow-500"
|
||||
: "text-destructive";
|
||||
|
||||
const invalidColor =
|
||||
kpis.invalidAlertRatio < 10
|
||||
? "text-green-500"
|
||||
: kpis.invalidAlertRatio < 25
|
||||
? "text-yellow-500"
|
||||
: "text-destructive";
|
||||
|
||||
return (
|
||||
<div className="grid gap-4 md:grid-cols-3">
|
||||
<Card className="rounded-none">
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">Error Coverage</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className={cn("text-2xl font-bold", coverageColor)}>
|
||||
{kpis.errorCoverageRatio.toFixed(1)}%
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{kpis.coveredIncidents} of {kpis.totalIncidents} incidents
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="rounded-none">
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">Total Downtime</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">
|
||||
{kpis.overallDowntimeFormatted}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="rounded-none">
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">Invalid Alerts</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className={cn("text-2xl font-bold", invalidColor)}>
|
||||
{kpis.invalidAlertRatio.toFixed(1)}%
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{kpis.invalidAlerts} of {kpis.totalFiringAlerts} alerts
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue