mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	Pass strategies as props
This commit is contained in:
		
							parent
							
								
									f11cd291c2
								
							
						
					
					
						commit
						08600fa7ee
					
				| @ -17,7 +17,7 @@ describe("FeatureForm", function () { | ||||
|         ]; | ||||
| 
 | ||||
|         Server.getArchivedFeatures.mockImplementation(function(cb) { | ||||
|           cb(archivedToggles); | ||||
|           cb(null, archivedToggles); | ||||
|         }); | ||||
| 
 | ||||
|         FeatureToggleStore.initStore(archivedToggles); | ||||
|  | ||||
| @ -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)"); | ||||
|         }); | ||||
|     }); | ||||
| 
 | ||||
| }); | ||||
| }); | ||||
|  | ||||
| @ -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); | ||||
|     }); | ||||
| 
 | ||||
| }); | ||||
| }); | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
| @ -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() { | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
							
								
								
									
										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 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; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user