diff --git a/WebApp/Components/Features/Events/Index.razor b/WebApp/Components/Features/Events/Index.razor index c651e3f..3d5df60 100644 --- a/WebApp/Components/Features/Events/Index.razor +++ b/WebApp/Components/Features/Events/Index.razor @@ -22,7 +22,9 @@ RowsPerPage="50" Dense="true" Striped="true" - Hover="true"> + Hover="true" + Loading="@_isLoading" + LoadingProgressColor="Color.Primary"> @@ -71,20 +73,28 @@ @code { MudDataGrid _dataGrid = null!; + private bool _isLoading = true; private async Task> ServerReload(GridState state) { - - var query = Context.Events.OrderBy(e => e.Name).Where(state.FilterDefinitions).OrderBy(state.SortDefinitions); - - var totalItems = await query.CountAsync(); - var pagedData = await query.Skip(state.Page * state.PageSize).Take(state.PageSize).ToArrayAsync(); - - return new GridData + _isLoading = true; + try { - TotalItems = totalItems, - Items = pagedData - }; + var query = Context.Events.OrderBy(e => e.Name).Where(state.FilterDefinitions).OrderBy(state.SortDefinitions); + + var totalItems = await query.CountAsync(); + var pagedData = await query.Skip(state.Page * state.PageSize).Take(state.PageSize).ToArrayAsync(); + + return new GridData + { + TotalItems = totalItems, + Items = pagedData + }; + } + finally + { + _isLoading = false; + } } private async Task DeleteEventDefinition(EventDefinition evt) diff --git a/WebApp/Components/Features/Students/Index.razor b/WebApp/Components/Features/Students/Index.razor index b0ef2a8..9ccce83 100644 --- a/WebApp/Components/Features/Students/Index.razor +++ b/WebApp/Components/Features/Students/Index.razor @@ -23,7 +23,9 @@ RowsPerPage="25" Dense="true" Striped="true" - Hover="true"> + Hover="true" + Loading="@_isLoading" + LoadingProgressColor="Color.Primary"> @@ -65,22 +67,30 @@ @code { MudDataGrid _dataGrid = null!; + private bool _isLoading = true; private async Task> ServerReload(GridState state) { - - var query = - Context.Students.OrderBy(e => e.LastName) - .Where(state.FilterDefinitions).OrderBy(state.SortDefinitions); - - var totalItems = await query.CountAsync(); - var pagedData = await query.Skip(state.Page * state.PageSize).Take(state.PageSize).ToArrayAsync(); - - return new GridData + _isLoading = true; + try { - TotalItems = totalItems, - Items = pagedData - }; + var query = + Context.Students.OrderBy(e => e.LastName) + .Where(state.FilterDefinitions).OrderBy(state.SortDefinitions); + + var totalItems = await query.CountAsync(); + var pagedData = await query.Skip(state.Page * state.PageSize).Take(state.PageSize).ToArrayAsync(); + + return new GridData + { + TotalItems = totalItems, + Items = pagedData + }; + } + finally + { + _isLoading = false; + } } private async Task DeleteStudent(Student student) diff --git a/WebApp/Components/Features/Students/Registration.razor b/WebApp/Components/Features/Students/Registration.razor index a974742..ccd2945 100644 --- a/WebApp/Components/Features/Students/Registration.razor +++ b/WebApp/Components/Features/Students/Registration.razor @@ -34,7 +34,7 @@ - + @@ -109,6 +109,7 @@ @code { MudDataGrid _dataGrid = null!; + private bool _isLoading = true; private bool _showRegionalOnly; private bool _showGrade; private bool _showRegionalId; @@ -167,35 +168,43 @@ private async Task> ServerReload(GridState state) { - // Load all students with their teams - var students = await Context.Students - .Include(s => s.Teams) - .ThenInclude(t => t.Event) - .Include(s => s.Teams) - .ThenInclude(t => t.Captain) - .ToListAsync(); - - // Filter to only students with teams - var studentTeams = students - .Where(s => s.Teams.Any(t => t?.Event != null && (!_showRegionalOnly || t.Event.RegionalEvent))) - .Select(s => new StudentTeamInfo - { - Student = s, - Teams = s.Teams?.Where(t => t?.Event != null).ToList() ?? [] - }) - .ToList(); - - // Apply sorting - var sortedData = ApplySorting(studentTeams, state.SortDefinitions); - - var totalItems = sortedData.Count(); - var pagedData = sortedData.Skip(state.Page * state.PageSize).Take(state.PageSize).ToArray(); - - return new GridData + _isLoading = true; + try { - TotalItems = totalItems, - Items = pagedData - }; + // Load all students with their teams + var students = await Context.Students + .Include(s => s.Teams) + .ThenInclude(t => t.Event) + .Include(s => s.Teams) + .ThenInclude(t => t.Captain) + .ToListAsync(); + + // Filter to only students with teams + var studentTeams = students + .Where(s => s.Teams.Any(t => t?.Event != null && (!_showRegionalOnly || t.Event.RegionalEvent))) + .Select(s => new StudentTeamInfo + { + Student = s, + Teams = s.Teams?.Where(t => t?.Event != null).ToList() ?? [] + }) + .ToList(); + + // Apply sorting + var sortedData = ApplySorting(studentTeams, state.SortDefinitions); + + var totalItems = sortedData.Count(); + var pagedData = sortedData.Skip(state.Page * state.PageSize).Take(state.PageSize).ToArray(); + + return new GridData + { + TotalItems = totalItems, + Items = pagedData + }; + } + finally + { + _isLoading = false; + } } /// diff --git a/WebApp/Components/Features/Teams/Index.razor b/WebApp/Components/Features/Teams/Index.razor index 7758d74..57deeb3 100644 --- a/WebApp/Components/Features/Teams/Index.razor +++ b/WebApp/Components/Features/Teams/Index.razor @@ -22,7 +22,9 @@ RowsPerPage="35" Dense="true" Striped="true" - Hover="true"> + Hover="true" + Loading="@_isLoading" + LoadingProgressColor="Color.Primary"> @@ -63,27 +65,36 @@ @code { MudDataGrid _dataGrid = null!; + private bool _isLoading = true; private async Task> ServerReload(GridState state) { - var query - = Context.Teams - .Include(e => e.Event) - .Include(e => e.Students) - .ThenInclude(e => e.EventRankings) - .OrderBy(e => e.Event.Name) - .ThenBy(e => e.Identifier) - .Where(state.FilterDefinitions) - .OrderBy(state.SortDefinitions); - - var totalItems = await query.CountAsync(); - var pagedData = await query.Skip(state.Page * state.PageSize).Take(state.PageSize).ToArrayAsync(); - - return new GridData + _isLoading = true; + try { - TotalItems = totalItems, - Items = pagedData - }; + var query + = Context.Teams + .Include(e => e.Event) + .Include(e => e.Students) + .ThenInclude(e => e.EventRankings) + .OrderBy(e => e.Event.Name) + .ThenBy(e => e.Identifier) + .Where(state.FilterDefinitions) + .OrderBy(state.SortDefinitions); + + var totalItems = await query.CountAsync(); + var pagedData = await query.Skip(state.Page * state.PageSize).Take(state.PageSize).ToArrayAsync(); + + return new GridData + { + TotalItems = totalItems, + Items = pagedData + }; + } + finally + { + _isLoading = false; + } } private async Task DeleteTeam(Team team) diff --git a/docs/plans/style-improvements.md b/docs/plans/style-improvements.md index 4610fcf..4fac40a 100644 --- a/docs/plans/style-improvements.md +++ b/docs/plans/style-improvements.md @@ -127,7 +127,7 @@ This document outlines recommended style improvements to enhance the visual desi --- -### 5. Add Loading States +### 5. Add Loading States ✅ COMPLETED **Locations**: All MudDataGrid and async components **Issue**: No visual feedback during data loading operations. @@ -331,7 +331,7 @@ Consider using MudChip components with rank colors for better visual distinction ### Phase 2: Visual Polish (Medium Impact, Medium Effort) 4. ✅ Refine typography hierarchy usage -5. Add loading states to all grids +5. ✅ Add loading states to all grids 6. ✅ Wrap pages in consistent container styling ### Phase 3: Enhancements (Nice to Have)