@page "/search" @attribute [Authorize] @inject IUserSessionService Session @inject ISessionManager SessionMgr @inject IElevationCoordinator Elevation @inject ISearchService SearchSvc @inject SearchCsvExportService CsvExport @inject SearchHtmlExportService HtmlExport @inject WebExportService WebExport @rendermode InteractiveServer

File Search

@if (!Session.HasProfile) { return; }
Search Options
@if (_running) { }
@if (!string.IsNullOrEmpty(_error)) {
@_error
} @if (_results.Count > 0) {
Results @_results.Count
@foreach (var r in _results.Take(500)) { }
NameExtPathCreatedModifiedSize (KB)
@System.IO.Path.GetFileName(r.Path) @r.FileExtension @r.Path @(r.Created?.ToString("yyyy-MM-dd") ?? "") @(r.LastModified?.ToString("yyyy-MM-dd") ?? "") @((r.SizeBytes / 1024.0).ToString("F1"))
@if (_results.Count > 500) {
Showing first 500 of @_results.Count. Export for full results.
}
} @code { private string _siteUrl = string.Empty, _extensions = string.Empty, _regex = string.Empty; private string _createdBy = string.Empty, _modifiedBy = string.Empty, _library = string.Empty; private int _maxResults = 5000; 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 RunSearch() { _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 exts = _extensions.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); var opts = new SearchOptions(exts, _regex, null, null, null, null, _createdBy.TrimOrNull(), _modifiedBy.TrimOrNull(), _library.TrimOrNull(), _maxResults, siteUrl); _results = (await Elevation.RunAsync(async c => { var ctx = await SessionMgr.GetOrCreateContextAsync(siteUrl, Session.CurrentProfile!, c); return await SearchSvc.SearchFilesAsync(ctx, opts, progress, c); }, _cts.Token)).ToList(); _status = $"Found {_results.Count} files."; } 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() { await WebExport.DownloadCsvAsync(CsvExport.BuildCsv(_results), $"search_{DateTime.Now:yyyyMMdd_HHmmss}.csv"); } private async Task ExportHtml() { await WebExport.DownloadHtmlAsync(HtmlExport.BuildHtml(_results, Session.CurrentBranding), $"search_{DateTime.Now:yyyyMMdd_HHmmss}.html"); } }