Files
chapter-organizer/WebApp/Services/MeetingScheduleClipboardService.cs
T
poprhythm ddb743847d Add meeting schedule state management services and related models
This commit introduces several new services and models to manage the meeting schedule state within localStorage. The MeetingScheduleState class is created to track scheduled teams, absent students, time slot counts, extended teams, and excluded students. Additionally, the IMeetingScheduleStateService interface and its implementation, MeetingScheduleStateService, are added to handle loading and saving state data. The MeetingScheduleClipboardService and MeetingScheduleDataService are also introduced to facilitate clipboard operations and data loading from the database, respectively. These enhancements improve the overall functionality and user experience of the meeting scheduling feature.
2026-01-19 23:02:55 -05:00

124 lines
4.2 KiB
C#

using System.Text;
using Core.Calculation;
using Core.Entities;
using Core.Utility;
namespace WebApp.Services;
/// <summary>
/// Service for formatting meeting schedule data for clipboard operations.
/// </summary>
public class MeetingScheduleClipboardService : IMeetingScheduleClipboardService
{
public string FormatScheduleForClipboard(
TeamSchedulerSolution solution,
Team[] allTeams,
IEnumerable<Student> absentStudents,
Dictionary<(int teamId, int timeSlotIndex, int studentId), bool> excludedStudents,
Func<string, int> getTimeSlotIndex)
{
var sb = new StringBuilder();
foreach (var timeslot in solution.TimeSlots)
{
AppendScheduledTeams(sb, timeslot, allTeams, absentStudents, excludedStudents, getTimeSlotIndex);
AppendUnscheduledStudents(sb, timeslot, solution, absentStudents);
sb.Append(Environment.NewLine);
}
return sb.ToString();
}
private void AppendScheduledTeams(
StringBuilder sb,
TeamScheduleTimeSlot timeslot,
Team[] allTeams,
IEnumerable<Student> absentStudents,
Dictionary<(int teamId, int timeSlotIndex, int studentId), bool> excludedStudents,
Func<string, int> getTimeSlotIndex)
{
var timeSlotIndex = getTimeSlotIndex(timeslot.Name);
foreach (var scheduledTeam in timeslot.Teams.OrderBy(e => e.ToString()))
{
var teamName = scheduledTeam.ToString();
if (scheduledTeam.Event.EventFormat is EventFormat.Individual)
{
sb.Append(teamName);
}
else
{
var studentsList = FormatStudentList(scheduledTeam, timeslot, timeSlotIndex, absentStudents, excludedStudents);
sb.Append($"{teamName} - {studentsList}");
}
sb.Append(Environment.NewLine);
}
}
private string FormatStudentList(
Team team,
TeamScheduleTimeSlot timeslot,
int timeSlotIndex,
IEnumerable<Student> absentStudents,
Dictionary<(int teamId, int timeSlotIndex, int studentId), bool> excludedStudents)
{
// Filter out excluded students for this team and time slot
var excludedStudentIds = excludedStudents.Keys
.Where(k => k.teamId == team.Id && k.timeSlotIndex == timeSlotIndex && excludedStudents[k])
.Select(k => k.studentId)
.ToHashSet();
var includedStudents = team.Students
.Where(s => !excludedStudentIds.Contains(s.Id))
.ToList();
// Create a temporary team with only included students for formatting
var teamForFormatting = new Team
{
Id = team.Id,
Event = team.Event,
Students = includedStudents,
Captain = team.Captain,
Identifier = team.Identifier
};
return TeamStudentNameFormatter.FormatStudentList(
teamForFormatting,
new TeamStudentNameFormatter.FormatOptions
{
Ordering = TeamStudentNameFormatter.OrderingStyle.CaptainFirst,
MarkOverlaps = true,
HasOverlaps = timeslot.StudentHasOverlaps,
MarkAbsent = true,
AbsentStudents = absentStudents.ToList()
});
}
private void AppendUnscheduledStudents(
StringBuilder sb,
TeamScheduleTimeSlot timeslot,
TeamSchedulerSolution solution,
IEnumerable<Student> absentStudents)
{
if (!timeslot.UnscheduledStudents.Any())
return;
sb.Append("--Unscheduled");
sb.Append(Environment.NewLine);
foreach (var student in timeslot.UnscheduledStudents)
{
var studentName = StudentNameFormatter.FormatStudentName(
student,
new StudentNameFormatter.FormatOptions
{
IsAbsent = absentStudents.Contains(student)
});
var unassignedTeams = solution.StudentUnassignedTeams(student);
var teamsList = string.Join(", ", unassignedTeams.Select(e => e.ToString()));
sb.Append($"{studentName} - {teamsList}");
sb.Append(Environment.NewLine);
}
}
}