Compare commits

..
2 Commits
Author SHA1 Message Date
poprhythm 4dcd9e5aab Add presubmission filter functionality to MeetingSchedule component
This commit introduces a new filter for presubmission teams in the MeetingSchedule component. It adds an AddRemoveFilter for managing teams whose events require presubmission, allowing users to add or remove these teams from the scheduled list. The corresponding methods for adding and removing presubmission teams are implemented, enhancing the component's functionality and improving user experience in managing event teams.
2026-03-10 11:55:06 -04:00
poprhythm 336bbb1dec Refactor Event components for improved data handling and null safety
This commit updates the Edit.razor and EventAttributes.razor components to enhance data handling and prevent potential null reference exceptions. In Edit.razor, comments are added to clarify the tracking of related careers, ensuring that the same instances are used to avoid tracking conflicts. The EventAttributes.razor component is modified to handle null EventDefinition gracefully, preventing errors when the parameter is not set. Additionally, the EventDefinitionService is updated to ensure existing careers are retrieved with tracking, improving data consistency. These changes collectively enhance the robustness and reliability of the event management features.
2026-03-10 11:12:28 -04:00
5 changed files with 47 additions and 7 deletions
@@ -1,5 +1,9 @@
@using WebApp.Models
@using WebApp.Models
@if (EventDefinition is null)
{
return;
}
@* @if (EventDefinition.LevelOfEffort.HasValue)
{
<span class="numberCircle">@EventDefinition.LevelOfEffort</span>
@@ -27,12 +31,17 @@
@code {
[Parameter]
public required EventDefinition EventDefinition { get; set; }
public EventDefinition? EventDefinition { get; set; }
private string _attributes = string.Empty;
protected override void OnParametersSet()
{
if (EventDefinition is null)
{
_attributes = string.Empty;
return;
}
_attributes = EventDefinition.EventFormat == EventFormat.Individual ? AppIcons.IndividualEvent : " ";
_attributes += EventDefinition.OnSiteActivity ? AppIcons.OnSiteActivity : " ";
_attributes += EventDefinition.RegionalEvent ? AppIcons.RegionalEvent : " ";
+6 -3
View File
@@ -1,4 +1,4 @@
@page "/events/edit"
@page "/events/edit"
@attribute [Authorize]
@using Microsoft.EntityFrameworkCore
@using WebApp.Components.Shared.Components
@@ -163,9 +163,10 @@
{
try
{
// Get the tracked entity from the database
// Get the tracked entity from the database (do not Include RelatedCareers:
// the same context may already be tracking those Career instances from the initial load,
// which would cause "another instance with the same key value is already being tracked").
var trackedEntity = await context.Events
.Include(e => e.RelatedCareers)
.FirstOrDefaultAsync(e => e.Id == EventDefinition!.Id);
if (trackedEntity == null)
@@ -177,6 +178,8 @@
// Update scalar properties from the form-bound entity
context.Entry(trackedEntity).CurrentValues.SetValues(EventDefinition!);
// RelatedCareersText is not mapped; copy it so ProcessRelatedCareersAsync can use it
trackedEntity.RelatedCareersText = EventDefinition!.RelatedCareersText;
// Normalize and process related careers
await EventDefinitionService.ProcessRelatedCareersAsync(trackedEntity);
@@ -87,6 +87,13 @@
AddTooltip="Add regional event teams"
RemoveTooltip="Remove regional event teams" />
</MudItem>
<MudItem xs="12" sm="6" lg="4">
<AddRemoveFilter Label="Presubmission"
OnAdd="AddPresubmission"
OnRemove="RemovePresubmission"
AddTooltip="Add teams whose events require presubmission"
RemoveTooltip="Remove teams whose events require presubmission" />
</MudItem>
<MudItem xs="12" sm="6" lg="4">
<AddRemoveFilter Label="Individual"
OnAdd="AddIndividual"
@@ -246,6 +253,13 @@
StateHasChanged();
}
private void AddPresubmission()
{
var presubmissionTeams = _teams.Where(t => t.Event?.Presubmission == true);
_scheduledTeams = _scheduledTeams.Concat(presubmissionTeams).Distinct();
StateHasChanged();
}
private void AddHighLevelOfEffort()
{
_scheduledTeams = _scheduledTeams.AddHighLevelOfEffort(_teams);
@@ -266,6 +280,16 @@
StateHasChanged();
}
private void RemovePresubmission()
{
var presubmissionTeamIds = _teams
.Where(t => t.Event?.Presubmission == true)
.Select(t => t.Id)
.ToHashSet();
_scheduledTeams = _scheduledTeams.Where(t => !presubmissionTeamIds.Contains(t.Id));
StateHasChanged();
}
private void AddIndividual()
{
var individualTeams = _teams.Where(t => t.Event.EventFormat == EventFormat.Individual);
@@ -244,6 +244,8 @@ else
.AsNoTracking()
.Include(e => e.Teams)
.ThenInclude(e => e.Captain)
.Include(e => e.Teams)
.ThenInclude(e => e.Event)
.Include(e => e.EventRankings)
.ThenInclude(e => e.EventDefinition)
.OrderBy(e => e.FirstName).ToArrayAsync();
+4 -2
View File
@@ -38,9 +38,11 @@ public class EventDefinitionService
return;
}
// Get all existing careers from database (case-insensitive lookup)
// Get existing careers with tracking so we use the same instances the context
// may already be tracking (e.g. from the event's RelatedCareers). Using
// AsNoTracking() would create duplicate instances and cause "another instance
// with the same key value is already being tracked".
var existingCareers = await _context.Careers
.AsNoTracking()
.Where(c => !string.IsNullOrWhiteSpace(c.Name))
.ToListAsync();