diff --git a/packages/unleash-frontend-next/src/component/feature/Feature.jsx b/packages/unleash-frontend-next/src/component/feature/Feature.jsx index 022b95a2ab..c975e20160 100644 --- a/packages/unleash-frontend-next/src/component/feature/Feature.jsx +++ b/packages/unleash-frontend-next/src/component/feature/Feature.jsx @@ -7,7 +7,7 @@ const Feature = ({ onClick, name, enabled, strategies }) => ( {name} - {strategies.map(s => `${s.name}, `)} + {strategies.map(s => s.name).join(', ')} diff --git a/packages/unleash-frontend-next/src/component/feature/FeatureList.jsx b/packages/unleash-frontend-next/src/component/feature/FeatureList.jsx index 89c0f83e44..6c3d2e11c5 100644 --- a/packages/unleash-frontend-next/src/component/feature/FeatureList.jsx +++ b/packages/unleash-frontend-next/src/component/feature/FeatureList.jsx @@ -27,7 +27,7 @@ export default class FeatureList extends React.Component { const features = this.props.features.map(featureToggle => onFeatureClick(featureToggle.name)} + onClick={() => onFeatureClick(featureToggle)} /> ); diff --git a/packages/unleash-frontend-next/src/store/featureToggleActions.js b/packages/unleash-frontend-next/src/store/featureToggleActions.js index e980c770c1..60fcdd281b 100644 --- a/packages/unleash-frontend-next/src/store/featureToggleActions.js +++ b/packages/unleash-frontend-next/src/store/featureToggleActions.js @@ -1,9 +1,14 @@ -export const ADD_FEATURE_TOGGLE = 'ADD_FEATURE_TOGGLE'; -export const TOGGLE_FEATURE_TOGGLE = 'TOGGLE_FEATURE_TOGGLE'; -export const REQUEST_FEATURE_TOGGLES = 'REQUEST_FEATURE_TOGGLES'; -export const RECEIVE_FEATURE_TOGGLES = 'RECEIVE_FEATURE_TOGGLES'; -export const ERROR_RECEIVE_FEATURE_TOGGLES = 'ERROR_RECEIVE_FEATURE_TOGGLES'; -export const ERROR_CREATING_FEATURE_TOGGLE = 'ERROR_CREATING_FEATURE_TOGGLE'; +import { urls } from './urls'; + +export const ADD_FEATURE_TOGGLE = 'ADD_FEATURE_TOGGLE'; +export const UPDATE_FEATURE_TOGGLE = 'UPDATE_FEATURE_TOGGLE'; +export const TOGGLE_FEATURE_TOGGLE = 'TOGGLE_FEATURE_TOGGLE'; +export const REQUEST_FEATURE_TOGGLES = 'REQUEST_FEATURE_TOGGLES'; +export const REQUEST_UPDATE_FEATURE_TOGGLES = 'REQUEST_UPDATE_FEATURE_TOGGLES'; +export const RECEIVE_FEATURE_TOGGLES = '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_UPDATING_FEATURE_TOGGLE = 'ERROR_UPDATING_FEATURE_TOGGLE'; function addFeatureToggle (featureToggle) { return { @@ -12,6 +17,13 @@ function addFeatureToggle (featureToggle) { }; }; +function updateFeatureToggle (featureToggle) { + return { + type: UPDATE_FEATURE_TOGGLE, + featureToggle, + }; +}; + function errorCreatingFeatureToggle (statusCode) { return { type: ERROR_CREATING_FEATURE_TOGGLE, @@ -20,10 +32,20 @@ function errorCreatingFeatureToggle (statusCode) { }; } -export const toggleFeature = (featureName) => ({ - type: TOGGLE_FEATURE_TOGGLE, - name: featureName, -}); +function errorUpdatingFeatureToggle (statusCode) { + return { + type: ERROR_UPDATING_FEATURE_TOGGLE, + statusCode, + receivedAt: Date.now(), + }; +} + +export function toggleFeature (featureToggle) { + return dispatch => { + const newValue = Object.assign({}, featureToggle, { enabled: !featureToggle.enabled }); + dispatch(requestUpdateFeatureToggle(newValue)); + }; +}; function requestFeatureToggles () { @@ -40,6 +62,12 @@ function receiveFeatureToggles (json) { }; } +function requestUpdateFeatureToggles () { + return { + type: REQUEST_UPDATE_FEATURE_TOGGLES, + }; +} + function errorReceiveFeatureToggles (statusCode) { return { type: ERROR_RECEIVE_FEATURE_TOGGLES, @@ -51,7 +79,7 @@ function errorReceiveFeatureToggles (statusCode) { export function fetchFeatureToggles () { return dispatch => { dispatch(requestFeatureToggles()); - return fetch('/features') + return fetch(urls.features) .then(response => { if (response.ok) { return response.json(); @@ -66,16 +94,17 @@ export function fetchFeatureToggles () { }; } +const headers = { + 'Accept': 'application/json', + 'Content-Type': 'application/json', +}; export function createFeatureToggles (featureToggle) { return dispatch => { - dispatch(requestFeatureToggles()); - return fetch('/features', { + dispatch(requestUpdateFeatureToggles()); + return fetch(urls.features, { method: 'POST', - headers: { - 'Accept': 'application/json', - 'Content-Type': 'application/json', - }, + headers, body: JSON.stringify(featureToggle), }) .then(response => { @@ -89,3 +118,24 @@ export function createFeatureToggles (featureToggle) { .catch(error => dispatch(errorCreatingFeatureToggle(error))); }; } + +export function requestUpdateFeatureToggle (featureToggle) { + return dispatch => { + dispatch(requestUpdateFeatureToggles()); + return fetch(`${urls.features}/${featureToggle.name}`, { + method: 'PUT', + headers, + body: JSON.stringify(featureToggle), + }) + .then(response => { + if (!response.ok) { + let error = new Error('failed fetching'); + error.status = response.status; + throw error; + } + }) + .then(() => dispatch(updateFeatureToggle(featureToggle))) + .catch(error => dispatch(errorUpdatingFeatureToggle(error))); + }; +} + diff --git a/packages/unleash-frontend-next/src/store/features.js b/packages/unleash-frontend-next/src/store/features.js index 915a144385..3fc88882fa 100644 --- a/packages/unleash-frontend-next/src/store/features.js +++ b/packages/unleash-frontend-next/src/store/features.js @@ -1,22 +1,18 @@ import { ADD_FEATURE_TOGGLE, - TOGGLE_FEATURE_TOGGLE, RECEIVE_FEATURE_TOGGLES, + UPDATE_FEATURE_TOGGLE, } from './featureToggleActions'; const feature = (state = {}, action) => { switch (action.type) { case ADD_FEATURE_TOGGLE: return action.featureToggle; - case TOGGLE_FEATURE_TOGGLE: - if (state.name !== action.name) { + case UPDATE_FEATURE_TOGGLE: + if (state.name !== action.featureToggle.name) { return state; } - - return Object.assign({}, state, { - enabled: !state.enabled, - }); - + return action.featureToggle; default: return state; } @@ -29,7 +25,7 @@ const features = (state = [], action) => { ...state, feature(undefined, action), ]; - case TOGGLE_FEATURE_TOGGLE: + case UPDATE_FEATURE_TOGGLE: return state.map(t => feature(t, action) ); diff --git a/packages/unleash-frontend-next/src/store/urls.js b/packages/unleash-frontend-next/src/store/urls.js new file mode 100644 index 0000000000..2f5d6621f5 --- /dev/null +++ b/packages/unleash-frontend-next/src/store/urls.js @@ -0,0 +1,6 @@ +export const urls = { + features: '/features', + strategies: '/strategies', + events: '/events', + archive: '/archive/features', +}; diff --git a/packages/unleash-frontend-next/webpack.config.js b/packages/unleash-frontend-next/webpack.config.js index df10d40f28..e9d5efb395 100644 --- a/packages/unleash-frontend-next/webpack.config.js +++ b/packages/unleash-frontend-next/webpack.config.js @@ -62,6 +62,14 @@ module.exports = { target: 'http://localhost:4242', secure: false, }, + '/strategies': { + target: 'http://localhost:4242', + secure: false, + }, + '/archive': { + target: 'http://localhost:4242', + secure: false, + }, }, }, };