diff --git a/frontend/cypress/integration/feature-toggle/feature.spec.js b/frontend/cypress/integration/feature-toggle/feature.spec.js index 404951534c..ea4d779eb6 100644 --- a/frontend/cypress/integration/feature-toggle/feature.spec.js +++ b/frontend/cypress/integration/feature-toggle/feature.spec.js @@ -82,7 +82,9 @@ describe('feature toggle', () => { cy.get('[data-test=NAVIGATE_TO_CREATE_FEATURE').click(); - cy.intercept('POST', '/api/admin/features').as('createFeature'); + cy.intercept('POST', '/api/admin/projects/default/features').as( + 'createFeature' + ); cy.get("[data-test='CF_NAME_ID'").type(featureToggleName); cy.get("[data-test='CF_DESC_ID'").type('hellowrdada'); diff --git a/frontend/package.json b/frontend/package.json index c88647cee9..ecaf782a48 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -33,6 +33,7 @@ "test": "react-scripts test", "prepare": "yarn run build", "e2e": "yarn run cypress open --config baseUrl='http://localhost:3000' --env PASSWORD_AUTH=true,AUTH_TOKEN=$AUTH_TOKEN", + "e2e:heroku": "yarn run cypress open --config baseUrl='http://localhost:3000' --env PASSWORD_AUTH=false,AUTH_TOKEN=$AUTH_TOKEN", "e2e:enterprise": "yarn run cypress open --config baseUrl='http://localhost:3000' --env PASSWORD_AUTH=true,ENTERPRISE=true,AUTH_TOKEN=$AUTH_TOKEN" }, "devDependencies": { diff --git a/frontend/src/component/common/Constraint/Constraint.styles.ts b/frontend/src/component/common/Constraint/Constraint.styles.ts index d9b3834573..2541965ff9 100644 --- a/frontend/src/component/common/Constraint/Constraint.styles.ts +++ b/frontend/src/component/common/Constraint/Constraint.styles.ts @@ -11,11 +11,21 @@ export const useStyles = makeStyles(theme => ({ alignItems: 'center', justifyContent: 'center', padding: '0.1rem 0.5rem', - border: `1px solid ${theme.palette.grey[300]}`, - borderRadius: '5px', fontSize: theme.fontSizes.smallBody, backgroundColor: theme.palette.grey[200], margin: '0.5rem 0', + position: 'relative', + borderRadius: '5px', + }, + constraintBtn: { + color: theme.palette.primary.main, + fontWeight: 'normal', + marginBottom: '0.5rem', + }, + btnContainer: { + position: 'absolute', + top: '6px', + right: 0, }, column: { flexDirection: 'column', diff --git a/frontend/src/component/common/Constraint/Constraint.tsx b/frontend/src/component/common/Constraint/Constraint.tsx index de1c96c1cc..8b960fac12 100644 --- a/frontend/src/component/common/Constraint/Constraint.tsx +++ b/frontend/src/component/common/Constraint/Constraint.tsx @@ -1,31 +1,75 @@ +import { Delete, Edit } from '@material-ui/icons'; import classnames from 'classnames'; +import { useParams } from 'react-router'; +import { IFeatureViewParams } from '../../../interfaces/params'; import { IConstraint } from '../../../interfaces/strategy'; import FeatureStrategiesSeparator from '../../feature/FeatureView2/FeatureStrategies/FeatureStrategiesEnvironments/FeatureStrategiesSeparator/FeatureStrategiesSeparator'; +import { UPDATE_FEATURE } from '../../providers/AccessProvider/permissions'; +import ConditionallyRender from '../ConditionallyRender'; +import PermissionIconButton from '../PermissionIconButton/PermissionIconButton'; import StringTruncator from '../StringTruncator/StringTruncator'; import { useStyles } from './Constraint.styles'; interface IConstraintProps { constraint: IConstraint; className?: string; + deleteCallback?: () => void; + editCallback?: () => void; } -const Constraint = ({ constraint, className, ...rest }: IConstraintProps) => { +const Constraint = ({ + constraint, + deleteCallback, + editCallback, + className, + ...rest +}: IConstraintProps) => { const styles = useStyles(); + const { projectId } = useParams(); const classes = classnames(styles.constraint, { [styles.column]: constraint.values.length > 2, }); + const editable = !!(deleteCallback && editCallback); + return (
- - + + + + {constraint.values.join(', ')} + +
+ + + + + + + + + + + } /> - - {constraint.values.join(', ')} - ); }; diff --git a/frontend/src/component/common/PermissionIconButton/PermissionIconButton.tsx b/frontend/src/component/common/PermissionIconButton/PermissionIconButton.tsx index ac743785ef..3c02b8b654 100644 --- a/frontend/src/component/common/PermissionIconButton/PermissionIconButton.tsx +++ b/frontend/src/component/common/PermissionIconButton/PermissionIconButton.tsx @@ -5,7 +5,7 @@ import AccessContext from '../../../contexts/AccessContext'; interface IPermissionIconButtonProps extends OverridableComponent { permission: string; - Icon: React.ElementType; + Icon?: React.ElementType; tooltip: string; onClick?: (e: any) => void; projectId?: string; diff --git a/frontend/src/component/feature/FeatureView2/FeatureStrategies/FeatureStrategyAccordion/FeatureStrategyAccordionBody/FeatureStrategyAccordionBody.styles.ts b/frontend/src/component/feature/FeatureView2/FeatureStrategies/FeatureStrategyAccordion/FeatureStrategyAccordionBody/FeatureStrategyAccordionBody.styles.ts index 0dc423ddbf..399f20e3fa 100644 --- a/frontend/src/component/feature/FeatureView2/FeatureStrategies/FeatureStrategyAccordion/FeatureStrategyAccordionBody/FeatureStrategyAccordionBody.styles.ts +++ b/frontend/src/component/feature/FeatureView2/FeatureStrategies/FeatureStrategyAccordion/FeatureStrategyAccordionBody/FeatureStrategyAccordionBody.styles.ts @@ -7,7 +7,8 @@ export const useStyles = makeStyles(theme => ({ marginBottom: '0.5rem', }, accordionContainer: { - width: '80%', + width: '100%', + paddingRight: '37px', [theme.breakpoints.down(800)]: { width: '100%', }, @@ -20,7 +21,4 @@ export const useStyles = makeStyles(theme => ({ marginTop: '0.5rem', fontSize: theme.fontSizes.smallBody, }, - constraintBody: { - maxWidth: '350px', - }, })); diff --git a/frontend/src/component/feature/FeatureView2/FeatureStrategies/FeatureStrategyAccordion/FeatureStrategyAccordionBody/FeatureStrategyAccordionBody.tsx b/frontend/src/component/feature/FeatureView2/FeatureStrategies/FeatureStrategyAccordion/FeatureStrategyAccordionBody/FeatureStrategyAccordionBody.tsx index 30266bfbc4..dc47742308 100644 --- a/frontend/src/component/feature/FeatureView2/FeatureStrategies/FeatureStrategyAccordion/FeatureStrategyAccordionBody/FeatureStrategyAccordionBody.tsx +++ b/frontend/src/component/feature/FeatureView2/FeatureStrategies/FeatureStrategyAccordion/FeatureStrategyAccordionBody/FeatureStrategyAccordionBody.tsx @@ -12,7 +12,6 @@ import { useContext, useState } from 'react'; import ConditionallyRender from '../../../../../common/ConditionallyRender'; import useUiConfig from '../../../../../../hooks/api/getters/useUiConfig/useUiConfig'; import { C } from '../../../../../common/flags'; -import { Button } from '@material-ui/core'; import { useStyles } from './FeatureStrategyAccordionBody.styles'; import Dialogue from '../../../../../common/Dialogue'; import DefaultStrategy from '../../common/DefaultStrategy/DefaultStrategy'; @@ -20,6 +19,9 @@ import { ADD_CONSTRAINT_ID } from '../../../../../../testIds'; import AccessContext from '../../../../../../contexts/AccessContext'; import { UPDATE_FEATURE } from '../../../../../providers/AccessProvider/permissions'; import Constraint from '../../../../../common/Constraint/Constraint'; +import PermissionButton from '../../../../../common/PermissionButton/PermissionButton'; +import { useParams } from 'react-router'; +import { IFeatureViewParams } from '../../../../../../interfaces/params'; interface IFeatureStrategyAccordionBodyProps { strategy: IFeatureStrategy; @@ -40,6 +42,7 @@ const FeatureStrategyAccordionBody: React.FC setStrategyConstraints, }) => { const styles = useStyles(); + const { projectId } = useParams(); const [constraintError, setConstraintError] = useState({}); const { strategies } = useStrategies(); const { uiConfig } = useUiConfig(); @@ -106,13 +109,25 @@ const FeatureStrategyAccordionBody: React.FC return ( { + setShowConstraints(true); + }} + deleteCallback={() => { + removeConstraint(index); + }} key={`${constraint.contextName}-${index}`} - className={styles.constraintBody} /> ); }); }; + const removeConstraint = (index: number) => { + const updatedConstraints = [...constraints]; + updatedConstraints.splice(index, 1); + + updateConstraints(updatedConstraints); + }; + const closeConstraintDialog = () => { setShowConstraints(false); const filteredConstraints = constraints.filter(constraint => { @@ -137,18 +152,17 @@ const FeatureStrategyAccordionBody: React.FC Constraints

{renderConstraints()} - - + Edit constraints - - } - /> + + + + Add constraints + } />