migrate collectors + results tables to data_table::render (issue 0081-J)
- Include viz/data_table.h; add g_dt_collectors + g_dt_results State members - ##collectors (3 cols): flat cells array -> data_table::render, Text renderers - ##results (4 cols): flat cells array -> data_table::render, Badge on Kind col (function=#3b82f6, pipeline=#8b5cf6, component=#f59e0b) - CMakeLists.txt: add fn_table_viz guard link block - app.md: populate uses_functions with Wave-1 stack IDs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -31,6 +31,11 @@ target_include_directories(odr_console PRIVATE
|
||||
|
||||
target_link_libraries(odr_console PRIVATE SQLite::SQLite3)
|
||||
|
||||
# fn_table_viz: declarative table rendering stack (issue 0081-J).
|
||||
if(TARGET fn_table_viz)
|
||||
target_link_libraries(odr_console PRIVATE fn_table_viz)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set_target_properties(odr_console PROPERTIES WIN32_EXECUTABLE TRUE)
|
||||
endif()
|
||||
|
||||
@@ -4,7 +4,12 @@ lang: cpp
|
||||
domain: tools
|
||||
description: "Lanzador GUI de funciones del registry para recolectar datos online. Panel de busqueda FTS5, jobs queue async (workers concurrentes), pipeline builder DAG, browser DuckDB, assertions/proposals. Aplica bucle reactivo de 5 pasos sobre operations.db propia."
|
||||
tags: [imgui, data-collection, scraping, duckdb, jobs, cdp]
|
||||
uses_functions: []
|
||||
uses_functions:
|
||||
- data_table_cpp_viz
|
||||
- viz_render_cpp_viz
|
||||
- compute_stage_cpp_core
|
||||
- tql_to_sql_cpp_core
|
||||
- llm_anthropic_cpp_core
|
||||
uses_types: []
|
||||
framework: "imgui"
|
||||
entry_point: "main.cpp"
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "core/icons_tabler.h"
|
||||
#include "core/tokens.h"
|
||||
#include "core/logger.h"
|
||||
#include "viz/data_table.h"
|
||||
|
||||
#include "data_registry.h"
|
||||
#include "data_collectors.h"
|
||||
@@ -40,6 +41,10 @@ static int g_coll_param_limit = 30;
|
||||
static std::string g_last_run_summary; // texto status del ultimo run
|
||||
static bool g_running = false;
|
||||
|
||||
// data_table::State persistentes (issue 0081-J: migration from inline BeginTable).
|
||||
static data_table::State g_dt_collectors;
|
||||
static data_table::State g_dt_results;
|
||||
|
||||
static void do_search() {
|
||||
g_results.clear();
|
||||
g_selected = -1;
|
||||
@@ -111,29 +116,36 @@ static void draw_collectors() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ImGui::BeginTable("##collectors", 3,
|
||||
ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders |
|
||||
ImGuiTableFlags_Resizable)) {
|
||||
ImGui::TableSetupColumn("ID", ImGuiTableColumnFlags_WidthFixed, 180);
|
||||
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, 200);
|
||||
ImGui::TableSetupColumn("Description", ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableHeadersRow();
|
||||
// Build flat cells array for data_table::render (row-major, 3 cols).
|
||||
{
|
||||
static std::vector<std::string> coll_cell_backing;
|
||||
static std::vector<const char*> coll_cells;
|
||||
|
||||
for (int i = 0; i < (int)g_collectors.size(); ++i) {
|
||||
const auto& c = g_collectors[i];
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
bool sel = (i == g_coll_selected);
|
||||
if (ImGui::Selectable(c.id.c_str(), sel,
|
||||
ImGuiSelectableFlags_SpanAllColumns)) {
|
||||
g_coll_selected = i;
|
||||
}
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::TextUnformatted(c.name.c_str());
|
||||
ImGui::TableSetColumnIndex(2);
|
||||
ImGui::TextUnformatted(c.description.c_str());
|
||||
coll_cell_backing.clear();
|
||||
coll_cell_backing.reserve(g_collectors.size() * 3);
|
||||
for (const auto& c : g_collectors) {
|
||||
coll_cell_backing.push_back(c.id);
|
||||
coll_cell_backing.push_back(c.name);
|
||||
coll_cell_backing.push_back(c.description);
|
||||
}
|
||||
ImGui::EndTable();
|
||||
coll_cells.resize(coll_cell_backing.size());
|
||||
for (size_t i = 0; i < coll_cell_backing.size(); ++i)
|
||||
coll_cells[i] = coll_cell_backing[i].c_str();
|
||||
|
||||
data_table::TableInput tbl;
|
||||
tbl.name = "collectors";
|
||||
tbl.headers = {"ID", "Name", "Description"};
|
||||
tbl.types = {data_table::ColumnType::String,
|
||||
data_table::ColumnType::String,
|
||||
data_table::ColumnType::String};
|
||||
tbl.cells = coll_cells.empty() ? nullptr : coll_cells.data();
|
||||
tbl.rows = (int)g_collectors.size();
|
||||
tbl.cols = 3;
|
||||
// All columns use default Text renderer — no column_specs needed.
|
||||
|
||||
ImGui::BeginChild("##collectors_dt", ImVec2(0, 200), false);
|
||||
data_table::render("##dt_collectors", {tbl}, g_dt_collectors);
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
if (g_coll_selected >= 0 &&
|
||||
@@ -192,32 +204,49 @@ static void draw_launcher() {
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::BeginTable("##results", 4,
|
||||
ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders |
|
||||
ImGuiTableFlags_ScrollY | ImGuiTableFlags_Resizable)) {
|
||||
ImGui::TableSetupColumn("ID", ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableSetupColumn("Kind", ImGuiTableColumnFlags_WidthFixed, 80);
|
||||
ImGui::TableSetupColumn("Domain", ImGuiTableColumnFlags_WidthFixed, 100);
|
||||
ImGui::TableSetupColumn("Description", ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableHeadersRow();
|
||||
// Build flat cells array for data_table::render (row-major, 4 cols).
|
||||
{
|
||||
static std::vector<std::string> res_cell_backing;
|
||||
static std::vector<const char*> res_cells;
|
||||
|
||||
for (int i = 0; i < (int)g_results.size(); ++i) {
|
||||
const auto& r = g_results[i];
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
bool sel = (i == g_selected);
|
||||
if (ImGui::Selectable(r.id.c_str(), sel,
|
||||
ImGuiSelectableFlags_SpanAllColumns)) {
|
||||
g_selected = i;
|
||||
}
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::TextUnformatted(r.kind.c_str());
|
||||
ImGui::TableSetColumnIndex(2);
|
||||
ImGui::TextUnformatted(r.domain.c_str());
|
||||
ImGui::TableSetColumnIndex(3);
|
||||
ImGui::TextUnformatted(r.description.c_str());
|
||||
res_cell_backing.clear();
|
||||
res_cell_backing.reserve(g_results.size() * 4);
|
||||
for (const auto& r : g_results) {
|
||||
res_cell_backing.push_back(r.id);
|
||||
res_cell_backing.push_back(r.kind);
|
||||
res_cell_backing.push_back(r.domain);
|
||||
res_cell_backing.push_back(r.description);
|
||||
}
|
||||
ImGui::EndTable();
|
||||
res_cells.resize(res_cell_backing.size());
|
||||
for (size_t i = 0; i < res_cell_backing.size(); ++i)
|
||||
res_cells[i] = res_cell_backing[i].c_str();
|
||||
|
||||
// Column spec for Kind (col 1): Badge per kind value.
|
||||
data_table::ColumnSpec cs_kind;
|
||||
cs_kind.id = "kind";
|
||||
cs_kind.renderer = data_table::CellRenderer::Badge;
|
||||
cs_kind.badges = {
|
||||
data_table::BadgeRule{"function", "#3b82f6", ""},
|
||||
data_table::BadgeRule{"pipeline", "#8b5cf6", ""},
|
||||
data_table::BadgeRule{"component", "#f59e0b", ""},
|
||||
};
|
||||
|
||||
data_table::TableInput tbl;
|
||||
tbl.name = "results";
|
||||
tbl.headers = {"ID", "Kind", "Domain", "Description"};
|
||||
tbl.types = {data_table::ColumnType::String,
|
||||
data_table::ColumnType::String,
|
||||
data_table::ColumnType::String,
|
||||
data_table::ColumnType::String};
|
||||
tbl.cells = res_cells.empty() ? nullptr : res_cells.data();
|
||||
tbl.rows = (int)g_results.size();
|
||||
tbl.cols = 4;
|
||||
tbl.column_specs.resize(4); // default Text for all
|
||||
tbl.column_specs[1] = cs_kind; // Badge for Kind
|
||||
|
||||
ImGui::BeginChild("##results_dt", ImVec2(0, -1), false);
|
||||
data_table::render("##dt_results", {tbl}, g_dt_results);
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
if (g_selected >= 0 && g_selected < (int)g_results.size()) {
|
||||
|
||||
Reference in New Issue
Block a user