();
@@ -82,6 +92,7 @@
private AlarmTriggerType _triggerType;
private string? _triggerConfig;
private bool _isLocked;
+ private bool _isMesReportable;
private string? _error;
private bool _busy;
@@ -92,6 +103,7 @@
_triggerType = InitialTriggerType;
_triggerConfig = InitialTriggerConfig;
_isLocked = InitialIsLocked;
+ _isMesReportable = InitialIsMesReportable;
}
private async Task Submit()
@@ -103,7 +115,7 @@
_busy = true;
try
{
- var error = await OnSaveAsync(new AlarmDraft(_name, _triggerType, _priority, _triggerConfig, _isLocked));
+ var error = await OnSaveAsync(new AlarmDraft(_name, _triggerType, _priority, _triggerConfig, _isLocked, _isMesReportable));
if (error == null)
{
Context.Close(true);
@@ -125,10 +137,12 @@
/// Priority level.
/// Structured trigger configuration payload.
/// Whether instances may override the alarm.
+ /// Whether the MES alarm-status API reports this alarm.
public sealed record AlarmDraft(
string Name,
AlarmTriggerType TriggerType,
int Priority,
string? TriggerConfig,
- bool IsLocked);
+ bool IsLocked,
+ bool IsMesReportable);
}
diff --git a/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Design/TemplateEdit.razor b/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Design/TemplateEdit.razor
index ed0d21c6..21d9cccb 100644
--- a/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Design/TemplateEdit.razor
+++ b/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Design/TemplateEdit.razor
@@ -907,6 +907,7 @@
| Trigger |
Priority |
Config |
+ MES |
Lock |
Actions |
@@ -922,6 +923,16 @@
config readable instead of merely hidden. *@
@(alarm.TriggerConfiguration ?? "—") |
+
+ @if (alarm.IsMesReportable)
+ {
+ MES
+ }
+ else
+ {
+ —
+ }
+ |
@if (alarm.IsLocked)
{
@@ -1436,7 +1447,7 @@
private Task OpenAddAlarmDialog()
=> ShowAlarmDialogAsync(
editId: null,
- new TemplateAlarmDialog.AlarmDraft(string.Empty, default, 500, null, false));
+ new TemplateAlarmDialog.AlarmDraft(string.Empty, default, 500, null, false, false));
private Task OpenEditAlarmDialog(TemplateAlarm alarm)
=> ShowAlarmDialogAsync(
@@ -1446,7 +1457,8 @@
alarm.TriggerType,
alarm.PriorityLevel,
alarm.TriggerConfiguration,
- alarm.IsLocked));
+ alarm.IsLocked,
+ alarm.IsMesReportable));
private async Task ShowAlarmDialogAsync(int? editId, TemplateAlarmDialog.AlarmDraft initial)
{
@@ -1461,6 +1473,7 @@
InitialPriority="initial.Priority"
InitialTriggerConfig="@initial.TriggerConfig"
InitialIsLocked="initial.IsLocked"
+ InitialIsMesReportable="initial.IsMesReportable"
AvailableAttributes="choices"
OnSaveAsync="d => SaveAlarmDraftAsync(editId, d)" />,
size: "modal-dialog-scrollable");
@@ -1521,6 +1534,7 @@
PriorityLevel = draft.Priority,
TriggerConfiguration = draft.TriggerConfig?.Trim(),
IsLocked = draft.IsLocked,
+ IsMesReportable = draft.IsMesReportable,
Description = existing.Description,
OnTriggerScriptId = existing.OnTriggerScriptId,
};
@@ -1536,7 +1550,8 @@
TriggerType = draft.TriggerType,
PriorityLevel = draft.Priority,
TriggerConfiguration = draft.TriggerConfig?.Trim(),
- IsLocked = draft.IsLocked
+ IsLocked = draft.IsLocked,
+ IsMesReportable = draft.IsMesReportable
};
var addResult = await TemplateService.AddAlarmAsync(_selectedTemplate.Id, alarm, user);
diff --git a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/Design/TemplateAlarmDialogMesReportableTests.cs b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/Design/TemplateAlarmDialogMesReportableTests.cs
new file mode 100644
index 00000000..d4351251
--- /dev/null
+++ b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/Design/TemplateAlarmDialogMesReportableTests.cs
@@ -0,0 +1,67 @@
+namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Design;
+
+///
+/// The template alarm authoring surface exposes TemplateAlarm.IsMesReportable:
+/// an "MES reportable" checkbox in the dialog body and an MES column on the
+/// template's Alarms tab. TemplateEdit is a heavyweight page (~10 injected
+/// services with their own graphs), so — like the rest of the TemplateEdit coverage
+/// in this suite (see TemplateNativeAlarmSourceEditorTests) — these are
+/// structural assertions over the component source that pin the wiring so it cannot
+/// silently regress. The persistence behaviour itself is covered by the
+/// TemplateService / ManagementActor alarm tests.
+///
+public class TemplateAlarmDialogMesReportableTests
+{
+ private static string DesignComponentsRoot
+ {
+ get
+ {
+ var dir = AppContext.BaseDirectory;
+ for (var i = 0; i < 6 && dir is not null; i++)
+ dir = Directory.GetParent(dir)?.FullName;
+ return Path.Combine(dir!, "src", "ZB.MOM.WW.ScadaBridge.CentralUI",
+ "Components", "Pages", "Design");
+ }
+ }
+
+ private static string AlarmDialogMarkup
+ => File.ReadAllText(Path.Combine(DesignComponentsRoot, "TemplateAlarmDialog.razor"));
+
+ private static string TemplateEditMarkup
+ => File.ReadAllText(Path.Combine(DesignComponentsRoot, "TemplateEdit.razor"));
+
+ [Fact]
+ public void AlarmDialog_HasMesReportableCheckbox()
+ {
+ var markup = AlarmDialogMarkup;
+ Assert.Contains("@bind=\"_isMesReportable\"", markup);
+ Assert.Contains("id=\"alarmMesReportable\"", markup);
+ Assert.Contains("MES reportable", markup);
+ }
+
+ [Fact]
+ public void AlarmDialog_ThreadsMesReportableThroughParameterAndDraft()
+ {
+ var markup = AlarmDialogMarkup;
+ Assert.Contains("InitialIsMesReportable", markup);
+ Assert.Contains("_isMesReportable = InitialIsMesReportable", markup);
+ Assert.Contains("bool IsMesReportable", markup);
+ }
+
+ [Fact]
+ public void AlarmsTab_HasMesColumn()
+ {
+ var markup = TemplateEditMarkup;
+ Assert.Contains(" | MES | ", markup);
+ Assert.Contains("data-test=\"alarm-mes-badge\"", markup);
+ Assert.Contains("alarm.IsMesReportable", markup);
+ }
+
+ [Fact]
+ public void AlarmsTab_PassesMesReportableIntoAndOutOfTheDialog()
+ {
+ var markup = TemplateEditMarkup;
+ Assert.Contains("InitialIsMesReportable=\"initial.IsMesReportable\"", markup);
+ Assert.Contains("IsMesReportable = draft.IsMesReportable", markup);
+ }
+}