feat(14-01): add SelectDirectoryUserCommand bridging directory to audit pipeline

- RelayCommand<GraphDirectoryUser> converts to GraphUserResult and adds to SelectedUsers
- Duplicate UPN check prevents adding same user twice
- Initialized in both DI and test constructors
- 4 new tests pass (add, skip duplicate, null, auditable)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dev
2026-04-09 09:26:12 +02:00
parent 381081da18
commit e6ba2d8146

View File

@@ -137,6 +137,7 @@ public partial class UserAccessAuditViewModel : FeatureViewModelBase
public IAsyncRelayCommand ExportHtmlCommand { get; } public IAsyncRelayCommand ExportHtmlCommand { get; }
public RelayCommand<GraphUserResult> AddUserCommand { get; } public RelayCommand<GraphUserResult> AddUserCommand { get; }
public RelayCommand<GraphUserResult> RemoveUserCommand { get; } public RelayCommand<GraphUserResult> RemoveUserCommand { get; }
public RelayCommand<GraphDirectoryUser> SelectDirectoryUserCommand { get; }
public IAsyncRelayCommand LoadDirectoryCommand { get; } public IAsyncRelayCommand LoadDirectoryCommand { get; }
public RelayCommand CancelDirectoryLoadCommand { get; } public RelayCommand CancelDirectoryLoadCommand { get; }
@@ -174,6 +175,7 @@ public partial class UserAccessAuditViewModel : FeatureViewModelBase
ExportHtmlCommand = new AsyncRelayCommand(ExportHtmlAsync, CanExport); ExportHtmlCommand = new AsyncRelayCommand(ExportHtmlAsync, CanExport);
AddUserCommand = new RelayCommand<GraphUserResult>(ExecuteAddUser); AddUserCommand = new RelayCommand<GraphUserResult>(ExecuteAddUser);
RemoveUserCommand = new RelayCommand<GraphUserResult>(ExecuteRemoveUser); RemoveUserCommand = new RelayCommand<GraphUserResult>(ExecuteRemoveUser);
SelectDirectoryUserCommand = new RelayCommand<GraphDirectoryUser>(ExecuteSelectDirectoryUser);
SelectedUsers.CollectionChanged += (_, _) => OnPropertyChanged(nameof(SelectedUsersLabel)); SelectedUsers.CollectionChanged += (_, _) => OnPropertyChanged(nameof(SelectedUsersLabel));
@@ -216,6 +218,7 @@ public partial class UserAccessAuditViewModel : FeatureViewModelBase
ExportHtmlCommand = new AsyncRelayCommand(ExportHtmlAsync, CanExport); ExportHtmlCommand = new AsyncRelayCommand(ExportHtmlAsync, CanExport);
AddUserCommand = new RelayCommand<GraphUserResult>(ExecuteAddUser); AddUserCommand = new RelayCommand<GraphUserResult>(ExecuteAddUser);
RemoveUserCommand = new RelayCommand<GraphUserResult>(ExecuteRemoveUser); RemoveUserCommand = new RelayCommand<GraphUserResult>(ExecuteRemoveUser);
SelectDirectoryUserCommand = new RelayCommand<GraphDirectoryUser>(ExecuteSelectDirectoryUser);
SelectedUsers.CollectionChanged += (_, _) => OnPropertyChanged(nameof(SelectedUsersLabel)); SelectedUsers.CollectionChanged += (_, _) => OnPropertyChanged(nameof(SelectedUsersLabel));
@@ -548,6 +551,16 @@ public partial class UserAccessAuditViewModel : FeatureViewModelBase
SelectedUsers.Remove(user); SelectedUsers.Remove(user);
} }
private void ExecuteSelectDirectoryUser(GraphDirectoryUser? dirUser)
{
if (dirUser == null) return;
var userResult = new GraphUserResult(dirUser.DisplayName, dirUser.UserPrincipalName, dirUser.Mail);
if (!SelectedUsers.Any(u => u.UserPrincipalName == userResult.UserPrincipalName))
{
SelectedUsers.Add(userResult);
}
}
private async Task DebounceSearchAsync(string query, CancellationToken ct) private async Task DebounceSearchAsync(string query, CancellationToken ct)
{ {
try try