Yayaw
Documentation
Vues

Vues

Douze façons d’afficher les mêmes enregistrements, quand utiliser chacune et quoi installer.

Une vue affiche les enregistrements d’une table d’une certaine façon. Onze vues sont des modes d’affichage d’une même table : elles partagent ses enregistrements, sa recherche, ses filtres, son tri, ses permissions et ses actions, sont enregistrées avec chaque vue enregistrée et dans l’URL, et l’on passe de l’une à l’autre sous Paramètres de la vue › Mode d’affichage. La douzième, le tableau de bord, est un composant distinct qui réunit sur une grille des vues enregistrées de plusieurs tables. React et Vue proposent les mêmes vues.

Listez les modes proposés par une table dans table.displayModes et choisissez le premier avec table.defaultDisplayMode. La plupart des vues sont incluses dans l’élément de registre de la table. Calendrier, Graphique, Carte et Tableau de bord sont des éléments optionnels : leurs bibliothèques restent hors de votre bundle tant que vous ne les installez pas, et les trois modes d’affichage optionnels ne sont proposés que si vous passez leur renderer dans displayModeRenderers.

Essayer toutes les vues

Cet aperçu propose tous les modes d’affichage d’une table sauf Gantt et Arborescence, qui demandent leurs propres données (un graphe de planification et une hiérarchie de dossiers). Ouvrez Paramètres de la vue, choisissez un Mode d’affichage, puis ouvrez ses réglages dans le même menu. Chaque mode garde ses propres réglages.

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.

Les douze vues

VueModeAffichePourFournie parGuide
TabletableLignes et colonnes, avec modification en ligne, regroupement et totauxComparer des valeurs, modifier plusieurs champs, sélectionner et exporterÉlément principalMise en page, Colonnes
ListelistUne ligne compacte par enregistrement : un titre et quelques propriétésParcourir beaucoup d’enregistrements sur tout écranÉlément principalListe
Tableau KanbankanbanDes cartes en colonnes, une colonne par option d’un champFaire avancer le travail d’étape en étapeÉlément principalKanban
GaleriegalleryDes cartes illustrées, avec une visionneuse de médiasParcourir produits, photos et fichiersÉlément principalGalerie
ChronologieganttDes barres sur une frise, avec hiérarchie et dépendancesPlanifier un travail daté et voir l’effet d’un changementÉlément principalGantt
CalendriercalendarMois, semaine ou liste des enregistrements datésPlacer événements et échéances, les déplacer d’un jour à l’autreOptionnel : yayaw-table-calendar, yayaw-table-vue-calendarCalendrier
GraphiquechartBarres, courbe, anneau ou nombre, regroupés par votre serveurMontrer les totaux et tendances des enregistrements de la vueOptionnel : yayaw-table-chart, yayaw-table-vue-chartVue graphique
FormulaireformUn formulaire qui crée un enregistrement par réponseRecueillir des demandes, y compris sur un lien publicÉlément principalVue formulaire
FilfeedDes publications avec auteur, date, texte et médiasSuivre actualités et annonces, les plus récentes d’abordÉlément principalVue fil
CartemapDes marqueurs issus d’une colonne de lieu, avec regroupements et fenêtresTrouver des enregistrements par lieu, chercher dans une zoneOptionnel : yayaw-table-map, yayaw-table-vue-mapVue carte
Tableau de bordYayawDashboardDes vues enregistrées de plusieurs tables, des nombres et des notes sur une grilleDonner une vue d’ensemble de plusieurs tables, avec des filtres communsOptionnel : yayaw-table-dashboard, yayaw-table-vue-dashboardTableau de bord
ArborescencefiletreeDes dossiers et fichiers reliés par une colonne parentParcourir et réorganiser une bibliothèque de fichiersÉlément principalVue arborescence

Chaque guide ci-dessus commence par un aperçu React et Vue de sa vue, avec le code qui l’exécute.

Choisir une vue

  • Lire et modifier des valeurs : Table, ou Liste sur petit écran et pour les enregistrements longs.

  • Un processus par étapes : Kanban. Avec des dates et des dépendances : Chronologie.

  • Des dates : Calendrier pour les événements et échéances, Chronologie pour les plans avec durées et dépendances.

  • Des images et des fichiers : Galerie pour les vignettes, Arborescence pour les dossiers.

  • Des chiffres : Graphique dans les vues d’une table, Tableau de bord pour combiner plusieurs tables.

  • Recueillir des données : Formulaire, qui peut aussi être partagé sur un lien public.

  • Des actualités : Fil, pour des enregistrements rédigés comme des publications.

  • Des lieux : Carte, à partir d’une colonne de lieu.

Une vue enregistrée conserve un mode d’affichage avec ses réglages : une même table peut ainsi garder côte à côte un calendrier « À rendre ce mois-ci », un graphique « Budget par catégorie » et un Kanban « Par statut ».

Données des exemples

Les aperçus de ces guides partagent un même jeu d’enregistrements : des projets d’ouverture de magasins avec une catégorie, un statut, un budget, des dates de début et de fin, un site, un responsable et une dernière actualité. Leurs enregistrements et colonnes et les dossiers et fichiers de l’aperçu Arborescence sont du TypeScript simple, commun à React et Vue. Les dates sont relatives à aujourd’hui : le calendrier et le fil montrent toujours des enregistrements actuels.

Chaque exemple de vue reprend cette configuration de table :

project-config.ts
import { defineTableConfig } from "@/components/ui/yayaw-table";
import { projectColumns, projectVisibleColumns } from "../shared/projects";

/** The Projects table every view example starts from. */
export const projectConfig = defineTableConfig({
  id: "projects",
  translations: { namespace: "projects", keys: { title: "Store openings" } },
  columns: {
    definitions: projectColumns,
    order: projectColumns.map((column) => column.id),
    visible: projectVisibleColumns,
    mandatory: ["name"],
    sort: [{ id: "start", desc: false }],
  },
  table: {
    allowCreate: true,
    allowEdit: true,
    allowDelete: false,
    allowDuplicate: false,
    allowBulkEdit: false,
    allowBulkDelete: false,
    enableRowSelection: false,
    enableViews: false,
    syncUrl: false,
    defaultPageSize: 10,
  },
});
project-config.ts
import { defineTableConfig } from "@/components/ui/yayaw-table-vue";
import { projectColumns, projectVisibleColumns } from "../shared/projects";

/** The Projects table every view example starts from. */
export const projectConfig = defineTableConfig({
  id: "projects",
  translations: { namespace: "projects", keys: { title: "Store openings" } },
  columns: {
    definitions: projectColumns,
    order: projectColumns.map((column) => column.id),
    visible: projectVisibleColumns,
    mandatory: ["name"],
    sort: [{ id: "start", desc: false }],
  },
  table: {
    allowCreate: true,
    allowEdit: true,
    allowDelete: false,
    allowDuplicate: false,
    allowBulkEdit: false,
    allowBulkDelete: false,
    enableRowSelection: false,
    enableViews: false,
    syncUrl: false,
    defaultPageSize: 10,
  },
});

Les aperçus gardent les enregistrements en mémoire : list pagine, recherche, filtre et trie, et applique les filtres d’un tableau de bord. Réinitialiser recharge l’aperçu et ses enregistrements. Remplacez cet hôte par vos propres actions serveur ; les vues qui ont besoin de tous les enregistrements, comme Calendrier, Carte, Graphique et Arborescence, acceptent aussi un scope que votre serveur peut appliquer (voir chaque guide).

memory-actions.ts
import type { TableActions } from "@/components/ui/yayaw-table/providers/table-provider";
import {
  matchesContractFilter,
  recordValue,
} from "@/components/ui/yayaw-table/utils/table-contracts";
import { listRecords } from "./list-records";

type MemoryRow = Record<string, unknown> & { id: string };

/**
 * An in-memory host for the view examples. Replace it with authenticated
 * server actions; views that need every row (calendar, map, chart, file tree)
 * filter the loaded rows themselves when `list` ignores their `scope`.
 */
export function createMemoryActions<T extends MemoryRow>(
  rows: T[],
  extra: Partial<TableActions> = {}
): TableActions {
  let created = 0;
  return {
    list: (params) => {
      // Dashboard filters arrive as `requiredFilters`, always joined with AND.
      const { requiredFilters } = recordValue(params);
      const required = Array.isArray(requiredFilters)
        ? requiredFilters.map(recordValue)
        : [];
      return listRecords(
        rows.filter((row) =>
          required.every((rule) =>
            matchesContractFilter(row[String(rule.columnId)], rule)
          )
        ),
        params
      );
    },
    create: (values) => {
      created += 1;
      const row = { ...values, id: `new-${created}` } as T;
      rows.push(row);
      return Promise.resolve({ success: true, data: structuredClone(row) });
    },
    update: (id, patch) => {
      const row = rows.find((item) => item.id === id);
      if (!row) {
        return Promise.resolve({ success: false, error: "Record not found." });
      }
      Object.assign(row, patch);
      return Promise.resolve({ success: true, data: structuredClone(row) });
    },
    delete: (id) => {
      const index = rows.findIndex((item) => item.id === id);
      if (index >= 0) {
        rows.splice(index, 1);
      }
      return Promise.resolve({ success: index >= 0 });
    },
    ...extra,
  };
}
memory-actions.ts
import {
  matchesContractFilter,
  recordValue,
} from "@/components/ui/yayaw-table-vue/table-contracts";
import type { TableActions } from "@/components/ui/yayaw-table-vue/types";
import { listRecords } from "./list-records";

type MemoryRow = Record<string, unknown> & { id: string };

/**
 * An in-memory host for the view examples. Replace it with authenticated
 * server actions; views that need every row (calendar, map, chart, file tree)
 * filter the loaded rows themselves when `list` ignores their `scope`.
 */
export function createMemoryActions<T extends MemoryRow>(
  rows: T[],
  extra: Partial<TableActions> = {}
): TableActions {
  let created = 0;
  return {
    list: (params) => {
      // Dashboard filters arrive as `requiredFilters`, always joined with AND.
      const { requiredFilters } = recordValue(params);
      const required = Array.isArray(requiredFilters)
        ? requiredFilters.map(recordValue)
        : [];
      return listRecords(
        rows.filter((row) =>
          required.every((rule) =>
            matchesContractFilter(row[String(rule.columnId)], rule)
          )
        ),
        params
      );
    },
    create: (values) => {
      created += 1;
      const row = { ...values, id: `new-${created}` } as T;
      rows.push(row);
      return Promise.resolve({ success: true, data: structuredClone(row) });
    },
    update: (id, patch) => {
      const row = rows.find((item) => item.id === id);
      if (!row) {
        return Promise.resolve({ success: false, error: "Record not found." });
      }
      Object.assign(row, patch);
      return Promise.resolve({ success: true, data: structuredClone(row) });
    },
    delete: (id) => {
      const index = rows.findIndex((item) => item.id === id);
      if (index >= 0) {
        rows.splice(index, 1);
      }
      return Promise.resolve({ success: index >= 0 });
    },
    ...extra,
  };
}

La table reçoit la configuration, les actions et les renderers optionnels :

projects-table.tsx
import { DataTable } from "@/components/ui/yayaw-table";
import { calendarRenderer } from "@/components/ui/yayaw-table-calendar/calendar-renderer";
import { chartRenderer } from "@/components/ui/yayaw-table-chart/chart-renderer";
import { mapRenderer } from "@/components/ui/yayaw-table-map/map-renderer";
import { createProjectRows, geocodeProjectPlaces } from "./projects";
import { createMemoryActions } from "./memory-actions";
import { exampleConfig } from "./all-views";

const actions = createMemoryActions(createProjectRows(), {
  geocode: geocodeProjectPlaces,
});

export function ProjectsTable() {
  return (
    <DataTable
      displayModeRenderers={{
        calendar: calendarRenderer,
        chart: chartRenderer,
        map: mapRenderer,
      }}
      getRowId={(row) => String(row.id)}
      getTableActions={() => actions}
      getTableConfig={() => exampleConfig}
      tableType="projects"
    />
  );
}
ProjectsTable.vue
<script setup lang="ts">
import { YayawDataTable } from "@/components/ui/yayaw-table-vue";
import { calendarRenderer } from "@/components/ui/yayaw-table-vue/calendar/calendar-renderer";
import { chartRenderer } from "@/components/ui/yayaw-table-vue/chart/chart-renderer";
import { mapRenderer } from "@/components/ui/yayaw-table-vue/map/map-renderer";
import { createProjectRows, geocodeProjectPlaces } from "./projects";
import { createMemoryActions } from "./memory-actions";
import { exampleConfig } from "./all-views";

const actions = createMemoryActions(createProjectRows(), {
  geocode: geocodeProjectPlaces,
});
const renderers = { calendar: calendarRenderer, chart: chartRenderer, map: mapRenderer };
</script>

<template>
  <YayawDataTable
    table-type="projects"
    :config="exampleConfig"
    :get-table-actions="() => actions"
    :get-row-id="(row) => String(row.id)"
    :display-mode-renderers="renderers"
  />
</template>

Comme toute table, l’édition React s’affiche dans votre QueryClientProvider et votre adaptateur nuqs, et l’édition Vue après VueQueryPlugin ; voir les démarrages rapides React et Vue.