From 900df537e321d277b8553102f858c015f5a0516d Mon Sep 17 00:00:00 2001 From: David Leek Date: Tue, 14 Jan 2025 13:02:53 +0100 Subject: [PATCH] chore: move strategy UI into milestonecard and open milestone when adding strategy to it (#9095) --- .../MilestoneCard/MilestoneCard.tsx | 361 ++++++++++++------ .../MilestoneList/MilestoneList.tsx | 12 +- .../ReleasePlanTemplateAddStrategyForm.tsx | 9 +- .../TemplateForm/TemplateForm.tsx | 114 +----- 4 files changed, 240 insertions(+), 256 deletions(-) diff --git a/frontend/src/component/releases/ReleasePlanTemplate/TemplateForm/MilestoneList/MilestoneCard/MilestoneCard.tsx b/frontend/src/component/releases/ReleasePlanTemplate/TemplateForm/MilestoneList/MilestoneCard/MilestoneCard.tsx index 9006f9202f6b..95d5a1bee2e9 100644 --- a/frontend/src/component/releases/ReleasePlanTemplate/TemplateForm/MilestoneList/MilestoneCard/MilestoneCard.tsx +++ b/frontend/src/component/releases/ReleasePlanTemplate/TemplateForm/MilestoneList/MilestoneCard/MilestoneCard.tsx @@ -20,6 +20,8 @@ import ExpandMore from '@mui/icons-material/ExpandMore'; import { MilestoneCardName } from './MilestoneCardName'; import { MilestoneStrategyMenuCards } from './MilestoneStrategyMenu/MilestoneStrategyMenuCards'; import { MilestoneStrategyDraggableItem } from './MilestoneStrategyDraggableItem'; +import { SidebarModal } from 'component/common/SidebarModal/SidebarModal'; +import { ReleasePlanTemplateAddStrategyForm } from '../../MilestoneStrategy/ReleasePlanTemplateAddStrategyForm'; const StyledMilestoneCard = styled(Card, { shouldForwardProp: (prop) => prop !== 'hasError', @@ -111,11 +113,6 @@ const StyledIconButton = styled(IconButton)(({ theme }) => ({ interface IMilestoneCardProps { milestone: IReleasePlanMilestonePayload; milestoneChanged: (milestone: IReleasePlanMilestonePayload) => void; - showAddStrategyDialog: ( - milestoneId: string, - strategy: Omit, - editing: boolean, - ) => void; errors: { [key: string]: string }; clearErrors: () => void; removable: boolean; @@ -125,7 +122,6 @@ interface IMilestoneCardProps { export const MilestoneCard = ({ milestone, milestoneChanged, - showAddStrategyDialog, errors, clearErrors, removable, @@ -137,6 +133,9 @@ export const MilestoneCard = ({ index: number; height: number; } | null>(null); + const [addUpdateStrategyOpen, setAddUpdateStrategyOpen] = useState(false); + const [strategyModeEdit, setStrategyModeEdit] = useState(false); + const [expanded, setExpanded] = useState(false); const isPopoverOpen = Boolean(anchor); const popoverId = isPopoverOpen ? 'MilestoneStrategyMenuPopover' @@ -146,16 +145,76 @@ export const MilestoneCard = ({ setAnchor(undefined); }; - const onSelectEditStrategy = ( + const [currentStrategy, setCurrentStrategy] = useState< + Omit + >({ + name: 'flexibleRollout', + parameters: { rollout: '50' }, + constraints: [], + title: '', + id: 'temp', + }); + + const milestoneStrategyChanged = ( strategy: Omit, ) => { - showAddStrategyDialog(milestone.id, strategy, true); + const strategies = milestone.strategies || []; + milestoneChanged({ + ...milestone, + strategies: [ + ...strategies.map((strat) => + strat.id === strategy.id ? strategy : strat, + ), + ], + }); }; - const onSelectStrategy = ( + const milestoneStrategyAdded = ( strategy: Omit, ) => { - showAddStrategyDialog(milestone.id, strategy, false); + milestoneChanged({ + ...milestone, + strategies: [ + ...(milestone.strategies || []), + { + ...strategy, + strategyName: strategy.strategyName, + sortOrder: milestone.strategies?.length || 0, + }, + ], + }); + }; + + const addUpdateStrategy = ( + strategy: Omit, + ) => { + const existingStrategy = milestone.strategies?.find( + (strat) => strat.id === strategy.id, + ); + if (existingStrategy) { + milestoneStrategyChanged(strategy); + } else { + milestoneStrategyAdded(strategy); + setExpanded(true); + } + setAddUpdateStrategyOpen(false); + setStrategyModeEdit(false); + setCurrentStrategy({ + name: 'flexibleRollout', + parameters: { rollout: '50' }, + constraints: [], + title: '', + id: 'temp', + }); + }; + + const openAddUpdateStrategyForm = ( + strategy: Omit, + editing: boolean, + ) => { + setStrategyModeEdit(editing); + setCurrentStrategy(strategy); + setAddUpdateStrategyOpen(true); }; const onDragOver = @@ -248,126 +307,180 @@ export const MilestoneCard = ({ if (!milestone.strategies || milestone.strategies.length === 0) { return ( - - - - - - - - - - - - - ({ - paddingBottom: theme.spacing(1), - }), - }} - > - + + + + + - - - - - + + + + + + + + ({ + paddingBottom: theme.spacing(1), + }), + }} + > + { + openAddUpdateStrategyForm( + strategy, + false, + ); + }} + /> + + + + + + + { + setAddUpdateStrategyOpen(false); + setStrategyModeEdit(false); + }} + open={addUpdateStrategyOpen} + > + { + setAddUpdateStrategyOpen(false); + setStrategyModeEdit(false); + }} + editMode={strategyModeEdit} + /> + + ); } return ( - - } + <> + setExpanded(change)} > - - - - {milestone.strategies.map((strg, index) => ( -
- - milestoneStrategyDeleted(strg.id) - } - onEditClick={() => { - onSelectEditStrategy(strg); + } + > + + + + {milestone.strategies.map((strg, index) => ( +
+ + milestoneStrategyDeleted(strg.id) + } + onEditClick={() => { + openAddUpdateStrategyForm(strg, true); + }} + isDragging={dragItem?.id === strg.id} + strategy={strg} + /> +
+ ))} + + setAnchor(ev.currentTarget)} + > + Add strategy + + + ({ + paddingBottom: theme.spacing(1), + }), }} - isDragging={dragItem?.id === strg.id} - strategy={strg} - /> -
- ))} - - setAnchor(ev.currentTarget)} - > - Add strategy - - - ({ - paddingBottom: theme.spacing(1), - }), - }} - > - - - -
-
+ > + { + openAddUpdateStrategyForm(strategy, false); + }} + /> + + + + + + { + setAddUpdateStrategyOpen(false); + setStrategyModeEdit(false); + }} + open={addUpdateStrategyOpen} + > + { + setAddUpdateStrategyOpen(false); + setStrategyModeEdit(false); + }} + editMode={strategyModeEdit} + /> + + ); }; diff --git a/frontend/src/component/releases/ReleasePlanTemplate/TemplateForm/MilestoneList/MilestoneList.tsx b/frontend/src/component/releases/ReleasePlanTemplate/TemplateForm/MilestoneList/MilestoneList.tsx index e76210be7ba8..ad4b81935edb 100644 --- a/frontend/src/component/releases/ReleasePlanTemplate/TemplateForm/MilestoneList/MilestoneList.tsx +++ b/frontend/src/component/releases/ReleasePlanTemplate/TemplateForm/MilestoneList/MilestoneList.tsx @@ -1,7 +1,4 @@ -import type { - IReleasePlanMilestonePayload, - IReleasePlanMilestoneStrategy, -} from 'interfaces/releasePlans'; +import type { IReleasePlanMilestonePayload } from 'interfaces/releasePlans'; import { MilestoneCard } from './MilestoneCard/MilestoneCard'; import { styled, Button, FormHelperText } from '@mui/material'; import Add from '@mui/icons-material/Add'; @@ -12,11 +9,6 @@ interface IMilestoneListProps { setMilestones: React.Dispatch< React.SetStateAction >; - openAddStrategyForm: ( - milestoneId: string, - strategy: Omit, - editing: boolean, - ) => void; errors: { [key: string]: string }; clearErrors: () => void; milestoneChanged: (milestone: IReleasePlanMilestonePayload) => void; @@ -30,7 +22,6 @@ const StyledAddMilestoneButton = styled(Button)(({ theme }) => ({ export const MilestoneList = ({ milestones, setMilestones, - openAddStrategyForm, errors, clearErrors, milestoneChanged, @@ -51,7 +42,6 @@ export const MilestoneList = ({ key={milestone.id} milestone={milestone} milestoneChanged={milestoneChanged} - showAddStrategyDialog={openAddStrategyForm} errors={errors} clearErrors={clearErrors} removable={milestones.length > 1} diff --git a/frontend/src/component/releases/ReleasePlanTemplate/TemplateForm/MilestoneStrategy/ReleasePlanTemplateAddStrategyForm.tsx b/frontend/src/component/releases/ReleasePlanTemplate/TemplateForm/MilestoneStrategy/ReleasePlanTemplateAddStrategyForm.tsx index d9ecc847c7fa..d6f5cdbfe288 100644 --- a/frontend/src/component/releases/ReleasePlanTemplate/TemplateForm/MilestoneStrategy/ReleasePlanTemplateAddStrategyForm.tsx +++ b/frontend/src/component/releases/ReleasePlanTemplate/TemplateForm/MilestoneStrategy/ReleasePlanTemplateAddStrategyForm.tsx @@ -124,18 +124,15 @@ const StyledDividerContent = styled(Box)(({ theme }) => ({ })); interface IReleasePlanTemplateAddStrategyFormProps { - milestoneId: string | undefined; onCancel: () => void; strategy: Omit; onAddUpdateStrategy: ( - milestoneId: string, strategy: Omit, ) => void; editMode: boolean; } export const ReleasePlanTemplateAddStrategyForm = ({ - milestoneId, onCancel, strategy, onAddUpdateStrategy, @@ -231,11 +228,7 @@ export const ReleasePlanTemplateAddStrategyForm = ({ }; const AddUpdateMilestoneStrategy = () => { - if (!milestoneId) { - return; - } - - onAddUpdateStrategy(milestoneId, currentStrategy); + onAddUpdateStrategy(currentStrategy); }; return ( diff --git a/frontend/src/component/releases/ReleasePlanTemplate/TemplateForm/TemplateForm.tsx b/frontend/src/component/releases/ReleasePlanTemplate/TemplateForm/TemplateForm.tsx index 25260e6a7a4c..e2ab3f8a1992 100644 --- a/frontend/src/component/releases/ReleasePlanTemplate/TemplateForm/TemplateForm.tsx +++ b/frontend/src/component/releases/ReleasePlanTemplate/TemplateForm/TemplateForm.tsx @@ -1,15 +1,9 @@ import Input from 'component/common/Input/Input'; import { styled, useTheme } from '@mui/material'; -import type { - IReleasePlanMilestonePayload, - IReleasePlanMilestoneStrategy, -} from 'interfaces/releasePlans'; +import type { IReleasePlanMilestonePayload } from 'interfaces/releasePlans'; import FormTemplate from 'component/common/FormTemplate/FormTemplate'; -import { useState } from 'react'; import { TemplateFormDescription } from './TemplateFormDescription'; import { MilestoneList } from './MilestoneList/MilestoneList'; -import { SidebarModal } from 'component/common/SidebarModal/SidebarModal'; -import { ReleasePlanTemplateAddStrategyForm } from './MilestoneStrategy/ReleasePlanTemplateAddStrategyForm'; const StyledInput = styled(Input)(({ theme }) => ({ width: '100%', @@ -61,77 +55,7 @@ export const TemplateForm: React.FC = ({ handleSubmit, children, }) => { - const [addUpdateStrategyOpen, setAddUpdateStrategyOpen] = useState(false); - const [activeMilestoneId, setActiveMilestoneId] = useState< - string | undefined - >(); - const [strategyModeEdit, setStrategyModeEdit] = useState(false); - const [strategy, setStrategy] = useState< - Omit - >({ - name: 'flexibleRollout', - parameters: { rollout: '50' }, - constraints: [], - title: '', - id: 'temp', - }); - const theme = useTheme(); - const openAddUpdateStrategyForm = ( - milestoneId: string, - strategy: Omit, - editing: boolean, - ) => { - setStrategyModeEdit(editing); - setActiveMilestoneId(milestoneId); - setStrategy(strategy); - setAddUpdateStrategyOpen(true); - }; - - const addUpdateStrategy = ( - milestoneId: string, - strategy: Omit, - ) => { - const milestone = milestones.find((m) => m.id === milestoneId); - const existingStrategy = milestone?.strategies?.find( - (strat) => strat.id === strategy.id, - ); - if (!milestone) { - return; - } - if (existingStrategy) { - milestoneStrategyChanged(milestone, strategy); - } else { - setMilestones((prev) => - prev.map((milestone, i) => - milestone.id === milestoneId - ? { - ...milestone, - strategies: [ - ...(milestone.strategies || []), - { - ...strategy, - strategyName: strategy.strategyName, - sortOrder: - milestone.strategies?.length || 0, - }, - ], - } - : milestone, - ), - ); - } - setAddUpdateStrategyOpen(false); - setStrategyModeEdit(false); - setActiveMilestoneId(undefined); - setStrategy({ - name: 'flexibleRollout', - parameters: { rollout: '50' }, - constraints: [], - title: '', - id: 'temp', - }); - }; const milestoneChanged = (milestone: IReleasePlanMilestonePayload) => { setMilestones((prev) => @@ -141,21 +65,6 @@ export const TemplateForm: React.FC = ({ ); }; - const milestoneStrategyChanged = ( - milestone: IReleasePlanMilestonePayload, - strategy: Omit, - ) => { - const strategies = milestone.strategies || []; - milestoneChanged({ - ...milestone, - strategies: [ - ...strategies.map((strat) => - strat.id === strategy.id ? strategy : strat, - ), - ], - }); - }; - return ( = ({ {children} - - { - setAddUpdateStrategyOpen(false); - setStrategyModeEdit(false); - }} - open={addUpdateStrategyOpen} - > - { - setAddUpdateStrategyOpen(false); - setStrategyModeEdit(false); - }} - editMode={strategyModeEdit} - /> - );