1
0
mirror of https://github.com/Unleash/unleash.git synced 2024-12-22 19:07:54 +01:00

Pass strategies as props

This commit is contained in:
Ivar Conradi Østhus 2015-03-17 22:01:46 +01:00
parent f11cd291c2
commit 08600fa7ee
11 changed files with 201 additions and 124 deletions

View File

@ -17,7 +17,7 @@ describe("FeatureForm", function () {
];
Server.getArchivedFeatures.mockImplementation(function(cb) {
cb(archivedToggles);
cb(null, archivedToggles);
});
FeatureToggleStore.initStore(archivedToggles);

View File

@ -3,31 +3,19 @@ jest.dontMock("../../../components/feature/FeatureForm");
var React = require("react/addons");
var TestUtils = React.addons.TestUtils;
var FeatureForm = require("../../../components/feature/FeatureForm");
var strategyStore = require("../../../stores/StrategyStore");
describe("FeatureForm", function () {
var Component;
beforeEach(function() {
strategyStore.getStrategies.mockImplementation(function() {
return {
then: function (callback) {
return callback({
strategies: [
{ name: "default"}
]
});
}
};
});
});
var strategies = [
{ name: "default"}
];
afterEach(function() {
React.unmountComponentAtNode(document.body);
});
describe("new", function () {
it("should render empty form", function() {
Component = TestUtils .renderIntoDocument(<FeatureForm />);
Component = TestUtils .renderIntoDocument(<FeatureForm strategies={strategies} />);
var name = Component.getDOMNode().querySelectorAll("input");
expect(name[0].value).toEqual(undefined);
});
@ -37,11 +25,11 @@ describe("FeatureForm", function () {
var feature = {name: "Test", strategy: "unknown"};
it("should show unknown strategy as deleted", function () {
Component = TestUtils .renderIntoDocument(<FeatureForm feature={feature} />);
Component = TestUtils .renderIntoDocument(<FeatureForm feature={feature} strategies={strategies} />);
var strategySelect = Component.getDOMNode().querySelector("select");
expect(strategySelect.value).toEqual("unknown (deleted)");
});
});
});
});

View File

@ -13,7 +13,10 @@ describe("FeatureList", function () {
{ name: "featureX", strategy: "other" },
{ name: "group.featureY", strategy: "default" }
];
Component = TestUtils .renderIntoDocument(<FeatureList features={features} />);
var strategies=[
{ name: "default"}
];
Component = TestUtils .renderIntoDocument(<FeatureList features={features} strategies={strategies} />);
});
afterEach(function() {
@ -52,4 +55,4 @@ describe("FeatureList", function () {
expect(features[0].textContent).toMatch(searchString);
});
});
});

View File

@ -44,7 +44,11 @@ var Feature = React.createClass({
return (
<tr>
<td colSpan="4" className="pan man no-border">
<FeatureForm feature={this.props.feature} onSubmit={this.saveFeature} onCancel={this.toggleEditMode} />
<FeatureForm
feature={this.props.feature}
onSubmit={this.saveFeature}
onCancel={this.toggleEditMode}
strategies={this.props.strategies} />
</td>
</tr>
);
@ -110,4 +114,4 @@ var Feature = React.createClass({
});
module.exports = Feature;
module.exports = Feature;

View File

@ -1,22 +1,16 @@
var React = require('react');
var TextInput = require('../form/TextInput');
var strategyStore = require('../../stores/StrategyStore');
var FeatureForm = React.createClass({
getInitialState: function() {
return {
strategyOptions: [],
requiredParams: [],
currentStrategy: this.props.feature ? this.props.feature.strategy : "default"
};
return {
strategyOptions: this.props.strategies,
requiredParams: [],
currentStrategy: this.props.feature ? this.props.feature.strategy : "default"
};
},
componentWillMount: function() {
strategyStore.getStrategies().then(this.handleStrategyResponse);
},
handleStrategyResponse: function(response) {
this.setState({strategyOptions: response.strategies});
if(this.props.feature) {
this.setSelectedStrategy(this.props.feature.strategy);
}
@ -41,9 +35,7 @@ var FeatureForm = React.createClass({
})[0];
if(selectedStrategy) {
if(selectedStrategy.parametersTemplate) {
this.setStrategyParams(selectedStrategy);
}
this.setStrategyParams(selectedStrategy);
} else {
var updatedStrategyName = name + " (deleted)";
this.setState({
@ -64,9 +56,9 @@ var FeatureForm = React.createClass({
render: function() {
var feature = this.props.feature || {
name: '',
strategy: 'default',
enabled: false
name: '',
strategy: 'default',
enabled: false
};
var idPrefix = this.props.feature ? this.props.feature.name : 'new';
@ -131,9 +123,9 @@ var FeatureForm = React.createClass({
renderStrategyOptions: function() {
return this.state.strategyOptions.map(function(strategy) {
return (
<option key={strategy.name} value={strategy.name}>
{strategy.name}
</option>
<option key={strategy.name} value={strategy.name}>
{strategy.name}
</option>
);
}.bind(this));
},
@ -178,4 +170,4 @@ var FeatureForm = React.createClass({
}
});
module.exports = FeatureForm;
module.exports = FeatureForm;

View File

@ -5,7 +5,8 @@ var noop = function() {};
var FeatureList = React.createClass({
propTypes: {
features: React.PropTypes.array.isRequired
features: React.PropTypes.array.isRequired,
strategies: React.PropTypes.array.isRequired
},
getDefaultProps: function() {
@ -47,7 +48,9 @@ var FeatureList = React.createClass({
key={feature.name}
feature={feature}
onChange={this.props.onFeatureChanged}
onArchive={this.props.onFeatureArchive}/>
onArchive={this.props.onFeatureArchive}
strategies={this.props.strategies}
/>
);
}.bind(this));
@ -83,4 +86,4 @@ var FeatureList = React.createClass({
}
});
module.exports = FeatureList;
module.exports = FeatureList;

View File

@ -4,6 +4,7 @@ var FeatureForm = require('./FeatureForm');
var FeatureActions = require('../../stores/FeatureToggleActions');
var ErrorActions = require('../../stores/ErrorActions');
var FeatureToggleStore = require('../../stores/FeatureToggleStore');
var StrategyStore = require('../../stores/StrategyStore');
var FeatureTogglesComponent = React.createClass({
getInitialState: function() {
@ -59,13 +60,17 @@ var FeatureTogglesComponent = React.createClass({
onFeatureArchive={this.archiveFeature}
onFeatureSubmit={this.createFeature}
onFeatureCancel={this.cancelNewFeature}
onNewFeature={this.newFeature} />
onNewFeature={this.newFeature}
strategies={StrategyStore.getStrategies()} />
</div>
);
},
renderCreateView: function() {
return <FeatureForm onCancel={this.cancelNewFeature} onSubmit={this.createFeature} />;
return <FeatureForm
onCancel={this.cancelNewFeature}
onSubmit={this.createFeature}
strategies={StrategyStore.getStrategies()} />;
},
renderCreateButton: function() {

View File

@ -1,36 +1,27 @@
var React = require('react');
var StrategyList = require('./StrategyList');
var StrategyForm = require('./StrategyForm');
var strategyStore = require('../../stores/StrategyStore');
var ErrorActions = require('../../stores/ErrorActions');
var React = require('react');
var StrategyList = require('./StrategyList');
var StrategyForm = require('./StrategyForm');
var StrategyStore = require('../../stores/StrategyStore');
var StrategyActions = require('../../stores/StrategyActions');
var StrategiesComponent = React.createClass({
getInitialState: function() {
return {
createView: false,
strategies: []
strategies: StrategyStore.getStrategies()
};
},
componentDidMount: function () {
this.fetchStrategies();
onStoreChange: function() {
this.setState({
strategies: StrategyStore.getStrategies()
});
},
fetchStrategies: function() {
strategyStore.getStrategies()
.then(function(res) {
this.setState({strategies: res.strategies});
}.bind(this))
.catch(this.initError);
componentDidMount: function() {
this.unsubscribe = StrategyStore.listen(this.onStoreChange);
},
initError: function() {
this.onError("Could not load inital strategies from server");
},
onError: function(error) {
ErrorActions.error(error);
componentWillUnmount: function() {
this.unsubscribe();
},
onNewStrategy: function() {
@ -42,32 +33,19 @@ var StrategiesComponent = React.createClass({
},
onSave: function(strategy) {
function handleSuccess() {
var strategies = this.state.strategies.concat([strategy]);
this.setState({
createView: false,
strategies: strategies
});
console.log("Saved strategy: ", strategy);
}
strategyStore.createStrategy(strategy)
.then(handleSuccess.bind(this))
.catch(this.onError);
StrategyActions.create.triggerPromise(strategy)
.then(this.onCancelNewStrategy);
},
onRemove: function(strategy) {
strategyStore.removeStrategy(strategy)
.then(this.fetchStrategies)
.catch(this.onError);
StrategyActions.remove.triggerPromise(strategy);
},
render: function() {
return (
<div>
{this.state.createView ? this.renderCreateView() : this.renderCreateButton()}
{this.state.createView ?
this.renderCreateView() : this.renderCreateButton()}
<hr />
<StrategyList
strategies={this.state.strategies}
@ -82,15 +60,15 @@ var StrategiesComponent = React.createClass({
onCancelNewStrategy={this.onCancelNewStrategy}
onSave={this.onSave}
/>);
},
},
renderCreateButton: function() {
return (
<button className="mal" onClick={this.onNewStrategy}>
Create strategy
</button>
);
}
});
renderCreateButton: function() {
return (
<button className="mal" onClick={this.onNewStrategy}>
Create strategy
</button>
);
}
});
module.exports = StrategiesComponent;
module.exports = StrategiesComponent;

View File

@ -0,0 +1,52 @@
var reqwest = require('reqwest');
var TYPE = 'json';
var CONTENT_TYPE = 'application/json';
var StrategyAPI = {
createStrategy: function (strategy, cb) {
reqwest({
url: 'strategies',
method: 'post',
type: TYPE,
contentType: CONTENT_TYPE,
data: JSON.stringify(strategy),
error: function(error) {
cb(error);
},
success: function() {
cb(null, strategy);
}
});
},
removeStrategy: function (strategy, cb) {
reqwest({
url: 'strategies/'+strategy.name,
method: 'delete',
type: TYPE,
error: function(error) {
cb(error);
},
success: function() {
cb(null, strategy);
}
});
},
getStrategies: function (cb) {
reqwest({
url: 'strategies',
method: 'get',
type: TYPE,
error: function(error) {
cb(error);
},
success: function(data) {
cb(null, data.strategies);
}
});
}
};
module.exports = StrategyAPI;

View File

@ -0,0 +1,29 @@
var Reflux = require("reflux");
var StrategyAPI = require('./StrategyAPI');
var StrategyActions = Reflux.createActions({
'create': { asyncResult: true },
'remove': { asyncResult: true },
});
StrategyActions.create.listen(function(feature){
StrategyAPI.createStrategy(feature, function(err) {
if(err) {
this.failed(err);
} else {
this.completed(feature);
}
}.bind(this));
});
StrategyActions.remove.listen(function(feature){
StrategyAPI.removeStrategy(feature, function(err) {
if(err) {
this.failed(err);
} else {
this.completed(feature);
}
}.bind(this));
});
module.exports = StrategyActions;

View File

@ -1,34 +1,57 @@
var reqwest = require('reqwest');
var Reflux = require('reflux');
var ErrorActions = require('./ErrorActions');
var StrategyActions = require('./StrategyActions');
var StrategyAPI = require('./StrategyAPI');
var filter = require('lodash/collection/filter');
var TYPE = 'json';
var CONTENT_TYPE = 'application/json';
var _strategies = [];
var StrategyStore = {
createStrategy: function (strategy) {
return reqwest({
url: 'strategies',
method: 'post',
type: TYPE,
contentType: CONTENT_TYPE,
data: JSON.stringify(strategy)
});
// Creates a DataStore
var StrategyStore = Reflux.createStore({
// Initial setup
init: function() {
this.listenTo(StrategyActions.create.completed, this.onCreate);
this.listenTo(StrategyActions.remove.completed, this.onRemove);
this.loadDataFromServer();
},
removeStrategy: function (strategy) {
return reqwest({
url: 'strategies/'+strategy.name,
method: 'delete',
type: TYPE
});
loadDataFromServer: function() {
//TODO: this should not be part of the store!
StrategyAPI.getStrategies(function(err, strategies) {
if(err) {
ErrorActions.error(err);
return;
} else {
this.setStrategies(strategies);
}
}.bind(this));
},
getStrategies: function () {
return reqwest({
url: 'strategies',
method: 'get',
type: TYPE
onCreate: function(strategy) {
this.setStrategies(_strategies.concat([strategy]));
},
onRemove: function(strategy) {
var strategies = filter(_strategies, function(item) {
return item.name !== strategy.name;
});
this.setStrategies(strategies);
},
setStrategies: function(strategies) {
_strategies = strategies;
this.trigger(_strategies);
},
getStrategies: function() {
return _strategies;
},
initStore: function(strategies) {
_strategies = strategies;
}
};
});
module.exports = StrategyStore;