Files
graph_explorer/issues/completed/0011-tablenode-expanded-promote.md
T

3.2 KiB

id, title, status, priority, created, completed, depends_on
id title status priority created completed depends_on
0011 Nodo tabla — UI expandida, promote/demote, ingesta CSV/Parquet completed high 2026-05-01 2026-05-01
0010

Objetivo

Fase 2 del nodo tabla. Sobre el cimiento DuckDB de 0010, anade UI completa: expandir nodo Table en el viewport para ver paginas de filas, promover una fila a entidad del grafo (nodo libre + arista punteada hacia su Table) y demover de vuelta. Ingesta de CSV / Parquet como punto de entrada para materializar tablas grandes.

UI expandida

  • Click sobre nodo Table -> selecciona; doble click -> toggle expanded en metadata.
  • Cuando expanded:
    • El cuadrado overlay crece para acomodar grid de cabecera + ~20 filas visibles. Mas filas exigen scroll dentro del overlay.
    • Cabecera con nombres de columns[]. Anchura proporcional al texto, max cap a un % del overlay.
    • Filas paginadas via ImGuiListClipper + tableview_page(offset,limit).
    • Indicador "promovida" (chip o color) en filas que ya estan en entities.
    • Doble-click en fila -> abre Inspector con esa entidad si esta promovida; si no, la promueve y abre Inspector.
  • Aristas entrantes/salientes del nodo Table se siguen dibujando al centro (mejora a "al borde" se aplaza).

Promote / demote

  • Context menu sobre fila visible (overlay expandido):
    • "Promote to graph node": crea entidad en operations.db con metadata de origen, posiciona el nodo al lado del Table y dibuja arista punteada hacia el Table (overlay).
    • "Demote": deletea la entidad. La fila sigue viva en DuckDB.
  • Una fila puede estar promovida una sola vez por (duckdb_path, table, row_id) — el helper de promocion debe checar y hacer no-op idempotente.

Ingesta

  • Boton/comando "Import dataset..." en menu o context menu del canvas.
  • Modal con:
    • Path al CSV / Parquet / JSON.
    • Nombre de la tabla DuckDB destino.
    • row_type (combo con los entity types del proyecto + "(none)").
    • Boton "Import" -> ejecuta:
      CREATE TABLE <name> AS SELECT * FROM read_csv_auto('<path>');
      
      sobre tables/<slug>.duckdb (crea el .duckdb si no existe).
    • Tras import, crea automaticamente un nodo Table en el viewport apuntando a la nueva tabla.

Cambios en codigo

  • tableview.{h,cpp}:
    • tableview_promote_row(ops_db, duckdb_path, duck_table, row_id, row_type, out_entity_id).
    • tableview_demote_row(ops_db, entity_id).
    • tableview_ingest_file(duckdb_path, file_path, dest_table, *file_kind).
  • views.cpp:
    • Render expandida via overlay. Hit-testing por fila (rect intersection).
    • Modal "Import dataset...".
  • main.cpp:
    • Wire context menu items. Recargar grafo tras promote/demote/ingest.

Definicion de hecho

  • Toggle expanded persiste en entities.metadata (JSON write).
  • Tabla con 1M filas se navega con scroll fluido (paginacion 200 filas).
  • Promote: la entidad creada aparece como nodo libre adyacente al Table, unida por arista punteada (visual solamente — no es relacion en BD).
  • Demote: el nodo desaparece, la fila sigue contandose en tableview_count.
  • Ingesta de CSV de 100k filas tarda < 5 s y deja la tabla lista para mostrar.
  • Doble-click en fila no promovida la promueve y enfoca Inspector.