github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/webui/src/lib/components/navbar.jsx (about) 1 import React from "react"; 2 import useUser from '../hooks/user' 3 import {auth, config} from "../api"; 4 import {useRouter} from "../hooks/router"; 5 import {Link} from "./nav"; 6 import {useAPI} from "../hooks/api"; 7 import {Navbar, Nav, NavDropdown} from "react-bootstrap"; 8 import Container from "react-bootstrap/Container"; 9 import {useLoginConfigContext} from "../hooks/conf"; 10 import {FeedPersonIcon} from "@primer/octicons-react"; 11 12 const NavUserInfo = () => { 13 const { user, loading, error } = useUser(); 14 const logoutUrl = useLoginConfigContext()?.logout_url || "/logout" 15 const { response: versionResponse, loading: versionLoading, error: versionError } = useAPI(() => { 16 return config.getLakeFSVersion() 17 }, []) 18 19 if (loading) return <Navbar.Text>Loading...</Navbar.Text>; 20 if (!user || !!error) return (<></>); 21 const notifyNewVersion = !versionLoading && !versionError && versionResponse.upgrade_recommended 22 const NavBarTitle = () => { 23 return ( 24 <> 25 {notifyNewVersion && <> <div className="user-menu-notification-indicator"></div> </> } 26 <FeedPersonIcon size={28} verticalAlign={"middle"}/> <span style={{marginLeft:6, fontSize:18}}>{user.friendly_name || user.id} </span> 27 </> 28 ) 29 } 30 return ( 31 <NavDropdown title={<NavBarTitle />} className="navbar-username" align="end"> 32 {notifyNewVersion && <> 33 <NavDropdown.Item href={versionResponse.upgrade_url}> 34 <> 35 <div className="menu-item-notification-indicator"></div> 36 New lakeFS version is available! 37 </> 38 </NavDropdown.Item><NavDropdown.Divider/></>} 39 <NavDropdown.Item 40 onClick={()=> { 41 auth.clearCurrentUser(); 42 window.location = logoutUrl; 43 }}> 44 Logout 45 </NavDropdown.Item> 46 <NavDropdown.Divider/> 47 {!versionLoading && !versionError && <> 48 <NavDropdown.Item disabled={true}> 49 <small>lakeFS {versionResponse.version}</small> 50 </NavDropdown.Item></>} 51 </NavDropdown> 52 ); 53 }; 54 55 const TopNavLink = ({ href, children }) => { 56 const router = useRouter(); 57 const isActive = (prefix) => router.route.indexOf(prefix) === 0; 58 59 return ( 60 <Link component={Nav.Link} active={isActive(href)} href={href}> 61 {children} 62 </Link> 63 ); 64 }; 65 66 const TopNav = ({logged = true}) => { 67 if (!logged) { 68 return ( 69 <Navbar variant="dark" bg="dark" expand="md"> 70 <Container fluid={true}> 71 <Link component={Navbar.Brand} href="/"> 72 <img src="/logo.png" alt="lakeFS" className="logo"/> 73 </Link> 74 </Container> 75 </Navbar> 76 ); 77 } 78 return ( 79 <Navbar variant="dark" bg="dark" expand="md"> 80 <Container fluid={true}> 81 <Link component={Navbar.Brand} href="/"> 82 <img src="/logo.png" alt="lakeFS" className="logo"/> 83 </Link> 84 <Navbar.Toggle aria-controls="navbarScroll" /> 85 <Navbar.Collapse id="navbarScroll"> 86 87 <Nav className="me-auto my-2 my-lg-0" 88 style={{ maxHeight: '100px' }} 89 navbarScroll> 90 <TopNavLink href="/repositories">Repositories</TopNavLink> 91 <TopNavLink href="/auth">Administration</TopNavLink> 92 </Nav> 93 94 <NavUserInfo/> 95 </Navbar.Collapse> 96 </Container> 97 </Navbar> 98 ); 99 }; 100 101 export default TopNav;