in src/PortfolioPlanning/Redux/Reducers/EpicTimelineReducer.ts [152:304]
function handlePortfolioItemsReceived(
state: IEpicTimelineState,
action: PortfolioItemsReceivedAction
): IEpicTimelineState {
return produce(state, draft => {
const { result, projectConfigurations } = action.payload;
const { items, projects, teamAreas, mergeStrategy } = result;
if (mergeStrategy === MergeType.Replace) {
draft.projects = projects.projects.map(project => {
return {
id: project.ProjectSK,
title: project.ProjectName,
configuration: projectConfigurations[project.ProjectSK.toLowerCase()]
};
});
draft.epics = items.items.map(item => {
// Using the first team found for the area, if available.
const teamIdValue: string =
teamAreas.teamsInArea[item.AreaId] && teamAreas.teamsInArea[item.AreaId][0]
? teamAreas.teamsInArea[item.AreaId][0].teamId
: null;
const backlogLevelName: string = projectConfigurations[item.ProjectId]
? projectConfigurations[item.ProjectId].backlogLevelNamesByWorkItemType[
item.WorkItemType.toLowerCase()
]
: null;
const iconProps: IWorkItemIcon = projectConfigurations[item.ProjectId]
? projectConfigurations[item.ProjectId].iconInfoByWorkItemType[item.WorkItemType.toLowerCase()]
: null;
return {
id: item.WorkItemId,
backlogLevel: backlogLevelName,
project: item.ProjectId,
teamId: teamIdValue,
title: item.Title,
iconProps,
startDate: item.StartDate,
endDate: item.TargetDate,
completedCount: item.CompletedCount,
totalCount: item.TotalCount,
completedEffort: item.CompletedEffort,
totalEffort: item.TotalEffort,
effortProgress: item.EffortProgress,
countProgress: item.CountProgress,
itemUpdating: false
};
});
draft.teams = {};
if (teamAreas.teamsInArea) {
Object.keys(teamAreas.teamsInArea).forEach(areaId => {
const teams = teamAreas.teamsInArea[areaId];
teams.forEach(team => {
if (!draft.teams[team.teamId]) {
draft.teams[team.teamId] = {
teamId: team.teamId,
teamName: team.teamName
};
}
});
});
}
} else if (mergeStrategy === MergeType.Add) {
projects.projects.forEach(newProjectInfo => {
const filteredProjects = draft.projects.filter(p => p.id === newProjectInfo.ProjectSK);
if (filteredProjects.length === 0) {
draft.projects.push({
id: newProjectInfo.ProjectSK,
title: newProjectInfo.ProjectName,
configuration: projectConfigurations[newProjectInfo.ProjectSK.toLowerCase()]
});
}
});
// TODO change draft.projects and draft.epics to maps
items.items.forEach(newItemInfo => {
const filteredItems = draft.epics.filter(p => p.id === newItemInfo.WorkItemId);
if (filteredItems.length === 0) {
// Using the first team found for the area, if available.
const teamIdValue: string =
teamAreas.teamsInArea[newItemInfo.AreaId] && teamAreas.teamsInArea[newItemInfo.AreaId][0]
? teamAreas.teamsInArea[newItemInfo.AreaId][0].teamId
: null;
const backlogLevelName: string = projectConfigurations[newItemInfo.ProjectId]
? projectConfigurations[newItemInfo.ProjectId].backlogLevelNamesByWorkItemType[
newItemInfo.WorkItemType.toLowerCase()
]
: null;
const iconProps: IWorkItemIcon = projectConfigurations[newItemInfo.ProjectId]
? projectConfigurations[newItemInfo.ProjectId].iconInfoByWorkItemType[
newItemInfo.WorkItemType.toLowerCase()
]
: null;
draft.epics.push({
id: newItemInfo.WorkItemId,
backlogLevel: backlogLevelName,
project: newItemInfo.ProjectId,
teamId: teamIdValue,
iconProps,
title: newItemInfo.Title,
startDate: newItemInfo.StartDate,
endDate: newItemInfo.TargetDate,
completedCount: newItemInfo.CompletedCount,
totalCount: newItemInfo.TotalCount,
completedEffort: newItemInfo.CompletedEffort,
totalEffort: newItemInfo.TotalEffort,
effortProgress: newItemInfo.EffortProgress,
countProgress: newItemInfo.CountProgress,
itemUpdating: false
});
}
});
if (teamAreas.teamsInArea && draft.teams) {
Object.keys(teamAreas.teamsInArea).forEach(areaId => {
const teams = teamAreas.teamsInArea[areaId];
teams.forEach(team => {
if (!draft.teams[team.teamId]) {
draft.teams[team.teamId] = {
teamId: team.teamId,
teamName: team.teamName
};
}
});
});
}
// Sort projects by name for displaying in the timeline.
draft.projects.sort(defaultIProjectComparer);
// Not loading anymore.
draft.planLoadingStatus = LoadingStatus.Loaded;
}
// Sort timeline items by name.
if (draft.epics) {
draft.epics.sort(defaultIWorkItemComparer);
}
});
}