mirror of
https://github.com/Unleash/unleash.git
synced 2025-02-23 00:22:19 +01:00
improvements
This commit is contained in:
parent
76b33cdd11
commit
787c5f317c
@ -5,6 +5,7 @@ import {
|
|||||||
AccordionDetails,
|
AccordionDetails,
|
||||||
SxProps,
|
SxProps,
|
||||||
Theme,
|
Theme,
|
||||||
|
useTheme,
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { IConstraint } from 'interfaces/strategy';
|
import { IConstraint } from 'interfaces/strategy';
|
||||||
import { ConstraintAccordionViewBody } from './ConstraintAccordionViewBody/ConstraintAccordionViewBody';
|
import { ConstraintAccordionViewBody } from './ConstraintAccordionViewBody/ConstraintAccordionViewBody';
|
||||||
@ -17,12 +18,12 @@ import {
|
|||||||
} from 'constants/operators';
|
} from 'constants/operators';
|
||||||
import { useStyles } from '../ConstraintAccordion.styles';
|
import { useStyles } from '../ConstraintAccordion.styles';
|
||||||
import {
|
import {
|
||||||
PlaygroundFeatureStrategyConstraintResult,
|
PlaygroundConstraintSchema,
|
||||||
PlaygroundRequestSchema,
|
PlaygroundRequestSchema,
|
||||||
} from '../../../../hooks/api/actions/usePlayground/playground.model';
|
} from '../../../../hooks/api/actions/usePlayground/playground.model';
|
||||||
|
|
||||||
interface IConstraintAccordionViewProps {
|
interface IConstraintAccordionViewProps {
|
||||||
constraint: IConstraint | PlaygroundFeatureStrategyConstraintResult;
|
constraint: IConstraint | PlaygroundConstraintSchema;
|
||||||
onDelete?: () => void;
|
onDelete?: () => void;
|
||||||
onEdit?: () => void;
|
onEdit?: () => void;
|
||||||
playgroundInput?: PlaygroundRequestSchema;
|
playgroundInput?: PlaygroundRequestSchema;
|
||||||
@ -41,6 +42,7 @@ export const ConstraintAccordionView = ({
|
|||||||
const { classes: styles } = useStyles();
|
const { classes: styles } = useStyles();
|
||||||
const [expandable, setExpandable] = useState(true);
|
const [expandable, setExpandable] = useState(true);
|
||||||
const [expanded, setExpanded] = useState(false);
|
const [expanded, setExpanded] = useState(false);
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
const singleValue = oneOf(
|
const singleValue = oneOf(
|
||||||
[...semVerOperators, ...numOperators, ...dateOperators],
|
[...semVerOperators, ...numOperators, ...dateOperators],
|
||||||
@ -51,6 +53,11 @@ export const ConstraintAccordionView = ({
|
|||||||
setExpanded(!expanded);
|
setExpanded(!expanded);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const backgroundColor = Boolean(playgroundInput)
|
||||||
|
? !Boolean((constraint as PlaygroundConstraintSchema).result)
|
||||||
|
? theme.palette.neutral.light
|
||||||
|
: 'inherit'
|
||||||
|
: 'inherit';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Accordion
|
<Accordion
|
||||||
@ -68,6 +75,7 @@ export const ConstraintAccordionView = ({
|
|||||||
'&:hover': {
|
'&:hover': {
|
||||||
cursor: expandable ? 'pointer' : 'default!important',
|
cursor: expandable ? 'pointer' : 'default!important',
|
||||||
},
|
},
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ConstraintAccordionViewHeader
|
<ConstraintAccordionViewHeader
|
||||||
|
@ -23,17 +23,28 @@ export const PlaygroundResultFeatureDetails = ({
|
|||||||
const { classes: styles } = useStyles();
|
const { classes: styles } = useStyles();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const description = feature.isEnabled
|
console.log(feature);
|
||||||
|
|
||||||
|
const description =
|
||||||
|
feature.isEnabled === 'unevaluated'
|
||||||
|
? `This feature toggle is Unevaluated in ${input?.environment} because `
|
||||||
|
: feature.isEnabled
|
||||||
? `This feature toggle is True in ${input?.environment} because `
|
? `This feature toggle is True in ${input?.environment} because `
|
||||||
: `This feature toggle is False in ${input?.environment} because `;
|
: `This feature toggle is False in ${input?.environment} because `;
|
||||||
|
|
||||||
const reason = feature.isEnabled
|
const reason =
|
||||||
|
feature.isEnabled === 'unevaluated'
|
||||||
|
? 'custom strategies are not evaluated yet'
|
||||||
|
: feature.isEnabled
|
||||||
? 'at least one strategy is True'
|
? 'at least one strategy is True'
|
||||||
: feature?.isEnabledInCurrentEnvironment
|
: feature?.isEnabledInCurrentEnvironment
|
||||||
? 'the environment is disabled'
|
? 'the environment is disabled'
|
||||||
: 'all strategies are False';
|
: 'all strategies are False';
|
||||||
|
|
||||||
const color = feature.isEnabled
|
const color =
|
||||||
|
feature.isEnabled === 'unevaluated'
|
||||||
|
? theme.palette.warning.main
|
||||||
|
: feature.isEnabled
|
||||||
? theme.palette.success.main
|
? theme.palette.success.main
|
||||||
: theme.palette.error.main;
|
: theme.palette.error.main;
|
||||||
|
|
||||||
@ -56,7 +67,19 @@ export const PlaygroundResultFeatureDetails = ({
|
|||||||
{feature.name}
|
{feature.name}
|
||||||
</Typography>
|
</Typography>
|
||||||
<span>
|
<span>
|
||||||
<PlaygroundResultChip enabled={feature.isEnabled} />
|
<PlaygroundResultChip
|
||||||
|
enabled={
|
||||||
|
feature.isEnabled === 'unevaluated'
|
||||||
|
? 'unknown'
|
||||||
|
: feature.isEnabled
|
||||||
|
}
|
||||||
|
label={String(feature.isEnabled)}
|
||||||
|
size={
|
||||||
|
feature.isEnabled === 'unevaluated'
|
||||||
|
? 'large'
|
||||||
|
: 'default'
|
||||||
|
}
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<IconButton onClick={onCloseClick} className={styles.icon}>
|
<IconButton onClick={onCloseClick} className={styles.icon}>
|
||||||
|
@ -12,6 +12,10 @@ export const useStyles = makeStyles()(theme => ({
|
|||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
gap: theme.spacing(2),
|
gap: theme.spacing(2),
|
||||||
},
|
},
|
||||||
|
disabled: {
|
||||||
|
backgroundColor: theme.palette.neutral.light,
|
||||||
|
opacity: '90%',
|
||||||
|
},
|
||||||
chip: {
|
chip: {
|
||||||
margin: '0.25rem',
|
margin: '0.25rem',
|
||||||
},
|
},
|
||||||
|
@ -3,6 +3,7 @@ import { ConditionallyRender } from 'component/common/ConditionallyRender/Condit
|
|||||||
import { useStyles } from './PlaygroundConstraintItem.styles';
|
import { useStyles } from './PlaygroundConstraintItem.styles';
|
||||||
import StringTruncator from 'component/common/StringTruncator/StringTruncator';
|
import StringTruncator from 'component/common/StringTruncator/StringTruncator';
|
||||||
import { CancelOutlined } from '@mui/icons-material';
|
import { CancelOutlined } from '@mui/icons-material';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
|
||||||
interface IConstraintItemProps {
|
interface IConstraintItemProps {
|
||||||
value: string[];
|
value: string[];
|
||||||
@ -23,10 +24,13 @@ export const PlaygroundConstraintItem = ({
|
|||||||
const color = input === 'no value' ? 'error' : 'neutral';
|
const color = input === 'no value' ? 'error' : 'neutral';
|
||||||
const reason = `value does not match any ${text}`;
|
const reason = `value does not match any ${text}`;
|
||||||
|
|
||||||
console.log(value, text, input, showReason);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div
|
||||||
|
className={classnames(
|
||||||
|
styles.container,
|
||||||
|
showReason ? styles.disabled : ''
|
||||||
|
)}
|
||||||
|
>
|
||||||
<Typography variant="subtitle1" color={theme.palette[color].main}>
|
<Typography variant="subtitle1" color={theme.palette[color].main}>
|
||||||
{input}
|
{input}
|
||||||
</Typography>
|
</Typography>
|
||||||
@ -72,6 +76,7 @@ export const PlaygroundConstraintItem = ({
|
|||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={Boolean(showReason)}
|
condition={Boolean(showReason)}
|
||||||
show={<CancelOutlined color={'error'} />}
|
show={<CancelOutlined color={'error'} />}
|
||||||
|
elseShow={<div />}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -40,12 +40,13 @@ export const PlaygroundResultFeatureStrategyItem = ({
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const Icon = getFeatureStrategyIcon(strategy.name);
|
const Icon = getFeatureStrategyIcon(strategy.name);
|
||||||
const label =
|
const label =
|
||||||
result.evaluationStatus !== 'complete'
|
result.evaluationStatus === 'incomplete'
|
||||||
? 'Unevaluated'
|
? 'Unknown'
|
||||||
: result.enabled
|
: result.enabled
|
||||||
? 'True'
|
? 'True'
|
||||||
: 'False';
|
: 'False';
|
||||||
const border = result.enabled
|
const border =
|
||||||
|
result.enabled && result.evaluationStatus === 'complete'
|
||||||
? `1px solid ${theme.palette.success.main}`
|
? `1px solid ${theme.palette.success.main}`
|
||||||
: `1px solid ${theme.palette.divider}`;
|
: `1px solid ${theme.palette.divider}`;
|
||||||
|
|
||||||
@ -77,6 +78,11 @@ export const PlaygroundResultFeatureStrategyItem = ({
|
|||||||
showIcon={false}
|
showIcon={false}
|
||||||
enabled={result.enabled}
|
enabled={result.enabled}
|
||||||
label={label}
|
label={label}
|
||||||
|
size={
|
||||||
|
result.evaluationStatus === 'incomplete'
|
||||||
|
? 'medium'
|
||||||
|
: 'default'
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.body}>
|
<div className={styles.body}>
|
||||||
|
@ -6,14 +6,16 @@ import { ReactComponent as FeatureEnabledIcon } from '../../../../../assets/icon
|
|||||||
import { ReactComponent as FeatureDisabledIcon } from '../../../../../assets/icons/isenabled-false.svg';
|
import { ReactComponent as FeatureDisabledIcon } from '../../../../../assets/icons/isenabled-false.svg';
|
||||||
|
|
||||||
interface IResultChipProps {
|
interface IResultChipProps {
|
||||||
enabled: boolean | 'unevaluated';
|
enabled: boolean | 'unknown';
|
||||||
// Result icon - defaults to true
|
// Result icon - defaults to true
|
||||||
showIcon?: boolean;
|
showIcon?: boolean;
|
||||||
label?: string;
|
label?: string;
|
||||||
|
size?: 'default' | 'medium' | 'large';
|
||||||
}
|
}
|
||||||
|
|
||||||
export const StyledChip = styled(Chip)(({ theme }) => ({
|
export const StyledChip = styled(Chip)<{ width?: number }>(
|
||||||
width: 60,
|
({ theme, width }) => ({
|
||||||
|
width: width ?? 60,
|
||||||
height: 24,
|
height: 24,
|
||||||
borderRadius: theme.shape.borderRadius,
|
borderRadius: theme.shape.borderRadius,
|
||||||
fontWeight: theme.typography.fontWeightMedium,
|
fontWeight: theme.typography.fontWeightMedium,
|
||||||
@ -21,7 +23,8 @@ export const StyledChip = styled(Chip)(({ theme }) => ({
|
|||||||
padding: 0,
|
padding: 0,
|
||||||
paddingLeft: theme.spacing(0.5),
|
paddingLeft: theme.spacing(0.5),
|
||||||
},
|
},
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
export const StyledFalseChip = styled(StyledChip)(({ theme }) => ({
|
export const StyledFalseChip = styled(StyledChip)(({ theme }) => ({
|
||||||
border: `1px solid ${theme.palette.error.main}`,
|
border: `1px solid ${theme.palette.error.main}`,
|
||||||
@ -45,15 +48,27 @@ export const StyledTrueChip = styled(StyledChip)(({ theme }) => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
export const StyledUnknownChip = styled(StyledChip)(({ theme }) => ({
|
||||||
|
border: `1px solid ${theme.palette.warning.main}`,
|
||||||
|
backgroundColor: colors.orange['100'],
|
||||||
|
['& .MuiChip-label']: {
|
||||||
|
color: theme.palette.warning.main,
|
||||||
|
},
|
||||||
|
['& .MuiChip-icon']: {
|
||||||
|
color: theme.palette.warning.main,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
export const PlaygroundResultChip = ({
|
export const PlaygroundResultChip = ({
|
||||||
enabled,
|
enabled,
|
||||||
showIcon = true,
|
showIcon = true,
|
||||||
label,
|
label,
|
||||||
|
size = 'default',
|
||||||
}: IResultChipProps) => {
|
}: IResultChipProps) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const icon = (
|
const icon = (
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={Boolean(enabled)}
|
condition={enabled !== 'unknown' && enabled}
|
||||||
show={
|
show={
|
||||||
<FeatureEnabledIcon
|
<FeatureEnabledIcon
|
||||||
color={theme.palette.success.main}
|
color={theme.palette.success.main}
|
||||||
@ -71,19 +86,41 @@ export const PlaygroundResultChip = ({
|
|||||||
|
|
||||||
const defaultLabel = enabled ? 'True' : 'False';
|
const defaultLabel = enabled ? 'True' : 'False';
|
||||||
|
|
||||||
|
let chipWidth = 60;
|
||||||
|
if (size === 'medium') {
|
||||||
|
chipWidth = 72;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size === 'large') {
|
||||||
|
chipWidth = 100;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={Boolean(enabled)}
|
condition={enabled !== 'unknown' && enabled}
|
||||||
show={
|
show={
|
||||||
<StyledTrueChip
|
<StyledTrueChip
|
||||||
icon={showIcon ? icon : undefined}
|
icon={showIcon ? icon : undefined}
|
||||||
label={label || defaultLabel}
|
label={label || defaultLabel}
|
||||||
|
width={chipWidth}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
elseShow={
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={enabled === 'unknown'}
|
||||||
|
show={
|
||||||
|
<StyledUnknownChip
|
||||||
|
label={label || 'Unknown'}
|
||||||
|
width={chipWidth}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
elseShow={
|
elseShow={
|
||||||
<StyledFalseChip
|
<StyledFalseChip
|
||||||
icon={showIcon ? icon : undefined}
|
icon={showIcon ? icon : undefined}
|
||||||
label={label || defaultLabel}
|
label={label || defaultLabel}
|
||||||
|
width={chipWidth}
|
||||||
|
/>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
Loading…
Reference in New Issue
Block a user