224 lines
7.5 KiB
TypeScript
224 lines
7.5 KiB
TypeScript
import AppBar from '@material-ui/core/AppBar';
|
|
import Button from '@material-ui/core/Button';
|
|
import IconButton from '@material-ui/core/IconButton';
|
|
import {createStyles, Theme, WithStyles, withStyles} from '@material-ui/core/styles';
|
|
import Toolbar from '@material-ui/core/Toolbar';
|
|
import Typography from '@material-ui/core/Typography';
|
|
import AccountCircle from '@material-ui/icons/AccountCircle';
|
|
import Chat from '@material-ui/icons/Chat';
|
|
import DevicesOther from '@material-ui/icons/DevicesOther';
|
|
import ExitToApp from '@material-ui/icons/ExitToApp';
|
|
import Highlight from '@material-ui/icons/Highlight';
|
|
import GitHubIcon from '@material-ui/icons/GitHub';
|
|
import MenuIcon from '@material-ui/icons/Menu';
|
|
import Apps from '@material-ui/icons/Apps';
|
|
import SupervisorAccount from '@material-ui/icons/SupervisorAccount';
|
|
import React, {Component, CSSProperties} from 'react';
|
|
import {Link} from 'react-router-dom';
|
|
import {observer} from 'mobx-react';
|
|
import {Hidden, PropTypes, withWidth} from '@material-ui/core';
|
|
import {Breakpoint} from '@material-ui/core/styles/createBreakpoints';
|
|
|
|
const styles = (theme: Theme) =>
|
|
createStyles({
|
|
appBar: {
|
|
zIndex: theme.zIndex.drawer + 1,
|
|
[theme.breakpoints.down('xs')]: {
|
|
paddingBottom: 10,
|
|
},
|
|
},
|
|
toolbar: {
|
|
justifyContent: 'space-between',
|
|
[theme.breakpoints.down('xs')]: {
|
|
flexWrap: 'wrap',
|
|
},
|
|
},
|
|
menuButtons: {
|
|
display: 'flex',
|
|
[theme.breakpoints.down('sm')]: {
|
|
flex: 1,
|
|
},
|
|
justifyContent: 'center',
|
|
[theme.breakpoints.down('xs')]: {
|
|
flexBasis: '100%',
|
|
marginTop: 5,
|
|
order: 1,
|
|
justifyContent: 'space-between',
|
|
},
|
|
},
|
|
title: {
|
|
[theme.breakpoints.up('md')]: {
|
|
flex: 1,
|
|
},
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
},
|
|
titleName: {
|
|
paddingRight: 10,
|
|
},
|
|
link: {
|
|
color: 'inherit',
|
|
textDecoration: 'none',
|
|
},
|
|
});
|
|
|
|
type Styles = WithStyles<'link' | 'menuButtons' | 'toolbar' | 'titleName' | 'title' | 'appBar'>;
|
|
|
|
interface IProps extends Styles {
|
|
loggedIn: boolean;
|
|
name: string;
|
|
admin: boolean;
|
|
version: string;
|
|
toggleTheme: VoidFunction;
|
|
showSettings: VoidFunction;
|
|
logout: VoidFunction;
|
|
style: CSSProperties;
|
|
width: Breakpoint;
|
|
setNavOpen: (open: boolean) => void;
|
|
}
|
|
|
|
@observer
|
|
class Header extends Component<IProps> {
|
|
public render() {
|
|
const {
|
|
classes,
|
|
version,
|
|
name,
|
|
loggedIn,
|
|
admin,
|
|
toggleTheme,
|
|
logout,
|
|
style,
|
|
setNavOpen,
|
|
width,
|
|
} = this.props;
|
|
|
|
const position = width === 'xs' ? 'sticky' : 'fixed';
|
|
|
|
return (
|
|
<AppBar position={position} style={style} className={classes.appBar}>
|
|
<Toolbar className={classes.toolbar}>
|
|
<div className={classes.title}>
|
|
<Link to="/" className={classes.link}>
|
|
<Typography variant="h5" className={classes.titleName} color="inherit">
|
|
Gotify
|
|
</Typography>
|
|
</Link>
|
|
<a
|
|
href={'https://github.com/gotify/server/releases/tag/v' + version}
|
|
className={classes.link}>
|
|
<Typography variant="button" color="inherit">
|
|
@{version}
|
|
</Typography>
|
|
</a>
|
|
</div>
|
|
{loggedIn && this.renderButtons(name, admin, logout, width, setNavOpen)}
|
|
<div>
|
|
<IconButton onClick={toggleTheme} color="inherit">
|
|
<Highlight />
|
|
</IconButton>
|
|
|
|
<a
|
|
href="https://github.com/gotify/server"
|
|
className={classes.link}
|
|
target="_blank"
|
|
rel="noopener noreferrer">
|
|
<IconButton color="inherit">
|
|
<GitHubIcon />
|
|
</IconButton>
|
|
</a>
|
|
</div>
|
|
</Toolbar>
|
|
</AppBar>
|
|
);
|
|
}
|
|
|
|
private renderButtons(
|
|
name: string,
|
|
admin: boolean,
|
|
logout: VoidFunction,
|
|
width: Breakpoint,
|
|
setNavOpen: (open: boolean) => void
|
|
) {
|
|
const {classes, showSettings} = this.props;
|
|
return (
|
|
<div className={classes.menuButtons}>
|
|
<Hidden smUp implementation="css">
|
|
<ResponsiveButton
|
|
icon={<MenuIcon />}
|
|
onClick={() => setNavOpen(true)}
|
|
label="menu"
|
|
width={width}
|
|
color="inherit"
|
|
/>
|
|
</Hidden>
|
|
{admin && (
|
|
<Link className={classes.link} to="/users" id="navigate-users">
|
|
<ResponsiveButton
|
|
icon={<SupervisorAccount />}
|
|
label="users"
|
|
width={width}
|
|
color="inherit"
|
|
/>
|
|
</Link>
|
|
)}
|
|
<Link className={classes.link} to="/applications" id="navigate-apps">
|
|
<ResponsiveButton icon={<Chat />} label="apps" width={width} color="inherit" />
|
|
</Link>
|
|
<Link className={classes.link} to="/clients" id="navigate-clients">
|
|
<ResponsiveButton
|
|
icon={<DevicesOther />}
|
|
label="clients"
|
|
width={width}
|
|
color="inherit"
|
|
/>
|
|
</Link>
|
|
<Link className={classes.link} to="/plugins" id="navigate-plugins">
|
|
<ResponsiveButton
|
|
icon={<Apps />}
|
|
label="plugins"
|
|
width={width}
|
|
color="inherit"
|
|
/>
|
|
</Link>
|
|
<ResponsiveButton
|
|
icon={<AccountCircle />}
|
|
label={name}
|
|
onClick={showSettings}
|
|
id="changepw"
|
|
width={width}
|
|
color="inherit"
|
|
/>
|
|
<ResponsiveButton
|
|
icon={<ExitToApp />}
|
|
label="Logout"
|
|
onClick={logout}
|
|
id="logout"
|
|
width={width}
|
|
color="inherit"
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
const ResponsiveButton: React.FC<{
|
|
width: Breakpoint;
|
|
color: PropTypes.Color;
|
|
label: string;
|
|
id?: string;
|
|
onClick?: () => void;
|
|
icon: React.ReactNode;
|
|
}> = ({width, icon, label, ...rest}) => {
|
|
if (width === 'xs' || width === 'sm') {
|
|
return <IconButton {...rest}>{icon}</IconButton>;
|
|
}
|
|
return (
|
|
<Button startIcon={icon} {...rest}>
|
|
{label}
|
|
</Button>
|
|
);
|
|
};
|
|
|
|
export default withWidth()(withStyles(styles, {withTheme: true})(Header));
|