diff --git a/public/js/app.jsx b/public/js/app.jsx
index 22a8ea2ee3..276e6b701c 100644
--- a/public/js/app.jsx
+++ b/public/js/app.jsx
@@ -2,6 +2,7 @@ var React = require('react');
var TabView = require('./components/TabView');
var Menu = require('./components/Menu');
var UserStore = require('./stores/UserStore');
+var ErrorMessages = require('./components/ErrorMessages');
var LogEntriesComponent = React.createFactory(require('./components/log/LogEntriesComponent'));
var FeatureTogglesComponent = React.createFactory(require('./components/feature/FeatureTogglesComponent'));
var StrategiesComponent = React.createFactory(require('./components/strategy/StrategiesComponent'));
@@ -37,10 +38,10 @@ React.render(
-
{this.state.createView ? this.renderCreateView() : this.renderCreateButton()}
@@ -111,11 +65,11 @@ var FeatureTogglesComponent = React.createClass({
},
renderCreateView: function() {
- return
+ return
;
},
renderCreateButton: function() {
- return
+ return
;
}
});
diff --git a/public/js/components/log/LogEntriesComponent.jsx b/public/js/components/log/LogEntriesComponent.jsx
index 45a943d7f6..71d5992e53 100644
--- a/public/js/components/log/LogEntriesComponent.jsx
+++ b/public/js/components/log/LogEntriesComponent.jsx
@@ -1,14 +1,13 @@
-var React = require('react'),
- LogEntryList = require('./LogEntryList'),
- eventStore = require('../../stores/EventStore'),
- ErrorMessages = require('../ErrorMessages');
+var React = require('react');
+var LogEntryList = require('./LogEntryList');
+var eventStore = require('../../stores/EventStore');
+var ErrorActions = require('../../stores/ErrorActions');
var LogEntriesComponent = React.createClass({
getInitialState: function() {
return {
createView: false,
- events: [],
- errors: []
+ events: []
};
},
@@ -19,29 +18,17 @@ var LogEntriesComponent = React.createClass({
},
initError: function() {
- this.onError("Could not load events from server");
- },
-
- clearErrors: function() {
- this.setState({errors: []});
- },
-
- onError: function(error) {
- var errors = this.state.errors.concat([error]);
- this.setState({errors: errors});
+ ErrorActions.error("Could not load events from server");
},
render: function() {
return (
-
-
-
);
},
});
-module.exports = LogEntriesComponent;
\ No newline at end of file
+module.exports = LogEntriesComponent;
diff --git a/public/js/components/strategy/StrategiesComponent.jsx b/public/js/components/strategy/StrategiesComponent.jsx
index 0df00d17de..1a625d61d5 100644
--- a/public/js/components/strategy/StrategiesComponent.jsx
+++ b/public/js/components/strategy/StrategiesComponent.jsx
@@ -1,15 +1,14 @@
-var React = require('react'),
- StrategyList = require('./StrategyList'),
- StrategyForm = require('./StrategyForm'),
- strategyStore = require('../../stores/StrategyStore'),
- ErrorMessages = require('../ErrorMessages');
+var React = require('react');
+var StrategyList = require('./StrategyList');
+var StrategyForm = require('./StrategyForm');
+var strategyStore = require('../../stores/StrategyStore');
+var ErrorActions = require('../../stores/ErrorActions');
var StrategiesComponent = React.createClass({
getInitialState: function() {
return {
createView: false,
- strategies: [],
- errors: []
+ strategies: []
};
},
@@ -17,12 +16,12 @@ var StrategiesComponent = React.createClass({
this.fetchStrategies();
},
- fetchStrategies: function(res) {
+ fetchStrategies: function() {
strategyStore.getStrategies()
- .then(function(res) {
- this.setState({strategies: res.strategies})
- }.bind(this))
- .catch(this.initError);
+ .then(function(res) {
+ this.setState({strategies: res.strategies});
+ }.bind(this))
+ .catch(this.initError);
},
@@ -30,13 +29,8 @@ var StrategiesComponent = React.createClass({
this.onError("Could not load inital strategies from server");
},
- clearErrors: function() {
- this.setState({errors: []});
- },
-
onError: function(error) {
- var errors = this.state.errors.concat([error]);
- this.setState({errors: errors});
+ ErrorActions.error(error);
},
onNewStrategy: function() {
@@ -66,33 +60,37 @@ var StrategiesComponent = React.createClass({
onRemove: function(strategy) {
strategyStore.removeStrategy(strategy)
- .then(this.fetchStrategies)
- .catch(this.onError);
+ .then(this.fetchStrategies)
+ .catch(this.onError);
},
render: function() {
return (
-
-
- {this.state.createView ? this.renderCreateView() : this.renderCreateButton()}
-
+ {this.state.createView ? this.renderCreateView() : this.renderCreateButton()}
-
-
+
- );
+ );
},
renderCreateView: function() {
- return (
)
+ return (
+
);
},
renderCreateButton: function() {
return (
-
+
);
}
});
-module.exports = StrategiesComponent;
\ No newline at end of file
+module.exports = StrategiesComponent;
diff --git a/public/js/stores/ErrorActions.js b/public/js/stores/ErrorActions.js
new file mode 100644
index 0000000000..f6e4aebc4b
--- /dev/null
+++ b/public/js/stores/ErrorActions.js
@@ -0,0 +1,8 @@
+var Reflux = require('reflux');
+
+var ErrorActions = Reflux.createActions([
+ "clear",
+ "error"
+]);
+
+module.exports = ErrorActions;
diff --git a/public/js/stores/ErrorStore.js b/public/js/stores/ErrorStore.js
new file mode 100644
index 0000000000..f038b12a47
--- /dev/null
+++ b/public/js/stores/ErrorStore.js
@@ -0,0 +1,65 @@
+var Reflux = require('reflux');
+var FeatureActions = require('./FeatureToggleActions');
+var ErrorActions = require('./ErrorActions');
+
+// Creates a DataStore
+var FeatureStore = Reflux.createStore({
+ // Initial setup
+ init: function() {
+ this.listenTo(FeatureActions.create.failed, this.onError);
+ this.listenTo(FeatureActions.update.failed, this.onError);
+ this.listenTo(FeatureActions.archive.failed, this.onError);
+ this.listenTo(FeatureActions.revive.failed, this.onError);
+ this.listenTo(ErrorActions.error, this.onError);
+ this.listenTo(ErrorActions.clear, this.onClear);
+ this.errors = [];
+ },
+
+ onError: function (error) {
+ if (this.isClientError(error)) {
+ var errors = JSON.parse(error.responseText);
+ errors.forEach(function(e) { this.addError(e.msg); }.bind(this));
+ } else if (error.status === 0) {
+ this.addError("server unreachable");
+ } else {
+ this.addError(error);
+ }
+ },
+
+ onClear: function() {
+ this.errors = [];
+ this.trigger([]);
+ },
+
+ addError: function(msg) {
+ var errors = this.errors;
+ if (errors[errors.length - 1] !== msg) {
+ errors.push(msg);
+ this.errors = errors;
+ this.trigger(errors);
+ }
+ },
+
+ isClientError: function(error) {
+ try {
+ return error.status >= 400 &&
+ error.status < 500 &&
+ JSON.parse(error.responseText);
+ } catch (e) {
+ if (e instanceof SyntaxError) {
+ // fall through;
+ console.log("Syntax error!");
+ } else {
+ throw e;
+ }
+ }
+
+ return false;
+ },
+
+ getErrors: function() {
+ return this.errors;
+ }
+});
+
+module.exports = FeatureStore;
diff --git a/public/js/stores/FeatureToggleStore.js b/public/js/stores/FeatureToggleStore.js
index bd09302346..2554b81d14 100644
--- a/public/js/stores/FeatureToggleStore.js
+++ b/public/js/stores/FeatureToggleStore.js
@@ -20,14 +20,18 @@ var FeatureStore = Reflux.createStore({
this.listenTo(FeatureActions.revive.completed, this.onRevive);
//TODO: this should not be part of the store!
- this.timer = new Timer(this.loadDataFromServer, 30*1000);
+ this.timer = new Timer(this.loadDataFromServer, 3*1000);
this.timer.start();
},
loadDataFromServer: function() {
//TODO: this should not be part of the store!
Server.getFeatures(function(err, featureToggles) {
- this.setToggles(featureToggles);
+ if(err) {
+ return;
+ } else {
+ this.setToggles(featureToggles);
+ }
}.bind(this));
},