- 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
4.1 KiB
4.1 KiB
phase, plan, subsystem, tags, dependency_graph, tech_stack, key_files, decisions, metrics
| phase | plan | subsystem | tags | dependency_graph | tech_stack | key_files | decisions | metrics | |||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 17-group-expansion-html-reports | 02 | html-export |
|
|
|
|
|
|
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 blockfilterTable()updated to skipdata-groupsub-rows- CSS
.group-expandableadds cursor pointer and hover opacity
PermissionsViewModel now injects ISharePointGroupResolver? as an optional last constructor parameter. In ExportHtmlAsync, before calling WriteAsync, it:
- Collects all distinct group names from
ResultswherePrincipalType == "SharePointGroup" - Calls
_groupResolver.ResolveGroupsAsync(ctx, clientId, groupNames, ct)if resolver is non-null and groups were found - Passes the resulting
groupMembersdict to bothWriteAsynccall sites (standard and simplified paths) - 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 warningsdotnet 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
grpmemtest patterns
Commits verified: