71 lines
2.7 KiB
Rust
71 lines
2.7 KiB
Rust
|
|
// 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()
|
||
|
|
}
|