feat(admin): add permission-based filtering to admin navigation

- add optional `permission` field to nav items in registry
- filter nav items by user permissions in `buildNavigationSections`
- auto-hide sections when all their items are filtered out
- fetch user permissions in `AdminLayout.server.js` and pass to navigation builder
- update docs and README to document `permission` param and new signature
This commit is contained in:
2026-04-25 09:27:07 -04:00
parent cb8266d9a9
commit 97f8baf502
5 changed files with 26 additions and 13 deletions
+8 -5
View File
@@ -102,12 +102,13 @@ if (!admin) return null;
---
### `buildNavigationSections(pathname)`
### `buildNavigationSections(pathname, userPermissions?)`
Construit les sections de navigation pour la sidebar à partir du registre. Marque l'entrée active selon `pathname`.
Construit les sections de navigation pour la sidebar à partir du registre. Marque l'entrée active selon `pathname`. Les items dont le champ `permission` n'est pas présent dans `userPermissions` sont automatiquement exclus ; si tous les items d'une section sont exclus, la section disparaît également.
```js
const sections = buildNavigationSections('/admin/users');
const permissions = await getUserPermissions(session.user.id);
const sections = buildNavigationSections('/admin/users', permissions);
// [{ id, title, icon, items: [{ name, href, icon, current }] }]
```
@@ -183,6 +184,7 @@ registerNavItem({
href: '/admin/orders',
sectionId: 'commerce',
order: 10,
permission: 'orders.view', // optionnel — masqué si l'utilisateur n'a pas cette permission
});
```
@@ -195,7 +197,7 @@ registerNavItem({
| `icon` | `string` | Nom d'icône Hugeicons |
| `order` | `number` | Ordre d'affichage (défaut : `0`) |
**`registerNavItem({ id, label, icon, href, sectionId?, order?, position? })`**
**`registerNavItem({ id, label, icon, href, sectionId?, order?, position?, permission? })`**
| Paramètre | Type | Description |
|-----------|------|-------------|
@@ -206,6 +208,7 @@ registerNavItem({
| `sectionId` | `string` | Section parente (défaut : `'main'`) |
| `order` | `number` | Ordre d'affichage (défaut : `0`) |
| `position` | `string` | `'bottom'` pour épingler en bas de la sidebar |
| `permission` | `string` | Clé de permission requise pour voir cette entrée (ex. `'orders.view'`). L'entrée est masquée si l'utilisateur ne possède pas cette permission. |
---
@@ -247,7 +250,7 @@ import { registerNavSection, registerNavItem, registerPage } from '@zen/core/fea
import OrdersPage from './admin/orders/OrdersPage.js';
registerNavSection({ id: 'commerce', title: 'Commerce', icon: 'ShoppingBag03Icon', order: 30 });
registerNavItem({ id: 'orders', label: 'Commandes', icon: 'ShoppingBag03Icon', href: '/admin/orders', sectionId: 'commerce' });
registerNavItem({ id: 'orders', label: 'Commandes', icon: 'ShoppingBag03Icon', href: '/admin/orders', sectionId: 'commerce', permission: 'orders.view' });
registerPage({ slug: 'orders', Component: OrdersPage, title: 'Commandes' });
```