mirror of
https://github.com/claunia/marechai.git
synced 2025-12-16 19:14:25 +00:00
Add list of GPUs.
This commit is contained in:
@@ -14,6 +14,7 @@ using Uno.UI;
|
||||
using CompanyDetailViewModel = Marechai.App.Presentation.ViewModels.CompanyDetailViewModel;
|
||||
using ComputersListViewModel = Marechai.App.Presentation.ViewModels.ComputersListViewModel;
|
||||
using ComputersViewModel = Marechai.App.Presentation.ViewModels.ComputersViewModel;
|
||||
using GpuListViewModel = Marechai.App.Presentation.ViewModels.GpusListViewModel;
|
||||
using MachineViewViewModel = Marechai.App.Presentation.ViewModels.MachineViewViewModel;
|
||||
using MainViewModel = Marechai.App.Presentation.ViewModels.MainViewModel;
|
||||
using NewsViewModel = Marechai.App.Presentation.ViewModels.NewsViewModel;
|
||||
@@ -122,6 +123,7 @@ public partial class App : Application
|
||||
services.AddSingleton<CompanyDetailService>();
|
||||
services.AddSingleton<CompanyDetailViewModel>();
|
||||
services.AddSingleton<MachineViewViewModel>();
|
||||
services.AddSingleton<GpusService>();
|
||||
services.AddTransient<PhotoDetailViewModel>();
|
||||
|
||||
services
|
||||
@@ -134,6 +136,7 @@ public partial class App : Application
|
||||
|
||||
services.AddTransient<ComputersListViewModel>();
|
||||
services.AddTransient<ConsolesListViewModel>();
|
||||
services.AddTransient<GpuListViewModel>();
|
||||
})
|
||||
.UseNavigation(RegisterRoutes));
|
||||
|
||||
@@ -160,6 +163,7 @@ public partial class App : Application
|
||||
new ViewMap<CompanyDetailPage, CompanyDetailViewModel>(),
|
||||
new ViewMap<MachineViewPage, MachineViewViewModel>(),
|
||||
new ViewMap<PhotoDetailPage, PhotoDetailViewModel>(),
|
||||
new ViewMap<GpuListPage, GpuListViewModel>(),
|
||||
new DataViewMap<SecondPage, SecondViewModel, Entity>());
|
||||
|
||||
routes.Register(new RouteMap("",
|
||||
@@ -201,6 +205,15 @@ public partial class App : Application
|
||||
views.FindByViewModel<
|
||||
CompanyDetailViewModel>())
|
||||
]),
|
||||
new RouteMap("gpus",
|
||||
views.FindByViewModel<GpuListViewModel>(),
|
||||
Nested:
|
||||
[
|
||||
new RouteMap("list-gpus",
|
||||
views.FindByViewModel<
|
||||
GpuListViewModel>(),
|
||||
true)
|
||||
]),
|
||||
new RouteMap("Second",
|
||||
views.FindByViewModel<SecondViewModel>())
|
||||
])
|
||||
|
||||
204
Marechai.App/Presentation/ViewModels/GpusListViewModel.cs
Normal file
204
Marechai.App/Presentation/ViewModels/GpusListViewModel.cs
Normal file
@@ -0,0 +1,204 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Threading.Tasks;
|
||||
using Marechai.App.Services;
|
||||
using Uno.Extensions.Navigation;
|
||||
|
||||
namespace Marechai.App.Presentation.ViewModels;
|
||||
|
||||
/// <summary>
|
||||
/// ViewModel for displaying a list of GPUs
|
||||
/// </summary>
|
||||
public partial class GpusListViewModel : ObservableObject
|
||||
{
|
||||
private readonly GpusService _gpusService;
|
||||
private readonly IStringLocalizer _localizer;
|
||||
private readonly ILogger<GpusListViewModel> _logger;
|
||||
private readonly INavigator _navigator;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _errorMessage = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<GpuListItem> _gpusList = [];
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _hasError;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isDataLoaded;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isLoading;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _pageTitle = string.Empty;
|
||||
|
||||
public GpusListViewModel(GpusService gpusService, IStringLocalizer localizer, ILogger<GpusListViewModel> logger,
|
||||
INavigator navigator)
|
||||
{
|
||||
_gpusService = gpusService;
|
||||
_localizer = localizer;
|
||||
_logger = logger;
|
||||
_navigator = navigator;
|
||||
LoadData = new AsyncRelayCommand(LoadDataAsync);
|
||||
NavigateToGpuCommand = new AsyncRelayCommand<GpuListItem>(NavigateToGpuAsync);
|
||||
}
|
||||
|
||||
public IAsyncRelayCommand LoadData { get; }
|
||||
public IAsyncRelayCommand<GpuListItem> NavigateToGpuCommand { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Loads all GPUs and sorts them with special handling for Framebuffer and Software
|
||||
/// </summary>
|
||||
private async Task LoadDataAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
IsLoading = true;
|
||||
ErrorMessage = string.Empty;
|
||||
HasError = false;
|
||||
IsDataLoaded = false;
|
||||
GpusList.Clear();
|
||||
|
||||
_logger.LogInformation("LoadDataAsync called for GPUs");
|
||||
|
||||
PageTitle = _localizer["GraphicalProcessingUnits"];
|
||||
|
||||
// Load GPUs from the API
|
||||
await LoadGpusFromApiAsync();
|
||||
|
||||
_logger.LogInformation("LoadGpusFromApiAsync completed. GpusList.Count={Count}", GpusList.Count);
|
||||
|
||||
if(GpusList.Count == 0)
|
||||
{
|
||||
ErrorMessage = _localizer["No graphics processing units found"].Value;
|
||||
HasError = true;
|
||||
|
||||
_logger.LogWarning("No GPUs found");
|
||||
}
|
||||
else
|
||||
IsDataLoaded = true;
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error loading GPUs: {Exception}", ex.Message);
|
||||
ErrorMessage = _localizer["Failed to load graphics processing units. Please try again later."].Value;
|
||||
HasError = true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
IsLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads GPUs from the API and sorts them with special handling for Framebuffer and Software
|
||||
/// </summary>
|
||||
private async Task LoadGpusFromApiAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
List<GpuDto> gpus = await _gpusService.GetAllGpusAsync();
|
||||
|
||||
if(gpus == null || gpus.Count == 0)
|
||||
{
|
||||
_logger.LogInformation("No GPUs returned from API");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Separate special GPUs from regular ones
|
||||
var specialGpus = new List<GpuListItem>();
|
||||
var regularGpus = new List<GpuListItem>();
|
||||
|
||||
foreach(GpuDto gpu in gpus)
|
||||
{
|
||||
string displayName = gpu.Name ?? string.Empty;
|
||||
|
||||
// Replace special database names
|
||||
if(displayName == "DB_FRAMEBUFFER")
|
||||
displayName = "Framebuffer";
|
||||
else if(displayName == "DB_SOFTWARE")
|
||||
displayName = "Software";
|
||||
else if(displayName == "DB_NONE") displayName = "None";
|
||||
|
||||
var gpuItem = new GpuListItem
|
||||
{
|
||||
Id = gpu.Id ?? 0,
|
||||
Name = displayName,
|
||||
Company = gpu.Company ?? string.Empty,
|
||||
IsSpecial = gpu.Name is "DB_FRAMEBUFFER" or "DB_SOFTWARE" or "DB_NONE"
|
||||
};
|
||||
|
||||
if(gpuItem.IsSpecial)
|
||||
specialGpus.Add(gpuItem);
|
||||
else
|
||||
regularGpus.Add(gpuItem);
|
||||
|
||||
_logger.LogInformation("GPU: {Name}, Company: {Company}, ID: {Id}, IsSpecial: {IsSpecial}",
|
||||
displayName,
|
||||
gpu.Company,
|
||||
gpu.Id,
|
||||
gpuItem.IsSpecial);
|
||||
}
|
||||
|
||||
// Sort special GPUs: Framebuffer first, then Software, then None
|
||||
specialGpus.Sort((a, b) =>
|
||||
{
|
||||
int orderA = a.Name == "Framebuffer"
|
||||
? 0
|
||||
: a.Name == "Software"
|
||||
? 1
|
||||
: 2;
|
||||
|
||||
int orderB = b.Name == "Framebuffer"
|
||||
? 0
|
||||
: b.Name == "Software"
|
||||
? 1
|
||||
: 2;
|
||||
|
||||
return orderA.CompareTo(orderB);
|
||||
});
|
||||
|
||||
// Sort regular GPUs alphabetically
|
||||
regularGpus.Sort((a, b) => string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
// Add special GPUs first, then regular GPUs
|
||||
foreach(GpuListItem gpu in specialGpus) GpusList.Add(gpu);
|
||||
|
||||
foreach(GpuListItem gpu in regularGpus) GpusList.Add(gpu);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error loading GPUs from API");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Navigates to the GPU detail view
|
||||
/// </summary>
|
||||
private async Task NavigateToGpuAsync(GpuListItem? gpu)
|
||||
{
|
||||
if(gpu is null) return;
|
||||
|
||||
_logger.LogInformation("Navigating to GPU detail: {GpuName} (ID: {GpuId})", gpu.Name, gpu.Id);
|
||||
|
||||
// For now, we'll just log it. Implement detail page navigation when ready.
|
||||
// await _navigator.NavigateViewModelAsync<GpuDetailViewModel>(this, data: gpu);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Data model for a GPU in the list
|
||||
/// </summary>
|
||||
public class GpuListItem
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Company { get; set; } = string.Empty;
|
||||
public bool IsSpecial { get; set; }
|
||||
}
|
||||
@@ -47,7 +47,7 @@ public partial class MainViewModel : ObservableObject
|
||||
NavigateToConsolesCommand = new AsyncRelayCommand(() => NavigateTo("consoles"));
|
||||
NavigateToDocumentsCommand = new AsyncRelayCommand(() => NavigateTo("documents"));
|
||||
NavigateToDumpsCommand = new AsyncRelayCommand(() => NavigateTo("dumps"));
|
||||
NavigateToGraphicalProcessingUnitsCommand = new AsyncRelayCommand(() => NavigateTo("gpus"));
|
||||
NavigateToGraphicalProcessingUnitsCommand = new AsyncRelayCommand(() => NavigateTo("gpus/list-gpus"));
|
||||
NavigateToMagazinesCommand = new AsyncRelayCommand(() => NavigateTo("magazines"));
|
||||
NavigateToPeopleCommand = new AsyncRelayCommand(() => NavigateTo("people"));
|
||||
NavigateToProcessorsCommand = new AsyncRelayCommand(() => NavigateTo("processors"));
|
||||
|
||||
207
Marechai.App/Presentation/Views/GpuListPage.xaml
Normal file
207
Marechai.App/Presentation/Views/GpuListPage.xaml
Normal file
@@ -0,0 +1,207 @@
|
||||
<?xml version="1.0"
|
||||
encoding="utf-8"?>
|
||||
|
||||
<Page x:Class="Marechai.App.Presentation.Views.GpuListPage"
|
||||
x:Name="PageRoot"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:utu="using:Uno.Toolkit.UI"
|
||||
NavigationCacheMode="Required"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
|
||||
<Grid utu:SafeArea.Insets="VisibleBounds">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Header -->
|
||||
<utu:NavigationBar Grid.Row="0"
|
||||
Content="Graphics Processing Units">
|
||||
</utu:NavigationBar>
|
||||
|
||||
<!-- Main Content -->
|
||||
<Grid Grid.Row="1">
|
||||
|
||||
<!-- Loading State -->
|
||||
<StackPanel Visibility="{Binding IsLoading}"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"
|
||||
Padding="32"
|
||||
Spacing="16">
|
||||
<ProgressRing IsActive="True"
|
||||
IsIndeterminate="True"
|
||||
Height="64"
|
||||
Width="64"
|
||||
Foreground="{ThemeResource SystemAccentColor}" />
|
||||
<TextBlock Text="Loading graphics processing units..."
|
||||
FontSize="14"
|
||||
TextAlignment="Center"
|
||||
Foreground="{ThemeResource SystemBaseMediumColor}" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- Error State -->
|
||||
<StackPanel Visibility="{Binding HasError}"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"
|
||||
Padding="24"
|
||||
Spacing="16"
|
||||
MaxWidth="400">
|
||||
<InfoBar IsOpen="True"
|
||||
Severity="Error"
|
||||
Title="Unable to Load Graphics Processing Units"
|
||||
Message="{Binding ErrorMessage}"
|
||||
IsClosable="False" />
|
||||
<Button Content="Retry"
|
||||
Command="{Binding LoadData}"
|
||||
HorizontalAlignment="Center"
|
||||
Style="{ThemeResource AccentButtonStyle}" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- GPUs List -->
|
||||
<Grid Visibility="{Binding IsDataLoaded}">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto"
|
||||
HorizontalScrollBarVisibility="Disabled">
|
||||
<Grid Padding="8">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" /> <RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Count Header -->
|
||||
<StackPanel Grid.Row="0"
|
||||
Padding="16,12"
|
||||
Orientation="Horizontal"
|
||||
Spacing="4">
|
||||
<TextBlock FontSize="12"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{ThemeResource SystemBaseMediumColor}"
|
||||
Text="RESULTS:" />
|
||||
<TextBlock FontSize="12"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{ThemeResource SystemBaseMediumColor}"
|
||||
Text="{Binding GpusList.Count}" />
|
||||
<TextBlock FontSize="12"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{ThemeResource SystemBaseMediumColor}"
|
||||
Text="graphics processing units" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- GPUs List -->
|
||||
<ItemsControl Grid.Row="1"
|
||||
ItemsSource="{Binding GpusList}"
|
||||
Padding="0"
|
||||
Margin="0,8,0,0"
|
||||
HorizontalAlignment="Stretch">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Vertical"
|
||||
Spacing="0"
|
||||
HorizontalAlignment="Stretch" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Button Padding="0"
|
||||
Margin="0,0,0,8"
|
||||
MinHeight="80"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
VerticalContentAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch"
|
||||
Command="{Binding DataContext.NavigateToGpuCommand, ElementName=PageRoot}"
|
||||
CommandParameter="{Binding}"
|
||||
Background="Transparent"
|
||||
BorderThickness="0">
|
||||
<Button.Template>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Grid MinHeight="80"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch">
|
||||
<!-- Shadow effect -->
|
||||
<Border x:Name="ShadowBorder"
|
||||
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
|
||||
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="8"
|
||||
Padding="16,12"
|
||||
Translation="0, 0, 4"
|
||||
VerticalAlignment="Stretch">
|
||||
<Border.Shadow>
|
||||
<ThemeShadow />
|
||||
</Border.Shadow>
|
||||
|
||||
<Grid ColumnSpacing="16">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- GPU Info -->
|
||||
<StackPanel Grid.Column="0"
|
||||
Spacing="8"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Stretch">
|
||||
<TextBlock Text="{Binding Name}"
|
||||
FontSize="16"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{ThemeResource TextControlForeground}"
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="6"
|
||||
VerticalAlignment="Center">
|
||||
<FontIcon Glyph=""
|
||||
FontSize="14"
|
||||
Foreground="{ThemeResource SystemAccentColor}" />
|
||||
<TextBlock Text="{Binding Company}"
|
||||
FontSize="13"
|
||||
Foreground="{ThemeResource SystemBaseMediumColor}"
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Navigation Arrow -->
|
||||
<StackPanel Grid.Column="1"
|
||||
VerticalAlignment="Center">
|
||||
<FontIcon Glyph=""
|
||||
FontSize="18"
|
||||
Foreground="{ThemeResource SystemAccentColor}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="PointerOver">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="ShadowBorder.Background"
|
||||
Value="{ThemeResource CardBackgroundFillColorSecondaryBrush}" />
|
||||
<Setter Target="ShadowBorder.Translation"
|
||||
Value="0, -2, 8" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Pressed">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="ShadowBorder.Background"
|
||||
Value="{ThemeResource CardBackgroundFillColorTertiaryBrush}" />
|
||||
<Setter Target="ShadowBorder.Translation"
|
||||
Value="0, 0, 2" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Button.Template>
|
||||
</Button>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
|
||||
</Page>
|
||||
37
Marechai.App/Presentation/Views/GpuListPage.xaml.cs
Normal file
37
Marechai.App/Presentation/Views/GpuListPage.xaml.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using Marechai.App.Presentation.ViewModels;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
|
||||
namespace Marechai.App.Presentation.Views;
|
||||
|
||||
/// <summary>
|
||||
/// Professional list view for displaying all graphics processing units.
|
||||
/// Features responsive layout, modern styling, and special handling for Framebuffer and Software entries.
|
||||
/// </summary>
|
||||
public sealed partial class GpuListPage : Page
|
||||
{
|
||||
public GpuListPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
Loaded += GpuListPage_Loaded;
|
||||
DataContextChanged += GpuListPage_DataContextChanged;
|
||||
}
|
||||
|
||||
private void GpuListPage_DataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args)
|
||||
{
|
||||
if(DataContext is GpusListViewModel vm)
|
||||
{
|
||||
// Load data when DataContext is set
|
||||
vm.LoadData.Execute(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void GpuListPage_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if(DataContext is GpusListViewModel vm)
|
||||
{
|
||||
// Load data when page is loaded (fallback)
|
||||
vm.LoadData.Execute(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
75
Marechai.App/Services/GpusService.cs
Normal file
75
Marechai.App/Services/GpusService.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Marechai.App.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Service for fetching and managing GPUs from the Marechai API
|
||||
/// </summary>
|
||||
public class GpusService
|
||||
{
|
||||
private readonly ApiClient _apiClient;
|
||||
private readonly ILogger<GpusService> _logger;
|
||||
|
||||
public GpusService(ApiClient apiClient, ILogger<GpusService> logger)
|
||||
{
|
||||
_apiClient = apiClient;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches all GPUs from the API
|
||||
/// </summary>
|
||||
public async Task<List<GpuDto>> GetAllGpusAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("Fetching all GPUs from API");
|
||||
|
||||
List<GpuDto> gpus = await _apiClient.Gpus.GetAsync();
|
||||
|
||||
if(gpus == null) return [];
|
||||
|
||||
_logger.LogInformation("Successfully fetched {Count} total GPUs", gpus.Count);
|
||||
|
||||
return gpus;
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error fetching all GPUs from API");
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches a single GPU by ID from the API
|
||||
/// </summary>
|
||||
public async Task<GpuDto?> GetGpuByIdAsync(int gpuId)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("Fetching GPU {GpuId} from API", gpuId);
|
||||
|
||||
GpuDto? gpu = await _apiClient.Gpus[gpuId].GetAsync();
|
||||
|
||||
if(gpu == null)
|
||||
{
|
||||
_logger.LogWarning("GPU {GpuId} not found", gpuId);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
_logger.LogInformation("Successfully fetched GPU {GpuId}: {GpuName}", gpuId, gpu.Name);
|
||||
|
||||
return gpu;
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error fetching GPU {GpuId} from API", gpuId);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user