Files
compliance-scanner-agent/compliance-dashboard/src/pages/overview.rs
Sharang Parnerkar b18824db25 Add graph explorer components, API handlers, and dependency updates
Adds code inspector, file tree components, graph visualization JS,
graph API handlers, sidebar navigation updates, and misc improvements.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 21:52:49 +01:00

103 lines
3.7 KiB
Rust

use dioxus::prelude::*;
use crate::components::page_header::PageHeader;
use crate::components::stat_card::StatCard;
#[cfg(feature = "server")]
use crate::infrastructure::stats::fetch_overview_stats;
#[component]
pub fn OverviewPage() -> Element {
let stats = use_resource(move || async move {
#[cfg(feature = "server")]
{
fetch_overview_stats().await.ok()
}
#[cfg(not(feature = "server"))]
{
crate::infrastructure::stats::fetch_overview_stats()
.await
.ok()
}
});
rsx! {
PageHeader {
title: "Overview",
description: "Security and compliance scanning dashboard",
}
match &*stats.read() {
Some(Some(s)) => rsx! {
div { class: "stat-cards",
StatCard { label: "Repositories", value: s.total_repositories.to_string() }
StatCard { label: "Total Findings", value: s.total_findings.to_string() }
StatCard {
label: "Critical",
value: s.critical_findings.to_string(),
color: "var(--danger)",
}
StatCard {
label: "High",
value: s.high_findings.to_string(),
color: "#f97316",
}
StatCard {
label: "Medium",
value: s.medium_findings.to_string(),
color: "var(--warning)",
}
StatCard {
label: "Low",
value: s.low_findings.to_string(),
color: "var(--success)",
}
StatCard { label: "Dependencies", value: s.total_sbom_entries.to_string() }
StatCard { label: "CVE Alerts", value: s.total_cve_alerts.to_string() }
StatCard { label: "Tracker Issues", value: s.total_issues.to_string() }
}
div { class: "card",
div { class: "card-header", "Severity Distribution" }
div { class: "severity-chart",
SeverityBar { label: "Critical", count: s.critical_findings, max: s.total_findings, color: "var(--danger)" }
SeverityBar { label: "High", count: s.high_findings, max: s.total_findings, color: "var(--orange)" }
SeverityBar { label: "Medium", count: s.medium_findings, max: s.total_findings, color: "var(--warning)" }
SeverityBar { label: "Low", count: s.low_findings, max: s.total_findings, color: "var(--success)" }
}
}
},
Some(None) => rsx! {
div { class: "card",
p { style: "color: var(--text-secondary);",
"Unable to load stats. Make sure the agent API is running."
}
}
},
None => rsx! {
div { class: "loading", "Loading overview..." }
},
}
}
}
#[component]
fn SeverityBar(label: String, count: u64, max: u64, color: String) -> Element {
let height_pct = if max > 0 {
(count as f64 / max as f64) * 100.0
} else {
0.0
};
rsx! {
div { class: "severity-bar",
div { class: "severity-bar-count", "{count}" }
div {
class: "severity-bar-fill",
style: "height: {height_pct.max(2.0)}%; background: {color};",
}
div { class: "severity-bar-label", "{label}" }
}
}
}