@inject UpdateServiceUseCase UpdateUseCase @inject IGetResourceByNameUseCase GetByNameUseCase @inject IDeleteResourceUseCase DeleteUseCase @inject ICloneResourceUseCase CloneUseCase @inject IRenameResourceUseCase RenameUseCase @inject NavigationManager Nav
@Service.Name
@if (!_isEditing) { } else { }
IP
@if (_isEditing) { } else if (!string.IsNullOrWhiteSpace(Service.Network?.Ip)) {
@Service.Network!.Ip
}
Port
@if (_isEditing) { } else if (Service.Network?.Port.HasValue == true) { var href = GetBrowsableHref(); if (href is not null) { @Service.Network.Port } else {
@Service.Network.Port
} }
Protocol
@if (_isEditing) { } else if (!string.IsNullOrWhiteSpace(Service.Network?.Protocol)) {
@Service.Network!.Protocol
}
URL
@if (_isEditing) { } else if (!string.IsNullOrWhiteSpace(Service.Network?.Url)) { @Service.Network.Url }
Runs On
@if (_isEditing) { @if (Service.RunsOn?.Count > 0) { @foreach(var parent in Service.RunsOn) { } } } else if (Service.RunsOn?.Count > 0) { @foreach(var parent in Service.RunsOn) { @parent } }
Notes
@if (_isEditing) { } else { }
Are you sure you want to delete @Service.Name? @code { bool _cloneOpen; void OpenClone() { _cloneOpen = true; } async Task HandleCloneSubmit(string newName) { await CloneUseCase.ExecuteAsync(Service.Name, newName); Nav.NavigateTo($"resources/services/{Uri.EscapeDataString(newName)}"); } } @code { [Parameter] [EditorRequired] public Service Service { get; set; } = default!; [Parameter] public EventCallback OnSave { get; set; } private bool _isEditing; private ServiceEditModel _edit = new(); void BeginEdit() { _edit = ServiceEditModel.From(Service); _isEditing = true; } async Task Save() { _isEditing = false; await UpdateUseCase.ExecuteAsync( _edit.Name, _edit.Ip, _edit.Port, _edit.Protocol, _edit.Url, _edit.RunsOn, _edit.Notes ); await OnSave.InvokeAsync(Service.Name); } void Cancel() { _isEditing = false; } bool _selectParentOpen; string? SelectedParentName; async Task HandleParentSelected(string? name) { SelectedParentName = name; var runsOn = (_isEditing ? _edit.RunsOn : Service.RunsOn) ?? new List(); runsOn = runsOn.Where(x => !string.IsNullOrWhiteSpace(x)).ToList(); if (!string.IsNullOrWhiteSpace(name) && !runsOn.Contains(name)) runsOn.Add(name); var ip = _isEditing ? _edit.Ip : Service.Network?.Ip; var port = _isEditing ? _edit.Port : Service.Network?.Port; var protocol = _isEditing ? _edit.Protocol : Service.Network?.Protocol; var url = _isEditing ? _edit.Url : Service.Network?.Url; var notes = _isEditing ? _edit.Notes : Service.Notes; await UpdateUseCase.ExecuteAsync(Service.Name, ip, port, protocol, url, runsOn, notes); // Refresh service from backend (optional, but if you do it, DO NOT nuke the edit buffer) Service = await GetByNameUseCase.ExecuteAsync(Service.Name); if (_isEditing) { // keep whatever the user typed; just sync RunsOn _edit.RunsOn = runsOn; } else { _edit = ServiceEditModel.From(Service); } } async Task HandleParentDeleted(string? name) { if (string.IsNullOrWhiteSpace(name)) return; SelectedParentName = name; var runsOn = (_isEditing ? _edit.RunsOn : Service.RunsOn) ?? new List(); runsOn = runsOn.Where(x => !string.IsNullOrWhiteSpace(x) && x != name).ToList(); var ip = _isEditing ? _edit.Ip : Service.Network?.Ip; var port = _isEditing ? _edit.Port : Service.Network?.Port; var protocol = _isEditing ? _edit.Protocol : Service.Network?.Protocol; var url = _isEditing ? _edit.Url : Service.Network?.Url; var notes = _isEditing ? _edit.Notes : Service.Notes; await UpdateUseCase.ExecuteAsync(Service.Name, ip, port, protocol, url, runsOn, notes); Service = await GetByNameUseCase.ExecuteAsync(Service.Name); if (_isEditing) _edit.RunsOn = runsOn; else _edit = ServiceEditModel.From(Service); } } @code { private bool _confirmDeleteOpen; [Parameter] public EventCallback OnDeleted { get; set; } void ConfirmDelete() { _confirmDeleteOpen = true; } async Task DeleteServer() { _confirmDeleteOpen = false; await DeleteUseCase.ExecuteAsync(Service.Name); if (OnDeleted.HasDelegate) await OnDeleted.InvokeAsync(Service.Name); } } @code { bool _renameOpen; void OpenRename() { _renameOpen = true; } async Task HandleRenameSubmit(string newName) { await RenameUseCase.ExecuteAsync(Service.Name, newName); Nav.NavigateTo($"resources/services/{Uri.EscapeDataString(newName)}"); } private string? GetBrowsableHref() { var ip = Service.Network?.Ip; var port = Service.Network?.Port; if (string.IsNullOrWhiteSpace(ip) || port is null) return null; var proto = Service.Network?.Protocol?.Trim().ToLowerInvariant(); var scheme = proto switch { "https" => "https", "http" => "http", _ => "http" }; // Build a correct absolute URL var ub = new UriBuilder(scheme, ip) { Port = port.Value }; return ub.Uri.ToString(); } }