From 4b8a346cfb4499d3d0ecabba9b0b417a6d700725 Mon Sep 17 00:00:00 2001 From: eelke Date: Sun, 26 Oct 2025 17:13:31 +0100 Subject: [PATCH] Server configuration list in DataGrid. Sorting already works out of the box. --- .../ConnectionStringService.cs | 2 +- .../IConnectionStringService.cs | 4 +- pgLabII/Migrations/LocalDbModelSnapshot.cs | 6 +- pgLabII/Model/ServerConfigurationEntity.cs | 3 +- .../EditServerConfigurationViewModel.cs | 6 +- .../ServerConfigurationViewModel.cs | 16 ++-- pgLabII/ViewModels/ServerListViewModel.cs | 45 +++++++++-- .../EditServerConfigurationWindow.axaml.cs | 1 - pgLabII/Views/ServerListView.axaml | 79 +++++++------------ 9 files changed, 87 insertions(+), 75 deletions(-) diff --git a/pgLabII.PgUtils/ConnectionStrings/ConnectionStringService.cs b/pgLabII.PgUtils/ConnectionStrings/ConnectionStringService.cs index 746d908..9c34546 100644 --- a/pgLabII.PgUtils/ConnectionStrings/ConnectionStringService.cs +++ b/pgLabII.PgUtils/ConnectionStrings/ConnectionStringService.cs @@ -23,7 +23,7 @@ public sealed class ConnectionStringService : IConnectionStringService public static ConnectionStringService CreateDefault() => new(new IConnectionStringCodec[] { new LibpqCodec(), new NpgsqlCodec(), new UrlCodec(), new JdbcCodec() }); - public Result DetectFormat(string input) + public Result DetectFormat(string? input) { if (string.IsNullOrWhiteSpace(input)) return Result.Fail("Empty input"); diff --git a/pgLabII.PgUtils/ConnectionStrings/IConnectionStringService.cs b/pgLabII.PgUtils/ConnectionStrings/IConnectionStringService.cs index fb6f04d..0a69e60 100644 --- a/pgLabII.PgUtils/ConnectionStrings/IConnectionStringService.cs +++ b/pgLabII.PgUtils/ConnectionStrings/IConnectionStringService.cs @@ -8,11 +8,11 @@ namespace pgLabII.PgUtils.ConnectionStrings; /// public interface IConnectionStringService { - Result DetectFormat(string input); + Result DetectFormat(string? input); Result ParseToDescriptor(string input); Result FormatFromDescriptor(ConnectionDescriptor descriptor, ConnStringFormat targetFormat); Result Convert(string input, ConnStringFormat targetFormat); -} \ No newline at end of file +} diff --git a/pgLabII/Migrations/LocalDbModelSnapshot.cs b/pgLabII/Migrations/LocalDbModelSnapshot.cs index c860147..a96a8c7 100644 --- a/pgLabII/Migrations/LocalDbModelSnapshot.cs +++ b/pgLabII/Migrations/LocalDbModelSnapshot.cs @@ -39,7 +39,7 @@ namespace pgLabII.Migrations b.HasKey("Id"); - b.ToTable("Documents"); + b.ToTable("Documents", (string)null); }); modelBuilder.Entity("pgLabII.Model.EditHistoryEntry", b => @@ -69,7 +69,7 @@ namespace pgLabII.Migrations b.HasIndex("DocumentId", "Timestamp"); - b.ToTable("EditHistory"); + b.ToTable("EditHistory", (string)null); }); modelBuilder.Entity("pgLabII.Model.ServerConfigurationEntity", b => @@ -112,7 +112,7 @@ namespace pgLabII.Migrations b.HasKey("Id"); - b.ToTable("ServerConfigurations"); + b.ToTable("ServerConfigurations", (string)null); }); modelBuilder.Entity("pgLabII.Model.EditHistoryEntry", b => diff --git a/pgLabII/Model/ServerConfigurationEntity.cs b/pgLabII/Model/ServerConfigurationEntity.cs index 8b95fc8..22e0f02 100644 --- a/pgLabII/Model/ServerConfigurationEntity.cs +++ b/pgLabII/Model/ServerConfigurationEntity.cs @@ -14,6 +14,5 @@ public class ServerConfigurationEntity public bool ColorEnabled { get; set; } = true; public int ColorArgb { get; set; } = unchecked((int)0xFF_33_33_33); // default dark gray public string UserName { get; set; } = ""; - - public string Password { get; set; } = ""; + public string Password { get; set; } = ""; } diff --git a/pgLabII/ViewModels/EditServerConfigurationViewModel.cs b/pgLabII/ViewModels/EditServerConfigurationViewModel.cs index 30c1116..5c59a7d 100644 --- a/pgLabII/ViewModels/EditServerConfigurationViewModel.cs +++ b/pgLabII/ViewModels/EditServerConfigurationViewModel.cs @@ -28,14 +28,14 @@ public partial class EditServerConfigurationViewModel : ViewModelBase public ServerConfigurationViewModel Configuration { get; set; } // Connection string IO - [Reactive] public partial string InputConnectionString { get; set; } + [Reactive] public partial string? InputConnectionString { get; set; } [Reactive] public partial ForcedFormatOption ForcedFormat { get; set; } [ObservableAsProperty] private ConnStringFormat? _detectedFormat; [Reactive] public partial ConnStringFormat OutputFormat { get; set; } - [Reactive] public partial string OutputConnectionString { get; set; } + [Reactive] public partial string? OutputConnectionString { get; set; } public ReactiveCommand ParseConnectionStringCommand { get; } public ReactiveCommand GenerateConnectionStringCommand { get; } @@ -69,7 +69,7 @@ public partial class EditServerConfigurationViewModel : ViewModelBase InitializeFromCopy(); } - private ConnStringFormat? DetectFormat(ForcedFormatOption format, string input) + private ConnStringFormat? DetectFormat(ForcedFormatOption format, string? input) { if (format != ForcedFormatOption.Auto) return null; diff --git a/pgLabII/ViewModels/ServerConfigurationViewModel.cs b/pgLabII/ViewModels/ServerConfigurationViewModel.cs index 2065b57..de313f8 100644 --- a/pgLabII/ViewModels/ServerConfigurationViewModel.cs +++ b/pgLabII/ViewModels/ServerConfigurationViewModel.cs @@ -3,11 +3,12 @@ using Avalonia.Media; using Npgsql; using pgLabII.Model; using ReactiveUI; +using ReactiveUI.SourceGenerators; namespace pgLabII.ViewModels; // UI ViewModel that wraps the persistence entity -public class ServerConfigurationViewModel : ReactiveObject +public partial class ServerConfigurationViewModel : ReactiveObject { private readonly ServerConfigurationEntity _entity; @@ -16,7 +17,7 @@ public class ServerConfigurationViewModel : ReactiveObject _entity = entity ?? throw new ArgumentNullException(nameof(entity)); EditCommand = ReactiveCommand.Create(() => { - var window = new Views.EditServerConfigurationWindow(new(this)) { New = false }; + var window = new Views.EditServerConfigurationWindow(new(this)); window.Show(); }); ExploreCommand = ReactiveCommand.Create(() => @@ -24,6 +25,10 @@ public class ServerConfigurationViewModel : ReactiveObject var window = new Views.SingleDatabaseWindow(entity); window.Show(); }); + + _backgroundBrushHelper = this.WhenAnyValue(x => x.ColorEnabled, x => x.Color, + (enabled, color) => enabled ? new SolidColorBrush(color) : null) + .ToProperty(this, x => x.BackgroundBrush); } public ServerConfigurationEntity Entity => _entity; @@ -67,7 +72,7 @@ public class ServerConfigurationViewModel : ReactiveObject public bool ColorEnabled { get => _entity.ColorEnabled; - set { if (_entity.ColorEnabled != value) { _entity.ColorEnabled = value; this.RaisePropertyChanged(); this.RaisePropertyChanged(nameof(BackgroundBrush)); } } + set { if (_entity.ColorEnabled != value) { _entity.ColorEnabled = value; this.RaisePropertyChanged(); } } } public Color Color @@ -80,12 +85,12 @@ public class ServerConfigurationViewModel : ReactiveObject { _entity.ColorArgb = argb; this.RaisePropertyChanged(); - this.RaisePropertyChanged(nameof(BackgroundBrush)); } } } - public IBrush? BackgroundBrush => ColorEnabled ? new SolidColorBrush(Color) : null; + //public IBrush? BackgroundBrush => ColorEnabled ? new SolidColorBrush(Color) : null; + [ObservableAsProperty] private IBrush? _backgroundBrush; public string UserName { @@ -115,6 +120,7 @@ public class ServerConfigurationViewModel : ReactiveObject } } + public ReactiveCommand EditCommand { get; } public ReactiveCommand ExploreCommand { get; } diff --git a/pgLabII/ViewModels/ServerListViewModel.cs b/pgLabII/ViewModels/ServerListViewModel.cs index 8319ed0..a8cbf0d 100644 --- a/pgLabII/ViewModels/ServerListViewModel.cs +++ b/pgLabII/ViewModels/ServerListViewModel.cs @@ -3,11 +3,14 @@ using ReactiveUI; using System.Reactive; using Avalonia.Media; using pgLabII.Views; +using ReactiveUI.SourceGenerators; namespace pgLabII.ViewModels; -public class ServerListViewModel : ViewModelBase +public partial class ServerListViewModel : ViewModelBase { + [Reactive] public partial ServerConfigurationViewModel? SelectedServerConfiguration { get; set; } + public ObservableCollection ServerConfigurations { get; } = [ new (new() @@ -18,7 +21,7 @@ public class ServerListViewModel : ViewModelBase Port = 5418, InitialDatabase = "postgres", UserName = "postgres", - Password = "admin", + Password = "admin" }) { Color = Colors.Aquamarine, @@ -31,22 +34,48 @@ public class ServerListViewModel : ViewModelBase }), ]; - public ReactiveCommand RemoveServerCommand { get; } - + public ReactiveCommand ExploreServerCommand { get; } + public ReactiveCommand EditServerCommand { get; } + public ReactiveCommand RemoveServerCommand { get; } public ReactiveCommand AddServerCommand { get; } public ServerListViewModel() { - RemoveServerCommand = ReactiveCommand.Create((sc) => + ExploreServerCommand = ReactiveCommand.Create((sc) => { - ServerConfigurations.Remove(sc); + var conf = sc ?? SelectedServerConfiguration; + if (conf is null) + return Unit.Default; + + var window = new Views.SingleDatabaseWindow(conf.Entity); + window.Show(); + return Unit.Default; + }); + + EditServerCommand = ReactiveCommand.Create((sc) => + { + var conf = sc ?? SelectedServerConfiguration; + if (conf is null) + return Unit.Default; + + EditServerConfigurationWindow window = new(new(conf)); + window.Show(); + return Unit.Default; + }); + + RemoveServerCommand = ReactiveCommand.Create((sc) => + { + var conf = sc ?? SelectedServerConfiguration; + if (conf is null) + return Unit.Default; + + ServerConfigurations.Remove(conf); return Unit.Default; }); AddServerCommand = ReactiveCommand.Create(() => { - EditServerConfigurationViewModel vm = new(); - EditServerConfigurationWindow window = new() { DataContext = vm, New = true }; + EditServerConfigurationWindow window = new(new()); window.Show(); }); } diff --git a/pgLabII/Views/EditServerConfigurationWindow.axaml.cs b/pgLabII/Views/EditServerConfigurationWindow.axaml.cs index 73135bf..5634cd3 100644 --- a/pgLabII/Views/EditServerConfigurationWindow.axaml.cs +++ b/pgLabII/Views/EditServerConfigurationWindow.axaml.cs @@ -32,6 +32,5 @@ public partial class EditServerConfigurationWindow : ReactiveWindow - - - - - - - - - - + \ No newline at end of file