2025-12-03 13:33:38 +01:00
|
|
|
using DiunaBI.UI.Shared.Services;
|
|
|
|
|
using Microsoft.AspNetCore.Components;
|
|
|
|
|
using Microsoft.AspNetCore.Components.Web;
|
|
|
|
|
using DiunaBI.Application.DTOModels.Common;
|
|
|
|
|
using DiunaBI.Domain.Entities;
|
|
|
|
|
using MudBlazor;
|
|
|
|
|
using Microsoft.JSInterop;
|
|
|
|
|
|
2025-12-05 09:51:04 +01:00
|
|
|
namespace DiunaBI.UI.Shared.Pages.Jobs;
|
2025-12-03 13:33:38 +01:00
|
|
|
|
2025-12-05 09:51:04 +01:00
|
|
|
public partial class Index : ComponentBase, IDisposable
|
2025-12-03 13:33:38 +01:00
|
|
|
{
|
|
|
|
|
[Inject] private JobService JobService { get; set; } = default!;
|
2025-12-04 22:20:00 +01:00
|
|
|
[Inject] private EntityChangeHubService HubService { get; set; } = default!;
|
2025-12-03 13:33:38 +01:00
|
|
|
[Inject] private ISnackbar Snackbar { get; set; } = default!;
|
|
|
|
|
[Inject] private NavigationManager NavigationManager { get; set; } = default!;
|
|
|
|
|
[Inject] private IJSRuntime JSRuntime { get; set; } = default!;
|
2025-12-08 21:42:10 +01:00
|
|
|
[Inject] private DateTimeHelper DateTimeHelper { get; set; } = default!;
|
2025-12-03 13:33:38 +01:00
|
|
|
|
|
|
|
|
private PagedResult<QueueJob> jobs = new();
|
|
|
|
|
private bool isLoading = false;
|
|
|
|
|
private int currentPage = 1;
|
|
|
|
|
private int pageSize = 50;
|
2025-12-08 21:28:24 +01:00
|
|
|
private IEnumerable<JobStatus> selectedStatuses = new HashSet<JobStatus>();
|
2025-12-03 13:33:38 +01:00
|
|
|
private JobType? selectedJobType = null;
|
|
|
|
|
|
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
|
|
|
{
|
2025-12-08 21:42:10 +01:00
|
|
|
await DateTimeHelper.InitializeAsync();
|
2025-12-03 13:33:38 +01:00
|
|
|
await LoadJobs();
|
2025-12-04 22:20:00 +01:00
|
|
|
|
|
|
|
|
// Subscribe to SignalR entity changes
|
|
|
|
|
HubService.EntityChanged += OnEntityChanged;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async void OnEntityChanged(string module, string id, string operation)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine($"🔔 JobListComponent.OnEntityChanged called: module={module}, id={id}, operation={operation}");
|
|
|
|
|
|
|
|
|
|
// Only react if it's a QueueJobs change
|
|
|
|
|
if (module.Equals("QueueJobs", StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine($"📨 Job {id} changed, refreshing job list");
|
|
|
|
|
await InvokeAsync(async () =>
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine($"🔄 LoadJobs starting...");
|
|
|
|
|
await LoadJobs();
|
|
|
|
|
Console.WriteLine($"🔄 StateHasChanged calling...");
|
|
|
|
|
StateHasChanged();
|
|
|
|
|
Console.WriteLine($"✅ Job list refresh complete");
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine($"⏭️ Skipping - module '{module}' is not QueueJobs");
|
|
|
|
|
}
|
2025-12-03 13:33:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task LoadJobs()
|
|
|
|
|
{
|
|
|
|
|
isLoading = true;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
2025-12-08 21:28:24 +01:00
|
|
|
var statusList = selectedStatuses?.ToList();
|
|
|
|
|
jobs = await JobService.GetJobsAsync(currentPage, pageSize, statusList, selectedJobType);
|
2025-12-03 13:33:38 +01:00
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine($"Loading jobs failed: {ex.Message}");
|
|
|
|
|
Snackbar.Add("Failed to load jobs", Severity.Error);
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
isLoading = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task OnPageChanged(int page)
|
|
|
|
|
{
|
|
|
|
|
currentPage = page;
|
|
|
|
|
await LoadJobs();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task ClearFilters()
|
|
|
|
|
{
|
2025-12-08 21:28:24 +01:00
|
|
|
selectedStatuses = new HashSet<JobStatus>();
|
2025-12-03 13:33:38 +01:00
|
|
|
selectedJobType = null;
|
|
|
|
|
currentPage = 1;
|
|
|
|
|
await LoadJobs();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-08 21:28:24 +01:00
|
|
|
private async Task OnStatusFilterChanged(IEnumerable<JobStatus> values)
|
|
|
|
|
{
|
|
|
|
|
selectedStatuses = values;
|
|
|
|
|
currentPage = 1;
|
|
|
|
|
await LoadJobs();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task OnJobTypeFilterChanged(JobType? value)
|
|
|
|
|
{
|
|
|
|
|
selectedJobType = value;
|
|
|
|
|
currentPage = 1;
|
|
|
|
|
await LoadJobs();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-03 13:33:38 +01:00
|
|
|
private async Task OnStatusClear()
|
|
|
|
|
{
|
2025-12-08 21:28:24 +01:00
|
|
|
selectedStatuses = new HashSet<JobStatus>();
|
2025-12-03 13:33:38 +01:00
|
|
|
currentPage = 1;
|
|
|
|
|
await LoadJobs();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task OnJobTypeClear()
|
|
|
|
|
{
|
|
|
|
|
selectedJobType = null;
|
|
|
|
|
currentPage = 1;
|
|
|
|
|
await LoadJobs();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnRowClick(QueueJob job)
|
|
|
|
|
{
|
|
|
|
|
NavigationManager.NavigateTo($"/jobs/{job.Id}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task OnRowRightClick(MouseEventArgs e, QueueJob job)
|
|
|
|
|
{
|
|
|
|
|
var url = NavigationManager.ToAbsoluteUri($"/jobs/{job.Id}").ToString();
|
|
|
|
|
await JSRuntime.InvokeVoidAsync("open", url, "_blank");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Color GetStatusColor(JobStatus status)
|
|
|
|
|
{
|
|
|
|
|
return status switch
|
|
|
|
|
{
|
|
|
|
|
JobStatus.Pending => Color.Default,
|
|
|
|
|
JobStatus.Running => Color.Info,
|
|
|
|
|
JobStatus.Completed => Color.Success,
|
|
|
|
|
JobStatus.Failed => Color.Error,
|
|
|
|
|
JobStatus.Retrying => Color.Warning,
|
|
|
|
|
_ => Color.Default
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Color GetJobTypeColor(JobType jobType)
|
|
|
|
|
{
|
|
|
|
|
return jobType switch
|
|
|
|
|
{
|
|
|
|
|
JobType.Import => Color.Primary,
|
|
|
|
|
JobType.Process => Color.Secondary,
|
|
|
|
|
_ => Color.Default
|
|
|
|
|
};
|
|
|
|
|
}
|
2025-12-04 22:20:00 +01:00
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
HubService.EntityChanged -= OnEntityChanged;
|
|
|
|
|
}
|
2025-12-03 13:33:38 +01:00
|
|
|
}
|