feat(08-01): add SimplifiedPermissionEntry wrapper and PermissionSummary model
- SimplifiedPermissionEntry wraps PermissionEntry with computed labels and risk level - Passthrough properties preserve DataGrid binding compatibility - PermissionSummary record for grouped risk-level counts - PermissionSummaryBuilder always returns all 4 risk levels for consistent UI Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
64
SharepointToolbox/Core/Models/PermissionSummary.cs
Normal file
64
SharepointToolbox/Core/Models/PermissionSummary.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
namespace SharepointToolbox.Core.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Summary counts of permission entries grouped by risk level.
|
||||
/// Displayed in the summary panel when simplified mode is active.
|
||||
/// </summary>
|
||||
public record PermissionSummary(
|
||||
/// <summary>Label for this group (e.g. "High Risk", "Read Only").</summary>
|
||||
string Label,
|
||||
/// <summary>The risk level this group represents.</summary>
|
||||
RiskLevel RiskLevel,
|
||||
/// <summary>Number of permission entries at this risk level.</summary>
|
||||
int Count,
|
||||
/// <summary>Number of distinct users at this risk level.</summary>
|
||||
int DistinctUsers
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Computes PermissionSummary groups from SimplifiedPermissionEntry collections.
|
||||
/// </summary>
|
||||
public static class PermissionSummaryBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// Risk level display labels.
|
||||
/// </summary>
|
||||
private static readonly Dictionary<RiskLevel, string> Labels = new()
|
||||
{
|
||||
[RiskLevel.High] = "High Risk",
|
||||
[RiskLevel.Medium] = "Medium Risk",
|
||||
[RiskLevel.Low] = "Low Risk",
|
||||
[RiskLevel.ReadOnly] = "Read Only",
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Builds summary counts grouped by risk level from a collection of simplified entries.
|
||||
/// Always returns all 4 risk levels, even if count is 0, for consistent UI binding.
|
||||
/// </summary>
|
||||
public static IReadOnlyList<PermissionSummary> Build(
|
||||
IEnumerable<SimplifiedPermissionEntry> entries)
|
||||
{
|
||||
var grouped = entries
|
||||
.GroupBy(e => e.RiskLevel)
|
||||
.ToDictionary(g => g.Key, g => g.ToList());
|
||||
|
||||
return Enum.GetValues<RiskLevel>()
|
||||
.Select(level =>
|
||||
{
|
||||
var items = grouped.GetValueOrDefault(level, new List<SimplifiedPermissionEntry>());
|
||||
var distinctUsers = items
|
||||
.SelectMany(e => e.UserLogins.Split(';', StringSplitOptions.RemoveEmptyEntries))
|
||||
.Select(u => u.Trim())
|
||||
.Where(u => u.Length > 0)
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
.Count();
|
||||
|
||||
return new PermissionSummary(
|
||||
Label: Labels[level],
|
||||
RiskLevel: level,
|
||||
Count: items.Count,
|
||||
DistinctUsers: distinctUsers);
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
61
SharepointToolbox/Core/Models/SimplifiedPermissionEntry.cs
Normal file
61
SharepointToolbox/Core/Models/SimplifiedPermissionEntry.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using SharepointToolbox.Core.Helpers;
|
||||
|
||||
namespace SharepointToolbox.Core.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Presentation wrapper around PermissionEntry that adds simplified labels
|
||||
/// and risk level classification without modifying the immutable source record.
|
||||
/// Used as the DataGrid ItemsSource when simplified mode is active.
|
||||
/// </summary>
|
||||
public class SimplifiedPermissionEntry
|
||||
{
|
||||
/// <summary>The original immutable PermissionEntry.</summary>
|
||||
public PermissionEntry Inner { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Human-readable labels for the permission levels.
|
||||
/// E.g. "Can edit files and list items" instead of "Contribute".
|
||||
/// </summary>
|
||||
public string SimplifiedLabels { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The highest risk level across all permission levels on this entry.
|
||||
/// Used for row-level color coding.
|
||||
/// </summary>
|
||||
public RiskLevel RiskLevel { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Individual mapping results for each permission level in the entry.
|
||||
/// Used when detailed breakdown per-role is needed.
|
||||
/// </summary>
|
||||
public IReadOnlyList<PermissionLevelMapping.MappingResult> Mappings { get; }
|
||||
|
||||
// ── Passthrough properties for DataGrid binding ──
|
||||
|
||||
public string ObjectType => Inner.ObjectType;
|
||||
public string Title => Inner.Title;
|
||||
public string Url => Inner.Url;
|
||||
public bool HasUniquePermissions => Inner.HasUniquePermissions;
|
||||
public string Users => Inner.Users;
|
||||
public string UserLogins => Inner.UserLogins;
|
||||
public string PermissionLevels => Inner.PermissionLevels;
|
||||
public string GrantedThrough => Inner.GrantedThrough;
|
||||
public string PrincipalType => Inner.PrincipalType;
|
||||
|
||||
public SimplifiedPermissionEntry(PermissionEntry entry)
|
||||
{
|
||||
Inner = entry;
|
||||
Mappings = PermissionLevelMapping.GetMappings(entry.PermissionLevels);
|
||||
SimplifiedLabels = PermissionLevelMapping.GetSimplifiedLabels(entry.PermissionLevels);
|
||||
RiskLevel = PermissionLevelMapping.GetHighestRisk(entry.PermissionLevels);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates SimplifiedPermissionEntry wrappers for a collection of entries.
|
||||
/// </summary>
|
||||
public static IReadOnlyList<SimplifiedPermissionEntry> WrapAll(
|
||||
IEnumerable<PermissionEntry> entries)
|
||||
{
|
||||
return entries.Select(e => new SimplifiedPermissionEntry(e)).ToList();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user