diff --git a/pgLabII/ViewModels/EditServerConfigurationViewModel.cs b/pgLabII/ViewModels/EditServerConfigurationViewModel.cs index 42108fe..30c1116 100644 --- a/pgLabII/ViewModels/EditServerConfigurationViewModel.cs +++ b/pgLabII/ViewModels/EditServerConfigurationViewModel.cs @@ -1,35 +1,18 @@ -using System; -using System.Linq; -using System.Reactive; +using System.Reactive; using System.Reactive.Linq; -using Npgsql; using pgLabII.Model; using pgLabII.PgUtils.ConnectionStrings; using pgLabII.Services; using ReactiveUI; +using ReactiveUI.SourceGenerators; namespace pgLabII.ViewModels; -public class EditServerConfigurationViewModel : ViewModelBase +public partial class EditServerConfigurationViewModel : ViewModelBase { - // Prefer new UI VM; keep old model for compatibility by wrapping when needed - public ServerConfigurationViewModel Configuration { get; set; } - - // Connection string IO - private string _inputConnectionString = string.Empty; - public string InputConnectionString - { - get => _inputConnectionString; - set - { - this.RaiseAndSetIfChanged(ref _inputConnectionString, value); - // auto-detect when input changes and we are in Auto mode - if (ForcedFormat == ForcedFormatOption.Auto) - { - DetectFormat(); - } - } - } + private readonly IConnectionStringService _service; + // Store original for reverting changes + private ServerConfigurationViewModel? _originalConfiguration; public enum ForcedFormatOption { @@ -40,50 +23,27 @@ public class EditServerConfigurationViewModel : ViewModelBase Jdbc } - private ForcedFormatOption _forcedFormat = ForcedFormatOption.Auto; - public ForcedFormatOption ForcedFormat - { - get => _forcedFormat; - set - { - this.RaiseAndSetIfChanged(ref _forcedFormat, value); - // When forcing off Auto, clear detected label; when switching to Auto, re-detect - if (value == ForcedFormatOption.Auto) - DetectFormat(); - else - DetectedFormat = null; - } - } + public Interaction CloseInteraction { get; } = new(); + // Prefer new UI VM; keep old model for compatibility by wrapping when needed + public ServerConfigurationViewModel Configuration { get; set; } + + // Connection string IO + [Reactive] public partial string InputConnectionString { get; set; } - private ConnStringFormat? _detectedFormat; - public ConnStringFormat? DetectedFormat - { - get => _detectedFormat; - private set => this.RaiseAndSetIfChanged(ref _detectedFormat, value); - } + [Reactive] public partial ForcedFormatOption ForcedFormat { get; set; } - private ConnStringFormat _outputFormat = ConnStringFormat.Url; - public ConnStringFormat OutputFormat - { - get => _outputFormat; - set => this.RaiseAndSetIfChanged(ref _outputFormat, value); - } + [ObservableAsProperty] private ConnStringFormat? _detectedFormat; + [Reactive] public partial ConnStringFormat OutputFormat { get; set; } - private string _outputConnectionString = string.Empty; - public string OutputConnectionString - { - get => _outputConnectionString; - set => this.RaiseAndSetIfChanged(ref _outputConnectionString, value); - } + [Reactive] public partial string OutputConnectionString { get; set; } public ReactiveCommand ParseConnectionStringCommand { get; } public ReactiveCommand GenerateConnectionStringCommand { get; } public ReactiveCommand CopyOutputConnectionStringCommand { get; } - public ReactiveCommand SaveAndCloseCommand { get; } - public ReactiveCommand CloseCommand { get; } + public ReactiveCommand SaveCommand { get; } + public ReactiveCommand RevertCommand { get; } - private readonly IConnectionStringService _service; public EditServerConfigurationViewModel() { @@ -94,25 +54,31 @@ public class EditServerConfigurationViewModel : ViewModelBase GenerateConnectionStringCommand = ReactiveCommand.Create(GenerateConnectionString); CopyOutputConnectionStringCommand = ReactiveCommand.Create(() => { /* no-op placeholder */ }); - SaveAndCloseCommand = ReactiveCommand.Create(() => { }); - CloseCommand = ReactiveCommand.Create(() => { }); + SaveCommand = ReactiveCommand.CreateFromTask(Save); + RevertCommand = ReactiveCommand.CreateFromTask(Revert); + + _detectedFormatHelper = this.WhenAnyValue(x => x.ForcedFormat, x => x.InputConnectionString, + DetectFormat) + .ToProperty(this, x => x.DetectedFormat); } public EditServerConfigurationViewModel(ServerConfigurationViewModel configuration) : this() { Configuration = configuration; + InitializeFromCopy(); } - private void DetectFormat() + private ConnStringFormat? DetectFormat(ForcedFormatOption format, string input) { - if (string.IsNullOrWhiteSpace(InputConnectionString)) - { - DetectedFormat = null; - return; - } + if (format != ForcedFormatOption.Auto) + return null; + + if (string.IsNullOrWhiteSpace(input)) + return null; + var res = _service.DetectFormat(InputConnectionString); - DetectedFormat = res.IsSuccess ? res.Value : null; + return res.IsSuccess ? res.Value : null; } private void ParseConnectionString() @@ -173,4 +139,73 @@ public class EditServerConfigurationViewModel : ViewModelBase if (r.IsSuccess) OutputConnectionString = r.Value; } + + /// + /// Creates a deep copy of the configuration for editing. + /// This ensures changes are isolated until Save is called. + /// + private void InitializeFromCopy() + { + _originalConfiguration = Configuration; + + // Create a copy of the entity + var copiedEntity = new ServerConfigurationEntity + { + Id = _originalConfiguration.Entity.Id, + Name = _originalConfiguration.Entity.Name, + Host = _originalConfiguration.Entity.Host, + Port = _originalConfiguration.Entity.Port, + InitialDatabase = _originalConfiguration.Entity.InitialDatabase, + SslMode = _originalConfiguration.Entity.SslMode, + ColorEnabled = _originalConfiguration.Entity.ColorEnabled, + ColorArgb = _originalConfiguration.Entity.ColorArgb, + UserName = _originalConfiguration.Entity.UserName, + Password = _originalConfiguration.Entity.Password + }; + + // Create a new ViewModel wrapping the copied entity + Configuration = new ServerConfigurationViewModel(copiedEntity); + } + + /// + /// Copies changes from the edited configuration back to the original. + /// + private async Task Save() + { + if (_originalConfiguration == null) return; + + // Copy all properties from the edited configuration back to the original + _originalConfiguration.Name = Configuration.Name; + _originalConfiguration.Host = Configuration.Host; + _originalConfiguration.Port = Configuration.Port; + _originalConfiguration.InitialDatabase = Configuration.InitialDatabase; + _originalConfiguration.DefaultSslMode = Configuration.DefaultSslMode; + _originalConfiguration.ColorEnabled = Configuration.ColorEnabled; + _originalConfiguration.Color = Configuration.Color; + _originalConfiguration.UserName = Configuration.UserName; + _originalConfiguration.Password = Configuration.Password; + + await CloseInteraction.Handle(true); + } + + /// + /// Reverts to the original configuration, discarding all changes. + /// + private async Task Revert() + { + if (_originalConfiguration == null) return; + + // Copy all properties from the original back to the working configuration + Configuration.Name = _originalConfiguration.Name; + Configuration.Host = _originalConfiguration.Host; + Configuration.Port = _originalConfiguration.Port; + Configuration.InitialDatabase = _originalConfiguration.InitialDatabase; + Configuration.DefaultSslMode = _originalConfiguration.DefaultSslMode; + Configuration.ColorEnabled = _originalConfiguration.ColorEnabled; + Configuration.Color = _originalConfiguration.Color; + Configuration.UserName = _originalConfiguration.UserName; + Configuration.Password = _originalConfiguration.Password; + + await CloseInteraction.Handle(false); + } } diff --git a/pgLabII/Views/EditServerConfigurationWindow.axaml b/pgLabII/Views/EditServerConfigurationWindow.axaml index 400fc06..292e1a5 100644 --- a/pgLabII/Views/EditServerConfigurationWindow.axaml +++ b/pgLabII/Views/EditServerConfigurationWindow.axaml @@ -12,7 +12,7 @@ - + @@ -93,6 +93,10 @@ - + + +