Files
Sharepoint-Toolbox/.planning/phases/13-user-directory-viewmodel/13-02-SUMMARY.md
Dev df6f4949a8 docs(13-02): complete User Directory ViewModel plan
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 16:44:56 +02:00

4.4 KiB

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, metrics
phase plan subsystem tags requires provides affects tech-stack key-files key-decisions metrics
13-user-directory-viewmodel 02 viewmodel
wpf
mvvm
user-directory
icollectionview
csharp
phase plan provides
13-user-directory-viewmodel 01 IGraphUserDirectoryService with includeGuests param, GraphDirectoryUser with UserType
Directory browse mode in UserAccessAuditViewModel with load, filter, sort, cancel
ICollectionView for directory users with member/guest and text filtering
16 unit tests for directory browse behavior
SharepointToolbox/ViewModels/Tabs/UserAccessAuditViewModel.cs
SharepointToolbox.Tests/ViewModels/UserAccessAuditViewModelDirectoryTests.cs
added patterns
ICollectionView with SortDescription and Filter predicate for directory users
Separate CancellationTokenSource for directory load (independent from base class CTS)
Optional constructor parameter for testability (IGraphUserDirectoryService?)
created modified
SharepointToolbox.Tests/ViewModels/UserAccessAuditViewModelDirectoryTests.cs
SharepointToolbox/ViewModels/Tabs/UserAccessAuditViewModel.cs
IGraphUserDirectoryService injected as optional param in test constructor to preserve backward compat
Directory always fetches with includeGuests=true from Graph; member/guest filtering is in-memory via ICollectionView
Separate _directoryCts field for directory load cancellation (not sharing base class _cts)
No App.xaml.cs change needed — DI auto-resolves IGraphUserDirectoryService for UserAccessAuditViewModel
duration completed tasks_completed tasks_total tests_added tests_passing files_changed
261s 2026-04-08T14:08:05Z 4 4 16 24 2

Phase 13 Plan 02: User Directory ViewModel Summary

Directory browse mode with paginated Graph load, member/guest toggle filter, text search across 4 fields, and DisplayName-sorted ICollectionView -- all testable without WPF View layer.

What Was Done

Task 1: Inject IGraphUserDirectoryService into ViewModel

  • Added _graphUserDirectoryService field to UserAccessAuditViewModel
  • Added required parameter to full (DI) constructor after brandingService
  • Added optional parameter to test constructor for backward compatibility
  • Verified DI auto-resolves via existing services.AddTransient<UserAccessAuditViewModel>() registration

Task 2: Add directory browse mode properties and commands

  • Added 6 observable properties: IsBrowseMode, DirectoryUsers, IsLoadingDirectory, DirectoryLoadStatus, IncludeGuests, DirectoryFilterText
  • Added DirectoryUserCount computed property reflecting filtered view count
  • Added DirectoryUsersView (ICollectionView) with default SortDescription on DisplayName ascending
  • Added LoadDirectoryCommand (IAsyncRelayCommand) and CancelDirectoryLoadCommand (RelayCommand)
  • Initialized CollectionView and commands in both constructors
  • Added change handlers: OnIncludeGuestsChanged, OnDirectoryFilterTextChanged, OnIsLoadingDirectoryChanged

Task 3: Implement LoadDirectoryAsync, filter predicate, tenant switch cleanup

  • LoadDirectoryAsync: validates service/profile, creates CTS, calls GetUsersAsync with progress reporting, populates on UI thread, handles cancel/error
  • DirectoryFilterPredicate: filters by IncludeGuests (UserType=="Member") then by text match on DisplayName, UPN, Department, JobTitle
  • PopulateDirectory helper: clears and repopulates collection, refreshes view
  • OnTenantSwitched: cancels directory CTS, clears DirectoryUsers, resets all directory state
  • Exposed TestLoadDirectoryAsync() internal method for test access

Task 4: Write comprehensive tests (16 tests)

  • Created UserAccessAuditViewModelDirectoryTests.cs with helper factories
  • Tests cover: defaults, load populates, progress status, no-profile guard, cancellation, member/guest filtering, text filtering (DisplayName, Department, JobTitle), sort order, tenant switch reset, filtered count, search mode regression

Deviations from Plan

None -- plan executed exactly as written.

Verification

  • dotnet build --no-restore -warnaserror: PASSED (0 warnings, 0 errors)
  • dotnet test --filter "FullyQualifiedName~UserAccessAuditViewModel": 24/24 PASSED (8 existing + 16 new)

Commits

Hash Message
4ba4de6 feat(13-02): add directory browse mode with paginated load, member/guest filter, and sortable ICollectionView