167 lines
No EOL
5.3 KiB
Text
167 lines
No EOL
5.3 KiB
Text
@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);
|
||
}
|
||
} |