mirror of
https://github.com/Unleash/unleash.git
synced 2025-04-24 01:18:01 +02:00
chore: release plan replacement UI (#9400)
This commit is contained in:
parent
da91ae6afe
commit
8d0820fc8b
@ -1,5 +1,5 @@
|
||||
import type React from 'react';
|
||||
import type { FC, ReactNode } from 'react';
|
||||
import { useRef, useState, type FC, type ReactNode } from 'react';
|
||||
import { Box, styled, Typography } from '@mui/material';
|
||||
import type {
|
||||
ChangeRequestState,
|
||||
@ -13,6 +13,7 @@ import { TooltipLink } from 'component/common/TooltipLink/TooltipLink';
|
||||
import EventDiff from 'component/events/EventDiff/EventDiff';
|
||||
import { ReleasePlan } from 'component/feature/FeatureView/FeatureOverview/ReleasePlan/ReleasePlan';
|
||||
import { ReleasePlanMilestone } from 'component/feature/FeatureView/FeatureOverview/ReleasePlan/ReleasePlanMilestone/ReleasePlanMilestone';
|
||||
import type { IReleasePlan } from 'interfaces/releasePlans';
|
||||
|
||||
export const ChangeItemWrapper = styled(Box)({
|
||||
display: 'flex',
|
||||
@ -55,26 +56,10 @@ const StyledCodeSection = styled('div')(({ theme }) => ({
|
||||
|
||||
const DeleteReleasePlan: FC<{
|
||||
change: IChangeRequestDeleteReleasePlan;
|
||||
environmentName: string;
|
||||
featureName: string;
|
||||
projectId: string;
|
||||
currentReleasePlan?: IReleasePlan;
|
||||
changeRequestState: ChangeRequestState;
|
||||
actions?: ReactNode;
|
||||
}> = ({
|
||||
change,
|
||||
environmentName,
|
||||
featureName,
|
||||
projectId,
|
||||
changeRequestState,
|
||||
actions,
|
||||
}) => {
|
||||
const { releasePlans } = useReleasePlans(
|
||||
projectId,
|
||||
featureName,
|
||||
environmentName,
|
||||
);
|
||||
const currentReleasePlan = releasePlans[0];
|
||||
|
||||
}> = ({ change, currentReleasePlan, changeRequestState, actions }) => {
|
||||
const releasePlan =
|
||||
changeRequestState === 'Applied' && change.payload.snapshot
|
||||
? change.payload.snapshot
|
||||
@ -104,26 +89,10 @@ const DeleteReleasePlan: FC<{
|
||||
|
||||
const StartMilestone: FC<{
|
||||
change: IChangeRequestStartMilestone;
|
||||
environmentName: string;
|
||||
featureName: string;
|
||||
projectId: string;
|
||||
currentReleasePlan?: IReleasePlan;
|
||||
changeRequestState: ChangeRequestState;
|
||||
actions?: ReactNode;
|
||||
}> = ({
|
||||
change,
|
||||
environmentName,
|
||||
featureName,
|
||||
projectId,
|
||||
changeRequestState,
|
||||
actions,
|
||||
}) => {
|
||||
const { releasePlans } = useReleasePlans(
|
||||
projectId,
|
||||
featureName,
|
||||
environmentName,
|
||||
);
|
||||
const currentReleasePlan = releasePlans[0];
|
||||
|
||||
}> = ({ change, currentReleasePlan, changeRequestState, actions }) => {
|
||||
const releasePlan =
|
||||
changeRequestState === 'Applied' && change.payload.snapshot
|
||||
? change.payload.snapshot
|
||||
@ -177,24 +146,107 @@ const StartMilestone: FC<{
|
||||
|
||||
const AddReleasePlan: FC<{
|
||||
change: IChangeRequestAddReleasePlan;
|
||||
currentReleasePlan?: IReleasePlan;
|
||||
environmentName: string;
|
||||
featureName: string;
|
||||
actions?: ReactNode;
|
||||
}> = ({ change, environmentName, featureName, actions }) => {
|
||||
}> = ({
|
||||
change,
|
||||
currentReleasePlan,
|
||||
environmentName,
|
||||
featureName,
|
||||
actions,
|
||||
}) => {
|
||||
const [currentTooltipOpen, setCurrentTooltipOpen] = useState(false);
|
||||
const currentTooltipCloseTimeoutRef = useRef<NodeJS.Timeout>();
|
||||
const openCurrentTooltip = () => {
|
||||
if (currentTooltipCloseTimeoutRef.current) {
|
||||
clearTimeout(currentTooltipCloseTimeoutRef.current);
|
||||
}
|
||||
setCurrentTooltipOpen(true);
|
||||
};
|
||||
const closeCurrentTooltip = () => {
|
||||
currentTooltipCloseTimeoutRef.current = setTimeout(() => {
|
||||
setCurrentTooltipOpen(false);
|
||||
}, 100);
|
||||
};
|
||||
|
||||
const planPreview = useReleasePlanPreview(
|
||||
change.payload.templateId,
|
||||
featureName,
|
||||
environmentName,
|
||||
);
|
||||
|
||||
const planPreviewDiff = {
|
||||
...planPreview,
|
||||
discriminator: 'plan',
|
||||
releasePlanTemplateId: change.payload.templateId,
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ChangeItemCreateEditDeleteWrapper>
|
||||
<ChangeItemInfo>
|
||||
<Typography color='success.dark'>
|
||||
+ Adding release plan:
|
||||
</Typography>
|
||||
{currentReleasePlan ? (
|
||||
<Typography>
|
||||
Replacing{' '}
|
||||
<TooltipLink
|
||||
tooltip={
|
||||
<div
|
||||
onMouseEnter={() =>
|
||||
openCurrentTooltip()
|
||||
}
|
||||
onMouseLeave={() =>
|
||||
closeCurrentTooltip()
|
||||
}
|
||||
>
|
||||
<ReleasePlan
|
||||
plan={currentReleasePlan}
|
||||
readonly
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
tooltipProps={{
|
||||
open: currentTooltipOpen,
|
||||
maxWidth: 500,
|
||||
maxHeight: 600,
|
||||
}}
|
||||
>
|
||||
<span
|
||||
onMouseEnter={() => openCurrentTooltip()}
|
||||
onMouseLeave={() => closeCurrentTooltip()}
|
||||
>
|
||||
current
|
||||
</span>
|
||||
</TooltipLink>{' '}
|
||||
release plan with:
|
||||
</Typography>
|
||||
) : (
|
||||
<Typography color='success.dark'>
|
||||
+ Adding release plan:
|
||||
</Typography>
|
||||
)}
|
||||
<Typography>{planPreview.name}</Typography>
|
||||
{currentReleasePlan && (
|
||||
<TooltipLink
|
||||
tooltip={
|
||||
<StyledCodeSection>
|
||||
<EventDiff
|
||||
entry={{
|
||||
preData: currentReleasePlan,
|
||||
data: planPreviewDiff,
|
||||
}}
|
||||
/>
|
||||
</StyledCodeSection>
|
||||
}
|
||||
tooltipProps={{
|
||||
maxWidth: 500,
|
||||
maxHeight: 600,
|
||||
}}
|
||||
>
|
||||
<ViewDiff>View Diff</ViewDiff>
|
||||
</TooltipLink>
|
||||
)}
|
||||
</ChangeItemInfo>
|
||||
<div>{actions}</div>
|
||||
</ChangeItemCreateEditDeleteWrapper>
|
||||
@ -221,11 +273,19 @@ export const ReleasePlanChange: FC<{
|
||||
projectId,
|
||||
changeRequestState,
|
||||
}) => {
|
||||
const { releasePlans } = useReleasePlans(
|
||||
projectId,
|
||||
featureName,
|
||||
environmentName,
|
||||
);
|
||||
const currentReleasePlan = releasePlans[0];
|
||||
|
||||
return (
|
||||
<>
|
||||
{change.action === 'addReleasePlan' && (
|
||||
<AddReleasePlan
|
||||
change={change}
|
||||
currentReleasePlan={currentReleasePlan}
|
||||
environmentName={environmentName}
|
||||
featureName={featureName}
|
||||
actions={actions}
|
||||
@ -234,9 +294,7 @@ export const ReleasePlanChange: FC<{
|
||||
{change.action === 'deleteReleasePlan' && (
|
||||
<DeleteReleasePlan
|
||||
change={change}
|
||||
environmentName={environmentName}
|
||||
featureName={featureName}
|
||||
projectId={projectId}
|
||||
currentReleasePlan={currentReleasePlan}
|
||||
changeRequestState={changeRequestState}
|
||||
actions={actions}
|
||||
/>
|
||||
@ -244,9 +302,7 @@ export const ReleasePlanChange: FC<{
|
||||
{change.action === 'startMilestone' && (
|
||||
<StartMilestone
|
||||
change={change}
|
||||
environmentName={environmentName}
|
||||
featureName={featureName}
|
||||
projectId={projectId}
|
||||
currentReleasePlan={currentReleasePlan}
|
||||
changeRequestState={changeRequestState}
|
||||
actions={actions}
|
||||
/>
|
||||
|
@ -4,6 +4,7 @@ import { ReleasePlan } from './ReleasePlan';
|
||||
import { useReleasePlanPreview } from 'hooks/useReleasePlanPreview';
|
||||
import { styled, Typography, Alert } from '@mui/material';
|
||||
import { useFeature } from 'hooks/api/getters/useFeature/useFeature';
|
||||
import { useReleasePlans } from 'hooks/api/getters/useReleasePlans/useReleasePlans';
|
||||
|
||||
const StyledReleasePlanContainer = styled('div')(({ theme }) => ({
|
||||
margin: theme.spacing(2, 0),
|
||||
@ -30,6 +31,13 @@ export const ReleasePlanAddDialog = ({
|
||||
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,
|
||||
@ -55,6 +63,15 @@ export const ReleasePlanAddDialog = ({
|
||||
onClick={onConfirm}
|
||||
onClose={() => setOpen(false)}
|
||||
>
|
||||
{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>
|
||||
)}
|
||||
{environmentEnabled ? (
|
||||
<Alert severity='info'>
|
||||
This environment is currently <strong>enabled</strong>.
|
||||
@ -70,8 +87,8 @@ export const ReleasePlanAddDialog = ({
|
||||
<Alert severity='warning'>
|
||||
This environment is currently <strong>disabled</strong>.
|
||||
<p>
|
||||
The milestones will not start automatically after adding
|
||||
the release plan. They will remain paused until the
|
||||
Milestones will not start automatically after adding the
|
||||
release plan. They will remain paused until the
|
||||
environment is enabled.
|
||||
</p>
|
||||
</Alert>
|
||||
|
Loading…
Reference in New Issue
Block a user