/** @jsx React.DOM */ /* jshint quotmark:false */ // FeatureListPage // Meny // FeatureList // Feature // FeatureViewer // - props // - button-edit // - button-delete // - toggle-status // FeatureEditor // - name // - status // - description // // NewFeaturePage // Meny // NewFeatureForm var FeatureEditor = React.createClass({ handleSubmit: function(e) { e.preventDefault(); this.props.onSubmit(this.props.feature); return; }, render: function () { return (
Edit/new feature

Give the feature a name

Describe the feature


); } }); 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 }); }, render: function () { return (

{this.props.feature.name}

{this.props.feature.description}


); } }); var Feature = React.createClass({ getInitialState: function() { return { mode: 'view', error: '' }; }, onToggleMode: function() { if (this.isInViewMode()) { this.setState({mode: 'edit'}); } else if (this.isInEditMode()) { this.setState({mode: 'view'}); } else { throw "invalid mode: " + this.state.mode; } }, onSubmit: function() { var isNew = false; var cb = function(err) { if (err) { this.setState({error: err}); } else { this.setState(this.getInitialState()); } }; if (isNew) { this.props.createFeature(this.props.feature, cb.bind(this)); } else { this.props.updateFeature(this.props.feature, cb.bind(this)); } }, render: function() { if (this.isInViewMode()) { return ( ); } else if (this.isInEditMode()) { return ( ); } else { throw "invalid mode: " + this.state.mode; } }, isInViewMode: function() { return this.state.mode === 'view'; }, isInEditMode: function() { return this.state.mode === 'edit'; } }); var FeatureList = React.createClass({ getInitialState: function() { return { features: [] }; }, componentDidMount: function () { 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, callback) { var newFeatures = this.state.features; newFeatures.forEach(function(f){ if(f.name === changeRequest.name) { f[changeRequest.field] = changeRequest.value; } }); reqwest({ url: 'features/' + changeRequest.name, method: 'patch', type: 'json', contentType: 'application/json', data: JSON.stringify(changeRequest) }).then(function() { this.setState({features: newFeatures}); callback(); }.bind(this), function() { callback('update failed'); window.alert('update failed'); }.bind(this)); }, createFeature: function (feature, callback) { reqwest({ url: 'features', method: 'post', type: 'json', contentType: 'application/json', data: JSON.stringify(feature) }).then(function() { callback(); }.bind(this), function() { callback('create failed'); window.alert('create failed'); }.bind(this)); }, render: function () { var featureNodes = this.state.features.map(function (feature) { return ( ); }.bind(this)); return (

Features

{featureNodes}
); } }); React.renderComponent( , document.getElementById('content') );