1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-05-12 01:17:04 +02:00

Visual updates to constraints (#1157)

This commit is contained in:
Tymoteusz Czech 2022-07-28 09:34:15 +02:00 committed by GitHub
parent 7df59cf286
commit c20aa300ce
8 changed files with 148 additions and 120 deletions

View File

@ -52,10 +52,13 @@ export const useStyles = makeStyles()(theme => ({
headerValuesContainerWrapper: { headerValuesContainerWrapper: {
display: 'flex', display: 'flex',
alignItems: 'stretch', alignItems: 'stretch',
margin: 'auto 0',
}, },
headerValuesContainer: { headerValuesContainer: {
display: 'flex', display: 'flex',
alignItems: 'stretch', justifyContent: 'stretch',
margin: 'auto 0',
flexDirection: 'column',
}, },
headerValues: { headerValues: {
fontSize: theme.fontSizes.smallBody, fontSize: theme.fontSizes.smallBody,

View File

@ -23,6 +23,7 @@ export const useStyles = makeStyles()(theme => ({
margin: '0.75rem 0 ', margin: '0.75rem 0 ',
}, },
customConstraintLabel: { customConstraintLabel: {
marginBottom: theme.spacing(1),
color: theme.palette.text.secondary, color: theme.palette.text.secondary,
}, },
})); }));

View File

@ -1,4 +1,4 @@
import React, { forwardRef, useImperativeHandle } from 'react'; import React, { forwardRef, Fragment, useImperativeHandle } from 'react';
import { Button, Tooltip } from '@mui/material'; import { Button, Tooltip } from '@mui/material';
import { HelpOutline } from '@mui/icons-material'; import { HelpOutline } from '@mui/icons-material';
import { IConstraint } from 'interfaces/strategy'; import { IConstraint } from 'interfaces/strategy';
@ -10,11 +10,14 @@ import { objectId } from 'utils/objectId';
import { useStyles } from './ConstraintAccordionList.styles'; import { useStyles } from './ConstraintAccordionList.styles';
import { createEmptyConstraint } from 'component/common/ConstraintAccordion/ConstraintAccordionList/createEmptyConstraint'; import { createEmptyConstraint } from 'component/common/ConstraintAccordion/ConstraintAccordionList/createEmptyConstraint';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator';
interface IConstraintAccordionListProps { interface IConstraintAccordionListProps {
constraints: IConstraint[]; constraints: IConstraint[];
setConstraints?: React.Dispatch<React.SetStateAction<IConstraint[]>>; setConstraints?: React.Dispatch<React.SetStateAction<IConstraint[]>>;
showCreateButton?: boolean; showCreateButton?: boolean;
/* Add "Custom constraints" title on the top - default `true` */
showLabel?: boolean;
} }
// Ref methods exposed by this component. // Ref methods exposed by this component.
@ -35,8 +38,15 @@ export const constraintAccordionListId = 'constraintAccordionListId';
export const ConstraintAccordionList = forwardRef< export const ConstraintAccordionList = forwardRef<
IConstraintAccordionListRef | undefined, IConstraintAccordionListRef | undefined,
IConstraintAccordionListProps IConstraintAccordionListProps
>(({ constraints, setConstraints, showCreateButton }, ref) => { >(
const state = useWeakMap<IConstraint, IConstraintAccordionListItemState>(); (
{ constraints, setConstraints, showCreateButton, showLabel = true },
ref
) => {
const state = useWeakMap<
IConstraint,
IConstraintAccordionListItemState
>();
const { context } = useUnleashContext(); const { context } = useUnleashContext();
const { classes: styles } = useStyles(); const { classes: styles } = useStyles();
@ -100,7 +110,9 @@ export const ConstraintAccordionList = forwardRef<
return ( return (
<div className={styles.container} id={constraintAccordionListId}> <div className={styles.container} id={constraintAccordionListId}>
<ConditionallyRender <ConditionallyRender
condition={constraints && constraints.length > 0} condition={
constraints && constraints.length > 0 && showLabel
}
show={ show={
<p className={styles.customConstraintLabel}> <p className={styles.customConstraintLabel}>
Custom constraints Custom constraints
@ -108,8 +120,12 @@ export const ConstraintAccordionList = forwardRef<
} }
/> />
{constraints.map((constraint, index) => ( {constraints.map((constraint, index) => (
<Fragment key={objectId(constraint)}>
<ConditionallyRender
condition={index > 0}
show={<StrategySeparator text="AND" />}
/>
<ConstraintAccordion <ConstraintAccordion
key={objectId(constraint)}
constraint={constraint} constraint={constraint}
onEdit={onEdit && onEdit.bind(null, constraint)} onEdit={onEdit && onEdit.bind(null, constraint)}
onCancel={onCancel.bind(null, index)} onCancel={onCancel.bind(null, index)}
@ -118,6 +134,7 @@ export const ConstraintAccordionList = forwardRef<
editing={Boolean(state.get(constraint)?.editing)} editing={Boolean(state.get(constraint)?.editing)}
compact compact
/> />
</Fragment>
))} ))}
<ConditionallyRender <ConditionallyRender
condition={Boolean(showCreateButton && onAdd)} condition={Boolean(showCreateButton && onAdd)}
@ -146,7 +163,6 @@ export const ConstraintAccordionList = forwardRef<
onClick={onAdd} onClick={onAdd}
variant="outlined" variant="outlined"
color="secondary" color="secondary"
sx={{ mb: 2 }}
> >
Add custom constraint Add custom constraint
</Button> </Button>
@ -155,4 +171,5 @@ export const ConstraintAccordionList = forwardRef<
/> />
</div> </div>
); );
}); }
);

View File

@ -6,7 +6,7 @@ interface IStrategySeparatorProps {
} }
const StyledContainer = styled('div')(({ theme }) => ({ const StyledContainer = styled('div')(({ theme }) => ({
height: theme.spacing(2), height: theme.spacing(1),
position: 'relative', position: 'relative',
width: '100%', width: '100%',
})); }));

View File

@ -256,7 +256,10 @@ export const StrategyExecution = ({ strategy }: IStrategyExecutionProps) => {
condition={constraints.length > 0} condition={constraints.length > 0}
show={ show={
<> <>
<ConstraintAccordionList constraints={constraints} /> <ConstraintAccordionList
constraints={constraints}
showLabel={false}
/>
<StrategySeparator text="AND" /> <StrategySeparator text="AND" />
</> </>
} }

View File

@ -16,6 +16,7 @@ export const useStyles = makeStyles()(theme => ({
alignItems: 'center', alignItems: 'center',
borderBottom: `1px solid ${theme.palette.grey[300]}`, borderBottom: `1px solid ${theme.palette.grey[300]}`,
fontWeight: theme.typography.fontWeightMedium, fontWeight: theme.typography.fontWeightMedium,
fontSize: theme.fontSizes.smallBody,
}, },
icon: { icon: {
fill: theme.palette.inactiveIcon, fill: theme.palette.inactiveIcon,

View File

@ -3,16 +3,18 @@ import { makeStyles } from 'tss-react/mui';
export const useStyles = makeStyles()(theme => ({ export const useStyles = makeStyles()(theme => ({
container: { container: {
width: '100%', width: '100%',
padding: '1rem', padding: theme.spacing(2, 3),
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-start',
fontSize: theme.fontSizes.smallBody, fontSize: theme.fontSizes.smallBody,
backgroundColor: theme.palette.grey[200], border: `1px solid ${theme.palette.dividerAlternative}`,
position: 'relative', position: 'relative',
borderRadius: '5px', borderRadius: '5px',
textAlign: 'center',
}, },
link: { link: {
textDecoration: 'none', textDecoration: 'none',
fontWeight: theme.fontWeight.bold, marginLeft: theme.spacing(1),
'&:hover': { '&:hover': {
textDecoration: 'underline', textDecoration: 'underline',
}, },

View File

@ -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 { useStyles } from 'component/feature/FeatureView/FeatureOverview/FeatureOverviewSegment/FeatureOverviewSegment.styles';
import { useSegments } from 'hooks/api/getters/useSegments/useSegments'; import { useSegments } from 'hooks/api/getters/useSegments/useSegments';
import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator'; import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator';
import { Link } from 'react-router-dom';
import { Fragment } from 'react';
interface IFeatureOverviewSegmentProps { interface IFeatureOverviewSegmentProps {
strategyId: string; strategyId: string;
@ -23,7 +24,7 @@ export const FeatureOverviewSegment = ({
{segments.map(segment => ( {segments.map(segment => (
<Fragment key={segment.id}> <Fragment key={segment.id}>
<div className={styles.container}> <div className={styles.container}>
Segment{' '} <DonutLarge color="secondary" sx={{ mr: 1 }} /> Segment:{' '}
<Link <Link
to={segmentPath(segment.id)} to={segmentPath(segment.id)}
className={styles.link} className={styles.link}