From 1bad5685a19000b4014f9eb880133fe9539a6728 Mon Sep 17 00:00:00 2001 From: Egutierrez Date: Tue, 19 May 2026 00:31:31 +0200 Subject: [PATCH] chore: auto-commit (3 archivos) - app.md - appicon.ico - tabs.cpp Co-Authored-By: Claude Opus 4.7 (1M context) --- app.md | 23 ++++----- appicon.ico | Bin 8841 -> 9521 bytes tabs.cpp | 146 +++++++++++++++++++++++++--------------------------- 3 files changed, 81 insertions(+), 88 deletions(-) diff --git a/app.md b/app.md index 93a064e..a109104 100644 --- a/app.md +++ b/app.md @@ -2,21 +2,10 @@ name: dag_engine_ui lang: cpp domain: tools +version: 0.1.0 description: "Frontend ImGui para dag_engine. Lista, lanza e inspecciona DAGs con live updates via WS." tags: [imgui, dashboard, dag, scheduler, http, websocket] uses_functions: - - data_table_cpp_viz - - viz_render_cpp_viz - - compute_stage_cpp_core - - compute_pipeline_cpp_core - - compute_column_stats_cpp_core - - auto_detect_type_cpp_core - - tql_emit_cpp_core - - tql_apply_cpp_core - - lua_engine_cpp_core - - join_tables_cpp_core - - tql_to_sql_cpp_core - - llm_anthropic_cpp_core - empty_state_cpp_core uses_types: [] uses_modules: [data_table_cpp] @@ -77,3 +66,13 @@ cd cpp && cmake --build build --target dag_engine_ui -j ## Backend Apunta a `http://127.0.0.1:8090` (dag_engine.service via systemd user unit). Para usuario / formato de DAG / troubleshooting: **[apps/dag_engine/README.md](../../apps/dag_engine/README.md)**. + + +## Capability growth log + +Una linea por bump SemVer. Bump-type segun `.claude/commands/version.md`: +- `major`: breaking observable (CLI args, schema BBDD propia, formato wire). +- `minor`: feature aditiva (nuevo panel, endpoint, opcion). +- `patch`: bugfix sin cambio observable. + +- v0.1.0 (2026-05-18) — baseline. diff --git a/appicon.ico b/appicon.ico index 05cc7f1598e7ea249512e51cbd118fcdc73dc628..bd387b3305d2a8e1fa28734c5c9dfb610e41395a 100644 GIT binary patch literal 9521 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 diff --git a/tabs.cpp b/tabs.cpp index 07492d9..bbb6c2d 100644 --- a/tabs.cpp +++ b/tabs.cpp @@ -371,86 +371,79 @@ void draw_run_detail(const std::string& api_url) { return; } - // Steps table — render nativo (ImGui::BeginTable) en vez de data_table::render - // para soportar la columna "Function" clickable (badge -> abre Function panel). - // Status sigue mostrando badge coloreado por tipo. - ImGui::BeginChild("##run_steps_wrap", ImVec2(-1, ImGui::GetContentRegionAvail().y * 0.5f)); - const ImGuiTableFlags steps_flags = - ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | - ImGuiTableFlags_Resizable | ImGuiTableFlags_SizingStretchProp | - ImGuiTableFlags_ScrollY; - if (ImGui::BeginTable("##dt_run_steps", 6, steps_flags)) { - ImGui::TableSetupScrollFreeze(0, 1); - ImGui::TableSetupColumn("Step", ImGuiTableColumnFlags_WidthStretch, 1.6f); - ImGui::TableSetupColumn("Function", ImGuiTableColumnFlags_WidthStretch, 2.2f); - ImGui::TableSetupColumn("Status", ImGuiTableColumnFlags_WidthStretch, 0.8f); - ImGui::TableSetupColumn("Exit", ImGuiTableColumnFlags_WidthStretch, 0.4f); - ImGui::TableSetupColumn("Duration", ImGuiTableColumnFlags_WidthStretch, 0.7f); - ImGui::TableSetupColumn("Started", ImGuiTableColumnFlags_WidthStretch, 1.2f); - ImGui::TableHeadersRow(); + // Steps table — migrado a data_table::render (issue 0107g). + // La columna Function usa CellRenderer::Button con action_id="open_fn". + // Celdas con function_id="" muestran "(shell)" via Text (no button). + static data_table::State g_st_run_steps; + static std::vector g_back_run_steps; + static std::vector g_ptrs_run_steps; - for (size_t i = 0; i < steps.size(); i++) { - auto& s = steps[i]; - ImGui::TableNextRow(); - - // Step name - ImGui::TableSetColumnIndex(0); - ImGui::TextUnformatted(s.step_name.c_str()); - - // Function — badge clickable o "(shell)" - ImGui::TableSetColumnIndex(1); - if (!s.function_id.empty()) { - ImGui::PushID(static_cast(i)); - // Small button styled like a badge (registry green). - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.13f, 0.55f, 0.30f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.18f, 0.65f, 0.38f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.10f, 0.45f, 0.25f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1, 1, 1, 1)); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6, 1)); - char btn[512]; - std::snprintf(btn, sizeof(btn), "%s %s", TI_FUNCTION, s.function_id.c_str()); - if (ImGui::SmallButton(btn)) { - auto& fp = function_panel(); - if (!fp.selected_id.empty() && fp.selected_id != s.function_id) { - fp.breadcrumb.push_back(fp.selected_id); - } - fp.selected_id = s.function_id; - fp.loaded = false; - fp.load_error.clear(); - } - ImGui::PopStyleVar(); - ImGui::PopStyleColor(4); - ImGui::PopID(); - } else { - ImGui::TextDisabled("(shell)"); - } - - // Status badge - ImGui::TableSetColumnIndex(2); - BadgeVariant v = BadgeVariant::Default; - if (s.status == "success") v = BadgeVariant::Success; - else if (s.status == "failed") v = BadgeVariant::Error; - else if (s.status == "running") v = BadgeVariant::Warning; - else if (s.status == "cancelled") v = BadgeVariant::Default; - else if (s.status == "pending") v = BadgeVariant::Info; - badge(s.status.c_str(), v); - - // Exit - ImGui::TableSetColumnIndex(3); - ImGui::Text("%d", s.exit_code); - - // Duration - ImGui::TableSetColumnIndex(4); - ImGui::TextUnformatted(format_duration(s.duration_ms).c_str()); - - // Started - ImGui::TableSetColumnIndex(5); - ImGui::TextUnformatted(s.started_at.c_str()); - } - ImGui::EndTable(); + g_back_run_steps.clear(); + for (const auto& s : steps) { + g_back_run_steps.push_back(s.step_name); + g_back_run_steps.push_back(s.function_id.empty() ? "(shell)" : s.function_id); + g_back_run_steps.push_back(s.status); + g_back_run_steps.push_back(std::to_string(s.exit_code)); + g_back_run_steps.push_back(format_duration(s.duration_ms)); + g_back_run_steps.push_back(s.started_at); } + g_ptrs_run_steps.clear(); + for (const auto& sv : g_back_run_steps) g_ptrs_run_steps.push_back(sv.c_str()); + + data_table::TableInput tbl_steps; + tbl_steps.name = "dt_run_steps"; + tbl_steps.headers = {"Step", "Function", "Status", "Exit", "Duration", "Started"}; + tbl_steps.types = { + data_table::ColumnType::String, data_table::ColumnType::String, + data_table::ColumnType::String, data_table::ColumnType::Int, + data_table::ColumnType::String, data_table::ColumnType::String, + }; + tbl_steps.cells = g_ptrs_run_steps.empty() ? nullptr : g_ptrs_run_steps.data(); + tbl_steps.rows = (int)steps.size(); + tbl_steps.cols = 6; + + tbl_steps.column_specs.resize(tbl_steps.cols); + for (int i = 0; i < tbl_steps.cols; i++) tbl_steps.column_specs[i].id = tbl_steps.headers[i]; + // Function → Button (celdas "(shell)" no son function_ids — se ven como texto si label=value) + tbl_steps.column_specs[1].renderer = data_table::CellRenderer::Button; + tbl_steps.column_specs[1].button_action = "open_fn"; + tbl_steps.column_specs[1].button_label = ""; // "" → usa valor de celda como label + tbl_steps.column_specs[1].button_color_hex = "#21882b"; + tbl_steps.column_specs[1].tooltip = "Open in Function panel"; + tbl_steps.column_specs[1].tooltip_on_hover = true; + // Status → CategoricalChip + tbl_steps.column_specs[2].renderer = data_table::CellRenderer::CategoricalChip; + tbl_steps.column_specs[2].chips = { + {"success", "#22c55e"}, + {"failed", "#ef4444"}, + {"running", "#f59e0b"}, + {"cancelled", "#a3a3a3"}, + {"pending", "#3b82f6"}, + }; + // Duration → Duration renderer + tbl_steps.column_specs[4].renderer = data_table::CellRenderer::Duration; + tbl_steps.column_specs[4].duration_warn_ms = 5000.0f; + tbl_steps.column_specs[4].duration_error_ms = 30000.0f; + + std::vector step_events; + ImGui::BeginChild("##run_steps_wrap", ImVec2(-1, ImGui::GetContentRegionAvail().y * 0.5f)); + data_table::render("##dt_run_steps", {tbl_steps}, g_st_run_steps, &step_events); ImGui::EndChild(); + for (const auto& ev : step_events) { + if (ev.kind == data_table::TableEventKind::ButtonClick + && ev.action_id == "open_fn" + && ev.value != "(shell)") { + auto& fp = function_panel(); + if (!fp.selected_id.empty() && fp.selected_id != ev.value) { + fp.breadcrumb.push_back(fp.selected_id); + } + fp.selected_id = ev.value; + fp.loaded = false; + fp.load_error.clear(); + } + } + // stdout/stderr expandible por step. ImGui::Separator(); ImGui::TextUnformatted("Step output:"); @@ -728,6 +721,7 @@ void draw_health(const std::string& /*api_url*/, return; } + // LAYOUT-TABLE — KPI/form/splitter, no data; keep BeginTable inline. if (ImGui::BeginTable("##health_kpis", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_SizingStretchSame)) {