This repository has been archived on 2022-08-14. You can view files and clone it, but cannot push or open issues or pull requests.
outline/frontend/components/Layout/Layout.js

106 lines
2.8 KiB
JavaScript
Raw Normal View History

2016-04-29 05:25:37 +00:00
import React from 'react';
2016-07-18 03:59:32 +00:00
import { browserHistory, Link } from 'react-router';
2016-06-06 06:57:58 +00:00
import Helmet from 'react-helmet';
import { observer } from 'mobx-react';
2016-07-18 03:59:32 +00:00
import keydown from 'react-keydown';
2016-07-23 20:12:56 +00:00
import _ from 'lodash';
2016-04-29 05:25:37 +00:00
2016-05-30 18:36:43 +00:00
import DropdownMenu, { MenuItem } from 'components/DropdownMenu';
2016-08-05 15:44:15 +00:00
import { Flex } from 'reflexbox';
2016-05-29 18:01:48 +00:00
import LoadingIndicator from 'components/LoadingIndicator';
2016-08-03 12:32:04 +00:00
import Alert from 'components/Alert';
2016-05-30 18:36:43 +00:00
import { Avatar } from 'rebass';
2016-04-30 18:46:32 +00:00
2016-04-29 05:25:37 +00:00
import styles from './Layout.scss';
2016-05-18 06:53:05 +00:00
import classNames from 'classnames/bind';
const cx = classNames.bind(styles);
2016-04-29 05:25:37 +00:00
@observer(['user'])
2016-04-29 05:25:37 +00:00
class Layout extends React.Component {
static propTypes = {
2016-08-03 12:32:04 +00:00
children: React.PropTypes.node,
2016-05-10 06:07:50 +00:00
actions: React.PropTypes.node,
2016-05-15 21:44:17 +00:00
title: React.PropTypes.node,
2016-06-06 06:57:58 +00:00
titleText: React.PropTypes.node,
2016-05-29 18:01:48 +00:00
loading: React.PropTypes.bool,
user: React.PropTypes.object.isRequired,
2016-07-18 03:59:32 +00:00
search: React.PropTypes.bool,
}
static defaultProps = {
search: true,
}
@keydown(['/', 't'])
search() {
2016-07-19 07:31:01 +00:00
// if (!this.props.search) return;
2016-07-23 20:12:56 +00:00
_.defer(() => browserHistory.push('/search'));
}
2016-07-19 07:31:01 +00:00
2016-07-23 20:12:56 +00:00
@keydown(['d'])
dashboard() {
// if (!this.props.search) return;
_.defer(() => browserHistory.push('/'));
2016-04-29 05:25:37 +00:00
}
render() {
const user = this.props.user;
2016-04-29 05:25:37 +00:00
return (
<div className={ styles.container }>
2016-06-06 06:57:58 +00:00
<Helmet
2016-08-03 12:32:04 +00:00
title={ this.props.titleText
2016-08-03 13:57:09 +00:00
? `${this.props.titleText} - Atlas`
: 'Atlas' }
2016-06-06 06:57:58 +00:00
/>
2016-05-29 18:01:48 +00:00
{ this.props.loading ? (
<LoadingIndicator />
) : null }
2016-08-03 12:32:04 +00:00
<div className={ cx(styles.header) }>
2016-06-06 07:05:21 +00:00
<div className={ styles.headerLeft }>
<Link to="/" className={ styles.team }>{ user.team.name }</Link>
2016-06-06 07:23:38 +00:00
<span className={ styles.title }>
2016-08-14 09:31:13 +00:00
{ this.props.title }
2016-06-06 07:23:38 +00:00
</span>
2016-05-07 18:52:08 +00:00
</div>
2016-08-05 15:44:15 +00:00
<Flex className={ styles.headerRight }>
2016-05-07 19:20:09 +00:00
<Flex align="center" className={ styles.actions }>
{ this.props.actions }
</Flex>
2016-07-18 03:59:32 +00:00
{ this.props.search && (
<Flex>
2016-07-18 04:55:59 +00:00
<div
onClick={ this.search }
className={ styles.search }
title="Search (/)"
>
2016-08-03 12:32:04 +00:00
<img src={ require('assets/icons/search.svg') } alt="Search" />
2016-07-18 03:59:32 +00:00
</div>
</Flex>
) }
2016-08-03 12:32:04 +00:00
<DropdownMenu
label={ <Avatar
2016-05-30 18:36:43 +00:00
circle
2016-08-03 12:32:04 +00:00
size={ 24 }
src={ user.user.avatarUrl }
2016-08-03 12:32:04 +00:00
/> }
>
<MenuItem onClick={ user.logout }>Logout</MenuItem>
2016-05-30 18:36:43 +00:00
</DropdownMenu>
2016-05-07 19:20:09 +00:00
</Flex>
2016-04-29 05:25:37 +00:00
</div>
2016-05-30 18:36:43 +00:00
<div
className={ cx(styles.content) }
>
2016-04-29 05:25:37 +00:00
{ this.props.children }
</div>
</div>
);
}
}
2016-07-18 03:59:32 +00:00
export default Layout;