feat(client-ui): ShelveAlarmWindow dialog (kind + duration)

This commit is contained in:
Joseph Doherty
2026-06-16 18:25:28 -04:00
parent 4f55d894a2
commit 60da9224bf
2 changed files with 118 additions and 0 deletions
@@ -0,0 +1,34 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ZB.MOM.WW.OtOpcUa.Client.UI.Views.ShelveAlarmWindow"
Title="Shelve Alarm" Width="420" SizeToContent="Height" MinHeight="280"
WindowStartupLocation="CenterOwner" CanResize="False">
<StackPanel Margin="16" Spacing="12">
<TextBlock Text="Shelve Alarm" FontWeight="Bold" FontSize="16" />
<StackPanel Spacing="4">
<TextBlock Text="Source:" FontSize="12" Foreground="Gray" />
<TextBlock Name="SourceText" FontWeight="SemiBold" />
</StackPanel>
<StackPanel Spacing="4">
<TextBlock Text="Condition:" FontSize="12" Foreground="Gray" />
<TextBlock Name="ConditionText" />
</StackPanel>
<StackPanel Spacing="4">
<TextBlock Text="Shelve type:" FontSize="12" Foreground="Gray" />
<ComboBox Name="KindCombo" SelectedIndex="0" HorizontalAlignment="Stretch">
<ComboBoxItem>OneShot</ComboBoxItem>
<ComboBoxItem>Timed</ComboBoxItem>
<ComboBoxItem>Unshelve</ComboBoxItem>
</ComboBox>
</StackPanel>
<StackPanel Name="DurationPanel" Spacing="4" IsEnabled="False">
<TextBlock Text="Duration (seconds):" FontSize="12" Foreground="Gray" />
<NumericUpDown Name="DurationInput" Minimum="1" Value="60" Increment="10" FormatString="0" />
</StackPanel>
<TextBlock Name="ResultText" Foreground="Gray" />
<StackPanel Orientation="Horizontal" Spacing="8" HorizontalAlignment="Right">
<Button Name="ShelveButton" Content="Shelve" />
<Button Name="CancelButton" Content="Cancel" />
</StackPanel>
</StackPanel>
</Window>
@@ -0,0 +1,84 @@
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Media;
using ZB.MOM.WW.OtOpcUa.Client.Shared.Models;
using ZB.MOM.WW.OtOpcUa.Client.UI.ViewModels;
namespace ZB.MOM.WW.OtOpcUa.Client.UI.Views;
public partial class ShelveAlarmWindow : Window
{
private readonly AlarmsViewModel _alarmsVm;
private readonly AlarmEventViewModel _alarm;
/// <summary>Designer ctor.</summary>
public ShelveAlarmWindow()
{
InitializeComponent();
_alarmsVm = null!;
_alarm = null!;
}
/// <summary>Creates the shelve dialog for an alarm.</summary>
public ShelveAlarmWindow(AlarmsViewModel alarmsVm, AlarmEventViewModel alarm)
{
InitializeComponent();
_alarmsVm = alarmsVm;
_alarm = alarm;
var sourceText = this.FindControl<TextBlock>("SourceText");
if (sourceText != null) sourceText.Text = alarm.SourceName;
var conditionText = this.FindControl<TextBlock>("ConditionText");
if (conditionText != null) conditionText.Text = $"{alarm.ConditionName} (Severity: {alarm.Severity})";
var kindCombo = this.FindControl<ComboBox>("KindCombo");
if (kindCombo != null) kindCombo.SelectionChanged += OnKindChanged;
var shelveButton = this.FindControl<Button>("ShelveButton");
if (shelveButton != null) shelveButton.Click += OnShelveClicked;
var cancelButton = this.FindControl<Button>("CancelButton");
if (cancelButton != null) cancelButton.Click += OnCancelClicked;
}
private void OnKindChanged(object? sender, SelectionChangedEventArgs e)
{
var durationPanel = this.FindControl<StackPanel>("DurationPanel");
var kindCombo = this.FindControl<ComboBox>("KindCombo");
if (durationPanel != null && kindCombo != null)
durationPanel.IsEnabled = kindCombo.SelectedIndex == 1; // Timed
}
private async void OnShelveClicked(object? sender, RoutedEventArgs e)
{
var kindCombo = this.FindControl<ComboBox>("KindCombo");
var durationInput = this.FindControl<NumericUpDown>("DurationInput");
var resultText = this.FindControl<TextBlock>("ResultText");
if (kindCombo == null || durationInput == null || resultText == null) return;
var kind = kindCombo.SelectedIndex switch
{
1 => ShelveKind.Timed,
2 => ShelveKind.Unshelve,
_ => ShelveKind.OneShot
};
var duration = (double)(durationInput.Value ?? 0m);
resultText.Foreground = Brushes.Gray;
resultText.Text = "Working...";
var (success, message) = await _alarmsVm.ShelveAlarmAsync(_alarm, kind, duration);
if (success)
{
Close();
}
else
{
resultText.Foreground = Brushes.Red;
resultText.Text = message;
}
}
private void OnCancelClicked(object? sender, RoutedEventArgs e) => Close();
}