1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-09-28 17:55:15 +02:00
unleash.unleash/frontend/src/component/common/StrategyItemContainer/StrategyItemContainer.tsx
Christopher Kolstad 53354224fc
chore: Bump biome and configure husky (#6589)
Upgrades biome to 1.6.1, and updates husky pre-commit hook.

Most changes here are making type imports explicit.
2024-03-18 13:58:05 +01:00

210 lines
7.3 KiB
TypeScript

import type { DragEventHandler, FC, ReactNode } from 'react';
import DragIndicator from '@mui/icons-material/DragIndicator';
import { Box, IconButton, styled } from '@mui/material';
import type { IFeatureStrategy } from 'interfaces/strategy';
import {
formatStrategyName,
getFeatureStrategyIcon,
} from 'utils/strategyNames';
import StringTruncator from 'component/common/StringTruncator/StringTruncator';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import type { PlaygroundStrategySchema } from 'openapi';
import { Badge } from '../Badge/Badge';
import { Link } from 'react-router-dom';
interface IStrategyItemContainerProps {
strategy: IFeatureStrategy | PlaygroundStrategySchema;
onDragStart?: DragEventHandler<HTMLButtonElement>;
onDragEnd?: DragEventHandler<HTMLButtonElement>;
actions?: ReactNode;
orderNumber?: number;
className?: string;
style?: React.CSSProperties;
description?: string;
}
const DragIcon = styled(IconButton)({
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',
},
}));
const StyledDescription = styled('div')(({ theme }) => ({
fontSize: theme.typography.fontSize,
fontWeight: 'normal',
color: theme.palette.text.secondary,
display: 'none',
top: theme.spacing(2.5),
[theme.breakpoints.up('md')]: {
display: 'block',
},
}));
const StyledCustomTitle = styled('div')(({ theme }) => ({
fontWeight: 'normal',
display: 'none',
[theme.breakpoints.up('md')]: {
display: 'block',
},
}));
const StyledHeaderContainer = styled('div')({
flexDirection: 'column',
justifyContent: 'center',
verticalAlign: 'middle',
});
const StyledContainer = styled(Box, {
shouldForwardProp: (prop) => prop !== 'disabled',
})<{ disabled?: boolean }>(({ theme, disabled }) => ({
borderRadius: theme.shape.borderRadiusMedium,
border: `1px solid ${theme.palette.divider}`,
'& + &': {
marginTop: theme.spacing(2),
},
background: disabled
? theme.palette.envAccordion.disabled
: theme.palette.background.paper,
}));
const StyledHeader = styled('div', {
shouldForwardProp: (prop) => prop !== 'draggable' && prop !== 'disabled',
})<{ draggable: boolean; disabled: boolean }>(
({ theme, draggable, disabled }) => ({
padding: theme.spacing(0.5, 2),
display: 'flex',
gap: theme.spacing(1),
alignItems: 'center',
borderBottom: `1px solid ${theme.palette.divider}`,
fontWeight: theme.typography.fontWeightMedium,
paddingLeft: draggable ? theme.spacing(1) : theme.spacing(2),
color: disabled
? theme.palette.text.secondary
: theme.palette.text.primary,
}),
);
export const StrategyItemContainer: FC<IStrategyItemContainerProps> = ({
strategy,
onDragStart,
onDragEnd,
actions,
children,
orderNumber,
style = {},
description,
}) => {
const Icon = getFeatureStrategyIcon(strategy.name);
const StrategyHeaderLink: React.FC =
'links' in strategy
? ({ children }) => <Link to={strategy.links.edit}>{children}</Link>
: ({ children }) => <> {children} </>;
return (
<Box sx={{ position: 'relative' }}>
<ConditionallyRender
condition={orderNumber !== undefined}
show={<StyledIndexLabel>{orderNumber}</StyledIndexLabel>}
/>
<StyledContainer
disabled={strategy?.disabled || false}
style={style}
>
<StyledHeader
draggable={Boolean(onDragStart)}
disabled={Boolean(strategy?.disabled)}
>
<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: 'action.active' }}
/>
</DragIcon>
)}
/>
<Icon
sx={{
fill: (theme) => theme.palette.action.disabled,
}}
/>
<StyledHeaderContainer>
<StrategyHeaderLink>
<StringTruncator
maxWidth='400'
maxLength={15}
text={formatStrategyName(String(strategy.name))}
/>
<ConditionallyRender
condition={Boolean(strategy.title)}
show={
<StyledCustomTitle>
{formatStrategyName(
String(strategy.title),
)}
</StyledCustomTitle>
}
/>
</StrategyHeaderLink>
<ConditionallyRender
condition={Boolean(description)}
show={
<StyledDescription>
{description}
</StyledDescription>
}
/>
</StyledHeaderContainer>
<ConditionallyRender
condition={Boolean(strategy?.disabled)}
show={() => (
<>
<Badge color='disabled'>Disabled</Badge>
</>
)}
/>
<Box
sx={{
marginLeft: 'auto',
display: 'flex',
minHeight: (theme) => theme.spacing(6),
alignItems: 'center',
}}
>
{actions}
</Box>
</StyledHeader>
<Box
sx={{
p: 2,
justifyItems: 'center',
}}
>
{children}
</Box>
</StyledContainer>
</Box>
);
};