Files
Sharepoint-Toolbox/.planning/phases/14-user-directory-view/14-01-PLAN.md
Dev e3ff27a673 docs: create milestone v2.3 roadmap (5 phases, 15-19)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 11:31:54 +02:00

11 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
phase plan type wave depends_on files_modified autonomous requirements must_haves
14-user-directory-view 01 execute 1
SharepointToolbox/Localization/Strings.resx
SharepointToolbox/Localization/Strings.fr.resx
SharepointToolbox/ViewModels/Tabs/UserAccessAuditViewModel.cs
SharepointToolbox/Views/Tabs/UserAccessAuditView.xaml.cs
SharepointToolbox.Tests/ViewModels/UserAccessAuditViewModelDirectoryTests.cs
true
UDIR-05
UDIR-01
truths artifacts key_links
SelectDirectoryUserCommand takes a GraphDirectoryUser, converts it to GraphUserResult, adds it to SelectedUsers via existing logic
After SelectDirectoryUserCommand, the user appears in SelectedUsers and can be audited with RunCommand
SelectDirectoryUserCommand does not add duplicates (same UPN check as existing AddUserCommand)
Localization keys for directory UI exist in both EN and FR resource files
Code-behind has a DirectoryDataGrid_MouseDoubleClick handler that invokes SelectDirectoryUserCommand
path provides contains
SharepointToolbox/ViewModels/Tabs/UserAccessAuditViewModel.cs SelectDirectoryUserCommand bridging directory selection to audit pipeline SelectDirectoryUserCommand
path provides contains
SharepointToolbox/Views/Tabs/UserAccessAuditView.xaml.cs Event handler for directory DataGrid double-click DirectoryDataGrid_MouseDoubleClick
path provides contains
SharepointToolbox.Tests/ViewModels/UserAccessAuditViewModelDirectoryTests.cs Tests for SelectDirectoryUserCommand SelectDirectoryUser
from to via pattern
SharepointToolbox/ViewModels/Tabs/UserAccessAuditViewModel.cs SharepointToolbox/Core/Models/GraphDirectoryUser.cs command parameter type GraphDirectoryUser
from to via pattern
SharepointToolbox/Views/Tabs/UserAccessAuditView.xaml.cs SharepointToolbox/ViewModels/Tabs/UserAccessAuditViewModel.cs command invocation SelectDirectoryUserCommand
Add localization keys for directory UI, the SelectDirectoryUserCommand that bridges directory selection to the audit pipeline, and a code-behind event handler for DataGrid double-click.

Purpose: Provides the infrastructure (localization, command, event handler) that Plan 14-02 needs to build the XAML view. SC2 requires selecting a directory user to trigger an audit — this command makes that possible.

Output: Localization keys (EN+FR), SelectDirectoryUserCommand with tests, code-behind event handler.

<execution_context> @C:/Users/dev/.claude/get-shit-done/workflows/execute-plan.md @C:/Users/dev/.claude/get-shit-done/templates/summary.md </execution_context>

@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/phases/14-user-directory-view/14-RESEARCH.md From SharepointToolbox/ViewModels/Tabs/UserAccessAuditViewModel.cs: ```csharp public RelayCommand AddUserCommand { get; }

private void ExecuteAddUser(GraphUserResult? user) { if (user == null) return; if (!SelectedUsers.Any(u => u.UserPrincipalName == user.UserPrincipalName)) { SelectedUsers.Add(user); } SearchQuery = string.Empty; SearchResults.Clear(); }


<!-- GraphDirectoryUser record -->
From SharepointToolbox/Core/Models/GraphDirectoryUser.cs:
```csharp
public record GraphDirectoryUser(
    string DisplayName, string UserPrincipalName,
    string? Mail, string? Department, string? JobTitle, string? UserType);

From SharepointToolbox/Services/IGraphUserSearchService.cs:

public record GraphUserResult(string DisplayName, string UserPrincipalName, string? Mail);

From SharepointToolbox/Views/Tabs/UserAccessAuditView.xaml.cs:

private void SearchResultsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (sender is ListBox listBox && listBox.SelectedItem is GraphUserResult user)
    {
        var vm = (UserAccessAuditViewModel)DataContext;
        if (vm.AddUserCommand.CanExecute(user))
            vm.AddUserCommand.Execute(user);
        listBox.SelectedItem = null;
    }
}

From Strings.resx:

<data name="audit.grp.users" xml:space="preserve"><value>Select Users</value></data>
<data name="audit.btn.run" xml:space="preserve"><value>Run Audit</value></data>
Task 1: Add localization keys for directory UI (EN + FR) SharepointToolbox/Localization/Strings.resx, SharepointToolbox/Localization/Strings.fr.resx - Both resx files contain matching keys for directory browse UI 1. Add to `Strings.resx` (EN): - `audit.mode.search` = "Search" - `audit.mode.browse` = "Browse Directory" - `directory.grp.browse` = "User Directory" - `directory.btn.load` = "Load Directory" - `directory.btn.cancel` = "Cancel" - `directory.filter.placeholder` = "Filter users..." - `directory.chk.guests` = "Include guests" - `directory.status.count` = "users" - `directory.hint.doubleclick` = "Double-click a user to add to audit" - `directory.col.name` = "Name" - `directory.col.upn` = "Email" - `directory.col.department` = "Department" - `directory.col.jobtitle` = "Job Title" - `directory.col.type` = "Type"
2. Add to `Strings.fr.resx` (FR):
   - `audit.mode.search` = "Recherche"
   - `audit.mode.browse` = "Parcourir l'annuaire"
   - `directory.grp.browse` = "Annuaire utilisateurs"
   - `directory.btn.load` = "Charger l'annuaire"
   - `directory.btn.cancel` = "Annuler"
   - `directory.filter.placeholder` = "Filtrer les utilisateurs..."
   - `directory.chk.guests` = "Inclure les invités"
   - `directory.status.count` = "utilisateurs"
   - `directory.hint.doubleclick` = "Double-cliquez sur un utilisateur pour l'ajouter à l'audit"
   - `directory.col.name` = "Nom"
   - `directory.col.upn` = "Courriel"
   - `directory.col.department` = "Département"
   - `directory.col.jobtitle` = "Poste"
   - `directory.col.type` = "Type"
dotnet build --no-restore -warnaserror 14 localization keys present in both EN and FR resource files. Task 2: Add SelectDirectoryUserCommand to ViewModel SharepointToolbox/ViewModels/Tabs/UserAccessAuditViewModel.cs, SharepointToolbox.Tests/ViewModels/UserAccessAuditViewModelDirectoryTests.cs - SelectDirectoryUserCommand is a RelayCommand - It converts GraphDirectoryUser to GraphUserResult and adds to SelectedUsers - Duplicate UPN check (same as AddUserCommand) - Does NOT clear SearchQuery/SearchResults (not in search mode context) - After execution, IsBrowseMode stays true — user can continue selecting from directory 1. Add command declaration in ViewModel: ```csharp public RelayCommand SelectDirectoryUserCommand { get; } ```
2. Initialize in BOTH constructors:
   ```csharp
   SelectDirectoryUserCommand = new RelayCommand<GraphDirectoryUser>(ExecuteSelectDirectoryUser);
   ```

3. Implement the command method:
   ```csharp
   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);
       }
   }
   ```

4. Add tests to `UserAccessAuditViewModelDirectoryTests.cs`:
   - Test: SelectDirectoryUserCommand adds user to SelectedUsers
   - Test: SelectDirectoryUserCommand skips duplicates
   - Test: SelectDirectoryUserCommand with null does nothing
   - Test: After SelectDirectoryUser, user can be audited with RunCommand (integration: add user + check SelectedUsers.Count > 0)
dotnet build --no-restore -warnaserror && dotnet test SharepointToolbox.Tests --filter "FullyQualifiedName~UserAccessAuditViewModelDirectory" --no-build -q SelectDirectoryUserCommand bridges directory selection to audit pipeline. Tests pass. Task 3: Add code-behind event handler for directory DataGrid SharepointToolbox/Views/Tabs/UserAccessAuditView.xaml.cs - DirectoryDataGrid_MouseDoubleClick handler extracts the clicked GraphDirectoryUser - Invokes SelectDirectoryUserCommand with the selected user - Uses the same pattern as SearchResultsListBox_SelectionChanged 1. Add to `UserAccessAuditView.xaml.cs`: ```csharp private void DirectoryDataGrid_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e) { if (sender is DataGrid grid && grid.SelectedItem is GraphDirectoryUser user) { var vm = (UserAccessAuditViewModel)DataContext; if (vm.SelectDirectoryUserCommand.CanExecute(user)) vm.SelectDirectoryUserCommand.Execute(user); } } ```
2. Add the required using statement if not present:
   ```csharp
   using System.Windows.Controls;  // Already present
   using SharepointToolbox.Core.Models;  // For GraphDirectoryUser
   ```
dotnet build --no-restore -warnaserror Code-behind event handler exists, ready to be wired in XAML (Plan 14-02). ```bash dotnet build --no-restore -warnaserror dotnet test SharepointToolbox.Tests --filter "FullyQualifiedName~UserAccessAuditViewModelDirectory" --no-build -q ``` Both must pass with zero failures.

<success_criteria>

  • 14 localization keys in both EN and FR resx files
  • SelectDirectoryUserCommand converts GraphDirectoryUser → GraphUserResult → SelectedUsers
  • Duplicate UPN check prevents adding same user twice
  • Code-behind event handler for DataGrid double-click
  • All tests pass, build clean </success_criteria>
After completion, create `.planning/phases/14-user-directory-view/14-01-SUMMARY.md`