feat(ui): Navigation neu strukturiert (flache Topbar + Verwaltung-Menü + /settings)
Topbar nur noch täglich genutzte Punkte (Dashboard/Zeit/Abwesenheiten/Kalender); HR/Admin-Funktionen im neuen "Verwaltung"-Dropdown. Zahnrad führt auf eigene /settings-Seite mit Kategorie-Kacheln statt 11er-Flachliste. Zentrale navConfig.ts für PRIMARY/MANAGEMENT/SETTINGS_GROUPS; Rollen-Gating unverändert. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
// Zentrale Navigations-Konfiguration für Layout (Topbar/Verwaltung) und
|
||||
// die Einstellungs-Seite (/settings). Rollen-Gating bleibt überall identisch:
|
||||
// roles === undefined → für alle Rollen sichtbar; sonst nur gelistete Rollen.
|
||||
|
||||
export interface NavItem {
|
||||
path: string
|
||||
label: string
|
||||
roles?: string[]
|
||||
/** Kurzbeschreibung – nur in den /settings-Kacheln genutzt */
|
||||
description?: string
|
||||
}
|
||||
|
||||
const ADMIN = ['COMPANY_ADMIN', 'SUPER_ADMIN']
|
||||
const HR_PLUS = ['COMPANY_ADMIN', 'SUPER_ADMIN', 'HR', 'MANAGER']
|
||||
const HR_ADMIN = ['COMPANY_ADMIN', 'SUPER_ADMIN', 'HR']
|
||||
|
||||
// Täglich genutzt – bleibt flach in der Topbar
|
||||
export const PRIMARY_NAV: NavItem[] = [
|
||||
{ path: '/dashboard', label: 'Dashboard' },
|
||||
{ path: '/time', label: 'Zeiterfassung' },
|
||||
{ path: '/absences', label: 'Abwesenheiten' },
|
||||
{ path: '/calendar', label: 'Kalender' },
|
||||
]
|
||||
|
||||
// HR/Admin-Funktionen – gebündelt im "Verwaltung"-Dropdown
|
||||
export const MANAGEMENT_NAV: NavItem[] = [
|
||||
{ path: '/reports', label: 'Berichte', roles: HR_PLUS },
|
||||
{ path: '/users', label: 'Mitarbeiter', roles: HR_ADMIN },
|
||||
{ path: '/hr/special-assignments', label: 'Sondervertretungen', roles: HR_PLUS },
|
||||
{ path: '/hr/payouts', label: 'Stunden-Auszahlung', roles: HR_ADMIN },
|
||||
{ path: '/admin/tenants', label: 'Mandanten', roles: ['SUPER_ADMIN'] },
|
||||
]
|
||||
|
||||
export interface SettingsGroup {
|
||||
title: string
|
||||
items: NavItem[]
|
||||
}
|
||||
|
||||
// Einstellungs-Seite (/settings): nach Kategorien gruppierte Kacheln
|
||||
export const SETTINGS_GROUPS: SettingsGroup[] = [
|
||||
{
|
||||
title: 'Stammdaten',
|
||||
items: [
|
||||
{ path: '/work-schedules', label: 'Arbeitspläne', roles: ADMIN, description: 'Wochenarbeitszeiten & Teilzeitmodelle' },
|
||||
{ path: '/settings/absence-types', label: 'Abwesenheitstypen', roles: ADMIN, description: 'Urlaub, Krankheit & weitere Typen' },
|
||||
{ path: '/settings/company', label: 'Firma', roles: ADMIN, description: 'Firmendaten, Urlaubsregeln & Optionen' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Geräte',
|
||||
items: [
|
||||
{ path: '/settings/kiosk', label: 'Kiosk-Geräte', roles: ADMIN, description: 'Terminals freigeben & überwachen' },
|
||||
{ path: '/settings/qr-stamp', label: 'QR-Stempeln', roles: ADMIN, description: 'Firmenweiten QR-Code verwalten' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Import',
|
||||
items: [
|
||||
{ path: '/users/import', label: 'Mitarbeiter-Import', roles: ADMIN, description: 'Mitarbeiter per CSV anlegen' },
|
||||
{ path: '/settings/import', label: 'Daten importieren', roles: HR_ADMIN, description: 'Zeit- & Abwesenheitsdaten importieren' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Integrationen',
|
||||
items: [
|
||||
{ path: '/settings/caldav', label: 'CalDAV', description: 'Kalender-Sync (Nextcloud o. ä.)' },
|
||||
{ path: '/settings/ldap', label: 'LDAP', roles: ADMIN, description: 'Verzeichnis-Sync der Mitarbeiter' },
|
||||
{ path: '/settings/smtp', label: 'SMTP', roles: ADMIN, description: 'E-Mail-Versand konfigurieren' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'System',
|
||||
items: [
|
||||
{ path: '/settings/audit-log', label: 'Audit-Log', roles: ADMIN, description: 'Sicherheits- & Änderungsprotokoll' },
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
export function visibleFor<T extends NavItem>(items: T[], role: string): T[] {
|
||||
return items.filter(n => !n.roles || n.roles.includes(role))
|
||||
}
|
||||
|
||||
/** Hat die Rolle Zugriff auf mindestens einen Einstellungs-Eintrag? */
|
||||
export function hasAnySettings(role: string): boolean {
|
||||
return SETTINGS_GROUPS.some(g => visibleFor(g.items, role).length > 0)
|
||||
}
|
||||
Reference in New Issue
Block a user