From c867d602e88ce5d90fc96fe9714d87c5057269f5 Mon Sep 17 00:00:00 2001 From: ivaosthu Date: Tue, 25 Oct 2016 22:04:43 +0200 Subject: [PATCH] Update input field for feature toggles --- .../src/component/feature/add-component.jsx | 38 +++---- .../src/component/feature/add-container.jsx | 5 + .../feature/configure-strategies.jsx | 40 +++++++ .../component/feature/configure-strategy.jsx | 65 +++++++++++ .../src/component/feature/edit-container.jsx | 4 + .../feature/select-strategies-container.js | 8 -- .../component/feature/select-strategies.jsx | 101 ------------------ .../component/feature/selected-strategies.jsx | 47 -------- .../{add-strategy.jsx => strategies-add.jsx} | 9 +- .../feature/strategies-for-toggle.jsx | 50 --------- ...r.jsx => strategies-section-container.jsx} | 4 +- .../component/feature/strategies-section.jsx | 44 ++++++++ .../src/component/input-helpers.js | 5 + packages/unleash-frontend-next/src/index.jsx | 7 +- .../src/store/input-actions.js | 2 + .../src/store/input-store.js | 9 ++ 16 files changed, 195 insertions(+), 243 deletions(-) create mode 100644 packages/unleash-frontend-next/src/component/feature/configure-strategies.jsx create mode 100644 packages/unleash-frontend-next/src/component/feature/configure-strategy.jsx delete mode 100644 packages/unleash-frontend-next/src/component/feature/select-strategies-container.js delete mode 100644 packages/unleash-frontend-next/src/component/feature/select-strategies.jsx delete mode 100644 packages/unleash-frontend-next/src/component/feature/selected-strategies.jsx rename packages/unleash-frontend-next/src/component/feature/{add-strategy.jsx => strategies-add.jsx} (92%) delete mode 100644 packages/unleash-frontend-next/src/component/feature/strategies-for-toggle.jsx rename packages/unleash-frontend-next/src/component/feature/{strategies-for-toggle-container.jsx => strategies-section-container.jsx} (66%) create mode 100644 packages/unleash-frontend-next/src/component/feature/strategies-section.jsx diff --git a/packages/unleash-frontend-next/src/component/feature/add-component.jsx b/packages/unleash-frontend-next/src/component/feature/add-component.jsx index 10008bfa98..340a542763 100644 --- a/packages/unleash-frontend-next/src/component/feature/add-component.jsx +++ b/packages/unleash-frontend-next/src/component/feature/add-component.jsx @@ -2,8 +2,7 @@ import React, { Component, PropTypes } from 'react'; import Input from 'react-toolbox/lib/input'; import Button from 'react-toolbox/lib/button'; import Switch from 'react-toolbox/lib/switch'; -import SelectStrategies from './strategies-for-toggle-container'; -import SelectedStrategies from './selected-strategies'; +import StrategiesSection from './strategies-section-container'; class AddFeatureToggleComponent extends Component { @@ -20,6 +19,7 @@ class AddFeatureToggleComponent extends Component { setValue, addStrategy, removeStrategy, + updateStrategy, onSubmit, onCancel, editmode = false, @@ -59,23 +59,11 @@ class AddFeatureToggleComponent extends Component {
-
-
-
Strategies:
-
- - -
- -
- -
+
@@ -89,13 +77,13 @@ class AddFeatureToggleComponent extends Component { }; AddFeatureToggleComponent.propTypes = { - strategies: PropTypes.array.required, input: PropTypes.object, - setValue: PropTypes.func.required, - addStrategy: PropTypes.func.required, - removeStrategy: PropTypes.func.required, - onSubmit: PropTypes.func.required, - onCancel: PropTypes.func.required, + setValue: PropTypes.func.isRequired, + addStrategy: PropTypes.func.isRequired, + removeStrategy: PropTypes.func.isRequired, + updateStrategy: PropTypes.func.isRequired, + onSubmit: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired, editmode: PropTypes.bool, }; diff --git a/packages/unleash-frontend-next/src/component/feature/add-container.jsx b/packages/unleash-frontend-next/src/component/feature/add-container.jsx index 7f43851213..5eac3a3c67 100644 --- a/packages/unleash-frontend-next/src/component/feature/add-container.jsx +++ b/packages/unleash-frontend-next/src/component/feature/add-container.jsx @@ -18,6 +18,7 @@ const prepare = (methods, dispatch) => { ); methods.onCancel = () => { + debugger; window.history.back(); }; @@ -25,6 +26,10 @@ const prepare = (methods, dispatch) => { methods.pushToList('strategies', v); }; + methods.updateStrategy = (v, n) => { + methods.updateInList('strategies', v, n); + }; + methods.removeStrategy = (v) => { methods.removeFromList('strategies', v); }; diff --git a/packages/unleash-frontend-next/src/component/feature/configure-strategies.jsx b/packages/unleash-frontend-next/src/component/feature/configure-strategies.jsx new file mode 100644 index 0000000000..83f6e23b22 --- /dev/null +++ b/packages/unleash-frontend-next/src/component/feature/configure-strategies.jsx @@ -0,0 +1,40 @@ +import React, { PropTypes } from 'react'; +import ConfigureStrategy from './configure-strategy'; +class ConfigureStrategies extends React.Component { + + static propTypes () { + return { + strategies: PropTypes.array.isRequired, + configuredStrategies: PropTypes.array.isRequired, + updateStrategy: PropTypes.func.isRequired, + removeStrategy: PropTypes.func.isRequired, + }; + } + + render () { + const { + strategies, + configuredStrategies, + } = this.props; + + if (!configuredStrategies || configuredStrategies.length === 0) { + return No strategies added; + } + + const blocks = configuredStrategies.map((strat, i) => ( + s.name === strat.name)} /> + )); + return ( +
+ {blocks} +
+ ); + } +} + +export default ConfigureStrategies; diff --git a/packages/unleash-frontend-next/src/component/feature/configure-strategy.jsx b/packages/unleash-frontend-next/src/component/feature/configure-strategy.jsx new file mode 100644 index 0000000000..db70d89850 --- /dev/null +++ b/packages/unleash-frontend-next/src/component/feature/configure-strategy.jsx @@ -0,0 +1,65 @@ +import React, { PropTypes } from 'react'; +import { Button, Input } from 'react-toolbox'; + +class ConfigureStrategies extends React.Component { + + static propTypes () { + return { + strategy: PropTypes.object.isRequired, + strategyDefinition: PropTypes.object.isRequired, + updateStrategy: PropTypes.func.isRequired, + removeStrategy: PropTypes.func.isRequired, + }; + } + + updateStrategy = (evt) => { + evt.preventDefault(); + this.props.updateStrategy({ + name: this.state.selectedStrategy.name, + parameters: this.state.parameters, + }); + }; + + handleConfigChange = (key, value) => { + const parameters = {}; + parameters[key] = value; + + const updatedStrategy = Object.assign({}, this.props.strategy, { parameters }); + + this.props.updateStrategy(this.props.strategy, updatedStrategy); + }; + + handleRemove = (evt) => { + evt.preventDefault(); + this.props.removeStrategy(this.props.strategy); + } + + renderInputFields (strategyDefinition) { + if (strategyDefinition.parametersTemplate) { + return Object.keys(strategyDefinition.parametersTemplate).map(field => ( + + )); + } + } + + render () { + const inputFields = this.renderInputFields(this.props.strategyDefinition); + return ( +
+ {this.props.strategy.name} +
+ ); + } +} + +export default ConfigureStrategies; diff --git a/packages/unleash-frontend-next/src/component/feature/edit-container.jsx b/packages/unleash-frontend-next/src/component/feature/edit-container.jsx index 492d0bcf6d..32051cea69 100644 --- a/packages/unleash-frontend-next/src/component/feature/edit-container.jsx +++ b/packages/unleash-frontend-next/src/component/feature/edit-container.jsx @@ -51,6 +51,10 @@ const prepare = (methods, dispatch) => { methods.removeFromList('strategies', v); }; + methods.updateStrategy = (v, n) => { + methods.updateInList('strategies', v, n); + }; + return methods; }; diff --git a/packages/unleash-frontend-next/src/component/feature/select-strategies-container.js b/packages/unleash-frontend-next/src/component/feature/select-strategies-container.js deleted file mode 100644 index 36e718f3f6..0000000000 --- a/packages/unleash-frontend-next/src/component/feature/select-strategies-container.js +++ /dev/null @@ -1,8 +0,0 @@ -import { connect } from 'react-redux'; -import AddStrategy from './add-strategy'; -import { fetchStrategies } from '../../store/strategy-actions'; - - -export default connect((state) => ({ - strategies: state.strategies.get('list').toArray(), -}), { fetchStrategies })(AddStrategy); diff --git a/packages/unleash-frontend-next/src/component/feature/select-strategies.jsx b/packages/unleash-frontend-next/src/component/feature/select-strategies.jsx deleted file mode 100644 index 79b4ea2ada..0000000000 --- a/packages/unleash-frontend-next/src/component/feature/select-strategies.jsx +++ /dev/null @@ -1,101 +0,0 @@ -import React, { PropTypes } from 'react'; -import Input from 'react-toolbox/lib/input'; -import Button from 'react-toolbox/lib/button'; - -class SelectStrategies extends React.Component { - constructor (props) { - super(props); - this.state = { - selectedStrategy: props.strategies[0], - parameters: {}, - }; - } - - static propTypes () { - return { - strategies: PropTypes.array.isRequired, - cancelConfig: PropTypes.func.isRequired, - addStrategy: PropTypes.func.isRequired, - }; - } - - componentWillMount () { - this.props.fetchStrategies(); - } - - componentWillReceiveProps (nextProps) { - // this will fix async strategies list loading after mounted - if (!this.state.selectedStrategy && nextProps.strategies.length > 0) { - this.setState({ selectedStrategy: nextProps.strategies[0] }); - } - } - - handleChange = (evt) => { - const strategyName = evt.target.value; - const selectedStrategy = this.props.strategies.find(s => s.name === strategyName); - this.setState({ selectedStrategy, parameters: {} }); - } - - addStrategy = (evt) => { - evt.preventDefault(); - this.props.addStrategy({ - name: this.state.selectedStrategy.name, - parameters: this.state.parameters, - }); - }; - - handleConfigChange = (key, value) => { - const parameters = this.state.parameters; - parameters[key] = value; - this.setState({ parameters }); - }; - - renderInputFields (selectedStrategy) { - if (selectedStrategy.parametersTemplate) { - return Object.keys(selectedStrategy.parametersTemplate).map(field => ( - - )); - } - } - - render () { - const strategies = this.props.strategies.map(s => ( - - )); - - const style = { - backgroundColor: '#ECE', - padding: '10px', - }; - - const selectedStrategy = this.state.selectedStrategy || this.props.strategies[0]; - - if (!selectedStrategy) { - return
Strategies loading...
; - } - - return ( -
- - -

Description: {selectedStrategy.description}

- - {this.renderInputFields(selectedStrategy)} - -
- ); - } -} - -export default SelectStrategies; diff --git a/packages/unleash-frontend-next/src/component/feature/selected-strategies.jsx b/packages/unleash-frontend-next/src/component/feature/selected-strategies.jsx deleted file mode 100644 index 123ff36727..0000000000 --- a/packages/unleash-frontend-next/src/component/feature/selected-strategies.jsx +++ /dev/null @@ -1,47 +0,0 @@ -import React, { PropTypes } from 'react'; -import Chip from 'react-toolbox/lib/chip'; -import Avatar from 'react-toolbox/lib/avatar'; - -class SelectedStrategies extends React.Component { - static propTypes () { - return { - configuredStrategies: PropTypes.array.isRequired, - removeStrategy: PropTypes.func.isRequired, - }; - } - - renderName (strategy) { - const parameters = strategy.parameters || {}; - const keys = Object.keys(parameters); - if (keys.length === 0) { - return {strategy.name}; - } - - const params = keys - .map(param => `${param}="${strategy.parameters[param]}"`) - .join('; '); - return {strategy.name} ({params}); - } - - render () { - const removeStrategy = this.props.removeStrategy; - const configuredStrategies = this.props.configuredStrategies.map((s, index) => ( - removeStrategy(s)} - > - - {this.renderName(s)} - - )); - return ( -
- {configuredStrategies.length > 0 ? configuredStrategies :

No activation strategies added

} -
- ); - } -} - -export default SelectedStrategies; diff --git a/packages/unleash-frontend-next/src/component/feature/add-strategy.jsx b/packages/unleash-frontend-next/src/component/feature/strategies-add.jsx similarity index 92% rename from packages/unleash-frontend-next/src/component/feature/add-strategy.jsx rename to packages/unleash-frontend-next/src/component/feature/strategies-add.jsx index e83b7f1b07..5968beb45b 100644 --- a/packages/unleash-frontend-next/src/component/feature/add-strategy.jsx +++ b/packages/unleash-frontend-next/src/component/feature/strategies-add.jsx @@ -1,5 +1,5 @@ import React, { PropTypes } from 'react'; -import { Button, Input } from 'react-toolbox'; +import { Button } from 'react-toolbox'; class AddStrategy extends React.Component { constructor (props) { @@ -17,11 +17,6 @@ class AddStrategy extends React.Component { }; } - componentWillMount () { - // TODO: move somewhere appropriate? - this.props.fetchStrategies(); - } - componentWillReceiveProps (nextProps) { // this will fix async strategies list loading after mounted if (!this.state.selectedStrategy && nextProps.strategies.length > 0) { @@ -65,9 +60,7 @@ class AddStrategy extends React.Component { - - - ); - } -} - -export default AddStrategiesToToggle; diff --git a/packages/unleash-frontend-next/src/component/feature/strategies-for-toggle-container.jsx b/packages/unleash-frontend-next/src/component/feature/strategies-section-container.jsx similarity index 66% rename from packages/unleash-frontend-next/src/component/feature/strategies-for-toggle-container.jsx rename to packages/unleash-frontend-next/src/component/feature/strategies-section-container.jsx index 36e718f3f6..a5c4fa24a7 100644 --- a/packages/unleash-frontend-next/src/component/feature/strategies-for-toggle-container.jsx +++ b/packages/unleash-frontend-next/src/component/feature/strategies-section-container.jsx @@ -1,8 +1,8 @@ import { connect } from 'react-redux'; -import AddStrategy from './add-strategy'; +import StrategiesSection from './strategies-section'; import { fetchStrategies } from '../../store/strategy-actions'; export default connect((state) => ({ strategies: state.strategies.get('list').toArray(), -}), { fetchStrategies })(AddStrategy); +}), { fetchStrategies })(StrategiesSection); diff --git a/packages/unleash-frontend-next/src/component/feature/strategies-section.jsx b/packages/unleash-frontend-next/src/component/feature/strategies-section.jsx new file mode 100644 index 0000000000..a16ed5f611 --- /dev/null +++ b/packages/unleash-frontend-next/src/component/feature/strategies-section.jsx @@ -0,0 +1,44 @@ +import React, { PropTypes } from 'react'; +import ConfigureStrategies from './configure-strategies'; +import AddStrategy from './strategies-add'; + +const headerStyle = { + borderBottom: '1px solid rgba(0, 0, 0, 0.12)', + paddingBottom: '5px', + marginBottom: '10px', +}; + +class StrategiesSection extends React.Component { + + static propTypes () { + return { + strategies: PropTypes.array.isRequired, + addStrategy: PropTypes.func.isRequired, + removeStrategy: PropTypes.func.isRequired, + updateStrategy: PropTypes.func.isRequired, + fetchStrategies: PropTypes.func.isRequired, + }; + } + + componentWillMount () { + this.props.fetchStrategies(); + } + + render () { + if (!this.props.strategies || this.props.strategies.length === 0) { + return Loding available strategies; + } + + return ( +
+
+
Strategies:
+ + +
+
+ ); + } +} + +export default StrategiesSection; diff --git a/packages/unleash-frontend-next/src/component/input-helpers.js b/packages/unleash-frontend-next/src/component/input-helpers.js index 53ecaa6fc8..afcb2e7c95 100644 --- a/packages/unleash-frontend-next/src/component/input-helpers.js +++ b/packages/unleash-frontend-next/src/component/input-helpers.js @@ -4,6 +4,7 @@ import { createSet, createPop, createPush, + createUp, createInit, } from '../store/input-actions'; @@ -56,6 +57,10 @@ export function createActions ({ id, prepare = (v) => v }) { dispatch(createPop({ id: getId(id, ownProps), key, value })); }, + updateInList (key, value, newValue) { + dispatch(createUp({ id: getId(id, ownProps), key, value, newValue })); + }, + incValue (key) { dispatch(createInc({ id: getId(id, ownProps), key })); }, diff --git a/packages/unleash-frontend-next/src/index.jsx b/packages/unleash-frontend-next/src/index.jsx index a45ca4a3ce..e86be7a31b 100644 --- a/packages/unleash-frontend-next/src/index.jsx +++ b/packages/unleash-frontend-next/src/index.jsx @@ -1,6 +1,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import { Router, Route, IndexRedirect, hashHistory } from 'react-router'; +import { Router, Route, IndexRedirect, useRouterHistory } from 'react-router'; +import { createHashHistory } from 'history'; import { Provider } from 'react-redux'; import thunkMiddleware from 'redux-thunk'; import { createStore, applyMiddleware } from 'redux'; @@ -16,6 +17,8 @@ import CreateStrategies from './page/strategies/create'; import HistoryPage from './page/history'; import Archive from './page/archive'; +const appHistory = useRouterHistory(createHashHistory)({ queryKey: false }); + const unleashStore = createStore( store, applyMiddleware( @@ -25,7 +28,7 @@ const unleashStore = createStore( ReactDOM.render( - + diff --git a/packages/unleash-frontend-next/src/store/input-actions.js b/packages/unleash-frontend-next/src/store/input-actions.js index 2f055c7b96..f94fe5a09f 100644 --- a/packages/unleash-frontend-next/src/store/input-actions.js +++ b/packages/unleash-frontend-next/src/store/input-actions.js @@ -3,6 +3,7 @@ export const actions = { INCREMENT_VALUE: 'INCREMENT_VALUE', LIST_PUSH: 'LIST_PUSH', LIST_POP: 'LIST_POP', + LIST_UP: 'LIST_UP', CLEAR: 'CLEAR', INIT: 'INIT', }; @@ -12,6 +13,7 @@ export const createInc = ({ id, key }) => ({ type: actions.INCREMENT_VALUE, id, export const createSet = ({ id, key, value }) => ({ type: actions.SET_VALUE, id, key, value }); export const createPush = ({ id, key, value }) => ({ type: actions.LIST_PUSH, id, key, value }); export const createPop = ({ id, key, value }) => ({ type: actions.LIST_POP, id, key, value }); +export const createUp = ({ id, key, value, newValue }) => ({ type: actions.LIST_UP, id, key, value, newValue }); export const createClear = ({ id }) => ({ type: actions.CLEAR, id }); export default actions; diff --git a/packages/unleash-frontend-next/src/store/input-store.js b/packages/unleash-frontend-next/src/store/input-store.js index 93119dab24..3379123398 100644 --- a/packages/unleash-frontend-next/src/store/input-store.js +++ b/packages/unleash-frontend-next/src/store/input-store.js @@ -48,6 +48,13 @@ function addToList (state, { id, key, value }) { return state.updateIn(id.concat([key]), (list) => list.push(value)); } +function updateInList (state, { id, key, value, newValue }) { + state = assertId(state, id); + state = assertList(state, id, key); + + return state.updateIn(id.concat([key]), (list) => list.set(list.indexOf(value), newValue)); +} + function removeFromList (state, { id, key, value }) { state = assertId(state, id); state = assertList(state, id, key); @@ -74,6 +81,8 @@ const inputState = (state = getInitState(), action) => { return addToList(state, action); case actions.LIST_POP: return removeFromList(state, action); + case actions.LIST_UP: + return updateInList(state, action); case actions.CLEAR: return clear(state, action); default: