Files
RpgRoller/RpgRoller/Components/Pages/HomeControls/AdminHome.razor.cs

195 lines
5.3 KiB
C#

using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using RpgRoller.Contracts;
using RpgRoller.Domain;
namespace RpgRoller.Components.Pages.HomeControls;
[ExcludeFromCodeCoverage]
public partial class AdminHome
{
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (!firstRender)
return;
await InitializeAsync();
await InvokeAsync(StateHasChanged);
}
private async Task InitializeAsync()
{
try
{
var me = await ApiClient.RequestAsync<MeResponse>("GET", "/api/me");
CurrentUser = me.User;
IsCurrentUserAdmin = HasAdminRole(me.User);
if (!IsCurrentUserAdmin)
return;
Users = (await ApiClient.RequestAsync<IReadOnlyList<AdminUserSummary>>("GET", "/api/admin/users"))
.OrderBy(user => user.Username, StringComparer.OrdinalIgnoreCase)
.ToList();
}
catch (ApiRequestException ex) when (ex.StatusCode == 401)
{
await LoggedOut.InvokeAsync("Session expired. Please log in again.");
}
catch (ApiRequestException ex)
{
SetStatus(ex.Message, true);
}
finally
{
IsLoading = false;
}
}
private async Task OpenWorkspaceAsync()
{
IsScreenMenuOpen = false;
await WorkspaceRequested.InvokeAsync();
}
private Task OpenAdminAsync()
{
IsScreenMenuOpen = false;
return Task.CompletedTask;
}
private async Task LogoutAsync()
{
if (IsMutating)
return;
IsMutating = true;
try
{
await ApiClient.RequestWithoutPayloadAsync("POST", "/api/auth/logout");
}
catch (ApiRequestException)
{
}
finally
{
IsMutating = false;
}
await LoggedOut.InvokeAsync("Logged out.");
}
private async Task ToggleAdminRoleAsync(AdminUserSummary user)
{
if (IsMutating || CurrentUser is null || user.Id == CurrentUser.Id)
return;
IsMutating = true;
try
{
IReadOnlyList<string> roles = HasAdminRole(user) ? Array.Empty<string>() : [UserRoles.Admin];
_ = await ApiClient.RequestAsync<AdminUserSummary>(
"PUT",
$"/api/admin/users/{user.Id}/roles",
new UpdateUserRolesRequest(roles));
await ReloadUsersAsync();
SetStatus("User roles updated.", false);
}
catch (ApiRequestException ex)
{
SetStatus(ex.Message, true);
}
finally
{
IsMutating = false;
}
}
private async Task DeleteUserAsync(AdminUserSummary user)
{
if (IsMutating || CurrentUser is null || user.Id == CurrentUser.Id)
return;
var confirmed = await JS.InvokeAsync<bool>("confirm", $"Delete user '{user.Username}'?");
if (!confirmed)
return;
IsMutating = true;
try
{
_ = await ApiClient.RequestAsync<bool>("DELETE", $"/api/admin/users/{user.Id}");
await ReloadUsersAsync();
SetStatus("User deleted.", false);
}
catch (ApiRequestException ex)
{
SetStatus(ex.Message, true);
}
finally
{
IsMutating = false;
}
}
private async Task ReloadUsersAsync()
{
Users = (await ApiClient.RequestAsync<IReadOnlyList<AdminUserSummary>>("GET", "/api/admin/users"))
.OrderBy(user => user.Username, StringComparer.OrdinalIgnoreCase)
.ToList();
}
private static bool HasAdminRole(UserSummary user)
{
return user.Roles.Contains(UserRoles.Admin, StringComparer.OrdinalIgnoreCase);
}
private static bool HasAdminRole(AdminUserSummary user)
{
return user.Roles.Contains(UserRoles.Admin, StringComparer.OrdinalIgnoreCase);
}
private void SetStatus(string message, bool isError)
{
StatusMessage = message;
StatusIsError = isError;
}
private void ToggleScreenMenu()
{
IsScreenMenuOpen = !IsScreenMenuOpen;
}
[Inject]
private RpgRollerApiClient ApiClient { get; set; } = null!;
[Inject]
private IJSRuntime JS { get; set; } = null!;
private bool IsLoading { get; set; } = true;
private bool IsMutating { get; set; }
private bool IsScreenMenuOpen { get; set; }
private bool IsCurrentUserAdmin { get; set; }
private UserSummary? CurrentUser { get; set; }
private List<AdminUserSummary> Users { get; set; } = [];
private string? StatusMessage { get; set; }
private bool StatusIsError { get; set; }
private IReadOnlyList<AppHeaderMenuItem> HeaderMenuItems
{
get
{
return
[
new AppHeaderMenuItem { Label = "Workspace", IsActive = false, OnSelected = OpenWorkspaceAsync },
new AppHeaderMenuItem { Label = "Admin", IsActive = true, OnSelected = OpenAdminAsync }
];
}
}
[Parameter]
public EventCallback<string?> LoggedOut { get; set; }
[Parameter]
public EventCallback WorkspaceRequested { get; set; }
}