Yayaw
Documentation
Recettes

Espace de consultation

Consulter, modifier, lire l’activité, annuler et enregistrer une vue.

Copiez le stockage et l’adaptateur communs, le catalogue produit et les fichiers de consultation et de vues ci-dessous. Cet exemple requiert le registre courant ou l’instantané v3.1.0, pas l’ancien v3.0.0.

record-config.ts

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

export const recordConfig = defineTableConfig({
  ...productConfig,
  table: {
    ...productConfig.table,
    allowEdit: true,
    enableViews: true,
    allowViewSave: true,
    rowClickMode: "default",
  },
  form: { editFormType: "products" },
});
record-config.ts
import { defineTableConfig } from "@/components/ui/yayaw-table-vue/config";
import { productConfig } from "./product-config";

export const recordConfig = defineTableConfig({
  ...productConfig,
  table: {
    ...productConfig.table,
    allowEdit: true,
    enableViews: true,
    allowViewSave: true,
    rowClickMode: "default",
  },
  form: { editFormType: "products" },
});

product-details.ts

product-details.ts
import type {
  DetailRevertHandler,
  RecordDetailsConfig,
} from "@/components/ui/yayaw-table/utils/record-details";
import { productStore } from "../shared/store";

export const productDetails: RecordDetailsConfig = {
  presentation: "drawer",
  title: (row) => String(row.name),
  updatedAt: (row) => String(row.updatedAt),
  sections: [
    {
      id: "product",
      title: "Product",
      fields: [
        { id: "name", label: "Name", type: "text" },
        {
          id: "price",
          label: "Price",
          type: "number",
          numberFormat: { style: "currency", currency: "EUR" },
        },
        { id: "stock", label: "Stock", type: "number" },
        { id: "status", label: "Status", type: "text" },
      ],
    },
  ],
  activity: (row) => productStore.activity(String(row.id)),
};
export const revertActivity: DetailRevertHandler = (row, entry) =>
  productStore.revert(String(row.id), entry.id);
product-details.ts
import type {
  DetailRevertHandler,
  RecordDetailsConfig,
} from "@/components/ui/yayaw-table-vue/record-details";
import { productStore } from "../shared/store";

export const productDetails: RecordDetailsConfig = {
  presentation: "drawer",
  title: (row) => String(row.name),
  updatedAt: (row) => String(row.updatedAt),
  sections: [
    {
      id: "product",
      title: "Product",
      fields: [
        { id: "name", label: "Name", type: "text" },
        {
          id: "price",
          label: "Price",
          type: "number",
          numberFormat: { style: "currency", currency: "EUR" },
        },
        { id: "stock", label: "Stock", type: "number" },
        { id: "status", label: "Status", type: "text" },
      ],
    },
  ],
  activity: (row) => productStore.activity(String(row.id)),
};
export const revertActivity: DetailRevertHandler = (row, entry) =>
  productStore.revert(String(row.id), entry.id);

view-actions.ts

view-actions.ts
import type {
  TableView,
  TableViewActions,
} from "@/components/ui/yayaw-table/types/view-types";

/** Demo persistence lasts for this module's lifetime. Scope server storage by user and organization. */
const views = new Map<string, TableView>();
const favorites = new Map<string, string | null>();
export const viewActions: TableViewActions = {
  list: ({ tableId }) =>
    Promise.resolve({
      data: [...views.values()].filter((view) => view.tableId === tableId),
    }),
  create: (input) => {
    const view = {
      ...input,
      id: crypto.randomUUID(),
      createdById: "demo-user",
    };
    views.set(view.id, structuredClone(view));
    return Promise.resolve({ success: true, data: view });
  },
  update: (id, input) => {
    const current = views.get(id);
    if (!current || (input.tableId && input.tableId !== current.tableId)) {
      return Promise.resolve({ success: false, error: "View not found." });
    }
    const view = { ...current, ...input };
    views.set(id, structuredClone(view));
    return Promise.resolve({ success: true, data: view });
  },
  delete: (id, { tableId }) => {
    if (views.get(id)?.tableId !== tableId) {
      return Promise.resolve({ success: false, error: "View not found." });
    }
    views.delete(id);
    if (favorites.get(tableId) === id) {
      favorites.delete(tableId);
    }
    return Promise.resolve({ success: true, data: { id } });
  },
  getFavorite: ({ tableId }) =>
    Promise.resolve({
      success: true,
      data: { viewId: favorites.get(tableId) ?? null },
    }),
  setFavorite: (viewId, { tableId }) => {
    if (viewId && views.get(viewId)?.tableId !== tableId) {
      return Promise.resolve({ success: false, error: "View not found." });
    }
    favorites.set(tableId, viewId);
    return Promise.resolve({ success: true, data: { viewId } });
  },
};
view-actions.ts
import type {
  TableView,
  TableViewActions,
} from "@/components/ui/yayaw-table-vue/types";

/** Demo persistence lasts for this module's lifetime. Scope server storage by user and organization. */
const views = new Map<string, TableView>();
const favorites = new Map<string, string | null>();
export const viewActions: TableViewActions = {
  list: ({ tableId }) =>
    Promise.resolve({
      data: [...views.values()].filter((view) => view.tableId === tableId),
    }),
  create: (input) => {
    const view = {
      ...input,
      id: crypto.randomUUID(),
      createdById: "demo-user",
    };
    views.set(view.id, structuredClone(view));
    return Promise.resolve({ success: true, data: view });
  },
  update: (id, input) => {
    const current = views.get(id);
    if (!current || (input.tableId && input.tableId !== current.tableId)) {
      return Promise.resolve({ success: false, error: "View not found." });
    }
    const view = { ...current, ...input };
    views.set(id, structuredClone(view));
    return Promise.resolve({ success: true, data: view });
  },
  delete: (id, { tableId }) => {
    if (views.get(id)?.tableId !== tableId) {
      return Promise.resolve({ success: false, error: "View not found." });
    }
    views.delete(id);
    if (favorites.get(tableId) === id) {
      favorites.delete(tableId);
    }
    return Promise.resolve({ success: true });
  },
  getFavorite: ({ tableId }) =>
    Promise.resolve({
      success: true,
      data: { viewId: favorites.get(tableId) ?? null },
    }),
  setFavorite: (viewId, { tableId }) => {
    if (viewId && views.get(viewId)?.tableId !== tableId) {
      return Promise.resolve({ success: false, error: "View not found." });
    }
    favorites.set(tableId, viewId);
    return Promise.resolve({ success: true, data: { viewId } });
  },
};

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. Ouvrez Oak desk et consultez ses champs typés.

  2. Passez le stock à 15 et enregistrez.

  3. Ouvrez Activity : le changement 12 → 15 apparaît.

  4. Annulez-le : le stock revient à 12 et un nouvel événement référence l’original.

  5. Vérifiez qu’une seconde annulation est indisponible.

  6. Modifiez les colonnes, enregistrez une vue, choisissez-la comme favori et remontez le tableau : elle est restaurée. Recharger le navigateur réinitialise ce stockage en mémoire.

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