feat(ui): show CompletedWithErrors as orange and group sub-jobs by status
This commit is contained in:
@@ -63,30 +63,33 @@
|
||||
};
|
||||
|
||||
string RowClass => Job.Status switch {
|
||||
EJobStatus.Completed => "",
|
||||
EJobStatus.Failed => "border-start border-2 border-danger",
|
||||
EJobStatus.Canceled => "",
|
||||
_ => ""
|
||||
EJobStatus.Completed => "",
|
||||
EJobStatus.CompletedWithErrors => "border-start border-2 border-warning",
|
||||
EJobStatus.Failed => "border-start border-2 border-danger",
|
||||
EJobStatus.Canceled => "",
|
||||
_ => ""
|
||||
};
|
||||
|
||||
string DotColor => Job.Status switch {
|
||||
EJobStatus.Queued => "#6c757d",
|
||||
EJobStatus.Running => "#0d6efd",
|
||||
EJobStatus.Waiting => "#0dcaf0",
|
||||
EJobStatus.Completed => "#198754",
|
||||
EJobStatus.Failed => "#dc3545",
|
||||
EJobStatus.Canceled => "#6c757d",
|
||||
_ => "#6c757d"
|
||||
EJobStatus.Queued => "#6c757d",
|
||||
EJobStatus.Running => "#0d6efd",
|
||||
EJobStatus.Waiting => "#0dcaf0",
|
||||
EJobStatus.Completed => "#198754",
|
||||
EJobStatus.CompletedWithErrors => "#fd7e14",
|
||||
EJobStatus.Failed => "#dc3545",
|
||||
EJobStatus.Canceled => "#6c757d",
|
||||
_ => "#6c757d"
|
||||
};
|
||||
|
||||
string StatusColor => Job.Status switch {
|
||||
EJobStatus.Queued => "secondary",
|
||||
EJobStatus.Running => "primary",
|
||||
EJobStatus.Waiting => "info",
|
||||
EJobStatus.Completed => "success",
|
||||
EJobStatus.Failed => "danger",
|
||||
EJobStatus.Canceled => "secondary",
|
||||
_ => "secondary"
|
||||
EJobStatus.Queued => "secondary",
|
||||
EJobStatus.Running => "primary",
|
||||
EJobStatus.Waiting => "info",
|
||||
EJobStatus.Completed => "success",
|
||||
EJobStatus.CompletedWithErrors => "warning",
|
||||
EJobStatus.Failed => "danger",
|
||||
EJobStatus.Canceled => "secondary",
|
||||
_ => "secondary"
|
||||
};
|
||||
|
||||
bool CanCancel => Job.Status is EJobStatus.Queued or EJobStatus.Running or EJobStatus.Waiting;
|
||||
@@ -98,9 +101,9 @@
|
||||
EJobStatus.Queued => now - Job.Created.ToLocalTime(),
|
||||
EJobStatus.Running or EJobStatus.Waiting when Job.Started.HasValue
|
||||
=> now - Job.Started.Value.ToLocalTime(),
|
||||
EJobStatus.Completed or EJobStatus.Failed or EJobStatus.Canceled when Job.Finished.HasValue && Job.Started.HasValue
|
||||
EJobStatus.Completed or EJobStatus.CompletedWithErrors or EJobStatus.Failed or EJobStatus.Canceled when Job.Finished.HasValue && Job.Started.HasValue
|
||||
=> Job.Finished.Value.ToLocalTime() - Job.Started.Value.ToLocalTime(),
|
||||
EJobStatus.Completed or EJobStatus.Failed or EJobStatus.Canceled when Job.Finished.HasValue
|
||||
EJobStatus.Completed or EJobStatus.CompletedWithErrors or EJobStatus.Failed or EJobStatus.Canceled when Job.Finished.HasValue
|
||||
=> Job.Finished.Value.ToLocalTime() - Job.Created.ToLocalTime(),
|
||||
_ => null
|
||||
};
|
||||
|
||||
@@ -15,10 +15,27 @@
|
||||
ExpandedChanged="(bool e) => OnExpanded(root.Id, e)" />
|
||||
|
||||
@if (_expandedParents.Contains(root.Id) && hasFetched && hasChildren) {
|
||||
<JobTree Jobs="children!"
|
||||
Level="@(Level + 1)"
|
||||
FetchChildren="@FetchChildren"
|
||||
EmptyText="" />
|
||||
var groups = children!.GroupBy(j => j.Status).OrderBy(g => (int)g.Key);
|
||||
@foreach (var group in groups) {
|
||||
var groupKey = $"{root.Id}-{(int)group.Key}";
|
||||
var isGroupExpanded = _expandedGroups.Contains(groupKey);
|
||||
<div class="ms-@((Level + 1) * 3)">
|
||||
<div class="small fw-semibold py-1 d-flex align-items-center gap-2 user-select-none"
|
||||
@onclick="() => ToggleGroup(groupKey)" role="button">
|
||||
<i class="bi @(isGroupExpanded ? "bi-chevron-down" : "bi-chevron-right")"></i>
|
||||
<span class="d-inline-block rounded-circle flex-shrink-0"
|
||||
style="width: 8px; height: 8px; background: @(StatusColor(group.Key))"></span>
|
||||
<span>@(StatusLabel(group.Key))</span>
|
||||
<span class="text-muted">@group.Count()</span>
|
||||
</div>
|
||||
@if (isGroupExpanded) {
|
||||
<JobTree Jobs="group.ToList()"
|
||||
Level="@(Level + 2)"
|
||||
FetchChildren="@FetchChildren"
|
||||
EmptyText="" />
|
||||
}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,6 +51,7 @@
|
||||
: Jobs?.OrderBy(j => j.Created).ToList() ?? [];
|
||||
|
||||
readonly HashSet<Guid> _expandedParents = [];
|
||||
readonly HashSet<string> _expandedGroups = [];
|
||||
readonly Dictionary<Guid, List<JobStatusDto>?> _childrenCache = [];
|
||||
|
||||
string? ChildSummary(JobStatusDto job, bool hasFetched, List<JobStatusDto>? children) {
|
||||
@@ -55,6 +73,28 @@
|
||||
return string.Join(" · ", parts);
|
||||
}
|
||||
|
||||
static string StatusColor(EJobStatus status) => status switch {
|
||||
EJobStatus.Queued => "#6c757d",
|
||||
EJobStatus.Running => "#0d6efd",
|
||||
EJobStatus.Waiting => "#0dcaf0",
|
||||
EJobStatus.Completed => "#198754",
|
||||
EJobStatus.CompletedWithErrors => "#fd7e14",
|
||||
EJobStatus.Failed => "#dc3545",
|
||||
EJobStatus.Canceled => "#6c757d",
|
||||
_ => "#6c757d"
|
||||
};
|
||||
|
||||
static string StatusLabel(EJobStatus status) => status switch {
|
||||
EJobStatus.Completed => "Succeeded",
|
||||
EJobStatus.CompletedWithErrors => "Completed with errors",
|
||||
EJobStatus.Failed => "Failed",
|
||||
EJobStatus.Canceled => "Canceled",
|
||||
EJobStatus.Queued => "Queued",
|
||||
EJobStatus.Running => "Running",
|
||||
EJobStatus.Waiting => "Waiting",
|
||||
_ => status.ToString()
|
||||
};
|
||||
|
||||
async Task OnExpanded(Guid id, bool expanded) {
|
||||
if (expanded) {
|
||||
_expandedParents.Add(id);
|
||||
@@ -65,4 +105,9 @@
|
||||
_expandedParents.Remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
void ToggleGroup(string groupKey) {
|
||||
if (!_expandedGroups.Remove(groupKey))
|
||||
_expandedGroups.Add(groupKey);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user