mirror of
https://github.com/Unleash/unleash.git
synced 2025-08-04 13:48:56 +02: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;
|
onEdit?: () => void;
|
||||||
sx?: SxProps<Theme>;
|
sx?: SxProps<Theme>;
|
||||||
compact?: boolean;
|
compact?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
renderAfter?: JSX.Element;
|
renderAfter?: JSX.Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,6 +69,7 @@ export const ConstraintAccordionView = ({
|
|||||||
onDelete,
|
onDelete,
|
||||||
sx = undefined,
|
sx = undefined,
|
||||||
compact = false,
|
compact = false,
|
||||||
|
disabled = false,
|
||||||
renderAfter,
|
renderAfter,
|
||||||
}: IConstraintAccordionViewProps) => {
|
}: IConstraintAccordionViewProps) => {
|
||||||
const [expandable, setExpandable] = useState(true);
|
const [expandable, setExpandable] = useState(true);
|
||||||
@ -102,6 +104,7 @@ export const ConstraintAccordionView = ({
|
|||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
singleValue={singleValue}
|
singleValue={singleValue}
|
||||||
allowExpand={setExpandable}
|
allowExpand={setExpandable}
|
||||||
|
disabled={disabled}
|
||||||
expanded={expanded}
|
expanded={expanded}
|
||||||
compact={compact}
|
compact={compact}
|
||||||
/>
|
/>
|
||||||
|
@ -13,6 +13,7 @@ interface IConstraintAccordionViewHeaderProps {
|
|||||||
expanded: boolean;
|
expanded: boolean;
|
||||||
allowExpand: (shouldExpand: boolean) => void;
|
allowExpand: (shouldExpand: boolean) => void;
|
||||||
compact?: boolean;
|
compact?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const StyledContainer = styled('div')(({ theme }) => ({
|
const StyledContainer = styled('div')(({ theme }) => ({
|
||||||
@ -34,6 +35,7 @@ export const ConstraintAccordionViewHeader = ({
|
|||||||
allowExpand,
|
allowExpand,
|
||||||
expanded,
|
expanded,
|
||||||
compact,
|
compact,
|
||||||
|
disabled,
|
||||||
}: IConstraintAccordionViewHeaderProps) => {
|
}: IConstraintAccordionViewHeaderProps) => {
|
||||||
const { context } = useUnleashContext();
|
const { context } = useUnleashContext();
|
||||||
const { contextName } = constraint;
|
const { contextName } = constraint;
|
||||||
@ -44,12 +46,13 @@ export const ConstraintAccordionViewHeader = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
<ConstraintIcon compact={compact} />
|
<ConstraintIcon compact={compact} disabled={disabled} />
|
||||||
<ConstraintAccordionViewHeaderInfo
|
<ConstraintAccordionViewHeaderInfo
|
||||||
constraint={constraint}
|
constraint={constraint}
|
||||||
singleValue={singleValue}
|
singleValue={singleValue}
|
||||||
allowExpand={allowExpand}
|
allowExpand={allowExpand}
|
||||||
expanded={expanded}
|
expanded={expanded}
|
||||||
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
<ConstraintAccordionHeaderActions
|
<ConstraintAccordionHeaderActions
|
||||||
onEdit={onEdit}
|
onEdit={onEdit}
|
||||||
|
@ -50,6 +50,7 @@ interface ConstraintAccordionViewHeaderMetaInfoProps {
|
|||||||
singleValue: boolean;
|
singleValue: boolean;
|
||||||
expanded: boolean;
|
expanded: boolean;
|
||||||
allowExpand: (shouldExpand: boolean) => void;
|
allowExpand: (shouldExpand: boolean) => void;
|
||||||
|
disabled?: boolean;
|
||||||
maxLength?: number;
|
maxLength?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,23 +59,34 @@ export const ConstraintAccordionViewHeaderInfo = ({
|
|||||||
singleValue,
|
singleValue,
|
||||||
allowExpand,
|
allowExpand,
|
||||||
expanded,
|
expanded,
|
||||||
|
disabled = false,
|
||||||
maxLength = 112, //The max number of characters in the values text for NOT allowing expansion
|
maxLength = 112, //The max number of characters in the values text for NOT allowing expansion
|
||||||
}: ConstraintAccordionViewHeaderMetaInfoProps) => {
|
}: ConstraintAccordionViewHeaderMetaInfoProps) => {
|
||||||
return (
|
return (
|
||||||
<StyledHeaderWrapper>
|
<StyledHeaderWrapper>
|
||||||
<StyledHeaderMetaInfo>
|
<StyledHeaderMetaInfo>
|
||||||
<Tooltip title={constraint.contextName} arrow>
|
<Tooltip title={constraint.contextName} arrow>
|
||||||
<StyledHeaderText>
|
<StyledHeaderText
|
||||||
|
sx={(theme) => ({
|
||||||
|
color: disabled
|
||||||
|
? theme.palette.text.secondary
|
||||||
|
: 'inherit',
|
||||||
|
})}
|
||||||
|
>
|
||||||
{constraint.contextName}
|
{constraint.contextName}
|
||||||
</StyledHeaderText>
|
</StyledHeaderText>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<ConstraintViewHeaderOperator constraint={constraint} />
|
<ConstraintViewHeaderOperator
|
||||||
|
constraint={constraint}
|
||||||
|
disabled={disabled}
|
||||||
|
/>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={singleValue}
|
condition={singleValue}
|
||||||
show={
|
show={
|
||||||
<ConstraintAccordionViewHeaderSingleValue
|
<ConstraintAccordionViewHeaderSingleValue
|
||||||
constraint={constraint}
|
constraint={constraint}
|
||||||
allowExpand={allowExpand}
|
allowExpand={allowExpand}
|
||||||
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
elseShow={
|
elseShow={
|
||||||
@ -83,6 +95,7 @@ export const ConstraintAccordionViewHeaderInfo = ({
|
|||||||
expanded={expanded}
|
expanded={expanded}
|
||||||
allowExpand={allowExpand}
|
allowExpand={allowExpand}
|
||||||
maxLength={maxLength}
|
maxLength={maxLength}
|
||||||
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -22,6 +22,7 @@ interface ConstraintSingleValueProps {
|
|||||||
expanded: boolean;
|
expanded: boolean;
|
||||||
maxLength: number;
|
maxLength: number;
|
||||||
allowExpand: (shouldExpand: boolean) => void;
|
allowExpand: (shouldExpand: boolean) => void;
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const StyledHeaderValuesContainerWrapper = styled('div')(({ theme }) => ({
|
const StyledHeaderValuesContainerWrapper = styled('div')(({ theme }) => ({
|
||||||
@ -55,6 +56,7 @@ export const ConstraintAccordionViewHeaderMultipleValues = ({
|
|||||||
expanded,
|
expanded,
|
||||||
allowExpand,
|
allowExpand,
|
||||||
maxLength,
|
maxLength,
|
||||||
|
disabled = false,
|
||||||
}: ConstraintSingleValueProps) => {
|
}: ConstraintSingleValueProps) => {
|
||||||
const [expandable, setExpandable] = useState(false);
|
const [expandable, setExpandable] = useState(false);
|
||||||
|
|
||||||
@ -72,7 +74,15 @@ export const ConstraintAccordionViewHeaderMultipleValues = ({
|
|||||||
return (
|
return (
|
||||||
<StyledHeaderValuesContainerWrapper>
|
<StyledHeaderValuesContainerWrapper>
|
||||||
<StyledHeaderValuesContainer>
|
<StyledHeaderValuesContainer>
|
||||||
<StyledValuesSpan>{text}</StyledValuesSpan>
|
<StyledValuesSpan
|
||||||
|
sx={(theme) => ({
|
||||||
|
color: disabled
|
||||||
|
? theme.palette.text.secondary
|
||||||
|
: 'inherit',
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
{text}
|
||||||
|
</StyledValuesSpan>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={expandable}
|
condition={expandable}
|
||||||
show={
|
show={
|
||||||
|
@ -15,6 +15,7 @@ const StyledSingleValueChip = styled(Chip)(({ theme }) => ({
|
|||||||
interface ConstraintSingleValueProps {
|
interface ConstraintSingleValueProps {
|
||||||
constraint: IConstraint;
|
constraint: IConstraint;
|
||||||
allowExpand: (shouldExpand: boolean) => void;
|
allowExpand: (shouldExpand: boolean) => void;
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const StyledHeaderValuesContainerWrapper = styled('div')(({ theme }) => ({
|
const StyledHeaderValuesContainerWrapper = styled('div')(({ theme }) => ({
|
||||||
@ -26,6 +27,7 @@ const StyledHeaderValuesContainerWrapper = styled('div')(({ theme }) => ({
|
|||||||
export const ConstraintAccordionViewHeaderSingleValue = ({
|
export const ConstraintAccordionViewHeaderSingleValue = ({
|
||||||
constraint,
|
constraint,
|
||||||
allowExpand,
|
allowExpand,
|
||||||
|
disabled = false,
|
||||||
}: ConstraintSingleValueProps) => {
|
}: ConstraintSingleValueProps) => {
|
||||||
const { locationSettings } = useLocationSettings();
|
const { locationSettings } = useLocationSettings();
|
||||||
|
|
||||||
@ -36,6 +38,9 @@ export const ConstraintAccordionViewHeaderSingleValue = ({
|
|||||||
return (
|
return (
|
||||||
<StyledHeaderValuesContainerWrapper>
|
<StyledHeaderValuesContainerWrapper>
|
||||||
<StyledSingleValueChip
|
<StyledSingleValueChip
|
||||||
|
sx={(theme) => ({
|
||||||
|
color: disabled ? theme.palette.text.secondary : 'inherit',
|
||||||
|
})}
|
||||||
label={formatConstraintValue(constraint, locationSettings)}
|
label={formatConstraintValue(constraint, locationSettings)}
|
||||||
/>
|
/>
|
||||||
</StyledHeaderValuesContainerWrapper>
|
</StyledHeaderValuesContainerWrapper>
|
||||||
|
@ -10,6 +10,7 @@ import { oneOf } from 'utils/oneOf';
|
|||||||
|
|
||||||
interface ConstraintViewHeaderOperatorProps {
|
interface ConstraintViewHeaderOperatorProps {
|
||||||
constraint: IConstraint;
|
constraint: IConstraint;
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const StyledHeaderValuesContainerWrapper = styled('div')(({ theme }) => ({
|
const StyledHeaderValuesContainerWrapper = styled('div')(({ theme }) => ({
|
||||||
@ -28,6 +29,7 @@ const StyledHeaderConstraintContainer = styled('div')(({ theme }) => ({
|
|||||||
|
|
||||||
export const ConstraintViewHeaderOperator = ({
|
export const ConstraintViewHeaderOperator = ({
|
||||||
constraint,
|
constraint,
|
||||||
|
disabled = false,
|
||||||
}: ConstraintViewHeaderOperatorProps) => {
|
}: ConstraintViewHeaderOperatorProps) => {
|
||||||
return (
|
return (
|
||||||
<StyledHeaderValuesContainerWrapper>
|
<StyledHeaderValuesContainerWrapper>
|
||||||
@ -47,6 +49,7 @@ export const ConstraintViewHeaderOperator = ({
|
|||||||
<ConstraintOperator
|
<ConstraintOperator
|
||||||
constraint={constraint}
|
constraint={constraint}
|
||||||
hasPrefix={Boolean(constraint.inverted)}
|
hasPrefix={Boolean(constraint.inverted)}
|
||||||
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
</StyledHeaderConstraintContainer>
|
</StyledHeaderConstraintContainer>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
|
@ -4,18 +4,24 @@ import { TrackChanges } from '@mui/icons-material';
|
|||||||
|
|
||||||
interface IConstraintIconProps {
|
interface IConstraintIconProps {
|
||||||
compact?: boolean;
|
compact?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ConstraintIcon: VFC<IConstraintIconProps> = ({ compact }) => (
|
export const ConstraintIcon: VFC<IConstraintIconProps> = ({
|
||||||
|
compact,
|
||||||
|
disabled,
|
||||||
|
}) => (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={(theme) => ({
|
||||||
backgroundColor: 'primary.light',
|
backgroundColor: disabled
|
||||||
|
? theme.palette.neutral.border
|
||||||
|
: 'primary.light',
|
||||||
p: compact ? '1px' : '2px',
|
p: compact ? '1px' : '2px',
|
||||||
borderRadius: '50%',
|
borderRadius: '50%',
|
||||||
width: compact ? '18px' : '24px',
|
width: compact ? '18px' : '24px',
|
||||||
height: compact ? '18px' : '24px',
|
height: compact ? '18px' : '24px',
|
||||||
marginRight: '13px',
|
marginRight: '13px',
|
||||||
}}
|
})}
|
||||||
>
|
>
|
||||||
<TrackChanges
|
<TrackChanges
|
||||||
sx={(theme) => ({
|
sx={(theme) => ({
|
||||||
|
@ -6,6 +6,7 @@ import { styled } from '@mui/material';
|
|||||||
interface IConstraintOperatorProps {
|
interface IConstraintOperatorProps {
|
||||||
constraint: IConstraint;
|
constraint: IConstraint;
|
||||||
hasPrefix?: boolean;
|
hasPrefix?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const StyledContainer = styled('div')(({ theme }) => ({
|
const StyledContainer = styled('div')(({ theme }) => ({
|
||||||
@ -15,19 +16,25 @@ const StyledContainer = styled('div')(({ theme }) => ({
|
|||||||
lineHeight: 1.25,
|
lineHeight: 1.25,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledName = styled('div')(({ theme }) => ({
|
const StyledName = styled('div', {
|
||||||
|
shouldForwardProp: (prop) => prop !== 'disabled',
|
||||||
|
})<{ disabled: boolean }>(({ theme, disabled }) => ({
|
||||||
fontSize: theme.fontSizes.smallBody,
|
fontSize: theme.fontSizes.smallBody,
|
||||||
lineHeight: 17 / 14,
|
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,
|
fontSize: theme.fontSizes.smallerBody,
|
||||||
color: theme.palette.neutral.main,
|
color: disabled ? theme.palette.text.secondary : theme.palette.neutral.main,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const ConstraintOperator = ({
|
export const ConstraintOperator = ({
|
||||||
constraint,
|
constraint,
|
||||||
hasPrefix,
|
hasPrefix,
|
||||||
|
disabled = false,
|
||||||
}: IConstraintOperatorProps) => {
|
}: IConstraintOperatorProps) => {
|
||||||
const operatorName = constraint.operator;
|
const operatorName = constraint.operator;
|
||||||
const operatorText = formatOperatorDescription(constraint.operator);
|
const operatorText = formatOperatorDescription(constraint.operator);
|
||||||
@ -40,8 +47,8 @@ export const ConstraintOperator = ({
|
|||||||
paddingLeft: hasPrefix ? 0 : undefined,
|
paddingLeft: hasPrefix ? 0 : undefined,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<StyledName>{operatorName}</StyledName>
|
<StyledName disabled={disabled}>{operatorName}</StyledName>
|
||||||
<StyledText>{operatorText}</StyledText>
|
<StyledText disabled={disabled}>{operatorText}</StyledText>
|
||||||
</StyledContainer>
|
</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 {
|
interface ISegmentItemProps {
|
||||||
segment: Partial<ISegment>;
|
segment: Partial<ISegment>;
|
||||||
isExpanded?: boolean;
|
isExpanded?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
constraintList?: JSX.Element;
|
constraintList?: JSX.Element;
|
||||||
headerContent?: JSX.Element;
|
headerContent?: JSX.Element;
|
||||||
}
|
}
|
||||||
@ -49,20 +50,33 @@ const StyledLink = styled(Link)(({ theme }) => ({
|
|||||||
textDecoration: 'underline',
|
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> = ({
|
export const SegmentItem: VFC<ISegmentItemProps> = ({
|
||||||
segment,
|
segment,
|
||||||
isExpanded,
|
isExpanded,
|
||||||
headerContent,
|
headerContent,
|
||||||
constraintList,
|
constraintList,
|
||||||
|
disabled = false,
|
||||||
}) => {
|
}) => {
|
||||||
const [isOpen, setIsOpen] = useState(isExpanded || false);
|
const [isOpen, setIsOpen] = useState(isExpanded || false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledAccordion expanded={isOpen}>
|
<StyledAccordion expanded={isOpen}>
|
||||||
<StyledAccordionSummary id={`segment-accordion-${segment.id}`}>
|
<StyledAccordionSummary id={`segment-accordion-${segment.id}`}>
|
||||||
<DonutLarge color='secondary' sx={{ mr: 1 }} />
|
<DonutLarge
|
||||||
<span>Segment:</span>
|
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}`}>
|
<StyledLink to={`/segments/edit/${segment.id}`}>
|
||||||
{segment.name}
|
{segment.name}
|
||||||
</StyledLink>
|
</StyledLink>
|
||||||
|
@ -9,8 +9,6 @@ import { ConditionallyRender } from 'component/common/ConditionallyRender/Condit
|
|||||||
import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator';
|
import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator';
|
||||||
import { styled } from '@mui/material';
|
import { styled } from '@mui/material';
|
||||||
import { ConstraintAccordionView } from 'component/common/ConstraintAccordion/ConstraintAccordionView/ConstraintAccordionView';
|
import { ConstraintAccordionView } from 'component/common/ConstraintAccordion/ConstraintAccordionView/ConstraintAccordionView';
|
||||||
import { ConstraintError } from './ConstraintError/ConstraintError';
|
|
||||||
import { ConstraintOk } from './ConstraintOk/ConstraintOk';
|
|
||||||
|
|
||||||
interface IConstraintExecutionWithoutResultsProps {
|
interface IConstraintExecutionWithoutResultsProps {
|
||||||
constraints?: PlaygroundConstraintSchema[];
|
constraints?: PlaygroundConstraintSchema[];
|
||||||
@ -35,7 +33,11 @@ export const ConstraintExecutionWithoutResults: VFC<
|
|||||||
condition={index > 0}
|
condition={index > 0}
|
||||||
show={<StrategySeparator text='AND' />}
|
show={<StrategySeparator text='AND' />}
|
||||||
/>
|
/>
|
||||||
<ConstraintAccordionView constraint={constraint} compact />
|
<ConstraintAccordionView
|
||||||
|
constraint={constraint}
|
||||||
|
compact
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
))}
|
))}
|
||||||
</ConstraintExecutionWrapper>
|
</ConstraintExecutionWrapper>
|
||||||
|
@ -52,6 +52,7 @@ export const DisabledStrategyExecution: VFC<IDisabledStrategyExecutionProps> =
|
|||||||
parameters={parameters}
|
parameters={parameters}
|
||||||
constraints={constraints}
|
constraints={constraints}
|
||||||
input={input}
|
input={input}
|
||||||
|
disabled
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
hasCustomStrategyParameters && (
|
hasCustomStrategyParameters && (
|
||||||
@ -61,9 +62,14 @@ export const DisabledStrategyExecution: VFC<IDisabledStrategyExecutionProps> =
|
|||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
name === 'default' && (
|
name === 'default' && (
|
||||||
<StyledBoxSummary sx={{ width: '100%' }}>
|
<StyledBoxSummary
|
||||||
The standard strategy is <Badge color='success'>ON</Badge>{' '}
|
sx={(theme) => ({
|
||||||
for all users.
|
width: '100%',
|
||||||
|
color: theme.palette.text.secondary,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
The standard strategy is{' '}
|
||||||
|
<Badge color={'disabled'}>ON</Badge> for all users.
|
||||||
</StyledBoxSummary>
|
</StyledBoxSummary>
|
||||||
),
|
),
|
||||||
].filter(Boolean);
|
].filter(Boolean);
|
||||||
@ -74,7 +80,12 @@ export const DisabledStrategyExecution: VFC<IDisabledStrategyExecutionProps> =
|
|||||||
// biome-ignore lint/suspicious/noArrayIndexKey: <explanation>
|
// biome-ignore lint/suspicious/noArrayIndexKey: <explanation>
|
||||||
<Fragment key={index}>
|
<Fragment key={index}>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={index > 0}
|
condition={
|
||||||
|
index > 0 &&
|
||||||
|
(strategyResult.name === 'flexibleRollout'
|
||||||
|
? index < items.length
|
||||||
|
: index < items.length - 1)
|
||||||
|
}
|
||||||
show={<StrategySeparator text='AND' />}
|
show={<StrategySeparator text='AND' />}
|
||||||
/>
|
/>
|
||||||
{item}
|
{item}
|
||||||
|
@ -8,6 +8,7 @@ interface IConstraintItemProps {
|
|||||||
text: string;
|
text: string;
|
||||||
input?: string | number | boolean | 'no value';
|
input?: string | number | boolean | 'no value';
|
||||||
showReason?: boolean;
|
showReason?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const StyledDivContainer = styled('div', {
|
const StyledDivContainer = styled('div', {
|
||||||
@ -34,12 +35,15 @@ const StyledChip = styled(Chip)(({ theme }) => ({
|
|||||||
margin: theme.spacing(0.5),
|
margin: theme.spacing(0.5),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledParagraph = styled('p')(({ theme }) => ({
|
const StyledParagraph = styled('p', {
|
||||||
|
shouldForwardProp: (prop) => prop !== 'disabled',
|
||||||
|
})<{ disabled: boolean }>(({ theme, disabled }) => ({
|
||||||
display: 'inline',
|
display: 'inline',
|
||||||
margin: theme.spacing(0.5, 0),
|
margin: theme.spacing(0.5, 0),
|
||||||
maxWidth: '95%',
|
maxWidth: '95%',
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
wordBreak: 'break-word',
|
wordBreak: 'break-word',
|
||||||
|
color: disabled ? theme.palette.text.secondary : 'inherit',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const PlaygroundParameterItem = ({
|
export const PlaygroundParameterItem = ({
|
||||||
@ -47,10 +51,11 @@ export const PlaygroundParameterItem = ({
|
|||||||
text,
|
text,
|
||||||
input,
|
input,
|
||||||
showReason = false,
|
showReason = false,
|
||||||
|
disabled = false,
|
||||||
}: IConstraintItemProps) => {
|
}: IConstraintItemProps) => {
|
||||||
const theme = useTheme();
|
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}`;
|
const reason = `value does not match any ${text}`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -64,7 +69,11 @@ export const PlaygroundParameterItem = ({
|
|||||||
show={
|
show={
|
||||||
<Typography
|
<Typography
|
||||||
variant='subtitle1'
|
variant='subtitle1'
|
||||||
color={theme.palette.error.main}
|
color={
|
||||||
|
disabled
|
||||||
|
? theme.palette.text.secondary
|
||||||
|
: theme.palette.error.main
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{reason}
|
{reason}
|
||||||
</Typography>
|
</Typography>
|
||||||
@ -75,7 +84,7 @@ export const PlaygroundParameterItem = ({
|
|||||||
show={<p>No {text}s added yet.</p>}
|
show={<p>No {text}s added yet.</p>}
|
||||||
elseShow={
|
elseShow={
|
||||||
<div>
|
<div>
|
||||||
<StyledParagraph>
|
<StyledParagraph disabled={disabled}>
|
||||||
{value.length}{' '}
|
{value.length}{' '}
|
||||||
{value.length > 1 ? `${text}s` : text} will get
|
{value.length > 1 ? `${text}s` : text} will get
|
||||||
access.
|
access.
|
||||||
@ -83,6 +92,7 @@ export const PlaygroundParameterItem = ({
|
|||||||
{value.map((v: string | number) => (
|
{value.map((v: string | number) => (
|
||||||
<StyledChip
|
<StyledChip
|
||||||
key={v}
|
key={v}
|
||||||
|
disabled={disabled}
|
||||||
label={
|
label={
|
||||||
<StringTruncator
|
<StringTruncator
|
||||||
maxWidth='300'
|
maxWidth='300'
|
||||||
@ -98,7 +108,9 @@ export const PlaygroundParameterItem = ({
|
|||||||
</StyledDivColumn>
|
</StyledDivColumn>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={Boolean(showReason)}
|
condition={Boolean(showReason)}
|
||||||
show={<CancelOutlined color={'error'} />}
|
show={
|
||||||
|
<CancelOutlined color={disabled ? 'disabled' : 'error'} />
|
||||||
|
}
|
||||||
elseShow={<div />}
|
elseShow={<div />}
|
||||||
/>
|
/>
|
||||||
</StyledDivContainer>
|
</StyledDivContainer>
|
||||||
|
@ -29,6 +29,7 @@ export const SegmentExecutionWithoutResult: VFC<
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
isExpanded
|
isExpanded
|
||||||
|
disabled
|
||||||
/>
|
/>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={
|
condition={
|
||||||
|
@ -71,7 +71,12 @@ export const StrategyExecution: VFC<IStrategyExecutionProps> = ({
|
|||||||
// biome-ignore lint/suspicious/noArrayIndexKey: <explanation>
|
// biome-ignore lint/suspicious/noArrayIndexKey: <explanation>
|
||||||
<Fragment key={index}>
|
<Fragment key={index}>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={index > 0}
|
condition={
|
||||||
|
index > 0 &&
|
||||||
|
(strategyResult.name === 'flexibleRollout'
|
||||||
|
? index < items.length
|
||||||
|
: index < items.length - 1)
|
||||||
|
}
|
||||||
show={<StrategySeparator text='AND' />}
|
show={<StrategySeparator text='AND' />}
|
||||||
/>
|
/>
|
||||||
{item}
|
{item}
|
||||||
|
@ -2,24 +2,34 @@ import {
|
|||||||
parseParameterNumber,
|
parseParameterNumber,
|
||||||
parseParameterStrings,
|
parseParameterStrings,
|
||||||
} from 'utils/parseParameter';
|
} from 'utils/parseParameter';
|
||||||
import { Box } from '@mui/material';
|
import { Box, styled } from '@mui/material';
|
||||||
import PercentageCircle from 'component/common/PercentageCircle/PercentageCircle';
|
import PercentageCircle from 'component/common/PercentageCircle/PercentageCircle';
|
||||||
import { PlaygroundParameterItem } from '../PlaygroundParameterItem/PlaygroundParameterItem';
|
import { PlaygroundParameterItem } from '../PlaygroundParameterItem/PlaygroundParameterItem';
|
||||||
import { StyledBoxSummary } from '../StrategyExecution.styles';
|
import { StyledBoxSummary } from '../StrategyExecution.styles';
|
||||||
import { PlaygroundConstraintSchema, PlaygroundRequestSchema } from 'openapi';
|
import { PlaygroundConstraintSchema, PlaygroundRequestSchema } from 'openapi';
|
||||||
import { getMappedParam } from '../helpers';
|
import { getMappedParam } from '../helpers';
|
||||||
import { Badge } from 'component/common/Badge/Badge';
|
import { Badge } from 'component/common/Badge/Badge';
|
||||||
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
|
import DisabledPercentageCircle from 'component/common/PercentageCircle/DisabledPercentageCircle';
|
||||||
|
|
||||||
export interface PlaygroundResultStrategyExecutionParametersProps {
|
export interface PlaygroundResultStrategyExecutionParametersProps {
|
||||||
parameters: { [key: string]: string };
|
parameters: { [key: string]: string };
|
||||||
constraints: PlaygroundConstraintSchema[];
|
constraints: PlaygroundConstraintSchema[];
|
||||||
input?: PlaygroundRequestSchema;
|
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 = ({
|
export const PlaygroundResultStrategyExecutionParameters = ({
|
||||||
parameters,
|
parameters,
|
||||||
constraints,
|
constraints,
|
||||||
input,
|
input,
|
||||||
|
disabled = false,
|
||||||
}: PlaygroundResultStrategyExecutionParametersProps) => {
|
}: PlaygroundResultStrategyExecutionParametersProps) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -35,20 +45,44 @@ export const PlaygroundResultStrategyExecutionParameters = ({
|
|||||||
key={key}
|
key={key}
|
||||||
sx={{ display: 'flex', alignItems: 'center' }}
|
sx={{ display: 'flex', alignItems: 'center' }}
|
||||||
>
|
>
|
||||||
<Box sx={{ mr: '1rem' }}>
|
<Box
|
||||||
<PercentageCircle
|
sx={(theme) => ({
|
||||||
percentage={percentage}
|
mr: '1rem',
|
||||||
size='2rem'
|
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>
|
</Box>
|
||||||
<div>
|
<StyledText disabled={disabled}>
|
||||||
<Badge color='success'>{percentage}%</Badge>{' '}
|
<Badge
|
||||||
|
color={
|
||||||
|
disabled ? 'disabled' : 'success'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{percentage}%
|
||||||
|
</Badge>{' '}
|
||||||
of your base{' '}
|
of your base{' '}
|
||||||
{constraints.length > 0
|
{constraints.length > 0
|
||||||
? 'who match constraints'
|
? 'who match constraints'
|
||||||
: ''}{' '}
|
: ''}{' '}
|
||||||
is included.
|
is included.
|
||||||
</div>
|
</StyledText>
|
||||||
</StyledBoxSummary>
|
</StyledBoxSummary>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -87,6 +121,7 @@ export const PlaygroundResultStrategyExecutionParameters = ({
|
|||||||
text={'host'}
|
text={'host'}
|
||||||
input={'no value'}
|
input={'no value'}
|
||||||
showReason={undefined}
|
showReason={undefined}
|
||||||
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -97,6 +132,7 @@ export const PlaygroundResultStrategyExecutionParameters = ({
|
|||||||
key={key}
|
key={key}
|
||||||
value={IPs}
|
value={IPs}
|
||||||
text={'IP'}
|
text={'IP'}
|
||||||
|
disabled={disabled}
|
||||||
input={
|
input={
|
||||||
input?.context?.[getMappedParam(key)]
|
input?.context?.[getMappedParam(key)]
|
||||||
? input?.context?.[getMappedParam(key)]
|
? input?.context?.[getMappedParam(key)]
|
||||||
|
Loading…
Reference in New Issue
Block a user