Files
RpgRoller/RpgRoller/Components/Pages/WorkspaceAdminCoordinator.cs
2026-04-05 02:05:24 +02:00

98 lines
3.1 KiB
C#

using System.Diagnostics.CodeAnalysis;
using Microsoft.JSInterop;
using RpgRoller.Contracts;
using RpgRoller.Domain;
namespace RpgRoller.Components.Pages;
[ExcludeFromCodeCoverage]
public sealed class WorkspaceAdminCoordinator(WorkspaceState state, WorkspaceFeedbackService feedback, IJSRuntime js, RpgRollerApiClient apiClient, WorkspaceQueryService workspaceQuery, Action clearAuthenticatedState, Func<Task> stopStateEventsAsync, Func<string?, Task> onLoggedOutAsync)
{
public async Task EnsureAdminUsersLoadedAsync()
{
if (!state.IsCurrentUserAdmin || state.HasLoadedAdminUsers || state.IsAdminDataLoading)
return;
state.IsAdminDataLoading = true;
try
{
await ReloadAdminUsersAsync();
}
catch (ApiRequestException ex) when (ex.StatusCode == 401)
{
clearAuthenticatedState();
await stopStateEventsAsync();
await onLoggedOutAsync("Session expired. Please log in again.");
}
catch (ApiRequestException ex)
{
feedback.SetStatus(ex.Message, true);
}
finally
{
state.IsAdminDataLoading = false;
}
}
public async Task ToggleAdminRoleAsync(AdminUserSummary user)
{
if (state.IsMutating || state.User is null || !state.IsCurrentUserAdmin || user.Id == state.User.Id)
return;
state.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 ReloadAdminUsersAsync();
feedback.SetStatus("User roles updated.", false);
}
catch (ApiRequestException ex)
{
feedback.SetStatus(ex.Message, true);
}
finally
{
state.IsMutating = false;
}
}
public async Task DeleteUserAsync(AdminUserSummary user)
{
if (state.IsMutating || state.User is null || !state.IsCurrentUserAdmin || user.Id == state.User.Id)
return;
var confirmed = await js.InvokeAsync<bool>("confirm", $"Delete user '{user.Username}'?");
if (!confirmed)
return;
state.IsMutating = true;
try
{
_ = await apiClient.RequestAsync<bool>("DELETE", $"/api/admin/users/{user.Id}");
await ReloadAdminUsersAsync();
feedback.SetStatus("User deleted.", false);
}
catch (ApiRequestException ex)
{
feedback.SetStatus(ex.Message, true);
}
finally
{
state.IsMutating = false;
}
}
private async Task ReloadAdminUsersAsync()
{
state.AdminUsers = (await workspaceQuery.GetAdminUsersAsync()).OrderBy(user => user.Username, StringComparer.OrdinalIgnoreCase).ToList();
state.HasLoadedAdminUsers = true;
}
private static bool HasAdminRole(AdminUserSummary user)
{
return user.Roles.Contains(UserRoles.Admin, StringComparer.OrdinalIgnoreCase);
}
}