mirror of
https://github.com/Unleash/unleash.git
synced 2025-04-19 01:17:18 +02:00
Feat: show disabled strategies in playground (#5081)
Show disabled strategies in separate list Do not show any results in segments/constraints when disabled Closes # [1-1506](https://linear.app/unleash/issue/1-1506/display-disabled-strategies-in-playground-page)  --------- Signed-off-by: andreas-unleash <andreas@getunleash.ai>
This commit is contained in:
parent
ba53d392b2
commit
1335da6366
@ -3,6 +3,7 @@ import { render } from 'utils/testRenderer';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { PlaygroundFeatureSchema, PlaygroundRequestSchema } from 'openapi';
|
import { PlaygroundFeatureSchema, PlaygroundRequestSchema } from 'openapi';
|
||||||
import { PlaygroundResultFeatureStrategyList } from './PlaygroundResultFeatureStrategyList';
|
import { PlaygroundResultFeatureStrategyList } from './PlaygroundResultFeatureStrategyList';
|
||||||
|
import { vi } from 'vitest';
|
||||||
|
|
||||||
const testCases = [
|
const testCases = [
|
||||||
{
|
{
|
||||||
@ -62,8 +63,72 @@ const testCases = [
|
|||||||
expectedText:
|
expectedText:
|
||||||
'If environment was enabled, then this feature toggle would be TRUE with strategies evaluated like so:',
|
'If environment was enabled, then this feature toggle would be TRUE with strategies evaluated like so:',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'Has disabled strategies and is enabled in environment',
|
||||||
|
feature: {
|
||||||
|
strategies: {
|
||||||
|
result: true,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
name: 'default',
|
||||||
|
parameters: {},
|
||||||
|
result: { enabled: true, evaluationStatus: 'complete' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'default',
|
||||||
|
parameters: {},
|
||||||
|
disabled: true,
|
||||||
|
result: {
|
||||||
|
enabled: 'unknown',
|
||||||
|
evaluationStatus: 'unevaluated',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
isEnabledInCurrentEnvironment: true,
|
||||||
|
hasUnsatisfiedDependency: false,
|
||||||
|
} as PlaygroundFeatureSchema,
|
||||||
|
expectedText:
|
||||||
|
'Disabled strategies are not evaluated for the overall result.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Has disabled strategies and is disabled in environment',
|
||||||
|
feature: {
|
||||||
|
strategies: {
|
||||||
|
result: true,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
name: 'default',
|
||||||
|
parameters: {},
|
||||||
|
result: { enabled: true, evaluationStatus: 'complete' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'default',
|
||||||
|
parameters: {},
|
||||||
|
disabled: true,
|
||||||
|
result: {
|
||||||
|
enabled: 'unknown',
|
||||||
|
evaluationStatus: 'unevaluated',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
isEnabledInCurrentEnvironment: false,
|
||||||
|
hasUnsatisfiedDependency: false,
|
||||||
|
} as PlaygroundFeatureSchema,
|
||||||
|
expectedText:
|
||||||
|
'Disabled strategies are not evaluated for the overall result.',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
vi.mock('../../../../../../hooks/useUiFlag', () => ({
|
||||||
|
useUiFlag: vi.fn().mockImplementation(() => true),
|
||||||
|
}));
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
vi.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
testCases.forEach(({ name, feature, expectedText }) => {
|
testCases.forEach(({ name, feature, expectedText }) => {
|
||||||
test(name, async () => {
|
test(name, async () => {
|
||||||
render(
|
render(
|
||||||
|
@ -5,6 +5,7 @@ import {
|
|||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { PlaygroundFeatureSchema, PlaygroundRequestSchema } from 'openapi';
|
import { PlaygroundFeatureSchema, PlaygroundRequestSchema } from 'openapi';
|
||||||
import { Alert } from '@mui/material';
|
import { Alert } from '@mui/material';
|
||||||
|
import { useUiFlag } from '../../../../../../hooks/useUiFlag';
|
||||||
|
|
||||||
interface PlaygroundResultFeatureStrategyListProps {
|
interface PlaygroundResultFeatureStrategyListProps {
|
||||||
feature: PlaygroundFeatureSchema;
|
feature: PlaygroundFeatureSchema;
|
||||||
@ -15,6 +16,17 @@ export const PlaygroundResultFeatureStrategyList = ({
|
|||||||
feature,
|
feature,
|
||||||
input,
|
input,
|
||||||
}: PlaygroundResultFeatureStrategyListProps) => {
|
}: PlaygroundResultFeatureStrategyListProps) => {
|
||||||
|
const playgroundImprovements = useUiFlag('playgroundImprovements');
|
||||||
|
const enabledStrategies = feature.strategies?.data?.filter(
|
||||||
|
(strategy) => !strategy.disabled,
|
||||||
|
);
|
||||||
|
const disabledStrategies = feature.strategies?.data?.filter(
|
||||||
|
(strategy) => strategy.disabled,
|
||||||
|
);
|
||||||
|
|
||||||
|
const showDisabledStrategies =
|
||||||
|
playgroundImprovements && disabledStrategies?.length > 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
@ -39,10 +51,28 @@ export const PlaygroundResultFeatureStrategyList = ({
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
elseShow={
|
elseShow={
|
||||||
|
<>
|
||||||
<PlaygroundResultStrategyLists
|
<PlaygroundResultStrategyLists
|
||||||
strategies={feature?.strategies?.data || []}
|
strategies={enabledStrategies || []}
|
||||||
input={input}
|
input={input}
|
||||||
|
titlePrefix={
|
||||||
|
showDisabledStrategies ? 'Enabled' : ''
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={showDisabledStrategies}
|
||||||
|
show={
|
||||||
|
<PlaygroundResultStrategyLists
|
||||||
|
strategies={disabledStrategies}
|
||||||
|
input={input}
|
||||||
|
titlePrefix={'Disabled'}
|
||||||
|
infoText={
|
||||||
|
'Disabled strategies are not evaluated for the overall result.'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
@ -4,6 +4,8 @@ import { PlaygroundStrategySchema, PlaygroundRequestSchema } from 'openapi';
|
|||||||
import { StrategyExecution } from './StrategyExecution/StrategyExecution';
|
import { StrategyExecution } from './StrategyExecution/StrategyExecution';
|
||||||
import { StrategyItemContainer } from 'component/common/StrategyItemContainer/StrategyItemContainer';
|
import { StrategyItemContainer } from 'component/common/StrategyItemContainer/StrategyItemContainer';
|
||||||
import { objectId } from 'utils/objectId';
|
import { objectId } from 'utils/objectId';
|
||||||
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
|
import { DisabledStrategyExecution } from './StrategyExecution/DisabledStrategyExecution';
|
||||||
|
|
||||||
interface IFeatureStrategyItemProps {
|
interface IFeatureStrategyItemProps {
|
||||||
strategy: PlaygroundStrategySchema;
|
strategy: PlaygroundStrategySchema;
|
||||||
@ -19,7 +21,8 @@ export const FeatureStrategyItem = ({
|
|||||||
const { result } = strategy;
|
const { result } = strategy;
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const label =
|
const label =
|
||||||
result.evaluationStatus === 'incomplete'
|
result.evaluationStatus === 'incomplete' ||
|
||||||
|
result.evaluationStatus === 'unevaluated'
|
||||||
? 'Unevaluated'
|
? 'Unevaluated'
|
||||||
: result.enabled
|
: result.enabled
|
||||||
? 'True'
|
? 'True'
|
||||||
@ -28,7 +31,8 @@ export const FeatureStrategyItem = ({
|
|||||||
return (
|
return (
|
||||||
<StrategyItemContainer
|
<StrategyItemContainer
|
||||||
style={{
|
style={{
|
||||||
borderColor: result.enabled
|
borderColor:
|
||||||
|
result.enabled && result.evaluationStatus === 'complete'
|
||||||
? theme.palette.success.main
|
? theme.palette.success.main
|
||||||
: 'none',
|
: 'none',
|
||||||
}}
|
}}
|
||||||
@ -42,11 +46,22 @@ export const FeatureStrategyItem = ({
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={Boolean(strategy.disabled)}
|
||||||
|
show={
|
||||||
|
<DisabledStrategyExecution
|
||||||
|
strategyResult={strategy}
|
||||||
|
input={input}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
elseShow={
|
||||||
<StrategyExecution
|
<StrategyExecution
|
||||||
strategyResult={strategy}
|
strategyResult={strategy}
|
||||||
input={input}
|
input={input}
|
||||||
percentageFill={theme.palette.background.elevation2}
|
percentageFill={theme.palette.background.elevation2}
|
||||||
/>
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
</StrategyItemContainer>
|
</StrategyItemContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
import { Fragment, VFC } from 'react';
|
||||||
|
import {
|
||||||
|
PlaygroundConstraintSchema,
|
||||||
|
PlaygroundRequestSchema,
|
||||||
|
PlaygroundStrategySchemaResultAnyOfEvaluationStatus,
|
||||||
|
} from 'openapi';
|
||||||
|
import { objectId } from 'utils/objectId';
|
||||||
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
|
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[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ConstraintExecutionWrapper = styled('div')(() => ({
|
||||||
|
width: '100%',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const ConstraintExecutionWithoutResults: VFC<
|
||||||
|
IConstraintExecutionWithoutResultsProps
|
||||||
|
> = ({ constraints }) => {
|
||||||
|
if (!constraints) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ConstraintExecutionWrapper>
|
||||||
|
{constraints?.map((constraint, index) => (
|
||||||
|
<Fragment key={objectId(constraint)}>
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={index > 0}
|
||||||
|
show={<StrategySeparator text='AND' />}
|
||||||
|
/>
|
||||||
|
<ConstraintAccordionView constraint={constraint} compact />
|
||||||
|
</Fragment>
|
||||||
|
))}
|
||||||
|
</ConstraintExecutionWrapper>
|
||||||
|
);
|
||||||
|
};
|
@ -0,0 +1,85 @@
|
|||||||
|
import { Fragment, VFC } from 'react';
|
||||||
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
|
import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator';
|
||||||
|
import { styled } from '@mui/material';
|
||||||
|
import { PlaygroundRequestSchema, PlaygroundStrategySchema } from 'openapi';
|
||||||
|
import { ConstraintExecution } from './ConstraintExecution/ConstraintExecution';
|
||||||
|
import { SegmentExecution } from './SegmentExecution/SegmentExecution';
|
||||||
|
import { PlaygroundResultStrategyExecutionParameters } from './StrategyExecutionParameters/StrategyExecutionParameters';
|
||||||
|
import { CustomStrategyParams } from './CustomStrategyParams/CustomStrategyParams';
|
||||||
|
import { formattedStrategyNames } from 'utils/strategyNames';
|
||||||
|
import { StyledBoxSummary } from './StrategyExecution.styles';
|
||||||
|
import { Badge } from 'component/common/Badge/Badge';
|
||||||
|
import { ConstraintExecutionWithoutResults } from './ConstraintExecution/ConstraintExecutionWithoutResults';
|
||||||
|
import { SegmentExecutionWithoutResult } from './SegmentExecution/SegmentExecutionWithoutResult';
|
||||||
|
|
||||||
|
interface IDisabledStrategyExecutionProps {
|
||||||
|
strategyResult: PlaygroundStrategySchema;
|
||||||
|
percentageFill?: string;
|
||||||
|
input?: PlaygroundRequestSchema;
|
||||||
|
}
|
||||||
|
|
||||||
|
const StyledStrategyExecutionWrapper = styled('div')(({ theme }) => ({
|
||||||
|
padding: theme.spacing(0),
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const DisabledStrategyExecution: VFC<IDisabledStrategyExecutionProps> =
|
||||||
|
({ strategyResult, input, percentageFill }) => {
|
||||||
|
const { name, constraints, segments, parameters } = strategyResult;
|
||||||
|
|
||||||
|
const hasSegments = Boolean(segments && segments.length > 0);
|
||||||
|
const hasConstraints = Boolean(constraints && constraints?.length > 0);
|
||||||
|
const hasExecutionParameters =
|
||||||
|
name !== 'default' &&
|
||||||
|
Object.keys(formattedStrategyNames).includes(name);
|
||||||
|
const hasCustomStrategyParameters =
|
||||||
|
Object.keys(parameters).length > 0 &&
|
||||||
|
strategyResult.result.evaluationStatus === 'incomplete'; // Use of custom strategy can be more explicit from the API
|
||||||
|
|
||||||
|
if (!parameters) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const items = [
|
||||||
|
hasSegments && (
|
||||||
|
<SegmentExecutionWithoutResult segments={segments} />
|
||||||
|
),
|
||||||
|
hasConstraints && (
|
||||||
|
<ConstraintExecutionWithoutResults constraints={constraints} />
|
||||||
|
),
|
||||||
|
hasExecutionParameters && (
|
||||||
|
<PlaygroundResultStrategyExecutionParameters
|
||||||
|
parameters={parameters}
|
||||||
|
constraints={constraints}
|
||||||
|
input={input}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
hasCustomStrategyParameters && (
|
||||||
|
<CustomStrategyParams
|
||||||
|
strategyName={name}
|
||||||
|
parameters={parameters}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
name === 'default' && (
|
||||||
|
<StyledBoxSummary sx={{ width: '100%' }}>
|
||||||
|
The standard strategy is <Badge color='success'>ON</Badge>{' '}
|
||||||
|
for all users.
|
||||||
|
</StyledBoxSummary>
|
||||||
|
),
|
||||||
|
].filter(Boolean);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledStrategyExecutionWrapper>
|
||||||
|
{items.map((item, index) => (
|
||||||
|
// biome-ignore lint/suspicious/noArrayIndexKey: <explanation>
|
||||||
|
<Fragment key={index}>
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={index > 0}
|
||||||
|
show={<StrategySeparator text='AND' />}
|
||||||
|
/>
|
||||||
|
{item}
|
||||||
|
</Fragment>
|
||||||
|
))}
|
||||||
|
</StyledStrategyExecutionWrapper>
|
||||||
|
);
|
||||||
|
};
|
@ -0,0 +1,47 @@
|
|||||||
|
import { Fragment, VFC } from 'react';
|
||||||
|
import { PlaygroundSegmentSchema, PlaygroundRequestSchema } from 'openapi';
|
||||||
|
import { ConstraintExecution } from '../ConstraintExecution/ConstraintExecution';
|
||||||
|
import { CancelOutlined } from '@mui/icons-material';
|
||||||
|
import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator';
|
||||||
|
import { styled, Typography } from '@mui/material';
|
||||||
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
|
import { SegmentItem } from 'component/common/SegmentItem/SegmentItem';
|
||||||
|
import { ConstraintExecutionWithoutResults } from '../ConstraintExecution/ConstraintExecutionWithoutResults';
|
||||||
|
|
||||||
|
interface ISegmentExecutionWithoutResultProps {
|
||||||
|
segments?: PlaygroundSegmentSchema[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SegmentExecutionWithoutResult: VFC<
|
||||||
|
ISegmentExecutionWithoutResultProps
|
||||||
|
> = ({ segments }) => {
|
||||||
|
if (!segments) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{segments.map((segment, index) => (
|
||||||
|
<Fragment key={segment.id}>
|
||||||
|
<SegmentItem
|
||||||
|
segment={segment}
|
||||||
|
constraintList={
|
||||||
|
<ConstraintExecutionWithoutResults
|
||||||
|
constraints={segment.constraints}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
isExpanded
|
||||||
|
/>
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={
|
||||||
|
// Add IF there is a next segment
|
||||||
|
index >= 0 &&
|
||||||
|
segments.length > 1 &&
|
||||||
|
// Don't add if it's the last segment item
|
||||||
|
index !== segments.length - 1
|
||||||
|
}
|
||||||
|
show={<StrategySeparator text='AND' />}
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
@ -10,6 +10,8 @@ import { CustomStrategyParams } from './CustomStrategyParams/CustomStrategyParam
|
|||||||
import { formattedStrategyNames } from 'utils/strategyNames';
|
import { formattedStrategyNames } from 'utils/strategyNames';
|
||||||
import { StyledBoxSummary } from './StrategyExecution.styles';
|
import { StyledBoxSummary } from './StrategyExecution.styles';
|
||||||
import { Badge } from 'component/common/Badge/Badge';
|
import { Badge } from 'component/common/Badge/Badge';
|
||||||
|
import { ConstraintExecutionWithoutResults } from './ConstraintExecution/ConstraintExecutionWithoutResults';
|
||||||
|
import { SegmentExecutionWithoutResult } from './SegmentExecution/SegmentExecutionWithoutResult';
|
||||||
|
|
||||||
interface IStrategyExecutionProps {
|
interface IStrategyExecutionProps {
|
||||||
strategyResult: PlaygroundStrategySchema;
|
strategyResult: PlaygroundStrategySchema;
|
||||||
|
@ -8,6 +8,7 @@ import {
|
|||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { FeatureStrategyItem } from './StrategyItem/FeatureStrategyItem';
|
import { FeatureStrategyItem } from './StrategyItem/FeatureStrategyItem';
|
||||||
import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator';
|
import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator';
|
||||||
|
import { useUiFlag } from '../../../../../../../hooks/useUiFlag';
|
||||||
|
|
||||||
const StyledAlertWrapper = styled('div')(({ theme }) => ({
|
const StyledAlertWrapper = styled('div')(({ theme }) => ({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@ -31,20 +32,38 @@ const StyledAlert = styled(Alert)(({ theme }) => ({
|
|||||||
interface PlaygroundResultStrategyListProps {
|
interface PlaygroundResultStrategyListProps {
|
||||||
strategies: PlaygroundStrategySchema[];
|
strategies: PlaygroundStrategySchema[];
|
||||||
input?: PlaygroundRequestSchema;
|
input?: PlaygroundRequestSchema;
|
||||||
|
titlePrefix?: string;
|
||||||
|
infoText?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const StyledSubtitle = styled(Typography)(({ theme }) => ({
|
||||||
|
margin: theme.spacing(2, 1, 2, 0),
|
||||||
|
color: 'text.secondary',
|
||||||
|
}));
|
||||||
|
|
||||||
export const PlaygroundResultStrategyLists = ({
|
export const PlaygroundResultStrategyLists = ({
|
||||||
strategies,
|
strategies,
|
||||||
input,
|
input,
|
||||||
|
titlePrefix,
|
||||||
|
infoText,
|
||||||
}: PlaygroundResultStrategyListProps) => (
|
}: PlaygroundResultStrategyListProps) => (
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={strategies.length > 0}
|
condition={strategies.length > 0}
|
||||||
show={
|
show={
|
||||||
<>
|
<>
|
||||||
<Typography
|
<StyledSubtitle variant={'subtitle1'}>{`${
|
||||||
variant={'subtitle1'}
|
titlePrefix
|
||||||
sx={{ mt: 2, ml: 1, mb: 2, color: 'text.secondary' }}
|
? titlePrefix.concat(' strategies')
|
||||||
>{`Strategies (${strategies?.length})`}</Typography>
|
: 'Strategies'
|
||||||
|
} (${strategies?.length})`}</StyledSubtitle>
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={Boolean(infoText)}
|
||||||
|
show={
|
||||||
|
<StyledSubtitle variant={'subtitle2'}>
|
||||||
|
{infoText}
|
||||||
|
</StyledSubtitle>
|
||||||
|
}
|
||||||
|
/>
|
||||||
<Box sx={{ width: '100%' }}>
|
<Box sx={{ width: '100%' }}>
|
||||||
{strategies?.map((strategy, index) => (
|
{strategies?.map((strategy, index) => (
|
||||||
<Fragment key={strategy.id}>
|
<Fragment key={strategy.id}>
|
||||||
@ -91,6 +110,17 @@ export const WrappedPlaygroundResultStrategyList = ({
|
|||||||
feature,
|
feature,
|
||||||
input,
|
input,
|
||||||
}: IWrappedPlaygroundResultStrategyListProps) => {
|
}: IWrappedPlaygroundResultStrategyListProps) => {
|
||||||
|
const playgroundImprovements = useUiFlag('playgroundImprovements');
|
||||||
|
const enabledStrategies = feature.strategies?.data?.filter(
|
||||||
|
(strategy) => !strategy.disabled,
|
||||||
|
);
|
||||||
|
const disabledStrategies = feature.strategies?.data?.filter(
|
||||||
|
(strategy) => strategy.disabled,
|
||||||
|
);
|
||||||
|
|
||||||
|
const showDisabledStrategies =
|
||||||
|
playgroundImprovements && disabledStrategies?.length > 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledAlertWrapper sx={{ pb: 1, mt: 2 }}>
|
<StyledAlertWrapper sx={{ pb: 1, mt: 2 }}>
|
||||||
<StyledAlert severity={'info'} color={'warning'}>
|
<StyledAlert severity={'info'} color={'warning'}>
|
||||||
@ -100,10 +130,26 @@ export const WrappedPlaygroundResultStrategyList = ({
|
|||||||
</StyledAlert>
|
</StyledAlert>
|
||||||
<StyledListWrapper sx={{ p: 2.5 }}>
|
<StyledListWrapper sx={{ p: 2.5 }}>
|
||||||
<PlaygroundResultStrategyLists
|
<PlaygroundResultStrategyLists
|
||||||
strategies={feature.strategies?.data || []}
|
strategies={enabledStrategies || []}
|
||||||
input={input}
|
input={input}
|
||||||
|
titlePrefix={showDisabledStrategies ? 'Enabled' : ''}
|
||||||
/>
|
/>
|
||||||
</StyledListWrapper>
|
</StyledListWrapper>
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={showDisabledStrategies}
|
||||||
|
show={
|
||||||
|
<StyledListWrapper sx={{ p: 2.5 }}>
|
||||||
|
<PlaygroundResultStrategyLists
|
||||||
|
strategies={disabledStrategies}
|
||||||
|
input={input}
|
||||||
|
titlePrefix={'Disabled'}
|
||||||
|
infoText={
|
||||||
|
'Disabled strategies are not evaluated for the overall result.'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</StyledListWrapper>
|
||||||
|
}
|
||||||
|
/>
|
||||||
</StyledAlertWrapper>
|
</StyledAlertWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user