Pages admin et widgets React

Sur cette page

Les plugins natifs peuvent étendre le panneau d’administration avec des pages React personnalisées, des widgets de tableau de bord, des widgets de champ et des colonnes de liste de contenu — les plugins sandboxés décrivent leur UI comme Block Kit à la place, car charger du JavaScript de plugin dans l’admin casserait l’isolation du sandbox.

Si votre plugin n’a besoin que d’un formulaire de paramètres, le formulaire auto-généré admin.settingsSchema (voir Votre premier plugin natif) couvre la plupart des cas sans écrire de React. Utilisez des composants personnalisés quand vous avez besoin d’une UI plus riche que ce que settingsSchema fournit.

Point d’entrée admin

Les plugins avec UI admin exportent des objets pages et widgets depuis un point d’entrée admin :

import { SEOSettingsPage } from "./components/SEOSettingsPage";
import { SEODashboardWidget } from "./components/SEODashboardWidget";

export const widgets = { "seo-overview": SEODashboardWidget };
export const pages = { "/settings": SEOSettingsPage };
{
	"exports": {
		".": "./dist/index.js",
		"./admin": "./dist/admin.js"
	}
}
definePlugin({
	id: "seo",
	version: "1.0.0",
	admin: {
		entry: "@my-org/plugin-seo/admin",
		pages: [{ path: "/settings", label: "SEO Settings", icon: "settings" }],
		widgets: [{ id: "seo-overview", title: "SEO Overview", size: "half" }],
	},
});

Pages admin

Les pages admin sont des composants React montés sous /_emdash/admin/plugins/<plugin-id>/<chemin>.

Déclarez les labels en anglais. L’admin les passe par son instance partagée Lingui avant le rendu de la barre latérale et de la palette de commandes, offrant une navigation localisée gratuite aux plugins qui chargent leur propre catalogue de messages.

Composant de page

import { useState, useEffect } from "react";
import { usePluginAPI } from "@emdash-cms/admin";

export function SettingsPage() {
	const api = usePluginAPI();
	const [settings, setSettings] = useState<Record<string, unknown>>({});
	const [saving, setSaving] = useState(false);

	useEffect(() => { api.get("settings").then(setSettings); }, []);

	const handleSave = async () => {
		setSaving(true);
		await api.post("settings/save", settings);
		setSaving(false);
	};

	return (
		<div>
			<h1>Paramètres du plugin</h1>
			<label>
				Titre du site
				<input type="text" value={(settings.siteTitle as string) || ""} onChange={(e) => setSettings({ ...settings, siteTitle: e.target.value })} />
			</label>
			<button onClick={handleSave} disabled={saving}>{saving ? "Enregistrement..." : "Enregistrer"}</button>
		</div>
	);
}

Hook API du plugin

import { usePluginAPI } from "@emdash-cms/admin";
function MyComponent() {
	const api = usePluginAPI();
	const data = await api.get("status");
	await api.post("settings/save", { enabled: true });
}

Widgets de tableau de bord

TailleDescription
fullLargeur complète
halfDemi-largeur
thirdUn tiers de largeur

Panneaux de l’éditeur de contenu

import type { ContentEditorPanelContext } from "@emdash-cms/admin";

function ContentInsights({ entry, locale }: ContentEditorPanelContext) {
	return <p>Analyse pour {entry.slug} en {locale ?? "le locale par défaut"}</p>;
}

export const contentEditorPanels = [
	{ id: "content-insights", title: "Aperçus du contenu", component: ContentInsights, collections: ["posts", "pages"], minRole: 40, order: 10 },
];

Colonnes de liste de contenu

Les plugins React de confiance peuvent ajouter des colonnes en lecture seule aux listes de collections de contenu actives.

UI de paramètres auto-générée

admin: {
	settingsSchema: {
		apiKey: { type: "secret", label: "API Key" },
		enabled: { type: "boolean", label: "Enabled", default: true },
	},
},

Configuration de build

tsdown

export default {
	entry: { index: "src/index.ts", admin: "src/admin.tsx" },
	format: "esm", dts: true,
	external: ["react", "react-dom", "emdash", "@emdash-cms/admin"],
};

tsup

export default {
	entry: ["src/index.ts", "src/admin.tsx"],
	format: "esm", dts: true,
	external: ["react", "react-dom", "emdash", "@emdash-cms/admin"],
};

Activer/désactiver un plugin

Quand un plugin est désactivé : les liens de la barre latérale sont masqués, les widgets ne sont pas rendus, les colonnes de liste de contenu ne sont pas rendues, les pages admin retournent 404, les hooks backend continuent de s’exécuter.

const enabled = await ctx.kv.get<boolean>("_emdash:enabled");