Iceshrimp.NET/Iceshrimp.Backend/Pages/Admin/Users.razor

167 lines
No EOL
5.3 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@page "/admin/users"
@using Iceshrimp.Backend.Components.Admin
@using Iceshrimp.Backend.Core.Configuration
@using Iceshrimp.Backend.Core.Database.Tables
@using Microsoft.EntityFrameworkCore
@using Microsoft.Extensions.Options
@inherits AdminComponentBase
<AdminPageHeader Title="Users"/>
<table class="auto-table">
<thead>
<th>Username</th>
<th>Status</th>
<th>Actions</th>
</thead>
<tbody>
@foreach (var user in _users)
{
<tr>
@if (Remote)
{
<td>@@@user.Username<span class="text-dim">@@@user.Host</span></td>
}
else
{
<td>@@@user.Username</td>
}
<td>
@{
var text = "Active";
if (user.IsSuspended)
text = "Suspended";
if (user.IsAdmin)
text += ", Administrator";
if (user.IsModerator)
text += ", Moderator";
}
<i>@text</i>
</td>
<td>
@if (user.Id == AuthUser.Id)
{
<i>It's you!</i>
}
else
{
if (!user.IsSuspended)
{
<a class="fake-link" onclick="suspendUser('@user.Id', event.target)">Suspend</a>
}
else
{
<a class="fake-link" onclick="unsuspendUser('@user.Id', event.target)">Unsuspend</a>
}
<span>
| <a class="fake-link" onclick="purgeUser('@user.Id', event.target)">Purge</a>
| <a class="fake-link" onclick="deleteUser('@user.Id', event.target)">Delete</a>
</span>
}
</td>
</tr>
}
</tbody>
</table>
@if (_users is [])
{
<p>
<i>No users found.</i>
</p>
}
else
{
<p>
@if (!Remote)
{
<i>Listing @_count <a href="/admin/users?remote=true">local</a> users. </i>
@if (Options.Value.Registrations == Enums.Registrations.Invite)
{
<i>Registrations are invite-only. </i>
<a class="fake-link" id="gen-invite" role="button" onclick="generateInviteAndCopy()">Generate
invite!</a>
}
else if (Options.Value.Registrations == Enums.Registrations.Open)
{
<i>Registrations are open.</i>
}
else
{
<i>Registrations are closed.</i>
}
}
else
{
<i>Listing @_count <a href="/admin/users">remote</a> users.</i>
}
</p>
}
<div class="flex">
@if (Offset is > 0)
{
<button role="link" data-target="/admin/users?@(_prevPageParams)" onclick="navigate(event)">
Previous page
</button>
}
else
{
<button disabled> Previous page</button>
}
@if (_users.Length == 50)
{
<button role="link" data-target="/admin/users?@(_nextPageParams)" onclick="navigate(event)">
Next page
</button>
}
else
{
<button disabled>Next page </button>
}
<form method="get" class="inline-flex flex-grow">
<input type="text" id="search" name="q" placeholder="Search..." class="flex-grow" value="@(Query ?? "")"/>
@if (Remote)
{
<input type="hidden" name="remote" value="true"/>
}
</form>
</div>
@code {
[Inject] public required IOptionsSnapshot<Config.SecuritySection> Options { get; set; }
[CascadingParameter] public required User AuthUser { get; set; }
[SupplyParameterFromQuery] public int? Offset { get; set; }
[SupplyParameterFromQuery] public bool Remote { get; set; }
[SupplyParameterFromQuery(Name = "q")] public string? Query { get; set; }
private User[] _users = [];
private int _count;
private string _prevPageParams = "";
private string _nextPageParams = "";
protected override async Task OnGet()
{
var query = Remote
? Database.Users.Where(p => p.IsRemoteUser)
.Where(p => ("@" + p.Username + "@" + p.Host).ToLower().Contains((Query ?? "").ToLower()))
.OrderBy(p => p.Username + "@" + p.Host)
: Database.Users.Where(p => p.IsLocalUser && !p.IsSystemUser)
.Where(p => ("@" + p.Username.ToLower()).Contains((Query ?? "").ToLower()))
.OrderBy(p => p.Username);
_users = await query.Skip(Offset ?? 0).Take(50).ToArrayAsync();
_count = await query.CountAsync();
if (Offset > 0)
_prevPageParams = (Query is { Length: > 0 } ? $"q={Query}&" : "") + (Remote ? "remote=true&" : "") + "offset=" + (Math.Max(0, Offset.Value - 50));
if (_users.Length == 50)
_nextPageParams = (Query is { Length: > 0 } ? $"q={Query}&" : "") + (Remote ? "remote=true&" : "") + "offset=" + ((Offset ?? 0) + 50);
}
}