top-left-title-does-not-function-as-a-link
[arvados-workbench2.git] / src / views-components / main-app-bar / main-app-bar.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import * as React from "react";
6 import { AppBar, Toolbar, Typography, Grid, IconButton, Badge, Button, MenuItem } from "@material-ui/core";
7 import { StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core/styles';
8 import { ArvadosTheme } from '~/common/custom-theme';
9 import { Link } from "react-router-dom";
10 import { User, getUserFullname } from "~/models/user";
11 import { SearchBar } from "~/components/search-bar/search-bar";
12 import { DropdownMenu } from "~/components/dropdown-menu/dropdown-menu";
13 import { DetailsIcon, NotificationIcon, UserPanelIcon, HelpIcon } from "~/components/icon/icon";
14 import { Routes } from '~/routes/routes';
15
16 type CssRules = 'link';
17
18 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
19     link: {
20         textDecoration: 'none',
21         color: 'inherit'
22     }
23 });
24
25 export interface MainAppBarMenuItem {
26     label: string;
27 }
28
29 export interface MainAppBarMenuItems {
30     accountMenu: MainAppBarMenuItem[];
31     helpMenu: MainAppBarMenuItem[];
32     anonymousMenu: MainAppBarMenuItem[];
33 }
34
35 interface MainAppBarDataProps {
36     searchText: string;
37     searchDebounce?: number;
38     breadcrumbs: React.ComponentType<any>;
39     user?: User;
40     menuItems: MainAppBarMenuItems;
41     buildInfo: string;
42 }
43
44 export interface MainAppBarActionProps {
45     onSearch: (searchText: string) => void;
46     onMenuItemClick: (menuItem: MainAppBarMenuItem) => void;
47     onDetailsPanelToggle: () => void;
48 }
49
50 export type MainAppBarProps = MainAppBarDataProps & MainAppBarActionProps & WithStyles<CssRules>;
51
52 export const MainAppBar = withStyles(styles)(
53     (props: MainAppBarProps) => {
54         return <AppBar position="static">
55             <Toolbar>
56                 <Grid container justify="space-between">
57                     <Grid item xs={3}>
58                         <Typography variant="headline" color="inherit" noWrap>
59                             <Link to={Routes.ROOT} className={props.classes.link}>
60                                 Arvados 2
61                             </Link>
62                         </Typography>
63                         <Typography variant="body1" color="inherit" noWrap >
64                             {props.buildInfo}
65                         </Typography>
66                     </Grid>
67                     <Grid item xs={6} container alignItems="center">
68                         {
69                             props.user && <SearchBar
70                                 value={props.searchText}
71                                 onSearch={props.onSearch}
72                                 debounce={props.searchDebounce}
73                             />
74                         }
75                     </Grid>
76                     <Grid item xs={3} container alignItems="center" justify="flex-end">
77                         {
78                             props.user ? renderMenuForUser(props) : renderMenuForAnonymous(props)
79                         }
80                     </Grid>
81                 </Grid>
82             </Toolbar>
83             <Toolbar >
84                 {props.user && <props.breadcrumbs />}
85                 {props.user && <IconButton color="inherit" onClick={props.onDetailsPanelToggle}>
86                     <DetailsIcon />
87                 </IconButton>
88                 }
89             </Toolbar>
90         </AppBar>;
91     }
92 );
93
94 const renderMenuForUser = ({ user, menuItems, onMenuItemClick }: MainAppBarProps) => {
95     return (
96         <>
97             <IconButton color="inherit">
98                 <Badge badgeContent={3} color="primary">
99                     <NotificationIcon />
100                 </Badge>
101             </IconButton>
102             <DropdownMenu icon={<UserPanelIcon />} id="account-menu">
103                 <MenuItem>
104                     {getUserFullname(user)}
105                 </MenuItem>
106                 {renderMenuItems(menuItems.accountMenu, onMenuItemClick)}
107             </DropdownMenu>
108             <DropdownMenu icon={<HelpIcon />} id="help-menu">
109                 {renderMenuItems(menuItems.helpMenu, onMenuItemClick)}
110             </DropdownMenu>
111         </>
112     );
113 };
114
115 const renderMenuForAnonymous = ({ onMenuItemClick, menuItems }: MainAppBarProps) => {
116     return menuItems.anonymousMenu.map((item, index) => (
117         <Button key={index} color="inherit" onClick={() => onMenuItemClick(item)}>
118             {item.label}
119         </Button>
120     ));
121 };
122
123 const renderMenuItems = (menuItems: MainAppBarMenuItem[], onMenuItemClick: (menuItem: MainAppBarMenuItem) => void) => {
124     return menuItems.map((item, index) => (
125         <MenuItem key={index} onClick={() => onMenuItemClick(item)}>
126             {item.label}
127         </MenuItem>
128     ));
129 };