- 17-02-SUMMARY.md created - STATE.md updated: session, decisions, progress - ROADMAP.md: phase 17 marked complete (2/2 plans) - REQUIREMENTS.md: RPT-01 marked complete
81 lines
4.1 KiB
Markdown
81 lines
4.1 KiB
Markdown
---
|
|
phase: 17-group-expansion-html-reports
|
|
plan: "02"
|
|
subsystem: html-export
|
|
tags: [html-export, group-expansion, permissions-viewmodel, tdd]
|
|
dependency_graph:
|
|
requires: ["17-01"]
|
|
provides: ["expandable-group-pills-html", "group-resolver-wired-to-export"]
|
|
affects: ["HtmlExportService", "PermissionsViewModel"]
|
|
tech_stack:
|
|
added: []
|
|
patterns: ["optional-parameter-backward-compat", "pre-render-resolution", "inline-js-toggle"]
|
|
key_files:
|
|
created: []
|
|
modified:
|
|
- SharepointToolbox/Services/Export/HtmlExportService.cs
|
|
- SharepointToolbox/ViewModels/Tabs/PermissionsViewModel.cs
|
|
- SharepointToolbox.Tests/Services/Export/HtmlExportServiceTests.cs
|
|
decisions:
|
|
- "groupMembers added as optional last parameter to both BuildHtml overloads and WriteAsync methods — null produces byte-identical output to pre-Phase 17"
|
|
- "Group pill expansion uses name-based lookup in groupMembers dict (not login) — matches how SharePoint groups are identified in Users field"
|
|
- "ISharePointGroupResolver injected as optional last parameter in PermissionsViewModel main constructor — DI works without explicit resolver if not registered"
|
|
- "Resolution failure logged as Warning and export proceeds without expansion — never blocks user export"
|
|
metrics:
|
|
duration_seconds: 204
|
|
completed_date: "2026-04-09"
|
|
tasks_completed: 2
|
|
files_modified: 3
|
|
---
|
|
|
|
# Phase 17 Plan 02: Group Expansion Wire-up Summary
|
|
|
|
Expandable SharePoint group pills in HTML reports with toggleGroup JS and PermissionsViewModel pre-render resolution via ISharePointGroupResolver.
|
|
|
|
## Tasks Completed
|
|
|
|
| Task | Description | Commit | Status |
|
|
|------|-------------|--------|--------|
|
|
| 1 (RED) | Failing tests for group pill expansion | c35ee76 | Done |
|
|
| 1 (GREEN) | HtmlExportService: groupMembers param + expandable pills + toggleGroup JS | 07ed6e2 | Done |
|
|
| 2 | PermissionsViewModel: ISharePointGroupResolver injection + ExportHtmlAsync wiring | aab3aee | Done |
|
|
|
|
## What Was Built
|
|
|
|
Both `BuildHtml` overloads in `HtmlExportService` now accept an optional `IReadOnlyDictionary<string, IReadOnlyList<ResolvedMember>>? groupMembers` parameter. When provided:
|
|
|
|
- SharePoint group pills render as `<span class="user-pill group-expandable" onclick="toggleGroup('grpmem0')">` with a down-arrow indicator
|
|
- A hidden `<tr data-group="grpmem0" style="display:none">` sub-row is injected immediately after the parent row, containing resolved member display names and logins
|
|
- Empty member lists (resolution failed) render `<em style="color:#888">members unavailable</em>`
|
|
- `toggleGroup(id)` JS function is added to the inline script block
|
|
- `filterTable()` updated to skip `data-group` sub-rows
|
|
- CSS `.group-expandable` adds cursor pointer and hover opacity
|
|
|
|
`PermissionsViewModel` now injects `ISharePointGroupResolver?` as an optional last constructor parameter. In `ExportHtmlAsync`, before calling `WriteAsync`, it:
|
|
1. Collects all distinct group names from `Results` where `PrincipalType == "SharePointGroup"`
|
|
2. Calls `_groupResolver.ResolveGroupsAsync(ctx, clientId, groupNames, ct)` if resolver is non-null and groups were found
|
|
3. Passes the resulting `groupMembers` dict to both `WriteAsync` call sites (standard and simplified paths)
|
|
4. On resolution failure, logs a warning and exports without expansion (graceful degradation)
|
|
|
|
## Deviations from Plan
|
|
|
|
None — plan executed exactly as written.
|
|
|
|
## Verification
|
|
|
|
- `dotnet build` — 0 errors, 0 warnings
|
|
- `dotnet test --filter "FullyQualifiedName~HtmlExportServiceTests"` — 32 tests pass (includes 6 new group expansion tests)
|
|
- `dotnet test` — 320 passed, 0 failed, 28 skipped (full suite green)
|
|
|
|
## Self-Check: PASSED
|
|
|
|
Files verified:
|
|
- SharepointToolbox/Services/Export/HtmlExportService.cs — contains `toggleGroup`, `groupMembers`, `group-expandable`
|
|
- SharepointToolbox/ViewModels/Tabs/PermissionsViewModel.cs — contains `_groupResolver`, `ResolveGroupsAsync`
|
|
- SharepointToolbox.Tests/Services/Export/HtmlExportServiceTests.cs — contains `grpmem` test patterns
|
|
|
|
Commits verified:
|
|
- c35ee76 — test(17-02): RED phase
|
|
- 07ed6e2 — feat(17-02): HtmlExportService implementation
|
|
- aab3aee — feat(17-02): PermissionsViewModel wiring
|