269 lines
9.5 KiB
Plaintext
269 lines
9.5 KiB
Plaintext
@page "/administration/users"
|
|
@rendermode InteractiveServer
|
|
@layout AdminLayout
|
|
|
|
@using System.Globalization
|
|
@using BlazorStrap
|
|
@using CurrieTechnologies.Razor.SweetAlert2
|
|
@using HopFrame.Database.Models
|
|
@using HopFrame.Security.Claims
|
|
@using HopFrame.Security.Services
|
|
@using HopFrame.Web.Pages.Administration.Layout
|
|
@using static Microsoft.AspNetCore.Components.Web.RenderMode
|
|
@using Microsoft.AspNetCore.Components.Web
|
|
@using HopFrame.Web.Components
|
|
@using BlazorStrap.V5
|
|
@using HopFrame.Web.Model
|
|
@using HopFrame.Web.Pages.Administration.Components
|
|
|
|
<PageTitle>Users</PageTitle>
|
|
<AuthorizedView Permission="@AdminPermissions.ViewUsers" RedirectIfUnauthorized="login?redirect=/administration/users"/>
|
|
|
|
<UserAddModal @ref="_userAddModal" OnSubmit="CreateUser"/>
|
|
|
|
<div class="title">
|
|
<h3>
|
|
Users administration
|
|
<span class="reload" @onclick="Reload">
|
|
<HopIconDisplay Type="HopIconDisplay.HopIcon.Reload"/>
|
|
</span>
|
|
</h3>
|
|
|
|
<form class="d-flex" role="search" @onsubmit="Search" id="search">
|
|
<input class="form-control me-2 input-dark" type="search" placeholder="Search" aria-label="Search" @bind="_searchText">
|
|
<BSButton Color="BSColor.Success" IsOutlined="true" type="submit">Search</BSButton>
|
|
</form>
|
|
<BSButton IsSubmit="false" Color="BSColor.Success" Target="add-user" OnClick="() => _userAddModal.ShowAsync()">Add User</BSButton>
|
|
</div>
|
|
|
|
<BSTable IsStriped="true" IsHoverable="true" IsDark="true" Color="BSColor.Dark">
|
|
<BSTHead>
|
|
<BSTR>
|
|
<BSTD>#</BSTD>
|
|
<BSTD>
|
|
<span class="sorter" @onclick="() => OrderBy(OrderType.Email)">E-Mail</span>
|
|
@if (_currentOrder == OrderType.Email) {
|
|
<HopIconDisplay Type="_currentOrderDirection == OrderDirection.Desc ? HopIconDisplay.HopIcon.ArrowDown : HopIconDisplay.HopIcon.ArrowUp"/>
|
|
}
|
|
</BSTD>
|
|
<BSTD>
|
|
<span class="sorter" @onclick="() => OrderBy(OrderType.Username)">Username</span>
|
|
@if (_currentOrder == OrderType.Username) {
|
|
<HopIconDisplay Type="_currentOrderDirection == OrderDirection.Desc ? HopIconDisplay.HopIcon.ArrowDown : HopIconDisplay.HopIcon.ArrowUp"/>
|
|
}
|
|
</BSTD>
|
|
<BSTD>
|
|
<span class="sorter" @onclick="() => OrderBy(OrderType.Registered)">Registered</span>
|
|
@if (_currentOrder == OrderType.Registered) {
|
|
<HopIconDisplay Type="_currentOrderDirection == OrderDirection.Desc ? HopIconDisplay.HopIcon.ArrowDown : HopIconDisplay.HopIcon.ArrowUp"/>
|
|
}
|
|
</BSTD>
|
|
<BSTD>Primary Group</BSTD>
|
|
|
|
@if (_hasEditPrivileges || _hasDeletePrivileges) {
|
|
<BSTD>Actions</BSTD>
|
|
}
|
|
</BSTR>
|
|
</BSTHead>
|
|
|
|
<BSTBody>
|
|
@foreach (var user in _users) {
|
|
<BSTR>
|
|
<BSTD class="bold">@user.Id</BSTD>
|
|
<BSTD>@user.Email</BSTD>
|
|
<BSTD>@user.Username</BSTD>
|
|
<BSTD>@user.CreatedAt</BSTD>
|
|
<BSTD>@GetFriendlyGroupName(user)</BSTD>
|
|
|
|
@if (_hasEditPrivileges || _hasDeletePrivileges) {
|
|
<BSTD>
|
|
<BSButtonGroup>
|
|
@if (_hasEditPrivileges) {
|
|
<BSButton Color="BSColor.Warning" OnClick="() => EditUser(user)">Edit</BSButton>
|
|
}
|
|
|
|
@if (_hasDeletePrivileges) {
|
|
<BSButton Color="BSColor.Danger" OnClick="() => Delete(user)">Delete</BSButton>
|
|
}
|
|
</BSButtonGroup>
|
|
</BSTD>
|
|
}
|
|
</BSTR>
|
|
}
|
|
</BSTBody>
|
|
</BSTable>
|
|
|
|
@inject IUserService UserService
|
|
@inject IPermissionService PermissionsService
|
|
@inject NavigationManager Navigator
|
|
@inject SweetAlertService Alerts
|
|
@inject ITokenContext Auth
|
|
|
|
@code {
|
|
private IList<User> _users = new List<User>();
|
|
private IDictionary<Guid, PermissionGroup> _userGroups = new Dictionary<Guid, PermissionGroup>();
|
|
|
|
private OrderType _currentOrder = OrderType.None;
|
|
private OrderDirection _currentOrderDirection = OrderDirection.Asc;
|
|
|
|
private string _searchText;
|
|
|
|
private bool _hasEditPrivileges = false;
|
|
private bool _hasDeletePrivileges = false;
|
|
|
|
private UserAddModal _userAddModal;
|
|
|
|
protected override async Task OnInitializedAsync() {
|
|
_users = await UserService.GetUsers();
|
|
|
|
foreach (var user in _users) {
|
|
var groups = await PermissionsService.GetUserPermissionGroups(user);
|
|
_userGroups.Add(user.Id, groups.FirstOrDefault());
|
|
}
|
|
|
|
_hasEditPrivileges = await PermissionsService.HasPermission(AdminPermissions.EditUsers, Auth.User.Id);
|
|
_hasDeletePrivileges = await PermissionsService.HasPermission(AdminPermissions.DeleteUsers, Auth.User.Id);
|
|
}
|
|
|
|
private async Task Reload() {
|
|
_users = new List<User>();
|
|
_userGroups = new Dictionary<Guid, PermissionGroup>();
|
|
|
|
_users = await UserService.GetUsers();
|
|
|
|
foreach (var user in _users) {
|
|
var groups = await PermissionsService.GetUserPermissionGroups(user);
|
|
_userGroups.Add(user.Id, groups.FirstOrDefault());
|
|
}
|
|
}
|
|
|
|
private async Task Search() {
|
|
var users = await UserService.GetUsers();
|
|
|
|
if (!string.IsNullOrWhiteSpace(_searchText)) {
|
|
users = users
|
|
.Where(user =>
|
|
user.Email.Contains(_searchText) ||
|
|
user.Username.Contains(_searchText) ||
|
|
user.Id.ToString().Contains(_searchText) ||
|
|
user.CreatedAt.ToString(CultureInfo.InvariantCulture).Contains(_searchText) ||
|
|
_userGroups[user.Id]?.Name.Contains(_searchText) == true)
|
|
.ToList();
|
|
}
|
|
|
|
_users = users;
|
|
OrderBy(_currentOrder, false);
|
|
}
|
|
|
|
private string GetFriendlyGroupName(User user) {
|
|
var group = _userGroups[user.Id];
|
|
if (group is null) return null;
|
|
|
|
return group.Name.Replace("group.", "");
|
|
}
|
|
|
|
private void OrderBy(OrderType type, bool changeDir = true) {
|
|
if (_currentOrder == type && changeDir) _currentOrderDirection = (OrderDirection)(((byte)_currentOrderDirection + 1) % 2);
|
|
|
|
if (type == OrderType.Email) {
|
|
_users = _currentOrderDirection == OrderDirection.Asc ? _users.OrderBy(user => user.Email).ToList() : _users.OrderByDescending(user => user.Email).ToList();
|
|
}
|
|
else if (type == OrderType.Username) {
|
|
_users = _currentOrderDirection == OrderDirection.Asc ? _users.OrderBy(user => user.Username).ToList() : _users.OrderByDescending(user => user.Username).ToList();
|
|
}
|
|
else if (type == OrderType.Registered) {
|
|
_users = _currentOrderDirection == OrderDirection.Asc ? _users.OrderBy(user => user.CreatedAt).ToList() : _users.OrderByDescending(user => user.CreatedAt).ToList();
|
|
}
|
|
|
|
_currentOrder = type;
|
|
}
|
|
|
|
private async Task Delete(User user) {
|
|
var result = await Alerts.FireAsync(new SweetAlertOptions {
|
|
Title = "Are you sure?",
|
|
Text = "You won't be able to revert this!",
|
|
Icon = SweetAlertIcon.Warning,
|
|
ConfirmButtonText = "Yes",
|
|
ShowCancelButton = true,
|
|
ShowConfirmButton = true
|
|
});
|
|
|
|
if (result.IsConfirmed) {
|
|
await UserService.DeleteUser(user);
|
|
await Reload();
|
|
|
|
StateHasChanged();
|
|
|
|
await Alerts.FireAsync(new SweetAlertOptions {
|
|
Title = "Deleted!",
|
|
Icon = SweetAlertIcon.Success,
|
|
Timer = 1500,
|
|
ShowConfirmButton = false
|
|
});
|
|
}
|
|
}
|
|
|
|
private void EditUser(User user) {
|
|
Navigator.NavigateTo("/administration/user/" + user.Id);
|
|
}
|
|
|
|
private enum OrderType {
|
|
None,
|
|
Email,
|
|
Username,
|
|
Registered
|
|
}
|
|
|
|
private enum OrderDirection : byte {
|
|
Asc = 0,
|
|
Desc = 1
|
|
}
|
|
|
|
private async void CreateUser(UserAdd newUser) {
|
|
string errorMessage = null;
|
|
|
|
if (_users.Any(user => user.Username == newUser.Username)) {
|
|
errorMessage = "Username is already taken!";
|
|
}
|
|
else if (_users.Any(user => user.Email == newUser.Email)) {
|
|
errorMessage = "E-Mail is already taken!";
|
|
}
|
|
else if (!newUser.PasswordIsValid) {
|
|
errorMessage = "The password needs to be at least 8 characters long!";
|
|
}
|
|
else if (!newUser.EmailIsValid) {
|
|
errorMessage = "Invalid E-Mail address!";
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(errorMessage)) {
|
|
await Alerts.FireAsync(new SweetAlertOptions {
|
|
Title = "Something went wrong!",
|
|
Text = errorMessage,
|
|
Icon = SweetAlertIcon.Error,
|
|
ShowConfirmButton = false,
|
|
Timer = 1500
|
|
});
|
|
|
|
return;
|
|
}
|
|
|
|
var user = await UserService.AddUser(newUser);
|
|
|
|
if (!string.IsNullOrWhiteSpace(newUser.Group)) {
|
|
await PermissionsService.AddPermission(user, newUser.Group);
|
|
}
|
|
|
|
await Reload();
|
|
|
|
StateHasChanged();
|
|
|
|
await Alerts.FireAsync(new SweetAlertOptions {
|
|
Title = "New user added!",
|
|
Icon = SweetAlertIcon.Success,
|
|
ShowConfirmButton = false,
|
|
Timer = 1500
|
|
|
|
});
|
|
}
|
|
|
|
} |