diff --git a/SharepointToolbox/Core/Models/PermissionSummary.cs b/SharepointToolbox/Core/Models/PermissionSummary.cs new file mode 100644 index 0000000..87fbf7f --- /dev/null +++ b/SharepointToolbox/Core/Models/PermissionSummary.cs @@ -0,0 +1,64 @@ +namespace SharepointToolbox.Core.Models; + +/// +/// Summary counts of permission entries grouped by risk level. +/// Displayed in the summary panel when simplified mode is active. +/// +public record PermissionSummary( + /// Label for this group (e.g. "High Risk", "Read Only"). + string Label, + /// The risk level this group represents. + RiskLevel RiskLevel, + /// Number of permission entries at this risk level. + int Count, + /// Number of distinct users at this risk level. + int DistinctUsers +); + +/// +/// Computes PermissionSummary groups from SimplifiedPermissionEntry collections. +/// +public static class PermissionSummaryBuilder +{ + /// + /// Risk level display labels. + /// + private static readonly Dictionary Labels = new() + { + [RiskLevel.High] = "High Risk", + [RiskLevel.Medium] = "Medium Risk", + [RiskLevel.Low] = "Low Risk", + [RiskLevel.ReadOnly] = "Read Only", + }; + + /// + /// 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. + /// + public static IReadOnlyList Build( + IEnumerable entries) + { + var grouped = entries + .GroupBy(e => e.RiskLevel) + .ToDictionary(g => g.Key, g => g.ToList()); + + return Enum.GetValues() + .Select(level => + { + var items = grouped.GetValueOrDefault(level, new List()); + 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(); + } +} diff --git a/SharepointToolbox/Core/Models/SimplifiedPermissionEntry.cs b/SharepointToolbox/Core/Models/SimplifiedPermissionEntry.cs new file mode 100644 index 0000000..d10ee63 --- /dev/null +++ b/SharepointToolbox/Core/Models/SimplifiedPermissionEntry.cs @@ -0,0 +1,61 @@ +using SharepointToolbox.Core.Helpers; + +namespace SharepointToolbox.Core.Models; + +/// +/// 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. +/// +public class SimplifiedPermissionEntry +{ + /// The original immutable PermissionEntry. + public PermissionEntry Inner { get; } + + /// + /// Human-readable labels for the permission levels. + /// E.g. "Can edit files and list items" instead of "Contribute". + /// + public string SimplifiedLabels { get; } + + /// + /// The highest risk level across all permission levels on this entry. + /// Used for row-level color coding. + /// + public RiskLevel RiskLevel { get; } + + /// + /// Individual mapping results for each permission level in the entry. + /// Used when detailed breakdown per-role is needed. + /// + public IReadOnlyList 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); + } + + /// + /// Creates SimplifiedPermissionEntry wrappers for a collection of entries. + /// + public static IReadOnlyList WrapAll( + IEnumerable entries) + { + return entries.Select(e => new SimplifiedPermissionEntry(e)).ToList(); + } +}