1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-01-20 00:08:02 +01:00

Merge pull request #45 from Unleash/use-toggle-endpoint

use toggle-endpoint, cleanup strategy sort IDs
This commit is contained in:
Sveinung Røsaker 2017-01-09 11:29:25 +01:00 committed by GitHub
commit e9581733dd
9 changed files with 50 additions and 12 deletions

View File

@ -8,7 +8,7 @@ import styles from './feature.scss';
const Feature = ({ const Feature = ({
feature, feature,
onFeatureClick, toggleFeature,
settings, settings,
metricsLastHour = { yes: 0, no: 0, isFallback: true }, metricsLastHour = { yes: 0, no: 0, isFallback: true },
metricsLastMinute = { yes: 0, no: 0, isFallback: true }, metricsLastMinute = { yes: 0, no: 0, isFallback: true },
@ -39,7 +39,7 @@ const Feature = ({
</div> </div>
</span> </span>
<span className={styles.iconListItemToggle}> <span className={styles.iconListItemToggle}>
<Switch title={`Toggle ${name}`} key="left-actions" onChange={() => onFeatureClick(feature)} checked={enabled} /> <Switch title={`Toggle ${name}`} key="left-actions" onChange={() => toggleFeature(name)} checked={enabled} />
</span> </span>
<span className={['mdl-list__item-primary-content', commonStyles.truncate].join(' ')}> <span className={['mdl-list__item-primary-content', commonStyles.truncate].join(' ')}>
<Link to={`/features/view/${name}`} className={[styles.link, commonStyles.truncate].join(' ')}> <Link to={`/features/view/${name}`} className={[styles.link, commonStyles.truncate].join(' ')}>
@ -58,7 +58,7 @@ const Feature = ({
Feature.propTypes = { Feature.propTypes = {
feature: PropTypes.object, feature: PropTypes.object,
onFeatureClick: PropTypes.func, toggleFeature: PropTypes.func,
}; };
export default Feature; export default Feature;

View File

@ -19,6 +19,11 @@ const prepare = (methods, dispatch) => {
methods.onSubmit = (input) => ( methods.onSubmit = (input) => (
(e) => { (e) => {
e.preventDefault(); e.preventDefault();
input.strategies.forEach((s) => {
delete s.id;
});
createFeatureToggles(input)(dispatch) createFeatureToggles(input)(dispatch)
.then(() => methods.clear()) .then(() => methods.clear())
.then(() => hashHistory.push(`/features/edit/${input.name}`)); .then(() => hashHistory.push(`/features/edit/${input.name}`));

View File

@ -29,6 +29,10 @@ const prepare = (methods, dispatch) => {
methods.onSubmit = (input) => ( methods.onSubmit = (input) => (
(e) => { (e) => {
e.preventDefault(); e.preventDefault();
input.strategies.forEach((s) => {
delete s.id;
});
// TODO: should add error handling // TODO: should add error handling
requestUpdateFeatureToggle(input)(dispatch) requestUpdateFeatureToggle(input)(dispatch)
.then(() => methods.clear()) .then(() => methods.clear())

View File

@ -9,7 +9,7 @@ export default class FeatureListComponent extends React.PureComponent {
static propTypes () { static propTypes () {
return { return {
onFeatureClick: PropTypes.func.isRequired, toggleFeature: PropTypes.func.isRequired,
features: PropTypes.array.isRequired, features: PropTypes.array.isRequired,
featureMetrics: PropTypes.object.isRequired, featureMetrics: PropTypes.object.isRequired,
fetchFeatureToggles: PropTypes.func.isRequired, fetchFeatureToggles: PropTypes.func.isRequired,
@ -46,7 +46,7 @@ export default class FeatureListComponent extends React.PureComponent {
} }
render () { render () {
const { features, onFeatureClick, featureMetrics, settings } = this.props; const { features, toggleFeature, featureMetrics, settings } = this.props;
return ( return (
<div> <div>
@ -103,7 +103,7 @@ export default class FeatureListComponent extends React.PureComponent {
metricsLastHour={featureMetrics.lastHour[feature.name]} metricsLastHour={featureMetrics.lastHour[feature.name]}
metricsLastMinute={featureMetrics.lastMinute[feature.name]} metricsLastMinute={featureMetrics.lastMinute[feature.name]}
feature={feature} feature={feature}
onFeatureClick={onFeatureClick}/> toggleFeature={toggleFeature}/>
)} )}
</ul> </ul>
<hr /> <hr />

View File

@ -70,7 +70,7 @@ const mapStateToProps = (state) => {
}; };
const mapDispatchToProps = { const mapDispatchToProps = {
onFeatureClick: toggleFeature, toggleFeature,
fetchFeatureToggles, fetchFeatureToggles,
fetchFeatureMetrics, fetchFeatureMetrics,
updateSetting: updateSettingForGroup('feature'), updateSetting: updateSettingForGroup('feature'),

View File

@ -92,7 +92,7 @@ export default class ViewFeatureToggleComponent extends React.Component {
return ( return (
<div> <div>
<h4> <h4>
<SwitchWithLabel checked={featureToggle.enabled} onChange={() => toggleFeature(featureToggle)} /> <SwitchWithLabel checked={featureToggle.enabled} onChange={() => toggleFeature(featureToggle.name)} />
{featureToggle.name} <small>{featureToggle.enabled ? 'is enabled' : 'is disabled'}</small> {featureToggle.name} <small>{featureToggle.enabled ? 'is enabled' : 'is disabled'}</small>
<IconButton style={{ float: 'right' }} name="delete" onClick={removeToggle} className="mdl-color-text--grey-600" /> <IconButton style={{ float: 'right' }} name="delete" onClick={removeToggle} className="mdl-color-text--grey-600" />

View File

@ -50,6 +50,15 @@ function update (featureToggle) {
.then(throwIfNotSuccess); .then(throwIfNotSuccess);
} }
function toggle (name) {
return fetch(`${URI}/${name}/toggle`, {
method: 'POST',
headers,
credentials: 'include',
})
.then(throwIfNotSuccess);
}
function remove (featureToggleName) { function remove (featureToggleName) {
return fetch(`${URI}/${featureToggleName}`, { return fetch(`${URI}/${featureToggleName}`, {
method: 'DELETE', method: 'DELETE',
@ -62,5 +71,6 @@ module.exports = {
create, create,
validate, validate,
update, update,
toggle,
remove, remove,
}; };

View File

@ -15,11 +15,10 @@ export const ERROR_CREATING_FEATURE_TOGGLE = 'ERROR_CREATING_FEATURE_TOGGLE';
export const ERROR_UPDATE_FEATURE_TOGGLE = 'ERROR_UPDATE_FEATURE_TOGGLE'; export const ERROR_UPDATE_FEATURE_TOGGLE = 'ERROR_UPDATE_FEATURE_TOGGLE';
export const ERROR_REMOVE_FEATURE_TOGGLE = 'ERROR_REMOVE_FEATURE_TOGGLE'; export const ERROR_REMOVE_FEATURE_TOGGLE = 'ERROR_REMOVE_FEATURE_TOGGLE';
export function toggleFeature (featureToggle) { export function toggleFeature (name) {
debug('Toggle feature toggle ', featureToggle); debug('Toggle feature toggle ', name);
return dispatch => { return dispatch => {
const newValue = Object.assign({}, featureToggle, { enabled: !featureToggle.enabled }); dispatch(requestToggleFeatureToggle(name));
dispatch(requestUpdateFeatureToggle(newValue));
}; };
}; };
@ -68,6 +67,16 @@ export function createFeatureToggles (featureToggle) {
}; };
} }
export function requestToggleFeatureToggle (name) {
return dispatch => {
dispatch({ type: START_UPDATE_FEATURE_TOGGLE });
return api.toggle(name)
.then(() => dispatch({ type: TOGGLE_FEATURE_TOGGLE, name }))
.catch(dispatchAndThrow(dispatch, ERROR_UPDATE_FEATURE_TOGGLE));
};
}
export function requestUpdateFeatureToggle (featureToggle) { export function requestUpdateFeatureToggle (featureToggle) {
return dispatch => { return dispatch => {
dispatch({ type: START_UPDATE_FEATURE_TOGGLE }); dispatch({ type: START_UPDATE_FEATURE_TOGGLE });

View File

@ -7,6 +7,7 @@ import {
RECEIVE_FEATURE_TOGGLES, RECEIVE_FEATURE_TOGGLES,
UPDATE_FEATURE_TOGGLE, UPDATE_FEATURE_TOGGLE,
REMOVE_FEATURE_TOGGLE, REMOVE_FEATURE_TOGGLE,
TOGGLE_FEATURE_TOGGLE,
} from './feature-actions'; } from './feature-actions';
@ -18,6 +19,15 @@ const features = (state = new List([]), action) => {
case REMOVE_FEATURE_TOGGLE: case REMOVE_FEATURE_TOGGLE:
debug(REMOVE_FEATURE_TOGGLE, action); debug(REMOVE_FEATURE_TOGGLE, action);
return state.filter(toggle => toggle.get('name') !== action.featureToggleName); return state.filter(toggle => toggle.get('name') !== action.featureToggleName);
case TOGGLE_FEATURE_TOGGLE:
debug(TOGGLE_FEATURE_TOGGLE, action);
return state.map(toggle => {
if (toggle.get('name') === action.name) {
return toggle.set('enabled', !toggle.get('enabled'));
} else {
return toggle;
}
});
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 => {