fix(ui): reemplaza panel-debajo-del-listado por DetailPopup de tamaño fijo

El detalle de un item de listado (actividad, departamento, usuario, proyecto nuevo,
catalogo) ya no se apila debajo ni al costado del listado: ahora abre en un popup que
cubre la ventana, deja el listado inactivo detras, nunca se cierra con clic afuera (solo
con el boton Cerrar o una accion explicita del formulario) y mantiene un alto FIJO por
instancia para que cambiar de pestaña interna (Info/Subtareas/Dependencias/Comentarios/
Documentos) no reajuste su tamaño.

De paso corrige un bug real de stacking: ContentDialog no usaba portal a document.body,
así que un dialogo de confirmacion abierto desde dentro de un DetailPopup quedaba oculto
detras de este. Ahora ambos son portales con una jerarquia de z-index explicita
(Flyout 100 < DetailPopup 200 < ContentDialog 250 < Toast 300).

En el detalle de actividad, Subtareas y Dependencias pasan de estar apiladas dentro de la
pestaña Info a ser cada una su propia pestaña.

Regla documentada en project-md-templates/UI-UX-WINDOWS.md (componente DetailPopup) para
que aplique a futuros proyectos de escritorio Windows del grupo.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Milton Gonzalez
2026-09-03 11:21:07 -05:00
parent 1d22adc42e
commit 1e6e7fecdd
10 changed files with 224 additions and 142 deletions
+49 -10
View File
@@ -118,10 +118,41 @@ openDialog({
**selección múltiple** (checkbox), fila con **hover** y **estado seleccionado** (`accent/.14`), y
**clic derecho** que abre el menú contextual de esa fila (ver §6). Alternativa por fila sin mouse
derecho: botón `⋯` que abre el mismo menú.
- **Master-Detail (Split View)** — patrón **nativo de Windows** (Correo, Configuración, Explorador):
lista angosta a la izquierda + panel de detalle a la derecha que se actualiza **en el sitio** al
seleccionar un ítem, sin modal. Preferir sobre "detalle en modal" cuando la pantalla es
principalmente de exploración/lectura de una lista larga.
- **DetailPopup** — patrón **por defecto** para ver/crear/editar el detalle de un ítem de un listado
de gestión (proyectos, actividades, usuarios, catálogos, etc.). Overlay que cubre la ventana y deja
**inactivo el listado detrás** (dim + sin interacción) mientras se usa el popup — a diferencia de un
panel lateral o de un panel apilado debajo del listado, el detalle NUNCA reduce ni empuja el
listado, y siempre aparece completo y en el mismo lugar sin importar el largo de la lista ni la
fila elegida. Reglas duras:
- **Nunca se cierra con clic afuera** (a diferencia de `Flyout`) — solo con el botón "Cerrar" de su
cabecera o una acción explícita del formulario (`Guardar`/`Cancelar`).
- **Alto FIJO por instancia**, no se ajusta al contenido: si el popup tiene pestañas o secciones
internas (p. ej. Info/Comentarios/Documentos), cambiar entre ellas **nunca** cambia el tamaño del
popup — solo el contenido interno hace scroll. El ancho/alto se elige según cuánto contenido
espera esa pantalla (un formulario simple de 2 campos no necesita el mismo alto que un detalle
con subtareas y dependencias), pero una vez abierto queda fijo.
- Header propio: título a la izquierda, botón "Cerrar" (ícono `X`) a la derecha.
- Contrato (React; adaptar al framework del proyecto):
`<DetailPopup open title onClose width height>{contenido}</DetailPopup>` — portal a
`document.body` (igual que `Flyout`/`ContentDialog`), **nunca** anidado dentro del árbol de la
página, para no quedar atrapado en el stacking context de un ancestro y terminar tapado por otro
overlay (bug real: sin portal, un `ContentDialog` abierto DESDE un `DetailPopup` quedaba oculto
detrás de este). Jerarquía de `z-index` entre overlays: `Flyout` (100) < `DetailPopup` (200) <
`ContentDialog` (250) < `Toast` (300) — así una confirmación abierta desde dentro de un
`DetailPopup` siempre queda por encima.
- Secciones internas relacionadas con el ítem (ej. una actividad con Info + Subtareas +
Dependencias + Comentarios + Documentos) van cada una en **su propia pestaña** dentro del popup,
nunca todas apiladas dentro de la pestaña "Info" — mismo criterio que pestañas reales a nivel de
pantalla completa (ver identidad web `UI-UX-LINKEDCORP.md`), aplicado ahora dentro del popup.
- **Master-Detail (Split View)** — patrón **nativo de Windows** (Correo, Explorador): lista angosta a
la izquierda + panel de detalle a la derecha que se actualiza **en el sitio** al seleccionar un
ítem, sin modal. Uso **restringido**: solo para pantallas cuya función principal es explorar/leer
una lista larga como actividad central de esa vista (no para listados de gestión con acciones
crear/editar — ahí va `DetailPopup`). Evitar cualquier variante que ubique el detalle "a un costado"
o "debajo" de un listado de gestión (panel lateral fijo, panel acoplado al borde, panel apilado
bajo la tabla): en la práctica el detalle se siente secundario y el listado pierde protagonismo o
queda "lejos" del detalle cuando la lista crece. Ante la duda entre Master-Detail y `DetailPopup`
para un listado de gestión, usar `DetailPopup`.
- **Menú contextual (clic derecho)** — el patrón de interacción **más característico de Windows**:
ítems con ícono + label + acelerador de teclado a la derecha (`Ctrl+E`, `Del`…), separadores,
submenú con flecha `▸` que se expande al pasar el mouse, ítem destructivo en `danger`. Debe estar
@@ -226,11 +257,14 @@ Alt+Tab); si es una decisión puntual ligada al contexto actual, es un `ContentD
1. **CommandBar** (`Nuevo`, `Actualizar`, acciones contextuales + overflow `···`).
2. **Elegir el patrón de datos** según el caso:
- **Listado + `DetailPopup`** (default para listados de gestión: proyectos, actividades, usuarios,
catálogos…): al hacer clic en una fila u optar "Nuevo", se abre un `DetailPopup` (overlay de
tamaño fijo, listado inactivo detrás, nunca se cierra con clic afuera) con el detalle/formulario
y sus acciones (`Guardar`, `Editar`, `Eliminar`). El listado se ve completo e intacto en cuanto
se cierra el popup.
- **Listado + Master-Detail**: lista con selección simple a la izquierda/arriba, detalle **en el
sitio** a la derecha/abajo. Preferido cuando el usuario navega/lee mucho (correo, catálogos).
- **Listado + ContentDialog de detalle**: al hacer clic en una fila se abre un `ContentDialog`
(o una ventana secundaria si el contenido es largo) con el detalle y acciones (`Editar`,
`Eliminar`). Preferido cuando el detalle es ocasional y la lista debe verse completa mientras se usa.
sitio** a la derecha/abajo, sin modal. Reservado para pantallas cuya función principal es
explorar/leer una lista larga (correo) — no para listados de gestión con crear/editar.
3. **Selección múltiple + acciones por lote**: casillas en la columna izquierda de la tabla; la barra
de estado muestra "`N` de `M` seleccionados"; las acciones de lote aparecen en la `CommandBar`
solo cuando hay selección.
@@ -261,11 +295,16 @@ Alt+Tab); si es una decisión puntual ligada al contexto actual, es un `ContentD
con el resto de Windows.
- ✅ Radios de esquina consistentes: `4px` controles, `8px` superficies elevadas y la ventana misma.
- ✅ Un solo set de íconos en toda la app (Lucide o Segoe Fluent Icons), heredando color del contexto.
- ✅ Master-Detail para listas de exploración; `ContentDialog`/ventana secundaria para detalle ocasional.
- ✅ `DetailPopup` (tamaño fijo, nunca se cierra con clic afuera) para ver/crear/editar el detalle de
un ítem de un listado de gestión; Master-Detail solo para pantallas de exploración/lectura pura.
- ✅ Foco visible solo con teclado (`:focus-visible`); hover visible siempre (mouse-first).
- ❌ `MessageBox`/`alert`/`confirm` del sistema. ❌ combos/selects/calendarios nativos sin estilar.
❌ mezclar sets de íconos. ❌ apilar listado + formulario + detalle en una sola pantalla sin
separación clara. ❌ usar `Toast` para pedir una decisión al usuario.
separación clara. ❌ usar `Toast` para pedir una decisión al usuario. ❌ panel de detalle lateral o
debajo del listado en pantallas de gestión (usar `DetailPopup`). ❌ que un `DetailPopup` cambie de
tamaño al moverse entre sus pestañas/secciones internas. ❌ montar `ContentDialog`/`DetailPopup` sin
portal a `document.body` (queda atrapado en el stacking context de un ancestro y puede terminar
tapado por otro overlay).
> Para que una app "se sienta Windows moderna": misma barra de título, mismo panel de navegación,
> mismos cuatro mecanismos de aviso (`ContentDialog`/`InfoBar`/`Toast`/`Flyout`) bien diferenciados,