Files
compliance-scanner-agent/compliance-dashboard/src/pages/graph_index.rs
T
Sharang ParnerkarandClaude Opus 4.6 0a365515e9 Enhance graph explorer: widen inspector, redesign index, add search suggestions
- Widen code inspector panel from 450px to 550px for better readability
- Redesign graph index landing page with polished repo cards showing
  name, git URL, branch, findings count, and relative update time
- Add search suggestions dropdown in graph explorer that appears on
  typing >= 2 chars, showing node name, kind badge, and file path
- Add full graph explorer styles matching Obsidian Control dark theme

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

91 lines
4.5 KiB
Rust

use dioxus::prelude::*;
use crate::app::Route;
use crate::components::page_header::PageHeader;
use crate::infrastructure::repositories::fetch_repositories;
#[component]
pub fn GraphIndexPage() -> Element {
let repos = use_resource(|| async { fetch_repositories(1).await.ok() });
rsx! {
PageHeader {
title: "Code Knowledge Graph",
description: "Select a repository to explore its code graph",
}
match &*repos.read() {
Some(Some(data)) => {
let repo_list = &data.data;
if repo_list.is_empty() {
rsx! {
div { class: "card",
p { "No repositories found. Add a repository first." }
}
}
} else {
rsx! {
div { class: "graph-index-grid",
for repo in repo_list {
{
let repo_id = repo.id.map(|id| id.to_hex()).unwrap_or_default();
let name = repo.name.clone();
let url = repo.git_url.clone();
let branch = repo.default_branch.clone();
let findings = repo.findings_count;
let findings_label = if findings != 1 { format!("{findings} findings") } else { "1 finding".to_string() };
let updated = {
let now = chrono::Utc::now();
let diff = now.signed_duration_since(repo.updated_at);
if diff.num_minutes() < 1 {
"just now".to_string()
} else if diff.num_hours() < 1 {
format!("{}m ago", diff.num_minutes())
} else if diff.num_days() < 1 {
format!("{}h ago", diff.num_hours())
} else if diff.num_days() < 30 {
format!("{}d ago", diff.num_days())
} else {
repo.updated_at.format("%Y-%m-%d").to_string()
}
};
rsx! {
Link {
to: Route::GraphExplorerPage { repo_id },
class: "graph-repo-card",
div { class: "graph-repo-card-header",
div { class: "graph-repo-card-icon", "\u{29BB}" }
h3 { class: "graph-repo-card-name", "{name}" }
}
if !url.is_empty() {
p { class: "graph-repo-card-url", "{url}" }
}
div { class: "graph-repo-card-meta",
span { class: "graph-repo-card-tag",
"\u{E0A0} {branch}"
}
span { class: "graph-repo-card-tag graph-repo-card-tag-findings",
"{findings_label}"
}
span { class: "graph-repo-card-tag",
"Updated {updated}"
}
}
}
}
}
}
}
}
}
},
Some(None) => rsx! {
div { class: "card", p { "Failed to load repositories." } }
},
None => rsx! {
div { class: "loading", "Loading repositories..." }
},
}
}
}