Improve loading UX with spinner and wider filter fields
Replaced plain loading text with a centered Bootstrap spinner in CatalogsGrid and MassDataGrid. Introduced hasLoaded flag for more accurate loading state handling. Increased min-width of filter input fields for better usability. Added .loading-container CSS for consistent spinner placement.
This commit is contained in:
@@ -86,8 +86,14 @@
|
|||||||
flex: 0 0 52px;
|
flex: 0 0 52px;
|
||||||
}
|
}
|
||||||
.filter-value {
|
.filter-value {
|
||||||
min-width: 140px;
|
min-width: 160px;
|
||||||
flex: 1 1 140px;
|
flex: 1 1 160px;
|
||||||
|
}
|
||||||
|
.loading-container {
|
||||||
|
min-height: 160px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
@@ -100,9 +106,13 @@ else if (!string.IsNullOrWhiteSpace(infoMessage))
|
|||||||
<div class="alert alert-success" role="alert">@infoMessage</div>
|
<div class="alert alert-success" role="alert">@infoMessage</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (isLoading)
|
@if (!hasLoaded || isLoading)
|
||||||
{
|
{
|
||||||
<p><em>Lade Daten...</em></p>
|
<div class="loading-container">
|
||||||
|
<div class="spinner-border text-primary" role="status">
|
||||||
|
<span class="visually-hidden">Lade...</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
else if (items.Count == 0)
|
else if (items.Count == 0)
|
||||||
{
|
{
|
||||||
@@ -196,6 +206,7 @@ else
|
|||||||
@code {
|
@code {
|
||||||
private List<CatalogReadDto> items = new();
|
private List<CatalogReadDto> items = new();
|
||||||
private bool isLoading;
|
private bool isLoading;
|
||||||
|
private bool hasLoaded;
|
||||||
private string? errorMessage;
|
private string? errorMessage;
|
||||||
private string? infoMessage;
|
private string? infoMessage;
|
||||||
private EditContext? editContext;
|
private EditContext? editContext;
|
||||||
@@ -342,6 +353,7 @@ else
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
hasLoaded = true;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,8 +113,14 @@
|
|||||||
flex: 1 1 140px;
|
flex: 1 1 140px;
|
||||||
}
|
}
|
||||||
.filter-value-amount {
|
.filter-value-amount {
|
||||||
min-width: 110px;
|
min-width: 140px;
|
||||||
flex-basis: 110px;
|
flex-basis: 140px;
|
||||||
|
}
|
||||||
|
.loading-container {
|
||||||
|
min-height: 160px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
@@ -127,9 +133,13 @@ else if (!string.IsNullOrWhiteSpace(infoMessage))
|
|||||||
<div class="alert alert-success" role="alert">@infoMessage</div>
|
<div class="alert alert-success" role="alert">@infoMessage</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (isLoading)
|
@if (!hasLoaded || isLoading)
|
||||||
{
|
{
|
||||||
<p><em>Lade Daten...</em></p>
|
<div class="loading-container">
|
||||||
|
<div class="spinner-border text-primary" role="status">
|
||||||
|
<span class="visually-hidden">Lade...</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
else if (items.Count == 0)
|
else if (items.Count == 0)
|
||||||
{
|
{
|
||||||
@@ -248,6 +258,7 @@ else
|
|||||||
@code {
|
@code {
|
||||||
private List<MassDataReadDto> items = new();
|
private List<MassDataReadDto> items = new();
|
||||||
private bool isLoading;
|
private bool isLoading;
|
||||||
|
private bool hasLoaded;
|
||||||
private string? errorMessage;
|
private string? errorMessage;
|
||||||
private string? infoMessage;
|
private string? infoMessage;
|
||||||
private int pageIndex;
|
private int pageIndex;
|
||||||
@@ -346,6 +357,7 @@ else
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
hasLoaded = true;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,8 +45,14 @@
|
|||||||
flex: 0 0 52px;
|
flex: 0 0 52px;
|
||||||
}
|
}
|
||||||
.filter-value {
|
.filter-value {
|
||||||
min-width: 140px;
|
min-width: 160px;
|
||||||
flex: 1 1 140px;
|
flex: 1 1 160px;
|
||||||
|
}
|
||||||
|
.loading-container {
|
||||||
|
min-height: 160px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
@@ -59,9 +65,13 @@ else if (!string.IsNullOrWhiteSpace(infoMessage))
|
|||||||
<div class="alert alert-success" role="alert">@infoMessage</div>
|
<div class="alert alert-success" role="alert">@infoMessage</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (isLoading)
|
@if (!hasLoaded || isLoading)
|
||||||
{
|
{
|
||||||
<p><em>Lade Daten...</em></p>
|
<div class="loading-container">
|
||||||
|
<div class="spinner-border text-primary" role="status">
|
||||||
|
<span class="visually-hidden">Lade...</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
else if (items.Count == 0)
|
else if (items.Count == 0)
|
||||||
{
|
{
|
||||||
@@ -155,6 +165,7 @@ else
|
|||||||
@code {
|
@code {
|
||||||
private List<CatalogReadDto> items = new();
|
private List<CatalogReadDto> items = new();
|
||||||
private bool isLoading;
|
private bool isLoading;
|
||||||
|
private bool hasLoaded;
|
||||||
private string? errorMessage;
|
private string? errorMessage;
|
||||||
private string? infoMessage;
|
private string? infoMessage;
|
||||||
private EditContext? editContext;
|
private EditContext? editContext;
|
||||||
@@ -301,6 +312,7 @@ else
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
hasLoaded = true;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,8 +113,14 @@
|
|||||||
flex: 1 1 140px;
|
flex: 1 1 140px;
|
||||||
}
|
}
|
||||||
.filter-value-amount {
|
.filter-value-amount {
|
||||||
min-width: 110px;
|
min-width: 140px;
|
||||||
flex-basis: 110px;
|
flex-basis: 140px;
|
||||||
|
}
|
||||||
|
.loading-container {
|
||||||
|
min-height: 160px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
@@ -127,9 +133,13 @@ else if (!string.IsNullOrWhiteSpace(infoMessage))
|
|||||||
<div class="alert alert-success" role="alert">@infoMessage</div>
|
<div class="alert alert-success" role="alert">@infoMessage</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (isLoading)
|
@if (!hasLoaded || isLoading)
|
||||||
{
|
{
|
||||||
<p><em>Lade Daten...</em></p>
|
<div class="loading-container">
|
||||||
|
<div class="spinner-border text-primary" role="status">
|
||||||
|
<span class="visually-hidden">Lade...</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
else if (items.Count == 0)
|
else if (items.Count == 0)
|
||||||
{
|
{
|
||||||
@@ -248,6 +258,7 @@ else
|
|||||||
@code {
|
@code {
|
||||||
private List<MassDataReadDto> items = new();
|
private List<MassDataReadDto> items = new();
|
||||||
private bool isLoading;
|
private bool isLoading;
|
||||||
|
private bool hasLoaded;
|
||||||
private string? errorMessage;
|
private string? errorMessage;
|
||||||
private string? infoMessage;
|
private string? infoMessage;
|
||||||
private int pageIndex;
|
private int pageIndex;
|
||||||
@@ -346,6 +357,7 @@ else
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
hasLoaded = true;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user