mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-01 00:08:27 +01:00
semi working input state store
This commit is contained in:
parent
d12396cf57
commit
ab64d7eb1c
@ -1,78 +1,88 @@
|
|||||||
import React, { PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
import { Input, Switch, Button } from 'react-toolbox';
|
import { Input, Switch, Button } from 'react-toolbox';
|
||||||
import AddFeatureToggleStrategy from './strategies-for-toggle';
|
import SelectStrategies from './strategies-for-toggle';
|
||||||
import SelectedStrategies from './selected-strategies';
|
import SelectedStrategies from './selected-strategies';
|
||||||
|
|
||||||
const AddFeatureToggleComponent = ({
|
class AddFeatureToggleComponent extends Component {
|
||||||
strategies,
|
|
||||||
featureToggle,
|
|
||||||
updateField,
|
|
||||||
addStrategy,
|
|
||||||
removeStrategy,
|
|
||||||
onSubmit,
|
|
||||||
onCancel,
|
|
||||||
editmode,
|
|
||||||
}) => {
|
|
||||||
const {
|
|
||||||
name, // eslint-disable-line
|
|
||||||
description,
|
|
||||||
enabled,
|
|
||||||
} = featureToggle;
|
|
||||||
const configuredStrategies = featureToggle.strategies;
|
|
||||||
|
|
||||||
return (
|
componentWillMount () {
|
||||||
<form onSubmit={onSubmit}>
|
// TODO unwind this stuff
|
||||||
<section>
|
if (this.props.initCallRequired === true) {
|
||||||
<Input
|
this.props.init(this.props.input);
|
||||||
type="text"
|
}
|
||||||
label="Name"
|
}
|
||||||
name="name"
|
|
||||||
disabled={editmode}
|
render () {
|
||||||
required
|
const {
|
||||||
value={name}
|
input,
|
||||||
onChange={updateField.bind(this, 'name')} />
|
setValue,
|
||||||
<Input
|
addStrategy,
|
||||||
type="text"
|
removeStrategy,
|
||||||
multiline label="Description"
|
onSubmit,
|
||||||
required
|
onCancel,
|
||||||
value={description}
|
editmode = false,
|
||||||
onChange={updateField.bind(this, 'description')} />
|
} = this.props;
|
||||||
|
|
||||||
|
const {
|
||||||
|
name, // eslint-disable-line
|
||||||
|
description,
|
||||||
|
enabled,
|
||||||
|
} = input;
|
||||||
|
const configuredStrategies = input.strategies || [];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form onSubmit={onSubmit(input)}>
|
||||||
|
<section>
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
label="Name"
|
||||||
|
name="name"
|
||||||
|
disabled={editmode}
|
||||||
|
required
|
||||||
|
value={name}
|
||||||
|
onChange={(v) => setValue('name', v)} />
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
multiline label="Description"
|
||||||
|
required
|
||||||
|
value={description}
|
||||||
|
onChange={(v) => setValue('description', v)} />
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<Switch
|
||||||
|
checked={enabled}
|
||||||
|
label="Enabled"
|
||||||
|
onChange={(v) => setValue('enabled', v)} />
|
||||||
|
<br />
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<strong>Activation strategies</strong>
|
||||||
|
<SelectedStrategies
|
||||||
|
configuredStrategies={configuredStrategies}
|
||||||
|
removeStrategy={removeStrategy} />
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<SelectStrategies addStrategy={addStrategy} />
|
||||||
|
</section>
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<Switch
|
<Button type="submit" raised primary label={editmode ? 'Update' : 'Create'} />
|
||||||
checked={enabled}
|
|
||||||
label="Enabled"
|
<Button type="cancel" raised label="Cancel" onClick={onCancel} />
|
||||||
onChange={updateField.bind(this, 'enabled')} />
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
<br />
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<strong>Activation strategies</strong>
|
|
||||||
<SelectedStrategies
|
|
||||||
configuredStrategies={configuredStrategies}
|
|
||||||
removeStrategy={removeStrategy} />
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<AddFeatureToggleStrategy strategies={strategies} addStrategy={addStrategy} />
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
|
|
||||||
<Button type="submit" raised primary label={editmode ? 'Update' : 'Create'} />
|
|
||||||
|
|
||||||
<Button type="cancel" raised label="Cancel" onClick={onCancel} />
|
|
||||||
</form>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
AddFeatureToggleComponent.propTypes = {
|
AddFeatureToggleComponent.propTypes = {
|
||||||
strategies: PropTypes.array.required,
|
strategies: PropTypes.array.required,
|
||||||
featureToggle: PropTypes.object,
|
input: PropTypes.object,
|
||||||
updateField: PropTypes.func.required,
|
setValue: PropTypes.func.required,
|
||||||
addStrategy: PropTypes.func.required,
|
addStrategy: PropTypes.func.required,
|
||||||
removeStrategy: PropTypes.func.required,
|
removeStrategy: PropTypes.func.required,
|
||||||
onSubmit: PropTypes.func.required,
|
onSubmit: PropTypes.func.required,
|
||||||
|
@ -1,80 +1,36 @@
|
|||||||
import React, { PropTypes } from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { createFeatureToggles } from '../../store/feature-actions';
|
import { createFeatureToggles } from '../../store/feature-actions';
|
||||||
import { fetchStrategies } from '../../store/strategy-actions';
|
import AddComponent from './add-component';
|
||||||
import AddFeatureToggleUI from './add-component';
|
import { createMapper, createActions } from '../input-helpers';
|
||||||
|
|
||||||
class AddFeatureToggle extends React.Component {
|
const ID = 'add-feature-toggle';
|
||||||
constructor () {
|
const mapStateToProps = createMapper({ id: ID });
|
||||||
super();
|
const prepare = (methods, dispatch) => {
|
||||||
this.state = {
|
methods.onSubmit = (input) => (
|
||||||
name: '',
|
(e) => {
|
||||||
description: '',
|
e.preventDefault();
|
||||||
enabled: false,
|
// TODO: should add error handling
|
||||||
strategies: [],
|
createFeatureToggles(input)(dispatch)
|
||||||
};
|
.then(() => methods.clear())
|
||||||
}
|
.then(() => window.history.back());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
static propTypes () {
|
methods.onCancel = () => {
|
||||||
return {
|
window.history.back();
|
||||||
dispatch: PropTypes.func.isRequired,
|
|
||||||
strategies: PropTypes.array,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
router: React.PropTypes.object,
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit = (evt) => {
|
|
||||||
evt.preventDefault();
|
|
||||||
this.props.dispatch(createFeatureToggles(this.state));
|
|
||||||
this.context.router.push('/features');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
onCancel = (evt) => {
|
methods.addStrategy = (v) => {
|
||||||
evt.preventDefault();
|
methods.pushToList('strategies', v);
|
||||||
this.context.router.push('/features');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
updateField = (key, value) => {
|
methods.removeStrategy = (v) => {
|
||||||
const change = {};
|
methods.removeFromList('strategies', v);
|
||||||
change[key] = value;
|
|
||||||
this.setState(change);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
addStrategy = (strategy) => {
|
return methods;
|
||||||
const strategies = this.state.strategies;
|
};
|
||||||
strategies.push(strategy);
|
const actions = createActions({ id: ID, prepare });
|
||||||
this.setState({ strategies });
|
|
||||||
}
|
|
||||||
|
|
||||||
removeStrategy = (strategy) => {
|
export default connect(mapStateToProps, actions)(AddComponent);
|
||||||
const strategies = this.state.strategies.filter(s => s !== strategy);
|
|
||||||
this.setState({ strategies });
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount () {
|
|
||||||
this.props.fetchStrategies();
|
|
||||||
}
|
|
||||||
|
|
||||||
render () {
|
|
||||||
return (
|
|
||||||
<AddFeatureToggleUI
|
|
||||||
strategies={this.props.strategies}
|
|
||||||
featureToggle={this.state}
|
|
||||||
updateField={this.updateField}
|
|
||||||
addStrategy={this.addStrategy}
|
|
||||||
removeStrategy={this.removeStrategy}
|
|
||||||
onSubmit={this.onSubmit}
|
|
||||||
onCancel={this.onCancel}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
|
||||||
strategies: state.strategies.get('list').toArray(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export default connect(mapStateToProps, { fetchStrategies })(AddFeatureToggle);
|
|
||||||
|
@ -1,86 +1,62 @@
|
|||||||
import React, { PropTypes } from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { editFeatureToggle } from '../../store/feature-actions';
|
|
||||||
import AddFeatureToggleComponent from './add-component';
|
|
||||||
import { fetchStrategies } from '../../store/strategy-actions';
|
|
||||||
|
|
||||||
|
import { requestUpdateFeatureToggle } from '../../store/feature-actions';
|
||||||
|
import AddComponent from './add-component';
|
||||||
|
import { createMapper, createActions } from '../input-helpers';
|
||||||
|
|
||||||
const mapStateToProps = (state, ownProps) => ({
|
const ID = 'edit-feature-toggle';
|
||||||
strategies: state.strategies.get('list').toArray(),
|
function getId (props) {
|
||||||
featureToggle: state.features.toJS().find(toggle => toggle.name === ownProps.featureToggleName) || {},
|
return [ID, props.featureToggleName];
|
||||||
|
}
|
||||||
|
// TODO: need to scope to the active featureToggle
|
||||||
|
// best is to emulate the "input-storage"?
|
||||||
|
const mapStateToProps = createMapper({
|
||||||
|
id: getId,
|
||||||
|
getDefault: (state, ownProps) => {
|
||||||
|
if (ownProps.featureToggleName) {
|
||||||
|
const match = state.features.findEntry((entry) => entry.get('name') === ownProps.featureToggleName);
|
||||||
|
|
||||||
|
if (match && match[1]) {
|
||||||
|
return match[1].toJS();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
prepare: (props) => {
|
||||||
|
props.editmode = true;
|
||||||
|
return props;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
class EditFeatureToggle extends React.Component {
|
const prepare = (methods, dispatch) => {
|
||||||
constructor (props) {
|
methods.onSubmit = (input) => (
|
||||||
super(props);
|
(e) => {
|
||||||
this.state = {
|
e.preventDefault();
|
||||||
name: props.featureToggle.name || '',
|
// TODO: should add error handling
|
||||||
description: props.featureToggle.description || '',
|
requestUpdateFeatureToggle(input)(dispatch)
|
||||||
enabled: props.featureToggle.enabled || false,
|
.then(() => methods.clear())
|
||||||
strategies: props.featureToggle.strategies || [],
|
.then(() => window.history.back());
|
||||||
};
|
}
|
||||||
}
|
);
|
||||||
|
|
||||||
static propTypes () {
|
methods.onCancel = () => {
|
||||||
return {
|
window.history.back();
|
||||||
dispatch: PropTypes.func.isRequired,
|
|
||||||
strategies: PropTypes.array,
|
|
||||||
featureToggle: PropTypes.featureToggle.isRequired,
|
|
||||||
fetchFeatureToggles: PropTypes.func.isRequired,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount () {
|
|
||||||
// todo fetch feature if missing? (reload of page does not fetch data from url)
|
|
||||||
this.props.fetchStrategies();
|
|
||||||
}
|
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
router: React.PropTypes.object,
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit = (evt) => {
|
|
||||||
evt.preventDefault();
|
|
||||||
this.props.dispatch(editFeatureToggle(this.state));
|
|
||||||
this.context.router.push('/features');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
onCancel = (evt) => {
|
methods.addStrategy = (v) => {
|
||||||
evt.preventDefault();
|
methods.pushToList('strategies', v);
|
||||||
this.context.router.push('/features');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
updateField = (key, value) => {
|
methods.removeStrategy = (v) => {
|
||||||
const change = {};
|
methods.removeFromList('strategies', v);
|
||||||
change[key] = value;
|
|
||||||
this.setState(change);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
addStrategy = (strategy) => {
|
return methods;
|
||||||
const strategies = this.state.strategies;
|
};
|
||||||
strategies.push(strategy);
|
|
||||||
this.setState({ strategies });
|
|
||||||
}
|
|
||||||
|
|
||||||
removeStrategy = (strategy) => {
|
const actions = createActions({
|
||||||
const strategies = this.state.strategies.filter(s => s !== strategy);
|
id: getId,
|
||||||
this.setState({ strategies });
|
prepare,
|
||||||
}
|
});
|
||||||
|
|
||||||
render () {
|
export default connect(mapStateToProps, actions)(AddComponent);
|
||||||
return (
|
|
||||||
<AddFeatureToggleComponent
|
|
||||||
editmode="true"
|
|
||||||
strategies={this.props.strategies}
|
|
||||||
featureToggle={this.state}
|
|
||||||
updateField={this.updateField}
|
|
||||||
addStrategy={this.addStrategy}
|
|
||||||
removeStrategy={this.removeStrategy}
|
|
||||||
onSubmit={this.onSubmit}
|
|
||||||
onCancel={this.onCancel}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default connect(mapStateToProps, { fetchStrategies })(EditFeatureToggle);
|
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
import { connect } from 'react-redux';
|
||||||
|
import SelectStrategies from './select-strategies';
|
||||||
|
import { fetchStrategies } from '../../store/strategy-actions';
|
||||||
|
|
||||||
|
|
||||||
|
export default connect((state) => ({
|
||||||
|
strategies: state.strategies.get('list').toArray(),
|
||||||
|
}), { fetchStrategies })(SelectStrategies);
|
@ -18,6 +18,17 @@ class SelectStrategies extends React.Component {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) => {
|
handleChange = (evt) => {
|
||||||
const strategyName = evt.target.value;
|
const strategyName = evt.target.value;
|
||||||
const selectedStrategy = this.props.strategies.find(s => s.name === strategyName);
|
const selectedStrategy = this.props.strategies.find(s => s.name === strategyName);
|
||||||
@ -63,7 +74,11 @@ class SelectStrategies extends React.Component {
|
|||||||
padding: '10px',
|
padding: '10px',
|
||||||
};
|
};
|
||||||
|
|
||||||
const selectedStrategy = this.state.selectedStrategy;
|
const selectedStrategy = this.state.selectedStrategy || this.props.strategies[0];
|
||||||
|
|
||||||
|
if (!selectedStrategy) {
|
||||||
|
return <div>Strategies loading...</div>;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={style}>
|
<div style={style}>
|
||||||
|
@ -19,7 +19,7 @@ class SelectedStrategies extends React.Component {
|
|||||||
|
|
||||||
render () {
|
render () {
|
||||||
const removeStrategy = this.props.removeStrategy;
|
const removeStrategy = this.props.removeStrategy;
|
||||||
const strategies = this.props.configuredStrategies.map((s, index) => (
|
const configuredStrategies = this.props.configuredStrategies.map((s, index) => (
|
||||||
<Chip
|
<Chip
|
||||||
key={`${index}-${s.name}`}
|
key={`${index}-${s.name}`}
|
||||||
deletable
|
deletable
|
||||||
@ -31,7 +31,7 @@ class SelectedStrategies extends React.Component {
|
|||||||
));
|
));
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{strategies.length > 0 ? strategies : <p>No activation strategies added</p>}
|
{configuredStrategies.length > 0 ? configuredStrategies : <p>No activation strategies added</p>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { PropTypes } from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
import SelectStrategies from './select-strategies';
|
import SelectStrategies from './select-strategies-container';
|
||||||
|
|
||||||
class AddStrategiesToToggle extends React.Component {
|
class AddStrategiesToToggle extends React.Component {
|
||||||
constructor () {
|
constructor () {
|
||||||
@ -11,7 +11,6 @@ class AddStrategiesToToggle extends React.Component {
|
|||||||
|
|
||||||
static propTypes () {
|
static propTypes () {
|
||||||
return {
|
return {
|
||||||
strategies: PropTypes.array.isRequired,
|
|
||||||
addStrategy: PropTypes.func.isRequired,
|
addStrategy: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -39,12 +38,11 @@ class AddStrategiesToToggle extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
return this.state.showConfigure ?
|
return (
|
||||||
<SelectStrategies
|
this.state.showConfigure ?
|
||||||
strategies={this.props.strategies}
|
<SelectStrategies cancelConfig={this.cancelConfig} addStrategy={this.addStrategy} /> :
|
||||||
cancelConfig={this.cancelConfig}
|
this.renderAddLink()
|
||||||
addStrategy={this.addStrategy} /> :
|
);
|
||||||
this.renderAddLink();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,32 +1,63 @@
|
|||||||
import { createInc, createClear, createSet } from '../store/input-actions';
|
import {
|
||||||
|
createInc,
|
||||||
|
createClear,
|
||||||
|
createSet,
|
||||||
|
createPop,
|
||||||
|
createPush,
|
||||||
|
createInit,
|
||||||
|
} from '../store/input-actions';
|
||||||
|
|
||||||
export function createMapper (id, prepare = (v) => v) {
|
function getId (id, ownProps) {
|
||||||
return (state) => {
|
if (typeof id === 'function') {
|
||||||
|
return id(ownProps); // should return array...
|
||||||
|
}
|
||||||
|
return [id];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createMapper ({ id, getDefault, prepare = (v) => v }) {
|
||||||
|
return (state, ownProps) => {
|
||||||
let input;
|
let input;
|
||||||
if (state.input.has(id)) {
|
let initCallRequired = false;
|
||||||
input = state.input.get(id).toJS();
|
const scope = getId(id, ownProps);
|
||||||
|
if (state.input.hasIn(scope)) {
|
||||||
|
input = state.input.getIn(scope).toJS();
|
||||||
} else {
|
} else {
|
||||||
input = {};
|
initCallRequired = true;
|
||||||
|
input = getDefault ? getDefault(state, ownProps) : {};
|
||||||
}
|
}
|
||||||
|
|
||||||
return prepare({
|
return prepare({
|
||||||
|
initCallRequired,
|
||||||
input,
|
input,
|
||||||
}, state);
|
}, state, ownProps);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createActions (id, prepare = (v) => v) {
|
export function createActions ({ id, prepare = (v) => v }) {
|
||||||
return (dispatch) => (prepare({
|
return (dispatch, ownProps) => (prepare({
|
||||||
|
|
||||||
clear () {
|
clear () {
|
||||||
dispatch(createClear({ id }));
|
dispatch(createClear({ id: getId(id, ownProps) }));
|
||||||
|
},
|
||||||
|
|
||||||
|
init (value) {
|
||||||
|
dispatch(createInit({ id: getId(id, ownProps), value }));
|
||||||
},
|
},
|
||||||
|
|
||||||
setValue (key, value) {
|
setValue (key, value) {
|
||||||
dispatch(createSet({ id, key, value }));
|
dispatch(createSet({ id: getId(id, ownProps), key, value }));
|
||||||
|
},
|
||||||
|
|
||||||
|
pushToList (key, value) {
|
||||||
|
dispatch(createPush({ id: getId(id, ownProps), key, value }));
|
||||||
|
},
|
||||||
|
|
||||||
|
removeFromList (key, value) {
|
||||||
|
dispatch(createPop({ id: getId(id, ownProps), key, value }));
|
||||||
},
|
},
|
||||||
|
|
||||||
incValue (key) {
|
incValue (key) {
|
||||||
dispatch(createInc({ id, key }));
|
dispatch(createInc({ id: getId(id, ownProps), key }));
|
||||||
},
|
},
|
||||||
}, dispatch));
|
}, dispatch, ownProps));
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import AddStrategy, { PARAM_PREFIX } from './add-strategy';
|
|||||||
|
|
||||||
const ID = 'add-strategy';
|
const ID = 'add-strategy';
|
||||||
|
|
||||||
const actions = createActions(ID, (methods, dispatch) => {
|
const prepare = (methods, dispatch) => {
|
||||||
methods.onSubmit = (input) => (
|
methods.onSubmit = (input) => (
|
||||||
(e) => {
|
(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -35,6 +35,11 @@ const actions = createActions(ID, (methods, dispatch) => {
|
|||||||
|
|
||||||
|
|
||||||
return methods;
|
return methods;
|
||||||
|
};
|
||||||
|
|
||||||
|
const actions = createActions({
|
||||||
|
id: ID,
|
||||||
|
prepare,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(createMapper(ID), actions)(AddStrategy);
|
export default connect(createMapper({ id: ID }), actions)(AddStrategy);
|
||||||
|
@ -1,11 +1,17 @@
|
|||||||
export const actions = {
|
export const actions = {
|
||||||
SET_VALUE: 'SET_VALUE',
|
SET_VALUE: 'SET_VALUE',
|
||||||
INCREMENT_VALUE: 'INCREMENT_VALUE',
|
INCREMENT_VALUE: 'INCREMENT_VALUE',
|
||||||
|
LIST_PUSH: 'LIST_PUSH',
|
||||||
|
LIST_POP: 'LIST_POP',
|
||||||
CLEAR: 'CLEAR',
|
CLEAR: 'CLEAR',
|
||||||
|
INIT: 'INIT',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const createInit = ({ id, value }) => ({ type: actions.INIT, id, value });
|
||||||
export const createInc = ({ id, key }) => ({ type: actions.INCREMENT_VALUE, id, key });
|
export const createInc = ({ id, key }) => ({ type: actions.INCREMENT_VALUE, id, key });
|
||||||
export const createSet = ({ id, key, value }) => ({ type: actions.SET_VALUE, id, key, value });
|
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 createClear = ({ id }) => ({ type: actions.CLEAR, id });
|
export const createClear = ({ id }) => ({ type: actions.CLEAR, id });
|
||||||
|
|
||||||
export default actions;
|
export default actions;
|
||||||
|
@ -1,41 +1,68 @@
|
|||||||
import { Map as $Map } from 'immutable';
|
import { Map as $Map, List, fromJS } from 'immutable';
|
||||||
import actions from './input-actions';
|
import actions from './input-actions';
|
||||||
|
|
||||||
function getInitState () {
|
function getInitState () {
|
||||||
return new $Map();
|
return new $Map();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function init (state, { id, value }) {
|
||||||
|
state = assertId(state, id);
|
||||||
|
return state.setIn(id, fromJS(value));
|
||||||
|
}
|
||||||
|
|
||||||
function assertId (state, id) {
|
function assertId (state, id) {
|
||||||
if (!state.has(id)) {
|
if (!state.hasIn(id)) {
|
||||||
return state.set(id, new $Map({ inputId: id }));
|
return state.setIn(id, new $Map({ inputId: id }));
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
function assertList (state, id, key) {
|
||||||
|
if (!state.getIn(id).has(key)) {
|
||||||
|
return state.setIn(id.concat([key]), new List());
|
||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setKeyValue (state, { id, key, value }) {
|
function setKeyValue (state, { id, key, value }) {
|
||||||
state = assertId(state, id);
|
state = assertId(state, id);
|
||||||
return state.setIn([id, key], value);
|
return state.setIn(id.concat([key]), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function increment (state, { id, key }) {
|
function increment (state, { id, key }) {
|
||||||
state = assertId(state, id);
|
state = assertId(state, id);
|
||||||
return state.updateIn([id, key], (value = 0) => value + 1);
|
return state.updateIn(id.concat([key]), (value = 0) => value + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function clear (state, { id }) {
|
function clear (state, { id }) {
|
||||||
if (state.has(id)) {
|
if (state.hasIn(id)) {
|
||||||
return state.remove(id);
|
return state.removeIn(id);
|
||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
const inputState = (state = getInitState(), action) => {
|
function addToList (state, { id, key, value }) {
|
||||||
|
state = assertId(state, id);
|
||||||
|
state = assertList(state, id, key);
|
||||||
|
|
||||||
|
return state.updateIn(id.concat([key]), (list) => list.push(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeFromList (state, { id, key, value }) {
|
||||||
|
state = assertId(state, id);
|
||||||
|
state = assertList(state, id, key);
|
||||||
|
|
||||||
|
return state.updateIn(id.concat([key]), (list) => list.remove(list.indexOf(value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
const inputState = (state = getInitState(), action) => {
|
||||||
if (!action.id) {
|
if (!action.id) {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
|
case actions.INIT:
|
||||||
|
return init(state, action);
|
||||||
case actions.SET_VALUE:
|
case actions.SET_VALUE:
|
||||||
if (actions.key != null && actions.value != null) {
|
if (actions.key != null && actions.value != null) {
|
||||||
throw new Error('Missing required key / value');
|
throw new Error('Missing required key / value');
|
||||||
@ -43,6 +70,10 @@ const inputState = (state = getInitState(), action) => {
|
|||||||
return setKeyValue(state, action);
|
return setKeyValue(state, action);
|
||||||
case actions.INCREMENT_VALUE:
|
case actions.INCREMENT_VALUE:
|
||||||
return increment(state, action);
|
return increment(state, action);
|
||||||
|
case actions.LIST_PUSH:
|
||||||
|
return addToList(state, action);
|
||||||
|
case actions.LIST_POP:
|
||||||
|
return removeFromList(state, action);
|
||||||
case actions.CLEAR:
|
case actions.CLEAR:
|
||||||
return clear(state, action);
|
return clear(state, action);
|
||||||
default:
|
default:
|
||||||
|
Loading…
Reference in New Issue
Block a user