frontend/src/js/components/Header.js (104 lines of code) (raw):
import React from 'react';
import PropTypes from 'prop-types';
import SearchIcon from 'react-icons/lib/md/search';
import Settings from 'react-icons/lib/md/settings';
import FolderIcon from 'react-icons/lib/md/folder-open';
import DatabaseIcon from 'react-icons/lib/fa/database';
import {SearchLink, NavSearchLink} from './UtilComponents/SearchLink';
function calculateActive(paths) {
return (linkPath, currentPath) => {
const matchingPath = paths.find((possibleMatch) => currentPath.pathname.indexOf(possibleMatch) !== -1);
return !!matchingPath;
};
}
function HeaderSearchLink({ to, children, activePaths, className }) {
return <NavSearchLink
to={to}
isActive={calculateActive(activePaths)}
activeClassName={className ? `main-header__item main-header__item--link main-header__item--active ${className}` : 'main-header__item main-header__item--link main-header__item--active'}
className={className ? `main-header__item main-header__item--link ${className}` : 'main-header__item main-header__item--link'}
>
{children}
</NavSearchLink>;
}
HeaderSearchLink.propTypes = {
to: PropTypes.string.isRequired,
children: PropTypes.node.isRequired,
className: PropTypes.string,
activePaths: PropTypes.arrayOf(PropTypes.string).isRequired
};
export default class Header extends React.Component {
static propTypes = {
user: PropTypes.shape({
displayName: PropTypes.string.isRequired,
username: PropTypes.string.isRequired
}),
config: PropTypes.shape({
label: PropTypes.string,
readOnly: PropTypes.bool.isRequired
}),
preferences: PropTypes.object,
};
state = {
isOpen: false
}
collectionsPaths = [
'/collections', '/ingestions', '/files', '/documents'
];
renderSettingsLink() {
return (
<HeaderSearchLink to='/settings/dataset-permissions' activePaths={['/settings']}>
<Settings className='main-header__item__icon'/>
</HeaderSearchLink>
);
}
renderHeaderLinks() {
return (
<React.Fragment>
<HeaderSearchLink to='/search' activePaths={['/search']}>
<SearchIcon className='main-header__item__icon'/>
Search
</HeaderSearchLink>
<HeaderSearchLink to='/collections' activePaths={this.collectionsPaths}>
<DatabaseIcon className='main-header__item__icon'/>
Datasets
</HeaderSearchLink>
<HeaderSearchLink to='/workspaces' activePaths={['/workspaces']}>
<FolderIcon className='main-header__item__icon'/>
Workspaces
</HeaderSearchLink>
</React.Fragment>
);
}
renderLabel() {
if (this.props.config.readOnly) {
return <span className='main-header__label'>
Giant is in read only mode for maintenance, actions like uploads are disabled
</span>
} else if (this.props.config.label) {
return <span className='main-header__label'>
{this.props.config.label}
</span>
}
}
renderUser(loggedIn) {
if(!loggedIn) {
return false;
}
return <span className='main-header__item'>
{this.props.user.displayName}
</span>;
}
render() {
const loggedIn = this.props.user !== undefined;
return (
<header className='main-header'>
<nav className='main-header__links'>
<div className='main-header__links-section'>
<SearchLink to='/' className='main-header__title-link'>
<h1 className='main-header__title'>Giant<span className='highlight'>.</span></h1>
</SearchLink>
{loggedIn ? this.renderHeaderLinks() : false}
{this.renderLabel()}
</div>
<div className='main-header__links-section'>
{this.renderUser(loggedIn)}
{loggedIn ? this.renderSettingsLink() : false}
</div>
</nav>
</header>
);
}
}