# Phase 6: Global Site Selection - Context

**Gathered:** 2026-04-07
**Status:** Ready for planning

<domain>
## Phase Boundary

Administrators can select one or more target sites once from the toolbar and have every feature tab use that selection by default — eliminating the need to re-enter site URLs on each tab. Individual tabs can override the global selection without clearing the global state.

Requirements: SITE-01, SITE-02

Success Criteria:
1. A multi-site picker control is visible in the main toolbar at all times, regardless of which tab is active
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
4. The global site selection persists across tab switches within the same session

</domain>

<decisions>
## Implementation Decisions

### Toolbar site picker placement
- Add a "Select Sites" button to the existing ToolBar (after the Clear Session button, separated by a Separator)
- Next to the button, show a summary label: "3 site(s) selected" or "No sites selected"
- Clicking the button opens the existing SitePickerDialog pattern (reuse from PermissionsViewModel)
- The picker requires a connected tenant (button disabled when no profile is connected)

### Global selection broadcast
- Create a new `GlobalSitesChangedMessage` (ValueChangedMessage<IReadOnlyList<SiteInfo>>) sent via WeakReferenceMessenger when the toolbar selection changes
- `MainWindowViewModel` owns the global site selection state: `ObservableCollection<SiteInfo> GlobalSelectedSites`
- On tenant switch, clear the global selection (sites belong to a tenant)

### Tab consumption of global selection
- `FeatureViewModelBase` registers for `GlobalSitesChangedMessage` in `OnActivated()` and stores the global sites in a protected property `IReadOnlyList<SiteInfo> GlobalSites`
- Each tab's `RunOperationAsync` checks: if local override sites exist, use those; else if GlobalSites is non-empty, use those; else fall back to the SiteUrl text box
- The SiteUrl TextBox on each tab shows a placeholder/hint when global sites are active (e.g., "Using 3 globally selected sites" as watermark text)

### Local override behavior
- Tabs that already have per-tab site pickers (like Permissions) keep them
- When a user picks sites locally on a tab, that overrides the global selection for that tab only
- A "Clear local selection" action resets the tab back to using global sites
- The global selection in the toolbar is never modified by per-tab overrides

### Tabs that DO NOT consume global sites
- Settings tab: no site URL needed
- Bulk Sites tab: creates sites from CSV, does not target existing sites
- Templates tab (apply): creates a new site, does not target existing sites

### Tabs that consume global sites (single-site)
- Storage, Search, Duplicates, Folder Structure: these currently take a single SiteUrl
- When global sites are selected, these tabs use the first site in the global list by default
- The SiteUrl TextBox is pre-filled with the first global site URL (user can change it = local override)

### Tabs that consume global sites (multi-site)
- Permissions: already supports multi-site; global sites pre-populate its SelectedSites collection
- Transfer: source site pre-filled from first global site

### Claude's Discretion
- Exact XAML layout of the toolbar site picker button and label
- Whether to refactor SitePickerDialog or reuse as-is from MainWindow code-behind
- Internal naming of properties and helper methods
- Whether to add a chip/tag display for selected sites or keep it as a count label
- Localization key names for new strings

</decisions>

<code_context>
## Existing Code Insights

### Reusable Assets
- `SitePickerDialog` (Views/Dialogs/): Filterable checkbox list of sites with Select All/Deselect All — loads from `ISiteListService.GetSitesAsync()`. Currently only wired from PermissionsView; needs to be wired from MainWindow toolbar too.
- `SiteInfo(string Url, string Title)` record (Core/Models/): Already used by SitePickerDialog and PermissionsViewModel
- `ISiteListService.GetSitesAsync(TenantProfile, progress, ct)`: Enumerates all sites in a tenant. Already registered in DI.
- `TenantSwitchedMessage`: Broadcast pattern for tenant changes — global site selection follows the same pattern
- `WeakReferenceMessenger`: Already used for TenantSwitched and ProgressUpdated messages
- `FeatureViewModelBase.OnActivated()`: Already registers for TenantSwitchedMessage — extend to also register for GlobalSitesChangedMessage

### Established Patterns
- Dialog factories set on ViewModels as `Func<Window>?` from View code-behind (keeps Window refs out of VMs)
- `[ObservableProperty]` for bindable state
- `ObservableCollection<T>` for list-bound UI elements
- Tab content resolved from DI in MainWindow.xaml.cs
- Localization via `TranslationSource.Instance["key"]` with Strings.resx / Strings.fr.resx

### Integration Points
- `MainWindow.xaml`: Add site picker button + label to ToolBar
- `MainWindowViewModel.cs`: Add GlobalSelectedSites, OpenGlobalSitePickerCommand, GlobalSitesChangedMessage broadcast
- `MainWindow.xaml.cs`: Wire SitePickerDialog factory for the toolbar (same pattern as PermissionsView)
- `FeatureViewModelBase.cs`: Register for GlobalSitesChangedMessage, add GlobalSites property
- `Core/Messages/`: New GlobalSitesChangedMessage class
- Each tab ViewModel: Update RunOperationAsync to check GlobalSites before falling back to SiteUrl
- `Strings.resx` / `Strings.fr.resx`: New localization keys for toolbar site picker
- `App.xaml.cs`: No new DI registrations needed (SitePickerDialog factory and ISiteListService already registered)

### Key Files
| File | Role |
|------|------|
| `MainWindow.xaml` | Toolbar XAML — add site picker controls |
| `MainWindowViewModel.cs` | Global selection state + command |
| `MainWindow.xaml.cs` | Wire SitePickerDialog factory for toolbar |
| `FeatureViewModelBase.cs` | Base class — receive global sites message |
| `Core/Messages/TenantSwitchedMessage.cs` | Pattern reference for new message |
| `Views/Dialogs/SitePickerDialog.xaml.cs` | Reuse as-is |
| `ViewModels/Tabs/PermissionsViewModel.cs` | Already has multi-site pattern — adapt to consume global sites |
| `ViewModels/Tabs/StorageViewModel.cs` | Single-site pattern — adapt to consume global sites |

</code_context>

<specifics>
## Specific Ideas

- The toolbar site count label should update live when sites are selected/deselected
- When no tenant is connected, the "Select Sites" button should be disabled with a tooltip explaining why
- Clearing the session (Clear Session button) should also clear the global site selection
- The global selection should survive tab switching (it lives on MainWindowViewModel, not on any tab)

</specifics>

<deferred>
## Deferred Ideas

None — all items are within phase scope

</deferred>

---

*Phase: 06-global-site-selection*
*Context gathered: 2026-04-07*
