feat: separate create/edit form pages, Playwright test infrastructure, /auth/token endpoint
Move all CRUD create/edit forms from inline on list pages to dedicated form pages with back-button navigation and post-save redirect. Add Playwright Docker container (browser server on port 3000) with 25 passing E2E tests covering login, navigation, and site CRUD workflows. Add POST /auth/token endpoint for clean JWT retrieval.
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
@inject IExternalSystemRepository ExternalSystemRepository
|
||||
@inject INotificationRepository NotificationRepository
|
||||
@inject IInboundApiRepository InboundApiRepository
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
<div class="container-fluid mt-3">
|
||||
<h4 class="mb-3">Integration Definitions</h4>
|
||||
@@ -62,22 +63,9 @@
|
||||
|
||||
// External Systems
|
||||
private List<ExternalSystemDefinition> _externalSystems = new();
|
||||
private bool _showExtSysForm;
|
||||
private ExternalSystemDefinition? _editingExtSys;
|
||||
private string _extSysName = "", _extSysUrl = "", _extSysAuth = "ApiKey";
|
||||
private string? _extSysAuthConfig;
|
||||
private int _extSysMaxRetries = 3;
|
||||
private int _extSysRetryDelaySeconds = 5;
|
||||
private string? _extSysFormError;
|
||||
|
||||
// Database Connections
|
||||
private List<DatabaseConnectionDefinition> _dbConnections = new();
|
||||
private bool _showDbConnForm;
|
||||
private DatabaseConnectionDefinition? _editingDbConn;
|
||||
private string _dbConnName = "", _dbConnString = "";
|
||||
private int _dbConnMaxRetries = 3;
|
||||
private int _dbConnRetryDelaySeconds = 5;
|
||||
private string? _dbConnFormError;
|
||||
|
||||
// SMTP Configuration
|
||||
private List<SmtpConfiguration> _smtpConfigs = new();
|
||||
@@ -92,26 +80,10 @@
|
||||
|
||||
// Notification Lists
|
||||
private List<NotificationList> _notificationLists = new();
|
||||
private bool _showNotifForm;
|
||||
private NotificationList? _editingNotifList;
|
||||
private string _notifName = "";
|
||||
private string? _notifFormError;
|
||||
|
||||
// Notification Recipients
|
||||
private Dictionary<int, List<NotificationRecipient>> _recipients = new();
|
||||
private bool _showRecipientForm;
|
||||
private int _recipientListId;
|
||||
private string _recipientName = "", _recipientEmail = "";
|
||||
private string? _recipientFormError;
|
||||
|
||||
// Inbound API Methods
|
||||
private List<ApiMethod> _apiMethods = new();
|
||||
private bool _showApiMethodForm;
|
||||
private ApiMethod? _editingApiMethod;
|
||||
private string _apiMethodName = "", _apiMethodScript = "";
|
||||
private int _apiMethodTimeout = 30;
|
||||
private string? _apiMethodParams, _apiMethodReturn;
|
||||
private string? _apiMethodFormError;
|
||||
|
||||
private ToastNotification _toast = default!;
|
||||
private ConfirmDialog _confirmDialog = default!;
|
||||
@@ -150,28 +122,9 @@
|
||||
{
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<h6 class="mb-0">External Systems</h6>
|
||||
<button class="btn btn-primary btn-sm" @onclick="ShowExtSysAddForm">Add</button>
|
||||
<button class="btn btn-primary btn-sm" @onclick='() => NavigationManager.NavigateTo("/design/external-systems/create")'>Add</button>
|
||||
</div>
|
||||
|
||||
@if (_showExtSysForm)
|
||||
{
|
||||
<div class="card mb-2"><div class="card-body">
|
||||
<div class="row g-2 align-items-end">
|
||||
<div class="col-md-2"><label class="form-label small">Name</label><input type="text" class="form-control form-control-sm" @bind="_extSysName" /></div>
|
||||
<div class="col-md-3"><label class="form-label small">Endpoint URL</label><input type="text" class="form-control form-control-sm" @bind="_extSysUrl" /></div>
|
||||
<div class="col-md-2"><label class="form-label small">Auth Type</label>
|
||||
<select class="form-select form-select-sm" @bind="_extSysAuth"><option>ApiKey</option><option>BasicAuth</option></select></div>
|
||||
<div class="col-md-2"><label class="form-label small">Auth Config (JSON)</label><input type="text" class="form-control form-control-sm" @bind="_extSysAuthConfig" /></div>
|
||||
<div class="col-md-1"><label class="form-label small">Max Retries</label><input type="number" class="form-control form-control-sm" @bind="_extSysMaxRetries" min="0" /></div>
|
||||
<div class="col-md-1"><label class="form-label small">Retry Delay (s)</label><input type="number" class="form-control form-control-sm" @bind="_extSysRetryDelaySeconds" min="0" /></div>
|
||||
<div class="col-md-1">
|
||||
<button class="btn btn-success btn-sm me-1" @onclick="SaveExtSys">Save</button>
|
||||
<button class="btn btn-outline-secondary btn-sm" @onclick="() => _showExtSysForm = false">Cancel</button></div>
|
||||
</div>
|
||||
@if (_extSysFormError != null) { <div class="text-danger small mt-1">@_extSysFormError</div> }
|
||||
</div></div>
|
||||
}
|
||||
|
||||
<table class="table table-sm table-striped">
|
||||
<thead class="table-dark"><tr><th>Name</th><th>URL</th><th>Auth</th><th>Retries</th><th>Delay</th><th style="width:120px;">Actions</th></tr></thead>
|
||||
<tbody>
|
||||
@@ -181,7 +134,7 @@
|
||||
<td>@es.Name</td><td class="small">@es.EndpointUrl</td><td><span class="badge bg-secondary">@es.AuthType</span></td>
|
||||
<td class="small">@es.MaxRetries</td><td class="small">@es.RetryDelay.TotalSeconds s</td>
|
||||
<td>
|
||||
<button class="btn btn-outline-primary btn-sm py-0 px-1 me-1" @onclick="() => { _editingExtSys = es; _extSysName = es.Name; _extSysUrl = es.EndpointUrl; _extSysAuth = es.AuthType; _extSysAuthConfig = es.AuthConfiguration; _extSysMaxRetries = es.MaxRetries; _extSysRetryDelaySeconds = (int)es.RetryDelay.TotalSeconds; _showExtSysForm = true; }">Edit</button>
|
||||
<button class="btn btn-outline-primary btn-sm py-0 px-1 me-1" @onclick='() => NavigationManager.NavigateTo($"/design/external-systems/{es.Id}/edit")'>Edit</button>
|
||||
<button class="btn btn-outline-danger btn-sm py-0 px-1" @onclick="() => DeleteExtSys(es)">Delete</button>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -190,31 +143,6 @@
|
||||
</table>
|
||||
};
|
||||
|
||||
private void ShowExtSysAddForm()
|
||||
{
|
||||
_showExtSysForm = true;
|
||||
_editingExtSys = null;
|
||||
_extSysName = _extSysUrl = string.Empty;
|
||||
_extSysAuth = "ApiKey";
|
||||
_extSysAuthConfig = null;
|
||||
_extSysMaxRetries = 3;
|
||||
_extSysRetryDelaySeconds = 5;
|
||||
_extSysFormError = null;
|
||||
}
|
||||
|
||||
private async Task SaveExtSys()
|
||||
{
|
||||
_extSysFormError = null;
|
||||
if (string.IsNullOrWhiteSpace(_extSysName) || string.IsNullOrWhiteSpace(_extSysUrl)) { _extSysFormError = "Name and URL required."; return; }
|
||||
try
|
||||
{
|
||||
if (_editingExtSys != null) { _editingExtSys.Name = _extSysName.Trim(); _editingExtSys.EndpointUrl = _extSysUrl.Trim(); _editingExtSys.AuthType = _extSysAuth; _editingExtSys.AuthConfiguration = _extSysAuthConfig?.Trim(); _editingExtSys.MaxRetries = _extSysMaxRetries; _editingExtSys.RetryDelay = TimeSpan.FromSeconds(_extSysRetryDelaySeconds); await ExternalSystemRepository.UpdateExternalSystemAsync(_editingExtSys); }
|
||||
else { var es = new ExternalSystemDefinition(_extSysName.Trim(), _extSysUrl.Trim(), _extSysAuth) { AuthConfiguration = _extSysAuthConfig?.Trim(), MaxRetries = _extSysMaxRetries, RetryDelay = TimeSpan.FromSeconds(_extSysRetryDelaySeconds) }; await ExternalSystemRepository.AddExternalSystemAsync(es); }
|
||||
await ExternalSystemRepository.SaveChangesAsync(); _showExtSysForm = false; _toast.ShowSuccess("Saved."); await LoadAllAsync();
|
||||
}
|
||||
catch (Exception ex) { _extSysFormError = ex.Message; }
|
||||
}
|
||||
|
||||
private async Task DeleteExtSys(ExternalSystemDefinition es)
|
||||
{
|
||||
if (!await _confirmDialog.ShowAsync($"Delete '{es.Name}'?", "Delete External System")) return;
|
||||
@@ -227,25 +155,9 @@
|
||||
{
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<h6 class="mb-0">Database Connections</h6>
|
||||
<button class="btn btn-primary btn-sm" @onclick="() => { _showDbConnForm = true; _editingDbConn = null; _dbConnName = _dbConnString = string.Empty; _dbConnMaxRetries = 3; _dbConnRetryDelaySeconds = 5; _dbConnFormError = null; }">Add</button>
|
||||
<button class="btn btn-primary btn-sm" @onclick='() => NavigationManager.NavigateTo("/design/db-connections/create")'>Add</button>
|
||||
</div>
|
||||
|
||||
@if (_showDbConnForm)
|
||||
{
|
||||
<div class="card mb-2"><div class="card-body">
|
||||
<div class="row g-2 align-items-end">
|
||||
<div class="col-md-3"><label class="form-label small">Name</label><input type="text" class="form-control form-control-sm" @bind="_dbConnName" /></div>
|
||||
<div class="col-md-4"><label class="form-label small">Connection String</label><input type="text" class="form-control form-control-sm" @bind="_dbConnString" /></div>
|
||||
<div class="col-md-1"><label class="form-label small">Max Retries</label><input type="number" class="form-control form-control-sm" @bind="_dbConnMaxRetries" min="0" /></div>
|
||||
<div class="col-md-1"><label class="form-label small">Retry Delay (s)</label><input type="number" class="form-control form-control-sm" @bind="_dbConnRetryDelaySeconds" min="0" /></div>
|
||||
<div class="col-md-3">
|
||||
<button class="btn btn-success btn-sm me-1" @onclick="SaveDbConn">Save</button>
|
||||
<button class="btn btn-outline-secondary btn-sm" @onclick="() => _showDbConnForm = false">Cancel</button></div>
|
||||
</div>
|
||||
@if (_dbConnFormError != null) { <div class="text-danger small mt-1">@_dbConnFormError</div> }
|
||||
</div></div>
|
||||
}
|
||||
|
||||
<table class="table table-sm table-striped">
|
||||
<thead class="table-dark"><tr><th>Name</th><th>Connection String</th><th>Retries</th><th>Delay</th><th style="width:120px;">Actions</th></tr></thead>
|
||||
<tbody>
|
||||
@@ -255,7 +167,7 @@
|
||||
<td>@dc.Name</td><td class="small text-muted text-truncate" style="max-width:400px;">@dc.ConnectionString</td>
|
||||
<td class="small">@dc.MaxRetries</td><td class="small">@dc.RetryDelay.TotalSeconds s</td>
|
||||
<td>
|
||||
<button class="btn btn-outline-primary btn-sm py-0 px-1 me-1" @onclick="() => { _editingDbConn = dc; _dbConnName = dc.Name; _dbConnString = dc.ConnectionString; _dbConnMaxRetries = dc.MaxRetries; _dbConnRetryDelaySeconds = (int)dc.RetryDelay.TotalSeconds; _showDbConnForm = true; }">Edit</button>
|
||||
<button class="btn btn-outline-primary btn-sm py-0 px-1 me-1" @onclick='() => NavigationManager.NavigateTo($"/design/db-connections/{dc.Id}/edit")'>Edit</button>
|
||||
<button class="btn btn-outline-danger btn-sm py-0 px-1" @onclick="() => DeleteDbConn(dc)">Delete</button>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -264,19 +176,6 @@
|
||||
</table>
|
||||
};
|
||||
|
||||
private async Task SaveDbConn()
|
||||
{
|
||||
_dbConnFormError = null;
|
||||
if (string.IsNullOrWhiteSpace(_dbConnName) || string.IsNullOrWhiteSpace(_dbConnString)) { _dbConnFormError = "Name and connection string required."; return; }
|
||||
try
|
||||
{
|
||||
if (_editingDbConn != null) { _editingDbConn.Name = _dbConnName.Trim(); _editingDbConn.ConnectionString = _dbConnString.Trim(); _editingDbConn.MaxRetries = _dbConnMaxRetries; _editingDbConn.RetryDelay = TimeSpan.FromSeconds(_dbConnRetryDelaySeconds); await ExternalSystemRepository.UpdateDatabaseConnectionAsync(_editingDbConn); }
|
||||
else { var dc = new DatabaseConnectionDefinition(_dbConnName.Trim(), _dbConnString.Trim()) { MaxRetries = _dbConnMaxRetries, RetryDelay = TimeSpan.FromSeconds(_dbConnRetryDelaySeconds) }; await ExternalSystemRepository.AddDatabaseConnectionAsync(dc); }
|
||||
await ExternalSystemRepository.SaveChangesAsync(); _showDbConnForm = false; _toast.ShowSuccess("Saved."); await LoadAllAsync();
|
||||
}
|
||||
catch (Exception ex) { _dbConnFormError = ex.Message; }
|
||||
}
|
||||
|
||||
private async Task DeleteDbConn(DatabaseConnectionDefinition dc)
|
||||
{
|
||||
if (!await _confirmDialog.ShowAsync($"Delete '{dc.Name}'?", "Delete DB Connection")) return;
|
||||
@@ -289,44 +188,16 @@
|
||||
{
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<h6 class="mb-0">Notification Lists</h6>
|
||||
<button class="btn btn-primary btn-sm" @onclick="() => { _showNotifForm = true; _editingNotifList = null; _notifName = string.Empty; _notifFormError = null; }">Add List</button>
|
||||
<button class="btn btn-primary btn-sm" @onclick='() => NavigationManager.NavigateTo("/design/notification-lists/create")'>Add List</button>
|
||||
</div>
|
||||
|
||||
@if (_showNotifForm)
|
||||
{
|
||||
<div class="card mb-2"><div class="card-body">
|
||||
<div class="row g-2 align-items-end">
|
||||
<div class="col-md-4"><label class="form-label small">Name</label><input type="text" class="form-control form-control-sm" @bind="_notifName" /></div>
|
||||
<div class="col-md-4">
|
||||
<button class="btn btn-success btn-sm me-1" @onclick="SaveNotifList">Save</button>
|
||||
<button class="btn btn-outline-secondary btn-sm" @onclick="() => _showNotifForm = false">Cancel</button></div>
|
||||
</div>
|
||||
@if (_notifFormError != null) { <div class="text-danger small mt-1">@_notifFormError</div> }
|
||||
</div></div>
|
||||
}
|
||||
|
||||
@if (_showRecipientForm)
|
||||
{
|
||||
<div class="card mb-2"><div class="card-body">
|
||||
<h6 class="card-title small">Add Recipient</h6>
|
||||
<div class="row g-2 align-items-end">
|
||||
<div class="col-md-3"><label class="form-label small">Name</label><input type="text" class="form-control form-control-sm" @bind="_recipientName" /></div>
|
||||
<div class="col-md-3"><label class="form-label small">Email</label><input type="email" class="form-control form-control-sm" @bind="_recipientEmail" /></div>
|
||||
<div class="col-md-3">
|
||||
<button class="btn btn-success btn-sm me-1" @onclick="SaveRecipient">Add</button>
|
||||
<button class="btn btn-outline-secondary btn-sm" @onclick="() => _showRecipientForm = false">Cancel</button></div>
|
||||
</div>
|
||||
@if (_recipientFormError != null) { <div class="text-danger small mt-1">@_recipientFormError</div> }
|
||||
</div></div>
|
||||
}
|
||||
|
||||
@foreach (var list in _notificationLists)
|
||||
{
|
||||
<div class="card mb-2">
|
||||
<div class="card-header d-flex justify-content-between align-items-center py-2">
|
||||
<strong>@list.Name</strong>
|
||||
<div>
|
||||
<button class="btn btn-outline-info btn-sm py-0 px-1 me-1" @onclick="() => { _showRecipientForm = true; _recipientListId = list.Id; _recipientName = _recipientEmail = string.Empty; _recipientFormError = null; }">+ Recipient</button>
|
||||
<button class="btn btn-outline-primary btn-sm py-0 px-1 me-1" @onclick='() => NavigationManager.NavigateTo($"/design/notification-lists/{list.Id}/edit")'>Edit</button>
|
||||
<button class="btn btn-outline-danger btn-sm py-0 px-1" @onclick="() => DeleteNotifList(list)">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -344,7 +215,6 @@
|
||||
{
|
||||
<span class="badge bg-light text-dark me-1 mb-1">
|
||||
@r.Name <@r.EmailAddress>
|
||||
<button type="button" class="btn-close ms-1" style="font-size: 0.5rem;" @onclick="() => DeleteRecipient(r)"></button>
|
||||
</span>
|
||||
}
|
||||
}
|
||||
@@ -353,19 +223,6 @@
|
||||
}
|
||||
};
|
||||
|
||||
private async Task SaveNotifList()
|
||||
{
|
||||
_notifFormError = null;
|
||||
if (string.IsNullOrWhiteSpace(_notifName)) { _notifFormError = "Name required."; return; }
|
||||
try
|
||||
{
|
||||
if (_editingNotifList != null) { _editingNotifList.Name = _notifName.Trim(); await NotificationRepository.UpdateNotificationListAsync(_editingNotifList); }
|
||||
else { var nl = new NotificationList(_notifName.Trim()); await NotificationRepository.AddNotificationListAsync(nl); }
|
||||
await NotificationRepository.SaveChangesAsync(); _showNotifForm = false; _toast.ShowSuccess("Saved."); await LoadAllAsync();
|
||||
}
|
||||
catch (Exception ex) { _notifFormError = ex.Message; }
|
||||
}
|
||||
|
||||
private async Task DeleteNotifList(NotificationList list)
|
||||
{
|
||||
if (!await _confirmDialog.ShowAsync($"Delete notification list '{list.Name}'?", "Delete")) return;
|
||||
@@ -373,54 +230,14 @@
|
||||
catch (Exception ex) { _toast.ShowError(ex.Message); }
|
||||
}
|
||||
|
||||
private async Task SaveRecipient()
|
||||
{
|
||||
_recipientFormError = null;
|
||||
if (string.IsNullOrWhiteSpace(_recipientName) || string.IsNullOrWhiteSpace(_recipientEmail)) { _recipientFormError = "Name and email required."; return; }
|
||||
try
|
||||
{
|
||||
var r = new NotificationRecipient(_recipientName.Trim(), _recipientEmail.Trim()) { NotificationListId = _recipientListId };
|
||||
await NotificationRepository.AddRecipientAsync(r); await NotificationRepository.SaveChangesAsync();
|
||||
_showRecipientForm = false; _toast.ShowSuccess("Recipient added."); await LoadAllAsync();
|
||||
}
|
||||
catch (Exception ex) { _recipientFormError = ex.Message; }
|
||||
}
|
||||
|
||||
private async Task DeleteRecipient(NotificationRecipient r)
|
||||
{
|
||||
try { await NotificationRepository.DeleteRecipientAsync(r.Id); await NotificationRepository.SaveChangesAsync(); _toast.ShowSuccess("Removed."); await LoadAllAsync(); }
|
||||
catch (Exception ex) { _toast.ShowError(ex.Message); }
|
||||
}
|
||||
|
||||
// ==== Inbound API Methods ====
|
||||
private RenderFragment RenderInboundApiMethods() => __builder =>
|
||||
{
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<h6 class="mb-0">Inbound API Methods</h6>
|
||||
<button class="btn btn-primary btn-sm" @onclick="() => { _showApiMethodForm = true; _editingApiMethod = null; _apiMethodName = _apiMethodScript = string.Empty; _apiMethodTimeout = 30; _apiMethodParams = _apiMethodReturn = null; _apiMethodFormError = null; }">Add Method</button>
|
||||
<button class="btn btn-primary btn-sm" @onclick='() => NavigationManager.NavigateTo("/design/api-methods/create")'>Add Method</button>
|
||||
</div>
|
||||
|
||||
@if (_showApiMethodForm)
|
||||
{
|
||||
<div class="card mb-2"><div class="card-body">
|
||||
<div class="row g-2">
|
||||
<div class="col-md-3"><label class="form-label small">Name</label><input type="text" class="form-control form-control-sm" @bind="_apiMethodName" disabled="@(_editingApiMethod != null)" /></div>
|
||||
<div class="col-md-2"><label class="form-label small">Timeout (s)</label><input type="number" class="form-control form-control-sm" @bind="_apiMethodTimeout" /></div>
|
||||
<div class="col-md-3"><label class="form-label small">Params (JSON)</label><input type="text" class="form-control form-control-sm" @bind="_apiMethodParams" /></div>
|
||||
<div class="col-md-3"><label class="form-label small">Returns (JSON)</label><input type="text" class="form-control form-control-sm" @bind="_apiMethodReturn" /></div>
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
<label class="form-label small">Script</label>
|
||||
<textarea class="form-control form-control-sm font-monospace" rows="5" @bind="_apiMethodScript" style="font-size: 0.8rem;"></textarea>
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
<button class="btn btn-success btn-sm me-1" @onclick="SaveApiMethod">Save</button>
|
||||
<button class="btn btn-outline-secondary btn-sm" @onclick="() => _showApiMethodForm = false">Cancel</button>
|
||||
</div>
|
||||
@if (_apiMethodFormError != null) { <div class="text-danger small mt-1">@_apiMethodFormError</div> }
|
||||
</div></div>
|
||||
}
|
||||
|
||||
<table class="table table-sm table-striped">
|
||||
<thead class="table-dark"><tr><th>Name</th><th>Timeout</th><th>Script (preview)</th><th style="width:120px;">Actions</th></tr></thead>
|
||||
<tbody>
|
||||
@@ -431,7 +248,7 @@
|
||||
<td>@m.TimeoutSeconds s</td>
|
||||
<td class="small font-monospace text-truncate" style="max-width:300px;">@m.Script[..Math.Min(60, m.Script.Length)]</td>
|
||||
<td>
|
||||
<button class="btn btn-outline-primary btn-sm py-0 px-1 me-1" @onclick="() => { _editingApiMethod = m; _apiMethodName = m.Name; _apiMethodScript = m.Script; _apiMethodTimeout = m.TimeoutSeconds; _apiMethodParams = m.ParameterDefinitions; _apiMethodReturn = m.ReturnDefinition; _showApiMethodForm = true; }">Edit</button>
|
||||
<button class="btn btn-outline-primary btn-sm py-0 px-1 me-1" @onclick='() => NavigationManager.NavigateTo($"/design/api-methods/{m.Id}/edit")'>Edit</button>
|
||||
<button class="btn btn-outline-danger btn-sm py-0 px-1" @onclick="() => DeleteApiMethod(m)">Delete</button>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -440,19 +257,6 @@
|
||||
</table>
|
||||
};
|
||||
|
||||
private async Task SaveApiMethod()
|
||||
{
|
||||
_apiMethodFormError = null;
|
||||
if (string.IsNullOrWhiteSpace(_apiMethodName) || string.IsNullOrWhiteSpace(_apiMethodScript)) { _apiMethodFormError = "Name and script required."; return; }
|
||||
try
|
||||
{
|
||||
if (_editingApiMethod != null) { _editingApiMethod.Script = _apiMethodScript; _editingApiMethod.TimeoutSeconds = _apiMethodTimeout; _editingApiMethod.ParameterDefinitions = _apiMethodParams?.Trim(); _editingApiMethod.ReturnDefinition = _apiMethodReturn?.Trim(); await InboundApiRepository.UpdateApiMethodAsync(_editingApiMethod); }
|
||||
else { var m = new ApiMethod(_apiMethodName.Trim(), _apiMethodScript) { TimeoutSeconds = _apiMethodTimeout, ParameterDefinitions = _apiMethodParams?.Trim(), ReturnDefinition = _apiMethodReturn?.Trim() }; await InboundApiRepository.AddApiMethodAsync(m); }
|
||||
await InboundApiRepository.SaveChangesAsync(); _showApiMethodForm = false; _toast.ShowSuccess("Saved."); await LoadAllAsync();
|
||||
}
|
||||
catch (Exception ex) { _apiMethodFormError = ex.Message; }
|
||||
}
|
||||
|
||||
private async Task DeleteApiMethod(ApiMethod m)
|
||||
{
|
||||
if (!await _confirmDialog.ShowAsync($"Delete API method '{m.Name}'?", "Delete")) return;
|
||||
|
||||
Reference in New Issue
Block a user