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 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 { Box, styled, Typography } from '@mui/material';
|
||||||
import type {
|
import type {
|
||||||
ChangeRequestState,
|
ChangeRequestState,
|
||||||
@ -13,6 +13,7 @@ import { TooltipLink } from 'component/common/TooltipLink/TooltipLink';
|
|||||||
import EventDiff from 'component/events/EventDiff/EventDiff';
|
import EventDiff from 'component/events/EventDiff/EventDiff';
|
||||||
import { ReleasePlan } from 'component/feature/FeatureView/FeatureOverview/ReleasePlan/ReleasePlan';
|
import { ReleasePlan } from 'component/feature/FeatureView/FeatureOverview/ReleasePlan/ReleasePlan';
|
||||||
import { ReleasePlanMilestone } from 'component/feature/FeatureView/FeatureOverview/ReleasePlan/ReleasePlanMilestone/ReleasePlanMilestone';
|
import { ReleasePlanMilestone } from 'component/feature/FeatureView/FeatureOverview/ReleasePlan/ReleasePlanMilestone/ReleasePlanMilestone';
|
||||||
|
import type { IReleasePlan } from 'interfaces/releasePlans';
|
||||||
|
|
||||||
export const ChangeItemWrapper = styled(Box)({
|
export const ChangeItemWrapper = styled(Box)({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@ -55,26 +56,10 @@ const StyledCodeSection = styled('div')(({ theme }) => ({
|
|||||||
|
|
||||||
const DeleteReleasePlan: FC<{
|
const DeleteReleasePlan: FC<{
|
||||||
change: IChangeRequestDeleteReleasePlan;
|
change: IChangeRequestDeleteReleasePlan;
|
||||||
environmentName: string;
|
currentReleasePlan?: IReleasePlan;
|
||||||
featureName: string;
|
|
||||||
projectId: string;
|
|
||||||
changeRequestState: ChangeRequestState;
|
changeRequestState: ChangeRequestState;
|
||||||
actions?: ReactNode;
|
actions?: ReactNode;
|
||||||
}> = ({
|
}> = ({ change, currentReleasePlan, changeRequestState, actions }) => {
|
||||||
change,
|
|
||||||
environmentName,
|
|
||||||
featureName,
|
|
||||||
projectId,
|
|
||||||
changeRequestState,
|
|
||||||
actions,
|
|
||||||
}) => {
|
|
||||||
const { releasePlans } = useReleasePlans(
|
|
||||||
projectId,
|
|
||||||
featureName,
|
|
||||||
environmentName,
|
|
||||||
);
|
|
||||||
const currentReleasePlan = releasePlans[0];
|
|
||||||
|
|
||||||
const releasePlan =
|
const releasePlan =
|
||||||
changeRequestState === 'Applied' && change.payload.snapshot
|
changeRequestState === 'Applied' && change.payload.snapshot
|
||||||
? change.payload.snapshot
|
? change.payload.snapshot
|
||||||
@ -104,26 +89,10 @@ const DeleteReleasePlan: FC<{
|
|||||||
|
|
||||||
const StartMilestone: FC<{
|
const StartMilestone: FC<{
|
||||||
change: IChangeRequestStartMilestone;
|
change: IChangeRequestStartMilestone;
|
||||||
environmentName: string;
|
currentReleasePlan?: IReleasePlan;
|
||||||
featureName: string;
|
|
||||||
projectId: string;
|
|
||||||
changeRequestState: ChangeRequestState;
|
changeRequestState: ChangeRequestState;
|
||||||
actions?: ReactNode;
|
actions?: ReactNode;
|
||||||
}> = ({
|
}> = ({ change, currentReleasePlan, changeRequestState, actions }) => {
|
||||||
change,
|
|
||||||
environmentName,
|
|
||||||
featureName,
|
|
||||||
projectId,
|
|
||||||
changeRequestState,
|
|
||||||
actions,
|
|
||||||
}) => {
|
|
||||||
const { releasePlans } = useReleasePlans(
|
|
||||||
projectId,
|
|
||||||
featureName,
|
|
||||||
environmentName,
|
|
||||||
);
|
|
||||||
const currentReleasePlan = releasePlans[0];
|
|
||||||
|
|
||||||
const releasePlan =
|
const releasePlan =
|
||||||
changeRequestState === 'Applied' && change.payload.snapshot
|
changeRequestState === 'Applied' && change.payload.snapshot
|
||||||
? change.payload.snapshot
|
? change.payload.snapshot
|
||||||
@ -177,24 +146,107 @@ const StartMilestone: FC<{
|
|||||||
|
|
||||||
const AddReleasePlan: FC<{
|
const AddReleasePlan: FC<{
|
||||||
change: IChangeRequestAddReleasePlan;
|
change: IChangeRequestAddReleasePlan;
|
||||||
|
currentReleasePlan?: IReleasePlan;
|
||||||
environmentName: string;
|
environmentName: string;
|
||||||
featureName: string;
|
featureName: string;
|
||||||
actions?: ReactNode;
|
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(
|
const planPreview = useReleasePlanPreview(
|
||||||
change.payload.templateId,
|
change.payload.templateId,
|
||||||
featureName,
|
featureName,
|
||||||
environmentName,
|
environmentName,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const planPreviewDiff = {
|
||||||
|
...planPreview,
|
||||||
|
discriminator: 'plan',
|
||||||
|
releasePlanTemplateId: change.payload.templateId,
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ChangeItemCreateEditDeleteWrapper>
|
<ChangeItemCreateEditDeleteWrapper>
|
||||||
<ChangeItemInfo>
|
<ChangeItemInfo>
|
||||||
<Typography color='success.dark'>
|
{currentReleasePlan ? (
|
||||||
+ Adding release plan:
|
<Typography>
|
||||||
</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>
|
<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>
|
</ChangeItemInfo>
|
||||||
<div>{actions}</div>
|
<div>{actions}</div>
|
||||||
</ChangeItemCreateEditDeleteWrapper>
|
</ChangeItemCreateEditDeleteWrapper>
|
||||||
@ -221,11 +273,19 @@ export const ReleasePlanChange: FC<{
|
|||||||
projectId,
|
projectId,
|
||||||
changeRequestState,
|
changeRequestState,
|
||||||
}) => {
|
}) => {
|
||||||
|
const { releasePlans } = useReleasePlans(
|
||||||
|
projectId,
|
||||||
|
featureName,
|
||||||
|
environmentName,
|
||||||
|
);
|
||||||
|
const currentReleasePlan = releasePlans[0];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{change.action === 'addReleasePlan' && (
|
{change.action === 'addReleasePlan' && (
|
||||||
<AddReleasePlan
|
<AddReleasePlan
|
||||||
change={change}
|
change={change}
|
||||||
|
currentReleasePlan={currentReleasePlan}
|
||||||
environmentName={environmentName}
|
environmentName={environmentName}
|
||||||
featureName={featureName}
|
featureName={featureName}
|
||||||
actions={actions}
|
actions={actions}
|
||||||
@ -234,9 +294,7 @@ export const ReleasePlanChange: FC<{
|
|||||||
{change.action === 'deleteReleasePlan' && (
|
{change.action === 'deleteReleasePlan' && (
|
||||||
<DeleteReleasePlan
|
<DeleteReleasePlan
|
||||||
change={change}
|
change={change}
|
||||||
environmentName={environmentName}
|
currentReleasePlan={currentReleasePlan}
|
||||||
featureName={featureName}
|
|
||||||
projectId={projectId}
|
|
||||||
changeRequestState={changeRequestState}
|
changeRequestState={changeRequestState}
|
||||||
actions={actions}
|
actions={actions}
|
||||||
/>
|
/>
|
||||||
@ -244,9 +302,7 @@ export const ReleasePlanChange: FC<{
|
|||||||
{change.action === 'startMilestone' && (
|
{change.action === 'startMilestone' && (
|
||||||
<StartMilestone
|
<StartMilestone
|
||||||
change={change}
|
change={change}
|
||||||
environmentName={environmentName}
|
currentReleasePlan={currentReleasePlan}
|
||||||
featureName={featureName}
|
|
||||||
projectId={projectId}
|
|
||||||
changeRequestState={changeRequestState}
|
changeRequestState={changeRequestState}
|
||||||
actions={actions}
|
actions={actions}
|
||||||
/>
|
/>
|
||||||
|
@ -4,6 +4,7 @@ import { ReleasePlan } from './ReleasePlan';
|
|||||||
import { useReleasePlanPreview } from 'hooks/useReleasePlanPreview';
|
import { useReleasePlanPreview } from 'hooks/useReleasePlanPreview';
|
||||||
import { styled, Typography, Alert } from '@mui/material';
|
import { styled, Typography, Alert } from '@mui/material';
|
||||||
import { useFeature } from 'hooks/api/getters/useFeature/useFeature';
|
import { useFeature } from 'hooks/api/getters/useFeature/useFeature';
|
||||||
|
import { useReleasePlans } from 'hooks/api/getters/useReleasePlans/useReleasePlans';
|
||||||
|
|
||||||
const StyledReleasePlanContainer = styled('div')(({ theme }) => ({
|
const StyledReleasePlanContainer = styled('div')(({ theme }) => ({
|
||||||
margin: theme.spacing(2, 0),
|
margin: theme.spacing(2, 0),
|
||||||
@ -30,6 +31,13 @@ export const ReleasePlanAddDialog = ({
|
|||||||
crProtected,
|
crProtected,
|
||||||
}: IReleasePlanAddDialogProps) => {
|
}: IReleasePlanAddDialogProps) => {
|
||||||
const { feature } = useFeature(projectId, featureName);
|
const { feature } = useFeature(projectId, featureName);
|
||||||
|
const { releasePlans } = useReleasePlans(
|
||||||
|
projectId,
|
||||||
|
featureName,
|
||||||
|
environment,
|
||||||
|
);
|
||||||
|
|
||||||
|
const activeReleasePlan = releasePlans[0];
|
||||||
|
|
||||||
const environmentData = feature?.environments.find(
|
const environmentData = feature?.environments.find(
|
||||||
({ name }) => name === environment,
|
({ name }) => name === environment,
|
||||||
@ -55,6 +63,15 @@ export const ReleasePlanAddDialog = ({
|
|||||||
onClick={onConfirm}
|
onClick={onConfirm}
|
||||||
onClose={() => setOpen(false)}
|
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 ? (
|
{environmentEnabled ? (
|
||||||
<Alert severity='info'>
|
<Alert severity='info'>
|
||||||
This environment is currently <strong>enabled</strong>.
|
This environment is currently <strong>enabled</strong>.
|
||||||
@ -70,8 +87,8 @@ export const ReleasePlanAddDialog = ({
|
|||||||
<Alert severity='warning'>
|
<Alert severity='warning'>
|
||||||
This environment is currently <strong>disabled</strong>.
|
This environment is currently <strong>disabled</strong>.
|
||||||
<p>
|
<p>
|
||||||
The milestones will not start automatically after adding
|
Milestones will not start automatically after adding the
|
||||||
the release plan. They will remain paused until the
|
release plan. They will remain paused until the
|
||||||
environment is enabled.
|
environment is enabled.
|
||||||
</p>
|
</p>
|
||||||
</Alert>
|
</Alert>
|
||||||
|
Loading…
Reference in New Issue
Block a user