Add computer list.

This commit is contained in:
2025-11-15 01:09:30 +00:00
parent b18396f8d8
commit 61ebf7b503
7 changed files with 169 additions and 46 deletions

View File

@@ -102,6 +102,12 @@ public partial class App : Application
services.AddSingleton<NewsViewModel>();
services.AddSingleton<ComputersService>();
services.AddSingleton<ComputersViewModel>();
services
.AddSingleton<IComputersListFilterContext,
ComputersListFilterContext>();
services.AddTransient<ComputersListViewModel>();
})
.UseNavigation(RegisterRoutes));
@@ -121,6 +127,7 @@ public partial class App : Application
new ViewMap<MainPage, MainViewModel>(),
new ViewMap<NewsPage, NewsViewModel>(),
new ViewMap<ComputersPage, ComputersViewModel>(),
new ViewMap<ComputersListPage, ComputersListViewModel>(),
new DataViewMap<SecondPage, SecondViewModel, Entity>());
routes.Register(new RouteMap("",
@@ -136,7 +143,13 @@ public partial class App : Application
views.FindByViewModel<NewsViewModel>(),
true),
new RouteMap("computers",
views.FindByViewModel<ComputersViewModel>()),
views.FindByViewModel<ComputersViewModel>(),
Nested:
[
new RouteMap("list",
views.FindByViewModel<
ComputersListViewModel>())
]),
new RouteMap("Second",
views.FindByViewModel<SecondViewModel>())
])

View File

@@ -10,6 +10,7 @@ namespace Marechai.App.Presentation;
public partial class ComputersViewModel : ObservableObject
{
private readonly ComputersService _computersService;
private readonly IComputersListFilterContext _filterContext;
private readonly IStringLocalizer _localizer;
private readonly ILogger<ComputersViewModel> _logger;
private readonly INavigator _navigator;
@@ -48,12 +49,14 @@ public partial class ComputersViewModel : ObservableObject
private ObservableCollection<int> yearsList = new();
public ComputersViewModel(ComputersService computersService, IStringLocalizer localizer,
ILogger<ComputersViewModel> logger, INavigator navigator)
ILogger<ComputersViewModel> logger, INavigator navigator,
IComputersListFilterContext filterContext)
{
_computersService = computersService;
_localizer = localizer;
_logger = logger;
_navigator = navigator;
_filterContext = filterContext;
LoadData = new AsyncRelayCommand(LoadDataAsync);
GoBackCommand = new AsyncRelayCommand(GoBackAsync);
NavigateByLetterCommand = new AsyncRelayCommand<char>(NavigateByLetterAsync);
@@ -146,32 +149,59 @@ public partial class ComputersViewModel : ObservableObject
/// Navigates to computers filtered by letter
/// </summary>
private async Task NavigateByLetterAsync(char letter)
{
try
{
_logger.LogInformation("Navigating to computers by letter: {Letter}", letter);
// TODO: Implement navigation to letter-filtered view
await Task.CompletedTask;
_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;
}
}
/// <summary>
/// Navigates to computers filtered by year
/// </summary>
private async Task NavigateByYearAsync(int year)
{
try
{
_logger.LogInformation("Navigating to computers by year: {Year}", year);
// TODO: Implement navigation to year-filtered view
await Task.CompletedTask;
_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;
}
}
/// <summary>
/// Navigates to all computers view
/// </summary>
private async Task NavigateAllComputersAsync()
{
try
{
_logger.LogInformation("Navigating to all computers");
// TODO: Implement navigation to all computers view
await Task.CompletedTask;
_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;
}
}
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Kiota.Abstractions.Serialization;
@@ -118,4 +119,81 @@ public class ComputersService
return 0;
}
}
/// <summary>
/// Fetches computers filtered by starting letter from the API
/// </summary>
public async Task<List<MachineDto>> GetComputersByLetterAsync(char letter)
{
try
{
_logger.LogInformation("Fetching computers starting with '{Letter}' from API", letter);
List<MachineDto> computers = await _apiClient.Computers.ByLetter[letter.ToString()].GetAsync();
if(computers == null) return new List<MachineDto>();
_logger.LogInformation("Successfully fetched {Count} computers starting with '{Letter}'",
computers.Count,
letter);
return computers;
}
catch(Exception ex)
{
_logger.LogError(ex, "Error fetching computers by letter '{Letter}' from API", letter);
return new List<MachineDto>();
}
}
/// <summary>
/// Fetches computers filtered by year from the API
/// </summary>
public async Task<List<MachineDto>> GetComputersByYearAsync(int year)
{
try
{
_logger.LogInformation("Fetching computers from year {Year} from API", year);
List<MachineDto> computers = await _apiClient.Computers.ByYear[year].GetAsync();
if(computers == null) return new List<MachineDto>();
_logger.LogInformation("Successfully fetched {Count} computers from year {Year}", computers.Count, year);
return computers;
}
catch(Exception ex)
{
_logger.LogError(ex, "Error fetching computers by year {Year} from API", year);
return new List<MachineDto>();
}
}
/// <summary>
/// Fetches all computers from the API
/// </summary>
public async Task<List<MachineDto>> GetAllComputersAsync()
{
try
{
_logger.LogInformation("Fetching all computers from API");
List<MachineDto> computers = await _apiClient.Computers.GetAsync();
if(computers == null) return new List<MachineDto>();
_logger.LogInformation("Successfully fetched {Count} total computers", computers.Count);
return computers;
}
catch(Exception ex)
{
_logger.LogError(ex, "Error fetching all computers from API");
return new List<MachineDto>();
}
}
}

View File

@@ -3,6 +3,7 @@
"Environment": "Production"
},
"ApiClient": {
"Url": "http://localhost:5023",
"UseNativeHandler": true
},
"LocalizationConfiguration": {

View File

@@ -80,7 +80,8 @@ public class ComputersController(MarechaiContext context) : ControllerBase
{
Id = m.Id,
Name = m.Name,
Company = m.Company.Name
Company = m.Company.Name,
Introduced = m.Introduced
})
.ToListAsync();
@@ -99,7 +100,8 @@ public class ComputersController(MarechaiContext context) : ControllerBase
{
Id = m.Id,
Name = m.Name,
Company = m.Company.Name
Company = m.Company.Name,
Introduced = m.Introduced
})
.ToListAsync();
@@ -115,7 +117,8 @@ public class ComputersController(MarechaiContext context) : ControllerBase
{
Id = m.Id,
Name = m.Name,
Company = m.Company.Name
Company = m.Company.Name,
Introduced = m.Introduced
})
.ToListAsync();
}

View File

@@ -80,7 +80,8 @@ public class ConsolesController(MarechaiContext context) : ControllerBase
{
Id = m.Id,
Name = m.Name,
Company = m.Company.Name
Company = m.Company.Name,
Introduced = m.Introduced
})
.ToListAsync();
@@ -99,7 +100,8 @@ public class ConsolesController(MarechaiContext context) : ControllerBase
{
Id = m.Id,
Name = m.Name,
Company = m.Company.Name
Company = m.Company.Name,
Introduced = m.Introduced
})
.ToListAsync();
@@ -115,7 +117,8 @@ public class ConsolesController(MarechaiContext context) : ControllerBase
{
Id = m.Id,
Name = m.Name,
Company = m.Company.Name
Company = m.Company.Name,
Introduced = m.Introduced
})
.ToListAsync();
}

View File

@@ -210,24 +210,19 @@ file class Program
builder.Services.AddScoped<TokenService, TokenService>();
// Read allowed CORS origins from configuration
string[] allowedOrigins = builder.Configuration.GetSection("CORS:AllowedOrigins").Get<string[]>();
string[] allowedOrigins = builder.Configuration.GetSection("CORS:AllowedOrigins").Get<string[]>() ??
Array.Empty<string>();
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowFrontend",
policy =>
{
switch(allowedOrigins)
{
case ["*"]:
// Check if wildcard is in the allowed origins
if(allowedOrigins.Contains("*"))
policy.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod();
break;
case { Length: > 0 }:
else if(allowedOrigins.Length > 0)
policy.WithOrigins(allowedOrigins).AllowAnyHeader().AllowAnyMethod();
break;
}
});
});