1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-05-03 01:18:43 +02:00

chore: segment execution in playground (#9558)

Adds segment execution results to the playground and moves the existing
segment execution into a legacy file.

New:

![image](https://github.com/user-attachments/assets/870d87dd-46a3-4867-bf89-256165f669f0)

Old:

![image](https://github.com/user-attachments/assets/7624a169-9622-4785-9405-405466a89e6f)
This commit is contained in:
Thomas Heartman 2025-03-18 13:54:00 +01:00 committed by GitHub
parent 99fcdb1f23
commit 43685f516e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 114 additions and 69 deletions

View File

@ -7,7 +7,7 @@ import type {
PlaygroundStrategySchema,
} from 'openapi';
import { ConstraintExecution } from './ConstraintExecution/LegacyConstraintExecution';
import { SegmentExecution } from './SegmentExecution/SegmentExecution';
import { SegmentExecution } from './SegmentExecution/LegacySegmentExecution';
import { PlaygroundResultStrategyExecutionParameters } from './StrategyExecutionParameters/StrategyExecutionParameters';
import { CustomStrategyParams } from './CustomStrategyParams/CustomStrategyParams';
import { formattedStrategyNames } from 'utils/strategyNames';

View File

@ -0,0 +1,76 @@
import { Fragment, type VFC } from 'react';
import type { PlaygroundSegmentSchema, PlaygroundRequestSchema } from 'openapi';
import { ConstraintExecution } from '../ConstraintExecution/LegacyConstraintExecution';
import CancelOutlined from '@mui/icons-material/CancelOutlined';
import { StrategySeparator } from 'component/common/StrategySeparator/LegacyStrategySeparator';
import { styled, Typography } from '@mui/material';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { SegmentItem } from 'component/common/SegmentItem/LegacySegmentItem';
interface ISegmentExecutionProps {
segments?: PlaygroundSegmentSchema[];
input?: PlaygroundRequestSchema;
}
const SegmentResultTextWrapper = styled('div')(({ theme }) => ({
color: theme.palette.error.main,
display: 'inline-flex',
justifyContent: 'center',
marginLeft: 'auto',
gap: theme.spacing(1),
}));
export const SegmentExecution: VFC<ISegmentExecutionProps> = ({
segments,
input,
}) => {
if (!segments) return null;
return (
<>
{segments.map((segment, index) => (
<Fragment key={segment.id}>
<SegmentItem
segment={segment}
constraintList={
<ConstraintExecution
constraints={segment.constraints}
input={input}
/>
}
headerContent={
<ConditionallyRender
condition={!segment.result}
show={
<SegmentResultTextWrapper>
<Typography
variant={'subtitle2'}
sx={{ pt: 0.25 }}
>
segment is false
</Typography>
<span>
<CancelOutlined />
</span>
</SegmentResultTextWrapper>
}
elseShow={undefined}
/>
}
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>
))}
</>
);
};

View File

@ -1,76 +1,37 @@
import { Fragment, type VFC } from 'react';
import type { FC } from 'react';
import type { PlaygroundSegmentSchema, PlaygroundRequestSchema } from 'openapi';
import { ConstraintExecution } from '../ConstraintExecution/LegacyConstraintExecution';
import CancelOutlined from '@mui/icons-material/CancelOutlined';
import { StrategySeparator } from 'component/common/StrategySeparator/LegacyStrategySeparator';
import { styled, Typography } from '@mui/material';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { SegmentItem } from 'component/common/SegmentItem/LegacySegmentItem';
import { ConstraintExecution } from '../ConstraintExecution/ConstraintExecution';
import { SegmentItem } from 'component/common/SegmentItem/SegmentItem';
import { objectId } from 'utils/objectId';
import { ConstraintsList } from 'component/common/ConstraintsList/ConstraintsList';
interface ISegmentExecutionProps {
segments?: PlaygroundSegmentSchema[];
type SegmentExecutionProps = {
segment: PlaygroundSegmentSchema;
input?: PlaygroundRequestSchema;
}
};
const SegmentResultTextWrapper = styled('div')(({ theme }) => ({
color: theme.palette.error.main,
display: 'inline-flex',
justifyContent: 'center',
marginLeft: 'auto',
gap: theme.spacing(1),
}));
export const SegmentExecution: VFC<ISegmentExecutionProps> = ({
segments,
export const SegmentExecution: FC<SegmentExecutionProps> = ({
segment,
input,
}) => {
if (!segments) return null;
const constraintList =
segment.constraints.length > 0 ? (
<ConstraintsList>
{segment.constraints.map((constraint) => (
<ConstraintExecution
key={objectId(constraint)}
constraint={constraint}
input={input}
/>
))}
</ConstraintsList>
) : undefined;
return (
<>
{segments.map((segment, index) => (
<Fragment key={segment.id}>
<SegmentItem
segment={segment}
constraintList={
<ConstraintExecution
constraints={segment.constraints}
input={input}
/>
}
headerContent={
<ConditionallyRender
condition={!segment.result}
show={
<SegmentResultTextWrapper>
<Typography
variant={'subtitle2'}
sx={{ pt: 0.25 }}
>
segment is false
</Typography>
<span>
<CancelOutlined />
</span>
</SegmentResultTextWrapper>
}
elseShow={undefined}
/>
}
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>
))}
</>
<SegmentItem
segment={segment}
constraintList={constraintList}
isExpanded
/>
);
};

View File

@ -3,13 +3,13 @@ import type {
PlaygroundStrategySchema,
} from 'openapi';
import { ConstraintExecution } from './ConstraintExecution/ConstraintExecution';
import { SegmentExecution } from './SegmentExecution/SegmentExecution';
import { formattedStrategyNames } from 'utils/strategyNames';
import { StyledBoxSummary } from './StrategyExecution.styles';
import { Badge } from 'component/common/Badge/Badge';
import { ConstraintsList } from 'component/common/ConstraintsList/ConstraintsList';
import { objectId } from 'utils/objectId';
import type { FC } from 'react';
import { SegmentExecution } from './SegmentExecution/SegmentExecution';
import { useStrategyParameters } from 'component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyExecution/hooks/useStrategyParameters';
import { useStrategies } from 'hooks/api/getters/useStrategies/useStrategies';
import { useCustomStrategyParameters } from 'component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyExecution/hooks/useCustomStrategyParameters';
@ -42,7 +42,15 @@ export const StrategyExecution: FC<StrategyExecutionProps> = ({
}
const items = [
hasSegments && <SegmentExecution segments={segments} input={input} />,
...(hasSegments
? segments.map((segment) => (
<SegmentExecution
key={objectId(segment)}
segment={segment}
input={input}
/>
))
: []),
...(hasConstraints
? constraints.map((constraint) => (
<ConstraintExecution