mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	chore: move strategy UI into milestonecard and open milestone when adding strategy to it (#9095)
This commit is contained in:
		
							parent
							
								
									74c1bd5ad8
								
							
						
					
					
						commit
						900df537e3
					
				@ -20,6 +20,8 @@ import ExpandMore from '@mui/icons-material/ExpandMore';
 | 
				
			|||||||
import { MilestoneCardName } from './MilestoneCardName';
 | 
					import { MilestoneCardName } from './MilestoneCardName';
 | 
				
			||||||
import { MilestoneStrategyMenuCards } from './MilestoneStrategyMenu/MilestoneStrategyMenuCards';
 | 
					import { MilestoneStrategyMenuCards } from './MilestoneStrategyMenu/MilestoneStrategyMenuCards';
 | 
				
			||||||
import { MilestoneStrategyDraggableItem } from './MilestoneStrategyDraggableItem';
 | 
					import { MilestoneStrategyDraggableItem } from './MilestoneStrategyDraggableItem';
 | 
				
			||||||
 | 
					import { SidebarModal } from 'component/common/SidebarModal/SidebarModal';
 | 
				
			||||||
 | 
					import { ReleasePlanTemplateAddStrategyForm } from '../../MilestoneStrategy/ReleasePlanTemplateAddStrategyForm';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const StyledMilestoneCard = styled(Card, {
 | 
					const StyledMilestoneCard = styled(Card, {
 | 
				
			||||||
    shouldForwardProp: (prop) => prop !== 'hasError',
 | 
					    shouldForwardProp: (prop) => prop !== 'hasError',
 | 
				
			||||||
@ -111,11 +113,6 @@ const StyledIconButton = styled(IconButton)(({ theme }) => ({
 | 
				
			|||||||
interface IMilestoneCardProps {
 | 
					interface IMilestoneCardProps {
 | 
				
			||||||
    milestone: IReleasePlanMilestonePayload;
 | 
					    milestone: IReleasePlanMilestonePayload;
 | 
				
			||||||
    milestoneChanged: (milestone: IReleasePlanMilestonePayload) => void;
 | 
					    milestoneChanged: (milestone: IReleasePlanMilestonePayload) => void;
 | 
				
			||||||
    showAddStrategyDialog: (
 | 
					 | 
				
			||||||
        milestoneId: string,
 | 
					 | 
				
			||||||
        strategy: Omit<IReleasePlanMilestoneStrategy, 'milestoneId'>,
 | 
					 | 
				
			||||||
        editing: boolean,
 | 
					 | 
				
			||||||
    ) => void;
 | 
					 | 
				
			||||||
    errors: { [key: string]: string };
 | 
					    errors: { [key: string]: string };
 | 
				
			||||||
    clearErrors: () => void;
 | 
					    clearErrors: () => void;
 | 
				
			||||||
    removable: boolean;
 | 
					    removable: boolean;
 | 
				
			||||||
@ -125,7 +122,6 @@ interface IMilestoneCardProps {
 | 
				
			|||||||
export const MilestoneCard = ({
 | 
					export const MilestoneCard = ({
 | 
				
			||||||
    milestone,
 | 
					    milestone,
 | 
				
			||||||
    milestoneChanged,
 | 
					    milestoneChanged,
 | 
				
			||||||
    showAddStrategyDialog,
 | 
					 | 
				
			||||||
    errors,
 | 
					    errors,
 | 
				
			||||||
    clearErrors,
 | 
					    clearErrors,
 | 
				
			||||||
    removable,
 | 
					    removable,
 | 
				
			||||||
@ -137,6 +133,9 @@ export const MilestoneCard = ({
 | 
				
			|||||||
        index: number;
 | 
					        index: number;
 | 
				
			||||||
        height: number;
 | 
					        height: number;
 | 
				
			||||||
    } | null>(null);
 | 
					    } | null>(null);
 | 
				
			||||||
 | 
					    const [addUpdateStrategyOpen, setAddUpdateStrategyOpen] = useState(false);
 | 
				
			||||||
 | 
					    const [strategyModeEdit, setStrategyModeEdit] = useState(false);
 | 
				
			||||||
 | 
					    const [expanded, setExpanded] = useState(false);
 | 
				
			||||||
    const isPopoverOpen = Boolean(anchor);
 | 
					    const isPopoverOpen = Boolean(anchor);
 | 
				
			||||||
    const popoverId = isPopoverOpen
 | 
					    const popoverId = isPopoverOpen
 | 
				
			||||||
        ? 'MilestoneStrategyMenuPopover'
 | 
					        ? 'MilestoneStrategyMenuPopover'
 | 
				
			||||||
@ -146,16 +145,76 @@ export const MilestoneCard = ({
 | 
				
			|||||||
        setAnchor(undefined);
 | 
					        setAnchor(undefined);
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const onSelectEditStrategy = (
 | 
					    const [currentStrategy, setCurrentStrategy] = useState<
 | 
				
			||||||
 | 
					        Omit<IReleasePlanMilestoneStrategy, 'milestoneId'>
 | 
				
			||||||
 | 
					    >({
 | 
				
			||||||
 | 
					        name: 'flexibleRollout',
 | 
				
			||||||
 | 
					        parameters: { rollout: '50' },
 | 
				
			||||||
 | 
					        constraints: [],
 | 
				
			||||||
 | 
					        title: '',
 | 
				
			||||||
 | 
					        id: 'temp',
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const milestoneStrategyChanged = (
 | 
				
			||||||
        strategy: Omit<IReleasePlanMilestoneStrategy, 'milestoneId'>,
 | 
					        strategy: Omit<IReleasePlanMilestoneStrategy, 'milestoneId'>,
 | 
				
			||||||
    ) => {
 | 
					    ) => {
 | 
				
			||||||
        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<IReleasePlanMilestoneStrategy, 'milestoneId'>,
 | 
					        strategy: Omit<IReleasePlanMilestoneStrategy, 'milestoneId'>,
 | 
				
			||||||
    ) => {
 | 
					    ) => {
 | 
				
			||||||
        showAddStrategyDialog(milestone.id, strategy, false);
 | 
					        milestoneChanged({
 | 
				
			||||||
 | 
					            ...milestone,
 | 
				
			||||||
 | 
					            strategies: [
 | 
				
			||||||
 | 
					                ...(milestone.strategies || []),
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    ...strategy,
 | 
				
			||||||
 | 
					                    strategyName: strategy.strategyName,
 | 
				
			||||||
 | 
					                    sortOrder: milestone.strategies?.length || 0,
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const addUpdateStrategy = (
 | 
				
			||||||
 | 
					        strategy: Omit<IReleasePlanMilestoneStrategy, 'milestoneId'>,
 | 
				
			||||||
 | 
					    ) => {
 | 
				
			||||||
 | 
					        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<IReleasePlanMilestoneStrategy, 'milestoneId'>,
 | 
				
			||||||
 | 
					        editing: boolean,
 | 
				
			||||||
 | 
					    ) => {
 | 
				
			||||||
 | 
					        setStrategyModeEdit(editing);
 | 
				
			||||||
 | 
					        setCurrentStrategy(strategy);
 | 
				
			||||||
 | 
					        setAddUpdateStrategyOpen(true);
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const onDragOver =
 | 
					    const onDragOver =
 | 
				
			||||||
@ -248,126 +307,180 @@ export const MilestoneCard = ({
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (!milestone.strategies || milestone.strategies.length === 0) {
 | 
					    if (!milestone.strategies || milestone.strategies.length === 0) {
 | 
				
			||||||
        return (
 | 
					        return (
 | 
				
			||||||
            <StyledMilestoneCard
 | 
					            <>
 | 
				
			||||||
                hasError={
 | 
					                <StyledMilestoneCard
 | 
				
			||||||
                    Boolean(errors?.[milestone.id]) ||
 | 
					                    hasError={
 | 
				
			||||||
                    Boolean(errors?.[`${milestone.id}_name`])
 | 
					                        Boolean(errors?.[milestone.id]) ||
 | 
				
			||||||
                }
 | 
					                        Boolean(errors?.[`${milestone.id}_name`])
 | 
				
			||||||
            >
 | 
					                    }
 | 
				
			||||||
                <StyledMilestoneCardBody>
 | 
					                >
 | 
				
			||||||
                    <Grid container>
 | 
					                    <StyledMilestoneCardBody>
 | 
				
			||||||
                        <StyledGridItem item xs={6} md={6}>
 | 
					                        <Grid container>
 | 
				
			||||||
                            <MilestoneCardName
 | 
					                            <StyledGridItem item xs={6} md={6}>
 | 
				
			||||||
                                milestone={milestone}
 | 
					                                <MilestoneCardName
 | 
				
			||||||
                                errors={errors}
 | 
					                                    milestone={milestone}
 | 
				
			||||||
                                clearErrors={clearErrors}
 | 
					                                    errors={errors}
 | 
				
			||||||
                                milestoneNameChanged={milestoneNameChanged}
 | 
					                                    clearErrors={clearErrors}
 | 
				
			||||||
                            />
 | 
					                                    milestoneNameChanged={milestoneNameChanged}
 | 
				
			||||||
                        </StyledGridItem>
 | 
					 | 
				
			||||||
                        <StyledMilestoneActionGrid item xs={6} md={6}>
 | 
					 | 
				
			||||||
                            <Button
 | 
					 | 
				
			||||||
                                variant='outlined'
 | 
					 | 
				
			||||||
                                color='primary'
 | 
					 | 
				
			||||||
                                onClick={(ev) => setAnchor(ev.currentTarget)}
 | 
					 | 
				
			||||||
                            >
 | 
					 | 
				
			||||||
                                Add strategy
 | 
					 | 
				
			||||||
                            </Button>
 | 
					 | 
				
			||||||
                            <StyledIconButton
 | 
					 | 
				
			||||||
                                title='Remove milestone'
 | 
					 | 
				
			||||||
                                onClick={onDeleteMilestone}
 | 
					 | 
				
			||||||
                                disabled={!removable}
 | 
					 | 
				
			||||||
                            >
 | 
					 | 
				
			||||||
                                <Delete />
 | 
					 | 
				
			||||||
                            </StyledIconButton>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                            <Popover
 | 
					 | 
				
			||||||
                                id={popoverId}
 | 
					 | 
				
			||||||
                                open={isPopoverOpen}
 | 
					 | 
				
			||||||
                                anchorEl={anchor}
 | 
					 | 
				
			||||||
                                onClose={onClose}
 | 
					 | 
				
			||||||
                                onClick={onClose}
 | 
					 | 
				
			||||||
                                PaperProps={{
 | 
					 | 
				
			||||||
                                    sx: (theme) => ({
 | 
					 | 
				
			||||||
                                        paddingBottom: theme.spacing(1),
 | 
					 | 
				
			||||||
                                    }),
 | 
					 | 
				
			||||||
                                }}
 | 
					 | 
				
			||||||
                            >
 | 
					 | 
				
			||||||
                                <MilestoneStrategyMenuCards
 | 
					 | 
				
			||||||
                                    openEditAddStrategy={onSelectStrategy}
 | 
					 | 
				
			||||||
                                />
 | 
					                                />
 | 
				
			||||||
                            </Popover>
 | 
					                            </StyledGridItem>
 | 
				
			||||||
                        </StyledMilestoneActionGrid>
 | 
					                            <StyledMilestoneActionGrid item xs={6} md={6}>
 | 
				
			||||||
                    </Grid>
 | 
					                                <Button
 | 
				
			||||||
                </StyledMilestoneCardBody>
 | 
					                                    variant='outlined'
 | 
				
			||||||
            </StyledMilestoneCard>
 | 
					                                    color='primary'
 | 
				
			||||||
 | 
					                                    onClick={(ev) =>
 | 
				
			||||||
 | 
					                                        setAnchor(ev.currentTarget)
 | 
				
			||||||
 | 
					                                    }
 | 
				
			||||||
 | 
					                                >
 | 
				
			||||||
 | 
					                                    Add strategy
 | 
				
			||||||
 | 
					                                </Button>
 | 
				
			||||||
 | 
					                                <StyledIconButton
 | 
				
			||||||
 | 
					                                    title='Remove milestone'
 | 
				
			||||||
 | 
					                                    onClick={onDeleteMilestone}
 | 
				
			||||||
 | 
					                                    disabled={!removable}
 | 
				
			||||||
 | 
					                                >
 | 
				
			||||||
 | 
					                                    <Delete />
 | 
				
			||||||
 | 
					                                </StyledIconButton>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                <Popover
 | 
				
			||||||
 | 
					                                    id={popoverId}
 | 
				
			||||||
 | 
					                                    open={isPopoverOpen}
 | 
				
			||||||
 | 
					                                    anchorEl={anchor}
 | 
				
			||||||
 | 
					                                    onClose={onClose}
 | 
				
			||||||
 | 
					                                    onClick={onClose}
 | 
				
			||||||
 | 
					                                    PaperProps={{
 | 
				
			||||||
 | 
					                                        sx: (theme) => ({
 | 
				
			||||||
 | 
					                                            paddingBottom: theme.spacing(1),
 | 
				
			||||||
 | 
					                                        }),
 | 
				
			||||||
 | 
					                                    }}
 | 
				
			||||||
 | 
					                                >
 | 
				
			||||||
 | 
					                                    <MilestoneStrategyMenuCards
 | 
				
			||||||
 | 
					                                        openEditAddStrategy={(strategy) => {
 | 
				
			||||||
 | 
					                                            openAddUpdateStrategyForm(
 | 
				
			||||||
 | 
					                                                strategy,
 | 
				
			||||||
 | 
					                                                false,
 | 
				
			||||||
 | 
					                                            );
 | 
				
			||||||
 | 
					                                        }}
 | 
				
			||||||
 | 
					                                    />
 | 
				
			||||||
 | 
					                                </Popover>
 | 
				
			||||||
 | 
					                            </StyledMilestoneActionGrid>
 | 
				
			||||||
 | 
					                        </Grid>
 | 
				
			||||||
 | 
					                    </StyledMilestoneCardBody>
 | 
				
			||||||
 | 
					                </StyledMilestoneCard>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <SidebarModal
 | 
				
			||||||
 | 
					                    label='Add strategy to template milestone'
 | 
				
			||||||
 | 
					                    onClose={() => {
 | 
				
			||||||
 | 
					                        setAddUpdateStrategyOpen(false);
 | 
				
			||||||
 | 
					                        setStrategyModeEdit(false);
 | 
				
			||||||
 | 
					                    }}
 | 
				
			||||||
 | 
					                    open={addUpdateStrategyOpen}
 | 
				
			||||||
 | 
					                >
 | 
				
			||||||
 | 
					                    <ReleasePlanTemplateAddStrategyForm
 | 
				
			||||||
 | 
					                        strategy={currentStrategy}
 | 
				
			||||||
 | 
					                        onAddUpdateStrategy={addUpdateStrategy}
 | 
				
			||||||
 | 
					                        onCancel={() => {
 | 
				
			||||||
 | 
					                            setAddUpdateStrategyOpen(false);
 | 
				
			||||||
 | 
					                            setStrategyModeEdit(false);
 | 
				
			||||||
 | 
					                        }}
 | 
				
			||||||
 | 
					                        editMode={strategyModeEdit}
 | 
				
			||||||
 | 
					                    />
 | 
				
			||||||
 | 
					                </SidebarModal>
 | 
				
			||||||
 | 
					            </>
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        <StyledAccordion>
 | 
					        <>
 | 
				
			||||||
            <StyledAccordionSummary
 | 
					            <StyledAccordion
 | 
				
			||||||
                expandIcon={<ExpandMore titleAccess='Toggle' />}
 | 
					                expanded={expanded}
 | 
				
			||||||
 | 
					                onChange={(e, change) => setExpanded(change)}
 | 
				
			||||||
            >
 | 
					            >
 | 
				
			||||||
                <MilestoneCardName
 | 
					                <StyledAccordionSummary
 | 
				
			||||||
                    milestone={milestone}
 | 
					                    expandIcon={<ExpandMore titleAccess='Toggle' />}
 | 
				
			||||||
                    errors={errors}
 | 
					                >
 | 
				
			||||||
                    clearErrors={clearErrors}
 | 
					                    <MilestoneCardName
 | 
				
			||||||
                    milestoneNameChanged={milestoneNameChanged}
 | 
					                        milestone={milestone}
 | 
				
			||||||
                />
 | 
					                        errors={errors}
 | 
				
			||||||
            </StyledAccordionSummary>
 | 
					                        clearErrors={clearErrors}
 | 
				
			||||||
            <StyledAccordionDetails>
 | 
					                        milestoneNameChanged={milestoneNameChanged}
 | 
				
			||||||
                {milestone.strategies.map((strg, index) => (
 | 
					                    />
 | 
				
			||||||
                    <div key={strg.id}>
 | 
					                </StyledAccordionSummary>
 | 
				
			||||||
                        <MilestoneStrategyDraggableItem
 | 
					                <StyledAccordionDetails>
 | 
				
			||||||
                            index={index}
 | 
					                    {milestone.strategies.map((strg, index) => (
 | 
				
			||||||
                            onDragEnd={onDragEnd}
 | 
					                        <div key={strg.id}>
 | 
				
			||||||
                            onDragStartRef={onDragStartRef}
 | 
					                            <MilestoneStrategyDraggableItem
 | 
				
			||||||
                            onDragOver={onDragOver(strg.id)}
 | 
					                                index={index}
 | 
				
			||||||
                            onDeleteClick={() =>
 | 
					                                onDragEnd={onDragEnd}
 | 
				
			||||||
                                milestoneStrategyDeleted(strg.id)
 | 
					                                onDragStartRef={onDragStartRef}
 | 
				
			||||||
                            }
 | 
					                                onDragOver={onDragOver(strg.id)}
 | 
				
			||||||
                            onEditClick={() => {
 | 
					                                onDeleteClick={() =>
 | 
				
			||||||
                                onSelectEditStrategy(strg);
 | 
					                                    milestoneStrategyDeleted(strg.id)
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                                onEditClick={() => {
 | 
				
			||||||
 | 
					                                    openAddUpdateStrategyForm(strg, true);
 | 
				
			||||||
 | 
					                                }}
 | 
				
			||||||
 | 
					                                isDragging={dragItem?.id === strg.id}
 | 
				
			||||||
 | 
					                                strategy={strg}
 | 
				
			||||||
 | 
					                            />
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                    ))}
 | 
				
			||||||
 | 
					                    <StyledAccordionFooter>
 | 
				
			||||||
 | 
					                        <StyledAddStrategyButton
 | 
				
			||||||
 | 
					                            variant='outlined'
 | 
				
			||||||
 | 
					                            color='primary'
 | 
				
			||||||
 | 
					                            onClick={(ev) => setAnchor(ev.currentTarget)}
 | 
				
			||||||
 | 
					                        >
 | 
				
			||||||
 | 
					                            Add strategy
 | 
				
			||||||
 | 
					                        </StyledAddStrategyButton>
 | 
				
			||||||
 | 
					                        <Button
 | 
				
			||||||
 | 
					                            variant='text'
 | 
				
			||||||
 | 
					                            color='primary'
 | 
				
			||||||
 | 
					                            onClick={onDeleteMilestone}
 | 
				
			||||||
 | 
					                            disabled={!removable}
 | 
				
			||||||
 | 
					                        >
 | 
				
			||||||
 | 
					                            <Delete /> Remove milestone
 | 
				
			||||||
 | 
					                        </Button>
 | 
				
			||||||
 | 
					                        <Popover
 | 
				
			||||||
 | 
					                            id={popoverId}
 | 
				
			||||||
 | 
					                            open={isPopoverOpen}
 | 
				
			||||||
 | 
					                            anchorEl={anchor}
 | 
				
			||||||
 | 
					                            onClose={onClose}
 | 
				
			||||||
 | 
					                            onClick={onClose}
 | 
				
			||||||
 | 
					                            PaperProps={{
 | 
				
			||||||
 | 
					                                sx: (theme) => ({
 | 
				
			||||||
 | 
					                                    paddingBottom: theme.spacing(1),
 | 
				
			||||||
 | 
					                                }),
 | 
				
			||||||
                            }}
 | 
					                            }}
 | 
				
			||||||
                            isDragging={dragItem?.id === strg.id}
 | 
					                        >
 | 
				
			||||||
                            strategy={strg}
 | 
					                            <MilestoneStrategyMenuCards
 | 
				
			||||||
                        />
 | 
					                                openEditAddStrategy={(strategy) => {
 | 
				
			||||||
                    </div>
 | 
					                                    openAddUpdateStrategyForm(strategy, false);
 | 
				
			||||||
                ))}
 | 
					                                }}
 | 
				
			||||||
                <StyledAccordionFooter>
 | 
					                            />
 | 
				
			||||||
                    <StyledAddStrategyButton
 | 
					                        </Popover>
 | 
				
			||||||
                        variant='outlined'
 | 
					                    </StyledAccordionFooter>
 | 
				
			||||||
                        color='primary'
 | 
					                </StyledAccordionDetails>
 | 
				
			||||||
                        onClick={(ev) => setAnchor(ev.currentTarget)}
 | 
					            </StyledAccordion>
 | 
				
			||||||
                    >
 | 
					
 | 
				
			||||||
                        Add strategy
 | 
					            <SidebarModal
 | 
				
			||||||
                    </StyledAddStrategyButton>
 | 
					                label='Add strategy to template milestone'
 | 
				
			||||||
                    <Button
 | 
					                onClose={() => {
 | 
				
			||||||
                        variant='text'
 | 
					                    setAddUpdateStrategyOpen(false);
 | 
				
			||||||
                        color='primary'
 | 
					                    setStrategyModeEdit(false);
 | 
				
			||||||
                        onClick={onDeleteMilestone}
 | 
					                }}
 | 
				
			||||||
                        disabled={!removable}
 | 
					                open={addUpdateStrategyOpen}
 | 
				
			||||||
                    >
 | 
					            >
 | 
				
			||||||
                        <Delete /> Remove milestone
 | 
					                <ReleasePlanTemplateAddStrategyForm
 | 
				
			||||||
                    </Button>
 | 
					                    strategy={currentStrategy}
 | 
				
			||||||
                    <Popover
 | 
					                    onAddUpdateStrategy={addUpdateStrategy}
 | 
				
			||||||
                        id={popoverId}
 | 
					                    onCancel={() => {
 | 
				
			||||||
                        open={isPopoverOpen}
 | 
					                        setAddUpdateStrategyOpen(false);
 | 
				
			||||||
                        anchorEl={anchor}
 | 
					                        setStrategyModeEdit(false);
 | 
				
			||||||
                        onClose={onClose}
 | 
					                    }}
 | 
				
			||||||
                        onClick={onClose}
 | 
					                    editMode={strategyModeEdit}
 | 
				
			||||||
                        PaperProps={{
 | 
					                />
 | 
				
			||||||
                            sx: (theme) => ({
 | 
					            </SidebarModal>
 | 
				
			||||||
                                paddingBottom: theme.spacing(1),
 | 
					        </>
 | 
				
			||||||
                            }),
 | 
					 | 
				
			||||||
                        }}
 | 
					 | 
				
			||||||
                    >
 | 
					 | 
				
			||||||
                        <MilestoneStrategyMenuCards
 | 
					 | 
				
			||||||
                            openEditAddStrategy={onSelectStrategy}
 | 
					 | 
				
			||||||
                        />
 | 
					 | 
				
			||||||
                    </Popover>
 | 
					 | 
				
			||||||
                </StyledAccordionFooter>
 | 
					 | 
				
			||||||
            </StyledAccordionDetails>
 | 
					 | 
				
			||||||
        </StyledAccordion>
 | 
					 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,4 @@
 | 
				
			|||||||
import type {
 | 
					import type { IReleasePlanMilestonePayload } from 'interfaces/releasePlans';
 | 
				
			||||||
    IReleasePlanMilestonePayload,
 | 
					 | 
				
			||||||
    IReleasePlanMilestoneStrategy,
 | 
					 | 
				
			||||||
} from 'interfaces/releasePlans';
 | 
					 | 
				
			||||||
import { MilestoneCard } from './MilestoneCard/MilestoneCard';
 | 
					import { MilestoneCard } from './MilestoneCard/MilestoneCard';
 | 
				
			||||||
import { styled, Button, FormHelperText } from '@mui/material';
 | 
					import { styled, Button, FormHelperText } from '@mui/material';
 | 
				
			||||||
import Add from '@mui/icons-material/Add';
 | 
					import Add from '@mui/icons-material/Add';
 | 
				
			||||||
@ -12,11 +9,6 @@ interface IMilestoneListProps {
 | 
				
			|||||||
    setMilestones: React.Dispatch<
 | 
					    setMilestones: React.Dispatch<
 | 
				
			||||||
        React.SetStateAction<IReleasePlanMilestonePayload[]>
 | 
					        React.SetStateAction<IReleasePlanMilestonePayload[]>
 | 
				
			||||||
    >;
 | 
					    >;
 | 
				
			||||||
    openAddStrategyForm: (
 | 
					 | 
				
			||||||
        milestoneId: string,
 | 
					 | 
				
			||||||
        strategy: Omit<IReleasePlanMilestoneStrategy, 'milestoneId'>,
 | 
					 | 
				
			||||||
        editing: boolean,
 | 
					 | 
				
			||||||
    ) => void;
 | 
					 | 
				
			||||||
    errors: { [key: string]: string };
 | 
					    errors: { [key: string]: string };
 | 
				
			||||||
    clearErrors: () => void;
 | 
					    clearErrors: () => void;
 | 
				
			||||||
    milestoneChanged: (milestone: IReleasePlanMilestonePayload) => void;
 | 
					    milestoneChanged: (milestone: IReleasePlanMilestonePayload) => void;
 | 
				
			||||||
@ -30,7 +22,6 @@ const StyledAddMilestoneButton = styled(Button)(({ theme }) => ({
 | 
				
			|||||||
export const MilestoneList = ({
 | 
					export const MilestoneList = ({
 | 
				
			||||||
    milestones,
 | 
					    milestones,
 | 
				
			||||||
    setMilestones,
 | 
					    setMilestones,
 | 
				
			||||||
    openAddStrategyForm,
 | 
					 | 
				
			||||||
    errors,
 | 
					    errors,
 | 
				
			||||||
    clearErrors,
 | 
					    clearErrors,
 | 
				
			||||||
    milestoneChanged,
 | 
					    milestoneChanged,
 | 
				
			||||||
@ -51,7 +42,6 @@ export const MilestoneList = ({
 | 
				
			|||||||
                        key={milestone.id}
 | 
					                        key={milestone.id}
 | 
				
			||||||
                        milestone={milestone}
 | 
					                        milestone={milestone}
 | 
				
			||||||
                        milestoneChanged={milestoneChanged}
 | 
					                        milestoneChanged={milestoneChanged}
 | 
				
			||||||
                        showAddStrategyDialog={openAddStrategyForm}
 | 
					 | 
				
			||||||
                        errors={errors}
 | 
					                        errors={errors}
 | 
				
			||||||
                        clearErrors={clearErrors}
 | 
					                        clearErrors={clearErrors}
 | 
				
			||||||
                        removable={milestones.length > 1}
 | 
					                        removable={milestones.length > 1}
 | 
				
			||||||
 | 
				
			|||||||
@ -124,18 +124,15 @@ const StyledDividerContent = styled(Box)(({ theme }) => ({
 | 
				
			|||||||
}));
 | 
					}));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface IReleasePlanTemplateAddStrategyFormProps {
 | 
					interface IReleasePlanTemplateAddStrategyFormProps {
 | 
				
			||||||
    milestoneId: string | undefined;
 | 
					 | 
				
			||||||
    onCancel: () => void;
 | 
					    onCancel: () => void;
 | 
				
			||||||
    strategy: Omit<IReleasePlanMilestoneStrategy, 'milestoneId'>;
 | 
					    strategy: Omit<IReleasePlanMilestoneStrategy, 'milestoneId'>;
 | 
				
			||||||
    onAddUpdateStrategy: (
 | 
					    onAddUpdateStrategy: (
 | 
				
			||||||
        milestoneId: string,
 | 
					 | 
				
			||||||
        strategy: Omit<IReleasePlanMilestoneStrategy, 'milestoneId'>,
 | 
					        strategy: Omit<IReleasePlanMilestoneStrategy, 'milestoneId'>,
 | 
				
			||||||
    ) => void;
 | 
					    ) => void;
 | 
				
			||||||
    editMode: boolean;
 | 
					    editMode: boolean;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const ReleasePlanTemplateAddStrategyForm = ({
 | 
					export const ReleasePlanTemplateAddStrategyForm = ({
 | 
				
			||||||
    milestoneId,
 | 
					 | 
				
			||||||
    onCancel,
 | 
					    onCancel,
 | 
				
			||||||
    strategy,
 | 
					    strategy,
 | 
				
			||||||
    onAddUpdateStrategy,
 | 
					    onAddUpdateStrategy,
 | 
				
			||||||
@ -231,11 +228,7 @@ export const ReleasePlanTemplateAddStrategyForm = ({
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const AddUpdateMilestoneStrategy = () => {
 | 
					    const AddUpdateMilestoneStrategy = () => {
 | 
				
			||||||
        if (!milestoneId) {
 | 
					        onAddUpdateStrategy(currentStrategy);
 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        onAddUpdateStrategy(milestoneId, currentStrategy);
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
 | 
				
			|||||||
@ -1,15 +1,9 @@
 | 
				
			|||||||
import Input from 'component/common/Input/Input';
 | 
					import Input from 'component/common/Input/Input';
 | 
				
			||||||
import { styled, useTheme } from '@mui/material';
 | 
					import { styled, useTheme } from '@mui/material';
 | 
				
			||||||
import type {
 | 
					import type { IReleasePlanMilestonePayload } from 'interfaces/releasePlans';
 | 
				
			||||||
    IReleasePlanMilestonePayload,
 | 
					 | 
				
			||||||
    IReleasePlanMilestoneStrategy,
 | 
					 | 
				
			||||||
} from 'interfaces/releasePlans';
 | 
					 | 
				
			||||||
import FormTemplate from 'component/common/FormTemplate/FormTemplate';
 | 
					import FormTemplate from 'component/common/FormTemplate/FormTemplate';
 | 
				
			||||||
import { useState } from 'react';
 | 
					 | 
				
			||||||
import { TemplateFormDescription } from './TemplateFormDescription';
 | 
					import { TemplateFormDescription } from './TemplateFormDescription';
 | 
				
			||||||
import { MilestoneList } from './MilestoneList/MilestoneList';
 | 
					import { MilestoneList } from './MilestoneList/MilestoneList';
 | 
				
			||||||
import { SidebarModal } from 'component/common/SidebarModal/SidebarModal';
 | 
					 | 
				
			||||||
import { ReleasePlanTemplateAddStrategyForm } from './MilestoneStrategy/ReleasePlanTemplateAddStrategyForm';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const StyledInput = styled(Input)(({ theme }) => ({
 | 
					const StyledInput = styled(Input)(({ theme }) => ({
 | 
				
			||||||
    width: '100%',
 | 
					    width: '100%',
 | 
				
			||||||
@ -61,77 +55,7 @@ export const TemplateForm: React.FC<ITemplateFormProps> = ({
 | 
				
			|||||||
    handleSubmit,
 | 
					    handleSubmit,
 | 
				
			||||||
    children,
 | 
					    children,
 | 
				
			||||||
}) => {
 | 
					}) => {
 | 
				
			||||||
    const [addUpdateStrategyOpen, setAddUpdateStrategyOpen] = useState(false);
 | 
					 | 
				
			||||||
    const [activeMilestoneId, setActiveMilestoneId] = useState<
 | 
					 | 
				
			||||||
        string | undefined
 | 
					 | 
				
			||||||
    >();
 | 
					 | 
				
			||||||
    const [strategyModeEdit, setStrategyModeEdit] = useState(false);
 | 
					 | 
				
			||||||
    const [strategy, setStrategy] = useState<
 | 
					 | 
				
			||||||
        Omit<IReleasePlanMilestoneStrategy, 'milestoneId'>
 | 
					 | 
				
			||||||
    >({
 | 
					 | 
				
			||||||
        name: 'flexibleRollout',
 | 
					 | 
				
			||||||
        parameters: { rollout: '50' },
 | 
					 | 
				
			||||||
        constraints: [],
 | 
					 | 
				
			||||||
        title: '',
 | 
					 | 
				
			||||||
        id: 'temp',
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const theme = useTheme();
 | 
					    const theme = useTheme();
 | 
				
			||||||
    const openAddUpdateStrategyForm = (
 | 
					 | 
				
			||||||
        milestoneId: string,
 | 
					 | 
				
			||||||
        strategy: Omit<IReleasePlanMilestoneStrategy, 'milestoneId'>,
 | 
					 | 
				
			||||||
        editing: boolean,
 | 
					 | 
				
			||||||
    ) => {
 | 
					 | 
				
			||||||
        setStrategyModeEdit(editing);
 | 
					 | 
				
			||||||
        setActiveMilestoneId(milestoneId);
 | 
					 | 
				
			||||||
        setStrategy(strategy);
 | 
					 | 
				
			||||||
        setAddUpdateStrategyOpen(true);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const addUpdateStrategy = (
 | 
					 | 
				
			||||||
        milestoneId: string,
 | 
					 | 
				
			||||||
        strategy: Omit<IReleasePlanMilestoneStrategy, 'milestoneId'>,
 | 
					 | 
				
			||||||
    ) => {
 | 
					 | 
				
			||||||
        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) => {
 | 
					    const milestoneChanged = (milestone: IReleasePlanMilestonePayload) => {
 | 
				
			||||||
        setMilestones((prev) =>
 | 
					        setMilestones((prev) =>
 | 
				
			||||||
@ -141,21 +65,6 @@ export const TemplateForm: React.FC<ITemplateFormProps> = ({
 | 
				
			|||||||
        );
 | 
					        );
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const milestoneStrategyChanged = (
 | 
					 | 
				
			||||||
        milestone: IReleasePlanMilestonePayload,
 | 
					 | 
				
			||||||
        strategy: Omit<IReleasePlanMilestoneStrategy, 'milestoneId'>,
 | 
					 | 
				
			||||||
    ) => {
 | 
					 | 
				
			||||||
        const strategies = milestone.strategies || [];
 | 
					 | 
				
			||||||
        milestoneChanged({
 | 
					 | 
				
			||||||
            ...milestone,
 | 
					 | 
				
			||||||
            strategies: [
 | 
					 | 
				
			||||||
                ...strategies.map((strat) =>
 | 
					 | 
				
			||||||
                    strat.id === strategy.id ? strategy : strat,
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        <FormTemplate
 | 
					        <FormTemplate
 | 
				
			||||||
            title={formTitle}
 | 
					            title={formTitle}
 | 
				
			||||||
@ -203,33 +112,12 @@ export const TemplateForm: React.FC<ITemplateFormProps> = ({
 | 
				
			|||||||
                <MilestoneList
 | 
					                <MilestoneList
 | 
				
			||||||
                    milestones={milestones}
 | 
					                    milestones={milestones}
 | 
				
			||||||
                    setMilestones={setMilestones}
 | 
					                    setMilestones={setMilestones}
 | 
				
			||||||
                    openAddStrategyForm={openAddUpdateStrategyForm}
 | 
					 | 
				
			||||||
                    errors={errors}
 | 
					                    errors={errors}
 | 
				
			||||||
                    clearErrors={clearErrors}
 | 
					                    clearErrors={clearErrors}
 | 
				
			||||||
                    milestoneChanged={milestoneChanged}
 | 
					                    milestoneChanged={milestoneChanged}
 | 
				
			||||||
                />
 | 
					                />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                {children}
 | 
					                {children}
 | 
				
			||||||
 | 
					 | 
				
			||||||
                <SidebarModal
 | 
					 | 
				
			||||||
                    label='Add strategy to template milestone'
 | 
					 | 
				
			||||||
                    onClose={() => {
 | 
					 | 
				
			||||||
                        setAddUpdateStrategyOpen(false);
 | 
					 | 
				
			||||||
                        setStrategyModeEdit(false);
 | 
					 | 
				
			||||||
                    }}
 | 
					 | 
				
			||||||
                    open={addUpdateStrategyOpen}
 | 
					 | 
				
			||||||
                >
 | 
					 | 
				
			||||||
                    <ReleasePlanTemplateAddStrategyForm
 | 
					 | 
				
			||||||
                        milestoneId={activeMilestoneId}
 | 
					 | 
				
			||||||
                        strategy={strategy}
 | 
					 | 
				
			||||||
                        onAddUpdateStrategy={addUpdateStrategy}
 | 
					 | 
				
			||||||
                        onCancel={() => {
 | 
					 | 
				
			||||||
                            setAddUpdateStrategyOpen(false);
 | 
					 | 
				
			||||||
                            setStrategyModeEdit(false);
 | 
					 | 
				
			||||||
                        }}
 | 
					 | 
				
			||||||
                        editMode={strategyModeEdit}
 | 
					 | 
				
			||||||
                    />
 | 
					 | 
				
			||||||
                </SidebarModal>
 | 
					 | 
				
			||||||
            </StyledForm>
 | 
					            </StyledForm>
 | 
				
			||||||
        </FormTemplate>
 | 
					        </FormTemplate>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user