feat(17-02): wire ISharePointGroupResolver into PermissionsViewModel export flow
- Add _groupResolver field (ISharePointGroupResolver?) with constructor injection - ISharePointGroupResolver added as optional last parameter in main constructor - ExportHtmlAsync resolves SharePoint group names before calling WriteAsync - Gracefully handles resolution failure with LogWarning, exports without expansion - Both WriteAsync call sites pass groupMembers dict (standard and simplified paths)
This commit is contained in:
@@ -27,6 +27,7 @@ public partial class PermissionsViewModel : FeatureViewModelBase
|
||||
private readonly CsvExportService? _csvExportService;
|
||||
private readonly HtmlExportService? _htmlExportService;
|
||||
private readonly IBrandingService? _brandingService;
|
||||
private readonly ISharePointGroupResolver? _groupResolver;
|
||||
private readonly ILogger<FeatureViewModelBase> _logger;
|
||||
|
||||
// ── Observable properties ───────────────────────────────────────────────
|
||||
@@ -134,7 +135,8 @@ public partial class PermissionsViewModel : FeatureViewModelBase
|
||||
CsvExportService csvExportService,
|
||||
HtmlExportService htmlExportService,
|
||||
IBrandingService brandingService,
|
||||
ILogger<FeatureViewModelBase> logger)
|
||||
ILogger<FeatureViewModelBase> logger,
|
||||
ISharePointGroupResolver? groupResolver = null)
|
||||
: base(logger)
|
||||
{
|
||||
_permissionsService = permissionsService;
|
||||
@@ -143,6 +145,7 @@ public partial class PermissionsViewModel : FeatureViewModelBase
|
||||
_csvExportService = csvExportService;
|
||||
_htmlExportService = htmlExportService;
|
||||
_brandingService = brandingService;
|
||||
_groupResolver = groupResolver;
|
||||
_logger = logger;
|
||||
|
||||
ExportCsvCommand = new AsyncRelayCommand(ExportCsvAsync, CanExport);
|
||||
@@ -330,10 +333,37 @@ public partial class PermissionsViewModel : FeatureViewModelBase
|
||||
branding = new ReportBranding(mspLogo, clientLogo);
|
||||
}
|
||||
|
||||
IReadOnlyDictionary<string, IReadOnlyList<ResolvedMember>>? groupMembers = null;
|
||||
if (_groupResolver != null && Results.Count > 0)
|
||||
{
|
||||
var groupNames = Results
|
||||
.Where(r => r.PrincipalType == "SharePointGroup")
|
||||
.SelectMany(r => r.Users.Split(';', StringSplitOptions.RemoveEmptyEntries))
|
||||
.Select(n => n.Trim())
|
||||
.Where(n => n.Length > 0)
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
.ToList();
|
||||
|
||||
if (groupNames.Count > 0 && _currentProfile != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var ctx = await _sessionManager.GetOrCreateContextAsync(
|
||||
_currentProfile, CancellationToken.None);
|
||||
groupMembers = await _groupResolver.ResolveGroupsAsync(
|
||||
ctx, _currentProfile.ClientId, groupNames, CancellationToken.None);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Group resolution failed — exporting without member expansion.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IsSimplifiedMode && SimplifiedResults.Count > 0)
|
||||
await _htmlExportService.WriteAsync(SimplifiedResults.ToList(), dialog.FileName, CancellationToken.None, branding);
|
||||
await _htmlExportService.WriteAsync(SimplifiedResults.ToList(), dialog.FileName, CancellationToken.None, branding, groupMembers);
|
||||
else
|
||||
await _htmlExportService.WriteAsync(Results, dialog.FileName, CancellationToken.None, branding);
|
||||
await _htmlExportService.WriteAsync(Results, dialog.FileName, CancellationToken.None, branding, groupMembers);
|
||||
OpenFile(dialog.FileName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
Reference in New Issue
Block a user