/** * Die Seitenleiste an einer Stelle beschrieben. * * `verfuegbar` wird umgestellt, sobald der Meilenstein die Seite liefert. So zeigt * die Huelle von Anfang an die echte Struktur, ohne auf Seiten zu verlinken, die * es noch nicht gibt. Die Beschriftungen haengen am Betriebsmodus (#008). */ import type { Recht } from "@/server/auth/rollen"; export type Betriebsmodus = "INTERN" | "DIENSTLEISTUNG"; export type NavEintrag = { readonly pfad: string; readonly beschriftung: string; /** * Abweichende Beschriftung im Modus DIENSTLEISTUNG. * * Dort heisst „Mitarbeiter“ „Personen“: es sind die Leute des Kunden, nicht * die eigenen Angestellten. Derselbe Eintrag, dieselbe Seite — nur das Wort * passt sich an (#008, ausgebaut in #011). */ readonly beschriftungDienstleistung?: string; /** Nur in diesem Modus zeigen. Fehlt der Wert, gilt der Eintrag in beiden. */ readonly nurModus?: Betriebsmodus; readonly symbol: string; /** Wer dieses Recht nicht hat, sieht den Eintrag gar nicht erst. */ readonly recht?: Recht; readonly verfuegbar: boolean; /** Issue, das die Seite liefert – nur fuer den Hinweis, solange sie fehlt. */ readonly ausIssue?: number; }; /** * **Jeder Eintrag nennt sein Recht.** * * Bis #035 stand `recht` nur am Admin-Bereich, und das genuegte: jede Rolle * durfte `lesen`, also war alles andere fuer jeden sichtbar. Mit `MITARBEITER` * stimmt das nicht mehr — diese Rolle darf **nicht** `lesen`, und ohne das Recht * an jedem Eintrag haette die Seitenleiste ihr sechs Links angeboten, die alle * auf `/kein-zugriff` fuehren. Ein Eintrag ohne `recht` ist seitdem die Ausnahme * und nicht die Regel. */ export const NAVIGATION: readonly NavEintrag[] = [ { pfad: "/", beschriftung: "Übersicht", symbol: "LayoutDashboard", recht: "lesen", verfuegbar: true }, { pfad: "/laeufe", beschriftung: "Läufe", symbol: "ListChecks", recht: "lesen", verfuegbar: true }, { pfad: "/vorlagen", beschriftung: "Vorlagen", symbol: "FileText", recht: "lesen", verfuegbar: true }, { pfad: "/mitarbeiter", beschriftung: "Mitarbeiter & Geräte", beschriftungDienstleistung: "Personen & Geräte", symbol: "Users", recht: "lesen", verfuegbar: true, }, { pfad: "/kunden", beschriftung: "Kunden", nurModus: "DIENSTLEISTUNG", symbol: "Building2", recht: "lesen", verfuegbar: true, }, { pfad: "/archiv", beschriftung: "Archiv", symbol: "Archive", recht: "lesen", verfuegbar: true }, { pfad: "/admin", beschriftung: "Admin", symbol: "Settings", recht: "verwaltung", verfuegbar: true }, /* * Die eine Seite der Selbstauskunft (#035). Sie steht am Ende, weil die * Reihenfolge fuer alle anderen Rollen gilt — und fuer einen `MITARBEITER` ist * sie der einzige Eintrag, da ist die Position gleichgueltig. */ { pfad: "/meine-geraete", beschriftung: "Meine Geräte", symbol: "Laptop", recht: "selbstauskunft", verfuegbar: true, }, ]; /** * Die sichtbaren Eintraege fuer diesen Modus und diese Rolle. * * Das Ausblenden ist Bequemlichkeit, keine Absicherung – die Rechtepruefung * sitzt in der Service-Schicht. Aber ein Leser soll nicht auf Knoepfe klicken, * die ihm hinterher eine Fehlermeldung zeigen. */ export function navigationFuer( modus: Betriebsmodus, darfEintrag: (recht: Recht) => boolean = () => true, ): readonly NavEintrag[] { return NAVIGATION.filter( (e) => (e.nurModus === undefined || e.nurModus === modus) && (e.recht === undefined || darfEintrag(e.recht)), ).map((eintrag) => modus === "DIENSTLEISTUNG" && eintrag.beschriftungDienstleistung ? { ...eintrag, beschriftung: eintrag.beschriftungDienstleistung } : eintrag, ); }