132 lines
6.9 KiB
Markdown
132 lines
6.9 KiB
Markdown
# 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*
|