mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-01 00:08:27 +01:00
Pass strategies as props
This commit is contained in:
parent
31dd7fed5a
commit
ebb1b3b0b7
@ -17,7 +17,7 @@ describe("FeatureForm", function () {
|
|||||||
];
|
];
|
||||||
|
|
||||||
Server.getArchivedFeatures.mockImplementation(function(cb) {
|
Server.getArchivedFeatures.mockImplementation(function(cb) {
|
||||||
cb(archivedToggles);
|
cb(null, archivedToggles);
|
||||||
});
|
});
|
||||||
|
|
||||||
FeatureToggleStore.initStore(archivedToggles);
|
FeatureToggleStore.initStore(archivedToggles);
|
||||||
|
@ -3,31 +3,19 @@ jest.dontMock("../../../components/feature/FeatureForm");
|
|||||||
var React = require("react/addons");
|
var React = require("react/addons");
|
||||||
var TestUtils = React.addons.TestUtils;
|
var TestUtils = React.addons.TestUtils;
|
||||||
var FeatureForm = require("../../../components/feature/FeatureForm");
|
var FeatureForm = require("../../../components/feature/FeatureForm");
|
||||||
var strategyStore = require("../../../stores/StrategyStore");
|
|
||||||
|
|
||||||
describe("FeatureForm", function () {
|
describe("FeatureForm", function () {
|
||||||
var Component;
|
var Component;
|
||||||
beforeEach(function() {
|
var strategies = [
|
||||||
strategyStore.getStrategies.mockImplementation(function() {
|
{ name: "default"}
|
||||||
return {
|
];
|
||||||
then: function (callback) {
|
|
||||||
return callback({
|
|
||||||
strategies: [
|
|
||||||
{ name: "default"}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(function() {
|
afterEach(function() {
|
||||||
React.unmountComponentAtNode(document.body);
|
React.unmountComponentAtNode(document.body);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("new", function () {
|
describe("new", function () {
|
||||||
it("should render empty form", function() {
|
it("should render empty form", function() {
|
||||||
Component = TestUtils .renderIntoDocument(<FeatureForm />);
|
Component = TestUtils .renderIntoDocument(<FeatureForm strategies={strategies} />);
|
||||||
var name = Component.getDOMNode().querySelectorAll("input");
|
var name = Component.getDOMNode().querySelectorAll("input");
|
||||||
expect(name[0].value).toEqual(undefined);
|
expect(name[0].value).toEqual(undefined);
|
||||||
});
|
});
|
||||||
@ -37,11 +25,11 @@ describe("FeatureForm", function () {
|
|||||||
var feature = {name: "Test", strategy: "unknown"};
|
var feature = {name: "Test", strategy: "unknown"};
|
||||||
|
|
||||||
it("should show unknown strategy as deleted", function () {
|
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");
|
var strategySelect = Component.getDOMNode().querySelector("select");
|
||||||
expect(strategySelect.value).toEqual("unknown (deleted)");
|
expect(strategySelect.value).toEqual("unknown (deleted)");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -13,7 +13,10 @@ describe("FeatureList", function () {
|
|||||||
{ name: "featureX", strategy: "other" },
|
{ name: "featureX", strategy: "other" },
|
||||||
{ name: "group.featureY", strategy: "default" }
|
{ 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() {
|
afterEach(function() {
|
||||||
@ -52,4 +55,4 @@ describe("FeatureList", function () {
|
|||||||
expect(features[0].textContent).toMatch(searchString);
|
expect(features[0].textContent).toMatch(searchString);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -44,7 +44,11 @@ var Feature = React.createClass({
|
|||||||
return (
|
return (
|
||||||
<tr>
|
<tr>
|
||||||
<td colSpan="4" className="pan man no-border">
|
<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>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
@ -110,4 +114,4 @@ var Feature = React.createClass({
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = Feature;
|
module.exports = Feature;
|
||||||
|
@ -1,22 +1,16 @@
|
|||||||
var React = require('react');
|
var React = require('react');
|
||||||
var TextInput = require('../form/TextInput');
|
var TextInput = require('../form/TextInput');
|
||||||
var strategyStore = require('../../stores/StrategyStore');
|
|
||||||
|
|
||||||
var FeatureForm = React.createClass({
|
var FeatureForm = React.createClass({
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
strategyOptions: [],
|
strategyOptions: this.props.strategies,
|
||||||
requiredParams: [],
|
requiredParams: [],
|
||||||
currentStrategy: this.props.feature ? this.props.feature.strategy : "default"
|
currentStrategy: this.props.feature ? this.props.feature.strategy : "default"
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillMount: function() {
|
componentWillMount: function() {
|
||||||
strategyStore.getStrategies().then(this.handleStrategyResponse);
|
|
||||||
},
|
|
||||||
|
|
||||||
handleStrategyResponse: function(response) {
|
|
||||||
this.setState({strategyOptions: response.strategies});
|
|
||||||
if(this.props.feature) {
|
if(this.props.feature) {
|
||||||
this.setSelectedStrategy(this.props.feature.strategy);
|
this.setSelectedStrategy(this.props.feature.strategy);
|
||||||
}
|
}
|
||||||
@ -41,9 +35,7 @@ var FeatureForm = React.createClass({
|
|||||||
})[0];
|
})[0];
|
||||||
|
|
||||||
if(selectedStrategy) {
|
if(selectedStrategy) {
|
||||||
if(selectedStrategy.parametersTemplate) {
|
this.setStrategyParams(selectedStrategy);
|
||||||
this.setStrategyParams(selectedStrategy);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
var updatedStrategyName = name + " (deleted)";
|
var updatedStrategyName = name + " (deleted)";
|
||||||
this.setState({
|
this.setState({
|
||||||
@ -64,9 +56,9 @@ var FeatureForm = React.createClass({
|
|||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var feature = this.props.feature || {
|
var feature = this.props.feature || {
|
||||||
name: '',
|
name: '',
|
||||||
strategy: 'default',
|
strategy: 'default',
|
||||||
enabled: false
|
enabled: false
|
||||||
};
|
};
|
||||||
|
|
||||||
var idPrefix = this.props.feature ? this.props.feature.name : 'new';
|
var idPrefix = this.props.feature ? this.props.feature.name : 'new';
|
||||||
@ -131,9 +123,9 @@ var FeatureForm = React.createClass({
|
|||||||
renderStrategyOptions: function() {
|
renderStrategyOptions: function() {
|
||||||
return this.state.strategyOptions.map(function(strategy) {
|
return this.state.strategyOptions.map(function(strategy) {
|
||||||
return (
|
return (
|
||||||
<option key={strategy.name} value={strategy.name}>
|
<option key={strategy.name} value={strategy.name}>
|
||||||
{strategy.name}
|
{strategy.name}
|
||||||
</option>
|
</option>
|
||||||
);
|
);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
@ -178,4 +170,4 @@ var FeatureForm = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = FeatureForm;
|
module.exports = FeatureForm;
|
||||||
|
@ -5,7 +5,8 @@ var noop = function() {};
|
|||||||
|
|
||||||
var FeatureList = React.createClass({
|
var FeatureList = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
features: React.PropTypes.array.isRequired
|
features: React.PropTypes.array.isRequired,
|
||||||
|
strategies: React.PropTypes.array.isRequired
|
||||||
},
|
},
|
||||||
|
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
@ -47,7 +48,9 @@ var FeatureList = React.createClass({
|
|||||||
key={feature.name}
|
key={feature.name}
|
||||||
feature={feature}
|
feature={feature}
|
||||||
onChange={this.props.onFeatureChanged}
|
onChange={this.props.onFeatureChanged}
|
||||||
onArchive={this.props.onFeatureArchive}/>
|
onArchive={this.props.onFeatureArchive}
|
||||||
|
strategies={this.props.strategies}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|
||||||
@ -83,4 +86,4 @@ var FeatureList = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = FeatureList;
|
module.exports = FeatureList;
|
||||||
|
@ -4,6 +4,7 @@ var FeatureForm = require('./FeatureForm');
|
|||||||
var FeatureActions = require('../../stores/FeatureToggleActions');
|
var FeatureActions = require('../../stores/FeatureToggleActions');
|
||||||
var ErrorActions = require('../../stores/ErrorActions');
|
var ErrorActions = require('../../stores/ErrorActions');
|
||||||
var FeatureToggleStore = require('../../stores/FeatureToggleStore');
|
var FeatureToggleStore = require('../../stores/FeatureToggleStore');
|
||||||
|
var StrategyStore = require('../../stores/StrategyStore');
|
||||||
|
|
||||||
var FeatureTogglesComponent = React.createClass({
|
var FeatureTogglesComponent = React.createClass({
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
@ -59,13 +60,17 @@ var FeatureTogglesComponent = React.createClass({
|
|||||||
onFeatureArchive={this.archiveFeature}
|
onFeatureArchive={this.archiveFeature}
|
||||||
onFeatureSubmit={this.createFeature}
|
onFeatureSubmit={this.createFeature}
|
||||||
onFeatureCancel={this.cancelNewFeature}
|
onFeatureCancel={this.cancelNewFeature}
|
||||||
onNewFeature={this.newFeature} />
|
onNewFeature={this.newFeature}
|
||||||
|
strategies={StrategyStore.getStrategies()} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
renderCreateView: function() {
|
renderCreateView: function() {
|
||||||
return <FeatureForm onCancel={this.cancelNewFeature} onSubmit={this.createFeature} />;
|
return <FeatureForm
|
||||||
|
onCancel={this.cancelNewFeature}
|
||||||
|
onSubmit={this.createFeature}
|
||||||
|
strategies={StrategyStore.getStrategies()} />;
|
||||||
},
|
},
|
||||||
|
|
||||||
renderCreateButton: function() {
|
renderCreateButton: function() {
|
||||||
|
@ -1,36 +1,27 @@
|
|||||||
var React = require('react');
|
var React = require('react');
|
||||||
var StrategyList = require('./StrategyList');
|
var StrategyList = require('./StrategyList');
|
||||||
var StrategyForm = require('./StrategyForm');
|
var StrategyForm = require('./StrategyForm');
|
||||||
var strategyStore = require('../../stores/StrategyStore');
|
var StrategyStore = require('../../stores/StrategyStore');
|
||||||
var ErrorActions = require('../../stores/ErrorActions');
|
var StrategyActions = require('../../stores/StrategyActions');
|
||||||
|
|
||||||
var StrategiesComponent = React.createClass({
|
var StrategiesComponent = React.createClass({
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
createView: false,
|
createView: false,
|
||||||
strategies: []
|
strategies: StrategyStore.getStrategies()
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidMount: function () {
|
onStoreChange: function() {
|
||||||
this.fetchStrategies();
|
this.setState({
|
||||||
|
strategies: StrategyStore.getStrategies()
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
componentDidMount: function() {
|
||||||
fetchStrategies: function() {
|
this.unsubscribe = StrategyStore.listen(this.onStoreChange);
|
||||||
strategyStore.getStrategies()
|
|
||||||
.then(function(res) {
|
|
||||||
this.setState({strategies: res.strategies});
|
|
||||||
}.bind(this))
|
|
||||||
.catch(this.initError);
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
componentWillUnmount: function() {
|
||||||
initError: function() {
|
this.unsubscribe();
|
||||||
this.onError("Could not load inital strategies from server");
|
|
||||||
},
|
|
||||||
|
|
||||||
onError: function(error) {
|
|
||||||
ErrorActions.error(error);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onNewStrategy: function() {
|
onNewStrategy: function() {
|
||||||
@ -42,32 +33,19 @@ var StrategiesComponent = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
onSave: function(strategy) {
|
onSave: function(strategy) {
|
||||||
function handleSuccess() {
|
StrategyActions.create.triggerPromise(strategy)
|
||||||
var strategies = this.state.strategies.concat([strategy]);
|
.then(this.onCancelNewStrategy);
|
||||||
|
|
||||||
this.setState({
|
|
||||||
createView: false,
|
|
||||||
strategies: strategies
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log("Saved strategy: ", strategy);
|
|
||||||
}
|
|
||||||
|
|
||||||
strategyStore.createStrategy(strategy)
|
|
||||||
.then(handleSuccess.bind(this))
|
|
||||||
.catch(this.onError);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onRemove: function(strategy) {
|
onRemove: function(strategy) {
|
||||||
strategyStore.removeStrategy(strategy)
|
StrategyActions.remove.triggerPromise(strategy);
|
||||||
.then(this.fetchStrategies)
|
|
||||||
.catch(this.onError);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{this.state.createView ? this.renderCreateView() : this.renderCreateButton()}
|
{this.state.createView ?
|
||||||
|
this.renderCreateView() : this.renderCreateButton()}
|
||||||
<hr />
|
<hr />
|
||||||
<StrategyList
|
<StrategyList
|
||||||
strategies={this.state.strategies}
|
strategies={this.state.strategies}
|
||||||
@ -82,15 +60,15 @@ var StrategiesComponent = React.createClass({
|
|||||||
onCancelNewStrategy={this.onCancelNewStrategy}
|
onCancelNewStrategy={this.onCancelNewStrategy}
|
||||||
onSave={this.onSave}
|
onSave={this.onSave}
|
||||||
/>);
|
/>);
|
||||||
},
|
},
|
||||||
|
|
||||||
renderCreateButton: function() {
|
renderCreateButton: function() {
|
||||||
return (
|
return (
|
||||||
<button className="mal" onClick={this.onNewStrategy}>
|
<button className="mal" onClick={this.onNewStrategy}>
|
||||||
Create strategy
|
Create strategy
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = StrategiesComponent;
|
module.exports = StrategiesComponent;
|
||||||
|
52
public/js/stores/StrategyAPI.js
Normal file
52
public/js/stores/StrategyAPI.js
Normal 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;
|
29
public/js/stores/StrategyActions.js
Normal file
29
public/js/stores/StrategyActions.js
Normal 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;
|
@ -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 _strategies = [];
|
||||||
var CONTENT_TYPE = 'application/json';
|
|
||||||
|
|
||||||
var StrategyStore = {
|
// Creates a DataStore
|
||||||
createStrategy: function (strategy) {
|
var StrategyStore = Reflux.createStore({
|
||||||
return reqwest({
|
|
||||||
url: 'strategies',
|
// Initial setup
|
||||||
method: 'post',
|
init: function() {
|
||||||
type: TYPE,
|
this.listenTo(StrategyActions.create.completed, this.onCreate);
|
||||||
contentType: CONTENT_TYPE,
|
this.listenTo(StrategyActions.remove.completed, this.onRemove);
|
||||||
data: JSON.stringify(strategy)
|
this.loadDataFromServer();
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
removeStrategy: function (strategy) {
|
loadDataFromServer: function() {
|
||||||
return reqwest({
|
//TODO: this should not be part of the store!
|
||||||
url: 'strategies/'+strategy.name,
|
StrategyAPI.getStrategies(function(err, strategies) {
|
||||||
method: 'delete',
|
|
||||||
type: TYPE
|
if(err) {
|
||||||
});
|
ErrorActions.error(err);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
this.setStrategies(strategies);
|
||||||
|
}
|
||||||
|
}.bind(this));
|
||||||
},
|
},
|
||||||
|
|
||||||
getStrategies: function () {
|
onCreate: function(strategy) {
|
||||||
return reqwest({
|
this.setStrategies(_strategies.concat([strategy]));
|
||||||
url: 'strategies',
|
},
|
||||||
method: 'get',
|
|
||||||
type: TYPE
|
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;
|
module.exports = StrategyStore;
|
||||||
|
Loading…
Reference in New Issue
Block a user