mirror of
https://github.com/Unleash/unleash.git
synced 2025-05-17 01:17:29 +02:00
feat: release plan review dialogue (#9712)
This commit is contained in:
parent
1930c0f408
commit
6c74c994aa
@ -68,7 +68,7 @@ const StyledTopRow = styled('div')(({ theme }) => ({
|
||||
interface IFeatureReleasePlanCardProps {
|
||||
template: IReleasePlanTemplate;
|
||||
onClick: () => void;
|
||||
onPreviewClick?: (e: React.MouseEvent) => void;
|
||||
onPreviewClick: (e: React.MouseEvent) => void;
|
||||
}
|
||||
|
||||
export const FeatureReleasePlanCard = ({
|
||||
@ -85,9 +85,7 @@ export const FeatureReleasePlanCard = ({
|
||||
|
||||
const handlePreviewClick = (e: React.MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
if (onPreviewClick) {
|
||||
onPreviewClick(e);
|
||||
}
|
||||
onPreviewClick(e);
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -14,7 +14,6 @@ import type { IReleasePlanTemplate } from 'interfaces/releasePlans';
|
||||
import { useChangeRequestApi } from 'hooks/api/actions/useChangeRequestApi/useChangeRequestApi';
|
||||
import { usePendingChangeRequests } from 'hooks/api/getters/usePendingChangeRequests/usePendingChangeRequests';
|
||||
import useToast from 'hooks/useToast';
|
||||
import { ReleasePlanAddDialog } from 'component/feature/FeatureView/FeatureOverview/ReleasePlan/ReleasePlanAddDialog';
|
||||
import { useReleasePlansApi } from 'hooks/api/actions/useReleasePlansApi/useReleasePlansApi';
|
||||
import { useReleasePlans } from 'hooks/api/getters/useReleasePlans/useReleasePlans';
|
||||
import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled';
|
||||
@ -22,6 +21,8 @@ import { formatUnknownError } from 'utils/formatUnknownError';
|
||||
import { useUiFlag } from 'hooks/useUiFlag';
|
||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||
import { OldFeatureStrategyMenuCards } from './FeatureStrategyMenuCards/OldFeatureStrategyMenuCards';
|
||||
import { ReleasePlanReviewDialog } from '../../FeatureView/FeatureOverview/ReleasePlan/ReleasePlanReviewDialog';
|
||||
import { ReleasePlanAddDialog } from '../../FeatureView/FeatureOverview/ReleasePlan/ReleasePlanAddDialog';
|
||||
|
||||
interface IFeatureStrategyMenuProps {
|
||||
label: string;
|
||||
@ -104,16 +105,14 @@ export const FeatureStrategyMenu = ({
|
||||
setAnchor(event.currentTarget);
|
||||
};
|
||||
|
||||
const addReleasePlan = async () => {
|
||||
if (!selectedTemplate) return;
|
||||
|
||||
const addReleasePlan = async (template: IReleasePlanTemplate) => {
|
||||
try {
|
||||
if (crProtected) {
|
||||
await addChange(projectId, environmentId, {
|
||||
feature: featureId,
|
||||
action: 'addReleasePlan',
|
||||
payload: {
|
||||
templateId: selectedTemplate.id,
|
||||
templateId: template.id,
|
||||
},
|
||||
});
|
||||
|
||||
@ -126,7 +125,7 @@ export const FeatureStrategyMenu = ({
|
||||
} else {
|
||||
await addReleasePlanToFeature(
|
||||
featureId,
|
||||
selectedTemplate.id,
|
||||
template.id,
|
||||
projectId,
|
||||
environmentId,
|
||||
);
|
||||
@ -141,7 +140,7 @@ export const FeatureStrategyMenu = ({
|
||||
trackEvent('release-management', {
|
||||
props: {
|
||||
eventType: 'add-plan',
|
||||
plan: selectedTemplate.name,
|
||||
plan: template.name,
|
||||
},
|
||||
});
|
||||
} catch (error: unknown) {
|
||||
@ -240,6 +239,10 @@ export const FeatureStrategyMenu = ({
|
||||
environmentId={environmentId}
|
||||
onlyReleasePlans={onlyReleasePlans}
|
||||
onAddReleasePlan={(template) => {
|
||||
setSelectedTemplate(template);
|
||||
addReleasePlan(template);
|
||||
}}
|
||||
onReviewReleasePlan={(template) => {
|
||||
setSelectedTemplate(template);
|
||||
setAddReleasePlanOpen(true);
|
||||
}}
|
||||
@ -258,18 +261,33 @@ export const FeatureStrategyMenu = ({
|
||||
/>
|
||||
)}
|
||||
</Popover>
|
||||
{selectedTemplate && (
|
||||
<ReleasePlanAddDialog
|
||||
open={addReleasePlanOpen}
|
||||
setOpen={setAddReleasePlanOpen}
|
||||
onConfirm={addReleasePlan}
|
||||
template={selectedTemplate}
|
||||
projectId={projectId}
|
||||
featureName={featureId}
|
||||
environment={environmentId}
|
||||
crProtected={crProtected}
|
||||
/>
|
||||
)}
|
||||
{selectedTemplate &&
|
||||
(newStrategyDropdownEnabled ? (
|
||||
<ReleasePlanReviewDialog
|
||||
open={addReleasePlanOpen}
|
||||
setOpen={setAddReleasePlanOpen}
|
||||
onConfirm={() => {
|
||||
addReleasePlan(selectedTemplate);
|
||||
}}
|
||||
template={selectedTemplate}
|
||||
projectId={projectId}
|
||||
featureName={featureId}
|
||||
environment={environmentId}
|
||||
crProtected={crProtected}
|
||||
/>
|
||||
) : (
|
||||
<ReleasePlanAddDialog
|
||||
open={addReleasePlanOpen}
|
||||
setOpen={setAddReleasePlanOpen}
|
||||
onConfirm={() => {
|
||||
addReleasePlan(selectedTemplate);
|
||||
}}
|
||||
template={selectedTemplate}
|
||||
projectId={projectId}
|
||||
featureName={featureId}
|
||||
environment={environmentId}
|
||||
/>
|
||||
))}
|
||||
</StyledStrategyMenu>
|
||||
);
|
||||
};
|
||||
|
@ -23,6 +23,7 @@ interface IFeatureStrategyMenuCardsProps {
|
||||
environmentId: string;
|
||||
onlyReleasePlans: boolean;
|
||||
onAddReleasePlan: (template: IReleasePlanTemplate) => void;
|
||||
onReviewReleasePlan: (template: IReleasePlanTemplate) => void;
|
||||
onClose?: () => void;
|
||||
}
|
||||
|
||||
@ -141,6 +142,7 @@ export const FeatureStrategyMenuCards = ({
|
||||
environmentId,
|
||||
onlyReleasePlans,
|
||||
onAddReleasePlan,
|
||||
onReviewReleasePlan,
|
||||
onClose,
|
||||
}: IFeatureStrategyMenuCardsProps) => {
|
||||
const { strategies } = useStrategies();
|
||||
@ -239,6 +241,9 @@ export const FeatureStrategyMenuCards = ({
|
||||
onClick={() =>
|
||||
onAddReleasePlan(template)
|
||||
}
|
||||
onPreviewClick={() =>
|
||||
onReviewReleasePlan(template)
|
||||
}
|
||||
/>
|
||||
</CardWrapper>
|
||||
))}
|
||||
|
@ -0,0 +1,148 @@
|
||||
import type { IReleasePlanTemplate } from 'interfaces/releasePlans';
|
||||
import { ReleasePlan } from './ReleasePlan';
|
||||
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 ReleasePlanReviewDialog = ({
|
||||
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>
|
||||
);
|
||||
};
|
Loading…
Reference in New Issue
Block a user