1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-09-24 17:51:14 +02:00

chore: update release template preview dialog (#10673)

https://linear.app/unleash/issue/2-3888/update-the-release-templates-preview-dialog-to-match-the-new-designs

Updates the release template preview dialog when using the new "add
strategy" modal, so it better matches the new design.

Used the legacy file pattern to leave the previous modal component
unchanged.

<img width="992" height="467" alt="image"
src="https://github.com/user-attachments/assets/fd000822-c987-47be-b8a4-3f137e0291ec"
/>

<img width="979" height="576" alt="image"
src="https://github.com/user-attachments/assets/02a27d5c-4480-4a49-88ae-0d573ff0f640"
/>
This commit is contained in:
Nuno Góis 2025-09-22 14:55:24 +01:00 committed by GitHub
parent 3296add50f
commit f36b39b721
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 228 additions and 73 deletions

View File

@ -19,6 +19,7 @@ import { useReleasePlans } from 'hooks/api/getters/useReleasePlans/useReleasePla
import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled'; import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled';
import { formatUnknownError } from 'utils/formatUnknownError'; import { formatUnknownError } from 'utils/formatUnknownError';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { LegacyReleasePlanReviewDialog } from 'component/feature/FeatureView/FeatureOverview/ReleasePlan/LegacyReleasePlanReviewDialog.tsx';
import { ReleasePlanReviewDialog } from '../../FeatureView/FeatureOverview/ReleasePlan/ReleasePlanReviewDialog.tsx'; import { ReleasePlanReviewDialog } from '../../FeatureView/FeatureOverview/ReleasePlan/ReleasePlanReviewDialog.tsx';
import { import {
FeatureStrategyMenuCards, FeatureStrategyMenuCards,
@ -288,6 +289,8 @@ export const FeatureStrategyMenu = ({
)} )}
</Dialog> </Dialog>
{selectedTemplate && ( {selectedTemplate && (
<>
{newStrategyModalEnabled ? (
<ReleasePlanReviewDialog <ReleasePlanReviewDialog
open={addReleasePlanOpen} open={addReleasePlanOpen}
setOpen={(open) => { setOpen={(open) => {
@ -305,6 +308,26 @@ export const FeatureStrategyMenu = ({
environment={environmentId} environment={environmentId}
crProtected={crProtected} crProtected={crProtected}
/> />
) : (
<LegacyReleasePlanReviewDialog
open={addReleasePlanOpen}
setOpen={(open) => {
setAddReleasePlanOpen(open);
if (!open) {
setIsStrategyMenuDialogOpen(true);
}
}}
onConfirm={() => {
addReleasePlan(selectedTemplate);
}}
template={selectedTemplate}
projectId={projectId}
featureName={featureId}
environment={environmentId}
crProtected={crProtected}
/>
)}
</>
)} )}
</StyledStrategyMenu> </StyledStrategyMenu>
); );

View File

@ -22,7 +22,7 @@ const StyledCard = styled('div', {
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
width: '100%', width: '100%',
height: '100%', height: theme.spacing(10),
maxWidth: '30rem', maxWidth: '30rem',
padding: theme.spacing(2), padding: theme.spacing(2),
color: 'inherit', color: 'inherit',

View File

@ -0,0 +1,148 @@
import type { IReleasePlanTemplate } from 'interfaces/releasePlans';
import { ReleasePlan } from './ReleasePlan.tsx';
import { useReleasePlanPreview } from 'hooks/useReleasePlanPreview';
import {
styled,
Typography,
Alert,
Box,
IconButton,
Dialog,
DialogContent,
DialogActions,
Button,
} from '@mui/material';
import { useFeature } from 'hooks/api/getters/useFeature/useFeature';
import { useReleasePlans } from 'hooks/api/getters/useReleasePlans/useReleasePlans';
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import CloseIcon from '@mui/icons-material/Close';
const StyledDialog = styled(Dialog)(({ theme }) => ({
'& .MuiDialog-paper': {
borderRadius: theme.shape.borderRadiusLarge,
maxWidth: theme.spacing(85),
},
}));
const StyledDialogActions = styled(DialogActions)(({ theme }) => ({
padding: theme.spacing(2, 4, 4),
}));
const TopRow = styled(Box)(({ theme }) => ({
display: 'flex',
justifyContent: 'space-between',
marginBottom: theme.spacing(2),
}));
const BackButton = styled(Box)(({ theme }) => ({
display: 'flex',
alignItems: 'center',
cursor: 'pointer',
}));
const StyledBackIcon = styled(ArrowBackIcon)(({ theme }) => ({
marginRight: theme.spacing(1),
color: theme.palette.primary.main,
display: 'flex',
alignSelf: 'center',
}));
const BackText = styled(Typography)(({ theme }) => ({
fontWeight: theme.typography.fontWeightMedium,
display: 'flex',
alignItems: 'center',
lineHeight: 1,
}));
interface IReleasePlanAddDialogProps {
open: boolean;
setOpen: React.Dispatch<React.SetStateAction<boolean>>;
onConfirm: () => void;
template: IReleasePlanTemplate;
projectId: string;
featureName: string;
environment: string;
crProtected?: boolean;
}
export const LegacyReleasePlanReviewDialog = ({
open,
setOpen,
onConfirm,
template,
projectId,
featureName,
environment,
crProtected,
}: IReleasePlanAddDialogProps) => {
const { feature } = useFeature(projectId, featureName);
const { releasePlans } = useReleasePlans(
projectId,
featureName,
environment,
);
const activeReleasePlan = releasePlans[0];
const environmentData = feature?.environments.find(
({ name }) => name === environment,
);
const environmentEnabled = environmentData?.enabled;
const planPreview = useReleasePlanPreview(
template.id,
featureName,
environment,
);
const handleClose = () => setOpen(false);
return (
<StyledDialog open={open} onClose={handleClose} fullWidth maxWidth='md'>
<DialogContent>
<TopRow>
<BackButton onClick={handleClose}>
<StyledBackIcon />
<BackText variant='body2' color='primary'>
Go back
</BackText>
</BackButton>
<IconButton
size='small'
onClick={handleClose}
edge='end'
aria-label='close'
>
<CloseIcon fontSize='small' />
</IconButton>
</TopRow>
{activeReleasePlan && (
<Alert severity='error' sx={{ mb: 1 }}>
This feature environment currently has{' '}
<strong>{activeReleasePlan.name}</strong> -{' '}
<strong>{activeReleasePlan.milestones[0].name}</strong>
{environmentEnabled ? ' running' : ' paused'}. Adding a
new release plan will replace the existing release plan.
</Alert>
)}
<div>
<ReleasePlan plan={planPreview} readonly />
</div>
{crProtected && (
<Typography sx={{ mt: 4 }}>
<strong>Adding</strong> release template{' '}
<strong>{template?.name}</strong> to{' '}
<strong>{featureName}</strong> in{' '}
<strong>{environment}</strong>.
</Typography>
)}
</DialogContent>
<StyledDialogActions>
<Button variant='contained' color='primary' onClick={onConfirm}>
{crProtected ? 'Add suggestion to draft' : 'Use template'}
</Button>
</StyledDialogActions>
</StyledDialog>
);
};

View File

@ -8,7 +8,6 @@ import {
Box, Box,
IconButton, IconButton,
Dialog, Dialog,
DialogContent,
DialogActions, DialogActions,
Button, Button,
} from '@mui/material'; } from '@mui/material';
@ -16,43 +15,31 @@ import { useFeature } from 'hooks/api/getters/useFeature/useFeature';
import { useReleasePlans } from 'hooks/api/getters/useReleasePlans/useReleasePlans'; import { useReleasePlans } from 'hooks/api/getters/useReleasePlans/useReleasePlans';
import ArrowBackIcon from '@mui/icons-material/ArrowBack'; import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import CloseIcon from '@mui/icons-material/Close'; import CloseIcon from '@mui/icons-material/Close';
import { useUiFlag } from 'hooks/useUiFlag.ts';
const StyledDialog = styled(Dialog)(({ theme }) => ({ const StyledDialog = styled(Dialog)(({ theme }) => ({
'& .MuiDialog-paper': { '& .MuiDialog-paper': {
borderRadius: theme.shape.borderRadiusLarge, borderRadius: theme.shape.borderRadiusLarge,
maxWidth: theme.spacing(85), width: theme.breakpoints.values.md,
}, },
})); }));
const StyledDialogActions = styled(DialogActions)(({ theme }) => ({ const StyledHeader = styled(Box)(({ theme }) => ({
padding: theme.spacing(2, 4, 4),
}));
const TopRow = styled(Box)(({ theme }) => ({
display: 'flex', display: 'flex',
justifyContent: 'space-between', justifyContent: 'space-between',
marginBottom: theme.spacing(2), alignItems: 'center',
padding: theme.spacing(4, 4, 2, 4),
})); }));
const BackButton = styled(Box)(({ theme }) => ({ const StyledSubHeader = styled(Box)(({ theme }) => ({
display: 'flex', padding: theme.spacing(0, 3, 3, 3),
alignItems: 'center',
cursor: 'pointer',
})); }));
const StyledBackIcon = styled(ArrowBackIcon)(({ theme }) => ({ const StyledBackIcon = styled(ArrowBackIcon)(({ theme }) => ({
marginRight: theme.spacing(1), marginRight: theme.spacing(1),
color: theme.palette.primary.main,
display: 'flex',
alignSelf: 'center',
})); }));
const BackText = styled(Typography)(({ theme }) => ({ const StyledDialogActions = styled(DialogActions)(({ theme }) => ({
fontWeight: theme.typography.fontWeightMedium, padding: theme.spacing(2, 4, 4),
display: 'flex',
alignItems: 'center',
lineHeight: 1,
})); }));
interface IReleasePlanAddDialogProps { interface IReleasePlanAddDialogProps {
@ -82,7 +69,6 @@ export const ReleasePlanReviewDialog = ({
featureName, featureName,
environment, environment,
); );
const newStrategyModalEnabled = useUiFlag('newStrategyModal');
const activeReleasePlan = releasePlans[0]; const activeReleasePlan = releasePlans[0];
@ -101,14 +87,8 @@ export const ReleasePlanReviewDialog = ({
return ( return (
<StyledDialog open={open} onClose={handleClose} fullWidth maxWidth='md'> <StyledDialog open={open} onClose={handleClose} fullWidth maxWidth='md'>
<DialogContent> <StyledHeader>
<TopRow> <Typography variant='h2'>Add strategy</Typography>
<BackButton onClick={handleClose}>
<StyledBackIcon />
<BackText variant='body2' color='primary'>
Go back
</BackText>
</BackButton>
<IconButton <IconButton
size='small' size='small'
onClick={handleClose} onClick={handleClose}
@ -117,36 +97,40 @@ export const ReleasePlanReviewDialog = ({
> >
<CloseIcon fontSize='small' /> <CloseIcon fontSize='small' />
</IconButton> </IconButton>
</TopRow> </StyledHeader>
<StyledSubHeader>
<Button variant='text' onClick={handleClose}>
<StyledBackIcon />
Go back
</Button>
</StyledSubHeader>
{activeReleasePlan && ( {activeReleasePlan && (
<Alert severity='error' sx={{ mb: 1 }}> <Box sx={{ px: 4, pb: 2 }}>
<Alert severity='error'>
This feature environment currently has{' '} This feature environment currently has{' '}
<strong>{activeReleasePlan.name}</strong> -{' '} <strong>{activeReleasePlan.name}</strong> -{' '}
<strong>{activeReleasePlan.milestones[0].name}</strong> <strong>{activeReleasePlan.milestones[0].name}</strong>
{environmentEnabled ? ' running' : ' paused'}. Adding a {environmentEnabled ? ' running' : ' paused'}. Adding a
new release plan will replace the existing release plan. new release plan will replace the existing release plan.
</Alert> </Alert>
</Box>
)} )}
<div> <Box sx={{ px: 2 }}>
<ReleasePlan plan={planPreview} readonly /> <ReleasePlan plan={planPreview} readonly />
</div> </Box>
{crProtected && ( {crProtected && (
<Typography sx={{ mt: 4 }}> <Box sx={{ px: 4, pt: 1 }}>
<Typography>
<strong>Adding</strong> release template{' '} <strong>Adding</strong> release template{' '}
<strong>{template?.name}</strong> to{' '} <strong>{template?.name}</strong> to{' '}
<strong>{featureName}</strong> in{' '} <strong>{featureName}</strong> in{' '}
<strong>{environment}</strong>. <strong>{environment}</strong>.
</Typography> </Typography>
</Box>
)} )}
</DialogContent>
<StyledDialogActions> <StyledDialogActions>
<Button variant='contained' color='primary' onClick={onConfirm}> <Button variant='contained' color='primary' onClick={onConfirm}>
{crProtected {crProtected ? 'Add suggestion to draft' : 'Apply template'}
? 'Add suggestion to draft'
: newStrategyModalEnabled
? 'Apply template'
: 'Use template'}
</Button> </Button>
</StyledDialogActions> </StyledDialogActions>
</StyledDialog> </StyledDialog>