Utiliser les Server Actions pour list, create, update, delete et opérations bulk
Server-side & Server Actions
La table est conçue pour fonctionner avec des données server-side : tri, filtrage et pagination sont envoyés à votre backend, et les opérations CRUD/bulk s'exécutent côté serveur. Dans Next.js, l'approche recommandée pour cela est d'utiliser les Server Actions.
Comment ça marche
- État dans l'URL – Tri, filtres, pagination et visibilité des colonnes sont stockés dans l'URL (via Nuqs). Le client lit cet état et appelle votre couche de données avec les mêmes paramètres.
- getTableActions(tableType) – Vous retournez un objet dont les méthodes sont vos Server Actions (ou n'importe quelles fonctions async qui appellent votre API).
- list(params) – Appelée avec
{ filters, advancedFilters, limit, page (1-based), orderBy, search }. Votre action s'exécute côté serveur et retourne{ data, meta: { pageCount, totalCount } }. - create, update, delete, duplicate, bulkDelete, bulkCopy, bulkUpdate – Même principe : la table appelle la fonction que vous fournissez ; vous l'implémentez en Server Action ou en appel API.
Donc la librairie ne récupère pas les données elle-même ; elle appelle ce que vous passez à getTableActions. Si ce sont des Server Actions, tout s'exécute côté serveur.
Exemple Next.js avec Server Actions
1. Module serveur (optionnel mais recommandé)
Conservez votre logique de données dans un module server-only (par ex. lib/products-server.ts) : list avec filtre/tri/pagination, create, update, delete, opérations bulk. Ce fichier doit être importé uniquement depuis des Server Actions ou d'autres modules serveur.
// app/example/lib/products-server.ts
import { products as initialProducts } from "../data";
const productsStore = [...initialProducts];
export async function listProducts(params: {
page?: number;
limit?: number;
filters?: Record<string, unknown>;
advancedFilters?: unknown[];
orderBy?: Record<string, "asc" | "desc">;
search?: string;
}) {
const { page = 1, limit = 10, filters = {}, orderBy = {}, search = "" } = params;
// Filter, sort, paginate productsStore...
return { data: pageData, meta: { pageCount, totalCount } };
}
export async function createProduct(data: Record<string, unknown>) {
// Insert into productsStore or DB
return { success: true, data: newProduct };
}
export async function updateProduct(id: string, data: Record<string, unknown>) {
// Update and return
return { success: true, data: updated };
}
export async function deleteProduct(id: string) {
return { success: true };
}
export async function bulkDeleteProducts(ids: string[]) { /* ... */ }
export async function bulkCopyProducts(ids: string[]) { /* ... */ }
export async function bulkUpdateProducts(ids: string[], updateData: unknown) { /* ... */ }2. Fichier Server Actions
Créez un fichier avec "use server" qui ré-expose ces fonctions (ou appelle votre API). Ce sont ces fonctions que vous passez à la table.
// app/example/actions/products.ts
"use server";
import {
listProducts as listProductsImpl,
createProduct as createProductImpl,
updateProduct as updateProductImpl,
deleteProduct as deleteProductImpl,
bulkDeleteProducts,
bulkCopyProducts,
bulkUpdateProducts,
} from "../lib/products-server";
export async function listProducts(params: Parameters<typeof listProductsImpl>[0]) {
return await listProductsImpl(params);
}
export async function createProduct(data: Record<string, unknown>) {
return await createProductImpl(data);
}
export async function updateProduct(id: string, data: Record<string, unknown>) {
return await updateProductImpl(id, data);
}
export async function deleteProduct(id: string) {
return await deleteProductImpl(id);
}
export async function bulkDelete(ids: string[]) {
return await bulkDeleteProducts(ids);
}
export async function bulkCopy(ids: string[]) {
return await bulkCopyProducts(ids);
}
export async function bulkUpdate(ids: string[], updateData: unknown) {
return await bulkUpdateProducts(ids, updateData);
}3. Connecter les actions à la table
Dans votre config de table, retournez ces Server Actions depuis getTableActions :
// app/example/setup/table-config.ts
import {
listProducts,
createProduct,
updateProduct,
deleteProduct,
bulkDelete,
bulkCopy,
bulkUpdate,
} from "../actions/products";
export const getTableActions = (tableType: string) => {
if (tableType === "products") {
return {
list: listProducts,
create: createProduct,
update: updateProduct,
delete: deleteProduct,
bulkDelete: bulkDelete,
bulkCopy: bulkCopy,
bulkUpdate: bulkUpdate,
};
}
};bulkDelete, bulkCopy, bulkUpdate sans : est aussi un raccourci JavaScript valide quand la variable et la clé ont le même nom.
Quand la table a besoin de données ou exécute une action, elle appellera ces fonctions. Dans Next.js, elles s'exécutent côté serveur ; les paramètres et valeurs de retour sont sérialisés automatiquement.
Structure des paramètres list
L'action list reçoit un objet unique avec :
| Key | Type | Description |
|---|---|---|
page | number | Index de page en base 1. |
limit | number | Taille de page. |
filters | Record<string, unknown> | Filtres colonnes (clé = id colonne, valeur = valeur du filtre). |
advancedFilters | array | Règles de filtre avancé (columnId, operator, values, type, isActive). |
orderBy | Record<string, "asc" | "desc"> | Tri par champ ; seule la première clé est utilisée pour le tri mono-colonne. |
search | string | Terme de recherche global. |
Retour attendu :
{ data: T[]; meta?: { pageCount?: number; totalCount?: number } }Mode server-side (par défaut)
YaYaw Table exécute toujours filtrage, pagination et tri en mode server-side. Aucune option manual* n'est requise dans la config table.
Votre action list doit gérer search, filters, advancedFilters, orderBy, page et limit.
Application d'exemple
La route /example tourne actuellement en mode local pour que les modifications restent interactives sans backend : elle utilise app/[locale]/example/lib/products-local-actions.ts avec stockage dans le localStorage du navigateur.
Les fichiers de référence Server Action sont toujours présents dans app/[locale]/example/actions/products.ts et app/[locale]/example/lib/products-server.ts. Connectez ces actions via getTableActions si vous voulez la même page en mode serveur complet.
Voir aussi :