Add Blazor WebApp and rework data handling to utilize Entity Framework

This commit is contained in:
2025-09-11 11:49:48 -04:00
parent 5220e61c79
commit 3daa3b81b3
111 changed files with 6039 additions and 946 deletions
+49 -39
View File
@@ -14,23 +14,31 @@ namespace Web.Controllers
{
private const string ContentDirectory = @"C:\Users\james\source\TSA Chapter Organizer\Tests\Parsers\TestInput\";
private CompetitiveEvent[] GetCompetitiveEvents()
private EventDefinition[] GetEvents()
{
var fileInfo = FileUtility.GetContentFile(ContentDirectory, "2024-25 RMS TSA student & event - Event Definitions.csv");
var fileInfo = FileUtility.GetContentFile(ContentDirectory, "2024-25 RMS TSA student & eventDefinition - EventDefinition Definitions.csv");
var eventRankingsParser = new EventDefinitionParser(fileInfo);
return eventRankingsParser.Parse();
}
private Student[] GetStudents(IList<CompetitiveEvent> events)
private Student[] GetStudents(IList<EventDefinition> events)
{
var fileInfo = FileUtility.GetContentFile(ContentDirectory, "2024-25 RMS TSA student & event - Nationals Student Event Rankings.csv");
var fileInfo = FileUtility.GetContentFile(ContentDirectory, "2024-25 RMS TSA student & eventDefinition - Nationals Student EventDefinition Rankings.csv");
var eventRankingsParser = new StudentParser(fileInfo);
return eventRankingsParser.Parse(events);
}
public Team[] GetTeams(IList<CompetitiveEvent> competitiveEvents, IList<Student> students)
public static StudentEventRanking[] GetStudentEventRankings(Student[] students, EventDefinition[] events)
{
var fileInfo = FileUtility.GetContentFile(ContentDirectory, "2024-25 RMS TSA - Student Event Rankings.csv");
var rankingParser = new StudentEventRankingParser(fileInfo);
return rankingParser.Parse(students, events);
}
public Team[] GetTeams(IList<EventDefinition> competitiveEvents, IList<Student> students)
{
var studentEventRankingsCsv = "2024-25 RMS TSA student & event - Nationals Teams.csv";
var studentEventRankingsCsv = "2024-25 RMS TSA student & eventDefinition - Nationals Teams.csv";
var fileInfo = FileUtility.GetContentFile(ContentDirectory, studentEventRankingsCsv);
var eventRankingsParser = new TeamParser(fileInfo);
@@ -43,9 +51,9 @@ namespace Web.Controllers
return teams;
}
public AssignmentAssumption[] GetAssignmentAssumptions(IList<CompetitiveEvent> competitiveEvents, IList<Student> students)
public AssignmentAssumption[] GetAssignmentAssumptions(IList<EventDefinition> competitiveEvents, IList<Student> students)
{
var assumptionsCsv = "2024-25 RMS TSA student & event - assumptions.csv";
var assumptionsCsv = "2024-25 RMS TSA student & eventDefinition - assumptions.csv";
var fileInfo = FileUtility.GetContentFile(ContentDirectory, assumptionsCsv);
var assumptionParser = new AssignmentAssumptionParser(fileInfo);
@@ -54,17 +62,17 @@ namespace Web.Controllers
return assumptions;
}
public IDictionary<CompetitiveEvent, List<EventOccurrence>> GetStateEventOccurrences(IList<CompetitiveEvent> competitiveEvents)
public IDictionary<EventDefinition, List<EventOccurrence>> GetStateEventOccurrences(IList<EventDefinition> competitiveEvents)
{
var eventTimesFilename = "2025 TN TSA State Competition Event Times.txt";
var eventTimesFilename = "2025 TN TSA State Competition EventDefinition Times.txt";
var fileInfo = FileUtility.GetContentFile(ContentDirectory, eventTimesFilename);
var parser = new EventOccurrenceParser(fileInfo, competitiveEvents);
return parser.Parse();
}
public IDictionary<CompetitiveEvent, List<EventOccurrence>> GetNationalEventOccurrences(IList<CompetitiveEvent> competitiveEvents)
public IDictionary<EventDefinition, List<EventOccurrence>> GetNationalEventOccurrences(IList<EventDefinition> competitiveEvents)
{
var eventTimesFilename = "2025 TSA Nationals Competition Event Times.txt";
var eventTimesFilename = "2025 TSA Nationals Competition EventDefinition Times.txt";
var fileInfo = FileUtility.GetContentFile(ContentDirectory, eventTimesFilename);
var parser = new EventOccurrenceParser(fileInfo, competitiveEvents);
var nationalEventOccurrences = parser.Parse();
@@ -104,13 +112,13 @@ namespace Web.Controllers
public IActionResult Events()
{
var competitiveEvents = GetCompetitiveEvents().Where(e => e.Name != "Chapter Team").ToArray();
var competitiveEvents = GetEvents().Where(e => e.Name != "Chapter Team").ToArray();
return View(competitiveEvents);
}
public IActionResult StudentEventHandout()
{
var competitiveEvents = GetCompetitiveEvents();
var competitiveEvents = GetEvents();
var students = GetStudents(competitiveEvents);
var teams = GetTeams(competitiveEvents, students);
@@ -119,10 +127,12 @@ namespace Web.Controllers
public IActionResult StudentEvents()
{
var competitiveEvents = GetCompetitiveEvents();
var students = GetStudents(competitiveEvents);
var events = GetEvents();
var students = GetStudents(events);
var rankings = GetStudentEventRankings(students, events);
var eventStudentPicksArray = DataProcessing.GetEventStudentPicks(competitiveEvents, students);
var eventStudentPicksArray = StudentEventRanking.GetEventStudentRankings(rankings);
var assignmentParameters = new AssignmentParameters
{
EffortUpperBound = 9,
@@ -131,9 +141,9 @@ namespace Web.Controllers
TeamSizeLimit = 4
};
var eventAssignment = new EventAssigner(competitiveEvents, students, assignmentParameters);
var eventAssignment = new EventAssigner(events, students, assignmentParameters);
var assignmentAssumptions = GetAssignmentAssumptions(competitiveEvents, students);
var assignmentAssumptions = GetAssignmentAssumptions(events, students);
foreach (var assumption in assignmentAssumptions)
{
@@ -149,39 +159,39 @@ namespace Web.Controllers
}
}
eventAssignment.RemoveEvent(new List<CompetitiveEvent>
eventAssignment.RemoveEvent(new List<EventDefinition>
{
competitiveEvents.First(e => e.Name == "Chapter Team")
events.First(e => e.Name == "Chapter Team")
});
eventAssignment.IncludedEvents(new List<CompetitiveEvent>
eventAssignment.IncludedEvents(new List<EventDefinition>
{
//competitiveEvents.First(e => e.Name == "System Control Technology")
});
var eventAssignmentsList = eventAssignment.Solve();
return View(Tuple.Create(competitiveEvents, students, eventStudentPicksArray, eventAssignmentsList, assignmentParameters));
return View(Tuple.Create(events, students, eventStudentPicksArray, eventAssignmentsList, assignmentParameters));
}
public IActionResult Teams()
{
var competitiveEvents = GetCompetitiveEvents();
var competitiveEvents = GetEvents();
var students = GetStudents(competitiveEvents);
var teams = GetTeams(competitiveEvents, students);
//teams = teams.Where(t => t.Event.RegionalEvent).ToArray();
//teams = teams.Where(t => t.EventDefinition.RegionalEvent).ToArray();
return View(Tuple.Create(teams));
}
public IActionResult Regionals()
{
var competitiveEvents = GetCompetitiveEvents();
var competitiveEvents = GetEvents();
var students = GetStudents(competitiveEvents);
var teams = GetTeams(competitiveEvents, students);
teams = teams.Where(t => t.Event.RegionalEvent).ToArray();
teams = teams.Where(t => t.EventDefinition.RegionalEvent).ToArray();
var enumerable = students.Where(s => !teams.SelectMany(ts => ts.Students).Contains(s)).ToArray();
return View(Tuple.Create(teams, enumerable));
@@ -189,7 +199,7 @@ namespace Web.Controllers
public IActionResult State()
{
var competitiveEvents = GetCompetitiveEvents();
var competitiveEvents = GetEvents();
var students = GetStudents(competitiveEvents);
var teams = GetTeams(competitiveEvents, students);
var eventOccurrences = GetStateEventOccurrences(competitiveEvents);
@@ -205,7 +215,7 @@ namespace Web.Controllers
}
public IActionResult Nationals()
{
var competitiveEvents = GetCompetitiveEvents();
var competitiveEvents = GetEvents();
var students = GetStudents(competitiveEvents);
var teams = GetTeams(competitiveEvents, students);
var eventOccurrences = GetNationalEventOccurrences(competitiveEvents);
@@ -222,7 +232,7 @@ namespace Web.Controllers
public IActionResult TeamGrid()
{
var competitiveEvents = GetCompetitiveEvents();
var competitiveEvents = GetEvents();
var students = GetStudents(competitiveEvents);
var teams = GetTeams(competitiveEvents, students);
@@ -231,7 +241,7 @@ namespace Web.Controllers
public IActionResult Students()
{
var competitiveEvents = GetCompetitiveEvents();
var competitiveEvents = GetEvents();
var students = GetStudents(competitiveEvents);
GetTeams(competitiveEvents, students);
@@ -276,7 +286,7 @@ namespace Web.Controllers
reverse: true,
slotPush:0);
var events = GetCompetitiveEvents();
var events = GetEvents();
var students = GetStudents(events);
var allTeams = GetTeams(events, students);
@@ -284,23 +294,23 @@ namespace Web.Controllers
var omittedEvents = allTeams.Where(t => scheduleOptions.OmittedEvents?.Any(s => t.Name.Contains(s)) == true).ToArray();
allTeams = allTeams.Where(t => !omittedEvents.Contains(t)).ToArray();
bool RegionalPredicate(Team t) => t.Event.RegionalEvent;
bool TeamPredicate(Team t) => t.Event.Format is EventFormat.Team;
bool RegionalPredicate(Team t) => t.EventDefinition.RegionalEvent;
bool TeamPredicate(Team t) => t.EventDefinition.EventFormat is EventFormat.Team;
bool RegionalTeamPredicate(Team t) => RegionalPredicate(t) && TeamPredicate(t);
bool HighEffort(Team t) => t.Event.LevelOfEffort == 3;
bool LowEffort(Team t) => t.Event.LevelOfEffort == 1;
bool HighEffort(Team t) => t.EventDefinition.LevelOfEffort == 3;
bool LowEffort(Team t) => t.EventDefinition.LevelOfEffort == 1;
bool RegionalTeamSomeEffortPredicate(Team t) => RegionalTeamPredicate(t) && !LowEffort(t);
bool IndividualPredicate(Team t) => t.Event.Format is EventFormat.Individual;
bool IndividualPredicate(Team t) => t.EventDefinition.EventFormat is EventFormat.Individual;
bool negativePredicate(Team t) => false;
var mustIncludeTeams =
from e in events
from t in allTeams
where t.Event == e &&
where t.EventDefinition == e &&
(scheduleOptions.MustIncludeEvents?.Any(s => s == "RegionalTeam") == true && RegionalTeamSomeEffortPredicate(t)
|| scheduleOptions.MustIncludeEvents?.Any( t.Event.Name.Contains) == true
|| scheduleOptions.MustIncludeEvents?.Any( t.EventDefinition.Name.Contains) == true
|| HighEffort(t))
select t;
+5 -5
View File
@@ -1,6 +1,6 @@
@using Core.Entities
@using Core.Utility
@model CompetitiveEvent[]
@model EventDefinition[]
@{
ViewData["Title"] = "Events Page";
}
@@ -12,7 +12,7 @@
{
<div class="row">
<div class="col">
<i>Regional Event</i>
<i>Regional EventDefinition</i>
</div>
</div>
}
@@ -21,14 +21,14 @@
<h5>@evt.Name</h5>
</div>
<div class="col-2">
@if (evt.Format is EventFormat.Team)
@if (evt.EventFormat is EventFormat.Team)
{
<html><strong>@evt.Format</strong><br/>Size: <strong>@evt.TeamSize</strong></html>
<html><strong>@evt.EventFormat</strong><br/>Size: <strong>@evt.TeamSize</strong></html>
}
else
{
<html>
<strong>@evt.Format</strong>
<strong>@evt.EventFormat</strong>
</html>
}
+27 -27
View File
@@ -1,12 +1,12 @@
@using System.Text.RegularExpressions
@using Core.Entities
@model Tuple<Team[], Student[], IDictionary<CompetitiveEvent, List<EventOccurrence>>>
@model Tuple<Team[], Student[], IDictionary<EventDefinition, List<EventOccurrence>>>
@{
ViewData["Title"] = "Teams";
var eventOccurrences = Model.Item3;
}
<div class="container nobrk pt-5">
<h2>Nationals Events</h2>
<h2>Nationals EventDefinitions</h2>
<table class="table">
<thead>
<tr>
@@ -20,7 +20,7 @@
@foreach (var team in Model.Item1)
{
var students = team.Students;
@if (true @* team.Event.Format == EventFormat.Team *@)
@if (true @* team.EventDefinition.EventDefinitionFormat == EventDefinitionEventDefinitionFormat.Team *@)
{
<tr>
<td>
@@ -46,32 +46,32 @@
}
</td>
<td>
@* @if (team.Event.StatePresubmission)
@* @if (team.EventDefinition.StatePresubmission)
{
<text>Pre-submission due Friday, March 14</text>
}
@if (team.Event.StatePretesting)
@if (team.EventDefinition.StatePretesting)
{
<text>Pre-testing Wednesday, April 2nd</text>
}
@if (team.Event.StatePreliminaryRound)
@if (team.EventDefinition.StatePreliminaryRound)
{
<text>Preliminary and Semifinalist Rounds</text>
} *@
</td>
<td>
@team.Event.Documentation
@team.EventDefinition.Documentation
</td>
</tr>
}
@* else if (team.Event.Format == EventFormat.Individual)
@* else if (team.EventDefinition.EventDefinitionFormat == EventDefinitionEventDefinitionFormat.Individual)
{
foreach (var student in students)
{
<tr>
<td>
@team.Event.Name - @student.FirstNameLastName (@student.RegionalID)
@team.EventDefinition.Name - @student.FirstNameLastName (@student.RegionalID)
</td>
<td>@team.RegionalTimeSlot</td>
<td></td>
@@ -92,14 +92,14 @@
<h3>@student.FirstNameLastName - @student.NationalID</h3>
<h4>TSA 2025 Nationals Schedule</h4>
<div class="row">
<div class="col col-2">Events</div>
<div class="col col-2">EventDefinitions</div>
<div class="col">
@foreach (var ev in student.Teams)
{
<div class="row">
<div class="col col-2">
@if (ev.Event.Format is EventFormat.Team)
@if (ev.EventDefinition.EventFormat is EventFormat.Team)
{
@ev.TeamNumber
}
@@ -117,7 +117,7 @@
</text>
</div>
<div class="col-6">
@ev.Event.SemifinalistActivity
@ev.EventDefinition.SemifinalistActivity
</div>
</div>
}
@@ -127,7 +127,7 @@
<thead>
<tr>
<td>Time</td>
<td>Event</td>
<td>EventDefinition</td>
<td></td>
<td>Location</td>
</tr>
@@ -136,9 +136,9 @@
@foreach (var date in
eventOccurrences
.Where(eo =>
student.Teams.Select(t => t.Event).Any(a => a == eo.Key)
|| eo.Key == CompetitiveEvent.GeneralSchedule
|| (eo.Key == CompetitiveEvent.VotingDelegates && student.VotingDelegate))
student.Teams.Select(t => t.EventDefinition).Any(a => a == eo.Key)
|| eo.Key == EventDefinition.GeneralSchedule
|| (eo.Key == EventDefinition.VotingDelegates && student.VotingDelegate))
.SelectMany(eo => eo.Value.Select(v => Tuple.Create(v, eo.Key)))
.GroupBy(de => de.Item1.StartTime.Date)
.OrderBy(d => d.Key)
@@ -151,8 +151,8 @@
// filter out occurrences where non-captain
.Where(de =>
!de.Item1.SignupSubmitPickup
|| de.Item2.Format is EventFormat.Individual
|| student.Teams.Any(t => t.Captain == student && t.Event == de.Item2)
|| de.Item2.EventFormat is EventFormat.Individual
|| student.Teams.Any(t => t.Captain == student && t.EventDefinition == de.Item2)
)
.OrderBy(de => de.Item1.StartTime);
@@ -176,7 +176,7 @@
<td class="@hlClass">@eventOccurrence.Item2.Name</td>
<td class="@hlClass">
@eventOccurrence.Item1.Name
@if (eventOccurrence.Item1.Name.Contains("Pick") && eventOccurrence.Item2.Format is EventFormat.Team)
@if (eventOccurrence.Item1.Name.Contains("Pick") && eventOccurrence.Item2.EventFormat is EventFormat.Team)
{
<br/>
<text>or coordinate with a teammate</text>
@@ -217,17 +217,17 @@
<tr><td colspan="4"><strong>@eventsForDate.Key.ToString("MMMM d") </strong> </td></tr>
@foreach (var occurrence in eventsForDate.OrderBy(o => o.Item1.StartTime))
{
var teams = Model.Item1.Where(t => t.Event == occurrence.Item2);
if (occurrence.Item2 != CompetitiveEvent.GeneralSchedule && occurrence.Item2 != CompetitiveEvent.VotingDelegates && !teams.Any())
var teams = Model.Item1.Where(t => t.EventDefinition == occurrence.Item2);
if (occurrence.Item2 != EventDefinition.GeneralSchedule && occurrence.Item2 != EventDefinition.VotingDelegates && !teams.Any())
continue;
<tr>
<td style="white-space:nowrap;">@occurrence.Item1.Time</td>
<td>
@if (occurrence.Item2 == CompetitiveEvent.GeneralSchedule)
@if (occurrence.Item2 == EventDefinition.GeneralSchedule)
{
<text>Everyone</text>
}
else if (occurrence.Item2 == CompetitiveEvent.VotingDelegates)
else if (occurrence.Item2 == EventDefinition.VotingDelegates)
{
<text>Voting Delegates - @string.Join(", ", Model.Item2.Where(stu => stu.VotingDelegate).Select(stu => stu.FirstName))</text>
}
@@ -294,7 +294,7 @@
@foreach (var t in assignments)
{
<td>
@if (t.Event.Format != EventFormat.Individual)
@if (t.EventDefinition.EventFormat != EventFormat.Individual)
{
@t.Name
@if (t.Captain == student)
@@ -304,7 +304,7 @@
}
else
{
@t.Event.Name
@t.EventDefinition.Name
}
</td>
}
@@ -337,7 +337,7 @@
@foreach (var t in assignments)
{
<p>
@if (t.Event.Format != EventFormat.Individual)
@if (t.EventDefinition.EventFormat != EventFormat.Individual)
{
@t.Name
@if (t.Captain == student)
@@ -347,7 +347,7 @@
}
else
{
@t.Event.Name
@t.EventDefinition.Name
}
</p>
}
+10 -10
View File
@@ -14,10 +14,10 @@
<td>Team Members</td>
</tr>
</thead>
@foreach (var team in Model.Item1.OrderBy(t => t.RegionalTimeSlotObj))
@foreach (var team in Model.Item1/*.OrderBy(t => t.RegionalTimeSlotObj)*/)
{
var students = team.Students;
@if (team.Event.Format == EventFormat.Team)
@if (team.EventDefinition.EventFormat == EventFormat.Team)
{
<tr>
<td>
@@ -28,7 +28,7 @@
@team.RegionalTimeSlot
</td>*@
<td>
@team.Event.RegionalNotes
@team.EventDefinition.Notes
</td>
<td>
@{
@@ -50,15 +50,15 @@
</td>
</tr>
}
else if (team.Event.Format == EventFormat.Individual)
else if (team.EventDefinition.EventFormat == EventFormat.Individual)
{
foreach (var student in students)
{
<tr>
<td>
@team.Event.Name #@student.RegionalID
@team.EventDefinition.Name #@student.RegionalID
</td>
<td>@team.Event.RegionalNotes</td>
<td>@team.EventDefinition.Notes</td>
<td>@student.FirstNameLastName</td>
</tr>
}
@@ -86,7 +86,7 @@
<td></td>
</tr>
var teams = Model.Item1.Where(t => t.Students.Contains(student));
foreach (var team in teams.OrderBy(t => t.RegionalTimeSlotObj))
foreach (var team in teams/*.OrderBy(t => t.RegionalTimeSlotObj)*/)
{
<tr>
<td></td>
@@ -97,13 +97,13 @@
<text>(Cpt.)</text>
}
</td>
<td>@team.Event.RegionalNotes @team.RegionalTimeSlot</td>
<td>@team.EventDefinition.Notes @*@team.RegionalTimeSlot*@</td>
</tr>
}
}
</table>
}
<p>No regional events: @string.Join(", ", @Model.Item2.Select(s=> s.FirstName))</p>
<p>No regional eventDefinitions: @string.Join(", ", @Model.Item2.Select(s=> s.FirstName))</p>
@functions
{
@@ -114,7 +114,7 @@
private void GetTeamClass(Team team)
{
if (team.Event.RegionalEvent)
if (team.EventDefinition.RegionalEvent)
{
@Html.Raw("regional")
;
+9 -9
View File
@@ -19,7 +19,7 @@
@foreach (var timeslot in schedule)
{
overlaps = Team.GetStudentTeamOverlaps(timeslot).ToList();
var partialTeams = timeslot.Where(t => t is PartialTeam && t.Event.Format is not EventFormat.Individual);
var partialTeams = timeslot.Where(t => t is PartialTeam && t.EventDefinition.EventFormat is not EventFormat.Individual);
var fullTeams = timeslot.Where(t => !partialTeams.Contains(t));
<h3>Time Slot @(slot + 1)</h3>
@@ -33,7 +33,7 @@
<th class="col-5"></th>
</thead>
<tbody>
@foreach (var team in fullTeams.Where(t => t.Event.Format is EventFormat.Team).OrderBy(t => t.Name))
@foreach (var team in fullTeams.Where(t => t.EventDefinition.EventFormat is EventFormat.Team).OrderBy(t => t.Name))
{
@await Html.PartialAsync("ScheduleTeamPartial", Tuple.Create(team, overlaps, Model.Item3.AbsentStudents))
}
@@ -58,16 +58,16 @@
}
<h4>Individual</h4>
<p><i>Use time for individual event or to <strong>work on a team event</strong> </i></p>
<p><i>Use time for individual eventDefinition or to <strong>work on a team eventDefinition</strong> </i></p>
<table class="table schedule">
<tbody>
<tr>
@foreach (var team in fullTeams.Where(t => t.Event.Format is EventFormat.Individual).OrderBy(t => t.Name))
@foreach (var team in fullTeams.Where(t => t.EventDefinition.EventFormat is EventFormat.Individual).OrderBy(t => t.Name))
{
<td>
<strong>@team.Captain?.FirstName</strong> (@team.Event.Name@if(team.Event.RegionalEvent){ @* <text> (<i>Regional</i>)</text> *@})
<strong>@team.Captain?.FirstName</strong> (@team.EventDefinition.Name@if(team.EventDefinition.RegionalEvent){ @* <text> (<i>Regional</i>)</text> *@})
</td>
@* @await Html.PartialAsync("ScheduleTeamPartial", Tuple.Create(team, overlaps)) *@
}
@@ -86,14 +86,14 @@
slot++;
}
<h3>Missed team events for today</h3>
<h3>Missed team eventDefinitions for today</h3>
<table class="table schedule">
@foreach (var student in allStudents.OrderBy(s => s.FirstName))
{
var studentMeetings = student.Teams.Where(t => allMeetingTeams.Any(mt => mt.Name == t.Name && mt.Students.Contains(student)));
var studentMissed = student.Teams.Where(t => studentMeetings.All(mt => mt.Name != t.Name)).ToList();
var studentMissedTeams = studentMissed.Where(t => t.Event.Format is EventFormat.Team);
var studentMissedIndividual = studentMissed.Where(t => t.Event.Format is EventFormat.Individual);
var studentMissedTeams = studentMissed.Where(t => t.EventDefinition.EventFormat is EventFormat.Team);
var studentMissedIndividual = studentMissed.Where(t => t.EventDefinition.EventFormat is EventFormat.Individual);
if (studentMissedTeams.Any())
{
<tr>
@@ -121,7 +121,7 @@
{
private void GetTeamClass(Team team)
{
if (team.Event.RegionalEvent)
if (team.EventDefinition.RegionalEvent)
{
@Html.Raw("regional")
;
@@ -9,17 +9,17 @@
<tr>
<td class="@{ GetTeamClass(team); } col-6" >
<strong>@team</strong>
@if (!string.IsNullOrEmpty(team.Event.EventAttributes()))
@if (!string.IsNullOrEmpty(team.EventDefinition.EventAttributes()))
{
<i>(@team.Event.EventAttributes())</i>
<i>(@team.EventDefinition.EventAttributes())</i>
}
<small><i>@team.Event.SemifinalistActivity</i></small>
@* @if (team.Event.StatePresubmission)
<small><i>@team.EventDefinition.SemifinalistActivity</i></small>
@* @if (team.EventDefinition.StatePresubmission)
{
<small>(pre-submission)</small>
}
@if (team.Event.StatePretesting)
@if (team.EventDefinition.StatePretesting)
{
<small>(pre-testing)</small>
} *@
@@ -58,7 +58,7 @@
}
</td>
<td>
@team.Event.Documentation
@team.EventDefinition.Documentation
</td>
</tr>
@@ -66,7 +66,7 @@
{
private void GetTeamClass(Team team)
{
// if (team.Event.RegionalEvent)
// if (team.EventDefinition.RegionalEvent)
// {
// @Html.Raw("regional")
// ;
+29 -29
View File
@@ -1,13 +1,13 @@
@using System.Text.RegularExpressions
@using Core.Entities
@using Core.Utility
@model Tuple<Team[], Student[], IDictionary<CompetitiveEvent, List<EventOccurrence>>>
@model Tuple<Team[], Student[], IDictionary<EventDefinition, List<EventOccurrence>>>
@{
ViewData["Title"] = "Teams";
var eventOccurrences = Model.Item3;
}
<div class="container nobrk pt-5">
<h2>State Events</h2>
<h2>State EventDefinitions</h2>
<table class="table">
<thead>
<tr>
@@ -21,7 +21,7 @@
@foreach (var team in Model.Item1)
{
var students = team.Students;
@if (true @* team.Event.Format == EventFormat.Team *@)
@if (true @* team.EventDefinition.EventDefinitionFormat == EventDefinitionEventDefinitionFormat.Team *@)
{
<tr>
<td>
@@ -47,32 +47,32 @@
}
</td>
<td>
@if (team.Event.StatePresubmission)
@if (team.EventDefinition.StatePresubmission)
{
<text>Pre-submission due Friday, March 14</text>
}
@if (team.Event.StatePretesting)
@if (team.EventDefinition.StatePretesting)
{
<text>Pre-testing Wednesday, April 2nd</text>
}
@if (team.Event.StatePreliminaryRound)
@if (team.EventDefinition.StatePreliminaryRound)
{
<text>Preliminary and Semifinalist Rounds</text>
}
</td>
<td>
@team.Event.Documentation
@team.EventDefinition.Documentation
</td>
</tr>
}
@* else if (team.Event.Format == EventFormat.Individual)
@* else if (team.EventDefinition.EventDefinitionFormat == EventDefinitionEventDefinitionFormat.Individual)
{
foreach (var student in students)
{
<tr>
<td>
@team.Event.Name - @student.FirstNameLastName (@student.RegionalID)
@team.EventDefinition.Name - @student.FirstNameLastName (@student.RegionalID)
</td>
<td>@team.RegionalTimeSlot</td>
<td></td>
@@ -93,14 +93,14 @@
<h3>@student.FirstNameLastName - @student.StateID</h3>
<h4>TSA 2025 TN State Schedule</h4>
<div class="row">
<div class="col col-2">Events</div>
<div class="col col-2">EventDefinitions</div>
<div class="col">
@foreach (var ev in student.Teams)
{
<div class="row">
<div class="col col-2">
@if (ev.Event.Format is EventFormat.Team)
@if (ev.EventDefinition.EventFormat is EventFormat.Team)
{
@ev.TeamNumber
}
@@ -118,7 +118,7 @@
</text>
</div>
<div class="col-6">
@ev.Event.SemifinalistActivity
@ev.EventDefinition.SemifinalistActivity
</div>
</div>
}
@@ -128,7 +128,7 @@
<thead>
<tr>
<td>Time</td>
<td>Event</td>
<td>EventDefinition</td>
<td></td>
<td>Location</td>
</tr>
@@ -137,9 +137,9 @@
@foreach (var date in
eventOccurrences
.Where(eo =>
student.Teams.Select(t => t.Event).Any(a => a == eo.Key)
|| eo.Key == CompetitiveEvent.GeneralSchedule
|| (eo.Key == CompetitiveEvent.VotingDelegates && student.VotingDelegate))
student.Teams.Select(t => t.EventDefinition).Any(a => a == eo.Key)
|| eo.Key == EventDefinition.GeneralSchedule
|| (eo.Key == EventDefinition.VotingDelegates && student.VotingDelegate))
.SelectMany(eo => eo.Value.Select(v => Tuple.Create(v, eo.Key)))
.GroupBy(de => de.Item1.Date + ", " + de.Item1.StartTime.DayOfWeek)
.OrderBy(d => d.Key)
@@ -152,8 +152,8 @@
// filter out occurrences where non-captain
.Where(de =>
!de.Item1.SignupSubmitPickup
|| de.Item2.Format is EventFormat.Individual
|| student.Teams.Any(t => t.Captain == student && t.Event == de.Item2)
|| de.Item2.EventFormat is EventFormat.Individual
|| student.Teams.Any(t => t.Captain == student && t.EventDefinition == de.Item2)
)
.OrderBy(de => de.Item1.StartTime);
@@ -169,7 +169,7 @@
<td>@eventOccurrence.Item1.Time</td>
<td>@eventOccurrence.Item2.Name</td>
<td>@eventOccurrence.Item1.Name
@if (eventOccurrence.Item1.Name.Contains("Pick") && eventOccurrence.Item2.Format is EventFormat.Team)
@if (eventOccurrence.Item1.Name.Contains("Pick") && eventOccurrence.Item2.EventFormat is EventFormat.Team)
{
<br/>
<text>or coordinate with a teammate</text>
@@ -210,17 +210,17 @@
<tr><td colspan="4"><strong>@eventsForDate.Key.ToString("MMMM d") </strong> </td></tr>
@foreach (var occurrence in eventsForDate.OrderBy(o => o.Item1.StartTime))
{
var teams = Model.Item1.Where(t => t.Event == occurrence.Item2);
if (occurrence.Item2 != CompetitiveEvent.GeneralSchedule && occurrence.Item2 != CompetitiveEvent.VotingDelegates && !teams.Any())
var teams = Model.Item1.Where(t => t.EventDefinition == occurrence.Item2);
if (occurrence.Item2 != EventDefinition.GeneralSchedule && occurrence.Item2 != EventDefinition.VotingDelegates && !teams.Any())
continue;
<tr>
<td>@occurrence.Item1.Time</td>
<td>
@if (occurrence.Item2 == CompetitiveEvent.GeneralSchedule)
@if (occurrence.Item2 == EventDefinition.GeneralSchedule)
{
<text>Everyone</text>
}
else if (occurrence.Item2 == CompetitiveEvent.VotingDelegates)
else if (occurrence.Item2 == EventDefinition.VotingDelegates)
{
<text>Voting Delegates - @string.Join(", ", Model.Item2.Where(stu => stu.VotingDelegate).Select(stu => stu.FirstName))</text>
}
@@ -287,7 +287,7 @@
@foreach (var t in assignments)
{
<td>
@if (t.Event.Format != EventFormat.Individual)
@if (t.EventDefinition.EventFormat != EventFormat.Individual)
{
@t.Name
@if (t.Captain == student)
@@ -297,14 +297,14 @@
}
else
{
@t.Event.Name
@t.EventDefinition.Name
}
@{
if (t.Event.Format == EventFormat.Individual)
if (t.EventDefinition.EventFormat == EventFormat.Individual)
{
<sup class="activity">(ind)</sup>
}
if (t.Event.OnSiteActivity)
if (t.EventDefinition.OnSiteActivity)
{
<sup class="activity">(act)</sup>
}
@@ -340,7 +340,7 @@
@foreach (var t in assignments)
{
<p>
@if (t.Event.Format != EventFormat.Individual)
@if (t.EventDefinition.EventFormat != EventFormat.Individual)
{
@t.Name
@if (t.Captain == student)
@@ -350,7 +350,7 @@
}
else
{
@t.Event.Name
@t.EventDefinition.Name
}
</p>
}
@@ -8,20 +8,20 @@
{
<div class="container nobrk pt-5">
<p><i>@DateTime.Today.ToShortDateString()</i></p>
<h2><i>TSA teams and events:</i> @s.FirstNameLastName </h2>
<h2><i>TSA teams and eventDefinitions:</i> @s.FirstNameLastName </h2>
@foreach (var team in
s.Teams.OrderByDescending(t => t.Event.Format == EventFormat.Team)
.ThenByDescending(t => t.Event.LevelOfEffort)
s.Teams.OrderByDescending(t => t.EventDefinition.EventFormat == EventFormat.Team)
.ThenByDescending(t => t.EventDefinition.LevelOfEffort)
.ThenByDescending(t => t.Name))
{
var evt = team.Event;
var evt = team.EventDefinition;
<div>
@if (evt.RegionalEvent)
{
<div class="row">
<div class="col">
<i>Regional Event</i>
<i>Regional EventDefinition</i>
</div>
</div>
}
@@ -30,7 +30,7 @@
<h5>@evt.Name&nbsp;&nbsp;&nbsp;@Html.Partial("EffortStarsPartial", evt.LevelOfEffort)</h5>
</div>
<div class="col-4">
@if (evt.Format is EventFormat.Team)
@if (evt.EventFormat is EventFormat.Team)
{
<html>
<strong>Teammates</strong><br/>
@@ -40,7 +40,7 @@
else
{
<html>
<strong>@evt.Format</strong>
<strong>@evt.EventFormat</strong>
</html>
}
+20 -18
View File
@@ -1,11 +1,11 @@
@using Core.Entities
@using Core.Utility
@model Tuple<CompetitiveEvent[], Student[], EventStudentPicks[], Team[], AssignmentParameters>
@model Tuple<EventDefinition[], Student[], EventStudentRankings[], Team[], AssignmentParameters>
@{
ViewData["Title"] = "Home Page";
var maxStudentPicks = Model.Item3.MaxBy(picks => picks.StudentPicks.Count).StudentPicks.Count;
var maxStudentPicks = Model.Item3.MaxBy(picks => picks.StudentRankings.Count).StudentRankings.Count;
var parameters = Model.Item5;
var unassignedEvents = Model.Item1.Where(e => Model.Item4.All(t => t.Event != e));
var unassignedEvents = Model.Item1.Where(e => Model.Item4.All(t => t.EventDefinition != e));
}
@@ -27,16 +27,17 @@
{
var assignments
= Model.Item4.Where(ea => ea.Students.Contains(student))
.Select(ea => ea.Event)
.Select(ea => ea.EventDefinition)
.Distinct()
.OrderBy(e =>
@* .OrderBy(e =>
{
var r = student.RankedEventPicks.IndexOf(e);
r = r >= 0 ? r : 10;
//r = r * (4 - e.LevelOfEffort.Value);
return r;
});
}) *@
;
<tr>
<td><strong>@student.FirstName</strong></td>
@@ -44,11 +45,12 @@
@foreach (var evt in assignments)
{
var h = student.RankedEventPicks.IndexOf(evt) + 1;
<td class="@{ GetOrderClass(h); }">
@* var h = student.RankedEventPicks.IndexOf(evt) + 1; *@
@* @{ class="GetOrderClass(h);" } *@
<td class="">
@evt.ShortName @Html.Partial("EffortStarsPartial", evt.LevelOfEffort)
@{
if (evt.Format == EventFormat.Individual)
if (evt.EventFormat == EventFormat.Individual)
{
<sup class="activity">(ind)</sup>
}
@@ -74,9 +76,9 @@
<thead>
<tr><td>Teams</td></tr>
</thead>
@foreach (var evt in Model.Item1.OrderByDescending(e => e.Format is EventFormat.Team))
@foreach (var evt in Model.Item1.OrderByDescending(e => e.EventFormat is EventFormat.Team))
{
var assignments = Model.Item4.FirstOrDefault(i => i.Event == evt);
var assignments = Model.Item4.FirstOrDefault(i => i.EventDefinition == evt);
@if (assignments == null)
{
continue;
@@ -86,7 +88,7 @@
<td class="table-primary"><strong>@evt.Name</strong></td>
<td colspan="1">
@Html.Partial("EffortStarsPartial", evt.LevelOfEffort)
@if (evt.Format is EventFormat.Individual)
@if (evt.EventFormat is EventFormat.Individual)
{
<text>(ind)</text>
}
@@ -120,7 +122,7 @@
@{
var unassigned = string.Join(", ", unassignedEvents.Select(e => e.Name));
}
<td colspan="8">Unassigned Events: @unassigned</td>
<td colspan="8">Unassigned EventDefinitions: @unassigned</td>
</tr>
</table>
@@ -151,7 +153,7 @@
continue;
<td class="@{ GetOrderClass(h); }">
@evt.ShortName @Html.Partial("EffortStarsPartial", evt.LevelOfEffort)
@if (evt.Format == EventFormat.Individual)
@if (evt.EventFormat == EventFormat.Individual)
{
<sup class="activity">(ind)</sup>
}
@@ -171,11 +173,11 @@
<table>
<thead>
<tr><td>Event</td><td>Level of Effort</td><td>Individual</td><td>Regional</td><td>On-site Activity</td><td>Team Size</td><td>Max Team Count</td></tr>
<tr><td>EventDefinition</td><td>Level of Effort</td><td>Individual</td><td>Regional</td><td>On-site Activity</td><td>Team Size</td><td>Max Team Count</td></tr>
</thead>
@foreach (var evt in Model.Item1)
{
var esp = Model.Item3.FirstOrDefault(i => i.Event == evt);
var esp = Model.Item3.FirstOrDefault(i => i.EventDefinition == evt);
<tr>
<td>
@@ -183,7 +185,7 @@
</td>
<td>@Html.Partial("EffortStarsPartial", evt.LevelOfEffort)</td>
<td>@if (evt.Format is EventFormat.Individual) { <text>ind</text> }</td>
<td>@if (evt.EventFormat is EventFormat.Individual) { <text>ind</text> }</td>
<td>@if (evt.RegionalEvent) { <text>reg</text> }</td>
<td>@if (evt.OnSiteActivity) { <text>act</text> }</td>
<td style="nowrap">@evt.TeamSize</td>
@@ -191,7 +193,7 @@
@for (var i = 0; i < maxStudentPicks; i++)
{
var d = esp?.StudentPicks.Skip(i).FirstOrDefault();
var d = esp?.StudentRankings.Skip(i).FirstOrDefault();
<td class="@{GetOrderClass(d?.Item2 ?? int.MaxValue);}">@d?.Item1.FirstName</td>
}
</tr>
+20 -18
View File
@@ -16,15 +16,16 @@
{
var assignments
= student.Teams.Where(ea => ea.Students.Contains(student))
.Select(ea => ea.Event)
.Select(ea => ea.EventDefinition)
.Distinct()
.OrderBy(e =>
@* .OrderBy(e =>
{
var r = student.RankedEventPicks.IndexOf(e);
r = r >= 0 ? r : 10;
//r = r * (4 - e.LevelOfEffort.Value);
return r;
}).ToList();
}) *@
.ToList();
<tr>
<td>
@@ -34,11 +35,12 @@
@foreach (var evt in assignments)
{
var h = student.RankedEventPicks.IndexOf(evt) + 1;
<td class="@{ GetOrderClass(h); }">
@* var h = student.RankedEventPicks.IndexOf(evt) + 1; *@
@* @{ GetOrderClass(h); } *@
<td class="">
@evt.ShortName @Html.Partial("EffortStarsPartial", evt.LevelOfEffort)
@{
if (evt.Format == EventFormat.Individual)
if (evt.EventFormat == EventFormat.Individual)
{
<sup class="activity">(ind)</sup>
}
@@ -63,7 +65,7 @@
<th>Team</th>
<th>Teammates</th>
</tr>
@foreach (var student in Model.Item1.OrderBy(s => s.Name))
@foreach (var student in Model.Item1.RankBy(s => s.Name))
{
var teams = student.Teams;
@@ -87,11 +89,11 @@
{
<span>(Cpt .)</span>
}
if (!team.Event.InterviewOrPresentation)
if (!team.EventDefinition.InterviewOrPresentation)
{
ind.Add("a");
}
if (team.Event.Format is EventFormat.Individual)
if (team.EventDefinition.EventDefinitionFormat is EventDefinitionEventDefinitionFormat.Individual)
{
ind.Add("i");
}
@@ -102,16 +104,16 @@
}
</td>
<td>
@string.Join(", ", team.Students.Where(s => s != student).OrderByDescending(s => s.TsaYear + s.Grade).Select(s => s.FirstName))
@string.Join(", ", team.Students.Where(s => s != student).RankByDescending(s => s.TsaYear + s.Grade).Select(s => s.FirstName))
</td>
</tr>
}
}
</table>
<p>
(a) denotes an event that has activity other than interview or presentation at state
(a) denotes an eventDefinition that has activity other than interview or presentation at state
<br />
(i) denotes an individual event
(i) denotes an individual eventDefinition
</p> *@
@@ -125,15 +127,16 @@
{
var assignments
= student.Teams.Where(ea => ea.Students.Contains(student))
.Select(ea => ea.Event)
.Select(ea => ea.EventDefinition)
.Distinct()
.OrderBy(e =>
@* .OrderBy(e =>
{
var r = student.RankedEventPicks.IndexOf(e);
r = r >= 0 ? r : 10;
//r = r * (4 - e.LevelOfEffort.Value);
return r;
}).ToList();
}) *@
.ToList();
<tr>
<td>
@@ -142,11 +145,10 @@
@foreach (var evt in assignments)
{
var h = student.RankedEventPicks.IndexOf(evt) + 1;
<td>
@evt.Name
@{
if (evt.Format == EventFormat.Individual)
if (evt.EventFormat == EventFormat.Individual)
{
<sup class="activity">(individual)</sup>
}
@@ -170,7 +172,7 @@
private void GetTeamClass(Team team)
{
// if (team.Event.RegionalEvent)
// if (team.EventDefinition.RegionalEvent)
// {
// @Html.Raw("regional");
// }
+2 -2
View File
@@ -9,10 +9,10 @@
<tr> <th></th>
@foreach (var team in Model.Item1)
{
if (team.Name == team.Event.Name)
if (team.Name == team.EventDefinition.Name)
{
<td style="writing-mode: vertical-rl;text-orientation:sideways">
@team.Event.ShortName
@team.EventDefinition.ShortName
</td>
}
else
+19 -19
View File
@@ -5,21 +5,21 @@
}
<table>
@foreach (var team in Model.Item1.Where(t => t.Event.Documentation.Contains("Port")))
@foreach (var team in Model.Item1.Where(t => t.EventDefinition.Documentation.Contains("Port")))
{
<tr>
<td>@team.Name @if (team.Event.Format is EventFormat.Individual)
<td>@team.Name @if (team.EventDefinition.EventFormat is EventFormat.Individual)
{
<text>(ind)</text>
}
</td><td>@team.Event.Documentation</td>
</td><td>@team.EventDefinition.Documentation</td>
@foreach(var student in @team.Students.OrderByDescending(s => s.TsaYear + s.Grade))
{
<td>@student.FirstName</td>
}
</tr>
}
@foreach (var student in Model.Item1.SelectMany(t => t.Students).Distinct().Where(s => s.Teams.Any(t => t.Event.Name.Contains("Port"))))
@foreach (var student in Model.Item1.SelectMany(t => t.Students).Distinct().Where(s => s.Teams.Any(t => t.EventDefinition.Name.Contains("Port"))))
{
<tr>
<td>@student.FirstName</td>
@@ -34,9 +34,9 @@
@{
var ind = false;
}
@foreach (var team in Model.Item1.OrderByDescending(t => t.Event.Format is EventFormat.Team))
@foreach (var team in Model.Item1.OrderByDescending(t => t.EventDefinition.EventFormat is EventFormat.Team))
{
@if (!ind && team.Event.Format is EventFormat.Individual)
@if (!ind && team.EventDefinition.EventFormat is EventFormat.Individual)
{
<tr>
<td><hr/></td><td>Individual</td><td><hr/></td>
@@ -46,17 +46,17 @@
<tr class="table-primary">
<td class="table-primary"><strong>@team.Name</strong></td>
<td colspan="1">
@* @Html.Partial("EffortStarsPartial", team.Event.LevelOfEffort) *@
@* @if (team.Event.RegionalEvent)
@* @Html.Partial("EffortStarsPartial", team.EventDefinition.LevelOfEffort) *@
@* @if (team.EventDefinition.RegionalEventDefinition)
{
<text>(reg)</text>
}
@if (team.Event.OnSiteActivity)
@if (team.EventDefinition.OnSiteActivity)
{
<text>(act)</text>
} *@
@team.Event.TeamSize
@team.EventDefinition.TeamSize
</td>
@*<td style="nowrap">@evt.MaxTeamCountState</td>*@
@foreach (var student in team.Students.OrderByDescending(s => (s.Grade + s.TsaYear) * (team.Captain == s ? 2 : 1)).ThenBy(s => s.FirstNameLastName))
@@ -71,9 +71,9 @@
<table class="table">
<thead>
<tr>
<td>Event</td>
<td>EventDefinition</td>
<td>Pre-submission</td>
<td>RegionalNotes</td>
<td>Notes</td>
<td>Team Members</td>
</tr>
</thead>
@@ -87,19 +87,19 @@
</tr>
@foreach (var student in students.OrderByDescending(s => (s.Grade + s.TsaYear) * (team.Captain == s ? 2 : 1)).ThenBy(s => s.FirstNameLastName))
@foreach (var student in students.RankByDescending(s => (s.Grade + s.TsaYear) * (team.Captain == s ? 2 : 1)).ThenBy(s => s.FirstNameLastName))
{
<td>@student.FirstNameLastName @if (team.Captain == student) { <text>(Cpt.)</text>}</td>
}
<tr>
<td class="event-desc" colspan="4">Team Size: @team.Event.TeamSize, Max Teams: @team.Event.MaxTeamCountState
<td class="eventDefinition-desc" colspan="4">Team Size: @team.EventDefinition.TeamSize, Max Teams: @team.EventDefinition.MaxTeamCountState
@{
if (!team.Event.InterviewOrPresentation)
if (!team.EventDefinition.InterviewOrPresentation)
{
<span class="activity"> (a)</span>
}
if (team.Event.Format is EventFormat.Individual)
if (team.EventDefinition.EventDefinitionFormat is EventDefinitionEventDefinitionFormat.Individual)
{
<span class="activity"> (i)</span>
}
@@ -109,9 +109,9 @@
}
</table>
<p>
(a) denotes an event that has activity other than interview or presentation at state
(a) denotes an eventDefinition that has activity other than interview or presentation at state
<br />
(i) denotes an individual event
(i) denotes an individual eventDefinition
</p>
*@
@@ -124,7 +124,7 @@
private void GetTeamClass(Team team)
{
// if (team.Event.RegionalEvent)
// if (team.EventDefinition.RegionalEvent)
// {
// @Html.Raw("regional");
// }
+3 -3
View File
@@ -25,15 +25,15 @@
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Events">Events</a>
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Events">EventDefinitions</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="StudentEvents">Student Event Picks</a>
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="StudentEvents">Student EventDefinition Picks</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="StudentEventHandout">Student Event Handout</a>
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="StudentEventHandout">Student EventDefinition Handout</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Teams">Teams</a>
+1 -2
View File
@@ -1,12 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="bootstrap" Version="5.3.2" />
<PackageReference Include="RandomNameGenerator" Version="1.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Core\Core.csproj" />