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>
This commit is contained in:
Sharang Parnerkar
2026-03-04 21:53:15 +01:00
co-authored by Claude Opus 4.6
parent b18824db25
commit 0a365515e9
3 changed files with 1884 additions and 189 deletions
+63 -26
View File
@@ -14,28 +14,61 @@ pub fn GraphIndexPage() -> Element {
description: "Select a repository to explore its code graph",
}
div { class: "card",
h3 { "Repositories" }
match &*repos.read() {
Some(Some(data)) => {
let repo_list = &data.data;
if repo_list.is_empty() {
rsx! { p { "No repositories found. Add a repository first." } }
} else {
rsx! {
div { class: "grid grid-cols-1 gap-3",
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();
rsx! {
Link {
to: Route::GraphExplorerPage { repo_id: repo_id },
class: "card hover:bg-gray-800 transition-colors cursor-pointer",
h4 { "{name}" }
if !url.is_empty() {
p { class: "text-sm text-muted", "{url}" }
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}"
}
}
}
@@ -44,10 +77,14 @@ pub fn GraphIndexPage() -> Element {
}
}
}
},
Some(None) => rsx! { p { "Failed to load repositories." } },
None => rsx! { p { "Loading repositories..." } },
}
}
},
Some(None) => rsx! {
div { class: "card", p { "Failed to load repositories." } }
},
None => rsx! {
div { class: "loading", "Loading repositories..." }
},
}
}
}