refactor(core): reorganize DTOs into Models and ViewModels folders
Move DTOs from ApiContracts to appropriate locations: - SignalR DTOs → ViewModels (renamed Dto→ViewModel suffix) - Pipeline DTOs → Models/Pipelines - UserInfoDto → Models/Auth - DataUpdateDto → Models/Infrastructure
This commit is contained in:
@@ -2,7 +2,6 @@ using System.Security.Claims;
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using JdeScoping.Api.Extensions;
|
using JdeScoping.Api.Extensions;
|
||||||
using JdeScoping.Core.ApiContracts;
|
using JdeScoping.Core.ApiContracts;
|
||||||
using JdeScoping.Core.ApiContracts.Auth;
|
|
||||||
using JdeScoping.Core.Interfaces;
|
using JdeScoping.Core.Interfaces;
|
||||||
using JdeScoping.Core.Models;
|
using JdeScoping.Core.Models;
|
||||||
using JdeScoping.Core.Models.Auth;
|
using JdeScoping.Core.Models.Auth;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using JdeScoping.Core.ApiContracts;
|
using JdeScoping.Core.ApiContracts;
|
||||||
using JdeScoping.Core.ApiContracts.Pipelines;
|
using JdeScoping.Core.Models.Pipelines;
|
||||||
using JdeScoping.Core.Models.Enums;
|
using JdeScoping.Core.Models.Enums;
|
||||||
using JdeScoping.DataSync.Configuration;
|
using JdeScoping.DataSync.Configuration;
|
||||||
using JdeScoping.DataSync.Contracts;
|
using JdeScoping.DataSync.Contracts;
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
using JdeScoping.Core.ApiContracts;
|
||||||
|
using JdeScoping.Core.Models.Infrastructure;
|
||||||
|
using JdeScoping.Core.Interfaces;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace JdeScoping.Api.Controllers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// API endpoints for data refresh/cache sync status.
|
||||||
|
/// </summary>
|
||||||
|
[Route(ApiRoutes.RefreshStatus.Base)]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class RefreshStatusController : ApiControllerBase
|
||||||
|
{
|
||||||
|
private readonly ILotFinderRepository _repository;
|
||||||
|
|
||||||
|
public RefreshStatusController(ILotFinderRepository repository)
|
||||||
|
{
|
||||||
|
_repository = repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets aggregated refresh status records within the specified date range.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="minDT">Start date filter.</param>
|
||||||
|
/// <param name="maxDT">End date filter.</param>
|
||||||
|
/// <param name="ct">Cancellation token.</param>
|
||||||
|
[HttpGet]
|
||||||
|
[ProducesResponseType(typeof(List<DataUpdateDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<ActionResult<List<DataUpdateDto>>> GetRefreshStatus(
|
||||||
|
[FromQuery] DateTime minDT,
|
||||||
|
[FromQuery] DateTime maxDT,
|
||||||
|
CancellationToken ct)
|
||||||
|
{
|
||||||
|
// Get raw data updates from repository
|
||||||
|
var updates = await _repository.GetLastDataUpdatesAsync(ct);
|
||||||
|
|
||||||
|
// Filter by date range
|
||||||
|
var filtered = updates
|
||||||
|
.Where(u => u.StartDt >= minDT && u.StartDt <= maxDT.AddDays(1))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
// Group by StartDt (rounded to minute) to aggregate multiple table updates into single rows
|
||||||
|
var aggregated = filtered
|
||||||
|
.GroupBy(u => new DateTime(u.StartDt.Year, u.StartDt.Month, u.StartDt.Day, u.StartDt.Hour, u.StartDt.Minute, 0))
|
||||||
|
.Select(g => new DataUpdateDto
|
||||||
|
{
|
||||||
|
StartDt = g.Key,
|
||||||
|
EndDt = g.Max(u => u.EndDt),
|
||||||
|
WasSuccessful = g.All(u => u.WasSuccessful),
|
||||||
|
BranchRecords = (int)(g.FirstOrDefault(u => u.TableName == "Branch")?.NumberRecords ?? 0),
|
||||||
|
ProfitCenterRecords = (int)(g.FirstOrDefault(u => u.TableName == "ProfitCenter")?.NumberRecords ?? 0),
|
||||||
|
WorkCenterRecords = (int)(g.FirstOrDefault(u => u.TableName == "WorkCenter")?.NumberRecords ?? 0),
|
||||||
|
OrgHierarchyRecords = (int)(g.FirstOrDefault(u => u.TableName == "OrgHierarchy")?.NumberRecords ?? 0),
|
||||||
|
StatusCodeRecords = (int)(g.FirstOrDefault(u => u.TableName == "StatusCode")?.NumberRecords ?? 0),
|
||||||
|
UserRecords = (int)(g.FirstOrDefault(u => u.TableName == "JdeUser")?.NumberRecords ?? 0),
|
||||||
|
ItemRecords = (int)(g.FirstOrDefault(u => u.TableName == "Item")?.NumberRecords ?? 0),
|
||||||
|
LotRecords = (int)(g.FirstOrDefault(u => u.TableName == "Lot")?.NumberRecords ?? 0),
|
||||||
|
WorkOrderRecords = (int)(g.FirstOrDefault(u => u.TableName.Contains("WorkOrder_"))?.NumberRecords ?? 0),
|
||||||
|
WorkOrderStepRecords = (int)(g.FirstOrDefault(u => u.TableName.Contains("WorkOrderStep"))?.NumberRecords ?? 0),
|
||||||
|
WorkOrderComponentRecords = (int)(g.FirstOrDefault(u => u.TableName.Contains("WorkOrderComponent"))?.NumberRecords ?? 0)
|
||||||
|
})
|
||||||
|
.OrderByDescending(d => d.StartDt)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
return Ok(aggregated);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using JdeScoping.Core.ApiContracts.SignalR;
|
using JdeScoping.Core.ViewModels;
|
||||||
using Microsoft.AspNetCore.SignalR;
|
using Microsoft.AspNetCore.SignalR;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@ namespace JdeScoping.Api.Hubs;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class StatusHub : Hub
|
public class StatusHub : Hub
|
||||||
{
|
{
|
||||||
private static StatusUpdateDto _cachedStatus = new()
|
private static StatusUpdateViewModel _cachedStatus = new()
|
||||||
{
|
{
|
||||||
Message = "Unknown",
|
Message = "Unknown",
|
||||||
Timestamp = DateTime.UtcNow
|
Timestamp = DateTime.UtcNow
|
||||||
@@ -27,7 +27,7 @@ public class StatusHub : Hub
|
|||||||
/// Caches the update and broadcasts to all clients.
|
/// Caches the update and broadcasts to all clients.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="statusUpdate">Status update to broadcast</param>
|
/// <param name="statusUpdate">Status update to broadcast</param>
|
||||||
public async Task SetStatus(StatusUpdateDto statusUpdate)
|
public async Task SetStatus(StatusUpdateViewModel statusUpdate)
|
||||||
{
|
{
|
||||||
_cachedStatus = statusUpdate;
|
_cachedStatus = statusUpdate;
|
||||||
await Clients.All.SendAsync("statusUpdate", statusUpdate);
|
await Clients.All.SendAsync("statusUpdate", statusUpdate);
|
||||||
@@ -38,7 +38,7 @@ public class StatusHub : Hub
|
|||||||
/// Called by clients to get initial cached status on connection.
|
/// Called by clients to get initial cached status on connection.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The most recent status update</returns>
|
/// <returns>The most recent status update</returns>
|
||||||
public StatusUpdateDto GetCachedStatus()
|
public StatusUpdateViewModel GetCachedStatus()
|
||||||
{
|
{
|
||||||
return _cachedStatus;
|
return _cachedStatus;
|
||||||
}
|
}
|
||||||
@@ -47,7 +47,7 @@ public class StatusHub : Hub
|
|||||||
/// Called by controllers/services to broadcast search updates.
|
/// Called by controllers/services to broadcast search updates.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="searchUpdate">Search update to broadcast</param>
|
/// <param name="searchUpdate">Search update to broadcast</param>
|
||||||
public async Task PublishSearchUpdate(SearchUpdateDto searchUpdate)
|
public async Task PublishSearchUpdate(SearchUpdateViewModel searchUpdate)
|
||||||
{
|
{
|
||||||
await Clients.All.SendAsync("searchUpdate", searchUpdate);
|
await Clients.All.SendAsync("searchUpdate", searchUpdate);
|
||||||
_logger.LogDebug("Search update published: ID={Id}, Status={Status}", searchUpdate.Id, searchUpdate.Status);
|
_logger.LogDebug("Search update published: ID={Id}, Status={Status}", searchUpdate.Id, searchUpdate.Status);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using JdeScoping.Api.Hubs;
|
using JdeScoping.Api.Hubs;
|
||||||
using JdeScoping.Core.ApiContracts.SignalR;
|
|
||||||
using JdeScoping.Core.Interfaces;
|
using JdeScoping.Core.Interfaces;
|
||||||
using JdeScoping.Core.Models.Search;
|
using JdeScoping.Core.Models.Search;
|
||||||
|
using JdeScoping.Core.ViewModels;
|
||||||
using Microsoft.AspNetCore.SignalR;
|
using Microsoft.AspNetCore.SignalR;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ public class SearchNotificationService : ISearchNotificationService
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var update = SearchUpdateDto.FromSearch(search);
|
var update = SearchUpdateViewModel.FromSearch(search);
|
||||||
await _hubContext.Clients.All.SendAsync("searchUpdate", update, ct);
|
await _hubContext.Clients.All.SendAsync("searchUpdate", update, ct);
|
||||||
_logger.LogDebug(
|
_logger.LogDebug(
|
||||||
"Search update notification sent: Id={SearchId}, Status={Status}",
|
"Search update notification sent: Id={SearchId}, Status={Status}",
|
||||||
@@ -56,7 +56,7 @@ public class SearchNotificationService : ISearchNotificationService
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var update = StatusUpdateDto.Create(status);
|
var update = StatusUpdateViewModel.Create(status);
|
||||||
await _hubContext.Clients.All.SendAsync("statusUpdate", update, ct);
|
await _hubContext.Clients.All.SendAsync("statusUpdate", update, ct);
|
||||||
_logger.LogDebug("Status notification sent: {Status}", status);
|
_logger.LogDebug("Status notification sent: {Status}", status);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using System.Net.Http.Json;
|
using System.Net.Http.Json;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using JdeScoping.Core.ApiContracts.Auth;
|
using JdeScoping.Core.Models.Auth;
|
||||||
using Microsoft.AspNetCore.Components.Authorization;
|
using Microsoft.AspNetCore.Components.Authorization;
|
||||||
|
|
||||||
namespace JdeScoping.Client.Auth;
|
namespace JdeScoping.Client.Auth;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using JdeScoping.Core.ApiContracts.Auth;
|
using JdeScoping.Core.Models.Auth;
|
||||||
|
|
||||||
namespace JdeScoping.Client.Auth;
|
namespace JdeScoping.Client.Auth;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using JdeScoping.Core.ApiContracts.Auth;
|
using JdeScoping.Core.Models.Auth;
|
||||||
using Microsoft.JSInterop;
|
using Microsoft.JSInterop;
|
||||||
|
|
||||||
namespace JdeScoping.Client.Auth;
|
namespace JdeScoping.Client.Auth;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
@namespace JdeScoping.Client.Components.Admin
|
@namespace JdeScoping.Client.Components.Admin
|
||||||
@using JdeScoping.Core.ApiContracts.Pipelines
|
@using JdeScoping.Core.Models.Pipelines
|
||||||
@using JdeScoping.Core.Models.Enums
|
@using JdeScoping.Core.Models.Enums
|
||||||
|
|
||||||
<RadzenCard class="rz-mb-4">
|
<RadzenCard class="rz-mb-4">
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
@page "/admin/pipeline-viewer"
|
@page "/admin/pipeline-viewer"
|
||||||
@attribute [Authorize]
|
@attribute [Authorize]
|
||||||
@using JdeScoping.Core.ApiContracts
|
@using JdeScoping.Core.ApiContracts
|
||||||
@using JdeScoping.Core.ApiContracts.Pipelines
|
@using JdeScoping.Core.Models.Pipelines
|
||||||
@using JdeScoping.Core.Models.Enums
|
@using JdeScoping.Core.Models.Enums
|
||||||
@inject IPipelineApiClient PipelineApi
|
@inject IPipelineApiClient PipelineApi
|
||||||
|
|
||||||
|
|||||||
@@ -31,31 +31,31 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<RadzenDataGrid Data="@_results" TItem="DataUpdateViewModel" AllowSorting="true" AllowPaging="true" PageSize="20"
|
<RadzenDataGrid Data="@_results" TItem="DataUpdateDto" AllowSorting="true" AllowPaging="true" PageSize="20"
|
||||||
PagerHorizontalAlign="HorizontalAlign.Center" AllowColumnResize="true" Style="text-align: center;">
|
PagerHorizontalAlign="HorizontalAlign.Center" AllowColumnResize="true" Style="text-align: center;">
|
||||||
<Columns>
|
<Columns>
|
||||||
<RadzenDataGridColumn TItem="DataUpdateViewModel" Property="StartDT" Title="Start" Width="160px">
|
<RadzenDataGridColumn TItem="DataUpdateDto" Property="StartDT" Title="Start" Width="160px">
|
||||||
<Template Context="item">
|
<Template Context="item">
|
||||||
@item.StartDt.ToString("MM/dd/yyyy hh:mm tt")
|
@item.StartDt.ToString("MM/dd/yyyy hh:mm tt")
|
||||||
</Template>
|
</Template>
|
||||||
</RadzenDataGridColumn>
|
</RadzenDataGridColumn>
|
||||||
<RadzenDataGridColumn TItem="DataUpdateViewModel" Property="EndDT" Title="End" Width="160px">
|
<RadzenDataGridColumn TItem="DataUpdateDto" Property="EndDT" Title="End" Width="160px">
|
||||||
<Template Context="item">
|
<Template Context="item">
|
||||||
@(item.EndDt?.ToString("MM/dd/yyyy hh:mm tt") ?? "")
|
@(item.EndDt?.ToString("MM/dd/yyyy hh:mm tt") ?? "")
|
||||||
</Template>
|
</Template>
|
||||||
</RadzenDataGridColumn>
|
</RadzenDataGridColumn>
|
||||||
<RadzenDataGridColumn TItem="DataUpdateViewModel" Property="BranchRecords" Title="Branch" Width="80px" TextAlign="TextAlign.Center" />
|
<RadzenDataGridColumn TItem="DataUpdateDto" Property="BranchRecords" Title="Branch" Width="80px" TextAlign="TextAlign.Center" />
|
||||||
<RadzenDataGridColumn TItem="DataUpdateViewModel" Property="ProfitCenterRecords" Title="Profit Center" Width="100px" TextAlign="TextAlign.Center" />
|
<RadzenDataGridColumn TItem="DataUpdateDto" Property="ProfitCenterRecords" Title="Profit Center" Width="100px" TextAlign="TextAlign.Center" />
|
||||||
<RadzenDataGridColumn TItem="DataUpdateViewModel" Property="WorkCenterRecords" Title="Work Center" Width="100px" TextAlign="TextAlign.Center" />
|
<RadzenDataGridColumn TItem="DataUpdateDto" Property="WorkCenterRecords" Title="Work Center" Width="100px" TextAlign="TextAlign.Center" />
|
||||||
<RadzenDataGridColumn TItem="DataUpdateViewModel" Property="OrgHierarchyRecords" Title="Org Hierarchy" Width="100px" TextAlign="TextAlign.Center" />
|
<RadzenDataGridColumn TItem="DataUpdateDto" Property="OrgHierarchyRecords" Title="Org Hierarchy" Width="100px" TextAlign="TextAlign.Center" />
|
||||||
<RadzenDataGridColumn TItem="DataUpdateViewModel" Property="StatusCodeRecords" Title="Status Code" Width="100px" TextAlign="TextAlign.Center" />
|
<RadzenDataGridColumn TItem="DataUpdateDto" Property="StatusCodeRecords" Title="Status Code" Width="100px" TextAlign="TextAlign.Center" />
|
||||||
<RadzenDataGridColumn TItem="DataUpdateViewModel" Property="UserRecords" Title="User" Width="80px" TextAlign="TextAlign.Center" />
|
<RadzenDataGridColumn TItem="DataUpdateDto" Property="UserRecords" Title="User" Width="80px" TextAlign="TextAlign.Center" />
|
||||||
<RadzenDataGridColumn TItem="DataUpdateViewModel" Property="ItemRecords" Title="Item" Width="80px" TextAlign="TextAlign.Center" />
|
<RadzenDataGridColumn TItem="DataUpdateDto" Property="ItemRecords" Title="Item" Width="80px" TextAlign="TextAlign.Center" />
|
||||||
<RadzenDataGridColumn TItem="DataUpdateViewModel" Property="LotRecords" Title="Lot" Width="80px" TextAlign="TextAlign.Center" />
|
<RadzenDataGridColumn TItem="DataUpdateDto" Property="LotRecords" Title="Lot" Width="80px" TextAlign="TextAlign.Center" />
|
||||||
<RadzenDataGridColumn TItem="DataUpdateViewModel" Property="WorkOrderRecords" Title="Work Order" Width="100px" TextAlign="TextAlign.Center" />
|
<RadzenDataGridColumn TItem="DataUpdateDto" Property="WorkOrderRecords" Title="Work Order" Width="100px" TextAlign="TextAlign.Center" />
|
||||||
<RadzenDataGridColumn TItem="DataUpdateViewModel" Property="WorkOrderStepRecords" Title="WO Step" Width="90px" TextAlign="TextAlign.Center" />
|
<RadzenDataGridColumn TItem="DataUpdateDto" Property="WorkOrderStepRecords" Title="WO Step" Width="90px" TextAlign="TextAlign.Center" />
|
||||||
<RadzenDataGridColumn TItem="DataUpdateViewModel" Property="WorkOrderComponentRecords" Title="WO Component" Width="110px" TextAlign="TextAlign.Center" />
|
<RadzenDataGridColumn TItem="DataUpdateDto" Property="WorkOrderComponentRecords" Title="WO Component" Width="110px" TextAlign="TextAlign.Center" />
|
||||||
<RadzenDataGridColumn TItem="DataUpdateViewModel" Property="WasSuccessful" Title="Was Successful?" Width="120px" TextAlign="TextAlign.Center">
|
<RadzenDataGridColumn TItem="DataUpdateDto" Property="WasSuccessful" Title="Was Successful?" Width="120px" TextAlign="TextAlign.Center">
|
||||||
<Template Context="item">
|
<Template Context="item">
|
||||||
@if (item.WasSuccessful)
|
@if (item.WasSuccessful)
|
||||||
{
|
{
|
||||||
@@ -72,7 +72,7 @@ else
|
|||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private List<DataUpdateViewModel> _results = [];
|
private List<DataUpdateDto> _results = [];
|
||||||
private bool _isLoading = true;
|
private bool _isLoading = true;
|
||||||
|
|
||||||
// Default to last 7 days
|
// Default to last 7 days
|
||||||
|
|||||||
@@ -315,7 +315,7 @@ else
|
|||||||
await HubConnection.StartAsync();
|
await HubConnection.StartAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleSearchUpdate(SearchUpdateDto update)
|
private void HandleSearchUpdate(SearchUpdateViewModel update)
|
||||||
{
|
{
|
||||||
if (update.Id == _search.Id)
|
if (update.Id == _search.Id)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ else
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleSearchUpdate(SearchUpdateDto update)
|
private void HandleSearchUpdate(SearchUpdateViewModel update)
|
||||||
{
|
{
|
||||||
InvokeAsync(() =>
|
InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
@@ -162,7 +162,7 @@ else
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleStatusUpdate(StatusUpdateDto update)
|
private void HandleStatusUpdate(StatusUpdateViewModel update)
|
||||||
{
|
{
|
||||||
InvokeAsync(() =>
|
InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ else
|
|||||||
await HubConnection.StartAsync();
|
await HubConnection.StartAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleSearchUpdate(SearchUpdateDto update)
|
private void HandleSearchUpdate(SearchUpdateViewModel update)
|
||||||
{
|
{
|
||||||
InvokeAsync(() =>
|
InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using JdeScoping.Core.ApiContracts;
|
using JdeScoping.Core.ApiContracts;
|
||||||
using JdeScoping.Core.ApiContracts.Auth;
|
|
||||||
using JdeScoping.Core.ApiContracts.Results;
|
using JdeScoping.Core.ApiContracts.Results;
|
||||||
using JdeScoping.Core.Models.Auth;
|
using JdeScoping.Core.Models.Auth;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using JdeScoping.Core.ApiContracts.SignalR;
|
using JdeScoping.Core.ViewModels;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using Microsoft.AspNetCore.SignalR.Client;
|
using Microsoft.AspNetCore.SignalR.Client;
|
||||||
|
|
||||||
@@ -13,8 +13,8 @@ public class HubConnectionService : IHubConnectionService, IAsyncDisposable
|
|||||||
private readonly NavigationManager _navigationManager;
|
private readonly NavigationManager _navigationManager;
|
||||||
private HubConnection? _hubConnection;
|
private HubConnection? _hubConnection;
|
||||||
|
|
||||||
public event Action<SearchUpdateDto>? OnSearchUpdate;
|
public event Action<SearchUpdateViewModel>? OnSearchUpdate;
|
||||||
public event Action<StatusUpdateDto>? OnStatusUpdate;
|
public event Action<StatusUpdateViewModel>? OnStatusUpdate;
|
||||||
|
|
||||||
public bool IsConnected => _hubConnection?.State == HubConnectionState.Connected;
|
public bool IsConnected => _hubConnection?.State == HubConnectionState.Connected;
|
||||||
|
|
||||||
@@ -43,12 +43,12 @@ public class HubConnectionService : IHubConnectionService, IAsyncDisposable
|
|||||||
])
|
])
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
_hubConnection.On<SearchUpdateDto>("searchUpdate", update =>
|
_hubConnection.On<SearchUpdateViewModel>("searchUpdate", update =>
|
||||||
{
|
{
|
||||||
OnSearchUpdate?.Invoke(update);
|
OnSearchUpdate?.Invoke(update);
|
||||||
});
|
});
|
||||||
|
|
||||||
_hubConnection.On<StatusUpdateDto>("statusUpdate", update =>
|
_hubConnection.On<StatusUpdateViewModel>("statusUpdate", update =>
|
||||||
{
|
{
|
||||||
OnStatusUpdate?.Invoke(update);
|
OnStatusUpdate?.Invoke(update);
|
||||||
});
|
});
|
||||||
@@ -92,7 +92,7 @@ public class HubConnectionService : IHubConnectionService, IAsyncDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<StatusUpdateDto?> GetCachedStatusAsync()
|
public async Task<StatusUpdateViewModel?> GetCachedStatusAsync()
|
||||||
{
|
{
|
||||||
if (_hubConnection == null || _hubConnection.State != HubConnectionState.Connected)
|
if (_hubConnection == null || _hubConnection.State != HubConnectionState.Connected)
|
||||||
{
|
{
|
||||||
@@ -101,7 +101,7 @@ public class HubConnectionService : IHubConnectionService, IAsyncDisposable
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return await _hubConnection.InvokeAsync<StatusUpdateDto>("GetCachedStatus");
|
return await _hubConnection.InvokeAsync<StatusUpdateViewModel>("GetCachedStatus");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using JdeScoping.Core.ApiContracts.SignalR;
|
using JdeScoping.Core.ViewModels;
|
||||||
|
|
||||||
namespace JdeScoping.Client.Services;
|
namespace JdeScoping.Client.Services;
|
||||||
|
|
||||||
@@ -10,12 +10,12 @@ public interface IHubConnectionService
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event fired when a search update is received.
|
/// Event fired when a search update is received.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event Action<SearchUpdateDto>? OnSearchUpdate;
|
event Action<SearchUpdateViewModel>? OnSearchUpdate;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event fired when a processor status update is received.
|
/// Event fired when a processor status update is received.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event Action<StatusUpdateDto>? OnStatusUpdate;
|
event Action<StatusUpdateViewModel>? OnStatusUpdate;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Starts the SignalR connection.
|
/// Starts the SignalR connection.
|
||||||
@@ -30,7 +30,7 @@ public interface IHubConnectionService
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the cached processor status from the server.
|
/// Gets the cached processor status from the server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Task<StatusUpdateDto?> GetCachedStatusAsync();
|
Task<StatusUpdateViewModel?> GetCachedStatusAsync();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current connection state.
|
/// Gets the current connection state.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using JdeScoping.Client.Models;
|
using JdeScoping.Core.Models.Infrastructure;
|
||||||
|
|
||||||
namespace JdeScoping.Client.Services;
|
namespace JdeScoping.Client.Services;
|
||||||
|
|
||||||
@@ -10,5 +10,5 @@ public interface IRefreshStatusService
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets refresh status records within the specified date range.
|
/// Gets refresh status records within the specified date range.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Task<List<DataUpdateViewModel>> GetRefreshStatusAsync(DateTime minDt, DateTime maxDt);
|
Task<List<DataUpdateDto>> GetRefreshStatusAsync(DateTime minDt, DateTime maxDt);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using JdeScoping.Core.ApiContracts;
|
using JdeScoping.Core.ApiContracts;
|
||||||
using JdeScoping.Core.ApiContracts.Pipelines;
|
using JdeScoping.Core.Models.Pipelines;
|
||||||
using JdeScoping.Core.ApiContracts.Results;
|
using JdeScoping.Core.ApiContracts.Results;
|
||||||
|
|
||||||
namespace JdeScoping.Client.Services;
|
namespace JdeScoping.Client.Services;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using System.Net.Http.Json;
|
using System.Net.Http.Json;
|
||||||
using JdeScoping.Client.Models;
|
using JdeScoping.Core.Models.Infrastructure;
|
||||||
|
|
||||||
namespace JdeScoping.Client.Services;
|
namespace JdeScoping.Client.Services;
|
||||||
|
|
||||||
@@ -16,13 +16,13 @@ public class RefreshStatusService : IRefreshStatusService
|
|||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<DataUpdateViewModel>> GetRefreshStatusAsync(DateTime minDt, DateTime maxDt)
|
public async Task<List<DataUpdateDto>> GetRefreshStatusAsync(DateTime minDt, DateTime maxDt)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var minDtStr = minDt.ToString("yyyy-MM-dd");
|
var minDtStr = minDt.ToString("yyyy-MM-dd");
|
||||||
var maxDtStr = maxDt.ToString("yyyy-MM-dd");
|
var maxDtStr = maxDt.ToString("yyyy-MM-dd");
|
||||||
var result = await _httpClient.GetFromJsonAsync<List<DataUpdateViewModel>>(
|
var result = await _httpClient.GetFromJsonAsync<List<DataUpdateDto>>(
|
||||||
$"api/refresh-status?minDT={minDtStr}&maxDT={maxDtStr}");
|
$"api/refresh-status?minDT={minDtStr}&maxDT={maxDtStr}");
|
||||||
return result ?? [];
|
return result ?? [];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,9 @@
|
|||||||
@using JdeScoping.Client.Models
|
@using JdeScoping.Client.Models
|
||||||
@using JdeScoping.Client.Pages
|
@using JdeScoping.Client.Pages
|
||||||
@using JdeScoping.Client.Services
|
@using JdeScoping.Client.Services
|
||||||
@using JdeScoping.Core.ApiContracts.Auth
|
@using JdeScoping.Core.ApiContracts
|
||||||
@using JdeScoping.Core.ApiContracts.SignalR
|
@using JdeScoping.Core.Models.Auth
|
||||||
|
@using JdeScoping.Core.Models.Infrastructure
|
||||||
|
@using JdeScoping.Core.Models.Pipelines
|
||||||
@using JdeScoping.Core.ViewModels
|
@using JdeScoping.Core.ViewModels
|
||||||
@using ClientSearchViewModel = JdeScoping.Client.Models.SearchViewModel
|
@using ClientSearchViewModel = JdeScoping.Client.Models.SearchViewModel
|
||||||
|
|||||||
@@ -122,6 +122,19 @@ public static class ApiRoutes
|
|||||||
public const string UploadPartOperations = "api/fileio/partoperations/upload";
|
public const string UploadPartOperations = "api/fileio/partoperations/upload";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Routes for data refresh status API endpoints.
|
||||||
|
/// </summary>
|
||||||
|
public static class RefreshStatus
|
||||||
|
{
|
||||||
|
/// <summary>Base route for refresh status endpoints.</summary>
|
||||||
|
public const string Base = "api/refresh-status";
|
||||||
|
|
||||||
|
/// <summary>Builds the route to get refresh status with date range.</summary>
|
||||||
|
public static string Get(DateTime minDt, DateTime maxDt) =>
|
||||||
|
$"api/refresh-status?minDT={minDt:yyyy-MM-dd}&maxDT={maxDt:yyyy-MM-dd}";
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Routes for pipeline configuration API endpoints.
|
/// Routes for pipeline configuration API endpoints.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using JdeScoping.Core.ApiContracts.Auth;
|
|
||||||
using JdeScoping.Core.ApiContracts.Results;
|
using JdeScoping.Core.ApiContracts.Results;
|
||||||
using JdeScoping.Core.Models.Auth;
|
using JdeScoping.Core.Models.Auth;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using JdeScoping.Core.ApiContracts.Pipelines;
|
using JdeScoping.Core.Models.Pipelines;
|
||||||
using JdeScoping.Core.ApiContracts.Results;
|
using JdeScoping.Core.ApiContracts.Results;
|
||||||
|
|
||||||
namespace JdeScoping.Core.ApiContracts;
|
namespace JdeScoping.Core.ApiContracts;
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
using JdeScoping.Core.ApiContracts.Auth;
|
|
||||||
|
|
||||||
namespace JdeScoping.Core.Models.Auth;
|
namespace JdeScoping.Core.Models.Auth;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
+1
-3
@@ -1,6 +1,4 @@
|
|||||||
using JdeScoping.Core.Models;
|
namespace JdeScoping.Core.Models.Auth;
|
||||||
|
|
||||||
namespace JdeScoping.Core.ApiContracts.Auth;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// API response DTO for authenticated user information.
|
/// API response DTO for authenticated user information.
|
||||||
+4
-3
@@ -1,9 +1,10 @@
|
|||||||
namespace JdeScoping.Client.Models;
|
namespace JdeScoping.Core.Models.Infrastructure;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// View model for data refresh/sync status display.
|
/// DTO for data refresh/sync status display.
|
||||||
|
/// Aggregates record counts from multiple table updates into a single row.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class DataUpdateViewModel
|
public class DataUpdateDto
|
||||||
{
|
{
|
||||||
public DateTime StartDt { get; set; }
|
public DateTime StartDt { get; set; }
|
||||||
public DateTime? EndDt { get; set; }
|
public DateTime? EndDt { get; set; }
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
namespace JdeScoping.Core.ApiContracts.Pipelines;
|
namespace JdeScoping.Core.Models.Pipelines;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Pipeline configuration DTO for display.
|
/// Pipeline configuration DTO for display.
|
||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
namespace JdeScoping.Core.ApiContracts.Pipelines;
|
namespace JdeScoping.Core.Models.Pipelines;
|
||||||
|
|
||||||
using Models.Enums;
|
using JdeScoping.Core.Models.Enums;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Pipeline execution history.
|
/// Pipeline execution history.
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
namespace JdeScoping.Core.ApiContracts.Pipelines;
|
namespace JdeScoping.Core.Models.Pipelines;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Response containing list of available pipeline names.
|
/// Response containing list of available pipeline names.
|
||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
namespace JdeScoping.Core.ApiContracts.Pipelines;
|
namespace JdeScoping.Core.Models.Pipelines;
|
||||||
|
|
||||||
using Models.Enums;
|
using JdeScoping.Core.Models.Enums;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Pipeline schedule status for each update type.
|
/// Pipeline schedule status for each update type.
|
||||||
+6
-6
@@ -1,11 +1,11 @@
|
|||||||
using JdeScoping.Core.Models.Search;
|
using JdeScoping.Core.Models.Search;
|
||||||
|
|
||||||
namespace JdeScoping.Core.ApiContracts.SignalR;
|
namespace JdeScoping.Core.ViewModels;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SignalR message DTO for search status updates.
|
/// SignalR message view model for search status updates.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public record SearchUpdateDto
|
public record SearchUpdateViewModel
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Search PK ID.
|
/// Search PK ID.
|
||||||
@@ -43,11 +43,11 @@ public record SearchUpdateDto
|
|||||||
public DateTime? EndDt { get; init; }
|
public DateTime? EndDt { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a SearchUpdateDto from a Search entity.
|
/// Creates a SearchUpdateViewModel from a Search entity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="search">The Search entity to convert.</param>
|
/// <param name="search">The Search entity to convert.</param>
|
||||||
/// <returns>A new SearchUpdateDto instance.</returns>
|
/// <returns>A new SearchUpdateViewModel instance.</returns>
|
||||||
public static SearchUpdateDto FromSearch(Search search) => new()
|
public static SearchUpdateViewModel FromSearch(Search search) => new()
|
||||||
{
|
{
|
||||||
Id = search.Id,
|
Id = search.Id,
|
||||||
Name = search.Name,
|
Name = search.Name,
|
||||||
+6
-6
@@ -1,9 +1,9 @@
|
|||||||
namespace JdeScoping.Core.ApiContracts.SignalR;
|
namespace JdeScoping.Core.ViewModels;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SignalR message DTO for processor status updates.
|
/// SignalR message view model for processor status updates.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public record StatusUpdateDto
|
public record StatusUpdateViewModel
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Status message to display.
|
/// Status message to display.
|
||||||
@@ -16,11 +16,11 @@ public record StatusUpdateDto
|
|||||||
public DateTime? Timestamp { get; init; }
|
public DateTime? Timestamp { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a StatusUpdateDto with the current timestamp.
|
/// Creates a StatusUpdateViewModel with the current timestamp.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="message">Status message.</param>
|
/// <param name="message">Status message.</param>
|
||||||
/// <returns>A new StatusUpdateDto instance.</returns>
|
/// <returns>A new StatusUpdateViewModel instance.</returns>
|
||||||
public static StatusUpdateDto Create(string message) => new()
|
public static StatusUpdateViewModel Create(string message) => new()
|
||||||
{
|
{
|
||||||
Message = message,
|
Message = message,
|
||||||
Timestamp = DateTime.UtcNow
|
Timestamp = DateTime.UtcNow
|
||||||
@@ -4,7 +4,6 @@ using System.Security.Cryptography;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using JdeScoping.Api.Controllers;
|
using JdeScoping.Api.Controllers;
|
||||||
using JdeScoping.Core.ApiContracts.Auth;
|
|
||||||
using JdeScoping.Core.Interfaces;
|
using JdeScoping.Core.Interfaces;
|
||||||
using JdeScoping.Core.Models;
|
using JdeScoping.Core.Models;
|
||||||
using JdeScoping.Core.Models.Auth;
|
using JdeScoping.Core.Models.Auth;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using JdeScoping.Api.Hubs;
|
using JdeScoping.Api.Hubs;
|
||||||
using JdeScoping.Core.ApiContracts.SignalR;
|
using JdeScoping.Core.ViewModels;
|
||||||
using Microsoft.AspNetCore.SignalR;
|
using Microsoft.AspNetCore.SignalR;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using NSubstitute;
|
using NSubstitute;
|
||||||
@@ -33,7 +33,7 @@ public class StatusHubTests
|
|||||||
var clientsProperty = typeof(Hub).GetProperty("Clients");
|
var clientsProperty = typeof(Hub).GetProperty("Clients");
|
||||||
clientsProperty?.SetValue(_hub, hubClients);
|
clientsProperty?.SetValue(_hub, hubClients);
|
||||||
|
|
||||||
var statusUpdate = new StatusUpdateDto
|
var statusUpdate = new StatusUpdateViewModel
|
||||||
{
|
{
|
||||||
Message = "Processing",
|
Message = "Processing",
|
||||||
Timestamp = DateTime.UtcNow
|
Timestamp = DateTime.UtcNow
|
||||||
@@ -90,7 +90,7 @@ public class StatusHubTests
|
|||||||
var clientsProperty = typeof(Hub).GetProperty("Clients");
|
var clientsProperty = typeof(Hub).GetProperty("Clients");
|
||||||
clientsProperty?.SetValue(_hub, hubClients);
|
clientsProperty?.SetValue(_hub, hubClients);
|
||||||
|
|
||||||
var searchUpdate = new SearchUpdateDto
|
var searchUpdate = new SearchUpdateViewModel
|
||||||
{
|
{
|
||||||
Id = 42,
|
Id = 42,
|
||||||
UserName = "testuser",
|
UserName = "testuser",
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using System.Net;
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using JdeScoping.Client.Services;
|
using JdeScoping.Client.Services;
|
||||||
using JdeScoping.Core.ApiContracts;
|
using JdeScoping.Core.ApiContracts;
|
||||||
using JdeScoping.Core.ApiContracts.Auth;
|
|
||||||
using JdeScoping.Core.ApiContracts.Results;
|
using JdeScoping.Core.ApiContracts.Results;
|
||||||
using JdeScoping.Core.Models.Auth;
|
using JdeScoping.Core.Models.Auth;
|
||||||
using RichardSzalay.MockHttp;
|
using RichardSzalay.MockHttp;
|
||||||
|
|||||||
Reference in New Issue
Block a user