El dashboard es la página de inicio (/). Muestra los widgets que la persona tiene visibles, en el lugar que eligió. El front no calcula nada: las cifras, los porcentajes, qué es “vencido” y a qué filtro del listado lleva cada cifra llegan de la API (ver Módulo Dashboard).
Pantalla
| Vista | Forma |
|---|---|
| Portátil y monitor | Grilla de 12 columnas con el lugar y el tamaño que guardó la persona (x, y, w, h). Cada fila de la grilla mide $dashboard-row-height |
| Tablet | Dos columnas, en el orden de lectura de la persona (de arriba abajo y de izquierda a derecha). Los widgets anchos (8 columnas o más) ocupan la fila completa |
| Celular | Los indicadores de a dos por fila; el resto, a lo ancho |
- Encabezado: desde tablet, el título, “Actualizado hace…” y los botones van en una sola fila. “Resumen general” (quien ve todo) o “Mi resumen” (quien ve lo suyo), “Actualizado hace…” con la explicación en el ícono de información, y los botones “Personalizar” (portátil y monitor) y “Actualizar”.
- Cada cifra es un enlace al listado con el filtro que la explica: “Vencidos” abre el listado con
overdue=1, cada barra de estado abre ese estado, y así con todas. - Al volver a la pestaña, si los datos tienen más de un minuto, se actualizan solos.
- En vivo: cuando cambia un incidente, las cifras se refrescan solas, como máximo una vez cada 10 segundos y nunca en modo Personalizar (tiempo real).
- Estados: esqueleto mientras carga; error con “Reintentar” (del diseño o de las cifras); y un mensaje claro si la persona ocultó todos sus widgets.
Widgets
El diseño original está centrado en el riesgo (ADR-0081): pulso, mapa de riesgo, flujo de estados, balance del backlog, próximos a vencer y, según el permiso, asignados a mí y carga por agente. Los demás se agregan desde “Agregar widget”.
| Widget | Cómo se ve |
|---|---|
| Pulso de la operación | Una frase: “370 vencidos, el 59 % de los pendientes. Hoy se crearon 22 y se resolvieron 12: el backlog sube” (los vencidos llevan al listado). El anillo del cumplimiento del plazo (AppRing) y las cifras del total, los pendientes y la prioridad más alta. En portátil y monitor, todo en una fila; en tablet y celular, uno debajo del otro |
| Mapa de riesgo | Tabla de prioridad (de Crítica a Baja) por vencimiento (Vencido, Hoy, 7 días, Después). Cada celda es un enlace al listado filtrado; su color crece con la cantidad frente a la celda más cargada ($risk-levels, riskLevel), con texto negro o blanco según el contraste. Al final, separada por una línea, la columna “Total”: todos los de esa prioridad en cualquier estado |
| Flujo de estados | Las etapas en orden, unidas por flechas, cada una con su cantidad; aparte, “Salen sin resolverse: Cancelado”. En columna, y en fila cuando el propio widget mide 32rem o más ($flow-row-from, por ancho del widget y no de la pantalla) |
| Balance del backlog | Área con los pendientes de cada día (AppAreaChart), con el mismo periodo de la tendencia (7, 30 o 90 días), “Pendientes hoy” y cuánto subieron (rojo) o bajaron (verde) |
| Total, Pendientes, Vencidos, Sin asignar | Cifra grande. “Vencidos” va en rojo cuando es mayor que cero y dice qué parte de los pendientes son |
| Por estado | Barras horizontales con el color de cada estado |
| Por prioridad | Dona con el total en el centro y una leyenda con cantidad y porcentaje |
| Creados vs. resueltos | Columnas por día, con 7, 30 o 90 días (AppSegmented) y los totales en texto |
| Próximos a vencer, Asignados a mí | Lista corta: código, título, prioridad, “Vencido” si aplica y cuándo vence; al final, “Ver los N en el listado” |
| Carga por agente | Barras con los pendientes de cada persona y cuántos ya vencieron |
Los colores salen de los tonos de estados y prioridades (incidentTones.ts). Nada se comunica solo con color: cada valor también va en texto.
Personalizar
Se edita en portátil y monitor con el botón “Personalizar”. En tablet y celular no hay botón: un ícono de información junto al título explica que se personaliza desde un computador, y los widgets siguen el orden elegido allí.
- Barra fija arriba, con “Agregar widget”, “Restaurar original”, “Cancelar” y “Guardar” (activo solo si hay cambios).
- Cada widget muestra sus datos reales (sin enlaces activos), con un marco punteado, la agarradera y el menú ⋯ arriba a la derecha, y la manija para cambiar su ancho en la esquina inferior derecha. Mientras se cambia, aparece su medida en columnas.
- El alto lo pone el contenido: fuera de Personalizar, cada tarjeta mide lo que su gráfico o su lista, con abajo el mismo margen que arriba. Las tarjetas de una misma fila quedan parejas, al alto de la más alta, y la más baja reparte ese alto en vez de dejar un hueco: las barras y las listas separan sus filas, la tendencia estira sus columnas y, en portátil y monitor, la dona crece (hasta 15rem). En las listas, el botón “Ver los N en el listado” queda siempre al pie, a lo ancho y con una flecha. Por eso en Personalizar se cambian el lugar y el ancho, pero no el alto.
- Topes: la grilla no deja pasar del mínimo ni del máximo de cada widget, los mismos que valida el back.
- Sin huecos: después de cada cambio, los widgets suben hasta donde no choquen.
- Teclado: el menú ⋯ ofrece mover arriba, abajo, a la izquierda y a la derecha; más ancho y más angosto; y quitar. Las opciones que chocan con un tope aparecen desactivadas.
- Agregar widget lista los ocultos con su nombre y qué muestran. El elegido entra al final, con el tamaño que tenía, y un aviso dice dónde quedó.
- Restaurar original pide confirmación y se aplica de inmediato.
- Cambios sin guardar: “Cancelar” pide confirmación para descartarlos, y salir de la página también avisa (al cambiar de sección y al cerrar o recargar la pestaña).
- Ventana angosta: si se achica a tamaño de tablet en pleno modo edición, el borrador se conserva y aparece el aviso para agrandarla.
- Errores al guardar: cada rechazo del back tiene su mensaje (superposición, tamaño fuera de rango, widget no disponible), visible en la página.
Mientras se personaliza, las cifras siguen al borrador: un widget recién agregado pide sus datos sin esperar a guardar.
Capas
| Capa | Pieza | Qué hace |
|---|---|---|
| domain | dashboard.ts | Tipos del diseño y de los datos de cada widget; orden de lectura para celular y tablet |
| domain | layoutEditing.ts | Reglas puras para mover, estirar, quitar y agregar sin salirse de la grilla ni de los topes, con compactación vertical |
| infrastructure | dashboardApi.ts, mappers.ts | Llamadas a la API y traducción de snake_case al modelo |
| application | useDashboard | Diseño y cifras de los widgets visibles en una sola consulta, período de la tendencia y actualización al volver a la pestaña |
| application | useDashboardEditor | Borrador del modo Personalizar: si hay cambios, guardar, cancelar y restaurar el original |
| presentation | DashboardPage, DashboardGrid | Página y grilla en las cuatro vistas |
| domain | risk.ts | Rumbo del backlog, intensidad de cada celda del mapa de riesgo y nombres de sus columnas |
| presentation | widgets/WidgetCard, WidgetContent, PulseWidget, RiskMapWidget, StatusFlowWidget, BacklogWidget, KpiWidget, DigestWidget, TrendWidget | Marco de cada widget y su contenido |
| presentation | edit/EditToolbar, AddWidgetMenu, DashboardEditor, EditableWidget | Barra del modo Personalizar, menú de widgets ocultos, grilla editable (único uso de grid-layout-plus) y marco de cada widget en edición |
Para llevar al listado filtrado, el módulo usa incidentListLocation del módulo de incidentes, que traduce el filtro a la URL igual que el propio listado.
Dónde está en el código
frontend/src/modules/dashboard/- Enlace al listado:
incidentListLocation - Gráficos: Gráficos
- Personalizar:
useDashboardEditor,layoutEditing.tsypresentation/edit/ - Aviso de cambios sin guardar:
useLeaveGuard - Pruebas:
dashboard.spec.ts,risk.spec.ts,layoutEditing.spec.tsy E2E ene2e/dashboard.spec.ts - Decisiones: ADR-0029, ADR-0030, ADR-0047, ADR-0048 ADR-0050 y ADR-0081