diff --git a/frontend/src/assets/icons/reorder.svg b/frontend/src/assets/icons/reorder.svg new file mode 100644 index 0000000000..99f4cb517f --- /dev/null +++ b/frontend/src/assets/icons/reorder.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/frontend/src/component/feature/strategy/StrategyCard/StrategyCard.styles.js b/frontend/src/component/feature/strategy/StrategyCard/StrategyCard.styles.js index 3f6c57a07d..7b0a825692 100644 --- a/frontend/src/component/feature/strategy/StrategyCard/StrategyCard.styles.js +++ b/frontend/src/component/feature/strategy/StrategyCard/StrategyCard.styles.js @@ -1,8 +1,20 @@ import { makeStyles } from '@material-ui/styles'; -export const useStyles = makeStyles({ +export const useStyles = makeStyles(theme => ({ strategyCard: { - width: '250px', + width: '337px', height: '100%', + [theme.breakpoints.down('xs')]: { + width: '100%', + }, + [theme.breakpoints.down('1250')]: { + width: '300px', + }, + [theme.breakpoints.down('1035')]: { + width: '280px', + }, + [theme.breakpoints.down('860')]: { + width: '380px', + }, }, -}); +})); diff --git a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/StrategyCardContentCustom/StrategyCardContentCustom.jsx b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/StrategyCardContentCustom/StrategyCardContentCustom.jsx index 733075e38a..bc0ee1ba58 100644 --- a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/StrategyCardContentCustom/StrategyCardContentCustom.jsx +++ b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/StrategyCardContentCustom/StrategyCardContentCustom.jsx @@ -5,7 +5,7 @@ import { Typography } from '@material-ui/core'; import { Link } from 'react-router-dom'; import StrategyCardPercentage from '../common/StrategyCardPercentage/StrageyCardPercentage'; -import StrategyCardConstraints from '../common/StrategyCardConstraints/StrategyCardConstraints'; +import StrategyCardConstraints from '../common/StrategyCardConstraints'; import { useCommonStyles } from '../../../../../../common.styles'; import ConditionallyRender from '../../../../../common/ConditionallyRender'; @@ -19,7 +19,9 @@ const StrategyCardContentCustom = ({ strategy, strategyDefinition }) => { return ( The strategy definition "{strategy.name}" does not exist.{' '} - Create a strategy named {strategy.name} + + Create a strategy named {strategy.name} + ); if (strategyDefinition.name === 'Loading') return null; @@ -42,7 +44,7 @@ const StrategyCardContentCustom = ({ strategy, strategyDefinition }) => { case 'list': /* eslint-disable-next-line */ const paramList = param - ? param.split(",").filter(listItem => listItem) + ? param.split(',').filter(listItem => listItem) : []; return ( @@ -51,7 +53,10 @@ const StrategyCardContentCustom = ({ strategy, strategyDefinition }) => { condition={paramList.length > 0} show={ <> - +
} @@ -64,29 +69,28 @@ const StrategyCardContentCustom = ({ strategy, strategyDefinition }) => { } + show={ + + } /> ); default: - return null + return null; } }; const renderCustomSections = () => - strategyDefinition.parameters.map(paramDefinition => getSection(paramDefinition)); + strategyDefinition.parameters.map(paramDefinition => + getSection(paramDefinition) + ); return (
+ {renderCustomSections()} - 0} - show={ - <> -
- - - } - />
); }; diff --git a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/StrategyCardContentDefault/StrategyCardContentDefault.jsx b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/StrategyCardContentDefault/StrategyCardContentDefault.jsx index dd87c6b95c..d6b5568310 100644 --- a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/StrategyCardContentDefault/StrategyCardContentDefault.jsx +++ b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/StrategyCardContentDefault/StrategyCardContentDefault.jsx @@ -3,7 +3,6 @@ import React from 'react'; import { Typography } from '@material-ui/core'; import { useCommonStyles } from '../../../../../../common.styles'; -import ConditionallyRender from '../../../../../common/ConditionallyRender'; import StrategyCardConstraints from '../common/StrategyCardConstraints/StrategyCardConstraints'; const StrategyCardContentDefault = ({ strategy }) => { @@ -13,18 +12,11 @@ const StrategyCardContentDefault = ({ strategy }) => { return ( <> + +
- The default strategy is either on or off for all users. + The default strategy is on for all users. - 0} - show={ - <> -
- - - } - /> ); }; diff --git a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/StrategyCardContentFlexible/StrategyCardContentFlexible.jsx b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/StrategyCardContentFlexible/StrategyCardContentFlexible.jsx index 68a770c5fc..ef5be58d36 100644 --- a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/StrategyCardContentFlexible/StrategyCardContentFlexible.jsx +++ b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/StrategyCardContentFlexible/StrategyCardContentFlexible.jsx @@ -2,11 +2,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import StrategyCardPercentage from '../common/StrategyCardPercentage/StrageyCardPercentage'; -import StrategyCardConstraints from '../common/StrategyCardConstraints/StrategyCardConstraints'; +import StrategyCardConstraints from '../common/StrategyCardConstraints'; import StrategyCardField from '../common/StrategyCardField/StrategyCardField'; import { useCommonStyles } from '../../../../../../common.styles'; -import ConditionallyRender from '../../../../../common/ConditionallyRender'; const StrategyCardContentFlexible = ({ strategy }) => { const commonStyles = useCommonStyles(); @@ -18,16 +17,9 @@ const StrategyCardContentFlexible = ({ strategy }) => { return (
+ +
- 0} - show={ - <> -
- - - } - />
diff --git a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/StrategyCardContentGradRandom/StrategyCardContentGradRandom.jsx b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/StrategyCardContentGradRandom/StrategyCardContentGradRandom.jsx index adceb38794..d77336c162 100644 --- a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/StrategyCardContentGradRandom/StrategyCardContentGradRandom.jsx +++ b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/StrategyCardContentGradRandom/StrategyCardContentGradRandom.jsx @@ -2,10 +2,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import StrategyCardPercentage from '../common/StrategyCardPercentage/StrageyCardPercentage'; -import StrategyCardConstraints from '../common/StrategyCardConstraints/StrategyCardConstraints'; +import StrategyCardConstraints from '../common/StrategyCardConstraints'; import { useCommonStyles } from '../../../../../../common.styles'; -import ConditionallyRender from '../../../../../common/ConditionallyRender'; const StrategyCardContentGradRandom = ({ strategy }) => { const commonStyles = useCommonStyles(); @@ -15,16 +14,9 @@ const StrategyCardContentGradRandom = ({ strategy }) => { return (
+ +
- 0} - show={ - <> -
- - - } - />
); }; diff --git a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/StrategyCardContentList/StrategyCardContentList.jsx b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/StrategyCardContentList/StrategyCardContentList.jsx index a25f5c8cb6..d0120002b1 100644 --- a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/StrategyCardContentList/StrategyCardContentList.jsx +++ b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/StrategyCardContentList/StrategyCardContentList.jsx @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -import StrategyCardConstraints from '../common/StrategyCardConstraints/StrategyCardConstraints'; +import StrategyCardConstraints from '../common/StrategyCardConstraints'; import { useCommonStyles } from '../../../../../../common.styles'; import ConditionallyRender from '../../../../../common/ConditionallyRender'; @@ -15,16 +15,14 @@ const StrategyCardContentList = ({ strategy, parameter, valuesName }) => { return (
+ + 0} - show={} - /> - 0} show={ <>
- + } /> diff --git a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/StrategyCardContentRollout/StrategyCardContentRollout.jsx b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/StrategyCardContentRollout/StrategyCardContentRollout.jsx index 5510fd5145..ac20d822c6 100644 --- a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/StrategyCardContentRollout/StrategyCardContentRollout.jsx +++ b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/StrategyCardContentRollout/StrategyCardContentRollout.jsx @@ -2,11 +2,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import StrategyCardPercentage from '../common/StrategyCardPercentage/StrageyCardPercentage'; -import StrategyCardConstraints from '../common/StrategyCardConstraints/StrategyCardConstraints'; +import StrategyCardConstraints from '../common/StrategyCardConstraints'; import StrategyCardField from '../common/StrategyCardField/StrategyCardField'; import { useCommonStyles } from '../../../../../../common.styles'; -import ConditionallyRender from '../../../../../common/ConditionallyRender'; const StrategyCardContentRollout = ({ strategy }) => { const commonStyles = useCommonStyles(); @@ -17,16 +16,9 @@ const StrategyCardContentRollout = ({ strategy }) => { return (
+ +
- 0} - show={ - <> -
- - - } - />
diff --git a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardConstraints/StrategyCardConstraints.jsx b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardConstraints/StrategyCardConstraints.jsx index e916761e53..f15090ab3d 100644 --- a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardConstraints/StrategyCardConstraints.jsx +++ b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardConstraints/StrategyCardConstraints.jsx @@ -1,55 +1,122 @@ import { Typography } from '@material-ui/core'; import PropTypes from 'prop-types'; import classnames from 'classnames'; -import React from 'react'; import { useStyles } from './StrategyCardConstraints.styles.js'; -import { useCommonStyles } from '../../../../../../../common.styles.js'; +import ConditionallyRender from '../../../../../../common/ConditionallyRender/ConditionallyRender'; +import { C } from '../../../../../../common/flags.js'; -const StrategyCardConstraints = ({ constraints }) => { +const StrategyCardConstraints = ({ constraints, flags }) => { const styles = useStyles(); - const commonStyles = useCommonStyles(); - const renderConstraintValues = constraint => - constraint.values.map(value => ( - - {value} - - )); + const isEnterprise = () => { + if (!flags) return false; + if (flags[C]) { + return true; + } + return false; + }; - const renderConstraints = () => - constraints.map((constraint, i) => ( -
-
- - context - - {constraint.contextName} -
-
- - operator - - {constraint.operator} -
+ const renderConstraintValues = constraint => { + const multiple = constraint.values.length > 1; + return constraint.values.map((value, index) => { + const notLastItem = index !== constraint.values.length - 1; + return ( + '{value}',} + elseShow={'{value}'} + /> + ); + }); + }; -
- - values - -
- {renderConstraintValues(constraint)} -
-
+ const renderConstraints = () => { + return constraints.map((constraint, i) => ( +
+ 0} + show={and} + /> +
+                    {constraint.contextName}
+
+                    {constraint.operator}
+
+                    {renderConstraintValues(constraint)}
+                
)); + }; return ( <> Constraints - {renderConstraints()} + + 0} + show={ + <> + + The following pre-conditions must be fulfilled for + this strategy to be executed + +
+ {renderConstraints()} +
+ + } + elseShow={ + <> + + No pre-conditions defined for this strategy. + + + Constraints allow you fine grained control + over how to execute your strategies. + + Learn more + + + } + elseShow={ + + Constraints are only available as an + enterprise feature.{' '} + + Learn more + + + } + /> + + } + /> ); }; diff --git a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardConstraints/StrategyCardConstraints.styles.js b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardConstraints/StrategyCardConstraints.styles.js index 28b9edde0e..0946eb2f8c 100644 --- a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardConstraints/StrategyCardConstraints.styles.js +++ b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardConstraints/StrategyCardConstraints.styles.js @@ -1,34 +1,27 @@ import { makeStyles } from '@material-ui/styles'; export const useStyles = makeStyles(theme => ({ + constraints: { + marginTop: '1rem', + }, constraintContainer: { backgroundColor: theme.palette.cards.container.bg, margin: '0.5rem 0', borderRadius: theme.borders.radius.main, padding: '0.8rem', - overflow: 'scroll', display: 'flex', alignItems: 'center', flexWrap: 'wrap', + '& span': { + marginRight: '0.4rem', + fontSize: '0.9rem', + }, }, - verticalSpacer: { - margin: '0 0.25rem', - }, - title: { - fontWeight: theme.fontWeight.semi, - }, - constraintDisplayContainer: { - display: 'flex', - flexDirection: 'column', - width: '50%', - }, - label: { - fontWeight: theme.fontWeight.bold, - }, - constraintValuesContainer: { + placeholderText: { marginTop: '0.25rem', }, - constraintValue: { - marginRight: '0.25rem', + link: { + display: 'block', + marginTop: '0.2rem', }, })); diff --git a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardConstraints/index.js b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardConstraints/index.js new file mode 100644 index 0000000000..36a256853a --- /dev/null +++ b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardConstraints/index.js @@ -0,0 +1,9 @@ +import { connect } from 'react-redux'; +import StrategyCardConstraints from './StrategyCardConstraints'; + +const mapStateToProps = (state, ownProps) => ({ + flags: state.uiConfig.toJS().flags, + constraints: ownProps.constraints, +}); + +export default connect(mapStateToProps)(StrategyCardConstraints); diff --git a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardField/StrategyCardField.jsx b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardField/StrategyCardField.jsx index 4ed099336e..7070188588 100644 --- a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardField/StrategyCardField.jsx +++ b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardField/StrategyCardField.jsx @@ -8,9 +8,7 @@ const StrategyCardField = ({ title, value }) => { const styles = useStyles(); return (
- - {title} - + {title} {value} diff --git a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardField/StrategyCardField.styles.js b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardField/StrategyCardField.styles.js index 93c707d765..b3c13df7c5 100644 --- a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardField/StrategyCardField.styles.js +++ b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardField/StrategyCardField.styles.js @@ -6,9 +6,6 @@ export const useStyles = makeStyles(theme => ({ justifyContent: 'space-between', margin: '0.4rem 0', }, - fieldTitle: { - fontWeight: theme.fontWeight.semi, - }, fieldValue: { maxWidth: '50%', }, diff --git a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardList/StrategyCardList.jsx b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardList/StrategyCardList.jsx index b3264865ab..51bfd554f4 100644 --- a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardList/StrategyCardList.jsx +++ b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardList/StrategyCardList.jsx @@ -10,9 +10,15 @@ const StrategyCardList = ({ list, valuesName }) => { return (
- List of {valuesName} + + List of {valuesName} + {list.map(listItem => ( - + ))}
); diff --git a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardList/StrategyCardList.styles.js b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardList/StrategyCardList.styles.js index ea1bb0f05e..146b110cc2 100644 --- a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardList/StrategyCardList.styles.js +++ b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardList/StrategyCardList.styles.js @@ -8,7 +8,6 @@ export const useStyles = makeStyles(theme => ({ margin: '0.25rem', }, strategyListHeader: { - fontWeight: theme.fontWeight.semi, marginBottom: '0.5rem', }, })); diff --git a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardPercentage/StrategyCardPercentage.styles.js b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardPercentage/StrategyCardPercentage.styles.js index adf5f4c237..301d751e30 100644 --- a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardPercentage/StrategyCardPercentage.styles.js +++ b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardContent/common/StrategyCardPercentage/StrategyCardPercentage.styles.js @@ -5,11 +5,7 @@ export const useStyles = makeStyles(theme => ({ display: 'flex', justifyContent: 'space-between', }, - title: { - fontWeight: theme.fontWeight.semi, - }, percentage: { - color: theme.palette.success.main, fontWeight: 'bold', }, })); diff --git a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardHeader/StrategyCardHeader.jsx b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardHeader/StrategyCardHeader.jsx index 85a8d76c0c..8b80695fd1 100644 --- a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardHeader/StrategyCardHeader.jsx +++ b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardHeader/StrategyCardHeader.jsx @@ -1,11 +1,23 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { CardHeader, Typography, IconButton, Icon } from '@material-ui/core'; +import { + CardHeader, + Typography, + IconButton, + Icon, + Tooltip, +} from '@material-ui/core'; import { useStyles } from './StrategyCardHeader.styles.js'; +import { ReactComponent as ReorderIcon } from '../../../../../assets/icons/reorder.svg'; -const StrategyCardHeader = ({ name, connectDragSource, removeStrategy, editStrategy }) => { +const StrategyCardHeader = ({ + name, + connectDragSource, + removeStrategy, + editStrategy, +}) => { const styles = useStyles(); return ( @@ -16,23 +28,36 @@ const StrategyCardHeader = ({ name, connectDragSource, removeStrategy, editStrat }} title={ <> - + {name}
- - edit - + + + + edit + + + {connectDragSource( - - reorder - + + + + + )} - - delete - + + + + delete + + +
} diff --git a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardHeader/StrategyCardHeader.styles.js b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardHeader/StrategyCardHeader.styles.js index 40160f8128..dabafe7bed 100644 --- a/frontend/src/component/feature/strategy/StrategyCard/StrategyCardHeader/StrategyCardHeader.styles.js +++ b/frontend/src/component/feature/strategy/StrategyCard/StrategyCardHeader/StrategyCardHeader.styles.js @@ -3,23 +3,21 @@ import { makeStyles } from '@material-ui/styles'; export const useStyles = makeStyles(theme => ({ strategyCardHeaderContent: { width: '100%', + display: 'flex', + alignItems: 'center', + justifyContent: 'space-between', }, strategyCardHeader: { display: 'flex', - flexDirection: 'column', background: `linear-gradient(${theme.palette.cards.gradient.top}, ${theme.palette.cards.gradient.bottom})`, color: '#fff', - textAlign: 'center', - width: '100%', + textAlign: 'left', }, strategyCardHeaderTitle: { - fontWeight: 'bold', - fontSize: theme.fontSizes.mainHeader, - marginBottom: '0.7rem', + fontSize: theme.fontSizes.subHeader, }, strategyCardHeaderActions: { display: 'flex', - justifyContent: 'space-between', color: '#fff', }, strateyCardHeaderIcon: { diff --git a/frontend/src/component/feature/strategy/strategies-list-component.jsx b/frontend/src/component/feature/strategy/strategies-list-component.jsx index 889e9b2dbf..87888a8dae 100644 --- a/frontend/src/component/feature/strategy/strategies-list-component.jsx +++ b/frontend/src/component/feature/strategy/strategies-list-component.jsx @@ -187,16 +187,20 @@ const StrategiesList = props => { className={styles.infoCard} onClose={() => setShowAlert(false)} > - Strategies allow you fine grained control over how to - activate your features, and are composable blocks that - are executed in an OR fashion. As an example, you can - have a gradual rollout that targets 80% of users in a - region of the world (using the enterprise feature of - constraints), and another gradual rollout that targets - 20% of the users in another region. If you don't add a - strategy, the default strategy is activated which means - that the feature will be strictly on/off for your entire - userbase. +
+ Activation strategies defines how you enable the new + feature to your users. Changes to the activation + strategies does not require redeployment of the + code. +
+
+ Multiple activation strategies are composable blocks + that is executed in an OR fashion. +
+ E.g. A gradual rollout activation strategy allows + you to gradually enable to feature to a subset of + your users without redeploy to production. +
} /> diff --git a/frontend/src/component/feature/strategy/strategy.module.scss b/frontend/src/component/feature/strategy/strategy.module.scss index 5c0f6b489f..78249eed75 100644 --- a/frontend/src/component/feature/strategy/strategy.module.scss +++ b/frontend/src/component/feature/strategy/strategy.module.scss @@ -11,7 +11,7 @@ width: 100%; display: block; background-color: #f2f9fc; - overflow: "visible"; + overflow: 'visible'; } .paragraph { @@ -156,3 +156,11 @@ padding: 0; } } + +@media (max-width: 860px) { + .strategyListCards { + flex-direction: column; + flex-wrap: none; + align-items: center; + } +}