diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/JdeScoping.ConfigManager.csproj b/NEW/src/Utils/JdeScoping.ConfigManager/JdeScoping.ConfigManager.csproj
index cb14031..073449e 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/JdeScoping.ConfigManager.csproj
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/JdeScoping.ConfigManager.csproj
@@ -17,6 +17,7 @@
+
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/AvaloniaDialogService.cs b/NEW/src/Utils/JdeScoping.ConfigManager/Services/AvaloniaDialogService.cs
new file mode 100644
index 0000000..cbd42e5
--- /dev/null
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/Services/AvaloniaDialogService.cs
@@ -0,0 +1,149 @@
+using System.Text;
+using Avalonia.Controls;
+using Avalonia.Platform.Storage;
+using MsBox.Avalonia;
+using MsBox.Avalonia.Enums;
+
+namespace JdeScoping.ConfigManager.Services;
+
+///
+/// Avalonia implementation of IDialogService using MsBox.Avalonia and platform storage.
+///
+public class AvaloniaDialogService : IDialogService
+{
+ private readonly Func _getMainWindow;
+
+ ///
+ /// Creates a new instance of AvaloniaDialogService.
+ ///
+ /// Factory function to get the main window for dialogs.
+ public AvaloniaDialogService(Func getMainWindow)
+ {
+ _getMainWindow = getMainWindow ?? throw new ArgumentNullException(nameof(getMainWindow));
+ }
+
+ ///
+ public async Task ShowFolderPickerAsync(string? title = null)
+ {
+ var window = _getMainWindow();
+ if (window == null)
+ return null;
+
+ var folders = await window.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
+ {
+ Title = title ?? "Select Folder",
+ AllowMultiple = false
+ });
+
+ return folders.Count > 0 ? folders[0].Path.LocalPath : null;
+ }
+
+ ///
+ public async Task ShowMessageAsync(string title, string message)
+ {
+ var box = MessageBoxManager.GetMessageBoxStandard(title, message, ButtonEnum.Ok, Icon.Info);
+ var window = _getMainWindow();
+ if (window != null)
+ {
+ await box.ShowWindowDialogAsync(window);
+ }
+ else
+ {
+ await box.ShowAsync();
+ }
+ }
+
+ ///
+ public async Task ShowConfirmationAsync(string title, string message)
+ {
+ var box = MessageBoxManager.GetMessageBoxStandard(title, message, ButtonEnum.YesNo, Icon.Question);
+ var window = _getMainWindow();
+ ButtonResult result;
+ if (window != null)
+ {
+ result = await box.ShowWindowDialogAsync(window);
+ }
+ else
+ {
+ result = await box.ShowAsync();
+ }
+ return result == ButtonResult.Yes;
+ }
+
+ ///
+ public async Task ShowDiffPreviewAsync(string title, DiffResult diff)
+ {
+ // Basic implementation - full diff preview dialog will be implemented in Task 22
+ if (!diff.HasChanges)
+ {
+ await ShowMessageAsync(title, "No changes detected.");
+ return false;
+ }
+
+ var summary = new StringBuilder();
+ summary.AppendLine($"Changes detected: {diff.Insertions} insertion(s), {diff.Deletions} deletion(s)");
+ summary.AppendLine();
+ summary.AppendLine("Do you want to apply these changes?");
+
+ return await ShowConfirmationAsync(title, summary.ToString());
+ }
+
+ ///
+ public async Task ShowValidationResultsAsync(ValidationResult appSettingsResult, ValidationResult pipelinesResult)
+ {
+ // Basic implementation - full validation results dialog will be implemented in Task 23
+ var message = new StringBuilder();
+
+ message.AppendLine("=== AppSettings Validation ===");
+ if (appSettingsResult.IsValid)
+ {
+ message.AppendLine("Valid");
+ }
+ else
+ {
+ foreach (var error in appSettingsResult.Errors)
+ {
+ message.AppendLine($"Error: {error}");
+ }
+ }
+ foreach (var warning in appSettingsResult.Warnings)
+ {
+ message.AppendLine($"Warning: {warning}");
+ }
+
+ message.AppendLine();
+ message.AppendLine("=== Pipelines Validation ===");
+ if (pipelinesResult.IsValid)
+ {
+ message.AppendLine("Valid");
+ }
+ else
+ {
+ foreach (var error in pipelinesResult.Errors)
+ {
+ message.AppendLine($"Error: {error}");
+ }
+ }
+ foreach (var warning in pipelinesResult.Warnings)
+ {
+ message.AppendLine($"Warning: {warning}");
+ }
+
+ var title = appSettingsResult.IsValid && pipelinesResult.IsValid
+ ? "Validation Passed"
+ : "Validation Issues Found";
+
+ var icon = appSettingsResult.IsValid && pipelinesResult.IsValid ? Icon.Success : Icon.Warning;
+
+ var box = MessageBoxManager.GetMessageBoxStandard(title, message.ToString(), ButtonEnum.Ok, icon);
+ var window = _getMainWindow();
+ if (window != null)
+ {
+ await box.ShowWindowDialogAsync(window);
+ }
+ else
+ {
+ await box.ShowAsync();
+ }
+ }
+}
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/IDialogService.cs b/NEW/src/Utils/JdeScoping.ConfigManager/Services/IDialogService.cs
new file mode 100644
index 0000000..16786f5
--- /dev/null
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/Services/IDialogService.cs
@@ -0,0 +1,45 @@
+namespace JdeScoping.ConfigManager.Services;
+
+///
+/// Abstraction for platform-specific dialog operations.
+/// Enables unit testing of view models that need to show dialogs.
+///
+public interface IDialogService
+{
+ ///
+ /// Shows a folder picker dialog.
+ ///
+ /// Optional title for the dialog.
+ /// The selected folder path, or null if cancelled.
+ Task ShowFolderPickerAsync(string? title = null);
+
+ ///
+ /// Shows a message dialog.
+ ///
+ /// The dialog title.
+ /// The message to display.
+ Task ShowMessageAsync(string title, string message);
+
+ ///
+ /// Shows a confirmation dialog with Yes/No options.
+ ///
+ /// The dialog title.
+ /// The confirmation message to display.
+ /// True if user clicked Yes, false otherwise.
+ Task ShowConfirmationAsync(string title, string message);
+
+ ///
+ /// Shows a diff preview dialog allowing the user to review changes.
+ ///
+ /// The dialog title.
+ /// The diff result to display.
+ /// True if user confirms the changes, false otherwise.
+ Task ShowDiffPreviewAsync(string title, DiffResult diff);
+
+ ///
+ /// Shows validation results for configuration files.
+ ///
+ /// Validation result for appsettings.json.
+ /// Validation result for pipelines.json.
+ Task ShowValidationResultsAsync(ValidationResult appSettingsResult, ValidationResult pipelinesResult);
+}