diff --git a/packages/unleash-frontend-next/src/component/app.jsx b/packages/unleash-frontend-next/src/component/app.jsx index 1b199f5182..34f65038f4 100644 --- a/packages/unleash-frontend-next/src/component/app.jsx +++ b/packages/unleash-frontend-next/src/component/app.jsx @@ -1,6 +1,7 @@ import React, { Component } from 'react'; import { Layout, Panel, NavDrawer, AppBar } from 'react-toolbox'; import style from './styles.scss'; +import ErrorContainer from './error/error-container'; import Navigation from './nav'; @@ -30,6 +31,7 @@ export default class App extends Component { {this.props.children} + diff --git a/packages/unleash-frontend-next/src/component/error/error-component.jsx b/packages/unleash-frontend-next/src/component/error/error-component.jsx new file mode 100644 index 0000000000..4d63b5fbff --- /dev/null +++ b/packages/unleash-frontend-next/src/component/error/error-component.jsx @@ -0,0 +1,31 @@ +import Snackbar from 'react-toolbox/lib/snackbar'; +import React, { PropTypes } from 'react'; + +class ErrorComponent extends React.Component { + static propTypes () { + return { + errors: PropTypes.array.isRequired, + showError: PropTypes.bool, + muteErrors: PropTypes.func.isRequired, + }; + } + + render () { + const snackbarMsg = this.props.errors.join(', '); + return ( + + ); + } +} + +export default ErrorComponent; diff --git a/packages/unleash-frontend-next/src/component/error/error-container.jsx b/packages/unleash-frontend-next/src/component/error/error-container.jsx new file mode 100644 index 0000000000..2cc154e1ba --- /dev/null +++ b/packages/unleash-frontend-next/src/component/error/error-container.jsx @@ -0,0 +1,13 @@ +import { connect } from 'react-redux'; +import ErrorComponent from './error-component'; +import { muteErrors } from '../../store/error-actions'; + + +const mapDispatchToProps = { + muteErrors, +}; + +export default connect((state) => ({ + errors: state.error.get('list').toArray(), + showError: state.error.get('showError'), +}), mapDispatchToProps)(ErrorComponent); diff --git a/packages/unleash-frontend-next/src/store/error-actions.js b/packages/unleash-frontend-next/src/store/error-actions.js new file mode 100644 index 0000000000..1eafce4915 --- /dev/null +++ b/packages/unleash-frontend-next/src/store/error-actions.js @@ -0,0 +1,6 @@ +export const MUTE_ERRORS = 'MUTE_ERRORS'; + +export const muteErrors = () => ({ type: MUTE_ERRORS }); + + + diff --git a/packages/unleash-frontend-next/src/store/error-store.js b/packages/unleash-frontend-next/src/store/error-store.js new file mode 100644 index 0000000000..2c16f5a6f3 --- /dev/null +++ b/packages/unleash-frontend-next/src/store/error-store.js @@ -0,0 +1,28 @@ +import { List, Map as $Map } from 'immutable'; +import { ERROR_RECEIVE_FEATURE_TOGGLES } from './feature-actions'; +import { MUTE_ERRORS } from './error-actions'; +const debug = require('debug')('unleash:error-store'); + +function getInitState () { + return new $Map({ + list: new List(), + showError: false, + }); +} + +const strategies = (state = getInitState(), action) => { + switch (action.type) { + case ERROR_RECEIVE_FEATURE_TOGGLES: + debug('Got error', action); + return state + .update('list', (list) => list.push('Failed fetching feature toggles')) + .set('showError', true); + case MUTE_ERRORS: + debug('muting errors'); + return state.set('showError', false); + default: + return state; + } +}; + +export default strategies; diff --git a/packages/unleash-frontend-next/src/store/index.js b/packages/unleash-frontend-next/src/store/index.js index 4565f8ff8e..c064657e98 100644 --- a/packages/unleash-frontend-next/src/store/index.js +++ b/packages/unleash-frontend-next/src/store/index.js @@ -4,6 +4,7 @@ import strategies from './strategy-store'; import input from './input-store'; import history from './history-store'; // eslint-disable-line import archive from './archive-store'; +import error from './error-store'; const unleashStore = combineReducers({ features, @@ -11,6 +12,7 @@ const unleashStore = combineReducers({ input, history, archive, + error, }); export default unleashStore;