Improve team identifier handling
This commit is contained in:
@@ -155,19 +155,10 @@
|
|||||||
|
|
||||||
<MudDivider Class="my-4" />
|
<MudDivider Class="my-4" />
|
||||||
|
|
||||||
<MudText Typo="Typo.h4">Absent Students</MudText>
|
<StudentToggleSelector Students="@_students"
|
||||||
<MudToggleGroup T="Student"
|
@bind-SelectedStudents="_absentStudents"
|
||||||
SelectionMode="SelectionMode.MultiSelection"
|
Title="Absent Students"
|
||||||
@bind-Values="_absentStudents"
|
ShowFullName="true" />
|
||||||
Vertical="true"
|
|
||||||
CheckMark>
|
|
||||||
@foreach (var student in _students.OrderBy(e => e.FirstName))
|
|
||||||
{
|
|
||||||
<MudToggleItem Value="@student" Style="font-size: .75rem;">
|
|
||||||
@student.FirstNameLastName
|
|
||||||
</MudToggleItem>
|
|
||||||
}
|
|
||||||
</MudToggleGroup>
|
|
||||||
</MudStack>
|
</MudStack>
|
||||||
</MudItem>
|
</MudItem>
|
||||||
|
|
||||||
|
|||||||
@@ -15,18 +15,45 @@
|
|||||||
<MudGrid>
|
<MudGrid>
|
||||||
<MudItem xs="12" sm="7">
|
<MudItem xs="12" sm="7">
|
||||||
<MudPaper Class="pa-4">
|
<MudPaper Class="pa-4">
|
||||||
<MudSelect T="EventDefinition" @bind-Value="@Team.Event" Label="Event">
|
<MudSelect T="EventDefinition" Value="@Team.Event" ValueChanged="OnEventChanged" Label="Event">
|
||||||
|
|
||||||
@foreach (var evt in _events)
|
@foreach (var evt in _events)
|
||||||
{
|
{
|
||||||
<MudSelectItem T="EventDefinition" Value="@(evt)"></MudSelectItem>
|
<MudSelectItem T="EventDefinition" Value="@(evt)"></MudSelectItem>
|
||||||
}
|
}
|
||||||
</MudSelect>
|
</MudSelect>
|
||||||
<MudTextField T="string?" Label="Number" @bind-Value="Team.Identifier" For="@(() => Team.Identifier)"></MudTextField>
|
@if (_existingTeams?.Count == 1)
|
||||||
|
{
|
||||||
|
<MudAlert Severity="Severity.Info" Class="my-2">
|
||||||
|
A team for @Team.Event.Name already exists. This will be team 2, and the existing team will become team 1.
|
||||||
|
</MudAlert>
|
||||||
|
}
|
||||||
|
else if (_existingTeams?.Count >= 2)
|
||||||
|
{
|
||||||
|
<MudAlert Severity="Severity.Error" Class="my-2">
|
||||||
|
Two teams for @Team.Event.Name already exist. Cannot create a third team.
|
||||||
|
</MudAlert>
|
||||||
|
}
|
||||||
|
|
||||||
|
<MudDivider Class="my-4" />
|
||||||
|
|
||||||
|
<StudentToggleSelector Students="@_students"
|
||||||
|
@bind-SelectedStudents="_selectedStudents"
|
||||||
|
Title="Students"
|
||||||
|
ShowFullName="true" />
|
||||||
|
|
||||||
|
<MudStack Class="mt-4">
|
||||||
|
<TeamCaptainSelector Students="@_selectedStudents"
|
||||||
|
@bind-SelectedCaptain="Team.Captain"
|
||||||
|
Title="Captain" />
|
||||||
|
</MudStack>
|
||||||
</MudPaper>
|
</MudPaper>
|
||||||
</MudItem>
|
</MudItem>
|
||||||
</MudGrid>
|
</MudGrid>
|
||||||
|
@if (!string.IsNullOrEmpty(_errorMessage))
|
||||||
|
{
|
||||||
|
<MudAlert Severity="Severity.Error" Class="mt-3">@_errorMessage</MudAlert>
|
||||||
|
}
|
||||||
<MudButton StartIcon="@Icons.Material.Filled.ArrowBack" Href="students">Back</MudButton>
|
<MudButton StartIcon="@Icons.Material.Filled.ArrowBack" Href="students">Back</MudButton>
|
||||||
<MudButton StartIcon="@Icons.Material.Filled.Add" OnClick="AddTeam">Add</MudButton>
|
<MudButton StartIcon="@Icons.Material.Filled.Add" OnClick="AddTeam">Add</MudButton>
|
||||||
</EditForm>
|
</EditForm>
|
||||||
@@ -36,6 +63,10 @@
|
|||||||
private Team Team { get; set; } = new();
|
private Team Team { get; set; } = new();
|
||||||
|
|
||||||
private List<EventDefinition>? _events;
|
private List<EventDefinition>? _events;
|
||||||
|
private List<Student> _students = [];
|
||||||
|
private IEnumerable<Student> _selectedStudents = [];
|
||||||
|
private string? _errorMessage;
|
||||||
|
private List<Team>? _existingTeams;
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
@@ -43,11 +74,76 @@
|
|||||||
await Context.Events
|
await Context.Events
|
||||||
.OrderBy(e => e.Name)
|
.OrderBy(e => e.Name)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
|
_students = await Context.Students.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task OnEventChanged(EventDefinition selectedEvent)
|
||||||
|
{
|
||||||
|
Team.Event = selectedEvent;
|
||||||
|
|
||||||
|
// Clear any previous error messages
|
||||||
|
_errorMessage = null;
|
||||||
|
|
||||||
|
// Get all existing teams for this event
|
||||||
|
_existingTeams = await Context.Teams
|
||||||
|
.Include(t => t.Event)
|
||||||
|
.Where(t => t.Event.Id == selectedEvent.Id)
|
||||||
|
.ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task AddTeam()
|
private async Task AddTeam()
|
||||||
{
|
{
|
||||||
Team.Identifier = Team.Event.Name;
|
// Clear previous error message
|
||||||
|
_errorMessage = null;
|
||||||
|
|
||||||
|
// Get current count of teams for this event
|
||||||
|
var existingTeamCount = await Context.Teams
|
||||||
|
.CountAsync(t => t.Event.Id == Team.Event.Id);
|
||||||
|
|
||||||
|
// Prohibit creation of third team
|
||||||
|
if (existingTeamCount >= 2)
|
||||||
|
{
|
||||||
|
_errorMessage = $"Cannot create a third team for {Team.Event.Name}. Maximum of 2 teams allowed.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle automatic numbering based on event format
|
||||||
|
if (Team.Event.EventFormat == EventFormat.Individual && _selectedStudents.Count() == 1)
|
||||||
|
{
|
||||||
|
// For individual events, use student's first name as identifier
|
||||||
|
var student = _selectedStudents.First();
|
||||||
|
Team.Identifier = student.FirstName;
|
||||||
|
Team.Captain = student;
|
||||||
|
}
|
||||||
|
else if (existingTeamCount == 1)
|
||||||
|
{
|
||||||
|
// This is the second team - assign numbers
|
||||||
|
var existingTeam = await Context.Teams
|
||||||
|
.FirstOrDefaultAsync(t => t.Event.Id == Team.Event.Id);
|
||||||
|
|
||||||
|
if (existingTeam != null)
|
||||||
|
{
|
||||||
|
// Update existing team to number 1
|
||||||
|
existingTeam.Identifier = "1";
|
||||||
|
Context.Teams.Update(existingTeam);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set new team to number 2
|
||||||
|
Team.Identifier = "2";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// This is the first team - no number
|
||||||
|
Team.Identifier = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add selected students to the team
|
||||||
|
foreach (var student in _selectedStudents)
|
||||||
|
{
|
||||||
|
Team.Students.Add(student);
|
||||||
|
}
|
||||||
|
|
||||||
Context.Teams.Add(Team);
|
Context.Teams.Add(Team);
|
||||||
|
|
||||||
await Context.SaveChangesAsync();
|
await Context.SaveChangesAsync();
|
||||||
|
|||||||
@@ -20,28 +20,15 @@ else
|
|||||||
<MudGrid>
|
<MudGrid>
|
||||||
<MudItem xs="12" sm="7">
|
<MudItem xs="12" sm="7">
|
||||||
<MudPaper Class="pa-4">
|
<MudPaper Class="pa-4">
|
||||||
<MudSelect
|
<StudentToggleSelector Students="@_students"
|
||||||
T="Student"
|
@bind-SelectedStudents="_selectedStudents"
|
||||||
MultiSelection="true"
|
Title="Students"
|
||||||
@bind-SelectedValues="@_selectedStudents"
|
ShowFullName="true" />
|
||||||
ToStringFunc="e => e.Name"
|
<MudStack Class="mt-4">
|
||||||
Label="Students">
|
<TeamCaptainSelector Students="@_selectedStudents"
|
||||||
|
@bind-SelectedCaptain="Team.Captain"
|
||||||
@foreach (var student in _students.OrderBy(e => e.FirstName))
|
Title="Captain" />
|
||||||
{
|
|
||||||
<MudSelectItem T="Student" Value="@student">@student.Name</MudSelectItem>
|
|
||||||
}
|
|
||||||
</MudSelect>
|
|
||||||
<MudStack>
|
|
||||||
<MudText>Captain</MudText>
|
|
||||||
<MudToggleGroup T="Student" SelectionMode="SelectionMode.ToggleSelection" @bind-Value="Team.Captain" CheckMark>
|
|
||||||
@foreach (var student in _selectedStudents.OrderBy(e => e.FirstName))
|
|
||||||
{
|
|
||||||
<MudToggleItem Value="@(student)" Text="@student.Name" />
|
|
||||||
}
|
|
||||||
</MudToggleGroup>
|
|
||||||
</MudStack>
|
</MudStack>
|
||||||
<MudTextField T="string?" Label="Identifier" @bind-Value="Team.Identifier" For="@(() => Team.Identifier)" Required="false" Clearable="true"></MudTextField>
|
|
||||||
</MudPaper>
|
</MudPaper>
|
||||||
</MudItem>
|
</MudItem>
|
||||||
</MudGrid>
|
</MudGrid>
|
||||||
@@ -57,7 +44,7 @@ else
|
|||||||
[SupplyParameterFromForm]
|
[SupplyParameterFromForm]
|
||||||
private Team? Team { get; set; }
|
private Team? Team { get; set; }
|
||||||
|
|
||||||
private IEnumerable<Student> _selectedStudents = new HashSet<Student>();
|
private IEnumerable<Student> _selectedStudents = [];
|
||||||
private List<Student> _students = [];
|
private List<Student> _students = [];
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
@@ -67,10 +54,7 @@ else
|
|||||||
.Include(e => e.Students)
|
.Include(e => e.Students)
|
||||||
.FirstOrDefaultAsync(m => m.Id == Id);
|
.FirstOrDefaultAsync(m => m.Id == Id);
|
||||||
_students = await Context.Students.ToListAsync();
|
_students = await Context.Students.ToListAsync();
|
||||||
foreach (var s in Team.Students)
|
_selectedStudents = Team.Students.ToList();
|
||||||
{
|
|
||||||
((HashSet<Student>)_selectedStudents).Add(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Team is null)
|
if (Team is null)
|
||||||
{
|
{
|
||||||
@@ -97,6 +81,13 @@ else
|
|||||||
Team.Students.Add(s);
|
Team.Students.Add(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update identifier for individual events
|
||||||
|
if (Team.Event.EventFormat == EventFormat.Individual && Team.Students.Count == 1)
|
||||||
|
{
|
||||||
|
Team.Captain ??= Team.Students[0];
|
||||||
|
Team.Identifier = Team.Captain.FirstName;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await Context.SaveChangesAsync();
|
await Context.SaveChangesAsync();
|
||||||
|
|||||||
@@ -83,6 +83,20 @@
|
|||||||
|
|
||||||
if (result == true)
|
if (result == true)
|
||||||
{
|
{
|
||||||
|
// If deleting a numbered team (1 or 2), clear the identifier of the remaining team
|
||||||
|
if (team.Identifier == "1" || team.Identifier == "2")
|
||||||
|
{
|
||||||
|
var remainingTeam = await Context.Teams
|
||||||
|
.Include(t => t.Event)
|
||||||
|
.FirstOrDefaultAsync(t => t.Event.Id == team.Event.Id && t.Id != team.Id);
|
||||||
|
|
||||||
|
if (remainingTeam != null)
|
||||||
|
{
|
||||||
|
remainingTeam.Identifier = null;
|
||||||
|
Context.Teams.Update(remainingTeam);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Context.Teams.Remove(team!);
|
Context.Teams.Remove(team!);
|
||||||
await Context.SaveChangesAsync();
|
await Context.SaveChangesAsync();
|
||||||
Snackbar.Add($"Delete event: Delete of Team {team}", Severity.Info);
|
Snackbar.Add($"Delete event: Delete of Team {team}", Severity.Info);
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
@if (Title != null)
|
||||||
|
{
|
||||||
|
<MudText Typo="Typo.h4">@Title</MudText>
|
||||||
|
}
|
||||||
|
|
||||||
|
<MudToggleGroup T="Student"
|
||||||
|
SelectionMode="SelectionMode.MultiSelection"
|
||||||
|
Values="@SelectedStudents"
|
||||||
|
ValuesChanged="@OnSelectedStudentsChanged"
|
||||||
|
Vertical="true"
|
||||||
|
CheckMark>
|
||||||
|
@foreach (var student in Students.OrderBy(e => e.FirstName))
|
||||||
|
{
|
||||||
|
<MudToggleItem Value="@student" Style="font-size: .75rem;">
|
||||||
|
@if (ShowFullName)
|
||||||
|
{
|
||||||
|
@student.FirstNameLastName
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@student.FirstName
|
||||||
|
}
|
||||||
|
</MudToggleItem>
|
||||||
|
}
|
||||||
|
</MudToggleGroup>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[Parameter]
|
||||||
|
public IEnumerable<Student> Students { get; set; } = [];
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public IEnumerable<Student> SelectedStudents { get; set; } = [];
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public EventCallback<IEnumerable<Student>> SelectedStudentsChanged { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string? Title { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public bool ShowFullName { get; set; } = true;
|
||||||
|
|
||||||
|
private async Task OnSelectedStudentsChanged(IEnumerable<Student> value)
|
||||||
|
{
|
||||||
|
SelectedStudents = value;
|
||||||
|
await SelectedStudentsChanged.InvokeAsync(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
@if (Title != null)
|
||||||
|
{
|
||||||
|
<MudText Typo="@TitleTypo">@Title</MudText>
|
||||||
|
}
|
||||||
|
|
||||||
|
<MudToggleGroup T="Student"
|
||||||
|
SelectionMode="SelectionMode.ToggleSelection"
|
||||||
|
Value="@SelectedCaptain"
|
||||||
|
ValueChanged="@OnSelectedCaptainChanged"
|
||||||
|
CheckMark>
|
||||||
|
@foreach (var student in Students.OrderBy(e => e.FirstName))
|
||||||
|
{
|
||||||
|
<MudToggleItem Value="@student" Text="@student.Name" />
|
||||||
|
}
|
||||||
|
</MudToggleGroup>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[Parameter]
|
||||||
|
public IEnumerable<Student> Students { get; set; } = [];
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public Student? SelectedCaptain { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public EventCallback<Student?> SelectedCaptainChanged { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string? Title { get; set; } = "Captain";
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public Typo TitleTypo { get; set; } = Typo.body1;
|
||||||
|
|
||||||
|
private async Task OnSelectedCaptainChanged(Student? value)
|
||||||
|
{
|
||||||
|
SelectedCaptain = value;
|
||||||
|
await SelectedCaptainChanged.InvokeAsync(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user