DataTable
Tabla con paginación, orden, búsqueda y filtros en servidor.
La tabla pide cada página a una Server Action tuya y guarda su estado en la URL (page, pageSize, q, sortBy, sortDir y una clave por filtro).
"use server";
import type { DataTableFetchParams, DataTableFetchResult } from "@fesa/components/datatable";
export async function getInvoicesPageAction(
params: DataTableFetchParams
): Promise<DataTableFetchResult<InvoiceRow>> {
const sort = params.sorting[0];
const [rows, total] = await Promise.all([
db.invoice.findMany({
orderBy: sort ? { [sort.id]: sort.desc ? "desc" : "asc" } : undefined,
skip: params.pageIndex * params.pageSize,
take: params.pageSize,
}),
db.invoice.count(),
]);
return { data: rows, totalRows: total };
}import { parseTableSearchParams, type PageSearchParams } from "@fesa/components/datatable/server";
export async function InvoicesView({ searchParams }: { searchParams?: PageSearchParams }) {
const tableParams = parseTableSearchParams((await searchParams) ?? {}, { defaultPageSize: 20 });
const first = await getInvoicesPageAction(tableParams);
return <InvoicesClient initialData={first.data} initialTotalRows={first.totalRows} />;
}"use client";
import { SmartDataTable, useSmartTable } from "@fesa/components/datatable";
export function InvoicesClient({ initialData, initialTotalRows }: Props) {
const table = useSmartTable<InvoiceRow>({
fetchPage: (params) => getInvoicesPageAction(params),
defaultPageSize: 20,
});
return (
<SmartDataTable
{...table.smartProps}
initialData={initialData}
initialTotalRows={initialTotalRows}
columns={columns}
/>
);
}