Refactor ViewModel constructors and ToModel methods to preserve original model state

This commit is contained in:
2025-12-14 18:54:07 +00:00
parent 7f49998683
commit 7599d57f21

View File

@@ -160,17 +160,20 @@ public sealed partial class MetadataEditorViewModel : ViewModelBase
// Available enum values for ComboBoxes // Available enum values for ComboBoxes
[NotNull] [NotNull]
public IEnumerable<LocalizedEnumValue<ReleaseType>> AvailableReleaseTypes => public IEnumerable<LocalizedEnumValue<ReleaseType>> AvailableReleaseTypes => LocalizedEnumHelper
LocalizedEnumHelper.GetLocalizedValues<ReleaseType>().OrderBy(static x => x.Description); .GetLocalizedValues<ReleaseType>()
.OrderBy(static x => x.Description);
[NotNull] [NotNull]
public IEnumerable<LocalizedEnumValue<Language>> AvailableLanguages => public IEnumerable<LocalizedEnumValue<Language>> AvailableLanguages =>
LocalizedEnumHelper.GetLocalizedValues<Language>().OrderBy(static x => x.Description); LocalizedEnumHelper.GetLocalizedValues<Language>().OrderBy(static x => x.Description);
[NotNull] [NotNull]
public IEnumerable<LocalizedEnumValue<Architecture>> AvailableArchitectures => public IEnumerable<LocalizedEnumValue<Architecture>> AvailableArchitectures => LocalizedEnumHelper
LocalizedEnumHelper.GetLocalizedValues<Architecture>().OrderBy(static x => x.Description); .GetLocalizedValues<Architecture>()
.OrderBy(static x => x.Description);
[NotNull] [NotNull]
public IEnumerable<LocalizedEnumValue<BarcodeType>> AvailableBarcodeTypes => public IEnumerable<LocalizedEnumValue<BarcodeType>> AvailableBarcodeTypes => LocalizedEnumHelper
LocalizedEnumHelper.GetLocalizedValues<BarcodeType>().OrderBy(static x => x.Description); .GetLocalizedValues<BarcodeType>()
.OrderBy(static x => x.Description);
void LoadMetadata([NotNull] string path) void LoadMetadata([NotNull] string path)
{ {
@@ -207,9 +210,8 @@ public sealed partial class MetadataEditorViewModel : ViewModelBase
// Enum lists // Enum lists
if(metadata.Languages != null) if(metadata.Languages != null)
{ foreach(Language lang in metadata.Languages)
foreach(Language lang in metadata.Languages) Languages.Add(new LocalizedEnumValue<Language>(lang)); Languages.Add(new LocalizedEnumValue<Language>(lang));
}
if(metadata.Architectures != null) if(metadata.Architectures != null)
{ {
@@ -219,19 +221,16 @@ public sealed partial class MetadataEditorViewModel : ViewModelBase
// Complex objects // Complex objects
if(metadata.Barcodes != null) if(metadata.Barcodes != null)
{ foreach(Barcode barcode in metadata.Barcodes)
foreach(Barcode barcode in metadata.Barcodes) Barcodes.Add(new BarcodeViewModel(barcode)); Barcodes.Add(new BarcodeViewModel(barcode));
}
if(metadata.Magazines != null) if(metadata.Magazines != null)
{ foreach(Magazine magazine in metadata.Magazines)
foreach(Magazine magazine in metadata.Magazines) Magazines.Add(new MagazineViewModel(magazine)); Magazines.Add(new MagazineViewModel(magazine));
}
if(metadata.Books != null) if(metadata.Books != null)
{ foreach(Book book in metadata.Books)
foreach(Book book in metadata.Books) Books.Add(new BookViewModel(book)); Books.Add(new BookViewModel(book));
}
if(metadata.RequiredOperatingSystems != null) if(metadata.RequiredOperatingSystems != null)
{ {
@@ -240,39 +239,32 @@ public sealed partial class MetadataEditorViewModel : ViewModelBase
} }
if(metadata.UserManuals != null) if(metadata.UserManuals != null)
{ foreach(UserManual manual in metadata.UserManuals)
foreach(UserManual manual in metadata.UserManuals) UserManuals.Add(new UserManualViewModel(manual)); UserManuals.Add(new UserManualViewModel(manual));
}
if(metadata.OpticalDiscs != null) if(metadata.OpticalDiscs != null)
{ foreach(OpticalDisc disc in metadata.OpticalDiscs)
foreach(OpticalDisc disc in metadata.OpticalDiscs) OpticalDiscs.Add(new OpticalDiscViewModel(disc)); OpticalDiscs.Add(new OpticalDiscViewModel(disc));
}
if(metadata.Advertisements != null) if(metadata.Advertisements != null)
{ foreach(Advertisement ad in metadata.Advertisements)
foreach(Advertisement ad in metadata.Advertisements) Advertisements.Add(new AdvertisementViewModel(ad)); Advertisements.Add(new AdvertisementViewModel(ad));
}
if(metadata.LinearMedias != null) if(metadata.LinearMedias != null)
{ foreach(LinearMedia media in metadata.LinearMedias)
foreach(LinearMedia media in metadata.LinearMedias) LinearMedias.Add(new LinearMediaViewModel(media)); LinearMedias.Add(new LinearMediaViewModel(media));
}
if(metadata.PciCards != null) if(metadata.PciCards != null)
{ foreach(Pci pci in metadata.PciCards)
foreach(Pci pci in metadata.PciCards) PciCards.Add(new PciViewModel(pci)); PciCards.Add(new PciViewModel(pci));
}
if(metadata.BlockMedias != null) if(metadata.BlockMedias != null)
{ foreach(BlockMedia media in metadata.BlockMedias)
foreach(BlockMedia media in metadata.BlockMedias) BlockMedias.Add(new BlockMediaViewModel(media)); BlockMedias.Add(new BlockMediaViewModel(media));
}
if(metadata.AudioMedias != null) if(metadata.AudioMedias != null)
{ foreach(AudioMedia media in metadata.AudioMedias)
foreach(AudioMedia media in metadata.AudioMedias) AudioMedias.Add(new AudioMediaViewModel(media)); AudioMedias.Add(new AudioMediaViewModel(media));
}
} }
catch(Exception ex) catch(Exception ex)
{ {
@@ -455,9 +447,8 @@ public sealed partial class MetadataEditorViewModel : ViewModelBase
void AddLanguage(object parameter) void AddLanguage(object parameter)
{ {
if(parameter is LocalizedEnumValue<Language> langValue) if(parameter is LocalizedEnumValue<Language> langValue)
{ if(!Languages.Any(l => l.Value == langValue.Value))
if(!Languages.Any(l => l.Value == langValue.Value)) Languages.Add(langValue); Languages.Add(langValue);
}
} }
[RelayCommand] [RelayCommand]
@@ -467,9 +458,8 @@ public sealed partial class MetadataEditorViewModel : ViewModelBase
void AddArchitecture(object parameter) void AddArchitecture(object parameter)
{ {
if(parameter is LocalizedEnumValue<Architecture> archValue) if(parameter is LocalizedEnumValue<Architecture> archValue)
{ if(!Architectures.Any(a => a.Value == archValue.Value))
if(!Architectures.Any(a => a.Value == archValue.Value)) Architectures.Add(archValue); Architectures.Add(archValue);
}
} }
[RelayCommand] [RelayCommand]
@@ -570,6 +560,8 @@ public sealed partial class BarcodeViewModel : ObservableObject
public sealed partial class MagazineViewModel : ObservableObject public sealed partial class MagazineViewModel : ObservableObject
{ {
readonly Magazine _originalModel;
[ObservableProperty] [ObservableProperty]
string _editorial; string _editorial;
[ObservableProperty] [ObservableProperty]
@@ -587,10 +579,11 @@ public sealed partial class MagazineViewModel : ObservableObject
[ObservableProperty] [ObservableProperty]
DateTime? _publicationDate; DateTime? _publicationDate;
public MagazineViewModel() {} public MagazineViewModel() => _originalModel = new Magazine();
public MagazineViewModel([NotNull] Magazine magazine) public MagazineViewModel([NotNull] Magazine magazine)
{ {
_originalModel = magazine;
Name = magazine.Name; Name = magazine.Name;
Editorial = magazine.Editorial; Editorial = magazine.Editorial;
PublicationDate = magazine.PublicationDate; PublicationDate = magazine.PublicationDate;
@@ -600,19 +593,24 @@ public sealed partial class MagazineViewModel : ObservableObject
} }
[NotNull] [NotNull]
public Magazine ToModel() => new() public Magazine ToModel()
{ {
Name = Name, // Update only the editable fields, preserve all others (Barcodes, Cover, Languages, Scan)
Editorial = Editorial, _originalModel.Name = Name;
PublicationDate = PublicationDate, _originalModel.Editorial = Editorial;
Number = Number, _originalModel.PublicationDate = PublicationDate;
Pages = Pages, _originalModel.Number = Number;
PageSize = PageSize _originalModel.Pages = Pages;
}; _originalModel.PageSize = PageSize;
return _originalModel;
}
} }
public sealed partial class BookViewModel : ObservableObject public sealed partial class BookViewModel : ObservableObject
{ {
readonly Book _originalModel;
[ObservableProperty] [ObservableProperty]
string _author; string _author;
@@ -632,10 +630,11 @@ public sealed partial class BookViewModel : ObservableObject
[ObservableProperty] [ObservableProperty]
DateTime? _publicationDate; DateTime? _publicationDate;
public BookViewModel() {} public BookViewModel() => _originalModel = new Book();
public BookViewModel([NotNull] Book book) public BookViewModel([NotNull] Book book)
{ {
_originalModel = book;
Name = book.Name; Name = book.Name;
Editorial = book.Editorial; Editorial = book.Editorial;
Author = book.Author; Author = book.Author;
@@ -645,15 +644,18 @@ public sealed partial class BookViewModel : ObservableObject
} }
[NotNull] [NotNull]
public Book ToModel() => new() public Book ToModel()
{ {
Name = Name, // Update only the editable fields, preserve all others (Barcodes, Cover, Languages, Scan)
Editorial = Editorial, _originalModel.Name = Name;
Author = Author, _originalModel.Editorial = Editorial;
PublicationDate = PublicationDate, _originalModel.Author = Author;
Pages = Pages, _originalModel.PublicationDate = PublicationDate;
PageSize = PageSize _originalModel.Pages = Pages;
}; _originalModel.PageSize = PageSize;
return _originalModel;
}
} }
public sealed partial class RequiredOperatingSystemViewModel : ObservableObject public sealed partial class RequiredOperatingSystemViewModel : ObservableObject
@@ -685,31 +687,39 @@ public sealed partial class RequiredOperatingSystemViewModel : ObservableObject
public sealed partial class UserManualViewModel : ObservableObject public sealed partial class UserManualViewModel : ObservableObject
{ {
readonly UserManual _originalModel;
[ObservableProperty] [ObservableProperty]
uint _pages; uint _pages;
[ObservableProperty] [ObservableProperty]
string _pageSize; string _pageSize;
public UserManualViewModel() {} public UserManualViewModel() => _originalModel = new UserManual();
public UserManualViewModel([NotNull] UserManual manual) public UserManualViewModel([NotNull] UserManual manual)
{ {
Pages = manual.Pages; _originalModel = manual;
PageSize = manual.PageSize; Pages = manual.Pages;
PageSize = manual.PageSize;
} }
[NotNull] [NotNull]
public UserManual ToModel() => new() public UserManual ToModel()
{ {
Pages = Pages, // Update only the editable fields, preserve all others (Language, Scan)
PageSize = PageSize _originalModel.Pages = Pages;
}; _originalModel.PageSize = PageSize;
return _originalModel;
}
} }
// Simplified ViewModels for complex media types (can be expanded as needed) // Simplified ViewModels for complex media types (can be expanded as needed)
public sealed partial class OpticalDiscViewModel : ObservableObject public sealed partial class OpticalDiscViewModel : ObservableObject
{ {
readonly OpticalDisc _originalModel;
[ObservableProperty] [ObservableProperty]
string _discSubType; string _discSubType;
@@ -721,52 +731,64 @@ public sealed partial class OpticalDiscViewModel : ObservableObject
[ObservableProperty] [ObservableProperty]
string _serialNumber; string _serialNumber;
public OpticalDiscViewModel() {} public OpticalDiscViewModel() => _originalModel = new OpticalDisc();
public OpticalDiscViewModel([NotNull] OpticalDisc disc) public OpticalDiscViewModel([NotNull] OpticalDisc disc)
{ {
PartNumber = disc.PartNumber; _originalModel = disc;
SerialNumber = disc.SerialNumber; PartNumber = disc.PartNumber;
DiscType = disc.DiscType; SerialNumber = disc.SerialNumber;
DiscSubType = disc.DiscSubType; DiscType = disc.DiscType;
DiscSubType = disc.DiscSubType;
} }
[NotNull] [NotNull]
public OpticalDisc ToModel() => new() public OpticalDisc ToModel()
{ {
PartNumber = PartNumber, // Update only the editable fields, preserve all others
SerialNumber = SerialNumber, _originalModel.PartNumber = PartNumber;
DiscType = DiscType, _originalModel.SerialNumber = SerialNumber;
DiscSubType = DiscSubType _originalModel.DiscType = DiscType;
}; _originalModel.DiscSubType = DiscSubType;
return _originalModel;
}
} }
public sealed partial class AdvertisementViewModel : ObservableObject public sealed partial class AdvertisementViewModel : ObservableObject
{ {
readonly Advertisement _originalModel;
[ObservableProperty] [ObservableProperty]
string _manufacturer; string _manufacturer;
[ObservableProperty] [ObservableProperty]
string _product; string _product;
public AdvertisementViewModel() {} public AdvertisementViewModel() => _originalModel = new Advertisement();
public AdvertisementViewModel([NotNull] Advertisement ad) public AdvertisementViewModel([NotNull] Advertisement ad)
{ {
Manufacturer = ad.Manufacturer; _originalModel = ad;
Product = ad.Product; Manufacturer = ad.Manufacturer;
Product = ad.Product;
} }
[NotNull] [NotNull]
public Advertisement ToModel() => new() public Advertisement ToModel()
{ {
Manufacturer = Manufacturer, // Update only the editable fields, preserve all others (File, FileSize, Frames, Duration, etc.)
Product = Product _originalModel.Manufacturer = Manufacturer;
}; _originalModel.Product = Product;
return _originalModel;
}
} }
public sealed partial class LinearMediaViewModel : ObservableObject public sealed partial class LinearMediaViewModel : ObservableObject
{ {
readonly LinearMedia _originalModel;
[ObservableProperty] [ObservableProperty]
string _manufacturer; string _manufacturer;
@@ -778,51 +800,63 @@ public sealed partial class LinearMediaViewModel : ObservableObject
[ObservableProperty] [ObservableProperty]
string _serialNumber; string _serialNumber;
public LinearMediaViewModel() {} public LinearMediaViewModel() => _originalModel = new LinearMedia();
public LinearMediaViewModel([NotNull] LinearMedia media) public LinearMediaViewModel([NotNull] LinearMedia media)
{ {
PartNumber = media.PartNumber; _originalModel = media;
SerialNumber = media.SerialNumber; PartNumber = media.PartNumber;
Manufacturer = media.Manufacturer; SerialNumber = media.SerialNumber;
Model = media.Model; Manufacturer = media.Manufacturer;
Model = media.Model;
} }
[NotNull] [NotNull]
public LinearMedia ToModel() => new() public LinearMedia ToModel()
{ {
PartNumber = PartNumber, // Update only the editable fields, preserve all others
SerialNumber = SerialNumber, _originalModel.PartNumber = PartNumber;
Manufacturer = Manufacturer, _originalModel.SerialNumber = SerialNumber;
Model = Model _originalModel.Manufacturer = Manufacturer;
}; _originalModel.Model = Model;
return _originalModel;
}
} }
public sealed partial class PciViewModel : ObservableObject public sealed partial class PciViewModel : ObservableObject
{ {
readonly Pci _originalModel;
[ObservableProperty] [ObservableProperty]
ushort _deviceID; ushort _deviceID;
[ObservableProperty] [ObservableProperty]
ushort _vendorID; ushort _vendorID;
public PciViewModel() {} public PciViewModel() => _originalModel = new Pci();
public PciViewModel([NotNull] Pci pci) public PciViewModel([NotNull] Pci pci)
{ {
VendorID = pci.VendorID; _originalModel = pci;
DeviceID = pci.DeviceID; VendorID = pci.VendorID;
DeviceID = pci.DeviceID;
} }
[NotNull] [NotNull]
public Pci ToModel() => new() public Pci ToModel()
{ {
VendorID = VendorID, // Update only the editable fields, preserve all others
DeviceID = DeviceID _originalModel.VendorID = VendorID;
}; _originalModel.DeviceID = DeviceID;
return _originalModel;
}
} }
public sealed partial class BlockMediaViewModel : ObservableObject public sealed partial class BlockMediaViewModel : ObservableObject
{ {
readonly BlockMedia _originalModel;
[ObservableProperty] [ObservableProperty]
string _firmware; string _firmware;
[ObservableProperty] [ObservableProperty]
@@ -834,28 +868,34 @@ public sealed partial class BlockMediaViewModel : ObservableObject
[ObservableProperty] [ObservableProperty]
string _serial; string _serial;
public BlockMediaViewModel() {} public BlockMediaViewModel() => _originalModel = new BlockMedia();
public BlockMediaViewModel([NotNull] BlockMedia media) public BlockMediaViewModel([NotNull] BlockMedia media)
{ {
Manufacturer = media.Manufacturer; _originalModel = media;
Model = media.Model; Manufacturer = media.Manufacturer;
Serial = media.Serial; Model = media.Model;
Firmware = media.Firmware; Serial = media.Serial;
Firmware = media.Firmware;
} }
[NotNull] [NotNull]
public BlockMedia ToModel() => new() public BlockMedia ToModel()
{ {
Manufacturer = Manufacturer, // Update only the editable fields, preserve all others
Model = Model, _originalModel.Manufacturer = Manufacturer;
Serial = Serial, _originalModel.Model = Model;
Firmware = Firmware _originalModel.Serial = Serial;
}; _originalModel.Firmware = Firmware;
return _originalModel;
}
} }
public sealed partial class AudioMediaViewModel : ObservableObject public sealed partial class AudioMediaViewModel : ObservableObject
{ {
readonly AudioMedia _originalModel;
[ObservableProperty] [ObservableProperty]
string _manufacturer; string _manufacturer;
@@ -868,22 +908,26 @@ public sealed partial class AudioMediaViewModel : ObservableObject
[ObservableProperty] [ObservableProperty]
string _serialNumber; string _serialNumber;
public AudioMediaViewModel() {} public AudioMediaViewModel() => _originalModel = new AudioMedia();
public AudioMediaViewModel([NotNull] AudioMedia media) public AudioMediaViewModel([NotNull] AudioMedia media)
{ {
Manufacturer = media.Manufacturer; _originalModel = media;
Model = media.Model; Manufacturer = media.Manufacturer;
PartNumber = media.PartNumber; Model = media.Model;
SerialNumber = media.SerialNumber; PartNumber = media.PartNumber;
SerialNumber = media.SerialNumber;
} }
[NotNull] [NotNull]
public AudioMedia ToModel() => new() public AudioMedia ToModel()
{ {
Manufacturer = Manufacturer, // Update only the editable fields, preserve all others
Model = Model, _originalModel.Manufacturer = Manufacturer;
PartNumber = PartNumber, _originalModel.Model = Model;
SerialNumber = SerialNumber _originalModel.PartNumber = PartNumber;
}; _originalModel.SerialNumber = SerialNumber;
return _originalModel;
}
} }