diff --git a/frontend/package.json b/frontend/package.json
index bc0112f599..0291b9784f 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -67,7 +67,7 @@
"identity-obj-proxy": "^3.0.0",
"immutable": "^3.8.1",
"jest": "^26.6.3",
- "lodash": "^4.17.15",
+ "lodash": "^4.17.20",
"mini-css-extract-plugin": "^0.9.0",
"node-fetch": "^2.6.1",
"node-sass": "^4.5.3",
diff --git a/frontend/src/component/common/common.module.scss b/frontend/src/component/common/common.module.scss
index 36b0466ca5..62d9f0b801 100644
--- a/frontend/src/component/common/common.module.scss
+++ b/frontend/src/component/common/common.module.scss
@@ -8,6 +8,10 @@
width: 100%;
}
+.sectionPadding {
+ padding: 0 16px;
+}
+
.horisontalScroll {
overflow-x: scroll;
-webkit-overflow-scrolling: touch;
diff --git a/frontend/src/component/common/index.js b/frontend/src/component/common/index.js
index 58d6dd6ab4..e603c4c34a 100644
--- a/frontend/src/component/common/index.js
+++ b/frontend/src/component/common/index.js
@@ -34,9 +34,9 @@ export const HeaderTitle = ({ title, actions, subtitle }) => (
diff --git a/frontend/src/component/common/util.js b/frontend/src/component/common/util.js
index b395f4e7a6..78f024d2e1 100644
--- a/frontend/src/component/common/util.js
+++ b/frontend/src/component/common/util.js
@@ -104,3 +104,5 @@ export const modalStyles = {
transform: 'translate(-50%, -50%)',
},
};
+
+export const updateIndexInArray = (array, index, newValue) => array.map((v, i) => (i === index ? newValue : v));
diff --git a/frontend/src/component/feature/create/__tests__/__snapshots__/add-feature-component-test.jsx.snap b/frontend/src/component/feature/create/__tests__/__snapshots__/add-feature-component-test.jsx.snap
index 94d8a69403..1e7d6ede48 100644
--- a/frontend/src/component/feature/create/__tests__/__snapshots__/add-feature-component-test.jsx.snap
+++ b/frontend/src/component/feature/create/__tests__/__snapshots__/add-feature-component-test.jsx.snap
@@ -28,75 +28,72 @@ exports[`render the create feature page 1`] = `
col={4}
>
-
-
- Disabled
-
-
+
+
+ Disabled
+ feature toggle
+
+
+
setValue('name', trim(v.target.value))}
/>
-
+
setValue('type', v.target.value)} />
|
-
- {
- setValue('enabled', !input.enabled);
- }}
- >
- {input.enabled ? 'Enabled' : 'Disabled'}
-
- |
-
+
setValue('project', v.target.value)} />
-
+
setValue('description', v.target.value)}
/>
+
+ {
+ setValue('enabled', !input.enabled);
+ }}
+ >
+ {input.enabled ? 'Enabled' : 'Disabled'} feature toggle
+
+
+
+ setValue('strategies', s)}
+ editable
+ />
+
diff --git a/frontend/src/component/feature/create/add-feature-container.jsx b/frontend/src/component/feature/create/add-feature-container.jsx
index 7330ec6d94..0204dee4b6 100644
--- a/frontend/src/component/feature/create/add-feature-container.jsx
+++ b/frontend/src/component/feature/create/add-feature-container.jsx
@@ -61,7 +61,10 @@ class WrapperComponent extends Component {
evt.preventDefault();
const { createFeatureToggles, history } = this.props;
const { featureToggle } = this.state;
- featureToggle.strategies = [defaultStrategy];
+
+ if (featureToggle.strategies < 1) {
+ featureToggle.strategies = [defaultStrategy];
+ }
createFeatureToggles(featureToggle).then(() => history.push(`/features/strategies/${featureToggle.name}`));
};
@@ -78,6 +81,7 @@ class WrapperComponent extends Component {
onCancel={this.onCancel}
validateName={this.validateName}
setValue={this.setValue}
+ setStrategies={this.setStrategies}
input={this.state.featureToggle}
errors={this.state.errors}
/>
diff --git a/frontend/src/component/feature/strategy/input-list.jsx b/frontend/src/component/feature/strategy/input-list.jsx
index 6bb6b3176a..7da5065ea1 100644
--- a/frontend/src/component/feature/strategy/input-list.jsx
+++ b/frontend/src/component/feature/strategy/input-list.jsx
@@ -31,7 +31,7 @@ export default class InputList extends Component {
const newValues = value.split(/,\s*/).filter(a => !list.includes(a));
if (newValues.length > 0) {
const newList = list.concat(newValues).filter(a => a);
- setConfig(name, newList.join(','), true);
+ setConfig(name, newList.join(','));
}
this.textInput.inputRef.value = '';
}
@@ -40,7 +40,7 @@ export default class InputList extends Component {
onClose(index) {
const { name, list, setConfig } = this.props;
list[index] = null;
- setConfig(name, list.length === 1 ? '' : list.filter(Boolean).join(','), true);
+ setConfig(name, list.length === 1 ? '' : list.filter(Boolean).join(','));
}
render() {
diff --git a/frontend/src/component/feature/strategy/loading-strategy.jsx b/frontend/src/component/feature/strategy/loading-strategy.jsx
new file mode 100644
index 0000000000..107793d160
--- /dev/null
+++ b/frontend/src/component/feature/strategy/loading-strategy.jsx
@@ -0,0 +1,9 @@
+import React from 'react';
+
+export default function LoadingStrategy() {
+ return (
+
+ Loading definition...
+
+ );
+}
diff --git a/frontend/src/component/feature/strategy/strategies-add.jsx b/frontend/src/component/feature/strategy/strategies-add.jsx
index 30edc9e967..0836707da1 100644
--- a/frontend/src/component/feature/strategy/strategies-add.jsx
+++ b/frontend/src/component/feature/strategy/strategies-add.jsx
@@ -21,6 +21,7 @@ class AddStrategy extends React.Component {
strategies: PropTypes.array.isRequired,
addStrategy: PropTypes.func,
featureToggleName: PropTypes.string.isRequired,
+ disabled: PropTypes.bool,
};
addStrategy(strategyName) {
@@ -45,10 +46,11 @@ class AddStrategy extends React.Component {
render() {
const menuStyle = {
- maxHeight: '300px',
+ maxHeight: '400px',
overflowY: 'auto',
backgroundColor: 'rgb(247, 248, 255)',
};
+ const { disabled = false } = this.props;
return (
diff --git a/frontend/src/component/feature/strategy/strategies-list-add-component.jsx b/frontend/src/component/feature/strategy/strategies-list-add-component.jsx
new file mode 100644
index 0000000000..6838b38380
--- /dev/null
+++ b/frontend/src/component/feature/strategy/strategies-list-add-component.jsx
@@ -0,0 +1,96 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import { DndProvider } from 'react-dnd';
+import { HTML5Backend } from 'react-dnd-html5-backend';
+import arrayMove from 'array-move';
+
+import ConfigureStrategy from './strategy-configure-container';
+import AddStrategy from './strategies-add';
+import { HeaderTitle } from '../../common';
+import { updateIndexInArray } from '../../common/util';
+import styles from './strategy.module.scss';
+
+const StrategiesList = props => {
+ const updateStrategy = index => strategy => {
+ const newStrategy = { ...strategy };
+ const newStrategies = updateIndexInArray(props.configuredStrategies, index, newStrategy);
+ props.saveStrategies(newStrategies);
+ };
+
+ const saveStrategy = () => () => {
+ // not needed for create flow
+ };
+
+ const addStrategy = strategy => {
+ const strategies = [...props.configuredStrategies];
+ strategies.push({ ...strategy });
+ props.saveStrategies(strategies);
+ };
+
+ const moveStrategy = async (index, toIndex) => {
+ const strategies = arrayMove(props.configuredStrategies, index, toIndex);
+ await props.saveStrategies(strategies);
+ };
+
+ const removeStrategy = index => async () => {
+ props.saveStrategies(props.configuredStrategies.filter((_, i) => i !== index));
+ };
+
+ const { strategies, configuredStrategies, featureToggleName } = props;
+
+ const hasName = featureToggleName && featureToggleName.length > 1;
+
+ const blocks = configuredStrategies.map((strategy, i) => (
+ s.name === strategy.name)}
+ editable
+ movable
+ />
+ ));
+ return (
+
+
+
+ }
+ />
+
+ {blocks.length > 0 ? (
+ blocks
+ ) : (
+
+ An activation strategy allows you to control how a feature toggle is enabled in your
+ applications. If you do not specify any activation strategies you will get the "default"
+ strategy.
+
+ )}
+
+
+
+ );
+};
+
+StrategiesList.propTypes = {
+ strategies: PropTypes.array.isRequired,
+ configuredStrategies: PropTypes.array.isRequired,
+ featureToggleName: PropTypes.string.isRequired,
+ saveStrategies: PropTypes.func,
+};
+
+export default StrategiesList;
diff --git a/frontend/src/component/feature/strategy/strategies-list-add-container.jsx b/frontend/src/component/feature/strategy/strategies-list-add-container.jsx
new file mode 100644
index 0000000000..8a89139fb4
--- /dev/null
+++ b/frontend/src/component/feature/strategy/strategies-list-add-container.jsx
@@ -0,0 +1,8 @@
+import { connect } from 'react-redux';
+import StrategiesList from './strategies-list-add-component';
+
+const mapStateToProps = state => ({
+ strategies: state.strategies.get('list').toArray(),
+});
+
+export default connect(mapStateToProps, undefined)(StrategiesList);
diff --git a/frontend/src/component/feature/strategy/strategies-list-component.jsx b/frontend/src/component/feature/strategy/strategies-list-component.jsx
new file mode 100644
index 0000000000..5eb4285569
--- /dev/null
+++ b/frontend/src/component/feature/strategy/strategies-list-component.jsx
@@ -0,0 +1,162 @@
+import React, { useState, useEffect } from 'react';
+import PropTypes from 'prop-types';
+
+import { DndProvider } from 'react-dnd';
+import { HTML5Backend } from 'react-dnd-html5-backend';
+import { cloneDeep } from 'lodash';
+import arrayMove from 'array-move';
+import { Button, Icon } from 'react-mdl';
+
+import ConfigureStrategy from './strategy-configure-container';
+import AddStrategy from './strategies-add';
+import { HeaderTitle } from '../../common';
+import { updateIndexInArray } from '../../common/util';
+import styles from './strategy.module.scss';
+
+const cleanStrategy = strategy => ({
+ name: strategy.name,
+ parameters: cloneDeep(strategy.parameters),
+ constraints: cloneDeep(strategy.constraints || []),
+});
+
+const StrategiesList = props => {
+ const [editableStrategies, updateEditableStrategies] = useState(cloneDeep(props.configuredStrategies));
+ const dirty = editableStrategies.some(p => p.dirty);
+
+ useEffect(() => {
+ if (!dirty) {
+ updateEditableStrategies(cloneDeep(props.configuredStrategies));
+ }
+ }, [props.configuredStrategies]);
+
+ const updateStrategy = index => (strategy, dirty = true) => {
+ const newStrategy = { ...strategy, dirty };
+ const newStrategies = updateIndexInArray(editableStrategies, index, newStrategy);
+ updateEditableStrategies(newStrategies);
+ };
+
+ const saveStrategy = index => async () => {
+ const strategies = [...props.configuredStrategies];
+ const strategy = editableStrategies[index];
+ const cleanedStrategy = cleanStrategy(strategy);
+
+ if (strategy.new) {
+ strategies.push(cleanedStrategy);
+ } else {
+ strategies[index] = cleanedStrategy;
+ }
+
+ // store in server
+ await props.saveStrategies(strategies);
+
+ // update local state
+ updateStrategy(index)(cleanedStrategy, false);
+ };
+
+ const addStrategy = strategy => {
+ const strategies = [...editableStrategies];
+ strategies.push({ ...strategy, dirty: true, new: true });
+ updateEditableStrategies(strategies);
+ };
+
+ const moveStrategy = async (index, toIndex) => {
+ if (!dirty) {
+ // console.log(`move strategy from ${index} to ${toIndex}`);
+ const strategies = arrayMove(editableStrategies, index, toIndex);
+ await props.saveStrategies(strategies);
+ updateEditableStrategies(strategies);
+ }
+ };
+
+ const removeStrategy = index => async () => {
+ // eslint-disable-next-line no-alert
+ if (window.confirm('Are you sure you want to remove this activation strategy?')) {
+ const strategy = editableStrategies[index];
+ if (!strategy.new) {
+ await props.saveStrategies(props.configuredStrategies.filter((_, i) => i !== index));
+ }
+
+ updateEditableStrategies(editableStrategies.filter((_, i) => i !== index));
+ }
+ };
+
+ const clearAll = () => {
+ updateEditableStrategies(cloneDeep(props.configuredStrategies));
+ };
+
+ const saveAll = async () => {
+ const cleanedStrategies = editableStrategies.map(cleanStrategy);
+ await props.saveStrategies(cleanedStrategies);
+ updateEditableStrategies(cleanedStrategies);
+ };
+
+ const { strategies, configuredStrategies, featureToggleName, editable } = props;
+
+ if (!configuredStrategies || configuredStrategies.length === 0) {
+ return (
+
+ No activation strategies selected.
+
+ );
+ }
+
+ const resolveStrategyDefinition = strategyName => {
+ if (!strategies || strategies.length === 0) {
+ return { name: 'Loading' };
+ }
+ return strategies.find(s => s.name === strategyName);
+ };
+
+ const blocks = editableStrategies.map((strategy, i) => (
+
+ ));
+ return (
+
+ {editable && (
+
+ }
+ />
+ )}
+ {blocks}
+
+
+
+ Save all
+
+
+
+ Clear all
+
+
+
+ );
+};
+
+StrategiesList.propTypes = {
+ strategies: PropTypes.array.isRequired,
+ configuredStrategies: PropTypes.array.isRequired,
+ featureToggleName: PropTypes.string.isRequired,
+ saveStrategies: PropTypes.func,
+ editable: PropTypes.bool,
+};
+
+export default StrategiesList;
diff --git a/frontend/src/component/feature/strategy/strategies-list-container.jsx b/frontend/src/component/feature/strategy/strategies-list-container.jsx
new file mode 100644
index 0000000000..3dbb754d6a
--- /dev/null
+++ b/frontend/src/component/feature/strategy/strategies-list-container.jsx
@@ -0,0 +1,8 @@
+import { connect } from 'react-redux';
+import StrategiesList from './strategies-list-component';
+
+const mapStateToProps = state => ({
+ strategies: state.strategies.get('list').toArray(),
+});
+
+export default connect(mapStateToProps, undefined)(StrategiesList);
diff --git a/frontend/src/component/feature/strategy/strategies-list.jsx b/frontend/src/component/feature/strategy/strategies-list.jsx
deleted file mode 100644
index 64ecf2b0b8..0000000000
--- a/frontend/src/component/feature/strategy/strategies-list.jsx
+++ /dev/null
@@ -1,76 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import ConfigureStrategy from './strategy-configure-container';
-import { DndProvider } from 'react-dnd';
-import { HTML5Backend } from 'react-dnd-html5-backend';
-
-const randomKeys = length => Array.from({ length }, () => Math.random());
-
-class StrategiesList extends React.Component {
- static propTypes = {
- strategies: PropTypes.array.isRequired,
- configuredStrategies: PropTypes.array.isRequired,
- featureToggleName: PropTypes.string.isRequired,
- updateStrategy: PropTypes.func,
- removeStrategy: PropTypes.func,
- moveStrategy: PropTypes.func,
- editable: PropTypes.bool,
- };
-
- constructor(props) {
- super();
- // temporal hack, until strategies get UIDs
- this.state = { keys: randomKeys(props.configuredStrategies.length) };
- }
-
- moveStrategy = async (index, toIndex) => {
- await this.props.moveStrategy(index, toIndex);
- this.setState({ keys: randomKeys(this.props.configuredStrategies.length) });
- };
- removeStrategy = async index => {
- await this.props.removeStrategy(index);
- this.setState({ keys: randomKeys(this.props.configuredStrategies.length) });
- };
-
- componentDidUpdate(props) {
- const { keys } = this.state;
- if (keys.length < props.configuredStrategies.length) {
- // eslint-disable-next-line react/no-did-update-set-state
- this.setState({ keys: randomKeys(props.configuredStrategies.length) });
- }
- }
-
- render() {
- const { strategies, configuredStrategies, updateStrategy, featureToggleName, editable } = this.props;
-
- const { keys } = this.state;
- if (!configuredStrategies || configuredStrategies.length === 0) {
- return (
-
- No activation strategies selected.
-
- );
- }
-
- const blocks = configuredStrategies.map((strategy, i) => (
- s.name === strategy.name)}
- editable={editable}
- />
- ));
- return (
-
- {blocks}
-
- );
- }
-}
-
-export default StrategiesList;
diff --git a/frontend/src/component/feature/strategy/strategy-configure-component.jsx b/frontend/src/component/feature/strategy/strategy-configure-component.jsx
index 8775d46a91..fcb8eb11fd 100644
--- a/frontend/src/component/feature/strategy/strategy-configure-component.jsx
+++ b/frontend/src/component/feature/strategy/strategy-configure-component.jsx
@@ -8,6 +8,7 @@ import DefaultStrategy from './default-strategy';
import GeneralStrategy from './general-strategy';
import UserWithIdStrategy from './user-with-id-strategy';
import UnknownStrategy from './unknown-strategy';
+import LoadingStrategy from './loading-strategy';
import styles from './strategy.module.scss';
@@ -18,61 +19,35 @@ export default class StrategyConfigureComponent extends React.Component {
index: PropTypes.number.isRequired,
strategyDefinition: PropTypes.object,
updateStrategy: PropTypes.func,
+ saveStrategy: PropTypes.func,
removeStrategy: PropTypes.func,
moveStrategy: PropTypes.func,
isDragging: PropTypes.bool.isRequired,
hovered: PropTypes.bool,
+ movable: PropTypes.bool,
connectDragPreview: PropTypes.func.isRequired,
connectDragSource: PropTypes.func.isRequired,
connectDropTarget: PropTypes.func.isRequired,
editable: PropTypes.bool,
};
- constructor(props) {
- super();
- this.state = {
- constraints: props.strategy.constraints ? [...props.strategy.constraints] : [],
- parameters: { ...props.strategy.parameters },
- edit: false,
- dirty: false,
- index: props.index,
- };
- }
-
updateParameters = parameters => {
- const { constraints } = this.state;
- const updatedStrategy = Object.assign({}, this.props.strategy, {
- parameters,
- constraints,
- });
+ const { strategy } = this.props;
+ const updatedStrategy = { ...strategy, parameters };
this.props.updateStrategy(updatedStrategy);
};
updateConstraints = constraints => {
- this.setState({ constraints, dirty: true });
+ const { strategy } = this.props;
+ const updatedStrategy = { ...strategy, constraints };
+ this.props.updateStrategy(updatedStrategy);
};
- updateParameter = async (field, value, forceUp = false) => {
- const { parameters } = this.state;
+ updateParameter = async (field, value) => {
+ const { strategy } = this.props;
+ const parameters = { ...strategy.parameters };
parameters[field] = value;
- if (forceUp) {
- await this.updateParameters(parameters);
- this.setState({ parameters, dirty: false });
- } else {
- this.setState({ parameters, dirty: true });
- }
- };
-
- onSave = evt => {
- evt.preventDefault();
- const { parameters } = this.state;
this.updateParameters(parameters);
- this.setState({ edit: false, dirty: false });
- };
-
- handleRemove = evt => {
- evt.preventDefault();
- this.props.removeStrategy();
};
resolveInputType() {
@@ -81,6 +56,8 @@ export default class StrategyConfigureComponent extends React.Component {
return UnknownStrategy;
}
switch (strategyDefinition.name) {
+ case 'Loading':
+ return LoadingStrategy;
case 'default':
return DefaultStrategy;
case 'flexibleRollout':
@@ -93,7 +70,6 @@ export default class StrategyConfigureComponent extends React.Component {
}
render() {
- const { dirty, parameters } = this.state;
const {
isDragging,
hovered,
@@ -104,11 +80,14 @@ export default class StrategyConfigureComponent extends React.Component {
strategyDefinition,
strategy,
index,
+ removeStrategy,
+ saveStrategy,
+ movable,
} = this.props;
- const { name } = strategy;
+ const { name, dirty, parameters } = strategy;
- const description = strategyDefinition ? strategyDefinition.description : 'Uknown';
+ const description = strategyDefinition ? strategyDefinition.description : 'Unknown';
const InputType = this.resolveInputType(name);
const cardClasses = [styles.card];
@@ -143,7 +122,7 @@ export default class StrategyConfigureComponent extends React.Component {
editable={editable}
/>
{editable && (
)}
{editable &&
+ movable &&
connectDragSource(
)}
+ {editable && !movable && (
+
+
+
+ )}
diff --git a/frontend/src/component/feature/strategy/strategy-input-props.js b/frontend/src/component/feature/strategy/strategy-input-props.js
index ad80363906..b36515efdc 100644
--- a/frontend/src/component/feature/strategy/strategy-input-props.js
+++ b/frontend/src/component/feature/strategy/strategy-input-props.js
@@ -2,6 +2,7 @@ import PropTypes from 'prop-types';
export default {
strategyDefinition: PropTypes.shape({
+ name: PropTypes.string,
parameters: PropTypes.array,
}).isRequired,
parameters: PropTypes.object.isRequired,
diff --git a/frontend/src/component/feature/strategy/strategy.module.scss b/frontend/src/component/feature/strategy/strategy.module.scss
index b8a7cb8fcf..8f343a5d29 100644
--- a/frontend/src/component/feature/strategy/strategy.module.scss
+++ b/frontend/src/component/feature/strategy/strategy.module.scss
@@ -1,7 +1,7 @@
.item {
flex: 1;
min-width: 400px;
- max-width: 100%;
+ max-width: 537px;
margin: 5px 0 5px 5px;
position: relative;
z-index: 1;
@@ -85,15 +85,25 @@
cursor: pointer;
display: inline-block;
vertical-align: bottom;
+
+ &.disabled {
+ cursor: default;
+ color: silver;
+ }
}
-
-.paddingDesktop {
+.strategyList {
+ display: flex;
+ flex-wrap: wrap;
padding: 10px;
}
+.strategyListAdd {
+ background-color: #f9f9f9;
+}
+
@media (max-width: 500px) {
- .paddingDesktop {
+ .strategyList {
padding: 0;
}
}
diff --git a/frontend/src/component/feature/strategy/unknown-strategy.jsx b/frontend/src/component/feature/strategy/unknown-strategy.jsx
index 4373b642bd..47ba46752a 100644
--- a/frontend/src/component/feature/strategy/unknown-strategy.jsx
+++ b/frontend/src/component/feature/strategy/unknown-strategy.jsx
@@ -1,9 +1,9 @@
import React from 'react';
-import strategyInputProps from './strategy-input-props';
+import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
-export default function UknownStrategy({ strategy }) {
+export default function UnknownStrategy({ strategy }) {
const { name } = strategy;
return (
@@ -13,4 +13,8 @@ export default function UknownStrategy({ strategy }) {
);
}
-UknownStrategy.propTypes = strategyInputProps;
+UnknownStrategy.propTypes = {
+ strategy: PropTypes.shape({
+ name: PropTypes.string,
+ }).isRequired,
+};
diff --git a/frontend/src/component/feature/view/__tests__/__snapshots__/update-strategies-component-test.jsx.snap b/frontend/src/component/feature/view/__tests__/__snapshots__/update-strategies-component-test.jsx.snap
index 9b0de07dff..b3bacd516f 100644
--- a/frontend/src/component/feature/view/__tests__/__snapshots__/update-strategies-component-test.jsx.snap
+++ b/frontend/src/component/feature/view/__tests__/__snapshots__/update-strategies-component-test.jsx.snap
@@ -1,3 +1,27 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`render the create feature page 1`] = `""`;
+exports[`render the create feature page 1`] = `
+
+`;
diff --git a/frontend/src/component/feature/view/update-strategies-component.jsx b/frontend/src/component/feature/view/update-strategies-component.jsx
index d364af3985..3ae49d067d 100644
--- a/frontend/src/component/feature/view/update-strategies-component.jsx
+++ b/frontend/src/component/feature/view/update-strategies-component.jsx
@@ -1,19 +1,14 @@
import React from 'react';
import PropTypes from 'prop-types';
-import StrategiesList from '../strategy/strategies-list';
-import AddStrategy from '../strategy/strategies-add';
-import { HeaderTitle } from '../../common';
-
-import styles from '../strategy/strategy.module.scss';
+import StrategiesList from '../strategy/strategies-list-container';
+// TODO: do we still need this wrapper?
function UpdateStrategiesComponent(props) {
- const { editable, configuredStrategies, strategies } = props;
+ const { configuredStrategies } = props;
if (!configuredStrategies || configuredStrategies.length === 0) return null;
- if (!strategies || strategies.length === 0) return null;
return (
-
- {editable && } />}
+
);
@@ -23,10 +18,6 @@ UpdateStrategiesComponent.propTypes = {
featureToggleName: PropTypes.string.isRequired,
strategies: PropTypes.array,
configuredStrategies: PropTypes.array.isRequired,
- addStrategy: PropTypes.func.isRequired,
- removeStrategy: PropTypes.func.isRequired,
- moveStrategy: PropTypes.func.isRequired,
- updateStrategy: PropTypes.func.isRequired,
editable: PropTypes.bool,
};
diff --git a/frontend/src/component/feature/view/update-strategies-container.jsx b/frontend/src/component/feature/view/update-strategies-container.jsx
index 3e4fc80c6f..1b63833a90 100644
--- a/frontend/src/component/feature/view/update-strategies-container.jsx
+++ b/frontend/src/component/feature/view/update-strategies-container.jsx
@@ -1,6 +1,5 @@
/* eslint-disable no-console */
import { connect } from 'react-redux';
-import arrayMove from 'array-move';
import { requestUpdateFeatureToggleStrategies } from '../../../store/feature-toggle/actions';
import UpdateStrategiesComponent from './update-strategies-component';
@@ -8,39 +7,11 @@ import UpdateStrategiesComponent from './update-strategies-component';
const mapStateToProps = (state, ownProps) => ({
featureToggleName: ownProps.featureToggle.name,
configuredStrategies: ownProps.featureToggle.strategies,
- strategies: state.strategies.get('list').toArray(),
});
const mapDispatchToProps = (dispatch, ownProps) => ({
- addStrategy: s => {
- console.log(`add ${s}`);
+ saveStrategies: strategies => {
const featureToggle = ownProps.featureToggle;
- const strategies = featureToggle.strategies.concat(s);
- return requestUpdateFeatureToggleStrategies(featureToggle, strategies)(dispatch);
- },
-
- removeStrategy: index => {
- console.log(`remove ${index}`);
- const featureToggle = ownProps.featureToggle;
- const strategies = featureToggle.strategies.filter((_, i) => i !== index);
- return requestUpdateFeatureToggleStrategies(featureToggle, strategies)(dispatch);
- },
-
- moveStrategy: (index, toIndex) => {
- // methods.moveItem('strategies', index, toIndex);
- console.log(`move strategy from ${index} to ${toIndex}`);
- console.log(ownProps.featureToggle);
- const featureToggle = ownProps.featureToggle;
- const strategies = arrayMove(featureToggle.strategies, index, toIndex);
- return requestUpdateFeatureToggleStrategies(featureToggle, strategies)(dispatch);
- },
-
- updateStrategy: (index, s) => {
- // methods.updateInList('strategies', index, n);
- console.log(`update strtegy at index ${index} with ${JSON.stringify(s)}`);
- const featureToggle = ownProps.featureToggle;
- const strategies = featureToggle.strategies.concat();
- strategies[index] = s;
return requestUpdateFeatureToggleStrategies(featureToggle, strategies)(dispatch);
},
});
diff --git a/frontend/src/component/strategies/__tests__/__snapshots__/list-component-test.jsx.snap b/frontend/src/component/strategies/__tests__/__snapshots__/list-component-test.jsx.snap
index 6d2d7bb21a..fbfcb06972 100644
--- a/frontend/src/component/strategies/__tests__/__snapshots__/list-component-test.jsx.snap
+++ b/frontend/src/component/strategies/__tests__/__snapshots__/list-component-test.jsx.snap
@@ -13,10 +13,10 @@ exports[`renders correctly with one strategy 1`] = `
@@ -104,10 +104,10 @@ exports[`renders correctly with one strategy without permissions 1`] = `
diff --git a/frontend/src/component/strategies/__tests__/__snapshots__/strategy-details-component-test.jsx.snap b/frontend/src/component/strategies/__tests__/__snapshots__/strategy-details-component-test.jsx.snap
index a7fee260d9..2dd87b1e64 100644
--- a/frontend/src/component/strategies/__tests__/__snapshots__/strategy-details-component-test.jsx.snap
+++ b/frontend/src/component/strategies/__tests__/__snapshots__/strategy-details-component-test.jsx.snap
@@ -10,10 +10,10 @@ exports[`renders correctly with one strategy 1`] = `
diff --git a/frontend/src/component/tag-types/__tests__/__snapshots__/tag-type-list-component-test.js.snap b/frontend/src/component/tag-types/__tests__/__snapshots__/tag-type-list-component-test.js.snap
index 6fc6f78ffb..77fc364546 100644
--- a/frontend/src/component/tag-types/__tests__/__snapshots__/tag-type-list-component-test.js.snap
+++ b/frontend/src/component/tag-types/__tests__/__snapshots__/tag-type-list-component-test.js.snap
@@ -13,10 +13,10 @@ exports[`renders a list with elements correctly 1`] = `
@@ -92,10 +92,10 @@ exports[`renders an empty list correctly 1`] = `
diff --git a/frontend/yarn.lock b/frontend/yarn.lock
index 06662296e6..7c63a50cd2 100644
--- a/frontend/yarn.lock
+++ b/frontend/yarn.lock
@@ -6533,7 +6533,7 @@ lodash@^4.0.0, lodash@^4.15.0, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
-lodash@^4.17.19:
+lodash@^4.17.19, lodash@^4.17.20:
version "4.17.20"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
|