@using RackPeek.Domain.Persistence @using RackPeek.Domain.Resources @using RackPeek.Domain.Resources.SubResources @using RackPeek.Domain.Resources.SystemResources @using RackPeek.Domain.Resources.SystemResources.UseCases @using RackPeek.Domain.UseCases.Drives @inject UpdateSystemUseCase UpdateUseCase @inject IGetResourceByNameUseCase GetByNameUseCase @inject IAddDriveUseCase AddDriveUseCase @inject IUpdateDriveUseCase UpdateDriveUseCase @inject IRemoveDriveUseCase RemoveDriveUseCase @inject IDeleteResourceUseCase DeleteUseCase @inject ICloneResourceUseCase CloneUseCase @inject NavigationManager Nav @inject IRenameResourceUseCase RenameUseCase @inject IResourceCollection ResourceCollection
@System.Name
@if (!_isEditing) { } else { }
Type
@if (_isEditing) { } else if (!string.IsNullOrWhiteSpace(System.Type)) {
@System.Type
}
OS
@if (_isEditing) { } else if (!string.IsNullOrWhiteSpace(System.Os)) {
@System.Os
}
Cores
@if (_isEditing) { } else if (System.Cores.HasValue) {
@System.Cores
}
RAM (GB)
@if (_isEditing) { } else if (System.Ram.HasValue) {
@System.Ram GB
}
IP Address
@if (_isEditing) { } else if (!string.IsNullOrWhiteSpace(EffectiveIp)) {
@EffectiveIp @if (string.IsNullOrWhiteSpace(System.Ip)) { (inherited) }
}
Runs On
@if (System.RunsOn?.Count > 0) { @foreach (var parent in System.RunsOn) { var kind = (_parentKinds.GetValueOrDefault(parent) ?? "").Trim().ToLower(); var url = "#"; if (Resource.IsHardware(kind)) { url = $"resources/hardware/{Uri.EscapeDataString(parent)}"; } else if (kind == "system") { url = $"resources/systems/{Uri.EscapeDataString(parent)}"; } @parent @if (_isEditing) { } } }
Drives
@if (System.Drives?.Any() == true) { @foreach (var drive in System.Drives) {
} }
Notes
@if (_isEditing) { } else { }
Are you sure you want to delete @System.Name?
This will detach all dependent systems.
@code { [Parameter] [EditorRequired] public SystemResource System { get; set; } = default!; [Parameter] public EventCallback OnSave { get; set; } private bool _isEditing; private SystemEditModel _edit = new(); void BeginEdit() { _edit = SystemEditModel.From(System); _isEditing = true; } async Task Save() { _isEditing = false; await OnSave.InvokeAsync(_edit); } void Cancel() { _isEditing = false; } bool _selectParentOpen; string? SelectedParentName; private readonly Dictionary _parentKinds = new(); protected override async Task OnParametersSetAsync() { await RefreshParentKinds(); await ResolveEffectiveIp(); } private async Task RefreshParentKinds() { _parentKinds.Clear(); foreach (var parent in System.RunsOn) { var kind = (await ResourceCollection.GetKind(parent))?.ToLower(); _parentKinds[parent] = kind ?? ""; } } async Task HandleParentSelected(string? name) { if (name == System.Name) { return; } SelectedParentName = name; // Start from the edit buffer when editing, otherwise from the persisted model var runsOn = (_isEditing ? _edit.RunsOn : System.RunsOn) ?? new List(); runsOn = runsOn.Where(x => !string.IsNullOrWhiteSpace(x)).ToList(); if (!string.IsNullOrWhiteSpace(name) && !runsOn.Contains(name)) runsOn.Add(name); // IMPORTANT: use _edit values when editing so we don't wipe typed fields var type = _isEditing ? _edit.Type : System.Type; var os = _isEditing ? _edit.Os : System.Os; var cores = _isEditing ? _edit.Cores : System.Cores; var ram = _isEditing ? _edit.Ram : System.Ram; var ip = _isEditing ? _edit.Ip : System.Ip; var notes = _isEditing ? _edit.Notes : System.Notes; await UpdateUseCase.ExecuteAsync( System.Name, type, os, cores, ram, ip, runsOn, notes); System = await GetByNameUseCase.ExecuteAsync(System.Name); if (_isEditing) _edit.RunsOn = runsOn; else _edit = SystemEditModel.From(System); await RefreshParentKinds(); } async Task HandleParentDeleted(string? name) { if (string.IsNullOrWhiteSpace(name)) return; SelectedParentName = name; var runsOn = (_isEditing ? _edit.RunsOn : System.RunsOn) ?? new List(); System.RunsOn = runsOn = runsOn.Where(x => !string.IsNullOrWhiteSpace(x) && x != name).ToList(); var type = _isEditing ? _edit.Type : System.Type; var os = _isEditing ? _edit.Os : System.Os; var cores = _isEditing ? _edit.Cores : System.Cores; var ram = _isEditing ? _edit.Ram : System.Ram; var ip = _isEditing ? _edit.Ip : System.Ip; var notes = _isEditing ? _edit.Notes : System.Notes; await UpdateUseCase.ExecuteAsync( System.Name, type, os, cores, ram, ip, runsOn, notes); System = await GetByNameUseCase.ExecuteAsync(System.Name); if (_isEditing) _edit.RunsOn = runsOn; else _edit = SystemEditModel.From(System); await RefreshParentKinds(); } #region Drives bool _driveModalOpen; int _editingDriveIndex; Drive? _editingDrive; void OpenAddDrive() { _editingDriveIndex = -1; _editingDrive = null; _driveModalOpen = true; } void OpenEditDrives(Drive drive) { _editingDrive = drive; System.Drives ??= new List(); _editingDriveIndex = System.Drives.IndexOf(drive); ; _driveModalOpen = true; } async Task HandleDriveSubmit(Drive drive) { System.Drives ??= new List(); if (_editingDriveIndex < 0) { await AddDriveUseCase.ExecuteAsync(System.Name, drive.Type ?? "hdd", drive.Size ?? 0); } else { await UpdateDriveUseCase.ExecuteAsync(System.Name, _editingDriveIndex, drive.Type ?? "hdd", drive.Size ?? 0); } System = await GetByNameUseCase.ExecuteAsync(System.Name); StateHasChanged(); } async Task HandleDriveDelete(Drive drive) { await RemoveDriveUseCase.ExecuteAsync(System.Name, _editingDriveIndex); System = await GetByNameUseCase.ExecuteAsync(System.Name); StateHasChanged(); } #endregion } @code { private bool _confirmDeleteOpen; [Parameter] public EventCallback OnDeleted { get; set; } void ConfirmDelete() { _confirmDeleteOpen = true; } async Task DeleteServer() { _confirmDeleteOpen = false; await DeleteUseCase.ExecuteAsync(System.Name); if (OnDeleted.HasDelegate) await OnDeleted.InvokeAsync(System.Name); } } @code { bool _cloneOpen; void OpenClone() { _cloneOpen = true; } async Task HandleCloneSubmit(string newName) { await CloneUseCase.ExecuteAsync(System.Name, newName); Nav.NavigateTo($"resources/systems/{Uri.EscapeDataString(newName)}"); } } @code { bool _renameOpen; void OpenRename() { _renameOpen = true; } async Task HandleRenameSubmit(string newName) { await RenameUseCase.ExecuteAsync(System.Name, newName); Nav.NavigateTo($"resources/systems/{Uri.EscapeDataString(newName)}"); } } @code{ private string? EffectiveIp; private async Task ResolveEffectiveIp() { // If system has its own IP, use it if (!string.IsNullOrWhiteSpace(System.Ip)) { EffectiveIp = System.Ip; return; } // Must have exactly one parent if (System.RunsOn?.Count != 1) { EffectiveIp = null; return; } var parentName = System.RunsOn.First(); // Must be a system if (!_parentKinds.TryGetValue(parentName, out var kind) || kind?.ToLower() != "system") { EffectiveIp = null; return; } // Load parent system var parent = await GetByNameUseCase.ExecuteAsync(parentName); EffectiveIp = string.IsNullOrWhiteSpace(parent?.Ip) ? null : parent.Ip; } }