14 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | must_haves | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 06-global-site-selection | 04 | execute | 2 |
|
|
true |
|
|
Purpose: Fulfills SITE-01 (all tabs consume global selection) and SITE-02 (per-tab override without clearing global state). Output: 6 updated tab ViewModels with OnGlobalSitesChanged overrides.
<execution_context> @C:/Users/SebastienQUEROL/.claude/get-shit-done/workflows/execute-plan.md @C:/Users/SebastienQUEROL/.claude/get-shit-done/templates/summary.md </execution_context>
@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/06-global-site-selection/06-CONTEXT.md @.planning/phases/06-global-site-selection/06-01-SUMMARY.md From SharepointToolbox/ViewModels/FeatureViewModelBase.cs: ```csharp protected IReadOnlyList GlobalSites { get; private set; }protected virtual void OnGlobalSitesChanged(IReadOnlyList sites) { // Derived classes override to react to global site changes }
<!-- PermissionsViewModel — multi-site pattern (has SelectedSites collection) -->
From SharepointToolbox/ViewModels/Tabs/PermissionsViewModel.cs:
```csharp
public ObservableCollection<SiteInfo> SelectedSites { get; } = new();
[ObservableProperty] private string _siteUrl = string.Empty;
// RunOperationAsync uses SelectedSites.Count > 0 ? SelectedSites : SiteUrl
From SharepointToolbox/ViewModels/Tabs/StorageViewModel.cs:
[ObservableProperty] private string _siteUrl = string.Empty;
// RunOperationAsync checks string.IsNullOrWhiteSpace(SiteUrl)
From SharepointToolbox/ViewModels/Tabs/TransferViewModel.cs:
[ObservableProperty] private string _sourceSiteUrl = string.Empty;
Add a private field to track whether the user has made a local site selection on this tab:
```csharp
private bool _hasLocalSiteOverride;
```
Override OnGlobalSitesChanged to pre-populate SelectedSites when no local override exists:
```csharp
protected override void OnGlobalSitesChanged(IReadOnlyList<SiteInfo> sites)
{
if (_hasLocalSiteOverride) return;
SelectedSites.Clear();
foreach (var site in sites)
SelectedSites.Add(site);
}
```
In the existing `ExecuteOpenSitePicker` method, set `_hasLocalSiteOverride = true;` after the user picks sites locally. Add this line right before `SelectedSites.Clear()`:
```csharp
private void ExecuteOpenSitePicker()
{
if (OpenSitePickerDialog == null) return;
var dialog = OpenSitePickerDialog.Invoke();
if (dialog?.ShowDialog() == true && dialog is Views.Dialogs.SitePickerDialog picker)
{
_hasLocalSiteOverride = true; // <-- ADD THIS LINE
SelectedSites.Clear();
foreach (var site in picker.SelectedUrls)
SelectedSites.Add(site);
}
}
```
In the existing `OnTenantSwitched` method, reset the local override flag:
```csharp
protected override void OnTenantSwitched(TenantProfile profile)
{
_currentProfile = profile;
_hasLocalSiteOverride = false; // <-- ADD THIS LINE
Results = new ObservableCollection<PermissionEntry>();
SiteUrl = string.Empty;
SelectedSites.Clear();
// ... rest unchanged
}
```
Do NOT modify RunOperationAsync — its existing logic already handles the correct priority: `SelectedSites.Count > 0 ? SelectedSites : SiteUrl`. When global sites are active, SelectedSites will be populated, so it naturally uses global sites. When user picks locally, SelectedSites has the local override.
cd "C:\Users\dev\Documents\projets\Sharepoint" && dotnet build SharepointToolbox/SharepointToolbox.csproj --no-incremental 2>&1 | tail -5
PermissionsViewModel overrides OnGlobalSitesChanged to pre-populate SelectedSites. Local site picker sets _hasLocalSiteOverride=true to prevent global from overwriting. Tenant switch resets the flag.
Task 2: Update single-site tab VMs (Storage, Search, Duplicates, FolderStructure) for global consumption
SharepointToolbox/ViewModels/Tabs/StorageViewModel.cs,
SharepointToolbox/ViewModels/Tabs/SearchViewModel.cs,
SharepointToolbox/ViewModels/Tabs/DuplicatesViewModel.cs,
SharepointToolbox/ViewModels/Tabs/FolderStructureViewModel.cs
All four single-site tabs follow the identical pattern: pre-fill SiteUrl from the first global site when the user has not typed a local URL.
For EACH of these four ViewModels, apply the same changes:
1. Add a using directive if not present:
```csharp
using SharepointToolbox.Core.Models; // for SiteInfo — likely already imported for TenantProfile
```
2. Add a private tracking field (place near other private fields):
```csharp
private bool _hasLocalSiteOverride;
```
3. Override OnGlobalSitesChanged:
```csharp
protected override void OnGlobalSitesChanged(IReadOnlyList<SiteInfo> sites)
{
if (_hasLocalSiteOverride) return;
SiteUrl = sites.Count > 0 ? sites[0].Url : string.Empty;
}
```
4. Detect local override when user modifies SiteUrl. Add a partial method for the [ObservableProperty] SiteUrl change notification:
```csharp
partial void OnSiteUrlChanged(string value)
{
// If the user typed something different from the global site, mark as local override.
// Empty string means user cleared it — revert to global.
if (string.IsNullOrWhiteSpace(value))
{
_hasLocalSiteOverride = false;
// Re-apply global sites if available
if (GlobalSites.Count > 0)
SiteUrl = GlobalSites[0].Url;
}
else if (GlobalSites.Count == 0 || value != GlobalSites[0].Url)
{
_hasLocalSiteOverride = true;
}
}
```
IMPORTANT: Check if any of these VMs already has a `partial void OnSiteUrlChanged` method. If so, merge the logic into the existing method rather than creating a duplicate. Currently:
- StorageViewModel: no OnSiteUrlChanged — add it
- SearchViewModel: no OnSiteUrlChanged — add it
- DuplicatesViewModel: no OnSiteUrlChanged — add it
- FolderStructureViewModel: no OnSiteUrlChanged — add it
5. In the existing `OnTenantSwitched` method of each VM, add `_hasLocalSiteOverride = false;` at the beginning of the method body (after `_currentProfile = profile;`).
Do NOT modify RunOperationAsync in any of these VMs — they already check `string.IsNullOrWhiteSpace(SiteUrl)` and use the value directly. When global sites are active, SiteUrl will be pre-filled, so the existing logic works.
cd "C:\Users\dev\Documents\projets\Sharepoint" && dotnet build SharepointToolbox/SharepointToolbox.csproj --no-incremental 2>&1 | tail -5
StorageViewModel, SearchViewModel, DuplicatesViewModel, and FolderStructureViewModel all override OnGlobalSitesChanged to pre-fill SiteUrl from first global site. Local typing sets _hasLocalSiteOverride=true. Tenant switch resets the flag. Build succeeds.
Task 3: Update TransferViewModel and verify BulkMembersViewModel excluded
SharepointToolbox/ViewModels/Tabs/TransferViewModel.cs,
SharepointToolbox/ViewModels/Tabs/BulkMembersViewModel.cs
**TransferViewModel** — Pre-fill SourceSiteUrl from first global site (same pattern as single-site tabs, but the field is SourceSiteUrl not SiteUrl).
1. Add tracking field:
```csharp
private bool _hasLocalSourceSiteOverride;
```
2. Override OnGlobalSitesChanged:
```csharp
protected override void OnGlobalSitesChanged(IReadOnlyList<SiteInfo> sites)
{
if (_hasLocalSourceSiteOverride) return;
SourceSiteUrl = sites.Count > 0 ? sites[0].Url : string.Empty;
}
```
3. Add partial method for SourceSiteUrl change notification:
```csharp
partial void OnSourceSiteUrlChanged(string value)
{
if (string.IsNullOrWhiteSpace(value))
{
_hasLocalSourceSiteOverride = false;
if (GlobalSites.Count > 0)
SourceSiteUrl = GlobalSites[0].Url;
}
else if (GlobalSites.Count == 0 || value != GlobalSites[0].Url)
{
_hasLocalSourceSiteOverride = true;
}
}
```
4. In the existing `OnTenantSwitched` method, add `_hasLocalSourceSiteOverride = false;` at the beginning.
**BulkMembersViewModel** — Verify it does NOT need changes. BulkMembersViewModel has no SiteUrl field (it reads site URLs from CSV rows). Confirm this by checking: it should NOT have an OnGlobalSitesChanged override. Do NOT modify this file — only verify it has no SiteUrl property.
Note: SettingsViewModel, BulkSitesViewModel, and TemplatesViewModel also do NOT consume global sites per the CONTEXT decisions. Do NOT modify them.
cd "C:\Users\dev\Documents\projets\Sharepoint" && dotnet build SharepointToolbox/SharepointToolbox.csproj --no-incremental 2>&1 | tail -5
TransferViewModel overrides OnGlobalSitesChanged to pre-fill SourceSiteUrl. BulkMembersViewModel is confirmed excluded (no SiteUrl, no override). Build succeeds.
- `dotnet build SharepointToolbox/SharepointToolbox.csproj` succeeds with 0 errors
- `dotnet test` shows no new failures
- PermissionsViewModel has OnGlobalSitesChanged override populating SelectedSites
- StorageViewModel, SearchViewModel, DuplicatesViewModel, FolderStructureViewModel have OnGlobalSitesChanged override setting SiteUrl
- TransferViewModel has OnGlobalSitesChanged override setting SourceSiteUrl
- BulkMembersViewModel, SettingsViewModel, BulkSitesViewModel, TemplatesViewModel are NOT modified
- All consuming VMs have _hasLocalSiteOverride tracking
- All consuming VMs reset the override flag on tenant switch
<success_criteria> Every tab that should consume global sites does so automatically. Multi-site tab (Permissions) pre-populates its SelectedSites collection. Single-site tabs pre-fill their SiteUrl/SourceSiteUrl from the first global site. Users can type a different URL on any tab without clearing the global state. Tabs that don't apply (Settings, BulkSites, Templates, BulkMembers) are unaffected. </success_criteria>
After completion, create `.planning/phases/06-global-site-selection/06-04-SUMMARY.md`