1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-10-27 11:02:16 +01:00

refactor: consolidated progression changes

This commit is contained in:
FredrikOseberg 2025-10-22 10:42:31 +02:00
parent cb9fa72de1
commit dc5d7a89b3
No known key found for this signature in database
GPG Key ID: 282FD8A6D8F9BCF0

View File

@ -1,5 +1,5 @@
import type { FC } from 'react'; import type { FC } from 'react';
import { Alert, styled } from '@mui/material'; import { styled } from '@mui/material';
import type { import type {
ChangeRequestState, ChangeRequestState,
IChangeRequestCreateMilestoneProgression, IChangeRequestCreateMilestoneProgression,
@ -26,6 +26,82 @@ const StyledTabs = styled(Tabs)(({ theme }) => ({
gap: theme.spacing(1), gap: theme.spacing(1),
})); }));
type ProgressionChange =
| IChangeRequestCreateMilestoneProgression
| IChangeRequestUpdateMilestoneProgression
| IChangeRequestDeleteMilestoneProgression;
const getFirstChangeWithSnapshot = (
progressionChanges: ProgressionChange[],
) => {
return (
progressionChanges.find(
(change) =>
change.payload?.snapshot &&
(change.action === 'createMilestoneProgression' ||
change.action === 'updateMilestoneProgression'),
) || progressionChanges.find((change) => change.payload?.snapshot)
);
};
const getMilestonesWithAutomation = (
progressionChanges: ProgressionChange[],
): Set<string> => {
return new Set(
progressionChanges
.filter(
(change) =>
change.action === 'createMilestoneProgression' ||
change.action === 'updateMilestoneProgression',
)
.map((change) =>
change.action === 'createMilestoneProgression'
? change.payload.sourceMilestone
: change.payload.sourceMilestoneId ||
change.payload.sourceMilestone,
)
.filter((id): id is string => Boolean(id)),
);
};
const getMilestonesWithDeletedAutomation = (
progressionChanges: ProgressionChange[],
): Set<string> => {
return new Set(
progressionChanges
.filter((change) => change.action === 'deleteMilestoneProgression')
.map(
(change) =>
change.payload.sourceMilestoneId ||
change.payload.sourceMilestone,
)
.filter((id): id is string => Boolean(id)),
);
};
const getChangeDescriptions = (
progressionChanges: ProgressionChange[],
basePlan: IReleasePlan,
): string[] => {
return progressionChanges.map((change) => {
const sourceId =
change.action === 'createMilestoneProgression'
? change.payload.sourceMilestone
: change.payload.sourceMilestoneId ||
change.payload.sourceMilestone;
const sourceName =
basePlan.milestones.find((milestone) => milestone.id === sourceId)
?.name || sourceId;
const action =
change.action === 'createMilestoneProgression'
? 'Adding'
: change.action === 'deleteMilestoneProgression'
? 'Deleting'
: 'Updating';
return `${action} automation for ${sourceName}`;
});
};
export const ConsolidatedProgressionChanges: FC<{ export const ConsolidatedProgressionChanges: FC<{
feature: IChangeRequestFeature; feature: IChangeRequestFeature;
currentReleasePlan?: IReleasePlan; currentReleasePlan?: IReleasePlan;
@ -57,84 +133,32 @@ export const ConsolidatedProgressionChanges: FC<{
if (progressionChanges.length === 0) return null; if (progressionChanges.length === 0) return null;
// Use snapshot from first change if available, otherwise use current release plan
const firstChangeWithSnapshot = const firstChangeWithSnapshot =
progressionChanges.find( getFirstChangeWithSnapshot(progressionChanges);
(change) =>
change.payload?.snapshot &&
(change.action === 'createMilestoneProgression' ||
change.action === 'updateMilestoneProgression'),
) || progressionChanges.find((change) => change.payload?.snapshot);
const basePlan = const basePlan =
firstChangeWithSnapshot?.payload?.snapshot || currentReleasePlan; firstChangeWithSnapshot?.payload?.snapshot || currentReleasePlan;
if (!basePlan) { if (!basePlan) {
return ( return null;
<Alert severity='error'>
Unable to load release plan data. Please refresh the page.
</Alert>
);
} }
// Apply all progression changes
const modifiedPlan = applyProgressionChanges(basePlan, progressionChanges); const modifiedPlan = applyProgressionChanges(basePlan, progressionChanges);
const milestonesWithAutomation =
// Collect milestone IDs with automation (modified or original) getMilestonesWithAutomation(progressionChanges);
const milestonesWithAutomation = new Set( const milestonesWithDeletedAutomation =
progressionChanges getMilestonesWithDeletedAutomation(progressionChanges);
.filter( const changeDescriptions = getChangeDescriptions(
(change) => progressionChanges,
change.action === 'createMilestoneProgression' || basePlan,
change.action === 'updateMilestoneProgression',
)
.map((change) =>
change.action === 'createMilestoneProgression'
? change.payload.sourceMilestone
: change.payload.sourceMilestoneId ||
change.payload.sourceMilestone,
)
.filter((id): id is string => Boolean(id)),
); );
const milestonesWithDeletedAutomation = new Set(
progressionChanges
.filter((change) => change.action === 'deleteMilestoneProgression')
.map(
(change) =>
change.payload.sourceMilestoneId ||
change.payload.sourceMilestone,
)
.filter((id): id is string => Boolean(id)),
);
const changeDescriptions = progressionChanges.map((change) => {
const sourceId =
change.action === 'createMilestoneProgression'
? change.payload.sourceMilestone
: change.payload.sourceMilestoneId ||
change.payload.sourceMilestone;
const sourceName =
basePlan.milestones.find((milestone) => milestone.id === sourceId)
?.name || sourceId;
const action =
change.action === 'createMilestoneProgression'
? 'Adding'
: change.action === 'deleteMilestoneProgression'
? 'Deleting'
: 'Updating';
return `${action} automation for ${sourceName}`;
});
// For diff view, we need to use basePlan with deleted automations shown
const basePlanWithDeletedAutomations: IReleasePlan = { const basePlanWithDeletedAutomations: IReleasePlan = {
...basePlan, ...basePlan,
milestones: basePlan.milestones.map((milestone) => { milestones: basePlan.milestones.map((milestone) =>
// If this milestone is being deleted, ensure it has its transition condition milestonesWithDeletedAutomation.has(milestone.id)
if (milestonesWithDeletedAutomation.has(milestone.id)) { ? milestone
return milestone; : milestone,
} ),
return milestone;
}),
}; };
return ( return (