@page "/storage" @attribute [Authorize] @inject IUserSessionService Session @inject ISessionManager SessionMgr @inject IElevationCoordinator Elevation @inject IStorageService StorageSvc @inject StorageCsvExportService CsvExport @inject StorageHtmlExportService HtmlExport @inject WebExportService WebExport @rendermode InteractiveServer

Storage Metrics

@if (!Session.HasProfile) { return; }
Scan Options
@if (_running) { }
@if (!string.IsNullOrEmpty(_error)) {
@_error
} @if (_results.Count > 0) {
Storage Report @_results.Count libraries
@foreach (var n in _results) { }
Library Site Files Total (MB) Versions (MB) Last Modified
@n.Name @n.SiteTitle @n.TotalFileCount.ToString("N0") @((n.TotalSizeBytes / 1048576.0).ToString("F2")) @((n.VersionSizeBytes / 1048576.0).ToString("F2")) @(n.LastModified?.ToString("yyyy-MM-dd") ?? "")
} @code { private string _siteUrl = string.Empty; private bool _includeSubsites, _includeHidden = true, _includeRecycleBin = true; private bool _running; private string _status = string.Empty, _error = string.Empty; private int _current, _total; private List _results = new(); private CancellationTokenSource? _cts; private async Task RunScan() { _error = string.Empty; _results.Clear(); _running = true; _cts = new CancellationTokenSource(); var siteUrl = string.IsNullOrWhiteSpace(_siteUrl) ? Session.CurrentProfile!.TenantUrl : _siteUrl.Trim(); var progress = new Progress(p => { _status = p.Message; _current = p.Current; _total = p.Total; InvokeAsync(StateHasChanged); }); try { var opts = new StorageScanOptions(IncludeSubsites: _includeSubsites, IncludeHiddenLibraries: _includeHidden, IncludeRecycleBin: _includeRecycleBin); _results = (await Elevation.RunAsync(async c => { var ctx = await SessionMgr.GetOrCreateContextAsync(siteUrl, Session.CurrentProfile!, c); return await StorageSvc.CollectStorageAsync(ctx, opts, progress, c); }, _cts.Token)).ToList(); _status = $"Complete: {_results.Count} nodes."; } catch (OperationCanceledException) { _status = "Cancelled."; } catch (Exception ex) { _error = ex.Message; } finally { _running = false; await InvokeAsync(StateHasChanged); } } private void Cancel() => _cts?.Cancel(); private async Task ExportCsv() { var csv = CsvExport.BuildCsv(_results); await WebExport.DownloadCsvAsync(csv, $"storage_{DateTime.Now:yyyyMMdd_HHmmss}.csv"); } private async Task ExportHtml() { var html = HtmlExport.BuildHtml(_results); await WebExport.DownloadHtmlAsync(html, $"storage_{DateTime.Now:yyyyMMdd_HHmmss}.html"); } }