From 7aefc573dc75cf068a087aed659d2e67de3cdd32 Mon Sep 17 00:00:00 2001 From: David Leek Date: Thu, 23 Jan 2025 13:48:44 +0100 Subject: [PATCH] feat: show a dialog when adding a release plan to a change request enabled feature environment (#9139) --- .../FeatureReleasePlanCard.tsx | 37 ++++++++---- .../FeatureStrategyMenu.tsx | 16 +++++ .../FeatureStrategyMenuCards.tsx | 6 ++ .../ReleasePlanAddChangeRequestDialog.tsx | 60 +++++++++++++++++++ 4 files changed, 108 insertions(+), 11 deletions(-) create mode 100644 frontend/src/component/feature/FeatureView/FeatureOverview/ReleasePlan/ReleasePlanAddChangeRequestDialog.tsx diff --git a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyMenu/FeatureReleasePlanCard/FeatureReleasePlanCard.tsx b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyMenu/FeatureReleasePlanCard/FeatureReleasePlanCard.tsx index 437c67baed..986913f937 100644 --- a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyMenu/FeatureReleasePlanCard/FeatureReleasePlanCard.tsx +++ b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyMenu/FeatureReleasePlanCard/FeatureReleasePlanCard.tsx @@ -7,6 +7,8 @@ import { useReleasePlansApi } from 'hooks/api/actions/useReleasePlansApi/useRele import useToast from 'hooks/useToast'; import { formatUnknownError } from 'utils/formatUnknownError'; import { useReleasePlans } from 'hooks/api/getters/useReleasePlans/useReleasePlans'; +import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled'; +import { useUiFlag } from 'hooks/useUiFlag'; const StyledIcon = styled('div')(({ theme }) => ({ width: theme.spacing(4), @@ -51,6 +53,7 @@ interface IFeatureReleasePlanCardProps { featureId: string; environmentId: string; releasePlanTemplate: IReleasePlanTemplate; + setTemplateForChangeRequestDialog: (template: IReleasePlanTemplate) => void; } export const FeatureReleasePlanCard = ({ @@ -58,26 +61,38 @@ export const FeatureReleasePlanCard = ({ featureId, environmentId, releasePlanTemplate, + setTemplateForChangeRequestDialog, }: IFeatureReleasePlanCardProps) => { const Icon = getFeatureStrategyIcon('releasePlanTemplate'); const { trackEvent } = usePlausibleTracker(); const { refetch } = useReleasePlans(projectId, featureId, environmentId); const { addReleasePlanToFeature } = useReleasePlansApi(); const { setToastApiError, setToastData } = useToast(); + const { isChangeRequestConfigured } = useChangeRequestsEnabled(projectId); + const releasePlanChangeRequestsEnabled = useUiFlag( + 'releasePlanChangeRequests', + ); const addReleasePlan = async () => { try { - await addReleasePlanToFeature( - featureId, - releasePlanTemplate.id, - projectId, - environmentId, - ); - setToastData({ - type: 'success', - text: 'Release plan added', - }); - refetch(); + if ( + releasePlanChangeRequestsEnabled && + isChangeRequestConfigured(environmentId) + ) { + setTemplateForChangeRequestDialog(releasePlanTemplate); + } else { + await addReleasePlanToFeature( + featureId, + releasePlanTemplate.id, + projectId, + environmentId, + ); + setToastData({ + type: 'success', + text: 'Release plan added', + }); + refetch(); + } } catch (error: unknown) { setToastApiError(formatUnknownError(error)); } diff --git a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyMenu/FeatureStrategyMenu.tsx b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyMenu/FeatureStrategyMenu.tsx index e456fa09a1..ec65c0b8ba 100644 --- a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyMenu/FeatureStrategyMenu.tsx +++ b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyMenu/FeatureStrategyMenu.tsx @@ -11,6 +11,8 @@ import { formatCreateStrategyPath } from '../FeatureStrategyCreate/FeatureStrate import MoreVert from '@mui/icons-material/MoreVert'; import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; import { useUiFlag } from 'hooks/useUiFlag'; +import { ReleasePlanAddChangeRequestDialog } from 'component/feature/FeatureView/FeatureOverview/ReleasePlan/ReleasePlanAddChangeRequestDialog'; +import type { IReleasePlanTemplate } from 'interfaces/releasePlans'; interface IFeatureStrategyMenuProps { label: string; @@ -50,6 +52,8 @@ export const FeatureStrategyMenu = ({ const [anchor, setAnchor] = useState(); const navigate = useNavigate(); const { trackEvent } = usePlausibleTracker(); + const [templateForChangeRequestDialog, setTemplateForChangeRequestDialog] = + useState(); const isPopoverOpen = Boolean(anchor); const popoverId = isPopoverOpen ? 'FeatureStrategyMenuPopover' : undefined; const flagOverviewRedesignEnabled = useUiFlag('flagOverviewRedesign'); @@ -115,6 +119,9 @@ export const FeatureStrategyMenu = ({ projectId={projectId} featureId={featureId} environmentId={environmentId} + setTemplateForChangeRequestDialog={ + setTemplateForChangeRequestDialog + } /> @@ -175,8 +182,17 @@ export const FeatureStrategyMenu = ({ projectId={projectId} featureId={featureId} environmentId={environmentId} + setTemplateForChangeRequestDialog={ + setTemplateForChangeRequestDialog + } /> + setTemplateForChangeRequestDialog(undefined)} + featureId={featureId} + environmentId={environmentId} + releaseTemplate={templateForChangeRequestDialog} + /> ); }; diff --git a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyMenu/FeatureStrategyMenuCards/FeatureStrategyMenuCards.tsx b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyMenu/FeatureStrategyMenuCards/FeatureStrategyMenuCards.tsx index 5ea9c98a85..6dc8c3225d 100644 --- a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyMenu/FeatureStrategyMenuCards/FeatureStrategyMenuCards.tsx +++ b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyMenu/FeatureStrategyMenuCards/FeatureStrategyMenuCards.tsx @@ -4,11 +4,13 @@ import { FeatureStrategyMenuCard } from '../FeatureStrategyMenuCard/FeatureStrat import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { useReleasePlanTemplates } from 'hooks/api/getters/useReleasePlanTemplates/useReleasePlanTemplates'; import { FeatureReleasePlanCard } from '../FeatureReleasePlanCard/FeatureReleasePlanCard'; +import type { IReleasePlanTemplate } from 'interfaces/releasePlans'; interface IFeatureStrategyMenuCardsProps { projectId: string; featureId: string; environmentId: string; + setTemplateForChangeRequestDialog: (template: IReleasePlanTemplate) => void; } const StyledTypography = styled(Typography)(({ theme }) => ({ @@ -20,6 +22,7 @@ export const FeatureStrategyMenuCards = ({ projectId, featureId, environmentId, + setTemplateForChangeRequestDialog, }: IFeatureStrategyMenuCardsProps) => { const { strategies } = useStrategies(); const { templates } = useReleasePlanTemplates(); @@ -68,6 +71,9 @@ export const FeatureStrategyMenuCards = ({ featureId={featureId} environmentId={environmentId} releasePlanTemplate={template} + setTemplateForChangeRequestDialog={ + setTemplateForChangeRequestDialog + } /> ))} diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/ReleasePlan/ReleasePlanAddChangeRequestDialog.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/ReleasePlan/ReleasePlanAddChangeRequestDialog.tsx new file mode 100644 index 0000000000..afbbf6b513 --- /dev/null +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/ReleasePlan/ReleasePlanAddChangeRequestDialog.tsx @@ -0,0 +1,60 @@ +import { Dialogue } from 'component/common/Dialogue/Dialogue'; +import useToast from 'hooks/useToast'; +import { styled, Button } from '@mui/material'; +import type { IReleasePlanTemplate } from 'interfaces/releasePlans'; + +const StyledBoldSpan = styled('span')(({ theme }) => ({ + fontWeight: theme.typography.fontWeightBold, +})); + +interface IReleasePlanAddChangeRequestDialogProps { + featureId: string; + environmentId: string; + releaseTemplate: IReleasePlanTemplate | undefined; + onClosing: () => void; +} + +export const ReleasePlanAddChangeRequestDialog = ({ + featureId, + environmentId, + releaseTemplate, + onClosing, +}: IReleasePlanAddChangeRequestDialogProps) => { + const { setToastData } = useToast(); + + const addReleasePlanToChangeRequest = async () => { + setToastData({ + type: 'success', + text: 'Added to draft', + }); + onClosing(); + }; + + return ( + { + onClosing(); + }} + customButton={ + + } + > +

+ Add release template{' '} + {releaseTemplate?.name} to{' '} + {featureId} in{' '} + {environmentId} +

+
+ ); +};