@page "/design/external-systems" @using ScadaLink.Security @using ScadaLink.Commons.Entities.ExternalSystems @using ScadaLink.Commons.Entities.Notifications @using ScadaLink.Commons.Entities.InboundApi @using ScadaLink.Commons.Interfaces.Repositories @attribute [Authorize(Policy = AuthorizationPolicies.RequireDesign)] @inject IExternalSystemRepository ExternalSystemRepository @inject INotificationRepository NotificationRepository @inject IInboundApiRepository InboundApiRepository @inject NavigationManager NavigationManager

Integration Definitions

Email configuration →
@if (_loading) { } else if (_errorMessage != null) {
@_errorMessage
} else { @if (_tab == "extsys") {
@RenderExternalSystems()
} else if (_tab == "dbconn") {
@RenderDbConnections()
} else if (_tab == "notif") {
@RenderNotificationLists()
} else if (_tab == "inbound") {
@RenderInboundApiMethods()
} else if (_tab == "apikeys") {
@RenderApiKeys()
} }
@code { private bool _loading = true; private string? _errorMessage; private string _tab = "extsys"; // External Systems private List _externalSystems = new(); private string _extsysSearch = ""; private IEnumerable FilteredExternalSystems => string.IsNullOrWhiteSpace(_extsysSearch) ? _externalSystems : _externalSystems.Where(es => es.Name?.Contains(_extsysSearch, StringComparison.OrdinalIgnoreCase) ?? false); // Database Connections private List _dbConnections = new(); private string _dbConnSearch = ""; private IEnumerable FilteredDbConnections => string.IsNullOrWhiteSpace(_dbConnSearch) ? _dbConnections : _dbConnections.Where(dc => dc.Name?.Contains(_dbConnSearch, StringComparison.OrdinalIgnoreCase) ?? false); // API Keys private List _apiKeys = new(); private string _apiKeySearch = ""; private IEnumerable FilteredApiKeys => string.IsNullOrWhiteSpace(_apiKeySearch) ? _apiKeys : _apiKeys.Where(k => k.Name?.Contains(_apiKeySearch, StringComparison.OrdinalIgnoreCase) ?? false); // Notification Lists private List _notificationLists = new(); private Dictionary> _recipients = new(); private string _notifSearch = ""; private IEnumerable FilteredNotificationLists => string.IsNullOrWhiteSpace(_notifSearch) ? _notificationLists : _notificationLists.Where(n => n.Name?.Contains(_notifSearch, StringComparison.OrdinalIgnoreCase) ?? false); // Inbound API Methods private List _apiMethods = new(); private string _apiMethodSearch = ""; private IEnumerable FilteredApiMethods => string.IsNullOrWhiteSpace(_apiMethodSearch) ? _apiMethods : _apiMethods.Where(m => m.Name?.Contains(_apiMethodSearch, StringComparison.OrdinalIgnoreCase) ?? false); private ToastNotification _toast = default!; private ConfirmDialog _confirmDialog = default!; protected override async Task OnInitializedAsync() { await LoadAllAsync(); } private async Task LoadAllAsync() { _loading = true; try { _externalSystems = (await ExternalSystemRepository.GetAllExternalSystemsAsync()).ToList(); _dbConnections = (await ExternalSystemRepository.GetAllDatabaseConnectionsAsync()).ToList(); _notificationLists = (await NotificationRepository.GetAllNotificationListsAsync()).ToList(); _recipients.Clear(); foreach (var list in _notificationLists) { var recips = await NotificationRepository.GetRecipientsByListIdAsync(list.Id); if (recips.Count > 0) _recipients[list.Id] = recips.ToList(); } _apiMethods = (await InboundApiRepository.GetAllApiMethodsAsync()).ToList(); _apiKeys = (await InboundApiRepository.GetAllApiKeysAsync()).ToList(); } catch (Exception ex) { _errorMessage = ex.Message; } _loading = false; } // ==== External Systems ==== private RenderFragment RenderExternalSystems() => __builder => {
External Systems
@if (_externalSystems.Count == 0) {

No external systems configured.

} else {
@if (!FilteredExternalSystems.Any()) {

No external systems match the filter.

}
@foreach (var es in FilteredExternalSystems) {
@es.Name

@es.EndpointUrl

@es.AuthType Max @es.MaxRetries retries Delay @es.RetryDelay.TotalSeconds s
}
} }; private async Task DeleteExtSys(ExternalSystemDefinition es) { if (!await _confirmDialog.ShowAsync($"Delete '{es.Name}'?", "Delete External System")) return; try { await ExternalSystemRepository.DeleteExternalSystemAsync(es.Id); await ExternalSystemRepository.SaveChangesAsync(); _toast.ShowSuccess("Deleted."); await LoadAllAsync(); } catch (Exception ex) { _toast.ShowError(ex.Message); } } // ==== Database Connections ==== private RenderFragment RenderDbConnections() => __builder => {
Database Connections
@if (_dbConnections.Count == 0) {

No database connections configured.

} else {
@if (!FilteredDbConnections.Any()) {

No database connections match the filter.

}
@foreach (var dc in FilteredDbConnections) {
@dc.Name

@dc.ConnectionString

Max @dc.MaxRetries retries Delay @dc.RetryDelay.TotalSeconds s
}
} }; private async Task DeleteDbConn(DatabaseConnectionDefinition dc) { if (!await _confirmDialog.ShowAsync($"Delete '{dc.Name}'?", "Delete DB Connection")) return; try { await ExternalSystemRepository.DeleteDatabaseConnectionAsync(dc.Id); await ExternalSystemRepository.SaveChangesAsync(); _toast.ShowSuccess("Deleted."); await LoadAllAsync(); } catch (Exception ex) { _toast.ShowError(ex.Message); } } // ==== Notification Lists ==== private RenderFragment RenderNotificationLists() => __builder => {
Notification Lists
@if (_notificationLists.Count == 0) {

No notification lists configured.

} else {
@if (!FilteredNotificationLists.Any()) {

No notification lists match the filter.

}
@foreach (var list in FilteredNotificationLists) { var recips = _recipients.GetValueOrDefault(list.Id);
@list.Name
@if (recips == null || recips.Count == 0) {

No recipients.

} else {
@foreach (var r in recips) { @r.Name <@r.EmailAddress> }
}
}
} }; private async Task DeleteNotifList(NotificationList list) { if (!await _confirmDialog.ShowAsync($"Delete notification list '{list.Name}'?", "Delete")) return; try { await NotificationRepository.DeleteNotificationListAsync(list.Id); await NotificationRepository.SaveChangesAsync(); _toast.ShowSuccess("Deleted."); await LoadAllAsync(); } catch (Exception ex) { _toast.ShowError(ex.Message); } } // ==== Inbound API Methods ==== private RenderFragment RenderInboundApiMethods() => __builder => {
Inbound API Methods
@if (_apiMethods.Count == 0) {

No API methods configured.

} else {
@if (!FilteredApiMethods.Any()) {

No API methods match the filter.

}
@foreach (var m in FilteredApiMethods) { var preview = m.Script.Length > 80 ? m.Script[..80] + "…" : m.Script;
@m.Name
POST /api/@m.Name
@preview
Timeout @m.TimeoutSeconds s
}
} }; private async Task DeleteApiMethod(ApiMethod m) { if (!await _confirmDialog.ShowAsync($"Delete API method '{m.Name}'?", "Delete")) return; try { await InboundApiRepository.DeleteApiMethodAsync(m.Id); await InboundApiRepository.SaveChangesAsync(); _toast.ShowSuccess("Deleted."); await LoadAllAsync(); } catch (Exception ex) { _toast.ShowError(ex.Message); } } // ==== API Keys ==== private RenderFragment RenderApiKeys() => __builder => {
API Keys
@if (_apiKeys.Count == 0) {

No API keys configured. Add your first API key from the Admin section.

} else {
@if (!FilteredApiKeys.Any()) {

No API keys match the filter.

}
@foreach (var key in FilteredApiKeys) {
@key.Name
@(key.IsEnabled ? "Enabled" : "Disabled")
}
} }; private async Task ToggleApiKeyEnabled(ApiKey key) { try { key.IsEnabled = !key.IsEnabled; await InboundApiRepository.UpdateApiKeyAsync(key); await InboundApiRepository.SaveChangesAsync(); _toast.ShowSuccess($"API key '{key.Name}' {(key.IsEnabled ? "enabled" : "disabled")}."); } catch (Exception ex) { _toast.ShowError(ex.Message); } } }