From e271b6e7f825d1a9ad7b12c903aec353f3c56ca5 Mon Sep 17 00:00:00 2001 From: Egutierrez Date: Mon, 18 May 2026 18:30:16 +0200 Subject: [PATCH] feat(viz): helpers puros para dod_evidence_panel (issue 0117) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DodItem/DodEvidence/DodPanelState + count_status/find_evidence/ status_icon_id/status_color_token. Sin ImGui — testeable en aislamiento. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../viz/dod_evidence_panel_helpers.cpp | 47 ++++++++++++ .../viz/dod_evidence_panel_helpers.h | 75 +++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 cpp/functions/viz/dod_evidence_panel_helpers.cpp create mode 100644 cpp/functions/viz/dod_evidence_panel_helpers.h diff --git a/cpp/functions/viz/dod_evidence_panel_helpers.cpp b/cpp/functions/viz/dod_evidence_panel_helpers.cpp new file mode 100644 index 00000000..8aa088e7 --- /dev/null +++ b/cpp/functions/viz/dod_evidence_panel_helpers.cpp @@ -0,0 +1,47 @@ +#include "dod_evidence_panel_helpers.h" + +namespace fn_viz { +namespace dod_panel { + +StatusCounts count_status(const DodPanelState& state) { + StatusCounts c; + c.total = static_cast(state.items.size()); + for (const auto& it : state.items) { + if (it.status == "pending") ++c.pending; + else if (it.status == "done") ++c.done; + else if (it.status == "validated") ++c.validated; + else if (it.status == "failed") ++c.failed; + else ++c.pending; // unknown treated as pending + + if (it.required) { + const DodEvidence* ev = find_evidence(state, it.id); + const bool resolved = (it.status == "done" || it.status == "validated"); + if (ev == nullptr && !resolved) ++c.missing_required; + } + } + return c; +} + +const DodEvidence* find_evidence(const DodPanelState& state, const std::string& item_id) { + for (const auto& ev : state.evidences) { + if (ev.item_id == item_id) return &ev; + } + return nullptr; +} + +std::string status_icon_id(const std::string& status) { + if (status == "done") return "circle-dot"; + if (status == "validated") return "circle-check"; + if (status == "failed") return "circle-x"; + return "circle-dashed"; // pending / unknown +} + +int status_color_token(const std::string& status) { + if (status == "done") return 1; + if (status == "validated") return 2; + if (status == "failed") return 3; + return 0; +} + +} // namespace dod_panel +} // namespace fn_viz diff --git a/cpp/functions/viz/dod_evidence_panel_helpers.h b/cpp/functions/viz/dod_evidence_panel_helpers.h new file mode 100644 index 00000000..5bdbbd15 --- /dev/null +++ b/cpp/functions/viz/dod_evidence_panel_helpers.h @@ -0,0 +1,75 @@ +#pragma once + +// dod_evidence_panel_helpers — logica pura, sin ImGui. +// Tests (cpp/tests/test_dod_evidence_panel.cpp) linkan SOLO este archivo +// para validar conteos, lookup y mapeo de status -> icon/color. + +#include +#include +#include +#include + +namespace fn_viz { + +struct DodItem { + std::string id; + std::string kind; // screenshot|log|url|cmd + std::string expected; + bool required = true; + std::string status; // pending|done|validated|failed +}; + +struct DodEvidence { + std::string item_id; + std::string kind; + std::string payload_path; // screenshot/log + std::string payload_url; // url + std::string payload_text; // cmd output + int64_t attached_at = 0; + bool validated = false; + std::string validated_by; +}; + +struct DodPanelState { + std::vector items; + std::vector evidences; + std::string run_id; + std::function on_validate; + std::function on_reject; +}; + +namespace dod_panel { + +struct StatusCounts { + int total = 0; + int pending = 0; + int done = 0; + int validated = 0; + int failed = 0; + int missing_required = 0; // required + no evidence + status != done/validated +}; + +// Cuenta items por status. Si un item required NO tiene evidence y su status +// no es done/validated, suma missing_required. +StatusCounts count_status(const DodPanelState& state); + +// Busca la primera evidence cuyo item_id == item_id. nullptr si no existe. +const DodEvidence* find_evidence(const DodPanelState& state, const std::string& item_id); + +// Status -> icon key (uso interno; en render se mapea a TI_*). +// pending -> "circle-dashed" +// done -> "circle-dot" +// validated -> "circle-check" +// failed -> "circle-x" +// otro -> "circle-dashed" +std::string status_icon_id(const std::string& status); + +// Status -> color token. +// 0 = neutral (pending / desconocido) +// 1 = info (done) +// 2 = success (validated) +// 3 = danger (failed) +int status_color_token(const std::string& status); + +} // namespace dod_panel +} // namespace fn_viz