mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	feat: Customisable UI via config
This feature enables overrides of certain UI elements from the API such as setting a different background color for the header. This will make it easier to customise the UI in different environemnt.
This commit is contained in:
		
							parent
							
								
									4acc854a65
								
							
						
					
					
						commit
						c4900262f2
					
				@ -6,7 +6,7 @@
 | 
				
			|||||||
    <meta name="viewport" content="width=device-width, initial-scale=1">
 | 
					    <meta name="viewport" content="width=device-width, initial-scale=1">
 | 
				
			||||||
    <meta name="description" content="unleash">
 | 
					    <meta name="description" content="unleash">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <title>Unleash UI</title>
 | 
					    <title>Unleash - Enterprise ready feature toggles</title>
 | 
				
			||||||
    <link rel="stylesheet" href="public/bundle.css">
 | 
					    <link rel="stylesheet" href="public/bundle.css">
 | 
				
			||||||
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
 | 
					    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
 | 
				
			||||||
    <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700" rel="stylesheet">
 | 
					    <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700" rel="stylesheet">
 | 
				
			||||||
 | 
				
			|||||||
@ -5,23 +5,13 @@ exports[`renders correctly with details 1`] = `
 | 
				
			|||||||
  logo="Unleash 1.1.0"
 | 
					  logo="Unleash 1.1.0"
 | 
				
			||||||
  type="bottom"
 | 
					  type="bottom"
 | 
				
			||||||
>
 | 
					>
 | 
				
			||||||
  <react-mdl-FooterLinkList>
 | 
					 | 
				
			||||||
    <a
 | 
					 | 
				
			||||||
      href="https://github.com/Unleash/unleash/"
 | 
					 | 
				
			||||||
      target="_blank"
 | 
					 | 
				
			||||||
    >
 | 
					 | 
				
			||||||
      GitHub
 | 
					 | 
				
			||||||
    </a>
 | 
					 | 
				
			||||||
    <a
 | 
					 | 
				
			||||||
      href="https://www.finn.no"
 | 
					 | 
				
			||||||
      target="_blank"
 | 
					 | 
				
			||||||
    >
 | 
					 | 
				
			||||||
  <small>
 | 
					  <small>
 | 
				
			||||||
        A product by
 | 
					    (test)
 | 
				
			||||||
 | 
					  </small>
 | 
				
			||||||
 | 
					  <br />
 | 
				
			||||||
 | 
					  <small>
 | 
				
			||||||
 | 
					    We are the best!
 | 
				
			||||||
  </small>
 | 
					  </small>
 | 
				
			||||||
       FINN.no
 | 
					 | 
				
			||||||
    </a>
 | 
					 | 
				
			||||||
  </react-mdl-FooterLinkList>
 | 
					 | 
				
			||||||
</react-mdl-FooterSection>
 | 
					</react-mdl-FooterSection>
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -30,22 +20,25 @@ exports[`renders correctly with empty api details 1`] = `
 | 
				
			|||||||
  logo="Unleash "
 | 
					  logo="Unleash "
 | 
				
			||||||
  type="bottom"
 | 
					  type="bottom"
 | 
				
			||||||
>
 | 
					>
 | 
				
			||||||
  <react-mdl-FooterLinkList>
 | 
					 | 
				
			||||||
    <a
 | 
					 | 
				
			||||||
      href="https://github.com/Unleash/unleash/"
 | 
					 | 
				
			||||||
      target="_blank"
 | 
					 | 
				
			||||||
    >
 | 
					 | 
				
			||||||
      GitHub
 | 
					 | 
				
			||||||
    </a>
 | 
					 | 
				
			||||||
    <a
 | 
					 | 
				
			||||||
      href="https://www.finn.no"
 | 
					 | 
				
			||||||
      target="_blank"
 | 
					 | 
				
			||||||
    >
 | 
					 | 
				
			||||||
  <small>
 | 
					  <small>
 | 
				
			||||||
        A product by
 | 
					    (test)
 | 
				
			||||||
 | 
					  </small>
 | 
				
			||||||
 | 
					  <br />
 | 
				
			||||||
 | 
					  <small>
 | 
				
			||||||
 | 
					    We are the best!
 | 
				
			||||||
  </small>
 | 
					  </small>
 | 
				
			||||||
       FINN.no
 | 
					</react-mdl-FooterSection>
 | 
				
			||||||
    </a>
 | 
					`;
 | 
				
			||||||
  </react-mdl-FooterLinkList>
 | 
					
 | 
				
			||||||
 | 
					exports[`renders correctly without uiConfig 1`] = `
 | 
				
			||||||
 | 
					<react-mdl-FooterSection
 | 
				
			||||||
 | 
					  logo="Unleash 1.1.0"
 | 
				
			||||||
 | 
					  type="bottom"
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
					  <small>
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					  </small>
 | 
				
			||||||
 | 
					  <br />
 | 
				
			||||||
 | 
					  <small />
 | 
				
			||||||
</react-mdl-FooterSection>
 | 
					</react-mdl-FooterSection>
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
 | 
				
			|||||||
@ -5,14 +5,28 @@ import renderer from 'react-test-renderer';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
jest.mock('react-mdl');
 | 
					jest.mock('react-mdl');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const uiConfig = {
 | 
				
			||||||
 | 
					    slogan: 'We are the best!',
 | 
				
			||||||
 | 
					    environment: 'test',
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test('renders correctly with empty api details', () => {
 | 
					test('renders correctly with empty api details', () => {
 | 
				
			||||||
    const tree = renderer.create(<ShowApiDetailsComponent fetchAll={jest.fn()} apiDetails={{}} />).toJSON();
 | 
					    const tree = renderer
 | 
				
			||||||
 | 
					        .create(<ShowApiDetailsComponent fetchAll={jest.fn()} apiDetails={{}} uiConfig={uiConfig} />)
 | 
				
			||||||
 | 
					        .toJSON();
 | 
				
			||||||
    expect(tree).toMatchSnapshot();
 | 
					    expect(tree).toMatchSnapshot();
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test('renders correctly with details', () => {
 | 
					test('renders correctly with details', () => {
 | 
				
			||||||
    const tree = renderer
 | 
					    const tree = renderer
 | 
				
			||||||
        .create(<ShowApiDetailsComponent fetchAll={jest.fn()} apiDetails={{ version: '1.1.0' }} />)
 | 
					        .create(<ShowApiDetailsComponent fetchAll={jest.fn()} apiDetails={{ version: '1.1.0' }} uiConfig={uiConfig} />)
 | 
				
			||||||
 | 
					        .toJSON();
 | 
				
			||||||
 | 
					    expect(tree).toMatchSnapshot();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test('renders correctly without uiConfig', () => {
 | 
				
			||||||
 | 
					    const tree = renderer
 | 
				
			||||||
 | 
					        .create(<ShowApiDetailsComponent fetchAll={jest.fn()} apiDetails={{ version: '1.1.0' }} uiConfig={{}} />)
 | 
				
			||||||
        .toJSON();
 | 
					        .toJSON();
 | 
				
			||||||
    expect(tree).toMatchSnapshot();
 | 
					    expect(tree).toMatchSnapshot();
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,11 @@
 | 
				
			|||||||
import React, { Component } from 'react';
 | 
					import React, { Component } from 'react';
 | 
				
			||||||
import PropTypes from 'prop-types';
 | 
					import PropTypes from 'prop-types';
 | 
				
			||||||
import { FooterSection, FooterLinkList } from 'react-mdl';
 | 
					import { FooterSection } from 'react-mdl';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ShowApiDetailsComponent extends Component {
 | 
					class ShowApiDetailsComponent extends Component {
 | 
				
			||||||
    static propTypes = {
 | 
					    static propTypes = {
 | 
				
			||||||
        apiDetails: PropTypes.object.isRequired,
 | 
					        apiDetails: PropTypes.object.isRequired,
 | 
				
			||||||
 | 
					        uiConfig: PropTypes.object.isRequired,
 | 
				
			||||||
        fetchAll: PropTypes.func.isRequired,
 | 
					        fetchAll: PropTypes.func.isRequired,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -14,16 +15,13 @@ class ShowApiDetailsComponent extends Component {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    render() {
 | 
					    render() {
 | 
				
			||||||
        const version = this.props.apiDetails.version || '';
 | 
					        const version = this.props.apiDetails.version || '';
 | 
				
			||||||
 | 
					        const { slogan, environment } = this.props.uiConfig;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return (
 | 
					        return (
 | 
				
			||||||
            <FooterSection type="bottom" logo={`Unleash ${version}`}>
 | 
					            <FooterSection type="bottom" logo={`Unleash ${version}`}>
 | 
				
			||||||
                <FooterLinkList>
 | 
					                <small>{environment ? `(${environment})` : ''}</small>
 | 
				
			||||||
                    <a href="https://github.com/Unleash/unleash/" target="_blank">
 | 
					                <br />
 | 
				
			||||||
                        GitHub
 | 
					                <small>{slogan}</small>
 | 
				
			||||||
                    </a>
 | 
					 | 
				
			||||||
                    <a href="https://www.finn.no" target="_blank">
 | 
					 | 
				
			||||||
                        <small>A product by</small> FINN.no
 | 
					 | 
				
			||||||
                    </a>
 | 
					 | 
				
			||||||
                </FooterLinkList>
 | 
					 | 
				
			||||||
            </FooterSection>
 | 
					            </FooterSection>
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -8,6 +8,10 @@ const mapDispatchToProps = {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const mapStateToProps = state => ({
 | 
					const mapStateToProps = state => ({
 | 
				
			||||||
    apiDetails: state.api.toJS(),
 | 
					    apiDetails: state.api.toJS(),
 | 
				
			||||||
 | 
					    uiConfig: state.uiConfig.toJS(),
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default connect(mapStateToProps, mapDispatchToProps)(ShowApiDetailsComponent);
 | 
					export default connect(
 | 
				
			||||||
 | 
					    mapStateToProps,
 | 
				
			||||||
 | 
					    mapDispatchToProps
 | 
				
			||||||
 | 
					)(ShowApiDetailsComponent);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,50 +1,30 @@
 | 
				
			|||||||
import React, { Component } from 'react';
 | 
					import React, { PureComponent } from 'react';
 | 
				
			||||||
import PropTypes from 'prop-types';
 | 
					import PropTypes from 'prop-types';
 | 
				
			||||||
import { Layout, Header, Navigation, Content, Footer, Grid, Cell } from 'react-mdl';
 | 
					import { Layout, Content, Footer, Grid, Cell } from 'react-mdl';
 | 
				
			||||||
import { Route, Redirect, Switch } from 'react-router-dom';
 | 
					import { Route, Redirect, Switch } from 'react-router-dom';
 | 
				
			||||||
import styles from './styles.scss';
 | 
					import styles from './styles.scss';
 | 
				
			||||||
import ErrorContainer from './error/error-container';
 | 
					import ErrorContainer from './error/error-container';
 | 
				
			||||||
 | 
					import Header from './menu/header';
 | 
				
			||||||
import AuthenticationContainer from './user/authentication-container';
 | 
					import AuthenticationContainer from './user/authentication-container';
 | 
				
			||||||
import ShowUserContainer from './user/show-user-container';
 | 
					
 | 
				
			||||||
import ShowApiDetailsContainer from './api/show-api-details-container';
 | 
					import ShowApiDetailsContainer from './api/show-api-details-container';
 | 
				
			||||||
import Features from '../page/features';
 | 
					import Features from '../page/features';
 | 
				
			||||||
import { DrawerMenu } from './menu/drawer';
 | 
					
 | 
				
			||||||
import { FooterMenu } from './menu/footer';
 | 
					import { FooterMenu } from './menu/footer';
 | 
				
			||||||
import Breadcrum from './menu/breadcrumb';
 | 
					 | 
				
			||||||
import { routes } from './menu/routes';
 | 
					import { routes } from './menu/routes';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class App extends Component {
 | 
					export default class App extends PureComponent {
 | 
				
			||||||
    static propTypes = {
 | 
					    static propTypes = {
 | 
				
			||||||
        location: PropTypes.object.isRequired,
 | 
					        location: PropTypes.object.isRequired,
 | 
				
			||||||
        match: PropTypes.object.isRequired,
 | 
					        match: PropTypes.object.isRequired,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    componentWillReceiveProps(nextProps) {
 | 
					 | 
				
			||||||
        if (this.props.location.pathname !== nextProps.location.pathname) {
 | 
					 | 
				
			||||||
            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);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    render() {
 | 
					    render() {
 | 
				
			||||||
        return (
 | 
					        return (
 | 
				
			||||||
            <div className={styles.container}>
 | 
					            <div className={styles.container}>
 | 
				
			||||||
                <AuthenticationContainer />
 | 
					                <AuthenticationContainer />
 | 
				
			||||||
                <Layout fixedHeader>
 | 
					                <Layout fixedHeader>
 | 
				
			||||||
                    <Header title={<Route path="/:path" component={Breadcrum} />}>
 | 
					                    <Header location={this.props.location} />
 | 
				
			||||||
                        <Navigation>
 | 
					 | 
				
			||||||
                            <ShowUserContainer />
 | 
					 | 
				
			||||||
                        </Navigation>
 | 
					 | 
				
			||||||
                    </Header>
 | 
					 | 
				
			||||||
                    <DrawerMenu />
 | 
					 | 
				
			||||||
                    <Content className="mdl-color--grey-50">
 | 
					                    <Content className="mdl-color--grey-50">
 | 
				
			||||||
                        <Grid noSpacing className={styles.content}>
 | 
					                        <Grid noSpacing className={styles.content}>
 | 
				
			||||||
                            <Cell col={12}>
 | 
					                            <Cell col={12}>
 | 
				
			||||||
 | 
				
			|||||||
@ -9,6 +9,9 @@ const mapStateToProps = state => {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const HistoryListContainer = connect(mapStateToProps, { fetchHistory })(HistoryComponent);
 | 
					const HistoryListContainer = connect(
 | 
				
			||||||
 | 
					    mapStateToProps,
 | 
				
			||||||
 | 
					    { fetchHistory }
 | 
				
			||||||
 | 
					)(HistoryComponent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default HistoryListContainer;
 | 
					export default HistoryListContainer;
 | 
				
			||||||
 | 
				
			|||||||
@ -25,7 +25,7 @@ exports[`should render DrawerMenu 1`] = `
 | 
				
			|||||||
  >
 | 
					  >
 | 
				
			||||||
    <a
 | 
					    <a
 | 
				
			||||||
      aria-current={null}
 | 
					      aria-current={null}
 | 
				
			||||||
      className="navigationLink mdl-color-text--grey-600"
 | 
					      className="navigationLink mdl-color-text--grey-900"
 | 
				
			||||||
      href="/features"
 | 
					      href="/features"
 | 
				
			||||||
      onClick={[Function]}
 | 
					      onClick={[Function]}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
@ -38,7 +38,7 @@ exports[`should render DrawerMenu 1`] = `
 | 
				
			|||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
    <a
 | 
					    <a
 | 
				
			||||||
      aria-current={null}
 | 
					      aria-current={null}
 | 
				
			||||||
      className="navigationLink mdl-color-text--grey-600"
 | 
					      className="navigationLink mdl-color-text--grey-900"
 | 
				
			||||||
      href="/strategies"
 | 
					      href="/strategies"
 | 
				
			||||||
      onClick={[Function]}
 | 
					      onClick={[Function]}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
@ -51,7 +51,7 @@ exports[`should render DrawerMenu 1`] = `
 | 
				
			|||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
    <a
 | 
					    <a
 | 
				
			||||||
      aria-current={null}
 | 
					      aria-current={null}
 | 
				
			||||||
      className="navigationLink mdl-color-text--grey-600"
 | 
					      className="navigationLink mdl-color-text--grey-900"
 | 
				
			||||||
      href="/history"
 | 
					      href="/history"
 | 
				
			||||||
      onClick={[Function]}
 | 
					      onClick={[Function]}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
@ -64,7 +64,7 @@ exports[`should render DrawerMenu 1`] = `
 | 
				
			|||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
    <a
 | 
					    <a
 | 
				
			||||||
      aria-current={null}
 | 
					      aria-current={null}
 | 
				
			||||||
      className="navigationLink mdl-color-text--grey-600"
 | 
					      className="navigationLink mdl-color-text--grey-900"
 | 
				
			||||||
      href="/archive"
 | 
					      href="/archive"
 | 
				
			||||||
      onClick={[Function]}
 | 
					      onClick={[Function]}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
@ -77,7 +77,7 @@ exports[`should render DrawerMenu 1`] = `
 | 
				
			|||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
    <a
 | 
					    <a
 | 
				
			||||||
      aria-current={null}
 | 
					      aria-current={null}
 | 
				
			||||||
      className="navigationLink mdl-color-text--grey-600"
 | 
					      className="navigationLink mdl-color-text--grey-900"
 | 
				
			||||||
      href="/applications"
 | 
					      href="/applications"
 | 
				
			||||||
      onClick={[Function]}
 | 
					      onClick={[Function]}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
@ -90,7 +90,7 @@ exports[`should render DrawerMenu 1`] = `
 | 
				
			|||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
    <a
 | 
					    <a
 | 
				
			||||||
      aria-current={null}
 | 
					      aria-current={null}
 | 
				
			||||||
      className="navigationLink mdl-color-text--grey-600"
 | 
					      className="navigationLink mdl-color-text--grey-900"
 | 
				
			||||||
      href="/logout"
 | 
					      href="/logout"
 | 
				
			||||||
      onClick={[Function]}
 | 
					      onClick={[Function]}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
@ -107,7 +107,7 @@ exports[`should render DrawerMenu 1`] = `
 | 
				
			|||||||
    className="navigation"
 | 
					    className="navigation"
 | 
				
			||||||
  >
 | 
					  >
 | 
				
			||||||
    <a
 | 
					    <a
 | 
				
			||||||
      className="navigationLink mdl-color-text--grey-600"
 | 
					      className="navigationLink mdl-color-text--grey-900"
 | 
				
			||||||
      href="https://unleash.github.io"
 | 
					      href="https://unleash.github.io"
 | 
				
			||||||
      target="_blank"
 | 
					      target="_blank"
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
@ -118,7 +118,7 @@ exports[`should render DrawerMenu 1`] = `
 | 
				
			|||||||
       User documentation
 | 
					       User documentation
 | 
				
			||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
    <a
 | 
					    <a
 | 
				
			||||||
      className="navigationLink mdl-color-text--grey-600"
 | 
					      className="navigationLink mdl-color-text--grey-900"
 | 
				
			||||||
      href="https://github.com/Unleash"
 | 
					      href="https://github.com/Unleash"
 | 
				
			||||||
      target="_blank"
 | 
					      target="_blank"
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
@ -156,7 +156,7 @@ exports[`should render DrawerMenu with "features" selected 1`] = `
 | 
				
			|||||||
  >
 | 
					  >
 | 
				
			||||||
    <a
 | 
					    <a
 | 
				
			||||||
      aria-current="page"
 | 
					      aria-current="page"
 | 
				
			||||||
      className="navigationLink mdl-color-text--grey-600 navigationLink mdl-color-text--black mdl-color--light-blue-50"
 | 
					      className="navigationLink mdl-color-text--grey-900 navigationLink mdl-color-text--black mdl-color--blue-grey-100"
 | 
				
			||||||
      href="/features"
 | 
					      href="/features"
 | 
				
			||||||
      onClick={[Function]}
 | 
					      onClick={[Function]}
 | 
				
			||||||
      style={Object {}}
 | 
					      style={Object {}}
 | 
				
			||||||
@ -170,7 +170,7 @@ exports[`should render DrawerMenu with "features" selected 1`] = `
 | 
				
			|||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
    <a
 | 
					    <a
 | 
				
			||||||
      aria-current={null}
 | 
					      aria-current={null}
 | 
				
			||||||
      className="navigationLink mdl-color-text--grey-600"
 | 
					      className="navigationLink mdl-color-text--grey-900"
 | 
				
			||||||
      href="/strategies"
 | 
					      href="/strategies"
 | 
				
			||||||
      onClick={[Function]}
 | 
					      onClick={[Function]}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
@ -183,7 +183,7 @@ exports[`should render DrawerMenu with "features" selected 1`] = `
 | 
				
			|||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
    <a
 | 
					    <a
 | 
				
			||||||
      aria-current={null}
 | 
					      aria-current={null}
 | 
				
			||||||
      className="navigationLink mdl-color-text--grey-600"
 | 
					      className="navigationLink mdl-color-text--grey-900"
 | 
				
			||||||
      href="/history"
 | 
					      href="/history"
 | 
				
			||||||
      onClick={[Function]}
 | 
					      onClick={[Function]}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
@ -196,7 +196,7 @@ exports[`should render DrawerMenu with "features" selected 1`] = `
 | 
				
			|||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
    <a
 | 
					    <a
 | 
				
			||||||
      aria-current={null}
 | 
					      aria-current={null}
 | 
				
			||||||
      className="navigationLink mdl-color-text--grey-600"
 | 
					      className="navigationLink mdl-color-text--grey-900"
 | 
				
			||||||
      href="/archive"
 | 
					      href="/archive"
 | 
				
			||||||
      onClick={[Function]}
 | 
					      onClick={[Function]}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
@ -209,7 +209,7 @@ exports[`should render DrawerMenu with "features" selected 1`] = `
 | 
				
			|||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
    <a
 | 
					    <a
 | 
				
			||||||
      aria-current={null}
 | 
					      aria-current={null}
 | 
				
			||||||
      className="navigationLink mdl-color-text--grey-600"
 | 
					      className="navigationLink mdl-color-text--grey-900"
 | 
				
			||||||
      href="/applications"
 | 
					      href="/applications"
 | 
				
			||||||
      onClick={[Function]}
 | 
					      onClick={[Function]}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
@ -222,7 +222,7 @@ exports[`should render DrawerMenu with "features" selected 1`] = `
 | 
				
			|||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
    <a
 | 
					    <a
 | 
				
			||||||
      aria-current={null}
 | 
					      aria-current={null}
 | 
				
			||||||
      className="navigationLink mdl-color-text--grey-600"
 | 
					      className="navigationLink mdl-color-text--grey-900"
 | 
				
			||||||
      href="/logout"
 | 
					      href="/logout"
 | 
				
			||||||
      onClick={[Function]}
 | 
					      onClick={[Function]}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
@ -239,7 +239,7 @@ exports[`should render DrawerMenu with "features" selected 1`] = `
 | 
				
			|||||||
    className="navigation"
 | 
					    className="navigation"
 | 
				
			||||||
  >
 | 
					  >
 | 
				
			||||||
    <a
 | 
					    <a
 | 
				
			||||||
      className="navigationLink mdl-color-text--grey-600"
 | 
					      className="navigationLink mdl-color-text--grey-900"
 | 
				
			||||||
      href="https://unleash.github.io"
 | 
					      href="https://unleash.github.io"
 | 
				
			||||||
      target="_blank"
 | 
					      target="_blank"
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
@ -250,7 +250,7 @@ exports[`should render DrawerMenu with "features" selected 1`] = `
 | 
				
			|||||||
       User documentation
 | 
					       User documentation
 | 
				
			||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
    <a
 | 
					    <a
 | 
				
			||||||
      className="navigationLink mdl-color-text--grey-600"
 | 
					      className="navigationLink mdl-color-text--grey-900"
 | 
				
			||||||
      href="https://github.com/Unleash"
 | 
					      href="https://github.com/Unleash"
 | 
				
			||||||
      target="_blank"
 | 
					      target="_blank"
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
 | 
				
			|||||||
@ -50,6 +50,12 @@ exports[`should render DrawerMenu 1`] = `
 | 
				
			|||||||
      >
 | 
					      >
 | 
				
			||||||
        Sign out
 | 
					        Sign out
 | 
				
			||||||
      </a>
 | 
					      </a>
 | 
				
			||||||
 | 
					      <a
 | 
				
			||||||
 | 
					        href="https://github.com/Unleash/unleash/"
 | 
				
			||||||
 | 
					        target="_blank"
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        GitHub
 | 
				
			||||||
 | 
					      </a>
 | 
				
			||||||
    </react-mdl-FooterLinkList>
 | 
					    </react-mdl-FooterLinkList>
 | 
				
			||||||
  </react-mdl-FooterDropDownSection>
 | 
					  </react-mdl-FooterDropDownSection>
 | 
				
			||||||
  <react-mdl-FooterDropDownSection
 | 
					  <react-mdl-FooterDropDownSection
 | 
				
			||||||
@ -138,6 +144,12 @@ exports[`should render DrawerMenu with "features" selected 1`] = `
 | 
				
			|||||||
      >
 | 
					      >
 | 
				
			||||||
        Sign out
 | 
					        Sign out
 | 
				
			||||||
      </a>
 | 
					      </a>
 | 
				
			||||||
 | 
					      <a
 | 
				
			||||||
 | 
					        href="https://github.com/Unleash/unleash/"
 | 
				
			||||||
 | 
					        target="_blank"
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        GitHub
 | 
				
			||||||
 | 
					      </a>
 | 
				
			||||||
    </react-mdl-FooterLinkList>
 | 
					    </react-mdl-FooterLinkList>
 | 
				
			||||||
  </react-mdl-FooterDropDownSection>
 | 
					  </react-mdl-FooterDropDownSection>
 | 
				
			||||||
  <react-mdl-FooterDropDownSection
 | 
					  <react-mdl-FooterDropDownSection
 | 
				
			||||||
 | 
				
			|||||||
@ -17,8 +17,8 @@ export const DrawerMenu = () => (
 | 
				
			|||||||
                <NavLink
 | 
					                <NavLink
 | 
				
			||||||
                    key={item.path}
 | 
					                    key={item.path}
 | 
				
			||||||
                    to={item.path}
 | 
					                    to={item.path}
 | 
				
			||||||
                    className={[styles.navigationLink, 'mdl-color-text--grey-600'].join(' ')}
 | 
					                    className={[styles.navigationLink, 'mdl-color-text--grey-900'].join(' ')}
 | 
				
			||||||
                    activeClassName={[styles.navigationLink, 'mdl-color-text--black', 'mdl-color--light-blue-50'].join(
 | 
					                    activeClassName={[styles.navigationLink, 'mdl-color-text--black', 'mdl-color--blue-grey-100'].join(
 | 
				
			||||||
                        ' '
 | 
					                        ' '
 | 
				
			||||||
                    )}
 | 
					                    )}
 | 
				
			||||||
                >
 | 
					                >
 | 
				
			||||||
@ -31,16 +31,16 @@ export const DrawerMenu = () => (
 | 
				
			|||||||
            <a
 | 
					            <a
 | 
				
			||||||
                href="https://unleash.github.io"
 | 
					                href="https://unleash.github.io"
 | 
				
			||||||
                target="_blank"
 | 
					                target="_blank"
 | 
				
			||||||
                className={[styles.navigationLink, 'mdl-color-text--grey-600'].join(' ')}
 | 
					                className={[styles.navigationLink, 'mdl-color-text--grey-900'].join(' ')}
 | 
				
			||||||
            >
 | 
					            >
 | 
				
			||||||
                <Icon name="library_books" className={styles.navigationIcon} /> User documentation
 | 
					                <Icon name="library_books" className={styles.navigationIcon} /> User documentation
 | 
				
			||||||
            </a>
 | 
					            </a>
 | 
				
			||||||
            <a
 | 
					            <a
 | 
				
			||||||
                href="https://github.com/Unleash"
 | 
					                href="https://github.com/Unleash"
 | 
				
			||||||
                target="_blank"
 | 
					                target="_blank"
 | 
				
			||||||
                className={[styles.navigationLink, 'mdl-color-text--grey-600'].join(' ')}
 | 
					                className={[styles.navigationLink, 'mdl-color-text--grey-900'].join(' ')}
 | 
				
			||||||
            >
 | 
					            >
 | 
				
			||||||
                <i className={['material-icons', styles.navigationIcon, styles.iconGitHub].join(' ')} />GitHub
 | 
					                <i className={['material-icons', styles.navigationIcon, styles.iconGitHub].join(' ')} /> GitHub
 | 
				
			||||||
            </a>
 | 
					            </a>
 | 
				
			||||||
        </Navigation>
 | 
					        </Navigation>
 | 
				
			||||||
    </Drawer>
 | 
					    </Drawer>
 | 
				
			||||||
 | 
				
			|||||||
@ -13,6 +13,9 @@ export const FooterMenu = () => (
 | 
				
			|||||||
                        {item.title}
 | 
					                        {item.title}
 | 
				
			||||||
                    </NavLink>
 | 
					                    </NavLink>
 | 
				
			||||||
                ))}
 | 
					                ))}
 | 
				
			||||||
 | 
					                <a href="https://github.com/Unleash/unleash/" target="_blank">
 | 
				
			||||||
 | 
					                    GitHub
 | 
				
			||||||
 | 
					                </a>
 | 
				
			||||||
            </FooterLinkList>
 | 
					            </FooterLinkList>
 | 
				
			||||||
        </FooterDropDownSection>
 | 
					        </FooterDropDownSection>
 | 
				
			||||||
        <FooterDropDownSection title="Clients">
 | 
					        <FooterDropDownSection title="Clients">
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										55
									
								
								frontend/src/component/menu/header.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								frontend/src/component/menu/header.jsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,55 @@
 | 
				
			|||||||
 | 
					import React, { PureComponent } from 'react';
 | 
				
			||||||
 | 
					import PropTypes from 'prop-types';
 | 
				
			||||||
 | 
					import { connect } from 'react-redux';
 | 
				
			||||||
 | 
					import { Header, Navigation } from 'react-mdl';
 | 
				
			||||||
 | 
					import { Route } from 'react-router-dom';
 | 
				
			||||||
 | 
					import { DrawerMenu } from './drawer';
 | 
				
			||||||
 | 
					import Breadcrum from './breadcrumb';
 | 
				
			||||||
 | 
					import ShowUserContainer from '../user/show-user-container';
 | 
				
			||||||
 | 
					import { fetchUIConfig } from './../../store/ui-config/actions';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class HeaderComponent extends PureComponent {
 | 
				
			||||||
 | 
					    static propTypes = {
 | 
				
			||||||
 | 
					        uiConfig: PropTypes.object.isRequired,
 | 
				
			||||||
 | 
					        fetchUIConfig: PropTypes.func.isRequired,
 | 
				
			||||||
 | 
					        location: PropTypes.object.isRequired,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    componentDidMount() {
 | 
				
			||||||
 | 
					        this.props.fetchUIConfig();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    componentWillReceiveProps(nextProps) {
 | 
				
			||||||
 | 
					        if (this.props.location.pathname !== nextProps.location.pathname) {
 | 
				
			||||||
 | 
					            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);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    render() {
 | 
				
			||||||
 | 
					        const { headerBackground } = this.props.uiConfig;
 | 
				
			||||||
 | 
					        const style = headerBackground ? { background: headerBackground } : {};
 | 
				
			||||||
 | 
					        return (
 | 
				
			||||||
 | 
					            <React.Fragment>
 | 
				
			||||||
 | 
					                <Header title={<Route path="/:path" component={Breadcrum} />} style={style}>
 | 
				
			||||||
 | 
					                    <Navigation>
 | 
				
			||||||
 | 
					                        <ShowUserContainer />
 | 
				
			||||||
 | 
					                    </Navigation>
 | 
				
			||||||
 | 
					                </Header>
 | 
				
			||||||
 | 
					                <DrawerMenu />
 | 
				
			||||||
 | 
					            </React.Fragment>
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default connect(
 | 
				
			||||||
 | 
					    state => ({ uiConfig: state.uiConfig.toJS() }),
 | 
				
			||||||
 | 
					    { fetchUIConfig }
 | 
				
			||||||
 | 
					)(HeaderComponent);
 | 
				
			||||||
@ -13,4 +13,7 @@ const mapStateToProps = state => ({
 | 
				
			|||||||
    location: state.settings ? state.settings.toJS().location : {},
 | 
					    location: state.settings ? state.settings.toJS().location : {},
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default connect(mapStateToProps, mapDispatchToProps)(ShowUserComponent);
 | 
					export default connect(
 | 
				
			||||||
 | 
					    mapStateToProps,
 | 
				
			||||||
 | 
					    mapDispatchToProps
 | 
				
			||||||
 | 
					)(ShowUserComponent);
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										13
									
								
								frontend/src/data/config-api.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								frontend/src/data/config-api.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					import { throwIfNotSuccess } from './helper';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const URI = 'api/admin/ui-config';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function fetchConfig() {
 | 
				
			||||||
 | 
					    return fetch(URI, { credentials: 'include' })
 | 
				
			||||||
 | 
					        .then(throwIfNotSuccess)
 | 
				
			||||||
 | 
					        .then(response => response.json());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default {
 | 
				
			||||||
 | 
					    fetchConfig,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -1,7 +1,8 @@
 | 
				
			|||||||
import 'whatwg-fetch';
 | 
					import 'whatwg-fetch';
 | 
				
			||||||
import 'react-mdl/extra/material.css';
 | 
					 | 
				
			||||||
import 'react-mdl/extra/material.js';
 | 
					import 'react-mdl/extra/material.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import 'react-mdl/extra/css/material.blue_grey-pink.min.css';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import React from 'react';
 | 
					import React from 'react';
 | 
				
			||||||
import ReactDOM from 'react-dom';
 | 
					import ReactDOM from 'react-dom';
 | 
				
			||||||
import { HashRouter, Route } from 'react-router-dom';
 | 
					import { HashRouter, Route } from 'react-router-dom';
 | 
				
			||||||
 | 
				
			|||||||
@ -11,6 +11,7 @@ import settings from './settings';
 | 
				
			|||||||
import user from './user';
 | 
					import user from './user';
 | 
				
			||||||
import api from './api';
 | 
					import api from './api';
 | 
				
			||||||
import applications from './application';
 | 
					import applications from './application';
 | 
				
			||||||
 | 
					import uiConfig from './ui-config';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const unleashStore = combineReducers({
 | 
					const unleashStore = combineReducers({
 | 
				
			||||||
    features,
 | 
					    features,
 | 
				
			||||||
@ -24,6 +25,7 @@ const unleashStore = combineReducers({
 | 
				
			|||||||
    settings,
 | 
					    settings,
 | 
				
			||||||
    user,
 | 
					    user,
 | 
				
			||||||
    applications,
 | 
					    applications,
 | 
				
			||||||
 | 
					    uiConfig,
 | 
				
			||||||
    api,
 | 
					    api,
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					// Jest Snapshot v1, https://goo.gl/fbAQLP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					exports[`should be default state 1`] = `
 | 
				
			||||||
 | 
					Object {
 | 
				
			||||||
 | 
					  "environment": undefined,
 | 
				
			||||||
 | 
					  "headerBackground": undefined,
 | 
				
			||||||
 | 
					  "slogan": "A product originally created by FINN.no.",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					exports[`should be merged state all 1`] = `
 | 
				
			||||||
 | 
					Object {
 | 
				
			||||||
 | 
					  "environment": "dev",
 | 
				
			||||||
 | 
					  "headerBackground": "red",
 | 
				
			||||||
 | 
					  "slogan": "hello",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					exports[`should only update headerBackground 1`] = `
 | 
				
			||||||
 | 
					Object {
 | 
				
			||||||
 | 
					  "environment": undefined,
 | 
				
			||||||
 | 
					  "headerBackground": "black",
 | 
				
			||||||
 | 
					  "slogan": "A product originally created by FINN.no.",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					`;
 | 
				
			||||||
@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					import { AssertionError } from 'assert';
 | 
				
			||||||
 | 
					import reducer from '../index';
 | 
				
			||||||
 | 
					import { receiveConfig } from '../actions';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test('should be default state', () => {
 | 
				
			||||||
 | 
					    const state = reducer(undefined, {});
 | 
				
			||||||
 | 
					    expect(state.toJS()).toMatchSnapshot();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test('should be merged state all', () => {
 | 
				
			||||||
 | 
					    const uiConfig = {
 | 
				
			||||||
 | 
					        headerBackground: 'red',
 | 
				
			||||||
 | 
					        slogan: 'hello',
 | 
				
			||||||
 | 
					        environment: 'dev',
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const state = reducer(undefined, receiveConfig(uiConfig));
 | 
				
			||||||
 | 
					    expect(state.toJS()).toMatchSnapshot();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test('should only update headerBackground', () => {
 | 
				
			||||||
 | 
					    localStorage.clear();
 | 
				
			||||||
 | 
					    const uiConfig = {
 | 
				
			||||||
 | 
					        headerBackground: 'black',
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const state = reducer(undefined, receiveConfig(uiConfig));
 | 
				
			||||||
 | 
					    expect(state.toJS()).toMatchSnapshot();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										18
									
								
								frontend/src/store/ui-config/actions.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								frontend/src/store/ui-config/actions.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					import api from '../../data/config-api';
 | 
				
			||||||
 | 
					import { dispatchAndThrow } from '../util';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const RECEIVE_CONFIG = 'RECEIVE_CONFIG';
 | 
				
			||||||
 | 
					export const ERROR_RECEIVE_CONFIG = 'ERROR_RECEIVE_CONFIG';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const receiveConfig = json => ({
 | 
				
			||||||
 | 
					    type: RECEIVE_CONFIG,
 | 
				
			||||||
 | 
					    value: json,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function fetchUIConfig() {
 | 
				
			||||||
 | 
					    return dispatch =>
 | 
				
			||||||
 | 
					        api
 | 
				
			||||||
 | 
					            .fetchConfig()
 | 
				
			||||||
 | 
					            .then(json => dispatch(receiveConfig(json)))
 | 
				
			||||||
 | 
					            .catch(dispatchAndThrow(dispatch, ERROR_RECEIVE_CONFIG));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										41
									
								
								frontend/src/store/ui-config/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								frontend/src/store/ui-config/index.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					import { Map as $Map } from 'immutable';
 | 
				
			||||||
 | 
					import { RECEIVE_CONFIG } from './actions';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const localStorage = window.localStorage || {
 | 
				
			||||||
 | 
					    setItem: () => {},
 | 
				
			||||||
 | 
					    getItem: () => {},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const basePath = location ? location.pathname : '/';
 | 
				
			||||||
 | 
					const UI_CONFIG = `${basePath}:ui_config`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const DEFAULT = new $Map({
 | 
				
			||||||
 | 
					    headerBackground: undefined,
 | 
				
			||||||
 | 
					    environment: undefined,
 | 
				
			||||||
 | 
					    slogan: 'A product originally created by FINN.no.',
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function getInitState() {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        const state = JSON.parse(localStorage.getItem(UI_CONFIG));
 | 
				
			||||||
 | 
					        return state ? DEFAULT.merge(state) : DEFAULT;
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					        return DEFAULT;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function updateConfig(state, config) {
 | 
				
			||||||
 | 
					    localStorage.setItem(UI_CONFIG, JSON.stringify(config));
 | 
				
			||||||
 | 
					    return state.merge(config);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const strategies = (state = getInitState(), action) => {
 | 
				
			||||||
 | 
					    switch (action.type) {
 | 
				
			||||||
 | 
					        case RECEIVE_CONFIG:
 | 
				
			||||||
 | 
					            return updateConfig(state, action.value);
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            return state;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default strategies;
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user