/* * QQQ - Low-code Application Framework for Engineers. * Copyright (C) 2021-2022. Kingsrook, LLC * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States * contact@kingsrook.com * https://github.com/Kingsrook/ * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ import {Popper, InputAdornment, Box} from "@mui/material"; import AppBar from "@mui/material/AppBar"; import Autocomplete from "@mui/material/Autocomplete"; import Icon from "@mui/material/Icon"; import IconButton from "@mui/material/IconButton"; import ListItemIcon from "@mui/material/ListItemIcon"; import {Theme} from "@mui/material/styles"; import TextField from "@mui/material/TextField"; import Toolbar from "@mui/material/Toolbar"; import React, {useContext, useEffect, useRef, useState} from "react"; import {useLocation, useNavigate} from "react-router-dom"; import QContext from "QContext"; import QBreadcrumbs, {routeToLabel} from "qqq/components/horseshoe/Breadcrumbs"; import {navbar, navbarContainer, navbarRow, navbarMobileMenu, recentlyViewedMenu,} from "qqq/components/horseshoe/Styles"; import MDTypography from "qqq/components/legacy/MDTypography"; import {setTransparentNavbar, useMaterialUIController, setMiniSidenav} from "qqq/context"; import HistoryUtils from "qqq/utils/HistoryUtils"; // Declaring prop types for NavBar interface Props { absolute?: boolean; light?: boolean; isMini?: boolean; } interface HistoryEntry { id: number; path: string; label: string; iconName?: string; } function NavBar({absolute, light, isMini}: Props): JSX.Element { const [navbarType, setNavbarType] = useState<"fixed" | "absolute" | "relative" | "static" | "sticky">(); const [controller, dispatch] = useMaterialUIController(); const {miniSidenav, transparentNavbar, fixedNavbar, darkMode,} = controller; const [openMenu, setOpenMenu] = useState(false); const [history, setHistory] = useState([] as HistoryEntry[]); const [autocompleteValue, setAutocompleteValue] = useState(null); const fullPath = useLocation().pathname; const route = useLocation().pathname.split("/").slice(1); const navigate = useNavigate(); const {pageHeader, setDotMenuOpen} = useContext(QContext); useEffect(() => { // Setting the navbar type if (fixedNavbar) { setNavbarType("sticky"); } else { setNavbarType("static"); } // A function that sets the transparent state of the navbar. function handleTransparentNavbar() { setTransparentNavbar(dispatch, (fixedNavbar && window.scrollY === 0) || !fixedNavbar); } /** The event listener that's calling the handleTransparentNavbar function when scrolling the window. */ window.addEventListener("scroll", handleTransparentNavbar); // Call the handleTransparentNavbar function to set the state with the initial value. handleTransparentNavbar(); buildHistoryEntries(); const history = HistoryUtils.get(); const options = [] as any; history.entries.reverse().forEach((entry, index) => options.push({label: `${entry.label} index`, id: index, key: index, path: entry.path, iconName: entry.iconName}) ); setHistory(options); // Remove event listener on cleanup return () => window.removeEventListener("scroll", handleTransparentNavbar); }, [dispatch, fixedNavbar]); const handleMiniSidenav = () => setMiniSidenav(dispatch, !miniSidenav); const goToHistory = (path: string) => { navigate(path); }; function buildHistoryEntries() { const history = HistoryUtils.get(); const options = [] as any; history.entries.reverse().forEach((entry, index) => options.push({label: entry.label, id: index, key: index, path: entry.path, iconName: entry.iconName}) ); setHistory(options); } function handleHistoryOnOpen() { buildHistoryEntries(); } const handleOpenMenu = (event: any) => setOpenMenu(event.currentTarget); const handleCloseMenu = () => setOpenMenu(false); const handleAutocompleteOnChange = (event: any, value: any, reason: any, details: any) => { if (value) { goToHistory(value.path); } setAutocompleteValue(null); }; const CustomPopper = function (props: any) { return (); }; const renderHistory = () => { return ( option.id === value.id} sx={recentlyViewedMenu} renderInput={(params) => keyboard_arrow_down ) }} />} renderOption={(props, option: HistoryEntry) => ( {option.iconName} {option.label} )} /> ); }; // Styles for the navbar icons const iconsStyle = ({ palette: {dark, white, text}, functions: {rgba}, }: { palette: any; functions: any; }) => ({ color: () => { let colorValue = light || darkMode ? white.main : dark.main; if (transparentNavbar && !light) { colorValue = darkMode ? rgba(text.main, 0.6) : text.main; } return colorValue; }, }); const {pathToLabelMap} = useContext(QContext); const fullPathToLabel = (fullPath: string, route: string): string => { if (fullPath.endsWith("/")) { fullPath = fullPath.replace(/\/+$/, ""); } if (pathToLabelMap && pathToLabelMap[fullPath]) { return pathToLabelMap[fullPath]; } return (routeToLabel(route)); }; const breadcrumbTitle = fullPathToLabel(fullPath, route[route.length - 1]); /////////////////////////////////////////////////////////////////////////////////////////////// // set the right-half of the navbar up so that below the 'md' breakpoint, it just disappears // /////////////////////////////////////////////////////////////////////////////////////////////// const navbarRowRight = (theme: Theme, {isMini}: any) => { return { [theme.breakpoints.down("md")]: { display: "none", }, ...navbarRow(theme, isMini) } }; return ( navbar(theme, { transparentNavbar, absolute, light, darkMode, })} > navbarRow(theme, {isMini})}> menu {isMini ? null : ( navbarRowRight(theme, {isMini})}> {renderHistory()} setDotMenuOpen(true)}> search )} { pageHeader && {pageHeader} } ); } // Declaring default props for NavBar NavBar.defaultProps = { absolute: false, light: false, isMini: false, }; export default NavBar;