1
0
mirror of https://github.com/Unleash/unleash.git synced 2024-10-18 20:09:08 +02:00
unleash.unleash/unleash-server/public/js/unleash.jsx

272 lines
8.9 KiB
React
Raw Normal View History

2014-10-21 18:57:05 +02:00
/** @jsx React.DOM */
/* jshint quotmark:false */
// FeatureListPage
// Meny
// FeatureList
// Feature
2014-10-23 16:00:13 +02:00
// FeatureViewer
// - props
// - button-edit
// - button-delete
// - toggle-status
2014-10-23 16:00:13 +02:00
// FeatureEditor
// - name
// - status
// - description
//
// NewFeaturePage
// Meny
// NewFeatureForm
2014-10-21 18:57:05 +02:00
2014-10-23 16:00:13 +02:00
var FeatureEditor = React.createClass({
2014-10-23 14:30:02 +02:00
2014-10-23 15:16:09 +02:00
getInitialState: function () {
return {name: '', description: '', strategy: 'Default'};
},
handleNameChange: function(e) { this.setState({name: e.target.value.trim()}); },
handleDescriptionChange: function(e) { this.setState({description: e.target.value.trim()}); },
handleStrategyChange: function(e) { this.setState({strategy: e.target.value.trim()}); },
handleSubmit: function(e) {
e.preventDefault();
this.props.onFeatureSubmit(this.state);
return;
},
2014-10-23 14:30:02 +02:00
render: function () {
return (
2014-10-23 15:16:09 +02:00
<form className="form-horizontal" onSubmit={this.handleSubmit}>
2014-10-23 14:30:02 +02:00
<fieldset>
<legend>Add a new feature</legend>
<div className="control-group">
2014-10-23 15:16:09 +02:00
<label className="control-label" htmlFor="name">Name </label>
2014-10-23 14:30:02 +02:00
<div className="controls">
2014-10-23 15:16:09 +02:00
<input
id="name"
type="text"
placeholder="Superfeature"
className="input-large"
required=""
onChange={this.handleNameChange}
value={this.state.name} />
2014-10-23 14:30:02 +02:00
<p className="help-block">Give the feature a name</p>
</div>
</div>
<div className="control-group">
2014-10-23 15:16:09 +02:00
<label className="control-label" htmlFor="description">Description</label>
2014-10-23 14:30:02 +02:00
<div className="controls">
2014-10-23 15:16:09 +02:00
<input
id="description"
type="text"
placeholder="It does this and that "
className="input-large"
onChange={this.handleDescriptionChange}
value={this.state.description} />
2014-10-23 14:30:02 +02:00
<p className="help-block">Describe the feature</p>
</div>
</div>
<div className="control-group">
2014-10-23 15:16:09 +02:00
<label className="control-label" htmlFor="strategy">Strategy</label>
2014-10-23 14:30:02 +02:00
<div className="controls">
2014-10-23 15:16:09 +02:00
<select
id="strategy"
className="input-large"
onChange={this.handleStrategyChange}
value={this.state.strategy}>
<option value="Default">Default</option>
2014-10-23 14:30:02 +02:00
</select>
</div>
</div>
<div className="control-group">
<div className="controls">
2014-10-23 15:16:09 +02:00
<input type="submit" value="Save" className="btn btn-success" />
2014-10-23 16:00:13 +02:00
<input
type="button"
value="Cancel"
className="btn"
onClick={this.props.onToggleMode} />
2014-10-23 14:30:02 +02:00
</div>
</div>
</fieldset>
</form>
);
}
});
2014-10-23 16:00:13 +02:00
var FeatureViewer = React.createClass({
// TODO: validate props?
handleEnableChange: function(event) {
var feature = this.props.feature;
this.props.updateFeature({
name: feature.name,
field: 'enabled',
value: event.target.checked
2014-10-23 16:00:13 +02:00
});
},
render: function () {
return (
<div>
<div className='line'>
<div className='unit r-size1of3'>
<div className='mod'>
<div className='inner'>
<div className='bd'>
<p>{this.props.feature.name}</p>
<p className='neutral'>{this.props.feature.description}</p>
</div>
</div>
</div>
</div>
<div className='unit r-size1of3'>
<div className='mod'>
<div className='inner'>
<div className='bd'>
<p>
<label>
{this.props.feature.status}
<input
type='checkbox'
checked={this.props.feature.enabled}
className='mll'
onChange={this.handleEnableChange}
/>
</label>
</p>
</div>
</div>
</div>
</div>
2014-10-21 18:57:05 +02:00
<div className='unit r-size1of3'>
<div className='mod'>
<div className='inner'>
<div className='bd'>
2014-10-23 16:00:13 +02:00
<button className='pam mtl mll' onClick={this.props.onToggleMode}>Edit</button>
<button className='pam mtl mll'>Delete</button>
</div>
</div>
</div>
</div>
</div>
<hr />
</div>
);
}
});
2014-10-21 18:57:05 +02:00
2014-10-23 16:00:13 +02:00
var Feature = React.createClass({
getInitialState: function() {
return { mode: 'view' };
},
onToggleMode: function() {
if (this.state.mode === 'view') {
this.setState({mode: 'edit'});
} else if (this.state.mode === 'edit') {
this.setState({mode: 'view'});
} else {
throw "invalid mode: " + this.state.mode;
}
},
render: function() {
if (this.state.mode === 'view') {
return (<FeatureViewer feature={this.props.feature} onToggleMode={this.onToggleMode} />);
} else if (this.state.mode === 'edit') {
return (<FeatureEditor feature={this.props.feature} onToggleMode={this.onToggleMode} />);
} else {
throw "invalid mode: " + this.state.mode;
}
}
});
2014-10-21 18:57:05 +02:00
var FeatureList = React.createClass({
getInitialState: function() {
return {
features: []
};
},
componentDidMount: function () {
2014-10-23 15:30:38 +02:00
this.loadFeaturesFromServer();
setInterval(this.loadFeaturesFromServer, this.props.pollInterval);
},
loadFeaturesFromServer: function () {
reqwest('/features').then(this.setFeatures);
},
setFeatures: function (data) {
this.setState({features: data.features});
},
updateFeature: function (changeRequest) {
var newFeatures = this.state.features;
newFeatures.forEach(function(f){
if(f.name === changeRequest.name) {
f[changeRequest.field] = changeRequest.value;
}
});
2014-10-23 15:16:09 +02:00
reqwest({
url: 'features/' + changeRequest.name,
method: 'patch',
type: 'json',
contentType: 'application/json',
data: JSON.stringify(changeRequest)
}).then(function() {
this.setState({features: newFeatures});
}.bind(this), function() {
window.alert('update failed');
}.bind(this));
2014-10-21 18:57:05 +02:00
},
2014-10-23 16:00:13 +02:00
createFeature: function (feature) {
2014-10-23 15:16:09 +02:00
reqwest({
url: 'features',
method: 'post',
type: 'json',
contentType: 'application/json',
data: JSON.stringify(feature)
}).then(function() {
// how do we communicate success?
}.bind(this), function() {
window.alert('create failed');
}.bind(this));
},
2014-10-21 18:57:05 +02:00
render: function () {
var featureNodes = this.state.features.map(function (feature) {
return (
<Feature feature={feature} updateFeature={this.updateFeature} />
2014-10-21 18:57:05 +02:00
);
}.bind(this));
2014-10-21 18:57:05 +02:00
return (
<div className='panel panel-primary'>
<div className='panel-heading'>
<h3 className='panel-title'>Features</h3>
2014-10-21 18:57:05 +02:00
</div>
<div className='panel-body'>
{featureNodes}
2014-10-21 18:57:05 +02:00
</div>
</div>
);
}
});
React.renderComponent(
2014-10-23 15:30:38 +02:00
<FeatureList pollInterval={1000} />,
2014-10-21 18:57:05 +02:00
document.getElementById('content')
);