8.4 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 | 02 | execute | 1 |
|
true |
|
|
Purpose: Central state management for global site selection — the toolbar UI (plan 06-03) binds to these properties. Output: Updated MainWindowViewModel.cs with GlobalSelectedSites, OpenGlobalSitePickerCommand, GlobalSitesSelectedLabel, and broadcast logic.
<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 From SharepointToolbox/ViewModels/MainWindowViewModel.cs: ```csharp public partial class MainWindowViewModel : ObservableRecipient { // Existing — DO NOT MODIFY public Func? OpenProfileManagementDialog { get; set; } public ObservableCollection TenantProfiles { get; } public IAsyncRelayCommand ConnectCommand { get; } public IAsyncRelayCommand ClearSessionCommand { get; } public RelayCommand ManageProfilesCommand { get; }// OnSelectedProfileChanged sends TenantSwitchedMessage
// ClearSessionAsync clears session
}
From SharepointToolbox/Core/Models/SiteInfo.cs:
```csharp
public record SiteInfo(string Url, string Title);
From SharepointToolbox/Views/Tabs/PermissionsView.xaml.cs:
vm.OpenSitePickerDialog = () =>
{
var factory = serviceProvider.GetRequiredService<Func<TenantProfile, SitePickerDialog>>();
return factory(vm.CurrentProfile ?? new TenantProfile());
};
From SharepointToolbox/Views/Dialogs/SitePickerDialog.xaml.cs:
public IReadOnlyList<SiteInfo> SelectedUrls =>
_allItems.Where(i => i.IsSelected).Select(i => new SiteInfo(i.Url, i.Title)).ToList();
// DialogResult = true on OK click
1. Add using directives at the top (if not already present):
```csharp
using SharepointToolbox.Core.Models; // for SiteInfo — may already be there for TenantProfile
```
2. Add a dialog factory property (same pattern as OpenProfileManagementDialog). Place it near the other dialog factory:
```csharp
/// <summary>
/// Factory set by MainWindow.xaml.cs to open the SitePickerDialog for global site selection.
/// Returns the opened Window; ViewModel calls ShowDialog() on it.
/// </summary>
public Func<Window>? OpenGlobalSitePickerDialog { get; set; }
```
3. Add the global site selection collection and label. Place after existing observable properties:
```csharp
public ObservableCollection<SiteInfo> GlobalSelectedSites { get; } = new();
/// <summary>
/// Label for toolbar display: "3 site(s) selected" or "No sites selected".
/// </summary>
public string GlobalSitesSelectedLabel =>
GlobalSelectedSites.Count > 0
? $"{GlobalSelectedSites.Count} site(s) selected"
: "No sites selected";
```
Note: The label uses a hardcoded string for now. Plan 06-03 will replace it with a localized string once the localization keys are added.
4. Add the command. Declare it near the other commands:
```csharp
public RelayCommand OpenGlobalSitePickerCommand { get; }
```
5. In the constructor, initialize the command (after ManageProfilesCommand initialization):
```csharp
OpenGlobalSitePickerCommand = new RelayCommand(ExecuteOpenGlobalSitePicker, () => SelectedProfile != null);
GlobalSelectedSites.CollectionChanged += (_, _) =>
{
OnPropertyChanged(nameof(GlobalSitesSelectedLabel));
BroadcastGlobalSites();
};
```
6. Add the command implementation method:
```csharp
private void ExecuteOpenGlobalSitePicker()
{
if (OpenGlobalSitePickerDialog == null) return;
var dialog = OpenGlobalSitePickerDialog.Invoke();
if (dialog?.ShowDialog() == true && dialog is Views.Dialogs.SitePickerDialog picker)
{
GlobalSelectedSites.Clear();
foreach (var site in picker.SelectedUrls)
GlobalSelectedSites.Add(site);
}
}
```
7. Add the broadcast helper method:
```csharp
private void BroadcastGlobalSites()
{
WeakReferenceMessenger.Default.Send(
new GlobalSitesChangedMessage(GlobalSelectedSites.ToList().AsReadOnly()));
}
```
8. In `OnSelectedProfileChanged`, add after the existing body:
```csharp
// Clear global site selection on tenant switch (sites belong to a tenant)
GlobalSelectedSites.Clear();
OpenGlobalSitePickerCommand.NotifyCanExecuteChanged();
```
9. In `ClearSessionAsync`, add at the END of the try block (before ConnectionStatus = "Not connected"):
```csharp
GlobalSelectedSites.Clear();
```
10. Add required using for the message (if not already imported):
```csharp
using SharepointToolbox.Core.Messages; // already present for TenantSwitchedMessage
```
IMPORTANT: The `using SharepointToolbox.Views.Dialogs;` namespace is needed for the `SitePickerDialog` cast in ExecuteOpenGlobalSitePicker. Add it if not present. This is acceptable since MainWindowViewModel already references `System.Windows.Window` (a View-layer type) via the dialog factory pattern.
cd "C:\Users\dev\Documents\projets\Sharepoint" && dotnet build SharepointToolbox/SharepointToolbox.csproj --no-incremental 2>&1 | tail -5
MainWindowViewModel compiles with GlobalSelectedSites collection, OpenGlobalSitePickerCommand (disabled when no profile), GlobalSitesSelectedLabel, broadcast on collection change, and clear on tenant switch + session clear.
- `dotnet build SharepointToolbox/SharepointToolbox.csproj` succeeds with 0 errors
- MainWindowViewModel.cs contains GlobalSelectedSites ObservableCollection
- MainWindowViewModel.cs contains OpenGlobalSitePickerCommand
- MainWindowViewModel.cs contains GlobalSitesSelectedLabel property
- MainWindowViewModel.cs sends GlobalSitesChangedMessage when collection changes
- OnSelectedProfileChanged clears GlobalSelectedSites
- ClearSessionAsync clears GlobalSelectedSites
<success_criteria> MainWindowViewModel owns the global site selection state, can open the site picker dialog, broadcasts changes to all tab VMs, and clears the selection on tenant switch and session clear. The toolbar UI (plan 06-03) can bind directly to these properties and commands. </success_criteria>
After completion, create `.planning/phases/06-global-site-selection/06-02-SUMMARY.md`