@using ZB.MOM.WW.ScadaBridge.Commons.Types @using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums @* M10 residual: body component for the template "Add / Edit Attribute" dialog hosted by IDialogService.ShowAsync. Renders ONLY the form fields + action buttons inside the host's .modal-body; the host owns the backdrop, header, focus trap, Escape, and focus restoration. Mirrors MoveDataConnectionDialog: the save round-trip runs from inside the body, a failure is shown INLINE and the dialog STAYS OPEN, and success closes with Close(true) so the page toasts and reloads. The actual persistence stays on the page (TemplateEdit owns TemplateService + the inherited-member rules) and is reached through the OnSaveAsync delegate, which returns null on success or the error message to display. *@
@if (Editing) {
Data type is fixed once the attribute is created.
}
@if (_dataType == DataType.List) {
@* List VALUE stays editable when editing; only DataType/ElementDataType are server-fixed (ShowElementType hides the type select on edit). *@
} else {
}
@if (_error != null) {
@_error
}
@code { /// Host-supplied context: Close(true) on a successful save, Cancel on dismiss. [Parameter, EditorRequired] public DialogContext Context { get; set; } = default!; /// True when editing an existing attribute (name + data type become read-only). [Parameter] public bool Editing { get; set; } [Parameter] public string InitialName { get; set; } = string.Empty; [Parameter] public string? InitialValue { get; set; } [Parameter] public DataType InitialDataType { get; set; } [Parameter] public DataType InitialElementDataType { get; set; } = DataType.String; [Parameter] public IReadOnlyList InitialListRows { get; set; } = Array.Empty(); [Parameter] public bool InitialIsLocked { get; set; } [Parameter] public string? InitialDataSourceRef { get; set; } /// /// Persists the draft. Returns null on success (the dialog closes with /// true) or the message to render inline, leaving the dialog open. /// [Parameter, EditorRequired] public Func> OnSaveAsync { get; set; } = default!; private string _name = string.Empty; private string? _value; private DataType _dataType; private DataType _elementDataType = DataType.String; private List _listRows = new(); private bool _isLocked; private string? _dataSourceRef; private string? _error; private bool _busy; protected override void OnInitialized() { _name = InitialName; _value = InitialValue; _dataType = InitialDataType; _elementDataType = InitialElementDataType; _listRows = InitialListRows.ToList(); _isLocked = InitialIsLocked; _dataSourceRef = InitialDataSourceRef; } // Switching the data type clears stale list state so a List ⇄ scalar // toggle never carries the other mode's value into the submit. private void OnDataTypeChanged(ChangeEventArgs e) { if (!Enum.TryParse((string?)e.Value, out var dt) || dt == _dataType) return; _dataType = dt; if (dt == DataType.List) { _value = null; _listRows = new(); if (!AttributeValueCodec.IsValidElementType(_elementDataType)) _elementDataType = DataType.String; } else { _listRows = new(); } } private async Task Submit() { if (_busy) return; _error = null; if (string.IsNullOrWhiteSpace(_name)) { _error = "Name is required."; return; } _busy = true; try { var draft = new AttributeDraft( _name, _dataType, _elementDataType, _listRows.ToList(), _value, _dataSourceRef, _isLocked); var error = await OnSaveAsync(draft); if (error == null) { Context.Close(true); } else { _error = error; } } finally { _busy = false; } } /// /// The authored attribute as submitted. The page resolves the stored value /// (list encoding + validation for ) and performs /// the add/update, so this record carries the raw form state only. /// /// Attribute name (ignored on edit — the stored name is fixed). /// Selected data type (fixed on edit). /// Element scalar type; meaningful only for a List attribute. /// Per-element string rows; meaningful only for a List attribute. /// Scalar value; meaningful only for a non-List attribute. /// Tag path binding, or null. /// Whether instances may override the attribute. public sealed record AttributeDraft( string Name, DataType DataType, DataType ElementDataType, List ListRows, string? Value, string? DataSourceRef, bool IsLocked); }