From cf1ba8fcc55cdd94a4043aab766e29327cc08994 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Mon, 17 Mar 2025 14:30:11 +0100 Subject: [PATCH] Chore(1-3390)/playground strategy execution: constraints (#9532) Implements the new design for playground constraints. They're not in use in segments yet, and strategy parameters have not been touched. This PR establishes a pattern that we can follow for strategies and parameters later. ![image](https://github.com/user-attachments/assets/c23d538d-f27f-43f2-8e29-fa8044c11d48) The PR also includes a change in how the constraint item organizes its children: it now takes care adding padding and spacing itself, instead of the children doing that. It looks right most places, but segments aren't quite right anymore. However, as this is behind a flag, I'd rather fix that in a separate PR. --------- Co-authored-by: Tymoteusz Czech <2625371+Tymek@users.noreply.github.com> --- .../ConstraintsList/ConstraintsList.tsx | 10 ++ .../StrategyEvaluationItem.tsx | 1 - .../common/SegmentItem/SegmentItem.tsx | 6 +- .../PlaygroundResultsFeatureStrategyList.tsx | 2 +- ....tsx => PlaygroundResultStrategyLists.tsx} | 0 .../StrategyItem/FeatureStrategyItem.tsx | 22 +--- .../LegacyFeatureStrategyItem.tsx | 2 +- ...intError.tsx => LegacyConstraintError.tsx} | 0 .../ConstraintExecution.tsx | 106 +++++++++++------- ...onstraintOk.tsx => LegacyConstraintOk.tsx} | 0 .../LegacyConstraintExecution.tsx | 59 ++++++++++ .../LegacyStrategyExecution.tsx | 87 ++++++++++++++ .../SegmentExecution/SegmentExecution.tsx | 2 +- .../StrategyExecution/StrategyExecution.tsx | 44 +++----- 14 files changed, 241 insertions(+), 100 deletions(-) rename frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/{playgroundResultStrategyLists.tsx => PlaygroundResultStrategyLists.tsx} (100%) rename frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/ConstraintError/{ConstraintError.tsx => LegacyConstraintError.tsx} (100%) rename frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/ConstraintOk/{ConstraintOk.tsx => LegacyConstraintOk.tsx} (100%) create mode 100644 frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/LegacyConstraintExecution.tsx create mode 100644 frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/LegacyStrategyExecution.tsx diff --git a/frontend/src/component/common/ConstraintsList/ConstraintsList.tsx b/frontend/src/component/common/ConstraintsList/ConstraintsList.tsx index b5a19888db..40875c543d 100644 --- a/frontend/src/component/common/ConstraintsList/ConstraintsList.tsx +++ b/frontend/src/component/common/ConstraintsList/ConstraintsList.tsx @@ -15,6 +15,16 @@ const StyledListItem = styled('li')(({ theme }) => ({ border: `1px solid ${theme.palette.divider}`, borderRadius: theme.shape.borderRadiusMedium, background: theme.palette.background.default, + padding: theme.spacing(2, 3), + display: 'flex', + flexFlow: 'column', + gap: theme.spacing(1), + '&:has(>.MuiAccordion-root)': { + // todo: look at this later. MUI accordions rely heavily on their + // padding, but it doesn't collapse with the surrounding padding here, + // so they become super chunky otherwise. + paddingBlock: 0, + }, })); const StyledAnd = styled('div')(({ theme }) => ({ diff --git a/frontend/src/component/common/ConstraintsList/StrategyEvaluationItem/StrategyEvaluationItem.tsx b/frontend/src/component/common/ConstraintsList/StrategyEvaluationItem/StrategyEvaluationItem.tsx index c78b0eed2a..5f26e7e4a6 100644 --- a/frontend/src/component/common/ConstraintsList/StrategyEvaluationItem/StrategyEvaluationItem.tsx +++ b/frontend/src/component/common/ConstraintsList/StrategyEvaluationItem/StrategyEvaluationItem.tsx @@ -12,7 +12,6 @@ const StyledContainer = styled('div')(({ theme }) => ({ gap: theme.spacing(1), alignItems: 'center', fontSize: theme.typography.body2.fontSize, - margin: theme.spacing(2, 3), })); const StyledContent = styled('div')(({ theme }) => ({ diff --git a/frontend/src/component/common/SegmentItem/SegmentItem.tsx b/frontend/src/component/common/SegmentItem/SegmentItem.tsx index 100f3090db..4552ef11be 100644 --- a/frontend/src/component/common/SegmentItem/SegmentItem.tsx +++ b/frontend/src/component/common/SegmentItem/SegmentItem.tsx @@ -26,14 +26,14 @@ const StyledAccordion = styled(Accordion)(({ theme }) => ({ boxShadow: 'none', margin: 0, padding: 0, + '::before': { + display: 'none', + }, })); const StyledAccordionSummary = styled(AccordionSummary)(({ theme }) => ({ padding: 0, fontSize: theme.typography.body2.fontSize, - '.MuiAccordionSummary-content, .Mui-expanded.MuiAccordionSummary-content': { - margin: 0, - }, })); const StyledAccordionDetails = styled(AccordionDetails)(({ theme }) => ({ diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/PlaygroundResultsFeatureStrategyList.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/PlaygroundResultsFeatureStrategyList.tsx index 8a88c62863..f9e2de12ee 100644 --- a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/PlaygroundResultsFeatureStrategyList.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/PlaygroundResultsFeatureStrategyList.tsx @@ -1,7 +1,7 @@ import { PlaygroundResultStrategyLists, WrappedPlaygroundResultStrategyList, -} from './StrategyList/playgroundResultStrategyLists'; +} from './StrategyList/PlaygroundResultStrategyLists'; import type { PlaygroundFeatureSchema, PlaygroundRequestSchema } from 'openapi'; import { Alert } from '@mui/material'; diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/playgroundResultStrategyLists.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/PlaygroundResultStrategyLists.tsx similarity index 100% rename from frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/playgroundResultStrategyLists.tsx rename to frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/PlaygroundResultStrategyLists.tsx diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/FeatureStrategyItem.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/FeatureStrategyItem.tsx index 39dd3be10d..8bcb309a67 100644 --- a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/FeatureStrategyItem.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/FeatureStrategyItem.tsx @@ -4,11 +4,9 @@ import type { PlaygroundStrategySchema, PlaygroundRequestSchema, } from 'openapi'; -import { StrategyExecution } from './StrategyExecution/StrategyExecution'; import { objectId } from 'utils/objectId'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; -import { DisabledStrategyExecution } from './StrategyExecution/DisabledStrategyExecution'; import { StrategyItemContainer } from 'component/common/StrategyItemContainer/StrategyItemContainer'; +import { StrategyExecution } from './StrategyExecution/StrategyExecution'; interface IFeatureStrategyItemProps { strategy: PlaygroundStrategySchema; @@ -45,23 +43,7 @@ export const FeatureStrategyItem = ({ /> } > - {/* todo: use new strategy execution components */} - - } - elseShow={ - - } - /> + ); }; diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/LegacyFeatureStrategyItem.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/LegacyFeatureStrategyItem.tsx index 2587097548..178df05f5c 100644 --- a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/LegacyFeatureStrategyItem.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/LegacyFeatureStrategyItem.tsx @@ -4,7 +4,7 @@ import type { PlaygroundStrategySchema, PlaygroundRequestSchema, } from 'openapi'; -import { StrategyExecution } from './StrategyExecution/StrategyExecution'; +import { StrategyExecution } from './StrategyExecution/LegacyStrategyExecution'; import { objectId } from 'utils/objectId'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { DisabledStrategyExecution } from './StrategyExecution/DisabledStrategyExecution'; diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/ConstraintError/ConstraintError.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/ConstraintError/LegacyConstraintError.tsx similarity index 100% rename from frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/ConstraintError/ConstraintError.tsx rename to frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/ConstraintError/LegacyConstraintError.tsx diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/ConstraintExecution.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/ConstraintExecution.tsx index b1f1499d36..415084de4d 100644 --- a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/ConstraintExecution.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/ConstraintExecution.tsx @@ -1,59 +1,79 @@ -import { Fragment, type VFC } from 'react'; +import type { FC } from 'react'; import type { PlaygroundConstraintSchema, PlaygroundRequestSchema, } from 'openapi'; -import { objectId } from 'utils/objectId'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; -import { StrategySeparator } from 'component/common/StrategySeparator/LegacyStrategySeparator'; +import { ConstraintItem } from 'component/common/ConstraintsList/ConstraintItem/ConstraintItem'; +import CheckCircle from '@mui/icons-material/CheckCircle'; import { styled } from '@mui/material'; -import { ConstraintAccordionView } from 'component/common/ConstraintAccordion/ConstraintAccordionView/ConstraintAccordionView'; -import { ConstraintError } from './ConstraintError/ConstraintError'; -import { ConstraintOk } from './ConstraintOk/ConstraintOk'; +import Cancel from '@mui/icons-material/Cancel'; interface IConstraintExecutionProps { - constraints?: PlaygroundConstraintSchema[]; + constraint?: PlaygroundConstraintSchema; input?: PlaygroundRequestSchema; } -export const ConstraintExecutionWrapper = styled('div')(() => ({ - width: '100%', +const StyledContainer = styled('div', { + shouldForwardProp: (prop) => prop !== 'variant', +})<{ variant: 'ok' | 'error' }>(({ theme, variant }) => ({ + '--font-size': theme.typography.body2.fontSize, display: 'flex', - flexDirection: 'column', + alignItems: 'center', + gap: theme.spacing(1), + paddingInline: theme.spacing(0.25), + color: + variant === 'ok' + ? theme.palette.success.dark + : theme.palette.error.dark, + + fontSize: 'var(--font-size)', + svg: { + fontSize: `calc(var(--font-size) * 1.25)`, + }, })); -export const ConstraintExecution: VFC = ({ - constraints, - input, -}) => { - if (!constraints) return null; - +const ConstraintOk = () => { return ( - - {constraints?.map((constraint, index) => ( - - 0} - show={} - /> - } - elseShow={ - - } - /> - } - /> - - ))} - + + + ); +}; + +export const ConstraintError = ({ text }: { text: string }) => { + return ( + + + ); +}; + +export const ConstraintExecution: FC = ({ + constraint, + input, +}) => { + if (!constraint) return null; + + const errorText = () => { + const value = input?.context[constraint.contextName]; + + if (value) { + return `Constraint not met – the value in the context: { ${value} } is not ${constraint.operator} ${constraint.contextName}`; + } + + return `Constraint not met – no value was specified for ${constraint.contextName}`; + }; + + return ( + <> + + {constraint.result ? ( + + ) : ( + + )} + ); }; diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/ConstraintOk/ConstraintOk.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/ConstraintOk/LegacyConstraintOk.tsx similarity index 100% rename from frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/ConstraintOk/ConstraintOk.tsx rename to frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/ConstraintOk/LegacyConstraintOk.tsx diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/LegacyConstraintExecution.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/LegacyConstraintExecution.tsx new file mode 100644 index 0000000000..8f237cfcdd --- /dev/null +++ b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/LegacyConstraintExecution.tsx @@ -0,0 +1,59 @@ +import { Fragment, type VFC } from 'react'; +import type { + PlaygroundConstraintSchema, + PlaygroundRequestSchema, +} from 'openapi'; +import { objectId } from 'utils/objectId'; +import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; +import { StrategySeparator } from 'component/common/StrategySeparator/LegacyStrategySeparator'; +import { styled } from '@mui/material'; +import { ConstraintAccordionView } from 'component/common/ConstraintAccordion/ConstraintAccordionView/ConstraintAccordionView'; +import { ConstraintError } from './ConstraintError/LegacyConstraintError'; +import { ConstraintOk } from './ConstraintOk/LegacyConstraintOk'; + +interface IConstraintExecutionProps { + constraints?: PlaygroundConstraintSchema[]; + input?: PlaygroundRequestSchema; +} + +export const ConstraintExecutionWrapper = styled('div')(() => ({ + width: '100%', + display: 'flex', + flexDirection: 'column', +})); + +export const ConstraintExecution: VFC = ({ + constraints, + input, +}) => { + if (!constraints) return null; + + return ( + + {constraints?.map((constraint, index) => ( + + 0} + show={} + /> + } + elseShow={ + + } + /> + } + /> + + ))} + + ); +}; diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/LegacyStrategyExecution.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/LegacyStrategyExecution.tsx new file mode 100644 index 0000000000..ebe65d71e4 --- /dev/null +++ b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/LegacyStrategyExecution.tsx @@ -0,0 +1,87 @@ +import { Fragment, type VFC } from 'react'; +import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; +import { StrategySeparator } from 'component/common/StrategySeparator/LegacyStrategySeparator'; +import { styled } from '@mui/material'; +import type { + PlaygroundRequestSchema, + PlaygroundStrategySchema, +} from 'openapi'; +import { ConstraintExecution } from './ConstraintExecution/LegacyConstraintExecution'; +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'; + +interface IStrategyExecutionProps { + strategyResult: PlaygroundStrategySchema; + percentageFill?: string; + input?: PlaygroundRequestSchema; +} + +const StyledStrategyExecutionWrapper = styled('div')(({ theme }) => ({ + padding: theme.spacing(0), +})); + +export const StrategyExecution: VFC = ({ + strategyResult, + input, +}) => { + 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 && , + hasConstraints && ( + + ), + hasExecutionParameters && ( + + ), + hasCustomStrategyParameters && ( + + ), + name === 'default' && ( + + The standard strategy is ON for + all users. + + ), + ].filter(Boolean); + + return ( + + {items.map((item, index) => ( + + 0 && + (strategyResult.name === 'flexibleRollout' + ? index < items.length + : index < items.length - 1) + } + show={} + /> + {item} + + ))} + + ); +}; diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/SegmentExecution/SegmentExecution.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/SegmentExecution/SegmentExecution.tsx index 80e8ccbae0..8a8563bdea 100644 --- a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/SegmentExecution/SegmentExecution.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/SegmentExecution/SegmentExecution.tsx @@ -1,6 +1,6 @@ import { Fragment, type VFC } from 'react'; import type { PlaygroundSegmentSchema, PlaygroundRequestSchema } from 'openapi'; -import { ConstraintExecution } from '../ConstraintExecution/ConstraintExecution'; +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'; diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/StrategyExecution.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/StrategyExecution.tsx index 0cf90d70b1..e7f55baf32 100644 --- a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/StrategyExecution.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/StrategyExecution.tsx @@ -1,7 +1,3 @@ -import { Fragment, type VFC } from 'react'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; -import { StrategySeparator } from 'component/common/StrategySeparator/LegacyStrategySeparator'; -import { styled } from '@mui/material'; import type { PlaygroundRequestSchema, PlaygroundStrategySchema, @@ -13,6 +9,9 @@ import { CustomStrategyParams } from './CustomStrategyParams/CustomStrategyParam 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'; interface IStrategyExecutionProps { strategyResult: PlaygroundStrategySchema; @@ -20,11 +19,7 @@ interface IStrategyExecutionProps { input?: PlaygroundRequestSchema; } -const StyledStrategyExecutionWrapper = styled('div')(({ theme }) => ({ - padding: theme.spacing(0), -})); - -export const StrategyExecution: VFC = ({ +export const StrategyExecution: FC = ({ strategyResult, input, }) => { @@ -45,9 +40,15 @@ export const StrategyExecution: VFC = ({ const items = [ hasSegments && , - hasConstraints && ( - - ), + ...(hasConstraints + ? constraints.map((constraint) => ( + + )) + : []), hasExecutionParameters && ( = ({ ), ].filter(Boolean); - return ( - - {items.map((item, index) => ( - - 0 && - (strategyResult.name === 'flexibleRollout' - ? index < items.length - : index < items.length - 1) - } - show={} - /> - {item} - - ))} - - ); + return {items}; };