diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Deployments.razor b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Deployments.razor
index 69fd15ba..01df5ffd 100644
--- a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Deployments.razor
+++ b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Deployments.razor
@@ -57,7 +57,8 @@
@Short(d.DeploymentId) |
@DisplayText.Abbreviate(d.RevisionHash, 12) |
- @d.Status |
+ @* #601: Sealed + a reason = sealed with a degraded address-space apply on some node(s). *@
+ @(d.Status == DeploymentStatus.Sealed && !string.IsNullOrEmpty(d.FailureReason) ? "Sealed (degraded)" : d.Status.ToString()) |
@d.CreatedBy |
@d.CreatedAtUtc.ToString("u") |
@(d.SealedAtUtc?.ToString("u") ?? "—") |
@@ -77,7 +78,8 @@
DeploymentStatus Status,
string CreatedBy,
DateTime CreatedAtUtc,
- DateTime? SealedAtUtc);
+ DateTime? SealedAtUtc,
+ string? FailureReason);
private IReadOnlyList _deployments = Array.Empty();
private bool _busy;
@@ -102,7 +104,8 @@
d.Status,
d.CreatedBy,
d.CreatedAtUtc,
- d.SealedAtUtc))
+ d.SealedAtUtc,
+ d.FailureReason))
.Take(50)
.ToListAsync();
diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Fleet.razor b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Fleet.razor
index 6e91c695..76cd5db1 100644
--- a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Fleet.razor
+++ b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Pages/Fleet.razor
@@ -88,7 +88,7 @@ else
@role
}
- @StatusLabel(r.Status) |
+ @StatusLabel(r.Status, r.FailureReason) |
@(r.AppliedAtUtc?.ToString("u") ?? "—") |
@(r.StartedAtUtc?.ToString("u") ?? "—") |
@(string.IsNullOrEmpty(r.FailureReason) ? "" : DisplayText.Abbreviate(r.FailureReason, 80)) |
@@ -184,15 +184,22 @@ else
}
}
- private static string StatusChipClass(NodeDeploymentStatus? status) => status switch
- {
- NodeDeploymentStatus.Applied => "chip-ok",
- NodeDeploymentStatus.Applying => "chip-caution",
- NodeDeploymentStatus.Failed => "chip-alert",
- _ => "chip-idle",
- };
+ // #601 — an Applied row carrying a reason is a DEGRADED apply (the node runs the revision but its address
+ // space may be partial); it must not render as the same green chip as a clean apply.
+ private static bool IsDegraded(NodeDeploymentStatus? status, string? failureReason) =>
+ status is { } s && ZB.MOM.WW.OtOpcUa.ControlPlane.Coordinators.ConfigPublishCoordinator.IsDegraded(s, failureReason);
- private static string StatusLabel(NodeDeploymentStatus? status) => status?.ToString() ?? "waiting";
+ private static string StatusChipClass(NodeDeploymentStatus? status, string? failureReason) =>
+ IsDegraded(status, failureReason) ? "chip-caution" : status switch
+ {
+ NodeDeploymentStatus.Applied => "chip-ok",
+ NodeDeploymentStatus.Applying => "chip-caution",
+ NodeDeploymentStatus.Failed => "chip-alert",
+ _ => "chip-idle",
+ };
+
+ private static string StatusLabel(NodeDeploymentStatus? status, string? failureReason) =>
+ IsDegraded(status, failureReason) ? "Applied (degraded)" : status?.ToString() ?? "waiting";
public async ValueTask DisposeAsync()
{