mirror of
https://github.com/Unleash/unleash.git
synced 2025-02-04 00:18:01 +01:00
refactor strategy item component for reuse
Co-authored-by: Fredrik Strand Oseberg <fredrik.no@gmail.com>
This commit is contained in:
parent
e75f03b8f2
commit
85858cf11f
@ -0,0 +1,95 @@
|
||||
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;
|
||||
}
|
||||
|
||||
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,
|
||||
}) => {
|
||||
const { classes: styles } = useStyles();
|
||||
const Icon = getFeatureStrategyIcon(strategy.name);
|
||||
|
||||
return (
|
||||
<Box sx={{ position: 'relative' }}>
|
||||
<ConditionallyRender
|
||||
condition={orderNumber !== undefined}
|
||||
show={<StyledIndexLabel>{orderNumber}</StyledIndexLabel>}
|
||||
/>
|
||||
|
||||
<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}>{actions}</div>
|
||||
</div>
|
||||
<div className={styles.body}>{children}</div>
|
||||
</div>
|
||||
</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>
|
||||
);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user