Skip to content

Commit

Permalink
feat: implement help menu and some changes on user info menu
Browse files Browse the repository at this point in the history
  • Loading branch information
nborde-CSM committed Oct 26, 2021
1 parent 634e524 commit 404356c
Show file tree
Hide file tree
Showing 5 changed files with 197 additions and 83 deletions.
2 changes: 1 addition & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ export {
UploadFile,
UPLOAD_FILE_STATUS_KEY,
} from './inputs';
export { UserInfo } from './menus';
export { UserInfo, HelpMenu } from './menus';
export { PrivateRoute, PublicRoute } from './misc';
120 changes: 120 additions & 0 deletions src/menus/HelpMenu/HelpMenu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { Box, Menu, MenuItem, makeStyles, ClickAwayListener } from '@material-ui/core';
import HelpOutlineIcon from '@material-ui/icons/HelpOutline';

const useStyles = makeStyles((theme) => ({
menuTrigger: {
backgroundRepeat: 'no-repeat',
minWidth: '32px',
height: '32px',
backgroundSize: '32px',
borderRadius: '50%',
flexShrink: 0,
transition: 'box-shadow ease-in-out 0.2s',
'&:hover': {
cursor: 'pointer',
},
display: 'flex',
flexDirection: 'row',
flexWrap: 'nowrap',
justifyContent: 'center',
alignItems: 'stretch',
},
menu: {
transform: 'translate3d(0,30px,0) !important',
},
menuContainer: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
},
link: {
color: theme.palette.text.primary,
},
menuIcon: {
color: theme.palette.primary.main,
fontSize: 32,
},
}));

export const HelpMenu = (props) => {
const classes = useStyles();
const [isMenuOpen, setMenuOpen] = useState(false);
const [anchorEl, setAnchorEl] = useState(null);

const handleClose = () => {
setMenuOpen(false);
};

const handleClick = (event) => {
setAnchorEl(event.target);
setMenuOpen(!isMenuOpen);
};

const { documentationUrl, supportUrl, labels } = props;

return (
<ClickAwayListener onClickAway={handleClose}>
<div>
<Box
data-cy="help-menu"
aria-haspopup="true"
onClick={handleClick}
className={`${classes.menuTrigger} ${isMenuOpen ? 'active' : ''}`}
>
<HelpOutlineIcon className={classes.menuIcon} />
</Box>
<Menu className={classes.menu} keepMounted anchorEl={anchorEl} open={isMenuOpen} onClose={handleClick}>
{documentationUrl && (
<MenuItem data-cy="download-documentation" className={classes.link} onClick={handleClick}>
<a href={documentationUrl} className={classes.link} target="_blank" rel="noreferrer">
{labels.documentation}
</a>
</MenuItem>
)}
{supportUrl && (
<MenuItem data-cy="support" className={classes.link} onClick={handleClick}>
<a href={supportUrl} className={classes.link} target="_blank" rel="noreferrer">
{labels.support}
</a>
</MenuItem>
)}
</Menu>
</div>
</ClickAwayListener>
);
};

HelpMenu.propTypes = {
/**
* Documentation url
*/
documentationUrl: PropTypes.string,
/**
* Support page url
*/
supportUrl: PropTypes.string,
/**
* Component's labels:
* Structure:
* <pre>
{
documentation: 'string',
suuport: 'string',
}
* </pre>
*/
labels: PropTypes.shape({
documentation: PropTypes.string.isRequired,
support: PropTypes.string,
}),
};

HelpMenu.defaultProps = {
supportUrl: null,
labels: {
documentation: 'Documentation',
support: 'Contact support',
},
};
4 changes: 4 additions & 0 deletions src/menus/HelpMenu/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Copyright (c) Cosmo Tech.
// Licensed under the MIT license.

export { HelpMenu } from './HelpMenu';
153 changes: 71 additions & 82 deletions src/menus/UserInfo/UserInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { Box, Menu, MenuItem, makeStyles } from '@material-ui/core';
import { Box, Menu, MenuItem, makeStyles, ClickAwayListener } from '@material-ui/core';
import { ArrowRight as ArrowRightIcon, Check as CheckIcon } from '@material-ui/icons';

const useStyles = makeStyles((theme) => ({
Expand Down Expand Up @@ -47,114 +47,106 @@ const useStyles = makeStyles((theme) => ({
menuIcon: {
marginLeft: '20px',
},
docLink: {
color: theme.palette.primary.contrastText,
},
}));

export const UserInfo = (props) => {
const classes = useStyles();
const [isMenuOpened, setIsMenuOpened] = useState(false);
const [isLangMenuOpened, setLangIsMenuOpened] = useState(false);
const [isMenuOpen, setMenuOpen] = useState(false);
const [isLanguageMenuOpen, setLanguangeMenuOpen] = useState(false);
const [anchorEl, setAnchorEl] = useState(null);
const [langAnchorEl, setLangAnchorEl] = useState(null);

const handleClose = () => {
setMenuOpen(false);
setLanguangeMenuOpen(false);
};

const handleClick = (e) => {
setAnchorEl(e.target);
setIsMenuOpened(!isMenuOpened);
setMenuOpen(!isMenuOpen);
};

const handleLanguageMenuClick = (e) => {
setLangAnchorEl(e.target);
setLangIsMenuOpened(!isLangMenuOpened);
setLanguangeMenuOpen(!isLanguageMenuOpen);
};

const setLanguage = (lang) => {
setIsMenuOpened(false);
setLangIsMenuOpened(false);
changeLanguage(lang);
handleClose();
};

const { userName, profilePlaceholder, languages, documentationUrl, onLogout, changeLanguage, language, labels } =
props;
const { userName, profilePlaceholder, languages, onLogout, changeLanguage, language, labels } = props;

return (
<React.Fragment>
<Box
data-cy="user-profile-menu"
aria-controls="user-profile-button"
aria-haspopup="true"
onClick={handleClick}
className={`${classes.menuTrigger} ${isMenuOpened ? 'active' : ''}`}
>
<img className={classes.profilePic} src={profilePlaceholder} />
<span className={classes.userName}>{userName}</span>
</Box>
<Menu
className={classes.menu}
data-cy="main-menu"
keepMounted
anchorEl={anchorEl}
open={isMenuOpened}
onClose={handleClick}
>
{languages && (
<MenuItem data-cy="change-language" onClick={handleLanguageMenuClick} className={classes.menuContainer}>
{labels.language}
<ArrowRightIcon className={classes.menuIcon} />
</MenuItem>
)}
{documentationUrl && (
<MenuItem data-cy="download-documentation">
<a href={documentationUrl} className={classes.docLink} target="_blank" rel="noreferrer">
{labels.documentation}
</a>
</MenuItem>
)}
<MenuItem data-cy="logout" onClick={onLogout}>
{labels.logOut}
</MenuItem>
</Menu>
{languages && (
<ClickAwayListener onClickAway={handleClose}>
<div>
<Box
data-cy="user-profile-menu"
aria-controls="user-profile-button"
aria-haspopup="true"
onClick={handleClick}
className={`${classes.menuTrigger} ${isMenuOpen ? 'active' : ''}`}
>
<img className={classes.profilePic} src={profilePlaceholder} />
<span className={classes.userName}>{userName}</span>
</Box>

<Menu
className={classes.menu}
id="simple-menu"
data-cy="main-menu"
keepMounted
anchorEl={langAnchorEl}
getContentAnchorEl={null}
anchorOrigin={{ vertical: 'top', horizontal: 'left' }}
transformOrigin={{ vertical: 'center', horizontal: 'right' }}
open={isLangMenuOpened}
onClose={handleLanguageMenuClick}
anchorEl={anchorEl}
open={isMenuOpen}
onClose={handleClick}
>
{
// Language menu items
Object.entries(languages).map(([langKey, langLabel]) => (
<MenuItem
data-cy={'set-lang-' + langKey}
key={langKey}
onClick={() => setLanguage(langKey)}
className={classes.menuContainer}
>
{langLabel}
{
// Add a check mark for the currently selected language
langKey === language && <CheckIcon className={classes.menuIcon} />
}
</MenuItem>
))
}
{languages && (
<MenuItem data-cy="change-language" onClick={handleLanguageMenuClick} className={classes.menuContainer}>
{labels.language}
<ArrowRightIcon className={classes.menuIcon} />
</MenuItem>
)}
<MenuItem data-cy="logout" onClick={onLogout}>
{labels.logOut}
</MenuItem>
</Menu>
)}
</React.Fragment>
{languages && (
<Menu
className={classes.menu}
id="simple-menu"
keepMounted
anchorEl={langAnchorEl}
getContentAnchorEl={null}
anchorOrigin={{ vertical: 'top', horizontal: 'left' }}
transformOrigin={{ vertical: 'center', horizontal: 'right' }}
open={isLanguageMenuOpen}
onClose={handleLanguageMenuClick}
>
{
// Language menu items
Object.entries(languages).map(([langKey, langLabel]) => (
<MenuItem
data-cy={'set-lang-' + langKey}
key={langKey}
onClick={() => setLanguage(langKey)}
className={classes.menuContainer}
>
{langLabel}
{
// Add a check mark for the currently selected language
langKey === language && <CheckIcon className={classes.menuIcon} />
}
</MenuItem>
))
}
</Menu>
)}
</div>
</ClickAwayListener>
);
};

UserInfo.propTypes = {
/**
* Documentation url
*/
documentationUrl: PropTypes.string,
/**
* List of available languages
*/
Expand Down Expand Up @@ -185,14 +177,12 @@ UserInfo.propTypes = {
* <pre>
{
language: 'string',
documentation: 'string',
logOut: 'string'
}
* </pre>
*/
labels: PropTypes.shape({
language: PropTypes.string.isRequired,
documentation: PropTypes.string.isRequired,
logOut: PropTypes.string.isRequired,
}),
};
Expand All @@ -201,7 +191,6 @@ UserInfo.defaultProps = {
profilePictureUrl: '../../assets/profile_placeholder.png',
labels: {
language: 'Change language',
documentation: 'Download documentation',
logOut: 'Log out',
},
};
1 change: 1 addition & 0 deletions src/menus/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
// Licensed under the MIT license.

export { UserInfo } from './UserInfo';
export { HelpMenu } from './HelpMenu';

0 comments on commit 404356c

Please sign in to comment.