mirror of
https://github.com/claunia/marechai.git
synced 2025-12-16 19:14:25 +00:00
Add computer list.
This commit is contained in:
@@ -102,6 +102,12 @@ public partial class App : Application
|
|||||||
services.AddSingleton<NewsViewModel>();
|
services.AddSingleton<NewsViewModel>();
|
||||||
services.AddSingleton<ComputersService>();
|
services.AddSingleton<ComputersService>();
|
||||||
services.AddSingleton<ComputersViewModel>();
|
services.AddSingleton<ComputersViewModel>();
|
||||||
|
|
||||||
|
services
|
||||||
|
.AddSingleton<IComputersListFilterContext,
|
||||||
|
ComputersListFilterContext>();
|
||||||
|
|
||||||
|
services.AddTransient<ComputersListViewModel>();
|
||||||
})
|
})
|
||||||
.UseNavigation(RegisterRoutes));
|
.UseNavigation(RegisterRoutes));
|
||||||
|
|
||||||
@@ -121,6 +127,7 @@ public partial class App : Application
|
|||||||
new ViewMap<MainPage, MainViewModel>(),
|
new ViewMap<MainPage, MainViewModel>(),
|
||||||
new ViewMap<NewsPage, NewsViewModel>(),
|
new ViewMap<NewsPage, NewsViewModel>(),
|
||||||
new ViewMap<ComputersPage, ComputersViewModel>(),
|
new ViewMap<ComputersPage, ComputersViewModel>(),
|
||||||
|
new ViewMap<ComputersListPage, ComputersListViewModel>(),
|
||||||
new DataViewMap<SecondPage, SecondViewModel, Entity>());
|
new DataViewMap<SecondPage, SecondViewModel, Entity>());
|
||||||
|
|
||||||
routes.Register(new RouteMap("",
|
routes.Register(new RouteMap("",
|
||||||
@@ -136,7 +143,13 @@ public partial class App : Application
|
|||||||
views.FindByViewModel<NewsViewModel>(),
|
views.FindByViewModel<NewsViewModel>(),
|
||||||
true),
|
true),
|
||||||
new RouteMap("computers",
|
new RouteMap("computers",
|
||||||
views.FindByViewModel<ComputersViewModel>()),
|
views.FindByViewModel<ComputersViewModel>(),
|
||||||
|
Nested:
|
||||||
|
[
|
||||||
|
new RouteMap("list",
|
||||||
|
views.FindByViewModel<
|
||||||
|
ComputersListViewModel>())
|
||||||
|
]),
|
||||||
new RouteMap("Second",
|
new RouteMap("Second",
|
||||||
views.FindByViewModel<SecondViewModel>())
|
views.FindByViewModel<SecondViewModel>())
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ namespace Marechai.App.Presentation;
|
|||||||
public partial class ComputersViewModel : ObservableObject
|
public partial class ComputersViewModel : ObservableObject
|
||||||
{
|
{
|
||||||
private readonly ComputersService _computersService;
|
private readonly ComputersService _computersService;
|
||||||
|
private readonly IComputersListFilterContext _filterContext;
|
||||||
private readonly IStringLocalizer _localizer;
|
private readonly IStringLocalizer _localizer;
|
||||||
private readonly ILogger<ComputersViewModel> _logger;
|
private readonly ILogger<ComputersViewModel> _logger;
|
||||||
private readonly INavigator _navigator;
|
private readonly INavigator _navigator;
|
||||||
@@ -48,12 +49,14 @@ public partial class ComputersViewModel : ObservableObject
|
|||||||
private ObservableCollection<int> yearsList = new();
|
private ObservableCollection<int> yearsList = new();
|
||||||
|
|
||||||
public ComputersViewModel(ComputersService computersService, IStringLocalizer localizer,
|
public ComputersViewModel(ComputersService computersService, IStringLocalizer localizer,
|
||||||
ILogger<ComputersViewModel> logger, INavigator navigator)
|
ILogger<ComputersViewModel> logger, INavigator navigator,
|
||||||
|
IComputersListFilterContext filterContext)
|
||||||
{
|
{
|
||||||
_computersService = computersService;
|
_computersService = computersService;
|
||||||
_localizer = localizer;
|
_localizer = localizer;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_navigator = navigator;
|
_navigator = navigator;
|
||||||
|
_filterContext = filterContext;
|
||||||
LoadData = new AsyncRelayCommand(LoadDataAsync);
|
LoadData = new AsyncRelayCommand(LoadDataAsync);
|
||||||
GoBackCommand = new AsyncRelayCommand(GoBackAsync);
|
GoBackCommand = new AsyncRelayCommand(GoBackAsync);
|
||||||
NavigateByLetterCommand = new AsyncRelayCommand<char>(NavigateByLetterAsync);
|
NavigateByLetterCommand = new AsyncRelayCommand<char>(NavigateByLetterAsync);
|
||||||
@@ -147,10 +150,19 @@ public partial class ComputersViewModel : ObservableObject
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private async Task NavigateByLetterAsync(char letter)
|
private async Task NavigateByLetterAsync(char letter)
|
||||||
{
|
{
|
||||||
_logger.LogInformation("Navigating to computers by letter: {Letter}", letter);
|
try
|
||||||
|
{
|
||||||
// TODO: Implement navigation to letter-filtered view
|
_logger.LogInformation("Navigating to computers by letter: {Letter}", letter);
|
||||||
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>
|
/// <summary>
|
||||||
@@ -158,10 +170,19 @@ public partial class ComputersViewModel : ObservableObject
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private async Task NavigateByYearAsync(int year)
|
private async Task NavigateByYearAsync(int year)
|
||||||
{
|
{
|
||||||
_logger.LogInformation("Navigating to computers by year: {Year}", year);
|
try
|
||||||
|
{
|
||||||
// TODO: Implement navigation to year-filtered view
|
_logger.LogInformation("Navigating to computers by year: {Year}", year);
|
||||||
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>
|
/// <summary>
|
||||||
@@ -169,9 +190,18 @@ public partial class ComputersViewModel : ObservableObject
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private async Task NavigateAllComputersAsync()
|
private async Task NavigateAllComputersAsync()
|
||||||
{
|
{
|
||||||
_logger.LogInformation("Navigating to all computers");
|
try
|
||||||
|
{
|
||||||
// TODO: Implement navigation to all computers view
|
_logger.LogInformation("Navigating to all computers");
|
||||||
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Kiota.Abstractions.Serialization;
|
using Microsoft.Kiota.Abstractions.Serialization;
|
||||||
|
|
||||||
@@ -118,4 +119,81 @@ public class ComputersService
|
|||||||
return 0;
|
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>();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
{
|
{
|
||||||
"AppConfig": {
|
"AppConfig": {
|
||||||
"Environment": "Production"
|
"Environment": "Production"
|
||||||
},
|
},
|
||||||
"ApiClient": {
|
"ApiClient": {
|
||||||
|
"Url": "http://localhost:5023",
|
||||||
"UseNativeHandler": true
|
"UseNativeHandler": true
|
||||||
},
|
},
|
||||||
"LocalizationConfiguration": {
|
"LocalizationConfiguration": {
|
||||||
|
|||||||
@@ -78,9 +78,10 @@ public class ComputersController(MarechaiContext context) : ControllerBase
|
|||||||
.ThenBy(m => m.Name)
|
.ThenBy(m => m.Name)
|
||||||
.Select(m => new MachineDto
|
.Select(m => new MachineDto
|
||||||
{
|
{
|
||||||
Id = m.Id,
|
Id = m.Id,
|
||||||
Name = m.Name,
|
Name = m.Name,
|
||||||
Company = m.Company.Name
|
Company = m.Company.Name,
|
||||||
|
Introduced = m.Introduced
|
||||||
})
|
})
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
@@ -97,9 +98,10 @@ public class ComputersController(MarechaiContext context) : ControllerBase
|
|||||||
.ThenBy(m => m.Name)
|
.ThenBy(m => m.Name)
|
||||||
.Select(m => new MachineDto
|
.Select(m => new MachineDto
|
||||||
{
|
{
|
||||||
Id = m.Id,
|
Id = m.Id,
|
||||||
Name = m.Name,
|
Name = m.Name,
|
||||||
Company = m.Company.Name
|
Company = m.Company.Name,
|
||||||
|
Introduced = m.Introduced
|
||||||
})
|
})
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
@@ -113,9 +115,10 @@ public class ComputersController(MarechaiContext context) : ControllerBase
|
|||||||
.ThenBy(m => m.Name)
|
.ThenBy(m => m.Name)
|
||||||
.Select(m => new MachineDto
|
.Select(m => new MachineDto
|
||||||
{
|
{
|
||||||
Id = m.Id,
|
Id = m.Id,
|
||||||
Name = m.Name,
|
Name = m.Name,
|
||||||
Company = m.Company.Name
|
Company = m.Company.Name,
|
||||||
|
Introduced = m.Introduced
|
||||||
})
|
})
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
}
|
}
|
||||||
@@ -78,9 +78,10 @@ public class ConsolesController(MarechaiContext context) : ControllerBase
|
|||||||
.ThenBy(m => m.Name)
|
.ThenBy(m => m.Name)
|
||||||
.Select(m => new MachineDto
|
.Select(m => new MachineDto
|
||||||
{
|
{
|
||||||
Id = m.Id,
|
Id = m.Id,
|
||||||
Name = m.Name,
|
Name = m.Name,
|
||||||
Company = m.Company.Name
|
Company = m.Company.Name,
|
||||||
|
Introduced = m.Introduced
|
||||||
})
|
})
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
@@ -97,9 +98,10 @@ public class ConsolesController(MarechaiContext context) : ControllerBase
|
|||||||
.ThenBy(m => m.Name)
|
.ThenBy(m => m.Name)
|
||||||
.Select(m => new MachineDto
|
.Select(m => new MachineDto
|
||||||
{
|
{
|
||||||
Id = m.Id,
|
Id = m.Id,
|
||||||
Name = m.Name,
|
Name = m.Name,
|
||||||
Company = m.Company.Name
|
Company = m.Company.Name,
|
||||||
|
Introduced = m.Introduced
|
||||||
})
|
})
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
@@ -113,9 +115,10 @@ public class ConsolesController(MarechaiContext context) : ControllerBase
|
|||||||
.ThenBy(m => m.Name)
|
.ThenBy(m => m.Name)
|
||||||
.Select(m => new MachineDto
|
.Select(m => new MachineDto
|
||||||
{
|
{
|
||||||
Id = m.Id,
|
Id = m.Id,
|
||||||
Name = m.Name,
|
Name = m.Name,
|
||||||
Company = m.Company.Name
|
Company = m.Company.Name,
|
||||||
|
Introduced = m.Introduced
|
||||||
})
|
})
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
}
|
}
|
||||||
@@ -210,24 +210,19 @@ file class Program
|
|||||||
builder.Services.AddScoped<TokenService, TokenService>();
|
builder.Services.AddScoped<TokenService, TokenService>();
|
||||||
|
|
||||||
// Read allowed CORS origins from configuration
|
// 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 =>
|
builder.Services.AddCors(options =>
|
||||||
{
|
{
|
||||||
options.AddPolicy("AllowFrontend",
|
options.AddPolicy("AllowFrontend",
|
||||||
policy =>
|
policy =>
|
||||||
{
|
{
|
||||||
switch(allowedOrigins)
|
// Check if wildcard is in the allowed origins
|
||||||
{
|
if(allowedOrigins.Contains("*"))
|
||||||
case ["*"]:
|
policy.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod();
|
||||||
policy.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod();
|
else if(allowedOrigins.Length > 0)
|
||||||
|
policy.WithOrigins(allowedOrigins).AllowAnyHeader().AllowAnyMethod();
|
||||||
break;
|
|
||||||
case { Length: > 0 }:
|
|
||||||
policy.WithOrigins(allowedOrigins).AllowAnyHeader().AllowAnyMethod();
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user