---
phase: 08-simplified-permissions
plan: 02
type: execute
wave: 2
depends_on: ["08-01"]
files_modified:
  - SharepointToolbox/ViewModels/Tabs/PermissionsViewModel.cs
autonomous: true
requirements:
  - SIMP-01
  - SIMP-02
  - SIMP-03
must_haves:
  truths:
    - "IsSimplifiedMode toggle switches between raw and simplified permission labels in the DataGrid"
    - "IsDetailView toggle controls whether individual rows are shown or collapsed into summary rows"
    - "Toggling modes does NOT re-run the scan — it re-renders from existing Results data"
    - "Summary counts per risk level are available as observable properties when simplified mode is on"
    - "SimplifiedResults collection is computed from Results whenever Results changes or mode toggles"
    - "ActiveItemsSource provides the correct collection for DataGrid binding depending on current mode"
  artifacts:
    - path: "SharepointToolbox/ViewModels/Tabs/PermissionsViewModel.cs"
      provides: "Extended PermissionsViewModel with simplified mode, detail toggle, and summary"
      contains: "IsSimplifiedMode"
  key_links:
    - from: "SharepointToolbox/ViewModels/Tabs/PermissionsViewModel.cs"
      to: "SharepointToolbox/Core/Helpers/PermissionLevelMapping.cs"
      via: "SimplifiedPermissionEntry.WrapAll uses PermissionLevelMapping internally"
      pattern: "SimplifiedPermissionEntry\\.WrapAll"
    - from: "SharepointToolbox/ViewModels/Tabs/PermissionsViewModel.cs"
      to: "SharepointToolbox/Core/Models/PermissionSummary.cs"
      via: "PermissionSummaryBuilder.Build computes summary from simplified entries"
      pattern: "PermissionSummaryBuilder\\.Build"
---

<objective>
Extend PermissionsViewModel with IsSimplifiedMode toggle, IsDetailView toggle, SimplifiedResults collection, summary statistics, and an ActiveItemsSource that the DataGrid binds to. All toggles re-render from cached data — no re-scan required.

Purpose: This is the ViewModel logic for all three SIMP requirements. The View (08-03) binds to these new properties.
Output: Updated PermissionsViewModel.cs
</objective>

<execution_context>
@C:/Users/dev/.claude/get-shit-done/workflows/execute-plan.md
@C:/Users/dev/.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/phases/08-simplified-permissions/08-01-SUMMARY.md

<interfaces>
<!-- From 08-01: New types this plan consumes -->
From SharepointToolbox/Core/Models/RiskLevel.cs:
```csharp
public enum RiskLevel { High, Medium, Low, ReadOnly }
```

From SharepointToolbox/Core/Helpers/PermissionLevelMapping.cs:
```csharp
public static class PermissionLevelMapping
{
    public record MappingResult(string Label, RiskLevel RiskLevel);
    public static MappingResult GetMapping(string roleName);
    public static IReadOnlyList<MappingResult> GetMappings(string permissionLevels);
    public static RiskLevel GetHighestRisk(string permissionLevels);
    public static string GetSimplifiedLabels(string permissionLevels);
}
```

From SharepointToolbox/Core/Models/SimplifiedPermissionEntry.cs:
```csharp
public class SimplifiedPermissionEntry
{
    public PermissionEntry Inner { get; }
    public string SimplifiedLabels { get; }
    public RiskLevel RiskLevel { get; }
    public IReadOnlyList<PermissionLevelMapping.MappingResult> Mappings { get; }
    // Passthrough: ObjectType, Title, Url, HasUniquePermissions, Users, UserLogins,
    //              PermissionLevels, GrantedThrough, PrincipalType
    public static IReadOnlyList<SimplifiedPermissionEntry> WrapAll(IEnumerable<PermissionEntry> entries);
}
```

From SharepointToolbox/Core/Models/PermissionSummary.cs:
```csharp
public record PermissionSummary(string Label, RiskLevel RiskLevel, int Count, int DistinctUsers);

public static class PermissionSummaryBuilder
{
    public static IReadOnlyList<PermissionSummary> Build(IEnumerable<SimplifiedPermissionEntry> entries);
}
```

<!-- Current PermissionsViewModel — the file being modified -->
From SharepointToolbox/ViewModels/Tabs/PermissionsViewModel.cs:
```csharp
public partial class PermissionsViewModel : FeatureViewModelBase
{
    // Existing fields and services — unchanged
    [ObservableProperty] private ObservableCollection<PermissionEntry> _results = new();
    
    // Existing commands — unchanged
    public IAsyncRelayCommand ExportCsvCommand { get; }
    public IAsyncRelayCommand ExportHtmlCommand { get; }
    public RelayCommand OpenSitePickerCommand { get; }
    
    // Full constructor and test constructor (internal)
}
```
</interfaces>
</context>

<tasks>

<task type="auto">
  <name>Task 1: Add simplified mode properties and summary computation to PermissionsViewModel</name>
  <files>SharepointToolbox/ViewModels/Tabs/PermissionsViewModel.cs</files>
  <action>
    Modify `SharepointToolbox/ViewModels/Tabs/PermissionsViewModel.cs` to add simplified mode support. Add the following new using statements at the top:

    ```csharp
    using SharepointToolbox.Core.Helpers;
    ```

    Add these new observable properties to the class (in the "Observable properties" section):

    ```csharp
    /// <summary>
    /// When true, displays simplified plain-language labels instead of raw SharePoint role names.
    /// Toggling does not re-run the scan.
    /// </summary>
    [ObservableProperty]
    private bool _isSimplifiedMode;

    /// <summary>
    /// When true, shows individual item-level rows (detailed view).
    /// When false, shows only summary rows grouped by risk level (simple view).
    /// Only meaningful when IsSimplifiedMode is true.
    /// </summary>
    [ObservableProperty]
    private bool _isDetailView = true;
    ```

    Add these computed collection properties (NOT ObservableProperty — manually raised):

    ```csharp
    /// <summary>
    /// Simplified wrappers computed from Results. Rebuilt when Results changes.
    /// </summary>
    private IReadOnlyList<SimplifiedPermissionEntry> _simplifiedResults = Array.Empty<SimplifiedPermissionEntry>();
    public IReadOnlyList<SimplifiedPermissionEntry> SimplifiedResults
    {
        get => _simplifiedResults;
        private set => SetProperty(ref _simplifiedResults, value);
    }

    /// <summary>
    /// Summary counts grouped by risk level. Rebuilt when SimplifiedResults changes.
    /// </summary>
    private IReadOnlyList<PermissionSummary> _summaries = Array.Empty<PermissionSummary>();
    public IReadOnlyList<PermissionSummary> Summaries
    {
        get => _summaries;
        private set => SetProperty(ref _summaries, value);
    }

    /// <summary>
    /// The collection the DataGrid actually binds to. Returns:
    /// - Results (raw) when simplified mode is OFF
    /// - SimplifiedResults when simplified mode is ON and detail view is ON
    /// - (View handles summary display separately via Summaries property)
    /// </summary>
    public object ActiveItemsSource => IsSimplifiedMode
        ? (object)SimplifiedResults
        : Results;
    ```

    Add partial methods triggered by property changes:

    ```csharp
    partial void OnIsSimplifiedModeChanged(bool value)
    {
        if (value && Results.Count > 0)
            RebuildSimplifiedData();
        OnPropertyChanged(nameof(ActiveItemsSource));
    }

    partial void OnIsDetailViewChanged(bool value)
    {
        OnPropertyChanged(nameof(ActiveItemsSource));
    }
    ```

    Add a private method to rebuild simplified data from existing Results:

    ```csharp
    /// <summary>
    /// Recomputes SimplifiedResults and Summaries from the current Results collection.
    /// Called when Results changes or when simplified mode is toggled on.
    /// </summary>
    private void RebuildSimplifiedData()
    {
        SimplifiedResults = SimplifiedPermissionEntry.WrapAll(Results);
        Summaries = PermissionSummaryBuilder.Build(SimplifiedResults);
    }
    ```

    Modify the existing `RunOperationAsync` method: after the line that sets `Results = new ObservableCollection<PermissionEntry>(allEntries);` (both in the dispatcher branch and the else branch), add:

    ```csharp
    if (IsSimplifiedMode)
        RebuildSimplifiedData();
    OnPropertyChanged(nameof(ActiveItemsSource));
    ```

    So the end of RunOperationAsync becomes (both branches):
    ```csharp
    Results = new ObservableCollection<PermissionEntry>(allEntries);
    if (IsSimplifiedMode)
        RebuildSimplifiedData();
    OnPropertyChanged(nameof(ActiveItemsSource));
    ```

    Modify `OnTenantSwitched` to also reset simplified state:
    After `Results = new ObservableCollection<PermissionEntry>();` add:
    ```csharp
    SimplifiedResults = Array.Empty<SimplifiedPermissionEntry>();
    Summaries = Array.Empty<PermissionSummary>();
    OnPropertyChanged(nameof(ActiveItemsSource));
    ```

    Do NOT change:
    - Constructor signatures (both full and test constructors remain unchanged)
    - Existing properties (SiteUrl, IncludeInherited, ScanFolders, etc.)
    - ExportCsvCommand and ExportHtmlCommand implementations (export updates are in plan 08-04)
    - OpenSitePickerCommand
    - _hasLocalSiteOverride / OnGlobalSitesChanged logic
  </action>
  <verify>
    <automated>cd "C:\Users\dev\Documents\projets\Sharepoint" && dotnet build SharepointToolbox/SharepointToolbox.csproj --no-incremental 2>&1 | tail -5</automated>
  </verify>
  <done>PermissionsViewModel has IsSimplifiedMode, IsDetailView, SimplifiedResults, Summaries, and ActiveItemsSource properties. Toggling IsSimplifiedMode rebuilds simplified data from cached Results without re-scanning. Toggling IsDetailView triggers ActiveItemsSource change notification. Existing tests still compile (no constructor changes).</done>
</task>

</tasks>

<verification>
- `dotnet build SharepointToolbox/SharepointToolbox.csproj` succeeds with 0 errors
- `dotnet test SharepointToolbox.Tests/ --filter PermissionsViewModelTests` passes (no constructor changes)
- PermissionsViewModel has IsSimplifiedMode, IsDetailView, SimplifiedResults, Summaries, ActiveItemsSource
- Toggling IsSimplifiedMode calls RebuildSimplifiedData + raises ActiveItemsSource changed
- RunOperationAsync calls RebuildSimplifiedData when IsSimplifiedMode is true
- OnTenantSwitched resets SimplifiedResults and Summaries
</verification>

<success_criteria>
The ViewModel is the orchestration layer for SIMP-01/02/03. All mode toggles re-render from cached data. The View (08-03) can bind to IsSimplifiedMode, IsDetailView, ActiveItemsSource, and Summaries. Export services (08-04) can access SimplifiedResults and IsSimplifiedMode.
</success_criteria>

<output>
After completion, create `.planning/phases/08-simplified-permissions/08-02-SUMMARY.md`
</output>
