@inherits LocalizableComponentBase @* The staff's log (/clientapi/moderator/log), newest first, 50 at a time: who acted (to administrators every login's name; to a moderator only its own; "the command line" for PrivaPub's CLI; nobody when an act on a persona of the acting login would tie the two), what was done, to what, and its note. Never an IP address. A moderator who isn't an administrator reads what isn't about a login. *@
@Localizer["Read again"]
@if (IsLoading) {

@Localizer["loading"]

} else if (failed) {

@Localizer["The log could not be read."]

} else if (entries.Count == 0) {

@Localizer["Nothing was done yet."]

}
    @foreach (var entry in entries) {
  1. @ActionName(entry.Action) @if (entry.TargetLabel is { Length: > 0 } label) { @label } @entry.At.GetPassedTime(Localizer)
    @By(entry) @entry.Action @if (entry.ReportId is { Length: > 0 } reportId) { @Localizer["Report: {0}", reportId] }
    @if (entry.Note is { Length: > 0 } note) {

    @note

    }
  2. }
@if (next is not null) { @if (isLoadingMore) { } @Localizer["Load more"] }
@code { const int PageSize = 50; [Inject] AdminService AdminService { get; set; } List entries = []; // the next page's `before`; null on the last string next; bool failed; bool isLoadingMore; protected override async Task OnInitializedAsync() { if (CascadingState.IsOffline) { WhenOnline(LoadData); StartOnlinePolling(); IsLoading = false; return; } await LoadData(); IsLoading = false; } async Task LoadData() { var page = await AdminService.Log(null, PageSize); failed = page is null; entries = page?.Items ?? []; next = page?.Next; } async Task Reload() { IsLoading = true; await LoadData(); IsLoading = false; } async Task More() { isLoadingMore = true; var page = await AdminService.Log(next, PageSize); isLoadingMore = false; if (page is null) { Toast.AddResponseError(Localizer["The log could not be read."]); return; } var known = entries.Select(e => e.Id).ToHashSet(); entries.AddRange(page.Items.Where(e => known.Add(e.Id))); next = page.Next; } string By(ViewAdminAction entry) => entry switch { { ByYou: true } => Localizer["by you"], { By: "cli" } => Localizer["by the command line"], { By: { Length: > 0 } name } => Localizer["by {0}", name], _ => Localizer["by someone not named"] }; string ActionName(string action) => action switch { "domain_block.insert" => Localizer["Server blocked"], "domain_block.delete" => Localizer["Server unblocked"], "backup.create" => Localizer["Backup made"], "backup.delete" => Localizer["Backup deleted"], "backup.restore" => Localizer["Backup restored"], "settings.update" => Localizer["Settings saved"], "settings.thumbnail" => Localizer["Thumbnail changed"], "rule.insert" => Localizer["Rule added"], "rule.update" => Localizer["Rule changed"], "rule.delete" => Localizer["Rule removed"], "announcement.insert" => Localizer["Announcement written"], "announcement.update" => Localizer["Announcement changed"], "announcement.delete" => Localizer["Announcement deleted"], "relay.insert" => Localizer["Relay added"], "relay.delete" => Localizer["Relay removed"], "report.resolve" => Localizer["Report resolved"], "root.promote" => Localizer["Login made administrator"], "root.demote" => Localizer["Login no longer administrator"], "root.create" => Localizer["Login made"], "root.delete" => Localizer["Login deleted"], "root.reset_totp" => Localizer["Two-factor sign-in reset"], "persona.move" => Localizer["Persona moved to another login"], _ => action }; }