Improved ManageUsers Page layout
This commit is contained in:
parent
669b4df68b
commit
7fd3b5e933
|
@ -2,6 +2,7 @@
|
||||||
@using Microsoft.AspNetCore.Authorization
|
@using Microsoft.AspNetCore.Authorization
|
||||||
@using Microsoft.AspNetCore.Identity
|
@using Microsoft.AspNetCore.Identity
|
||||||
@using Wave.Data
|
@using Wave.Data
|
||||||
|
@using Humanizer
|
||||||
|
|
||||||
@rendermode InteractiveServer
|
@rendermode InteractiveServer
|
||||||
@attribute [Authorize(Policy = "RoleAssignPermissions")]
|
@attribute [Authorize(Policy = "RoleAssignPermissions")]
|
||||||
|
@ -11,31 +12,33 @@
|
||||||
|
|
||||||
<PageTitle>@(TitlePrefix + Localizer["Title"])</PageTitle>
|
<PageTitle>@(TitlePrefix + Localizer["Title"])</PageTitle>
|
||||||
|
|
||||||
<h1 class="text-3xl lg:text-5xl font-light mb-6">@Localizer["Title"]</h1>
|
<h1 class="text-3xl lg:text-5xl font-light mb-6">@Localizer["Title"]</h1>
|
||||||
|
|
||||||
<section class="mb-3 overflow-x-auto">
|
<section class="mb-3 overflow-x-auto">
|
||||||
<h3 class="text-xl lg:text-3xl mb-2">
|
<h3 class="text-xl lg:text-3xl mb-2">
|
||||||
@Localizer["Authors"]
|
@Localizer[CurrentRole.ToString().Pluralize()]
|
||||||
<!-- TODO:: implement -->
|
</h3>
|
||||||
<button class="btn btn-sm btn-square btn-ghost text-success">
|
<div class="flex gap-2">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
|
<InputSelect class="select select-bordered select-sm w-full max-w-xs" Value="CurrentRole"
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v6m3-3H9m12 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
ValueExpression="() => CurrentRole"
|
||||||
</svg>
|
TValue="Role" ValueChanged="async c => await LoadAsync(c)">
|
||||||
</button>
|
@foreach (var role in Enum.GetValues<Role>()) {
|
||||||
</h3>
|
<option value="@role">@Localizer[role.ToString()]</option>
|
||||||
<UserTable Users="Authors" RemoveCallback="@(async u => await Remove(u, "Author"))" />
|
}
|
||||||
</section>
|
</InputSelect>
|
||||||
<section class="mb-3 overflow-x-auto">
|
<button class="btn btn-sm btn-square btn-ghost text-success">
|
||||||
<h3 class="text-xl lg:text-3xl mb-2">@Localizer["Reviewers"]</h3>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
|
||||||
<UserTable Users="Reviewers" RemoveCallback="@(async u => await Remove(u, "Reviewer"))" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v6m3-3H9m12 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||||
</section>
|
</svg>
|
||||||
<section class="mb-3 overflow-x-auto">
|
</button>
|
||||||
<h3 class="text-xl lg:text-3xl mb-2">@Localizer["Moderators"]</h3>
|
</div>
|
||||||
<UserTable Users="Moderators" RemoveCallback="@(async u => await Remove(u, "Moderator"))" />
|
@if (Busy) {
|
||||||
</section>
|
<div class="flex place-content-center">
|
||||||
<section class="mb-3 overflow-x-auto">
|
<span class="loading loading-spinner loading-lg"></span>
|
||||||
<h3 class="text-xl lg:text-3xl mb-2">@Localizer["Administrators"]</h3>
|
</div>
|
||||||
<UserTable Users="Admins" RemoveCallback="@(async u => await Remove(u, "Admin"))" />
|
} else {
|
||||||
|
<UserTable Users="Users" RemoveCallback="@(async u => await RemoveAsync(u, CurrentRole))"/>
|
||||||
|
}
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<ToastComponent @ref="Toast" />
|
<ToastComponent @ref="Toast" />
|
||||||
|
@ -43,35 +46,45 @@
|
||||||
@code {
|
@code {
|
||||||
[CascadingParameter(Name = "TitlePrefix")]
|
[CascadingParameter(Name = "TitlePrefix")]
|
||||||
private string TitlePrefix { get; set; } = default!;
|
private string TitlePrefix { get; set; } = default!;
|
||||||
|
|
||||||
public ToastComponent Toast { get; set; } = null!;
|
public ToastComponent Toast { get; set; } = null!;
|
||||||
|
|
||||||
private IList<ApplicationUser> Authors { get; set; } = new List<ApplicationUser>();
|
|
||||||
private IList<ApplicationUser> Reviewers { get; set; } = new List<ApplicationUser>();
|
|
||||||
private IList<ApplicationUser> Moderators { get; set; } = new List<ApplicationUser>();
|
|
||||||
private IList<ApplicationUser> Admins { get; set; } = new List<ApplicationUser>();
|
|
||||||
|
|
||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
private Task<AuthenticationState> AuthenticationState { get; set; } = default!;
|
private Task<AuthenticationState> AuthenticationState { get; set; } = default!;
|
||||||
private ApplicationUser? User { get; set; }
|
private ApplicationUser? User { get; set; }
|
||||||
|
private Role CurrentRole { get; set; } = Role.Admin;
|
||||||
|
private List<ApplicationUser> Users { get; } = [];
|
||||||
|
private bool Busy { get; set; }
|
||||||
|
|
||||||
protected override async Task OnAfterRenderAsync(bool firstRender) {
|
protected override async Task OnAfterRenderAsync(bool firstRender) {
|
||||||
if (!firstRender) return;
|
if (!firstRender) return;
|
||||||
var state = await AuthenticationState;
|
var state = await AuthenticationState;
|
||||||
User = await UserManager.GetUserAsync(state.User);
|
User = await UserManager.GetUserAsync(state.User);
|
||||||
|
await LoadAsync(CurrentRole);
|
||||||
|
}
|
||||||
|
|
||||||
Authors = await UserManager.GetUsersInRoleAsync("Author");
|
private async Task LoadAsync(Role role) {
|
||||||
Reviewers = await UserManager.GetUsersInRoleAsync("Reviewer");
|
try {
|
||||||
Moderators = await UserManager.GetUsersInRoleAsync("Moderator");
|
Busy = true;
|
||||||
Admins = await UserManager.GetUsersInRoleAsync("Admin");
|
var users = await UserManager.GetUsersInRoleAsync(role.ToString());
|
||||||
}
|
Users.Clear();
|
||||||
|
CurrentRole = role;
|
||||||
|
Users.AddRange(users);
|
||||||
|
} finally {
|
||||||
|
Busy = false;
|
||||||
|
}
|
||||||
|
await InvokeAsync(StateHasChanged);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task Remove(ApplicationUser user, string role) {
|
private async Task RemoveAsync(ApplicationUser user, Role role) {
|
||||||
if (User is null) return;
|
if (User is null) return;
|
||||||
if (user.Id == User.Id) {
|
if (user.Id == User.Id) {
|
||||||
Toast.ShowError(Localizer["Error_EditSelf"]);
|
Toast.ShowError(Localizer["Error_EditSelf"]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await UserManager.RemoveFromRoleAsync(user, role);
|
await UserManager.RemoveFromRoleAsync(user, role.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private enum Role {
|
||||||
|
Author, Reviewer, Moderator, Admin
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,7 @@
|
||||||
<data name="Moderators" xml:space="preserve">
|
<data name="Moderators" xml:space="preserve">
|
||||||
<value>Moderator*innen</value>
|
<value>Moderator*innen</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Administrators" xml:space="preserve">
|
<data name="Admins" xml:space="preserve">
|
||||||
<value>Administrator*innen</value>
|
<value>Administrator*innen</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Error_EditSelf" xml:space="preserve">
|
<data name="Error_EditSelf" xml:space="preserve">
|
||||||
|
|
|
@ -110,7 +110,7 @@
|
||||||
<data name="Moderators" xml:space="preserve">
|
<data name="Moderators" xml:space="preserve">
|
||||||
<value>Moderators</value>
|
<value>Moderators</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Administrators" xml:space="preserve">
|
<data name="Admins" xml:space="preserve">
|
||||||
<value>Administrators</value>
|
<value>Administrators</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Error_EditSelf" xml:space="preserve">
|
<data name="Error_EditSelf" xml:space="preserve">
|
||||||
|
|
2
Wave/wwwroot/css/main.min.css
vendored
2
Wave/wwwroot/css/main.min.css
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue