Extract workspace admin coordinator

This commit is contained in:
2026-04-05 00:08:46 +02:00
parent b3cde614e7
commit abee1729c5
4 changed files with 147 additions and 92 deletions

View File

@@ -186,93 +186,11 @@ public partial class Workspace : IAsyncDisposable
return SwitchScreenAsync(ScreenAdmin);
}
private async Task EnsureAdminUsersLoadedAsync()
{
if (!IsCurrentUserAdmin || HasLoadedAdminUsers || IsAdminDataLoading)
return;
private Task EnsureAdminUsersLoadedAsync() => Admin.EnsureAdminUsersLoadedAsync();
IsAdminDataLoading = true;
try
{
await ReloadAdminUsersAsync();
}
catch (ApiRequestException ex) when (ex.StatusCode == 401)
{
ClearAuthenticatedState();
await StopStateEventsAsync();
await LoggedOut.InvokeAsync("Session expired. Please log in again.");
}
catch (ApiRequestException ex)
{
SetStatus(ex.Message, true);
}
finally
{
IsAdminDataLoading = false;
}
}
private Task ToggleAdminRoleAsync(AdminUserSummary user) => Admin.ToggleAdminRoleAsync(user);
private async Task ReloadAdminUsersAsync()
{
AdminUsers = (await WorkspaceQuery.GetAdminUsersAsync())
.OrderBy(user => user.Username, StringComparer.OrdinalIgnoreCase)
.ToList();
HasLoadedAdminUsers = true;
}
private async Task ToggleAdminRoleAsync(AdminUserSummary user)
{
if (IsMutating || User is null || !IsCurrentUserAdmin || user.Id == User.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 ReloadAdminUsersAsync();
SetStatus("User roles updated.", false);
}
catch (ApiRequestException ex)
{
SetStatus(ex.Message, true);
}
finally
{
IsMutating = false;
}
}
private async Task DeleteUserAsync(AdminUserSummary user)
{
if (IsMutating || User is null || !IsCurrentUserAdmin || user.Id == User.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 ReloadAdminUsersAsync();
SetStatus("User deleted.", false);
}
catch (ApiRequestException ex)
{
SetStatus(ex.Message, true);
}
finally
{
IsMutating = false;
}
}
private Task DeleteUserAsync(AdminUserSummary user) => Admin.DeleteUserAsync(user);
private async Task SetMobilePanelAsync(string panel)
{
@@ -970,14 +888,18 @@ public partial class Workspace : IAsyncDisposable
private bool CanDeleteSelectedCampaign => State.CanDeleteSelectedCampaign;
private bool IsSelectedCampaignD6 => State.IsSelectedCampaignD6;
private static bool HasAdminRole(AdminUserSummary user)
{
return user.Roles.Contains(UserRoles.Admin, StringComparer.OrdinalIgnoreCase);
}
private bool IsPlayScreen => State.IsPlayScreen;
private bool IsManagementScreen => State.IsManagementScreen;
private bool IsAdminScreen => State.IsAdminScreen;
private WorkspaceAdminCoordinator Admin => m_Admin ??= new(
State,
Feedback,
JS,
ApiClient,
WorkspaceQuery,
ClearAuthenticatedState,
StopStateEventsAsync,
message => LoggedOut.InvokeAsync(message));
private WorkspaceFeedbackService Feedback => m_Feedback ??= new(State, () => InvokeAsync(StateHasChanged));
private WorkspaceSessionCoordinator Session => m_Session ??= new(
State,
@@ -1021,6 +943,7 @@ public partial class Workspace : IAsyncDisposable
private const string MobilePanelSessionKey = "play-panel";
private const int CampaignLogWindowSize = 25;
private WorkspaceAdminCoordinator? m_Admin;
private WorkspaceFeedbackService? m_Feedback;
private WorkspaceSessionCoordinator? m_Session;
}