mirror of
https://github.com/Unleash/unleash.git
synced 2025-06-14 01:16:17 +02:00
Segment view for strategy evaluation (#9399)
Refactored "segments" part of strategy evaluation. This shows a lot of places, that use "Legacy" component.
This commit is contained in:
parent
8d0820fc8b
commit
1b67b288ee
@ -0,0 +1,52 @@
|
|||||||
|
import { Children, isValidElement, type FC, type ReactNode } from 'react';
|
||||||
|
import { styled } from '@mui/material';
|
||||||
|
|
||||||
|
const StyledList = styled('ul')(({ theme }) => ({
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
listStyle: 'none',
|
||||||
|
padding: 0,
|
||||||
|
margin: 0,
|
||||||
|
gap: theme.spacing(1),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledListItem = styled('li')(({ theme }) => ({
|
||||||
|
position: 'relative',
|
||||||
|
border: `1px solid ${theme.palette.divider}`,
|
||||||
|
borderRadius: theme.shape.borderRadiusMedium,
|
||||||
|
background: theme.palette.background.default,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledAnd = styled('div')(({ theme }) => ({
|
||||||
|
position: 'absolute',
|
||||||
|
top: theme.spacing(-0.5),
|
||||||
|
left: theme.spacing(2),
|
||||||
|
transform: 'translateY(-50%)',
|
||||||
|
padding: theme.spacing(0.75, 1),
|
||||||
|
lineHeight: 1,
|
||||||
|
fontSize: theme.fontSizes.smallerBody,
|
||||||
|
color: theme.palette.text.primary,
|
||||||
|
background: theme.palette.background.application,
|
||||||
|
borderRadius: theme.shape.borderRadiusLarge,
|
||||||
|
zIndex: theme.zIndex.fab,
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const ConstraintsList: FC<{ children: ReactNode }> = ({ children }) => {
|
||||||
|
const result: ReactNode[] = [];
|
||||||
|
Children.forEach(children, (child, index) => {
|
||||||
|
if (isValidElement(child)) {
|
||||||
|
result.push(
|
||||||
|
<StyledListItem key={index}>
|
||||||
|
{index > 0 ? (
|
||||||
|
<StyledAnd role='separator' key={`${index}-divider`}>
|
||||||
|
AND
|
||||||
|
</StyledAnd>
|
||||||
|
) : null}
|
||||||
|
{child}
|
||||||
|
</StyledListItem>,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return <StyledList>{result}</StyledList>;
|
||||||
|
};
|
@ -12,6 +12,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,
|
||||||
|
padding: theme.spacing(2, 3),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledType = styled('span')(({ theme }) => ({
|
const StyledType = styled('span')(({ theme }) => ({
|
141
frontend/src/component/common/SegmentItem/LegacySegmentItem.tsx
Normal file
141
frontend/src/component/common/SegmentItem/LegacySegmentItem.tsx
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
import { useState, type VFC } from 'react';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import DonutLarge from '@mui/icons-material/DonutLarge';
|
||||||
|
import type { ISegment } from 'interfaces/segment';
|
||||||
|
import {
|
||||||
|
Accordion,
|
||||||
|
AccordionDetails,
|
||||||
|
AccordionSummary,
|
||||||
|
Button,
|
||||||
|
styled,
|
||||||
|
Typography,
|
||||||
|
} from '@mui/material';
|
||||||
|
import { ConstraintAccordionList } from 'component/common/ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList';
|
||||||
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
|
|
||||||
|
interface ISegmentItemProps {
|
||||||
|
segment: Partial<ISegment>;
|
||||||
|
isExpanded?: boolean;
|
||||||
|
disabled?: boolean | null;
|
||||||
|
constraintList?: JSX.Element;
|
||||||
|
headerContent?: JSX.Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
const StyledAccordion = styled(Accordion, {
|
||||||
|
shouldForwardProp: (prop) => prop !== 'isDisabled',
|
||||||
|
})<{ isDisabled: boolean | null }>(({ theme, isDisabled }) => ({
|
||||||
|
border: `1px solid ${theme.palette.divider}`,
|
||||||
|
'&.segment-accordion': {
|
||||||
|
borderRadius: theme.shape.borderRadiusMedium,
|
||||||
|
},
|
||||||
|
boxShadow: 'none',
|
||||||
|
margin: 0,
|
||||||
|
transition: 'all 0.1s ease',
|
||||||
|
'&:before': {
|
||||||
|
opacity: '0 !important',
|
||||||
|
},
|
||||||
|
'&.Mui-expanded': { backgroundColor: theme.palette.neutral.light },
|
||||||
|
backgroundColor: isDisabled
|
||||||
|
? theme.palette.envAccordion.disabled
|
||||||
|
: theme.palette.background.paper,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledAccordionSummary = styled(AccordionSummary)(({ theme }) => ({
|
||||||
|
margin: theme.spacing(0, 0.5),
|
||||||
|
fontSize: theme.typography.body2.fontSize,
|
||||||
|
'.MuiAccordionSummary-content': {
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledLink = styled(Link)(({ theme }) => ({
|
||||||
|
textDecoration: 'none',
|
||||||
|
marginLeft: theme.spacing(1),
|
||||||
|
'&:hover': {
|
||||||
|
textDecoration: 'underline',
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledText = styled('span', {
|
||||||
|
shouldForwardProp: (prop) => prop !== 'disabled',
|
||||||
|
})<{ disabled: boolean | null }>(({ theme, disabled }) => ({
|
||||||
|
color: disabled ? theme.palette.text.secondary : 'inherit',
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const SegmentItem: VFC<ISegmentItemProps> = ({
|
||||||
|
segment,
|
||||||
|
isExpanded,
|
||||||
|
headerContent,
|
||||||
|
constraintList,
|
||||||
|
disabled = false,
|
||||||
|
}) => {
|
||||||
|
const [isOpen, setIsOpen] = useState(isExpanded || false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledAccordion
|
||||||
|
className='segment-accordion'
|
||||||
|
isDisabled={disabled}
|
||||||
|
expanded={isOpen}
|
||||||
|
>
|
||||||
|
<StyledAccordionSummary id={`segment-accordion-${segment.id}`}>
|
||||||
|
<DonutLarge
|
||||||
|
sx={(theme) => ({
|
||||||
|
mr: 1,
|
||||||
|
color: disabled
|
||||||
|
? theme.palette.neutral.border
|
||||||
|
: theme.palette.secondary.main,
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
<StyledText disabled={disabled}>Segment:</StyledText>
|
||||||
|
<StyledLink to={`/segments/edit/${segment.id}`}>
|
||||||
|
{segment.name}
|
||||||
|
</StyledLink>
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={Boolean(headerContent)}
|
||||||
|
show={headerContent}
|
||||||
|
/>
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={!isExpanded}
|
||||||
|
show={
|
||||||
|
<Button
|
||||||
|
size='small'
|
||||||
|
variant='outlined'
|
||||||
|
onClick={() => setIsOpen((value) => !value)}
|
||||||
|
sx={{
|
||||||
|
my: 0,
|
||||||
|
ml: 'auto',
|
||||||
|
fontSize: (theme) =>
|
||||||
|
theme.typography.body2.fontSize,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{isOpen ? 'Close preview' : 'Preview'}
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</StyledAccordionSummary>
|
||||||
|
<AccordionDetails sx={{ pt: 0 }}>
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={Boolean(constraintList)}
|
||||||
|
show={constraintList}
|
||||||
|
elseShow={
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={(segment?.constraints?.length || 0) > 0}
|
||||||
|
show={
|
||||||
|
<ConstraintAccordionList
|
||||||
|
constraints={segment!.constraints!}
|
||||||
|
showLabel={false}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
elseShow={
|
||||||
|
<Typography>
|
||||||
|
This segment has no constraints.
|
||||||
|
</Typography>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</AccordionDetails>
|
||||||
|
</StyledAccordion>
|
||||||
|
);
|
||||||
|
};
|
@ -1,6 +1,5 @@
|
|||||||
import { useState, type VFC } from 'react';
|
import { useMemo, useState, type FC } from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import DonutLarge from '@mui/icons-material/DonutLarge';
|
|
||||||
import type { ISegment } from 'interfaces/segment';
|
import type { ISegment } from 'interfaces/segment';
|
||||||
import {
|
import {
|
||||||
Accordion,
|
Accordion,
|
||||||
@ -10,132 +9,106 @@ import {
|
|||||||
styled,
|
styled,
|
||||||
Typography,
|
Typography,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { ConstraintAccordionList } from 'component/common/ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList';
|
import { StrategyEvaluationItem } from 'component/common/ConstraintsList/StrategyEvaluationItem/StrategyEvaluationItem';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConstraintItem } from 'component/common/ConstraintsList/ConstraintItem/ConstraintItem';
|
||||||
|
import { objectId } from 'utils/objectId';
|
||||||
|
import { ConstraintsList } from 'component/common/ConstraintsList/ConstraintsList';
|
||||||
|
|
||||||
interface ISegmentItemProps {
|
type SegmentItemProps = {
|
||||||
segment: Partial<ISegment>;
|
segment: Partial<ISegment>;
|
||||||
isExpanded?: boolean;
|
isExpanded?: boolean;
|
||||||
disabled?: boolean | null;
|
disabled?: boolean | null;
|
||||||
constraintList?: JSX.Element;
|
constraintList?: JSX.Element;
|
||||||
headerContent?: JSX.Element;
|
headerContent?: JSX.Element;
|
||||||
}
|
};
|
||||||
|
|
||||||
const StyledAccordion = styled(Accordion, {
|
const StyledAccordion = styled(Accordion)(({ theme }) => ({
|
||||||
shouldForwardProp: (prop) => prop !== 'isDisabled',
|
|
||||||
})<{ isDisabled: boolean | null }>(({ theme, isDisabled }) => ({
|
|
||||||
border: `1px solid ${theme.palette.divider}`,
|
|
||||||
'&.segment-accordion': {
|
|
||||||
borderRadius: theme.shape.borderRadiusMedium,
|
|
||||||
},
|
|
||||||
boxShadow: 'none',
|
boxShadow: 'none',
|
||||||
margin: 0,
|
margin: 0,
|
||||||
transition: 'all 0.1s ease',
|
padding: 0,
|
||||||
'&:before': {
|
|
||||||
opacity: '0 !important',
|
|
||||||
},
|
|
||||||
'&.Mui-expanded': { backgroundColor: theme.palette.neutral.light },
|
|
||||||
backgroundColor: isDisabled
|
|
||||||
? theme.palette.envAccordion.disabled
|
|
||||||
: theme.palette.background.paper,
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledAccordionSummary = styled(AccordionSummary)(({ theme }) => ({
|
const StyledAccordionSummary = styled(AccordionSummary)(({ theme }) => ({
|
||||||
margin: theme.spacing(0, 0.5),
|
padding: 0,
|
||||||
fontSize: theme.typography.body2.fontSize,
|
fontSize: theme.typography.body2.fontSize,
|
||||||
'.MuiAccordionSummary-content': {
|
'.MuiAccordionSummary-content, .Mui-expanded.MuiAccordionSummary-content': {
|
||||||
display: 'flex',
|
margin: 0,
|
||||||
alignItems: 'center',
|
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledLink = styled(Link)(({ theme }) => ({
|
const StyledAccordionDetails = styled(AccordionDetails)(({ theme }) => ({
|
||||||
|
padding: theme.spacing(0, 2, 3),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledLink = styled(Link)({
|
||||||
textDecoration: 'none',
|
textDecoration: 'none',
|
||||||
marginLeft: theme.spacing(1),
|
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
textDecoration: 'underline',
|
textDecoration: 'underline',
|
||||||
},
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const StyledActionsContainer = styled('div')(({ theme }) => ({
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
marginLeft: 'auto',
|
||||||
|
marginRight: theme.spacing(2),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledText = styled('span', {
|
const StyledButton = styled(Button)(({ theme }) => ({
|
||||||
shouldForwardProp: (prop) => prop !== 'disabled',
|
fontSize: theme.typography.body2.fontSize,
|
||||||
})<{ disabled: boolean | null }>(({ theme, disabled }) => ({
|
|
||||||
color: disabled ? theme.palette.text.secondary : 'inherit',
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const SegmentItem: VFC<ISegmentItemProps> = ({
|
export const SegmentItem: FC<SegmentItemProps> = ({
|
||||||
segment,
|
segment,
|
||||||
isExpanded,
|
isExpanded,
|
||||||
headerContent,
|
headerContent,
|
||||||
constraintList,
|
constraintList,
|
||||||
disabled = false,
|
|
||||||
}) => {
|
}) => {
|
||||||
const [isOpen, setIsOpen] = useState(isExpanded || false);
|
const [isOpen, setIsOpen] = useState(isExpanded || false);
|
||||||
|
|
||||||
|
const constraints = useMemo(() => {
|
||||||
|
if (constraintList) {
|
||||||
|
return constraintList;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (segment.constraints?.length) {
|
||||||
|
return (
|
||||||
|
<ConstraintsList>
|
||||||
|
{segment.constraints.map((constraint, index) => (
|
||||||
|
<ConstraintItem
|
||||||
|
key={`${objectId(constraint)}-${index}`}
|
||||||
|
{...constraint}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</ConstraintsList>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <Typography>This segment has no constraints.</Typography>;
|
||||||
|
}, [constraintList, segment.constraints]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledAccordion
|
<StyledAccordion expanded={isOpen}>
|
||||||
className='segment-accordion'
|
|
||||||
isDisabled={disabled}
|
|
||||||
expanded={isOpen}
|
|
||||||
>
|
|
||||||
<StyledAccordionSummary id={`segment-accordion-${segment.id}`}>
|
<StyledAccordionSummary id={`segment-accordion-${segment.id}`}>
|
||||||
<DonutLarge
|
<StrategyEvaluationItem type='Segment'>
|
||||||
sx={(theme) => ({
|
<StyledLink to={`/segments/edit/${segment.id}`}>
|
||||||
mr: 1,
|
{segment.name}
|
||||||
color: disabled
|
</StyledLink>
|
||||||
? theme.palette.neutral.border
|
</StrategyEvaluationItem>
|
||||||
: theme.palette.secondary.main,
|
{headerContent ? headerContent : null}
|
||||||
})}
|
{!isExpanded ? (
|
||||||
/>
|
<StyledActionsContainer>
|
||||||
<StyledText disabled={disabled}>Segment:</StyledText>
|
<StyledButton
|
||||||
<StyledLink to={`/segments/edit/${segment.id}`}>
|
|
||||||
{segment.name}
|
|
||||||
</StyledLink>
|
|
||||||
<ConditionallyRender
|
|
||||||
condition={Boolean(headerContent)}
|
|
||||||
show={headerContent}
|
|
||||||
/>
|
|
||||||
<ConditionallyRender
|
|
||||||
condition={!isExpanded}
|
|
||||||
show={
|
|
||||||
<Button
|
|
||||||
size='small'
|
size='small'
|
||||||
variant='outlined'
|
variant='outlined'
|
||||||
onClick={() => setIsOpen((value) => !value)}
|
onClick={() => setIsOpen((value) => !value)}
|
||||||
sx={{
|
|
||||||
my: 0,
|
|
||||||
ml: 'auto',
|
|
||||||
fontSize: (theme) =>
|
|
||||||
theme.typography.body2.fontSize,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{isOpen ? 'Close preview' : 'Preview'}
|
{isOpen ? 'Close preview' : 'Preview'}
|
||||||
</Button>
|
</StyledButton>
|
||||||
}
|
</StyledActionsContainer>
|
||||||
/>
|
) : null}
|
||||||
</StyledAccordionSummary>
|
</StyledAccordionSummary>
|
||||||
<AccordionDetails sx={{ pt: 0 }}>
|
<StyledAccordionDetails>{constraints}</StyledAccordionDetails>
|
||||||
<ConditionallyRender
|
|
||||||
condition={Boolean(constraintList)}
|
|
||||||
show={constraintList}
|
|
||||||
elseShow={
|
|
||||||
<ConditionallyRender
|
|
||||||
condition={(segment?.constraints?.length || 0) > 0}
|
|
||||||
show={
|
|
||||||
<ConstraintAccordionList
|
|
||||||
constraints={segment!.constraints!}
|
|
||||||
showLabel={false}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
elseShow={
|
|
||||||
<Typography>
|
|
||||||
This segment has no constraints.
|
|
||||||
</Typography>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</AccordionDetails>
|
|
||||||
</StyledAccordion>
|
</StyledAccordion>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -3,7 +3,7 @@ import { Fragment, useState } from 'react';
|
|||||||
import type { ISegment } from 'interfaces/segment';
|
import type { ISegment } from 'interfaces/segment';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { FeatureStrategySegmentChip } from 'component/feature/FeatureStrategy/FeatureStrategySegment/FeatureStrategySegmentChip';
|
import { FeatureStrategySegmentChip } from 'component/feature/FeatureStrategy/FeatureStrategySegment/FeatureStrategySegmentChip';
|
||||||
import { SegmentItem } from 'component/common/SegmentItem/SegmentItem';
|
import { SegmentItem } from 'component/common/SegmentItem/LegacySegmentItem';
|
||||||
import { styled } from '@mui/material';
|
import { styled } from '@mui/material';
|
||||||
|
|
||||||
interface IFeatureStrategySegmentListProps {
|
interface IFeatureStrategySegmentListProps {
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
import { styled } from '@mui/material';
|
|
||||||
|
|
||||||
const StyledAnd = styled('div')(({ theme }) => ({
|
|
||||||
position: 'absolute',
|
|
||||||
top: theme.spacing(-0.5),
|
|
||||||
left: theme.spacing(2),
|
|
||||||
transform: 'translateY(-50%)',
|
|
||||||
padding: theme.spacing(0.75, 1),
|
|
||||||
lineHeight: 1,
|
|
||||||
fontSize: theme.fontSizes.smallerBody,
|
|
||||||
color: theme.palette.text.primary,
|
|
||||||
background: theme.palette.background.application,
|
|
||||||
borderRadius: theme.shape.borderRadiusLarge,
|
|
||||||
}));
|
|
||||||
|
|
||||||
export const StrategyEvaluationSeparator = () => (
|
|
||||||
<StyledAnd role='separator'>AND</StyledAnd>
|
|
||||||
);
|
|
@ -1,17 +1,17 @@
|
|||||||
import { Children, isValidElement, type FC, type ReactNode } from 'react';
|
import type { FC } from 'react';
|
||||||
import { styled } from '@mui/material';
|
import { styled } from '@mui/material';
|
||||||
import type { CreateFeatureStrategySchema } from 'openapi';
|
import type { CreateFeatureStrategySchema } 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 './ConstraintItem/ConstraintItem';
|
import { ConstraintItem } from 'component/common/ConstraintsList/ConstraintItem/ConstraintItem';
|
||||||
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 { StrategyEvaluationSeparator } from './StrategyEvaluationSeparator/StrategyEvaluationSeparator';
|
|
||||||
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';
|
||||||
|
|
||||||
const FilterContainer = styled('div', {
|
const FilterContainer = styled('div', {
|
||||||
shouldForwardProp: (prop) => prop !== 'grayscale',
|
shouldForwardProp: (prop) => prop !== 'grayscale',
|
||||||
@ -19,49 +19,6 @@ const FilterContainer = styled('div', {
|
|||||||
grayscale ? { filter: 'grayscale(1)', opacity: 0.67 } : {},
|
grayscale ? { filter: 'grayscale(1)', opacity: 0.67 } : {},
|
||||||
);
|
);
|
||||||
|
|
||||||
const StyledList = styled('ul')(({ theme }) => ({
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
listStyle: 'none',
|
|
||||||
padding: 0,
|
|
||||||
margin: 0,
|
|
||||||
'&.disabled-strategy': {
|
|
||||||
filter: 'grayscale(1)',
|
|
||||||
opacity: 0.67,
|
|
||||||
},
|
|
||||||
gap: theme.spacing(1),
|
|
||||||
}));
|
|
||||||
|
|
||||||
const StyledListItem = styled('li')(({ theme }) => ({
|
|
||||||
position: 'relative',
|
|
||||||
padding: theme.spacing(2, 3),
|
|
||||||
border: `1px solid ${theme.palette.divider}`,
|
|
||||||
borderRadius: theme.shape.borderRadiusMedium,
|
|
||||||
background: theme.palette.background.default,
|
|
||||||
}));
|
|
||||||
|
|
||||||
const List: FC<{ children: ReactNode }> = ({ children }) => {
|
|
||||||
const result: ReactNode[] = [];
|
|
||||||
Children.forEach(children, (child, index) => {
|
|
||||||
if (isValidElement(child)) {
|
|
||||||
result.push(
|
|
||||||
<ListItem key={index}>
|
|
||||||
{index > 0 ? (
|
|
||||||
<StrategyEvaluationSeparator key={`${index}-divider`} />
|
|
||||||
) : null}
|
|
||||||
{child}
|
|
||||||
</ListItem>,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return <StyledList>{result}</StyledList>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const ListItem: FC<{ children: ReactNode }> = ({ children }) => (
|
|
||||||
<StyledListItem>{children}</StyledListItem>
|
|
||||||
);
|
|
||||||
|
|
||||||
type StrategyExecutionProps = {
|
type StrategyExecutionProps = {
|
||||||
strategy: IFeatureStrategyPayload | CreateFeatureStrategySchema;
|
strategy: IFeatureStrategyPayload | CreateFeatureStrategySchema;
|
||||||
displayGroupId?: boolean;
|
displayGroupId?: boolean;
|
||||||
@ -93,7 +50,7 @@ export const StrategyExecution: FC<StrategyExecutionProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<FilterContainer grayscale={strategy.disabled === true}>
|
<FilterContainer grayscale={strategy.disabled === true}>
|
||||||
<List>
|
<ConstraintsList>
|
||||||
{strategySegments?.map((segment) => (
|
{strategySegments?.map((segment) => (
|
||||||
<SegmentItem segment={segment} />
|
<SegmentItem segment={segment} />
|
||||||
))}
|
))}
|
||||||
@ -104,7 +61,7 @@ export const StrategyExecution: FC<StrategyExecutionProps> = ({
|
|||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
{isCustomStrategy ? customStrategyItems : strategyParameters}
|
{isCustomStrategy ? customStrategyItems : strategyParameters}
|
||||||
</List>
|
</ConstraintsList>
|
||||||
</FilterContainer>
|
</FilterContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -5,8 +5,8 @@ import {
|
|||||||
parseParameterString,
|
parseParameterString,
|
||||||
parseParameterStrings,
|
parseParameterStrings,
|
||||||
} from 'utils/parseParameter';
|
} from 'utils/parseParameter';
|
||||||
import { StrategyEvaluationItem } from '../StrategyEvaluationItem/StrategyEvaluationItem';
|
import { StrategyEvaluationItem } from 'component/common/ConstraintsList/StrategyEvaluationItem/StrategyEvaluationItem';
|
||||||
import { StrategyEvaluationChip } from '../StrategyEvaluationChip/StrategyEvaluationChip';
|
import { StrategyEvaluationChip } from 'component/common/ConstraintsList/StrategyEvaluationChip/StrategyEvaluationChip';
|
||||||
import type {
|
import type {
|
||||||
CreateFeatureStrategySchema,
|
CreateFeatureStrategySchema,
|
||||||
StrategySchema,
|
StrategySchema,
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { type FC, useMemo } from 'react';
|
import { type FC, useMemo } from 'react';
|
||||||
import { StrategyEvaluationChip } from '../StrategyEvaluationChip/StrategyEvaluationChip';
|
import { StrategyEvaluationChip } from 'component/common/ConstraintsList/StrategyEvaluationChip/StrategyEvaluationChip';
|
||||||
import {
|
import {
|
||||||
parseParameterNumber,
|
parseParameterNumber,
|
||||||
parseParameterStrings,
|
parseParameterStrings,
|
||||||
} from 'utils/parseParameter';
|
} from 'utils/parseParameter';
|
||||||
import { StrategyEvaluationItem } from '../StrategyEvaluationItem/StrategyEvaluationItem';
|
import { StrategyEvaluationItem } from 'component/common/ConstraintsList/StrategyEvaluationItem/StrategyEvaluationItem';
|
||||||
import type { IFeatureStrategyPayload } from 'interfaces/strategy';
|
import type { IFeatureStrategyPayload } from 'interfaces/strategy';
|
||||||
import type { CreateFeatureStrategySchema } from 'openapi';
|
import type { CreateFeatureStrategySchema } from 'openapi';
|
||||||
|
|
||||||
@ -38,7 +38,11 @@ const RolloutParameter: FC<{
|
|||||||
{hasConstraints ? 'who match constraints ' : ' '}
|
{hasConstraints ? 'who match constraints ' : ' '}
|
||||||
is included.
|
is included.
|
||||||
</span>
|
</span>
|
||||||
{/* TODO: displayGroupId */}
|
{displayGroupId && parameters?.groupId ? (
|
||||||
|
<StrategyEvaluationChip
|
||||||
|
label={`groupId: ${parameters?.groupId}`}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
</StrategyEvaluationItem>
|
</StrategyEvaluationItem>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Fragment } from 'react';
|
import { Fragment } from 'react';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { StrategySeparator } from 'component/common/StrategySeparator/LegacyStrategySeparator';
|
import { StrategySeparator } from 'component/common/StrategySeparator/LegacyStrategySeparator';
|
||||||
import { SegmentItem } from '../../../../common/SegmentItem/SegmentItem';
|
import { SegmentItem } from 'component/common/SegmentItem/LegacySegmentItem';
|
||||||
import type { ISegment } from 'interfaces/segment';
|
import type { ISegment } from 'interfaces/segment';
|
||||||
|
|
||||||
interface IFeatureOverviewSegmentProps {
|
interface IFeatureOverviewSegmentProps {
|
||||||
|
@ -5,7 +5,7 @@ import CancelOutlined from '@mui/icons-material/CancelOutlined';
|
|||||||
import { StrategySeparator } from 'component/common/StrategySeparator/LegacyStrategySeparator';
|
import { StrategySeparator } from 'component/common/StrategySeparator/LegacyStrategySeparator';
|
||||||
import { styled, Typography } from '@mui/material';
|
import { styled, Typography } from '@mui/material';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { SegmentItem } from 'component/common/SegmentItem/SegmentItem';
|
import { SegmentItem } from 'component/common/SegmentItem/LegacySegmentItem';
|
||||||
|
|
||||||
interface ISegmentExecutionProps {
|
interface ISegmentExecutionProps {
|
||||||
segments?: PlaygroundSegmentSchema[];
|
segments?: PlaygroundSegmentSchema[];
|
||||||
|
@ -2,7 +2,7 @@ import { Fragment, type VFC } from 'react';
|
|||||||
import type { PlaygroundSegmentSchema } from 'openapi';
|
import type { PlaygroundSegmentSchema } from 'openapi';
|
||||||
import { StrategySeparator } from 'component/common/StrategySeparator/LegacyStrategySeparator';
|
import { StrategySeparator } from 'component/common/StrategySeparator/LegacyStrategySeparator';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { SegmentItem } from 'component/common/SegmentItem/SegmentItem';
|
import { SegmentItem } from 'component/common/SegmentItem/LegacySegmentItem';
|
||||||
import { ConstraintExecutionWithoutResults } from '../ConstraintExecution/ConstraintExecutionWithoutResults';
|
import { ConstraintExecutionWithoutResults } from '../ConstraintExecution/ConstraintExecutionWithoutResults';
|
||||||
|
|
||||||
interface ISegmentExecutionWithoutResultProps {
|
interface ISegmentExecutionWithoutResultProps {
|
||||||
|
@ -2,7 +2,7 @@ import { Fragment, useState } from 'react';
|
|||||||
import type { ISegment } from 'interfaces/segment';
|
import type { ISegment } from 'interfaces/segment';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { FeatureStrategySegmentChip } from 'component/feature/FeatureStrategy/FeatureStrategySegment/FeatureStrategySegmentChip';
|
import { FeatureStrategySegmentChip } from 'component/feature/FeatureStrategy/FeatureStrategySegment/FeatureStrategySegmentChip';
|
||||||
import { SegmentItem } from 'component/common/SegmentItem/SegmentItem';
|
import { SegmentItem } from 'component/common/SegmentItem/LegacySegmentItem';
|
||||||
import { styled } from '@mui/material';
|
import { styled } from '@mui/material';
|
||||||
|
|
||||||
const StyledList = styled('div')(({ theme }) => ({
|
const StyledList = styled('div')(({ theme }) => ({
|
||||||
|
Loading…
Reference in New Issue
Block a user