feat(0036c): doble click en Group abre NodeGroups; cleanup Table panel

Cambia el dispatch del doble click sobre nodos del viewport: si el tipo
es Group o Table, ahora abre/enfoca la NodeGroups window correspondiente
via views_node_groups_open(...). El branch de Group ya no carga el
panel Table generico con un filtro group_id (logica heredada de 0035d
que provocaba el bug de "tabla vacia").

Limpieza correlativa en views_table:
  - Eliminado el breadcrumb "Group: <name> (N)" + boton Clear filter.
  - Eliminado el filtro r.group_id != table_filter_group_id en
    build_visible y la restriccion de types_present.
  - Eliminado el reset on-close de los campos de filtro.

Eliminados los campos AppState::table_filter_group_id y
table_filter_group_name (audit: git grep table_filter_group_id devuelve
vacio fuera de issues/).

Render de NodeGroups ahora consume focus_request: llama
SetNextWindowFocus() antes de Begin y SetWindowFocus() dentro, asi la
window queda al frente tanto al crearse como al re-enfocarse.

El right-click "Open NodeGroups" del context menu sigue intacto
(want_toggle_nodegroups + node_groups_set_expanded). El doble click es
flujo paralelo nuevo.

Refs: issues/0036c-double-click-group-opens-nodegroups.md
This commit is contained in:
2026-05-04 00:56:44 +02:00
parent 7277f63985
commit 8f91b4ed23
3 changed files with 27 additions and 62 deletions
+14 -14
View File
@@ -1941,32 +1941,32 @@ static void render() {
}
// Note editor — abrir / guardar.
// Excepcion (issue 0035d): si el nodo es un Group, en lugar de abrir
// Note se abre el panel Table con filtro por group_id.
// Excepcion (issue 0036c): si el nodo es un Group o un Table, abrir/enfocar
// la NodeGroups window correspondiente en lugar del panel Note.
if (g_app.want_open_note && g_app.open_note_target >= 0
&& g_app.open_note_target < g_graph.node_count) {
int n = g_app.open_note_target;
const char* sql_id = ge::entity_index_lookup(g_idx, g_graph.nodes[n].user_data);
// Detectar si el nodo es de tipo Group.
// Detectar si el nodo es de tipo Group o Table.
bool is_group = false;
bool is_table = false;
uint16_t tid = g_graph.nodes[n].type_id;
const char* type_name = (tid < (uint16_t)g_graph.type_count
&& g_graph.types[tid].name)
? g_graph.types[tid].name : "";
if (type_name && std::strcmp(type_name, "Group") == 0) is_group = true;
else if (type_name && std::strcmp(type_name, "Table") == 0) is_table = true;
if (is_group && sql_id) {
// Drill-in: abrir Table panel filtrado por group_id = sql_id.
g_app.table_filter_group_id = sql_id;
const char* lbl = graph::graph_label(&g_graph, g_graph.nodes[n].label_idx);
g_app.table_filter_group_name = lbl ? lbl : sql_id;
// Reset filtros que pueden ocultar las filas del grupo.
g_app.table_search_buf[0] = 0;
g_app.table_col_filters.clear();
g_app.table_show_all = true;
g_app.panel_table = true;
ImGui::SetWindowFocus("Table");
if ((is_group || is_table) && sql_id) {
// Drill-in: abre/enfoca la NodeGroups window. views_node_groups_open
// crea la entry si no existe, marca focus_request=true en cualquier
// caso (el render lo consume con SetWindowFocus).
ge::NodeGroupsKind kind = is_group
? ge::NodeGroupsKind::Group
: ge::NodeGroupsKind::Table;
ge::views_node_groups_open(g_app, sql_id, kind,
g_input_path.c_str());
} else if (sql_id) {
std::string md;
ge::entity_get_notes(g_app.input_db_path.c_str(), sql_id, &md);