fix: SBOM multi-ecosystem support with correct package managers and licenses (#8)
Some checks failed
CI / Format (push) Successful in 3s
CI / Clippy (push) Successful in 4m28s
CI / Security Audit (push) Failing after 1m52s
CI / Tests (push) Has been skipped
CI / Detect Changes (push) Has been skipped
CI / Deploy Agent (push) Has been skipped
CI / Deploy Dashboard (push) Has been skipped
CI / Deploy Docs (push) Has been skipped
CI / Deploy MCP (push) Has been skipped

This commit was merged in pull request #8.
This commit is contained in:
2026-03-10 12:37:29 +00:00
parent 0065c7c4b2
commit daff5812a6
7 changed files with 340 additions and 28 deletions

View File

@@ -36,6 +36,9 @@ pub fn SbomPage() -> Element {
.ok()
});
// ── Dynamic filter options (package managers + licenses from DB) ──
let sbom_filters = use_resource(|| async { fetch_sbom_filters().await.ok() });
// ── SBOM list (filtered) ──
let sbom = use_resource(move || {
let p = page();
@@ -132,14 +135,20 @@ pub fn SbomPage() -> Element {
class: "sbom-filter-select",
onchange: move |e| { pm_filter.set(e.value()); page.set(1); },
option { value: "", "All Managers" }
option { value: "npm", "npm" }
option { value: "cargo", "Cargo" }
option { value: "pip", "pip" }
option { value: "go", "Go" }
option { value: "maven", "Maven" }
option { value: "nuget", "NuGet" }
option { value: "composer", "Composer" }
option { value: "gem", "RubyGems" }
{
match &*sbom_filters.read() {
Some(Some(f)) => rsx! {
for pm in &f.package_managers {
{
let val = pm.clone();
let label = pm_display_name(&val);
rsx! { option { value: "{val}", "{label}" } }
}
}
},
_ => rsx! {},
}
}
}
input {
class: "sbom-filter-input",
@@ -166,14 +175,19 @@ pub fn SbomPage() -> Element {
class: "sbom-filter-select",
onchange: move |e| { license_filter.set(e.value()); page.set(1); },
option { value: "", "All Licenses" }
option { value: "MIT", "MIT" }
option { value: "Apache-2.0", "Apache 2.0" }
option { value: "BSD-3-Clause", "BSD 3-Clause" }
option { value: "ISC", "ISC" }
option { value: "GPL-3.0", "GPL 3.0" }
option { value: "GPL-2.0", "GPL 2.0" }
option { value: "LGPL-2.1", "LGPL 2.1" }
option { value: "MPL-2.0", "MPL 2.0" }
{
match &*sbom_filters.read() {
Some(Some(f)) => rsx! {
for lic in &f.licenses {
{
let val = lic.clone();
rsx! { option { value: "{val}", "{val}" } }
}
}
},
_ => rsx! {},
}
}
}
// ── Export button ──
@@ -633,6 +647,21 @@ pub fn SbomPage() -> Element {
}
}
fn pm_display_name(pm: &str) -> &str {
match pm {
"npm" => "npm",
"cargo" => "Cargo",
"pip" => "pip",
"go" | "golang" => "Go",
"maven" => "Maven",
"nuget" => "NuGet",
"composer" => "Composer",
"gem" => "RubyGems",
"github" => "GitHub Actions",
other => other,
}
}
fn license_css_class(license: Option<&str>) -> &'static str {
match license {
Some(l) => {