feat(configmanager): wire up form selection in MainWindowViewModel
- Add IFileSystem and IDialogService dependencies to constructor - Implement OnSelectedNodeChanged to create appropriate form ViewModels - Add LoadConfigForTesting helper for unit testing - Add MarkAsChanged helper to track unsaved changes - Update OpenFolderAsync to use IDialogService - Add comprehensive unit tests for form selection
This commit is contained in:
@@ -3,6 +3,7 @@ using System.Windows.Input;
|
||||
using Avalonia.Media;
|
||||
using JdeScoping.ConfigManager.Models;
|
||||
using JdeScoping.ConfigManager.Services;
|
||||
using JdeScoping.ConfigManager.ViewModels.Forms;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace JdeScoping.ConfigManager.ViewModels;
|
||||
@@ -12,10 +13,12 @@ namespace JdeScoping.ConfigManager.ViewModels;
|
||||
/// </summary>
|
||||
public class MainWindowViewModel : ViewModelBase
|
||||
{
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly IConfigFileService _configFileService;
|
||||
private readonly IValidationService _validationService;
|
||||
private readonly IBackupService _backupService;
|
||||
private readonly IAutoDiscoveryService _autoDiscoveryService;
|
||||
private readonly IDialogService? _dialogService;
|
||||
private readonly ILogger<MainWindowViewModel>? _logger;
|
||||
|
||||
private string _configFolderPath = "No folder selected";
|
||||
@@ -28,30 +31,45 @@ public class MainWindowViewModel : ViewModelBase
|
||||
private ConfigModel? _appSettings;
|
||||
private PipelinesConfigModel? _pipelines;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the currently loaded configuration folder path.
|
||||
/// </summary>
|
||||
public string ConfigFolderPath
|
||||
{
|
||||
get => _configFolderPath;
|
||||
set => SetProperty(ref _configFolderPath, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether there are unsaved configuration changes.
|
||||
/// </summary>
|
||||
public bool HasUnsavedChanges
|
||||
{
|
||||
get => _hasUnsavedChanges;
|
||||
set => SetProperty(ref _hasUnsavedChanges, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the validation status message displayed to the user.
|
||||
/// </summary>
|
||||
public string ValidationStatus
|
||||
{
|
||||
get => _validationStatus;
|
||||
set => SetProperty(ref _validationStatus, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the brush color for the validation status indicator.
|
||||
/// </summary>
|
||||
public IBrush ValidationStatusColor
|
||||
{
|
||||
get => _validationStatusColor;
|
||||
set => SetProperty(ref _validationStatusColor, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the currently selected tree node in the configuration tree view.
|
||||
/// </summary>
|
||||
public TreeNodeViewModel? SelectedNode
|
||||
{
|
||||
get => _selectedNode;
|
||||
@@ -62,33 +80,80 @@ public class MainWindowViewModel : ViewModelBase
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the view model for the form displayed when a node is selected.
|
||||
/// </summary>
|
||||
public object? SelectedFormViewModel
|
||||
{
|
||||
get => _selectedFormViewModel;
|
||||
set => SetProperty(ref _selectedFormViewModel, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of tree nodes representing the configuration structure.
|
||||
/// </summary>
|
||||
public ObservableCollection<TreeNodeViewModel> TreeNodes { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the command for opening a configuration folder.
|
||||
/// </summary>
|
||||
public ICommand OpenFolderCommand { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the command for saving configuration changes.
|
||||
/// </summary>
|
||||
public ICommand SaveCommand { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the command for exiting the application.
|
||||
/// </summary>
|
||||
public ICommand ExitCommand { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the command for undoing the last configuration change.
|
||||
/// </summary>
|
||||
public ICommand UndoCommand { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the command for redoing the last undone configuration change.
|
||||
/// </summary>
|
||||
public ICommand RedoCommand { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the command for validating the current configuration.
|
||||
/// </summary>
|
||||
public ICommand ValidateCommand { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the command for testing database connections.
|
||||
/// </summary>
|
||||
public ICommand TestConnectionCommand { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MainWindowViewModel"/> class.
|
||||
/// </summary>
|
||||
/// <param name="fileSystem">File system abstraction for I/O operations.</param>
|
||||
/// <param name="configFileService">Service for loading and saving configuration files.</param>
|
||||
/// <param name="validationService">Service for validating configuration settings.</param>
|
||||
/// <param name="backupService">Service for creating configuration backups.</param>
|
||||
/// <param name="autoDiscoveryService">Service for discovering configuration folder locations.</param>
|
||||
/// <param name="dialogService">Service for showing platform dialogs.</param>
|
||||
/// <param name="logger">Optional logger for recording view model activities.</param>
|
||||
public MainWindowViewModel(
|
||||
IFileSystem fileSystem,
|
||||
IConfigFileService configFileService,
|
||||
IValidationService validationService,
|
||||
IBackupService backupService,
|
||||
IAutoDiscoveryService autoDiscoveryService,
|
||||
IDialogService? dialogService,
|
||||
ILogger<MainWindowViewModel>? logger)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
_configFileService = configFileService;
|
||||
_validationService = validationService;
|
||||
_backupService = backupService;
|
||||
_autoDiscoveryService = autoDiscoveryService;
|
||||
_dialogService = dialogService;
|
||||
_logger = logger;
|
||||
|
||||
OpenFolderCommand = new AsyncRelayCommand(OpenFolderAsync);
|
||||
@@ -106,10 +171,12 @@ public class MainWindowViewModel : ViewModelBase
|
||||
/// Design-time constructor for XAML previewer.
|
||||
/// </summary>
|
||||
public MainWindowViewModel() : this(
|
||||
new FileSystem(),
|
||||
new ConfigFileService(new FileSystem()),
|
||||
new ValidationService(),
|
||||
new BackupService(new FileSystem()),
|
||||
new AutoDiscoveryService(new FileSystem()),
|
||||
null,
|
||||
null)
|
||||
{
|
||||
}
|
||||
@@ -131,9 +198,17 @@ public class MainWindowViewModel : ViewModelBase
|
||||
/// </summary>
|
||||
private async Task OpenFolderAsync()
|
||||
{
|
||||
// TODO: Show folder picker dialog
|
||||
_logger?.LogInformation("Open folder requested");
|
||||
await Task.CompletedTask;
|
||||
if (_dialogService == null)
|
||||
{
|
||||
_logger?.LogWarning("Dialog service is not available");
|
||||
return;
|
||||
}
|
||||
|
||||
var folder = await _dialogService.ShowFolderPickerAsync("Select Configuration Folder");
|
||||
if (folder != null)
|
||||
{
|
||||
await LoadConfigAsync(folder);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -201,8 +276,48 @@ public class MainWindowViewModel : ViewModelBase
|
||||
/// </summary>
|
||||
private void OnSelectedNodeChanged()
|
||||
{
|
||||
// TODO: Load appropriate form ViewModel based on selected node
|
||||
SelectedFormViewModel = null;
|
||||
if (_selectedNode == null || _appSettings == null)
|
||||
{
|
||||
SelectedFormViewModel = null;
|
||||
return;
|
||||
}
|
||||
|
||||
SelectedFormViewModel = _selectedNode.SectionKey switch
|
||||
{
|
||||
"DataSync" => new DataSyncFormViewModel(_appSettings.DataSync, MarkAsChanged),
|
||||
"DataAccess" => new DataAccessFormViewModel(_appSettings.DataAccess, MarkAsChanged),
|
||||
"Auth" => new AuthFormViewModel(_appSettings.Auth, MarkAsChanged),
|
||||
"Ldap" => new LdapFormViewModel(_appSettings.Ldap, MarkAsChanged),
|
||||
"Search" => new SearchFormViewModel(_appSettings.Search, MarkAsChanged),
|
||||
"ExcelExport" => new ExcelExportFormViewModel(_appSettings.ExcelExport, MarkAsChanged),
|
||||
_ when _selectedNode.NodeType == TreeNodeType.Pipeline && _pipelines != null
|
||||
=> _pipelines.Pipelines.TryGetValue(_selectedNode.SectionKey!, out var pipeline)
|
||||
? new PipelineFormViewModel(_selectedNode.SectionKey!, pipeline, MarkAsChanged)
|
||||
: null,
|
||||
_ => null
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Marks the configuration as having unsaved changes.
|
||||
/// </summary>
|
||||
private void MarkAsChanged()
|
||||
{
|
||||
HasUnsavedChanges = true;
|
||||
if (_selectedNode != null)
|
||||
_selectedNode.IsModified = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads configuration for testing purposes.
|
||||
/// </summary>
|
||||
/// <param name="appSettings">The application settings configuration model.</param>
|
||||
/// <param name="pipelines">The pipelines configuration model.</param>
|
||||
public void LoadConfigForTesting(ConfigModel? appSettings, PipelinesConfigModel? pipelines)
|
||||
{
|
||||
_appSettings = appSettings;
|
||||
_pipelines = pipelines;
|
||||
BuildTreeNodes();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user