From c20aa300ce03b9f1c94d35777828ef53688faac7 Mon Sep 17 00:00:00 2001 From: Tymoteusz Czech <2625371+Tymek@users.noreply.github.com> Date: Thu, 28 Jul 2022 09:34:15 +0200 Subject: [PATCH] Visual updates to constraints (#1157) --- .../ConstraintAccordion.styles.ts | 5 +- .../ConstraintAccordionList.styles.ts | 1 + .../ConstraintAccordionList.tsx | 237 ++++++++++-------- .../StrategySeparator/StrategySeparator.tsx | 2 +- .../StrategyExecution/StrategyExecution.tsx | 5 +- .../StrategyItem/StrategyItem.styles.ts | 1 + .../FeatureOverviewSegment.styles.ts | 10 +- .../FeatureOverviewSegment.tsx | 7 +- 8 files changed, 148 insertions(+), 120 deletions(-) diff --git a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordion.styles.ts b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordion.styles.ts index e6b9d79490..a9c099a44f 100644 --- a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordion.styles.ts +++ b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordion.styles.ts @@ -52,10 +52,13 @@ export const useStyles = makeStyles()(theme => ({ headerValuesContainerWrapper: { display: 'flex', alignItems: 'stretch', + margin: 'auto 0', }, headerValuesContainer: { display: 'flex', - alignItems: 'stretch', + justifyContent: 'stretch', + margin: 'auto 0', + flexDirection: 'column', }, headerValues: { fontSize: theme.fontSizes.smallBody, diff --git a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList.styles.ts b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList.styles.ts index 192606a2e2..571a8c663b 100644 --- a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList.styles.ts +++ b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList.styles.ts @@ -23,6 +23,7 @@ export const useStyles = makeStyles()(theme => ({ margin: '0.75rem 0 ', }, customConstraintLabel: { + marginBottom: theme.spacing(1), color: theme.palette.text.secondary, }, })); diff --git a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList.tsx b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList.tsx index 6f99bbb3fd..85b3c33772 100644 --- a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList.tsx +++ b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList.tsx @@ -1,4 +1,4 @@ -import React, { forwardRef, useImperativeHandle } from 'react'; +import React, { forwardRef, Fragment, useImperativeHandle } from 'react'; import { Button, Tooltip } from '@mui/material'; import { HelpOutline } from '@mui/icons-material'; import { IConstraint } from 'interfaces/strategy'; @@ -10,11 +10,14 @@ import { objectId } from 'utils/objectId'; import { useStyles } from './ConstraintAccordionList.styles'; import { createEmptyConstraint } from 'component/common/ConstraintAccordion/ConstraintAccordionList/createEmptyConstraint'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; +import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator'; interface IConstraintAccordionListProps { constraints: IConstraint[]; setConstraints?: React.Dispatch>; showCreateButton?: boolean; + /* Add "Custom constraints" title on the top - default `true` */ + showLabel?: boolean; } // Ref methods exposed by this component. @@ -35,124 +38,138 @@ export const constraintAccordionListId = 'constraintAccordionListId'; export const ConstraintAccordionList = forwardRef< IConstraintAccordionListRef | undefined, IConstraintAccordionListProps ->(({ constraints, setConstraints, showCreateButton }, ref) => { - const state = useWeakMap(); - const { context } = useUnleashContext(); - const { classes: styles } = useStyles(); +>( + ( + { constraints, setConstraints, showCreateButton, showLabel = true }, + ref + ) => { + const state = useWeakMap< + IConstraint, + IConstraintAccordionListItemState + >(); + const { context } = useUnleashContext(); + const { classes: styles } = useStyles(); - const addConstraint = - setConstraints && - ((contextName: string) => { - const constraint = createEmptyConstraint(contextName); - state.set(constraint, { editing: true, new: true }); - setConstraints(prev => [...prev, constraint]); - }); + const addConstraint = + setConstraints && + ((contextName: string) => { + const constraint = createEmptyConstraint(contextName); + state.set(constraint, { editing: true, new: true }); + setConstraints(prev => [...prev, constraint]); + }); - useImperativeHandle(ref, () => ({ - addConstraint, - })); + useImperativeHandle(ref, () => ({ + addConstraint, + })); - const onAdd = - addConstraint && - (() => { - addConstraint(context[0].name); - }); + const onAdd = + addConstraint && + (() => { + addConstraint(context[0].name); + }); - const onEdit = - setConstraints && - ((constraint: IConstraint) => { - state.set(constraint, { editing: true }); - }); + const onEdit = + setConstraints && + ((constraint: IConstraint) => { + state.set(constraint, { editing: true }); + }); - const onRemove = - setConstraints && - ((index: number) => { + const onRemove = + setConstraints && + ((index: number) => { + const constraint = constraints[index]; + state.set(constraint, {}); + setConstraints( + produce(draft => { + draft.splice(index, 1); + }) + ); + }); + + const onSave = + setConstraints && + ((index: number, constraint: IConstraint) => { + state.set(constraint, {}); + setConstraints( + produce(draft => { + draft[index] = constraint; + }) + ); + }); + + const onCancel = (index: number) => { const constraint = constraints[index]; + state.get(constraint)?.new && onRemove?.(index); state.set(constraint, {}); - setConstraints( - produce(draft => { - draft.splice(index, 1); - }) - ); - }); + }; - const onSave = - setConstraints && - ((index: number, constraint: IConstraint) => { - state.set(constraint, {}); - setConstraints( - produce(draft => { - draft[index] = constraint; - }) - ); - }); + if (context.length === 0) { + return null; + } - const onCancel = (index: number) => { - const constraint = constraints[index]; - state.get(constraint)?.new && onRemove?.(index); - state.set(constraint, {}); - }; - - if (context.length === 0) { - return null; - } - - return ( -
- 0} - show={ -

- Custom constraints -

- } - /> - {constraints.map((constraint, index) => ( - + 0 && showLabel + } + show={ +

+ Custom constraints +

+ } /> - ))} - -
-

Add any number of custom constraints

- - ( + + 0} + show={} + /> + + + ))} + + +
- -
- } - /> - - ); -}); + } + /> + + ); + } +); diff --git a/frontend/src/component/common/StrategySeparator/StrategySeparator.tsx b/frontend/src/component/common/StrategySeparator/StrategySeparator.tsx index 4867a5c2a7..3678a96c44 100644 --- a/frontend/src/component/common/StrategySeparator/StrategySeparator.tsx +++ b/frontend/src/component/common/StrategySeparator/StrategySeparator.tsx @@ -6,7 +6,7 @@ interface IStrategySeparatorProps { } const StyledContainer = styled('div')(({ theme }) => ({ - height: theme.spacing(2), + height: theme.spacing(1), position: 'relative', width: '100%', })); diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyExecution/StrategyExecution.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyExecution/StrategyExecution.tsx index e1214863a9..804615d3fa 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyExecution/StrategyExecution.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyExecution/StrategyExecution.tsx @@ -256,7 +256,10 @@ export const StrategyExecution = ({ strategy }: IStrategyExecutionProps) => { condition={constraints.length > 0} show={ <> - + } diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyItem.styles.ts b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyItem.styles.ts index 2972a4ee62..9e3068e1f5 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyItem.styles.ts +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyItem.styles.ts @@ -16,6 +16,7 @@ export const useStyles = makeStyles()(theme => ({ alignItems: 'center', borderBottom: `1px solid ${theme.palette.grey[300]}`, fontWeight: theme.typography.fontWeightMedium, + fontSize: theme.fontSizes.smallBody, }, icon: { fill: theme.palette.inactiveIcon, diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSegment/FeatureOverviewSegment.styles.ts b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSegment/FeatureOverviewSegment.styles.ts index 0892fc7382..fff6285997 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSegment/FeatureOverviewSegment.styles.ts +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSegment/FeatureOverviewSegment.styles.ts @@ -3,16 +3,18 @@ import { makeStyles } from 'tss-react/mui'; export const useStyles = makeStyles()(theme => ({ container: { width: '100%', - padding: '1rem', + padding: theme.spacing(2, 3), + display: 'flex', + alignItems: 'center', + justifyContent: 'flex-start', fontSize: theme.fontSizes.smallBody, - backgroundColor: theme.palette.grey[200], + border: `1px solid ${theme.palette.dividerAlternative}`, position: 'relative', borderRadius: '5px', - textAlign: 'center', }, link: { textDecoration: 'none', - fontWeight: theme.fontWeight.bold, + marginLeft: theme.spacing(1), '&:hover': { textDecoration: 'underline', }, diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSegment/FeatureOverviewSegment.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSegment/FeatureOverviewSegment.tsx index abed942c7d..8467f78c49 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSegment/FeatureOverviewSegment.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSegment/FeatureOverviewSegment.tsx @@ -1,8 +1,9 @@ +import { Fragment } from 'react'; +import { Link } from 'react-router-dom'; +import { DonutLarge } from '@mui/icons-material'; import { useStyles } from 'component/feature/FeatureView/FeatureOverview/FeatureOverviewSegment/FeatureOverviewSegment.styles'; import { useSegments } from 'hooks/api/getters/useSegments/useSegments'; import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator'; -import { Link } from 'react-router-dom'; -import { Fragment } from 'react'; interface IFeatureOverviewSegmentProps { strategyId: string; @@ -23,7 +24,7 @@ export const FeatureOverviewSegment = ({ {segments.map(segment => (
- Segment{' '} + Segment:{' '}