FactuGES_ERP/docs/suppliers/frontend-suppliers-ui-ux-design.md
David a13ababdf6 refactor: replace RdxEditorLayout with RdxPageContent across multiple components
- Updated ScopedListProformasPageView, ProformaUpdateEditorForm, ProformaUpdatePage, RecurringProformaCreatePage, and others to use RdxPageContent instead of RdxEditorLayout.
- Removed RdxPageStack and replaced it with RdxPageContent for consistent layout management.
- Deleted RdxEditorLayout component and its associated tests.
- Introduced RdxPageContent component to handle main content and optional aside layout.
- Adjusted tests to reflect changes in component structure and layout.
2026-09-14 11:00:56 +02:00

7.7 KiB

Frontend de suppliers: diseño e implementación UI/UX

1. Objetivo

El frontend de suppliers debe ofrecer listado, detalle, creación y edición con el mismo lenguaje visual y los mismos patrones de navegación que customers, respetando el contrato funcional más pequeño de Supplier.

Este documento es la fuente normativa para la implementación. La paridad buscada es de arquitectura y experiencia, no de campos ni capacidades de negocio.

2. Estado actual

Antes de esta implementación, Supplier solo disponía de entidades frontend, adapters, APIs y hooks de TanStack Query. La sidebar enlazaba a /suppliers, pero no existían manifest, rutas, páginas, formularios ni traducciones del módulo.

El API client tenía una incompatibilidad activa: la actualización delegaba en IDataSource.updateOne(), que usa PUT, aunque Supplier solo expone PATCH.

3. Customer como referencia

Se adoptan de Customer:

  • manifest y rutas lazy por módulo;
  • páginas de listado con RdxPageContainer, RdxPageHeader, búsqueda con debounce y DataTable;
  • editores fullscreen con RdxEditorPageLayout, header persistente, protección de cambios sin guardar y secciones Rdx;
  • PageErrorState, skeletons, alertas y toasts del sistema;
  • React Hook Form con validación Zod;
  • queries y mutations encapsuladas en hooks y adapters de transporte.

No se copia la fiscalidad, la eliminación, el panel lateral ni las acciones exclusivas de Customer.

4. Diferencias funcionales Customer/Supplier

Área Customer Supplier
Lifecycle Puede tener capacidades propias Status solo informativo
Eliminación Existe contrato Customer No existe DELETE Supplier
Fiscalidad Incluye configuración fiscal Fuera de alcance
Pagos Puede incluir términos y métodos Fuera de alcance
Dirección Contrato agrupado en áreas modernas DTO Supplier plano
Actualización Contrato propio PATCH parcial, sin null para borrar

5. Arquitectura frontend Supplier

Page
 -> controller hook
 -> query/mutation hook
 -> API function
 -> DTO adapter
 -> frontend entity

Los DTO snake_case quedan limitados a common, API y adapters. Páginas, formularios y entidades usan camelCase.

6. Rutas

Ruta Pantalla Layout
/suppliers Listado app-sidebar
/suppliers/create Creación app-fullscreen
/suppliers/:id Detalle app-fullscreen
/suppliers/:id/edit Edición app-fullscreen

Se adopta edit, que es la convención vigente de Customer. No se crean rutas DELETE, activate o deactivate.

7. Listado

El listado usa header, descripción, acción principal, SimpleSearchInput, tabla server-side y paginación. Las columnas son:

  • identidad: nombre, nombre comercial, TIN y tipo empresa/persona;
  • referencia;
  • contacto principal;
  • status no interactivo;
  • acciones Ver y Editar.

Solo name, reference y email_primary ofrecen sorting, porque pertenecen a la whitelist real. La búsqueda usa el query param q, debounce de 300 ms y reinicia la página.

8. Detail

El detalle presenta un header con nombre, contexto secundario y badge de status. Se agrupa en Identificación, Contacto, Dirección y Preferencias. Los valores ausentes muestran - para mantener una cuadrícula estable. Las únicas acciones son Volver y Editar.

9. Create

Create reutiliza el editor común Supplier y genera el UUID en el cliente. El payload conserva el DTO plano del backend y omite campos opcionales vacíos. Tras éxito actualiza caché, muestra feedback y navega al detalle.

10. Update

Update carga el detalle, adapta la entidad al formulario y construye el PATCH desde dirtyFields. Solo se envían campos modificados con valor utilizable. Un campo vacío se omite porque el contrato vigente no admite null => borrar; la UI no inventa esa semántica.

La petición se realiza explícitamente con método PATCH, nunca con IDataSource.updateOne().

11. Formularios y validación

Un único SupplierFormSchema en camelCase valida create y update. Se reutilizan schemas semánticos de Core para TIN, país, código postal, idioma, moneda, teléfono y web. Las secciones son Identificación, Dirección, Contacto y Preferencias.

isCompany es boolean y usa el selector visual empresa/persona. status no forma parte del formulario.

12. API / React Query

Las keys separan listado y detalle. Create establece el detalle e invalida listados. Update establece el detalle, parchea filas presentes e invalida listados. El cambio de empresa reutiliza el reset global de queries y el interceptor común que añade X-Company-Id.

13. Estados loading/error/empty

  • List usa SkeletonDataTable en carga inicial.
  • Detail y Update usan skeleton de editor.
  • Errores bloqueantes usan PageErrorState con reintento y regreso.
  • Errores de mutación usan ErrorAlert y toast.
  • La tabla conserva el empty state común; una búsqueda sin resultados mantiene visible el buscador.

14. Responsive

Header y acciones apilan en móvil. Formularios pasan de dos columnas a una. Las tarjetas de detalle usan una columna en móvil y dos en escritorio. La tabla conserva scroll horizontal y paginación del componente compartido.

15. Accesibilidad

Todos los inputs tienen labels asociados mediante los componentes Rdx. Los botones incluyen nombre accesible, los iconos decorativos usan aria-hidden, las filas de acciones son navegables y los errores se asocian mediante React Hook Form. El foco se mueve al primer campo inválido.

16. i18n

Todos los textos visibles pertenecen al namespace Suppliers. Se mantienen recursos completos en es y en; no se insertan textos de interfaz específicos en componentes.

17. Componentes reutilizados

  • RdxPageContainer, RdxPageContent, RdxPageHeader, RdxPageActions;
  • RdxEditorPageLayout, RdxPanel, RdxFormGrid;
  • DataTable, SkeletonDataTable, DataTableColumnHeader, RdxRowActions;
  • TextField, SelectField, PageFormHeader, FormActionsBar;
  • SimpleSearchInput, PageErrorState, ErrorAlert;
  • UnsavedChangesProvider y useReturnToNavigation.

18. Componentes Supplier específicos

  • SuppliersGrid y sus columnas, porque expresan identidad y acciones Supplier;
  • SupplierStatusBadge, limitado al status del dominio;
  • SupplierEditorForm y sus secciones, porque el DTO plano y la ausencia de fiscalidad son específicos;
  • páginas y controllers de List, Detail, Create y Update.

No se extraen componentes desde Customer: la similitud visual no justifica acoplar ambos dominios.

19. Decisiones descartadas

Quedan expresamente fuera:

  • DELETE;
  • activate/deactivate y cualquier lifecycle HTTP;
  • paymentTermId;
  • paymentMethodId;
  • fiscalidad y defaults fiscales;
  • integración con supplier-invoices;
  • edición de status;
  • refactor del DTO plano de dirección;
  • semántica null => borrar no soportada.

20. Plan de implementación

  1. Corregir API PATCH, keys, adapters y estrategia de caché.
  2. Registrar manifest y rutas Supplier.
  3. Implementar listado y navegación.
  4. Implementar detalle.
  5. Implementar formulario compartido y Create.
  6. Implementar Update con dirtyFields.
  7. Añadir recursos es y en.
  8. Revisar responsive y accesibilidad.
  9. Añadir tests de mappers, PATCH parcial y rutas.
  10. Ejecutar tests, typecheck, lint, build dirigido y checklist manual.

Checklist manual

  • Abrir listado, buscar por nombre, TIN y referencia.
  • Ordenar nombre, referencia y email.
  • Abrir detalle y navegar a editar.
  • Guardar un único campo y confirmar que el PATCH es parcial.
  • Guardar isCompany = false.
  • Crear Supplier y validar errores de formulario/API.
  • Confirmar actualización de detail y list.
  • Cambiar de empresa y comprobar aislamiento.
  • Revisar listado, detalle y formularios en desktop, tablet y móvil.