feat(nakui-ui): confirmación de delete vía banner modal antes de borrar

El click en `✕` ya no borra inmediatamente: marca el record como
pendiente y abre un banner amber al tope con [Cancelar] / [Confirmar].
Sólo [Confirmar] llama `commit_delete` (la lógica del store/log no
cambia).

Cambios:
- Nuevo `MetaUi.pending_delete: Option<(String, Uuid)>`.
- Click en ✕ → set pending_delete + clear toast.
- Banner renderea como sibling del row sidebar+main en `flex_col`
  raíz; None cuando no hay pending. Texto: "¿Borrar {Entity} {id}?".
- [Cancelar] → toast informativo, sin tocar el store.
- [Confirmar] → limpia pending primero (evita banner colgado en
  caso de error) y llama `commit_delete`.
- `select_view` también limpia pending (record podría no ser visible
  en la nueva view).

22 tests verdes — la lógica del store/log no cambió, sólo el state
machine de UI. La compilación garantiza el wireup de las closures.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sergio
2026-05-09 21:20:16 +00:00
parent 46185951d0
commit fdb9bbe058
2 changed files with 156 additions and 13 deletions
+42
View File
@@ -6,6 +6,48 @@ ratio/diff ver `git show <sha>`.
## 2026-05-09
### feat(nakui-ui): confirmación de delete vía banner modal antes de borrar
Cierra el primer pending del último round: borrar un record pedía un
solo click en `✕` y se ejecutaba inmediatamente (irreversible —
queda en el log como `Morphism { name: "ui.delete_record" }`). Ahora
hay un paso intermedio: el click marca el record como pendiente y el
banner amber al tope de la ventana ofrece [Cancelar] o [Confirmar].
Cambios:
- **Nuevo state `MetaUi.pending_delete: Option<(String, Uuid)>`**.
Set en el click del `✕`; limpiado por:
- [Cancelar] → toast "delete cancelado (Entity)".
- [Confirmar] → llama `commit_delete` (igual que antes) y emite
el toast usual.
- Navegación a otra view (`select_view`) — el record marcado
podría no estar visible en la nueva pantalla.
- **Click handler de `✕` ya no llama `commit_delete`**: sólo setea
`pending_delete` y limpia toast. La acción destructiva ahora vive
exclusivamente en el botón [Confirmar] del banner.
- **Nuevo método `render_confirm_delete_banner`**: devuelve
`Option<Div>` (None si no hay pending). Banner amber con el texto
`¿Borrar {Entity} {short_uuid}?` + dos botones. Renderea como
sibling del row sidebar+main en `flex_col` raíz — no es overlay
flotante (GPUI no expone z-index trivialmente), pero la posición
fija al tope + color amber lo hacen imposible de ignorar.
- **Limpieza pre-commit**: `pending_delete = None` se ejecuta antes
de `commit_delete`, así un fallo del commit no deja el banner
colgado además del toast de error.
22 tests verdes — la lógica del store/log no cambió, sólo el state
machine de UI. La confirmación es puramente UX/state, no testable
sin GPUI cx, pero la compilación garantiza wireup correcto de las
closures.
Pendientes restantes:
- **Snapshot/compaction** del log para repos grandes (replay full
cada startup escala mal).
- **Edit delta-only** — sólo campos modificados, no todos.
- **EntityRef validation post-submit** — validar UUID parseable
al submit en lugar de al execute del morphism.
- **Atajo de teclado Esc para Cancelar** — requiere event
dispatcher de GPUI, fuera de scope inmediato.
### feat(nakui-ui): validación estricta de params del morphism vía FieldKind del FieldSpec
Cierra el último trade-off documentado: `infer_param_value` adivinaba
el tipo de cada param por la shape del string (i64 → f64 → bool →