1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-01-06 00:07:44 +01:00

Implement Feature Toggle Delete

This commit is contained in:
ivaosthu 2016-10-22 18:14:16 +02:00
parent fb2c9538dd
commit d9bc649bad
9 changed files with 52 additions and 14 deletions

View File

@ -75,8 +75,8 @@ class ConfigureStrategy extends React.Component {
{this.renderInputFields(selectedStrategy)} {this.renderInputFields(selectedStrategy)}
<Button raised mini accent label="cancel" onClick={this.props.cancelConfig} /> <Button icon="add" accent label="add strategy" onClick={this.addStrategy} />
<Button raised mini label="add strategy" onClick={this.addStrategy} /> <Button label="cancel" onClick={this.props.cancelConfig} />
</div> </div>
); );
} }

View File

@ -1,5 +1,5 @@
import React, { PropTypes } from 'react'; import React, { PropTypes } from 'react';
import { Chip } from 'react-toolbox'; import { Avatar, Chip } from 'react-toolbox';
class ConfiguredStrategies extends React.Component { class ConfiguredStrategies extends React.Component {
static propTypes () { static propTypes () {
@ -10,9 +10,10 @@ class ConfiguredStrategies extends React.Component {
} }
renderName (strategy) { renderName (strategy) {
const params = Object.keys(strategy.parameters) const parameters = strategy.parameters || {};
.map(param => `${param}='${strategy.parameters[param]}'`) const params = Object.keys(parameters)
.join(', '); .map(param => `${param}="${strategy.parameters[param]}"`)
.join('; ');
return <span>{strategy.name} ({params})</span>; return <span>{strategy.name} ({params})</span>;
} }
@ -22,14 +23,16 @@ class ConfiguredStrategies extends React.Component {
<Chip <Chip
key={`${index}-${s.name}`} key={`${index}-${s.name}`}
deletable deletable
onDeleteClick={() => removeStrategy(s)}> onDeleteClick={() => removeStrategy(s)}
>
<Avatar icon="edit" />
{this.renderName(s)} {this.renderName(s)}
</Chip> </Chip>
)); ));
return ( return (
<div> <p>
{strategies.length > 0 ? strategies : <p>No activation strategies added</p>} {strategies.length > 0 ? strategies : <p>No activation strategies added</p>}
</div> </p>
); );
} }
} }

View File

@ -4,22 +4,27 @@ import React, { PropTypes } from 'react';
import { Switch, FontIcon } from 'react-toolbox'; import { Switch, FontIcon } from 'react-toolbox';
import { Link } from 'react-router'; import { Link } from 'react-router';
const Feature = ({ onClick, name, enabled, strategies }) => ( const Feature = ({ onClick, name, enabled, strategies, onFeatureRemove }) => (
<tr> <tr>
<td style={{ paddingTop: '1.5rem' }}><Switch onChange={onClick} checked={enabled} /></td> <td style={{ paddingTop: '1.5rem' }}><Switch onChange={onClick} checked={enabled} /></td>
<td><a href="/edit">{name}</a></td> <td>
<Link to={`/features/edit/${name}`} title={`Edit ${name}`}>
{name}
</Link>
</td>
<td>{strategies.map(s => s.name).join(', ')}</td> <td>{strategies.map(s => s.name).join(', ')}</td>
<td style={{ textAlign: 'right' }}> <td style={{ textAlign: 'right' }}>
<Link to={`/features/edit/${name}`} title={`Edit ${name}`}> <Link to={`/features/edit/${name}`} title={`Edit ${name}`}>
<FontIcon value="edit" /> <FontIcon value="edit" />
</Link> </Link>
<FontIcon value="delete" /> <FontIcon style={{ cursor: 'pointer' }} value="delete" onClick={onFeatureRemove} />
</td> </td>
</tr> </tr>
); );
Feature.propTypes = { Feature.propTypes = {
onClick: PropTypes.func.isRequired, onClick: PropTypes.func.isRequired,
onFeatureRemove: PropTypes.func.isRequired,
enabled: PropTypes.bool.isRequired, enabled: PropTypes.bool.isRequired,
strategies: PropTypes.array.isRequired, strategies: PropTypes.array.isRequired,
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,

View File

@ -10,6 +10,7 @@ export default class FeatureList extends React.Component {
static propTypes () { static propTypes () {
return { return {
onFeatureClick: PropTypes.func.isRequired, onFeatureClick: PropTypes.func.isRequired,
onFeatureRemove: PropTypes.func.isRequired,
features: PropTypes.array.isRequired, features: PropTypes.array.isRequired,
fetchFeatureToggles: PropTypes.array.isRequired, fetchFeatureToggles: PropTypes.array.isRequired,
}; };
@ -21,10 +22,12 @@ export default class FeatureList extends React.Component {
render () { render () {
const onFeatureClick = this.props.onFeatureClick; const onFeatureClick = this.props.onFeatureClick;
const onFeatureRemove = this.props.onFeatureRemove;
const features = this.props.features.map(featureToggle => const features = this.props.features.map(featureToggle =>
<Feature key={featureToggle.name} <Feature key={featureToggle.name}
{...featureToggle} {...featureToggle}
onClick={() => onFeatureClick(featureToggle)} onClick={() => onFeatureClick(featureToggle)}
onFeatureRemove={() => onFeatureRemove(featureToggle.name)}
/> />
); );

View File

@ -1,5 +1,5 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { toggleFeature, fetchFeatureToggles } from '../../store/feature-actions'; import { toggleFeature, fetchFeatureToggles, removeFeatureToggle } from '../../store/feature-actions';
import FeatureList from './FeatureList'; import FeatureList from './FeatureList';
const mapStateToProps = (state) => ({ const mapStateToProps = (state) => ({
@ -9,6 +9,7 @@ const mapStateToProps = (state) => ({
const mapDispatchToProps = { const mapDispatchToProps = {
onFeatureClick: toggleFeature, onFeatureClick: toggleFeature,
onFeatureRemove: removeFeatureToggle,
fetchFeatureToggles, fetchFeatureToggles,
}; };

View File

@ -1,7 +1,13 @@
import React, { Component } from 'react'; import React, { Component, PropTypes } from 'react';
import EditFeatureToggle from '../../component/feature/EditFeatureToggle'; import EditFeatureToggle from '../../component/feature/EditFeatureToggle';
export default class Features extends Component { export default class Features extends Component {
static propTypes () {
return {
params: PropTypes.object.isRequired,
};
}
static contextTypes = { static contextTypes = {
router: React.PropTypes.object, router: React.PropTypes.object,
} }

View File

@ -2,6 +2,7 @@ import api from './feature-api';
const debug = require('debug')('unleash:feature-actions'); const debug = require('debug')('unleash:feature-actions');
export const ADD_FEATURE_TOGGLE = 'ADD_FEATURE_TOGGLE'; export const ADD_FEATURE_TOGGLE = 'ADD_FEATURE_TOGGLE';
export const REMOVE_FEATURE_TOGGLE = 'REMOVE_FEATURE_TOGGLE';
export const UPDATE_FEATURE_TOGGLE = 'UPDATE_FEATURE_TOGGLE'; export const UPDATE_FEATURE_TOGGLE = 'UPDATE_FEATURE_TOGGLE';
export const TOGGLE_FEATURE_TOGGLE = 'TOGGLE_FEATURE_TOGGLE'; export const TOGGLE_FEATURE_TOGGLE = 'TOGGLE_FEATURE_TOGGLE';
export const REQUEST_FEATURE_TOGGLES = 'REQUEST_FEATURE_TOGGLES'; export const REQUEST_FEATURE_TOGGLES = 'REQUEST_FEATURE_TOGGLES';
@ -11,6 +12,7 @@ export const RECEIVE_FEATURE_TOGGLES = 'RECEIVE_FEATURE_TOGGLES';
export const ERROR_RECEIVE_FEATURE_TOGGLES = 'ERROR_RECEIVE_FEATURE_TOGGLES'; export const ERROR_RECEIVE_FEATURE_TOGGLES = 'ERROR_RECEIVE_FEATURE_TOGGLES';
export const ERROR_CREATING_FEATURE_TOGGLE = 'ERROR_CREATING_FEATURE_TOGGLE'; export const ERROR_CREATING_FEATURE_TOGGLE = 'ERROR_CREATING_FEATURE_TOGGLE';
export const ERROR_UPDATING_FEATURE_TOGGLE = 'ERROR_UPDATING_FEATURE_TOGGLE'; export const ERROR_UPDATING_FEATURE_TOGGLE = 'ERROR_UPDATING_FEATURE_TOGGLE';
export const ERROR_REMOVE_FEATURE_TOGGLE = 'ERROR_REMOVE_FEATURE_TOGGLE';
function addFeatureToggle (featureToggle) { function addFeatureToggle (featureToggle) {
return { return {
@ -123,3 +125,10 @@ export function requestUpdateFeatureToggle (featureToggle) {
}; };
} }
export function removeFeatureToggle (featureToggleName) {
return dispatch => (api.remove(featureToggleName)
.then(() => dispatch({ type: REMOVE_FEATURE_TOGGLE, featureToggleName }))
.catch(error => dispatch({ type: ERROR_REMOVE_FEATURE_TOGGLE, featureToggleName, error }))
);
}

View File

@ -36,8 +36,15 @@ function update (featureToggle) {
}).then(throwIfNotSuccess); }).then(throwIfNotSuccess);
} }
function remove (featureToggleName) {
return fetch(`${URI}/${featureToggleName}`, {
method: 'DELETE',
}).then(throwIfNotSuccess);
}
module.exports = { module.exports = {
fetchAll, fetchAll,
create, create,
update, update,
remove,
}; };

View File

@ -6,6 +6,7 @@ import {
ADD_FEATURE_TOGGLE, ADD_FEATURE_TOGGLE,
RECEIVE_FEATURE_TOGGLES, RECEIVE_FEATURE_TOGGLES,
UPDATE_FEATURE_TOGGLE, UPDATE_FEATURE_TOGGLE,
REMOVE_FEATURE_TOGGLE,
} from './feature-actions'; } from './feature-actions';
@ -14,6 +15,9 @@ const features = (state = new List([]), action) => {
case ADD_FEATURE_TOGGLE: case ADD_FEATURE_TOGGLE:
debug(ADD_FEATURE_TOGGLE, action); debug(ADD_FEATURE_TOGGLE, action);
return state.push(new $Map(action.featureToggle)); return state.push(new $Map(action.featureToggle));
case REMOVE_FEATURE_TOGGLE:
debug(REMOVE_FEATURE_TOGGLE, action);
return state.filter(toggle => toggle.get('name') !== action.featureToggleName);
case UPDATE_FEATURE_TOGGLE: case UPDATE_FEATURE_TOGGLE:
debug(UPDATE_FEATURE_TOGGLE, action); debug(UPDATE_FEATURE_TOGGLE, action);
return state.map(toggle => { return state.map(toggle => {