Skip to content
Snippets Groups Projects
Commit 42c3ea0e authored by esikkala's avatar esikkala
Browse files

Add story for TopBar

parent 6c268276
No related branches found
No related tags found
No related merge requests found
import { addDecorator } from '@storybook/react' import { addDecorator } from '@storybook/react'
import { DocsPage, DocsContainer } from '@storybook/addon-docs/blocks'
import React from 'react' import React from 'react'
import { createStore } from 'redux' import { createStore } from 'redux'
import { Provider } from 'react-redux' import { Provider } from 'react-redux'
......
...@@ -29,6 +29,9 @@ const useStyles = makeStyles(theme => ({ ...@@ -29,6 +29,9 @@ const useStyles = makeStyles(theme => ({
} }
})) }))
/**
A component for creating a responsive page with static content.
*/
const TextPage = props => { const TextPage = props => {
const classes = useStyles() const classes = useStyles()
return ( return (
......
...@@ -6,4 +6,4 @@ export default { ...@@ -6,4 +6,4 @@ export default {
title: 'TextPage' title: 'TextPage'
} }
export const string = () => <TextPage>Some content</TextPage> export const basic = () => <TextPage>Some content</TextPage>
...@@ -7,7 +7,7 @@ import IconButton from '@material-ui/core/IconButton' ...@@ -7,7 +7,7 @@ import IconButton from '@material-ui/core/IconButton'
import Typography from '@material-ui/core/Typography' import Typography from '@material-ui/core/Typography'
import MenuItem from '@material-ui/core/MenuItem' import MenuItem from '@material-ui/core/MenuItem'
import Menu from '@material-ui/core/Menu' import Menu from '@material-ui/core/Menu'
import { withStyles } from '@material-ui/core/styles' import { makeStyles } from '@material-ui/core/styles'
import MoreIcon from '@material-ui/icons/MoreVert' import MoreIcon from '@material-ui/icons/MoreVert'
import Button from '@material-ui/core/Button' import Button from '@material-ui/core/Button'
import { Link, NavLink } from 'react-router-dom' import { Link, NavLink } from 'react-router-dom'
...@@ -19,7 +19,7 @@ import { has } from 'lodash' ...@@ -19,7 +19,7 @@ import { has } from 'lodash'
import secoLogo from '../../img/logos/seco-logo-48x50.png' import secoLogo from '../../img/logos/seco-logo-48x50.png'
import { showLanguageButton } from '../../configs/sampo/GeneralConfig' import { showLanguageButton } from '../../configs/sampo/GeneralConfig'
const styles = theme => ({ const useStyles = makeStyles((theme) => ({
grow: { grow: {
flexGrow: 1 flexGrow: 1
}, },
...@@ -67,40 +67,26 @@ const styles = theme => ({ ...@@ -67,40 +67,26 @@ const styles = theme => ({
display: 'none' display: 'none'
} }
} }
}) }))
class TopBar extends React.Component { const TopBar = props => {
state = { const [mobileMoreAnchorEl, setMobileMoreAnchorEl] = React.useState(null)
infoAnchorEl: null, const isMobileMenuOpen = Boolean(mobileMoreAnchorEl)
mobileMoreAnchorEl: null const { perspectives, currentLocale, availableLocales, rootUrl } = props
}; const classes = useStyles()
const handleMobileMenuOpen = event => setMobileMoreAnchorEl(event.currentTarget)
handleInfoMenuOpen = event => { const handleMobileMenuClose = () => setMobileMoreAnchorEl(null)
this.setState({ infoAnchorEl: event.currentTarget })
};
handleInfoMenuClose = () => {
this.setState({ infoAnchorEl: null })
};
handleMobileMenuOpen = event => {
this.setState({ mobileMoreAnchorEl: event.currentTarget })
};
handleMobileMenuClose = () => {
this.setState({ mobileMoreAnchorEl: null })
};
// https://material-ui.com/components/buttons/#third-party-routing-library // https://material-ui.com/components/buttons/#third-party-routing-library
AdapterLink = React.forwardRef((props, ref) => <Link innerRef={ref} {...props} />); const AdapterLink = React.forwardRef((props, ref) => <Link innerRef={ref} {...props} />)
AdapterNavLink = React.forwardRef((props, ref) => <NavLink innerRef={ref} {...props} />); const AdapterNavLink = React.forwardRef((props, ref) => <NavLink innerRef={ref} {...props} />)
renderMobileMenuItem = perspective => { const renderMobileMenuItem = perspective => {
const searchMode = perspective.id.startsWith('clientFS') ? 'federated-search' : 'faceted-search' const searchMode = perspective.id.startsWith('clientFS') ? 'federated-search' : 'faceted-search'
if (has(perspective, 'externalUrl')) { if (has(perspective, 'externalUrl')) {
return ( return (
<a <a
className={this.props.classes.link} className={classes.link}
key={perspective.id} key={perspective.id}
href={perspective.externalUrl} href={perspective.externalUrl}
target='_blank' target='_blank'
...@@ -115,8 +101,8 @@ class TopBar extends React.Component { ...@@ -115,8 +101,8 @@ class TopBar extends React.Component {
return ( return (
<MenuItem <MenuItem
key={perspective.id} key={perspective.id}
component={this.AdapterLink} component={AdapterLink}
to={`${this.props.rootUrl}/${perspective.id}/${searchMode}`} to={`${props.rootUrl}/${perspective.id}/${searchMode}`}
> >
{intl.get(`perspectives.${perspective.id}.label`).toUpperCase()} {intl.get(`perspectives.${perspective.id}.label`).toUpperCase()}
</MenuItem> </MenuItem>
...@@ -124,19 +110,19 @@ class TopBar extends React.Component { ...@@ -124,19 +110,19 @@ class TopBar extends React.Component {
} }
} }
renderDesktopTopMenuItem = perspective => { const renderDesktopTopMenuItem = perspective => {
const searchMode = perspective.id.startsWith('clientFS') ? 'federated-search' : 'faceted-search' const searchMode = perspective.id.startsWith('clientFS') ? 'federated-search' : 'faceted-search'
if (has(perspective, 'externalUrl')) { if (has(perspective, 'externalUrl')) {
return ( return (
<a <a
className={this.props.classes.link} className={classes.link}
key={perspective.id} key={perspective.id}
href={perspective.externalUrl} href={perspective.externalUrl}
target='_blank' target='_blank'
rel='noopener noreferrer' rel='noopener noreferrer'
> >
<Button <Button
className={this.props.classes.appBarButton} className={classes.appBarButton}
> >
{intl.get(`perspectives.${perspective.id}.label`).toUpperCase()} {intl.get(`perspectives.${perspective.id}.label`).toUpperCase()}
</Button> </Button>
...@@ -146,11 +132,11 @@ class TopBar extends React.Component { ...@@ -146,11 +132,11 @@ class TopBar extends React.Component {
return ( return (
<Button <Button
key={perspective.id} key={perspective.id}
className={this.props.classes.appBarButton} className={classes.appBarButton}
component={this.AdapterNavLink} component={AdapterNavLink}
to={`${this.props.rootUrl}/${perspective.id}/${searchMode}`} to={`${props.rootUrl}/${perspective.id}/${searchMode}`}
isActive={(match, location) => location.pathname.startsWith(`${this.props.rootUrl}/${perspective.id}`)} isActive={(match, location) => location.pathname.startsWith(`${props.rootUrl}/${perspective.id}`)}
activeClassName={this.props.classes.appBarButtonActive} activeClassName={classes.appBarButtonActive}
> >
{intl.get(`perspectives.${perspective.id}.label`).toUpperCase()} {intl.get(`perspectives.${perspective.id}.label`).toUpperCase()}
</Button> </Button>
...@@ -158,32 +144,32 @@ class TopBar extends React.Component { ...@@ -158,32 +144,32 @@ class TopBar extends React.Component {
} }
} }
renderMobileMenu = perspectives => const renderMobileMenu = perspectives =>
<Menu <Menu
anchorEl={this.state.mobileMoreAnchorEl} anchorEl={mobileMoreAnchorEl}
anchorOrigin={{ vertical: 'top', horizontal: 'right' }} anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
transformOrigin={{ vertical: 'top', horizontal: 'right' }} transformOrigin={{ vertical: 'top', horizontal: 'right' }}
open={Boolean(this.state.mobileMoreAnchorEl)} open={isMobileMenuOpen}
onClose={this.handleMobileMenuClose} onClose={handleMobileMenuClose}
> >
{perspectives.map(perspective => this.renderMobileMenuItem(perspective))} {perspectives.map(perspective => renderMobileMenuItem(perspective))}
<Divider /> <Divider />
<MenuItem <MenuItem
key='feedback' key='feedback'
component={this.AdapterLink} component={AdapterLink}
to={`${this.props.rootUrl}/feedback`} to={`${props.rootUrl}/feedback`}
> >
{intl.get('topBar.feedback').toUpperCase()} {intl.get('topBar.feedback').toUpperCase()}
</MenuItem> </MenuItem>
<MenuItem <MenuItem
key={0} key={0}
component={this.AdapterLink} component={AdapterLink}
to={`${this.props.rootUrl}/about`} to={`${props.rootUrl}/about`}
> >
{intl.get('topBar.info.aboutThePortal').toUpperCase()} {intl.get('topBar.info.aboutThePortal').toUpperCase()}
</MenuItem> </MenuItem>
<a <a
className={this.props.classes.link} className={classes.link}
key={1} key={1}
href={intl.get('topBar.info.blogUrl')} href={intl.get('topBar.info.blogUrl')}
target='_blank' target='_blank'
...@@ -195,85 +181,81 @@ class TopBar extends React.Component { ...@@ -195,85 +181,81 @@ class TopBar extends React.Component {
</a> </a>
<MenuItem <MenuItem
key='info' key='info'
component={this.AdapterLink} component={AdapterLink}
to={`${this.props.rootUrl}/instructions`} to={`${props.rootUrl}/instructions`}
> >
{intl.get('topBar.instructions').toUpperCase()} {intl.get('topBar.instructions').toUpperCase()}
</MenuItem> </MenuItem>
</Menu> </Menu>
render () { return (
const { classes, perspectives, currentLocale, availableLocales, rootUrl } = this.props <div className={classes.root}>
return ( {/* Add an empty Typography element to ensure that that the MuiTypography class is loaded for
<div className={classes.root}>
{/* Add an empty Typography element to ensure that that the MuiTypography class is loaded for
any lower level components that use MuiTypography class only in translation files */} any lower level components that use MuiTypography class only in translation files */}
<Typography /> <Typography />
<AppBar position='absolute'> <AppBar position='absolute'>
<Toolbar className={classes.toolbar}> <Toolbar className={classes.toolbar}>
<Button component={this.AdapterLink} to='/'> <Button component={AdapterLink} to='/'>
<Typography className={classes.homeButtonText} variant='h6'>{intl.get('appTitle.short')}</Typography> <Typography className={classes.homeButtonText} variant='h6'>{intl.get('appTitle.short')}</Typography>
</Button>
<TopBarSearchField
fetchFullTextResults={props.fetchFullTextResults}
clearResults={props.clearResults}
xsScreen={props.xsScreen}
rootUrl={rootUrl}
/>
<div className={classes.grow} />
<div className={classes.sectionDesktop}>
{perspectives.map((perspective, index) => renderDesktopTopMenuItem(perspective, index))}
<div className={classes.appBarDivider} />
<Button
className={classes.appBarButton}
component={AdapterNavLink}
to={`${props.rootUrl}/feedback`}
isActive={(match, location) => location.pathname.startsWith(`${props.rootUrl}/feedback`)}
activeClassName={classes.appBarButtonActive}
>
{intl.get('topBar.feedback')}
</Button> </Button>
<TopBarSearchField <TopBarInfoButton rootUrl={props.rootUrl} />
fetchFullTextResults={this.props.fetchFullTextResults} <Button
clearResults={this.props.clearResults} className={classes.appBarButton}
xsScreen={this.props.xsScreen} component={AdapterNavLink}
rootUrl={rootUrl} to={`${props.rootUrl}/instructions`}
/> isActive={(match, location) => location.pathname.startsWith(`${props.rootUrl}/instructions`)}
<div className={classes.grow} /> activeClassName={classes.appBarButtonActive}
<div className={classes.sectionDesktop}>
{perspectives.map((perspective, index) => this.renderDesktopTopMenuItem(perspective, index))}
<div className={classes.appBarDivider} />
<Button
className={classes.appBarButton}
component={this.AdapterNavLink}
to={`${this.props.rootUrl}/feedback`}
isActive={(match, location) => location.pathname.startsWith(`${this.props.rootUrl}/feedback`)}
activeClassName={this.props.classes.appBarButtonActive}
>
{intl.get('topBar.feedback')}
</Button>
<TopBarInfoButton rootUrl={this.props.rootUrl} />
<Button
className={classes.appBarButton}
component={this.AdapterNavLink}
to={`${this.props.rootUrl}/instructions`}
isActive={(match, location) => location.pathname.startsWith(`${this.props.rootUrl}/instructions`)}
activeClassName={this.props.classes.appBarButtonActive}
>
{intl.get('topBar.instructions')}
</Button>
{showLanguageButton &&
<TopBarLanguageButton
currentLocale={currentLocale}
availableLocales={availableLocales}
loadLocales={this.props.loadLocales}
location={this.props.location}
/>}
</div>
<a
className={classes.secoLogo}
href='https://seco.cs.aalto.fi'
target='_blank'
rel='noopener noreferrer'
> >
<Button><img src={secoLogo} /></Button> {intl.get('topBar.instructions')}
</a> </Button>
<div className={classes.sectionMobile}> {showLanguageButton &&
<IconButton aria-haspopup='true' onClick={this.handleMobileMenuOpen} color='inherit'> <TopBarLanguageButton
<MoreIcon /> currentLocale={currentLocale}
</IconButton> availableLocales={availableLocales}
</div> loadLocales={props.loadLocales}
</Toolbar> location={props.location}
</AppBar> />}
{this.renderMobileMenu(perspectives)} </div>
</div> <a
) className={classes.secoLogo}
} href='https://seco.cs.aalto.fi'
target='_blank'
rel='noopener noreferrer'
>
<Button><img src={secoLogo} /></Button>
</a>
<div className={classes.sectionMobile}>
<IconButton aria-haspopup='true' onClick={handleMobileMenuOpen} color='inherit'>
<MoreIcon />
</IconButton>
</div>
</Toolbar>
</AppBar>
{renderMobileMenu(perspectives)}
</div>
)
} }
TopBar.propTypes = { TopBar.propTypes = {
classes: PropTypes.object.isRequired,
fetchFullTextResults: PropTypes.func.isRequired, fetchFullTextResults: PropTypes.func.isRequired,
clearResults: PropTypes.func.isRequired, clearResults: PropTypes.func.isRequired,
loadLocales: PropTypes.func.isRequired, loadLocales: PropTypes.func.isRequired,
...@@ -282,7 +264,10 @@ TopBar.propTypes = { ...@@ -282,7 +264,10 @@ TopBar.propTypes = {
availableLocales: PropTypes.array.isRequired, availableLocales: PropTypes.array.isRequired,
xsScreen: PropTypes.bool.isRequired, xsScreen: PropTypes.bool.isRequired,
location: PropTypes.object.isRequired, location: PropTypes.object.isRequired,
/**
* Root url of the application.
*/
rootUrl: PropTypes.string.isRequired rootUrl: PropTypes.string.isRequired
} }
export default withStyles(styles)(TopBar) export default TopBar
import React from 'react'
import TopBar from './TopBar'
import { useSelector } from 'react-redux'
import { useLocation } from 'react-router-dom'
import { perspectiveConfig } from '../../configs/sampo/PerspectiveConfig'
export default {
component: TopBar,
title: 'TopBar'
}
export const basic = props => {
const fullTextSearch = useSelector(state => state.fullTextSearch)
const options = useSelector(state => state.options)
const location = useLocation()
// console.log(props)
return (
<TopBar
rootUrl=''
search={fullTextSearch}
perspectives={perspectiveConfig}
currentLocale={options.currentLocale}
availableLocales={options.availableLocales}
xsScreen={false}
location={location}
/>
)
}
...@@ -112,7 +112,7 @@ class TopBarSearchField extends React.Component { ...@@ -112,7 +112,7 @@ class TopBarSearchField extends React.Component {
TopBarSearchField.propTypes = { TopBarSearchField.propTypes = {
classes: PropTypes.object.isRequired, classes: PropTypes.object.isRequired,
fetchFullTextResults: PropTypes.func.isRequired, fetchFullTextResults: PropTypes.func,
xsScreen: PropTypes.bool.isRequired, xsScreen: PropTypes.bool.isRequired,
rootUrl: PropTypes.string.isRequired rootUrl: PropTypes.string.isRequired
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment