- Added `useCompanyNavigationEntries` for defining navigation entries. - Created `CompanyContextBar` for displaying company information and navigation. - Developed `CompanyHeader` for showing company identity and status. - Introduced `CompanyNavigationSheet` for mobile navigation options. - Implemented `CompanySectionNavigation` for section-specific navigation. - Added `workspaceContentFocusTarget` to manage focus behavior. - Created `WorkspaceMobileNavigationProvider` for managing mobile navigation state. - Developed `WorkspaceMobileSheet` for consistent mobile sheet UI. - Added `WorkspaceSkipLink` for accessibility improvements. - Established `WorkspaceMobileNavigationContext` for navigation state management. - Created `WorkspaceNavigationContent` for displaying workspace navigation. - Implemented `WorkspaceSearchContent` and `WorkspaceSearch` for search functionality.
97 lines
11 KiB
Markdown
97 lines
11 KiB
Markdown
# V01.1 — Navegación móvil y franja contextual
|
||
|
||
Primera entrega de la [arquitectura responsive V01](propuesta-navegacion-responsive-v01.md), 21 de octubre de 2026. V01 sigue parcialmente pendiente: esta entrega solo modifica la composición por debajo de 768 px.
|
||
|
||
## Comportamiento implementado
|
||
|
||
- Cabecera móvil compacta: menú global, marca, búsqueda y cuenta. La búsqueda reutiliza estado, filtrado y destinos actuales, sin consultar activos/personas.
|
||
- Franja sticky con compañía, sección actual y botón Secciones; nombre completo accesible y tooltip para texto truncado. No hay 21 enlaces apilados antes del contenido.
|
||
- Sheet global con destinos, compañías y configuración; Sheet contextual con los 21 destinos, contadores, cambio de compañía y edición existentes. Una raíz modal y una presentación activa; el cambio contextual → global conserva modalidad sin apilar Sheet.
|
||
- Destinos con BrowserLink nativo, `aria-current` y estilos de Button; botones para acciones. Enter navega, Espacio conserva la interacción nativa de enlaces. Se verificaron Ctrl+clic y clic central abriendo otra pestaña, sin cerrar el menú original ni cambiar su URL.
|
||
- Escape/cierre devuelve foco al disparador; navegación ordinaria lo traslada al contenido. Cancelar edición de compañía desde el menú devuelve foco a Secciones. Base UI conserva el trap y el bloqueo de fondo; no se implementan manualmente.
|
||
- Enlace Saltar al contenido al inicio del teclado, con destino `main` real y separación del bloque sticky. Scroll vertical principal único; scroll propio en menús extensos y tabla horizontal cuando lo requiere.
|
||
- Cruzar a 768 px cierra el menú y devuelve foco visible; volver a móvil no reabre menús. Apertura efímera, sin nuevas preferencias.
|
||
|
||
Las barras de escritorio, el colapso manual 228/72, la secundaria de 240, los filtros, paginación, rutas y permisos permanecen con sus contratos anteriores. La edición usa la acción ya disponible en la ficha: no se inventa un permiso ni se amplía acceso. No cambian `inventory=1100`, `dashboard=1200` ni `useCompactDetail`; V01.2–V01.4 quedan pendientes.
|
||
|
||
## Componentes y decisiones
|
||
|
||
`CompaniesWorkspace` compone `WorkspaceMobileNavigationProvider`, salto al contenido, sidebar y cabecera sobre el scroll existente. `WorkspaceMobileSheet` encapsula popup, título, cierre traducido y foco; el consumidor aporta contenido. Los controles de modalidad pertenecen a Base UI.
|
||
|
||
`WorkspaceNavigationContent` comparte destinos globales entre escritorio y móvil. `useCompanyNavigationEntries` concentra los 21 destinos contextuales; `CompanySectionNavigation` comparte presentación y contadores. `CompanyContextBar` y `CompanyNavigationSheet` contienen las responsabilidades móviles; `CompanyHeader` conserva el encabezado desktop extraído del componente anterior.
|
||
|
||
`WorkspaceSearch` conserva una sola consulta local; `WorkspaceSearchContent` comparte input/resultados entre las presentaciones. No duplica consultas remotas ni crea otro motor. El catálogo semántico propio incorpora MenuIcon de Tabler. No se modifica vendor ni se añaden dependencias.
|
||
|
||
Los estilos nuevos se limitan al shell móvil, sticky y separación de foco. El breakpoint de 768 es el existente; no se introducen 920/1160/1660 ni observadores de capacidad. Los enlaces de navegación usan las variantes públicas de Button sin el comportamiento de teclado de un botón no nativo.
|
||
|
||
## Geometría medida
|
||
|
||
Mismo entorno sintético, cuatro pantallas y siete resoluciones antes/después: 28 geometrías por fase. Se esperó a carga, fuentes y transiciones. No son wireframes.
|
||
|
||
| Resolución | Activos: Y de main antes → después | Ancho main antes/después | Tabla útil antes/después |
|
||
| --- | --- | --- | --- |
|
||
| 320×640 | 1496,31 → 106 | 320 | 286 |
|
||
| 390×844 | 1429,66 → 106 | 390 | 356 |
|
||
| 768×1024 | 88 → 88 | 300 | 249 |
|
||
| 1024×768 | 88 → 88 | 556 | 505 |
|
||
| 1366×768 | 88 → 88 | 898 | 847 |
|
||
| 1440×900 | 88 → 88 | 972 | 921 |
|
||
| 1920×1080 | 88 → 88 | 1452 | 1401 |
|
||
|
||
A tamaño normal, cabecera/franja miden 57/49 px efectivos incluidos bordes. Ambos móviles cumplen `main.y <= 128` y muestran título sin scroll. No hay overflow horizontal del documento en la matriz; la tabla conserva su scroll propio. Dashboard/directorio comienzan tras la cabecera compacta, sin franja de compañía. La escasa capacidad de tablet a 768 continúa como deuda de V01.2, no se presenta como corregida.
|
||
|
||
## Validación ejecutada
|
||
|
||
Se preparó una única instancia desechable con `scripts/visual-audit.py`: no había archivo de sesión reutilizable. Login real de usuario ordinario, compañía y activo sintéticos, servicios/puertos propios. Las pruebas visuales bloquean escrituras HTTP; altas y ediciones se cancelan. No se accede a datos reales ni se retiran contenedores anteriores ajenos. Al terminar, el preparador retiró su entorno y eliminó la sesión privada; las evidencias permanecen sin credenciales.
|
||
|
||
Pruebas de componentes: nuevos casos es/en en `apps/web/src/app.test.tsx` y `companies-page.test.tsx`, con 21 href únicos, estado activo, nombres accesibles y menús cerrados sin compañía. Ambos casos pasan. No dependen de clases para simular interacciones; teclado/modalidad se comprueban en Chromium.
|
||
|
||
Se amplía `scripts/visual-audit-ui.test.py`, usando el mismo cliente MCP y preparador, sin otro framework. El directorio de salida es configurable y restringido a `.artifacts/playwright/`:
|
||
|
||
```bash
|
||
METIS_PLAYWRIGHT_STORAGE_STATE=.artifacts/playwright/authenticated-ID/session.json \
|
||
METIS_UI_AUDIT_DIRECTORY=.artifacts/playwright/v01-1/after \
|
||
python3 scripts/visual-audit-ui.test.py
|
||
```
|
||
|
||
Sustituir ID por la sesión activa, manteniendo el preparador abierto. La suite comprueba geometría, 21 destinos y último enlace por teclado, Tab/Shift+Tab/Espacio/Enter/Escape, retorno de foco, rutas y Atrás/Adelante, clics modificados, transferencia entre menús, búsqueda, sticky, resize, cuenta/idioma y edición cancelada. Incluye regresiones V02, V03, V06 y V09. Se espera al foco final de la primitiva tras atravesar sus guardas, no a una espera fija.
|
||
|
||
**Resultado final:** nueve pruebas MCP pasan en 288,506 s. Después se amplió el caso de teclado con un ciclo inverso de 26 pulsaciones Shift+Tab y se repitió ese caso completo: pasa en 25,263 s. En ambos sentidos se mantiene el foco en el Sheet y se alcanza el último destino. Logs: `technical/visual-ui.log` y `technical/visual-keyboard.log`.
|
||
|
||
Se simula un nombre largo mediante respuestas GET interceptadas, sin guardarlo. A 320 px conserva el presupuesto de 106 y no desborda. En 320×360 se alcanza el último enlace y el cierre permanece visible. La ampliación de fuente raíz al 200 % mantiene el ancho sin overflow y aumenta main.y a 210 px: excepción justificada al presupuesto nominal por ampliación de texto. Se conserva contenido y scroll; no se fuerza un alto fijo recortando textos.
|
||
|
||
El intento de zoom real con atajos de Chromium headless no cambió devicePixelRatio. No se declara comprobado zoom real 200/400 %: ampliar fuente y probar viewport de 320 son comprobaciones distintas. También quedan pendientes Cmd+clic en macOS, lector de pantalla, modo oscuro completo y combinaciones de muchos roles/compañías. El usuario ordinario no recibe enlace de administración de usuarios; el comportamiento administrativo conserva su condición existente.
|
||
|
||
## Comprobaciones técnicas
|
||
|
||
| Comprobación | Resultado |
|
||
| --- | --- |
|
||
| Typecheck dirigido compañías y web | Pasa |
|
||
| Biome de los archivos TS/TSX/JSON modificados | Pasa |
|
||
| Espaciado ESLint dirigido | Pasa tras corregir cuatro separaciones |
|
||
| Nuevos tests de componentes es/en | 2 pasan |
|
||
| `pnpm build` | Pasa; conserva aviso de chunk grande |
|
||
| `pnpm typecheck` | Falla en vendor `calendar.tsx:165`, contrato locale de react-day-picker; sin modificar vendor |
|
||
| `pnpm lint` | Falla con 15 errores en código ajeno de fotos/procesos/migraciones; además avisos de assets de skills |
|
||
| `pnpm check` | Falla global; archivos modificados comprobados separadamente |
|
||
| `pnpm test` con BD aislada | Falla en dos expectativas antiguas de `companies-page.test.tsx`: «Personas (1)» y texto antiguo sobre acceso de persona. No se corrigen fuera de alcance; la suite global no se declara aprobada |
|
||
|
||
La BD de tests se crea en otro contenedor y se elimina al terminar. Se conserva el log de Turbo para distinguir paquetes ejecutados/cacheados y no atribuir validación a suites que su fallo haya interrumpido. Los fallos citados estaban documentados antes de V01.1; se contrastan con los archivos implicados, no se supone que todo error nuevo sea previo.
|
||
|
||
La consola de la suite final no registra errores ni warnings. En la matriz previa apareció un 404 accesorio de favicon; no bloquea navegación.
|
||
|
||
Durante desarrollo se corrigieron una expansión indebida del separador móvil y expectativas/esperas de las propias pruebas. Los intentos parciales no sustituyen el resultado final. No se ignora un fallo de la aplicación para hacer pasar una prueba.
|
||
|
||
## Evidencias y documentación
|
||
|
||
Evidencias locales, excluidas de Git:
|
||
|
||
- [Baseline](../.artifacts/playwright/v01-1/before/measurements.json) y [matriz posterior](../.artifacts/playwright/v01-1/after-layout/measurements.json).
|
||
- [Últimos resultados por escenario](../.artifacts/playwright/v01-1/after/summary-latest.json), [historial de mediciones interactivas](../.artifacts/playwright/v01-1/after/measurements.json), [ciclo de teclado ampliado](../.artifacts/playwright/v01-1/keyboard/measurements.json), [consola](../.artifacts/playwright/v01-1/after/console.json) e [índice de capturas con dimensiones y SHA-256](../.artifacts/playwright/v01-1/evidence-index.json).
|
||
- [Activos 320 antes](../.artifacts/playwright/v01-1/before/assets-320.png), [después](../.artifacts/playwright/v01-1/after-layout/assets-320.png), [Sheet contextual](../.artifacts/playwright/v01-1/after/navigation-company-menu-390.png), [global](../.artifacts/playwright/v01-1/after/navigation-global-menu-390.png) y [búsqueda](../.artifacts/playwright/v01-1/after/navigation-search-320.png).
|
||
- Logs de comandos en `.artifacts/playwright/v01-1/technical/`. Las capturas se abrieron y examinaron; geometría, snapshot y comportamiento son pruebas distintas.
|
||
|
||
Para compartir evidencias, entregar solo `v01-1/`; no incluir `authenticated-*`, sesiones ni credenciales. Se actualizan DESIGN.md y componentes de interfaz para esta entrega, conservando los estados de los otros hallazgos.
|
||
|
||
Skills consultadas: `ux-navigation` dirige orientación y separación de ámbitos; `shadcn` aporta contratos Sheet/Base UI y primitivas existentes; `frontend-design` conserva identidad y jerarquía; composición y reglas React justifican modelos compartidos, estado efímero y suscripción responsive acotada. La CLI informativa shadcn falló por DNS; se consultaron sus [docs oficiales de Sheet](https://ui.shadcn.com/docs/components/base/sheet) y [Dialog de Base UI](https://base-ui.com/react/components/dialog), contrastadas con el código instalado. No se aplicaron auditores no instalados ni se instalaron herramientas.
|