mirror of
https://github.com/Unleash/unleash.git
synced 2025-05-26 01:17:00 +02:00
chore(1-3422): playground strategies list (#9504)
Initial rough work on adapting the playground strategies to the new designs. This PR primarily splits components into Legacy files and adds new replacements. There are *some* updates (including spacing and text color), but nothing juicy yet. However, I wanted to get this in now, before this PR grows even bigger.
This commit is contained in:
parent
9547fd962f
commit
a064672635
@ -1,7 +1,8 @@
|
||||
import { screen } from '@testing-library/react';
|
||||
import { render } from 'utils/testRenderer';
|
||||
import { FeatureDetails } from './FeatureDetails';
|
||||
import { FeatureDetails as LegacyFeatureDetails } from './LegacyFeatureDetails';
|
||||
import type { PlaygroundFeatureSchema, PlaygroundRequestSchema } from 'openapi';
|
||||
import { FeatureDetails } from './FeatureDetails';
|
||||
|
||||
const testCases = [
|
||||
{
|
||||
@ -10,7 +11,7 @@ const testCases = [
|
||||
hasUnsatisfiedDependency: true,
|
||||
isEnabledInCurrentEnvironment: false,
|
||||
} as PlaygroundFeatureSchema,
|
||||
expectedText1: 'This feature flag is False in development because',
|
||||
expectedText1: /This feature flag is False in development because/,
|
||||
expectedText2:
|
||||
'parent dependency is not satisfied and the environment is disabled',
|
||||
},
|
||||
@ -20,7 +21,7 @@ const testCases = [
|
||||
hasUnsatisfiedDependency: true,
|
||||
isEnabledInCurrentEnvironment: true,
|
||||
} as PlaygroundFeatureSchema,
|
||||
expectedText1: 'This feature flag is False in development because',
|
||||
expectedText1: /This feature flag is False in development because/,
|
||||
expectedText2: 'parent dependency is not satisfied',
|
||||
},
|
||||
{
|
||||
@ -29,7 +30,7 @@ const testCases = [
|
||||
hasUnsatisfiedDependency: false,
|
||||
isEnabledInCurrentEnvironment: false,
|
||||
} as PlaygroundFeatureSchema,
|
||||
expectedText1: 'This feature flag is False in development because',
|
||||
expectedText1: /This feature flag is False in development because/,
|
||||
expectedText2: 'the environment is disabled',
|
||||
},
|
||||
{
|
||||
@ -37,7 +38,7 @@ const testCases = [
|
||||
feature: {
|
||||
isEnabled: true,
|
||||
} as PlaygroundFeatureSchema,
|
||||
expectedText1: 'This feature flag is True in development because',
|
||||
expectedText1: /This feature flag is True in development because/,
|
||||
expectedText2: 'at least one strategy is True',
|
||||
},
|
||||
{
|
||||
@ -48,7 +49,7 @@ const testCases = [
|
||||
data: [{ name: 'custom' }],
|
||||
},
|
||||
} as PlaygroundFeatureSchema,
|
||||
expectedText1: 'This feature flag is Unknown in development because',
|
||||
expectedText1: /This feature flag is Unknown in development because/,
|
||||
expectedText2: 'no strategies could be fully evaluated',
|
||||
},
|
||||
{
|
||||
@ -59,7 +60,7 @@ const testCases = [
|
||||
data: [{ name: 'custom' }, { name: 'default' }],
|
||||
},
|
||||
} as PlaygroundFeatureSchema,
|
||||
expectedText1: 'This feature flag is Unknown in development because',
|
||||
expectedText1: /This feature flag is Unknown in development because/,
|
||||
expectedText2: 'not all strategies could be fully evaluated',
|
||||
},
|
||||
{
|
||||
@ -70,12 +71,29 @@ const testCases = [
|
||||
data: [{ name: 'default' }],
|
||||
},
|
||||
} as PlaygroundFeatureSchema,
|
||||
expectedText1: 'This feature flag is False in development because',
|
||||
expectedText1: /This feature flag is False in development because/,
|
||||
expectedText2:
|
||||
'all strategies are either False or could not be fully evaluated',
|
||||
},
|
||||
];
|
||||
|
||||
testCases.forEach(({ name, feature, expectedText1, expectedText2 }) => {
|
||||
test(`${name} (legacy)`, async () => {
|
||||
render(
|
||||
<LegacyFeatureDetails
|
||||
feature={feature}
|
||||
input={
|
||||
{ environment: 'development' } as PlaygroundRequestSchema
|
||||
}
|
||||
onClose={() => {}}
|
||||
/>,
|
||||
);
|
||||
|
||||
await screen.findByText(expectedText1);
|
||||
await screen.findByText(expectedText2);
|
||||
});
|
||||
});
|
||||
|
||||
testCases.forEach(({ name, feature, expectedText1, expectedText2 }) => {
|
||||
test(name, async () => {
|
||||
render(
|
||||
|
@ -1,45 +1,32 @@
|
||||
import type { PlaygroundFeatureSchema, PlaygroundRequestSchema } from 'openapi';
|
||||
import { Alert, IconButton, Typography, useTheme, styled } from '@mui/material';
|
||||
import { Alert, Typography, useTheme, styled, IconButton } from '@mui/material';
|
||||
import { PlaygroundResultChip } from '../../PlaygroundResultChip/PlaygroundResultChip';
|
||||
import CloseOutlined from '@mui/icons-material/CloseOutlined';
|
||||
import type React from 'react';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import {
|
||||
checkForEmptyValues,
|
||||
hasCustomStrategies,
|
||||
hasOnlyCustomStrategies,
|
||||
} from './helpers';
|
||||
|
||||
const StyledDivWrapper = styled('div')({
|
||||
const HeaderRow = styled('div')({
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
width: '100%',
|
||||
});
|
||||
|
||||
const StyledDivTitleRow = styled('div')(({ theme }) => ({
|
||||
const HeaderGroup = styled('hgroup')(({ theme }) => ({
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
gap: theme.spacing(1.5),
|
||||
marginTop: theme.spacing(1.5),
|
||||
}));
|
||||
|
||||
const StyledDivAlertRow = styled('div')(({ theme }) => ({
|
||||
margin: theme.spacing(1, 0),
|
||||
const StyledTypographyName = styled('h3')(({ theme }) => ({
|
||||
fontWeight: 'bold',
|
||||
fontSize: theme.typography.subtitle1.fontSize,
|
||||
margin: 0,
|
||||
}));
|
||||
|
||||
const StyledDivDescriptionRow = styled('div')(({ theme }) => ({
|
||||
margin: theme.spacing(1, 0.5),
|
||||
}));
|
||||
|
||||
const StyledTypographyName = styled(Typography)(({ theme }) => ({
|
||||
fontWeight: 600,
|
||||
padding: theme.spacing(0.5),
|
||||
}));
|
||||
|
||||
const StyledIconButton = styled(IconButton)({
|
||||
textAlign: 'right',
|
||||
});
|
||||
|
||||
interface PlaygroundFeatureResultDetailsProps {
|
||||
feature: PlaygroundFeatureSchema;
|
||||
input?: PlaygroundRequestSchema;
|
||||
@ -57,7 +44,7 @@ export const FeatureDetails = ({
|
||||
return [
|
||||
`This feature flag is True in ${input?.environment} because `,
|
||||
'at least one strategy is True',
|
||||
theme.palette.success.main,
|
||||
theme.palette.success.contrastText,
|
||||
];
|
||||
|
||||
if (
|
||||
@ -67,7 +54,7 @@ export const FeatureDetails = ({
|
||||
return [
|
||||
`This feature flag is False in ${input?.environment} because `,
|
||||
'parent dependency is not satisfied and the environment is disabled',
|
||||
theme.palette.error.main,
|
||||
theme.palette.error.contrastText,
|
||||
];
|
||||
}
|
||||
|
||||
@ -75,35 +62,35 @@ export const FeatureDetails = ({
|
||||
return [
|
||||
`This feature flag is False in ${input?.environment} because `,
|
||||
'the environment is disabled',
|
||||
theme.palette.error.main,
|
||||
theme.palette.error.contrastText,
|
||||
];
|
||||
|
||||
if (hasOnlyCustomStrategies(feature))
|
||||
return [
|
||||
`This feature flag is Unknown in ${input?.environment} because `,
|
||||
'no strategies could be fully evaluated',
|
||||
theme.palette.warning.main,
|
||||
theme.palette.warning.contrastText,
|
||||
];
|
||||
|
||||
if (hasCustomStrategies(feature))
|
||||
return [
|
||||
`This feature flag is Unknown in ${input?.environment} because `,
|
||||
'not all strategies could be fully evaluated',
|
||||
theme.palette.warning.main,
|
||||
theme.palette.warning.contrastText,
|
||||
];
|
||||
|
||||
if (feature.hasUnsatisfiedDependency) {
|
||||
return [
|
||||
`This feature flag is False in ${input?.environment} because `,
|
||||
'parent dependency is not satisfied',
|
||||
theme.palette.error.main,
|
||||
theme.palette.error.contrastText,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
`This feature flag is False in ${input?.environment} because `,
|
||||
'all strategies are either False or could not be fully evaluated',
|
||||
theme.palette.error.main,
|
||||
theme.palette.error.contrastText,
|
||||
];
|
||||
})();
|
||||
|
||||
@ -124,61 +111,43 @@ export const FeatureDetails = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
<StyledDivWrapper>
|
||||
<StyledDivTitleRow>
|
||||
<StyledTypographyName variant={'subtitle1'}>
|
||||
{feature.name}
|
||||
</StyledTypographyName>
|
||||
<ConditionallyRender
|
||||
condition={feature?.strategies?.result !== 'unknown'}
|
||||
show={() => (
|
||||
<HeaderRow>
|
||||
<HeaderGroup>
|
||||
<StyledTypographyName>{feature.name}</StyledTypographyName>
|
||||
<p>
|
||||
{feature?.strategies?.result !== 'unknown' ? (
|
||||
<PlaygroundResultChip
|
||||
tabindex={-1}
|
||||
enabled={feature.isEnabled}
|
||||
label={feature.isEnabled ? 'True' : 'False'}
|
||||
/>
|
||||
)}
|
||||
elseShow={() => (
|
||||
) : (
|
||||
<PlaygroundResultChip
|
||||
tabindex={-1}
|
||||
enabled='unknown'
|
||||
label={'Unknown'}
|
||||
showIcon={false}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</StyledDivTitleRow>
|
||||
<StyledIconButton onClick={onCloseClick}>
|
||||
</p>
|
||||
</HeaderGroup>
|
||||
<IconButton aria-label='Close' onClick={onCloseClick}>
|
||||
<CloseOutlined />
|
||||
</StyledIconButton>
|
||||
</StyledDivWrapper>
|
||||
<StyledDivDescriptionRow>
|
||||
<Typography variant='body1' component='span'>
|
||||
{description}
|
||||
</Typography>
|
||||
<Typography variant='subtitle1' color={color} component='span'>
|
||||
</IconButton>
|
||||
</HeaderRow>
|
||||
<p>
|
||||
{description}
|
||||
<Typography color={color} component='span'>
|
||||
{reason}
|
||||
</Typography>
|
||||
<Typography variant='body1' component='span'>
|
||||
.
|
||||
</Typography>
|
||||
</StyledDivDescriptionRow>
|
||||
<ConditionallyRender
|
||||
condition={Boolean(noValueTxt)}
|
||||
show={
|
||||
<StyledDivAlertRow>
|
||||
<Alert color={'info'}>{noValueTxt}</Alert>
|
||||
</StyledDivAlertRow>
|
||||
}
|
||||
/>
|
||||
<ConditionallyRender
|
||||
condition={Boolean(customStrategiesTxt)}
|
||||
show={
|
||||
<StyledDivAlertRow>
|
||||
<Alert severity='warning' color='info'>
|
||||
{customStrategiesTxt}
|
||||
</Alert>
|
||||
</StyledDivAlertRow>
|
||||
}
|
||||
/>
|
||||
.
|
||||
</p>
|
||||
{noValueTxt ? <Alert color={'info'}>{noValueTxt}</Alert> : null}
|
||||
{customStrategiesTxt ? (
|
||||
<Alert severity='warning' color='info'>
|
||||
{customStrategiesTxt}
|
||||
</Alert>
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -0,0 +1,184 @@
|
||||
import type { PlaygroundFeatureSchema, PlaygroundRequestSchema } from 'openapi';
|
||||
import { Alert, IconButton, Typography, useTheme, styled } from '@mui/material';
|
||||
import { PlaygroundResultChip } from '../../PlaygroundResultChip/PlaygroundResultChip';
|
||||
import CloseOutlined from '@mui/icons-material/CloseOutlined';
|
||||
import type React from 'react';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import {
|
||||
checkForEmptyValues,
|
||||
hasCustomStrategies,
|
||||
hasOnlyCustomStrategies,
|
||||
} from './helpers';
|
||||
|
||||
const StyledDivWrapper = styled('div')({
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
width: '100%',
|
||||
});
|
||||
|
||||
const StyledDivTitleRow = styled('div')(({ theme }) => ({
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
gap: theme.spacing(1.5),
|
||||
marginTop: theme.spacing(1.5),
|
||||
}));
|
||||
|
||||
const StyledDivAlertRow = styled('div')(({ theme }) => ({
|
||||
margin: theme.spacing(1, 0),
|
||||
}));
|
||||
|
||||
const StyledDivDescriptionRow = styled('div')(({ theme }) => ({
|
||||
margin: theme.spacing(1, 0.5),
|
||||
}));
|
||||
|
||||
const StyledTypographyName = styled(Typography)(({ theme }) => ({
|
||||
fontWeight: 600,
|
||||
padding: theme.spacing(0.5),
|
||||
}));
|
||||
|
||||
const StyledIconButton = styled(IconButton)({
|
||||
textAlign: 'right',
|
||||
});
|
||||
|
||||
interface PlaygroundFeatureResultDetailsProps {
|
||||
feature: PlaygroundFeatureSchema;
|
||||
input?: PlaygroundRequestSchema;
|
||||
onClose: () => void;
|
||||
}
|
||||
export const FeatureDetails = ({
|
||||
feature,
|
||||
input,
|
||||
onClose,
|
||||
}: PlaygroundFeatureResultDetailsProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const [description, reason, color] = (() => {
|
||||
if (feature.isEnabled)
|
||||
return [
|
||||
`This feature flag is True in ${input?.environment} because `,
|
||||
'at least one strategy is True',
|
||||
theme.palette.success.main,
|
||||
];
|
||||
|
||||
if (
|
||||
feature.hasUnsatisfiedDependency &&
|
||||
!feature.isEnabledInCurrentEnvironment
|
||||
) {
|
||||
return [
|
||||
`This feature flag is False in ${input?.environment} because `,
|
||||
'parent dependency is not satisfied and the environment is disabled',
|
||||
theme.palette.error.main,
|
||||
];
|
||||
}
|
||||
|
||||
if (!feature.isEnabledInCurrentEnvironment)
|
||||
return [
|
||||
`This feature flag is False in ${input?.environment} because `,
|
||||
'the environment is disabled',
|
||||
theme.palette.error.main,
|
||||
];
|
||||
|
||||
if (hasOnlyCustomStrategies(feature))
|
||||
return [
|
||||
`This feature flag is Unknown in ${input?.environment} because `,
|
||||
'no strategies could be fully evaluated',
|
||||
theme.palette.warning.main,
|
||||
];
|
||||
|
||||
if (hasCustomStrategies(feature))
|
||||
return [
|
||||
`This feature flag is Unknown in ${input?.environment} because `,
|
||||
'not all strategies could be fully evaluated',
|
||||
theme.palette.warning.main,
|
||||
];
|
||||
|
||||
if (feature.hasUnsatisfiedDependency) {
|
||||
return [
|
||||
`This feature flag is False in ${input?.environment} because `,
|
||||
'parent dependency is not satisfied',
|
||||
theme.palette.error.main,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
`This feature flag is False in ${input?.environment} because `,
|
||||
'all strategies are either False or could not be fully evaluated',
|
||||
theme.palette.error.main,
|
||||
];
|
||||
})();
|
||||
|
||||
const noValueTxt = checkForEmptyValues(input?.context)
|
||||
? 'You did not provide a value for your context field in step 2 of the configuration'
|
||||
: undefined;
|
||||
|
||||
const customStrategiesTxt = hasCustomStrategies(feature)
|
||||
? `This feature uses custom strategies. Custom strategies can't be evaluated, so they will be marked accordingly.`
|
||||
: undefined;
|
||||
|
||||
const onCloseClick =
|
||||
onClose &&
|
||||
((event: React.SyntheticEvent) => {
|
||||
event.stopPropagation();
|
||||
onClose();
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<StyledDivWrapper>
|
||||
<StyledDivTitleRow>
|
||||
<StyledTypographyName variant={'subtitle1'}>
|
||||
{feature.name}
|
||||
</StyledTypographyName>
|
||||
<ConditionallyRender
|
||||
condition={feature?.strategies?.result !== 'unknown'}
|
||||
show={() => (
|
||||
<PlaygroundResultChip
|
||||
enabled={feature.isEnabled}
|
||||
label={feature.isEnabled ? 'True' : 'False'}
|
||||
/>
|
||||
)}
|
||||
elseShow={() => (
|
||||
<PlaygroundResultChip
|
||||
enabled='unknown'
|
||||
label={'Unknown'}
|
||||
showIcon={false}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</StyledDivTitleRow>
|
||||
<StyledIconButton onClick={onCloseClick}>
|
||||
<CloseOutlined />
|
||||
</StyledIconButton>
|
||||
</StyledDivWrapper>
|
||||
<StyledDivDescriptionRow>
|
||||
<Typography variant='body1' component='span'>
|
||||
{description}
|
||||
</Typography>
|
||||
<Typography variant='subtitle1' color={color} component='span'>
|
||||
{reason}
|
||||
</Typography>
|
||||
<Typography variant='body1' component='span'>
|
||||
.
|
||||
</Typography>
|
||||
</StyledDivDescriptionRow>
|
||||
<ConditionallyRender
|
||||
condition={Boolean(noValueTxt)}
|
||||
show={
|
||||
<StyledDivAlertRow>
|
||||
<Alert color={'info'}>{noValueTxt}</Alert>
|
||||
</StyledDivAlertRow>
|
||||
}
|
||||
/>
|
||||
<ConditionallyRender
|
||||
condition={Boolean(customStrategiesTxt)}
|
||||
show={
|
||||
<StyledDivAlertRow>
|
||||
<Alert severity='warning' color='info'>
|
||||
{customStrategiesTxt}
|
||||
</Alert>
|
||||
</StyledDivAlertRow>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
@ -2,8 +2,11 @@ import { useRef, useState } from 'react';
|
||||
import type { PlaygroundFeatureSchema, PlaygroundRequestSchema } from 'openapi';
|
||||
import { IconButton, Popover, styled } from '@mui/material';
|
||||
import InfoOutlined from '@mui/icons-material/InfoOutlined';
|
||||
import { FeatureDetails as LegacyFeatureDetails } from './FeatureDetails/LegacyFeatureDetails';
|
||||
import { PlaygroundResultFeatureStrategyList as LegacyPlaygroundResultFeatureStrategyList } from './FeatureStrategyList/LegacyPlaygroundResultFeatureStrategyList';
|
||||
import { useUiFlag } from 'hooks/useUiFlag';
|
||||
import { FeatureDetails } from './FeatureDetails/FeatureDetails';
|
||||
import { PlaygroundResultFeatureStrategyList } from './FeatureStrategyList/PlaygroundResultFeatureStrategyList';
|
||||
import { PlaygroundResultFeatureStrategyList } from './FeatureStrategyList/PlaygroundResultsFeatureStrategyList';
|
||||
|
||||
interface FeatureResultInfoPopoverCellProps {
|
||||
feature: PlaygroundFeatureSchema;
|
||||
@ -21,6 +24,7 @@ export const FeatureResultInfoPopoverCell = ({
|
||||
}: FeatureResultInfoPopoverCellProps) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const ref = useRef(null);
|
||||
const useNewStrategyDesign = useUiFlag('flagOverviewRedesign');
|
||||
|
||||
const togglePopover = () => {
|
||||
setOpen(!open);
|
||||
@ -43,7 +47,7 @@ export const FeatureResultInfoPopoverCell = ({
|
||||
sx: (theme) => ({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
padding: theme.spacing(6),
|
||||
padding: theme.spacing(useNewStrategyDesign ? 4 : 6),
|
||||
width: 728,
|
||||
maxWidth: '100%',
|
||||
height: 'auto',
|
||||
@ -61,15 +65,31 @@ export const FeatureResultInfoPopoverCell = ({
|
||||
horizontal: 'left',
|
||||
}}
|
||||
>
|
||||
<FeatureDetails
|
||||
feature={feature}
|
||||
input={input}
|
||||
onClose={() => setOpen(false)}
|
||||
/>
|
||||
<PlaygroundResultFeatureStrategyList
|
||||
feature={feature}
|
||||
input={input}
|
||||
/>
|
||||
{useNewStrategyDesign ? (
|
||||
<>
|
||||
<FeatureDetails
|
||||
feature={feature}
|
||||
input={input}
|
||||
onClose={() => setOpen(false)}
|
||||
/>
|
||||
<PlaygroundResultFeatureStrategyList
|
||||
feature={feature}
|
||||
input={input}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<LegacyFeatureDetails
|
||||
feature={feature}
|
||||
input={input}
|
||||
onClose={() => setOpen(false)}
|
||||
/>
|
||||
<LegacyPlaygroundResultFeatureStrategyList
|
||||
feature={feature}
|
||||
input={input}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Popover>
|
||||
</FeatureResultPopoverWrapper>
|
||||
);
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { screen } from '@testing-library/react';
|
||||
import { render } from 'utils/testRenderer';
|
||||
import type { PlaygroundFeatureSchema, PlaygroundRequestSchema } from 'openapi';
|
||||
import { PlaygroundResultFeatureStrategyList } from './PlaygroundResultFeatureStrategyList';
|
||||
import { PlaygroundResultFeatureStrategyList as LegacyPlaygroundResultFeatureStrategyList } from './LegacyPlaygroundResultFeatureStrategyList';
|
||||
import { vi } from 'vitest';
|
||||
import { PlaygroundResultFeatureStrategyList } from './PlaygroundResultsFeatureStrategyList';
|
||||
|
||||
const testCases = [
|
||||
{
|
||||
@ -135,6 +136,21 @@ afterAll(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
testCases.forEach(({ name, feature, expectedText }) => {
|
||||
test(`${name} (legacy)`, async () => {
|
||||
render(
|
||||
<LegacyPlaygroundResultFeatureStrategyList
|
||||
feature={feature}
|
||||
input={
|
||||
{ environment: 'development' } as PlaygroundRequestSchema
|
||||
}
|
||||
/>,
|
||||
);
|
||||
|
||||
await screen.findByText(expectedText);
|
||||
});
|
||||
});
|
||||
|
||||
testCases.forEach(({ name, feature, expectedText }) => {
|
||||
test(name, async () => {
|
||||
render(
|
||||
|
@ -0,0 +1,67 @@
|
||||
import {
|
||||
PlaygroundResultStrategyLists,
|
||||
WrappedPlaygroundResultStrategyList,
|
||||
} from './StrategyList/playgroundResultStrategyLists';
|
||||
import type { PlaygroundFeatureSchema, PlaygroundRequestSchema } from 'openapi';
|
||||
import { Alert } from '@mui/material';
|
||||
|
||||
interface PlaygroundResultFeatureStrategyListProps {
|
||||
feature: PlaygroundFeatureSchema;
|
||||
input?: PlaygroundRequestSchema;
|
||||
}
|
||||
|
||||
export const PlaygroundResultFeatureStrategyList = ({
|
||||
feature,
|
||||
input,
|
||||
}: PlaygroundResultFeatureStrategyListProps) => {
|
||||
const enabledStrategies = feature.strategies?.data?.filter(
|
||||
(strategy) => !strategy.disabled,
|
||||
);
|
||||
const disabledStrategies = feature.strategies?.data?.filter(
|
||||
(strategy) => strategy.disabled,
|
||||
);
|
||||
|
||||
const showDisabledStrategies = disabledStrategies?.length > 0;
|
||||
|
||||
if ((feature?.strategies?.data.length ?? 0) === 0) {
|
||||
return (
|
||||
<Alert severity='warning' sx={{ mt: 2 }}>
|
||||
There are no strategies added to this feature flag in the
|
||||
selected environment.
|
||||
</Alert>
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
(feature.hasUnsatisfiedDependency ||
|
||||
!feature.isEnabledInCurrentEnvironment) &&
|
||||
Boolean(feature?.strategies?.data)
|
||||
) {
|
||||
return (
|
||||
<WrappedPlaygroundResultStrategyList
|
||||
feature={feature}
|
||||
input={input}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<PlaygroundResultStrategyLists
|
||||
strategies={enabledStrategies || []}
|
||||
input={input}
|
||||
titlePrefix={showDisabledStrategies ? 'Enabled' : ''}
|
||||
/>
|
||||
{showDisabledStrategies ? (
|
||||
<PlaygroundResultStrategyLists
|
||||
strategies={disabledStrategies}
|
||||
input={input}
|
||||
titlePrefix={'Disabled'}
|
||||
infoText={
|
||||
'Disabled strategies are not evaluated for the overall result.'
|
||||
}
|
||||
/>
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
};
|
@ -11,12 +11,14 @@ interface IResultChipProps {
|
||||
label: string;
|
||||
// Result icon - defaults to true
|
||||
showIcon?: boolean;
|
||||
tabindex?: number;
|
||||
}
|
||||
|
||||
export const PlaygroundResultChip: VFC<IResultChipProps> = ({
|
||||
enabled,
|
||||
label,
|
||||
showIcon = true,
|
||||
tabindex,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const icon = (
|
||||
@ -28,12 +30,14 @@ export const PlaygroundResultChip: VFC<IResultChipProps> = ({
|
||||
condition={typeof enabled === 'boolean' && Boolean(enabled)}
|
||||
show={
|
||||
<FeatureEnabledIcon
|
||||
aria-hidden
|
||||
color={theme.palette.success.main}
|
||||
strokeWidth='0.25'
|
||||
/>
|
||||
}
|
||||
elseShow={
|
||||
<FeatureDisabledIcon
|
||||
aria-hidden
|
||||
color={theme.palette.error.main}
|
||||
strokeWidth='0.25'
|
||||
/>
|
||||
@ -56,6 +60,7 @@ export const PlaygroundResultChip: VFC<IResultChipProps> = ({
|
||||
condition={typeof enabled === 'boolean' && Boolean(enabled)}
|
||||
show={
|
||||
<Badge
|
||||
tabIndex={tabindex}
|
||||
color='success'
|
||||
icon={showIcon ? icon : undefined}
|
||||
>
|
||||
@ -63,7 +68,11 @@ export const PlaygroundResultChip: VFC<IResultChipProps> = ({
|
||||
</Badge>
|
||||
}
|
||||
elseShow={
|
||||
<Badge color='error' icon={showIcon ? icon : undefined}>
|
||||
<Badge
|
||||
color='error'
|
||||
icon={showIcon ? icon : undefined}
|
||||
tabIndex={tabindex}
|
||||
>
|
||||
{label}
|
||||
</Badge>
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user