Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3b918b365 | ||
|
|
bf32b9939a |
@@ -461,6 +461,25 @@ impl PipelineOrchestrator {
|
|||||||
} },
|
} },
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
// Refresh the target's cached findings count. The shared pipeline
|
||||||
|
// (Stage 7) increments `repositories`, which the unified path does
|
||||||
|
// not use, so set the accurate total on the target itself.
|
||||||
|
let total = self
|
||||||
|
.db
|
||||||
|
.findings()
|
||||||
|
.count_documents(doc! { "repo_id": target_id })
|
||||||
|
.await
|
||||||
|
.unwrap_or(*count as u64);
|
||||||
|
self.db
|
||||||
|
.onboarded_targets()
|
||||||
|
.update_one(
|
||||||
|
doc! { "_id": oid },
|
||||||
|
doc! { "$set": {
|
||||||
|
"findings_count": total as i64,
|
||||||
|
"updated_at": mongodb::bson::DateTime::now(),
|
||||||
|
} },
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
tracing::error!(target_id, error = %e, "Unified scan pipeline failed");
|
tracing::error!(target_id, error = %e, "Unified scan pipeline failed");
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ pub fn FindingsPage() -> Element {
|
|||||||
let mut selected_ids = use_signal(Vec::<String>::new);
|
let mut selected_ids = use_signal(Vec::<String>::new);
|
||||||
|
|
||||||
let repos = use_resource(|| async {
|
let repos = use_resource(|| async {
|
||||||
crate::infrastructure::repositories::fetch_repositories(1)
|
crate::infrastructure::onboarding::fetch_targets()
|
||||||
.await
|
.await
|
||||||
.ok()
|
.ok()
|
||||||
});
|
});
|
||||||
@@ -86,14 +86,14 @@ pub fn FindingsPage() -> Element {
|
|||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
onchange: move |e| { repo_filter.set(e.value()); page.set(1); },
|
onchange: move |e| { repo_filter.set(e.value()); page.set(1); },
|
||||||
option { value: "", "All Repositories" }
|
option { value: "", "All Targets" }
|
||||||
{
|
{
|
||||||
match &*repos.read() {
|
match &*repos.read() {
|
||||||
Some(Some(resp)) => rsx! {
|
Some(Some(resp)) => rsx! {
|
||||||
for repo in &resp.data {
|
for t in &resp.data {
|
||||||
{
|
{
|
||||||
let id = repo.id.as_ref().map(|id| id.to_hex()).unwrap_or_default();
|
let id = t.get("_id").and_then(|o| o.get("$oid")).and_then(|s| s.as_str()).unwrap_or_default().to_string();
|
||||||
let name = repo.name.clone();
|
let name = t.get("name").and_then(|n| n.as_str()).unwrap_or_default().to_string();
|
||||||
rsx! {
|
rsx! {
|
||||||
option { value: "{id}", "{name}" }
|
option { value: "{id}", "{name}" }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ pub fn SbomPage() -> Element {
|
|||||||
let mut diff_repo_a = use_signal(String::new);
|
let mut diff_repo_a = use_signal(String::new);
|
||||||
let mut diff_repo_b = use_signal(String::new);
|
let mut diff_repo_b = use_signal(String::new);
|
||||||
|
|
||||||
// ── Repos for dropdowns ──
|
// ── Targets for dropdowns ──
|
||||||
let repos = use_resource(|| async {
|
let repos = use_resource(|| async {
|
||||||
crate::infrastructure::repositories::fetch_repositories(1)
|
crate::infrastructure::onboarding::fetch_targets()
|
||||||
.await
|
.await
|
||||||
.ok()
|
.ok()
|
||||||
});
|
});
|
||||||
@@ -114,14 +114,14 @@ pub fn SbomPage() -> Element {
|
|||||||
select {
|
select {
|
||||||
class: "sbom-filter-select",
|
class: "sbom-filter-select",
|
||||||
onchange: move |e| { repo_filter.set(e.value()); page.set(1); },
|
onchange: move |e| { repo_filter.set(e.value()); page.set(1); },
|
||||||
option { value: "", "All Repositories" }
|
option { value: "", "All Targets" }
|
||||||
{
|
{
|
||||||
match &*repos.read() {
|
match &*repos.read() {
|
||||||
Some(Some(resp)) => rsx! {
|
Some(Some(resp)) => rsx! {
|
||||||
for repo in &resp.data {
|
for repo in &resp.data {
|
||||||
{
|
{
|
||||||
let id = repo.id.as_ref().map(|id| id.to_hex()).unwrap_or_default();
|
let id = repo.get("_id").and_then(|o| o.get("$oid")).and_then(|s| s.as_str()).unwrap_or_default().to_string();
|
||||||
let name = repo.name.clone();
|
let name = repo.get("name").and_then(|n| n.as_str()).unwrap_or_default().to_string();
|
||||||
rsx! { option { value: "{id}", "{name}" } }
|
rsx! { option { value: "{id}", "{name}" } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -476,8 +476,8 @@ pub fn SbomPage() -> Element {
|
|||||||
Some(Some(resp)) => rsx! {
|
Some(Some(resp)) => rsx! {
|
||||||
for repo in &resp.data {
|
for repo in &resp.data {
|
||||||
{
|
{
|
||||||
let id = repo.id.as_ref().map(|id| id.to_hex()).unwrap_or_default();
|
let id = repo.get("_id").and_then(|o| o.get("$oid")).and_then(|s| s.as_str()).unwrap_or_default().to_string();
|
||||||
let name = repo.name.clone();
|
let name = repo.get("name").and_then(|n| n.as_str()).unwrap_or_default().to_string();
|
||||||
rsx! { option { value: "{id}", "{name}" } }
|
rsx! { option { value: "{id}", "{name}" } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -498,8 +498,8 @@ pub fn SbomPage() -> Element {
|
|||||||
Some(Some(resp)) => rsx! {
|
Some(Some(resp)) => rsx! {
|
||||||
for repo in &resp.data {
|
for repo in &resp.data {
|
||||||
{
|
{
|
||||||
let id = repo.id.as_ref().map(|id| id.to_hex()).unwrap_or_default();
|
let id = repo.get("_id").and_then(|o| o.get("$oid")).and_then(|s| s.as_str()).unwrap_or_default().to_string();
|
||||||
let name = repo.name.clone();
|
let name = repo.get("name").and_then(|n| n.as_str()).unwrap_or_default().to_string();
|
||||||
rsx! { option { value: "{id}", "{name}" } }
|
rsx! { option { value: "{id}", "{name}" } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user