Files
fn_registry/dev/data_table_integration_audit.md
T
egutierrez b9716a7cd6 chore: snapshot WIP previo + flow 0008 + 7 sub-issues (0112-0119)
Snapshot de WIP acumulado de sesiones previas antes de merge wave 1
del flow 0008 (kanban_cpp + agent_runner_api + DoD schema).

Incluye:
- dev/flows/0008-kanban-cpp-and-agent-workflows.md
- dev/issues/0112-0119*.md (7 sub-issues)
- WIP previo en cmd/fn/doctor.go, registry/*, modules/, cpp/, etc.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 18:17:08 +02:00

25 KiB

data_table integration audit — 8 apps

Canonical pattern (from modules/data_table/data_table.md):

static data_table::State g_table_state;       // PERSISTENT entre frames
data_table::TableInput tbl;
tbl.name = "my_table";
tbl.headers = {"col1","col2"};
tbl.types   = {data_table::ColumnType::String, data_table::ColumnType::Int};
tbl.cells   = cells_ptr;  // row-major flat array
tbl.rows    = N;
tbl.cols    = 2;

std::vector<data_table::TableEvent> events;
ImGui::BeginChild("##tbl_host");
data_table::render("##my_tbl_id", { tbl }, g_table_state, &events);
ImGui::EndChild();

for (const auto& ev : events) {
    if (ev.kind == data_table::TableEventKind::RowDoubleClick) { ... }
}

Anti-patterns the audit flags:

  • inline_begintable [warn]: app calls ImGui::BeginTable directly instead of data_table::render. Migrar la tabla a data_table::render con un TableInput.
  • state_not_persistent [error]: data_table::State declarado dentro de funcion sin static. Mover a static local o miembro global; sino se pierde drill/sort/filtros cada frame.
  • no_child_host [warn]: data_table::render se llama sin BeginChild/Begin en las ~30 lineas previas. Envolver con ImGui::BeginChild("##host");ImGui::EndChild();.
  • no_event_sink [info]: app declara uses_modules data_table_cpp pero no captura events_out. Pasar &events para reaccionar a double-click / right-click / ButtonClick.
  • cmake_missing_link [error]: app.md declara uses_modules: [data_table_cpp] pero CMakeLists.txt no enlaza fn_module_data_table.

app_gestion [warn] (apps/app_gestion)

inline_begintable [warn] apps/app_gestion/main.cpp:722

snippet: if (ImGui::BeginTable("##linked_tbl", 4,

    717                          ? "?" : a->linked_build.c_str());
    718      if (a->linked_modules.empty()) {
    719          ImGui::TextDisabled("(sin info — la app no se ha buildeado todavia,"
    720                              " o no genera _modules_generated.cpp)");
    721      } else {
>>  722          if (ImGui::BeginTable("##linked_tbl", 4,
    723                                ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
    724              ImGui::TableSetupColumn("module");
    725              ImGui::TableSetupColumn("linked");
    726              ImGui::TableSetupColumn("registry");
    727              ImGui::TableSetupColumn("status");

dag_engine_ui [warn] (apps/dag_engine_ui)

inline_begintable [warn] apps/dag_engine_ui/tabs.cpp:382

snippet: if (ImGui::BeginTable("##dt_run_steps", 6, steps_flags)) {

    377      ImGui::BeginChild("##run_steps_wrap", ImVec2(-1, ImGui::GetContentRegionAvail().y * 0.5f));
    378      const ImGuiTableFlags steps_flags =
    379          ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg |
    380          ImGuiTableFlags_Resizable | ImGuiTableFlags_SizingStretchProp |
    381          ImGuiTableFlags_ScrollY;
>>  382      if (ImGui::BeginTable("##dt_run_steps", 6, steps_flags)) {
    383          ImGui::TableSetupScrollFreeze(0, 1);
    384          ImGui::TableSetupColumn("Step",     ImGuiTableColumnFlags_WidthStretch, 1.6f);
    385          ImGui::TableSetupColumn("Function", ImGuiTableColumnFlags_WidthStretch, 2.2f);
    386          ImGui::TableSetupColumn("Status",   ImGuiTableColumnFlags_WidthStretch, 0.8f);
    387          ImGui::TableSetupColumn("Exit",     ImGuiTableColumnFlags_WidthStretch, 0.4f);

inline_begintable [warn] apps/dag_engine_ui/tabs.cpp:731

snippet: if (ImGui::BeginTable("##health_kpis", 4,

    726                      "Trigger a DAG to populate health metrics.");
    727          ImGui::End();
    728          return;
    729      }
    730  
>>  731      if (ImGui::BeginTable("##health_kpis", 4,
    732                            ImGuiTableFlags_Borders | ImGuiTableFlags_SizingStretchSame))
    733      {
    734          ImGui::TableNextRow();
    735  
    736          ImGui::TableNextColumn();

data_factory [warn] (apps/data_factory)

no_child_host [warn] apps/data_factory/tabs.cpp:291

snippet: data_table::render(dt_id, {tbl}, *st, &events);

    286      }
    287      cells_to_ptrs(*backing, *ptrs);
    288      tbl.cells = ptrs->data();
    289  
    290      std::vector<data_table::TableEvent> events;
>>  291      data_table::render(dt_id, {tbl}, *st, &events);
    292  
    293      for (auto& ev : events) {
    294          if (ev.kind == data_table::TableEventKind::RowDoubleClick &&
    295              ev.row >= 0 && ev.row < static_cast<int>(filtered.size()))
    296          {

no_child_host [warn] apps/data_factory/tabs.cpp:454

snippet: data_table::render("##dt_tables", {tbl}, g_st_tables, &tbl_events);

    449          }
    450          cells_to_ptrs(g_back_tables, g_ptrs_tables);
    451          tbl.cells = g_ptrs_tables.data();
    452  
    453          std::vector<data_table::TableEvent> tbl_events;
>>  454          data_table::render("##dt_tables", {tbl}, g_st_tables, &tbl_events);
    455          for (auto& ev : tbl_events) {
    456              if (ev.kind == data_table::TableEventKind::RowDoubleClick &&
    457                  ev.row >= 0 && ev.row < static_cast<int>(tables.size()))
    458              {
    459                  const auto& t = tables[ev.row];

no_child_host [warn] apps/data_factory/tabs.cpp:531

snippet: data_table::render("##dt_databases", {tbl}, g_st_databases);

    526              g_back_databases.push_back(d.last_seen_at.empty() ? "-" : d.last_seen_at);
    527          }
    528          cells_to_ptrs(g_back_databases, g_ptrs_databases);
    529          tbl.cells = g_ptrs_databases.data();
    530  
>>  531          data_table::render("##dt_databases", {tbl}, g_st_databases);
    532      }
    533      ImGui::End();
    534  }
    535  
    536  // ---------------------------------------------------------------------------

no_child_host [warn] apps/data_factory/tabs.cpp:619

snippet: data_table::render("##dt_kpis", {tbl}, g_st_kpis);

    614          std::snprintf(buf, sizeof(buf), "%lld KB", kb_24h);          g_back_kpis.push_back(buf);
    615  
    616          cells_to_ptrs(g_back_kpis, g_ptrs_kpis);
    617          tbl.cells = g_ptrs_kpis.data();
    618  
>>  619          data_table::render("##dt_kpis", {tbl}, g_st_kpis);
    620      }
    621  
    622      ImGui::Separator();
    623      ImGui::TextDisabled("Computed client-side from %zu runs in cache.", runs_all.size());
    624      ImGui::End();

no_child_host [warn] apps/data_factory/tabs.cpp:883

snippet: data_table::render("##dt_node_runs", {tbl}, g_st_node_runs, &events);

    878          }
    879          cells_to_ptrs(g_back_node_runs, g_ptrs_node_runs);
    880          tbl.cells = g_ptrs_node_runs.data();
    881  
    882          std::vector<data_table::TableEvent> events;
>>  883          data_table::render("##dt_node_runs", {tbl}, g_st_node_runs, &events);
    884  
    885          for (auto& ev : events) {
    886              if (ev.kind == data_table::TableEventKind::RowDoubleClick &&
    887                  ev.row >= 0 && ev.row < static_cast<int>(shown_runs.size()))
    888              {

no_child_host [warn] apps/data_factory/tabs.cpp:992

snippet: data_table::render("##dt_preview", {tbl}, g_st_preview, nullptr, true);

    987              }
    988          }
    989          cells_to_ptrs(g_back_preview, g_ptrs_preview);
    990          tbl.cells = g_ptrs_preview.data();
    991  
>>  992          data_table::render("##dt_preview", {tbl}, g_st_preview, nullptr, true);
    993      }
    994  
    995      // Pagination controls.
    996      ImGui::Separator();
    997      {

graph_explorer [warn] (projects/osint_graph/apps/graph_explorer)

inline_begintable [warn] projects/osint_graph/apps/graph_explorer/extract_panel.cpp:981

snippet: if (ImGui::BeginTable("##ents", 5,

    976      }
    977  
    978      // Tabla de entidades.
    979      if (!res->entities.empty() &&
    980          ImGui::CollapsingHeader("Entities", ImGuiTreeNodeFlags_DefaultOpen)) {
>>  981          if (ImGui::BeginTable("##ents", 5,
    982                  ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg |
    983                  ImGuiTableFlags_ScrollY,
    984                  ImVec2(0.0f, 200.0f))) {
    985              ImGui::TableSetupColumn("",     ImGuiTableColumnFlags_WidthFixed, 28.0f);
    986              ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed, 120.0f);

inline_begintable [warn] projects/osint_graph/apps/graph_explorer/extract_panel.cpp:1027

snippet: if (ImGui::BeginTable("##rels", 5,

   1022      }
   1023  
   1024      // Tabla de relaciones.
   1025      if (!res->relations.empty() &&
   1026          ImGui::CollapsingHeader("Relations", ImGuiTreeNodeFlags_DefaultOpen)) {
>> 1027          if (ImGui::BeginTable("##rels", 5,
   1028                  ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg |
   1029                  ImGuiTableFlags_ScrollY,
   1030                  ImVec2(0.0f, 160.0f))) {
   1031              ImGui::TableSetupColumn("",      ImGuiTableColumnFlags_WidthFixed, 28.0f);
   1032              ImGui::TableSetupColumn("From",  ImGuiTableColumnFlags_WidthFixed, 100.0f);

inline_begintable [warn] projects/osint_graph/apps/graph_explorer/main.cpp:1127

snippet: if (ImGui::BeginTable("##enr_params", 2,

   1122      // con mas params de los que llenamos al abrir la ventana.
   1123      if (g_app.enr_modal_param_bufs.size() < spec->params.size()) {
   1124          g_app.enr_modal_param_bufs.resize(spec->params.size());
   1125      }
   1126  
>> 1127      if (ImGui::BeginTable("##enr_params", 2,
   1128                             ImGuiTableFlags_SizingStretchProp |
   1129                             ImGuiTableFlags_NoBordersInBody)) {
   1130          ImGui::TableSetupColumn("name",  ImGuiTableColumnFlags_WidthFixed, 110.0f);
   1131          ImGui::TableSetupColumn("value", ImGuiTableColumnFlags_WidthStretch);
   1132  

inline_begintable [warn] projects/osint_graph/apps/graph_explorer/views.cpp:885

snippet: if (ImGui::BeginTable("##insp_id", 2,

    880      // Layout label-izquierda / input-derecha via 2-col table. El label
    881      // alineado al frame del input y el input estirado al ancho restante.
    882      ImGui::TextUnformatted("Identity");
    883      ImGui::Separator();
    884  
>>  885      if (ImGui::BeginTable("##insp_id", 2,
    886                             ImGuiTableFlags_SizingStretchProp |
    887                             ImGuiTableFlags_NoBordersInBody)) {
    888          ImGui::TableSetupColumn("k", ImGuiTableColumnFlags_WidthFixed, 90.0f);
    889          ImGui::TableSetupColumn("v", ImGuiTableColumnFlags_WidthStretch);
    890  

inline_begintable [warn] projects/osint_graph/apps/graph_explorer/views.cpp:958

snippet: if (ImGui::BeginTable("##insp_fields", 2,

    953          ImGui::TextUnformatted("Fields");
    954          ImGui::Separator();
    955          const EntitySpec* spec = find_entity_spec(app.parsed_types,
    956                                                      app.insp_type_buf);
    957  
>>  958          if (ImGui::BeginTable("##insp_fields", 2,
    959                                 ImGuiTableFlags_SizingStretchProp |
    960                                 ImGuiTableFlags_NoBordersInBody)) {
    961              ImGui::TableSetupColumn("k", ImGuiTableColumnFlags_WidthFixed, 90.0f);
    962              ImGui::TableSetupColumn("v", ImGuiTableColumnFlags_WidthStretch);
    963  

inline_begintable [warn] projects/osint_graph/apps/graph_explorer/views.cpp:1546

snippet: // OLD: ImGui::BeginTable("##tablev", 6, ...) with manual sort/filter/clipper.

   1541  }
   1542  
   1543  // ----------------------------------------------------------------------------
   1544  // Table view (issue 0004) — migrated to data_table::render (issue 0081-J).
   1545  //
>> 1546  // OLD: ImGui::BeginTable("##tablev", 6, ...) with manual sort/filter/clipper.
   1547  //      Per-column filter popups + chips toolbar + TabBar per type.
   1548  //      Click on row selected node in graph viewport.
   1549  //
   1550  // NEW: data_table::render() provides sort + filter + viz + stages.
   1551  //      AppState::table_dt_state persists the UI state between frames.

inline_begintable [warn] projects/osint_graph/apps/graph_explorer/views.cpp:1854

snippet: if (col_count > 0 && ImGui::BeginTable("##te_rows", col_count, tflags,

   1849                                  : (int)m.columns.size() + 2;
   1850          ImGuiTableFlags tflags =
   1851              ImGuiTableFlags_Borders   | ImGuiTableFlags_RowBg    |
   1852              ImGuiTableFlags_ScrollY   | ImGuiTableFlags_Resizable |
   1853              ImGuiTableFlags_SizingStretchProp;
>> 1854          if (col_count > 0 && ImGui::BeginTable("##te_rows", col_count, tflags,
   1855                                  ImVec2(0, -ImGui::GetFrameHeightWithSpacing()))) {
   1856              ImGui::TableSetupScrollFreeze(0, 1);
   1857              if (is_group) {
   1858                  for (size_t i = 0; i < m.columns.size(); ++i) {
   1859                      bool is_id = (i == 0);

inline_begintable [warn] projects/osint_graph/apps/graph_explorer/views.cpp:2292

snippet: if (ImGui::BeginTable("##te_fields", 5,

   2287                  // Fields table
   2288                  ImGui::Spacing();
   2289                  ImGui::TextUnformatted("Fields");
   2290                  ImGui::Separator();
   2291  
>> 2292                  if (ImGui::BeginTable("##te_fields", 5,
   2293                                         ImGuiTableFlags_BordersInnerV
   2294                                       | ImGuiTableFlags_RowBg
   2295                                       | ImGuiTableFlags_SizingStretchProp)) {
   2296                      ImGui::TableSetupColumn("name");
   2297                      ImGui::TableSetupColumn("type",     ImGuiTableColumnFlags_WidthFixed, 90.0f);

no_child_host [warn] projects/osint_graph/apps/graph_explorer/views.cpp:1632

snippet: data_table::render("##tablev_dt", {tbl}, app.table_dt_state);

   1627      tbl.rows  = s_rows_cached;
   1628      tbl.cols  = k_ncols;
   1629  
   1630      // Render con chrome completo (barra de chips + breadcrumb).
   1631      // app.table_dt_state persiste entre frames.
>> 1632      data_table::render("##tablev_dt", {tbl}, app.table_dt_state);
   1633  
   1634      ImGui::End();
   1635  }
   1636  
   1637  // ----------------------------------------------------------------------------

navegator_dashboard [warn] (projects/navegator/apps/navegator_dashboard)

inline_begintable [warn] projects/navegator/apps/navegator_dashboard/autoextract_panel.cpp:528

snippet: if (ImGui::BeginTable("##ax_schema", 5, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {

    523      {
    524          std::lock_guard<std::mutex> lk(g_ax.mu);
    525          sc_copy = g_ax.schema;
    526      }
    527  
>>  528      if (ImGui::BeginTable("##ax_schema", 5, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
    529          ImGui::TableSetupColumn("field");
    530          ImGui::TableSetupColumn("selector");
    531          ImGui::TableSetupColumn("sample");
    532          ImGui::TableSetupColumn("type");
    533          ImGui::TableSetupColumn("keep");

no_child_host [warn] projects/navegator/apps/navegator_dashboard/panels.cpp:234

snippet: data_table::render("##dt_browsers", {tbl}, g_browsers.dt_state, &dt_events, /show_chrome=/false);

    229                  data_table::BadgeRule{"visible",  "#22c55e", "visible"},
    230              };
    231          }
    232  
    233          std::vector<data_table::TableEvent> dt_events;
>>  234          data_table::render("##dt_browsers", {tbl}, g_browsers.dt_state, &dt_events, /*show_chrome=*/false);
    235          for (auto& ev : dt_events) {
    236              if (ev.kind == data_table::TableEventKind::RowDoubleClick &&
    237                  ev.row >= 0 && ev.row < static_cast<int>(g_browsers.instances.size())) {
    238                  g_session().select_browser(g_browsers.instances[ev.row].port);
    239              }

no_child_host [warn] projects/navegator/apps/navegator_dashboard/panels.cpp:456

snippet: data_table::render("##dt_tabs", {tbl}, g_tabs_ui.dt_state, &dt_events, /show_chrome=/false);

    451              data_table::BadgeRule{"no",  "#6b7280", "no"},
    452          };
    453      }
    454  
    455      std::vector<data_table::TableEvent> dt_events;
>>  456      data_table::render("##dt_tabs", {tbl}, g_tabs_ui.dt_state, &dt_events, /*show_chrome=*/false);
    457      for (auto& ev : dt_events) {
    458          if (ev.kind == data_table::TableEventKind::RowDoubleClick &&
    459              ev.row >= 0 && ev.row < static_cast<int>(visible_tabs.size())) {
    460              const CdpTab* tp = visible_tabs[ev.row];
    461              if (tp && !tp->ws_url.empty()) {

no_child_host [warn] projects/navegator/apps/navegator_dashboard/panels.cpp:1016

snippet: data_table::render("##dt_wsframes", {ws_tbl}, g_dt_wsframes, false);

   1011                      data_table::BadgeRule{"ping",   "#6b7280", "ping"},
   1012                      data_table::BadgeRule{"pong",   "#6b7280", "pong"},
   1013                  };
   1014              }
   1015  
>> 1016              data_table::render("##dt_wsframes", {ws_tbl}, g_dt_wsframes, false);
   1017              ImGui::EndTabItem();
   1018          }
   1019          ImGui::EndTabBar();
   1020      }
   1021  }

no_child_host [warn] projects/navegator/apps/navegator_dashboard/panels.cpp:1322

snippet: data_table::render("##dt_requests", {req_tbl}, g_net_ui.dt_state, &dt_events, /show_chrome=/true);

   1317              cs.duration_warn_ms  = 1000.0f;
   1318              cs.duration_error_ms = 5000.0f;
   1319          }
   1320  
   1321          std::vector<data_table::TableEvent> dt_events;
>> 1322          data_table::render("##dt_requests", {req_tbl}, g_net_ui.dt_state, &dt_events, /*show_chrome=*/true);
   1323          for (auto& ev : dt_events) {
   1324              if (ev.kind == data_table::TableEventKind::RowDoubleClick &&
   1325                  ev.row >= 0 && ev.row < static_cast<int>(filtered.size())) {
   1326                  g_net_ui.selected_id    = filtered[ev.row]->id;
   1327                  g_net_ui.selected_index = ev.row;

inline_begintable [warn] projects/navegator/apps/navegator_dashboard/recipes_panel.cpp:238

snippet: } else if (ImGui::BeginTable("##recipes_tbl", 6,

    233      }
    234  
    235      if (rows_copy.empty()) {
    236          ImGui::TextDisabled("No recipes in projects/navegator/profiles/default/recipes/.");
    237          ImGui::TextDisabled("Use AutoExtract panel to create one.");
>>  238      } else if (ImGui::BeginTable("##recipes_tbl", 6,
    239                                   ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
    240          ImGui::TableSetupColumn("name");
    241          ImGui::TableSetupColumn("url_pattern");
    242          ImGui::TableSetupColumn("last_status");
    243          ImGui::TableSetupColumn("last_at");

odr_console [ok] (projects/online_data_recopilation/apps/odr_console)

no_event_sink [info] projects/online_data_recopilation/apps/odr_console:0

snippet: no TableEvent / events_out found in any source file

registry_dashboard [warn] (projects/fn_monitoring/apps/registry_dashboard)

inline_begintable [warn] projects/fn_monitoring/apps/registry_dashboard/views.cpp:380

snippet: if (ImGui::BeginTable("##kpi_grid", 4, flags)) {

    375      // del registry). Si no hay datos cargados, queda vacio y el card mostrara
    376      // solo valor + delta placeholder.
    377      const float* spark_data  = data.date_values.empty() ? nullptr : data.date_values.data();
    378      const int    spark_count = static_cast<int>(data.date_values.size());
    379  
>>  380      if (ImGui::BeginTable("##kpi_grid", 4, flags)) {
    381          struct KPI { const char* label; float value; const char* fmt; const char* icon; };
    382          const KPI cards[8] = {
    383              {"Functions",  static_cast<float>(stats.total_functions),  "%.0f",   TI_FUNCTION},
    384              {"Types",      static_cast<float>(stats.total_types),      "%.0f",   TI_HEXAGON},
    385              {"Apps",       static_cast<float>(stats.total_apps),       "%.0f",   TI_APPS},

inline_begintable [warn] projects/fn_monitoring/apps/registry_dashboard/views.cpp:436

snippet: if (ImGui::BeginTable("##chart_grid", 4, flags)) {

    431  void draw_charts(RegistryData& data, float height) {
    432      const ImGuiTableFlags flags = ImGuiTableFlags_SizingStretchSame
    433                                  | ImGuiTableFlags_NoPadOuterX;
    434      const float plot_h = height - 48.0f;
    435  
>>  436      if (ImGui::BeginTable("##chart_grid", 4, flags)) {
    437          ImGui::TableNextRow();
    438  
    439          ImGui::TableSetColumnIndex(0);
    440          {
    441              ImVec2 sz(ImGui::GetContentRegionAvail().x, height);

inline_begintable [warn] projects/fn_monitoring/apps/registry_dashboard/views.cpp:648

snippet: if (ImGui::BeginTable("##monitor_kpi", 7, flags)) {

    643  
    644      // 7 KPI cards: Calls / MCP / Reg% / Errors / Violations / Copies / Versions
    645      // "MCP" = calls Claude lanza via tools registry-aware (mcp / fn_cli_run /
    646      //        heredoc). "Reg %" = porcentaje del total con function_id no vacio.
    647      const ImGuiTableFlags flags = ImGuiTableFlags_SizingStretchSame | ImGuiTableFlags_NoPadOuterX;
>>  648      if (ImGui::BeginTable("##monitor_kpi", 7, flags)) {
    649          struct KPI { const char* label; float value; const char* icon; const char* fmt; };
    650          const KPI cards[7] = {
    651              {"Calls",      static_cast<float>(cu.total_calls),      TI_ACTIVITY,        "%.0f"},
    652              {"MCP",        static_cast<float>(cu.total_mcp),        TI_PLUG_CONNECTED,  "%.0f"},
    653              {"Reg %",      static_cast<float>(cu.registry_pct),     TI_PERCENTAGE,      "%.1f%%"},

inline_begintable [warn] projects/fn_monitoring/apps/registry_dashboard/views.cpp:1110

snippet: if (!ImGui::BeginTable("##proj_layout", 2, flags)) return;

   1105      }
   1106  
   1107      // Dos columnas: izquierda arbol, derecha detalle.
   1108      const ImGuiTableFlags flags = ImGuiTableFlags_Resizable
   1109                                  | ImGuiTableFlags_SizingStretchProp;
>> 1110      if (!ImGui::BeginTable("##proj_layout", 2, flags)) return;
   1111  
   1112      ImGui::TableSetupColumn("tree",   ImGuiTableColumnFlags_WidthStretch, 1.0f);
   1113      ImGui::TableSetupColumn("detail", ImGuiTableColumnFlags_WidthStretch, 2.5f);
   1114      ImGui::TableNextRow();
   1115  

inline_begintable [warn] projects/fn_monitoring/apps/registry_dashboard/views.cpp:1448

snippet: if (!ImGui::BeginTable("##explorer_layout", 2, flags)) return;

   1443          return;
   1444      }
   1445  
   1446      const ImGuiTableFlags flags = ImGuiTableFlags_Resizable
   1447                                  | ImGuiTableFlags_SizingStretchProp;
>> 1448      if (!ImGui::BeginTable("##explorer_layout", 2, flags)) return;
   1449  
   1450      ImGui::TableSetupColumn("list",   ImGuiTableColumnFlags_WidthStretch, 1.0f);
   1451      ImGui::TableSetupColumn("detail", ImGuiTableColumnFlags_WidthStretch, 2.4f);
   1452      ImGui::TableNextRow();
   1453  

inline_begintable [warn] projects/fn_monitoring/apps/registry_dashboard/work_tab.cpp:239

snippet: if (ImGui::BeginTable("##flows_work", 8,

    234      // Flows table
    235      ImGui::PushStyleColor(ImGuiCol_Text, fn_tokens::colors::text_muted);
    236      ImGui::TextUnformatted("Flows");
    237      ImGui::PopStyleColor();
    238  
>>  239      if (ImGui::BeginTable("##flows_work", 8,
    240          ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders |
    241          ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_Resizable)) {
    242          ImGui::TableSetupColumn("ID",        ImGuiTableColumnFlags_WidthFixed, 50.0f);
    243          ImGui::TableSetupColumn("Name");
    244          ImGui::TableSetupColumn("Pattern",   ImGuiTableColumnFlags_WidthFixed, 110.0f);

inline_begintable [warn] projects/fn_monitoring/apps/registry_dashboard/work_tab.cpp:272

snippet: if (ImGui::BeginTable("##top_issues_work", 7,

    267      ImGui::Spacing();
    268      ImGui::PushStyleColor(ImGuiCol_Text, fn_tokens::colors::text_muted);
    269      ImGui::TextUnformatted("Top issues (priority alta, not done)");
    270      ImGui::PopStyleColor();
    271  
>>  272      if (ImGui::BeginTable("##top_issues_work", 7,
    273          ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders |
    274          ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_Resizable)) {
    275          ImGui::TableSetupColumn("ID",     ImGuiTableColumnFlags_WidthFixed, 70.0f);
    276          ImGui::TableSetupColumn("Title");
    277          ImGui::TableSetupColumn("Type",   ImGuiTableColumnFlags_WidthFixed, 80.0f);

no_event_sink [info] projects/fn_monitoring/apps/registry_dashboard:0

snippet: no TableEvent / events_out found in any source file

services_monitor [ok] (apps/services_monitor)

no_event_sink [info] apps/services_monitor:0

snippet: no TableEvent / events_out found in any source file