2016-12-20 19:28:45 +01:00
|
|
|
|
import React, { Component, PropTypes } from 'react';
|
2017-08-28 19:15:47 +02:00
|
|
|
|
import {
|
|
|
|
|
Layout,
|
|
|
|
|
Drawer,
|
|
|
|
|
Header,
|
|
|
|
|
Navigation,
|
|
|
|
|
Content,
|
|
|
|
|
Footer,
|
|
|
|
|
FooterSection,
|
|
|
|
|
FooterDropDownSection,
|
|
|
|
|
FooterLinkList,
|
|
|
|
|
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';
|
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
|
|
|
|
|
2017-08-28 19:15:47 +02:00
|
|
|
|
function replace(input, params) {
|
2016-12-05 17:04:00 +01:00
|
|
|
|
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 {
|
2017-07-10 23:38:44 +02:00
|
|
|
|
static propTypes = {
|
|
|
|
|
location: PropTypes.object.isRequired,
|
|
|
|
|
params: PropTypes.object.isRequired,
|
|
|
|
|
routes: PropTypes.array.isRequired,
|
2017-08-28 19:15:47 +02:00
|
|
|
|
};
|
2016-11-10 14:26:24 +01:00
|
|
|
|
|
2016-12-04 11:56:41 +01:00
|
|
|
|
static contextTypes = {
|
|
|
|
|
router: React.PropTypes.object,
|
2017-08-28 19:15:47 +02:00
|
|
|
|
};
|
2016-11-10 14:26:24 +01:00
|
|
|
|
|
2017-08-28 19:15:47 +02:00
|
|
|
|
componentWillReceiveProps(nextProps) {
|
2016-12-05 17:10:32 +01:00
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-28 19:15:47 +02:00
|
|
|
|
getSections() {
|
2016-12-05 17:04:00 +01:00
|
|
|
|
const { routes, params } = this.props;
|
|
|
|
|
const unique = {};
|
2017-08-28 19:15:47 +02:00
|
|
|
|
const result = routes
|
|
|
|
|
.splice(1)
|
|
|
|
|
.map(routeEntry => ({
|
2017-01-20 14:09:44 +01:00
|
|
|
|
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:04:00 +01:00
|
|
|
|
|
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()
|
2017-01-20 14:09:44 +01:00
|
|
|
|
.concat('Unleash')
|
|
|
|
|
.join(' – ');
|
2016-12-05 17:15:55 +01:00
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-28 19:15:47 +02:00
|
|
|
|
getTitleWithLinks() {
|
2016-12-05 17:15:55 +01:00
|
|
|
|
const result = this.getSections();
|
2016-12-05 17:04:00 +01:00
|
|
|
|
return (
|
|
|
|
|
<span>
|
|
|
|
|
{result.map((entry, index) => (
|
2017-08-28 19:15:47 +02:00
|
|
|
|
<span
|
|
|
|
|
key={entry.link + index}
|
|
|
|
|
className={
|
|
|
|
|
index > 0 ? 'mdl-layout--large-screen-only' : ''
|
|
|
|
|
}
|
|
|
|
|
>
|
2017-01-20 14:09:44 +01:00
|
|
|
|
{index > 0 ? ' › ' : null}
|
2017-08-28 19:15:47 +02:00
|
|
|
|
<Link
|
|
|
|
|
className={[
|
|
|
|
|
styles.headerTitleLink,
|
|
|
|
|
'mdl-color-text--primary-contrast',
|
|
|
|
|
].join(' ')}
|
|
|
|
|
to={entry.link}
|
|
|
|
|
>
|
2017-01-20 14:09:44 +01:00
|
|
|
|
{entry.name}
|
|
|
|
|
</Link>
|
|
|
|
|
</span>
|
2016-12-05 17:04:00 +01:00
|
|
|
|
))}
|
|
|
|
|
</span>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-28 19:15:47 +02:00
|
|
|
|
render() {
|
2016-12-29 14:01:03 +01:00
|
|
|
|
const shouldUpdateScroll = (prevRouterProps, { location }) => {
|
2017-08-28 19:15:47 +02:00
|
|
|
|
if (
|
|
|
|
|
prevRouterProps &&
|
|
|
|
|
location.pathname !== prevRouterProps.location.pathname
|
|
|
|
|
) {
|
2016-12-29 14:01:03 +01:00
|
|
|
|
return location.action === 'POP';
|
|
|
|
|
} else {
|
|
|
|
|
return [0, 0];
|
|
|
|
|
}
|
|
|
|
|
};
|
2017-08-28 19:15:47 +02: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';
|
2017-01-20 12:57:05 +01:00
|
|
|
|
return (
|
|
|
|
|
<Link
|
|
|
|
|
to={path}
|
2017-08-28 19:15:47 +02:00
|
|
|
|
className={
|
|
|
|
|
isDrawerNavigation &&
|
|
|
|
|
[styles.navigationLink, linkColor].join(' ')
|
|
|
|
|
}
|
|
|
|
|
>
|
|
|
|
|
{icon && (
|
|
|
|
|
<Icon
|
|
|
|
|
name={icon}
|
|
|
|
|
className={
|
|
|
|
|
isDrawerNavigation &&
|
|
|
|
|
[styles.navigationIcon, iconColor].join(' ')
|
|
|
|
|
}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
{caption}
|
2017-01-20 12:57:05 +01:00
|
|
|
|
</Link>
|
|
|
|
|
);
|
|
|
|
|
};
|
2016-12-04 11:56:41 +01:00
|
|
|
|
|
|
|
|
|
return (
|
2017-03-01 21:53:25 +01:00
|
|
|
|
<div className={styles.container}>
|
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">
|
2017-08-28 19:15:47 +02:00
|
|
|
|
<span
|
|
|
|
|
className={[
|
|
|
|
|
styles.drawerTitle,
|
|
|
|
|
'mdl-layout-title',
|
|
|
|
|
].join(' ')}
|
|
|
|
|
>
|
|
|
|
|
<img
|
|
|
|
|
src="public/logo.png"
|
|
|
|
|
width="32"
|
|
|
|
|
height="32"
|
|
|
|
|
className={styles.drawerTitleLogo}
|
|
|
|
|
/>
|
|
|
|
|
<span className={styles.drawerTitleText}>
|
|
|
|
|
Unleash
|
|
|
|
|
</span>
|
2017-03-07 11:39:10 +01:00
|
|
|
|
</span>
|
2017-08-28 19:15:47 +02:00
|
|
|
|
<hr />
|
2017-01-20 12:57:05 +01:00
|
|
|
|
<Navigation className={styles.navigation}>
|
2017-08-28 19:15:47 +02:00
|
|
|
|
{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
|
|
|
|
|
)}
|
2017-01-20 12:57:05 +01:00
|
|
|
|
</Navigation>
|
2017-08-28 19:15:47 +02:00
|
|
|
|
<hr />
|
2017-01-20 12:57:05 +01:00
|
|
|
|
<Navigation className={styles.navigation}>
|
2017-08-28 19:15:47 +02:00
|
|
|
|
<a
|
|
|
|
|
href="https://github.com/Unleash"
|
|
|
|
|
target="_blank"
|
|
|
|
|
className={[
|
|
|
|
|
styles.navigationLink,
|
|
|
|
|
'mdl-color-text--grey-900',
|
|
|
|
|
].join(' ')}
|
|
|
|
|
>
|
|
|
|
|
<i
|
|
|
|
|
className={[
|
|
|
|
|
'material-icons',
|
|
|
|
|
styles.navigationIcon,
|
|
|
|
|
styles.iconGitHub,
|
|
|
|
|
].join(' ')}
|
|
|
|
|
/>GitHub
|
2017-01-20 12:57:05 +01:00
|
|
|
|
</a>
|
2016-12-04 11:56:41 +01:00
|
|
|
|
</Navigation>
|
|
|
|
|
</Drawer>
|
2017-08-28 19:15:47 +02:00
|
|
|
|
<ScrollContainer
|
|
|
|
|
scrollKey="container"
|
|
|
|
|
shouldUpdateScroll={shouldUpdateScroll}
|
|
|
|
|
>
|
2017-06-29 08:36:10 +02:00
|
|
|
|
<Content className="mdl-color--grey-50">
|
|
|
|
|
<Grid noSpacing className={styles.content}>
|
|
|
|
|
<Cell col={12}>
|
|
|
|
|
{this.props.children}
|
|
|
|
|
<ErrorContainer />
|
|
|
|
|
</Cell>
|
|
|
|
|
</Grid>
|
|
|
|
|
<Footer size="mega">
|
|
|
|
|
<FooterSection type="middle">
|
|
|
|
|
<FooterDropDownSection title="Menu">
|
|
|
|
|
<FooterLinkList>
|
2017-08-28 19:15:47 +02:00
|
|
|
|
{createListItem(
|
|
|
|
|
'/features',
|
|
|
|
|
'Feature Toggles'
|
|
|
|
|
)}
|
|
|
|
|
{createListItem(
|
|
|
|
|
'/strategies',
|
|
|
|
|
'Strategies'
|
|
|
|
|
)}
|
|
|
|
|
{createListItem(
|
|
|
|
|
'/history',
|
|
|
|
|
'Event History'
|
|
|
|
|
)}
|
|
|
|
|
{createListItem(
|
|
|
|
|
'/archive',
|
|
|
|
|
'Archived Toggles'
|
|
|
|
|
)}
|
|
|
|
|
{createListItem(
|
|
|
|
|
'/applications',
|
|
|
|
|
'Applications'
|
|
|
|
|
)}
|
2017-06-29 08:36:10 +02:00
|
|
|
|
</FooterLinkList>
|
|
|
|
|
</FooterDropDownSection>
|
|
|
|
|
<FooterDropDownSection title="Clients">
|
|
|
|
|
<FooterLinkList>
|
2017-08-28 19:15:47 +02: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>
|
2017-06-29 08:36:10 +02:00
|
|
|
|
</FooterLinkList>
|
|
|
|
|
</FooterDropDownSection>
|
|
|
|
|
</FooterSection>
|
|
|
|
|
<FooterSection type="bottom" logo="Unleash">
|
2016-12-04 11:56:41 +01:00
|
|
|
|
<FooterLinkList>
|
2017-08-28 19:15:47 +02:00
|
|
|
|
<a
|
|
|
|
|
href="https://github.com/Unleash/unleash/"
|
|
|
|
|
target="_blank"
|
|
|
|
|
>
|
2016-12-04 11:56:41 +01:00
|
|
|
|
GitHub
|
2017-06-29 08:36:10 +02:00
|
|
|
|
</a>
|
2017-08-28 19:15:47 +02:00
|
|
|
|
<a
|
|
|
|
|
href="https://finn.no"
|
|
|
|
|
target="_blank"
|
|
|
|
|
>
|
|
|
|
|
<small>A product by</small> FINN.no
|
|
|
|
|
</a>
|
2017-06-29 08:36:10 +02:00
|
|
|
|
</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
|
|
|
|
}
|
2017-08-28 19:15:47 +02:00
|
|
|
|
}
|