docs(13-02): complete User Directory ViewModel plan
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
---
|
||||
phase: 13-user-directory-viewmodel
|
||||
plan: 02
|
||||
subsystem: viewmodel
|
||||
tags: [wpf, mvvm, user-directory, icollectionview, csharp]
|
||||
|
||||
requires:
|
||||
- phase: 13-user-directory-viewmodel
|
||||
plan: 01
|
||||
provides: IGraphUserDirectoryService with includeGuests param, GraphDirectoryUser with UserType
|
||||
provides:
|
||||
- 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
|
||||
affects:
|
||||
- SharepointToolbox/ViewModels/Tabs/UserAccessAuditViewModel.cs
|
||||
- SharepointToolbox.Tests/ViewModels/UserAccessAuditViewModelDirectoryTests.cs
|
||||
|
||||
tech-stack:
|
||||
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?)
|
||||
|
||||
key-files:
|
||||
created:
|
||||
- SharepointToolbox.Tests/ViewModels/UserAccessAuditViewModelDirectoryTests.cs
|
||||
modified:
|
||||
- SharepointToolbox/ViewModels/Tabs/UserAccessAuditViewModel.cs
|
||||
|
||||
key-decisions:
|
||||
- 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
|
||||
|
||||
metrics:
|
||||
duration: 261s
|
||||
completed: "2026-04-08T14:08:05Z"
|
||||
tasks_completed: 4
|
||||
tasks_total: 4
|
||||
tests_added: 16
|
||||
tests_passing: 24
|
||||
files_changed: 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 |
|
||||
Reference in New Issue
Block a user