Aller au contenu

Collections racines dynamiques

Construisons un exemple plus complexe où la navigation principale est chargée dynamiquement depuis la base de données. Nous utiliserons la collection units comme celle qui génère le reste de la navigation.

Pour cet exemple, nous aurons Units et Lessons comme types de contenu principaux — imaginez que nous modélisons la structure d’un cours.

Dans la collection units, nous créerons un document pour chaque unité :

dynamic_navigation_collection

Et chacun de ces documents générera un nouvel élément de navigation. Dans ce cas, nous aurons 3 éléments de navigation, un pour chaque unité :

dynamic_navigation_home

Définissons la collection units comme la collection principale :

import { buildCollection } from "@firecms/core";
export type Unit = {
name: string;
description: string;
}
export const unitsCollection = buildCollection<Unit>({
name: "Units",
singularName: "Unit",
group: "Main",
id: "units",
path: "units",
customId: true,
icon: "LocalLibrary",
callbacks: {
onSaveSuccess: ({ context }) => {
context.navigation.refreshNavigation();
},
onDelete: ({ context }) => {
context.navigation.refreshNavigation();
}
},
properties: {
name: {
name: "Name",
validation: { required: true },
dataType: "string"
},
description: {
name: "Description",
validation: { required: true },
dataType: "string",
multiline: true
}
}
});

En général dans FireCMS, vous passez une liste statique de collections au composant CMS principal, mais dans ce cas, nous devons construire les collections dynamiquement en fonction des données dans la base de données.

FireCMS vous permet de passer une fonction qui retourne une liste de collections à la prop collections du composant FireCMSApp.

import { buildCollection, EntityCollectionsBuilder } from "@firecms/core";
import { Unit, unitsCollection } from "./unit_collection";
const collectionBuilder: EntityCollectionsBuilder = async ({
dataSource,
user
}) => {
const units = await dataSource.fetchCollection<Unit>({
path: "units",
});
const lessonCollections = units.map(unit => buildCollection<Unit>({
name: unit.values.name,
id: `units/${unit.id}/lessons`,
path: `units/${unit.id}/lessons`,
description: unit.values.description,
group: "Units",
properties: {
name: {
name: "Name",
dataType: "string"
},
description: {
name: "Description",
dataType: "string"
}
}
}));
return [
unitsCollection,
...lessonCollections
]
};

Ce code récupère les données générées dans la collection units et crée une nouvelle collection pour chacun des documents.

En assemblant tout, nous obtenons une application simple qui nous permet de créer de nouvelles unités et leçons et naviguer entre elles :

import { buildCollection } from "@firecms/core";
import { FireCMSAppConfig } from "@firecms/cloud";
type Unit = {
name: string;
description: string;
}
const unitsCollection = buildCollection<Unit>({
name: "Units",
singularName: "Unit",
group: "Main",
id: "units",
path: "units",
customId: true,
icon: "LocalLibrary",
callbacks: {
onSaveSuccess: ({ context }) => {
context.navigation.refreshNavigation();
},
onDelete: ({ context }) => {
context.navigation.refreshNavigation();
}
},
properties: {
name: {
name: "Name",
validation: { required: true },
dataType: "string"
},
description: {
name: "Description",
validation: { required: true },
dataType: "string",
multiline: true
}
}
});
const appConfig: FireCMSAppConfig = {
version: "1",
collections: async ({ dataSource }) => {
const units = await dataSource.fetchCollection<Unit>({
path: "units",
});
const lessonCollections = units.map(unit => buildCollection({
name: unit.values.name,
id: `units/${unit.id}/lessons`,
path: `units/${unit.id}/lessons`,
description: unit.values.description,
group: "Units",
properties: {
name: {
name: "Name",
dataType: "string"
}
}
}));
return [
unitsCollection,
...lessonCollections
]
}
}
export default appConfig;