@* Create/edit modal for a UNS area, wired straight into IUnsTreeService. The host page owns visibility and supplies the parent cluster (create) or the loaded AreaEditDto (edit) plus the served-by cluster list. On a successful save it raises OnSaved so the host can reload the tree. *@ @using System.ComponentModel.DataAnnotations @using Microsoft.AspNetCore.Components.Forms @using ZB.MOM.WW.OtOpcUa.AdminUI.Uns @inject IUnsTreeService Svc @if (Visible) { } @code { /// Whether the modal is shown. The host owns this flag. [Parameter] public bool Visible { get; set; } /// true to create a new area; false to edit . [Parameter] public bool IsNew { get; set; } /// The parent cluster id used to default the served-by select on create. [Parameter] public string? ClusterId { get; set; } /// The area being edited, when is false. [Parameter] public AreaEditDto? Existing { get; set; } /// The selectable served-by clusters as (Id, Display) pairs. [Parameter] public IReadOnlyList<(string Id, string Display)> Clusters { get; set; } = Array.Empty<(string, string)>(); /// Raised after a successful create/save so the host can reload and close. [Parameter] public EventCallback OnSaved { get; set; } /// Raised when the user cancels so the host can close. [Parameter] public EventCallback OnCancel { get; set; } private FormModel _form = new(); private bool _busy; private string? _error; protected override void OnParametersSet() { // Rebuild the working form whenever the host (re)opens the modal for a fresh target. if (IsNew) { _form = new FormModel { ClusterId = ClusterId ?? "" }; } else if (Existing is not null) { _form = new FormModel { UnsAreaId = Existing.UnsAreaId, Name = Existing.Name, Notes = Existing.Notes, ClusterId = Existing.ClusterId, }; } _error = null; } private async Task SaveAsync() { _busy = true; _error = null; try { var result = IsNew ? await Svc.CreateAreaAsync(_form.ClusterId, _form.UnsAreaId, _form.Name, _form.Notes) : await Svc.UpdateAreaAsync(_form.UnsAreaId, _form.Name, _form.Notes, _form.ClusterId, Existing!.RowVersion); if (result.Ok) { await OnSaved.InvokeAsync(); } else { _error = result.Error; } } finally { _busy = false; } } private Task CancelAsync() => OnCancel.InvokeAsync(); private sealed class FormModel { [Required, RegularExpression("^[A-Za-z0-9_-]+$")] public string UnsAreaId { get; set; } = ""; [Required] public string Name { get; set; } = ""; [Required] public string ClusterId { get; set; } = ""; public string? Notes { get; set; } } }