Yayaw
Documentation
Recettes

Administration groupée

Conserver la sélection entre pages et soumettre les champs choisis.

Ce que vous allez construire

Combinez sélection sur plusieurs pages, modifications groupées validées, permissions par ligne et action Archiver fournie par l’application.

Partez de l’installation React ou Vue. Assemblez les fichiers complets ci-dessous et les modules partagés. Le stockage mémoire se réinitialise au rechargement ; une API doit conserver les mêmes contrats.

Fichiers nécessaires : shared/products.ts, shared/store.ts, shared/admin-mutations.ts, product-config.ts, list-records.ts, view-actions.ts, editable-actions.ts, admin-actions.ts, product-form.ts, get-form-config.ts, admin-config.ts, recipe-admin.

Copiez le stockage et l’adaptateur communs et le catalogue de formulaire produit. La recette affiche volontairement deux lignes par page pour rendre la sélection entre pages visible.

admin-config.ts

admin-config.ts
import { defineTableConfig } from "@/components/ui/yayaw-table/config/helpers";
import { productConfig } from "./product-config";

export const adminConfig = defineTableConfig({
  ...productConfig,
  table: {
    ...productConfig.table,
    layoutPreset: "admin",
    defaultPageSize: 2,
    pageSizeOptions: [2, 10, 20],
    enableRowSelection: true,
    enableMultiRowSelection: true,
    preserveSelectionOnQuery: true,
    allowEdit: true,
    allowBulkEdit: true,
    canEditRow: (row) => row.status !== "archived",
    canSelectRow: (row) => row.status !== "archived",
    bulkExport: true,
  },
  form: { editFormType: "products" },
});
admin-config.ts
import { defineTableConfig } from "@/components/ui/yayaw-table-vue/config";
import { productConfig } from "./product-config";

export const adminConfig = defineTableConfig({
  ...productConfig,
  table: {
    ...productConfig.table,
    layoutPreset: "admin",
    defaultPageSize: 2,
    pageSizeOptions: [2, 10, 20],
    enableRowSelection: true,
    enableMultiRowSelection: true,
    preserveSelectionOnQuery: true,
    allowEdit: true,
    allowBulkEdit: true,
    canEditRow: (row) => row.status !== "archived",
    canSelectRow: (row) => row.status !== "archived",
    bulkExport: true,
  },
  form: { editFormType: "products" },
});

Composant d’entrée

Agrandir ↗

Données de démonstration. Les modifications restent dans cet aperçu.

Agrandir ↗

Données de démonstration. Les modifications restent dans cet aperçu.

Vérifier le résultat

  1. Sélectionnez une fiche sur la première page.

  2. Allez à la deuxième page et sélectionnez-en une autre : deux identifiants sont sélectionnés.

  3. Ouvrez l’édition groupée et choisissez uniquement Status.

  4. Choisissez Archived et validez : les deux fiches changent ; stock et prix restent intacts.

  5. Appelez bulkUpdate avec un identifiant absent : failedIds le signale, les succès restent enregistrés.

  6. Vérifiez que Name est exclu grâce à bulkEdit: false.

Utilisez le playground existant pour explorer les contrôles de la bibliothèque.

Vérifier la politique des lignes dans les mutations

La même règle est vérifiée au moment de l’écriture. Cette démonstration ne remplace pas l’authentification : ajoutez les vérifications de l’utilisateur et de l’organisation sur votre serveur. Les cibles inconnues ou archivées sont signalées dans failedIds ; l’éditeur intégré ne renvoie pas les écritures déjà réussies.

admin-mutations.ts
import { type createProductStore, productStore } from "./store";

/** Demo record policy. A real server must also authenticate and scope every request. */
export function createAdminMutations(
  store: ReturnType<typeof createProductStore>
) {
  const update = (id: string, patch: Record<string, unknown>) => {
    if (store.rows.find((row) => row.id === id)?.status === "archived") {
      return { success: false, error: "Archived products are read-only." };
    }
    return store.update(id, patch);
  };
  const bulkUpdate = (ids: string[], patch: Record<string, unknown>) => {
    const failedIds: string[] = [];
    for (const id of new Set(ids)) {
      if (!update(id, patch).success) {
        failedIds.push(id);
      }
    }
    return {
      success: failedIds.length === 0,
      failedIds,
      ...(failedIds.length
        ? {
            error:
              "Some products cannot be edited. Retry the remaining records.",
          }
        : {}),
    };
  };
  return { update, bulkUpdate };
}

export const adminMutations = createAdminMutations(productStore);
admin-actions.ts
import type { TableActions } from "@/components/ui/yayaw-table/providers/table-provider";
import { adminMutations } from "../shared/admin-mutations";
import { editableActions } from "./editable-actions";

const adminActions: TableActions = {
  ...editableActions,
  update: (id, patch) => Promise.resolve(adminMutations.update(id, patch)),
  bulkUpdate: (ids, patch) =>
    Promise.resolve(adminMutations.bulkUpdate(ids, patch)),
};
export const getAdminActions = (tableType: string) =>
  tableType === "products" ? adminActions : undefined;
admin-actions.ts
import type { TableActions } from "@/components/ui/yayaw-table-vue/types";
import { adminMutations } from "../shared/admin-mutations";
import { editableActions } from "./editable-actions";

const adminActions: TableActions = {
  ...editableActions,
  update: (id, patch) => Promise.resolve(adminMutations.update(id, patch)),
  bulkUpdate: (ids, patch) =>
    Promise.resolve(adminMutations.bulkUpdate(ids, patch)),
};
export const getAdminActions = (tableType: string) =>
  tableType === "products" ? adminActions : undefined;

Vérifier le résultat pas à pas

ActionRésultat attendu
Sélectionnez deux produits et ouvrez Modifier.La liste de propriétés est vide et Appliquer est désactivé.
Ajoutez Stock, saisissez 24, puis appliquez.Seul Stock change sur ces deux cibles ; noms, prix et troisième produit restent inchangés.
Ajoutez puis retirez Prix avant d’appliquer une autre propriété.Prix est absent de la modification envoyée.
Sélectionnez un produit, choisissez Archiver et confirmez.Son statut devient Archived ; la ligne ne peut plus être sélectionnée ni modifiée.
Exportez les lignes sélectionnées avant de les archiver.Le CSV contient les lignes sélectionnées, pas seulement la page courante.

Sur mobile, utilisez les Réglages de la vue pour la présentation, le menu Données pour l’export, et le bouton de recherche de la barre d’outils. Réinitialiser une vue n’annule pas les écritures. Testez aussi le clavier.