Removed dialogs for editing equipment and points, and their related resources
This commit is contained in:
@@ -1,7 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using GazpromApp.Messages;
|
||||
using GazpromApp.Models;
|
||||
using GazpromApp.Utils;
|
||||
|
||||
@@ -9,6 +13,7 @@ namespace GazpromApp.ViewModels;
|
||||
|
||||
public partial class EquipmentViewModel : ViewModelBase
|
||||
{
|
||||
public ViewModelBase? Parent { get; set; }
|
||||
private Equipment Equipment { get; }
|
||||
|
||||
[ObservableProperty]
|
||||
@@ -17,31 +22,72 @@ public partial class EquipmentViewModel : ViewModelBase
|
||||
[ObservableProperty]
|
||||
private string? _description;
|
||||
|
||||
public ObservableCollection<ImageViewModel> Images { get; init; } = [];
|
||||
|
||||
public ObservableCollection<PropertyViewModel> Properties { get; }
|
||||
[ObservableProperty]
|
||||
private DateTime _creationDate;
|
||||
|
||||
public ObservableCollection<InspectionViewModel> Inspections { get; }
|
||||
public ObservableCollection<ImageViewModel> Images { get; set; } = [];
|
||||
|
||||
public ObservableCollection<PropertyViewModel> Properties { get; set; }
|
||||
|
||||
public ObservableCollection<InspectionViewModel> Inspections { get; set; }
|
||||
|
||||
public ObservableCollection<EquipmentViewModel> Equipments { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
private string _nearestInspection;
|
||||
|
||||
[RelayCommand]
|
||||
private void AddEquipment()
|
||||
{
|
||||
Equipments.Add(new EquipmentViewModel{ Name = "Новое оборудование", Description = "Описание оборудования", Parent = this});
|
||||
CallSavePoint(this);
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void RemoveEquipment()
|
||||
{
|
||||
WeakReferenceMessenger.Default.Send(new RemoveEquipmentMessage(this));
|
||||
}
|
||||
|
||||
private void RemoveEquipment(object sender, RemoveEquipmentMessage msg)
|
||||
{
|
||||
if (Equipments.Contains(msg.Equipment))
|
||||
Equipments.Remove(msg.Equipment);
|
||||
CallSavePoint(this);
|
||||
}
|
||||
|
||||
private void CallSavePoint(EquipmentViewModel equipment)
|
||||
{
|
||||
var current = equipment;
|
||||
while (current.Parent is EquipmentViewModel model)
|
||||
current = model ?? throw new InvalidOperationException("Parent equipment not found in hierarchy");
|
||||
|
||||
if (current.Parent is PointViewModel pointViewModel)
|
||||
WeakReferenceMessenger.Default.Send(new EditPointMessage(pointViewModel));
|
||||
}
|
||||
|
||||
public EquipmentViewModel()
|
||||
{
|
||||
Name = string.Empty;
|
||||
Description = string.Empty;
|
||||
CreationDate = DateTime.Now;
|
||||
Properties = [];
|
||||
Inspections = [];
|
||||
Equipments = [];
|
||||
NearestInspection = "Нету инспекций";
|
||||
Equipment = new Equipment();
|
||||
|
||||
WeakReferenceMessenger.Default.Register<RemoveEquipmentMessage>(this, RemoveEquipment);
|
||||
}
|
||||
|
||||
public EquipmentViewModel(Equipment equipment)
|
||||
{
|
||||
Name = equipment.Name;
|
||||
Description = equipment.Description;
|
||||
CreationDate = equipment.CreationDate;
|
||||
Images = new ObservableCollection<ImageViewModel>(equipment.Images.Select(i => new ImageViewModel(i)));
|
||||
Properties = new ObservableCollection<PropertyViewModel>(equipment.Properties.Select(e => new PropertyViewModel(e)));
|
||||
Equipments = new ObservableCollection<EquipmentViewModel>(equipment.Equipments.Select(e => new EquipmentViewModel(e){Parent = this}));
|
||||
|
||||
var times = equipment.Inspections.Select(e => new InspectionViewModel(e))
|
||||
.Select(e => e.GetNearestDates())
|
||||
@@ -59,14 +105,20 @@ public partial class EquipmentViewModel : ViewModelBase
|
||||
|
||||
if (Inspections.Count == 0) NearestInspection = "Нету инспекций";
|
||||
Equipment = equipment;
|
||||
|
||||
WeakReferenceMessenger.Default.Register<RemoveEquipmentMessage>(this, RemoveEquipment);
|
||||
}
|
||||
|
||||
public Equipment GetEquipment()
|
||||
{
|
||||
Equipment.Name = Name;
|
||||
Equipment.Description = Description;
|
||||
Equipment.CreationDate = CreationDate;
|
||||
Equipment.Images = Images.Select(e => e.GetImage()).ToList();
|
||||
Equipment.Inspections = Inspections.Select(e => e.GetInspection()).ToList();
|
||||
Equipment.Properties = Properties.Select(e => e.GetProperty()).ToList();
|
||||
Equipment.Equipments = Equipments.Select(e => e.GetEquipment()).ToList();
|
||||
|
||||
return Equipment;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +1,49 @@
|
||||
using System.IO;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Avalonia.Media.Imaging;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using GazpromApp.Messages;
|
||||
using GazpromApp.Models;
|
||||
|
||||
namespace GazpromApp.ViewModels;
|
||||
|
||||
public partial class ImageViewModel : ViewModelBase
|
||||
{
|
||||
public ViewModelBase? Parent;
|
||||
private Image Image { get; }
|
||||
|
||||
[ObservableProperty]
|
||||
private byte[]? _bytes;
|
||||
|
||||
|
||||
[ObservableProperty] private byte[]? _bytes;
|
||||
|
||||
[ObservableProperty] private DateTime _creationDate;
|
||||
|
||||
// EF stuff
|
||||
|
||||
[ObservableProperty]
|
||||
private Point? _point;
|
||||
|
||||
[ObservableProperty]
|
||||
private Equipment? _equipment;
|
||||
|
||||
[ObservableProperty]
|
||||
private Bitmap? _fileName;
|
||||
|
||||
[ObservableProperty] private Point? _point;
|
||||
|
||||
[ObservableProperty] private Equipment? _equipment;
|
||||
|
||||
[ObservableProperty] private Bitmap? _fileName;
|
||||
|
||||
[RelayCommand]
|
||||
private async Task ViewImage() => _ = await WeakReferenceMessenger.Default.Send(new ViewImageMessage(this));
|
||||
|
||||
[RelayCommand]
|
||||
private void DeleteImage() => _ = Parent switch
|
||||
{
|
||||
PointViewModel pmv => pmv.Images.Remove(this),
|
||||
EquipmentViewModel emv => emv.Images.Remove(this),
|
||||
EditPointViewModel editPointViewModel => editPointViewModel.Images.Remove(this),
|
||||
EditEquipmentViewModel editEquipmentViewModel => editEquipmentViewModel.Images.Remove(this),
|
||||
_ => false
|
||||
};
|
||||
|
||||
public ImageViewModel(Image image)
|
||||
{
|
||||
Bytes = image.Bytes;
|
||||
CreationDate = image.CreationDate;
|
||||
Equipment = image.Equipment;
|
||||
Point = image.Point;
|
||||
FileName = image.Bytes is { Length: > 0 } ? new Bitmap(new MemoryStream(image.Bytes)) : null;
|
||||
@@ -35,6 +53,7 @@ public partial class ImageViewModel : ViewModelBase
|
||||
public ImageViewModel()
|
||||
{
|
||||
Bytes = null;
|
||||
CreationDate = DateTime.Now;
|
||||
Equipment = null;
|
||||
Point = null;
|
||||
Image = new Image();
|
||||
@@ -45,6 +64,7 @@ public partial class ImageViewModel : ViewModelBase
|
||||
var ms = new MemoryStream();
|
||||
FileName?.Save(ms);
|
||||
Image.Bytes = ms.ToArray();
|
||||
Image.CreationDate = CreationDate;
|
||||
Image.Equipment = Equipment;
|
||||
Image.Point = Point;
|
||||
return Image;
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using GazpromApp.Enums;
|
||||
using GazpromApp.Messages;
|
||||
using GazpromApp.Models;
|
||||
|
||||
namespace GazpromApp.ViewModels;
|
||||
@@ -11,6 +15,8 @@ public partial class InspectionViewModel : ViewModelBase
|
||||
[ObservableProperty]
|
||||
private string _name;
|
||||
[ObservableProperty]
|
||||
private DateTime _creationDate;
|
||||
[ObservableProperty]
|
||||
private DateTimeOffset _inspectionDate;
|
||||
[ObservableProperty]
|
||||
private PeriodType _periodType;
|
||||
@@ -21,10 +27,25 @@ public partial class InspectionViewModel : ViewModelBase
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isEditing;
|
||||
|
||||
[RelayCommand]
|
||||
private void EditInspection()
|
||||
{
|
||||
IsEditing = !IsEditing;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void RemoveInspection() => WeakReferenceMessenger.Default.Send(new RemoveInspectionMessage(this));
|
||||
|
||||
// ReSharper disable once MemberCanBeMadeStatic.Global
|
||||
public PeriodType[] AllPeriods => Enum.GetValues<PeriodType>()
|
||||
.Where(p => p != PeriodType.Unknown)
|
||||
.ToArray();
|
||||
|
||||
public InspectionViewModel()
|
||||
{
|
||||
Name = string.Empty;
|
||||
CreationDate = DateTime.Now;
|
||||
InspectionDate = DateTimeOffset.Now;
|
||||
PeriodType = 0;
|
||||
PeriodValue = 1;
|
||||
@@ -34,6 +55,7 @@ public partial class InspectionViewModel : ViewModelBase
|
||||
public InspectionViewModel(Inspection inspection)
|
||||
{
|
||||
Name = inspection.Name;
|
||||
CreationDate = inspection.CreationDate;
|
||||
InspectionDate = inspection.InspectionDate;
|
||||
PeriodType = inspection.PeriodType.ToPeriodType();
|
||||
PeriodValue = inspection.PeriodValue;
|
||||
@@ -43,6 +65,7 @@ public partial class InspectionViewModel : ViewModelBase
|
||||
public Inspection GetInspection()
|
||||
{
|
||||
Inspection.Name = Name;
|
||||
Inspection.CreationDate = CreationDate;
|
||||
Inspection.InspectionDate = InspectionDate;
|
||||
Inspection.PeriodType = PeriodType.ToDescription();
|
||||
Inspection.PeriodValue = PeriodValue;
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using GazpromApp.Messages;
|
||||
using GazpromApp.Models;
|
||||
|
||||
namespace GazpromApp.ViewModels;
|
||||
@@ -14,39 +21,64 @@ public partial class PointViewModel : ViewModelBase
|
||||
[ObservableProperty]
|
||||
private string? _description;
|
||||
|
||||
[ObservableProperty]
|
||||
private DateTime _creationDate;
|
||||
|
||||
[ObservableProperty]
|
||||
private double? _latitude;
|
||||
|
||||
[ObservableProperty]
|
||||
private double? _longitude;
|
||||
|
||||
[RelayCommand]
|
||||
private void AddEquipment()
|
||||
{
|
||||
Equipment.Add(new EquipmentViewModel(new Equipment()) {Name = "Новое оборудование", Description = "Описание оборудования", Parent = this});
|
||||
WeakReferenceMessenger.Default.Send(new EditPointMessage(this));
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void RemovePoint()
|
||||
{
|
||||
WeakReferenceMessenger.Default.Send(new RemovePointMessage(this));
|
||||
}
|
||||
|
||||
private void RemoveEquipment(object sender, RemoveEquipmentMessage msg)
|
||||
{
|
||||
if (msg.Equipment.GetEquipment().Point == GetPoint())
|
||||
Equipment.Remove(msg.Equipment);
|
||||
}
|
||||
|
||||
// EF stuff
|
||||
[ObservableProperty]
|
||||
private List<Image> _images;
|
||||
private ObservableCollection<ImageViewModel> _images;
|
||||
[ObservableProperty]
|
||||
private List<Equipment> _equipment;
|
||||
private ObservableCollection<EquipmentViewModel> _equipment;
|
||||
[ObservableProperty]
|
||||
private List<Property> _properties;
|
||||
private ObservableCollection<PropertyViewModel> _properties;
|
||||
|
||||
public PointViewModel(Point point)
|
||||
{
|
||||
Point = point;
|
||||
Name = point.Name;
|
||||
CreationDate = point.CreationDate;
|
||||
Description = point.Description;
|
||||
Latitude = point.Latitude;
|
||||
Longitude = point.Longitude;
|
||||
Images = point.Images;
|
||||
Equipment = point.Equipment;
|
||||
Properties = point.Properties;
|
||||
Images = new ObservableCollection<ImageViewModel>(point.Images.Select(i => new ImageViewModel(i)));
|
||||
Equipment = new ObservableCollection<EquipmentViewModel>(point.Equipment.Select(i => new EquipmentViewModel(i){Parent = this}));
|
||||
Properties = new ObservableCollection<PropertyViewModel>(point.Properties.Select(i => new PropertyViewModel(i)));
|
||||
|
||||
WeakReferenceMessenger.Default.Register<RemoveEquipmentMessage>(this, RemoveEquipment);
|
||||
}
|
||||
|
||||
public Point GetPoint()
|
||||
{
|
||||
Point.Name = Name;
|
||||
Point.Description = Description;
|
||||
Point.Equipment = Equipment;
|
||||
Point.Images = Images;
|
||||
Point.Properties = Properties;
|
||||
Point.CreationDate = CreationDate;
|
||||
Point.Equipment = Equipment.Select(e => e.GetEquipment()).ToList();
|
||||
Point.Images = Images.Select(i => i.GetImage()).ToList();
|
||||
Point.Properties = Properties.Select(p => p.GetProperty()).ToList();
|
||||
return Point;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,10 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using GazpromApp.Messages;
|
||||
using GazpromApp.Models;
|
||||
|
||||
namespace GazpromApp.ViewModels;
|
||||
@@ -8,6 +12,8 @@ namespace GazpromApp.ViewModels;
|
||||
|
||||
public partial class PropertyViewModel : ViewModelBase
|
||||
{
|
||||
public ViewModelBase? Parent { get; init; }
|
||||
|
||||
private Property Property { get; }
|
||||
|
||||
[ObservableProperty]
|
||||
@@ -16,19 +22,36 @@ public partial class PropertyViewModel : ViewModelBase
|
||||
[ObservableProperty]
|
||||
private string _value;
|
||||
|
||||
[ObservableProperty]
|
||||
private DateTime _creationDate;
|
||||
|
||||
public ObservableCollection<PropertyViewModel> Properties { get; set; }
|
||||
|
||||
// Visual and other properties
|
||||
|
||||
public PropertyViewModel? Parent { get; init; }
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isEditing;
|
||||
|
||||
[RelayCommand]
|
||||
private void AddProperty() => Properties.Add(new PropertyViewModel() {Parent = this});
|
||||
|
||||
[RelayCommand]
|
||||
private void RemoveProperty() => WeakReferenceMessenger.Default.Send(new RemovePropertyMessage(this));
|
||||
|
||||
[RelayCommand]
|
||||
private void EditProperty() => IsEditing = !IsEditing;
|
||||
|
||||
private void RemoveProperty(object sender, RemovePropertyMessage msg)
|
||||
{
|
||||
if (Properties.Contains(msg.Property))
|
||||
Properties.Remove(msg.Property);
|
||||
}
|
||||
|
||||
public Property GetProperty(Property? parent = null)
|
||||
{
|
||||
Property.Name = Name;
|
||||
Property.Value = Value;
|
||||
Property.CreationDate = CreationDate;
|
||||
Property.Parent = parent;
|
||||
Property.Properties = Properties.Select(e => e.GetProperty(Property)).ToList();
|
||||
return Property;
|
||||
@@ -38,19 +61,25 @@ public partial class PropertyViewModel : ViewModelBase
|
||||
{
|
||||
Name = "Имя свойства";
|
||||
Value = "Значение свойства";
|
||||
CreationDate = DateTime.Now;
|
||||
Properties = [];
|
||||
Parent = null;
|
||||
Property = new Property();
|
||||
|
||||
WeakReferenceMessenger.Default.Register<RemovePropertyMessage>(this, RemoveProperty);
|
||||
}
|
||||
|
||||
public PropertyViewModel(Property property, PropertyViewModel? parent = null)
|
||||
{
|
||||
Name = property.Name;
|
||||
Value = property.Value;
|
||||
CreationDate = property.CreationDate;
|
||||
Properties = new ObservableCollection<PropertyViewModel>(
|
||||
property.Properties.Select(e => new PropertyViewModel(e, this)));
|
||||
Parent = property.Parent is null ? null : parent;
|
||||
Property = property;
|
||||
|
||||
WeakReferenceMessenger.Default.Register<RemovePropertyMessage>(this, RemoveProperty);
|
||||
}
|
||||
|
||||
public PropertyViewModel(PropertyViewModel property)
|
||||
@@ -60,5 +89,7 @@ public partial class PropertyViewModel : ViewModelBase
|
||||
Properties = [];
|
||||
Parent = property;
|
||||
Property = new Property();
|
||||
|
||||
WeakReferenceMessenger.Default.Register<RemovePropertyMessage>(this, RemoveProperty);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using Avalonia.Controls;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using GazpromApp.Enums;
|
||||
using GazpromApp.Messages;
|
||||
using GazpromApp.Models;
|
||||
using GazpromApp.Views;
|
||||
|
||||
namespace GazpromApp.ViewModels;
|
||||
|
||||
public partial class SaveChangesViewModel : ViewModelBase
|
||||
{
|
||||
[ObservableProperty]
|
||||
private bool _isSave;
|
||||
[ObservableProperty]
|
||||
private bool _isCancel;
|
||||
|
||||
[RelayCommand]
|
||||
private void Cancel(Window w)
|
||||
{
|
||||
((SaveChangesView)w).CanClose = true;
|
||||
WeakReferenceMessenger.Default.Send(new SaveChangesResult(false, true));
|
||||
w.Close(this);
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void Save(Window w)
|
||||
{
|
||||
((SaveChangesView)w).CanClose = true;
|
||||
WeakReferenceMessenger.Default.Send(new SaveChangesResult(true, false));
|
||||
w.Close(this);
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void DontSave(Window w)
|
||||
{
|
||||
((SaveChangesView)w).CanClose = true;
|
||||
WeakReferenceMessenger.Default.Send(new SaveChangesResult(false, false));
|
||||
w.Close(this);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Media.Imaging;
|
||||
using Avalonia.Platform.Storage;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
@@ -16,26 +15,15 @@ using Image = GazpromApp.Models.Image;
|
||||
|
||||
namespace GazpromApp.ViewModels;
|
||||
|
||||
public partial class EditEquipmentDialogViewModel : ViewModelBase
|
||||
public partial class EditEquipmentViewModel : ViewModelBase
|
||||
{
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(CompleteEditCommand))]
|
||||
private string? _name;
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(CompleteEditCommand))]
|
||||
private string? _description;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isNameEditing;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isDescriptionEditing;
|
||||
|
||||
public ObservableCollection<ImageViewModel> Images { get; set; }
|
||||
|
||||
public ObservableCollection<InspectionViewModel> Inspections { get; set; }
|
||||
|
||||
[RelayCommand]
|
||||
private void EditName()
|
||||
{
|
||||
@@ -43,6 +31,13 @@ public partial class EditEquipmentDialogViewModel : ViewModelBase
|
||||
IsDescriptionEditing = false;
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(CompleteEditCommand))]
|
||||
private string? _description;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isDescriptionEditing;
|
||||
|
||||
[RelayCommand]
|
||||
private void EditDescription()
|
||||
{
|
||||
@@ -50,20 +45,17 @@ public partial class EditEquipmentDialogViewModel : ViewModelBase
|
||||
IsNameEditing = false;
|
||||
}
|
||||
|
||||
public ObservableCollection<ImageViewModel> Images { get; set; }
|
||||
|
||||
[RelayCommand]
|
||||
private async Task AddImage(Window w)
|
||||
{
|
||||
var files = await w.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
AllowMultiple = true,
|
||||
Title = "Выберите одну или несколько картинок",
|
||||
FileTypeFilter = [FilePickerFileTypes.ImageAll]
|
||||
});
|
||||
var files = await WeakReferenceMessenger.Default.Send(new RequestImageMessage(this));
|
||||
foreach (var file in files)
|
||||
{
|
||||
try
|
||||
{
|
||||
Images.Add(new ImageViewModel(new Image()) { FileName = new Bitmap(HttpUtility.UrlDecode(file.Path.AbsolutePath) ) });
|
||||
Images.Add(new ImageViewModel(new Image()) { FileName = new Bitmap(HttpUtility.UrlDecode(file.Path.AbsolutePath)), Parent = this});
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
@@ -76,35 +68,20 @@ public partial class EditEquipmentDialogViewModel : ViewModelBase
|
||||
_ = await WeakReferenceMessenger.Default.Send(new ErrorMessage(new ErrorViewModel(error)));
|
||||
}
|
||||
}
|
||||
|
||||
IsImagesEmpty = Images.Count == 0;
|
||||
}
|
||||
|
||||
public ObservableCollection<InspectionViewModel> Inspections { get; set; }
|
||||
|
||||
[RelayCommand]
|
||||
private static async Task ViewImage(ImageViewModel image) => _ = await WeakReferenceMessenger.Default.Send(new ViewImageMessage(image));
|
||||
private void AddInspection() => Inspections.Add(new InspectionViewModel
|
||||
{ Name = "Название инспекции", InspectionDate = DateTimeOffset.Now, PeriodValue = 1, PeriodType = PeriodType.Day });
|
||||
|
||||
private void RemoveInspection(object sender, RemoveInspectionMessage msg)
|
||||
{
|
||||
if (Inspections.Contains(msg.Inspection))
|
||||
Inspections.Remove(msg.Inspection);
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void DeleteImage(ImageViewModel image)
|
||||
{
|
||||
Images.Remove(image);
|
||||
IsImagesEmpty = Images.Count == 0;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void AddInspection()
|
||||
{
|
||||
Inspections.Add(new InspectionViewModel { Name = "Название инспекции", InspectionDate = DateTimeOffset.Now, PeriodValue = 1, PeriodType = PeriodType.Day });
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void EditInspection(InspectionViewModel inspection)
|
||||
{
|
||||
foreach (var item in Inspections)
|
||||
if (item != inspection)
|
||||
item.IsEditing = false;
|
||||
inspection.IsEditing = !inspection.IsEditing;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void DeleteInspection(InspectionViewModel inspection)
|
||||
{
|
||||
@@ -114,21 +91,12 @@ public partial class EditEquipmentDialogViewModel : ViewModelBase
|
||||
public ObservableCollection<PropertyViewModel> Properties { get; set; }
|
||||
|
||||
[RelayCommand]
|
||||
private void AddPropertySimple() => Properties.Add(new PropertyViewModel());
|
||||
private void AddProperty() => Properties.Add(new PropertyViewModel {Parent = this});
|
||||
|
||||
[RelayCommand]
|
||||
private static void AddProperty(PropertyViewModel property) => property.Properties.Add(new PropertyViewModel(property));
|
||||
|
||||
[RelayCommand]
|
||||
private static void EditProperty(PropertyViewModel property) => property.IsEditing = !property.IsEditing;
|
||||
|
||||
[RelayCommand]
|
||||
private void DeleteProperty(PropertyViewModel property)
|
||||
private void RemoveProperty(object sender, RemovePropertyMessage msg)
|
||||
{
|
||||
if (property.Parent is null)
|
||||
Properties.Remove(property);
|
||||
else
|
||||
property.Parent?.Properties.Remove(property);
|
||||
if (Properties.Contains(msg.Property))
|
||||
Properties.Remove(msg.Property);
|
||||
}
|
||||
|
||||
private bool CanCompleteEdit() => !string.IsNullOrWhiteSpace(Name);
|
||||
@@ -136,32 +104,24 @@ public partial class EditEquipmentDialogViewModel : ViewModelBase
|
||||
[RelayCommand(CanExecute = nameof(CanCompleteEdit))]
|
||||
private void CompleteEdit()
|
||||
{
|
||||
IsClosed = true;
|
||||
var equipment = new Equipment
|
||||
{
|
||||
Name = Name,
|
||||
Description = Description,
|
||||
Images = Images.Select(e => e.GetImage()).ToList(),
|
||||
Inspections = Inspections.Select(e => e.GetInspection()).ToList(),
|
||||
Properties = Properties.Select(e => e.GetProperty()).ToList()
|
||||
};
|
||||
WeakReferenceMessenger.Default.Send(new EditEquipmentDone(new EquipmentViewModel(equipment)));
|
||||
_equipment.Name = Name;
|
||||
_equipment.Description = Description;
|
||||
_equipment.Images = Images;
|
||||
_equipment.Inspections = Inspections;
|
||||
_equipment.Properties = Properties;
|
||||
_ = _equipment.GetEquipment();
|
||||
|
||||
CallUpdatePoint(_equipment);
|
||||
}
|
||||
|
||||
|
||||
[RelayCommand]
|
||||
private void CancelEdit(Window w)
|
||||
{
|
||||
IsClosed = true;
|
||||
WeakReferenceMessenger.Default.Send(new EditEquipmentDone(_equipment));
|
||||
CallUpdatePoint(_equipment);
|
||||
}
|
||||
|
||||
// Visual and other properties
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isImagesEmpty;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isClosed;
|
||||
|
||||
private readonly EquipmentViewModel _equipment;
|
||||
|
||||
@@ -169,8 +129,23 @@ public partial class EditEquipmentDialogViewModel : ViewModelBase
|
||||
public PeriodType[] AllPeriods => Enum.GetValues<PeriodType>()
|
||||
.Where(p => p != PeriodType.Unknown)
|
||||
.ToArray();
|
||||
|
||||
private void CallUpdatePoint(ViewModelBase vm)
|
||||
{
|
||||
switch (vm)
|
||||
{
|
||||
case PointViewModel pointViewModel:
|
||||
WeakReferenceMessenger.Default.Send(new EditPointMessage(pointViewModel));
|
||||
break;
|
||||
case EquipmentViewModel equipmentViewModel:
|
||||
CallUpdatePoint(equipmentViewModel.Parent ?? throw new InvalidOperationException("Parent equipment not found in hierarchy"));
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(vm), vm, null);
|
||||
}
|
||||
}
|
||||
|
||||
public EditEquipmentDialogViewModel()
|
||||
public EditEquipmentViewModel()
|
||||
{
|
||||
Name = "Testing";
|
||||
Description = "Testing";
|
||||
@@ -178,12 +153,10 @@ public partial class EditEquipmentDialogViewModel : ViewModelBase
|
||||
Inspections = [];
|
||||
Properties = [];
|
||||
|
||||
IsImagesEmpty = true;
|
||||
|
||||
_equipment = new EquipmentViewModel();
|
||||
}
|
||||
|
||||
public EditEquipmentDialogViewModel(EquipmentViewModel equipment)
|
||||
public EditEquipmentViewModel(EquipmentViewModel equipment)
|
||||
{
|
||||
Name = equipment.Name;
|
||||
Description = equipment.Description;
|
||||
@@ -191,8 +164,14 @@ public partial class EditEquipmentDialogViewModel : ViewModelBase
|
||||
Inspections = new ObservableCollection<InspectionViewModel>(equipment.Inspections.Select(e => e));
|
||||
Properties = new ObservableCollection<PropertyViewModel>(equipment.Properties.Select(e => e));
|
||||
|
||||
IsImagesEmpty = Images.Count == 0;
|
||||
|
||||
_equipment = equipment;
|
||||
|
||||
WeakReferenceMessenger.Default.Register<RemovePropertyMessage>(this, RemoveProperty);
|
||||
WeakReferenceMessenger.Default.Register<RemoveInspectionMessage>(this, RemoveInspection);
|
||||
}
|
||||
|
||||
~EditEquipmentViewModel()
|
||||
{
|
||||
WeakReferenceMessenger.Default.UnregisterAll(this);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Media.Imaging;
|
||||
using Avalonia.Platform.Storage;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
@@ -16,7 +15,7 @@ using Image = GazpromApp.Models.Image;
|
||||
|
||||
namespace GazpromApp.ViewModels;
|
||||
|
||||
public partial class EditPointDialogViewModel : ViewModelBase
|
||||
public partial class EditPointViewModel : ViewModelBase
|
||||
{
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(CompleteEditCommand))]
|
||||
@@ -51,17 +50,12 @@ public partial class EditPointDialogViewModel : ViewModelBase
|
||||
[RelayCommand]
|
||||
private async Task AddImage(Window w)
|
||||
{
|
||||
var files = await w.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
AllowMultiple = true,
|
||||
Title = "Выберите одну или несколько картинок",
|
||||
FileTypeFilter = [FilePickerFileTypes.ImageAll]
|
||||
});
|
||||
var files = await WeakReferenceMessenger.Default.Send(new RequestImageMessage(this));
|
||||
foreach (var file in files)
|
||||
{
|
||||
try
|
||||
{
|
||||
Images.Add(new ImageViewModel(new Image()) { FileName = new Bitmap(HttpUtility.UrlDecode(file.Path.AbsolutePath) ) });
|
||||
Images.Add(new ImageViewModel(new Image()) { FileName = new Bitmap(HttpUtility.UrlDecode(file.Path.AbsolutePath)), Parent = this});
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
@@ -74,66 +68,19 @@ public partial class EditPointDialogViewModel : ViewModelBase
|
||||
_ = await WeakReferenceMessenger.Default.Send(new ErrorMessage(new ErrorViewModel(error)));
|
||||
}
|
||||
}
|
||||
|
||||
IsImagesEmpty = Images.Count == 0;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void DeleteImage(ImageViewModel image)
|
||||
{
|
||||
Images.Remove(image);
|
||||
IsImagesEmpty = Images.Count == 0;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private static async Task ViewImage(ImageViewModel image) => _ = await WeakReferenceMessenger.Default.Send(new ViewImageMessage(image));
|
||||
|
||||
public ObservableCollection<EquipmentViewModel> Equipment { get; set; }
|
||||
|
||||
[RelayCommand]
|
||||
private async Task AddEquipment()
|
||||
{
|
||||
var equipment = await WeakReferenceMessenger.Default.Send(new NewEquipmentMessage());
|
||||
|
||||
if (equipment != null)
|
||||
Equipment.Add(equipment);
|
||||
|
||||
IsEquipmentEmpty = Equipment.Count == 0;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task EditEquipment(EquipmentViewModel equipment)
|
||||
{
|
||||
var e = await WeakReferenceMessenger.Default.Send(new EditEquipmentMessage(equipment)) ?? equipment;
|
||||
Equipment[Equipment.IndexOf(equipment)] = e;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void DeleteEquipment(EquipmentViewModel equipment)
|
||||
{
|
||||
Equipment.Remove(equipment);
|
||||
|
||||
IsEquipmentEmpty = Equipment.Count == 0;
|
||||
}
|
||||
|
||||
public ObservableCollection<PropertyViewModel> Properties { get; set; }
|
||||
|
||||
[RelayCommand]
|
||||
private void AddPropertySimple() => Properties.Add(new PropertyViewModel());
|
||||
private void AddProperty() => Properties.Add(new PropertyViewModel {Parent = this});
|
||||
|
||||
[RelayCommand]
|
||||
private static void AddProperty(PropertyViewModel property) => property.Properties.Add(new PropertyViewModel(property));
|
||||
|
||||
[RelayCommand]
|
||||
private static void EditProperty(PropertyViewModel property) => property.IsEditing = !property.IsEditing;
|
||||
|
||||
[RelayCommand]
|
||||
private void DeleteProperty(PropertyViewModel property)
|
||||
private void RemoveProperty(object sender, RemovePropertyMessage msg)
|
||||
{
|
||||
if (property.Parent is null)
|
||||
Properties.Remove(property);
|
||||
else
|
||||
property.Parent?.Properties.Remove(property);
|
||||
if (Properties.Contains(msg.Property))
|
||||
Properties.Remove(msg.Property);
|
||||
}
|
||||
|
||||
private bool CanCompleteEdit() => !string.IsNullOrWhiteSpace(Name);
|
||||
@@ -141,41 +88,30 @@ public partial class EditPointDialogViewModel : ViewModelBase
|
||||
[RelayCommand(CanExecute = nameof(CanCompleteEdit))]
|
||||
private void CompleteEdit()
|
||||
{
|
||||
IsClosed = true;
|
||||
_point.Name = Name;
|
||||
_point.Description = Description;
|
||||
_point.Images = Images.Select(e => e.GetImage()).ToList();
|
||||
_point.Equipment = Equipment.Select(e => e.GetEquipment()).ToList();
|
||||
_point.Properties = Properties.Select(e => e.GetProperty()).ToList();
|
||||
_point.Images = Images;
|
||||
_point.Equipment = Equipment;
|
||||
_point.Properties = Properties;
|
||||
_ = _point.GetPoint();
|
||||
|
||||
WeakReferenceMessenger.Default.Send(new EditPointDone(new PointViewModel(_point.GetPoint())));
|
||||
WeakReferenceMessenger.Default.Send(new EditPointMessage(_point));
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void CancelEdit(Window w)
|
||||
{
|
||||
IsClosed = true;
|
||||
WeakReferenceMessenger.Default.Send(new EditPointDone(_point));
|
||||
WeakReferenceMessenger.Default.Send(new EditPointMessage(_point));
|
||||
}
|
||||
|
||||
// Visual and other properties
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isImagesEmpty;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isEquipmentEmpty;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isClosed;
|
||||
|
||||
private readonly PointViewModel _point;
|
||||
|
||||
public EditPointDialogViewModel()
|
||||
public EditPointViewModel()
|
||||
{
|
||||
Name = "";
|
||||
Description = "";
|
||||
Name = "fsdfasdfasd";
|
||||
Description = "asfasdfasdfa";
|
||||
Images = [];
|
||||
Equipment = [
|
||||
new EquipmentViewModel
|
||||
@@ -245,23 +181,25 @@ public partial class EditPointDialogViewModel : ViewModelBase
|
||||
}
|
||||
];
|
||||
|
||||
IsImagesEmpty = true;
|
||||
IsEquipmentEmpty = true;
|
||||
|
||||
_point = new PointViewModel(new Point());
|
||||
_point = new PointViewModel(new Point());
|
||||
}
|
||||
|
||||
public EditPointDialogViewModel(PointViewModel point)
|
||||
public EditPointViewModel(PointViewModel point)
|
||||
{
|
||||
Name = point.Name;
|
||||
Description = point.Description;
|
||||
Images = new ObservableCollection<ImageViewModel>(point.Images.Select(e => new ImageViewModel(e)));
|
||||
Equipment = new ObservableCollection<EquipmentViewModel>(point.Equipment.Select(e => new EquipmentViewModel(e)));
|
||||
Properties = new ObservableCollection<PropertyViewModel>(point.Properties.Select(e => new PropertyViewModel(e)));
|
||||
|
||||
IsImagesEmpty = Images.Count == 0;
|
||||
IsEquipmentEmpty = Equipment.Count == 0;
|
||||
Images = new ObservableCollection<ImageViewModel>(point.Images);
|
||||
Images.ToList().ForEach(i => i.Parent = this);
|
||||
Equipment = new ObservableCollection<EquipmentViewModel>(point.Equipment);
|
||||
Properties = new ObservableCollection<PropertyViewModel>(point.Properties);
|
||||
|
||||
_point = point;
|
||||
|
||||
WeakReferenceMessenger.Default.Register<RemovePropertyMessage>(this, RemoveProperty);
|
||||
}
|
||||
|
||||
~EditPointViewModel()
|
||||
{
|
||||
WeakReferenceMessenger.Default.UnregisterAll(this);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
@@ -21,14 +21,19 @@ public partial class MainWindowViewModel : ViewModelBase
|
||||
{
|
||||
public ObservableCollection<PointViewModel> Points { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
private object? _selectedItem;
|
||||
|
||||
[ObservableProperty]
|
||||
private ViewModelBase? _selectedItemViewModel;
|
||||
|
||||
[RelayCommand]
|
||||
private async Task AddPoint()
|
||||
{
|
||||
var point = await WeakReferenceMessenger.Default.Send(new NewPointMessage());
|
||||
if (point == null) return;
|
||||
|
||||
IsLoading = true;
|
||||
|
||||
var point = new PointViewModel(new Point {Name = "Новый объект", Description = "Описание объекта"});
|
||||
|
||||
_context.Point.Add(point.GetPoint());
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
@@ -37,49 +42,16 @@ public partial class MainWindowViewModel : ViewModelBase
|
||||
IsLoading = false;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task EditPoint(PointViewModel point)
|
||||
{
|
||||
var p = await WeakReferenceMessenger.Default.Send(new EditPointMessage(point));
|
||||
if (p == null) return;
|
||||
|
||||
IsLoading = true;
|
||||
|
||||
_context.Update(p.GetPoint());
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
var index = Points.IndexOf(point);
|
||||
if (index != -1)
|
||||
Points[index] = p;
|
||||
|
||||
IsLoading = false;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task RemovePoint(PointViewModel point)
|
||||
{
|
||||
IsLoading = true;
|
||||
|
||||
var pointInDb = await _context.Point.FindAsync(point.GetPoint().Id);
|
||||
if (pointInDb == null) return;
|
||||
|
||||
_context.Remove(pointInDb);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
Points.Remove(point);
|
||||
|
||||
IsLoading = false;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task ImportPoint(Window w)
|
||||
{
|
||||
Directory.CreateDirectory(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "GazpromApp"));
|
||||
var files = await w.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
AllowMultiple = true,
|
||||
SuggestedStartLocation =
|
||||
await w.StorageProvider.TryGetFolderFromPathAsync(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments))
|
||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "GazpromApp"))
|
||||
});
|
||||
|
||||
if (files.Count < 1) return;
|
||||
@@ -92,6 +64,7 @@ public partial class MainWindowViewModel : ViewModelBase
|
||||
var decoded = HttpUtility.UrlDecode(url);
|
||||
var point = DataSerialization.LoadPoint(decoded);
|
||||
point?.SetPropertyParents();
|
||||
point?.SetEquipmentParents();
|
||||
|
||||
if (point == null) continue;
|
||||
_context.Point.Add(point);
|
||||
@@ -108,33 +81,81 @@ public partial class MainWindowViewModel : ViewModelBase
|
||||
[RelayCommand]
|
||||
private async Task ExportPoint(Window w)
|
||||
{
|
||||
Directory.CreateDirectory(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "GazpromApp"));
|
||||
var folder = await w.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
{
|
||||
AllowMultiple = false,
|
||||
SuggestedStartLocation =
|
||||
await w.StorageProvider.TryGetFolderFromPathAsync(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments))
|
||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "GazpromApp"))
|
||||
});
|
||||
if (folder.Count != 1) return;
|
||||
foreach (var point in Points)
|
||||
DataSerialization.SavePoint(point.GetPoint(), Path.Combine(HttpUtility.UrlDecode(folder[0].Path.AbsolutePath), point.Name + ".json") );
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(SyncDbCommand))]
|
||||
private bool _canSync = false;
|
||||
|
||||
private bool CanSyncDb() => CanSync;
|
||||
|
||||
[RelayCommand(CanExecute = nameof(CanSyncDb))]
|
||||
private async Task SyncDb()
|
||||
{
|
||||
IsLoading = true;
|
||||
|
||||
foreach (var point in _pointsToUpdate)
|
||||
{
|
||||
_context.Update(point.GetPoint());
|
||||
|
||||
var index = Points.IndexOf(point);
|
||||
if (index != -1)
|
||||
Points[index] = point;
|
||||
}
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
foreach (var point in _pointsToDelete)
|
||||
{
|
||||
var pointInDb = await _context.Point.FindAsync(point.GetPoint().Id);
|
||||
if (pointInDb == null) continue;
|
||||
|
||||
_context.Remove(pointInDb);
|
||||
|
||||
Points.Remove(point);
|
||||
}
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
_pointsToUpdate.Clear();
|
||||
_pointsToDelete.Clear();
|
||||
|
||||
|
||||
IsLoading = false;
|
||||
CanSync = false;
|
||||
}
|
||||
|
||||
// Visual and other properties
|
||||
[ObservableProperty] private bool _isLoading = true;
|
||||
|
||||
private readonly AppDbContext _context;
|
||||
|
||||
private async Task LoadChildrenForProperties(List<Property> properties)
|
||||
private async Task LoadChildrenForProperties(List<Property> properties, HashSet<Guid> loadedIds)
|
||||
{
|
||||
if (properties.Count == 0)
|
||||
return;
|
||||
|
||||
var parentIds = properties.Select(p => p.Id).ToList();
|
||||
var parentIds = properties.Select(p => p.Id)
|
||||
.Where(id => !loadedIds.Contains(id))
|
||||
.ToList();
|
||||
|
||||
if (parentIds.Count == 0)
|
||||
return;
|
||||
|
||||
parentIds.ForEach(id => loadedIds.Add(id));
|
||||
|
||||
var children = await _context.Property
|
||||
.Where(p => p.ParentPropertyId.HasValue && parentIds.Contains(p.ParentPropertyId.Value))
|
||||
.AsNoTracking()
|
||||
.OrderBy(p => p.CreationDate)
|
||||
.ToListAsync();
|
||||
|
||||
if (children.Count != 0)
|
||||
@@ -142,36 +163,85 @@ public partial class MainWindowViewModel : ViewModelBase
|
||||
var childrenLookup = children.ToLookup(child => child.ParentPropertyId);
|
||||
|
||||
foreach (var parent in properties.Where(parent => childrenLookup.Contains(parent.Id)))
|
||||
parent.Properties.AddRange(childrenLookup[parent.Id]);
|
||||
{
|
||||
parent.Properties.Clear();
|
||||
parent.Properties.AddRange(childrenLookup[parent.Id]);
|
||||
}
|
||||
|
||||
// ReSharper disable once TailRecursiveCall
|
||||
await LoadChildrenForProperties(children);
|
||||
await LoadChildrenForProperties(children, loadedIds);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task LoadChildrenForEquipments(List<Equipment> equipments, HashSet<Guid> loadedIds)
|
||||
{
|
||||
if (equipments.Count == 0)
|
||||
return;
|
||||
|
||||
var parentIds = equipments.Select(e => e.Id)
|
||||
.Where(id => !loadedIds.Contains(id))
|
||||
.ToList();
|
||||
|
||||
if (parentIds.Count == 0)
|
||||
return;
|
||||
|
||||
parentIds.ForEach(id => loadedIds.Add(id));
|
||||
|
||||
var children = await _context.Equipment
|
||||
.Where(e => e.ParentEquipmentId.HasValue && parentIds.Contains(e.ParentEquipmentId.Value))
|
||||
.OrderBy(e => e.CreationDate)
|
||||
.ToListAsync();
|
||||
|
||||
if (children.Count != 0)
|
||||
{
|
||||
var childrenLookup = children.ToLookup(child => child.ParentEquipmentId);
|
||||
|
||||
foreach (var parent in equipments.Where(parent => childrenLookup.Contains(parent.Id)))
|
||||
{
|
||||
parent.Equipments.Clear();
|
||||
parent.Equipments.AddRange(childrenLookup[parent.Id]);
|
||||
}
|
||||
|
||||
await LoadChildrenForEquipments(children, loadedIds);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async Task LoadDataAsync()
|
||||
{
|
||||
IsLoading = true;
|
||||
|
||||
// ReSharper disable once EntityFramework.NPlusOne.IncompleteDataQuery
|
||||
var pointsFromDb = await _context.Point
|
||||
.Include(p => p.Images)
|
||||
.OrderBy(p => p.CreationDate)
|
||||
.Include(p => p.Images
|
||||
.OrderBy(i => i.CreationDate))
|
||||
.Include(p => p.Equipment
|
||||
.OrderBy(e => e.CreationDate))
|
||||
.ThenInclude(e => e.Properties
|
||||
.OrderBy(p => p.CreationDate))
|
||||
.Include(p => p.Equipment)
|
||||
.ThenInclude(e => e.Properties)
|
||||
.ThenInclude(e => e.Images
|
||||
.OrderBy(i => i.CreationDate))
|
||||
.Include(p => p.Equipment)
|
||||
.ThenInclude(e => e.Images)
|
||||
.Include(p => p.Equipment)
|
||||
.ThenInclude(e => e.Inspections)
|
||||
.Include(p => p.Properties)
|
||||
.AsNoTracking()
|
||||
.ThenInclude(e => e.Inspections
|
||||
.OrderBy(i => i.CreationDate))
|
||||
.Include(p => p.Properties
|
||||
.OrderBy(p => p.CreationDate))
|
||||
.ToListAsync();
|
||||
|
||||
var topLevelProperties = pointsFromDb.SelectMany(p => p.Properties)
|
||||
.Concat(pointsFromDb.SelectMany(p => p.Equipment).SelectMany(e => e.Properties))
|
||||
.ToList();
|
||||
|
||||
if (topLevelProperties.Count != 0)
|
||||
await LoadChildrenForProperties(topLevelProperties);
|
||||
var topLevelEquipments = pointsFromDb.SelectMany(p => p.Equipment)
|
||||
.ToList();
|
||||
|
||||
if (topLevelProperties.Count != 0)
|
||||
await LoadChildrenForProperties(topLevelProperties, []);
|
||||
|
||||
if (topLevelEquipments.Count != 0)
|
||||
await LoadChildrenForEquipments(topLevelEquipments, []);
|
||||
|
||||
Points.Clear();
|
||||
foreach (var point in pointsFromDb)
|
||||
Points.Add(new PointViewModel(point));
|
||||
@@ -179,16 +249,48 @@ public partial class MainWindowViewModel : ViewModelBase
|
||||
IsLoading = false;
|
||||
}
|
||||
|
||||
private readonly ObservableCollection<PointViewModel> _pointsToUpdate = [];
|
||||
private readonly ObservableCollection<PointViewModel> _pointsToDelete = [];
|
||||
|
||||
private void EditPoint(object sender, EditPointMessage msg)
|
||||
{
|
||||
if (!_pointsToUpdate.Contains(msg.Point))
|
||||
_pointsToUpdate.Add(msg.Point);
|
||||
CanSync = true;
|
||||
}
|
||||
|
||||
private void RemovePoint(object sender, RemovePointMessage msg)
|
||||
{
|
||||
if (!_pointsToDelete.Contains(msg.Point))
|
||||
_pointsToDelete.Add(msg.Point);
|
||||
Points.Remove(msg.Point);
|
||||
CanSync = true;
|
||||
}
|
||||
|
||||
private void HandleSelectionChanged(object sender, SelectionChangedMessage msg)
|
||||
{
|
||||
SelectedItemViewModel = msg.ViewModel switch
|
||||
{
|
||||
PointViewModel pointViewModel => new EditPointViewModel(pointViewModel),
|
||||
EquipmentViewModel equipmentViewModel => new EditEquipmentViewModel(equipmentViewModel),
|
||||
_ => msg.ViewModel
|
||||
};
|
||||
}
|
||||
|
||||
public MainWindowViewModel(AppDbContext context)
|
||||
{
|
||||
Points = [];
|
||||
_context = context;
|
||||
_ = LoadDataAsync();
|
||||
|
||||
WeakReferenceMessenger.Default.Register<EditPointMessage>(this, EditPoint);
|
||||
WeakReferenceMessenger.Default.Register<RemovePointMessage>(this, RemovePoint);
|
||||
WeakReferenceMessenger.Default.Register<SelectionChangedMessage>(this, HandleSelectionChanged);
|
||||
}
|
||||
|
||||
public MainWindowViewModel()
|
||||
{
|
||||
Points = [new PointViewModel(new Point()) { Name = "Name test", Description = "Description test" }];
|
||||
Points = [new PointViewModel(new Point()) { Name = "Новый объект", Description = "Описание объекта" }];
|
||||
_context = new AppDbContext();
|
||||
IsLoading = false;
|
||||
}
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Media.Imaging;
|
||||
using Avalonia.Platform.Storage;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using GazpromApp.Enums;
|
||||
using GazpromApp.Messages;
|
||||
using GazpromApp.Models;
|
||||
using Image = GazpromApp.Models.Image;
|
||||
|
||||
namespace GazpromApp.ViewModels;
|
||||
|
||||
public partial class NewEquipmentDialogViewModel : ViewModelBase
|
||||
{
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(EnterEquipmentCommand))]
|
||||
private string? _name;
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(EnterEquipmentCommand))]
|
||||
private string? _description;
|
||||
|
||||
public ObservableCollection<ImageViewModel> Images { get; } = [];
|
||||
|
||||
[RelayCommand]
|
||||
private async Task AddImage(Window w)
|
||||
{
|
||||
var files = await w.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
AllowMultiple = true,
|
||||
Title = "Выберите одну или несколько картинок",
|
||||
FileTypeFilter = [FilePickerFileTypes.ImageAll]
|
||||
});
|
||||
|
||||
foreach (var file in files)
|
||||
{
|
||||
try
|
||||
{
|
||||
Images.Add(new ImageViewModel(new Image()) { FileName = new Bitmap(HttpUtility.UrlDecode(file.Path.AbsolutePath)) });
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
var error = new Error
|
||||
{
|
||||
Title = "Ошибка обработки картинки",
|
||||
Message = $"Картинка не была добавлена: \"{HttpUtility.UrlDecode(file.Name)}\"",
|
||||
Severity = ErrorSeverity.Error
|
||||
};
|
||||
_ = await WeakReferenceMessenger.Default.Send(new ErrorMessage(new ErrorViewModel(error)));
|
||||
}
|
||||
}
|
||||
|
||||
IsImagesEmpty = Images.Count == 0;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void DeleteImage(ImageViewModel image)
|
||||
{
|
||||
Images.Remove(image);
|
||||
IsImagesEmpty = Images.Count == 0;
|
||||
}
|
||||
|
||||
private bool CanEnterEquipment() => !string.IsNullOrEmpty(Name);
|
||||
|
||||
[RelayCommand (CanExecute = nameof(CanEnterEquipment))]
|
||||
private void EnterEquipment()
|
||||
{
|
||||
var equipment = new Equipment
|
||||
{
|
||||
Name = Name,
|
||||
Description = Description ?? string.Empty,
|
||||
Images = Images.Select(e => e.GetImage()).ToList()
|
||||
|
||||
};
|
||||
WeakReferenceMessenger.Default.Send(new NewEquipmentDone(new EquipmentViewModel(equipment)));
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private static void CancelEnterEquipment(Window w)
|
||||
{
|
||||
w.Close();
|
||||
}
|
||||
|
||||
// Visual and other stuff
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isImagesEmpty;
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Media.Imaging;
|
||||
using Avalonia.Platform.Storage;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using GazpromApp.Enums;
|
||||
using GazpromApp.Messages;
|
||||
using GazpromApp.Models;
|
||||
using Image = GazpromApp.Models.Image;
|
||||
using Point = GazpromApp.Models.Point;
|
||||
|
||||
namespace GazpromApp.ViewModels;
|
||||
|
||||
public partial class NewPointDialogViewModel : ViewModelBase
|
||||
{
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(EnterPointCommand))]
|
||||
private string? _name;
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(EnterPointCommand))]
|
||||
private string? _description;
|
||||
|
||||
public ObservableCollection<ImageViewModel> Images { get; } = [];
|
||||
|
||||
[RelayCommand]
|
||||
private async Task AddImage(Window w)
|
||||
{
|
||||
var files = await w.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
AllowMultiple = true,
|
||||
Title = "Выберите одну или несколько картинок",
|
||||
FileTypeFilter = [FilePickerFileTypes.ImageAll]
|
||||
});
|
||||
foreach (var file in files)
|
||||
{
|
||||
try
|
||||
{
|
||||
Images.Add(new ImageViewModel(new Image()) { FileName = new Bitmap(HttpUtility.UrlDecode(file.Path.AbsolutePath)) });
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
var error = new Error
|
||||
{
|
||||
Title = "Ошибка обработки картинки",
|
||||
Message = $"Картинка не была добавлена: \"{HttpUtility.UrlDecode(file.Name)}\"",
|
||||
Severity = ErrorSeverity.Error
|
||||
};
|
||||
_ = await WeakReferenceMessenger.Default.Send(new ErrorMessage(new ErrorViewModel(error)));
|
||||
}
|
||||
}
|
||||
|
||||
IsImagesEmpty = Images.Count == 0;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void DeleteImage(ImageViewModel image)
|
||||
{
|
||||
Images.Remove(image);
|
||||
IsImagesEmpty = Images.Count == 0;
|
||||
}
|
||||
|
||||
private bool CanEnterPoint() => !string.IsNullOrEmpty(Name);
|
||||
|
||||
[RelayCommand (CanExecute = nameof(CanEnterPoint))]
|
||||
private void EnterPoint()
|
||||
{
|
||||
var point = new Point
|
||||
{
|
||||
Name = Name,
|
||||
Description = Description,
|
||||
Images = Images.Select(e => e.GetImage()).ToList()
|
||||
};
|
||||
WeakReferenceMessenger.Default.Send(new NewPointDone(new PointViewModel(point)));
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private static void CancelEnterPoint(Window w)
|
||||
{
|
||||
w.Close();
|
||||
}
|
||||
|
||||
// Visual properties
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isImagesEmpty = true;
|
||||
}
|
||||
Reference in New Issue
Block a user