docs(06-04): complete tab-vms global site consumption plan

- Add 06-04-SUMMARY.md with all task details and self-check
- Update STATE.md: progress bar 80%, decisions, session record
- Update ROADMAP.md: phase 6 now 4/5 plans complete (In Progress)
- Mark SITE-02 complete in REQUIREMENTS.md
This commit is contained in:
Dev
2026-04-07 10:10:18 +02:00
parent 0a91dd4ff3
commit da905b6ec0
4 changed files with 132 additions and 9 deletions

View File

@@ -8,7 +8,7 @@
### Global Site Selection ### Global Site Selection
- [x] **SITE-01**: User can select one or multiple target sites from the toolbar and all feature tabs use that selection as default - [x] **SITE-01**: User can select one or multiple target sites from the toolbar and all feature tabs use that selection as default
- [ ] **SITE-02**: User can override global site selection per-tab for single-site operations - [x] **SITE-02**: User can override global site selection per-tab for single-site operations
### User Access Audit ### User Access Audit
@@ -46,7 +46,7 @@ None deferred — all active requirements scoped to v1.1.
| Requirement | Phase | Status | | Requirement | Phase | Status |
|-------------|-------|--------| |-------------|-------|--------|
| SITE-01 | Phase 6 | Complete | | SITE-01 | Phase 6 | Complete |
| SITE-02 | Phase 6 | Pending | | SITE-02 | Phase 6 | Complete |
| UACC-01 | Phase 7 | Pending | | UACC-01 | Phase 7 | Pending |
| UACC-02 | Phase 7 | Pending | | UACC-02 | Phase 7 | Pending |
| SIMP-01 | Phase 8 | Pending | | SIMP-01 | Phase 8 | Pending |

View File

@@ -36,7 +36,7 @@
2. Selecting sites in the toolbar causes all feature tabs to default to those sites when an operation is run 2. Selecting sites in the toolbar causes all feature tabs to default to those sites when an operation is run
3. A user can override the global selection on any individual tab without clearing the global state 3. A user can override the global selection on any individual tab without clearing the global state
4. The global site selection persists across tab switches within the same session 4. The global site selection persists across tab switches within the same session
**Plans:** 3/5 plans executed **Plans:** 4/5 plans executed
Plans: Plans:
- [ ] 06-01-PLAN.md — GlobalSitesChangedMessage + FeatureViewModelBase extension - [ ] 06-01-PLAN.md — GlobalSitesChangedMessage + FeatureViewModelBase extension
- [ ] 06-02-PLAN.md — MainWindowViewModel global selection state + command - [ ] 06-02-PLAN.md — MainWindowViewModel global selection state + command
@@ -86,7 +86,7 @@ Plans:
| 3. Storage and File Operations | v1.0 | 8/8 | Complete | 2026-04-02 | | 3. Storage and File Operations | v1.0 | 8/8 | Complete | 2026-04-02 |
| 4. Bulk Operations and Provisioning | v1.0 | 10/10 | Complete | 2026-04-03 | | 4. Bulk Operations and Provisioning | v1.0 | 10/10 | Complete | 2026-04-03 |
| 5. Distribution and Hardening | v1.0 | 3/3 | Complete | 2026-04-03 | | 5. Distribution and Hardening | v1.0 | 3/3 | Complete | 2026-04-03 |
| 6. Global Site Selection | 3/5 | In Progress| | - | | 6. Global Site Selection | 4/5 | In Progress| | - |
| 7. User Access Audit | v1.1 | 0/? | Not started | - | | 7. User Access Audit | v1.1 | 0/? | Not started | - |
| 8. Simplified Permissions | v1.1 | 0/? | Not started | - | | 8. Simplified Permissions | v1.1 | 0/? | Not started | - |
| 9. Storage Visualization | v1.1 | 0/? | Not started | - | | 9. Storage Visualization | v1.1 | 0/? | Not started | - |

View File

@@ -3,14 +3,14 @@ gsd_state_version: 1.0
milestone: v1.0 milestone: v1.0
milestone_name: milestone milestone_name: milestone
status: completed status: completed
stopped_at: Completed 06-03-PLAN.md — toolbar Select Sites button, localization keys, and dialog factory wiring done stopped_at: Completed 06-04-PLAN.md — all 6 tab VMs wired to OnGlobalSitesChanged with local override protection
last_updated: "2026-04-07T08:08:43.719Z" last_updated: "2026-04-07T08:10:03.678Z"
last_activity: 2026-04-07 — Roadmap created (Phases 6-9), 10/10 requirements mapped last_activity: 2026-04-07 — Roadmap created (Phases 6-9), 10/10 requirements mapped
progress: progress:
total_phases: 4 total_phases: 4
completed_phases: 0 completed_phases: 0
total_plans: 5 total_plans: 5
completed_plans: 3 completed_plans: 4
--- ---
# Project State # Project State
@@ -45,6 +45,7 @@ Phase 6 [ ] → Phase 7 [ ] → Phase 8 [ ] → Phase 9 [ ]
| Phase 06-global-site-selection P02 | 8 | 1 tasks | 1 files | | Phase 06-global-site-selection P02 | 8 | 1 tasks | 1 files |
| Phase 06-global-site-selection P01 | 2 | 2 tasks | 3 files | | Phase 06-global-site-selection P01 | 2 | 2 tasks | 3 files |
| Phase 06-global-site-selection P03 | 2 | 3 tasks | 5 files | | Phase 06-global-site-selection P03 | 2 | 3 tasks | 5 files |
| Phase 06-global-site-selection P04 | 2 | 3 tasks | 6 files |
## Accumulated Context ## Accumulated Context
@@ -62,6 +63,9 @@ Decisions are logged in PROJECT.md Key Decisions table.
- [Phase 06-01]: FeatureViewModelBase.OnGlobalSitesReceived (private) updates GlobalSites then calls OnGlobalSitesChanged (protected virtual) — separates storage from derived class hooks - [Phase 06-01]: FeatureViewModelBase.OnGlobalSitesReceived (private) updates GlobalSites then calls OnGlobalSitesChanged (protected virtual) — separates storage from derived class hooks
- [Phase 06-03]: Added using SharepointToolbox.Core.Models to MainWindow.xaml.cs for TenantProfile in SitePickerDialog factory lambda - [Phase 06-03]: Added using SharepointToolbox.Core.Models to MainWindow.xaml.cs for TenantProfile in SitePickerDialog factory lambda
- [Phase 06-03]: toolbar.selectSites.tooltipDisabled added to resources but not wired in XAML — WPF Button disabled tooltip requires style trigger (deferred) - [Phase 06-03]: toolbar.selectSites.tooltipDisabled added to resources but not wired in XAML — WPF Button disabled tooltip requires style trigger (deferred)
- [Phase 06-global-site-selection]: PermissionsViewModel uses _hasLocalSiteOverride guard for SelectedSites; site picker sets flag, tenant switch resets it
- [Phase 06-global-site-selection]: Single-site VMs use partial void OnSiteUrlChanged to detect local typing; clearing field reverts to global
- [Phase 06-global-site-selection]: BulkMembersViewModel confirmed excluded: no SiteUrl field, CSV-driven per-row site URLs
### Pending Todos ### Pending Todos
@@ -73,6 +77,6 @@ None.
## Session Continuity ## Session Continuity
Last session: 2026-04-07T08:08:43.717Z Last session: 2026-04-07T08:10:03.675Z
Stopped at: Completed 06-03-PLAN.md — toolbar Select Sites button, localization keys, and dialog factory wiring done Stopped at: Completed 06-04-PLAN.md — all 6 tab VMs wired to OnGlobalSitesChanged with local override protection
Resume file: None Resume file: None

View File

@@ -0,0 +1,119 @@
---
phase: 06-global-site-selection
plan: 04
subsystem: tab-viewmodels
tags: [wpf, mvvm, community-toolkit, global-sites, override-pattern]
# Dependency graph
requires:
- 06-01 (FeatureViewModelBase.OnGlobalSitesChanged virtual hook)
provides:
- PermissionsViewModel.OnGlobalSitesChanged (multi-site: pre-populates SelectedSites)
- StorageViewModel.OnGlobalSitesChanged (single-site: pre-fills SiteUrl)
- SearchViewModel.OnGlobalSitesChanged (single-site: pre-fills SiteUrl)
- DuplicatesViewModel.OnGlobalSitesChanged (single-site: pre-fills SiteUrl)
- FolderStructureViewModel.OnGlobalSitesChanged (single-site: pre-fills SiteUrl)
- TransferViewModel.OnGlobalSitesChanged (single-site: pre-fills SourceSiteUrl)
affects:
- 06-05-per-tab-override (consumes GlobalSites in RunOperationAsync as fallback)
# Tech tracking
tech-stack:
added: []
patterns:
- "partial void OnXxxChanged — CommunityToolkit partial property change notification used to detect local user input and set override flag"
- "_hasLocalSiteOverride / _hasLocalSourceSiteOverride field pattern — prevents global site changes from overwriting user's local entry"
- "Tenant switch resets override flag — ensures fresh tenant starts with global site pre-fill active"
key-files:
created: []
modified:
- SharepointToolbox/ViewModels/Tabs/PermissionsViewModel.cs
- SharepointToolbox/ViewModels/Tabs/StorageViewModel.cs
- SharepointToolbox/ViewModels/Tabs/SearchViewModel.cs
- SharepointToolbox/ViewModels/Tabs/DuplicatesViewModel.cs
- SharepointToolbox/ViewModels/Tabs/FolderStructureViewModel.cs
- SharepointToolbox/ViewModels/Tabs/TransferViewModel.cs
key-decisions:
- "PermissionsViewModel uses _hasLocalSiteOverride to guard SelectedSites; site picker dialog sets flag to true, tenant switch resets it to false"
- "Single-site VMs use partial void OnSiteUrlChanged to detect local typing; clearing the field reverts to global, non-empty different value sets override"
- "BulkMembersViewModel excluded: confirmed no SiteUrl field (CSV-driven per-row site URLs)"
- "SettingsViewModel, BulkSitesViewModel, TemplatesViewModel excluded per CONTEXT decisions — not modified"
# Metrics
duration: 2min
completed: 2026-04-07
requirements-completed:
- SITE-01
- SITE-02
---
# Phase 06 Plan 04: Tab ViewModels Global Site Consumption Summary
**All 6 consuming tab ViewModels wired to override OnGlobalSitesChanged — PermissionsViewModel pre-populates SelectedSites (multi-site), 4 single-site tabs pre-fill SiteUrl, TransferViewModel pre-fills SourceSiteUrl, all with local-override protection via _hasLocalSiteOverride flag**
## Performance
- **Duration:** ~2 min
- **Started:** 2026-04-07T08:06:19Z
- **Completed:** 2026-04-07T08:08:35Z
- **Tasks:** 3
- **Files modified:** 6
## Accomplishments
- PermissionsViewModel: Added `OnGlobalSitesChanged` override that pre-populates `SelectedSites` from global sites when no local override is active
- PermissionsViewModel: Site picker dialog (`ExecuteOpenSitePicker`) now sets `_hasLocalSiteOverride = true` before clearing/repopulating SelectedSites
- PermissionsViewModel: `OnTenantSwitched` resets `_hasLocalSiteOverride = false` so new tenant immediately uses global sites
- StorageViewModel, SearchViewModel, DuplicatesViewModel, FolderStructureViewModel: Added identical `OnGlobalSitesChanged` + `partial void OnSiteUrlChanged` + `_hasLocalSiteOverride` pattern
- TransferViewModel: Added `OnGlobalSitesChanged` + `partial void OnSourceSiteUrlChanged` + `_hasLocalSourceSiteOverride` pattern for `SourceSiteUrl`
- BulkMembersViewModel confirmed excluded — no `SiteUrl` field, CSV-driven, no changes made
- All 134 tests pass (0 failures, 22 skipped — same baseline as plan 06-01)
- Build succeeds with 0 errors, 0 warnings
## Task Commits
Each task was committed atomically:
1. **Task 1: Update PermissionsViewModel for multi-site global consumption** - `1bf47b5` (feat)
2. **Task 2: Update single-site tab VMs (Storage, Search, Duplicates, FolderStructure)** - `6a2e4d1` (feat)
3. **Task 3: Update TransferViewModel and verify BulkMembersViewModel excluded** - `0a91dd4` (feat)
## Files Created/Modified
- `SharepointToolbox/ViewModels/Tabs/PermissionsViewModel.cs` — Added `_hasLocalSiteOverride`, `OnGlobalSitesChanged`, updated `ExecuteOpenSitePicker` and `OnTenantSwitched`
- `SharepointToolbox/ViewModels/Tabs/StorageViewModel.cs` — Added `_hasLocalSiteOverride`, `OnGlobalSitesChanged`, `OnSiteUrlChanged`, updated `OnTenantSwitched`
- `SharepointToolbox/ViewModels/Tabs/SearchViewModel.cs` — Added `_hasLocalSiteOverride`, `OnGlobalSitesChanged`, `OnSiteUrlChanged`, updated `OnTenantSwitched`
- `SharepointToolbox/ViewModels/Tabs/DuplicatesViewModel.cs` — Added `_hasLocalSiteOverride`, `OnGlobalSitesChanged`, `OnSiteUrlChanged`, updated `OnTenantSwitched`
- `SharepointToolbox/ViewModels/Tabs/FolderStructureViewModel.cs` — Added `_hasLocalSiteOverride`, `OnGlobalSitesChanged`, `OnSiteUrlChanged`, updated `OnTenantSwitched`
- `SharepointToolbox/ViewModels/Tabs/TransferViewModel.cs` — Added `_hasLocalSourceSiteOverride`, `OnGlobalSitesChanged`, `OnSourceSiteUrlChanged`, updated `OnTenantSwitched`
## Decisions Made
- Used `partial void OnSiteUrlChanged` (CommunityToolkit partial method) to detect user typing — this fires for every programmatic and user-driven change, so the guard `value != GlobalSites[0].Url` ensures global pre-fills don't incorrectly set the override flag
- When user clears SiteUrl (empty string), the override resets and global is re-applied immediately — design choice to make clearing feel like "go back to global"
- PermissionsViewModel pattern differs from single-site VMs: it has no `OnSiteUrlChanged` because its authoritative input is `SelectedSites` (managed by site picker dialog), not free text
## Deviations from Plan
None — plan executed exactly as written. BulkMembersViewModel was confirmed to have no `SiteUrl` field as expected.
## Issues Encountered
None.
## User Setup Required
None — no external service configuration required.
## Self-Check: PASSED
All 7 expected files found. All 3 task commits verified in git log.
## Next Phase Readiness
- All 6 consuming tab VMs now react to `GlobalSitesChangedMessage` automatically
- Local override pattern is consistent across all tabs — users can type freely without clearing global state
- Plan 06-05 (per-tab override enforcement in RunOperationAsync) can proceed
- No blockers