@inherits LocalizableComponentBase @* The server's rules (/clientapi/admin/settings): written, explained, put in order and removed here, then saved together. A rule keeps its id while it is listed, so the reports that name it keep their meaning; one removed is kept, greyed below, as old reports name it, and can come back. Saving starts from the settings PrivaPub has now (InstanceAdminService.SaveSettings), so what Instance or Media limits saved stays. *@
@if (IsLoading) {

@Localizer["loading"]

} else if (settings is null) {

@Localizer["The server's settings could not be read."]

@Localizer["Retry"]
} else {

@Localizer["Everyone reads them on the About page, and a report of a violation names the ones broken."]

@if (rows.Count == 0) {

@Localizer["The server has no rules."]

}
    @foreach (var (row, position) in Numbered) {
  1. @(position + 1).
  2. }
@Localizer["Add a rule"] @Localizer["Discard changes"] @if (isSaving) { } @Localizer["Save the rules"]
@if (rows.Count >= ServerSettingsForm.MaxRules) {

@Localizer["A server has {0} rules at most.", ServerSettingsForm.MaxRules]

} @if (Removed.Count > 0) {
@Localizer["Removed rules, kept as old reports name them"] @foreach (var rule in Removed) {
@rule.Text @if (rule.DeletedAt is { } deletedAt) { @Localizer["Removed {0} ago", deletedAt.GetPassedTime(Localizer)] } @Localizer["Bring it back"]
}
} }
@code { [Inject] InstanceAdminService InstanceAdminService { get; set; } ViewServerSettings settings; // the rules as being written, in their order: a listed rule keeps its id, a new one has none List rows = []; bool isSaving; IEnumerable<(ServerRuleForm Row, int Position)> Numbered => rows.Select((row, position) => (row, position)); // the rules the server keeps deleted, unless they are listed again above List Removed => [.. (settings?.Rules ?? []).Where(r => r.IsDeleted && rows.All(row => row.Id != r.Id))]; protected override async Task OnInitializedAsync() { if (CascadingState.IsOffline) { WhenOnline(LoadData); StartOnlinePolling(); IsLoading = false; return; } await LoadData(); IsLoading = false; } async Task LoadData() { settings = await InstanceAdminService.Settings(); Reset(); } async Task Retry() { IsLoading = true; await LoadData(); IsLoading = false; } void Reset() => rows = settings is null ? [] : InstanceAdminService.FormOf(settings).Rules; void Add() => rows.Add(new ServerRuleForm()); // gone from the list, it is removed when the rules are saved (kept, marked, for the reports naming it) void Remove(ServerRuleForm row) => rows.Remove(row); void Move(int position, int by) { var row = rows[position]; rows.RemoveAt(position); rows.Insert(position + by, row); } // listed again with its id, it is the same rule: the reports naming it name it still void Restore(ViewServerRule rule) => rows.Add(new ServerRuleForm { Id = rule.Id, Text = rule.Text, Hint = rule.Hint }); async Task Save() { var rules = rows.Select(r => new ServerRuleForm { Id = r.Id, Text = r.Text?.Trim(), Hint = string.IsNullOrWhiteSpace(r.Hint) ? null : r.Hint.Trim() }).ToList(); isSaving = true; var result = await InstanceAdminService.SaveSettings(latest => latest.Rules = rules); isSaving = false; if (result.IsInvalid) { Toast.AddResponseError(result); return; } settings = (ViewServerSettings)result.Data; Reset(); Toast.AddResponseSuccess(Localizer["The rules are saved."]); } }