b08f5418ec
- Replace ISearchService injection with ISearchApiClient - Add @using for JdeScoping.Core.ApiContracts and JdeScoping.Client.Extensions - Update LoadSearchesAsync to use ApiResult<T>.Switch() pattern - Add _errorMessage field for error state - Display RadzenAlert for error conditions - Use ToClientList() extension method to convert Core->Client view models
159 lines
5.7 KiB
Plaintext
159 lines
5.7 KiB
Plaintext
@page "/"
|
|
@page "/searches"
|
|
@attribute [Authorize]
|
|
@using JdeScoping.Core.ApiContracts
|
|
@using JdeScoping.Client.Extensions
|
|
@inject ISearchApiClient SearchApi
|
|
@inject IHubConnectionService HubConnection
|
|
@inject NavigationManager NavigationManager
|
|
@implements IDisposable
|
|
|
|
<PageTitle>Searches - JDE Scoping Tool</PageTitle>
|
|
|
|
<RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center" JustifyContent="JustifyContent.SpaceBetween" class="rz-mb-4">
|
|
<RadzenText TextStyle="TextStyle.H4" class="rz-m-0">Searches</RadzenText>
|
|
<RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem">
|
|
<RadzenButton Text="Start New Search" Icon="add" ButtonStyle="ButtonStyle.Primary" Click="@CreateNewSearch" />
|
|
<RadzenButton Text="View Search Queue" Icon="queue" ButtonStyle="ButtonStyle.Light" Click="@ViewQueue" />
|
|
</RadzenStack>
|
|
</RadzenStack>
|
|
|
|
@if (_isLoading)
|
|
{
|
|
<LoadingIndicator Message="Loading searches..." />
|
|
}
|
|
else if (!string.IsNullOrEmpty(_errorMessage))
|
|
{
|
|
<RadzenAlert AlertStyle="AlertStyle.Danger" ShowIcon="true" Variant="Variant.Flat" class="rz-mb-4">
|
|
@_errorMessage
|
|
</RadzenAlert>
|
|
}
|
|
else
|
|
{
|
|
<RadzenDataGrid @ref="_grid" Data="@_searches" TItem="ClientSearchViewModel" AllowSorting="true" AllowPaging="true" PageSize="10"
|
|
PagerHorizontalAlign="HorizontalAlign.Center" AllowColumnResize="true" RowDoubleClick="@OnRowDoubleClick">
|
|
<Columns>
|
|
<RadzenDataGridColumn TItem="ClientSearchViewModel" Property="Name" Title="Name" Width="250px" />
|
|
<RadzenDataGridColumn TItem="ClientSearchViewModel" Property="SubmitDT" Title="Submitted" Width="180px">
|
|
<Template Context="search">
|
|
@(search.SubmitDt?.ToString("MM/dd/yyyy hh:mm:ss tt") ?? "")
|
|
</Template>
|
|
</RadzenDataGridColumn>
|
|
<RadzenDataGridColumn TItem="ClientSearchViewModel" Property="Status" Title="Status" Width="100px">
|
|
<Template Context="search">
|
|
<RadzenBadge BadgeStyle="@GetBadgeStyle(search.Status)" Text="@search.Status" />
|
|
</Template>
|
|
</RadzenDataGridColumn>
|
|
<RadzenDataGridColumn TItem="ClientSearchViewModel" Title="Actions" Width="100px" Sortable="false">
|
|
<Template Context="search">
|
|
<RadzenButton Text="View" Size="ButtonSize.Small" ButtonStyle="ButtonStyle.Info" Click="@(() => ViewSearch(search.Id))" />
|
|
</Template>
|
|
</RadzenDataGridColumn>
|
|
</Columns>
|
|
</RadzenDataGrid>
|
|
}
|
|
|
|
@code {
|
|
private List<ClientSearchViewModel> _searches = [];
|
|
private RadzenDataGrid<ClientSearchViewModel>? _grid;
|
|
private bool _isLoading = true;
|
|
private string? _errorMessage;
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
await LoadSearchesAsync();
|
|
await SetupSignalRAsync();
|
|
}
|
|
|
|
private async Task LoadSearchesAsync()
|
|
{
|
|
_isLoading = true;
|
|
_errorMessage = null;
|
|
try
|
|
{
|
|
var result = await SearchApi.GetUserSearchesAsync();
|
|
result.Switch(
|
|
searches => { _searches = searches.ToClientList(); },
|
|
notFound => { _errorMessage = "No searches found."; _searches = []; },
|
|
validation => { _errorMessage = string.Join("; ", validation.FieldErrors.SelectMany(e => e.Value)); },
|
|
unauthorized => { _errorMessage = "Session expired. Please login again."; },
|
|
forbidden => { _errorMessage = "Access denied."; },
|
|
error => { _errorMessage = error.Message; }
|
|
);
|
|
}
|
|
finally
|
|
{
|
|
_isLoading = false;
|
|
}
|
|
}
|
|
|
|
private async Task SetupSignalRAsync()
|
|
{
|
|
HubConnection.OnSearchUpdate += HandleSearchUpdate;
|
|
await HubConnection.StartAsync();
|
|
}
|
|
|
|
private void HandleSearchUpdate(SearchUpdate update)
|
|
{
|
|
InvokeAsync(() =>
|
|
{
|
|
var existing = _searches.FirstOrDefault(s => s.Id == update.Id);
|
|
if (existing != null)
|
|
{
|
|
existing.Status = update.Status;
|
|
existing.SubmitDt = update.SubmitDt;
|
|
existing.StartDt = update.StartDt;
|
|
existing.EndDt = update.EndDt;
|
|
}
|
|
else
|
|
{
|
|
_searches.Insert(0, new ClientSearchViewModel
|
|
{
|
|
Id = update.Id,
|
|
Name = update.Name,
|
|
UserName = update.UserName,
|
|
Status = update.Status,
|
|
SubmitDt = update.SubmitDt,
|
|
StartDt = update.StartDt,
|
|
EndDt = update.EndDt
|
|
});
|
|
}
|
|
StateHasChanged();
|
|
});
|
|
}
|
|
|
|
private void CreateNewSearch()
|
|
{
|
|
NavigationManager.NavigateTo("/search");
|
|
}
|
|
|
|
private void ViewQueue()
|
|
{
|
|
NavigationManager.NavigateTo("/search/queue");
|
|
}
|
|
|
|
private void ViewSearch(int id)
|
|
{
|
|
NavigationManager.NavigateTo($"/search/{id}");
|
|
}
|
|
|
|
private void OnRowDoubleClick(DataGridRowMouseEventArgs<ClientSearchViewModel> args)
|
|
{
|
|
ViewSearch(args.Data.Id);
|
|
}
|
|
|
|
private static BadgeStyle GetBadgeStyle(string status) => status switch
|
|
{
|
|
"Error" => BadgeStyle.Danger,
|
|
"Ended" => BadgeStyle.Success,
|
|
"Running" => BadgeStyle.Info,
|
|
"Queued" => BadgeStyle.Warning,
|
|
_ => BadgeStyle.Light
|
|
};
|
|
|
|
public void Dispose()
|
|
{
|
|
HubConnection.OnSearchUpdate -= HandleSearchUpdate;
|
|
}
|
|
}
|