Fix two pre-existing blockers found during UAT: - ProfileManagementViewModel: add NotifyCanExecuteChanged on property changes - SessionManager: open browser in openBrowserCallback (was no-op) Remaining blocker: SitePickerDialog parsing error from PnP Framework. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
136 lines
4.2 KiB
C#
136 lines
4.2 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.");
|
|
}
|
|
}
|
|
|
|
partial void OnNewNameChanged(string value) => NotifyCommandsCanExecuteChanged();
|
|
partial void OnNewTenantUrlChanged(string value) => NotifyCommandsCanExecuteChanged();
|
|
partial void OnNewClientIdChanged(string value) => NotifyCommandsCanExecuteChanged();
|
|
|
|
private void NotifyCommandsCanExecuteChanged()
|
|
{
|
|
AddCommand.NotifyCanExecuteChanged();
|
|
RenameCommand.NotifyCanExecuteChanged();
|
|
}
|
|
|
|
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.");
|
|
}
|
|
}
|
|
}
|