merge master + cr change
[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, Tooltip } 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                     <Tooltip title="Additional Info">
87                         <DetailsIcon />
88                     </Tooltip>
89                 </IconButton>}
90             </Toolbar>
91         </AppBar>;
92     }
93 );
94
95 const renderMenuForUser = ({ user, menuItems, onMenuItemClick }: MainAppBarProps) => {
96     return (
97         <>
98             <IconButton color="inherit">
99                 <Tooltip title="Notification">
100                     <Badge badgeContent={3} color="primary">
101                         <NotificationIcon />
102                     </Badge>
103                 </Tooltip>
104             </IconButton>
105             <DropdownMenu icon={<UserPanelIcon />} id="account-menu" title="Account Management">
106                 <MenuItem>
107                     {getUserFullname(user)}
108                 </MenuItem>
109                 {renderMenuItems(menuItems.accountMenu, onMenuItemClick)}
110             </DropdownMenu>
111             <DropdownMenu icon={<HelpIcon />} id="help-menu" title="Help">
112                 {renderMenuItems(menuItems.helpMenu, onMenuItemClick)}
113             </DropdownMenu>
114         </>
115     );
116 };
117
118 const renderMenuForAnonymous = ({ onMenuItemClick, menuItems }: MainAppBarProps) => {
119     return menuItems.anonymousMenu.map((item, index) => (
120         <Button key={index} color="inherit" onClick={() => onMenuItemClick(item)}>
121             {item.label}
122         </Button>
123     ));
124 };
125
126 const renderMenuItems = (menuItems: MainAppBarMenuItem[], onMenuItemClick: (menuItem: MainAppBarMenuItem) => void) => {
127     return menuItems.map((item, index) => (
128         <MenuItem key={index} onClick={() => onMenuItemClick(item)}>
129             {item.label}
130         </MenuItem>
131     ));
132 };