1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-11-24 20:06:55 +01:00

refactor: extract different milestone button types (#10901)

This commit is contained in:
Mateusz Kwasniewski 2025-10-31 15:02:36 +01:00 committed by GitHub
parent 2458e5d5aa
commit b21c101439
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -10,10 +10,8 @@ export type MilestoneStatus =
| { type: 'paused' } | { type: 'paused' }
| { type: 'completed' }; | { type: 'completed' };
const StyledStatusButton = styled('button', { const BaseStatusButton = styled('button')<{ disabled?: boolean }>(
shouldForwardProp: (prop) => prop !== 'status', ({ theme, disabled }) => ({
})<{ status: MilestoneStatus; disabled?: boolean }>(
({ theme, status, disabled }) => ({
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
border: 'none', border: 'none',
@ -21,41 +19,15 @@ const StyledStatusButton = styled('button', {
padding: 0, padding: 0,
paddingRight: theme.spacing(1), paddingRight: theme.spacing(1),
cursor: 'pointer', cursor: 'pointer',
backgroundColor:
status.type === 'active'
? theme.palette.success.light
: theme.palette.neutral.light,
'&:focus-visible': {
outline: `2px solid ${theme.palette.primary.main}`,
},
'&:hover': {
backgroundColor:
status.type === 'active'
? theme.palette.success.light
: status.type === 'paused'
? 'transparent'
: theme.palette.neutral.light,
textDecoration: 'none',
},
fontSize: theme.fontSizes.smallerBody, fontSize: theme.fontSizes.smallerBody,
lineHeight: theme.fontSizes.smallerBody, lineHeight: theme.fontSizes.smallerBody,
fontWeight: theme.fontWeight.medium, fontWeight: theme.fontWeight.medium,
borderRadius: theme.shape.borderRadiusMedium, borderRadius: theme.shape.borderRadiusMedium,
color: textDecoration: 'none',
status.type === 'active' '&:focus-visible': {
? theme.palette.success.contrastText outline: `2px solid ${theme.palette.primary.main}`,
: status.type === 'paused' },
? theme.palette.text.primary
: theme.palette.primary.main,
'& svg': { '& svg': {
color:
status.type === 'active'
? theme.palette.success.main
: status.type === 'paused'
? theme.palette.text.disabled
: status.type === 'completed'
? theme.palette.neutral.border
: theme.palette.primary.main,
height: theme.spacing(3), height: theme.spacing(3),
width: theme.spacing(3), width: theme.spacing(3),
}, },
@ -65,6 +37,67 @@ const StyledStatusButton = styled('button', {
}), }),
); );
const ActiveStatusButton = styled(BaseStatusButton)(({ theme }) => ({
backgroundColor: theme.palette.success.light,
color: theme.palette.success.contrastText,
'&:hover': {
backgroundColor: theme.palette.success.light,
textDecoration: 'none',
},
'& svg': {
color: theme.palette.success.main,
},
}));
const PausedStatusButton = styled(BaseStatusButton)(({ theme }) => ({
backgroundColor: theme.palette.neutral.light,
color: theme.palette.text.primary,
'&:hover': {
backgroundColor: 'transparent',
textDecoration: 'none',
},
'& svg': {
color: theme.palette.text.disabled,
},
}));
const ScheduledStatusButton = styled(BaseStatusButton)(({ theme }) => ({
backgroundColor: 'transparent',
color: theme.palette.primary.main,
textDecoration: 'underline',
'&:hover': {
backgroundColor: 'transparent',
textDecoration: 'none',
},
'& svg': {
color: theme.palette.primary.main,
},
}));
const DefaultStatusButton = styled(BaseStatusButton)(({ theme }) => ({
backgroundColor: theme.palette.neutral.light,
color: theme.palette.primary.main,
'&:hover': {
backgroundColor: theme.palette.neutral.light,
textDecoration: 'none',
},
'& svg': {
color: theme.palette.primary.main,
},
}));
const CompletedStatusButton = styled(BaseStatusButton)(({ theme }) => ({
backgroundColor: theme.palette.neutral.light,
color: theme.palette.primary.main,
'&:hover': {
backgroundColor: theme.palette.neutral.light,
textDecoration: 'none',
},
'& svg': {
color: theme.palette.neutral.border,
},
}));
interface IReleasePlanMilestoneStatusProps { interface IReleasePlanMilestoneStatusProps {
status: MilestoneStatus; status: MilestoneStatus;
onStartMilestone: () => void; onStartMilestone: () => void;
@ -97,27 +130,48 @@ const getStatusIcon = (status: MilestoneStatus) => {
} }
}; };
const getStatusButton = (
status: MilestoneStatus,
progressionsEnabled: boolean,
) => {
if (status.type === 'active') return ActiveStatusButton;
if (status.type === 'paused') return PausedStatusButton;
if (
progressionsEnabled &&
status.type === 'not-started' &&
status.scheduledAt
) {
return ScheduledStatusButton;
}
if (status.type === 'completed') return CompletedStatusButton;
return DefaultStatusButton;
};
export const ReleasePlanMilestoneStatus = ({ export const ReleasePlanMilestoneStatus = ({
status, status,
onStartMilestone, onStartMilestone,
}: IReleasePlanMilestoneStatusProps) => { }: IReleasePlanMilestoneStatusProps) => {
const milestoneProgressionsEnabled = useUiFlag('milestoneProgression'); const milestoneProgressionsEnabled = useUiFlag('milestoneProgression');
const StatusButton = getStatusButton(status, milestoneProgressionsEnabled);
const statusText = getStatusText(status, milestoneProgressionsEnabled); const statusText = getStatusText(status, milestoneProgressionsEnabled);
const statusIcon = getStatusIcon(status); const statusIcon = getStatusIcon(status);
const disabled = status.type === 'active' || status.type === 'paused'; const disabled = status.type === 'active' || status.type === 'paused';
const isScheduled =
milestoneProgressionsEnabled &&
status.type === 'not-started' &&
status.scheduledAt;
return ( return (
<StyledStatusButton <StatusButton
status={status}
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
onStartMilestone(); onStartMilestone();
}} }}
disabled={disabled} disabled={disabled}
> >
{statusIcon} {!isScheduled && statusIcon}
{statusText} {statusText}
</StyledStatusButton> </StatusButton>
); );
}; };