dashboard: nest the dropped-NC detail under the NC row

The detail block was rendered after *all* health rows, so it dangled below
the new model: row instead of the NC: row it explains — its indentation read
as broken. Build it into health_rows right after the NC row, with a tree
marker (↳ dropped (only 1 pin on the net):) and consistent nesting.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-03 18:38:58 +02:00
parent 7810711fd4
commit 29242ae016

View File

@@ -149,6 +149,26 @@ Component Tui::BuildDashboardScreen() {
"NC: " + std::to_string(orph_total) + " orphan pin(s) (" "NC: " + std::to_string(orph_total) + " orphan pin(s) ("
+ std::to_string(orph_imported) + " imported, " + std::to_string(orph_imported) + " imported, "
+ std::to_string(orph_dropped) + " dropped)")); + std::to_string(orph_dropped) + " dropped)"));
// Detail nested directly under the NC row it explains. "dropped" = the
// pin was the only one on its net, so essim detached it (a heuristic;
// listing them lets the user spot a false positive). Imported NCs were
// explicit in the netlist, so they are not expanded.
if (orph_dropped > 0) {
health_rows.push_back(
text(" ↳ dropped (only 1 pin on the net):") | dim);
for (auto &dkv : dropped_by_module) {
std::sort(dkv.second.begin(), dkv.second.end(), NaturalLess);
std::string csv;
for (size_t i = 0; i < dkv.second.size(); ++i) {
if (i) csv += ", ";
csv += dkv.second[i];
}
health_rows.push_back(hbox({
text(" " + dkv.first + ": ") | bold,
text(csv) | dim,
}));
}
}
// Model-driven checks (BSDL pin specs, JTAG chain, source conflicts), // Model-driven checks (BSDL pin specs, JTAG chain, source conflicts),
// reusing the nets computed above. // reusing the nets computed above.
@@ -253,27 +273,6 @@ Component Tui::BuildDashboardScreen() {
lines.push_back(separator()); lines.push_back(separator());
lines.push_back(text(" Health") | bold); lines.push_back(text(" Health") | bold);
for (auto &h : health_rows) lines.push_back(std::move(h)); for (auto &h : health_rows) lines.push_back(std::move(h));
// Detail rows for the dropped-singleton NCs. Imported NCs are not
// expanded — they were already explicit in the netlist. Dropped NCs
// come from a heuristic, so listing them gives the user a chance to
// spot a false positive.
if (orph_dropped > 0) {
lines.push_back(hbox({
text(" dropped — net has only 1 pin (NC):") | dim,
}));
for (auto &dkv : dropped_by_module) {
std::sort(dkv.second.begin(), dkv.second.end(), NaturalLess);
std::string csv;
for (size_t i = 0; i < dkv.second.size(); ++i) {
if (i) csv += ", ";
csv += dkv.second[i];
}
lines.push_back(hbox({
text(" " + dkv.first + ": ") | bold,
text(csv),
}));
}
}
lines.push_back(separator()); lines.push_back(separator());
lines.push_back(text(" Analysis") | bold); lines.push_back(text(" Analysis") | bold);
lines.push_back(hbox({text("") | dim, lines.push_back(hbox({text("") | dim,