docs(06): create phase plan for global site selection (5 plans, 3 waves)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
254
.planning/phases/06-global-site-selection/06-03-PLAN.md
Normal file
254
.planning/phases/06-global-site-selection/06-03-PLAN.md
Normal file
@@ -0,0 +1,254 @@
|
||||
---
|
||||
phase: 06-global-site-selection
|
||||
plan: 03
|
||||
type: execute
|
||||
wave: 2
|
||||
depends_on: [06-02]
|
||||
files_modified:
|
||||
- SharepointToolbox/MainWindow.xaml
|
||||
- SharepointToolbox/MainWindow.xaml.cs
|
||||
- SharepointToolbox/Localization/Strings.resx
|
||||
- SharepointToolbox/Localization/Strings.fr.resx
|
||||
- SharepointToolbox/ViewModels/MainWindowViewModel.cs
|
||||
autonomous: true
|
||||
requirements:
|
||||
- SITE-01
|
||||
must_haves:
|
||||
truths:
|
||||
- "A 'Select Sites' button is visible in the toolbar after the Clear Session button"
|
||||
- "A label next to the button shows the count of selected sites (e.g., '3 site(s) selected') or 'No sites selected'"
|
||||
- "Clicking the button opens SitePickerDialog and updates the global selection"
|
||||
- "The button is disabled when no tenant profile is connected"
|
||||
- "The button and label use localized strings (EN + FR)"
|
||||
- "The global site selection persists across tab switches (lives on MainWindowViewModel)"
|
||||
artifacts:
|
||||
- path: "SharepointToolbox/MainWindow.xaml"
|
||||
provides: "Toolbar with global site picker button and count label"
|
||||
contains: "OpenGlobalSitePickerCommand"
|
||||
- path: "SharepointToolbox/MainWindow.xaml.cs"
|
||||
provides: "SitePickerDialog factory wiring for toolbar"
|
||||
contains: "OpenGlobalSitePickerDialog"
|
||||
- path: "SharepointToolbox/Localization/Strings.resx"
|
||||
provides: "EN localization keys for global site picker"
|
||||
contains: "toolbar.selectSites"
|
||||
- path: "SharepointToolbox/Localization/Strings.fr.resx"
|
||||
provides: "FR localization keys for global site picker"
|
||||
contains: "toolbar.selectSites"
|
||||
key_links:
|
||||
- from: "SharepointToolbox/MainWindow.xaml"
|
||||
to: "SharepointToolbox/ViewModels/MainWindowViewModel.cs"
|
||||
via: "Command binding for OpenGlobalSitePickerCommand"
|
||||
pattern: "OpenGlobalSitePickerCommand"
|
||||
- from: "SharepointToolbox/MainWindow.xaml.cs"
|
||||
to: "SharepointToolbox/Views/Dialogs/SitePickerDialog.xaml.cs"
|
||||
via: "Dialog factory lambda using DI"
|
||||
pattern: "OpenGlobalSitePickerDialog"
|
||||
---
|
||||
|
||||
<objective>
|
||||
Add the global site picker button and count label to the main toolbar, wire the SitePickerDialog factory from code-behind, add localization keys for all new toolbar strings, and update MainWindowViewModel to use localized label text.
|
||||
|
||||
Purpose: Makes the global site selection visible and interactive in the UI. Users see the button at all times regardless of active tab.
|
||||
Output: Updated MainWindow.xaml with toolbar controls, MainWindow.xaml.cs with dialog wiring, localization files with new EN/FR keys, MainWindowViewModel using localized label.
|
||||
</objective>
|
||||
|
||||
<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>
|
||||
|
||||
<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-02-SUMMARY.md
|
||||
|
||||
<interfaces>
|
||||
<!-- MainWindowViewModel properties to bind to (from plan 06-02) -->
|
||||
```csharp
|
||||
public ObservableCollection<SiteInfo> GlobalSelectedSites { get; }
|
||||
public string GlobalSitesSelectedLabel { get; } // "3 site(s) selected" or "No sites selected"
|
||||
public RelayCommand OpenGlobalSitePickerCommand { get; }
|
||||
public Func<Window>? OpenGlobalSitePickerDialog { get; set; } // Factory set by code-behind
|
||||
```
|
||||
|
||||
<!-- Existing toolbar XAML structure -->
|
||||
From SharepointToolbox/MainWindow.xaml (ToolBar section):
|
||||
```xml
|
||||
<ToolBar DockPanel.Dock="Top">
|
||||
<ComboBox Width="220" ... />
|
||||
<Button Content="..." Command="{Binding ConnectCommand}" />
|
||||
<Button Content="..." Command="{Binding ManageProfilesCommand}" />
|
||||
<Separator />
|
||||
<Button Content="..." Command="{Binding ClearSessionCommand}" />
|
||||
<!-- NEW: Separator + Select Sites button + count label go HERE -->
|
||||
</ToolBar>
|
||||
```
|
||||
|
||||
<!-- Dialog factory pattern from PermissionsView (replicate for MainWindow) -->
|
||||
From SharepointToolbox/Views/Tabs/PermissionsView.xaml.cs:
|
||||
```csharp
|
||||
vm.OpenSitePickerDialog = () =>
|
||||
{
|
||||
var factory = serviceProvider.GetRequiredService<Func<TenantProfile, SitePickerDialog>>();
|
||||
return factory(vm.CurrentProfile ?? new TenantProfile());
|
||||
};
|
||||
```
|
||||
|
||||
<!-- Localization binding pattern used throughout the app -->
|
||||
```xml
|
||||
Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[toolbar.connect]}"
|
||||
```
|
||||
|
||||
<!-- TranslationSource pattern for code-behind label -->
|
||||
```csharp
|
||||
Localization.TranslationSource.Instance["key"]
|
||||
```
|
||||
</interfaces>
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Add localization keys for global site picker (EN + FR)</name>
|
||||
<files>SharepointToolbox/Localization/Strings.resx, SharepointToolbox/Localization/Strings.fr.resx</files>
|
||||
<action>
|
||||
Add the following localization keys to both resource files.
|
||||
|
||||
In `Strings.resx` (English), add these data entries (maintain alphabetical ordering with existing keys if the file is sorted, otherwise append at the end before the closing `</root>` tag):
|
||||
|
||||
```xml
|
||||
<data name="toolbar.selectSites" xml:space="preserve">
|
||||
<value>Select Sites</value>
|
||||
</data>
|
||||
<data name="toolbar.selectSites.tooltip" xml:space="preserve">
|
||||
<value>Select target sites for all tabs</value>
|
||||
</data>
|
||||
<data name="toolbar.selectSites.tooltipDisabled" xml:space="preserve">
|
||||
<value>Connect to a tenant first</value>
|
||||
</data>
|
||||
<data name="toolbar.globalSites.count" xml:space="preserve">
|
||||
<value>{0} site(s) selected</value>
|
||||
</data>
|
||||
<data name="toolbar.globalSites.none" xml:space="preserve">
|
||||
<value>No sites selected</value>
|
||||
</data>
|
||||
```
|
||||
|
||||
In `Strings.fr.resx` (French), add the matching entries:
|
||||
|
||||
```xml
|
||||
<data name="toolbar.selectSites" xml:space="preserve">
|
||||
<value>Choisir les sites</value>
|
||||
</data>
|
||||
<data name="toolbar.selectSites.tooltip" xml:space="preserve">
|
||||
<value>Choisir les sites cibles pour tous les onglets</value>
|
||||
</data>
|
||||
<data name="toolbar.selectSites.tooltipDisabled" xml:space="preserve">
|
||||
<value>Connectez-vous d'abord</value>
|
||||
</data>
|
||||
<data name="toolbar.globalSites.count" xml:space="preserve">
|
||||
<value>{0} site(s) selectionne(s)</value>
|
||||
</data>
|
||||
<data name="toolbar.globalSites.none" xml:space="preserve">
|
||||
<value>Aucun site selectionne</value>
|
||||
</data>
|
||||
```
|
||||
|
||||
Verify the resx files are well-formed XML after editing.
|
||||
</action>
|
||||
<verify>
|
||||
<automated>cd "C:\Users\dev\Documents\projets\Sharepoint" && dotnet build SharepointToolbox/SharepointToolbox.csproj --no-incremental 2>&1 | tail -5</automated>
|
||||
</verify>
|
||||
<done>Both Strings.resx and Strings.fr.resx contain the 5 new keys each. Build succeeds (resx compiles).</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Update MainWindowViewModel label to use localized strings</name>
|
||||
<files>SharepointToolbox/ViewModels/MainWindowViewModel.cs</files>
|
||||
<action>
|
||||
Update the GlobalSitesSelectedLabel property (added in plan 06-02) to use the new localization keys instead of hardcoded strings.
|
||||
|
||||
Replace the GlobalSitesSelectedLabel property with:
|
||||
```csharp
|
||||
public string GlobalSitesSelectedLabel =>
|
||||
GlobalSelectedSites.Count > 0
|
||||
? string.Format(Localization.TranslationSource.Instance["toolbar.globalSites.count"], GlobalSelectedSites.Count)
|
||||
: Localization.TranslationSource.Instance["toolbar.globalSites.none"];
|
||||
```
|
||||
|
||||
This follows the same pattern used by PermissionsViewModel.SitesSelectedLabel.
|
||||
</action>
|
||||
<verify>
|
||||
<automated>cd "C:\Users\dev\Documents\projets\Sharepoint" && dotnet build SharepointToolbox/SharepointToolbox.csproj --no-incremental 2>&1 | tail -5</automated>
|
||||
</verify>
|
||||
<done>GlobalSitesSelectedLabel uses TranslationSource localized keys instead of hardcoded strings.</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 3: Add toolbar UI controls and wire SitePickerDialog factory</name>
|
||||
<files>SharepointToolbox/MainWindow.xaml, SharepointToolbox/MainWindow.xaml.cs</files>
|
||||
<action>
|
||||
**MainWindow.xaml** — Add a Separator, "Select Sites" button, and count label to the ToolBar, after the existing Clear Session button:
|
||||
|
||||
```xml
|
||||
<Separator />
|
||||
<Button Content="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[toolbar.selectSites]}"
|
||||
Command="{Binding OpenGlobalSitePickerCommand}"
|
||||
ToolTip="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[toolbar.selectSites.tooltip]}" />
|
||||
<TextBlock Text="{Binding GlobalSitesSelectedLabel}"
|
||||
VerticalAlignment="Center" Margin="6,0,0,0"
|
||||
Foreground="Gray" />
|
||||
```
|
||||
|
||||
Place these three elements immediately after the existing `<Button Content="..." Command="{Binding ClearSessionCommand}" />` line, before the closing `</ToolBar>` tag.
|
||||
|
||||
Note: The button is automatically disabled when SelectedProfile is null because OpenGlobalSitePickerCommand's CanExecute checks `SelectedProfile != null`. A disabled tooltip would require a style trigger — defer that (per context, it's Claude's discretion for exact XAML layout).
|
||||
|
||||
**MainWindow.xaml.cs** — Wire the SitePickerDialog factory for the global site picker. In the constructor, after the existing line that wires `OpenProfileManagementDialog`, add:
|
||||
|
||||
```csharp
|
||||
// Wire global site picker dialog factory (same pattern as PermissionsView)
|
||||
viewModel.OpenGlobalSitePickerDialog = () =>
|
||||
{
|
||||
var factory = serviceProvider.GetRequiredService<Func<TenantProfile, SitePickerDialog>>();
|
||||
return factory(viewModel.SelectedProfile ?? new TenantProfile());
|
||||
};
|
||||
```
|
||||
|
||||
This requires adding a using directive for SitePickerDialog if not already present:
|
||||
```csharp
|
||||
using SharepointToolbox.Views.Dialogs; // already imported for ProfileManagementDialog
|
||||
```
|
||||
|
||||
Also add using for TenantProfile if not already present:
|
||||
```csharp
|
||||
using SharepointToolbox.Core.Models; // already imported
|
||||
```
|
||||
</action>
|
||||
<verify>
|
||||
<automated>cd "C:\Users\dev\Documents\projets\Sharepoint" && dotnet build SharepointToolbox/SharepointToolbox.csproj --no-incremental 2>&1 | tail -5</automated>
|
||||
</verify>
|
||||
<done>MainWindow.xaml shows "Select Sites" button + count label in toolbar. MainWindow.xaml.cs wires the SitePickerDialog factory to MainWindowViewModel.OpenGlobalSitePickerDialog. Build succeeds.</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
- `dotnet build SharepointToolbox/SharepointToolbox.csproj` succeeds with 0 errors
|
||||
- MainWindow.xaml ToolBar contains the Select Sites button bound to OpenGlobalSitePickerCommand
|
||||
- MainWindow.xaml ToolBar contains a TextBlock bound to GlobalSitesSelectedLabel
|
||||
- MainWindow.xaml.cs sets viewModel.OpenGlobalSitePickerDialog factory
|
||||
- Strings.resx contains 5 new toolbar.* keys
|
||||
- Strings.fr.resx contains 5 matching FR translations
|
||||
- MainWindowViewModel.GlobalSitesSelectedLabel uses localized strings
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
The toolbar displays a "Select Sites" button and a site count label. Clicking the button opens SitePickerDialog (when connected to a tenant). The label updates to show the count of selected sites. All strings are localized in EN and FR.
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/06-global-site-selection/06-03-SUMMARY.md`
|
||||
</output>
|
||||
Reference in New Issue
Block a user