@using Microsoft.EntityFrameworkCore @using WebApp.Components.Shared.Components @using WebApp.Models @page "/teams" @attribute [Authorize] @inject AppDbContext Context @inject IDialogService DialogService @inject ISnackbar Snackbar Create New Printout Handout @(_showRegionalOnly ? "Showing Regional Only" : "Show Regional Only") @context.Item.ToString() @code { MudDataGrid _dataGrid = null!; private bool _isLoading = true; private bool _showRegionalOnly = false; private async Task ToggleRegionalFilter() { try { _showRegionalOnly = !_showRegionalOnly; if (_dataGrid != null) { await _dataGrid.ReloadServerData(); } } catch (Exception ex) { Snackbar.Add($"Error applying filter: {ex.Message}", Severity.Error); } } private async Task> ServerReload(GridState state) { _isLoading = true; try { IQueryable query = Context.Teams .Include(e => e.Event) .Include(e => e.Students) .ThenInclude(e => e.EventRankings); // Apply regional filter if enabled // Note: RegionalEvent is a computed property, so we must use the underlying property if (_showRegionalOnly) { query = query.Where(t => t.Event.ChapterEligibilityCountRegionals > 0); } // Apply grid filter definitions query = query.Where(state.FilterDefinitions); // Load all data first var allTeams = await query.ToArrayAsync(); // Always sort by EventFormat FIRST to separate group/individual teams // Sort in memory to ensure this ordering is maintained regardless of user sorts var sortedTeams = allTeams.OrderByEventFormatFirst(); // Apply user sort definitions as secondary sorts (within each group) bool appliedUserSort = false; if (state.SortDefinitions != null && state.SortDefinitions.Any()) { var sortDef = state.SortDefinitions.First(); var sortBy = sortDef.SortBy ?? ""; // Handle Event.Name sorting if (sortBy == "Event.Name" || (sortBy.Contains("Event") && sortBy.Contains("Name"))) { sortedTeams = sortDef.Descending ? sortedTeams.ThenByDescending(t => t.Event.Name) : sortedTeams.ThenBy(t => t.Event.Name); appliedUserSort = true; } // Handle Identifier sorting else if (sortBy == "Identifier") { sortedTeams = sortDef.Descending ? sortedTeams.ThenByDescending(t => t.Identifier ?? "") : sortedTeams.ThenBy(t => t.Identifier ?? ""); appliedUserSort = true; } } // Apply default secondary sorting if (!appliedUserSort) { sortedTeams = sortedTeams .ThenBy(t => t.Event.Name) .ThenBy(t => t.Identifier ?? ""); } else { // Add default sorting as tie-breakers if (state.SortDefinitions?.First().SortBy != "Event.Name") { sortedTeams = sortedTeams.ThenBy(t => t.Event.Name); } if (state.SortDefinitions?.First().SortBy != "Identifier") { sortedTeams = sortedTeams.ThenBy(t => t.Identifier ?? ""); } } var totalItems = sortedTeams.Count(); var pagedData = sortedTeams.Skip(state.Page * state.PageSize).Take(state.PageSize).ToArray(); return new GridData { TotalItems = totalItems, Items = pagedData }; } finally { _isLoading = false; } } private async Task DeleteTeam(Team team) { //_isRowBlocked = true; var result = await DialogService .ShowMessageBox("Delete team", (MarkupString)$"Are you sure want to delete {team}? This cannot be undone.", yesText: "Yes", noText: "Cancel"); 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!); await Context.SaveChangesAsync(); Snackbar.Add($"Delete event: Delete of Team {team}", Severity.Info); } //_isRowBlocked = false; StateHasChanged(); await _dataGrid.ReloadServerData(); } }