Rustelo/features/content-graph/templates/components/ontology_context.rs

71 lines
2.7 KiB
Rust
Raw Normal View History

2026-07-18 20:14:32 +01:00
// content_graph/ontology_context.rs
//
// Badge component showing the on+re ontology nodes connected to a content item.
// Pure HTML — no JS, fully SSR-safe.
// Data comes from ONTOLOGY_CONTEXT static map generated at build time.
use leptos::prelude::*;
use super::generated::ontology::{OntologyRef, ONTOLOGY_CONTEXT};
// ── Level / kind display helpers ──────────────────────────────────────────────
fn ref_icon(kind: &str) -> &'static str {
match kind {
"Implements" | "ImplementedBy" => "",
"ManifestsIn" => "",
"Resolves" => "",
"Complements" | "DependsOn" => "~",
"DocumentedIn" | "References" => "",
_ => "·",
}
}
fn ref_css(kind: &str) -> &'static str {
match kind {
"Implements" | "ImplementedBy" => "text-violet-500",
"ManifestsIn" => "text-blue-500",
"Resolves" => "text-emerald-500",
_ => "text-amber-500",
}
}
// ── Component ─────────────────────────────────────────────────────────────────
/// Footer/sidebar badge showing on+re ontology nodes connected to this content.
///
/// Renders nothing when the node has no ontology connections.
#[component]
pub fn OntologyContext(node_id: String) -> impl IntoView {
let refs: &'static [OntologyRef] = ONTOLOGY_CONTEXT
.iter()
.find(|(id, _)| *id == node_id.as_str())
.map(|(_, refs)| *refs)
.unwrap_or(&[]);
if refs.is_empty() {
return view! { <></> }.into_any();
}
view! {
<div class="content-graph-ontology-context mt-6 pt-4 ds-border-t space-y-2">
<p class="text-xs font-semibold ds-text uppercase tracking-wide opacity-50">
"Ontology context"
</p>
<ul class="flex flex-wrap gap-2">
{refs.iter().map(|r| {
let icon = ref_icon(r.kind);
let css = ref_css(r.kind);
view! {
<li class="flex items-center gap-1 text-xs ds-text">
<span class=css>{icon}</span>
<span class="font-mono opacity-80">{r.id}</span>
<span class="opacity-50">{r.name}</span>
</li>
}
}).collect_view()}
</ul>
</div>
}.into_any()
}