diff --git a/Directory.Packages.props b/Directory.Packages.props
index 8b5e726..47b4882 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -7,6 +7,7 @@
+
@@ -15,14 +16,18 @@
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
-
-
-
-
-
+
+
+
+
\ No newline at end of file
diff --git a/pgLabII/App.axaml b/pgLabII/App.axaml
index 9a371e6..9af82b4 100644
--- a/pgLabII/App.axaml
+++ b/pgLabII/App.axaml
@@ -13,9 +13,7 @@
+
-
-
-
\ No newline at end of file
diff --git a/pgLabII/App.axaml.cs b/pgLabII/App.axaml.cs
index bcda51c..799f898 100644
--- a/pgLabII/App.axaml.cs
+++ b/pgLabII/App.axaml.cs
@@ -1,6 +1,9 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.DependencyInjection;
+using pgLabII.Infra;
using pgLabII.ViewModels;
using pgLabII.Views;
@@ -15,27 +18,37 @@ public partial class App : Application
public override void OnFrameworkInitializationCompleted()
{
- if (Resources[nameof(Composition)] is Composition composition)
+ // If you use CommunityToolkit, line below is needed to remove Avalonia data validation.
+ // Without this line you will get duplicate validations from both Avalonia and CT
+ // BindingPlugins.DataValidators.RemoveAt(0);
+
+ // Register all the services needed for the application to run
+ var collection = new ServiceCollection();
+ collection.AddCommonServices();
+
+ // Creates a ServiceProvider containing services from the provided IServiceCollection
+ var services = collection.BuildServiceProvider();
+
+ MigrateLocalDb(services);
+
+ MainWindow win = services.GetRequiredService();
+ if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
- switch (ApplicationLifetime)
- {
- case IClassicDesktopStyleApplicationLifetime desktop:
- desktop.MainWindow = composition.MainWindow;
- break;
-
- case ISingleViewApplicationLifetime singleViewPlatform:
- singleViewPlatform.MainView = composition.MainWindow;
- break;
- }
-
- // Handles disposables
- if (ApplicationLifetime is IControlledApplicationLifetime controlledApplicationLifetime)
- {
- //controlledApplicationLifetime.Exit += (_, _) => composition.Dispose();
- }
+ desktop.MainWindow = win;
+ }
+ else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewPlatform)
+ {
+ singleViewPlatform.MainView = win;
}
base.OnFrameworkInitializationCompleted();
}
+ private void MigrateLocalDb(ServiceProvider services)
+ {
+ using var scope = services.CreateScope();
+
+ var db = services.GetRequiredService();
+ //db.Database.Migrate();
+ }
}
diff --git a/pgLabII/Composition.cs b/pgLabII/Composition.cs
deleted file mode 100644
index dc16d1f..0000000
--- a/pgLabII/Composition.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using pgLabII.ViewModels;
-using pgLabII.Views;
-using Pure.DI;
-using static Pure.DI.Lifetime;
-
-namespace pgLabII;
-
-internal partial class Composition
-{
- public void Setup() => DI.Setup()
- .Root(nameof(MainWindow))
-// .Root(nameof(ServerListView))
- .Root(nameof(MainViewModel))
-// .Bind().As(Singleton).To()
-
- .Root(nameof(ServerListViewModel))
-// .Bind().As(Singleton).To()
- ;
-
-}
diff --git a/pgLabII/ConnectionManager/ConnectionRepository.cs b/pgLabII/ConnectionManager/ConnectionRepository.cs
new file mode 100644
index 0000000..1259b40
--- /dev/null
+++ b/pgLabII/ConnectionManager/ConnectionRepository.cs
@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace pgLabII.ConnectionManager;
+internal class ConnectionRepository
+{
+}
diff --git a/pgLabII/Infra/ColorConverter.cs b/pgLabII/Infra/ColorConverter.cs
new file mode 100644
index 0000000..0274701
--- /dev/null
+++ b/pgLabII/Infra/ColorConverter.cs
@@ -0,0 +1,13 @@
+using Avalonia.Media;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+namespace pgLabII.Infra;
+
+public class ColorConverter : ValueConverter
+{
+ public ColorConverter()
+ : base(
+ v => v.ToUInt32(),
+ v => Color.FromUInt32(v))
+ { }
+}
diff --git a/pgLabII/Infra/LocalDb.cs b/pgLabII/Infra/LocalDb.cs
new file mode 100644
index 0000000..cb4c492
--- /dev/null
+++ b/pgLabII/Infra/LocalDb.cs
@@ -0,0 +1,58 @@
+using System;
+using Avalonia.Media;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+using pgLabII.Model;
+
+namespace pgLabII.Infra;
+
+internal class LocalDb : DbContext
+{
+ public DbSet ServerConfigurations => Set();
+
+ public string DbPath { get; }
+
+ public LocalDb()
+ {
+ var folder = Environment.SpecialFolder.LocalApplicationData;
+ var path = Environment.GetFolderPath(folder);
+ DbPath = System.IO.Path.Join(path, "local.db");
+ }
+
+ // The following configures EF to create a Sqlite database file in the
+ // special "local" folder for your platform.
+ protected override void OnConfiguring(DbContextOptionsBuilder options)
+ => options.UseSqlite($"Data Source={DbPath}");
+
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
+ {
+
+
+ new ServerConfigurationEntityConfiguration().Configure(modelBuilder.Entity());
+ }
+
+ protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
+ {
+ base.ConfigureConventions(configurationBuilder);
+
+ configurationBuilder
+ .Properties()
+ .HaveConversion();
+ }
+}
+
+public class ServerConfigurationEntityConfiguration : IEntityTypeConfiguration
+{
+ public void Configure(EntityTypeBuilder b)
+ {
+ b.HasKey(e => e.Id);
+ }
+}
+
+public class ServerUserEntityConfiguration : IEntityTypeConfiguration
+{
+ public void Configure(EntityTypeBuilder b)
+ {
+ b.HasKey(e => e.Id);
+ }
+}
diff --git a/pgLabII/Model/Database.cs b/pgLabII/Model/Database.cs
new file mode 100644
index 0000000..2762fc6
--- /dev/null
+++ b/pgLabII/Model/Database.cs
@@ -0,0 +1,9 @@
+namespace pgLabII.Model;
+
+public class Database
+{
+ public int Oid { get; set; }
+ public string Name { get; set; } = "";
+ public int OwnerId { get; set; }
+
+}
diff --git a/pgLabII/ViewModels/ServerConfiguration.cs b/pgLabII/Model/ServerConfiguration.cs
similarity index 55%
rename from pgLabII/ViewModels/ServerConfiguration.cs
rename to pgLabII/Model/ServerConfiguration.cs
index 009eb52..eafdcda 100644
--- a/pgLabII/ViewModels/ServerConfiguration.cs
+++ b/pgLabII/Model/ServerConfiguration.cs
@@ -7,18 +7,19 @@ using Npgsql;
using pgLabII.Views;
using ReactiveUI;
-namespace pgLabII.ViewModels;
+namespace pgLabII.Model;
public class ServerConfiguration : ReactiveObject
{
- private Color? _color;
+ private Color _color;
+ private bool _colorEnabled = true;
public Guid Id { get; set; } = Guid.NewGuid();
///
/// For the user to help him identify the item
///
public string Name { get; set; } = "";
- public Color? Color
+ public Color Color
{
get => _color;
set
@@ -32,13 +33,27 @@ public class ServerConfiguration : ReactiveObject
}
}
+ public bool ColorEnabled
+ {
+ get => _colorEnabled;
+ set
+ {
+ if (_colorEnabled != value)
+ {
+ _colorEnabled = value;
+ this.RaisePropertyChanged();
+ this.RaisePropertyChanged(propertyName: nameof(BackgroundBrush));
+ }
+ }
+ }
+
public string Host { get; set; } = "";
public ushort Port { get; set; } = 5432;
public string InitialDatabase { get; set; } = "";
public SslMode DefaultSslMode { get; set; } = SslMode.Prefer;
- public IBrush? BackgroundBrush => Color.HasValue ? new SolidColorBrush(Color.Value) : null;
+ public IBrush? BackgroundBrush => ColorEnabled ? new SolidColorBrush(Color) : null;
- public ObservableCollection Users { get; } = [];
+ public ServerUser User { get; set; } = new();
public ReactiveCommand EditCommand { get; }
@@ -46,9 +61,22 @@ public class ServerConfiguration : ReactiveObject
{
EditCommand = ReactiveCommand.Create(() =>
{
- EditServerConfigurationWindow window = new() { DataContext = this };
+ EditServerConfigurationWindow window = new() { DataContext = this, New = false };
window.Show();
});
}
+
+ public ServerConfiguration(ServerConfiguration src)
+ : this()
+ {
+ Color = src.Color;
+ ColorEnabled = src.ColorEnabled;
+ Id = src.Id;
+ Name = src.Name;
+ Port = src.Port;
+ InitialDatabase = src.InitialDatabase;
+ DefaultSslMode = src.DefaultSslMode;
+ User = src.User;
+ }
}
diff --git a/pgLabII/ViewModels/ServerUser.cs b/pgLabII/Model/ServerUser.cs
similarity index 51%
rename from pgLabII/ViewModels/ServerUser.cs
rename to pgLabII/Model/ServerUser.cs
index d7742f9..c8d4574 100644
--- a/pgLabII/ViewModels/ServerUser.cs
+++ b/pgLabII/Model/ServerUser.cs
@@ -1,11 +1,11 @@
-using Npgsql;
-using pgLabII.ViewModels;
+using System;
-namespace pgLabII.ViewModels;
+namespace pgLabII.Model;
public class ServerUser : ViewModelBase
{
+ public Guid Id { get; set; }
+ public Guid ServerConfigurationId { get; set; }
public string Name { get; set; } = "";
public string Password { get; set; } = "";
- public SslMode? SslModeOverride { get; set; }
}
diff --git a/pgLabII/ServiceCollectionExtensions.cs b/pgLabII/ServiceCollectionExtensions.cs
new file mode 100644
index 0000000..aab7efc
--- /dev/null
+++ b/pgLabII/ServiceCollectionExtensions.cs
@@ -0,0 +1,31 @@
+using Microsoft.Extensions.DependencyInjection;
+using pgLabII.Infra;
+using pgLabII.ViewModels;
+using pgLabII.Views;
+
+namespace pgLabII;
+
+internal static class ServiceCollectionExtensions
+{
+ public static void AddCommonServices(this IServiceCollection collection)
+ {
+ collection.AddTransient();
+ collection.AddTransient();
+ collection.AddTransient();
+ collection.AddScoped();
+ }
+}
+
+/*
+ * .Root(nameof(MainWindow))
+ // .Root(nameof(ServerListView))
+ .Root(nameof(MainViewModel))
+ // .Bind().As(Singleton).To()
+
+ .Root(nameof(ServerListViewModel))
+ .Bind().As(Scoped).To()
+ .Root(nameof(LocalDb))
+ // .Bind().As(Singleton).To()
+ ;
+
+*/
diff --git a/pgLabII/ViewModels/EditServerConfigurationViewModel.cs b/pgLabII/ViewModels/EditServerConfigurationViewModel.cs
new file mode 100644
index 0000000..2d27905
--- /dev/null
+++ b/pgLabII/ViewModels/EditServerConfigurationViewModel.cs
@@ -0,0 +1,33 @@
+using System.Reactive;
+using pgLabII.Model;
+using ReactiveUI;
+
+namespace pgLabII.ViewModels;
+
+public class EditServerConfigurationViewModel : ViewModelBase
+{
+ public ServerConfiguration Configuration { get; set; }
+
+ public ReactiveCommand SaveAndCloseCommand { get; }
+ public ReactiveCommand CloseCommand { get; }
+
+ public EditServerConfigurationViewModel()
+ {
+ Configuration = new();
+
+ SaveAndCloseCommand = ReactiveCommand.Create(() =>
+ {
+ });
+ CloseCommand = ReactiveCommand.Create(() =>
+ {
+ });
+ }
+
+ public EditServerConfigurationViewModel(ServerConfiguration configuration)
+ : this()
+ {
+ Configuration = configuration;
+ }
+
+
+}
diff --git a/pgLabII/ViewModels/MainViewModel.cs b/pgLabII/ViewModels/MainViewModel.cs
index 20eb607..bf3e70f 100644
--- a/pgLabII/ViewModels/MainViewModel.cs
+++ b/pgLabII/ViewModels/MainViewModel.cs
@@ -1,4 +1,7 @@
+using System;
+using Microsoft.Extensions.DependencyInjection;
+
namespace pgLabII.ViewModels;
public class MainViewModel : ViewModelBase
diff --git a/pgLabII/ViewModels/ServerListViewModel.cs b/pgLabII/ViewModels/ServerListViewModel.cs
index 1837fd0..562159b 100644
--- a/pgLabII/ViewModels/ServerListViewModel.cs
+++ b/pgLabII/ViewModels/ServerListViewModel.cs
@@ -1,10 +1,9 @@
-using System;
-using System.Collections.ObjectModel;
-using System.Linq;
+using System.Collections.ObjectModel;
using ReactiveUI;
using System.Reactive;
using Avalonia.Media;
-using DynamicData;
+using pgLabII.Views;
+using pgLabII.Model;
namespace pgLabII.ViewModels;
@@ -14,19 +13,28 @@ public class ServerListViewModel : ViewModelBase
[
new ServerConfiguration()
{
- Name = "Foo",
+ Name = "Local pg15",
Color = Colors.Aquamarine,
- Host = "db.host.nl"
+ ColorEnabled = true,
+ Host = "localhost",
+ Port = 5434,
+ User = new ()
+ {
+ Name = "postgres",
+ Password = "admin",
+ },
},
new ServerConfiguration()
{
Name = "Bar",
- Color = Colors.Bisque,
+ ColorEnabled = false,
Host = "db.host.nl"
}
];
public ReactiveCommand RemoveServerCommand { get; }
+
+ public ReactiveCommand AddServerCommand { get; }
public ServerListViewModel()
{
@@ -35,5 +43,12 @@ public class ServerListViewModel : ViewModelBase
ServerConfigurations.Remove(sc);
return Unit.Default;
});
+
+ AddServerCommand = ReactiveCommand.Create(() =>
+ {
+ ServerConfiguration sc = new();
+ EditServerConfigurationWindow window = new() { DataContext = sc, New = true };
+ window.Show();
+ });
}
}
diff --git a/pgLabII/ViewModels/ServerViewModel.cs b/pgLabII/ViewModels/ServerViewModel.cs
new file mode 100644
index 0000000..315fa8f
--- /dev/null
+++ b/pgLabII/ViewModels/ServerViewModel.cs
@@ -0,0 +1,9 @@
+namespace pgLabII.ViewModels;
+
+///
+/// Toplevel viewmodel for the global resources of a postgresql installation.
+///
+public class ServerViewModel : ViewModelBase
+{
+
+}
diff --git a/pgLabII/Views/DatabaseListView.axaml b/pgLabII/Views/DatabaseListView.axaml
new file mode 100644
index 0000000..2325a9e
--- /dev/null
+++ b/pgLabII/Views/DatabaseListView.axaml
@@ -0,0 +1,8 @@
+
+ Welcome to Avalonia!
+
diff --git a/pgLabII/Views/DatabaseListView.axaml.cs b/pgLabII/Views/DatabaseListView.axaml.cs
new file mode 100644
index 0000000..462dea5
--- /dev/null
+++ b/pgLabII/Views/DatabaseListView.axaml.cs
@@ -0,0 +1,14 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace pgLabII.Views;
+
+public partial class DatabaseListView : UserControl
+{
+ public DatabaseListView()
+ {
+ InitializeComponent();
+ }
+}
+
diff --git a/pgLabII/Views/EditServerConfigurationWindow.axaml b/pgLabII/Views/EditServerConfigurationWindow.axaml
index 3a004df..5694da0 100644
--- a/pgLabII/Views/EditServerConfigurationWindow.axaml
+++ b/pgLabII/Views/EditServerConfigurationWindow.axaml
@@ -4,26 +4,28 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
xmlns:vm="clr-namespace:pgLabII.ViewModels"
- x:DataType="vm:ServerConfiguration"
+ x:DataType="vm:EditServerConfigurationViewModel"
x:Class="pgLabII.Views.EditServerConfigurationWindow"
Title="EditServerConfiguration">
-
+
Name:
-
+
Color:
-
+
+
Host:
-
+
diff --git a/pgLabII/Views/EditServerConfigurationWindow.axaml.cs b/pgLabII/Views/EditServerConfigurationWindow.axaml.cs
index 7e50771..40b17d5 100644
--- a/pgLabII/Views/EditServerConfigurationWindow.axaml.cs
+++ b/pgLabII/Views/EditServerConfigurationWindow.axaml.cs
@@ -1,6 +1,7 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
+using pgLabII.ViewModels;
namespace pgLabII.Views;
@@ -9,6 +10,11 @@ public partial class EditServerConfigurationWindow : Window
public EditServerConfigurationWindow()
{
InitializeComponent();
+
+ DataContext = new EditServerConfigurationViewModel(
+ new());
}
+
+ public bool New { get; set; }
}
diff --git a/pgLabII/Views/MainView.axaml b/pgLabII/Views/MainView.axaml
index 0836b10..b9ccb74 100644
--- a/pgLabII/Views/MainView.axaml
+++ b/pgLabII/Views/MainView.axaml
@@ -7,9 +7,19 @@
xmlns:app="clr-namespace:pgLabII"
DataContext="{StaticResource Composition}"
x:Class="pgLabII.Views.MainView"
- x:DataType="app:Composition">
-
-
+ x:DataType="vm:MainViewModel">
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pgLabII/Views/MainWindow.axaml.cs b/pgLabII/Views/MainWindow.axaml.cs
index f085ff6..a07b870 100644
--- a/pgLabII/Views/MainWindow.axaml.cs
+++ b/pgLabII/Views/MainWindow.axaml.cs
@@ -1,11 +1,13 @@
-using Avalonia.Controls;
+using Avalonia.Controls;
+using pgLabII.ViewModels;
namespace pgLabII.Views;
public partial class MainWindow : Window
{
- public MainWindow()
+ public MainWindow(ServerListViewModel model)
{
+ DataContext = model;
InitializeComponent();
}
-}
\ No newline at end of file
+}
diff --git a/pgLabII/Views/ServerListView.axaml b/pgLabII/Views/ServerListView.axaml
index e3c2319..211c3f3 100644
--- a/pgLabII/Views/ServerListView.axaml
+++ b/pgLabII/Views/ServerListView.axaml
@@ -6,55 +6,61 @@
xmlns:vm="clr-namespace:pgLabII.ViewModels"
xmlns:app="clr-namespace:pgLabII"
DataContext="{StaticResource Composition}"
- x:DataType="app:Composition"
+ x:DataType="vm:ServerListViewModel"
x:Class="pgLabII.Views.ServerListView">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pgLabII/Views/ServerListView.axaml.cs b/pgLabII/Views/ServerListView.axaml.cs
index d4a80df..d2d8eeb 100644
--- a/pgLabII/Views/ServerListView.axaml.cs
+++ b/pgLabII/Views/ServerListView.axaml.cs
@@ -1,6 +1,5 @@
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Markup.Xaml;
+using Avalonia.Controls;
+using pgLabII.ViewModels;
namespace pgLabII.Views;
@@ -8,6 +7,8 @@ public partial class ServerListView : UserControl
{
public ServerListView()
{
+ //DataContext = new ServerListViewModel();
+
InitializeComponent();
}
}
diff --git a/pgLabII/Views/ServerWindow.axaml b/pgLabII/Views/ServerWindow.axaml
new file mode 100644
index 0000000..9f1a78c
--- /dev/null
+++ b/pgLabII/Views/ServerWindow.axaml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/pgLabII/Views/ServerWindow.axaml.cs b/pgLabII/Views/ServerWindow.axaml.cs
new file mode 100644
index 0000000..a754f5b
--- /dev/null
+++ b/pgLabII/Views/ServerWindow.axaml.cs
@@ -0,0 +1,14 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace pgLabII.Views;
+
+public partial class ServerWindow : Window
+{
+ public ServerWindow()
+ {
+ InitializeComponent();
+ }
+}
+
diff --git a/pgLabII/pgLabII.csproj b/pgLabII/pgLabII.csproj
index e370bf8..610a935 100644
--- a/pgLabII/pgLabII.csproj
+++ b/pgLabII/pgLabII.csproj
@@ -12,6 +12,7 @@
+
@@ -20,16 +21,16 @@
All
-
-
-
- all
+
runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
-