Files
Sharepoint-Toolbox/SharepointToolbox/ViewModels/ProfileManagementViewModel.cs
Dev 5920d42614 feat(01-06): build WPF shell — MainWindow XAML, ViewModels, LogPanelSink wiring
- Add FeatureTabBase UserControl with ProgressBar/TextBlock/CancelButton strip
  (Visibility bound to IsRunning, shown only during operations)
- Add MainWindowViewModel with TenantProfiles ObservableCollection, ConnectCommand,
  ClearSessionCommand, ManageProfilesCommand, ProgressUpdatedMessage subscription
- Add ProfileManagementViewModel wrapping ProfileService CRUD with input validation
- Add SettingsViewModel (extends FeatureViewModelBase) with language/folder settings
- Update MainWindow.xaml: DockPanel shell with Toolbar, TabControl (8 tabs), 150px
  RichTextBox LogPanel, StatusBar (tenant name | ProgressStatus | ProgressPercentage)
- MainWindow.xaml.cs: DI constructor, DataContext=viewModel, LoadProfilesAsync on Loaded
- App.xaml.cs: register all services, wire LogPanelSink after MainWindow resolved,
  register DispatcherUnhandledException and UnobservedTaskException global handlers
- App.xaml: add BoolToVisibilityConverter resource
2026-04-02 12:32:41 +02:00

126 lines
3.7 KiB
C#

using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.Extensions.Logging;
using SharepointToolbox.Core.Models;
using SharepointToolbox.Services;
namespace SharepointToolbox.ViewModels;
public partial class ProfileManagementViewModel : ObservableObject
{
private readonly ProfileService _profileService;
private readonly ILogger<ProfileManagementViewModel> _logger;
[ObservableProperty]
private TenantProfile? _selectedProfile;
[ObservableProperty]
private string _newName = string.Empty;
[ObservableProperty]
private string _newTenantUrl = string.Empty;
[ObservableProperty]
private string _newClientId = string.Empty;
[ObservableProperty]
private string _validationMessage = string.Empty;
public ObservableCollection<TenantProfile> Profiles { get; } = new();
public IAsyncRelayCommand AddCommand { get; }
public IAsyncRelayCommand RenameCommand { get; }
public IAsyncRelayCommand DeleteCommand { get; }
public ProfileManagementViewModel(ProfileService profileService, ILogger<ProfileManagementViewModel> logger)
{
_profileService = profileService;
_logger = logger;
AddCommand = new AsyncRelayCommand(AddAsync, CanAdd);
RenameCommand = new AsyncRelayCommand(RenameAsync, () => SelectedProfile != null && !string.IsNullOrWhiteSpace(NewName));
DeleteCommand = new AsyncRelayCommand(DeleteAsync, () => SelectedProfile != null);
}
public async Task LoadAsync()
{
try
{
var profiles = await _profileService.GetProfilesAsync();
Profiles.Clear();
foreach (var p in profiles)
Profiles.Add(p);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to load profiles.");
}
}
private bool CanAdd()
{
if (string.IsNullOrWhiteSpace(NewName)) return false;
if (!Uri.TryCreate(NewTenantUrl, UriKind.Absolute, out _)) return false;
if (string.IsNullOrWhiteSpace(NewClientId)) return false;
return true;
}
private async Task AddAsync()
{
if (!CanAdd()) return;
try
{
var profile = new TenantProfile
{
Name = NewName.Trim(),
TenantUrl = NewTenantUrl.Trim(),
ClientId = NewClientId.Trim()
};
await _profileService.AddProfileAsync(profile);
Profiles.Add(profile);
NewName = string.Empty;
NewTenantUrl = string.Empty;
NewClientId = string.Empty;
ValidationMessage = string.Empty;
}
catch (Exception ex)
{
ValidationMessage = ex.Message;
_logger.LogError(ex, "Failed to add profile.");
}
}
private async Task RenameAsync()
{
if (SelectedProfile == null || string.IsNullOrWhiteSpace(NewName)) return;
try
{
await _profileService.RenameProfileAsync(SelectedProfile.Name, NewName.Trim());
SelectedProfile.Name = NewName.Trim();
NewName = string.Empty;
}
catch (Exception ex)
{
ValidationMessage = ex.Message;
_logger.LogError(ex, "Failed to rename profile.");
}
}
private async Task DeleteAsync()
{
if (SelectedProfile == null) return;
try
{
await _profileService.DeleteProfileAsync(SelectedProfile.Name);
Profiles.Remove(SelectedProfile);
SelectedProfile = null;
}
catch (Exception ex)
{
ValidationMessage = ex.Message;
_logger.LogError(ex, "Failed to delete profile.");
}
}
}