mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	Merge remote-tracking branch 'origin/task/Add_strategy_information_to_playground_results' into task/Add_strategy_information_to_playground_results
# Conflicts: # src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/PlaygroundResultFeatureStrategyList/PlaygroundResultStrategyList/PlaygroundResultFeatureStrategyItem/PlaygroundResultFeatureStrategyItem.tsx
This commit is contained in:
		
						commit
						3b2947e9af
					
				| @ -26,6 +26,8 @@ export const useStyles = makeStyles()(theme => ({ | ||||
|     actions: { | ||||
|         marginLeft: 'auto', | ||||
|         display: 'flex', | ||||
|         minHeight: theme.spacing(6), | ||||
|         alignItems: 'center', | ||||
|     }, | ||||
|     resultChip: { | ||||
|         marginLeft: 'auto', | ||||
| @ -0,0 +1,96 @@ | ||||
| import { DragEventHandler, FC, ReactNode } from 'react'; | ||||
| import { DragIndicator } from '@mui/icons-material'; | ||||
| import { styled, IconButton, Box } from '@mui/material'; | ||||
| import classNames from 'classnames'; | ||||
| import { IFeatureStrategy } from 'interfaces/strategy'; | ||||
| import { | ||||
|     getFeatureStrategyIcon, | ||||
|     formatStrategyName, | ||||
| } from 'utils/strategyNames'; | ||||
| import StringTruncator from 'component/common/StringTruncator/StringTruncator'; | ||||
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; | ||||
| import { useStyles } from './StrategyItemContainer.styles'; | ||||
| 
 | ||||
| interface IStrategyItemContainerProps { | ||||
|     strategy: IFeatureStrategy; | ||||
|     onDragStart?: DragEventHandler<HTMLButtonElement>; | ||||
|     onDragEnd?: DragEventHandler<HTMLButtonElement>; | ||||
|     actions?: ReactNode; | ||||
|     orderNumber?: number; | ||||
|     className?: string; | ||||
| } | ||||
| 
 | ||||
| const DragIcon = styled(IconButton)(({ theme }) => ({ | ||||
|     padding: 0, | ||||
|     cursor: 'inherit', | ||||
|     transition: 'color 0.2s ease-in-out', | ||||
| })); | ||||
| 
 | ||||
| const StyledIndexLabel = styled('div')(({ theme }) => ({ | ||||
|     fontSize: theme.typography.fontSize, | ||||
|     color: theme.palette.text.secondary, | ||||
|     position: 'absolute', | ||||
|     display: 'none', | ||||
|     right: 'calc(100% + 6px)', | ||||
|     top: theme.spacing(2.5), | ||||
|     [theme.breakpoints.up('md')]: { | ||||
|         display: 'block', | ||||
|     }, | ||||
| })); | ||||
| 
 | ||||
| export const StrategyItemContainer: FC<IStrategyItemContainerProps> = ({ | ||||
|     strategy, | ||||
|     onDragStart, | ||||
|     onDragEnd, | ||||
|     actions, | ||||
|     children, | ||||
|     orderNumber, | ||||
|     className, | ||||
| }) => { | ||||
|     const { classes: styles } = useStyles(); | ||||
|     const Icon = getFeatureStrategyIcon(strategy.name); | ||||
| 
 | ||||
|     return ( | ||||
|         <Box sx={{ position: 'relative' }}> | ||||
|             <ConditionallyRender | ||||
|                 condition={orderNumber !== undefined} | ||||
|                 show={<StyledIndexLabel>{orderNumber}</StyledIndexLabel>} | ||||
|             /> | ||||
|             <Box className={classNames(styles.container, className)}> | ||||
|                 <div | ||||
|                     className={classNames(styles.header, { | ||||
|                         [styles.headerDraggable]: Boolean(onDragStart), | ||||
|                     })} | ||||
|                 > | ||||
|                     <ConditionallyRender | ||||
|                         condition={Boolean(onDragStart)} | ||||
|                         show={() => ( | ||||
|                             <DragIcon | ||||
|                                 draggable | ||||
|                                 disableRipple | ||||
|                                 size="small" | ||||
|                                 onDragStart={onDragStart} | ||||
|                                 onDragEnd={onDragEnd} | ||||
|                                 sx={{ cursor: 'move' }} | ||||
|                             > | ||||
|                                 <DragIndicator | ||||
|                                     titleAccess="Drag to reorder" | ||||
|                                     cursor="grab" | ||||
|                                     sx={{ color: 'neutral.main' }} | ||||
|                                 /> | ||||
|                             </DragIcon> | ||||
|                         )} | ||||
|                     /> | ||||
|                     <Icon className={styles.icon} /> | ||||
|                     <StringTruncator | ||||
|                         maxWidth="150" | ||||
|                         maxLength={15} | ||||
|                         text={formatStrategyName(strategy.name)} | ||||
|                     /> | ||||
|                     <div className={styles.actions}>{actions}</div> | ||||
|                 </div> | ||||
|                 <div className={styles.body}>{children}</div> | ||||
|             </Box> | ||||
|         </Box> | ||||
|     ); | ||||
| }; | ||||
| @ -1,9 +1,9 @@ | ||||
| import { Box, styled } from '@mui/material'; | ||||
| import { DragEventHandler, RefObject, useRef } from 'react'; | ||||
| import { Box } from '@mui/material'; | ||||
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; | ||||
| import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator'; | ||||
| import { IFeatureEnvironment } from 'interfaces/featureToggle'; | ||||
| import { IFeatureStrategy } from 'interfaces/strategy'; | ||||
| import { DragEventHandler, RefObject, useRef } from 'react'; | ||||
| import { StrategyItem } from './StrategyItem/StrategyItem'; | ||||
| 
 | ||||
| interface IStrategyDraggableItemProps { | ||||
| @ -22,19 +22,6 @@ interface IStrategyDraggableItemProps { | ||||
|     ) => DragEventHandler<HTMLDivElement>; | ||||
|     onDragEnd: () => void; | ||||
| } | ||||
| 
 | ||||
| const StyledIndexLabel = styled('div')(({ theme }) => ({ | ||||
|     fontSize: theme.typography.fontSize, | ||||
|     color: theme.palette.text.secondary, | ||||
|     position: 'absolute', | ||||
|     display: 'none', | ||||
|     right: 'calc(100% + 6px)', | ||||
|     top: theme.spacing(2.5), | ||||
|     [theme.breakpoints.up('md')]: { | ||||
|         display: 'block', | ||||
|     }, | ||||
| })); | ||||
| 
 | ||||
| export const StrategyDraggableItem = ({ | ||||
|     strategy, | ||||
|     index, | ||||
| @ -58,16 +45,15 @@ export const StrategyDraggableItem = ({ | ||||
|                 condition={index > 0} | ||||
|                 show={<StrategySeparator text="OR" />} | ||||
|             /> | ||||
|             <Box sx={{ position: 'relative' }}> | ||||
|                 <StyledIndexLabel>{index + 1}</StyledIndexLabel> | ||||
|                 <StrategyItem | ||||
|                     strategy={strategy} | ||||
|                     environmentId={environmentName} | ||||
|                     otherEnvironments={otherEnvironments} | ||||
|                     onDragStart={onDragStartRef(ref, index)} | ||||
|                     onDragEnd={onDragEnd} | ||||
|                 /> | ||||
|             </Box> | ||||
| 
 | ||||
|             <StrategyItem | ||||
|                 strategy={strategy} | ||||
|                 environmentId={environmentName} | ||||
|                 otherEnvironments={otherEnvironments} | ||||
|                 onDragStart={onDragStartRef(ref, index)} | ||||
|                 onDragEnd={onDragEnd} | ||||
|                 orderNumber={index + 1} | ||||
|             /> | ||||
|         </Box> | ||||
|     ); | ||||
| }; | ||||
|  | ||||
| @ -20,7 +20,6 @@ import StringTruncator from 'component/common/StringTruncator/StringTruncator'; | ||||
| 
 | ||||
| interface IStrategyExecutionProps { | ||||
|     strategy: IFeatureStrategy; | ||||
|     percentageFill?: string; | ||||
| } | ||||
| 
 | ||||
| const NoItems: VFC = () => ( | ||||
|  | ||||
| @ -1,24 +1,17 @@ | ||||
| import { DragEventHandler } from 'react'; | ||||
| import { DragIndicator, Edit } from '@mui/icons-material'; | ||||
| import { styled, useTheme, IconButton } from '@mui/material'; | ||||
| import { DragEventHandler, VFC } from 'react'; | ||||
| import { Edit } from '@mui/icons-material'; | ||||
| import { Link } from 'react-router-dom'; | ||||
| import classNames from 'classnames'; | ||||
| import { IFeatureEnvironment } from 'interfaces/featureToggle'; | ||||
| import { IFeatureStrategy } from 'interfaces/strategy'; | ||||
| import { | ||||
|     getFeatureStrategyIcon, | ||||
|     formatStrategyName, | ||||
| } from 'utils/strategyNames'; | ||||
| import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton'; | ||||
| import { UPDATE_FEATURE_STRATEGY } from 'component/providers/AccessProvider/permissions'; | ||||
| import { formatEditStrategyPath } from 'component/feature/FeatureStrategy/FeatureStrategyEdit/FeatureStrategyEdit'; | ||||
| import { FeatureStrategyRemove } from 'component/feature/FeatureStrategy/FeatureStrategyRemove/FeatureStrategyRemove'; | ||||
| import StringTruncator from 'component/common/StringTruncator/StringTruncator'; | ||||
| import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; | ||||
| import { StrategyExecution } from './StrategyExecution/StrategyExecution'; | ||||
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; | ||||
| import { CopyStrategyIconMenu } from './CopyStrategyIconMenu/CopyStrategyIconMenu'; | ||||
| import { useStyles } from './StrategyItem.styles'; | ||||
| import { StrategyItemContainer } from 'component/common/StrategyItemContainer/StrategyItemContainer'; | ||||
| 
 | ||||
| interface IStrategyItemProps { | ||||
|     environmentId: string; | ||||
| @ -26,26 +19,19 @@ interface IStrategyItemProps { | ||||
|     onDragStart?: DragEventHandler<HTMLButtonElement>; | ||||
|     onDragEnd?: DragEventHandler<HTMLButtonElement>; | ||||
|     otherEnvironments?: IFeatureEnvironment['name'][]; | ||||
|     orderNumber?: number; | ||||
| } | ||||
| 
 | ||||
| const DragIcon = styled(IconButton)(({ theme }) => ({ | ||||
|     padding: 0, | ||||
|     cursor: 'inherit', | ||||
|     transition: 'color 0.2s ease-in-out', | ||||
| })); | ||||
| 
 | ||||
| export const StrategyItem = ({ | ||||
| export const StrategyItem: VFC<IStrategyItemProps> = ({ | ||||
|     environmentId, | ||||
|     strategy, | ||||
|     onDragStart, | ||||
|     onDragEnd, | ||||
|     otherEnvironments, | ||||
| }: IStrategyItemProps) => { | ||||
|     orderNumber, | ||||
| }) => { | ||||
|     const projectId = useRequiredPathParam('projectId'); | ||||
|     const featureId = useRequiredPathParam('featureId'); | ||||
|     const theme = useTheme(); | ||||
|     const { classes: styles } = useStyles(); | ||||
|     const Icon = getFeatureStrategyIcon(strategy.name); | ||||
| 
 | ||||
|     const editStrategyPath = formatEditStrategyPath( | ||||
|         projectId, | ||||
| @ -55,38 +41,13 @@ export const StrategyItem = ({ | ||||
|     ); | ||||
| 
 | ||||
|     return ( | ||||
|         <div className={styles.container}> | ||||
|             <div | ||||
|                 className={classNames(styles.header, { | ||||
|                     [styles.headerDraggable]: Boolean(onDragStart), | ||||
|                 })} | ||||
|             > | ||||
|                 <ConditionallyRender | ||||
|                     condition={Boolean(onDragStart)} | ||||
|                     show={() => ( | ||||
|                         <DragIcon | ||||
|                             draggable | ||||
|                             disableRipple | ||||
|                             size="small" | ||||
|                             onDragStart={onDragStart} | ||||
|                             onDragEnd={onDragEnd} | ||||
|                             sx={{ cursor: 'move' }} | ||||
|                         > | ||||
|                             <DragIndicator | ||||
|                                 titleAccess="Drag to reorder" | ||||
|                                 cursor="grab" | ||||
|                                 sx={{ color: 'neutral.main' }} | ||||
|                             /> | ||||
|                         </DragIcon> | ||||
|                     )} | ||||
|                 /> | ||||
|                 <Icon className={styles.icon} /> | ||||
|                 <StringTruncator | ||||
|                     maxWidth="150" | ||||
|                     maxLength={15} | ||||
|                     text={formatStrategyName(strategy.name)} | ||||
|                 /> | ||||
|                 <div className={styles.actions}> | ||||
|         <StrategyItemContainer | ||||
|             strategy={strategy} | ||||
|             onDragStart={onDragStart} | ||||
|             onDragEnd={onDragEnd} | ||||
|             orderNumber={orderNumber} | ||||
|             actions={ | ||||
|                 <> | ||||
|                     <ConditionallyRender | ||||
|                         condition={Boolean( | ||||
|                             otherEnvironments && otherEnvironments?.length > 0 | ||||
| @ -115,14 +76,10 @@ export const StrategyItem = ({ | ||||
|                         strategyId={strategy.id} | ||||
|                         icon | ||||
|                     /> | ||||
|                 </div> | ||||
|             </div> | ||||
|             <div className={styles.body}> | ||||
|                 <StrategyExecution | ||||
|                     strategy={strategy} | ||||
|                     percentageFill={theme.palette.grey[200]} | ||||
|                 /> | ||||
|             </div> | ||||
|         </div> | ||||
|                 </> | ||||
|             } | ||||
|         > | ||||
|             <StrategyExecution strategy={strategy} /> | ||||
|         </StrategyItemContainer> | ||||
|     ); | ||||
| }; | ||||
|  | ||||
| @ -4,11 +4,11 @@ export const useStyles = makeStyles()(theme => ({ | ||||
|     popoverPaper: { | ||||
|         display: 'flex', | ||||
|         flexDirection: 'column', | ||||
|         alignItems: 'flex-start', | ||||
|         padding: theme.spacing(6), | ||||
|         maxWidth: '728px', | ||||
|         width: 728, | ||||
|         maxWidth: '100%', | ||||
|         height: 'auto', | ||||
|         overflowY: 'scroll', | ||||
|         overflowY: 'auto', | ||||
|         backgroundColor: theme.palette.tertiary.light, | ||||
|     }, | ||||
| })); | ||||
|  | ||||
| @ -1,13 +1,10 @@ | ||||
| import { | ||||
|     PlaygroundResultStrategyLists, | ||||
|     WrappedPlaygroundResultStrategyList, | ||||
| } from './PlaygroundResultStrategyList/playgroundResultStrategyLists'; | ||||
| import { ConditionallyRender } from '../../../../../common/ConditionallyRender/ConditionallyRender'; | ||||
| import React from 'react'; | ||||
| import { PlaygroundResultStrategyLists } from './PlaygroundResultStrategyList/playgroundResultStrategyLists'; | ||||
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; | ||||
| import { | ||||
|     PlaygroundFeatureSchema, | ||||
|     PlaygroundRequestSchema, | ||||
| } from '../../../../../../hooks/api/actions/usePlayground/playground.model'; | ||||
| } from 'hooks/api/actions/usePlayground/playground.model'; | ||||
| import { Alert } from '@mui/material'; | ||||
| 
 | ||||
| interface PlaygroundResultFeatureStrategyListProps { | ||||
|     feature: PlaygroundFeatureSchema; | ||||
| @ -19,24 +16,24 @@ export const PlaygroundResultFeatureStrategyList = ({ | ||||
|     input, | ||||
| }: PlaygroundResultFeatureStrategyListProps) => { | ||||
|     return ( | ||||
|         <ConditionallyRender | ||||
|             condition={ | ||||
|                 !feature.isEnabledInCurrentEnvironment && | ||||
|                 Boolean(feature?.strategies?.data) | ||||
|             } | ||||
|             show={ | ||||
|                 <WrappedPlaygroundResultStrategyList | ||||
|                     strategies={feature?.strategies?.data!} | ||||
|                     feature={feature} | ||||
|                     input={input} | ||||
|                 /> | ||||
|             } | ||||
|             elseShow={ | ||||
|                 <PlaygroundResultStrategyLists | ||||
|                     strategies={feature?.strategies?.data!} | ||||
|                     input={input} | ||||
|                 /> | ||||
|             } | ||||
|         /> | ||||
|         <> | ||||
|             <ConditionallyRender | ||||
|                 condition={ | ||||
|                     !feature.isEnabledInCurrentEnvironment && | ||||
|                     Boolean(feature?.strategies?.data) | ||||
|                 } | ||||
|                 show={ | ||||
|                     <Alert severity={'info'} color={'info'}> | ||||
|                         If environment would be enabled then this feature would | ||||
|                         be {feature.strategies?.result ? 'TRUE' : 'FALSE'} and | ||||
|                         the strategies would evaluate like this:{' '} | ||||
|                     </Alert> | ||||
|                 } | ||||
|             /> | ||||
|             <PlaygroundResultStrategyLists | ||||
|                 strategies={feature?.strategies?.data || []} | ||||
|                 input={input} | ||||
|             /> | ||||
|         </> | ||||
|     ); | ||||
| }; | ||||
|  | ||||
| @ -1,106 +0,0 @@ | ||||
| import { Box, styled, Typography, useTheme } from '@mui/material'; | ||||
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; | ||||
| import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator'; | ||||
| import { | ||||
|     formatStrategyName, | ||||
|     getFeatureStrategyIcon, | ||||
| } from 'utils/strategyNames'; | ||||
| import StringTruncator from 'component/common/StringTruncator/StringTruncator'; | ||||
| import { PlaygroundResultChip } from '../../../../PlaygroundResultChip/PlaygroundResultChip'; | ||||
| import { | ||||
|     PlaygroundStrategySchema, | ||||
|     PlaygroundRequestSchema, | ||||
| } from 'hooks/api/actions/usePlayground/playground.model'; | ||||
| import { PlaygroundResultStrategyExecution } from './PlaygroundResultStrategyExecution/PlaygroundResultStrategyExecution'; | ||||
| import { useStyles } from './PlaygroundResultFeatureStrategyItem.styles'; | ||||
| 
 | ||||
| interface IPlaygroundResultFeatureStrategyItemProps { | ||||
|     strategy: PlaygroundStrategySchema; | ||||
|     index: number; | ||||
|     input?: PlaygroundRequestSchema; | ||||
|     compact: boolean; | ||||
| } | ||||
| 
 | ||||
| const StyledItemWrapper = styled('div')(({ theme }) => ({ | ||||
|     display: 'flex', | ||||
|     flexDirection: 'row', | ||||
|     alignItems: 'center', | ||||
|     margin: theme.spacing(0.5, 0), | ||||
|     gap: theme.spacing(1), | ||||
| })); | ||||
| 
 | ||||
| export const PlaygroundResultFeatureStrategyItem = ({ | ||||
|     strategy, | ||||
|     input, | ||||
|     index, | ||||
|     compact, | ||||
| }: IPlaygroundResultFeatureStrategyItemProps) => { | ||||
|     const { result, name } = strategy; | ||||
|     const { classes: styles } = useStyles(); | ||||
|     const theme = useTheme(); | ||||
|     const Icon = getFeatureStrategyIcon(strategy.name); | ||||
|     const label = | ||||
|         result.evaluationStatus === 'incomplete' | ||||
|             ? 'Unevaluated' | ||||
|             : result.enabled | ||||
|             ? 'True' | ||||
|             : 'False'; | ||||
|     const border = | ||||
|         result.enabled && result.evaluationStatus === 'complete' | ||||
|             ? `1px solid ${theme.palette.success.main}` | ||||
|             : `1px solid ${theme.palette.divider}`; | ||||
| 
 | ||||
|     return ( | ||||
|         <Box | ||||
|             sx={{ | ||||
|                 width: '100%', | ||||
|                 position: 'relative', | ||||
|                 paddingRight: compact ? '12px' : 0, | ||||
|                 ml: '-12px', | ||||
|             }} | ||||
|         > | ||||
|             <ConditionallyRender | ||||
|                 condition={index > 0} | ||||
|                 show={<StrategySeparator text="OR" />} | ||||
|             /> | ||||
|             <StyledItemWrapper sx={{ mr: 3 }}> | ||||
|                 <Typography | ||||
|                     variant={'subtitle1'} | ||||
|                     color={'text.secondary'} | ||||
|                     sx={{ ml: 2 }} | ||||
|                 > | ||||
|                     {index + 1} | ||||
|                 </Typography> | ||||
|                 <Box className={styles.innerContainer} sx={{ border }}> | ||||
|                     <div className={styles.header}> | ||||
|                         <div className={styles.headerName}> | ||||
|                             <Icon className={styles.icon} /> | ||||
|                             <StringTruncator | ||||
|                                 maxWidth="150" | ||||
|                                 maxLength={15} | ||||
|                                 text={formatStrategyName(name)} | ||||
|                             /> | ||||
|                         </div> | ||||
|                         <PlaygroundResultChip | ||||
|                             showIcon={false} | ||||
|                             enabled={result.enabled} | ||||
|                             label={label} | ||||
|                             size={ | ||||
|                                 result.evaluationStatus === 'incomplete' | ||||
|                                     ? 'large' | ||||
|                                     : 'default' | ||||
|                             } | ||||
|                         /> | ||||
|                     </div> | ||||
|                     <div className={styles.body}> | ||||
|                         <PlaygroundResultStrategyExecution | ||||
|                             strategyResult={strategy} | ||||
|                             input={input} | ||||
|                             percentageFill={theme.palette.tertiary.light} | ||||
|                         /> | ||||
|                     </div> | ||||
|                 </Box> | ||||
|             </StyledItemWrapper> | ||||
|         </Box> | ||||
|     ); | ||||
| }; | ||||
| @ -34,4 +34,7 @@ export const useStyles = makeStyles()(theme => ({ | ||||
|         borderRadius: theme.shape.borderRadiusMedium, | ||||
|         background: theme.palette.background.default, | ||||
|     }, | ||||
|     successBorder: { | ||||
|         border: `1px solid ${theme.palette.success.main}`, | ||||
|     }, | ||||
| })); | ||||
| @ -0,0 +1,64 @@ | ||||
| import { useTheme } from '@mui/material'; | ||||
| import { PlaygroundResultChip } from '../../../../PlaygroundResultChip/PlaygroundResultChip'; | ||||
| import { | ||||
|     PlaygroundStrategySchema, | ||||
|     PlaygroundRequestSchema, | ||||
| } from 'hooks/api/actions/usePlayground/playground.model'; | ||||
| import { StrategyExecution } from './StrategyExecution/StrategyExecution'; | ||||
| import { useStyles } from './FeatureStrategyItem.styles'; | ||||
| import { StrategyItemContainer } from 'component/common/StrategyItemContainer/StrategyItemContainer'; | ||||
| import { objectId } from 'utils/objectId'; | ||||
| 
 | ||||
| interface IFeatureStrategyItemProps { | ||||
|     strategy: PlaygroundStrategySchema; | ||||
|     index: number; | ||||
|     input?: PlaygroundRequestSchema; | ||||
|     compact: boolean; | ||||
| } | ||||
| 
 | ||||
| export const FeatureStrategyItem = ({ | ||||
|     strategy, | ||||
|     input, | ||||
|     index, | ||||
|     compact, | ||||
| }: IFeatureStrategyItemProps) => { | ||||
|     const { result } = strategy; | ||||
|     const { classes: styles } = useStyles(); | ||||
|     const theme = useTheme(); | ||||
|     const label = | ||||
|         result.evaluationStatus === 'incomplete' | ||||
|             ? 'Unevaluated' | ||||
|             : result.enabled | ||||
|             ? 'True' | ||||
|             : 'False'; | ||||
| 
 | ||||
|     return ( | ||||
|         <StrategyItemContainer | ||||
|             className={ | ||||
|                 result.enabled && result.evaluationStatus === 'complete' | ||||
|                     ? styles.successBorder | ||||
|                     : undefined | ||||
|             } | ||||
|             strategy={{ ...strategy, id: `${objectId(strategy)}` }} | ||||
|             orderNumber={index + 1} | ||||
|             actions={ | ||||
|                 <PlaygroundResultChip | ||||
|                     showIcon={false} | ||||
|                     enabled={result.enabled} | ||||
|                     label={label} | ||||
|                     size={ | ||||
|                         result.evaluationStatus === 'incomplete' | ||||
|                             ? 'large' | ||||
|                             : 'default' | ||||
|                     } | ||||
|                 /> | ||||
|             } | ||||
|         > | ||||
|             <StrategyExecution | ||||
|                 strategyResult={strategy} | ||||
|                 input={input} | ||||
|                 percentageFill={theme.palette.tertiary.light} | ||||
|             /> | ||||
|         </StrategyItemContainer> | ||||
|     ); | ||||
| }; | ||||
| @ -1,4 +1,4 @@ | ||||
| import { useState } from 'react'; | ||||
| import { useState, VFC } from 'react'; | ||||
| import { | ||||
|     Accordion, | ||||
|     AccordionSummary, | ||||
| @ -14,7 +14,7 @@ import { | ||||
|     numOperators, | ||||
|     semVerOperators, | ||||
| } from 'constants/operators'; | ||||
| import { useStyles } from './PlaygroundConstraintAccordion.styles'; | ||||
| import { useStyles } from './ConstraintAccordion.styles'; | ||||
| import { | ||||
|     PlaygroundConstraintSchema, | ||||
|     PlaygroundRequestSchema, | ||||
| @ -28,12 +28,12 @@ interface IConstraintAccordionViewProps { | ||||
|     sx?: SxProps<Theme>; | ||||
| } | ||||
| 
 | ||||
| export const PlaygroundResultConstraintAccordionView = ({ | ||||
| export const ConstraintAccordionView: VFC<IConstraintAccordionViewProps> = ({ | ||||
|     constraint, | ||||
|     sx = undefined, | ||||
|     maxLength, | ||||
|     playgroundInput, | ||||
| }: IConstraintAccordionViewProps) => { | ||||
| }) => { | ||||
|     const { classes: styles } = useStyles(); | ||||
|     const [expandable, setExpandable] = useState(true); | ||||
|     const [expanded, setExpanded] = useState(false); | ||||
| @ -3,7 +3,7 @@ import { ConditionallyRender } from 'component/common/ConditionallyRender/Condit | ||||
| import { PlaygroundConstraintAccordionViewHeaderSingleValue } from './PlaygroundContraintAccordionViewHeaderSingleValue/PlaygroundConstraintAccordionViewHeaderSingleValue'; | ||||
| import { PLaygroundConstraintAccordionViewHeaderMultipleValues } from './PlaygroundContraintAccordionViewHeaderMultipleValues/PLaygroundConstraintAccordionViewHeaderMultipleValues'; | ||||
| import React from 'react'; | ||||
| import { useStyles } from '../../PlaygroundConstraintAccordion.styles'; | ||||
| import { useStyles } from '../../ConstraintAccordion.styles'; | ||||
| import { CancelOutlined } from '@mui/icons-material'; | ||||
| import { | ||||
|     PlaygroundConstraintSchema, | ||||
| @ -2,7 +2,7 @@ import { ConditionallyRender } from 'component/common/ConditionallyRender/Condit | ||||
| import { styled, Typography } from '@mui/material'; | ||||
| import React, { useEffect, useMemo, useState } from 'react'; | ||||
| import classnames from 'classnames'; | ||||
| import { useStyles } from '../../../PlaygroundConstraintAccordion.styles'; | ||||
| import { useStyles } from '../../../ConstraintAccordion.styles'; | ||||
| import { PlaygroundConstraintSchema } from 'hooks/api/actions/usePlayground/playground.model'; | ||||
| 
 | ||||
| const StyledValuesSpan = styled('span')(({ theme }) => ({ | ||||
| @ -1,7 +1,7 @@ | ||||
| import React, { useEffect } from 'react'; | ||||
| import { Chip, styled, Typography } from '@mui/material'; | ||||
| import { formatConstraintValue } from 'utils/formatConstraintValue'; | ||||
| import { useStyles } from '../../../PlaygroundConstraintAccordion.styles'; | ||||
| import { useStyles } from '../../../ConstraintAccordion.styles'; | ||||
| import { useLocationSettings } from 'hooks/useLocationSettings'; | ||||
| import { PlaygroundConstraintSchema } from 'hooks/api/actions/usePlayground/playground.model'; | ||||
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; | ||||
| @ -1,42 +1,42 @@ | ||||
| import { Fragment, VFC } from 'react'; | ||||
| import { | ||||
|     PlaygroundConstraintSchema, | ||||
|     PlaygroundRequestSchema, | ||||
| } from 'hooks/api/actions/usePlayground/playground.model'; | ||||
| import React, { Fragment } from 'react'; | ||||
| import { objectId } from '../../../../../../../../../../utils/objectId'; | ||||
| import { ConditionallyRender } from '../../../../../../../../../common/ConditionallyRender/ConditionallyRender'; | ||||
| import { StrategySeparator } from '../../../../../../../../../common/StrategySeparator/StrategySeparator'; | ||||
| 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 { PlaygroundResultConstraintAccordionView } from './PlaygroundResultConstraintAccordion/PlaygroundResultConstraintAccordionView/PlaygroundResultConstraintAccordionView'; | ||||
| import { ConstraintAccordionView } from './ConstraintAccordion/ConstraintAccordionView/ConstraintAccordionView'; | ||||
| 
 | ||||
| interface PlaygroundResultConstraintExecutionProps { | ||||
| interface IConstraintExecutionProps { | ||||
|     constraints?: PlaygroundConstraintSchema[]; | ||||
|     compact: boolean; | ||||
|     input?: PlaygroundRequestSchema; | ||||
| } | ||||
| 
 | ||||
| export const PlaygroundResultConstraintExecutionWrapper = styled('div')(() => ({ | ||||
| export const ConstraintExecutionWrapper = styled('div')(() => ({ | ||||
|     width: '100%', | ||||
|     display: 'flex', | ||||
|     flexDirection: 'column', | ||||
| })); | ||||
| 
 | ||||
| export const PlaygroundResultConstraintExecution = ({ | ||||
| export const ConstraintExecution: VFC<IConstraintExecutionProps> = ({ | ||||
|     constraints, | ||||
|     compact, | ||||
|     input, | ||||
| }: PlaygroundResultConstraintExecutionProps) => { | ||||
| }) => { | ||||
|     if (!constraints) return null; | ||||
| 
 | ||||
|     return ( | ||||
|         <PlaygroundResultConstraintExecutionWrapper> | ||||
|         <ConstraintExecutionWrapper> | ||||
|             {constraints?.map((constraint, index) => ( | ||||
|                 <Fragment key={objectId(constraint)}> | ||||
|                     <ConditionallyRender | ||||
|                         condition={index > 0 && constraints?.length > 1} | ||||
|                         show={<StrategySeparator text="AND" />} | ||||
|                     /> | ||||
|                     <PlaygroundResultConstraintAccordionView | ||||
|                     <ConstraintAccordionView | ||||
|                         constraint={constraint} | ||||
|                         playgroundInput={input} | ||||
|                         maxLength={compact ? 25 : 50} | ||||
| @ -46,6 +46,6 @@ export const PlaygroundResultConstraintExecution = ({ | ||||
|                     /> | ||||
|                 </Fragment> | ||||
|             ))} | ||||
|         </PlaygroundResultConstraintExecutionWrapper> | ||||
|         </ConstraintExecutionWrapper> | ||||
|     ); | ||||
| }; | ||||
| @ -1,10 +1,10 @@ | ||||
| import React, { Fragment, VFC } from 'react'; | ||||
| import { | ||||
|     parseParameterNumber, | ||||
|     parseParameterString, | ||||
|     parseParameterStrings, | ||||
| } from 'utils/parseParameter'; | ||||
| import React, { Fragment } from 'react'; | ||||
| import { PlaygroundParameterItem } from '../PlaygroundParamteterItem/PlaygroundParameterItem'; | ||||
| import { PlaygroundParameterItem } from '../PlaygroundParameterItem/PlaygroundParameterItem'; | ||||
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; | ||||
| import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator'; | ||||
| import { Chip } from '@mui/material'; | ||||
| @ -12,17 +12,17 @@ import PercentageCircle from 'component/common/PercentageCircle/PercentageCircle | ||||
| import { PlaygroundConstraintSchema } from 'hooks/api/actions/usePlayground/playground.model'; | ||||
| import { useStrategies } from 'hooks/api/getters/useStrategies/useStrategies'; | ||||
| 
 | ||||
| interface PlaygroundResultStrategyExecutionCustomStrategyProps { | ||||
| interface ICustomStrategyProps { | ||||
|     parameters: { [key: string]: string }; | ||||
|     strategyName: string; | ||||
|     constraints: PlaygroundConstraintSchema[]; | ||||
| } | ||||
| 
 | ||||
| export const PlaygroundResultStrategyExecutionCustomStrategyParams = ({ | ||||
| export const CustomStrategyParams: VFC<ICustomStrategyProps> = ({ | ||||
|     strategyName, | ||||
|     constraints, | ||||
|     parameters, | ||||
| }: PlaygroundResultStrategyExecutionCustomStrategyProps) => { | ||||
| }) => { | ||||
|     const { strategies } = useStrategies(); | ||||
|     const definition = strategies.find(strategyDefinition => { | ||||
|         return strategyDefinition.name === strategyName; | ||||
| @ -1,16 +1,17 @@ | ||||
| import { VFC } from 'react'; | ||||
| import { | ||||
|     PlaygroundSegmentSchema, | ||||
|     PlaygroundRequestSchema, | ||||
| } from '../../../../../../../../../../hooks/api/actions/usePlayground/playground.model'; | ||||
| import { PlaygroundResultConstraintExecution } from '../PlaygroundResultConstraintExecution/PlaygroundResultConstraintExecution'; | ||||
| } from 'hooks/api/actions/usePlayground/playground.model'; | ||||
| import { ConstraintExecution } from '../ConstraintExecution/ConstraintExecution'; | ||||
| import { CancelOutlined, DonutLarge } from '@mui/icons-material'; | ||||
| import { Link } from 'react-router-dom'; | ||||
| import { StrategySeparator } from '../../../../../../../../../common/StrategySeparator/StrategySeparator'; | ||||
| import { useStyles } from './PlaygroundResultSegmentExecution.styles'; | ||||
| import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator'; | ||||
| import { useStyles } from './SegmentExecution.styles'; | ||||
| import { styled, Typography } from '@mui/material'; | ||||
| import { ConditionallyRender } from '../../../../../../../../../common/ConditionallyRender/ConditionallyRender'; | ||||
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; | ||||
| 
 | ||||
| interface PlaygroundResultSegmentExecutionProps { | ||||
| interface ISegmentExecutionProps { | ||||
|     segments?: PlaygroundSegmentSchema[]; | ||||
|     input?: PlaygroundRequestSchema; | ||||
|     hasConstraints: boolean; | ||||
| @ -58,11 +59,11 @@ const SegmentResultTextWrapper = styled('div')(({ theme }) => ({ | ||||
|     gap: theme.spacing(1), | ||||
| })); | ||||
| 
 | ||||
| export const PlaygroundResultSegmentExecution = ({ | ||||
| export const SegmentExecution: VFC<ISegmentExecutionProps> = ({ | ||||
|     segments, | ||||
|     input, | ||||
|     hasConstraints, | ||||
| }: PlaygroundResultSegmentExecutionProps) => { | ||||
| }) => { | ||||
|     const { classes: styles } = useStyles(); | ||||
| 
 | ||||
|     if (!segments) return null; | ||||
| @ -99,7 +100,7 @@ export const PlaygroundResultSegmentExecution = ({ | ||||
|                         /> | ||||
|                     </SegmentExecutionHeader> | ||||
|                     <SegmentExecutionConstraintWrapper> | ||||
|                         <PlaygroundResultConstraintExecution | ||||
|                         <ConstraintExecution | ||||
|                             constraints={segment.constraints} | ||||
|                             input={input} | ||||
|                             compact | ||||
| @ -1,19 +1,19 @@ | ||||
| import { VFC } from 'react'; | ||||
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; | ||||
| import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator'; | ||||
| import { Box, Chip, styled } from '@mui/material'; | ||||
| import { useStyles } from './PlaygroundResultStrategyExecution.styles'; | ||||
| import { useStyles } from './StrategyExecution.styles'; | ||||
| import { | ||||
|     PlaygroundRequestSchema, | ||||
|     PlaygroundStrategySchema, | ||||
| } from 'hooks/api/actions/usePlayground/playground.model'; | ||||
| import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; | ||||
| import React from 'react'; | ||||
| import { PlaygroundResultConstraintExecution } from './PlaygroundResultConstraintExecution/PlaygroundResultConstraintExecution'; | ||||
| import { PlaygroundResultSegmentExecution } from './PlaygroundResultSegmentExecution/PlaygroundResultSegmentExecution'; | ||||
| import { PlaygroundResultStrategyExecutionParameters } from './PlaygroundResultStrategyExecutionParameters/PlaygroundResultStrategyExecutionParameters'; | ||||
| import { PlaygroundResultStrategyExecutionCustomStrategyParams } from './PlaygroundResultStrategyExecutionCustomStrategyParams/PlaygroundResultStrategyExecutionCustomStrategyParams'; | ||||
| import { ConstraintExecution } from './ConstraintExecution/ConstraintExecution'; | ||||
| import { SegmentExecution } from './SegmentExecution/SegmentExecution'; | ||||
| import { PlaygroundResultStrategyExecutionParameters } from './StrategyExecutionParameters/StrategyExecutionParameters'; | ||||
| import { CustomStrategyParams } from './CustomStrategyParams/CustomStrategyParams'; | ||||
| 
 | ||||
| interface PlaygroundResultStrategyExecutionProps { | ||||
| interface IStrategyExecutionProps { | ||||
|     strategyResult: PlaygroundStrategySchema; | ||||
|     percentageFill?: string; | ||||
|     input?: PlaygroundRequestSchema; | ||||
| @ -27,10 +27,10 @@ const StyledParamWrapper = styled('div')(({ theme }) => ({ | ||||
|     padding: theme.spacing(0, 0), | ||||
| })); | ||||
| 
 | ||||
| export const PlaygroundResultStrategyExecution = ({ | ||||
| export const StrategyExecution: VFC<IStrategyExecutionProps> = ({ | ||||
|     strategyResult, | ||||
|     input, | ||||
| }: PlaygroundResultStrategyExecutionProps) => { | ||||
| }) => { | ||||
|     const { name, constraints, segments, parameters } = strategyResult; | ||||
| 
 | ||||
|     const { uiConfig } = useUiConfig(); | ||||
| @ -51,7 +51,7 @@ export const PlaygroundResultStrategyExecution = ({ | ||||
|                     Boolean(segments && segments.length > 0) | ||||
|                 } | ||||
|                 show={ | ||||
|                     <PlaygroundResultSegmentExecution | ||||
|                     <SegmentExecution | ||||
|                         segments={segments} | ||||
|                         hasConstraints={hasConstraints} | ||||
|                         input={input} | ||||
| @ -62,7 +62,7 @@ export const PlaygroundResultStrategyExecution = ({ | ||||
|                 condition={Boolean(constraints && constraints.length > 0)} | ||||
|                 show={ | ||||
|                     <> | ||||
|                         <PlaygroundResultConstraintExecution | ||||
|                         <ConstraintExecution | ||||
|                             constraints={constraints} | ||||
|                             compact={true} | ||||
|                             input={input} | ||||
| @ -100,7 +100,7 @@ export const PlaygroundResultStrategyExecution = ({ | ||||
|                     input={input} | ||||
|                 /> | ||||
|                 <StyledParamWrapper sx={{ pt: 2 }}> | ||||
|                     <PlaygroundResultStrategyExecutionCustomStrategyParams | ||||
|                     <CustomStrategyParams | ||||
|                         strategyName={strategyResult.name} | ||||
|                         parameters={parameters} | ||||
|                         constraints={constraints} | ||||
| @ -4,9 +4,9 @@ import { | ||||
| } from 'utils/parseParameter'; | ||||
| import { Box, Chip } from '@mui/material'; | ||||
| import PercentageCircle from 'component/common/PercentageCircle/PercentageCircle'; | ||||
| import { PlaygroundParameterItem } from '../PlaygroundParamteterItem/PlaygroundParameterItem'; | ||||
| import { PlaygroundParameterItem } from '../PlaygroundParameterItem/PlaygroundParameterItem'; | ||||
| import React from 'react'; | ||||
| import { useStyles } from '../PlaygroundResultStrategyExecution.styles'; | ||||
| import { useStyles } from '../StrategyExecution.styles'; | ||||
| import { | ||||
|     PlaygroundConstraintSchema, | ||||
|     PlaygroundRequestSchema, | ||||
| @ -1,11 +1,13 @@ | ||||
| import { Fragment } from 'react'; | ||||
| import { Alert, Box, styled, Typography } from '@mui/material'; | ||||
| import { | ||||
|     PlaygroundFeatureSchema, | ||||
|     PlaygroundStrategySchema, | ||||
|     PlaygroundRequestSchema, | ||||
| } from '../../../../../../../hooks/api/actions/usePlayground/playground.model'; | ||||
| import { ConditionallyRender } from '../../../../../../common/ConditionallyRender/ConditionallyRender'; | ||||
| import { Alert, styled, Typography } from '@mui/material'; | ||||
| import { PlaygroundResultFeatureStrategyItem } from './PlaygroundResultFeatureStrategyItem/PlaygroundResultFeatureStrategyItem'; | ||||
| } from 'hooks/api/actions/usePlayground/playground.model'; | ||||
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; | ||||
| import { FeatureStrategyItem } from './StrategyItem/FeatureStrategyItem'; | ||||
| import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator'; | ||||
| 
 | ||||
| const StyledAlertWrapper = styled('div')(({ theme }) => ({ | ||||
|     display: 'flex', | ||||
| @ -34,30 +36,36 @@ export const PlaygroundResultStrategyLists = ({ | ||||
|     strategies, | ||||
|     input, | ||||
|     compact = false, | ||||
| }: PlaygroundResultStrategyListProps) => { | ||||
|     return ( | ||||
|         <ConditionallyRender | ||||
|             condition={strategies.length > 0} | ||||
|             show={ | ||||
|                 <> | ||||
|                     <Typography | ||||
|                         variant={'subtitle1'} | ||||
|                         sx={{ mt: 2, ml: 1, mb: 2, color: 'text.secondary' }} | ||||
|                     >{`Strategies (${strategies.length})`}</Typography> | ||||
| }: PlaygroundResultStrategyListProps) => ( | ||||
|     <ConditionallyRender | ||||
|         condition={strategies.length > 0} | ||||
|         show={ | ||||
|             <> | ||||
|                 <Typography | ||||
|                     variant={'subtitle1'} | ||||
|                     sx={{ mt: 2, ml: 1, mb: 2, color: 'text.secondary' }} | ||||
|                 >{`Strategies (${strategies.length})`}</Typography> | ||||
|                 <Box sx={{ width: '100%' }}> | ||||
|                     {strategies.map((strategy, index) => ( | ||||
|                         <PlaygroundResultFeatureStrategyItem | ||||
|                             key={strategy.id} | ||||
|                             strategy={strategy} | ||||
|                             index={index} | ||||
|                             compact={compact} | ||||
|                             input={input} | ||||
|                         /> | ||||
|                         <Fragment key={strategy.id}> | ||||
|                             <ConditionallyRender | ||||
|                                 condition={index > 0} | ||||
|                                 show={<StrategySeparator text="OR" />} | ||||
|                             /> | ||||
|                             <FeatureStrategyItem | ||||
|                                 key={strategy.id} | ||||
|                                 strategy={strategy} | ||||
|                                 index={index} | ||||
|                                 compact={compact} | ||||
|                                 input={input} | ||||
|                             /> | ||||
|                         </Fragment> | ||||
|                     ))} | ||||
|                 </> | ||||
|             } | ||||
|         /> | ||||
|     ); | ||||
| }; | ||||
|                 </Box> | ||||
|             </> | ||||
|         } | ||||
|     /> | ||||
| ); | ||||
| 
 | ||||
| interface WrappedPlaygroundResultStrategyListProps | ||||
|     extends PlaygroundResultStrategyListProps { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user