mirror of
https://github.com/claunia/marechai.git
synced 2025-12-16 19:14:25 +00:00
Add company detail page.
This commit is contained in:
373
Marechai.App/Presentation/ViewModels/CompanyDetailViewModel.cs
Normal file
373
Marechai.App/Presentation/ViewModels/CompanyDetailViewModel.cs
Normal file
@@ -0,0 +1,373 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Marechai.App.Helpers;
|
||||
using Marechai.App.Presentation.Models;
|
||||
using Marechai.App.Services;
|
||||
using Marechai.Data;
|
||||
using Uno.Extensions.Navigation;
|
||||
|
||||
namespace Marechai.App.Presentation.ViewModels;
|
||||
|
||||
public partial class CompanyDetailViewModel : ObservableObject
|
||||
{
|
||||
private readonly CompanyDetailService _companyDetailService;
|
||||
private readonly IStringLocalizer _localizer;
|
||||
private readonly ILogger<CompanyDetailViewModel> _logger;
|
||||
private readonly INavigator _navigator;
|
||||
|
||||
[ObservableProperty]
|
||||
private CompanyDto? _company;
|
||||
|
||||
[ObservableProperty]
|
||||
private int _companyId;
|
||||
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<CompanyDetailMachine> _computers = [];
|
||||
|
||||
[ObservableProperty]
|
||||
private string _computersFilterText = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _consoelsFilterText = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<CompanyDetailMachine> _consoles = [];
|
||||
|
||||
[ObservableProperty]
|
||||
private string _errorMessage = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<CompanyDetailMachine> _filteredComputers = [];
|
||||
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<CompanyDetailMachine> _filteredConsoles = [];
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _hasError;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isDataLoaded;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isLoading;
|
||||
|
||||
[ObservableProperty]
|
||||
private CompanyDto? _soldToCompany;
|
||||
|
||||
public CompanyDetailViewModel(CompanyDetailService companyDetailService, IStringLocalizer localizer,
|
||||
ILogger<CompanyDetailViewModel> logger, INavigator navigator)
|
||||
{
|
||||
_companyDetailService = companyDetailService;
|
||||
_localizer = localizer;
|
||||
_logger = logger;
|
||||
_navigator = navigator;
|
||||
LoadData = new AsyncRelayCommand(LoadDataAsync);
|
||||
GoBackCommand = new AsyncRelayCommand(GoBackAsync);
|
||||
NavigateToMachineCommand = new AsyncRelayCommand<CompanyDetailMachine>(NavigateToMachineAsync);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the display text for the company's status
|
||||
/// </summary>
|
||||
public string CompanyStatusDisplay => Company != null ? GetStatusMessage(Company) : string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the display text for the company's founded date
|
||||
/// </summary>
|
||||
public string CompanyFoundedDateDisplay => Company != null ? GetFoundedDateDisplay(Company) : string.Empty;
|
||||
|
||||
public IAsyncRelayCommand LoadData { get; }
|
||||
public ICommand GoBackCommand { get; }
|
||||
public IAsyncRelayCommand<CompanyDetailMachine> NavigateToMachineCommand { get; }
|
||||
public string Title { get; } = "Company Details";
|
||||
|
||||
partial void OnCompanyChanged(CompanyDto? oldValue, CompanyDto? newValue)
|
||||
{
|
||||
// Notify that computed properties have changed
|
||||
OnPropertyChanged(nameof(CompanyStatusDisplay));
|
||||
OnPropertyChanged(nameof(CompanyFoundedDateDisplay));
|
||||
}
|
||||
|
||||
partial void OnComputersFilterTextChanged(string value)
|
||||
{
|
||||
FilterComputers(value);
|
||||
}
|
||||
|
||||
partial void OnConsoelsFilterTextChanged(string value)
|
||||
{
|
||||
FilterConsoles(value);
|
||||
}
|
||||
|
||||
private void FilterComputers(string filterText)
|
||||
{
|
||||
ObservableCollection<CompanyDetailMachine> filtered = string.IsNullOrWhiteSpace(filterText)
|
||||
? new ObservableCollection<
|
||||
CompanyDetailMachine>(Computers)
|
||||
: new
|
||||
ObservableCollection<
|
||||
CompanyDetailMachine>(Computers.Where(c =>
|
||||
c.Name.Contains(filterText,
|
||||
StringComparison
|
||||
.OrdinalIgnoreCase)));
|
||||
|
||||
FilteredComputers = filtered;
|
||||
}
|
||||
|
||||
private void FilterConsoles(string filterText)
|
||||
{
|
||||
ObservableCollection<CompanyDetailMachine> filtered = string.IsNullOrWhiteSpace(filterText)
|
||||
? new ObservableCollection<
|
||||
CompanyDetailMachine>(Consoles)
|
||||
: new
|
||||
ObservableCollection<
|
||||
CompanyDetailMachine>(Consoles.Where(c =>
|
||||
c.Name.Contains(filterText,
|
||||
StringComparison
|
||||
.OrdinalIgnoreCase)));
|
||||
|
||||
FilteredConsoles = filtered;
|
||||
}
|
||||
|
||||
private async Task NavigateToMachineAsync(CompanyDetailMachine? machine)
|
||||
{
|
||||
if(machine == null) return;
|
||||
|
||||
var navParam = new MachineViewNavigationParameter
|
||||
{
|
||||
MachineId = machine.Id,
|
||||
NavigationSource = this
|
||||
};
|
||||
|
||||
await _navigator.NavigateViewModelAsync<MachineViewViewModel>(this, data: navParam);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the formatted founding date with unknown handling
|
||||
/// </summary>
|
||||
public string GetFoundedDateDisplay(CompanyDto company)
|
||||
{
|
||||
if(company.Founded is null) return string.Empty;
|
||||
|
||||
DateTime date = company.Founded.Value.DateTime;
|
||||
|
||||
if(company.FoundedMonthIsUnknown ?? false) return $"{date.Year}.";
|
||||
|
||||
if(company.FoundedDayIsUnknown ?? false) return $"{date:Y}.";
|
||||
|
||||
return $"{date:D}.";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the formatted sold/event date with unknown handling
|
||||
/// </summary>
|
||||
public string GetEventDateDisplay(CompanyDto? company, bool monthUnknown = false, bool dayUnknown = false)
|
||||
{
|
||||
if(company?.Sold is null) return _localizer["unknown date"].Value;
|
||||
|
||||
DateTime date = company.Sold.Value.DateTime;
|
||||
|
||||
if(monthUnknown || (company.SoldMonthIsUnknown ?? false)) return $"{date.Year}";
|
||||
|
||||
if(dayUnknown || (company.SoldDayIsUnknown ?? false)) return $"{date:Y}";
|
||||
|
||||
return $"{date:D}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the status message for the company
|
||||
/// </summary>
|
||||
public string GetStatusMessage(CompanyDto company)
|
||||
{
|
||||
return company.Status switch
|
||||
{
|
||||
1 => _localizer["Company is active."].Value,
|
||||
2 => GetSoldStatusMessage(company),
|
||||
3 => GetMergedStatusMessage(company),
|
||||
4 => GetBankruptcyMessage(company),
|
||||
5 => GetDefunctMessage(company),
|
||||
6 => GetRenamedStatusMessage(company),
|
||||
_ => _localizer["Current company status is unknown."].Value
|
||||
};
|
||||
}
|
||||
|
||||
private string GetSoldStatusMessage(CompanyDto company)
|
||||
{
|
||||
if(SoldToCompany != null)
|
||||
{
|
||||
return string.Format(_localizer["Company sold to {0} on {1}."].Value,
|
||||
SoldToCompany.Name,
|
||||
GetEventDateDisplay(company));
|
||||
}
|
||||
|
||||
if(company.Sold != null)
|
||||
{
|
||||
return string.Format(_localizer["Company sold on {0} to an unknown company."].Value,
|
||||
GetEventDateDisplay(company));
|
||||
}
|
||||
|
||||
return SoldToCompany != null
|
||||
? string.Format(_localizer["Company sold to {0} on an unknown date."].Value, SoldToCompany.Name)
|
||||
: _localizer["Company was sold to an unknown company on an unknown date."].Value;
|
||||
}
|
||||
|
||||
private string GetMergedStatusMessage(CompanyDto company)
|
||||
{
|
||||
if(SoldToCompany != null)
|
||||
{
|
||||
return string.Format(_localizer["Company merged on {0} to form {1}."].Value,
|
||||
GetEventDateDisplay(company),
|
||||
SoldToCompany.Name);
|
||||
}
|
||||
|
||||
if(company.Sold != null)
|
||||
{
|
||||
return string.Format(_localizer["Company merged on {0} to form an unknown company."].Value,
|
||||
GetEventDateDisplay(company));
|
||||
}
|
||||
|
||||
return SoldToCompany != null
|
||||
? string.Format(_localizer["Company merged on an unknown date to form {0}."].Value,
|
||||
SoldToCompany.Name)
|
||||
: _localizer["Company merged to form an unknown company on an unknown date."].Value;
|
||||
}
|
||||
|
||||
private string GetBankruptcyMessage(CompanyDto company) => company.Sold != null
|
||||
? string.Format(_localizer
|
||||
["Company declared bankruptcy on {0}."]
|
||||
.Value,
|
||||
GetEventDateDisplay(company))
|
||||
: _localizer
|
||||
["Company declared bankruptcy on an unknown date."]
|
||||
.Value;
|
||||
|
||||
private string GetDefunctMessage(CompanyDto company) => company.Sold != null
|
||||
? string.Format(_localizer
|
||||
["Company ceased operations on {0}."]
|
||||
.Value,
|
||||
GetEventDateDisplay(company))
|
||||
: _localizer
|
||||
["Company ceased operations on an unknown date."]
|
||||
.Value;
|
||||
|
||||
private string GetRenamedStatusMessage(CompanyDto company)
|
||||
{
|
||||
if(SoldToCompany != null)
|
||||
{
|
||||
return string.Format(_localizer["Company renamed to {0} on {1}."].Value,
|
||||
SoldToCompany.Name,
|
||||
GetEventDateDisplay(company));
|
||||
}
|
||||
|
||||
if(company.Sold != null)
|
||||
{
|
||||
return string.Format(_localizer["Company was renamed on {0} to an unknown name."].Value,
|
||||
GetEventDateDisplay(company));
|
||||
}
|
||||
|
||||
return SoldToCompany != null
|
||||
? string.Format(_localizer["Company renamed to {0} on an unknown date."].Value, SoldToCompany.Name)
|
||||
: _localizer["Company renamed to an unknown name on an unknown date."].Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads company details from the API
|
||||
/// </summary>
|
||||
private async Task LoadDataAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
IsLoading = true;
|
||||
ErrorMessage = string.Empty;
|
||||
HasError = false;
|
||||
IsDataLoaded = false;
|
||||
|
||||
if(CompanyId <= 0)
|
||||
{
|
||||
ErrorMessage = _localizer["Invalid company ID."].Value;
|
||||
HasError = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Load company details
|
||||
Company = await _companyDetailService.GetCompanyByIdAsync(CompanyId);
|
||||
|
||||
if(Company is null)
|
||||
{
|
||||
ErrorMessage = _localizer["Company not found."].Value;
|
||||
HasError = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Load sold-to company if applicable
|
||||
if(Company.SoldToId != null)
|
||||
{
|
||||
int soldToId = UntypedNodeExtractor.ExtractInt(Company.SoldToId);
|
||||
if(soldToId > 0) SoldToCompany = await _companyDetailService.GetSoldToCompanyAsync(soldToId);
|
||||
}
|
||||
|
||||
// Load computers and consoles made by this company
|
||||
List<MachineDto> machines = await _companyDetailService.GetComputersByCompanyAsync(CompanyId);
|
||||
Computers.Clear();
|
||||
Consoles.Clear();
|
||||
FilteredComputers.Clear();
|
||||
FilteredConsoles.Clear();
|
||||
|
||||
foreach(MachineDto machine in machines)
|
||||
{
|
||||
int machineId = UntypedNodeExtractor.ExtractInt(machine.Id);
|
||||
|
||||
var machineItem = new CompanyDetailMachine
|
||||
{
|
||||
Id = machineId,
|
||||
Name = machine.Name ?? string.Empty
|
||||
};
|
||||
|
||||
// Categorize by machine type enum
|
||||
if(machine.Type == (int)MachineType.Computer)
|
||||
Computers.Add(machineItem);
|
||||
else if(machine.Type == (int)MachineType.Console) Consoles.Add(machineItem);
|
||||
}
|
||||
|
||||
// Initialize filtered lists
|
||||
FilteredComputers = new ObservableCollection<CompanyDetailMachine>(Computers);
|
||||
FilteredConsoles = new ObservableCollection<CompanyDetailMachine>(Consoles);
|
||||
|
||||
IsDataLoaded = true;
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
_logger.LogError("Error loading company details: {Exception}", ex.Message);
|
||||
ErrorMessage = _localizer["Failed to load company details. Please try again later."].Value;
|
||||
HasError = true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
IsLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles back navigation
|
||||
/// </summary>
|
||||
private async Task GoBackAsync()
|
||||
{
|
||||
await _navigator.NavigateViewModelAsync<CompaniesViewModel>(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Data model for a machine in the company detail view
|
||||
/// </summary>
|
||||
public class CompanyDetailMachine
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
}
|
||||
Reference in New Issue
Block a user