491161204e
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.1 KiB
4.1 KiB
id, title, status, priority, created, depends_on
| id | title | status | priority | created | depends_on | |||
|---|---|---|---|---|---|---|---|---|
| 0010 | Nodo tabla — contenedor cuadrado con filas que son nodos del grafo | pending | medium | 2026-04-30 |
|
Objetivo
Un tipo especial de nodo, Table, que se renderiza en el viewport como
un rectangulo (no circulo) y agrupa visualmente N entidades del grafo. Cada
fila de la tabla = un nodo real del grafo (con su type_ref, sus fields,
sus tags). Las filas se pueden extraer (salen al canvas como nodos
sueltos) y meter (un nodo suelto entra como fila).
Distinto del issue 0004 (vista tabla global por tipo): ese es una ventana
auxiliar que tabula entidades existentes; este es un nodo en el grafo
que existe en entities y posee filas via relaciones.
Modelo de datos
- El nodo tabla es una entidad normal con
type_ref = 'Table'y metadata:{ "row_type": "Person", // tipo esperado de las filas (puede ser vacio = mixto) "columns": ["name","age","email"], // subset de fields del row_type a mostrar como columnas "expanded": true // estado de UI persistido } - La pertenencia se modela con relaciones:
name = "CONTAINS_ROW",from_entity = <table_id>,to_entity = <row_entity_id>,order = N.
- Una fila puede pertenecer a varias tablas (varias relaciones
CONTAINS_ROWapuntando al mismo nodo). Confirmado en la conversacion. - Las columnas pueden ser fijas (
row_typedefinido → columnas = subset de losfieldsde ese tipo) o libres (definidas por el creador de la tabla encolumns).
Render en viewport
- Forma:
squareorounded_squarecon tamano dependiente del numero de filas (clamp a min/max). - Cuando esta colapsada: caja con titulo + contador (
Table · 23 filas). - Cuando esta expandida: caja crece y dibuja un grid interno (filas x columnas) con los valores principales. Las filas son arrastrables individualmente.
- Las relaciones
CONTAINS_ROWno se dibujan como aristas normales (serian ruido visual). En su lugar, una fila extraida muestra una arista fina punteada hacia su tabla de origen. - Aristas entrantes/salientes del nodo tabla se dibujan al borde del rectangulo, no al centro.
Operaciones
- Crear tabla: en context menu del viewport, "New table here". Pide
row_typeopcional. Crea entidadTabley la posiciona donde el click. - Anadir fila (tabla expandida o seleccionada): boton "+ row" que crea una entidad nueva con
type_ref = row_type(si esta definido) y la engancha viaCONTAINS_ROW. - Extraer fila: borra la relacion
CONTAINS_ROW. La fila queda como nodo libre, posicionada al lado de la tabla. - Extraer multiples: shift+click en filas dentro de la tabla expandida, "Extract selected".
- Meter fila: drag de un nodo sobre el rectangulo de una tabla. Confirm dialog si su
type_refno coincide conrow_typede la tabla. - Editar fila: doble-click en fila → abre Inspector con esa entidad seleccionada.
Cambios en codigo
entity_ops:bool table_create(db_path, name, row_type, columns_csv, char* out_id).bool table_add_row(db_path, table_id, char* out_row_id)(crea entidad + relacion CONTAINS_ROW).bool table_extract_row(db_path, table_id, row_id)(borra solo la relacion).bool table_attach_row(db_path, table_id, row_id, int order).bool table_list_rows(db_path, table_id, vector<string>* out_row_ids).
- Renderer del viewport (
graph_viewport.cppy/ograph_renderer): branch parais_table_node(detectado portype_ref == "Table") que dibuja rectangulo + grid expandido y devuelve hit-testing por filas individuales. graph_load_from_operations: filtrar las aristasCONTAINS_ROWpara que no entren en el layout fisico (no aplican fuerzas).
Definicion de hecho
- Crear tabla, anadir filas, extraer y meter filas funciona round-trip via SQLite.
- Tabla colapsada y expandida se renderizan correctamente en el viewport.
- Doble-click en fila enfoca el Inspector con esa entidad.
- Una fila puede pertenecer a varias tablas sin duplicarse.
- Borrar la tabla pregunta: "borrar tabla y todas sus filas" o "extraer filas y borrar solo la tabla".