FesaComponents
DataTable

Conceptos en 5 minutos

Qué es la librería, cómo fluye la data y por qué el estado vive en la URL.

@fesa/components/datatable es la tabla de datos compartida de los sistemas FESA. Esta guía te lleva de cero a un listado completo en producción. Si ya conoces la librería, salta a la referencia de API o a las recetas.

Antes de escribir código, entiende las cuatro piezas. Todo lo demás son detalles.

URL?page=2&sortBy=name&q=acmeview.tsx (servidor)parseTableSearchParamsprimera página por SSRSmartDataTablestore propio: página, orden,búsqueda, selección…pinta y pide páginasServer ActiongetXPageAction(params)permisos + Prisma skip/takela leeinitialData (sin doble fetch)fetchFn{ data, totalRows }la reescribe (replaceState)

1. La page action — el único acceso a datos

Una Server Action que recibe qué página quiere la tabla (índice, tamaño, orden, búsqueda y tus filtros) y devuelve esa página y el total. La librería jamás toca la base de datos: tú escribes esta función, con tus permisos y tu Prisma.

(params: DataTableFetchParams) => Promise<{ data: T[]; totalRows: number }>

2. La view — la primera página viaja en el HTML

Un Server Component lee la URL con parseTableSearchParams, llama la action una vez y pasa el resultado como initialData. Así la página llega pintada del servidor y la tabla no repite la consulta al montar. Recargar o compartir el link reproduce exactamente la misma vista.

3. El client — SmartDataTable hace el resto

Desde ahí, cada cambio de página, orden o búsqueda es solo una llamada a la action — no un re-render de la página completa. La tabla gestiona su propio estado en un store interno con protecciones anti-race (una respuesta lenta jamás pisa una nueva).

4. La URL — el estado vive ahí

La tabla escribe su estado en la URL con replaceState (sin disparar navegación). Convención única en todos los proyectos:

ParámetroSignificadoEjemplo
pagePágina (1-based; no se escribe si es la 1)?page=3
pageSizeFilas por página (si difiere del default)?pageSize=50
qBúsqueda global?q=acme
sortBy + sortDirOrden?sortBy=name&sortDir=desc
una clave por filtroFiltros del módulo?status=PAID&business=acme-sa

Por qué replaceState y no router.replace

La tabla ya pide sus datos por Server Action. Disparar una navegación RSC en cada tecleo volvería a traer la página entera del servidor. La URL se actualiza solo para que el estado sobreviva a una recarga y se pueda compartir.

Siguientes pasos

En esta pagina