mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	Chore(1-3825)/remove legacy strategy separator (#10137)
Deletes the legacy strategy separator and removes all references to it. Luckily, all references to the separator were in dangling files that could themselves be deleted directly.
This commit is contained in:
		
							parent
							
								
									74ae35298d
								
							
						
					
					
						commit
						b66cff9af5
					
				| @ -1,55 +0,0 @@ | |||||||
| // deprecated; remove with the `flagOverviewRedesign` flag
 |  | ||||||
| import { Box, styled, useTheme } from '@mui/material'; |  | ||||||
| import { ConditionallyRender } from '../ConditionallyRender/ConditionallyRender.tsx'; |  | ||||||
| 
 |  | ||||||
| interface IStrategySeparatorProps { |  | ||||||
|     text: 'AND' | 'OR'; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| const StyledContent = styled('div')(({ theme }) => ({ |  | ||||||
|     padding: theme.spacing(0.75, 1), |  | ||||||
|     color: theme.palette.text.primary, |  | ||||||
|     fontSize: theme.fontSizes.smallerBody, |  | ||||||
|     backgroundColor: theme.palette.background.elevation2, |  | ||||||
|     borderRadius: theme.shape.borderRadius, |  | ||||||
|     position: 'absolute', |  | ||||||
|     zIndex: theme.zIndex.fab, |  | ||||||
|     top: '50%', |  | ||||||
|     left: theme.spacing(2), |  | ||||||
|     transform: 'translateY(-50%)', |  | ||||||
|     lineHeight: 1, |  | ||||||
| })); |  | ||||||
| 
 |  | ||||||
| const StyledCenteredContent = styled(StyledContent)(({ theme }) => ({ |  | ||||||
|     top: '50%', |  | ||||||
|     left: '50%', |  | ||||||
|     transform: 'translate(-50%, -50%)', |  | ||||||
|     backgroundColor: theme.palette.seen.primary, |  | ||||||
|     borderRadius: theme.shape.borderRadiusLarge, |  | ||||||
|     padding: theme.spacing(0.75, 1.5), |  | ||||||
| })); |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * @deprecated remove with 'flagOverviewRedesign' flag. This pollutes a lot of places in the codebase 😞 |  | ||||||
|  */ |  | ||||||
| export const StrategySeparator = ({ text }: IStrategySeparatorProps) => { |  | ||||||
|     const theme = useTheme(); |  | ||||||
| 
 |  | ||||||
|     return ( |  | ||||||
|         <Box |  | ||||||
|             sx={{ |  | ||||||
|                 height: theme.spacing(text === 'AND' ? 1 : 1.5), |  | ||||||
|                 position: 'relative', |  | ||||||
|                 width: '100%', |  | ||||||
|             }} |  | ||||||
|         > |  | ||||||
|             <ConditionallyRender |  | ||||||
|                 condition={text === 'AND'} |  | ||||||
|                 show={() => <StyledContent>{text}</StyledContent>} |  | ||||||
|                 elseShow={() => ( |  | ||||||
|                     <StyledCenteredContent>{text}</StyledCenteredContent> |  | ||||||
|                 )} |  | ||||||
|             /> |  | ||||||
|         </Box> |  | ||||||
|     ); |  | ||||||
| }; |  | ||||||
| @ -1,33 +0,0 @@ | |||||||
| import { Fragment } from 'react'; |  | ||||||
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; |  | ||||||
| import { StrategySeparator } from 'component/common/StrategySeparator/LegacyStrategySeparator'; |  | ||||||
| import type { ISegment } from 'interfaces/segment'; |  | ||||||
| import { SegmentItem } from 'component/common/SegmentItem/SegmentItem'; |  | ||||||
| 
 |  | ||||||
| interface IFeatureOverviewSegmentProps { |  | ||||||
|     segments?: ISegment[]; |  | ||||||
|     disabled?: boolean | null; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export const FeatureOverviewSegment = ({ |  | ||||||
|     segments, |  | ||||||
|     disabled = false, |  | ||||||
| }: IFeatureOverviewSegmentProps) => { |  | ||||||
|     if (!segments || segments.length === 0) { |  | ||||||
|         return null; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return ( |  | ||||||
|         <> |  | ||||||
|             {segments.map((segment, index) => ( |  | ||||||
|                 <Fragment key={segment.id}> |  | ||||||
|                     <ConditionallyRender |  | ||||||
|                         condition={index > 0} |  | ||||||
|                         show={<StrategySeparator text='AND' />} |  | ||||||
|                     /> |  | ||||||
|                     <SegmentItem segment={segment} disabled={disabled} /> |  | ||||||
|                 </Fragment> |  | ||||||
|             ))} |  | ||||||
|         </> |  | ||||||
|     ); |  | ||||||
| }; |  | ||||||
| @ -1,97 +0,0 @@ | |||||||
| import { Box, styled, Typography, useTheme } from '@mui/material'; |  | ||||||
| import CancelOutlined from '@mui/icons-material/CancelOutlined'; |  | ||||||
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; |  | ||||||
| import StringTruncator from 'component/common/StringTruncator/StringTruncator'; |  | ||||||
| 
 |  | ||||||
| interface ICustomParameterItem { |  | ||||||
|     text: string; |  | ||||||
|     input?: string | null; |  | ||||||
|     isRequired?: boolean; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| const StyledWrapper = styled(Box)(({ theme }) => ({ |  | ||||||
|     width: '100%', |  | ||||||
|     padding: theme.spacing(2, 3), |  | ||||||
|     borderRadius: theme.shape.borderRadiusMedium, |  | ||||||
|     border: `1px solid ${theme.palette.divider}`, |  | ||||||
|     display: 'flex', |  | ||||||
|     flexDirection: 'row', |  | ||||||
|     alignItems: 'center', |  | ||||||
|     gap: 2, |  | ||||||
| })); |  | ||||||
| 
 |  | ||||||
| export const CustomParameterItem = ({ |  | ||||||
|     text, |  | ||||||
|     input = null, |  | ||||||
|     isRequired = false, |  | ||||||
| }: ICustomParameterItem) => { |  | ||||||
|     const theme = useTheme(); |  | ||||||
| 
 |  | ||||||
|     const color = input === null ? 'error' : 'neutral'; |  | ||||||
|     const requiredError = isRequired && input === null; |  | ||||||
| 
 |  | ||||||
|     return ( |  | ||||||
|         <StyledWrapper> |  | ||||||
|             <Typography |  | ||||||
|                 variant='subtitle1' |  | ||||||
|                 color={theme.palette[color].main} |  | ||||||
|                 sx={{ minWidth: 118 }} |  | ||||||
|             > |  | ||||||
|                 {`${input === null ? 'no value' : input}`} |  | ||||||
|             </Typography> |  | ||||||
|             <Box |  | ||||||
|                 sx={{ |  | ||||||
|                     flexGrow: 1, |  | ||||||
|                     flexDirection: 'column', |  | ||||||
|                 }} |  | ||||||
|             > |  | ||||||
|                 <Box sx={{ flexGrow: 1 }}> |  | ||||||
|                     <ConditionallyRender |  | ||||||
|                         condition={Boolean(requiredError)} |  | ||||||
|                         show={ |  | ||||||
|                             <> |  | ||||||
|                                 <Typography |  | ||||||
|                                     component='span' |  | ||||||
|                                     color={theme.palette.error.main} |  | ||||||
|                                 > |  | ||||||
|                                     {' required parameter '} |  | ||||||
|                                 </Typography> |  | ||||||
|                                 <StringTruncator |  | ||||||
|                                     maxWidth='300' |  | ||||||
|                                     text={text} |  | ||||||
|                                     maxLength={50} |  | ||||||
|                                 /> |  | ||||||
|                                 <Typography |  | ||||||
|                                     component='span' |  | ||||||
|                                     color={theme.palette.error.main} |  | ||||||
|                                 > |  | ||||||
|                                     {' is not set '} |  | ||||||
|                                 </Typography> |  | ||||||
|                             </> |  | ||||||
|                         } |  | ||||||
|                         elseShow={ |  | ||||||
|                             <> |  | ||||||
|                                 <Typography |  | ||||||
|                                     component='span' |  | ||||||
|                                     color='text.disabled' |  | ||||||
|                                 > |  | ||||||
|                                     {' set on parameter '} |  | ||||||
|                                 </Typography> |  | ||||||
|                                 <StringTruncator |  | ||||||
|                                     maxWidth='300' |  | ||||||
|                                     text={text} |  | ||||||
|                                     maxLength={50} |  | ||||||
|                                 /> |  | ||||||
|                             </> |  | ||||||
|                         } |  | ||||||
|                     /> |  | ||||||
|                 </Box> |  | ||||||
|             </Box> |  | ||||||
|             <ConditionallyRender |  | ||||||
|                 condition={Boolean(requiredError)} |  | ||||||
|                 show={<CancelOutlined color={'error'} />} |  | ||||||
|                 elseShow={<div />} |  | ||||||
|             /> |  | ||||||
|         </StyledWrapper> |  | ||||||
|     ); |  | ||||||
| }; |  | ||||||
| @ -1,115 +0,0 @@ | |||||||
| import { Fragment, type VFC } from 'react'; |  | ||||||
| import { |  | ||||||
|     parseParameterNumber, |  | ||||||
|     parseParameterString, |  | ||||||
|     parseParameterStrings, |  | ||||||
| } from 'utils/parseParameter'; |  | ||||||
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; |  | ||||||
| import { StrategySeparator } from 'component/common/StrategySeparator/LegacyStrategySeparator'; |  | ||||||
| import { useStrategies } from 'hooks/api/getters/useStrategies/useStrategies'; |  | ||||||
| import { CustomParameterItem } from './CustomParameterItem/CustomParameterItem.tsx'; |  | ||||||
| 
 |  | ||||||
| interface ICustomStrategyProps { |  | ||||||
|     parameters: { [key: string]: string }; |  | ||||||
|     strategyName: string; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export const CustomStrategyParams: VFC<ICustomStrategyProps> = ({ |  | ||||||
|     strategyName, |  | ||||||
|     parameters, |  | ||||||
| }) => { |  | ||||||
|     const { strategies } = useStrategies(); |  | ||||||
|     const definition = strategies.find((strategyDefinition) => { |  | ||||||
|         return strategyDefinition.name === strategyName; |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     if (!definition?.editable) { |  | ||||||
|         return null; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     const items = definition?.parameters.map((param) => { |  | ||||||
|         const paramValue = parameters[param.name]; |  | ||||||
|         const isRequired = param.required; |  | ||||||
| 
 |  | ||||||
|         switch (param?.type) { |  | ||||||
|             case 'list': { |  | ||||||
|                 const values = parseParameterStrings(paramValue); |  | ||||||
|                 return ( |  | ||||||
|                     <CustomParameterItem |  | ||||||
|                         isRequired={isRequired} |  | ||||||
|                         text={param.name} |  | ||||||
|                         input={values?.length > 0 ? values.join(', ') : null} |  | ||||||
|                     /> |  | ||||||
|                 ); |  | ||||||
|             } |  | ||||||
|             case 'percentage': { |  | ||||||
|                 const percentage = parseParameterNumber(paramValue); |  | ||||||
|                 const correctPercentage = !( |  | ||||||
|                     paramValue === undefined || |  | ||||||
|                     paramValue === '' || |  | ||||||
|                     percentage < 0 || |  | ||||||
|                     percentage > 100 |  | ||||||
|                 ); |  | ||||||
|                 return ( |  | ||||||
|                     <CustomParameterItem |  | ||||||
|                         text={param.name} |  | ||||||
|                         isRequired={isRequired} |  | ||||||
|                         input={correctPercentage ? `${percentage}%` : undefined} |  | ||||||
|                     /> |  | ||||||
|                 ); |  | ||||||
|             } |  | ||||||
|             case 'boolean': { |  | ||||||
|                 const bool = ['true', 'false'].includes(paramValue) |  | ||||||
|                     ? paramValue |  | ||||||
|                     : undefined; |  | ||||||
|                 return ( |  | ||||||
|                     <CustomParameterItem |  | ||||||
|                         isRequired={isRequired} |  | ||||||
|                         text={param.name} |  | ||||||
|                         input={paramValue !== undefined ? bool : undefined} |  | ||||||
|                     /> |  | ||||||
|                 ); |  | ||||||
|             } |  | ||||||
|             case 'string': { |  | ||||||
|                 const value = parseParameterString(paramValue); |  | ||||||
|                 return ( |  | ||||||
|                     <CustomParameterItem |  | ||||||
|                         text={param.name} |  | ||||||
|                         isRequired={isRequired} |  | ||||||
|                         input={value !== undefined ? value : undefined} |  | ||||||
|                     /> |  | ||||||
|                 ); |  | ||||||
|             } |  | ||||||
|             case 'number': { |  | ||||||
|                 const isCorrect = !( |  | ||||||
|                     paramValue === undefined || paramValue === '' |  | ||||||
|                 ); |  | ||||||
|                 const number = parseParameterNumber(paramValue); |  | ||||||
|                 return ( |  | ||||||
|                     <CustomParameterItem |  | ||||||
|                         text={param.name} |  | ||||||
|                         isRequired={isRequired} |  | ||||||
|                         input={isCorrect ? `${number}` : undefined} |  | ||||||
|                     /> |  | ||||||
|                 ); |  | ||||||
|             } |  | ||||||
|             case 'default': |  | ||||||
|                 return null; |  | ||||||
|         } |  | ||||||
|         return null; |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     return ( |  | ||||||
|         <> |  | ||||||
|             {items.map((item, index) => ( |  | ||||||
|                 <Fragment key={index}> |  | ||||||
|                     <ConditionallyRender |  | ||||||
|                         condition={index > 0} |  | ||||||
|                         show={<StrategySeparator text='AND' />} |  | ||||||
|                     /> |  | ||||||
|                     {item} |  | ||||||
|                 </Fragment> |  | ||||||
|             ))} |  | ||||||
|         </> |  | ||||||
|     ); |  | ||||||
| }; |  | ||||||
| @ -1,92 +0,0 @@ | |||||||
| 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 { PlaygroundResultStrategyExecutionParameters } from './StrategyExecutionParameters/StrategyExecutionParameters.tsx'; |  | ||||||
| import { CustomStrategyParams } from './CustomStrategyParams/CustomStrategyParams.tsx'; |  | ||||||
| import { formattedStrategyNames } from 'utils/strategyNames'; |  | ||||||
| import { StyledBoxSummary } from './StrategyExecution.styles'; |  | ||||||
| import { Badge } from 'component/common/Badge/Badge'; |  | ||||||
| import { ConstraintExecutionWithoutResults } from './ConstraintExecution/ConstraintExecutionWithoutResults.tsx'; |  | ||||||
| import { SegmentExecutionWithoutResult } from './SegmentExecution/SegmentExecutionWithoutResult.tsx'; |  | ||||||
| 
 |  | ||||||
| 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} |  | ||||||
|                 disabled |  | ||||||
|             /> |  | ||||||
|         ), |  | ||||||
|         hasCustomStrategyParameters && ( |  | ||||||
|             <CustomStrategyParams strategyName={name} parameters={parameters} /> |  | ||||||
|         ), |  | ||||||
|         name === 'default' && ( |  | ||||||
|             <StyledBoxSummary |  | ||||||
|                 sx={(theme) => ({ |  | ||||||
|                     width: '100%', |  | ||||||
|                     color: theme.palette.text.secondary, |  | ||||||
|                 })} |  | ||||||
|             > |  | ||||||
|                 The standard strategy is <Badge color={'disabled'}>ON</Badge>{' '} |  | ||||||
|                 for all users. |  | ||||||
|             </StyledBoxSummary> |  | ||||||
|         ), |  | ||||||
|     ].filter(Boolean); |  | ||||||
| 
 |  | ||||||
|     return ( |  | ||||||
|         <StyledStrategyExecutionWrapper> |  | ||||||
|             {items.map((item, index) => ( |  | ||||||
|                 <Fragment key={index}> |  | ||||||
|                     <ConditionallyRender |  | ||||||
|                         condition={ |  | ||||||
|                             index > 0 && |  | ||||||
|                             (strategyResult.name === 'flexibleRollout' |  | ||||||
|                                 ? index < items.length |  | ||||||
|                                 : index < items.length - 1) |  | ||||||
|                         } |  | ||||||
|                         show={<StrategySeparator text='AND' />} |  | ||||||
|                     /> |  | ||||||
|                     {item} |  | ||||||
|                 </Fragment> |  | ||||||
|             ))} |  | ||||||
|         </StyledStrategyExecutionWrapper> |  | ||||||
|     ); |  | ||||||
| }; |  | ||||||
| @ -1,65 +0,0 @@ | |||||||
| import type { IReleasePlanMilestoneStrategy } from 'interfaces/releasePlans'; |  | ||||||
| import { type DragEventHandler, type RefObject, useRef } from 'react'; |  | ||||||
| import { Box, IconButton } from '@mui/material'; |  | ||||||
| import Edit from '@mui/icons-material/Edit'; |  | ||||||
| import Delete from '@mui/icons-material/DeleteOutlined'; |  | ||||||
| import { StrategySeparator } from 'component/common/StrategySeparator/LegacyStrategySeparator'; |  | ||||||
| import { MilestoneStrategyItem } from './MilestoneStrategyItem.tsx'; |  | ||||||
| 
 |  | ||||||
| interface IMilestoneStrategyDraggableItemProps { |  | ||||||
|     strategy: Omit<IReleasePlanMilestoneStrategy, 'milestoneId'>; |  | ||||||
|     index: number; |  | ||||||
|     isDragging?: boolean; |  | ||||||
|     onDragStartRef: ( |  | ||||||
|         ref: RefObject<HTMLDivElement>, |  | ||||||
|         index: number, |  | ||||||
|     ) => DragEventHandler<HTMLButtonElement>; |  | ||||||
|     onDragOver: ( |  | ||||||
|         ref: RefObject<HTMLDivElement>, |  | ||||||
|         index: number, |  | ||||||
|     ) => DragEventHandler<HTMLDivElement>; |  | ||||||
|     onDragEnd: () => void; |  | ||||||
|     onDeleteClick: () => void; |  | ||||||
|     onEditClick: () => void; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export const MilestoneStrategyDraggableItem = ({ |  | ||||||
|     strategy, |  | ||||||
|     index, |  | ||||||
|     isDragging, |  | ||||||
|     onDragStartRef, |  | ||||||
|     onDragOver, |  | ||||||
|     onDragEnd, |  | ||||||
|     onDeleteClick, |  | ||||||
|     onEditClick, |  | ||||||
| }: IMilestoneStrategyDraggableItemProps) => { |  | ||||||
|     const ref = useRef<HTMLDivElement>(null); |  | ||||||
|     return ( |  | ||||||
|         <Box |  | ||||||
|             key={strategy.id} |  | ||||||
|             ref={ref} |  | ||||||
|             onDragOver={onDragOver(ref, index)} |  | ||||||
|             sx={{ opacity: isDragging ? '0.5' : '1' }} |  | ||||||
|         > |  | ||||||
|             {index > 0 && <StrategySeparator text='OR' />} |  | ||||||
|             <MilestoneStrategyItem |  | ||||||
|                 strategy={strategy} |  | ||||||
|                 onDragStart={onDragStartRef(ref, index)} |  | ||||||
|                 onDragEnd={onDragEnd} |  | ||||||
|                 actions={ |  | ||||||
|                     <> |  | ||||||
|                         <IconButton title='Edit strategy' onClick={onEditClick}> |  | ||||||
|                             <Edit /> |  | ||||||
|                         </IconButton> |  | ||||||
|                         <IconButton |  | ||||||
|                             title='Remove release plan' |  | ||||||
|                             onClick={onDeleteClick} |  | ||||||
|                         > |  | ||||||
|                             <Delete /> |  | ||||||
|                         </IconButton> |  | ||||||
|                     </> |  | ||||||
|                 } |  | ||||||
|             /> |  | ||||||
|         </Box> |  | ||||||
|     ); |  | ||||||
| }; |  | ||||||
| @ -1,101 +0,0 @@ | |||||||
| import { Box, IconButton, styled } from '@mui/material'; |  | ||||||
| import { VariantsSplitPreview } from 'component/common/VariantsSplitPreview/VariantsSplitPreview'; |  | ||||||
| import { |  | ||||||
|     formatStrategyName, |  | ||||||
|     getFeatureStrategyIcon, |  | ||||||
| } from 'utils/strategyNames'; |  | ||||||
| import type { IFeatureStrategy } from 'interfaces/strategy'; |  | ||||||
| import { StrategyExecution } from 'component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyExecution/StrategyExecution'; |  | ||||||
| import type { DragEventHandler, ReactNode } from 'react'; |  | ||||||
| import DragIndicator from '@mui/icons-material/DragIndicator'; |  | ||||||
| 
 |  | ||||||
| const StyledStrategy = styled('div')(({ theme }) => ({ |  | ||||||
|     background: theme.palette.background.paper, |  | ||||||
| })); |  | ||||||
| 
 |  | ||||||
| const DragIcon = styled(IconButton)({ |  | ||||||
|     padding: 0, |  | ||||||
|     cursor: 'inherit', |  | ||||||
|     transition: 'color 0.2s ease-in-out', |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| const StyledHeader = styled('div', { |  | ||||||
|     shouldForwardProp: (prop) => prop !== 'draggable', |  | ||||||
| })<{ draggable: boolean }>(({ theme, draggable }) => ({ |  | ||||||
|     display: 'flex', |  | ||||||
|     padding: theme.spacing(2), |  | ||||||
|     gap: theme.spacing(1), |  | ||||||
|     alignItems: 'center', |  | ||||||
|     color: theme.palette.text.primary, |  | ||||||
|     '& > svg': { |  | ||||||
|         fill: theme.palette.action.disabled, |  | ||||||
|     }, |  | ||||||
|     borderBottom: `1px solid ${theme.palette.divider}`, |  | ||||||
| })); |  | ||||||
| 
 |  | ||||||
| const StyledStrategyExecution = styled('div')(({ theme }) => ({ |  | ||||||
|     padding: theme.spacing(2), |  | ||||||
| })); |  | ||||||
| 
 |  | ||||||
| interface IReleasePlanMilestoneStrategyProps { |  | ||||||
|     strategy: IFeatureStrategy; |  | ||||||
|     onDragStart?: DragEventHandler<HTMLButtonElement>; |  | ||||||
|     onDragEnd?: DragEventHandler<HTMLButtonElement>; |  | ||||||
|     actions?: ReactNode; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export const MilestoneStrategyItem = ({ |  | ||||||
|     strategy, |  | ||||||
|     onDragStart, |  | ||||||
|     onDragEnd, |  | ||||||
|     actions, |  | ||||||
| }: IReleasePlanMilestoneStrategyProps) => { |  | ||||||
|     const Icon = getFeatureStrategyIcon(strategy.strategyName); |  | ||||||
| 
 |  | ||||||
|     return ( |  | ||||||
|         <StyledStrategy> |  | ||||||
|             <StyledHeader draggable={Boolean(onDragStart)}> |  | ||||||
|                 <DragIcon |  | ||||||
|                     draggable |  | ||||||
|                     disableRipple |  | ||||||
|                     size='small' |  | ||||||
|                     onDragStart={onDragStart} |  | ||||||
|                     onDragEnd={onDragEnd} |  | ||||||
|                     sx={{ cursor: 'move' }} |  | ||||||
|                 > |  | ||||||
|                     <DragIndicator |  | ||||||
|                         titleAccess='Drag to reorder' |  | ||||||
|                         cursor='grab' |  | ||||||
|                         sx={{ color: 'action.active' }} |  | ||||||
|                     /> |  | ||||||
|                 </DragIcon> |  | ||||||
|                 <Icon /> |  | ||||||
|                 {`${formatStrategyName(String(strategy.strategyName))}${strategy.title ? `: ${strategy.title}` : ''}`} |  | ||||||
|                 <Box |  | ||||||
|                     sx={{ |  | ||||||
|                         marginLeft: 'auto', |  | ||||||
|                         display: 'flex', |  | ||||||
|                         minHeight: (theme) => theme.spacing(6), |  | ||||||
|                         alignItems: 'center', |  | ||||||
|                     }} |  | ||||||
|                 > |  | ||||||
|                     {actions} |  | ||||||
|                 </Box> |  | ||||||
|             </StyledHeader> |  | ||||||
|             <StyledStrategyExecution> |  | ||||||
|                 <StrategyExecution strategy={strategy} /> |  | ||||||
|                 {strategy.variants && |  | ||||||
|                     strategy.variants.length > 0 && |  | ||||||
|                     (strategy.disabled ? ( |  | ||||||
|                         <Box sx={{ opacity: '0.5' }}> |  | ||||||
|                             <VariantsSplitPreview |  | ||||||
|                                 variants={strategy.variants} |  | ||||||
|                             /> |  | ||||||
|                         </Box> |  | ||||||
|                     ) : ( |  | ||||||
|                         <VariantsSplitPreview variants={strategy.variants} /> |  | ||||||
|                     ))} |  | ||||||
|             </StyledStrategyExecution> |  | ||||||
|         </StyledStrategy> |  | ||||||
|     ); |  | ||||||
| }; |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user