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:
parent
bb779828d3
commit
d14ae2d8ed
@ -32,7 +32,7 @@ const StyledOperatorGroup = styled('div')(({ theme }) => ({
|
|||||||
gap: theme.spacing(0.5),
|
gap: theme.spacing(0.5),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const ConstraintItem: FC<
|
export const ConstraintItemHeader: FC<
|
||||||
ConstraintSchema & Pick<StrategyEvaluationItemProps, 'onSetTruncated'>
|
ConstraintSchema & Pick<StrategyEvaluationItemProps, 'onSetTruncated'>
|
||||||
> = ({
|
> = ({
|
||||||
caseInsensitive,
|
caseInsensitive,
|
@ -10,17 +10,21 @@ const StyledList = styled('ul')(({ theme }) => ({
|
|||||||
gap: theme.spacing(1),
|
gap: theme.spacing(1),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledListItem = styled('li')(({ theme }) => ({
|
export const ConstraintListItem = styled('div')(({ theme }) => ({
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
border: `1px solid ${theme.palette.divider}`,
|
border: `1px solid ${theme.palette.divider}`,
|
||||||
borderRadius: theme.shape.borderRadiusMedium,
|
borderRadius: theme.shape.borderRadiusMedium,
|
||||||
background: theme.palette.background.default,
|
background: theme.palette.background.default,
|
||||||
padding: theme.spacing(2, 3),
|
padding: theme.spacing(1.5, 3),
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexFlow: 'column',
|
flexFlow: 'column',
|
||||||
gap: theme.spacing(2),
|
gap: theme.spacing(2),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const StyledListItem = styled('li')({
|
||||||
|
position: 'relative',
|
||||||
|
});
|
||||||
|
|
||||||
const StyledAnd = styled('div')(({ theme }) => ({
|
const StyledAnd = styled('div')(({ theme }) => ({
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
top: theme.spacing(-0.5),
|
top: theme.spacing(-0.5),
|
||||||
|
@ -16,6 +16,7 @@ const StyledContainer = styled('div')(({ theme }) => ({
|
|||||||
gap: theme.spacing(1),
|
gap: theme.spacing(1),
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
fontSize: theme.typography.body2.fontSize,
|
fontSize: theme.typography.body2.fontSize,
|
||||||
|
minHeight: theme.spacing(4),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledContent = styled('div')(({ theme }) => ({
|
const StyledContent = styled('div')(({ theme }) => ({
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { IconButton, styled } from '@mui/material';
|
import { IconButton, styled } from '@mui/material';
|
||||||
import type { IConstraint } from 'interfaces/strategy';
|
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 { useState } from 'react';
|
||||||
import VisibilityIcon from '@mui/icons-material/Visibility';
|
import VisibilityIcon from '@mui/icons-material/Visibility';
|
||||||
import VisibilityOffIcon from '@mui/icons-material/VisibilityOff';
|
import VisibilityOffIcon from '@mui/icons-material/VisibilityOff';
|
||||||
@ -43,7 +43,7 @@ export const ConstraintAccordionViewHeaderInfo = ({
|
|||||||
return (
|
return (
|
||||||
<StyledHeaderWrapper>
|
<StyledHeaderWrapper>
|
||||||
<StyledHeaderMetaInfo>
|
<StyledHeaderMetaInfo>
|
||||||
<ConstraintItem
|
<ConstraintItemHeader
|
||||||
{...constraint}
|
{...constraint}
|
||||||
onSetTruncated={(state: boolean) => {
|
onSetTruncated={(state: boolean) => {
|
||||||
setExpandable(state);
|
setExpandable(state);
|
||||||
|
@ -7,6 +7,9 @@ interface IConstraintIconProps {
|
|||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated remove with `flagOverviewRedesign`
|
||||||
|
*/
|
||||||
export const ConstraintIcon: VFC<IConstraintIconProps> = ({
|
export const ConstraintIcon: VFC<IConstraintIconProps> = ({
|
||||||
compact,
|
compact,
|
||||||
disabled,
|
disabled,
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import type { IConstraint } from 'interfaces/strategy';
|
import type { IConstraint } from 'interfaces/strategy';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
|
||||||
|
|
||||||
import { ConstraintAccordionEdit } from './ConstraintAccordionEdit/ConstraintAccordionEdit';
|
import { ConstraintAccordionEdit } from './ConstraintAccordionEdit/ConstraintAccordionEdit';
|
||||||
import { ConstraintAccordionView } from './ConstraintAccordionView/ConstraintAccordionView';
|
import { ConstraintAccordionView } from './ConstraintAccordionView/ConstraintAccordionView';
|
||||||
@ -27,26 +26,24 @@ export const NewConstraintAccordion = ({
|
|||||||
}: IConstraintAccordionProps) => {
|
}: IConstraintAccordionProps) => {
|
||||||
if (!constraint) return null;
|
if (!constraint) return null;
|
||||||
|
|
||||||
|
if (editing && onSave) {
|
||||||
|
return (
|
||||||
|
<ConstraintAccordionEdit
|
||||||
|
constraint={constraint}
|
||||||
|
onCancel={onCancel}
|
||||||
|
onSave={onSave!}
|
||||||
|
onDelete={onDelete}
|
||||||
|
onAutoSave={onAutoSave!}
|
||||||
|
compact={compact}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ConditionallyRender
|
<ConstraintAccordionView
|
||||||
condition={Boolean(editing && onSave)}
|
constraint={constraint}
|
||||||
show={
|
onEdit={onEdit}
|
||||||
<ConstraintAccordionEdit
|
onDelete={onDelete}
|
||||||
constraint={constraint}
|
|
||||||
onCancel={onCancel}
|
|
||||||
onSave={onSave!}
|
|
||||||
onDelete={onDelete}
|
|
||||||
onAutoSave={onAutoSave!}
|
|
||||||
compact={compact}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
elseShow={
|
|
||||||
<ConstraintAccordionView
|
|
||||||
constraint={constraint}
|
|
||||||
onEdit={onEdit}
|
|
||||||
onDelete={onDelete}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -9,9 +9,12 @@ import {
|
|||||||
styled,
|
styled,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { StrategyEvaluationItem } from 'component/common/ConstraintsList/StrategyEvaluationItem/StrategyEvaluationItem';
|
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 { objectId } from 'utils/objectId';
|
||||||
import { ConstraintsList } from 'component/common/ConstraintsList/ConstraintsList';
|
import {
|
||||||
|
ConstraintListItem,
|
||||||
|
ConstraintsList,
|
||||||
|
} from 'component/common/ConstraintsList/ConstraintsList';
|
||||||
|
|
||||||
type SegmentItemProps = {
|
type SegmentItemProps = {
|
||||||
segment: Partial<ISegment>;
|
segment: Partial<ISegment>;
|
||||||
@ -21,7 +24,11 @@ type SegmentItemProps = {
|
|||||||
headerContent?: JSX.Element;
|
headerContent?: JSX.Element;
|
||||||
};
|
};
|
||||||
|
|
||||||
const StyledAccordion = styled(Accordion)(({ theme }) => ({
|
const StyledConstraintListItem = styled(ConstraintListItem)(() => ({
|
||||||
|
padding: 0,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledAccordion = styled(Accordion)(() => ({
|
||||||
boxShadow: 'none',
|
boxShadow: 'none',
|
||||||
margin: 0,
|
margin: 0,
|
||||||
padding: 0,
|
padding: 0,
|
||||||
@ -32,16 +39,14 @@ const StyledAccordion = styled(Accordion)(({ theme }) => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledAccordionSummary = styled(AccordionSummary)(({ theme }) => ({
|
const StyledAccordionSummary = styled(AccordionSummary)(({ theme }) => ({
|
||||||
padding: 0,
|
padding: theme.spacing(0, 3),
|
||||||
fontSize: theme.typography.body2.fontSize,
|
fontSize: theme.typography.body2.fontSize,
|
||||||
minHeight: 'unset',
|
minHeight: 'unset',
|
||||||
'.MuiAccordionSummary-content, .MuiAccordionSummary-content.Mui-expanded': {
|
|
||||||
margin: 0,
|
|
||||||
},
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledAccordionDetails = styled(AccordionDetails)(({ theme }) => ({
|
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)({
|
const StyledLink = styled(Link)({
|
||||||
@ -55,8 +60,6 @@ const StyledActionsContainer = styled('div')(({ theme }) => ({
|
|||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
marginLeft: 'auto',
|
marginLeft: 'auto',
|
||||||
marginTop: theme.spacing(-0.5),
|
|
||||||
marginBottom: theme.spacing(-0.5),
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledButton = styled(Button)(({ theme }) => ({
|
const StyledButton = styled(Button)(({ theme }) => ({
|
||||||
@ -85,10 +88,12 @@ export const SegmentItem: FC<SegmentItemProps> = ({
|
|||||||
return (
|
return (
|
||||||
<ConstraintsList>
|
<ConstraintsList>
|
||||||
{segment.constraints.map((constraint, index) => (
|
{segment.constraints.map((constraint, index) => (
|
||||||
<ConstraintItem
|
<ConstraintListItem
|
||||||
key={`${objectId(constraint)}-${index}`}
|
key={`${objectId(constraint)}-${index}`}
|
||||||
{...constraint}
|
>
|
||||||
/>
|
{/* FIXME: use accordion */}
|
||||||
|
<ConstraintItemHeader {...constraint} />
|
||||||
|
</ConstraintListItem>
|
||||||
))}
|
))}
|
||||||
</ConstraintsList>
|
</ConstraintsList>
|
||||||
);
|
);
|
||||||
@ -102,27 +107,29 @@ export const SegmentItem: FC<SegmentItemProps> = ({
|
|||||||
}, [constraintList, segment.constraints]);
|
}, [constraintList, segment.constraints]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledAccordion expanded={isOpen} disableGutters>
|
<StyledConstraintListItem>
|
||||||
<StyledAccordionSummary id={`segment-accordion-${segment.id}`}>
|
<StyledAccordion expanded={isOpen} disableGutters>
|
||||||
<StrategyEvaluationItem type='Segment'>
|
<StyledAccordionSummary id={`segment-accordion-${segment.id}`}>
|
||||||
<StyledLink to={`/segments/edit/${segment.id}`}>
|
<StrategyEvaluationItem type='Segment'>
|
||||||
{segment.name}
|
<StyledLink to={`/segments/edit/${segment.id}`}>
|
||||||
</StyledLink>
|
{segment.name}
|
||||||
</StrategyEvaluationItem>
|
</StyledLink>
|
||||||
{headerContent ? headerContent : null}
|
</StrategyEvaluationItem>
|
||||||
{!isExpanded ? (
|
{headerContent ? headerContent : null}
|
||||||
<StyledActionsContainer>
|
{!isExpanded ? (
|
||||||
<StyledButton
|
<StyledActionsContainer>
|
||||||
size='small'
|
<StyledButton
|
||||||
variant='outlined'
|
size='small'
|
||||||
onClick={() => setIsOpen((value) => !value)}
|
variant='outlined'
|
||||||
>
|
onClick={() => setIsOpen((value) => !value)}
|
||||||
{isOpen ? 'Close preview' : 'Preview'}
|
>
|
||||||
</StyledButton>
|
{isOpen ? 'Close preview' : 'Preview'}
|
||||||
</StyledActionsContainer>
|
</StyledButton>
|
||||||
) : null}
|
</StyledActionsContainer>
|
||||||
</StyledAccordionSummary>
|
) : null}
|
||||||
<StyledAccordionDetails>{constraints}</StyledAccordionDetails>
|
</StyledAccordionSummary>
|
||||||
</StyledAccordion>
|
<StyledAccordionDetails>{constraints}</StyledAccordionDetails>
|
||||||
|
</StyledAccordion>
|
||||||
|
</StyledConstraintListItem>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -4,14 +4,17 @@ import type { FeatureStrategySchema } from 'openapi';
|
|||||||
import type { IFeatureStrategyPayload } from 'interfaces/strategy';
|
import type { IFeatureStrategyPayload } from 'interfaces/strategy';
|
||||||
import { useUiFlag } from 'hooks/useUiFlag';
|
import { useUiFlag } from 'hooks/useUiFlag';
|
||||||
import { StrategyExecution as LegacyStrategyExecution } from './LegacyStrategyExecution';
|
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 { useStrategies } from 'hooks/api/getters/useStrategies/useStrategies';
|
||||||
import { objectId } from 'utils/objectId';
|
import { objectId } from 'utils/objectId';
|
||||||
import { useCustomStrategyParameters } from './hooks/useCustomStrategyParameters';
|
import { useCustomStrategyParameters } from './hooks/useCustomStrategyParameters';
|
||||||
import { useStrategyParameters } from './hooks/useStrategyParameters';
|
import { useStrategyParameters } from './hooks/useStrategyParameters';
|
||||||
import { useSegments } from 'hooks/api/getters/useSegments/useSegments';
|
import { useSegments } from 'hooks/api/getters/useSegments/useSegments';
|
||||||
import { SegmentItem } from 'component/common/SegmentItem/SegmentItem';
|
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', {
|
const FilterContainer = styled('div', {
|
||||||
shouldForwardProp: (prop) => prop !== 'grayscale',
|
shouldForwardProp: (prop) => prop !== 'grayscale',
|
||||||
@ -58,12 +61,19 @@ export const StrategyExecution: FC<StrategyExecutionProps> = ({
|
|||||||
<SegmentItem segment={segment} key={segment.id} />
|
<SegmentItem segment={segment} key={segment.id} />
|
||||||
))}
|
))}
|
||||||
{constraints?.map((constraint, index) => (
|
{constraints?.map((constraint, index) => (
|
||||||
<ConstraintItem
|
<ConstraintListItem
|
||||||
key={`${objectId(constraint)}-${index}`}
|
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>
|
</ConstraintsList>
|
||||||
</FilterContainer>
|
</FilterContainer>
|
||||||
);
|
);
|
||||||
|
@ -3,7 +3,7 @@ import type {
|
|||||||
PlaygroundConstraintSchema,
|
PlaygroundConstraintSchema,
|
||||||
PlaygroundRequestSchema,
|
PlaygroundRequestSchema,
|
||||||
} from 'openapi';
|
} 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 CheckCircle from '@mui/icons-material/CheckCircle';
|
||||||
import { styled } from '@mui/material';
|
import { styled } from '@mui/material';
|
||||||
import Cancel from '@mui/icons-material/Cancel';
|
import Cancel from '@mui/icons-material/Cancel';
|
||||||
@ -68,7 +68,7 @@ export const ConstraintExecution: FC<IConstraintExecutionProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ConstraintItem {...constraint} />
|
<ConstraintItemHeader {...constraint} />
|
||||||
{constraint.result ? (
|
{constraint.result ? (
|
||||||
<ConstraintOk />
|
<ConstraintOk />
|
||||||
) : (
|
) : (
|
||||||
|
Loading…
Reference in New Issue
Block a user