--- phase: 07-user-access-audit plan: 05 type: execute wave: 4 depends_on: ["07-04"] files_modified: - SharepointToolbox/Views/Tabs/UserAccessAuditView.xaml - SharepointToolbox/Views/Tabs/UserAccessAuditView.xaml.cs autonomous: true requirements: - UACC-01 - UACC-02 must_haves: truths: - "View has left panel with people picker (TextBox + autocomplete Popup), site picker button, scan options, run/cancel/export buttons" - "View has right panel with summary banner (total accesses, sites, high-privilege) and DataGrid" - "DataGrid columns: User, Site, Object, Permission Level, Access Type, Granted Through" - "Access type rows are color-coded: Direct (blue tint), Group (green tint), Inherited (gray tint)" - "High-privilege entries show warning icon, external users show guest badge" - "Group-by toggle switches DataGrid GroupStyle between user and site" - "Filter TextBox filters results in real-time" - "People picker shows autocomplete Popup with search results below the search TextBox" artifacts: - path: "SharepointToolbox/Views/Tabs/UserAccessAuditView.xaml" provides: "XAML layout for User Access Audit tab" contains: "UserAccessAuditView" - path: "SharepointToolbox/Views/Tabs/UserAccessAuditView.xaml.cs" provides: "Code-behind for dialog factory wiring" contains: "UserAccessAuditView" key_links: - from: "SharepointToolbox/Views/Tabs/UserAccessAuditView.xaml" to: "SharepointToolbox/ViewModels/Tabs/UserAccessAuditViewModel.cs" via: "DataContext binding to ViewModel properties" pattern: "Binding" --- Create the XAML view for the User Access Audit tab with people picker autocomplete, site picker, scan options, summary banner, color-coded DataGrid with grouping, filter, and export buttons. Purpose: The visual interface for the audit feature. Follows the established PermissionsView two-panel layout pattern. Output: UserAccessAuditView.xaml + UserAccessAuditView.xaml.cs @C:/Users/dev/.claude/get-shit-done/workflows/execute-plan.md @C:/Users/dev/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/phases/07-user-access-audit/07-CONTEXT.md @.planning/phases/07-user-access-audit/07-04-SUMMARY.md From SharepointToolbox/ViewModels/Tabs/UserAccessAuditViewModel.cs (expected): ```csharp // People picker [ObservableProperty] string SearchQuery; [ObservableProperty] ObservableCollection SearchResults; [ObservableProperty] ObservableCollection SelectedUsers; [ObservableProperty] bool IsSearching; RelayCommand AddUserCommand; RelayCommand RemoveUserCommand; string SelectedUsersLabel { get; } // Site selection ObservableCollection SelectedSites; RelayCommand OpenSitePickerCommand; string SitesSelectedLabel { get; } // Scan options [ObservableProperty] bool IncludeInherited; [ObservableProperty] bool ScanFolders; [ObservableProperty] bool IncludeSubsites; // Results [ObservableProperty] ObservableCollection Results; ICollectionView ResultsView { get; } [ObservableProperty] string FilterText; [ObservableProperty] bool IsGroupByUser; // Summary int TotalAccessCount { get; } int SitesCount { get; } int HighPrivilegeCount { get; } // Commands (from base + this VM) IAsyncRelayCommand RunCommand; // from base RelayCommand CancelCommand; // from base IAsyncRelayCommand ExportCsvCommand; IAsyncRelayCommand ExportHtmlCommand; // State from base bool IsRunning; string StatusMessage; int ProgressValue; ``` PermissionsView.xaml: Left panel (290px) + Right panel (*) + Bottom StatusBar Localization: {Binding Source={x:Static loc:TranslationSource.Instance}, Path=[key]} Task 1: Create UserAccessAuditView XAML layout SharepointToolbox/Views/Tabs/UserAccessAuditView.xaml Create `SharepointToolbox/Views/Tabs/UserAccessAuditView.xaml` following the PermissionsView.xaml pattern (left panel config + right panel DataGrid + bottom status bar). Layout structure: 1. **Left panel (290px)** in DockPanel: a. **People Picker GroupBox** ("Select Users"): - TextBox bound to SearchQuery (UpdateSourceTrigger=PropertyChanged) - Below TextBox: a Popup (IsOpen bound to SearchResults.Count > 0 and IsSearching or has results) containing a ListBox of SearchResults. Each item shows DisplayName + Mail. Clicking an item fires AddUserCommand. - Below Popup: ItemsControl showing SelectedUsers as removable chips/pills. Each pill has user name + X button (RemoveUserCommand). - TextBlock showing SelectedUsersLabel b. **Site Selection GroupBox** ("Target Sites"): - Button "Select Sites" bound to OpenSitePickerCommand - TextBlock showing SitesSelectedLabel c. **Scan Options GroupBox**: - CheckBox "Include inherited" bound to IncludeInherited - CheckBox "Scan folders" bound to ScanFolders - CheckBox "Include subsites" bound to IncludeSubsites d. **Action buttons**: - Run Audit / Cancel row - Export CSV / Export HTML row 2. **Right panel** in Grid: a. **Summary banner** (StackPanel, horizontal, at top): - Three stat cards (Border with background): Total Accesses, Sites, High Privilege - Each shows the count value and label b. **Toolbar row**: - Filter TextBox bound to FilterText - ToggleButton "Group by User" / "Group by Site" bound to IsGroupByUser c. **DataGrid** bound to ResultsView (ICollectionView): - Columns: User (DisplayName), Site (SiteTitle), Object (ObjectTitle), Permission Level, Access Type, Granted Through - Row style with DataTriggers for color coding: - AccessType.Direct: light blue background (#EBF5FB) - AccessType.Group: light green background (#EAFAF1) - AccessType.Inherited: light gray background (#F4F6F6) - DataTemplate for Access Type column: TextBlock with icon (Unicode chars: Direct = key icon, Group = people icon, Inherited = arrow-down icon) - DataTrigger for IsHighPrivilege=true: bold text + warning icon (Unicode shield) - DataTrigger for IsExternalUser=true: guest badge styling - GroupStyle with expander header showing group name + count d. **DataGrid GroupStyle**: Expander with header template showing group key (user name or site title) and item count 3. **Bottom StatusBar** spanning both columns: ProgressBar + StatusMessage (same as PermissionsView) Color-coding approach: - Use Style with DataTriggers on the DataGrid Row, binding to AccessType property - Access type icons: use Unicode characters that render in Segoe UI Symbol: - Direct: "\uE192" (key) or plain text "Direct" with blue foreground - Group: "\uE125" (people) or plain text "Group" with green foreground - Inherited: "\uE19C" (hierarchy) or plain text "Inherited" with gray foreground - High privilege warning: "\u26A0" (warning triangle) prepended to permission level - External user badge: orange-tinted pill in user column The people picker Popup approach: - Use a Popup element positioned below the SearchQuery TextBox - Popup.IsOpen bound to a computed property (HasSearchResults) or use a MultiBinding - Popup contains a ListBox with ItemTemplate showing DisplayName and Mail - Clicking a ListBox item invokes AddUserCommand via EventTrigger or by binding SelectedItem - Simpler alternative: Use a ListBox directly below the TextBox (not a Popup) that is visible when SearchResults.Count > 0. This avoids Popup complexity. For the autocomplete, the simplest WPF approach is: - ListBox below TextBox, Visibility collapsed when SearchResults is empty - ListBox.ItemTemplate shows "{DisplayName} ({Mail})" - On SelectionChanged or mouse click, add user to SelectedUsers via AddUserCommand Localization keys to use (will be added in 07-07): - audit.grp.users, audit.grp.sites, audit.grp.options - audit.search.placeholder, audit.btn.run, audit.btn.exportCsv, audit.btn.exportHtml - audit.summary.total, audit.summary.sites, audit.summary.highPriv - audit.toggle.byUser, audit.toggle.bySite - audit.filter.placeholder - btn.cancel (existing key) cd "C:\Users\dev\Documents\projets\Sharepoint" && dotnet build SharepointToolbox/SharepointToolbox.csproj --no-incremental 2>&1 | tail -5 UserAccessAuditView.xaml compiles. Layout has: people picker with autocomplete list + removable user pills, site picker button, scan option checkboxes, run/cancel/export buttons, summary banner with 3 stats, filter TextBox, group-by toggle, color-coded DataGrid with access type icons and group headers, status bar. Task 2: Create UserAccessAuditView code-behind SharepointToolbox/Views/Tabs/UserAccessAuditView.xaml.cs Create `SharepointToolbox/Views/Tabs/UserAccessAuditView.xaml.cs`: ```csharp using System.Windows.Controls; namespace SharepointToolbox.Views.Tabs; public partial class UserAccessAuditView : UserControl { public UserAccessAuditView(ViewModels.Tabs.UserAccessAuditViewModel viewModel) { InitializeComponent(); DataContext = viewModel; // Wire site picker dialog factory (same pattern as PermissionsView) viewModel.OpenSitePickerDialog = () => { if (viewModel.CurrentProfile is null) return null!; var factory = new Views.Dialogs.SitePickerDialog( App.Current.MainWindow is MainWindow mw ? ((IServiceProvider)mw.GetType().GetField("_serviceProvider", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) ?.GetValue(mw)!).GetService(typeof(Services.ISiteListService)) as Services.ISiteListService : null!, viewModel.CurrentProfile); return factory; }; } } ``` IMPORTANT: The actual dialog factory wiring will be cleaner — it will be done from MainWindow.xaml.cs in plan 07-07 (same pattern as PermissionsView where the View's constructor receives the ViewModel from DI, and MainWindow sets the dialog factory after creating the View). So keep the code-behind minimal: ```csharp using System.Windows.Controls; using SharepointToolbox.ViewModels.Tabs; namespace SharepointToolbox.Views.Tabs; public partial class UserAccessAuditView : UserControl { public UserAccessAuditView(UserAccessAuditViewModel viewModel) { InitializeComponent(); DataContext = viewModel; } } ``` The dialog factory wiring for the site picker will be handled in 07-07 from MainWindow.xaml.cs, following the same pattern where MainWindow wires dialog factories after resolving Views from DI. cd "C:\Users\dev\Documents\projets\Sharepoint" && dotnet build SharepointToolbox/SharepointToolbox.csproj --no-incremental 2>&1 | tail -5 UserAccessAuditView.xaml.cs compiles, receives UserAccessAuditViewModel via constructor injection, sets DataContext. - `dotnet build SharepointToolbox/SharepointToolbox.csproj` succeeds with 0 errors - UserAccessAuditView.xaml + .cs compile as a UserControl - XAML has two-panel layout with all required UI elements - DataGrid has color-coded rows via DataTriggers on AccessType - Summary banner shows three computed stats - People picker has search TextBox + results list + selected user pills The complete audit tab UI is rendered: administrators see a people picker, site selector, scan options, and a rich DataGrid with color-coded access types, grouping toggle, filter, summary banner, and export buttons. All bound to ViewModel properties from 07-04. After completion, create `.planning/phases/07-user-access-audit/07-05-SUMMARY.md`