1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-08-27 13:49:10 +02:00

improved constraints list

This commit is contained in:
Tymoteusz Czech 2025-03-20 10:41:00 +01:00
parent bb779828d3
commit d14ae2d8ed
No known key found for this signature in database
GPG Key ID: 133555230D88D75F
9 changed files with 90 additions and 68 deletions

View File

@ -32,7 +32,7 @@ const StyledOperatorGroup = styled('div')(({ theme }) => ({
gap: theme.spacing(0.5),
}));
export const ConstraintItem: FC<
export const ConstraintItemHeader: FC<
ConstraintSchema & Pick<StrategyEvaluationItemProps, 'onSetTruncated'>
> = ({
caseInsensitive,

View File

@ -10,17 +10,21 @@ const StyledList = styled('ul')(({ theme }) => ({
gap: theme.spacing(1),
}));
const StyledListItem = styled('li')(({ theme }) => ({
export const ConstraintListItem = styled('div')(({ theme }) => ({
position: 'relative',
border: `1px solid ${theme.palette.divider}`,
borderRadius: theme.shape.borderRadiusMedium,
background: theme.palette.background.default,
padding: theme.spacing(2, 3),
padding: theme.spacing(1.5, 3),
display: 'flex',
flexFlow: 'column',
gap: theme.spacing(2),
}));
const StyledListItem = styled('li')({
position: 'relative',
});
const StyledAnd = styled('div')(({ theme }) => ({
position: 'absolute',
top: theme.spacing(-0.5),

View File

@ -16,6 +16,7 @@ const StyledContainer = styled('div')(({ theme }) => ({
gap: theme.spacing(1),
alignItems: 'center',
fontSize: theme.typography.body2.fontSize,
minHeight: theme.spacing(4),
}));
const StyledContent = styled('div')(({ theme }) => ({

View File

@ -1,6 +1,6 @@
import { IconButton, styled } from '@mui/material';
import type { IConstraint } from 'interfaces/strategy';
import { ConstraintItem } from 'component/common/ConstraintsList/ConstraintItem/ConstraintItem';
import { ConstraintItemHeader } from 'component/common/ConstraintsList/ConstraintItemHeader/ConstraintItemHeader';
import { useState } from 'react';
import VisibilityIcon from '@mui/icons-material/Visibility';
import VisibilityOffIcon from '@mui/icons-material/VisibilityOff';
@ -43,7 +43,7 @@ export const ConstraintAccordionViewHeaderInfo = ({
return (
<StyledHeaderWrapper>
<StyledHeaderMetaInfo>
<ConstraintItem
<ConstraintItemHeader
{...constraint}
onSetTruncated={(state: boolean) => {
setExpandable(state);

View File

@ -7,6 +7,9 @@ interface IConstraintIconProps {
disabled?: boolean;
}
/**
* @deprecated remove with `flagOverviewRedesign`
*/
export const ConstraintIcon: VFC<IConstraintIconProps> = ({
compact,
disabled,

View File

@ -1,5 +1,4 @@
import type { IConstraint } from 'interfaces/strategy';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { ConstraintAccordionEdit } from './ConstraintAccordionEdit/ConstraintAccordionEdit';
import { ConstraintAccordionView } from './ConstraintAccordionView/ConstraintAccordionView';
@ -27,26 +26,24 @@ export const NewConstraintAccordion = ({
}: IConstraintAccordionProps) => {
if (!constraint) return null;
if (editing && onSave) {
return (
<ConstraintAccordionEdit
constraint={constraint}
onCancel={onCancel}
onSave={onSave!}
onDelete={onDelete}
onAutoSave={onAutoSave!}
compact={compact}
/>
);
}
return (
<ConditionallyRender
condition={Boolean(editing && onSave)}
show={
<ConstraintAccordionEdit
constraint={constraint}
onCancel={onCancel}
onSave={onSave!}
onDelete={onDelete}
onAutoSave={onAutoSave!}
compact={compact}
/>
}
elseShow={
<ConstraintAccordionView
constraint={constraint}
onEdit={onEdit}
onDelete={onDelete}
/>
}
<ConstraintAccordionView
constraint={constraint}
onEdit={onEdit}
onDelete={onDelete}
/>
);
};

View File

@ -9,9 +9,12 @@ import {
styled,
} from '@mui/material';
import { StrategyEvaluationItem } from 'component/common/ConstraintsList/StrategyEvaluationItem/StrategyEvaluationItem';
import { ConstraintItem } from 'component/common/ConstraintsList/ConstraintItem/ConstraintItem';
import { ConstraintItemHeader } from 'component/common/ConstraintsList/ConstraintItemHeader/ConstraintItemHeader';
import { objectId } from 'utils/objectId';
import { ConstraintsList } from 'component/common/ConstraintsList/ConstraintsList';
import {
ConstraintListItem,
ConstraintsList,
} from 'component/common/ConstraintsList/ConstraintsList';
type SegmentItemProps = {
segment: Partial<ISegment>;
@ -21,7 +24,11 @@ type SegmentItemProps = {
headerContent?: JSX.Element;
};
const StyledAccordion = styled(Accordion)(({ theme }) => ({
const StyledConstraintListItem = styled(ConstraintListItem)(() => ({
padding: 0,
}));
const StyledAccordion = styled(Accordion)(() => ({
boxShadow: 'none',
margin: 0,
padding: 0,
@ -32,16 +39,14 @@ const StyledAccordion = styled(Accordion)(({ theme }) => ({
}));
const StyledAccordionSummary = styled(AccordionSummary)(({ theme }) => ({
padding: 0,
padding: theme.spacing(0, 3),
fontSize: theme.typography.body2.fontSize,
minHeight: 'unset',
'.MuiAccordionSummary-content, .MuiAccordionSummary-content.Mui-expanded': {
margin: 0,
},
}));
const StyledAccordionDetails = styled(AccordionDetails)(({ theme }) => ({
padding: theme.spacing(2, 0, 1),
borderTop: `1px dashed ${theme.palette.divider}`,
padding: theme.spacing(1.5, 3, 2.5),
}));
const StyledLink = styled(Link)({
@ -55,8 +60,6 @@ const StyledActionsContainer = styled('div')(({ theme }) => ({
display: 'flex',
alignItems: 'center',
marginLeft: 'auto',
marginTop: theme.spacing(-0.5),
marginBottom: theme.spacing(-0.5),
}));
const StyledButton = styled(Button)(({ theme }) => ({
@ -85,10 +88,12 @@ export const SegmentItem: FC<SegmentItemProps> = ({
return (
<ConstraintsList>
{segment.constraints.map((constraint, index) => (
<ConstraintItem
<ConstraintListItem
key={`${objectId(constraint)}-${index}`}
{...constraint}
/>
>
{/* FIXME: use accordion */}
<ConstraintItemHeader {...constraint} />
</ConstraintListItem>
))}
</ConstraintsList>
);
@ -102,27 +107,29 @@ export const SegmentItem: FC<SegmentItemProps> = ({
}, [constraintList, segment.constraints]);
return (
<StyledAccordion expanded={isOpen} disableGutters>
<StyledAccordionSummary id={`segment-accordion-${segment.id}`}>
<StrategyEvaluationItem type='Segment'>
<StyledLink to={`/segments/edit/${segment.id}`}>
{segment.name}
</StyledLink>
</StrategyEvaluationItem>
{headerContent ? headerContent : null}
{!isExpanded ? (
<StyledActionsContainer>
<StyledButton
size='small'
variant='outlined'
onClick={() => setIsOpen((value) => !value)}
>
{isOpen ? 'Close preview' : 'Preview'}
</StyledButton>
</StyledActionsContainer>
) : null}
</StyledAccordionSummary>
<StyledAccordionDetails>{constraints}</StyledAccordionDetails>
</StyledAccordion>
<StyledConstraintListItem>
<StyledAccordion expanded={isOpen} disableGutters>
<StyledAccordionSummary id={`segment-accordion-${segment.id}`}>
<StrategyEvaluationItem type='Segment'>
<StyledLink to={`/segments/edit/${segment.id}`}>
{segment.name}
</StyledLink>
</StrategyEvaluationItem>
{headerContent ? headerContent : null}
{!isExpanded ? (
<StyledActionsContainer>
<StyledButton
size='small'
variant='outlined'
onClick={() => setIsOpen((value) => !value)}
>
{isOpen ? 'Close preview' : 'Preview'}
</StyledButton>
</StyledActionsContainer>
) : null}
</StyledAccordionSummary>
<StyledAccordionDetails>{constraints}</StyledAccordionDetails>
</StyledAccordion>
</StyledConstraintListItem>
);
};

View File

@ -4,14 +4,17 @@ import type { FeatureStrategySchema } from 'openapi';
import type { IFeatureStrategyPayload } from 'interfaces/strategy';
import { useUiFlag } from 'hooks/useUiFlag';
import { StrategyExecution as LegacyStrategyExecution } from './LegacyStrategyExecution';
import { ConstraintItem } from 'component/common/ConstraintsList/ConstraintItem/ConstraintItem';
import { ConstraintItemHeader } from 'component/common/ConstraintsList/ConstraintItemHeader/ConstraintItemHeader';
import { useStrategies } from 'hooks/api/getters/useStrategies/useStrategies';
import { objectId } from 'utils/objectId';
import { useCustomStrategyParameters } from './hooks/useCustomStrategyParameters';
import { useStrategyParameters } from './hooks/useStrategyParameters';
import { useSegments } from 'hooks/api/getters/useSegments/useSegments';
import { SegmentItem } from 'component/common/SegmentItem/SegmentItem';
import { ConstraintsList } from 'component/common/ConstraintsList/ConstraintsList';
import {
ConstraintListItem,
ConstraintsList,
} from 'component/common/ConstraintsList/ConstraintsList';
const FilterContainer = styled('div', {
shouldForwardProp: (prop) => prop !== 'grayscale',
@ -58,12 +61,19 @@ export const StrategyExecution: FC<StrategyExecutionProps> = ({
<SegmentItem segment={segment} key={segment.id} />
))}
{constraints?.map((constraint, index) => (
<ConstraintItem
<ConstraintListItem
key={`${objectId(constraint)}-${index}`}
{...constraint}
/>
>
{/* FIXME: use constraint accordion */}
<ConstraintItemHeader {...constraint} />
</ConstraintListItem>
))}
{(isCustomStrategy
? customStrategyItems
: strategyParameters
).map((item, index) => (
<ConstraintListItem key={index}>{item}</ConstraintListItem>
))}
{isCustomStrategy ? customStrategyItems : strategyParameters}
</ConstraintsList>
</FilterContainer>
);

View File

@ -3,7 +3,7 @@ import type {
PlaygroundConstraintSchema,
PlaygroundRequestSchema,
} from 'openapi';
import { ConstraintItem } from 'component/common/ConstraintsList/ConstraintItem/ConstraintItem';
import { ConstraintItemHeader } from 'component/common/ConstraintsList/ConstraintItemHeader/ConstraintItemHeader';
import CheckCircle from '@mui/icons-material/CheckCircle';
import { styled } from '@mui/material';
import Cancel from '@mui/icons-material/Cancel';
@ -68,7 +68,7 @@ export const ConstraintExecution: FC<IConstraintExecutionProps> = ({
return (
<>
<ConstraintItem {...constraint} />
<ConstraintItemHeader {...constraint} />
{constraint.result ? (
<ConstraintOk />
) : (