import { Menubar } from 'primereact/menubar'; import React, { useContext, useEffect, useRef, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { AuthContext } from '../contexts'; import { Configuration } from '../services'; import { Airport } from '../services'; import { AirportOverview, BackendReturnStatus, IAuthState } from '../types'; export const NavBar: React.FC = () => { const [menuTree, setMenuTree] = useState(undefined); const authContext = useContext(AuthContext); const currentAuth = useRef(); const navigate = useNavigate(); currentAuth.current = authContext.auth; const firBasedSubMenu = (airports: AirportOverview[], endpoint: string): any[] => { if (airports.length === 0) { return [{ label: 'No airport available', disabled: true, }]; } const firAirports: [string, AirportOverview[]][] = []; // cluster airports based on FIRs airports.forEach((airport) => { const idx = firAirports.findIndex((value) => value[0] === airport.flightInformationRegion); if (idx !== -1) { firAirports[idx][1].push(airport); } else { firAirports.push([airport.flightInformationRegion, [airport]]); } }); // create the submenu for every FIR const retval: any[] = []; firAirports.forEach((fir) => { retval.push({ label: fir[0], items: [], }); // sort airports alphabetically fir[1].sort(); // create the airport with the link fir[1].forEach((airport) => { retval[retval.length - 1].push({ label: `${airport.icao} - ${airport.name}`, command: () => navigate(`${endpoint}?icao=${airport.icao}`), }); }); }); return retval; } const updateMenuItems = async () => { if (currentAuth.current === undefined || !currentAuth.current.valid) return []; Airport.all().then((response) => { if (response.status !== BackendReturnStatus.Ok) return []; const newMenuTree: { label: string; items?: any[]; command?: () => void }[] = [ { label: 'Airports', items: [] as any[], } ]; // create the airports subtree const airportSubtree = firBasedSubMenu(response.airports, '/sequence'); newMenuTree[0].items = airportSubtree; // collect all configuration airports const configurationAirports: AirportOverview[] = []; response.airports.forEach((airport) => { const idx = currentAuth.current?.user.airportConfigurationAccess.findIndex((value) => airport.icao === value); if (idx !== -1) configurationAirports.push(airport); }); // create the configuration subtree if (configurationAirports.length !== 0) { const configurationSubtree = firBasedSubMenu(configurationAirports, '/configure/airport'); newMenuTree[1].items = configurationSubtree; } if (currentAuth.current?.user.administrator) { newMenuTree.push({ label: 'Administration', items: [ { label: 'Users', command: () => navigate('/admin/users'), }, { label: 'Airports', command: () => navigate('/admin/airports'), }, ], }); } newMenuTree.push({ label: 'Logout', command: () => navigate('/logout'), }); setMenuTree(newMenuTree); }); } useEffect(() => { const event = new EventSource(`${Configuration.resourceServer}/airport/renew`); event.onmessage = () => { updateMenuItems(); } return () => { event.close(); } // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { if (currentAuth.current?.valid) { updateMenuItems(); } else { setMenuTree([]); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [authContext]); if (menuTree === undefined || !currentAuth.current.valid) return <>; return (menuTree.length !== 0 ? : <>); };