verdaccio-ui/src/components/Header/Header.tsx
Priscila Oliveira ae73772a37 feat(eslint-config): add order rule in import
* refactor: added eslint-plugin-import

* refactor: disable some rules for muiComponents

* fix: fixed import
2019-10-07 22:19:18 +02:00

288 lines
7.1 KiB
TypeScript

import React, { SyntheticEvent, Component, Fragment, ReactElement } from 'react';
import { Link } from 'react-router-dom';
import { css } from 'emotion';
import MenuItem from '@material-ui/core/MenuItem';
import Menu from '@material-ui/core/Menu';
import Info from '@material-ui/icons/Info';
import Help from '@material-ui/icons/Help';
import AccountCircle from '@material-ui/icons/AccountCircle';
import { default as IconSearch } from '@material-ui/icons/Search';
import { getRegistryURL } from '../../utils/url';
import Logo from '../Logo';
import RegistryInfoDialog from '../RegistryInfoDialog/RegistryInfoDialog';
import Label from '../Label/Label';
import Search from '../Search/Search';
import RegistryInfoContent from '../RegistryInfoContent/RegistryInfoContent';
import IconButton from '../../muiComponents/IconButton';
import Tooltip from '../../muiComponents/Tooltip';
import Button from '../../muiComponents/Button';
import {
Greetings,
NavBar,
InnerNavBar,
MobileNavBar,
InnerMobileNavBar,
LeftSide,
RightSide,
IconSearchButton,
SearchWrapper,
StyledExternalLink,
} from './styles';
interface Props {
logo?: string;
username?: string;
onLogout: () => void;
onToggleLoginModal: () => void;
scope: string;
withoutSearch?: boolean;
}
interface State {
anchorEl?: null | Element | ((element: Element) => Element);
openInfoDialog: boolean;
registryUrl: string;
showMobileNavBar: boolean;
}
type ToolTipType = 'search' | 'help' | 'info';
class Header extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
openInfoDialog: false,
registryUrl: getRegistryURL(),
showMobileNavBar: false,
};
}
public render(): ReactElement<HTMLElement> {
const { showMobileNavBar } = this.state;
const { withoutSearch = false } = this.props;
return (
<div>
<NavBar position="static">
<InnerNavBar>
{this.renderLeftSide()}
{this.renderRightSide()}
</InnerNavBar>
{this.renderInfoDialog()}
</NavBar>
{showMobileNavBar && !withoutSearch && (
<MobileNavBar>
<InnerMobileNavBar>
<Search />
</InnerMobileNavBar>
<Button color="inherit" onClick={this.handleDismissMNav}>
{'Cancel'}
</Button>
</MobileNavBar>
)}
</div>
);
}
/**
* opens popover menu for logged in user.
*/
public handleLoggedInMenu = (event: SyntheticEvent<HTMLElement>) => {
this.setState({
anchorEl: event.currentTarget,
});
};
/**
* closes popover menu for logged in user
*/
public handleLoggedInMenuClose = () => {
this.setState({
anchorEl: null,
});
};
/**
* opens registry information dialog.
*/
public handleOpenRegistryInfoDialog = () => {
this.setState({
openInfoDialog: true,
});
};
/**
* closes registry information dialog.
*/
public handleCloseRegistryInfoDialog = () => {
this.setState({
openInfoDialog: false,
});
};
/**
* close/open popover menu for logged in users.
*/
public handleToggleLogin = () => {
const { onToggleLoginModal } = this.props;
this.setState(
{
anchorEl: null,
},
onToggleLoginModal
);
};
public handleToggleMNav = () => {
const { showMobileNavBar } = this.state;
this.setState({
showMobileNavBar: !showMobileNavBar,
});
};
public handleDismissMNav = () => {
this.setState({
showMobileNavBar: false,
});
};
public renderLeftSide = () => {
const { withoutSearch = false } = this.props;
return (
<LeftSide>
<Link
className={css`
margin-right: 1em;
`}
to={'/'}>
{this.renderLogo()}
</Link>
{!withoutSearch && (
<SearchWrapper>
<Search />
</SearchWrapper>
)}
</LeftSide>
);
};
public renderLogo = () => {
const { logo } = this.props;
if (logo) {
return <img alt="logo" height="40px" src={logo} />;
} else {
return <Logo />;
}
};
public renderToolTipIcon = (title: string, type: ToolTipType) => {
let content;
switch (type) {
case 'help':
content = (
<StyledExternalLink blank={true} to={'https://verdaccio.org/docs/en/installation'}>
<IconButton color={'inherit'}>
<Help />
</IconButton>
</StyledExternalLink>
);
break;
case 'info':
content = (
<IconButton color="inherit" id="header--button-registryInfo" onClick={this.handleOpenRegistryInfoDialog}>
<Info />
</IconButton>
);
break;
case 'search':
content = (
<IconSearchButton color="inherit" onClick={this.handleToggleMNav}>
<IconSearch />
</IconSearchButton>
);
break;
}
return (
<Tooltip disableFocusListener={true} title={title}>
{content}
</Tooltip>
);
};
public renderRightSide = () => {
const { username = '', withoutSearch = false } = this.props;
return (
<RightSide>
{!withoutSearch && this.renderToolTipIcon('Search packages', 'search')}
{this.renderToolTipIcon('Documentation', 'help')}
{this.renderToolTipIcon('Registry Information', 'info')}
{username ? (
this.renderMenu()
) : (
<Button color="inherit" id="header--button-login" onClick={this.handleToggleLogin}>
{'Login'}
</Button>
)}
</RightSide>
);
};
private renderGreetings = () => {
const { username = '' } = this.props;
return (
<Fragment>
<Greetings>{'Hi,'}</Greetings>
<Label capitalize={true} text={username} weight="bold" />
</Fragment>
);
};
/**
* render popover menu
*/
private renderMenu = () => {
const { onLogout } = this.props;
const { anchorEl } = this.state;
const open = Boolean(anchorEl);
return (
<>
<IconButton color="inherit" id="header--button-account" onClick={this.handleLoggedInMenu}>
<AccountCircle />
</IconButton>
<Menu
anchorEl={anchorEl}
anchorOrigin={{
vertical: 'top',
horizontal: 'right',
}}
id="sidebar-menu"
onClose={this.handleLoggedInMenuClose}
open={open}
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}>
<MenuItem disabled={true}>{this.renderGreetings()}</MenuItem>
<MenuItem id="header--button-logout" onClick={onLogout}>
{'Logout'}
</MenuItem>
</Menu>
</>
);
};
private renderInfoDialog = () => {
const { scope } = this.props;
const { openInfoDialog, registryUrl } = this.state;
return (
<RegistryInfoDialog onClose={this.handleCloseRegistryInfoDialog} open={openInfoDialog}>
<RegistryInfoContent registryUrl={registryUrl} scope={scope} />
</RegistryInfoDialog>
);
};
}
export default Header;