import type { FC } from 'react'; import { styled } from '@mui/material'; import type { ChangeRequestState, IChangeRequestChangeMilestoneProgression, IChangeRequestDeleteMilestoneProgression, IChangeRequestFeature, } from 'component/changeRequest/changeRequest.types'; import type { IReleasePlan } from 'interfaces/releasePlans'; import { Tab, TabList, TabPanel, Tabs } from './ChangeTabComponents.tsx'; import { Added, ChangeItemInfo, ChangeItemWrapper, Deleted, } from './Change.styles.tsx'; import type { ChangeMilestoneProgressionSchema } from 'openapi'; import { MilestoneListRenderer } from './MilestoneListRenderer.tsx'; import { applyProgressionChanges } from './applyProgressionChanges.js'; import { EventDiff } from 'component/events/EventDiff/EventDiff'; const StyledTabs = styled(Tabs)(({ theme }) => ({ display: 'flex', flexFlow: 'column', gap: theme.spacing(1), })); type ProgressionChange = | IChangeRequestChangeMilestoneProgression | IChangeRequestDeleteMilestoneProgression; const getFirstChangeWithSnapshot = ( progressionChanges: ProgressionChange[], ) => { return ( progressionChanges.find( (change) => change.payload?.snapshot && change.action === 'changeMilestoneProgression', ) || progressionChanges.find((change) => change.payload?.snapshot) ); }; const getMilestonesWithAutomation = ( progressionChanges: ProgressionChange[], ): Set => { return new Set( progressionChanges .filter((change) => change.action === 'changeMilestoneProgression') .map((change) => change.payload.sourceMilestone) .filter((id): id is string => Boolean(id)), ); }; const getMilestonesWithDeletedAutomation = ( progressionChanges: ProgressionChange[], ): Set => { return new Set( progressionChanges .filter((change) => change.action === 'deleteMilestoneProgression') .map((change) => change.payload.sourceMilestone) .filter((id): id is string => Boolean(id)), ); }; const getChangeDescriptions = ( progressionChanges: ProgressionChange[], basePlan: IReleasePlan, ): string[] => { return progressionChanges.map((change) => { const sourceId = change.payload.sourceMilestone; const sourceName = basePlan.milestones.find((milestone) => milestone.id === sourceId) ?.name || sourceId; const action = change.action === 'changeMilestoneProgression' ? 'Changing' : 'Deleting'; return `${action} automation for ${sourceName}`; }); }; export const ConsolidatedProgressionChanges: FC<{ feature: IChangeRequestFeature; currentReleasePlan?: IReleasePlan; changeRequestState: ChangeRequestState; onUpdateChangeRequestSubmit?: ( sourceMilestoneId: string, payload: ChangeMilestoneProgressionSchema, ) => Promise; onDeleteChangeRequestSubmit?: (sourceMilestoneId: string) => Promise; }> = ({ feature, currentReleasePlan, changeRequestState, onUpdateChangeRequestSubmit, onDeleteChangeRequestSubmit, }) => { // Get all progression changes for this feature const progressionChanges = feature.changes.filter( ( change, ): change is | IChangeRequestChangeMilestoneProgression | IChangeRequestDeleteMilestoneProgression => change.action === 'changeMilestoneProgression' || change.action === 'deleteMilestoneProgression', ); if (progressionChanges.length === 0) return null; const firstChangeWithSnapshot = getFirstChangeWithSnapshot(progressionChanges); const basePlan = firstChangeWithSnapshot?.payload?.snapshot || currentReleasePlan; if (!basePlan) { return null; } const modifiedPlan = applyProgressionChanges(basePlan, progressionChanges); const milestonesWithAutomation = getMilestonesWithAutomation(progressionChanges); const milestonesWithDeletedAutomation = getMilestonesWithDeletedAutomation(progressionChanges); const changeDescriptions = getChangeDescriptions( progressionChanges, basePlan, ); return ( {progressionChanges.map((change, index) => { const Component = change.action === 'deleteMilestoneProgression' ? Deleted : Added; return ( {changeDescriptions[index]} ); })}
View change View diff
); };