Files
DiunaBI/DiunaBI.UI.Shared/Pages/Jobs/Details.razor
Michał Zieliński c7d9acead0
Some checks failed
Build Docker Images / test (map[name:Morska plugin_project:DiunaBI.Plugins.Morska]) (push) Failing after 1m18s
Build Docker Images / test (map[name:PedrolloPL plugin_project:DiunaBI.Plugins.PedrolloPL]) (push) Failing after 1m18s
Build Docker Images / build-and-push (map[image_suffix:morska name:Morska plugin_project:DiunaBI.Plugins.Morska]) (push) Failing after 1m38s
Build Docker Images / build-and-push (map[image_suffix:pedrollopl name:PedrolloPL plugin_project:DiunaBI.Plugins.PedrolloPL]) (push) Failing after 1m37s
UI refactor (structure cleanup)
2025-12-05 09:51:04 +01:00

271 lines
9.4 KiB
Plaintext

@page "/jobs/{id:guid}"
@using DiunaBI.UI.Shared.Services
@using DiunaBI.Domain.Entities
@using MudBlazor
@inject JobService JobService
@inject EntityChangeHubService HubService
@inject NavigationManager NavigationManager
@inject ISnackbar Snackbar
@implements IDisposable
<MudCard>
<MudCardHeader>
<CardHeaderContent>
<MudText Typo="Typo.h5">Job Details</MudText>
</CardHeaderContent>
<CardHeaderActions>
@if (job != null && job.Status == JobStatus.Failed)
{
<MudButton Variant="Variant.Filled"
Color="Color.Warning"
OnClick="RetryJob"
StartIcon="@Icons.Material.Filled.Refresh">
Retry
</MudButton>
}
@if (job != null && (job.Status == JobStatus.Pending || job.Status == JobStatus.Retrying))
{
<MudButton Variant="Variant.Filled"
Color="Color.Error"
OnClick="CancelJob"
StartIcon="@Icons.Material.Filled.Cancel">
Cancel
</MudButton>
}
<MudButton Variant="Variant.Text"
OnClick="GoBack"
StartIcon="@Icons.Material.Filled.ArrowBack">
Back to List
</MudButton>
</CardHeaderActions>
</MudCardHeader>
<MudCardContent>
@if (isLoading)
{
<MudProgressLinear Color="Color.Primary" Indeterminate="true" />
}
else if (job == null)
{
<MudAlert Severity="Severity.Error">Job not found</MudAlert>
}
else
{
<MudGrid>
<MudItem xs="12" md="6">
<MudTextField Value="@job.LayerName"
Label="Layer Name"
Variant="Variant.Outlined"
ReadOnly="true"
FullWidth="true"/>
</MudItem>
<MudItem xs="12" md="6">
<MudTextField Value="@job.PluginName"
Label="Plugin Name"
Variant="Variant.Outlined"
ReadOnly="true"
FullWidth="true"/>
</MudItem>
<MudItem xs="12" md="4">
<MudTextField Value="@job.JobType.ToString()"
Label="Job Type"
Variant="Variant.Outlined"
ReadOnly="true"
FullWidth="true"/>
</MudItem>
<MudItem xs="12" md="4">
<MudTextField Value="@job.Status.ToString()"
Label="Status"
Variant="Variant.Outlined"
ReadOnly="true"
FullWidth="true"
Adornment="Adornment.Start"
AdornmentIcon="@GetStatusIcon(job.Status)"
AdornmentColor="@GetStatusColor(job.Status)"/>
</MudItem>
<MudItem xs="12" md="4">
<MudTextField Value="@job.Priority.ToString()"
Label="Priority"
Variant="Variant.Outlined"
ReadOnly="true"
FullWidth="true"/>
</MudItem>
<MudItem xs="12" md="6">
<MudTextField Value="@job.CreatedAt.ToString("yyyy-MM-dd HH:mm:ss")"
Label="Created At"
Variant="Variant.Outlined"
ReadOnly="true"
FullWidth="true"/>
</MudItem>
<MudItem xs="12" md="6">
<MudTextField Value="@(job.LastAttemptAt?.ToString("yyyy-MM-dd HH:mm:ss") ?? "-")"
Label="Last Attempt At"
Variant="Variant.Outlined"
ReadOnly="true"
FullWidth="true"/>
</MudItem>
<MudItem xs="12" md="6">
<MudTextField Value="@(job.CompletedAt?.ToString("yyyy-MM-dd HH:mm:ss") ?? "-")"
Label="Completed At"
Variant="Variant.Outlined"
ReadOnly="true"
FullWidth="true"/>
</MudItem>
<MudItem xs="12" md="6">
<MudTextField Value="@($"{job.RetryCount} / {job.MaxRetries}")"
Label="Retry Count / Max Retries"
Variant="Variant.Outlined"
ReadOnly="true"
FullWidth="true"/>
</MudItem>
@if (!string.IsNullOrEmpty(job.LastError))
{
<MudItem xs="12">
<MudTextField Value="@job.LastError"
Label="Last Error"
Variant="Variant.Outlined"
ReadOnly="true"
FullWidth="true"
Lines="5"
AdornmentIcon="@Icons.Material.Filled.Error"
AdornmentColor="Color.Error"/>
</MudItem>
}
<MudItem xs="12">
<MudDivider Class="my-4"/>
</MudItem>
<MudItem xs="12">
<MudButton Variant="Variant.Outlined"
Color="Color.Primary"
OnClick="@(() => NavigationManager.NavigateTo($"/layers/{job.LayerId}"))"
StartIcon="@Icons.Material.Filled.Layers">
View Layer Details
</MudButton>
</MudItem>
</MudGrid>
}
</MudCardContent>
</MudCard>
@code {
[Parameter]
public Guid Id { get; set; }
private QueueJob? job;
private bool isLoading = true;
protected override async Task OnInitializedAsync()
{
await LoadJob();
// Subscribe to SignalR entity changes
HubService.EntityChanged += OnEntityChanged;
}
private async void OnEntityChanged(string module, string id, string operation)
{
// Only react if it's a QueueJobs change for this specific job
if (module.Equals("QueueJobs", StringComparison.OrdinalIgnoreCase) &&
Guid.TryParse(id, out var jobId) && jobId == Id)
{
Console.WriteLine($"📨 Job {jobId} changed, refreshing detail page");
await InvokeAsync(async () =>
{
await LoadJob();
StateHasChanged();
});
}
}
private async Task LoadJob()
{
isLoading = true;
try
{
job = await JobService.GetJobByIdAsync(Id);
}
catch (Exception ex)
{
Console.WriteLine($"Loading job failed: {ex.Message}");
Snackbar.Add("Failed to load job", Severity.Error);
}
finally
{
isLoading = false;
}
}
private async Task RetryJob()
{
if (job == null) return;
var success = await JobService.RetryJobAsync(job.Id);
if (success)
{
Snackbar.Add("Job reset to Pending status", Severity.Success);
await LoadJob();
}
else
{
Snackbar.Add("Failed to retry job", Severity.Error);
}
}
private async Task CancelJob()
{
if (job == null) return;
var success = await JobService.CancelJobAsync(job.Id);
if (success)
{
Snackbar.Add("Job cancelled", Severity.Success);
await LoadJob();
}
else
{
Snackbar.Add("Failed to cancel job", Severity.Error);
}
}
private void GoBack()
{
NavigationManager.NavigateTo("/jobs");
}
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 string GetStatusIcon(JobStatus status)
{
return status switch
{
JobStatus.Pending => Icons.Material.Filled.HourglassEmpty,
JobStatus.Running => Icons.Material.Filled.PlayArrow,
JobStatus.Completed => Icons.Material.Filled.CheckCircle,
JobStatus.Failed => Icons.Material.Filled.Error,
JobStatus.Retrying => Icons.Material.Filled.Refresh,
_ => Icons.Material.Filled.Help
};
}
public void Dispose()
{
HubService.EntityChanged -= OnEntityChanged;
}
}