@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)
{
-
@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
}
}
@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
};
}