import React, { useEffect, useMemo } from "react"; import LinkIcon from "@mui/icons-material/Link"; import { useI18n } from "../../contexts/I18nContext"; import { RouteInfo, useRouter } from "../../contexts/RouterContext"; import { useUser } from "../../contexts/UserContext"; import { NavigationOverrides } from "../../types"; import { hasGroup } from "../../util/has_group"; import { hasPermission } from "../../util/has_permission"; import { isURL } from "../../util/is_url"; import NavRailItem from "./NavRailItem"; export interface NavRailRoutesProps { navigation: NavigationOverrides; } export const NavRailRoutes: React.FC = ({ navigation }) => { const { routes, setCustomRoutes } = useRouter(); const { user } = useUser(); const { t } = useI18n(); useEffect(() => { const newRoutes = Object.values(navigation) .filter((entry): entry is { route: RouteInfo } => Boolean(entry && entry?.route)) .map((entry) => entry.route); setCustomRoutes(newRoutes); }, [navigation, setCustomRoutes]); const navItems = useMemo(() => { const appItems: React.ReactNode[] = []; for (const [routeId, navEntry] of Object.entries(navigation)) { if (navEntry == null || navEntry === false || navEntry.hidden) continue; const navInfo = typeof navEntry === "object" ? navEntry : {}; if (navInfo.permission && !hasPermission(user, navInfo.permission)) continue; if (navInfo.group && !hasGroup(user, navInfo.group)) continue; if (navInfo.excludedGroup && hasGroup(user, navInfo.excludedGroup)) continue; let title = navInfo.title; let icon = navInfo.icon; let route: RouteInfo | undefined; let href: string | undefined; if (isURL(routeId)) { icon ??= LinkIcon; href = routeId; } else { route = routes.find((r) => r.id === routeId); if (route == null) { console.warn(`No route found for navigation entry ${routeId}`); continue; } title ??= route.title; } appItems.push( , ); } return appItems; }, [routes, navigation, user, t]); return <>{navItems}; }; export default NavRailRoutes;