20d8bbf360
0010 cambia de modelo SQLite CONTAINS_ROW a tier DuckDB: operations.db sigue con grafo + filas promovidas, tablas grandes viven en projects/<proj>/apps/graph_explorer/tables/<slug>.duckdb. 0011 separa la fase 2 (UI expandida + promote/demote + ingesta CSV).
3.2 KiB
3.2 KiB
id, title, status, priority, created, depends_on
| id | title | status | priority | created | depends_on | |
|---|---|---|---|---|---|---|
| 0011 | Nodo tabla — UI expandida, promote/demote, ingesta CSV/Parquet | pending | high | 2026-05-01 |
|
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
expandeden 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.dbcon 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.
- "Promote to graph node": crea entidad en
- 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:
sobre
CREATE TABLE <name> AS SELECT * FROM read_csv_auto('<path>');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.