- sbo-field: fila etiqueta + control, con obligatorio (*), flecha dorada,
etiqueta enlazable y mensaje de error.
- sbo-text-field, sbo-textarea-field, sbo-number-field, sbo-date-field,
sbo-select-field y sbo-lookup-field, con enlace bidireccional por señales
([(value)]) y entradas comunes (label, required, readonly, disabled, error).
- sbo-number-field: formateado fuera de foco (1,234.50), acepta 12,5 y
1,234.50 al escribir, redondea a los decimales indicados y conserva el
valor si el texto no es un número (parseDecimal).
- sbo-select-field devuelve el valor con su tipo original (número o texto).
- sbo-lookup-field: botón "…" y F4 abren sbo-value-help (VhLookup); elegir
rellena el campo, emite la fila y devuelve el foco; escribir el código a
mano sigue siendo válido.
- Estilos globales de formulario (forms.css) tomados del mockup, con
ancho de etiqueta configurable (--label-w).
- Verificado en Chrome contra SAP real, en claro y oscuro: cliente elegido
de la lista rellena código, nombre y RUC; edición de números; selects.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- sbo-value-help: búsqueda por columna con contains(), columnas declarativas
(texto, número, importe, fecha, format a medida), paginación del servidor
con total, baseFilter/orderby, Esc/Enter, errores con reintento.
- Selección única (un clic confirma) o múltiple (casillas, seleccionar
página, Confirmar (n)). Mejoras sobre el sistema anterior: lo marcado se
conserva entre páginas, el filtro base va entre paréntesis (un "or" ya no
rompe la precedencia) y las comillas del texto buscado se escapan.
- Cambiar la columna elegida no consulta hasta pulsar Buscar.
- Peticiones con httpResource: las obsoletas se cancelan solas.
- Helpers reutilizables: core/sl/odata (escape, contains, combinar filtros)
y core/format (importes y fechas sin desfase de zona horaria).
- Verificado en Chrome contra SAP real (253 clientes, 1209 artículos):
búsqueda por Nombre, paginación, selección múltiple entre páginas y
tema oscuro.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- Login contra POST /api/auth/login; SessionStore en localStorage con el
timeout deslizante que informa el servidor (sessionTimeoutMinutes).
- Interceptor: Bearer en /api, renueva actividad y, ante 401, cierra la
sesión y vuelve al login recordando la ruta (solo rutas internas).
- Guards: sesión, invitado y permiso por pantalla (data.path). Corrige que
inject() no puede usarse tras un await en permissionGuard.
- Layout con barra superior (empresa, usuario, tema, salir) y menú lateral
filtrado por GET /api/user/menu; plegable y con botón en pantallas angostas.
- Menú único en libs/sap-types (MENU, filterMenu); el backend verifica por
test que las rutas de permiso de sus recursos existan en él.
- Una ruta por pantalla del menú; las no construidas muestran "no disponible".
- Verificado en Chrome headless contra el backend y SAP reales: redirección
sin sesión, menú de 20 pantallas, navegación, plegado, tema oscuro y
persistencia, vista móvil, salir, token inválido y credenciales malas.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- apps/web: Angular 22 standalone, zoneless, OnPush, vitest; proxy /api
hacia el backend; presupuesto de bundle (aviso 260 kB, error 400 kB).
- libs/sap-types: tipos de auth/permisos/Service Layer y el evaluador de
patrones de menú, compartidos por api y web (se compila en postinstall).
El backend deja de tener su propia copia del evaluador.
- Temas por variables CSS: claro por defecto con la paleta del mockup de
Oferta de ventas, oscuro incluido; ThemeService + selector, con el tema
guardado aplicado antes del primer pintado. Agregar un tema = 1 css +
1 import + 1 entrada.
- Criterios de interfaz ligera en CLAUDE.md y README.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>