@page "/design/api-methods/create" @page "/design/api-methods/{Id:int}/edit" @using ScadaLink.Security @using ScadaLink.Commons.Entities.InboundApi @using ScadaLink.Commons.Interfaces.Repositories @attribute [Authorize(Policy = AuthorizationPolicies.RequireDesign)] @inject IInboundApiRepository InboundApiRepository @inject NavigationManager NavigationManager

@(Id.HasValue ? "Edit API Method" : "Add API Method")

@if (_loading) { } else {
@if (_allKeys.Count == 0) {
No API keys configured. Create one to authorize callers for this method.
} else {
@foreach (var key in _allKeys) { var checkboxId = $"approved-key-{key.Id}";
}
Callers must present a checked key in the X-API-Key header to invoke this method.
}
@if (_formError != null) {
@_formError
}
}
@code { [Parameter] public int? Id { get; set; } private bool _loading = true; private string _name = "", _script = ""; private int _timeoutSeconds = 30; private string? _params, _returns; private string? _formError; private MonacoEditor? _editor; private IReadOnlyList _markers = Array.Empty(); private ApiMethod? _existing; private List _allKeys = new(); private HashSet _selectedKeyIds = new(); protected override async Task OnInitializedAsync() { try { _allKeys = (await InboundApiRepository.GetAllApiKeysAsync()).ToList(); } catch (Exception ex) { _formError = ex.Message; } if (Id.HasValue) { try { _existing = await InboundApiRepository.GetApiMethodByIdAsync(Id.Value); if (_existing != null) { _name = _existing.Name; _script = _existing.Script; _timeoutSeconds = _existing.TimeoutSeconds; _params = _existing.ParameterDefinitions; _returns = _existing.ReturnDefinition; _selectedKeyIds = ParseApprovedKeyIds(_existing.ApprovedApiKeyIds); } } catch (Exception ex) { _formError = ex.Message; } } _loading = false; } private static HashSet ParseApprovedKeyIds(string? value) { if (string.IsNullOrWhiteSpace(value)) return new HashSet(); return value.Split(',', StringSplitOptions.RemoveEmptyEntries) .Select(s => int.TryParse(s.Trim(), out var id) ? id : -1) .Where(id => id > 0) .ToHashSet(); } private void ToggleKey(int keyId, bool isChecked) { if (isChecked) _selectedKeyIds.Add(keyId); else _selectedKeyIds.Remove(keyId); } private string? SerializeApprovedKeyIds() => _selectedKeyIds.Count == 0 ? null : string.Join(",", _selectedKeyIds.OrderBy(id => id)); private async Task Save() { _formError = null; if (string.IsNullOrWhiteSpace(_name) || string.IsNullOrWhiteSpace(_script)) { _formError = "Name and script required."; return; } try { var approvedKeyIds = SerializeApprovedKeyIds(); if (_existing != null) { _existing.Script = _script; _existing.TimeoutSeconds = _timeoutSeconds; _existing.ParameterDefinitions = _params?.Trim(); _existing.ReturnDefinition = _returns?.Trim(); _existing.ApprovedApiKeyIds = approvedKeyIds; await InboundApiRepository.UpdateApiMethodAsync(_existing); } else { var m = new ApiMethod(_name.Trim(), _script) { TimeoutSeconds = _timeoutSeconds, ParameterDefinitions = _params?.Trim(), ReturnDefinition = _returns?.Trim(), ApprovedApiKeyIds = approvedKeyIds }; await InboundApiRepository.AddApiMethodAsync(m); } await InboundApiRepository.SaveChangesAsync(); NavigationManager.NavigateTo("/design/external-systems"); } catch (Exception ex) { _formError = ex.Message; } } private void GoBack() => NavigationManager.NavigateTo("/design/external-systems"); }