// tab_joins — 2 tablas (orders + customers) pasadas a data_table::render. // Demuestra la UI de joins del modulo: drag 'customers' chip → canvas. // Issue 0108 fase 2. #include "tabs.h" #include "qa_state.h" #include "data_table/data_table.h" #include #include #include namespace tables_qa::tabs { namespace { // --------------------------------------------------------------------------- // Backing storage — dos tablas independientes. // --------------------------------------------------------------------------- struct JoinsState { // orders: order_id, customer_id, amount, status std::vector orders_back = { "1001", "C01", "250.00", "shipped", "1002", "C02", "89.99", "pending", "1003", "C01", "540.50", "delivered", "1004", "C03", "12.00", "cancelled", "1005", "C04", "310.75", "shipped", "1006", "C02", "75.00", "pending", "1007", "C05", "1200.00", "delivered", "1008", "C01", "43.20", "shipped", "1009", "C03", "920.00", "processing", "1010", "C04", "67.80", "cancelled", }; std::vector orders_ptrs; // customers: customer_id, name, country, vip_level std::vector customers_back = { "C01", "Alice Romero", "ES", "gold", "C02", "Bob Chen", "US", "silver", "C03", "Carla Müller", "DE", "bronze", "C04", "David Okafor", "NG", "gold", "C05", "Eva Lindqvist", "SE", "silver", }; std::vector customers_ptrs; data_table::State dt; std::vector last_events; bool seeded = false; }; JoinsState g_jst; void seed(JoinsState& s) { s.orders_ptrs.clear(); for (auto& v : s.orders_back) s.orders_ptrs.push_back(v.c_str()); s.customers_ptrs.clear(); for (auto& v : s.customers_back) s.customers_ptrs.push_back(v.c_str()); s.seeded = true; } } // anon // --------------------------------------------------------------------------- void render_joins() { if (!g_jst.seeded) seed(g_jst); // --- Controls bar ------------------------------------------------------- ImGui::TextDisabled( "Drag 'customers' table from chips bar into the canvas to join."); ImGui::Spacing(); // JoinStrategy selector — display only; the module handles the actual join. static int s_strategy = 0; // 0=Left 1=Inner 2=Right 3=Full const char* strategies[] = { "Left", "Inner", "Right", "Full" }; ImGui::SetNextItemWidth(120.0f); ImGui::Combo("Join strategy", &s_strategy, strategies, 4); ImGui::SameLine(); ImGui::TextDisabled("(display only — use the module join UI to apply)"); ImGui::Spacing(); if (ImGui::Button("Reset join state")) { g_jst.dt = data_table::State{}; } ImGui::Spacing(); ImGui::Separator(); ImGui::Spacing(); // --- Build TableInputs -------------------------------------------------- // Main table: orders data_table::TableInput orders_tbl; orders_tbl.name = "orders"; orders_tbl.headers = { "order_id", "customer_id", "amount", "status" }; orders_tbl.types = { data_table::ColumnType::Int, data_table::ColumnType::String, data_table::ColumnType::Float, data_table::ColumnType::String, }; orders_tbl.cells = g_jst.orders_ptrs.data(); orders_tbl.rows = 10; orders_tbl.cols = 4; orders_tbl.column_specs.resize(orders_tbl.cols); for (int i = 0; i < orders_tbl.cols; i++) orders_tbl.column_specs[i].id = orders_tbl.headers[i]; // Secondary table: customers (joinable) data_table::TableInput customers_tbl; customers_tbl.name = "customers"; customers_tbl.headers = { "customer_id", "name", "country", "vip_level" }; customers_tbl.types = { data_table::ColumnType::String, data_table::ColumnType::String, data_table::ColumnType::String, data_table::ColumnType::String, }; customers_tbl.cells = g_jst.customers_ptrs.data(); customers_tbl.rows = 5; customers_tbl.cols = 4; customers_tbl.column_specs.resize(customers_tbl.cols); for (int i = 0; i < customers_tbl.cols; i++) customers_tbl.column_specs[i].id = customers_tbl.headers[i]; // --- Render ------------------------------------------------------------- ImGui::BeginChild("##joins_host", ImVec2(-1, -1)); g_jst.last_events.clear(); data_table::render("##joins_tbl", { orders_tbl, customers_tbl }, g_jst.dt, &g_jst.last_events, /*show_chrome=*/true); ImGui::EndChild(); qa::consume_events(g_jst.last_events); } } // namespace tables_qa::tabs