diff --git a/WebApp/Components/Features/MeetingSchedule/Index.razor b/WebApp/Components/Features/MeetingSchedule/Index.razor index 57daf69..fe1ad39 100644 --- a/WebApp/Components/Features/MeetingSchedule/Index.razor +++ b/WebApp/Components/Features/MeetingSchedule/Index.razor @@ -377,6 +377,8 @@ _solutionData.ReloadServerData(); } + // TODO: Move team extension logic into Core.Calculation.TeamScheduler to handle extended teams + // as part of the constraint programming model rather than post-processing private void ExtendTeamsInSolution(TeamSchedulerSolution solution, IEnumerable extendedTeams, Student[] allStudents) { if (solution.TimeSlots == null || !solution.TimeSlots.Any()) @@ -388,7 +390,7 @@ var extendedTeamIds = extendedTeamsList.Select(t => t.Id).ToHashSet(); - // Find which time slot each extended team is in + // Find which time slot each extended team is in and extend both forward and backward for (int slotIndex = 0; slotIndex < solution.TimeSlots.Length; slotIndex++) { var currentSlot = solution.TimeSlots[slotIndex]; @@ -397,34 +399,47 @@ if (!teamsToExtend.Any()) continue; - // Check if there's a next time slot - if (slotIndex + 1 >= solution.TimeSlots.Length) + // Extend forward: add to next time slot (if exists) + if (slotIndex + 1 < solution.TimeSlots.Length) { - // Cannot extend - this is the last time slot - continue; - } - - var nextSlot = solution.TimeSlots[slotIndex + 1]; - - // Add extended teams to the next time slot - var nextSlotTeamsList = nextSlot.Teams.ToList(); - var nextSlotTeamIds = nextSlotTeamsList.Select(t => t.Id).ToHashSet(); - - foreach (var team in teamsToExtend) - { - if (!nextSlotTeamIds.Contains(team.Id)) + var nextSlot = solution.TimeSlots[slotIndex + 1]; + var nextSlotTeamsList = nextSlot.Teams.ToList(); + var nextSlotTeamIds = nextSlotTeamsList.Select(t => t.Id).ToHashSet(); + + foreach (var team in teamsToExtend) { - nextSlotTeamsList.Add(team); - nextSlotTeamIds.Add(team.Id); + if (!nextSlotTeamIds.Contains(team.Id)) + { + nextSlotTeamsList.Add(team); + nextSlotTeamIds.Add(team.Id); + } } + + nextSlot.Teams = nextSlotTeamsList.ToArray(); + nextSlot.StudentOverlaps = TeamSchedulerSolution.GetStudentTeamOverlaps(nextSlot.Teams); + nextSlot.UnscheduledStudents = TeamSchedulerSolution.GetStudentsNotInTimSlot(nextSlot.Teams, allStudents); } - // Update the next slot with the extended teams - nextSlot.Teams = nextSlotTeamsList.ToArray(); + // Extend backward: add to previous time slot (if exists) + if (slotIndex > 0) + { + var previousSlot = solution.TimeSlots[slotIndex - 1]; + var previousSlotTeamsList = previousSlot.Teams.ToList(); + var previousSlotTeamIds = previousSlotTeamsList.Select(t => t.Id).ToHashSet(); + + foreach (var team in teamsToExtend) + { + if (!previousSlotTeamIds.Contains(team.Id)) + { + previousSlotTeamsList.Add(team); + previousSlotTeamIds.Add(team.Id); + } + } - // Recalculate overlaps and unscheduled students for the next slot - nextSlot.StudentOverlaps = TeamSchedulerSolution.GetStudentTeamOverlaps(nextSlot.Teams); - nextSlot.UnscheduledStudents = TeamSchedulerSolution.GetStudentsNotInTimSlot(nextSlot.Teams, allStudents); + previousSlot.Teams = previousSlotTeamsList.ToArray(); + previousSlot.StudentOverlaps = TeamSchedulerSolution.GetStudentTeamOverlaps(previousSlot.Teams); + previousSlot.UnscheduledStudents = TeamSchedulerSolution.GetStudentsNotInTimSlot(previousSlot.Teams, allStudents); + } } }