Files
marechai/Marechai.App/Presentation/ViewModels/ComputersViewModel.cs

207 lines
7.1 KiB
C#
Raw Normal View History

2025-11-14 20:59:12 +00:00
using System;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using System.Windows.Input;
using Marechai.App.Services;
using Uno.Extensions.Navigation;
2025-11-15 02:46:54 +00:00
namespace Marechai.App.Presentation.ViewModels;
2025-11-14 20:59:12 +00:00
public partial class ComputersViewModel : ObservableObject
{
private readonly ComputersService _computersService;
2025-11-15 01:09:30 +00:00
private readonly IComputersListFilterContext _filterContext;
2025-11-14 20:59:12 +00:00
private readonly IStringLocalizer _localizer;
private readonly ILogger<ComputersViewModel> _logger;
private readonly INavigator _navigator;
[ObservableProperty]
private int computerCount;
[ObservableProperty]
private string computerCountText = string.Empty;
[ObservableProperty]
private string errorMessage = string.Empty;
[ObservableProperty]
private bool hasError;
[ObservableProperty]
private bool isDataLoaded;
[ObservableProperty]
private bool isLoading;
[ObservableProperty]
2025-11-15 02:38:47 +00:00
private ObservableCollection<char> lettersList = [];
2025-11-14 20:59:12 +00:00
[ObservableProperty]
private int maximumYear;
[ObservableProperty]
private int minimumYear;
[ObservableProperty]
private string yearsGridTitle = string.Empty;
[ObservableProperty]
2025-11-15 02:38:47 +00:00
private ObservableCollection<int> yearsList = [];
2025-11-14 20:59:12 +00:00
public ComputersViewModel(ComputersService computersService, IStringLocalizer localizer,
2025-11-15 01:09:30 +00:00
ILogger<ComputersViewModel> logger, INavigator navigator,
IComputersListFilterContext filterContext)
2025-11-14 20:59:12 +00:00
{
_computersService = computersService;
_localizer = localizer;
_logger = logger;
_navigator = navigator;
2025-11-15 01:09:30 +00:00
_filterContext = filterContext;
2025-11-14 20:59:12 +00:00
LoadData = new AsyncRelayCommand(LoadDataAsync);
GoBackCommand = new AsyncRelayCommand(GoBackAsync);
NavigateByLetterCommand = new AsyncRelayCommand<char>(NavigateByLetterAsync);
NavigateByYearCommand = new AsyncRelayCommand<int>(NavigateByYearAsync);
NavigateAllComputersCommand = new AsyncRelayCommand(NavigateAllComputersAsync);
InitializeLetters();
}
public IAsyncRelayCommand LoadData { get; }
public ICommand GoBackCommand { get; }
public IAsyncRelayCommand<char> NavigateByLetterCommand { get; }
public IAsyncRelayCommand<int> NavigateByYearCommand { get; }
public IAsyncRelayCommand NavigateAllComputersCommand { get; }
public string Title { get; } = "Computers";
/// <summary>
/// Initializes the alphabet list (A-Z)
/// </summary>
private void InitializeLetters()
{
LettersList.Clear();
for(var c = 'A'; c <= 'Z'; c++) LettersList.Add(c);
}
/// <summary>
/// Loads computers count, minimum and maximum years from the API
/// </summary>
private async Task LoadDataAsync()
{
try
{
IsLoading = true;
ErrorMessage = string.Empty;
HasError = false;
IsDataLoaded = false;
YearsList.Clear();
// Load all data in parallel for better performance
Task<int> countTask = _computersService.GetComputersCountAsync();
Task<int> minYearTask = _computersService.GetMinimumYearAsync();
Task<int> maxYearTask = _computersService.GetMaximumYearAsync();
await Task.WhenAll(countTask, minYearTask, maxYearTask);
ComputerCount = countTask.Result;
MinimumYear = minYearTask.Result;
MaximumYear = maxYearTask.Result;
// Update display text
ComputerCountText = _localizer["Computers in the database"];
// Generate years list
if(MinimumYear > 0 && MaximumYear > 0)
{
for(int year = MinimumYear; year <= MaximumYear; year++) YearsList.Add(year);
YearsGridTitle = $"Browse by Year ({MinimumYear} - {MaximumYear})";
}
if(ComputerCount == 0)
{
ErrorMessage = _localizer["No computers found"].Value;
HasError = true;
}
else
IsDataLoaded = true;
}
catch(Exception ex)
{
_logger.LogError("Error loading computers data: {Exception}", ex.Message);
ErrorMessage = _localizer["Failed to load computers data. Please try again later."].Value;
HasError = true;
}
finally
{
IsLoading = false;
}
}
/// <summary>
/// Handles back navigation
/// </summary>
private async Task GoBackAsync()
{
await _navigator.NavigateViewModelAsync<MainViewModel>(this);
}
/// <summary>
/// Navigates to computers filtered by letter
/// </summary>
private async Task NavigateByLetterAsync(char letter)
{
2025-11-15 01:09:30 +00:00
try
{
_logger.LogInformation("Navigating to computers by letter: {Letter}", letter);
_filterContext.FilterType = ComputerListFilterType.Letter;
_filterContext.FilterValue = letter.ToString();
await _navigator.NavigateViewModelAsync<ComputersListViewModel>(this);
}
catch(Exception ex)
{
_logger.LogError("Error navigating to letter computers: {Exception}", ex.Message);
ErrorMessage = _localizer["Failed to navigate. Please try again."].Value;
HasError = true;
}
2025-11-14 20:59:12 +00:00
}
/// <summary>
/// Navigates to computers filtered by year
/// </summary>
private async Task NavigateByYearAsync(int year)
{
2025-11-15 01:09:30 +00:00
try
{
_logger.LogInformation("Navigating to computers by year: {Year}", year);
_filterContext.FilterType = ComputerListFilterType.Year;
_filterContext.FilterValue = year.ToString();
await _navigator.NavigateViewModelAsync<ComputersListViewModel>(this);
}
catch(Exception ex)
{
_logger.LogError("Error navigating to year computers: {Exception}", ex.Message);
ErrorMessage = _localizer["Failed to navigate. Please try again."].Value;
HasError = true;
}
2025-11-14 20:59:12 +00:00
}
/// <summary>
/// Navigates to all computers view
/// </summary>
private async Task NavigateAllComputersAsync()
{
2025-11-15 01:09:30 +00:00
try
{
_logger.LogInformation("Navigating to all computers");
_filterContext.FilterType = ComputerListFilterType.All;
_filterContext.FilterValue = string.Empty;
await _navigator.NavigateViewModelAsync<ComputersListViewModel>(this);
}
catch(Exception ex)
{
_logger.LogError("Error navigating to all computers: {Exception}", ex.Message);
ErrorMessage = _localizer["Failed to navigate. Please try again."].Value;
HasError = true;
}
2025-11-14 20:59:12 +00:00
}
}