Revamp CHS View UI with enhanced loading experience, improved layout, and search functionality

This commit is contained in:
2026-01-01 17:38:02 +00:00
parent 097d055173
commit 33ccad3b85
2 changed files with 167 additions and 62 deletions

View File

@@ -34,79 +34,168 @@
@inject Microsoft.EntityFrameworkCore.IDbContextFactory<DbContext> DbContextFactory
<PageTitle>Chs</PageTitle>
<PageTitle>CHS</PageTitle>
@if(!_initialized)
{
<div class="stats-section">
<h1 style="color: red; align-content: center; padding: 2rem">Loading...</h1>
<div class="d-flex justify-content-center align-items-center" style="min-height: 60vh;">
<div class="text-center">
<div class="spinner-border text-info" role="status" style="width: 3rem; height: 3rem;">
<span class="visually-hidden">Loading...</span>
</div>
<h3 class="mt-3 text-light">Loading CHS data...</h3>
</div>
</div>
return;
}
<section class="stats-section">
<h4>CHS</h4>
<table class="table table-dark table-striped table-bordered mt-4 mb-4">
<thead class="thead-dark">
<tr>
<th class="fw-bold bg-secondary text-light">
@DisplayNameHelper.GetDisplayName(typeof(Chs), nameof(Chs.Cylinders))
</th>
<th class="fw-bold bg-secondary text-light">
@DisplayNameHelper.GetDisplayName(typeof(Chs), nameof(Chs.Heads))
</th>
<th class="fw-bold bg-secondary text-light">
@DisplayNameHelper.GetDisplayName(typeof(Chs), nameof(Chs.Sectors))
</th>
</tr>
</thead>
<tbody>
@foreach(Chs item in _items)
{
<tr>
<td>
@item.Cylinders
</td>
<td>
@item.Heads
</td>
<td>
@item.Sectors
</td>
</tr>
}
</tbody>
</table>
<div class="container-fluid px-4 py-4">
<!-- Header Section -->
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<h1 class="h2 mb-1 text-light">
<i class="bi bi-hdd-rack text-info"></i> CHS (Cylinder-Head-Sector)
</h1>
<p class="text-secondary mb-0">Manage drive geometry database</p>
</div>
</div>
<!-- Duplicates Alert -->
@if(_duplicates.Count > 0)
{
<div>
The following CHS have duplicates.
<table class="table">
<tbody>
@foreach(ChsModel item in _duplicates)
{
<tr>
<td>
@item.Cylinders/@item.Heads/@item.Sectors
</td>
</tr>
}
</tbody>
</table>
<div class="alert alert-warning bg-dark border-warning text-light shadow-sm mb-4" role="alert">
<div class="d-flex align-items-start">
<i class="bi bi-exclamation-triangle-fill text-warning fs-3 me-3"></i>
<div class="flex-grow-1">
<h5 class="alert-heading mb-2 text-warning">Duplicates Found</h5>
<p class="mb-2">The following CHS configurations have duplicates in the database:</p>
<div class="bg-black p-3 rounded border border-warning mb-3">
@foreach(ChsModel item in _duplicates)
{
<div class="mb-1">
<span class="badge bg-warning text-dark me-1">C: @item.Cylinders</span>
<span class="badge bg-warning text-dark me-1">H: @item.Heads</span>
<span class="badge bg-warning text-dark">S: @item.Sectors</span>
</div>
}
</div>
<button type="button" class="btn btn-warning" @onclick="ConsolidateDuplicatesAsync">
<i class="bi bi-arrow-down-up"></i> Consolidate Duplicates
</button>
</div>
</div>
</div>
<Button class="btn btn-danger" @onclick="ConsolidateDuplicatesAsync">Consolidate Duplicates</Button>
}
</section>
<BlazorBootstrap.Modal @ref="_consolidateModal" Title="Consolidate duplicates" Size="ModalSize.Small">
<!-- Search and Filter Bar -->
<div class="card bg-dark shadow-sm mb-4 border-secondary">
<div class="card-body">
<div class="row g-3">
<div class="col-md-6">
<div class="input-group">
<span class="input-group-text bg-secondary text-light border-secondary">
<i class="bi bi-search"></i>
</span>
<input type="text"
class="form-control bg-dark text-light border-secondary"
placeholder="Search by cylinders, heads, or sectors..."
@bind="_searchTerm"
@bind:event="oninput" />
</div>
</div>
<div class="col-md-6 text-end">
<span class="badge bg-info text-dark fs-6 py-2 px-3">
<i class="bi bi-database"></i> Total: @FilteredItems.Count() / @_items.Count
</span>
</div>
</div>
</div>
</div>
<!-- Data Table -->
<div class="card bg-dark shadow-sm border-secondary">
<div class="card-header bg-info text-dark">
<h5 class="mb-0">
<i class="bi bi-list-ul"></i> CHS Database
</h5>
</div>
<div class="card-body p-0">
@if(FilteredItems.Any())
{
<div class="table-responsive">
<table class="table table-dark table-hover table-striped mb-0">
<thead class="table-secondary">
<tr>
<th style="width: 80px;">
<i class="bi bi-hash"></i> ID
</th>
<th>
<i class="bi bi-arrow-repeat"></i> Cylinders
</th>
<th>
<i class="bi bi-diagram-3"></i> Heads
</th>
<th>
<i class="bi bi-grid-3x3"></i> Sectors
</th>
</tr>
</thead>
<tbody>
@foreach(Chs item in FilteredItems)
{
<tr>
<td class="align-middle">
<span class="badge bg-info text-dark text-center"
style="min-width: 60px; display: inline-block;">@item.Id</span>
</td>
<td class="align-middle">
<span class="badge bg-primary text-center"
style="min-width: 100px; display: inline-block;">@item.Cylinders.ToString("N0")</span>
</td>
<td class="align-middle">
<span class="badge bg-success text-center"
style="min-width: 100px; display: inline-block;">@item.Heads</span>
</td>
<td class="align-middle">
<span class="badge bg-warning text-dark text-center"
style="min-width: 100px; display: inline-block;">@item.Sectors</span>
</td>
</tr>
}
</tbody>
</table>
</div>
}
else
{
<div class="text-center py-5">
<i class="bi bi-inbox text-secondary" style="font-size: 4rem;"></i>
<h4 class="text-secondary mt-3">No CHS data found</h4>
<p class="text-secondary">@(string.IsNullOrWhiteSpace(_searchTerm) ? "No data available" : "Try adjusting your search criteria")</p>
</div>
}
</div>
</div>
</div>
<BlazorBootstrap.Modal @ref="_consolidateModal"
Title="Consolidate Duplicates"
Size="ModalSize.Small"
IsVerticallyCentered="true">
<BodyTemplate>
<div class="text-danger">Are you sure you want to delete the duplicates?</div>
<div class="text-danger bg-dark p-3 rounded border border-danger">
<i class="bi bi-exclamation-triangle-fill me-2"></i>
Are you sure you want to consolidate and delete duplicate CHS entries? This action cannot be undone.
</div>
</BodyTemplate>
<FooterTemplate>
<button class="btn btn-secondary" @onclick="HideConsolidateModalAsync">Cancel</button>
<button class="btn btn-danger" @onclick="ConfirmConsolidateAsync">Delete</button>
<button type="button" class="btn btn-secondary" @onclick="HideConsolidateModalAsync">
<i class="bi bi-x-circle"></i> Cancel
</button>
<button type="button" class="btn btn-danger" @onclick="ConfirmConsolidateAsync">
<i class="bi bi-trash"></i> Delete Duplicates
</button>
</FooterTemplate>
</BlazorBootstrap.Modal>
</BlazorBootstrap.Modal>

View File

@@ -35,10 +35,26 @@ namespace Aaru.Server.Components.Admin.Pages.Chs;
public partial class View
{
private Modal? _consolidateModal;
List<ChsModel> _duplicates;
bool _initialized;
List<CommonTypes.Metadata.Chs> _items;
private Modal? _consolidateModal;
private List<ChsModel> _duplicates = new();
private bool _initialized;
private List<CommonTypes.Metadata.Chs> _items = new();
private string _searchTerm = string.Empty;
private IEnumerable<CommonTypes.Metadata.Chs> FilteredItems
{
get
{
if(string.IsNullOrWhiteSpace(_searchTerm)) return _items;
return _items.Where(item =>
item.Cylinders.ToString()
.Contains(_searchTerm, StringComparison.OrdinalIgnoreCase) ||
item.Heads.ToString().Contains(_searchTerm, StringComparison.OrdinalIgnoreCase) ||
item.Sectors.ToString().Contains(_searchTerm, StringComparison.OrdinalIgnoreCase) ||
item.Id.ToString().Contains(_searchTerm, StringComparison.OrdinalIgnoreCase));
}
}
/// <inheritdoc />