@using ZB.MOM.WW.ScadaBridge.CentralUI.Services @using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management @inject IServiceProvider MutationServices @page "/notifications/lists" @using ZB.MOM.WW.ScadaBridge.Security @using ZB.MOM.WW.ScadaBridge.Commons.Entities.Notifications @using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories @using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums @attribute [Authorize(Policy = AuthorizationPolicies.RequireDesign)] @inject INotificationRepository NotificationRepository @inject NavigationManager NavigationManager @inject IDialogService Dialog

Notification Lists

@if (_loading) { } else if (_errorMessage != null) {
@_errorMessage
} else if (_lists.Count == 0) {
No notification lists
} else {
@foreach (var list in _lists) { var recipients = _recipients.GetValueOrDefault(list.Id) ?? (IReadOnlyList)Array.Empty(); }
Name Type Recipients Actions
@list.Name @list.Type @if (recipients.Count == 0) { No recipients } else { @foreach (var r in recipients.Take(MaxVisibleRecipients)) { @* Type-aware contact: SMS recipients carry a PhoneNumber and a null EmailAddress, so an email-shaped badge would render "Name <>". Fall back to whichever contact field is populated. The two identifiers are separated inside the chip — name, then contact in a lighter weight — rather than fused into one "Name " run. *@ var contact = list.Type == NotificationType.Sms ? r.PhoneNumber : r.EmailAddress; @r.Name@contact } @if (recipients.Count > MaxVisibleRecipients) { @* Long lists roll up rather than filling the cell with chips. The remainder stays readable on the tooltip, and the full set is always available on the list's Edit page. *@ +@(recipients.Count - MaxVisibleRecipients) more } }
}
@code { /// /// Recipient chips rendered inline before the "+N more" roll-up. A list may /// hold dozens of recipients and the cell is uncapped, so the grid would /// otherwise render one chip per recipient into a single row. /// private const int MaxVisibleRecipients = 5; private bool _loading = true; private string? _errorMessage; private List _lists = new(); private readonly Dictionary> _recipients = new(); private ToastNotification _toast = default!; protected override async Task OnInitializedAsync() => await LoadAsync(); private async Task LoadAsync() { _loading = true; _errorMessage = null; try { _lists = (await NotificationRepository.GetAllNotificationListsAsync()).ToList(); _recipients.Clear(); foreach (var list in _lists) { _recipients[list.Id] = await NotificationRepository.GetRecipientsByListIdAsync(list.Id); } } catch (Exception ex) { _errorMessage = $"Failed to load notification lists: {ex.Message}"; } _loading = false; } /// /// Tooltip for the "+N more" roll-up chip: the recipients that were not given /// a chip of their own, using the same type-aware contact field as the chips. /// private static string RemainingRecipientsTitle( NotificationList list, IReadOnlyList recipients) => string.Join(", ", recipients .Skip(MaxVisibleRecipients) .Select(r => $"{r.Name} — {(list.Type == NotificationType.Sms ? r.PhoneNumber : r.EmailAddress)}")); private async Task DeleteList(NotificationList list) { if (!await Dialog.ConfirmAsync("Delete", $"Delete notification list '{list.Name}'?", danger: true)) { return; } try { await MutationServices.ExecuteConfigurationAsync(new DeleteNotificationListCommand(list.Id)); _toast.ShowSuccess("Deleted."); await LoadAsync(); } catch (Exception ex) { _toast.ShowError($"Failed to delete notification list: {ex.Message}"); } } }