mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	fix: grey out text and icons for disabled strategies in playground (#5113)
What it says on the tin Closes # [1-1512](https://linear.app/unleash/issue/1-1512/grey-out-everything-icons-labels-etc-when-strategy-is-disabled) <img width="689" alt="Screenshot 2023-10-20 at 12 25 51" src="https://github.com/Unleash/unleash/assets/104830839/3192a125-0e2a-46f2-a266-e4d6c171bdad"> <img width="711" alt="Screenshot 2023-10-20 at 14 52 30" src="https://github.com/Unleash/unleash/assets/104830839/15040439-c059-4725-9518-82e363fd7230"> --------- Signed-off-by: andreas-unleash <andreas@getunleash.ai>
This commit is contained in:
		
							parent
							
								
									03faffa1d6
								
							
						
					
					
						commit
						69d050a70f
					
				@ -23,6 +23,7 @@ interface IConstraintAccordionViewProps {
 | 
			
		||||
    onEdit?: () => void;
 | 
			
		||||
    sx?: SxProps<Theme>;
 | 
			
		||||
    compact?: boolean;
 | 
			
		||||
    disabled?: boolean;
 | 
			
		||||
    renderAfter?: JSX.Element;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -68,6 +69,7 @@ export const ConstraintAccordionView = ({
 | 
			
		||||
    onDelete,
 | 
			
		||||
    sx = undefined,
 | 
			
		||||
    compact = false,
 | 
			
		||||
    disabled = false,
 | 
			
		||||
    renderAfter,
 | 
			
		||||
}: IConstraintAccordionViewProps) => {
 | 
			
		||||
    const [expandable, setExpandable] = useState(true);
 | 
			
		||||
@ -102,6 +104,7 @@ export const ConstraintAccordionView = ({
 | 
			
		||||
                        onDelete={onDelete}
 | 
			
		||||
                        singleValue={singleValue}
 | 
			
		||||
                        allowExpand={setExpandable}
 | 
			
		||||
                        disabled={disabled}
 | 
			
		||||
                        expanded={expanded}
 | 
			
		||||
                        compact={compact}
 | 
			
		||||
                    />
 | 
			
		||||
 | 
			
		||||
@ -13,6 +13,7 @@ interface IConstraintAccordionViewHeaderProps {
 | 
			
		||||
    expanded: boolean;
 | 
			
		||||
    allowExpand: (shouldExpand: boolean) => void;
 | 
			
		||||
    compact?: boolean;
 | 
			
		||||
    disabled?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const StyledContainer = styled('div')(({ theme }) => ({
 | 
			
		||||
@ -34,6 +35,7 @@ export const ConstraintAccordionViewHeader = ({
 | 
			
		||||
    allowExpand,
 | 
			
		||||
    expanded,
 | 
			
		||||
    compact,
 | 
			
		||||
    disabled,
 | 
			
		||||
}: IConstraintAccordionViewHeaderProps) => {
 | 
			
		||||
    const { context } = useUnleashContext();
 | 
			
		||||
    const { contextName } = constraint;
 | 
			
		||||
@ -44,12 +46,13 @@ export const ConstraintAccordionViewHeader = ({
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <StyledContainer>
 | 
			
		||||
            <ConstraintIcon compact={compact} />
 | 
			
		||||
            <ConstraintIcon compact={compact} disabled={disabled} />
 | 
			
		||||
            <ConstraintAccordionViewHeaderInfo
 | 
			
		||||
                constraint={constraint}
 | 
			
		||||
                singleValue={singleValue}
 | 
			
		||||
                allowExpand={allowExpand}
 | 
			
		||||
                expanded={expanded}
 | 
			
		||||
                disabled={disabled}
 | 
			
		||||
            />
 | 
			
		||||
            <ConstraintAccordionHeaderActions
 | 
			
		||||
                onEdit={onEdit}
 | 
			
		||||
 | 
			
		||||
@ -50,6 +50,7 @@ interface ConstraintAccordionViewHeaderMetaInfoProps {
 | 
			
		||||
    singleValue: boolean;
 | 
			
		||||
    expanded: boolean;
 | 
			
		||||
    allowExpand: (shouldExpand: boolean) => void;
 | 
			
		||||
    disabled?: boolean;
 | 
			
		||||
    maxLength?: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -58,23 +59,34 @@ export const ConstraintAccordionViewHeaderInfo = ({
 | 
			
		||||
    singleValue,
 | 
			
		||||
    allowExpand,
 | 
			
		||||
    expanded,
 | 
			
		||||
    disabled = false,
 | 
			
		||||
    maxLength = 112, //The max number of characters in the values text for NOT allowing expansion
 | 
			
		||||
}: ConstraintAccordionViewHeaderMetaInfoProps) => {
 | 
			
		||||
    return (
 | 
			
		||||
        <StyledHeaderWrapper>
 | 
			
		||||
            <StyledHeaderMetaInfo>
 | 
			
		||||
                <Tooltip title={constraint.contextName} arrow>
 | 
			
		||||
                    <StyledHeaderText>
 | 
			
		||||
                    <StyledHeaderText
 | 
			
		||||
                        sx={(theme) => ({
 | 
			
		||||
                            color: disabled
 | 
			
		||||
                                ? theme.palette.text.secondary
 | 
			
		||||
                                : 'inherit',
 | 
			
		||||
                        })}
 | 
			
		||||
                    >
 | 
			
		||||
                        {constraint.contextName}
 | 
			
		||||
                    </StyledHeaderText>
 | 
			
		||||
                </Tooltip>
 | 
			
		||||
                <ConstraintViewHeaderOperator constraint={constraint} />
 | 
			
		||||
                <ConstraintViewHeaderOperator
 | 
			
		||||
                    constraint={constraint}
 | 
			
		||||
                    disabled={disabled}
 | 
			
		||||
                />
 | 
			
		||||
                <ConditionallyRender
 | 
			
		||||
                    condition={singleValue}
 | 
			
		||||
                    show={
 | 
			
		||||
                        <ConstraintAccordionViewHeaderSingleValue
 | 
			
		||||
                            constraint={constraint}
 | 
			
		||||
                            allowExpand={allowExpand}
 | 
			
		||||
                            disabled={disabled}
 | 
			
		||||
                        />
 | 
			
		||||
                    }
 | 
			
		||||
                    elseShow={
 | 
			
		||||
@ -83,6 +95,7 @@ export const ConstraintAccordionViewHeaderInfo = ({
 | 
			
		||||
                            expanded={expanded}
 | 
			
		||||
                            allowExpand={allowExpand}
 | 
			
		||||
                            maxLength={maxLength}
 | 
			
		||||
                            disabled={disabled}
 | 
			
		||||
                        />
 | 
			
		||||
                    }
 | 
			
		||||
                />
 | 
			
		||||
 | 
			
		||||
@ -22,6 +22,7 @@ interface ConstraintSingleValueProps {
 | 
			
		||||
    expanded: boolean;
 | 
			
		||||
    maxLength: number;
 | 
			
		||||
    allowExpand: (shouldExpand: boolean) => void;
 | 
			
		||||
    disabled?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const StyledHeaderValuesContainerWrapper = styled('div')(({ theme }) => ({
 | 
			
		||||
@ -55,6 +56,7 @@ export const ConstraintAccordionViewHeaderMultipleValues = ({
 | 
			
		||||
    expanded,
 | 
			
		||||
    allowExpand,
 | 
			
		||||
    maxLength,
 | 
			
		||||
    disabled = false,
 | 
			
		||||
}: ConstraintSingleValueProps) => {
 | 
			
		||||
    const [expandable, setExpandable] = useState(false);
 | 
			
		||||
 | 
			
		||||
@ -72,7 +74,15 @@ export const ConstraintAccordionViewHeaderMultipleValues = ({
 | 
			
		||||
    return (
 | 
			
		||||
        <StyledHeaderValuesContainerWrapper>
 | 
			
		||||
            <StyledHeaderValuesContainer>
 | 
			
		||||
                <StyledValuesSpan>{text}</StyledValuesSpan>
 | 
			
		||||
                <StyledValuesSpan
 | 
			
		||||
                    sx={(theme) => ({
 | 
			
		||||
                        color: disabled
 | 
			
		||||
                            ? theme.palette.text.secondary
 | 
			
		||||
                            : 'inherit',
 | 
			
		||||
                    })}
 | 
			
		||||
                >
 | 
			
		||||
                    {text}
 | 
			
		||||
                </StyledValuesSpan>
 | 
			
		||||
                <ConditionallyRender
 | 
			
		||||
                    condition={expandable}
 | 
			
		||||
                    show={
 | 
			
		||||
 | 
			
		||||
@ -15,6 +15,7 @@ const StyledSingleValueChip = styled(Chip)(({ theme }) => ({
 | 
			
		||||
interface ConstraintSingleValueProps {
 | 
			
		||||
    constraint: IConstraint;
 | 
			
		||||
    allowExpand: (shouldExpand: boolean) => void;
 | 
			
		||||
    disabled?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const StyledHeaderValuesContainerWrapper = styled('div')(({ theme }) => ({
 | 
			
		||||
@ -26,6 +27,7 @@ const StyledHeaderValuesContainerWrapper = styled('div')(({ theme }) => ({
 | 
			
		||||
export const ConstraintAccordionViewHeaderSingleValue = ({
 | 
			
		||||
    constraint,
 | 
			
		||||
    allowExpand,
 | 
			
		||||
    disabled = false,
 | 
			
		||||
}: ConstraintSingleValueProps) => {
 | 
			
		||||
    const { locationSettings } = useLocationSettings();
 | 
			
		||||
 | 
			
		||||
@ -36,6 +38,9 @@ export const ConstraintAccordionViewHeaderSingleValue = ({
 | 
			
		||||
    return (
 | 
			
		||||
        <StyledHeaderValuesContainerWrapper>
 | 
			
		||||
            <StyledSingleValueChip
 | 
			
		||||
                sx={(theme) => ({
 | 
			
		||||
                    color: disabled ? theme.palette.text.secondary : 'inherit',
 | 
			
		||||
                })}
 | 
			
		||||
                label={formatConstraintValue(constraint, locationSettings)}
 | 
			
		||||
            />
 | 
			
		||||
        </StyledHeaderValuesContainerWrapper>
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,7 @@ import { oneOf } from 'utils/oneOf';
 | 
			
		||||
 | 
			
		||||
interface ConstraintViewHeaderOperatorProps {
 | 
			
		||||
    constraint: IConstraint;
 | 
			
		||||
    disabled?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const StyledHeaderValuesContainerWrapper = styled('div')(({ theme }) => ({
 | 
			
		||||
@ -28,6 +29,7 @@ const StyledHeaderConstraintContainer = styled('div')(({ theme }) => ({
 | 
			
		||||
 | 
			
		||||
export const ConstraintViewHeaderOperator = ({
 | 
			
		||||
    constraint,
 | 
			
		||||
    disabled = false,
 | 
			
		||||
}: ConstraintViewHeaderOperatorProps) => {
 | 
			
		||||
    return (
 | 
			
		||||
        <StyledHeaderValuesContainerWrapper>
 | 
			
		||||
@ -47,6 +49,7 @@ export const ConstraintViewHeaderOperator = ({
 | 
			
		||||
                <ConstraintOperator
 | 
			
		||||
                    constraint={constraint}
 | 
			
		||||
                    hasPrefix={Boolean(constraint.inverted)}
 | 
			
		||||
                    disabled={disabled}
 | 
			
		||||
                />
 | 
			
		||||
            </StyledHeaderConstraintContainer>
 | 
			
		||||
            <ConditionallyRender
 | 
			
		||||
 | 
			
		||||
@ -4,18 +4,24 @@ import { TrackChanges } from '@mui/icons-material';
 | 
			
		||||
 | 
			
		||||
interface IConstraintIconProps {
 | 
			
		||||
    compact?: boolean;
 | 
			
		||||
    disabled?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const ConstraintIcon: VFC<IConstraintIconProps> = ({ compact }) => (
 | 
			
		||||
export const ConstraintIcon: VFC<IConstraintIconProps> = ({
 | 
			
		||||
    compact,
 | 
			
		||||
    disabled,
 | 
			
		||||
}) => (
 | 
			
		||||
    <Box
 | 
			
		||||
        sx={{
 | 
			
		||||
            backgroundColor: 'primary.light',
 | 
			
		||||
        sx={(theme) => ({
 | 
			
		||||
            backgroundColor: disabled
 | 
			
		||||
                ? theme.palette.neutral.border
 | 
			
		||||
                : 'primary.light',
 | 
			
		||||
            p: compact ? '1px' : '2px',
 | 
			
		||||
            borderRadius: '50%',
 | 
			
		||||
            width: compact ? '18px' : '24px',
 | 
			
		||||
            height: compact ? '18px' : '24px',
 | 
			
		||||
            marginRight: '13px',
 | 
			
		||||
        }}
 | 
			
		||||
        })}
 | 
			
		||||
    >
 | 
			
		||||
        <TrackChanges
 | 
			
		||||
            sx={(theme) => ({
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,7 @@ import { styled } from '@mui/material';
 | 
			
		||||
interface IConstraintOperatorProps {
 | 
			
		||||
    constraint: IConstraint;
 | 
			
		||||
    hasPrefix?: boolean;
 | 
			
		||||
    disabled?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const StyledContainer = styled('div')(({ theme }) => ({
 | 
			
		||||
@ -15,19 +16,25 @@ const StyledContainer = styled('div')(({ theme }) => ({
 | 
			
		||||
    lineHeight: 1.25,
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
const StyledName = styled('div')(({ theme }) => ({
 | 
			
		||||
const StyledName = styled('div', {
 | 
			
		||||
    shouldForwardProp: (prop) => prop !== 'disabled',
 | 
			
		||||
})<{ disabled: boolean }>(({ theme, disabled }) => ({
 | 
			
		||||
    fontSize: theme.fontSizes.smallBody,
 | 
			
		||||
    lineHeight: 17 / 14,
 | 
			
		||||
    color: disabled ? theme.palette.text.secondary : theme.palette.text.primary,
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
const StyledText = styled('div')(({ theme }) => ({
 | 
			
		||||
const StyledText = styled('div', {
 | 
			
		||||
    shouldForwardProp: (prop) => prop !== 'disabled',
 | 
			
		||||
})<{ disabled: boolean }>(({ theme, disabled }) => ({
 | 
			
		||||
    fontSize: theme.fontSizes.smallerBody,
 | 
			
		||||
    color: theme.palette.neutral.main,
 | 
			
		||||
    color: disabled ? theme.palette.text.secondary : theme.palette.neutral.main,
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
export const ConstraintOperator = ({
 | 
			
		||||
    constraint,
 | 
			
		||||
    hasPrefix,
 | 
			
		||||
    disabled = false,
 | 
			
		||||
}: IConstraintOperatorProps) => {
 | 
			
		||||
    const operatorName = constraint.operator;
 | 
			
		||||
    const operatorText = formatOperatorDescription(constraint.operator);
 | 
			
		||||
@ -40,8 +47,8 @@ export const ConstraintOperator = ({
 | 
			
		||||
                paddingLeft: hasPrefix ? 0 : undefined,
 | 
			
		||||
            }}
 | 
			
		||||
        >
 | 
			
		||||
            <StyledName>{operatorName}</StyledName>
 | 
			
		||||
            <StyledText>{operatorText}</StyledText>
 | 
			
		||||
            <StyledName disabled={disabled}>{operatorName}</StyledName>
 | 
			
		||||
            <StyledText disabled={disabled}>{operatorText}</StyledText>
 | 
			
		||||
        </StyledContainer>
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,46 @@
 | 
			
		||||
import { useTheme } from '@mui/material';
 | 
			
		||||
import { CSSProperties } from 'react';
 | 
			
		||||
 | 
			
		||||
interface IPercentageCircleProps {
 | 
			
		||||
    percentage: number;
 | 
			
		||||
    size?: `${number}rem`;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const PercentageCircle = ({
 | 
			
		||||
    percentage,
 | 
			
		||||
    size = '4rem',
 | 
			
		||||
}: IPercentageCircleProps) => {
 | 
			
		||||
    const theme = useTheme();
 | 
			
		||||
 | 
			
		||||
    const style: CSSProperties = {
 | 
			
		||||
        display: 'block',
 | 
			
		||||
        borderRadius: '100%',
 | 
			
		||||
        transform: 'rotate(-90deg)',
 | 
			
		||||
        height: size,
 | 
			
		||||
        width: size,
 | 
			
		||||
        background: theme.palette.background.elevation2,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // The percentage circle used to be drawn by CSS with a conic-gradient,
 | 
			
		||||
    // but the result was either jagged or blurry. SVG seems to look better.
 | 
			
		||||
    // See https://stackoverflow.com/a/70659532.
 | 
			
		||||
    const radius = 100 / (2 * Math.PI);
 | 
			
		||||
    const diameter = 2 * radius;
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <svg viewBox={`0 0 ${diameter} ${diameter}`} style={style} aria-hidden>
 | 
			
		||||
            <title>A circle progress bar with {percentage}% completion.</title>
 | 
			
		||||
            <circle
 | 
			
		||||
                r={radius}
 | 
			
		||||
                cx={radius}
 | 
			
		||||
                cy={radius}
 | 
			
		||||
                fill='none'
 | 
			
		||||
                stroke={theme.palette.neutral.border}
 | 
			
		||||
                strokeWidth={diameter}
 | 
			
		||||
                strokeDasharray={`${percentage} 100`}
 | 
			
		||||
            />
 | 
			
		||||
        </svg>
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default PercentageCircle;
 | 
			
		||||
@ -16,6 +16,7 @@ import { ConditionallyRender } from 'component/common/ConditionallyRender/Condit
 | 
			
		||||
interface ISegmentItemProps {
 | 
			
		||||
    segment: Partial<ISegment>;
 | 
			
		||||
    isExpanded?: boolean;
 | 
			
		||||
    disabled?: boolean;
 | 
			
		||||
    constraintList?: JSX.Element;
 | 
			
		||||
    headerContent?: JSX.Element;
 | 
			
		||||
}
 | 
			
		||||
@ -49,20 +50,33 @@ const StyledLink = styled(Link)(({ theme }) => ({
 | 
			
		||||
        textDecoration: 'underline',
 | 
			
		||||
    },
 | 
			
		||||
}));
 | 
			
		||||
const StyledText = styled('span', {
 | 
			
		||||
    shouldForwardProp: (prop) => prop !== 'disabled',
 | 
			
		||||
})<{ disabled: boolean }>(({ 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 expanded={isOpen}>
 | 
			
		||||
            <StyledAccordionSummary id={`segment-accordion-${segment.id}`}>
 | 
			
		||||
                <DonutLarge color='secondary' sx={{ mr: 1 }} />
 | 
			
		||||
                <span>Segment:</span>
 | 
			
		||||
                <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>
 | 
			
		||||
 | 
			
		||||
@ -9,8 +9,6 @@ import { ConditionallyRender } from 'component/common/ConditionallyRender/Condit
 | 
			
		||||
import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator';
 | 
			
		||||
import { styled } from '@mui/material';
 | 
			
		||||
import { ConstraintAccordionView } from 'component/common/ConstraintAccordion/ConstraintAccordionView/ConstraintAccordionView';
 | 
			
		||||
import { ConstraintError } from './ConstraintError/ConstraintError';
 | 
			
		||||
import { ConstraintOk } from './ConstraintOk/ConstraintOk';
 | 
			
		||||
 | 
			
		||||
interface IConstraintExecutionWithoutResultsProps {
 | 
			
		||||
    constraints?: PlaygroundConstraintSchema[];
 | 
			
		||||
@ -35,7 +33,11 @@ export const ConstraintExecutionWithoutResults: VFC<
 | 
			
		||||
                        condition={index > 0}
 | 
			
		||||
                        show={<StrategySeparator text='AND' />}
 | 
			
		||||
                    />
 | 
			
		||||
                    <ConstraintAccordionView constraint={constraint} compact />
 | 
			
		||||
                    <ConstraintAccordionView
 | 
			
		||||
                        constraint={constraint}
 | 
			
		||||
                        compact
 | 
			
		||||
                        disabled
 | 
			
		||||
                    />
 | 
			
		||||
                </Fragment>
 | 
			
		||||
            ))}
 | 
			
		||||
        </ConstraintExecutionWrapper>
 | 
			
		||||
 | 
			
		||||
@ -52,6 +52,7 @@ export const DisabledStrategyExecution: VFC<IDisabledStrategyExecutionProps> =
 | 
			
		||||
                    parameters={parameters}
 | 
			
		||||
                    constraints={constraints}
 | 
			
		||||
                    input={input}
 | 
			
		||||
                    disabled
 | 
			
		||||
                />
 | 
			
		||||
            ),
 | 
			
		||||
            hasCustomStrategyParameters && (
 | 
			
		||||
@ -61,9 +62,14 @@ export const DisabledStrategyExecution: VFC<IDisabledStrategyExecutionProps> =
 | 
			
		||||
                />
 | 
			
		||||
            ),
 | 
			
		||||
            name === 'default' && (
 | 
			
		||||
                <StyledBoxSummary sx={{ width: '100%' }}>
 | 
			
		||||
                    The standard strategy is <Badge color='success'>ON</Badge>{' '}
 | 
			
		||||
                    for all users.
 | 
			
		||||
                <StyledBoxSummary
 | 
			
		||||
                    sx={(theme) => ({
 | 
			
		||||
                        width: '100%',
 | 
			
		||||
                        color: theme.palette.text.secondary,
 | 
			
		||||
                    })}
 | 
			
		||||
                >
 | 
			
		||||
                    The standard strategy is{' '}
 | 
			
		||||
                    <Badge color={'disabled'}>ON</Badge> for all users.
 | 
			
		||||
                </StyledBoxSummary>
 | 
			
		||||
            ),
 | 
			
		||||
        ].filter(Boolean);
 | 
			
		||||
@ -74,7 +80,12 @@ export const DisabledStrategyExecution: VFC<IDisabledStrategyExecutionProps> =
 | 
			
		||||
                    // biome-ignore lint/suspicious/noArrayIndexKey: <explanation>
 | 
			
		||||
                    <Fragment key={index}>
 | 
			
		||||
                        <ConditionallyRender
 | 
			
		||||
                            condition={index > 0}
 | 
			
		||||
                            condition={
 | 
			
		||||
                                index > 0 &&
 | 
			
		||||
                                (strategyResult.name === 'flexibleRollout'
 | 
			
		||||
                                    ? index < items.length
 | 
			
		||||
                                    : index < items.length - 1)
 | 
			
		||||
                            }
 | 
			
		||||
                            show={<StrategySeparator text='AND' />}
 | 
			
		||||
                        />
 | 
			
		||||
                        {item}
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,7 @@ interface IConstraintItemProps {
 | 
			
		||||
    text: string;
 | 
			
		||||
    input?: string | number | boolean | 'no value';
 | 
			
		||||
    showReason?: boolean;
 | 
			
		||||
    disabled?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const StyledDivContainer = styled('div', {
 | 
			
		||||
@ -34,12 +35,15 @@ const StyledChip = styled(Chip)(({ theme }) => ({
 | 
			
		||||
    margin: theme.spacing(0.5),
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
const StyledParagraph = styled('p')(({ theme }) => ({
 | 
			
		||||
const StyledParagraph = styled('p', {
 | 
			
		||||
    shouldForwardProp: (prop) => prop !== 'disabled',
 | 
			
		||||
})<{ disabled: boolean }>(({ theme, disabled }) => ({
 | 
			
		||||
    display: 'inline',
 | 
			
		||||
    margin: theme.spacing(0.5, 0),
 | 
			
		||||
    maxWidth: '95%',
 | 
			
		||||
    textAlign: 'center',
 | 
			
		||||
    wordBreak: 'break-word',
 | 
			
		||||
    color: disabled ? theme.palette.text.secondary : 'inherit',
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
export const PlaygroundParameterItem = ({
 | 
			
		||||
@ -47,10 +51,11 @@ export const PlaygroundParameterItem = ({
 | 
			
		||||
    text,
 | 
			
		||||
    input,
 | 
			
		||||
    showReason = false,
 | 
			
		||||
    disabled = false,
 | 
			
		||||
}: IConstraintItemProps) => {
 | 
			
		||||
    const theme = useTheme();
 | 
			
		||||
 | 
			
		||||
    const color = input === 'no value' ? 'error' : 'neutral';
 | 
			
		||||
    const color = input === 'no value' && !disabled ? 'error' : 'neutral';
 | 
			
		||||
    const reason = `value does not match any ${text}`;
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
@ -64,7 +69,11 @@ export const PlaygroundParameterItem = ({
 | 
			
		||||
                    show={
 | 
			
		||||
                        <Typography
 | 
			
		||||
                            variant='subtitle1'
 | 
			
		||||
                            color={theme.palette.error.main}
 | 
			
		||||
                            color={
 | 
			
		||||
                                disabled
 | 
			
		||||
                                    ? theme.palette.text.secondary
 | 
			
		||||
                                    : theme.palette.error.main
 | 
			
		||||
                            }
 | 
			
		||||
                        >
 | 
			
		||||
                            {reason}
 | 
			
		||||
                        </Typography>
 | 
			
		||||
@ -75,7 +84,7 @@ export const PlaygroundParameterItem = ({
 | 
			
		||||
                    show={<p>No {text}s added yet.</p>}
 | 
			
		||||
                    elseShow={
 | 
			
		||||
                        <div>
 | 
			
		||||
                            <StyledParagraph>
 | 
			
		||||
                            <StyledParagraph disabled={disabled}>
 | 
			
		||||
                                {value.length}{' '}
 | 
			
		||||
                                {value.length > 1 ? `${text}s` : text} will get
 | 
			
		||||
                                access.
 | 
			
		||||
@ -83,6 +92,7 @@ export const PlaygroundParameterItem = ({
 | 
			
		||||
                            {value.map((v: string | number) => (
 | 
			
		||||
                                <StyledChip
 | 
			
		||||
                                    key={v}
 | 
			
		||||
                                    disabled={disabled}
 | 
			
		||||
                                    label={
 | 
			
		||||
                                        <StringTruncator
 | 
			
		||||
                                            maxWidth='300'
 | 
			
		||||
@ -98,7 +108,9 @@ export const PlaygroundParameterItem = ({
 | 
			
		||||
            </StyledDivColumn>
 | 
			
		||||
            <ConditionallyRender
 | 
			
		||||
                condition={Boolean(showReason)}
 | 
			
		||||
                show={<CancelOutlined color={'error'} />}
 | 
			
		||||
                show={
 | 
			
		||||
                    <CancelOutlined color={disabled ? 'disabled' : 'error'} />
 | 
			
		||||
                }
 | 
			
		||||
                elseShow={<div />}
 | 
			
		||||
            />
 | 
			
		||||
        </StyledDivContainer>
 | 
			
		||||
 | 
			
		||||
@ -29,6 +29,7 @@ export const SegmentExecutionWithoutResult: VFC<
 | 
			
		||||
                            />
 | 
			
		||||
                        }
 | 
			
		||||
                        isExpanded
 | 
			
		||||
                        disabled
 | 
			
		||||
                    />
 | 
			
		||||
                    <ConditionallyRender
 | 
			
		||||
                        condition={
 | 
			
		||||
 | 
			
		||||
@ -71,7 +71,12 @@ export const StrategyExecution: VFC<IStrategyExecutionProps> = ({
 | 
			
		||||
                // biome-ignore lint/suspicious/noArrayIndexKey: <explanation>
 | 
			
		||||
                <Fragment key={index}>
 | 
			
		||||
                    <ConditionallyRender
 | 
			
		||||
                        condition={index > 0}
 | 
			
		||||
                        condition={
 | 
			
		||||
                            index > 0 &&
 | 
			
		||||
                            (strategyResult.name === 'flexibleRollout'
 | 
			
		||||
                                ? index < items.length
 | 
			
		||||
                                : index < items.length - 1)
 | 
			
		||||
                        }
 | 
			
		||||
                        show={<StrategySeparator text='AND' />}
 | 
			
		||||
                    />
 | 
			
		||||
                    {item}
 | 
			
		||||
 | 
			
		||||
@ -2,24 +2,34 @@ import {
 | 
			
		||||
    parseParameterNumber,
 | 
			
		||||
    parseParameterStrings,
 | 
			
		||||
} from 'utils/parseParameter';
 | 
			
		||||
import { Box } from '@mui/material';
 | 
			
		||||
import { Box, styled } from '@mui/material';
 | 
			
		||||
import PercentageCircle from 'component/common/PercentageCircle/PercentageCircle';
 | 
			
		||||
import { PlaygroundParameterItem } from '../PlaygroundParameterItem/PlaygroundParameterItem';
 | 
			
		||||
import { StyledBoxSummary } from '../StrategyExecution.styles';
 | 
			
		||||
import { PlaygroundConstraintSchema, PlaygroundRequestSchema } from 'openapi';
 | 
			
		||||
import { getMappedParam } from '../helpers';
 | 
			
		||||
import { Badge } from 'component/common/Badge/Badge';
 | 
			
		||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
 | 
			
		||||
import DisabledPercentageCircle from 'component/common/PercentageCircle/DisabledPercentageCircle';
 | 
			
		||||
 | 
			
		||||
export interface PlaygroundResultStrategyExecutionParametersProps {
 | 
			
		||||
    parameters: { [key: string]: string };
 | 
			
		||||
    constraints: PlaygroundConstraintSchema[];
 | 
			
		||||
    input?: PlaygroundRequestSchema;
 | 
			
		||||
    disabled?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const StyledText = styled('div', {
 | 
			
		||||
    shouldForwardProp: (prop) => prop !== 'disabled',
 | 
			
		||||
})<{ disabled: boolean }>(({ theme, disabled }) => ({
 | 
			
		||||
    color: disabled ? theme.palette.text.secondary : theme.palette.neutral.main,
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
export const PlaygroundResultStrategyExecutionParameters = ({
 | 
			
		||||
    parameters,
 | 
			
		||||
    constraints,
 | 
			
		||||
    input,
 | 
			
		||||
    disabled = false,
 | 
			
		||||
}: PlaygroundResultStrategyExecutionParametersProps) => {
 | 
			
		||||
    return (
 | 
			
		||||
        <>
 | 
			
		||||
@ -35,20 +45,44 @@ export const PlaygroundResultStrategyExecutionParameters = ({
 | 
			
		||||
                                key={key}
 | 
			
		||||
                                sx={{ display: 'flex', alignItems: 'center' }}
 | 
			
		||||
                            >
 | 
			
		||||
                                <Box sx={{ mr: '1rem' }}>
 | 
			
		||||
                                    <PercentageCircle
 | 
			
		||||
                                        percentage={percentage}
 | 
			
		||||
                                        size='2rem'
 | 
			
		||||
                                <Box
 | 
			
		||||
                                    sx={(theme) => ({
 | 
			
		||||
                                        mr: '1rem',
 | 
			
		||||
                                        color: disabled
 | 
			
		||||
                                            ? theme.palette.neutral.border
 | 
			
		||||
                                            : theme.palette.text.secondary,
 | 
			
		||||
                                    })}
 | 
			
		||||
                                >
 | 
			
		||||
                                    <ConditionallyRender
 | 
			
		||||
                                        condition={disabled}
 | 
			
		||||
                                        show={
 | 
			
		||||
                                            <DisabledPercentageCircle
 | 
			
		||||
                                                percentage={percentage}
 | 
			
		||||
                                                size='2rem'
 | 
			
		||||
                                            />
 | 
			
		||||
                                        }
 | 
			
		||||
                                        elseShow={
 | 
			
		||||
                                            <PercentageCircle
 | 
			
		||||
                                                percentage={percentage}
 | 
			
		||||
                                                size='2rem'
 | 
			
		||||
                                            />
 | 
			
		||||
                                        }
 | 
			
		||||
                                    />
 | 
			
		||||
                                </Box>
 | 
			
		||||
                                <div>
 | 
			
		||||
                                    <Badge color='success'>{percentage}%</Badge>{' '}
 | 
			
		||||
                                <StyledText disabled={disabled}>
 | 
			
		||||
                                    <Badge
 | 
			
		||||
                                        color={
 | 
			
		||||
                                            disabled ? 'disabled' : 'success'
 | 
			
		||||
                                        }
 | 
			
		||||
                                    >
 | 
			
		||||
                                        {percentage}%
 | 
			
		||||
                                    </Badge>{' '}
 | 
			
		||||
                                    of your base{' '}
 | 
			
		||||
                                    {constraints.length > 0
 | 
			
		||||
                                        ? 'who match constraints'
 | 
			
		||||
                                        : ''}{' '}
 | 
			
		||||
                                    is included.
 | 
			
		||||
                                </div>
 | 
			
		||||
                                </StyledText>
 | 
			
		||||
                            </StyledBoxSummary>
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
@ -87,6 +121,7 @@ export const PlaygroundResultStrategyExecutionParameters = ({
 | 
			
		||||
                                text={'host'}
 | 
			
		||||
                                input={'no value'}
 | 
			
		||||
                                showReason={undefined}
 | 
			
		||||
                                disabled={disabled}
 | 
			
		||||
                            />
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
@ -97,6 +132,7 @@ export const PlaygroundResultStrategyExecutionParameters = ({
 | 
			
		||||
                                key={key}
 | 
			
		||||
                                value={IPs}
 | 
			
		||||
                                text={'IP'}
 | 
			
		||||
                                disabled={disabled}
 | 
			
		||||
                                input={
 | 
			
		||||
                                    input?.context?.[getMappedParam(key)]
 | 
			
		||||
                                        ? input?.context?.[getMappedParam(key)]
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user