diff --git a/lib/eventType.js b/lib/eventType.js index 029516a712..98078a4188 100644 --- a/lib/eventType.js +++ b/lib/eventType.js @@ -1,6 +1,7 @@ module.exports = { featureCreated : 'feature-created', featureUpdated : 'feature-updated', + featureArchive : 'feature-archive', strategyCreated: 'strategy-created', strategyDeleted: 'strategy-deleted' }; \ No newline at end of file diff --git a/lib/featureApi.js b/lib/featureApi.js index fe9bd715b8..65718febd4 100644 --- a/lib/featureApi.js +++ b/lib/featureApi.js @@ -79,6 +79,32 @@ module.exports = function (app) { }); }); + app.delete('/features/:featureName', function (req, res) { + var featureName = req.params.featureName; + var userName = req.connection.remoteAddress; + + featureDb.getFeature(featureName) + .then(function () { + return eventStore.create({ + type: eventType.featureArchive, + createdBy: userName, + data: { + name: featureName + } + }); + }) + .then(function () { + res.status(200).end(); + }) + .catch(NotFoundError, function () { + res.status(404).end(); + }) + .catch(function (err) { + logger.error("Could not archive feature="+featureName, err); + res.status(500).end(); + }); + }); + function validateUniqueName(req) { return new Promise(function(resolve, reject) { featureDb.getFeature(req.body.name) diff --git a/lib/featureDb.js b/lib/featureDb.js index f1f5334b35..5acb14cf8b 100644 --- a/lib/featureDb.js +++ b/lib/featureDb.js @@ -13,10 +13,15 @@ eventStore.on(eventType.featureUpdated, function (event) { return updateFeature(event.data); }); +eventStore.on(eventType.featureArchive, function (event) { + return archiveFeature(event.data); +}); + function getFeatures() { return knex .select(FEATURE_COLUMNS) .from('features') + .where({archived: 0}) .orderBy('name', 'asc') .map(rowToFeature); } @@ -70,6 +75,16 @@ function updateFeature(data) { }); } +function archiveFeature(data) { + return knex('features') + .where({name: data.name}) + .update({archived: 1}) + .catch(function (err) { + logger.error('Could not archive feature, error was: ', err); + }); +} + + module.exports = { getFeatures: getFeatures, getFeature: getFeature, diff --git a/public/js/components/feature/Feature.jsx b/public/js/components/feature/Feature.jsx index 47bc20f1e6..30b1913930 100644 --- a/public/js/components/feature/Feature.jsx +++ b/public/js/components/feature/Feature.jsx @@ -33,6 +33,12 @@ var Feature = React.createClass({ this.toggleEditMode(); }, + archiveFeature: function() { + if (confirm("Are you sure you want to delete " + this.props.feature.name + "?")) { + this.props.onArchive(this.props.feature); + } + }, + renderEditMode: function() { return ( @@ -64,14 +70,19 @@ var Feature = React.createClass({ {this.props.feature.strategy} - +
-
+
+ +
+
-
+
diff --git a/public/js/components/feature/FeatureList.jsx b/public/js/components/feature/FeatureList.jsx index f344e71507..6831c38121 100644 --- a/public/js/components/feature/FeatureList.jsx +++ b/public/js/components/feature/FeatureList.jsx @@ -8,7 +8,8 @@ var FeatureList = React.createClass({ + onChange={this.props.onFeatureChanged} + onArchive={this.props.onFeatureArchive}/> ); }.bind(this)); diff --git a/public/js/components/feature/FeatureTogglesComponent.jsx b/public/js/components/feature/FeatureTogglesComponent.jsx index 4f2d86e612..d3f732d26c 100644 --- a/public/js/components/feature/FeatureTogglesComponent.jsx +++ b/public/js/components/feature/FeatureTogglesComponent.jsx @@ -55,6 +55,15 @@ var FeatureTogglesComponent = React.createClass({ .catch(this.handleError); }, + archiveFeature: function (feature) { + this.stopFeaturePoller(); + + this.state.featureStore + .archiveFeature(feature) + .then(this.startFeaturePoller) + .catch(this.handleError); + }, + startFeaturePoller: function () { this.state.featurePoller.start(); }, @@ -121,6 +130,7 @@ var FeatureTogglesComponent = React.createClass({ diff --git a/public/js/stores/FeatureStore.js b/public/js/stores/FeatureStore.js index b70dbd2932..1cb85f6504 100644 --- a/public/js/stores/FeatureStore.js +++ b/public/js/stores/FeatureStore.js @@ -27,6 +27,14 @@ FeatureStore.prototype = { }); }, + archiveFeature: function (feature) { + return reqwest({ + url: 'features/' + feature.name, + method: 'delete', + type: TYPE + }); + }, + getFeatures: function () { return reqwest({ url: 'features',