Add loading states to MudDataGrid components

Implemented loading indicators and progress colors for all MudDataGrid instances across Events, Students, Teams, and Registration components to enhance user experience during data loading operations.
This commit is contained in:
2025-12-27 10:39:16 -05:00
parent cb362d6754
commit d19326781a
5 changed files with 113 additions and 73 deletions
+21 -11
View File
@@ -22,7 +22,9 @@
RowsPerPage="50"
Dense="true"
Striped="true"
Hover="true">
Hover="true"
Loading="@_isLoading"
LoadingProgressColor="Color.Primary">
<Columns>
<PropertyColumn Property="@(e => e.Name)" Title="Event Name" Sortable="true">
<CellTemplate>
@@ -71,20 +73,28 @@
@code {
MudDataGrid<EventDefinition> _dataGrid = null!;
private bool _isLoading = true;
private async Task<GridData<EventDefinition>> ServerReload(GridState<EventDefinition> 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<EventDefinition>
_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<EventDefinition>
{
TotalItems = totalItems,
Items = pagedData
};
}
finally
{
_isLoading = false;
}
}
private async Task DeleteEventDefinition(EventDefinition evt)
+23 -13
View File
@@ -23,7 +23,9 @@
RowsPerPage="25"
Dense="true"
Striped="true"
Hover="true">
Hover="true"
Loading="@_isLoading"
LoadingProgressColor="Color.Primary">
<Columns>
<PropertyColumn Property="@(e => e.LastName)" Title="Name" Sortable="true">
<CellTemplate>
@@ -65,22 +67,30 @@
@code {
MudDataGrid<Student> _dataGrid = null!;
private bool _isLoading = true;
private async Task<GridData<Student>> ServerReload(GridState<Student> 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<Student>
_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<Student>
{
TotalItems = totalItems,
Items = pagedData
};
}
finally
{
_isLoading = false;
}
}
private async Task DeleteStudent(Student student)
@@ -34,7 +34,7 @@
</MudStack>
</MudText>
<MudDataGrid T="StudentTeamInfo" ServerData="ServerReload" @ref="_dataGrid" @key="_gridKey" Filterable="true" RowsPerPage="35" Dense="true" Striped="true" Hover="true">
<MudDataGrid T="StudentTeamInfo" ServerData="ServerReload" @ref="_dataGrid" @key="_gridKey" Filterable="true" RowsPerPage="35" Dense="true" Striped="true" Hover="true" Loading="@_isLoading" LoadingProgressColor="Color.Primary">
<Columns>
<PropertyColumn Property="@(e => e.Student.LastName)" Title="Student" Sortable="true">
@@ -109,6 +109,7 @@
@code {
MudDataGrid<StudentTeamInfo> _dataGrid = null!;
private bool _isLoading = true;
private bool _showRegionalOnly;
private bool _showGrade;
private bool _showRegionalId;
@@ -167,35 +168,43 @@
private async Task<GridData<StudentTeamInfo>> ServerReload(GridState<StudentTeamInfo> 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<StudentTeamInfo>
_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<StudentTeamInfo>
{
TotalItems = totalItems,
Items = pagedData
};
}
finally
{
_isLoading = false;
}
}
/// <summary>
+29 -18
View File
@@ -22,7 +22,9 @@
RowsPerPage="35"
Dense="true"
Striped="true"
Hover="true">
Hover="true"
Loading="@_isLoading"
LoadingProgressColor="Color.Primary">
<Columns>
<TemplateColumn Title="Event" Sortable="true" SortBy="@(t => t.Event.Name)">
<CellTemplate>
@@ -63,27 +65,36 @@
@code {
MudDataGrid<Team> _dataGrid = null!;
private bool _isLoading = true;
private async Task<GridData<Team>> ServerReload(GridState<Team> 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<Team>
_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<Team>
{
TotalItems = totalItems,
Items = pagedData
};
}
finally
{
_isLoading = false;
}
}
private async Task DeleteTeam(Team team)
+2 -2
View File
@@ -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)