2016-12-20 19:28:45 +01:00
|
|
|
import React, { Component, PropTypes } from 'react';
|
2016-12-04 11:56:41 +01:00
|
|
|
import { Layout, Drawer, Header, Navigation, Content,
|
|
|
|
Footer, FooterSection, FooterDropDownSection, FooterLinkList,
|
2016-12-10 14:06:42 +01:00
|
|
|
Grid, Cell, Icon,
|
2016-12-04 11:56:41 +01:00
|
|
|
} from 'react-mdl';
|
2016-12-05 17:04:00 +01:00
|
|
|
import { Link } from 'react-router';
|
2017-01-20 12:57:05 +01:00
|
|
|
import styles from './styles.scss';
|
|
|
|
import { styles as commonStyles } from './common';
|
2016-11-10 14:26:24 +01:00
|
|
|
import ErrorContainer from './error/error-container';
|
|
|
|
|
2016-11-24 21:32:29 +01:00
|
|
|
import UserContainer from './user/user-container';
|
2016-11-25 15:37:06 +01:00
|
|
|
import ShowUserContainer from './user/show-user-container';
|
2016-12-29 11:55:25 +01:00
|
|
|
import { ScrollContainer } from 'react-router-scroll';
|
2016-11-24 21:32:29 +01:00
|
|
|
|
2016-12-05 17:04:00 +01:00
|
|
|
const base = {
|
|
|
|
name: 'Unleash',
|
|
|
|
link: '/',
|
|
|
|
};
|
|
|
|
|
|
|
|
function replace (input, params) {
|
|
|
|
if (!params) {
|
|
|
|
return input;
|
|
|
|
}
|
|
|
|
Object.keys(params).forEach(key => {
|
|
|
|
input = input.replace(`:${key}`, params[key]);
|
|
|
|
});
|
|
|
|
return input;
|
|
|
|
}
|
|
|
|
|
2016-11-10 14:26:24 +01:00
|
|
|
export default class App extends Component {
|
2016-12-20 19:28:45 +01:00
|
|
|
static propTypes () {
|
|
|
|
return {
|
|
|
|
location: PropTypes.object.isRequired,
|
|
|
|
params: PropTypes.object.isRequired,
|
|
|
|
routes: PropTypes.array.isRequired,
|
|
|
|
};
|
|
|
|
}
|
2016-11-10 14:26:24 +01:00
|
|
|
|
2016-12-04 11:56:41 +01:00
|
|
|
static contextTypes = {
|
|
|
|
router: React.PropTypes.object,
|
|
|
|
}
|
2016-11-10 14:26:24 +01:00
|
|
|
|
2016-12-05 17:10:32 +01:00
|
|
|
componentWillReceiveProps (nextProps) {
|
|
|
|
if (this.props.location.pathname !== nextProps.location.pathname) {
|
2016-12-11 19:30:56 +01:00
|
|
|
clearTimeout(this.timer);
|
|
|
|
this.timer = setTimeout(() => {
|
|
|
|
const layout = document.querySelector('.mdl-js-layout');
|
|
|
|
const drawer = document.querySelector('.mdl-layout__drawer');
|
|
|
|
// hack, might get a built in alternative later
|
|
|
|
if (drawer.classList.contains('is-visible')) {
|
|
|
|
layout.MaterialLayout.toggleDrawer();
|
|
|
|
}
|
|
|
|
}, 10);
|
2016-12-05 17:10:32 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-05 17:15:55 +01:00
|
|
|
getSections () {
|
2016-12-22 10:43:13 +01:00
|
|
|
if (window.innerWidth < 768) {
|
|
|
|
return [base];
|
|
|
|
}
|
2016-12-05 17:04:00 +01:00
|
|
|
const { routes, params } = this.props;
|
|
|
|
const unique = {};
|
|
|
|
let result = [base].concat(routes.splice(1).map((routeEntry) => ({
|
|
|
|
name: replace(routeEntry.pageTitle, params),
|
|
|
|
link: replace(routeEntry.link || routeEntry.path, params),
|
|
|
|
}))).filter(entry => {
|
|
|
|
if (!unique[entry.link]) {
|
|
|
|
unique[entry.link] = true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
2016-12-05 17:15:55 +01:00
|
|
|
// mutate document.title:
|
|
|
|
document.title = result
|
|
|
|
.map(e => e.name)
|
2016-12-05 17:16:51 +01:00
|
|
|
.reverse()
|
2016-12-05 17:15:55 +01:00
|
|
|
.join(' - ');
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
getTitleWithLinks () {
|
|
|
|
const result = this.getSections();
|
2016-12-05 17:04:00 +01:00
|
|
|
return (
|
|
|
|
<span>
|
|
|
|
{result.map((entry, index) => (
|
2016-12-09 14:00:37 +01:00
|
|
|
<span key={entry.link + index}><Link style={{ color: '#f1f1f1', textDecoration: 'none' }} to={entry.link}>
|
2016-12-05 17:04:00 +01:00
|
|
|
{entry.name}
|
|
|
|
</Link> {(index + 1) < result.length ? ' / ' : null}</span>
|
|
|
|
))}
|
|
|
|
</span>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2016-11-10 14:26:24 +01:00
|
|
|
render () {
|
2016-12-29 14:01:03 +01:00
|
|
|
const shouldUpdateScroll = (prevRouterProps, { location }) => {
|
|
|
|
if (prevRouterProps && location.pathname !== prevRouterProps.location.pathname) {
|
|
|
|
return location.action === 'POP';
|
|
|
|
} else {
|
|
|
|
return [0, 0];
|
|
|
|
}
|
|
|
|
};
|
2017-01-20 12:57:05 +01:00
|
|
|
const createListItem = (path, caption, icon, isDrawerNavigation = false) => {
|
|
|
|
const linkColor = isDrawerNavigation &&
|
|
|
|
this.context.router.isActive(path) ? 'mdl-color-text--black' : 'mdl-color-text--grey-900';
|
|
|
|
const iconColor = isDrawerNavigation &&
|
|
|
|
this.context.router.isActive(path) ? 'mdl-color-text--black' : 'mdl-color-text--grey-600';
|
|
|
|
return (
|
|
|
|
<Link
|
|
|
|
to={path}
|
|
|
|
className={isDrawerNavigation && [styles.navigationLink, linkColor].join(' ')}>
|
|
|
|
{icon && <Icon name={icon} className={isDrawerNavigation && [styles.navigationIcon, iconColor].join(' ')}/>}{caption}
|
|
|
|
</Link>
|
|
|
|
);
|
|
|
|
};
|
2016-12-04 11:56:41 +01:00
|
|
|
|
|
|
|
return (
|
2017-01-20 12:57:05 +01:00
|
|
|
<div>
|
2016-12-04 11:56:41 +01:00
|
|
|
<UserContainer />
|
|
|
|
<Layout fixedHeader>
|
2016-12-05 17:04:00 +01:00
|
|
|
<Header title={this.getTitleWithLinks()}>
|
2016-12-04 11:56:41 +01:00
|
|
|
<Navigation>
|
|
|
|
<ShowUserContainer />
|
|
|
|
</Navigation>
|
|
|
|
</Header>
|
2017-01-20 12:57:05 +01:00
|
|
|
<Drawer className="mdl-color--white">
|
|
|
|
<span className={[styles.title, 'mdl-layout-title'].join(' ')}>Unleash</span>
|
|
|
|
<hr className={commonStyles.divider}/>
|
|
|
|
<Navigation className={styles.navigation}>
|
|
|
|
{createListItem('/features', 'Feature toggles', 'list', true)}
|
|
|
|
{createListItem('/strategies', 'Strategies', 'extension', true)}
|
|
|
|
{createListItem('/history', 'Event history', 'history', true)}
|
|
|
|
{createListItem('/archive', 'Archived toggles', 'archive', true)}
|
|
|
|
{createListItem('/applications', 'Applications', 'apps', true)}
|
|
|
|
</Navigation>
|
|
|
|
<hr className={commonStyles.divider}/>
|
|
|
|
<Navigation className={styles.navigation}>
|
|
|
|
<a href="https://github.com/Unleash" target="_blank" className={[styles.navigationLink, 'mdl-color-text--grey-900'].join(' ')}>
|
|
|
|
<i className={[
|
|
|
|
'material-icons',
|
|
|
|
styles.navigationIcon,
|
|
|
|
styles.githubIcon,
|
|
|
|
'mdl-color-text--grey-600',
|
|
|
|
].join(' ')}/>GitHub
|
|
|
|
</a>
|
2016-12-04 11:56:41 +01:00
|
|
|
</Navigation>
|
|
|
|
</Drawer>
|
2016-12-29 14:01:03 +01:00
|
|
|
<ScrollContainer scrollKey="container" shouldUpdateScroll={shouldUpdateScroll}>
|
2016-12-04 11:56:41 +01:00
|
|
|
<Content>
|
2016-12-05 19:29:07 +01:00
|
|
|
<Grid shadow={1} style={{ maxWidth: '1200px', margin: '0 auto' }}>
|
2016-12-04 11:56:41 +01:00
|
|
|
<Cell col={12}>
|
|
|
|
{this.props.children}
|
|
|
|
<ErrorContainer />
|
|
|
|
</Cell>
|
|
|
|
</Grid>
|
|
|
|
<Footer size="mega">
|
|
|
|
<FooterSection type="middle">
|
|
|
|
<FooterDropDownSection title="Menu">
|
|
|
|
<FooterLinkList>
|
|
|
|
{createListItem('/features', 'Feature toggles')}
|
|
|
|
{createListItem('/strategies', 'Strategies')}
|
|
|
|
{createListItem('/history', 'Event history')}
|
|
|
|
{createListItem('/archive', 'Archived toggles')}
|
|
|
|
</FooterLinkList>
|
|
|
|
</FooterDropDownSection>
|
|
|
|
<FooterDropDownSection title="Metrics">
|
|
|
|
<FooterLinkList>
|
2016-12-05 15:15:01 +01:00
|
|
|
{createListItem('/applications', 'Applications')}
|
2016-12-04 11:56:41 +01:00
|
|
|
</FooterLinkList>
|
|
|
|
</FooterDropDownSection>
|
|
|
|
<FooterDropDownSection title="Clients">
|
|
|
|
<FooterLinkList>
|
2017-01-09 17:42:25 +01:00
|
|
|
<a href="https://github.com/Unleash/unleash-client-node/">Node.js</a>
|
|
|
|
<a href="https://github.com/Unleash/unleash-client-java/">Java</a>
|
|
|
|
<a href="https://github.com/Unleash/unleash-client-go/">Go</a>
|
2016-12-04 11:56:41 +01:00
|
|
|
</FooterLinkList>
|
|
|
|
</FooterDropDownSection>
|
|
|
|
</FooterSection>
|
|
|
|
<FooterSection type="bottom" logo="Unleash Admin">
|
|
|
|
<FooterLinkList>
|
|
|
|
<a href="https://github.com/Unleash/unleash/" target="_blank">
|
|
|
|
GitHub
|
|
|
|
</a>
|
|
|
|
<a href="https://finn.no" target="_blank"><small>A product by</small> FINN.no</a>
|
|
|
|
</FooterLinkList>
|
|
|
|
</FooterSection>
|
|
|
|
</Footer>
|
|
|
|
</Content>
|
2016-12-29 11:55:25 +01:00
|
|
|
</ScrollContainer>
|
2016-12-04 11:56:41 +01:00
|
|
|
</Layout>
|
|
|
|
</div>
|
|
|
|
);
|
2016-11-10 14:26:24 +01:00
|
|
|
}
|
|
|
|
};
|