Compare commits
10
Commits
bd8b780a39
...
c1f0c8714f
+7
@@ -5,13 +5,20 @@
|
||||
<map>
|
||||
<entry key="App.axaml" value="GazpromApp.csproj" />
|
||||
<entry key="Views/EditEquipmentDialog.axaml" value="GazpromApp.csproj" />
|
||||
<entry key="Views/EditEquipmentView.axaml" value="GazpromApp.csproj" />
|
||||
<entry key="Views/EditPointDialog.axaml" value="GazpromApp.csproj" />
|
||||
<entry key="Views/EditPointView.axaml" value="GazpromApp.csproj" />
|
||||
<entry key="Views/EquipmentView.axaml" value="GazpromApp.csproj" />
|
||||
<entry key="Views/ErrorView.axaml" value="GazpromApp.csproj" />
|
||||
<entry key="Views/ImageView.axaml" value="GazpromApp.csproj" />
|
||||
<entry key="Views/InspectionView.axaml" value="GazpromApp.csproj" />
|
||||
<entry key="Views/MainWindow.axaml" value="GazpromApp.csproj" />
|
||||
<entry key="Views/NewEquipmentDialog.axaml" value="GazpromApp.csproj" />
|
||||
<entry key="Views/NewPointDialog.axaml" value="GazpromApp.csproj" />
|
||||
<entry key="Views/NewPointView.axaml" value="GazpromApp.csproj" />
|
||||
<entry key="Views/PointView.axaml" value="GazpromApp.csproj" />
|
||||
<entry key="Views/PropertyView.axaml" value="GazpromApp.csproj" />
|
||||
<entry key="Views/SaveChangesView.axaml" value="GazpromApp.csproj" />
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
|
||||
+7
@@ -9,5 +9,12 @@
|
||||
<jdbc-url>jdbc:sqlite:identifier.sqlite</jdbc-url>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
</data-source>
|
||||
<data-source source="LOCAL" name="GazpromApp.db" uuid="594ee7a3-9498-4753-a25d-1e2967c88d5c">
|
||||
<driver-ref>sqlite.xerial</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
|
||||
<jdbc-url>jdbc:sqlite:$USER_HOME$/AppData/Local/GazpromApp/GazpromApp.db</jdbc-url>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
</data-source>
|
||||
</component>
|
||||
</project>
|
||||
@@ -2,6 +2,8 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
x:Class="GazpromApp.App"
|
||||
xmlns:local="using:GazpromApp"
|
||||
xmlns:icons="using:Material.Icons.Avalonia"
|
||||
xmlns:material="using:Material.Styles.Themes"
|
||||
RequestedThemeVariant="Default">
|
||||
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->
|
||||
|
||||
@@ -10,6 +12,7 @@
|
||||
</Application.DataTemplates>
|
||||
|
||||
<Application.Styles>
|
||||
<FluentTheme />
|
||||
<material:MaterialTheme BaseTheme="Inherit" PrimaryColor="LightBlue" SecondaryColor="Amber"/>
|
||||
<icons:MaterialIconStyles/>
|
||||
</Application.Styles>
|
||||
</Application>
|
||||
+23
-6
@@ -1,16 +1,20 @@
|
||||
using System.Linq;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Data.Core;
|
||||
using Avalonia.Data.Core.Plugins;
|
||||
using System.Linq;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using GazpromApp.Utils;
|
||||
using GazpromApp.ViewModels;
|
||||
using GazpromApp.Views;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace GazpromApp;
|
||||
|
||||
public partial class App : Application
|
||||
public class App : Application
|
||||
{
|
||||
private static ServiceProvider? Services { get; set; }
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
@@ -18,14 +22,27 @@ public partial class App : Application
|
||||
|
||||
public override void OnFrameworkInitializationCompleted()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
|
||||
services.AddDbContext<AppDbContext>(options =>
|
||||
{
|
||||
var dbPath = new AppDbContext().DbPath;
|
||||
options.UseSqlite($"Data Source={dbPath}");
|
||||
});
|
||||
|
||||
services.AddTransient<MainWindowViewModel>();
|
||||
|
||||
Services = services.BuildServiceProvider();
|
||||
|
||||
var dbContext = Services.GetRequiredService<AppDbContext>();
|
||||
dbContext.Database.EnsureCreated();
|
||||
|
||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
// Avoid duplicate validations from both Avalonia and the CommunityToolkit.
|
||||
// More info: https://docs.avaloniaui.net/docs/guides/development-guides/data-validation#manage-validationplugins
|
||||
DisableAvaloniaDataAnnotationValidation();
|
||||
desktop.MainWindow = new MainWindow
|
||||
{
|
||||
DataContext = new MainWindowViewModel(),
|
||||
DataContext = Services.GetRequiredService<MainWindowViewModel>()
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+22
-1
@@ -1,4 +1,8 @@
|
||||
namespace GazpromApp.Enums;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Avalonia.Data.Converters;
|
||||
|
||||
namespace GazpromApp.Enums;
|
||||
|
||||
public enum PeriodType
|
||||
{
|
||||
@@ -35,4 +39,21 @@ public static class PeriodTypeExtensions
|
||||
_ => PeriodType.Unknown
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class PeriodConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is PeriodType periodType)
|
||||
return periodType.ToDescription();
|
||||
return false;
|
||||
}
|
||||
|
||||
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is string periodType)
|
||||
return periodType.ToPeriodType();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AnimatedImage.Avalonia" Version="2.0.0" />
|
||||
<PackageReference Include="Avalonia" Version="11.3.2" />
|
||||
<PackageReference Include="Avalonia.Controls.ItemsRepeater" Version="11.1.5" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="11.3.2" />
|
||||
@@ -25,6 +26,8 @@
|
||||
</PackageReference>
|
||||
<PackageReference Include="AvaloniaUI.DiagnosticsSupport" Version="2.0.4" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.1" />
|
||||
<PackageReference Include="Material.Avalonia" Version="3.12.0" />
|
||||
<PackageReference Include="Material.Icons.Avalonia" Version="2.4.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.6">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||
using System;
|
||||
using GazpromApp.ViewModels;
|
||||
|
||||
namespace GazpromApp.Messages;
|
||||
|
||||
public class EditEquipmentMessage(EquipmentViewModel equipment) : AsyncRequestMessage<EquipmentViewModel?>
|
||||
public class EditEquipmentMessage(EquipmentViewModel equipment)
|
||||
{
|
||||
public EquipmentViewModel Equipment { get; } = equipment;
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||
using GazpromApp.Models;
|
||||
using GazpromApp.ViewModels;
|
||||
|
||||
namespace GazpromApp.Messages;
|
||||
|
||||
public class EditPointMessage(PointViewModel pointViewModel) : AsyncRequestMessage<PointViewModel?>
|
||||
public class EditPointMessage(PointViewModel point)
|
||||
{
|
||||
public PointViewModel Point { get; } = pointViewModel;
|
||||
public PointViewModel Point { get; } = point;
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
using GazpromApp.ViewModels;
|
||||
|
||||
namespace GazpromApp.Messages;
|
||||
|
||||
public class NewEquipmentDone(EquipmentViewModel equipment)
|
||||
{
|
||||
public EquipmentViewModel Equipment { get; } = equipment;
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||
using GazpromApp.ViewModels;
|
||||
|
||||
namespace GazpromApp.Messages;
|
||||
|
||||
public class NewEquipmentMessage : AsyncRequestMessage<EquipmentViewModel?>;
|
||||
@@ -1,8 +0,0 @@
|
||||
using GazpromApp.ViewModels;
|
||||
|
||||
namespace GazpromApp.Messages;
|
||||
|
||||
public class NewPointDone(PointViewModel pointViewModel)
|
||||
{
|
||||
public PointViewModel Point { get; } = pointViewModel;
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
using GazpromApp.ViewModels;
|
||||
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||
namespace GazpromApp.Messages;
|
||||
|
||||
public class NewPointMessage : AsyncRequestMessage<PointViewModel?>;
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace GazpromApp.Messages;
|
||||
|
||||
public class EditEquipmentDone(EquipmentViewModel equipment)
|
||||
public class RemoveEquipmentMessage(EquipmentViewModel equipment)
|
||||
{
|
||||
public EquipmentViewModel Equipment { get; } = equipment;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using GazpromApp.ViewModels;
|
||||
|
||||
namespace GazpromApp.Messages;
|
||||
|
||||
public class RemoveInspectionMessage(InspectionViewModel inspection)
|
||||
{
|
||||
public InspectionViewModel Inspection { get; } = inspection;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace GazpromApp.Messages;
|
||||
|
||||
public class EditPointDone(PointViewModel pointViewModel)
|
||||
public class RemovePointMessage(PointViewModel pointViewModel)
|
||||
{
|
||||
public PointViewModel Point { get; } = pointViewModel;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using GazpromApp.ViewModels;
|
||||
|
||||
namespace GazpromApp.Messages;
|
||||
|
||||
public class RemovePropertyMessage(PropertyViewModel property)
|
||||
{
|
||||
public PropertyViewModel Property { get; } = property;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
using Avalonia.Platform.Storage;
|
||||
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||
using GazpromApp.ViewModels;
|
||||
|
||||
namespace GazpromApp.Messages;
|
||||
|
||||
public class RequestImageMessage(ViewModelBase viewModel) : AsyncRequestMessage<IReadOnlyList<IStorageFile>>
|
||||
{
|
||||
private ViewModelBase Caller { get; set; } = viewModel;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||
using GazpromApp.ViewModels;
|
||||
|
||||
namespace GazpromApp.Messages;
|
||||
|
||||
public class SaveChangesMessage(SaveChangesViewModel saveChanges) : AsyncRequestMessage<SaveChangesViewModel?>
|
||||
{
|
||||
public SaveChangesViewModel SaveChanges { get; } = saveChanges;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace GazpromApp.Messages;
|
||||
|
||||
public class SaveChangesResult(bool save, bool cancel)
|
||||
{
|
||||
public bool Save { get; } = save;
|
||||
public bool Cancel { get; } = cancel;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using GazpromApp.ViewModels;
|
||||
|
||||
namespace GazpromApp.Messages;
|
||||
|
||||
public class SelectionChangedMessage(ViewModelBase viewModel)
|
||||
{
|
||||
public ViewModelBase ViewModel { get; } = viewModel;
|
||||
}
|
||||
+34
-11
@@ -1,26 +1,49 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace GazpromApp.Models;
|
||||
|
||||
public class Equipment
|
||||
{
|
||||
public Equipment()
|
||||
{
|
||||
LocalId = Id == Guid.Empty ? Guid.NewGuid() : Id;
|
||||
}
|
||||
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public int Id { get; set; }
|
||||
[JsonIgnore]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[NotMapped]
|
||||
public Guid LocalId { get; set; }
|
||||
|
||||
[Required]
|
||||
public string? Name { get; set; } = string.Empty;
|
||||
[Required]
|
||||
public string? Description { get; set; } = string.Empty;
|
||||
[Required]
|
||||
public int PointId { get; set; }
|
||||
public int ImageId { get; set; }
|
||||
public List<int> InspectionIds { get; set; } = [];
|
||||
public DateTime CreationDate { get; set; }
|
||||
|
||||
// Foreign keys
|
||||
[JsonIgnore]
|
||||
public Guid? PointId { get; set; }
|
||||
[JsonIgnore]
|
||||
public List<Guid> ImageIds { get; set; } = [];
|
||||
[JsonIgnore]
|
||||
public List<Guid> InspectionIds { get; set; } = [];
|
||||
[JsonIgnore]
|
||||
public List<Guid> EquipmentIds { get; set; } = [];
|
||||
public Guid? ParentEquipmentId { get; set; }
|
||||
|
||||
// EF stuff
|
||||
public Image? Image { get; set; }
|
||||
public Models.Point? Point { get; set; }
|
||||
// Navigation Properties
|
||||
public List<Image> Images { get; set; } = [];
|
||||
[JsonIgnore]
|
||||
public Point? Point { get; set; } = null!;
|
||||
public List<Property> Properties { get; set; } = [];
|
||||
public List<Inspection> Inspections { get; set; } = [];
|
||||
public List<Equipment> Equipments { get; set; } = [];
|
||||
public Equipment? ParentEquipment { get; set; }
|
||||
}
|
||||
+3
-4
@@ -1,11 +1,10 @@
|
||||
using GazpromApp.Enums;
|
||||
using GazpromApp.ViewModels;
|
||||
|
||||
namespace GazpromApp.Models;
|
||||
|
||||
public class Error
|
||||
{
|
||||
public string? Title { get; set; }
|
||||
public string? Message { get; set; }
|
||||
public ErrorSeverity Severity { get; set; }
|
||||
public string? Title { get; init; }
|
||||
public string? Message { get; init; }
|
||||
public ErrorSeverity Severity { get; init; }
|
||||
}
|
||||
+17
-5
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace GazpromApp.Models;
|
||||
public class Image
|
||||
@@ -9,10 +9,22 @@ public class Image
|
||||
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public int Id { get; set; }
|
||||
[JsonIgnore]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[Required]
|
||||
public byte[] Bytes { get; set; } = [];
|
||||
// EF stuff
|
||||
public List<Point> Points { get; set; } = [];
|
||||
public List<Equipment> Equipment { get; set; } = [];
|
||||
public DateTime CreationDate { get; set; }
|
||||
|
||||
// Foreign keys
|
||||
[JsonIgnore]
|
||||
public Guid? PointId { get; set; }
|
||||
[JsonIgnore]
|
||||
public Guid? EquipmentId { get; set; }
|
||||
|
||||
// Navigation Properties
|
||||
[JsonIgnore]
|
||||
public Point? Point { get; set; }
|
||||
[JsonIgnore]
|
||||
public Equipment? Equipment { get; set; }
|
||||
}
|
||||
+13
-5
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace GazpromApp.Models;
|
||||
|
||||
@@ -8,17 +9,24 @@ public class Inspection
|
||||
{
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public int Id { get; set; }
|
||||
[JsonIgnore]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[Required]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public DateTime CreationDate { get; set; }
|
||||
[Required]
|
||||
public DateTime InspectionDate { get; set; }
|
||||
public DateTimeOffset InspectionDate { get; set; }
|
||||
[Required]
|
||||
public string PeriodType { get; set; } = string.Empty;
|
||||
[Required]
|
||||
public float PeriodValue { get; set; }
|
||||
public int EquipmentId { get; set; }
|
||||
|
||||
// Foreign keys
|
||||
[JsonIgnore]
|
||||
public Guid EquipmentId { get; set; }
|
||||
|
||||
// EF stuff
|
||||
public Equipment? Equipment { get; set; }
|
||||
// Navigation Properties
|
||||
[JsonIgnore]
|
||||
public Equipment? Equipment { get; } = new();
|
||||
}
|
||||
+10
-8
@@ -1,6 +1,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace GazpromApp.Models;
|
||||
|
||||
@@ -8,16 +10,16 @@ public class Point
|
||||
{
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public int Id { get; set; }
|
||||
[JsonIgnore]
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
[Required]
|
||||
public string? Name { get; set; } = string.Empty;
|
||||
[Required]
|
||||
public string? Description { get; set; } = string.Empty;
|
||||
[Required]
|
||||
public double Latitude { get; set; } = 0;
|
||||
[Required]
|
||||
public double Longitude { get; set; } = 0;
|
||||
// EF stuff
|
||||
public DateTime CreationDate { get; set; }
|
||||
public double Latitude { get; set; }
|
||||
public double Longitude { get; set; }
|
||||
// Navigation Properties
|
||||
public List<Image> Images { get; set; } = [];
|
||||
public List<Equipment> Equipment { get; set; } = [];
|
||||
public List<Property> Properties { get; set; } = [];
|
||||
|
||||
+29
-5
@@ -1,17 +1,41 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace GazpromApp.Models;
|
||||
|
||||
public class Property
|
||||
{
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public int Id { get; set; }
|
||||
public int ParentId { get; set; }
|
||||
[JsonIgnore]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[Required]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Value { get; set; } = string.Empty;
|
||||
public List<Models.Point> Points { get; set; } = [];
|
||||
public List<Equipment> Equipment { get; } = [];
|
||||
public DateTime CreationDate { get; set; }
|
||||
|
||||
// For self-referencing hierarchy (Property of a Property)
|
||||
[JsonIgnore]
|
||||
public Guid? ParentPropertyId { get; set; }
|
||||
[JsonIgnore]
|
||||
public Property? Parent { get; set; }
|
||||
|
||||
// For a Property of a Point
|
||||
[JsonIgnore]
|
||||
public Guid? PointId { get; set; }
|
||||
[JsonIgnore]
|
||||
public Point? Point { get; set; }
|
||||
|
||||
// For a Property of an Equipment
|
||||
[JsonIgnore]
|
||||
public Guid? EquipmentId { get; set; }
|
||||
[JsonIgnore]
|
||||
public Equipment? Equipment { get; set; }
|
||||
|
||||
// Child properties in the hierarchy
|
||||
public List<Property> Properties { get; set; } = [];
|
||||
}
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
using Avalonia;
|
||||
using System;
|
||||
using System;
|
||||
using Avalonia;
|
||||
|
||||
namespace GazpromApp;
|
||||
|
||||
@@ -7,7 +7,7 @@ sealed class Program
|
||||
{
|
||||
// Initialization code. Don't use any Avalonia, third-party APIs or any
|
||||
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
|
||||
// yet and stuff might break.
|
||||
// yet, and stuff might break.
|
||||
[STAThread]
|
||||
public static void Main(string[] args) => BuildAvaloniaApp()
|
||||
.StartWithClassicDesktopLifetime(args);
|
||||
|
||||
+81
-30
@@ -1,51 +1,102 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.IO;
|
||||
using GazpromApp.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace GazpromApp.Utils;
|
||||
|
||||
public class AppDbContext : DbContext
|
||||
{
|
||||
public DbSet<Models.Image> Image { get; set; }
|
||||
public DbSet<Image> Image { get; set; }
|
||||
public DbSet<Equipment> Equipment { get; set; }
|
||||
public DbSet<Models.Point> Point { get; set; }
|
||||
public DbSet<Inspection> Inspection { get; set; }
|
||||
public DbSet<Property> Property { get; set; }
|
||||
public DbSet<Point> Point { get; set; }
|
||||
|
||||
public string DbPath { get; }
|
||||
|
||||
public AppDbContext()
|
||||
{
|
||||
var path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||||
Directory.CreateDirectory(Path.Combine(path, "GazpromApp"));
|
||||
DbPath = Path.Combine(Path.Combine(path, "GazpromApp"), "GazpromApp.db");
|
||||
}
|
||||
|
||||
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
|
||||
{
|
||||
var path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||||
Directory.CreateDirectory(Path.Combine(path, "GazpromApp"));
|
||||
DbPath = Path.Combine(Path.Combine(path, "GazpromApp"), "GazpromApp.db");
|
||||
}
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
base.OnConfiguring(optionsBuilder);
|
||||
optionsBuilder.UseSqlite("Data Source=MainDB.db");
|
||||
optionsBuilder.UseSqlite($"Data Source={DbPath}");
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
base.OnModelCreating(modelBuilder);
|
||||
|
||||
// ==== Point RELATIONSHIPS ====
|
||||
modelBuilder.Entity<Point>()
|
||||
.HasMany(p => p.Equipment)
|
||||
.WithOne(e => e.Point)
|
||||
.HasForeignKey(e => e.PointId)
|
||||
.IsRequired(false)
|
||||
.OnDelete(DeleteBehavior.Cascade); // Deleting a Point deletes its Equipment.
|
||||
|
||||
// Images
|
||||
modelBuilder.Entity<Models.Point>()
|
||||
.HasMany(e => e.Images)
|
||||
.WithMany(e => e.Points);
|
||||
|
||||
modelBuilder.Entity<Equipment>()
|
||||
.HasOne(e => e.Image)
|
||||
.WithMany(e => e.Equipment)
|
||||
.HasForeignKey(e => e.ImageId);
|
||||
|
||||
// Properties
|
||||
modelBuilder.Entity<Models.Point>()
|
||||
.HasMany(e => e.Properties)
|
||||
.WithMany(e => e.Points);
|
||||
|
||||
modelBuilder.Entity<Equipment>()
|
||||
.HasMany(e => e.Properties)
|
||||
.WithMany(e => e.Equipment);
|
||||
|
||||
// Equipment
|
||||
modelBuilder.Entity<Equipment>()
|
||||
.HasOne(e => e.Point)
|
||||
.WithMany(e => e.Equipment)
|
||||
.HasForeignKey(e => e.PointId);
|
||||
modelBuilder.Entity<Point>()
|
||||
.HasMany(p => p.Images)
|
||||
.WithOne(i => i.Point)
|
||||
.HasForeignKey(i => i.PointId)
|
||||
.OnDelete(DeleteBehavior.Cascade); // Deleting a Point deletes its Images.
|
||||
|
||||
|
||||
// ==== Equipment RELATIONSHIPS ====
|
||||
modelBuilder.Entity<Equipment>()
|
||||
.HasMany(e => e.Inspections)
|
||||
.WithOne(e => e.Equipment)
|
||||
.HasForeignKey(e => e.EquipmentId);
|
||||
.WithOne(i => i.Equipment)
|
||||
.HasForeignKey(i => i.EquipmentId)
|
||||
.OnDelete(DeleteBehavior.Cascade); // Deleting Equipment deletes its Inspections.
|
||||
|
||||
modelBuilder.Entity<Equipment>()
|
||||
.HasMany(e => e.Images)
|
||||
.WithOne(i => i.Equipment)
|
||||
.HasForeignKey(i => i.EquipmentId)
|
||||
.OnDelete(DeleteBehavior.Cascade); // Equipment has one Image.
|
||||
|
||||
modelBuilder.Entity<Equipment>()
|
||||
.HasMany(e => e.Equipments)
|
||||
.WithOne(e => e.ParentEquipment)
|
||||
.HasForeignKey(e => e.ParentEquipmentId)
|
||||
.IsRequired(false)
|
||||
.OnDelete(DeleteBehavior.Cascade); // Equipment has many Equipments.
|
||||
|
||||
// ==== PROPERTY RELATIONSHIPS ====
|
||||
// Property as a child of a Point
|
||||
modelBuilder.Entity<Point>()
|
||||
.HasMany(p => p.Properties)
|
||||
.WithOne(prop => prop.Point)
|
||||
.HasForeignKey(prop => prop.PointId)
|
||||
.IsRequired(false)
|
||||
.OnDelete(DeleteBehavior.Cascade); // Deleting a Point deletes its Properties.
|
||||
|
||||
// Property as a child of an Equipment
|
||||
modelBuilder.Entity<Equipment>()
|
||||
.HasMany(e => e.Properties)
|
||||
.WithOne(prop => prop.Equipment)
|
||||
.HasForeignKey(prop => prop.EquipmentId)
|
||||
.IsRequired(false)
|
||||
.OnDelete(DeleteBehavior.Cascade); // Deleting Equipment deletes its Properties.
|
||||
|
||||
// Property as a child of another Property (self-referencing)
|
||||
modelBuilder.Entity<Property>()
|
||||
.HasMany(p => p.Properties)
|
||||
.WithOne(p => p.Parent)
|
||||
.HasForeignKey(p => p.ParentPropertyId)
|
||||
.IsRequired(false)
|
||||
.OnDelete(DeleteBehavior.Cascade); // Deleting a parent Property deletes its children.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using GazpromApp.Models;
|
||||
|
||||
namespace GazpromApp.Utils;
|
||||
|
||||
public static class DataSerialization
|
||||
{
|
||||
private static void SaveData(string path, string data)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
File.WriteAllText(path, data);
|
||||
return;
|
||||
}
|
||||
|
||||
var dir = Path.GetDirectoryName(path) ?? "";
|
||||
var fileName = Path.GetFileNameWithoutExtension(path);
|
||||
var ext = Path.GetExtension(path);
|
||||
var index = 1;
|
||||
|
||||
while (File.Exists(Path.Combine(dir, $"{fileName} ({index}){ext}")))
|
||||
index++;
|
||||
|
||||
File.WriteAllText(Path.Combine(dir, $"{fileName} ({index}){ext}"), data);
|
||||
}
|
||||
|
||||
private static string LoadData(string path)
|
||||
{
|
||||
var text = File.ReadAllText(path);
|
||||
return text;
|
||||
}
|
||||
|
||||
public static void SavePoint(Point point, string path)
|
||||
{
|
||||
SaveData(path, point.Serialize());
|
||||
}
|
||||
|
||||
public static Point? LoadPoint(string path)
|
||||
{
|
||||
return Deserialization.Deserialize(LoadData(path));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Serialization
|
||||
{
|
||||
public static string Serialize(this Point point)
|
||||
{
|
||||
return JsonSerializer.Serialize(point);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Deserialization
|
||||
{
|
||||
public static Point? Deserialize(string point)
|
||||
{
|
||||
try
|
||||
{
|
||||
return !string.IsNullOrEmpty(point) ? JsonSerializer.Deserialize<Point>(point) : null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new ArgumentException("Ошибка расшифровки json файла");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using GazpromApp.Enums;
|
||||
using GazpromApp.ViewModels;
|
||||
|
||||
namespace GazpromApp.Utils;
|
||||
|
||||
public static class DateCalculator
|
||||
{
|
||||
public static DateTime[] GetNearestDates(this InspectionViewModel inspection)
|
||||
{
|
||||
var today = DateTime.Today;
|
||||
|
||||
var firstFutureDate = AddPeriod(inspection.InspectionDate.DateTime, inspection.PeriodType, inspection.PeriodValue);
|
||||
|
||||
if (firstFutureDate > today)
|
||||
{
|
||||
return [inspection.InspectionDate.DateTime, firstFutureDate];
|
||||
}
|
||||
|
||||
var futureDate = Enumerable.Range(1, int.MaxValue)
|
||||
.Select(i => AddPeriod(inspection.InspectionDate.DateTime, inspection.PeriodType, inspection.PeriodValue * i))
|
||||
.First(d => d > today);
|
||||
|
||||
var pastDate = SubtractPeriod(futureDate, inspection.PeriodType, inspection.PeriodValue);
|
||||
|
||||
return [pastDate, futureDate];
|
||||
}
|
||||
|
||||
private static DateTime AddPeriod(DateTime date, PeriodType periodType, float value)
|
||||
{
|
||||
return periodType switch
|
||||
{
|
||||
PeriodType.Day => date.AddDays(value),
|
||||
PeriodType.Week => date.AddDays(value * 7),
|
||||
PeriodType.Month => date.AddDays(value * 30.436875), // Avg days/month
|
||||
PeriodType.Year => date.AddDays(value * 365.2425), // Avg days/year (incl. leap years)
|
||||
PeriodType.Unknown => throw new ArgumentException("Invalid period type"),
|
||||
_ => throw new ArgumentException("Invalid period type")
|
||||
};
|
||||
}
|
||||
|
||||
private static DateTime SubtractPeriod(DateTime date, PeriodType periodType, float value)
|
||||
{
|
||||
return AddPeriod(date, periodType, -value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using System.Linq;
|
||||
using GazpromApp.Models;
|
||||
|
||||
namespace GazpromApp.Utils;
|
||||
|
||||
public static class ParentsHelper
|
||||
{
|
||||
public static void SetPropertyParents(this Point point)
|
||||
{
|
||||
foreach (var prop in point.Properties)
|
||||
{
|
||||
SetPropertyParentsRecursively(prop);
|
||||
}
|
||||
|
||||
foreach (var prop in point.Equipment.SelectMany(equipment => equipment.Properties))
|
||||
{
|
||||
SetPropertyParentsRecursively(prop);
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetPropertyParentsRecursively(Property property)
|
||||
{
|
||||
foreach (var childProp in property.Properties)
|
||||
{
|
||||
childProp.Parent = property;
|
||||
childProp.ParentPropertyId = property.Id;
|
||||
SetPropertyParentsRecursively(childProp);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetEquipmentParents(this Point point)
|
||||
{
|
||||
foreach (var prop in point.Equipment)
|
||||
{
|
||||
SetEquipmentParentsRecursively(prop);
|
||||
}
|
||||
|
||||
foreach (var prop in point.Equipment.SelectMany(equipment1 => equipment1.Equipments))
|
||||
{
|
||||
SetEquipmentParentsRecursively(prop);
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetEquipmentParentsRecursively(Equipment equipment)
|
||||
{
|
||||
foreach (var childProp in equipment.Equipments)
|
||||
{
|
||||
childProp.ParentEquipment = equipment;
|
||||
childProp.ParentEquipmentId = equipment.Id;
|
||||
SetEquipmentParentsRecursively(childProp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,58 +1,124 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using Avalonia.Media.Imaging;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using GazpromApp.Messages;
|
||||
using GazpromApp.Models;
|
||||
using GazpromApp.Utils;
|
||||
|
||||
namespace GazpromApp.ViewModels;
|
||||
|
||||
public partial class EquipmentViewModel : ViewModelBase
|
||||
{
|
||||
public ViewModelBase? Parent { get; set; }
|
||||
private Equipment Equipment { get; }
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _name;
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _description;
|
||||
|
||||
[ObservableProperty]
|
||||
private ImageViewModel? _image;
|
||||
|
||||
[ObservableProperty]
|
||||
private DateTime _creationDate;
|
||||
|
||||
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;
|
||||
Image = null;
|
||||
CreationDate = DateTime.Now;
|
||||
Properties = [];
|
||||
Inspections = [];
|
||||
NearestInspection = DateTime.Now.ToLongDateString();
|
||||
Equipments = [];
|
||||
NearestInspection = "Нету инспекций";
|
||||
Equipment = new Equipment();
|
||||
|
||||
WeakReferenceMessenger.Default.Register<RemoveEquipmentMessage>(this, RemoveEquipment);
|
||||
}
|
||||
|
||||
public EquipmentViewModel(Equipment equipment)
|
||||
{
|
||||
Name = equipment.Name;
|
||||
Description = equipment.Description;
|
||||
Image = new ImageViewModel(equipment.Image ?? new Image());
|
||||
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)));
|
||||
Inspections = new ObservableCollection<InspectionViewModel>(equipment.Inspections.Select(e => new InspectionViewModel(e)));
|
||||
NearestInspection = DateTime.Now.ToLongDateString();
|
||||
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())
|
||||
.ToList();
|
||||
|
||||
Inspections = new ObservableCollection<InspectionViewModel>(equipment.Inspections
|
||||
.Select((e, i) => new InspectionViewModel(e) { InspectionDate = times[i][0] }));
|
||||
|
||||
NearestInspection = times
|
||||
.Where(e => e[1] > DateTime.Now)
|
||||
.Select(e => e[1])
|
||||
.OrderBy(e => e)
|
||||
.FirstOrDefault()
|
||||
.ToLongDateString();
|
||||
|
||||
if (Inspections.Count == 0) NearestInspection = "Нету инспекций";
|
||||
Equipment = equipment;
|
||||
|
||||
WeakReferenceMessenger.Default.Register<RemoveEquipmentMessage>(this, RemoveEquipment);
|
||||
}
|
||||
|
||||
public Equipment GetEquipment()
|
||||
{
|
||||
return new Equipment()
|
||||
{
|
||||
Name = Name,
|
||||
Description = Description,
|
||||
Image = Image?.GetImage(),
|
||||
};
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ public partial class ErrorViewModel : ViewModelBase
|
||||
w.Close();
|
||||
}
|
||||
|
||||
private ErrorSeverity severity;
|
||||
private readonly ErrorSeverity _severity;
|
||||
|
||||
// Visual and other properties
|
||||
[ObservableProperty] private bool _isErrorVisible;
|
||||
@@ -38,7 +38,7 @@ public partial class ErrorViewModel : ViewModelBase
|
||||
{
|
||||
Title = error.Title;
|
||||
Message = error.Message;
|
||||
severity = error.Severity;
|
||||
_severity = error.Severity;
|
||||
switch (error.Severity)
|
||||
{
|
||||
case ErrorSeverity.Error:
|
||||
@@ -48,21 +48,20 @@ public partial class ErrorViewModel : ViewModelBase
|
||||
IsWarnVisible = true;
|
||||
break;
|
||||
case ErrorSeverity.Message:
|
||||
IsInfoVisible = true;
|
||||
break;
|
||||
default:
|
||||
IsInfoVisible = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ReSharper disable once UnusedMember.Global
|
||||
public Error GetError()
|
||||
{
|
||||
Error error = new Error()
|
||||
var error = new Error
|
||||
{
|
||||
Title = Title,
|
||||
Message = Message,
|
||||
Severity = severity,
|
||||
Severity = _severity
|
||||
};
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -1,47 +1,72 @@
|
||||
using System.Collections.Generic;
|
||||
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
|
||||
{
|
||||
[ObservableProperty]
|
||||
private byte[]? _bytes;
|
||||
public ViewModelBase? Parent;
|
||||
private Image Image { get; }
|
||||
|
||||
[ObservableProperty] private byte[]? _bytes;
|
||||
|
||||
[ObservableProperty] private DateTime _creationDate;
|
||||
|
||||
// EF stuff
|
||||
[ObservableProperty]
|
||||
private List<Point>? _points;
|
||||
[ObservableProperty]
|
||||
private List<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;
|
||||
Points = image.Points;
|
||||
Point = image.Point;
|
||||
FileName = image.Bytes is { Length: > 0 } ? new Bitmap(new MemoryStream(image.Bytes)) : null;
|
||||
Image = image;
|
||||
}
|
||||
|
||||
public ImageViewModel()
|
||||
{
|
||||
Bytes = null;
|
||||
CreationDate = DateTime.Now;
|
||||
Equipment = null;
|
||||
Points = null;
|
||||
Point = null;
|
||||
Image = new Image();
|
||||
}
|
||||
|
||||
public Image GetImage()
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
var ms = new MemoryStream();
|
||||
FileName?.Save(ms);
|
||||
return new Image()
|
||||
{
|
||||
Bytes = ms.ToArray(),
|
||||
Equipment = Equipment ?? [],
|
||||
Points = Points ?? [],
|
||||
};
|
||||
Image.Bytes = ms.ToArray();
|
||||
Image.CreationDate = CreationDate;
|
||||
Image.Equipment = Equipment;
|
||||
Image.Point = Point;
|
||||
return Image;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,76 @@
|
||||
using GazpromApp.Models;
|
||||
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;
|
||||
|
||||
public partial class InspectionViewModel : ViewModelBase
|
||||
{
|
||||
private Inspection Inspection { get; }
|
||||
[ObservableProperty]
|
||||
private string _name;
|
||||
[ObservableProperty]
|
||||
private DateTime _creationDate;
|
||||
[ObservableProperty]
|
||||
private DateTimeOffset _inspectionDate;
|
||||
[ObservableProperty]
|
||||
private PeriodType _periodType;
|
||||
[ObservableProperty]
|
||||
private float _periodValue;
|
||||
|
||||
// Visual properties
|
||||
|
||||
[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;
|
||||
Inspection = new Inspection();
|
||||
}
|
||||
|
||||
public InspectionViewModel(Inspection inspection)
|
||||
{
|
||||
|
||||
Name = inspection.Name;
|
||||
CreationDate = inspection.CreationDate;
|
||||
InspectionDate = inspection.InspectionDate;
|
||||
PeriodType = inspection.PeriodType.ToPeriodType();
|
||||
PeriodValue = inspection.PeriodValue;
|
||||
Inspection = inspection;
|
||||
}
|
||||
|
||||
public Inspection GetInspection()
|
||||
{
|
||||
Inspection.Name = Name;
|
||||
Inspection.CreationDate = CreationDate;
|
||||
if (InspectionDate.Year > 2500)
|
||||
InspectionDate = DateTimeOffset.Now;
|
||||
Inspection.InspectionDate = InspectionDate;
|
||||
Inspection.PeriodType = PeriodType.ToDescription();
|
||||
Inspection.PeriodValue = PeriodValue;
|
||||
return Inspection;
|
||||
}
|
||||
}
|
||||
@@ -1,50 +1,84 @@
|
||||
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;
|
||||
|
||||
public partial class PointViewModel : ViewModelBase
|
||||
{
|
||||
private Point Point { get; }
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _name;
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _description;
|
||||
|
||||
[ObservableProperty]
|
||||
private DateTime _creationDate;
|
||||
|
||||
[ObservableProperty]
|
||||
private double? _latitude;
|
||||
|
||||
[ObservableProperty]
|
||||
private double? _longitude;
|
||||
|
||||
// EF stuff
|
||||
[ObservableProperty]
|
||||
private List<Image>? _images;
|
||||
[ObservableProperty]
|
||||
private List<Equipment>? _equipment;
|
||||
[ObservableProperty]
|
||||
private List<Property>? _properties;
|
||||
|
||||
public PointViewModel(Models.Point point)
|
||||
[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);
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<ImageViewModel> _images;
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<EquipmentViewModel> _equipment;
|
||||
[ObservableProperty]
|
||||
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 Models.Point GetPoint()
|
||||
public Point GetPoint()
|
||||
{
|
||||
return new Models.Point()
|
||||
{
|
||||
Name = this.Name,
|
||||
Description = this.Description,
|
||||
Equipment = this.Equipment ?? [],
|
||||
Properties = this.Properties ?? [],
|
||||
};
|
||||
Point.Name = Name;
|
||||
Point.Description = Description;
|
||||
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,28 +1,95 @@
|
||||
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;
|
||||
|
||||
|
||||
public partial class PropertyViewModel : ViewModelBase
|
||||
{
|
||||
public ViewModelBase? Parent { get; init; }
|
||||
|
||||
private Property Property { get; }
|
||||
|
||||
[ObservableProperty]
|
||||
private string _name;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _value;
|
||||
|
||||
public ObservableCollection<PropertyViewModel> Properties { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private DateTime _creationDate;
|
||||
|
||||
public ObservableCollection<PropertyViewModel> Properties { get; set; }
|
||||
|
||||
// Visual and other properties
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isEditing;
|
||||
|
||||
public PropertyViewModel()
|
||||
[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)
|
||||
{
|
||||
Name = string.Empty;
|
||||
Value = string.Empty;
|
||||
if (Properties.Contains(msg.Property))
|
||||
Properties.Remove(msg.Property);
|
||||
}
|
||||
|
||||
public PropertyViewModel(Property 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;
|
||||
}
|
||||
|
||||
public PropertyViewModel()
|
||||
{
|
||||
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)
|
||||
{
|
||||
Name = "Имя свойства";
|
||||
Value = "Значение свойства";
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
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;
|
||||
|
||||
namespace GazpromApp.ViewModels;
|
||||
|
||||
public partial class EditEquipmentDialogViewModel : ViewModelBase
|
||||
{
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(CompleteEditCommand))]
|
||||
private string? _name;
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(CompleteEditCommand))]
|
||||
private string? _description;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isNameEditing;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isDescriptionEditing;
|
||||
|
||||
[ObservableProperty]
|
||||
private ImageViewModel? _image;
|
||||
|
||||
[RelayCommand]
|
||||
private void EditName()
|
||||
{
|
||||
IsNameEditing = !IsNameEditing;
|
||||
IsDescriptionEditing = false;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void EditDescription()
|
||||
{
|
||||
IsDescriptionEditing = !IsDescriptionEditing;
|
||||
IsNameEditing = false;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task AddImage(Window w)
|
||||
{
|
||||
IReadOnlyList<IStorageFile> files = await w.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions()
|
||||
{
|
||||
AllowMultiple = false,
|
||||
Title = "Выберите картинку",
|
||||
FileTypeFilter = [FilePickerFileTypes.ImageAll],
|
||||
});
|
||||
|
||||
IsImageSelected = files.Count > 0;
|
||||
|
||||
try
|
||||
{
|
||||
Image = IsImageSelected ? new ImageViewModel(new Models.Image()) { FileName = new Bitmap(HttpUtility.UrlDecode(files[0].Path.AbsolutePath)) } : null;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
Error error = new Error()
|
||||
{
|
||||
Title = "Ошибка обработки картинки",
|
||||
Message = "Картинка не была добавлена",
|
||||
Severity = ErrorSeverity.Error,
|
||||
};
|
||||
_ = await WeakReferenceMessenger.Default.Send(new ErrorMessage(new ErrorViewModel(error)));
|
||||
|
||||
IsImageSelected = false;
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task ViewImage()
|
||||
{
|
||||
if (Image is null) return;
|
||||
_ = await WeakReferenceMessenger.Default.Send(new ViewImageMessage(Image));
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void DeleteImage()
|
||||
{
|
||||
Image = null;
|
||||
IsImageSelected = false;
|
||||
}
|
||||
|
||||
private bool CanCompleteEdit() => !string.IsNullOrWhiteSpace(Name);
|
||||
|
||||
[RelayCommand(CanExecute = nameof(CanCompleteEdit))]
|
||||
private void CompleteEdit()
|
||||
{
|
||||
IsClosed = true;
|
||||
Equipment equipment = new Equipment()
|
||||
{
|
||||
Name = Name,
|
||||
Description = Description,
|
||||
Image = Image?.GetImage(),
|
||||
Properties = [],
|
||||
};
|
||||
WeakReferenceMessenger.Default.Send(new EditEquipmentDone(new EquipmentViewModel(equipment)));
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void CancelEdit(Window w)
|
||||
{
|
||||
IsClosed = true;
|
||||
WeakReferenceMessenger.Default.Send(new EditEquipmentDone(_equipment));
|
||||
}
|
||||
|
||||
// Visual and other properties
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isImageSelected;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isClosed;
|
||||
|
||||
private readonly EquipmentViewModel _equipment;
|
||||
|
||||
public EditEquipmentDialogViewModel()
|
||||
{
|
||||
Name = "";
|
||||
Description = "";
|
||||
Image = null;
|
||||
|
||||
IsImageSelected = false;
|
||||
|
||||
_equipment = new EquipmentViewModel(new Equipment());
|
||||
}
|
||||
|
||||
public EditEquipmentDialogViewModel(EquipmentViewModel equipment)
|
||||
{
|
||||
Name = equipment.Name;
|
||||
Description = equipment.Description;
|
||||
Image = equipment.Image;
|
||||
|
||||
IsImageSelected = equipment.Image is { Bytes.Length: > 0 };
|
||||
|
||||
_equipment = equipment;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Media.Imaging;
|
||||
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 EditEquipmentViewModel : ViewModelBase
|
||||
{
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(CompleteEditCommand))]
|
||||
private string? _name;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isNameEditing;
|
||||
|
||||
[RelayCommand]
|
||||
private void EditName()
|
||||
{
|
||||
IsNameEditing = !IsNameEditing;
|
||||
IsDescriptionEditing = false;
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(CompleteEditCommand))]
|
||||
private string? _description;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isDescriptionEditing;
|
||||
|
||||
[RelayCommand]
|
||||
private void EditDescription()
|
||||
{
|
||||
IsDescriptionEditing = !IsDescriptionEditing;
|
||||
IsNameEditing = false;
|
||||
}
|
||||
|
||||
public ObservableCollection<ImageViewModel> Images { get; set; }
|
||||
|
||||
[RelayCommand]
|
||||
private async Task AddImage(Window w)
|
||||
{
|
||||
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)), Parent = this});
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
var error = new Error
|
||||
{
|
||||
Title = "Ошибка обработки картинки",
|
||||
Message = $"Картинка не была добавлена: \"{HttpUtility.UrlDecode(file.Name)}\"",
|
||||
Severity = ErrorSeverity.Error
|
||||
};
|
||||
_ = await WeakReferenceMessenger.Default.Send(new ErrorMessage(new ErrorViewModel(error)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<InspectionViewModel> Inspections { get; set; }
|
||||
|
||||
[RelayCommand]
|
||||
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 DeleteInspection(InspectionViewModel inspection)
|
||||
{
|
||||
Inspections.Remove(inspection);
|
||||
}
|
||||
|
||||
public ObservableCollection<PropertyViewModel> Properties { get; set; }
|
||||
|
||||
[RelayCommand]
|
||||
private void AddProperty() => Properties.Add(new PropertyViewModel {Parent = this});
|
||||
|
||||
private void RemoveProperty(object sender, RemovePropertyMessage msg)
|
||||
{
|
||||
if (Properties.Contains(msg.Property))
|
||||
Properties.Remove(msg.Property);
|
||||
}
|
||||
|
||||
private bool CanCompleteEdit() => !string.IsNullOrWhiteSpace(Name);
|
||||
|
||||
[RelayCommand(CanExecute = nameof(CanCompleteEdit))]
|
||||
private void CompleteEdit()
|
||||
{
|
||||
_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)
|
||||
{
|
||||
CallUpdatePoint(_equipment);
|
||||
}
|
||||
|
||||
// Visual and other properties
|
||||
|
||||
|
||||
private readonly EquipmentViewModel _equipment;
|
||||
|
||||
// ReSharper disable once MemberCanBeMadeStatic.Global
|
||||
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 EditEquipmentViewModel()
|
||||
{
|
||||
Name = "Testing";
|
||||
Description = "Testing";
|
||||
Images = [];
|
||||
Inspections = [];
|
||||
Properties = [];
|
||||
|
||||
_equipment = new EquipmentViewModel();
|
||||
}
|
||||
|
||||
public EditEquipmentViewModel(EquipmentViewModel equipment)
|
||||
{
|
||||
Name = equipment.Name;
|
||||
Description = equipment.Description;
|
||||
Images = equipment.Images;
|
||||
Inspections = new ObservableCollection<InspectionViewModel>(equipment.Inspections.Select(e => e));
|
||||
Properties = new ObservableCollection<PropertyViewModel>(equipment.Properties.Select(e => e));
|
||||
|
||||
_equipment = equipment;
|
||||
|
||||
WeakReferenceMessenger.Default.Register<RemovePropertyMessage>(this, RemoveProperty);
|
||||
WeakReferenceMessenger.Default.Register<RemoveInspectionMessage>(this, RemoveInspection);
|
||||
}
|
||||
|
||||
~EditEquipmentViewModel()
|
||||
{
|
||||
WeakReferenceMessenger.Default.UnregisterAll(this);
|
||||
}
|
||||
}
|
||||
@@ -1,197 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
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 GazpromApp.Views;
|
||||
using Image = GazpromApp.Models.Image;
|
||||
|
||||
namespace GazpromApp.ViewModels;
|
||||
|
||||
public partial class EditPointDialogViewModel : ViewModelBase
|
||||
{
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(CompleteEditCommand))]
|
||||
private string? _name;
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(CompleteEditCommand))]
|
||||
private string? _description;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isNameEditing;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isDescriptionEditing;
|
||||
|
||||
[RelayCommand]
|
||||
private void EditName()
|
||||
{
|
||||
IsNameEditing = !IsNameEditing;
|
||||
IsDescriptionEditing = false;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void EditDescription()
|
||||
{
|
||||
IsDescriptionEditing = !IsDescriptionEditing;
|
||||
IsNameEditing = false;
|
||||
}
|
||||
|
||||
public ObservableCollection<ImageViewModel> Images { get; set; }
|
||||
|
||||
[RelayCommand]
|
||||
private async Task AddImage(Window w)
|
||||
{
|
||||
IReadOnlyList<IStorageFile> 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)
|
||||
{
|
||||
Error 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;
|
||||
}
|
||||
|
||||
[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()
|
||||
{
|
||||
EquipmentViewModel? equipment = await WeakReferenceMessenger.Default.Send(new NewEquipmentMessage());
|
||||
|
||||
if (equipment != null)
|
||||
Equipment.Add(equipment);
|
||||
|
||||
IsEquipmentEmpty = Equipment.Count == 0;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task EditEquipment(EquipmentViewModel equipment)
|
||||
{
|
||||
EquipmentViewModel 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;
|
||||
}
|
||||
|
||||
private bool CanCompleteEdit() => !string.IsNullOrWhiteSpace(Name);
|
||||
|
||||
[RelayCommand(CanExecute = nameof(CanCompleteEdit))]
|
||||
private void CompleteEdit()
|
||||
{
|
||||
IsClosed = true;
|
||||
Point point = new Point()
|
||||
{
|
||||
Name = Name,
|
||||
Description = Description,
|
||||
Images = Images.Select(e => e.GetImage()).ToList(),
|
||||
Equipment = Equipment.Select(e => e.GetEquipment()).ToList()
|
||||
};
|
||||
WeakReferenceMessenger.Default.Send(new EditPointDone(new PointViewModel(point)));
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void CancelEdit(Window w)
|
||||
{
|
||||
IsClosed = true;
|
||||
WeakReferenceMessenger.Default.Send(new EditPointDone(_point));
|
||||
}
|
||||
|
||||
// Visual and other properties
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isImagesEmpty;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isEquipmentEmpty;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isClosed;
|
||||
|
||||
private readonly PointViewModel _point;
|
||||
|
||||
public EditPointDialogViewModel()
|
||||
{
|
||||
Name = "";
|
||||
Description = "";
|
||||
Images = [];
|
||||
Equipment = [
|
||||
new EquipmentViewModel
|
||||
{
|
||||
Name = "Equipment Name Very Long",
|
||||
Description = "Really big description for the equipment to show the long textReally big description for the equipment to show the long textReally big description for the equipment to show the long textReally big description for the equipment to show the long text", Image = null
|
||||
},
|
||||
new EquipmentViewModel
|
||||
{
|
||||
Name = "Equipment Name Very Long",
|
||||
Description = "Really big description for the equipment to show the long textReally big description for the equipment to show the long textReally big description for the equipment to show the long textReally big description for the equipment to show the long text", Image = null
|
||||
}
|
||||
];
|
||||
|
||||
IsImagesEmpty = true;
|
||||
IsEquipmentEmpty = true;
|
||||
|
||||
_point = new PointViewModel(new Point());
|
||||
}
|
||||
|
||||
public EditPointDialogViewModel(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)));
|
||||
|
||||
IsImagesEmpty = Images.Count == 0;
|
||||
IsEquipmentEmpty = Equipment.Count == 0;
|
||||
|
||||
_point = point;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Media.Imaging;
|
||||
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 EditPointViewModel : ViewModelBase
|
||||
{
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(CompleteEditCommand))]
|
||||
private string? _name;
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(CompleteEditCommand))]
|
||||
private string? _description;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isNameEditing;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isDescriptionEditing;
|
||||
|
||||
[RelayCommand]
|
||||
private void EditName()
|
||||
{
|
||||
IsNameEditing = !IsNameEditing;
|
||||
IsDescriptionEditing = false;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void EditDescription()
|
||||
{
|
||||
IsDescriptionEditing = !IsDescriptionEditing;
|
||||
IsNameEditing = false;
|
||||
}
|
||||
|
||||
public ObservableCollection<ImageViewModel> Images { get; set; }
|
||||
|
||||
[RelayCommand]
|
||||
private async Task AddImage(Window w)
|
||||
{
|
||||
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)), Parent = this});
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
var error = new Error
|
||||
{
|
||||
Title = "Ошибка обработки картинки",
|
||||
Message = $"Картинка не была добавлена: \"{HttpUtility.UrlDecode(file.Name)}\"",
|
||||
Severity = ErrorSeverity.Error
|
||||
};
|
||||
_ = await WeakReferenceMessenger.Default.Send(new ErrorMessage(new ErrorViewModel(error)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<EquipmentViewModel> Equipment { get; set; }
|
||||
|
||||
public ObservableCollection<PropertyViewModel> Properties { get; set; }
|
||||
|
||||
[RelayCommand]
|
||||
private void AddProperty() => Properties.Add(new PropertyViewModel {Parent = this});
|
||||
|
||||
private void RemoveProperty(object sender, RemovePropertyMessage msg)
|
||||
{
|
||||
if (Properties.Contains(msg.Property))
|
||||
Properties.Remove(msg.Property);
|
||||
}
|
||||
|
||||
private bool CanCompleteEdit() => !string.IsNullOrWhiteSpace(Name);
|
||||
|
||||
[RelayCommand(CanExecute = nameof(CanCompleteEdit))]
|
||||
private void CompleteEdit()
|
||||
{
|
||||
_point.Name = Name;
|
||||
_point.Description = Description;
|
||||
_point.Images = Images;
|
||||
_point.Equipment = Equipment;
|
||||
_point.Properties = Properties;
|
||||
_ = _point.GetPoint();
|
||||
|
||||
WeakReferenceMessenger.Default.Send(new EditPointMessage(_point));
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void CancelEdit(Window w)
|
||||
{
|
||||
WeakReferenceMessenger.Default.Send(new EditPointMessage(_point));
|
||||
}
|
||||
|
||||
// Visual and other properties
|
||||
|
||||
private readonly PointViewModel _point;
|
||||
|
||||
public EditPointViewModel()
|
||||
{
|
||||
Name = "fsdfasdfasd";
|
||||
Description = "asfasdfasdfa";
|
||||
Images = [];
|
||||
Equipment = [
|
||||
new EquipmentViewModel
|
||||
{
|
||||
Name = "Equipment Name Very Long",
|
||||
Description = "Really big description for the equipment to show the long textReally big description for the equipment to show the long textReally big description for the equipment to show the long textReally big description for the equipment to show the long text",
|
||||
Images = []
|
||||
},
|
||||
new EquipmentViewModel
|
||||
{
|
||||
Name = "Equipment Name Very Long",
|
||||
Description = "Really big description for the equipment to show the long textReally big description for the equipment to show the long textReally big description for the equipment to show the long textReally big description for the equipment to show the long text",
|
||||
Images = []
|
||||
}
|
||||
];
|
||||
Properties = [
|
||||
new PropertyViewModel
|
||||
{
|
||||
Name = "Property Name",
|
||||
Value = "Property Value",
|
||||
Properties = [
|
||||
new PropertyViewModel
|
||||
{
|
||||
Name = "Property Name",
|
||||
Value = "Property Value",
|
||||
Properties = [
|
||||
new PropertyViewModel
|
||||
{
|
||||
Name = "Property Name",
|
||||
Value = "Property Value",
|
||||
Properties = [],
|
||||
Parent = null
|
||||
},
|
||||
new PropertyViewModel
|
||||
{
|
||||
Name = "Property Name",
|
||||
Value = "Property Value",
|
||||
Properties = [],
|
||||
Parent = null
|
||||
},
|
||||
new PropertyViewModel
|
||||
{
|
||||
Name = "Property Name",
|
||||
Value = "Property Value",
|
||||
Properties = [],
|
||||
Parent = null
|
||||
}
|
||||
],
|
||||
Parent = null
|
||||
},
|
||||
new PropertyViewModel
|
||||
{
|
||||
Name = "Property Name",
|
||||
Value = "Property Value",
|
||||
Properties = [],
|
||||
Parent = null
|
||||
}
|
||||
],
|
||||
Parent = null
|
||||
},
|
||||
new PropertyViewModel
|
||||
{
|
||||
Name = "Property Name",
|
||||
Value = "Property Value",
|
||||
Properties = [],
|
||||
Parent = null
|
||||
}
|
||||
];
|
||||
|
||||
_point = new PointViewModel(new Point());
|
||||
}
|
||||
|
||||
public EditPointViewModel(PointViewModel point)
|
||||
{
|
||||
Name = point.Name;
|
||||
Description = point.Description;
|
||||
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,45 +1,297 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using GazpromApp.Messages;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Platform.Storage;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Threading.Tasks;
|
||||
using GazpromApp.Messages;
|
||||
using GazpromApp.Models;
|
||||
using GazpromApp.Utils;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace GazpromApp.ViewModels;
|
||||
|
||||
public partial class MainWindowViewModel : ViewModelBase
|
||||
{
|
||||
public ObservableCollection<PointViewModel> Points { get; } = [];
|
||||
public ObservableCollection<PointViewModel> Points { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
private object? _selectedItem;
|
||||
|
||||
[ObservableProperty]
|
||||
private ViewModelBase? _selectedItemViewModel;
|
||||
|
||||
[RelayCommand]
|
||||
private async Task AddPoint()
|
||||
{
|
||||
PointViewModel? point = await WeakReferenceMessenger.Default.Send(new NewPointMessage());
|
||||
IsLoading = true;
|
||||
|
||||
if (point != null)
|
||||
Points.Add(point);
|
||||
var point = new PointViewModel(new Point {Name = "Новый объект", Description = "Описание объекта"});
|
||||
|
||||
IsLineVisible = Points.Count > 0;
|
||||
_context.Point.Add(point.GetPoint());
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
Points.Add(point);
|
||||
|
||||
IsLoading = false;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task EditPoint(PointViewModel point)
|
||||
private async Task ImportPoint(Window w)
|
||||
{
|
||||
PointViewModel p = await WeakReferenceMessenger.Default.Send(new EditPointMessage(point)) ?? point;
|
||||
Points[Points.IndexOf(point)] = p;
|
||||
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(
|
||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "GazpromApp"))
|
||||
});
|
||||
|
||||
if (files.Count < 1) return;
|
||||
|
||||
IsLoading = true;
|
||||
|
||||
foreach (var file in files)
|
||||
{
|
||||
var url = file.Path.AbsolutePath;
|
||||
var decoded = HttpUtility.UrlDecode(url);
|
||||
var point = DataSerialization.LoadPoint(decoded);
|
||||
point?.SetPropertyParents();
|
||||
point?.SetEquipmentParents();
|
||||
|
||||
if (point == null) continue;
|
||||
_context.Point.Add(point);
|
||||
await _context.SaveChangesAsync();
|
||||
_context.Update(point);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
Points.Add(new PointViewModel(point));
|
||||
}
|
||||
|
||||
IsLoading = false;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void RemovePoint(PointViewModel point)
|
||||
private async Task ExportPoint(Window w)
|
||||
{
|
||||
Points.Remove(point);
|
||||
|
||||
IsLineVisible = Points.Count > 0;
|
||||
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(
|
||||
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") );
|
||||
}
|
||||
|
||||
// Visual properties
|
||||
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isLineVisible;
|
||||
[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, HashSet<Guid> loadedIds)
|
||||
{
|
||||
if (properties.Count == 0)
|
||||
return;
|
||||
|
||||
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))
|
||||
.OrderBy(p => p.CreationDate)
|
||||
.ToListAsync();
|
||||
|
||||
if (children.Count != 0)
|
||||
{
|
||||
var childrenLookup = children.ToLookup(child => child.ParentPropertyId);
|
||||
|
||||
foreach (var parent in properties.Where(parent => childrenLookup.Contains(parent.Id)))
|
||||
{
|
||||
parent.Properties.Clear();
|
||||
parent.Properties.AddRange(childrenLookup[parent.Id]);
|
||||
}
|
||||
|
||||
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
|
||||
.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.Images
|
||||
.OrderBy(i => i.CreationDate))
|
||||
.Include(p => p.Equipment)
|
||||
.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();
|
||||
|
||||
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));
|
||||
|
||||
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 = "Новый объект", Description = "Описание объекта" }];
|
||||
_context = new AppDbContext();
|
||||
IsLoading = false;
|
||||
}
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
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;
|
||||
|
||||
namespace GazpromApp.ViewModels;
|
||||
|
||||
public partial class NewEquipmentDialogViewModel : ViewModelBase
|
||||
{
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(EnterEquipmentCommand))]
|
||||
private string? _name;
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyCanExecuteChangedFor(nameof(EnterEquipmentCommand))]
|
||||
private string? _description;
|
||||
|
||||
[ObservableProperty]
|
||||
private ImageViewModel? _image;
|
||||
|
||||
[RelayCommand]
|
||||
private async Task AddImage(Window w)
|
||||
{
|
||||
IReadOnlyList<IStorageFile> files = await w.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions()
|
||||
{
|
||||
AllowMultiple = false,
|
||||
Title = "Выберите картинку",
|
||||
FileTypeFilter = [FilePickerFileTypes.ImageAll],
|
||||
});
|
||||
|
||||
IsImageSelected = files.Count > 0;
|
||||
|
||||
try
|
||||
{
|
||||
Image = IsImageSelected ? new ImageViewModel(new Models.Image()) { FileName = new Bitmap(HttpUtility.UrlDecode(files[0].Path.AbsolutePath)) } : null;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
Error error = new Error()
|
||||
{
|
||||
Title = "Ошибка обработки картинки",
|
||||
Message = "Картинка не была добавлена",
|
||||
Severity = ErrorSeverity.Error,
|
||||
};
|
||||
_ = await WeakReferenceMessenger.Default.Send(new ErrorMessage(new ErrorViewModel(error)));
|
||||
|
||||
IsImageSelected = false;
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void DeleteImage()
|
||||
{
|
||||
Image = null;
|
||||
IsImageSelected = false;
|
||||
}
|
||||
|
||||
private bool CanEnterEquipment() => !string.IsNullOrEmpty(Name);
|
||||
|
||||
[RelayCommand (CanExecute = nameof(CanEnterEquipment))]
|
||||
private void EnterEquipment()
|
||||
{
|
||||
Equipment equipment = new Equipment()
|
||||
{
|
||||
Name = Name,
|
||||
Description = Description ?? string.Empty,
|
||||
Image = (Image ?? new ImageViewModel()).GetImage()
|
||||
|
||||
};
|
||||
WeakReferenceMessenger.Default.Send(new NewEquipmentDone(new EquipmentViewModel(equipment)));
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private static void CancelEnterEquipment(Window w)
|
||||
{
|
||||
w.Close();
|
||||
}
|
||||
|
||||
// Visual and other stuff
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isImageSelected;
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
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)
|
||||
{
|
||||
IReadOnlyList<IStorageFile> 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)
|
||||
{
|
||||
Error 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()
|
||||
{
|
||||
Point 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;
|
||||
}
|
||||
@@ -2,6 +2,4 @@
|
||||
|
||||
namespace GazpromApp.ViewModels;
|
||||
|
||||
public class ViewModelBase : ObservableObject
|
||||
{
|
||||
}
|
||||
public class ViewModelBase : ObservableObject;
|
||||
@@ -1,80 +0,0 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="using:GazpromApp.ViewModels"
|
||||
x:Name="Window"
|
||||
mc:Ignorable="d" d:DesignWidth="1000" d:DesignHeight="600"
|
||||
Width="1000" Height="600"
|
||||
x:Class="GazpromApp.Views.EditEquipmentDialog"
|
||||
x:DataType="vm:EditEquipmentDialogViewModel"
|
||||
Title="Редактирование/просмотр оборудования"
|
||||
Icon="/Assets/ic_fluent_table_edit_24_filled (Custom).png"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Closing="Window_OnClosing"
|
||||
Closed="Window_OnClosed">
|
||||
<Design.DataContext>
|
||||
<vm:EditEquipmentDialogViewModel/>
|
||||
</Design.DataContext>
|
||||
<Grid RowDefinitions="70,150,*,Auto" ColumnDefinitions="*,100,220" x:Name="Root">
|
||||
<TextBlock Grid.Column="0" Grid.Row="0" FontSize="28" Margin="20,4,0,4"
|
||||
Text="{Binding Name}"
|
||||
IsVisible="{Binding !IsNameEditing}"/>
|
||||
<TextBox Grid.Column="0" Grid.Row="0" Margin="12,12,0,4"
|
||||
Text="{Binding Name}"
|
||||
IsVisible="{Binding IsNameEditing}"/>
|
||||
<Button Grid.Column="1" Grid.Row="0" HorizontalAlignment="Center" Margin="10"
|
||||
Command="{Binding EditNameCommand}">
|
||||
<Image Width="24" Height="24" Source="avares://GazpromApp/Assets/ic_fluent_edit_24_filled (Custom).png"/>
|
||||
</Button>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.Row="1" Margin="20,4,0,4"
|
||||
Text="{Binding Description}"
|
||||
IsVisible="{Binding !IsDescriptionEditing}"/>
|
||||
<TextBox Grid.Column="0" Grid.Row="1" Margin="12,4,0,4"
|
||||
Text="{Binding Description}"
|
||||
IsVisible="{Binding IsDescriptionEditing}"/>
|
||||
<Button Grid.Column="1" Grid.Row="1" HorizontalAlignment="Center" Margin="10"
|
||||
Command="{Binding EditDescriptionCommand}">
|
||||
<Image Width="24" Height="24" Source="avares://GazpromApp/Assets/ic_fluent_edit_24_filled (Custom).png"/>
|
||||
</Button>
|
||||
|
||||
<Grid Grid.Row="0" Grid.RowSpan="2" Grid.Column="2"
|
||||
ColumnDefinitions="*,20,4,20,8" RowDefinitions="8,20,*"
|
||||
IsVisible="{Binding IsImageSelected}">
|
||||
|
||||
<Image Grid.ColumnSpan="5" Grid.RowSpan="3"
|
||||
Source="{Binding Image.FileName, FallbackValue=null}"/>
|
||||
<Button Grid.Row="1" Grid.Column="1" Width="20" Height="20"
|
||||
Command="{Binding ViewImageCommand}">
|
||||
<Image Width="16" Height="16" Source="avares://GazpromApp/Assets/ic_fluent_eye_show_24_filled (Custom) 16.png"/>
|
||||
</Button>
|
||||
<Button Grid.Row="1" Grid.Column="3" Width="20" Height="20"
|
||||
Command="{Binding DeleteImageCommand}">
|
||||
<Image Width="16" Height="16" Source="avares://GazpromApp/Assets/ic_fluent_delete_24_filled (Custom) 16.png"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
<Button Grid.Row="0" Grid.RowSpan="2" Grid.Column="2" HorizontalAlignment="Center"
|
||||
IsVisible="{Binding !IsImageSelected}"
|
||||
Command="{Binding AddImageCommand}"
|
||||
CommandParameter="{Binding #Window}">
|
||||
<Image Width="24" Height="24"
|
||||
Source="avares://GazpromApp/Assets/ic_fluent_camera_add_24_filled (Custom).png"/>
|
||||
</Button>
|
||||
|
||||
<TabControl Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="2">
|
||||
<TabItem Header="Тех. осмотры">
|
||||
|
||||
</TabItem>
|
||||
<TabItem Header="Свойства">
|
||||
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
|
||||
<Button Grid.Column="0" Grid.Row="3" Margin="8" Content="Отменить"
|
||||
Command="{Binding CancelEditCommand}"
|
||||
CommandParameter="{Binding #Window}"/>
|
||||
<Button Grid.Column="2" Grid.Row="3" Margin="8" Content="Сохранить" HorizontalAlignment="Right"
|
||||
Command="{Binding CompleteEditCommand}"/>
|
||||
</Grid>
|
||||
</Window>
|
||||
@@ -1,68 +0,0 @@
|
||||
using System;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using GazpromApp.Messages;
|
||||
using GazpromApp.Models;
|
||||
using GazpromApp.ViewModels;
|
||||
|
||||
namespace GazpromApp.Views;
|
||||
|
||||
public partial class EditEquipmentDialog : Window
|
||||
{
|
||||
public Equipment? Equipment;
|
||||
|
||||
public EditEquipmentDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
if (Design.IsDesignMode)
|
||||
return;
|
||||
|
||||
// view image
|
||||
WeakReferenceMessenger.Default.Register<EditEquipmentDialog, ViewImageMessage>(this, static (w, m) =>
|
||||
{
|
||||
ImageView dialog = new ImageView()
|
||||
{
|
||||
DataContext = m.Image
|
||||
};
|
||||
m.Reply(dialog.ShowDialog<ImageViewModel?>(w));
|
||||
});
|
||||
|
||||
// error handling
|
||||
WeakReferenceMessenger.Default.Register<EditEquipmentDialog, ErrorMessage>(this, static (w, m) =>
|
||||
{
|
||||
ErrorView dialog = new ErrorView()
|
||||
{
|
||||
DataContext = m.Error
|
||||
};
|
||||
m.Reply(dialog.ShowDialog<ErrorViewModel?>(w));
|
||||
});
|
||||
|
||||
// new property dialog
|
||||
|
||||
// edit property dialog
|
||||
|
||||
// complete editing equipment
|
||||
WeakReferenceMessenger.Default.Register<EditEquipmentDialog, EditEquipmentDone>(this, static (w, m) =>
|
||||
{
|
||||
w.Close(m.Equipment);
|
||||
});
|
||||
}
|
||||
|
||||
private void Window_OnClosing(object? sender, WindowClosingEventArgs e)
|
||||
{
|
||||
if (DataContext is EditEquipmentDialogViewModel { IsClosed: false} vm)
|
||||
vm.CancelEditCommand.Execute(this);
|
||||
}
|
||||
|
||||
private void Window_OnClosed(object? sender, EventArgs e)
|
||||
{
|
||||
WeakReferenceMessenger.Default.Unregister<ViewImageMessage>(this);
|
||||
WeakReferenceMessenger.Default.Unregister<ErrorMessage>(this);
|
||||
//
|
||||
//
|
||||
WeakReferenceMessenger.Default.Unregister<EditEquipmentDone>(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="using:GazpromApp.ViewModels"
|
||||
xmlns:views="using:GazpromApp.Views"
|
||||
xmlns:icons="using:Material.Icons.Avalonia"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="GazpromApp.Views.EditEquipmentView"
|
||||
x:DataType="vm:EditEquipmentViewModel">
|
||||
|
||||
<Design.DataContext>
|
||||
<vm:EditEquipmentViewModel/>
|
||||
</Design.DataContext>
|
||||
<Grid RowDefinitions="70,150,*,Auto" ColumnDefinitions="*,100,220" x:Name="Root">
|
||||
<Grid.Styles>
|
||||
<Style Selector="Button.empty">
|
||||
<Setter Property="IsVisible" Value="True" />
|
||||
</Style>
|
||||
<Style Selector="Button.not-empty">
|
||||
<Setter Property="IsVisible" Value="False" />
|
||||
</Style>
|
||||
</Grid.Styles>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.Row="0" FontSize="28" Margin="20,4"
|
||||
Text="{Binding Name, FallbackValue='Название'}"
|
||||
IsVisible="{Binding !IsNameEditing, FallbackValue=true}"/>
|
||||
<TextBox Grid.Column="0" Grid.Row="0" FontSize="28" Margin="20, 4"
|
||||
Text="{Binding Name, FallbackValue='Название'}"
|
||||
IsVisible="{Binding IsNameEditing, FallbackValue=false}"/>
|
||||
<Button Grid.Column="1" Grid.Row="0" HorizontalAlignment="Center" Margin="10" Width="40" Height="40"
|
||||
Command="{Binding EditNameCommand}">
|
||||
<icons:MaterialIcon Kind="Edit" Width="24" Height="24"/>
|
||||
</Button>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.Row="1" Margin="20,4"
|
||||
Text="{Binding Description, FallbackValue='Описание'}"
|
||||
IsVisible="{Binding !IsDescriptionEditing, FallbackValue=true}"/>
|
||||
<TextBox Grid.Column="0" Grid.Row="1" Margin="20,4" AcceptsReturn="True" TextWrapping="Wrap"
|
||||
Text="{Binding Description, FallbackValue='Название'}"
|
||||
IsVisible="{Binding IsDescriptionEditing, FallbackValue=false}"/>
|
||||
<Button Grid.Column="1" Grid.Row="1" HorizontalAlignment="Center" Margin="10" Width="40" Height="40"
|
||||
Command="{Binding EditDescriptionCommand}">
|
||||
<icons:MaterialIcon Kind="Edit" Width="24" Height="24"/>
|
||||
</Button>
|
||||
|
||||
<Panel Grid.Row="0" Grid.RowSpan="2" Grid.Column="2" HorizontalAlignment="Center">
|
||||
<ScrollViewer HorizontalAlignment="Center">
|
||||
<StackPanel>
|
||||
<ItemsRepeater HorizontalAlignment="Center"
|
||||
ItemsSource="{Binding Images}">
|
||||
<ItemsRepeater.Layout>
|
||||
<UniformGridLayout Orientation="Horizontal" MaximumRowsOrColumns="1"/>
|
||||
</ItemsRepeater.Layout>
|
||||
<ItemsRepeater.ItemTemplate>
|
||||
<DataTemplate DataType="vm:ImageViewModel">
|
||||
<Border Margin="4" CornerRadius="4" Background="LightGray">
|
||||
<Grid Margin="2" Width="200" Height="200" Background="LightGray"
|
||||
ColumnDefinitions="*,32,4,32,8" RowDefinitions="8,32,*">
|
||||
<Image Stretch="Uniform" Width="200" Height="200" Grid.RowSpan="3" Grid.ColumnSpan="5"
|
||||
Source="{Binding FileName}" />
|
||||
<Button Grid.Row="1" Grid.Column="1" Width="32" Height="32"
|
||||
Command="{Binding ViewImageCommand}">
|
||||
<icons:MaterialIcon Kind="PrintPreview" Width="24" Height="24"/>
|
||||
</Button>
|
||||
<Button Grid.Row="1" Grid.Column="3" Width="32" Height="32"
|
||||
Command="{Binding DeleteImageCommand}">
|
||||
<icons:MaterialIcon Kind="Delete" Width="24" Height="24"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsRepeater.ItemTemplate>
|
||||
</ItemsRepeater>
|
||||
<Button HorizontalAlignment="Center" VerticalAlignment="Center" Width="40" Height="40"
|
||||
Classes.empty="{Binding !!Images.Count}"
|
||||
Classes.not-empty="{Binding !Images.Count}"
|
||||
Command="{Binding AddImageCommand}">
|
||||
<icons:MaterialIcon Kind="CameraPlus" Width="24" Height="24"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
<Button HorizontalAlignment="Center" VerticalAlignment="Center" Width="40" Height="40"
|
||||
Classes.empty="{Binding !Images.Count}"
|
||||
Classes.not-empty="{Binding !!Images.Count}"
|
||||
Command="{Binding AddImageCommand}">
|
||||
<icons:MaterialIcon Kind="CameraPlus" Width="24" Height="24"/>
|
||||
</Button>
|
||||
</Panel>
|
||||
|
||||
<TabControl Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3">
|
||||
<TabItem Header="Свойства">
|
||||
<ScrollViewer>
|
||||
<StackPanel>
|
||||
<TreeView ItemsSource="{Binding Properties}">
|
||||
<TreeView.DataTemplates>
|
||||
<TreeDataTemplate DataType="{x:Type vm:PropertyViewModel}"
|
||||
ItemsSource="{Binding Properties}">
|
||||
<views:PropertyView/>
|
||||
</TreeDataTemplate>
|
||||
</TreeView.DataTemplates>
|
||||
</TreeView>
|
||||
<Button HorizontalAlignment="Center" Margin="4" Width="32" Height="32"
|
||||
Command="{Binding AddPropertyCommand}">
|
||||
<icons:MaterialIcon Kind="Add" Width="24" Height="24"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
<TabItem Header="Инспекции">
|
||||
<ScrollViewer>
|
||||
<StackPanel>
|
||||
<TreeView ItemsSource="{Binding Inspections}">
|
||||
<TreeView.DataTemplates>
|
||||
<TreeDataTemplate DataType="{x:Type vm:InspectionViewModel}"
|
||||
ItemsSource="{Binding Inspection}">
|
||||
<views:InspectionView/>
|
||||
</TreeDataTemplate>
|
||||
</TreeView.DataTemplates>
|
||||
</TreeView>
|
||||
<Button HorizontalAlignment="Center" Margin="4" Width="32" Height="32"
|
||||
Command="{Binding AddInspectionCommand}">
|
||||
<icons:MaterialIcon Kind="Add" Width="24" Height="24"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
|
||||
<Button Grid.Column="0" Grid.Row="3" Margin="8" Content="Отменить" HorizontalAlignment="Left"
|
||||
Command="{Binding CancelEditCommand}"/>
|
||||
<Button Grid.Column="2" Grid.Row="3" Margin="8" Content="Сохранить" HorizontalAlignment="Right"
|
||||
Command="{Binding CompleteEditCommand}"/>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,13 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace GazpromApp.Views;
|
||||
|
||||
public partial class EditEquipmentView : UserControl
|
||||
{
|
||||
public EditEquipmentView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="using:GazpromApp.ViewModels"
|
||||
x:Name="Window"
|
||||
mc:Ignorable="d" d:DesignWidth="1000" d:DesignHeight="600"
|
||||
Width="1000" Height="600"
|
||||
x:Class="GazpromApp.Views.EditPointDialog"
|
||||
x:DataType="vm:EditPointDialogViewModel"
|
||||
Title="Редактирование/просмотр объекта"
|
||||
Icon="/Assets/ic_fluent_edit_24_filled (Custom).png"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Closing="Window_OnClosing"
|
||||
Closed="Window_OnClosed">
|
||||
<Design.DataContext>
|
||||
<vm:EditPointDialogViewModel/>
|
||||
</Design.DataContext>
|
||||
<Grid RowDefinitions="70,150,*,Auto" ColumnDefinitions="*,100,220" x:Name="Root">
|
||||
<TextBlock Grid.Column="0" Grid.Row="0" FontSize="28" Margin="20,4,0,4"
|
||||
Text="{Binding Name}"
|
||||
IsVisible="{Binding !IsNameEditing}"/>
|
||||
<TextBox Grid.Column="0" Grid.Row="0" Margin="12,12,0,4"
|
||||
Text="{Binding Name}"
|
||||
IsVisible="{Binding IsNameEditing}"/>
|
||||
<Button Grid.Column="1" Grid.Row="0" HorizontalAlignment="Center" Margin="10"
|
||||
Command="{Binding EditNameCommand}">
|
||||
<Image Width="24" Height="24" Source="avares://GazpromApp/Assets/ic_fluent_edit_24_filled (Custom).png"/>
|
||||
</Button>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.Row="1" Margin="20,4,0,4"
|
||||
Text="{Binding Description}"
|
||||
IsVisible="{Binding !IsDescriptionEditing}"/>
|
||||
<TextBox Grid.Column="0" Grid.Row="1" Margin="12,4,0,4"
|
||||
Text="{Binding Description}"
|
||||
IsVisible="{Binding IsDescriptionEditing}"/>
|
||||
<Button Grid.Column="1" Grid.Row="1" HorizontalAlignment="Center" Margin="10"
|
||||
Command="{Binding EditDescriptionCommand}">
|
||||
<Image Width="24" Height="24" Source="avares://GazpromApp/Assets/ic_fluent_edit_24_filled (Custom).png"/>
|
||||
</Button>
|
||||
|
||||
<Panel Grid.Row="0" Grid.RowSpan="2" Grid.Column="2" HorizontalAlignment="Center">
|
||||
<ScrollViewer HorizontalAlignment="Center">
|
||||
<StackPanel>
|
||||
<ItemsRepeater HorizontalAlignment="Center"
|
||||
ItemsSource="{Binding Images}">
|
||||
<ItemsRepeater.Layout>
|
||||
<UniformGridLayout Orientation="Horizontal" MaximumRowsOrColumns="1"/>
|
||||
</ItemsRepeater.Layout>
|
||||
<ItemsRepeater.ItemTemplate>
|
||||
<DataTemplate DataType="vm:ImageViewModel">
|
||||
<Border Margin="4" CornerRadius="4" Background="LightGray">
|
||||
<Grid Margin="2" Width="200" Height="200" Background="LightGray"
|
||||
ColumnDefinitions="*,20,4,20,8" RowDefinitions="8,20,*">
|
||||
<Image Stretch="Uniform" Width="200" Height="200" Grid.RowSpan="3" Grid.ColumnSpan="5"
|
||||
Source="{Binding FileName}" />
|
||||
<Button Grid.Row="1" Grid.Column="1" Width="20" Height="20"
|
||||
Command="{Binding #Root.((vm:EditPointDialogViewModel)DataContext).ViewImageCommand}"
|
||||
CommandParameter="{Binding .}">
|
||||
<Image Width="16" Height="16" Source="avares://GazpromApp/Assets/ic_fluent_eye_show_24_filled (Custom) 16.png"/>
|
||||
</Button>
|
||||
<Button Grid.Row="1" Grid.Column="3" Width="20" Height="20"
|
||||
Command="{Binding #Root.((vm:EditPointDialogViewModel)DataContext).DeleteImageCommand}"
|
||||
CommandParameter="{Binding .}">
|
||||
<Image Width="16" Height="16" Source="avares://GazpromApp/Assets/ic_fluent_delete_24_filled (Custom) 16.png"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsRepeater.ItemTemplate>
|
||||
</ItemsRepeater>
|
||||
<Button HorizontalAlignment="Center" VerticalAlignment="Center" IsVisible="{Binding !IsImagesEmpty}"
|
||||
Command="{Binding AddImageCommand}"
|
||||
CommandParameter="{Binding #Window}">
|
||||
<Image Width="24" Source="avares://GazpromApp/Assets/ic_fluent_camera_add_24_filled (Custom).png"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
<Button HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
IsVisible="{Binding IsImagesEmpty}"
|
||||
Command="{Binding AddImageCommand}"
|
||||
CommandParameter="{Binding #Window}">
|
||||
<Image Width="24" Source="avares://GazpromApp/Assets/ic_fluent_camera_add_24_filled (Custom).png"/>
|
||||
</Button>
|
||||
</Panel>
|
||||
|
||||
<TabControl Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="2">
|
||||
<TabItem Header="Оборудование">
|
||||
<ScrollViewer>
|
||||
<StackPanel>
|
||||
<ItemsRepeater
|
||||
IsVisible="{Binding !IsEquipmentEmpty}"
|
||||
ItemsSource="{Binding Equipment}">
|
||||
<ItemsRepeater.Layout>
|
||||
<StackLayout Orientation="Vertical"/>
|
||||
</ItemsRepeater.Layout>
|
||||
<ItemsRepeater.ItemTemplate>
|
||||
<DataTemplate DataType="vm:EquipmentViewModel">
|
||||
<Expander HorizontalAlignment="Stretch" Margin="0,4,0,4">
|
||||
<Expander.Header>
|
||||
<Grid Height="54" HorizontalAlignment="Left"
|
||||
ColumnDefinitions="52, 300, *, Auto">
|
||||
<Image Height="50" Width="50" Margin="0,2,2,2" HorizontalAlignment="Center" Stretch="Uniform"
|
||||
Source="{Binding Image.FileName, FallbackValue=null}"/>
|
||||
<TextBlock Grid.Column="1" FontSize="20" VerticalAlignment="Center" Margin="4,0,0,0"
|
||||
Text="{Binding Name}"/>
|
||||
<TextBlock Grid.Column="2" FontSize="15" TextWrapping="Wrap" VerticalAlignment="Center" HorizontalAlignment="Stretch"
|
||||
Text="{Binding Description}"/>
|
||||
</Grid>
|
||||
</Expander.Header>
|
||||
<Grid ColumnDefinitions="Auto, *, Auto, Auto">
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<TextBlock FontSize="18" Text="Ближайший ТО: "/>
|
||||
<TextBlock FontSize="18" Text="{Binding NearestInspection}"/>
|
||||
<TextBlock FontSize="18" Text="Свойств: " Margin="18, 0,0,0"/>
|
||||
<TextBlock FontSize="18" Text="{Binding Properties.Count}"/>
|
||||
</StackPanel>
|
||||
<Button Grid.Column="2"
|
||||
Command="{Binding #Root.((vm:EditPointDialogViewModel)DataContext).EditEquipmentCommand}"
|
||||
CommandParameter="{Binding .}"
|
||||
Margin="4,0,4,0">
|
||||
<Image Source="avares://GazpromApp/Assets/ic_fluent_edit_24_filled (Custom).png"/>
|
||||
</Button>
|
||||
<Button Grid.Column="3"
|
||||
Command="{Binding #Root.((vm:EditPointDialogViewModel)DataContext).DeleteEquipmentCommand}"
|
||||
CommandParameter="{Binding .}"
|
||||
Margin="4,0,4,0">
|
||||
<Image Source="avares://GazpromApp/Assets/ic_fluent_delete_24_filled (Custom).png"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Expander>
|
||||
</DataTemplate>
|
||||
</ItemsRepeater.ItemTemplate>
|
||||
</ItemsRepeater>
|
||||
<Button Height="30" Width="30" HorizontalAlignment="Center" Margin="0,20,0,0"
|
||||
Command="{Binding AddEquipmentCommand}">
|
||||
<Image Height="24" Width="24" Source="avares://GazpromApp/Assets/ic_fluent_add_24_filled (Custom).png"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
<TabItem Header="Свойства">
|
||||
<ScrollViewer>
|
||||
<StackPanel>
|
||||
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
|
||||
<Button Grid.Column="0" Grid.Row="3" Margin="8" Content="Отменить"
|
||||
Command="{Binding CancelEditCommand}"
|
||||
CommandParameter="{Binding #Window}"/>
|
||||
<Button Grid.Column="2" Grid.Row="3" Margin="8" Content="Сохранить" HorizontalAlignment="Right"
|
||||
Command="{Binding CompleteEditCommand}"/>
|
||||
</Grid>
|
||||
</Window>
|
||||
@@ -1,126 +0,0 @@
|
||||
using System;
|
||||
using Avalonia.Controls;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using GazpromApp.Messages;
|
||||
using GazpromApp.Models;
|
||||
using GazpromApp.ViewModels;
|
||||
|
||||
namespace GazpromApp.Views;
|
||||
|
||||
public partial class EditPointDialog : Window
|
||||
{
|
||||
public Point? Point;
|
||||
|
||||
public EditPointDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
if (Design.IsDesignMode)
|
||||
return;
|
||||
|
||||
// view image
|
||||
WeakReferenceMessenger.Default.Register<EditPointDialog, ViewImageMessage>(this, static (w, m) =>
|
||||
{
|
||||
ImageView dialog = new ImageView()
|
||||
{
|
||||
DataContext = m.Image
|
||||
};
|
||||
m.Reply(dialog.ShowDialog<ImageViewModel?>(w));
|
||||
});
|
||||
|
||||
// error
|
||||
WeakReferenceMessenger.Default.Register<EditPointDialog, ErrorMessage>(this, static (w, m) =>
|
||||
{
|
||||
ErrorView dialog = new ErrorView()
|
||||
{
|
||||
DataContext = m.Error
|
||||
};
|
||||
m.Reply(dialog.ShowDialog<ErrorViewModel?>(w));
|
||||
});
|
||||
|
||||
// new equipment
|
||||
WeakReferenceMessenger.Default.Register<EditPointDialog, NewEquipmentMessage>(this, (w, m) =>
|
||||
{
|
||||
WeakReferenceMessenger.Default.Unregister<ErrorMessage>(this);
|
||||
NewEquipmentDialog dialog = new NewEquipmentDialog()
|
||||
{
|
||||
DataContext = new NewEquipmentDialogViewModel()
|
||||
};
|
||||
m.Reply(dialog.ShowDialog<EquipmentViewModel?>(w));
|
||||
});
|
||||
|
||||
// edit equipment
|
||||
WeakReferenceMessenger.Default.Register<EditPointDialog, EditEquipmentMessage>(this, (w, m) =>
|
||||
{
|
||||
WeakReferenceMessenger.Default.Unregister<ViewImageMessage>(this);
|
||||
WeakReferenceMessenger.Default.Unregister<ErrorMessage>(this);
|
||||
EditEquipmentDialog dialog = new EditEquipmentDialog()
|
||||
{
|
||||
DataContext = new EditEquipmentDialogViewModel(m.Equipment)
|
||||
};
|
||||
m.Reply(dialog.ShowDialog<EquipmentViewModel?>(w));
|
||||
});
|
||||
|
||||
// re registering error when new equipment done
|
||||
WeakReferenceMessenger.Default.Register<EditPointDialog, NewEquipmentDone>(this, (_, _) =>
|
||||
{
|
||||
WeakReferenceMessenger.Default.Register<EditPointDialog, ErrorMessage>(this, static (w, m) =>
|
||||
{
|
||||
ErrorView dialog = new ErrorView()
|
||||
{
|
||||
DataContext = m.Error
|
||||
};
|
||||
m.Reply(dialog.ShowDialog<ErrorViewModel?>(w));
|
||||
});
|
||||
});
|
||||
|
||||
// re registering view image and error view
|
||||
WeakReferenceMessenger.Default.Register<EditPointDialog, EditEquipmentDone>(this, (_, _) =>
|
||||
{
|
||||
WeakReferenceMessenger.Default.Register<EditPointDialog, ViewImageMessage>(this, static (w, m) =>
|
||||
{
|
||||
ImageView dialog = new ImageView()
|
||||
{
|
||||
DataContext = m.Image
|
||||
};
|
||||
m.Reply(dialog.ShowDialog<ImageViewModel?>(w));
|
||||
});
|
||||
|
||||
WeakReferenceMessenger.Default.Register<EditPointDialog, ErrorMessage>(this, static (w, m) =>
|
||||
{
|
||||
ErrorView dialog = new ErrorView()
|
||||
{
|
||||
DataContext = m.Error
|
||||
};
|
||||
m.Reply(dialog.ShowDialog<ErrorViewModel?>(w));
|
||||
});
|
||||
});
|
||||
|
||||
// new property
|
||||
|
||||
// edit property
|
||||
|
||||
// complete editing point
|
||||
WeakReferenceMessenger.Default.Register<EditPointDialog, EditPointDone>(this, static (w, m) =>
|
||||
{
|
||||
w.Close(m.Point);
|
||||
});
|
||||
}
|
||||
|
||||
private void Window_OnClosing(object? sender, WindowClosingEventArgs e)
|
||||
{
|
||||
if (DataContext is EditPointDialogViewModel { IsClosed: false } vm)
|
||||
vm.CancelEditCommand.Execute(this);
|
||||
}
|
||||
|
||||
private void Window_OnClosed(object? sender, EventArgs e)
|
||||
{
|
||||
WeakReferenceMessenger.Default.Unregister<ViewImageMessage>(this);
|
||||
WeakReferenceMessenger.Default.Unregister<ErrorMessage>(this);
|
||||
WeakReferenceMessenger.Default.Unregister<NewEquipmentMessage>(this);
|
||||
WeakReferenceMessenger.Default.Unregister<EditEquipmentMessage>(this);
|
||||
// new prop
|
||||
// edit prop
|
||||
WeakReferenceMessenger.Default.Unregister<EditPointDone>(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="using:GazpromApp.ViewModels"
|
||||
xmlns:views="using:GazpromApp.Views"
|
||||
xmlns:icons="using:Material.Icons.Avalonia"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="500"
|
||||
x:Class="GazpromApp.Views.EditPointView"
|
||||
x:DataType="vm:EditPointViewModel">
|
||||
<Design.DataContext>
|
||||
<vm:EditPointViewModel/>
|
||||
</Design.DataContext>
|
||||
<Grid RowDefinitions="70,150,*,Auto" ColumnDefinitions="*,100,220" x:Name="Root">
|
||||
<Grid.Styles>
|
||||
<Style Selector="Button.empty">
|
||||
<Setter Property="IsVisible" Value="True" />
|
||||
</Style>
|
||||
<Style Selector="Button.not-empty">
|
||||
<Setter Property="IsVisible" Value="False" />
|
||||
</Style>
|
||||
</Grid.Styles>
|
||||
<TextBlock Grid.Column="0" Grid.Row="0" FontSize="28" Margin="20,4"
|
||||
Text="{Binding Name, FallbackValue='Название'}"
|
||||
IsVisible="{Binding !IsNameEditing, FallbackValue=true}"/>
|
||||
<TextBox Grid.Column="0" Grid.Row="0" FontSize="28" Margin="20, 4"
|
||||
Text="{Binding Name, FallbackValue='Название'}"
|
||||
IsVisible="{Binding IsNameEditing, FallbackValue=false}"/>
|
||||
<Button Grid.Column="1" Grid.Row="0" HorizontalAlignment="Center" Margin="10" Width="40" Height="40"
|
||||
Command="{Binding EditNameCommand}">
|
||||
<icons:MaterialIcon Kind="Edit" Width="24" Height="24"/>
|
||||
</Button>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.Row="1" Margin="20,4"
|
||||
Text="{Binding Description, FallbackValue='Описание'}"
|
||||
IsVisible="{Binding !IsDescriptionEditing, FallbackValue=true}"/>
|
||||
<TextBox Grid.Column="0" Grid.Row="1" Margin="20,4" AcceptsReturn="True" TextWrapping="Wrap"
|
||||
Text="{Binding Description, FallbackValue='Название'}"
|
||||
IsVisible="{Binding IsDescriptionEditing, FallbackValue=false}"/>
|
||||
<Button Grid.Column="1" Grid.Row="1" HorizontalAlignment="Center" Margin="10" Width="40" Height="40"
|
||||
Command="{Binding EditDescriptionCommand}">
|
||||
<icons:MaterialIcon Kind="Edit" Width="24" Height="24"/>
|
||||
</Button>
|
||||
|
||||
<Panel Grid.Row="0" Grid.RowSpan="2" Grid.Column="2" HorizontalAlignment="Center">
|
||||
<ScrollViewer HorizontalAlignment="Center">
|
||||
<StackPanel>
|
||||
<ItemsRepeater HorizontalAlignment="Center"
|
||||
ItemsSource="{Binding Images}">
|
||||
<ItemsRepeater.Layout>
|
||||
<UniformGridLayout Orientation="Horizontal" MaximumRowsOrColumns="1"/>
|
||||
</ItemsRepeater.Layout>
|
||||
<ItemsRepeater.ItemTemplate>
|
||||
<DataTemplate DataType="vm:ImageViewModel">
|
||||
<Border Margin="4" CornerRadius="4" Background="LightGray">
|
||||
<Grid Margin="2" Width="200" Height="200" Background="LightGray"
|
||||
ColumnDefinitions="*,32,4,32,8" RowDefinitions="8,32,*">
|
||||
<Image Stretch="Uniform" Width="200" Height="200" Grid.RowSpan="3" Grid.ColumnSpan="5"
|
||||
Source="{Binding FileName}" />
|
||||
<Button Grid.Row="1" Grid.Column="1" Width="32" Height="32"
|
||||
Command="{Binding ViewImageCommand}">
|
||||
<icons:MaterialIcon Kind="PrintPreview" Width="24" Height="24"/>
|
||||
</Button>
|
||||
<Button Grid.Row="1" Grid.Column="3" Width="32" Height="32"
|
||||
Command="{Binding DeleteImageCommand}">
|
||||
<icons:MaterialIcon Kind="Delete" Width="24" Height="24"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsRepeater.ItemTemplate>
|
||||
</ItemsRepeater>
|
||||
<Button HorizontalAlignment="Center" VerticalAlignment="Center" Width="40" Height="40"
|
||||
Classes.empty="{Binding !!Images.Count}"
|
||||
Classes.not-empty="{Binding !Images.Count}"
|
||||
Command="{Binding AddImageCommand}">
|
||||
<icons:MaterialIcon Kind="CameraPlus" Width="24" Height="24"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
<Button HorizontalAlignment="Center" VerticalAlignment="Center" Width="40" Height="40"
|
||||
Classes.empty="{Binding !Images.Count}"
|
||||
Classes.not-empty="{Binding !!Images.Count}"
|
||||
Command="{Binding AddImageCommand}">
|
||||
<icons:MaterialIcon Kind="CameraPlus" Width="24" Height="24"/>
|
||||
</Button>
|
||||
</Panel>
|
||||
|
||||
<ScrollViewer Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3">
|
||||
<StackPanel>
|
||||
<TextBlock Text="Свойства:" FontSize="24" Margin="24,0"/>
|
||||
<TreeView ItemsSource="{Binding Properties}">
|
||||
<TreeView.DataTemplates>
|
||||
<TreeDataTemplate DataType="{x:Type vm:PropertyViewModel}"
|
||||
ItemsSource="{Binding Properties}">
|
||||
<views:PropertyView/>
|
||||
</TreeDataTemplate>
|
||||
</TreeView.DataTemplates>
|
||||
</TreeView>
|
||||
<Button HorizontalAlignment="Center" Margin="4" Width="32" Height="32"
|
||||
Command="{Binding AddPropertyCommand}">
|
||||
<icons:MaterialIcon Kind="Add" Width="24" Height="24"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<Button Grid.Column="0" Grid.Row="3" Margin="8" Content="Отменить" HorizontalAlignment="Left"
|
||||
Command="{Binding CancelEditCommand}"/>
|
||||
<Button Grid.Column="2" Grid.Row="3" Margin="8" Content="Сохранить" HorizontalAlignment="Right"
|
||||
Command="{Binding CompleteEditCommand}"/>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,13 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace GazpromApp.Views;
|
||||
|
||||
public partial class EditPointView : UserControl
|
||||
{
|
||||
public EditPointView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="using:GazpromApp.ViewModels"
|
||||
xmlns:icons="using:Material.Icons.Avalonia"
|
||||
mc:Ignorable="d" d:DesignWidth="300" d:DesignHeight="500"
|
||||
x:Class="GazpromApp.Views.EquipmentView"
|
||||
x:DataType="vm:EquipmentViewModel">
|
||||
<Expander>
|
||||
<Expander.Header>
|
||||
<Grid ColumnDefinitions="Auto, Auto, *, Auto, Auto">
|
||||
<icons:MaterialIcon Kind="Location" Margin="0,0,8,0" Width="24" Height="24"/>
|
||||
<TextBlock Grid.Column="1" VerticalAlignment="Center" TextWrapping="WrapWithOverflow"
|
||||
Text="{Binding Name}"/>
|
||||
<Button Width="32" Grid.Column="3" Margin="0,0,8,0"
|
||||
Command="{Binding AddEquipmentCommand}">
|
||||
<icons:MaterialIcon Kind="Add" Width="24" Height="24"/>
|
||||
</Button>
|
||||
<Button Width="32" Grid.Column="4" Margin="0,0,8,0"
|
||||
Command="{Binding RemoveEquipmentCommand}">
|
||||
<icons:MaterialIcon Kind="Delete" Width="24" Height="24"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Expander.Header>
|
||||
<Grid RowDefinitions="Auto,Auto,Auto" RowSpacing="4" Margin="8,4,8,2">
|
||||
<TextBlock Text="{Binding Description}" />
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal">
|
||||
<TextBlock Text="Оборудований: "/>
|
||||
<TextBlock Text="{Binding Equipments.Count}"/>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="2" Orientation="Horizontal">
|
||||
<TextBlock Text="Свойств: "/>
|
||||
<TextBlock Text="{Binding Properties.Count}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Expander>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,13 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace GazpromApp.Views;
|
||||
|
||||
public partial class EquipmentView : UserControl
|
||||
{
|
||||
public EquipmentView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace GazpromApp.Views;
|
||||
|
||||
@@ -11,8 +9,8 @@ public partial class ErrorView : Window
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
if (Design.IsDesignMode)
|
||||
return;
|
||||
// if (Design.IsDesignMode)
|
||||
// return;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.Controls;
|
||||
|
||||
namespace GazpromApp.Views;
|
||||
|
||||
@@ -13,6 +11,6 @@ public partial class ImageView : Window
|
||||
if (Design.IsDesignMode)
|
||||
return;
|
||||
|
||||
this.ExtendClientAreaToDecorationsHint = true;
|
||||
ExtendClientAreaToDecorationsHint = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="using:GazpromApp.ViewModels"
|
||||
xmlns:icons="using:Material.Icons.Avalonia"
|
||||
xmlns:enums="using:GazpromApp.Enums"
|
||||
mc:Ignorable="d" d:DesignWidth="930" d:DesignHeight="450"
|
||||
x:Class="GazpromApp.Views.InspectionView"
|
||||
x:DataType="vm:InspectionViewModel">
|
||||
<Design.DataContext>
|
||||
<vm:InspectionViewModel/>
|
||||
</Design.DataContext>
|
||||
<UserControl.Resources>
|
||||
<enums:PeriodConverter x:Key="PeriodConverter"/>
|
||||
</UserControl.Resources>
|
||||
<Border CornerRadius="4" BorderThickness="1">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<Grid ColumnDefinitions="*, Auto">
|
||||
<TextBlock Grid.Column="0" Margin="12,6" FontSize="22" Height="50"
|
||||
IsVisible="{Binding !IsEditing}"
|
||||
Text="{Binding Name}"/>
|
||||
<TextBox Grid.Column="0" Margin="12,6" FontSize="18" Height="50"
|
||||
IsVisible="{Binding IsEditing}"
|
||||
Text="{Binding Name}"/>
|
||||
<Button Grid.Column="1" HorizontalAlignment="Right" Margin="12,6" Height="40" Width="40"
|
||||
Command="{Binding EditInspectionCommand}">
|
||||
<icons:MaterialIcon Kind="Edit" Width="24" Height="24"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid ColumnDefinitions="*, Auto">
|
||||
<WrapPanel VerticalAlignment="Top">
|
||||
<TextBlock Margin="10,2" Text="Дата проведения:"
|
||||
FontSize="18" VerticalAlignment="Center"/>
|
||||
<DatePicker FontSize="18" VerticalAlignment="Center" MaxYear="2500-01-01"
|
||||
SelectedDate="{Binding InspectionDate}"/>
|
||||
|
||||
<TextBlock Margin="10,2" Text="Период:" FontSize="18" VerticalAlignment="Center"/>
|
||||
<NumericUpDown AllowSpin="True" Width="120" Margin="10,2" FontSize="18"
|
||||
Value="{Binding PeriodValue}"
|
||||
Minimum="0"/>
|
||||
<ComboBox Width="110" VerticalAlignment="Center" Margin="10,2" FontSize="18"
|
||||
ItemsSource="{Binding AllPeriods}"
|
||||
SelectedItem="{Binding PeriodType, Mode=TwoWay}"
|
||||
DisplayMemberBinding="{Binding .,
|
||||
Converter={StaticResource PeriodConverter}}"/>
|
||||
</WrapPanel>
|
||||
<Button Grid.Column="1" Margin="12,6" Height="40" Width="40"
|
||||
Command="{Binding RemoveInspectionCommand}">
|
||||
<icons:MaterialIcon Kind="Delete" Width="24" Height="24"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,13 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace GazpromApp.Views;
|
||||
|
||||
public partial class InspectionView : UserControl
|
||||
{
|
||||
public InspectionView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
+43
-56
@@ -2,94 +2,81 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:anim="https://github.com/whistyun/AnimatedImage.Avalonia"
|
||||
xmlns:vm="using:GazpromApp.ViewModels"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
Width="1424" Height="714"
|
||||
xmlns:views="using:GazpromApp.Views"
|
||||
xmlns:icons="using:Material.Icons.Avalonia"
|
||||
mc:Ignorable="d" d:DesignWidth="1024" d:DesignHeight="600"
|
||||
x:Class="GazpromApp.Views.MainWindow"
|
||||
x:DataType="vm:MainWindowViewModel"
|
||||
x:Name="Window"
|
||||
Icon="/Assets/gazpromapp.ico"
|
||||
Title="GazpromApp"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
>
|
||||
|
||||
WindowState="Maximized"
|
||||
Closing="Window_OnClosing">
|
||||
<Design.DataContext>
|
||||
<!-- This only sets the DataContext for the previewer in an IDE,
|
||||
to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
|
||||
<vm:MainWindowViewModel/>
|
||||
</Design.DataContext>
|
||||
|
||||
<DockPanel x:Name="Root">
|
||||
<Menu DockPanel.Dock="Top">
|
||||
<MenuItem Command="{Binding AddPointCommand}">
|
||||
<MenuItem Command="{Binding SyncDbCommand}">
|
||||
<MenuItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Width="24" Height="24" Source="avares://GazpromApp/Assets/ic_fluent_home_add_24_filled (Custom).png"/>
|
||||
<TextBlock Margin="8,0,0,0" Text="Добавить" VerticalAlignment="Center"/>
|
||||
<icons:MaterialIcon Kind="Sync" Width="24" Height="24"/>
|
||||
<TextBlock Margin="8,0,0,0" Text="Сохранить и обновить" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
<MenuItem>
|
||||
<MenuItem Command="{Binding ExportPointCommand}"
|
||||
CommandParameter="{Binding #Window}">
|
||||
<MenuItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Width="24" Height="24" Source="avares://GazpromApp/Assets/ic_fluent_arrow_export_ltr_24_filled (Custom).png"/>
|
||||
<icons:MaterialIcon Kind="Upload" Width="24" Height="24"/>
|
||||
<TextBlock Margin="8,0,0,0" Text="Экспорт" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
<MenuItem>
|
||||
<MenuItem Command="{Binding ImportPointCommand}"
|
||||
CommandParameter="{Binding #Window}">
|
||||
<MenuItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Width="24" Height="24" Source="avares://GazpromApp/Assets/ic_fluent_arrow_import_24_filled (Custom).png"/>
|
||||
<icons:MaterialIcon Kind="Download" Width="24" Height="24"/>
|
||||
<TextBlock Margin="8,0,0,0" Text="Импорт" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
<Grid DockPanel.Dock="Top" HorizontalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition MaxHeight="50"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="100"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<ScrollViewer Grid.ColumnSpan="3">
|
||||
<Grid DockPanel.Dock="Top" HorizontalAlignment="Stretch"
|
||||
ColumnDefinitions="*,2,2*">
|
||||
<ScrollViewer>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<ItemsControl ItemsSource="{Binding Points}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate DataType="vm:PointViewModel">
|
||||
<Grid Margin="10,6,18,6" RowDefinitions="12, Auto">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" MaxWidth="300"/>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Rectangle Margin="-2,0,-2,5" Grid.ColumnSpan="4" Height="1" Fill="Gray" Opacity="0.25" VerticalAlignment="Top"/>
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" Text="{Binding Name}" FontSize="24" Margin="4" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Description}" Margin="4" VerticalAlignment="Center"/>
|
||||
<Button Grid.Row="1" Grid.Column="2"
|
||||
Command="{Binding #Root.((vm:MainWindowViewModel)DataContext).EditPointCommand}"
|
||||
CommandParameter="{Binding .}"
|
||||
Margin="4">
|
||||
<Image Source="avares://GazpromApp/Assets/ic_fluent_edit_24_filled (Custom).png"/>
|
||||
</Button>
|
||||
<Button Grid.Row="1" Grid.Column="3"
|
||||
Command="{Binding #Root.((vm:MainWindowViewModel)DataContext).RemovePointCommand}"
|
||||
CommandParameter="{Binding .}"
|
||||
Margin="4">
|
||||
<Image Source="avares://GazpromApp/Assets/ic_fluent_delete_24_filled (Custom).png"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
<Rectangle IsVisible="{Binding IsLineVisible}" Margin="6,6,6,0" Height="1" Fill="Gray" Opacity="0.25"/>
|
||||
<TreeView ItemsSource="{Binding Points}"
|
||||
SelectionChanged="TreeView_OnSelectionChanged">
|
||||
<TreeView.DataTemplates>
|
||||
<TreeDataTemplate DataType="{x:Type vm:PointViewModel}"
|
||||
ItemsSource="{Binding Equipment}">
|
||||
<views:PointView Padding="0,0,20,0"/>
|
||||
</TreeDataTemplate>
|
||||
<TreeDataTemplate DataType="{x:Type vm:EquipmentViewModel}"
|
||||
ItemsSource="{Binding Equipments}">
|
||||
<views:EquipmentView Padding="0,0,20,0"/>
|
||||
</TreeDataTemplate>
|
||||
</TreeView.DataTemplates>
|
||||
</TreeView>
|
||||
<Button Classes="Accent" Height="32" Width="32" Margin="4" HorizontalAlignment="Center"
|
||||
Command="{Binding AddPointCommand}">
|
||||
<icons:MaterialIcon Kind="Add" Width="24" Height="24"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
||||
</ScrollViewer>
|
||||
<GridSplitter Background="#b6b6b6" Grid.Column="1" ResizeDirection="Columns"/>
|
||||
<ContentControl Grid.Column="2" Content="{Binding SelectedItemViewModel}"/>
|
||||
<Image Width="100" Height="100" VerticalAlignment="Center"
|
||||
IsVisible="{Binding IsLoading}"
|
||||
HorizontalAlignment="Center"
|
||||
Grid.Row="0" Grid.Column="0"
|
||||
anim:ImageBehavior.AnimatedSource="avares://GazpromApp/Assets/loading.gif"/>
|
||||
</Grid>
|
||||
</DockPanel>
|
||||
</Window>
|
||||
|
||||
+72
-17
@@ -1,36 +1,91 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Platform.Storage;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using GazpromApp.Messages;
|
||||
using GazpromApp.ViewModels;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
|
||||
namespace GazpromApp.Views;
|
||||
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
private bool _canClose = false;
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
if (Design.IsDesignMode)
|
||||
return;
|
||||
|
||||
WeakReferenceMessenger.Default.Register<MainWindow, RequestImageMessage>(this, HandleImageSelection);
|
||||
WeakReferenceMessenger.Default.Register<MainWindow, ViewImageMessage>(this, HandleImageViewer);
|
||||
WeakReferenceMessenger.Default.Register<MainWindow, ErrorMessage>(this, HandleErrorViewer);
|
||||
WeakReferenceMessenger.Default.Register<MainWindow, SaveChangesResult>(this, HandleSave);
|
||||
}
|
||||
|
||||
private static void HandleImageSelection(MainWindow sender, RequestImageMessage msg)
|
||||
{
|
||||
var files = sender.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
AllowMultiple = true,
|
||||
Title = "Выберите одну или несколько картинок",
|
||||
FileTypeFilter = [FilePickerFileTypes.ImageAll]
|
||||
});
|
||||
|
||||
msg.Reply(files);
|
||||
}
|
||||
|
||||
WeakReferenceMessenger.Default.Register<MainWindow, NewPointMessage>(this, static (w, m) =>
|
||||
private static void HandleImageViewer(MainWindow sender, ViewImageMessage msg)
|
||||
{
|
||||
var dialog = new ImageView
|
||||
{
|
||||
NewPointDialog dialog = new NewPointDialog()
|
||||
{
|
||||
DataContext = new NewPointDialogViewModel()
|
||||
};
|
||||
m.Reply(dialog.ShowDialog<PointViewModel?>(w));
|
||||
});
|
||||
|
||||
WeakReferenceMessenger.Default.Register<MainWindow, EditPointMessage>(this, static (w, m) =>
|
||||
DataContext = msg.Image
|
||||
};
|
||||
msg.Reply(dialog.ShowDialog<ImageViewModel?>(sender));
|
||||
}
|
||||
|
||||
private static void HandleErrorViewer(MainWindow sender, ErrorMessage msg)
|
||||
{
|
||||
var dialog = new ErrorView
|
||||
{
|
||||
EditPointDialog dialog = new EditPointDialog()
|
||||
{
|
||||
DataContext = new EditPointDialogViewModel(m.Point),
|
||||
Point = m.Point.GetPoint()
|
||||
};
|
||||
m.Reply(dialog.ShowDialog<PointViewModel?>(w));
|
||||
});
|
||||
DataContext = msg.Error
|
||||
};
|
||||
msg.Reply(dialog.ShowDialog<ErrorViewModel?>(sender));
|
||||
}
|
||||
|
||||
private void TreeView_OnSelectionChanged(object? sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (e.AddedItems.Count > 0)
|
||||
WeakReferenceMessenger.Default.Send(new SelectionChangedMessage((ViewModelBase)e.AddedItems[0]!));
|
||||
}
|
||||
|
||||
private void HandleSave(object sender, SaveChangesResult msg)
|
||||
{
|
||||
if (msg.Cancel) return;
|
||||
if (msg.Save)
|
||||
((MainWindowViewModel)DataContext!).SyncDbCommand.Execute(null);
|
||||
ForceClose();
|
||||
}
|
||||
|
||||
private void ForceClose()
|
||||
{
|
||||
_canClose = true;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Window_OnClosing(object? sender, WindowClosingEventArgs e)
|
||||
{
|
||||
if (_canClose) return;
|
||||
if (!((MainWindowViewModel)DataContext!).CanSync) return;
|
||||
var dialog = new SaveChangesView
|
||||
{
|
||||
DataContext = new SaveChangesViewModel()
|
||||
};
|
||||
dialog.ShowDialog<SaveChangesViewModel?>(this);
|
||||
e.Cancel = true;
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="using:GazpromApp.ViewModels"
|
||||
x:Name="Window"
|
||||
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="500"
|
||||
Width="500" Height="500"
|
||||
x:Class="GazpromApp.Views.NewEquipmentDialog"
|
||||
x:DataType="vm:NewEquipmentDialogViewModel"
|
||||
Title="Создание нового оборудования"
|
||||
Icon="/Assets/ic_fluent_table_add_24_filled (Custom).png"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Closed="Window_OnClosed">
|
||||
<Design.DataContext>
|
||||
<vm:NewEquipmentDialogViewModel/>
|
||||
</Design.DataContext>
|
||||
<Grid Margin="12" x:Name="Root">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition MaxWidth="120"/>
|
||||
<ColumnDefinition MinWidth="300"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition MaxHeight="50"/>
|
||||
<RowDefinition MaxHeight="100"/>
|
||||
<RowDefinition MinHeight="200" Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Grid.Column="0" Grid.Row="0" Margin="8" Text="Название: "/>
|
||||
<TextBlock Grid.Column="0" Grid.Row="1" Margin="8" Text="Описание: "/>
|
||||
<TextBlock Grid.Column="0" Grid.Row="2" Margin="8" Text="Изображение: "/>
|
||||
<TextBox Grid.Column="1" Grid.Row="0" Margin="8"
|
||||
Text="{Binding Name}"/>
|
||||
<TextBox Grid.Column="1" Grid.Row="1" Margin="8"
|
||||
Text="{Binding Description}"/>
|
||||
|
||||
<Grid Grid.Column="1" Grid.Row="2" Margin="2"
|
||||
ColumnDefinitions="*,20,8,20,8" RowDefinitions="8,20,*"
|
||||
IsVisible="True">
|
||||
<Image Stretch="Uniform" Grid.RowSpan="3" Grid.ColumnSpan="3"
|
||||
Source="{Binding Image.FileName, FallbackValue=null}"/>
|
||||
<Button Grid.Row="1" Grid.Column="1" Width="20" Height="20"
|
||||
IsVisible="{Binding IsImageSelected}"
|
||||
Command="{Binding AddImageCommand}"
|
||||
CommandParameter="{Binding #Window}">
|
||||
<Image Width="16" Height="16" Source="avares://GazpromApp/Assets/ic_fluent_edit_24_filled (Custom) 16.png"/>
|
||||
</Button>
|
||||
<Button Grid.Row="1" Grid.Column="3" Width="20" Height="20"
|
||||
IsVisible="{Binding IsImageSelected}"
|
||||
Command="{Binding DeleteImageCommand}">
|
||||
<Image Width="16" Height="16" Source="avares://GazpromApp/Assets/ic_fluent_delete_24_filled (Custom) 16.png"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
<Button Grid.Row="2" Grid.Column="1" HorizontalAlignment="Center"
|
||||
IsVisible="{Binding !IsImageSelected}"
|
||||
Command="{Binding AddImageCommand}"
|
||||
CommandParameter="{Binding #Window}">
|
||||
<Image Width="24" Source="avares://GazpromApp/Assets/ic_fluent_camera_add_24_filled (Custom).png"/>
|
||||
</Button>
|
||||
|
||||
<Button Grid.Column="0" Grid.Row="3" Margin="8" Content="Отменить"
|
||||
Command="{Binding CancelEnterEquipmentCommand}"
|
||||
CommandParameter="{Binding #Window}"/>
|
||||
<Button Grid.Column="1" Grid.Row="3" Margin="8" Content="Добавить" HorizontalAlignment="Right"
|
||||
Command="{Binding EnterEquipmentCommand}"/>
|
||||
</Grid>
|
||||
</Window>
|
||||
@@ -1,37 +0,0 @@
|
||||
using System;
|
||||
using Avalonia.Controls;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using GazpromApp.Messages;
|
||||
using GazpromApp.ViewModels;
|
||||
|
||||
namespace GazpromApp.Views;
|
||||
|
||||
public partial class NewEquipmentDialog : Window
|
||||
{
|
||||
public NewEquipmentDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
// done entering new equipment
|
||||
WeakReferenceMessenger.Default.Register<NewEquipmentDialog, NewEquipmentDone>(this, static (w, m) =>
|
||||
{
|
||||
w.Close(m.Equipment);
|
||||
});
|
||||
|
||||
// register to work with errors
|
||||
WeakReferenceMessenger.Default.Register<NewEquipmentDialog, ErrorMessage>(this, static (w, m) =>
|
||||
{
|
||||
ErrorView dialog = new ErrorView()
|
||||
{
|
||||
DataContext = m.Error
|
||||
};
|
||||
m.Reply(dialog.ShowDialog<ErrorViewModel?>(w));
|
||||
});
|
||||
}
|
||||
|
||||
private void Window_OnClosed(object? sender, EventArgs e)
|
||||
{
|
||||
WeakReferenceMessenger.Default.Unregister<NewEquipmentDone>(this);
|
||||
WeakReferenceMessenger.Default.Unregister<ErrorMessage>(this);
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="using:GazpromApp.ViewModels"
|
||||
x:Name="Window"
|
||||
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="500"
|
||||
Width="500" Height="500"
|
||||
x:Class="GazpromApp.Views.NewPointDialog"
|
||||
x:DataType="vm:NewPointDialogViewModel"
|
||||
Title="Создание нового объекта"
|
||||
Icon="/Assets/ic_fluent_home_add_24_filled (Custom).png"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Closed="Window_OnClosed">
|
||||
<Design.DataContext>
|
||||
<vm:NewPointDialogViewModel/>
|
||||
</Design.DataContext>
|
||||
<Grid Margin="12" x:Name="Root">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition MaxWidth="120"/>
|
||||
<ColumnDefinition MinWidth="300"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition MaxHeight="50"/>
|
||||
<RowDefinition MaxHeight="100"/>
|
||||
<RowDefinition MinHeight="200" Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Grid.Column="0" Grid.Row="0" Margin="8" Text="Название: "/>
|
||||
<TextBlock Grid.Column="0" Grid.Row="1" Margin="8" Text="Описание: "/>
|
||||
<TextBlock Grid.Column="0" Grid.Row="2" Margin="8" Text="Изображение: "/>
|
||||
<TextBox Grid.Column="1" Grid.Row="0" Margin="8"
|
||||
Text="{Binding Name}"/>
|
||||
<TextBox Grid.Column="1" Grid.Row="1" Margin="8"
|
||||
Text="{Binding Description}"/>
|
||||
<Panel Grid.Column="1" Grid.Row="2" Margin="8" IsVisible="{Binding !IsImagesEmpty}">
|
||||
<ScrollViewer>
|
||||
<StackPanel>
|
||||
<ItemsRepeater ItemsSource="{Binding Images}" HorizontalAlignment="Center">
|
||||
<ItemsRepeater.Layout>
|
||||
<UniformGridLayout Orientation="Horizontal" MaximumRowsOrColumns="1"/>
|
||||
</ItemsRepeater.Layout>
|
||||
<ItemsRepeater.ItemTemplate>
|
||||
<DataTemplate DataType="vm:ImageViewModel">
|
||||
<Border Margin="4" CornerRadius="4" Background="LightGray">
|
||||
<Grid Margin="2" Width="200" Height="200" Background="LightGray"
|
||||
ColumnDefinitions="*,20,8" RowDefinitions="8,20,*">
|
||||
<Image Stretch="Uniform" Width="200" Height="200" Grid.RowSpan="3" Grid.ColumnSpan="3"
|
||||
Source="{Binding FileName}" />
|
||||
<Button Grid.Row="1" Grid.Column="1" Width="20" Height="20"
|
||||
Command="{Binding #Root.((vm:NewPointDialogViewModel)DataContext).DeleteImageCommand}"
|
||||
CommandParameter="{Binding .}">
|
||||
<Image Width="16" Height="16" Source="avares://GazpromApp/Assets/ic_fluent_delete_24_filled (Custom) 16.png"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsRepeater.ItemTemplate>
|
||||
</ItemsRepeater>
|
||||
<Button HorizontalAlignment="Center" IsVisible="True"
|
||||
Command="{Binding AddImageCommand}"
|
||||
CommandParameter="{Binding #Window}">
|
||||
<Image Width="24" Source="avares://GazpromApp/Assets/ic_fluent_camera_add_24_filled (Custom).png"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Panel>
|
||||
<Panel Grid.Column="1" Grid.Row="2" Margin="8"
|
||||
IsVisible="{Binding IsImagesEmpty}">
|
||||
<Button HorizontalAlignment="Center" IsVisible="True"
|
||||
Command="{Binding AddImageCommand}"
|
||||
CommandParameter="{Binding #Window}">
|
||||
<Image Width="24" Source="avares://GazpromApp/Assets/ic_fluent_camera_add_24_filled (Custom).png"/>
|
||||
</Button>
|
||||
</Panel>
|
||||
<Button Grid.Column="0" Grid.Row="3" Margin="8" Content="Отменить"
|
||||
Command="{Binding CancelEnterPointCommand}"
|
||||
CommandParameter="{Binding #Window}"/>
|
||||
<Button Grid.Column="1" Grid.Row="3" Margin="8" Content="Добавить" HorizontalAlignment="Right"
|
||||
Command="{Binding EnterPointCommand}"/>
|
||||
</Grid>
|
||||
</Window>
|
||||
@@ -1,36 +0,0 @@
|
||||
using System;
|
||||
using Avalonia.Controls;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using GazpromApp.Messages;
|
||||
using GazpromApp.ViewModels;
|
||||
|
||||
namespace GazpromApp.Views;
|
||||
|
||||
public partial class NewPointDialog : Window
|
||||
{
|
||||
public NewPointDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
// done entering new point
|
||||
WeakReferenceMessenger.Default.Register<NewPointDialog, NewPointDone>(this, static (w, m) =>
|
||||
{
|
||||
w.Close(m.Point);
|
||||
});
|
||||
|
||||
// register to work with errors
|
||||
WeakReferenceMessenger.Default.Register<NewPointDialog, ErrorMessage>(this, static (w, m) =>
|
||||
{
|
||||
ErrorView dialog = new ErrorView()
|
||||
{
|
||||
DataContext = m.Error
|
||||
};
|
||||
m.Reply(dialog.ShowDialog<ErrorViewModel?>(w));
|
||||
});
|
||||
}
|
||||
|
||||
private void Window_OnClosed(object? sender, EventArgs e)
|
||||
{
|
||||
WeakReferenceMessenger.Default.Unregister<ErrorMessage>(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="using:GazpromApp.ViewModels"
|
||||
xmlns:views="using:GazpromApp.Views"
|
||||
xmlns:icons="using:Material.Icons.Avalonia"
|
||||
mc:Ignorable="d" d:DesignWidth="300" d:DesignHeight="500"
|
||||
x:Class="GazpromApp.Views.PointView"
|
||||
x:DataType="vm:PointViewModel">
|
||||
<Expander>
|
||||
<Expander.Header>
|
||||
<Grid ColumnDefinitions="Auto, Auto, *, Auto, Auto">
|
||||
<icons:MaterialIcon Kind="Location" Margin="0,0,8,0" Width="24" Height="24"/>
|
||||
<TextBlock Grid.Column="1" VerticalAlignment="Center" TextWrapping="WrapWithOverflow"
|
||||
Text="{Binding Name}"/>
|
||||
<Button Width="32" Grid.Column="3" Margin="0,0,8,0"
|
||||
Command="{Binding AddEquipmentCommand}">
|
||||
<icons:MaterialIcon Kind="Add" Width="24" Height="24"/>
|
||||
</Button>
|
||||
<Button Width="32" Grid.Column="4" Margin="0,0,8,0"
|
||||
Command="{Binding RemovePointCommand}">
|
||||
<icons:MaterialIcon Kind="Delete" Width="24" Height="24"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Expander.Header>
|
||||
<Grid RowDefinitions="Auto,Auto,Auto,Auto" RowSpacing="4" Margin="8,4,8,2">
|
||||
<Grid.Styles>
|
||||
<Style Selector="ItemsRepeater.empty">
|
||||
<Setter Property="IsVisible" Value="True" />
|
||||
</Style>
|
||||
<Style Selector="ItemsRepeater.not-empty">
|
||||
<Setter Property="IsVisible" Value="False" />
|
||||
</Style>
|
||||
</Grid.Styles>
|
||||
<TextBlock Text="{Binding Description}"/>
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal">
|
||||
<TextBlock Text="Оборудований: "/>
|
||||
<TextBlock Text="{Binding Equipment.Count}"/>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="2" Orientation="Horizontal">
|
||||
<TextBlock Text="Свойств: "/>
|
||||
<TextBlock Text="{Binding Properties.Count}"/>
|
||||
</StackPanel>
|
||||
<ItemsRepeater Grid.Row="3" Margin="4,8"
|
||||
ItemsSource="{Binding Images}"
|
||||
Classes.empty="{Binding !!Images.Count}"
|
||||
Classes.not-empty="{Binding !Images.Count}">
|
||||
<ItemsRepeater.Layout>
|
||||
<StackLayout Orientation="Horizontal" Spacing="4"/>
|
||||
</ItemsRepeater.Layout>
|
||||
<ItemsRepeater.ItemTemplate>
|
||||
<DataTemplate DataType="vm:ImageViewModel">
|
||||
<Image Width="64" Height="64" Source="{Binding FileName}"/>
|
||||
</DataTemplate>
|
||||
</ItemsRepeater.ItemTemplate>
|
||||
</ItemsRepeater>
|
||||
</Grid>
|
||||
</Expander>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Windows.Input;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace GazpromApp.Views;
|
||||
|
||||
public partial class PointView : UserControl
|
||||
{
|
||||
public PointView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="using:GazpromApp.ViewModels"
|
||||
xmlns:icons="using:Material.Icons.Avalonia"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="GazpromApp.Views.PropertyView"
|
||||
x:DataType="vm:PropertyViewModel">
|
||||
<Grid ColumnDefinitions="150,*,Auto,Auto,Auto">
|
||||
<TextBlock Grid.Column="0" FontSize="18" VerticalAlignment="Center"
|
||||
IsVisible="{Binding !IsEditing}"
|
||||
Text="{Binding Name}"/>
|
||||
<TextBox Grid.Column="0" FontSize="18"
|
||||
IsVisible="{Binding IsEditing}"
|
||||
Text="{Binding Name}"/>
|
||||
|
||||
<TextBlock Grid.Column="1" FontSize="18" VerticalAlignment="Center"
|
||||
IsVisible="{Binding !IsEditing}"
|
||||
Text="{Binding Value}"/>
|
||||
<TextBox Grid.Column="1"
|
||||
IsVisible="{Binding IsEditing}"
|
||||
Text="{Binding Value}"/>
|
||||
|
||||
<Button Grid.Column="2" Width="32" Height="32" Margin="4" VerticalAlignment="Center"
|
||||
Command="{Binding AddPropertyCommand}">
|
||||
<icons:MaterialIcon Kind="Add" Width="24" Height="24"/>
|
||||
</Button>
|
||||
<Button Grid.Column="3" Width="32" Height="32" Margin="4" VerticalAlignment="Center"
|
||||
Command="{Binding EditPropertyCommand}">
|
||||
<Panel>
|
||||
<icons:MaterialIcon Kind="Edit" Width="24" Height="24"
|
||||
IsVisible="{Binding !IsEditing}"/>
|
||||
<icons:MaterialIcon Kind="ContentSave" Width="24" Height="24"
|
||||
IsVisible="{Binding IsEditing}"/>
|
||||
</Panel>
|
||||
</Button>
|
||||
<Button Grid.Column="4" Width="32" Height="32" Margin="4" VerticalAlignment="Center"
|
||||
Command="{Binding RemovePropertyCommand}">
|
||||
<icons:MaterialIcon Kind="Delete" Width="24" Height="24"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,13 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace GazpromApp.Views;
|
||||
|
||||
public partial class PropertyView : UserControl
|
||||
{
|
||||
public PropertyView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="using:GazpromApp.ViewModels"
|
||||
x:Name="Window"
|
||||
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="180"
|
||||
Width="400" Height="180"
|
||||
x:Class="GazpromApp.Views.SaveChangesView"
|
||||
x:DataType="vm:SaveChangesViewModel"
|
||||
Title="Не сохраненные данные"
|
||||
Icon="/Assets/ic_fluent_error_circle_24_filled (1) (Custom).png"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Closing="Window_OnClosing"
|
||||
Closed="Window_OnClosed">
|
||||
<Grid x:Name="Root" Margin="16"
|
||||
ColumnDefinitions="50, *" RowDefinitions="50, *, Auto">
|
||||
<Image Grid.Row="0" Grid.Column="0"
|
||||
Source="avares://GazpromApp/Assets/ic_fluent_info_24_filled (Custom).png"/>
|
||||
<Panel Grid.Row="0" Grid.Column="1" Grid.RowSpan="2">
|
||||
<StackPanel Margin="8">
|
||||
<TextBlock Text="Есть несохраненные изменения." FontSize="20" MaxLines="2" TextWrapping="Wrap"/>
|
||||
<TextBlock Text="Уверены что хотите закрыть?" MaxLines="3" TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
</Panel>
|
||||
<Panel Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2">
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Spacing="8">
|
||||
<Button Content="Не сохранять" Background="LightCoral"
|
||||
Command="{Binding DontSaveCommand}"
|
||||
CommandParameter="{Binding #Window}"/>
|
||||
<Button Content="Отмена"
|
||||
Command="{Binding CancelCommand}"
|
||||
CommandParameter="{Binding #Window}"/>
|
||||
<Button Content="Сохранить"
|
||||
Command="{Binding SaveCommand}"
|
||||
CommandParameter="{Binding #Window}"/>
|
||||
</StackPanel>
|
||||
</Panel>
|
||||
</Grid>
|
||||
</Window>
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace GazpromApp.Views;
|
||||
|
||||
public partial class SaveChangesView : Window
|
||||
{
|
||||
public bool CanClose = false;
|
||||
public SaveChangesView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void Window_OnClosing(object? sender, WindowClosingEventArgs e)
|
||||
{
|
||||
if (CanClose) return;
|
||||
e.Cancel = true;
|
||||
}
|
||||
|
||||
private void Window_OnClosed(object? sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
004891c51b7c26ff54260c1cbfcff302500ddbafa20549c101da76cc7da60e8a
|
||||
cc067bc255287b1def9594eac16771691c8ab80aebe0b1c73635a5ea9772fd91
|
||||
|
||||
Binary file not shown.
@@ -13,7 +13,7 @@ using System.Reflection;
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("GazpromApp")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+5816f21e6cc989b7059d5a18a1f56939b27bf40d")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+08eaa30209fb07132671006392af33044278fb88")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("GazpromApp")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("GazpromApp")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
@@ -1 +1 @@
|
||||
22f6a7bf36b71d326c8840f0501afa961a7d4f13e9163340a4acf3e167738c72
|
||||
991b92f7461b0b0cb8dff258086ca1dd3fd0a9b1938281c5774aefca5ef9edfc
|
||||
|
||||
@@ -32,10 +32,13 @@ build_property.EnableCodeStyleSeverity =
|
||||
[D:/RiderProjects/GazpromApp/App.axaml]
|
||||
build_metadata.AdditionalFiles.SourceItemGroup = AvaloniaXaml
|
||||
|
||||
[D:/RiderProjects/GazpromApp/Views/EditEquipmentDialog.axaml]
|
||||
[D:/RiderProjects/GazpromApp/Views/EditEquipmentView.axaml]
|
||||
build_metadata.AdditionalFiles.SourceItemGroup = AvaloniaXaml
|
||||
|
||||
[D:/RiderProjects/GazpromApp/Views/EditPointDialog.axaml]
|
||||
[D:/RiderProjects/GazpromApp/Views/EditPointView.axaml]
|
||||
build_metadata.AdditionalFiles.SourceItemGroup = AvaloniaXaml
|
||||
|
||||
[D:/RiderProjects/GazpromApp/Views/EquipmentView.axaml]
|
||||
build_metadata.AdditionalFiles.SourceItemGroup = AvaloniaXaml
|
||||
|
||||
[D:/RiderProjects/GazpromApp/Views/ErrorView.axaml]
|
||||
@@ -44,11 +47,17 @@ build_metadata.AdditionalFiles.SourceItemGroup = AvaloniaXaml
|
||||
[D:/RiderProjects/GazpromApp/Views/ImageView.axaml]
|
||||
build_metadata.AdditionalFiles.SourceItemGroup = AvaloniaXaml
|
||||
|
||||
[D:/RiderProjects/GazpromApp/Views/InspectionView.axaml]
|
||||
build_metadata.AdditionalFiles.SourceItemGroup = AvaloniaXaml
|
||||
|
||||
[D:/RiderProjects/GazpromApp/Views/MainWindow.axaml]
|
||||
build_metadata.AdditionalFiles.SourceItemGroup = AvaloniaXaml
|
||||
|
||||
[D:/RiderProjects/GazpromApp/Views/NewEquipmentDialog.axaml]
|
||||
[D:/RiderProjects/GazpromApp/Views/PointView.axaml]
|
||||
build_metadata.AdditionalFiles.SourceItemGroup = AvaloniaXaml
|
||||
|
||||
[D:/RiderProjects/GazpromApp/Views/NewPointDialog.axaml]
|
||||
[D:/RiderProjects/GazpromApp/Views/PropertyView.axaml]
|
||||
build_metadata.AdditionalFiles.SourceItemGroup = AvaloniaXaml
|
||||
|
||||
[D:/RiderProjects/GazpromApp/Views/SaveChangesView.axaml]
|
||||
build_metadata.AdditionalFiles.SourceItemGroup = AvaloniaXaml
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -201,3 +201,11 @@ D:\RiderProjects\GazpromApp\bin\Debug\net8.0\zh-Hant\Microsoft.CodeAnalysis.Work
|
||||
D:\RiderProjects\GazpromApp\bin\Debug\net8.0\AvaloniaUI.DiagnosticsSupport.Avalonia.dll
|
||||
D:\RiderProjects\GazpromApp\bin\Debug\net8.0\Microsoft.IO.RecyclableMemoryStream.dll
|
||||
D:\RiderProjects\GazpromApp\bin\Debug\net8.0\Avalonia.Controls.ItemsRepeater.dll
|
||||
D:\RiderProjects\GazpromApp\bin\Debug\net8.0\AnimatedImage.Avalonia.dll
|
||||
D:\RiderProjects\GazpromApp\bin\Debug\net8.0\AnimatedImage.dll
|
||||
D:\RiderProjects\GazpromApp\bin\Debug\net8.0\Material.Avalonia.dll
|
||||
D:\RiderProjects\GazpromApp\bin\Debug\net8.0\Material.Colors.dll
|
||||
D:\RiderProjects\GazpromApp\bin\Debug\net8.0\Material.Ripple.dll
|
||||
D:\RiderProjects\GazpromApp\bin\Debug\net8.0\Material.Styles.dll
|
||||
D:\RiderProjects\GazpromApp\bin\Debug\net8.0\Material.Icons.dll
|
||||
D:\RiderProjects\GazpromApp\bin\Debug\net8.0\Material.Icons.Avalonia.dll
|
||||
|
||||
@@ -44,12 +44,16 @@
|
||||
"auditLevel": "low",
|
||||
"auditMode": "direct"
|
||||
},
|
||||
"SdkAnalysisLevel": "9.0.200"
|
||||
"SdkAnalysisLevel": "9.0.300"
|
||||
},
|
||||
"frameworks": {
|
||||
"net8.0": {
|
||||
"targetAlias": "net8.0",
|
||||
"dependencies": {
|
||||
"AnimatedImage.Avalonia": {
|
||||
"target": "Package",
|
||||
"version": "[2.0.0, )"
|
||||
},
|
||||
"Avalonia": {
|
||||
"target": "Package",
|
||||
"version": "[11.3.2, )"
|
||||
@@ -82,6 +86,14 @@
|
||||
"target": "Package",
|
||||
"version": "[8.2.1, )"
|
||||
},
|
||||
"Material.Avalonia": {
|
||||
"target": "Package",
|
||||
"version": "[3.12.0, )"
|
||||
},
|
||||
"Material.Icons.Avalonia": {
|
||||
"target": "Package",
|
||||
"version": "[2.4.1, )"
|
||||
},
|
||||
"Microsoft.EntityFrameworkCore": {
|
||||
"target": "Package",
|
||||
"version": "[9.0.6, )"
|
||||
@@ -113,7 +125,7 @@
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.204/PortableRuntimeIdentifierGraph.json"
|
||||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.302/PortableRuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.entityframeworkcore\9.0.6\buildTransitive\net8.0\Microsoft.EntityFrameworkCore.props" Condition="Exists('$(NuGetPackageRoot)microsoft.entityframeworkcore\9.0.6\buildTransitive\net8.0\Microsoft.EntityFrameworkCore.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.codeanalysis.analyzers\3.3.4\buildTransitive\Microsoft.CodeAnalysis.Analyzers.props" Condition="Exists('$(NuGetPackageRoot)microsoft.codeanalysis.analyzers\3.3.4\buildTransitive\Microsoft.CodeAnalysis.Analyzers.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.entityframeworkcore.design\9.0.6\build\net8.0\Microsoft.EntityFrameworkCore.Design.props" Condition="Exists('$(NuGetPackageRoot)microsoft.entityframeworkcore.design\9.0.6\build\net8.0\Microsoft.EntityFrameworkCore.Design.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)harfbuzzsharp.nativeassets.webassembly\8.3.1.1\buildTransitive\netstandard1.0\HarfBuzzSharp.NativeAssets.WebAssembly.props" Condition="Exists('$(NuGetPackageRoot)harfbuzzsharp.nativeassets.webassembly\8.3.1.1\buildTransitive\netstandard1.0\HarfBuzzSharp.NativeAssets.WebAssembly.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)avalonia\11.3.2\buildTransitive\Avalonia.props" Condition="Exists('$(NuGetPackageRoot)avalonia\11.3.2\buildTransitive\Avalonia.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)harfbuzzsharp.nativeassets.webassembly\8.3.1.1\buildTransitive\netstandard1.0\HarfBuzzSharp.NativeAssets.WebAssembly.props" Condition="Exists('$(NuGetPackageRoot)harfbuzzsharp.nativeassets.webassembly\8.3.1.1\buildTransitive\netstandard1.0\HarfBuzzSharp.NativeAssets.WebAssembly.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)avaloniaui.diagnosticssupport\2.0.4\buildTransitive\AvaloniaUI.DiagnosticsSupport.props" Condition="Exists('$(NuGetPackageRoot)avaloniaui.diagnosticssupport\2.0.4\buildTransitive\AvaloniaUI.DiagnosticsSupport.props')" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.options\9.0.6\buildTransitive\net8.0\Microsoft.Extensions.Options.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.options\9.0.6\buildTransitive\net8.0\Microsoft.Extensions.Options.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\9.0.6\buildTransitive\net8.0\Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\9.0.6\buildTransitive\net8.0\Microsoft.Extensions.Logging.Abstractions.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.codeanalysis.analyzers\3.3.4\buildTransitive\Microsoft.CodeAnalysis.Analyzers.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.codeanalysis.analyzers\3.3.4\buildTransitive\Microsoft.CodeAnalysis.Analyzers.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)harfbuzzsharp.nativeassets.webassembly\8.3.1.1\buildTransitive\netstandard1.0\HarfBuzzSharp.NativeAssets.WebAssembly.targets" Condition="Exists('$(NuGetPackageRoot)harfbuzzsharp.nativeassets.webassembly\8.3.1.1\buildTransitive\netstandard1.0\HarfBuzzSharp.NativeAssets.WebAssembly.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)communitytoolkit.mvvm\8.2.1\buildTransitive\netstandard2.1\CommunityToolkit.Mvvm.targets" Condition="Exists('$(NuGetPackageRoot)communitytoolkit.mvvm\8.2.1\buildTransitive\netstandard2.1\CommunityToolkit.Mvvm.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)avalonia.buildservices\0.0.31\buildTransitive\Avalonia.BuildServices.targets" Condition="Exists('$(NuGetPackageRoot)avalonia.buildservices\0.0.31\buildTransitive\Avalonia.BuildServices.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)avalonia\11.3.2\buildTransitive\Avalonia.targets" Condition="Exists('$(NuGetPackageRoot)avalonia\11.3.2\buildTransitive\Avalonia.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)harfbuzzsharp.nativeassets.webassembly\8.3.1.1\buildTransitive\netstandard1.0\HarfBuzzSharp.NativeAssets.WebAssembly.targets" Condition="Exists('$(NuGetPackageRoot)harfbuzzsharp.nativeassets.webassembly\8.3.1.1\buildTransitive\netstandard1.0\HarfBuzzSharp.NativeAssets.WebAssembly.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)communitytoolkit.mvvm\8.2.1\buildTransitive\netstandard2.1\CommunityToolkit.Mvvm.targets" Condition="Exists('$(NuGetPackageRoot)communitytoolkit.mvvm\8.2.1\buildTransitive\netstandard2.1\CommunityToolkit.Mvvm.targets')" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
+150
-2
@@ -2,6 +2,28 @@
|
||||
"version": 3,
|
||||
"targets": {
|
||||
"net8.0": {
|
||||
"AnimatedImage.Avalonia/2.0.0": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
"Avalonia": "11.0.0"
|
||||
},
|
||||
"compile": {
|
||||
"lib/net6.0/AnimatedImage.Avalonia.dll": {
|
||||
"related": ".xml"
|
||||
},
|
||||
"lib/net6.0/AnimatedImage.dll": {
|
||||
"related": ".Avalonia.xml;.xml"
|
||||
}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net6.0/AnimatedImage.Avalonia.dll": {
|
||||
"related": ".xml"
|
||||
},
|
||||
"lib/net6.0/AnimatedImage.dll": {
|
||||
"related": ".Avalonia.xml;.xml"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Avalonia/11.3.2": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
@@ -519,6 +541,46 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Material.Avalonia/3.12.0": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
"Avalonia": "11.1.0"
|
||||
},
|
||||
"compile": {
|
||||
"lib/net8.0/Material.Avalonia.dll": {},
|
||||
"lib/net8.0/Material.Colors.dll": {},
|
||||
"lib/net8.0/Material.Ripple.dll": {},
|
||||
"lib/net8.0/Material.Styles.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net8.0/Material.Avalonia.dll": {},
|
||||
"lib/net8.0/Material.Colors.dll": {},
|
||||
"lib/net8.0/Material.Ripple.dll": {},
|
||||
"lib/net8.0/Material.Styles.dll": {}
|
||||
}
|
||||
},
|
||||
"Material.Icons/2.4.1": {
|
||||
"type": "package",
|
||||
"compile": {
|
||||
"lib/netstandard2.0/Material.Icons.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/Material.Icons.dll": {}
|
||||
}
|
||||
},
|
||||
"Material.Icons.Avalonia/2.4.1": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
"Avalonia": "11.0.0",
|
||||
"Material.Icons": "2.4.1"
|
||||
},
|
||||
"compile": {
|
||||
"lib/netstandard2.0/Material.Icons.Avalonia.dll": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/Material.Icons.Avalonia.dll": {}
|
||||
}
|
||||
},
|
||||
"MicroCom.Runtime/0.11.0": {
|
||||
"type": "package",
|
||||
"compile": {
|
||||
@@ -1766,6 +1828,30 @@
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"AnimatedImage.Avalonia/2.0.0": {
|
||||
"sha512": "Ts0lfQjbozqk1q1uoXBm/dRH8nmxTTmMunan8IBuHsIPKG1MUL+60KDmbCyurnE0rNJh24boGjhIj2Ec9W5Jbg==",
|
||||
"type": "package",
|
||||
"path": "animatedimage.avalonia/2.0.0",
|
||||
"files": [
|
||||
".nupkg.metadata",
|
||||
".signature.p7s",
|
||||
"AnimatedImage.Avalonia.md",
|
||||
"animatedimage.avalonia.2.0.0.nupkg.sha512",
|
||||
"animatedimage.avalonia.nuspec",
|
||||
"lib/net462/AnimatedImage.Avalonia.dll",
|
||||
"lib/net462/AnimatedImage.Avalonia.xml",
|
||||
"lib/net462/AnimatedImage.dll",
|
||||
"lib/net462/AnimatedImage.xml",
|
||||
"lib/net6.0/AnimatedImage.Avalonia.dll",
|
||||
"lib/net6.0/AnimatedImage.Avalonia.xml",
|
||||
"lib/net6.0/AnimatedImage.dll",
|
||||
"lib/net6.0/AnimatedImage.xml",
|
||||
"lib/netcoreapp3.1/AnimatedImage.Avalonia.dll",
|
||||
"lib/netcoreapp3.1/AnimatedImage.Avalonia.xml",
|
||||
"lib/netcoreapp3.1/AnimatedImage.dll",
|
||||
"lib/netcoreapp3.1/AnimatedImage.xml"
|
||||
]
|
||||
},
|
||||
"Avalonia/11.3.2": {
|
||||
"sha512": "3w1v4/wEpHFq6WWVNyyrne2Jyz5bdQvnK3AW36rCto42L+AtdbnO/SG2SIqJ7ObXJl+Y3LXz2XDGx9Blzqduow==",
|
||||
"type": "package",
|
||||
@@ -2438,6 +2524,53 @@
|
||||
"logo.png"
|
||||
]
|
||||
},
|
||||
"Material.Avalonia/3.12.0": {
|
||||
"sha512": "CtYyhPnP9+9UfKRGHjJGe6isxVjaM1F4cvjUHa0r7qtTskBjHNJAIJOtRMLwqD8/kl5zx1ZhS9Jtuuloqxg6Yg==",
|
||||
"type": "package",
|
||||
"path": "material.avalonia/3.12.0",
|
||||
"files": [
|
||||
".nupkg.metadata",
|
||||
".signature.p7s",
|
||||
"FavIcon.png",
|
||||
"README.md",
|
||||
"lib/net8.0/Material.Avalonia.dll",
|
||||
"lib/net8.0/Material.Colors.dll",
|
||||
"lib/net8.0/Material.Ripple.dll",
|
||||
"lib/net8.0/Material.Styles.dll",
|
||||
"lib/netstandard2.0/Material.Avalonia.dll",
|
||||
"lib/netstandard2.0/Material.Colors.dll",
|
||||
"lib/netstandard2.0/Material.Ripple.dll",
|
||||
"lib/netstandard2.0/Material.Styles.dll",
|
||||
"material.avalonia.3.12.0.nupkg.sha512",
|
||||
"material.avalonia.nuspec"
|
||||
]
|
||||
},
|
||||
"Material.Icons/2.4.1": {
|
||||
"sha512": "5/8ekF4GXqpluBF+kPfv3TytBpV5Z+h4CUU5iNCDC7+A9hPQvtn08ZUjMUXtcRGxGyfScHYDqzshzTvYiPTCdA==",
|
||||
"type": "package",
|
||||
"path": "material.icons/2.4.1",
|
||||
"files": [
|
||||
".nupkg.metadata",
|
||||
".signature.p7s",
|
||||
"README.md",
|
||||
"lib/netstandard2.0/Material.Icons.dll",
|
||||
"material.icons.2.4.1.nupkg.sha512",
|
||||
"material.icons.nuspec"
|
||||
]
|
||||
},
|
||||
"Material.Icons.Avalonia/2.4.1": {
|
||||
"sha512": "bJZzJCHfZDBg33ZyiSxvexMs2qMGkkv1XEgkAJkqLK9I8WNIUGLCnXcjoBrpSh2Sd2ytoD1IEjV72Zy54St3zA==",
|
||||
"type": "package",
|
||||
"path": "material.icons.avalonia/2.4.1",
|
||||
"files": [
|
||||
".nupkg.metadata",
|
||||
".signature.p7s",
|
||||
"README.md",
|
||||
"lib/netstandard2.0/Material.Icons.Avalonia.dll",
|
||||
"material.icons.avalonia.2.4.1.nupkg.sha512",
|
||||
"material.icons.avalonia.nuspec"
|
||||
]
|
||||
},
|
||||
"MicroCom.Runtime/0.11.0": {
|
||||
"sha512": "MEnrZ3UIiH40hjzMDsxrTyi8dtqB5ziv3iBeeU4bXsL/7NLSal9F1lZKpK+tfBRnUoDSdtcW3KufE4yhATOMCA==",
|
||||
"type": "package",
|
||||
@@ -4695,6 +4828,7 @@
|
||||
},
|
||||
"projectFileDependencyGroups": {
|
||||
"net8.0": [
|
||||
"AnimatedImage.Avalonia >= 2.0.0",
|
||||
"Avalonia >= 11.3.2",
|
||||
"Avalonia.Controls.ItemsRepeater >= 11.1.5",
|
||||
"Avalonia.Desktop >= 11.3.2",
|
||||
@@ -4703,6 +4837,8 @@
|
||||
"Avalonia.Themes.Fluent >= 11.3.2",
|
||||
"AvaloniaUI.DiagnosticsSupport >= 2.0.4",
|
||||
"CommunityToolkit.Mvvm >= 8.2.1",
|
||||
"Material.Avalonia >= 3.12.0",
|
||||
"Material.Icons.Avalonia >= 2.4.1",
|
||||
"Microsoft.EntityFrameworkCore >= 9.0.6",
|
||||
"Microsoft.EntityFrameworkCore.Design >= 9.0.6",
|
||||
"Microsoft.EntityFrameworkCore.Sqlite >= 9.0.6"
|
||||
@@ -4752,12 +4888,16 @@
|
||||
"auditLevel": "low",
|
||||
"auditMode": "direct"
|
||||
},
|
||||
"SdkAnalysisLevel": "9.0.200"
|
||||
"SdkAnalysisLevel": "9.0.300"
|
||||
},
|
||||
"frameworks": {
|
||||
"net8.0": {
|
||||
"targetAlias": "net8.0",
|
||||
"dependencies": {
|
||||
"AnimatedImage.Avalonia": {
|
||||
"target": "Package",
|
||||
"version": "[2.0.0, )"
|
||||
},
|
||||
"Avalonia": {
|
||||
"target": "Package",
|
||||
"version": "[11.3.2, )"
|
||||
@@ -4790,6 +4930,14 @@
|
||||
"target": "Package",
|
||||
"version": "[8.2.1, )"
|
||||
},
|
||||
"Material.Avalonia": {
|
||||
"target": "Package",
|
||||
"version": "[3.12.0, )"
|
||||
},
|
||||
"Material.Icons.Avalonia": {
|
||||
"target": "Package",
|
||||
"version": "[2.4.1, )"
|
||||
},
|
||||
"Microsoft.EntityFrameworkCore": {
|
||||
"target": "Package",
|
||||
"version": "[9.0.6, )"
|
||||
@@ -4821,7 +4969,7 @@
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.204/PortableRuntimeIdentifierGraph.json"
|
||||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.302/PortableRuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dgSpecHash": "jPpTgNZhtko=",
|
||||
"dgSpecHash": "dxfLR4PjleQ=",
|
||||
"success": true,
|
||||
"projectFilePath": "D:\\RiderProjects\\GazpromApp\\GazpromApp.csproj",
|
||||
"expectedPackageFiles": [
|
||||
"C:\\Users\\retrd\\.nuget\\packages\\animatedimage.avalonia\\2.0.0\\animatedimage.avalonia.2.0.0.nupkg.sha512",
|
||||
"C:\\Users\\retrd\\.nuget\\packages\\avalonia\\11.3.2\\avalonia.11.3.2.nupkg.sha512",
|
||||
"C:\\Users\\retrd\\.nuget\\packages\\avalonia.angle.windows.natives\\2.1.25547.20250602\\avalonia.angle.windows.natives.2.1.25547.20250602.nupkg.sha512",
|
||||
"C:\\Users\\retrd\\.nuget\\packages\\avalonia.buildservices\\0.0.31\\avalonia.buildservices.0.0.31.nupkg.sha512",
|
||||
@@ -28,6 +29,9 @@
|
||||
"C:\\Users\\retrd\\.nuget\\packages\\harfbuzzsharp.nativeassets.webassembly\\8.3.1.1\\harfbuzzsharp.nativeassets.webassembly.8.3.1.1.nupkg.sha512",
|
||||
"C:\\Users\\retrd\\.nuget\\packages\\harfbuzzsharp.nativeassets.win32\\8.3.1.1\\harfbuzzsharp.nativeassets.win32.8.3.1.1.nupkg.sha512",
|
||||
"C:\\Users\\retrd\\.nuget\\packages\\humanizer.core\\2.14.1\\humanizer.core.2.14.1.nupkg.sha512",
|
||||
"C:\\Users\\retrd\\.nuget\\packages\\material.avalonia\\3.12.0\\material.avalonia.3.12.0.nupkg.sha512",
|
||||
"C:\\Users\\retrd\\.nuget\\packages\\material.icons\\2.4.1\\material.icons.2.4.1.nupkg.sha512",
|
||||
"C:\\Users\\retrd\\.nuget\\packages\\material.icons.avalonia\\2.4.1\\material.icons.avalonia.2.4.1.nupkg.sha512",
|
||||
"C:\\Users\\retrd\\.nuget\\packages\\microcom.runtime\\0.11.0\\microcom.runtime.0.11.0.nupkg.sha512",
|
||||
"C:\\Users\\retrd\\.nuget\\packages\\microsoft.bcl.asyncinterfaces\\7.0.0\\microsoft.bcl.asyncinterfaces.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\retrd\\.nuget\\packages\\microsoft.build.framework\\17.8.3\\microsoft.build.framework.17.8.3.nupkg.sha512",
|
||||
|
||||
@@ -1 +1 @@
|
||||
"restore":{"projectUniqueName":"D:\\RiderProjects\\GazpromApp\\GazpromApp.csproj","projectName":"GazpromApp","projectPath":"D:\\RiderProjects\\GazpromApp\\GazpromApp.csproj","outputPath":"D:\\RiderProjects\\GazpromApp\\obj\\","projectStyle":"PackageReference","fallbackFolders":["C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"],"originalTargetFrameworks":["net8.0"],"sources":{"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\":{},"https://api.nuget.org/v3/index.json":{}},"frameworks":{"net8.0":{"targetAlias":"net8.0","projectReferences":{}}},"warningProperties":{"warnAsError":["NU1605"]},"restoreAuditProperties":{"enableAudit":"true","auditLevel":"low","auditMode":"direct"},"SdkAnalysisLevel":"9.0.200"}"frameworks":{"net8.0":{"targetAlias":"net8.0","dependencies":{"Avalonia":{"target":"Package","version":"[11.3.2, )"},"Avalonia.Controls.ItemsRepeater":{"target":"Package","version":"[11.1.5, )"},"Avalonia.Desktop":{"target":"Package","version":"[11.3.2, )"},"Avalonia.Diagnostics":{"target":"Package","version":"[11.3.2, )"},"Avalonia.Fonts.Inter":{"target":"Package","version":"[11.3.2, )"},"Avalonia.Themes.Fluent":{"target":"Package","version":"[11.3.2, )"},"AvaloniaUI.DiagnosticsSupport":{"target":"Package","version":"[2.0.4, )"},"CommunityToolkit.Mvvm":{"target":"Package","version":"[8.2.1, )"},"Microsoft.EntityFrameworkCore":{"target":"Package","version":"[9.0.6, )"},"Microsoft.EntityFrameworkCore.Design":{"include":"Runtime, Build, Native, ContentFiles, Analyzers, BuildTransitive","suppressParent":"All","target":"Package","version":"[9.0.6, )"},"Microsoft.EntityFrameworkCore.Sqlite":{"target":"Package","version":"[9.0.6, )"}},"imports":["net461","net462","net47","net471","net472","net48","net481"],"assetTargetFallback":true,"warn":true,"frameworkReferences":{"Microsoft.NETCore.App":{"privateAssets":"all"}},"runtimeIdentifierGraphPath":"C:\\Program Files\\dotnet\\sdk\\9.0.204/PortableRuntimeIdentifierGraph.json"}}
|
||||
"restore":{"projectUniqueName":"D:\\RiderProjects\\GazpromApp\\GazpromApp.csproj","projectName":"GazpromApp","projectPath":"D:\\RiderProjects\\GazpromApp\\GazpromApp.csproj","outputPath":"D:\\RiderProjects\\GazpromApp\\obj\\","projectStyle":"PackageReference","fallbackFolders":["C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"],"originalTargetFrameworks":["net8.0"],"sources":{"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\":{},"https://api.nuget.org/v3/index.json":{}},"frameworks":{"net8.0":{"targetAlias":"net8.0","projectReferences":{}}},"warningProperties":{"warnAsError":["NU1605"]},"restoreAuditProperties":{"enableAudit":"true","auditLevel":"low","auditMode":"direct"},"SdkAnalysisLevel":"9.0.300"}"frameworks":{"net8.0":{"targetAlias":"net8.0","dependencies":{"AnimatedImage.Avalonia":{"target":"Package","version":"[2.0.0, )"},"Avalonia":{"target":"Package","version":"[11.3.2, )"},"Avalonia.Controls.ItemsRepeater":{"target":"Package","version":"[11.1.5, )"},"Avalonia.Desktop":{"target":"Package","version":"[11.3.2, )"},"Avalonia.Diagnostics":{"target":"Package","version":"[11.3.2, )"},"Avalonia.Fonts.Inter":{"target":"Package","version":"[11.3.2, )"},"Avalonia.Themes.Fluent":{"target":"Package","version":"[11.3.2, )"},"AvaloniaUI.DiagnosticsSupport":{"target":"Package","version":"[2.0.4, )"},"CommunityToolkit.Mvvm":{"target":"Package","version":"[8.2.1, )"},"Material.Avalonia":{"target":"Package","version":"[3.12.0, )"},"Material.Icons.Avalonia":{"target":"Package","version":"[2.4.1, )"},"Microsoft.EntityFrameworkCore":{"target":"Package","version":"[9.0.6, )"},"Microsoft.EntityFrameworkCore.Design":{"include":"Runtime, Build, Native, ContentFiles, Analyzers, BuildTransitive","suppressParent":"All","target":"Package","version":"[9.0.6, )"},"Microsoft.EntityFrameworkCore.Sqlite":{"target":"Package","version":"[9.0.6, )"}},"imports":["net461","net462","net47","net471","net472","net48","net481"],"assetTargetFallback":true,"warn":true,"frameworkReferences":{"Microsoft.NETCore.App":{"privateAssets":"all"}},"runtimeIdentifierGraphPath":"C:\\Program Files\\dotnet\\sdk\\9.0.302/PortableRuntimeIdentifierGraph.json"}}
|
||||
@@ -1 +1 @@
|
||||
17514599119483488
|
||||
17536846459734642
|
||||
@@ -1 +1 @@
|
||||
17514599119483488
|
||||
17536846459734642
|
||||
Reference in New Issue
Block a user