--- phase: 02-permissions plan: 07 type: execute wave: 4 depends_on: - 02-06 files_modified: - SharepointToolbox/Views/Tabs/PermissionsView.xaml - SharepointToolbox/Views/Tabs/PermissionsView.xaml.cs - SharepointToolbox/App.xaml.cs - SharepointToolbox/MainWindow.xaml - SharepointToolbox/MainWindow.xaml.cs autonomous: false requirements: - PERM-01 - PERM-02 - PERM-03 - PERM-04 - PERM-05 - PERM-06 - PERM-07 must_haves: truths: - "The Permissions tab in the running application shows PermissionsView — not the 'Coming soon' FeatureTabBase stub" - "User can enter a site URL, click Generate Report, see progress, and results appear in a DataGrid" - "User can click Export CSV and Export HTML — file save dialog appears and file is created" - "Scan Options panel shows checkboxes for Scan Folders, Include Inherited Permissions, and a Folder Depth input" - "View Sites button opens SitePickerDialog and selected sites appear as '{N} site(s) selected' label" - "Cancel button stops the scan mid-operation" artifacts: - path: "SharepointToolbox/Views/Tabs/PermissionsView.xaml" provides: "Complete Permissions tab UI" - path: "SharepointToolbox/Views/Tabs/PermissionsView.xaml.cs" provides: "Code-behind: sets DataContext, wires dialog factory" - path: "SharepointToolbox/App.xaml.cs" provides: "DI registration for Phase 2 services" contains: "PermissionsViewModel" - path: "SharepointToolbox/MainWindow.xaml" provides: "Permissions TabItem uses PermissionsView instead of FeatureTabBase stub" key_links: - from: "PermissionsView.xaml.cs" to: "PermissionsViewModel" via: "DataContext = ServiceProvider.GetRequiredService()" pattern: "GetRequiredService.*PermissionsViewModel" - from: "PermissionsView.xaml.cs" to: "SitePickerDialog" via: "viewModel.OpenSitePickerDialog factory" pattern: "OpenSitePickerDialog" - from: "App.xaml.cs" to: "PermissionsViewModel, PermissionsService, SiteListService, CsvExportService, HtmlExportService" via: "services.AddTransient / AddScoped" pattern: "AddTransient.*Permissions" --- Create PermissionsView XAML, wire it into MainWindow replacing the FeatureTabBase stub, register all Phase 2 services in DI, and checkpoint with a human visual verification of the running application. Purpose: This is the integration plan — all services exist, ViewModel exists, now wire everything together and confirm the full feature works end-to-end in the UI. Output: PermissionsView.xaml + .cs, updated App.xaml.cs DI, updated MainWindow.xaml. @C:/Users/SebastienQUEROL/.claude/get-shit-done/workflows/execute-plan.md @C:/Users/SebastienQUEROL/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/phases/02-permissions/02-RESEARCH.md From MainWindow.xaml (current stub — line 45 is the Permissions tab): ```xml ``` PermissionsView code-behind wiring pattern (same as SettingsView from Phase 1): ```csharp public partial class PermissionsView : UserControl { public PermissionsView(IServiceProvider serviceProvider) { InitializeComponent(); var vm = serviceProvider.GetRequiredService(); DataContext = vm; // Wire dialog factory — avoids Window/DI coupling in ViewModel (Phase 1 pattern) vm.OpenSitePickerDialog = () => serviceProvider.GetRequiredService(); } } ``` SitePickerDialog needs the current TenantProfile — pass it via a factory: ```csharp // In PermissionsView code-behind, the dialog factory must pass the current profile from the ViewModel: vm.OpenSitePickerDialog = () => serviceProvider.GetRequiredService>()(vm.CurrentProfile!); // Register in DI: services.AddTransient>(sp => // profile => new SitePickerDialog(sp.GetRequiredService(), profile)); ``` PermissionsView DataGrid columns (results binding): - Object Type (ObjectType) - Title - URL (as hyperlink or plain text) - Has Unique Permissions (HasUniquePermissions — bool, display as Yes/No) - Users - Permission Levels (PermissionLevels) - Granted Through (GrantedThrough) - Principal Type (PrincipalType) All text in XAML uses TranslationSource binding: `{Binding [btn.gen.perms], Source={x:Static loc:TranslationSource.Instance}}` Task 1: Create PermissionsView XAML + code-behind and register DI SharepointToolbox/Views/Tabs/PermissionsView.xaml SharepointToolbox/Views/Tabs/PermissionsView.xaml.cs SharepointToolbox/App.xaml.cs SharepointToolbox/MainWindow.xaml SharepointToolbox/MainWindow.xaml.cs READ App.xaml.cs and MainWindow.xaml before modifying to understand existing structure. Step 1 — Create PermissionsView.xaml: WPF UserControl. Layout with a Grid split into: - Left panel (~280px): Scan configuration - GroupBox "Scan Options" (bound to `[grp.scan.opts]`): - TextBlock + TextBox for SiteUrl (bound to `{Binding SiteUrl}`) - Button "View Sites" (bound to `{Binding [btn.view.sites]}`, Command=`{Binding OpenSitePickerCommand}`) - TextBlock showing `{Binding SitesSelectedLabel}` (e.g., "3 site(s) selected") — expose this as [ObservableProperty] in ViewModel - CheckBox "Scan Folders" (bound to `{Binding ScanFolders}`) - CheckBox "Include Inherited Permissions" (bound to `{Binding IncludeInherited}`) - CheckBox "Recursive (subsites)" (bound to `{Binding IncludeSubsites}`) - Label + TextBox for FolderDepth (bound to `{Binding FolderDepth}`) - CheckBox "Maximum (all levels)" — when checked sets FolderDepth to 999 - Buttons row: "Generate Report" (bound to `{Binding RunCommand}`), "Cancel" (bound to `{Binding CancelCommand}`) - Buttons row: "Export CSV" (bound to `{Binding ExportCsvCommand}`), "Export HTML" (bound to `{Binding ExportHtmlCommand}`) - Right panel (remaining space): Results DataGrid - DataGrid bound to `{Binding Results}`, AutoGenerateColumns=False, IsReadOnly=True, VirtualizingPanel.IsVirtualizing=True, EnableRowVirtualization=True - Columns: ObjectType, Title, Url, HasUniquePermissions (display Yes/No via StringFormat or converter), Users, PermissionLevels, GrantedThrough, PrincipalType - Bottom StatusBar: ProgressBar (bound to `{Binding ProgressValue}`) + TextBlock (bound to `{Binding StatusMessage}`) Step 2 — Create PermissionsView.xaml.cs code-behind: ```csharp public partial class PermissionsView : UserControl { public PermissionsView(IServiceProvider serviceProvider) { InitializeComponent(); var vm = serviceProvider.GetRequiredService(); DataContext = vm; vm.OpenSitePickerDialog = () => { var factory = serviceProvider.GetRequiredService>(); return factory(vm.CurrentProfile ?? new TenantProfile()); }; } } ``` Step 3 — Update App.xaml.cs DI registrations. Add inside the `ConfigureServices` method: ```csharp // Phase 2: Permissions services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient>(sp => profile => new SitePickerDialog(sp.GetRequiredService(), profile)); ``` Step 4 — Update MainWindow.xaml: replace the FIRST `` (the Permissions tab) with: ```xml ``` Add `xmlns:views="clr-namespace:SharepointToolbox.Views.Tabs"` to the Window namespaces if not already present. Add localization key `tab.permissions` = "Permissions" (EN) / "Permissions" (FR — same word) to resx files and Strings.Designer.cs. Step 5 — Update MainWindow.xaml.cs if needed to resolve PermissionsView from DI (same pattern used for SettingsView — check existing code for how the Settings tab UserControl is created). dotnet build C:/Users/dev/Documents/projets/Sharepoint/SharepointToolbox.slnx 2>&1 | tail -5 dotnet build succeeds with 0 errors. All services registered in DI. PermissionsView compiles. MainWindow.xaml has `<views:PermissionsView />` instead of `<controls:FeatureTabBase />` for the Permissions tab. Checkpoint: Visual verification of Permissions tab in running application Human verifies the running application visually as described in how-to-verify below. HUMAN — run app and confirm checklist: tab visible, scan options present, export buttons disabled, French locale works Human types "approved" confirming all 7 checklist items pass. Full Permissions tab: scan configuration panel, DataGrid results display, export buttons, site picker dialog. All Phase 2 services registered in DI. The tab replaces the previous "Coming soon" stub. 1. Run the application (F5 or `dotnet run --project SharepointToolbox`) 2. The Permissions tab is visible in the tab bar — it shows the scan options panel and an empty DataGrid (not "Coming soon") 3. The Scan Options panel shows: Site URL input, View Sites button, Scan Folders checkbox, Include Inherited Permissions checkbox, Recursive checkbox, Folder Depth input, Generate Report button, Cancel button, Export CSV button, Export HTML button 4. Click "View Sites" — SitePickerDialog opens (may fail with auth error if not connected to a tenant — that is expected; verify the dialog opens and shows a loading state or error, not a crash) 5. Export CSV / Export HTML buttons are disabled (grayed out) when no results are loaded 6. Switch the language to French (Settings tab) — all Permissions tab labels change to French text (no English fallback visible) 7. The Cancel button exists and is disabled when no scan is running Type "approved" if all verifications pass, or describe what is wrong - `dotnet build C:/Users/dev/Documents/projets/Sharepoint/SharepointToolbox.slnx` → 0 errors - `dotnet test C:/Users/dev/Documents/projets/Sharepoint/SharepointToolbox.slnx` → all tests pass (Phase 1 + Phase 2) - MainWindow.xaml no longer has `` for the Permissions tab position - App.xaml.cs contains `AddTransient()` - Human confirms: Permissions tab visible and functional in running app - Running application shows Permissions tab with full UI (not a stub) - All Phase 2 services registered in DI: IPermissionsService, ISiteListService, CsvExportService, HtmlExportService - Language switching works — all Phase 2 labels translate to French - Export buttons are disabled when no results; enabled after scan completes - Full test suite passes (Phase 1 + Phase 2: target ~50+ tests passing) After completion, create `.planning/phases/02-permissions/02-07-SUMMARY.md`