Files
timemaster/frontend/src/components/navConfig.ts
T
patrickandClaude Opus 4.8 c497a14446 refactor(ui): Verwaltung-Dropdown aufgelöst – Berichte flach, Rest in /settings
Verwaltung-Dropdown entfernt. Berichte wandert flach in die Topbar (HR+).
Mitarbeiter/Sondervertretungen/Auszahlung als Gruppe "Personal" und Mandanten
als Gruppe "Mandant" auf der /settings-Kachelseite.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 22:27:51 +02:00

94 lines
3.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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' },
{ path: '/reports', label: 'Berichte', roles: HR_PLUS },
]
export interface SettingsGroup {
title: string
items: NavItem[]
}
// Einstellungs-Seite (/settings): nach Kategorien gruppierte Kacheln.
// Enthält auch die HR/Admin-Verwaltung (Personal, Mandant).
export const SETTINGS_GROUPS: SettingsGroup[] = [
{
title: 'Personal',
items: [
{ path: '/users', label: 'Mitarbeiter', roles: HR_ADMIN, description: 'Mitarbeiter anlegen & bearbeiten' },
{ path: '/hr/special-assignments', label: 'Sondervertretungen', roles: HR_PLUS, description: 'Sondervertretungen verwalten' },
{ path: '/hr/payouts', label: 'Stunden-Auszahlung', roles: HR_ADMIN, description: 'Überstunden auszahlen' },
],
},
{
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: 'Mandant',
items: [
{ path: '/admin/tenants', label: 'Mandanten', roles: ['SUPER_ADMIN'], description: 'Firmen & Reseller verwalten' },
],
},
{
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)
}