diff --git a/frontend/src/component/feature/form/strategy-configure.jsx b/frontend/src/component/feature/form/strategy-configure.jsx
index 3e37c0e60d..5d2aabb283 100644
--- a/frontend/src/component/feature/form/strategy-configure.jsx
+++ b/frontend/src/component/feature/form/strategy-configure.jsx
@@ -47,24 +47,23 @@ class StrategyConfigure extends React.Component {
this.props.removeStrategy();
}
- renderInputFields (strategyDefinition) {
- if (strategyDefinition.parametersTemplate) {
- const keys = Object.keys(strategyDefinition.parametersTemplate);
- if (keys.length === 0) {
- return null;
- }
- return keys.map(field => {
- const type = strategyDefinition.parametersTemplate[field];
- let value = this.props.strategy.parameters[field];
+ renderInputFields ({ parameters }) {
+ if (parameters && parameters.length > 0) {
+ return parameters.map(({ name, type, description, required }) => {
+ let value = this.props.strategy.parameters[name];
if (type === 'percentage') {
if (value == null || (typeof value === 'string' && value === '')) {
value = 50; // default value
}
- return (
);
+ return (
+
+
+ {description &&
{description}
}
+
+ );
} else if (type === 'list') {
let list = [];
if (typeof value === 'string') {
@@ -73,33 +72,44 @@ class StrategyConfigure extends React.Component {
.split(',')
.filter(Boolean);
}
- return (
);
+ return (
+
+
+ {description &&
{description}
}
+
+ );
} else if (type === 'number') {
return (
-
+
+
+ {description &&
{description}
}
+
);
} else {
return (
-
+
+
+ {description &&
{description}
}
+
);
}
});
diff --git a/frontend/src/component/feature/form/strategy-input-list.jsx b/frontend/src/component/feature/form/strategy-input-list.jsx
index 1a93ce5200..aa63e09361 100644
--- a/frontend/src/component/feature/form/strategy-input-list.jsx
+++ b/frontend/src/component/feature/form/strategy-input-list.jsx
@@ -1,36 +1,80 @@
-import React from 'react';
+import React, { Component, PropTypes } from 'react';
import {
Textfield,
IconButton,
Chip,
} from 'react-mdl';
-export default ({ field, list, setConfig }) => (
-
-
{field}
- {list.map((entryValue, index) => (
-
{
- list[index] = null;
- setConfig(field, list.filter(Boolean).join(','));
- }}>{entryValue}
- ))}
+export default class InputList extends Component {
-
);
+ }
+}
diff --git a/frontend/src/component/feature/form/strategy-input-persentage.jsx b/frontend/src/component/feature/form/strategy-input-persentage.jsx
index 7c718a9db8..563d949de1 100644
--- a/frontend/src/component/feature/form/strategy-input-persentage.jsx
+++ b/frontend/src/component/feature/form/strategy-input-persentage.jsx
@@ -8,9 +8,9 @@ const labelStyle = {
fontSize: '12px',
};
-export default ({ field, value, onChange }) => (
+export default ({ name, value, onChange }) => (
-
{field}: {value}%
-
+
{name}: {value}%
+
);
diff --git a/frontend/src/component/input-helpers.js b/frontend/src/component/input-helpers.js
index 8afefcec4e..c0b24790bc 100644
--- a/frontend/src/component/input-helpers.js
+++ b/frontend/src/component/input-helpers.js
@@ -57,8 +57,8 @@ export function createActions ({ id, prepare = (v) => v }) {
dispatch(createPop({ id: getId(id, ownProps), key, index }));
},
- updateInList (key, index, newValue) {
- dispatch(createUp({ id: getId(id, ownProps), key, index, newValue }));
+ updateInList (key, index, newValue, merge = false) {
+ dispatch(createUp({ id: getId(id, ownProps), key, index, newValue, merge }));
},
incValue (key) {
diff --git a/frontend/src/component/strategies/add-container.js b/frontend/src/component/strategies/add-container.js
index aba64bbba8..b7e865413b 100644
--- a/frontend/src/component/strategies/add-container.js
+++ b/frontend/src/component/strategies/add-container.js
@@ -3,7 +3,7 @@ import { connect } from 'react-redux';
import { createMapper, createActions } from '../input-helpers';
import { createStrategy } from '../../store/strategy/actions';
-import AddStrategy, { PARAM_PREFIX, TYPE_PREFIX } from './add-strategy';
+import AddStrategy from './add-strategy';
const ID = 'add-strategy';
@@ -12,15 +12,28 @@ const prepare = (methods, dispatch) => {
(e) => {
e.preventDefault();
- const parametersTemplate = {};
- Object.keys(input).forEach(key => {
- if (key.startsWith(PARAM_PREFIX)) {
- parametersTemplate[input[key]] = input[key.replace(PARAM_PREFIX, TYPE_PREFIX)] || 'string';
- }
- });
- input.parametersTemplate = parametersTemplate;
- createStrategy(input)(dispatch)
+
+ // clean
+ const parameters = input.parameters
+ .filter((name) => !!name)
+ .map(({
+ name,
+ type = 'string',
+ description = '',
+ required = false,
+ }) => ({
+ name,
+ type,
+ description,
+ required,
+ }));
+
+ createStrategy({
+ name: input.name,
+ description: input.description,
+ parameters,
+ })(dispatch)
.then(() => methods.clear())
// somewhat quickfix / hacky to go back..
.then(() => window.history.back());
diff --git a/frontend/src/component/strategies/add-strategy.jsx b/frontend/src/component/strategies/add-strategy.jsx
index d9ef8047f1..3bf98184ba 100644
--- a/frontend/src/component/strategies/add-strategy.jsx
+++ b/frontend/src/component/strategies/add-strategy.jsx
@@ -1,6 +1,6 @@
import React, { PropTypes } from 'react';
-import { Textfield, IconButton, Menu, MenuItem } from 'react-mdl';
+import { Textfield, IconButton, Menu, MenuItem, Checkbox } from 'react-mdl';
import { HeaderTitle, FormButtons } from '../common';
@@ -15,40 +15,60 @@ const trim = (value) => {
function gerArrayWithEntries (num) {
return Array.from(Array(num));
}
-export const PARAM_PREFIX = 'param_';
-export const TYPE_PREFIX = 'type_';
-const genParams = (input, num = 0, setValue) => (
{gerArrayWithEntries(num).map((v, i) => {
- const key = `${PARAM_PREFIX}${i + 1}`;
- const typeKey = `${TYPE_PREFIX}${i + 1}`;
- return (
-
-
setValue(key, target.value)}
- value={input[key]} />
-
-
-
-
+const Parameter = ({ set, input = {}, index }) => (
+
+
set({ name: target.value }, true)}
+ value={input.name} />
+
+
+
- );
-})} );
+ set({ description: target.value })}
+ value={input.description}
+ />
+ set({ required: !input.required })}
+ ripple
+ defaultChecked
+ />
+
+);
+
+const Parameters = ({ input = [], count = 0, updateInList }) => (
+
{
+ gerArrayWithEntries(count)
+ .map((v, i) =>
updateInList('parameters', i, v, true)}
+ index={i}
+ input={input[i]}
+ />)
+});
const AddStrategy = ({
input,
setValue,
+ updateInList,
incValue,
// clear,
onCancel,
@@ -78,7 +98,7 @@ const AddStrategy = ({
- {genParams(input, input._params, setValue)}
+
{
e.preventDefault();
incValue('_params');
@@ -97,6 +117,7 @@ const AddStrategy = ({
AddStrategy.propTypes = {
input: PropTypes.object,
setValue: PropTypes.func,
+ updateInList: PropTypes.func,
incValue: PropTypes.func,
clear: PropTypes.func,
onCancel: PropTypes.func,
diff --git a/frontend/src/component/strategies/list-component.jsx b/frontend/src/component/strategies/list-component.jsx
index 94befbb283..41aa438caf 100644
--- a/frontend/src/component/strategies/list-component.jsx
+++ b/frontend/src/component/strategies/list-component.jsx
@@ -1,7 +1,7 @@
import React, { Component } from 'react';
import { Link } from 'react-router';
-import { List, ListItem, ListItemContent, Chip, Icon, IconButton } from 'react-mdl';
+import { List, ListItem, ListItemContent, IconButton } from 'react-mdl';
import { HeaderTitle } from '../common';
class StrategiesListComponent extends Component {
@@ -14,12 +14,6 @@ class StrategiesListComponent extends Component {
this.props.fetchStrategies();
}
- getParameterMap ({ parametersTemplate }) {
- return Object.keys(parametersTemplate || {}).map(k => (
- {k}
- ));
- }
-
render () {
const { strategies, removeStrategy } = this.props;
diff --git a/frontend/src/component/strategies/show-strategy-component.js b/frontend/src/component/strategies/show-strategy-component.js
index b2fbe45388..24fc36c56a 100644
--- a/frontend/src/component/strategies/show-strategy-component.js
+++ b/frontend/src/component/strategies/show-strategy-component.js
@@ -1,6 +1,5 @@
import React, { Component } from 'react';
-import { Grid, Cell } from 'react-mdl';
-
+import { Grid, Cell, List, ListItem, ListItemContent } from 'react-mdl';
import { AppsLinkList, TogglesLinkList, HeaderTitle } from '../common';
class ShowStrategyComponent extends Component {
@@ -16,13 +15,17 @@ class ShowStrategyComponent extends Component {
}
}
- renderParameters (parametersTemplate) {
- if (parametersTemplate) {
- return Object.keys(parametersTemplate).map((name, i) => (
- {name} ({parametersTemplate[name]})
+ renderParameters (params) {
+ if (params) {
+ return params.map(({ name, type, description, required }, i) => (
+
+
+ {name} ({type})
+
+
));
} else {
- return (no params);
+ return (no params);
}
}
@@ -41,28 +44,28 @@ class ShowStrategyComponent extends Component {
const {
name,
description,
- parametersTemplate = {},
+ parameters = [],
} = strategy;
return (
-
+
Parameters
-
- {this.renderParameters(parametersTemplate)}
-
+
+ {this.renderParameters(parameters)}
+
|
-
+
Applications using this strategy
|
-
+
Toggles using this strategy
diff --git a/frontend/src/store/input-actions.js b/frontend/src/store/input-actions.js
index b664bb1b98..5b6f5bead6 100644
--- a/frontend/src/store/input-actions.js
+++ b/frontend/src/store/input-actions.js
@@ -13,7 +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, index }) => ({ type: actions.LIST_POP, id, key, index });
-export const createUp = ({ id, key, index, newValue }) => ({ type: actions.LIST_UP, id, key, index, newValue });
+export const createUp = ({ id, key, index, newValue, merge }) => ({ type: actions.LIST_UP, id, key, index, newValue, merge });
export const createClear = ({ id }) => ({ type: actions.CLEAR, id });
export default actions;
diff --git a/frontend/src/store/input-store.js b/frontend/src/store/input-store.js
index 70de30ccf4..743c7c570f 100644
--- a/frontend/src/store/input-store.js
+++ b/frontend/src/store/input-store.js
@@ -48,11 +48,18 @@ function addToList (state, { id, key, value }) {
return state.updateIn(id.concat([key]), (list) => list.push(value));
}
-function updateInList (state, { id, key, index, newValue }) {
+function updateInList (state, { id, key, index, newValue, merge }) {
state = assertId(state, id);
state = assertList(state, id, key);
- return state.updateIn(id.concat([key]), (list) => list.set(index, newValue));
+ return state.updateIn(id.concat([key]), (list) => {
+ if (merge && list.has(index)) {
+ newValue = list.get(index).merge(new $Map(newValue));
+ } else if (typeof newValue !== 'string' ) {
+ newValue = fromJS(newValue);
+ }
+ return list.set(index, newValue);
+ });
}
function removeFromList (state, { id, key, index }) {
| | | |