feat(modules): add external module system with auto-discovery and public pages support
- add `src/core/modules/` with registry, discovery (server), and public index - add `src/core/public-pages/` with registry, server component, and public index - add `src/core/users/permissions-registry.js` for runtime permission registration - expose `./modules`, `./public-pages`, and `./public-pages/server` package exports - rename `registerFeatureRoutes` to `registerApiRoutes` with backward-compatible alias - extend `seedDefaultRolesAndPermissions` to include module-registered permissions - update `initializeZen` and shared init to wire module discovery and registration - add `docs/MODULES.md` documenting the `@zen/module-*` authoring contract - update `docs/DEV.md` with references to module system docs
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
|
||||
Ce répertoire fournit l'interface d'administration complète : layout, navigation, tableau de bord, gestion des utilisateurs et des rôles. Il expose un **registre runtime** pour permettre aux projets consommateurs d'ajouter des widgets, des entrées de navigation et des pages sans modifier le core.
|
||||
|
||||
> Le pattern `zen.extensions.js` documenté ici reste valide pour les extensions in-projet (extensions ad hoc spécifiques à une app). Pour distribuer une extension réutilisable comme un package npm, consulter [docs/MODULES.md](../../../docs/MODULES.md) — la même API d'enregistrement s'utilise mais le module est auto-découvert via les `dependencies` du projet consommateur.
|
||||
|
||||
---
|
||||
|
||||
## Structure
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Input, Textarea, Switch, Modal, ColorPicker } from '@zen/core/shared/components';
|
||||
import { useToast } from '@zen/core/toast';
|
||||
import { getPermissionGroups } from '@zen/core/users/constants';
|
||||
|
||||
const PERMISSION_GROUPS = getPermissionGroups();
|
||||
|
||||
const RoleEditModal = ({ roleId, isOpen, onClose, onSaved }) => {
|
||||
const toast = useToast();
|
||||
@@ -19,9 +16,12 @@ const RoleEditModal = ({ roleId, isOpen, onClose, onSaved }) => {
|
||||
const [description, setDescription] = useState('');
|
||||
const [color, setColor] = useState('#6b7280');
|
||||
const [selectedPerms, setSelectedPerms] = useState([]);
|
||||
// Catalogue dynamique des permissions (core + modules), récupéré via l'API.
|
||||
const [permissionGroups, setPermissionGroups] = useState({});
|
||||
|
||||
useEffect(() => {
|
||||
if (!isOpen) return;
|
||||
fetchPermissions();
|
||||
if (isNew) {
|
||||
setName('');
|
||||
setDescription('');
|
||||
@@ -33,6 +33,18 @@ const RoleEditModal = ({ roleId, isOpen, onClose, onSaved }) => {
|
||||
fetchRole();
|
||||
}, [isOpen, roleId]);
|
||||
|
||||
const fetchPermissions = async () => {
|
||||
try {
|
||||
const response = await fetch('/zen/api/permissions', { credentials: 'include' });
|
||||
if (!response.ok) return;
|
||||
const data = await response.json();
|
||||
setPermissionGroups(data.groups || {});
|
||||
} catch {
|
||||
// Si le catalogue n'est pas joignable, on laisse l'utilisateur sauvegarder
|
||||
// ses changements ; les permissions invalides sont filtrées côté serveur.
|
||||
}
|
||||
};
|
||||
|
||||
const fetchRole = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
@@ -146,7 +158,7 @@ const RoleEditModal = ({ roleId, isOpen, onClose, onSaved }) => {
|
||||
|
||||
<div className="flex flex-col gap-3">
|
||||
<p className="text-xs font-semibold uppercase tracking-wide text-neutral-500 dark:text-neutral-400">Permissions</p>
|
||||
{Object.entries(PERMISSION_GROUPS).map(([group, perms]) => (
|
||||
{Object.entries(permissionGroups).map(([group, perms]) => (
|
||||
<div key={group} className="rounded-xl border border-neutral-200 dark:border-neutral-700/60 overflow-hidden">
|
||||
<div className="px-4 py-2.5 bg-neutral-50 dark:bg-neutral-800/60 border-b border-neutral-200 dark:border-neutral-700/60">
|
||||
<p className="text-[11px] font-medium font-ibm-plex-mono text-neutral-500 dark:text-neutral-400 uppercase tracking-wide">
|
||||
|
||||
Reference in New Issue
Block a user