feat(ui): enrich DebugView alarm table with severity + condition state + native metadata
This commit is contained in:
@@ -191,9 +191,10 @@
|
||||
<thead class="table-light sticky-top">
|
||||
<tr>
|
||||
<th>Alarm</th>
|
||||
<th>Kind</th>
|
||||
<th>State</th>
|
||||
<th>Sev</th>
|
||||
<th>Level</th>
|
||||
<th>Priority</th>
|
||||
<th>Timestamp</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -201,18 +202,44 @@
|
||||
@foreach (var alarm in FilteredAlarmStates)
|
||||
{
|
||||
<tr class="@GetAlarmRowClass(alarm.State)"
|
||||
title="@(string.IsNullOrEmpty(alarm.Message) ? null : alarm.Message)">
|
||||
title="@BuildAlarmTooltip(alarm)">
|
||||
<td class="small">
|
||||
@alarm.AlarmName
|
||||
@if (!string.IsNullOrEmpty(alarm.Message))
|
||||
{
|
||||
<span class="ms-1 text-info" aria-label="Has operator message">💬</span>
|
||||
}
|
||||
@if (!string.IsNullOrEmpty(alarm.SourceReference))
|
||||
{
|
||||
<div class="text-muted font-monospace text-truncate" style="font-size: .7rem; max-width: 180px;"
|
||||
title="@alarm.SourceReference">@alarm.SourceReference</div>
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge @GetKindBadge(alarm.Kind)"
|
||||
aria-label="@($"Alarm kind: {alarm.Kind}")">@FormatKind(alarm.Kind)</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge @GetAlarmStateBadge(alarm.State)"
|
||||
aria-label="@($"Alarm state: {alarm.State}")">@alarm.State</span>
|
||||
@if (alarm.Kind != AlarmKind.Computed)
|
||||
{
|
||||
@if (alarm.Condition.Active && !alarm.Condition.Acknowledged)
|
||||
{
|
||||
<span class="badge bg-warning text-dark ms-1" aria-label="Unacknowledged">Unacked</span>
|
||||
}
|
||||
@if (alarm.Condition.Shelve != AlarmShelveState.Unshelved)
|
||||
{
|
||||
<span class="badge bg-info text-dark ms-1" title="@alarm.Condition.Shelve"
|
||||
aria-label="@($"Shelved: {alarm.Condition.Shelve}")">Shelved</span>
|
||||
}
|
||||
@if (alarm.Condition.Suppressed)
|
||||
{
|
||||
<span class="badge bg-info text-dark ms-1" aria-label="Suppressed">Suppressed</span>
|
||||
}
|
||||
}
|
||||
</td>
|
||||
<td class="small font-monospace">@alarm.Condition.Severity</td>
|
||||
<td>
|
||||
@if (alarm.Level != AlarmLevel.None)
|
||||
{
|
||||
@@ -224,7 +251,6 @@
|
||||
<span class="text-muted small">—</span>
|
||||
}
|
||||
</td>
|
||||
<td class="small">@alarm.Priority</td>
|
||||
<td class="small text-muted"
|
||||
title="@alarm.Timestamp.LocalDateTime.ToString("HH:mm:ss.fff")">
|
||||
@alarm.Timestamp.LocalDateTime.ToString("HH:mm:ss")
|
||||
@@ -284,7 +310,8 @@
|
||||
string.IsNullOrWhiteSpace(_alarmFilter)
|
||||
? _alarmStates.Values.OrderBy(a => a.AlarmName).ToList()
|
||||
: _alarmStates.Values
|
||||
.Where(a => a.AlarmName.Contains(_alarmFilter, StringComparison.OrdinalIgnoreCase))
|
||||
.Where(a => a.AlarmName.Contains(_alarmFilter, StringComparison.OrdinalIgnoreCase)
|
||||
|| a.SourceReference.Contains(_alarmFilter, StringComparison.OrdinalIgnoreCase))
|
||||
.OrderBy(a => a.AlarmName)
|
||||
.ToList();
|
||||
|
||||
@@ -575,6 +602,40 @@
|
||||
_ => "bg-secondary"
|
||||
};
|
||||
|
||||
/// <summary>Badge class distinguishing computed (neutral) from native (info) alarms.</summary>
|
||||
private static string GetKindBadge(AlarmKind kind) => kind switch
|
||||
{
|
||||
AlarmKind.Computed => "bg-secondary",
|
||||
_ => "bg-info text-dark"
|
||||
};
|
||||
|
||||
/// <summary>Short display label for the alarm kind.</summary>
|
||||
private static string FormatKind(AlarmKind kind) => kind switch
|
||||
{
|
||||
AlarmKind.NativeOpcUa => "OPC UA",
|
||||
AlarmKind.NativeMxAccess => "MxAccess",
|
||||
_ => "Computed"
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Builds the row tooltip from the alarm's operator message plus native
|
||||
/// metadata (type, category, operator, raise time, current/limit value).
|
||||
/// Returns null when there is nothing extra to show.
|
||||
/// </summary>
|
||||
private static string? BuildAlarmTooltip(AlarmStateChanged a)
|
||||
{
|
||||
var parts = new List<string>();
|
||||
if (!string.IsNullOrEmpty(a.Message)) parts.Add(a.Message);
|
||||
if (!string.IsNullOrEmpty(a.AlarmTypeName)) parts.Add($"Type: {a.AlarmTypeName}");
|
||||
if (!string.IsNullOrEmpty(a.Category)) parts.Add($"Category: {a.Category}");
|
||||
if (!string.IsNullOrEmpty(a.OperatorUser)) parts.Add($"By: {a.OperatorUser}");
|
||||
if (!string.IsNullOrEmpty(a.OperatorComment)) parts.Add($"Comment: {a.OperatorComment}");
|
||||
if (a.OriginalRaiseTime.HasValue) parts.Add($"Raised: {a.OriginalRaiseTime.Value.LocalDateTime:HH:mm:ss}");
|
||||
if (!string.IsNullOrEmpty(a.CurrentValue)) parts.Add($"Value: {a.CurrentValue}");
|
||||
if (!string.IsNullOrEmpty(a.LimitValue)) parts.Add($"Limit: {a.LimitValue}");
|
||||
return parts.Count == 0 ? null : string.Join(" · ", parts);
|
||||
}
|
||||
|
||||
private static string FormatLevel(AlarmLevel level) => level switch
|
||||
{
|
||||
AlarmLevel.HighHigh => "HiHi",
|
||||
|
||||
Reference in New Issue
Block a user