RobotNet/RobotNet.IdentityServer/Components/Account/Pages/Role.razor
2025-10-15 15:15:53 +07:00

924 lines
36 KiB
Plaintext

@page "/Account/Rolemanager"
@rendermode InteractiveServer
@attribute [Authorize]
@using Microsoft.AspNetCore.Authorization
@using MudBlazor
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Identity
@using Microsoft.AspNetCore.Components
@using RobotNet.IdentityServer.Data
@using Microsoft.EntityFrameworkCore
@using System.Threading
@inherits LayoutComponentBase
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject UserManager<ApplicationUser> UserManager
@inject RoleManager<ApplicationRole> RoleManager
@inject ISnackbar Snackbar
@inject IDialogService DialogService
@inject NavigationManager NavigationManager
<MudDialogProvider />
<MudSnackbarProvider />
<div class="pa-4">
<div class="role-header">
<MudGrid>
<MudItem xs="12" md="8">
<div class="d-flex align-center">
<MudIcon Icon="@Icons.Material.Filled.AdminPanelSettings" Size="Size.Large" Class="mr-3" />
<div>
<MudText Typo="Typo.h4" Class="mb-1">Role Management</MudText>
<MudText Typo="Typo.body1" Style="opacity: 0.9;">Quản lý vai trò và phân quyền người dùng</MudText>
</div>
</div>
</MudItem>
<MudItem xs="12" md="4" Class="text-right">
<div class="stats-card">
<MudText Typo="Typo.h5">@Roles.Count</MudText>
<MudText Typo="Typo.body2">Tổng số vai trò</MudText>
</div>
</MudItem>
</MudGrid>
</div>
<MudGrid>
<MudItem xs="12" lg="4">
<MudPaper Class="modern-card pa-4" Elevation="0">
<div class="section-title">
<MudIcon Icon="@Icons.Material.Filled.Security" />
<MudText Typo="Typo.h6">Danh Sách Vai Trò</MudText>
</div>
<div class="search-container mb-3">
<MudTextField @bind-Value="roleSearchTerm"
Label="Tìm kiếm vai trò"
Variant="Variant.Outlined"
Adornment="Adornment.Start"
AdornmentIcon="@Icons.Material.Filled.Search"
Margin="Margin.Dense"
FullWidth="true" />
</div>
<div class="mb-3">
<MudButton Variant="Variant.Filled"
Color="Color.Primary"
StartIcon="@Icons.Material.Filled.Add"
OnClick="AddRole"
Class="action-button"
FullWidth="true">
Tạo Vai Trò Mới
</MudButton>
</div>
<div class="table-container">
<MudTable Items="@FilteredRoles" Hover="true" Dense="true" Striped="true">
<HeaderContent>
<MudTh><MudText Typo="Typo.subtitle2">Tên Vai Trò</MudText></MudTh>
<MudTh Style="width: 100px;"><MudText Typo="Typo.subtitle2">Thao Tác</MudText></MudTh>
</HeaderContent>
<RowTemplate>
<MudTd>
<div class="d-flex align-center">
<MudIcon Icon="@GetRoleIcon(context.Name ?? string.Empty)" Size="Size.Small" Class="mr-2" Color="@GetRoleColor(context.Name ?? string.Empty)" />
<MudText Typo="Typo.body2">@context.Name</MudText>
</div>
</MudTd>
<MudTd>
@if (LoggedInUserRoles.Contains(context.Name ?? string.Empty))
{
<MudTooltip Text="Vai trò không thể chỉnh sửa ">
<MudIconButton Icon="@Icons.Material.Filled.Lock"
Size="Size.Small"
Color="Color.Default"
Disabled="true" />
</MudTooltip>
}
else
{
<MudTooltip Text="Chỉnh sửa">
<MudIconButton Icon="@Icons.Material.Filled.Edit"
Size="Size.Small"
Color="Color.Primary"
OnClick="() => EditRole(context)"
Class="action-button mr-1" />
</MudTooltip>
<MudTooltip Text="Xóa">
<MudIconButton Icon="@Icons.Material.Filled.Delete"
Size="Size.Small"
Color="Color.Error"
OnClick="() => DelRole(context.Id, context.Name ?? string.Empty)"
Class="action-button" />
</MudTooltip>
}
</MudTd>
</RowTemplate>
<PagerContent>
<MudTablePager PageSizeOptions="new int[] { 5, 10, 25, 50, 100, int.MaxValue }"
RowsPerPageString="@rowsPerPageString" />
</PagerContent>
</MudTable>
</div>
</MudPaper>
</MudItem>
<MudItem xs="12" lg="8">
<MudPaper Class="modern-card pa-4" Elevation="0">
<div class="section-title">
<MudIcon Icon="@Icons.Material.Filled.People" />
<MudText Typo="Typo.h6">Quản Lý Người Dùng</MudText>
</div>
<div class="search-container mb-3">
<MudTextField @bind-Value="userSearchTerm"
Label="Tìm kiếm người dùng"
Variant="Variant.Outlined"
Adornment="Adornment.Start"
AdornmentIcon="@Icons.Material.Filled.Search"
Margin="Margin.Dense"
FullWidth="true" />
</div>
<div class="table-container">
<MudTable Items="@FilteredUsers" Hover="true" Dense="true" Striped="true">
<HeaderContent>
<MudTh><MudText Typo="Typo.subtitle2">Người Dùng</MudText></MudTh>
<MudTh><MudText Typo="Typo.subtitle2">Vai Trò</MudText></MudTh>
<MudTh Style="width: 100px;"><MudText Typo="Typo.subtitle2">Thao Tác</MudText></MudTh>
</HeaderContent>
<RowTemplate>
<MudTd>
<div class="d-flex align-center">
<div class="user-avatar">
@(context.UserName?.Substring(0, 1).ToUpper())
</div>
<div>
<MudText Typo="Typo.body2" Class="font-weight-medium">@context.UserName</MudText>
@if (context.UserId == LoggedInUserId)
{
<MudChip T="string"
Size="Size.Small"
Color="Color.Info"
Class="mt-1">
Bạn
</MudChip>
}
</div>
</div>
</MudTd>
<MudTd>
<div class="d-flex flex-wrap">
@if (context.Roles.Any())
{
foreach (var role in context.Roles)
{
<MudChip T="string"
Size="Size.Small"
Color="@GetRoleChipColor(role)"
Icon="@GetRoleIcon(role)"
Class="role-chip">
@role
</MudChip>
}
}
else
{
<MudChip T="string"
Size="Size.Small"
Color="Color.Default"
Class="role-chip">
Chưa có vai trò
</MudChip>
}
</div>
</MudTd>
<MudTd>
@if (context.UserId == LoggedInUserId)
{
<MudTooltip Text="Không thể chỉnh sửa vai trò của chính mình">
<MudIconButton Icon="@Icons.Material.Filled.Lock"
Size="Size.Small"
Color="Color.Default"
Disabled="true" />
</MudTooltip>
}
else
{
<MudTooltip Text="Quản lý vai trò">
<MudIconButton Icon="@Icons.Material.Filled.ManageAccounts"
Size="Size.Small"
Color="Color.Primary"
OnClick="() => ManageUserRoles(context.UserId ?? string.Empty, context.UserName ?? string.Empty)"
Class="action-button" />
</MudTooltip>
}
</MudTd>
</RowTemplate>
<PagerContent>
<MudTablePager PageSizeOptions="new int[] { 5, 10, 25, 50, 100, int.MaxValue }" />
</PagerContent>
</MudTable>
</div>
</MudPaper>
</MudItem>
</MudGrid>
</div>
<MudDialog @bind-Visible="CreateRoleVisible">
<TitleContent>
<div class="d-flex align-center">
<MudIcon Icon="@Icons.Material.Filled.Add" Class="mr-3" />
<MudText Typo="Typo.h6">Tạo Vai Trò Mới</MudText>
</div>
</TitleContent>
<DialogContent>
<MudTextField Label="Tên vai trò"
@bind-Value="NewRoleName"
Required="true"
Variant="Variant.Outlined"
FullWidth="true"
Margin="Margin.Dense"
Style="overflow:hidden;" />
</DialogContent>
<DialogActions>
<MudButton Color="Color.Primary"
Variant="Variant.Filled"
OnClick="CreateRole"
StartIcon="@Icons.Material.Filled.Save">
Tạo
</MudButton>
<MudButton Variant="Variant.Text"
OnClick="@(() => CreateRoleVisible = false)">
Hủy
</MudButton>
</DialogActions>
</MudDialog>
<MudDialog @bind-Visible="EditRoleVisible">
<TitleContent>
<div class="d-flex align-center">
<MudIcon Icon="@Icons.Material.Filled.Edit" Class="mr-3" />
<MudText Typo="Typo.h6">Chỉnh Sửa Vai Trò</MudText>
</div>
</TitleContent>
<DialogContent>
<MudTextField Label="Tên vai trò mới"
@bind-Value="EditRoleName"
Required="true"
Variant="Variant.Outlined"
FullWidth="true"
Margin="Margin.Dense" />
</DialogContent>
<DialogActions>
<MudButton Color="Color.Primary"
Variant="Variant.Filled"
OnClick="SaveEditRole"
StartIcon="@Icons.Material.Filled.Save">
Lưu
</MudButton>
<MudButton Variant="Variant.Text"
OnClick="@(() => EditRoleVisible = false)">
Hủy
</MudButton>
</DialogActions>
</MudDialog>
<MudDialog @bind-Visible="DelRoleVisible">
<TitleContent>
<div class="d-flex align-center">
<MudIcon Icon="@Icons.Material.Filled.Warning" Color="Color.Error" Class="mr-3" />
<MudText Typo="Typo.h6">Xác Nhận Xóa</MudText>
</div>
</TitleContent>
<DialogContent>
<MudAlert Severity="Severity.Warning" Class="mb-3">
Bạn có chắc chắn muốn xóa vai trò <strong>@RoleNameToDelete</strong>?
</MudAlert>
<MudText Typo="Typo.body2">Hành động này không thể hoàn tác.</MudText>
</DialogContent>
<DialogActions>
<MudButton Color="Color.Error"
Variant="Variant.Filled"
OnClick="ConfirmDelRole"
StartIcon="@Icons.Material.Filled.Delete">
Xóa
</MudButton>
<MudButton Variant="Variant.Text"
OnClick="@(() => DelRoleVisible = false)">
Hủy
</MudButton>
</DialogActions>
</MudDialog>
<MudDialog @bind-Visible="ManageUserRolesVisible">
<TitleContent>
<div class="d-flex align-center">
<MudIcon Icon="@Icons.Material.Filled.ManageAccounts" Class="mr-3" />
<MudText Typo="Typo.h6">Quản Lý Vai Trò: @SelectedUserName</MudText>
</div>
</TitleContent>
<DialogContent>
<MudGrid>
<MudItem xs="12">
<MudPaper Class="pa-4" Style="background: #f8fafc; border-radius: 12px;">
<MudText Typo="Typo.subtitle1" Class="mb-3">
<MudIcon Icon="@Icons.Material.Filled.Badge" Size="Size.Small" Class="mr-2" />
Vai Trò Hiện Tại
</MudText>
<div class="d-flex flex-wrap">
@if (AssignedRoles.Any())
{
foreach (var role in AssignedRoles)
{
if (role.Equals("Administrator", StringComparison.OrdinalIgnoreCase))
{
<MudChip T="string"
Color="Color.Warning"
Variant="Variant.Filled"
Icon="@Icons.Material.Filled.Lock"
Class="ma-1">
@role (Được bảo vệ)
</MudChip>
}
else
{
<MudChip T="string"
Color="@GetRoleChipColor(role)"
Variant="Variant.Filled"
Icon="@GetRoleIcon(role)"
Class="ma-1">
@role
</MudChip>
}
}
}
else
{
<MudText Typo="Typo.body2" Color="Color.Default">
Chưa có vai trò nào
</MudText>
}
</div>
</MudPaper>
</MudItem>
<MudItem xs="12" md="6">
<MudPaper Class="pa-4" Style="border: 2px dashed #e2e8f0; border-radius: 12px;">
<MudText Typo="Typo.subtitle1" Class="mb-3" Color="Color.Success">
<MudIcon Icon="@Icons.Material.Filled.Add" Size="Size.Small" Class="mr-2" />
Thêm Vai Trò
</MudText>
<MudSelect T="string"
Label="Chọn vai trò để thêm"
MultiSelection="true"
@bind-SelectedValues="selectedRolesToAdd"
Variant="Variant.Outlined"
Clearable="true"
Dense="true"
MaxHeight="200"
FullWidth="true">
@foreach (var role in AvailableRoles)
{
<MudSelectItem T="string" Value="@role">
<div class="d-flex align-center">
<MudIcon Icon="@GetRoleIcon(role)" Size="Size.Small" Class="mr-2" />
@role
</div>
</MudSelectItem>
}
</MudSelect>
<MudButton Color="Color.Success"
Variant="Variant.Filled"
StartIcon="@Icons.Material.Filled.Add"
OnClick="AddSelectedRolesToUser"
Disabled="@(!selectedRolesToAdd.Any())"
Class="mt-3"
FullWidth="true">
Thêm (@selectedRolesToAdd.Count())
</MudButton>
</MudPaper>
</MudItem>
@{
var removableRoles = AssignedRoles
.Where(role => !role.Equals("Administrator", StringComparison.OrdinalIgnoreCase))
.ToList();
}
@if (removableRoles.Any())
{
<MudItem xs="12" md="6">
<MudPaper Class="pa-4" Style="border: 2px dashed #fed7d4; border-radius: 12px;">
<MudText Typo="Typo.subtitle1" Class="mb-3" Color="Color.Error">
<MudIcon Icon="@Icons.Material.Filled.Remove" Size="Size.Small" Class="mr-2" />
Xóa Vai Trò
</MudText>
<MudSelect T="string"
Label="Chọn vai trò để xóa"
MultiSelection="true"
@bind-SelectedValues="selectedRolesToRemove"
Variant="Variant.Outlined"
Clearable="true"
Dense="true"
MaxHeight="200"
FullWidth="true">
@foreach (var role in removableRoles)
{
<MudSelectItem T="string" Value="@role">
<div class="d-flex align-center">
<MudIcon Icon="@GetRoleIcon(role)" Size="Size.Small" Class="mr-2" />
@role
</div>
</MudSelectItem>
}
</MudSelect>
<MudButton Color="Color.Error"
Variant="Variant.Filled"
StartIcon="@Icons.Material.Filled.Remove"
OnClick="RemoveSelectedRolesFromUser"
Disabled="@(!selectedRolesToRemove.Any())"
Class="mt-3"
FullWidth="true">
Xóa (@selectedRolesToRemove.Count())
</MudButton>
</MudPaper>
</MudItem>
}
</MudGrid>
</DialogContent>
<DialogActions>
<MudButton Variant="Variant.Text"
OnClick="@(() => ManageUserRolesVisible = false)">
Đóng
</MudButton>
</DialogActions>
</MudDialog>
@code {
private bool CreateRoleVisible { get; set; }
private bool DelRoleVisible { get; set; }
private bool EditRoleVisible { get; set; }
private bool ManageUserRolesVisible { get; set; } = false;
private string CurrentRoleId { get; set; } = "";
private string EditRoleName { get; set; } = "";
private string NewRoleName { get; set; } = "";
private string RoleNameToDelete { get; set; } = "";
private string RoleIdToDelete { get; set; } = "";
private string SelectedUserName { get; set; } = string.Empty;
private string UserIdToManageRoles { get; set; } = string.Empty;
private string LoggedInUserId { get; set; } = string.Empty;
private List<string> LoggedInUserRoles { get; set; } = new();
private List<string> AllRoles { get; set; } = new List<string>();
private List<string> AvailableRoles { get; set; } = new List<string>();
private List<string> AssignedRoles { get; set; } = new List<string>();
private List<ApplicationRole> Roles { get; set; } = new List<ApplicationRole>();
private List<UserRoleModel> UsersWithRoles { get; set; } = new List<UserRoleModel>();
private IEnumerable<string> selectedRolesToAdd = new HashSet<string>();
private IEnumerable<string> selectedRolesToRemove = new HashSet<string>();
private string rowsPerPageString = "Rows:";
private string roleSearchTerm = "";
private string userSearchTerm = "";
private IEnumerable<ApplicationRole> FilteredRoles =>
string.IsNullOrWhiteSpace(roleSearchTerm)
? Roles
: Roles?.Where(r => r.Name != null && r.Name.Contains(roleSearchTerm, StringComparison.OrdinalIgnoreCase)) ?? Enumerable.Empty<ApplicationRole>();
private IEnumerable<UserRoleModel> FilteredUsers =>
string.IsNullOrWhiteSpace(userSearchTerm)
? UsersWithRoles
: UsersWithRoles?.Where(u => u.UserName != null && u.UserName.Contains(userSearchTerm, StringComparison.OrdinalIgnoreCase)) ?? Enumerable.Empty<UserRoleModel>();
private string GetRoleIcon(string roleName)
{
return roleName?.ToLower() switch
{
"administrator" => Icons.Material.Filled.SupervisorAccount,
"user" => Icons.Material.Filled.Person,
"guest" => Icons.Material.Filled.PersonOutline,
_ => Icons.Material.Filled.Security
};
}
private Color GetRoleColor(string roleName)
{
return roleName?.ToLower() switch
{
"administrator" => Color.Error,
"user" => Color.Primary,
"guest" => Color.Default,
_ => Color.Info
};
}
private Color GetRoleChipColor(string roleName)
{
return roleName?.ToLower() switch
{
"administrator" => Color.Error,
"user" => Color.Primary,
"guest" => Color.Default,
_ => Color.Info
};
}
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
var authenticationState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var currentUser = authenticationState.User;
if (currentUser.Identity?.IsAuthenticated == true)
{
LoggedInUserId = currentUser.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value ?? string.Empty;
var currentUserObj = await UserManager.GetUserAsync(currentUser);
if (currentUserObj != null)
{
LoggedInUserRoles = (await UserManager.GetRolesAsync(currentUserObj)).ToList();
}
Roles = await RoleManager.Roles.OrderBy(r => r.CreatedDate).ToListAsync();
await LoadAllRoles();
await LoadUsersWithRoles();
StateHasChanged();
}
else
{
Snackbar.Add("User is not authenticated.", Severity.Error);
}
}
private async Task LoadUsersWithRoles()
{
try
{
var users = await UserManager.Users.ToListAsync();
if (users == null || !users.Any())
{
Snackbar.Add("No users found.", Severity.Error);
return;
}
var userRoleList = new List<UserRoleModel>();
foreach (var user in users)
{
var userRoles = await UserManager.GetRolesAsync(user);
userRoleList.Add(new UserRoleModel
{
UserName = user.UserName,
Roles = userRoles.ToList(),
UserId = user.Id
});
}
UsersWithRoles = userRoleList.OrderBy(u => u.UserId == LoggedInUserId ? 0 : 1).ToList();
StateHasChanged();
}
catch (Exception ex)
{
Snackbar.Add($"Lỗi khi tải người dùng và role: {ex.Message}", Severity.Error);
UsersWithRoles = new List<UserRoleModel>();
}
}
private async Task LoadAllRoles()
{
try
{
var roles = await RoleManager.Roles
.Select(role => role.Name)
.ToListAsync();
AllRoles = roles.Where(name => !string.IsNullOrEmpty(name)).Cast<string>().ToList() ?? new List<string>();
if (!AllRoles.Any())
{
Snackbar.Add("Không tìm thấy vai trò nào.", Severity.Warning);
}
}
catch (Exception ex)
{
Snackbar.Add($"Lỗi khi tải danh sách vai trò: {ex.Message}", Severity.Error);
AllRoles = new List<string>();
}
}
private void AddRole()
{
CreateRoleVisible = true;
StateHasChanged();
}
private void DelRole(string roleId, string roleName)
{
RoleIdToDelete = roleId;
RoleNameToDelete = roleName;
DelRoleVisible = true;
StateHasChanged();
}
private void EditRole(ApplicationRole role)
{
if (role?.Name is not null)
{
CurrentRoleId = role.Id;
EditRoleName = role.Name;
EditRoleVisible = true;
StateHasChanged();
}
else
{
Snackbar.Add("Role information is incomplete or invalid.", Severity.Error);
}
}
private async Task ManageUserRoles(string userId, string userName)
{
if (!LoggedInUserRoles.Contains("Administrator"))
{
Snackbar.Add("Bạn không có quyền quản lý role của user khác.", Severity.Error);
return;
}
if (!AllRoles.Any())
{
Snackbar.Add("Không có vai trò nào có thể chỉ định", Severity.Warning);
return;
}
SelectedUserName = userName;
UserIdToManageRoles = userId;
var user = await UserManager.FindByIdAsync(userId);
if (user != null)
{
var userRoles = await UserManager.GetRolesAsync(user);
AssignedRoles = userRoles.ToList();
AvailableRoles = AllRoles
.Except(userRoles)
.Where(role => !role.Equals("Administrator", StringComparison.OrdinalIgnoreCase))
.ToList();
}
selectedRolesToAdd = new HashSet<string>();
selectedRolesToRemove = new HashSet<string>();
ManageUserRolesVisible = true;
StateHasChanged();
}
private async Task AddSelectedRolesToUser()
{
foreach (var role in selectedRolesToAdd.ToList())
{
await AddRoleToSelectedUser(role);
}
selectedRolesToAdd = new HashSet<string>();
StateHasChanged();
}
private async Task RemoveSelectedRolesFromUser()
{
foreach (var role in selectedRolesToRemove.ToList())
{
await RemoveRoleFromSelectedUser(role);
}
selectedRolesToRemove = new HashSet<string>();
StateHasChanged();
}
private async Task AddRoleToSelectedUser(string roleName)
{
if (roleName.Equals("Administrator", StringComparison.OrdinalIgnoreCase))
{
Snackbar.Add("Không thể gán role Admin cho user khác.", Severity.Error);
return;
}
if (!LoggedInUserRoles.Contains("Administrator"))
{
Snackbar.Add("Bạn không có quyền thực hiện thao tác này.", Severity.Error);
return;
}
var user = await UserManager.FindByIdAsync(UserIdToManageRoles);
if (user != null)
{
var result = await UserManager.AddToRoleAsync(user, roleName);
if (result.Succeeded)
{
AssignedRoles.Add(roleName);
AvailableRoles.Remove(roleName);
selectedRolesToAdd = selectedRolesToAdd.Where(r => r != roleName);
Snackbar.Add($"Thêm role '{roleName}' cho {SelectedUserName} Thành Công.", Severity.Success);
await LoadUsersWithRoles();
StateHasChanged();
}
else
{
Snackbar.Add($"Failed to add role '{roleName}' to user.", Severity.Error);
}
}
}
private async Task RemoveRoleFromSelectedUser(string roleName)
{
if (roleName.Equals("Administrator", StringComparison.OrdinalIgnoreCase))
{
Snackbar.Add("Không thể xóa role Admin của user.", Severity.Error);
return;
}
if (!LoggedInUserRoles.Contains("Administrator"))
{
Snackbar.Add("Bạn không có quyền thực hiện thao tác này.", Severity.Error);
return;
}
var user = await UserManager.FindByIdAsync(UserIdToManageRoles);
if (user != null)
{
var result = await UserManager.RemoveFromRoleAsync(user, roleName);
if (result.Succeeded)
{
AssignedRoles.Remove(roleName);
AvailableRoles.Add(roleName);
selectedRolesToRemove = selectedRolesToRemove.Where(r => r != roleName);
Snackbar.Add($"Thành công xoá role '{roleName}' của {SelectedUserName}.", Severity.Success);
await LoadUsersWithRoles();
StateHasChanged();
}
else
{
Snackbar.Add($"Failed to remove role '{roleName}' from user.", Severity.Error);
}
}
}
private async Task CreateRole()
{
if (string.IsNullOrWhiteSpace(NewRoleName))
{
Snackbar.Add(" Tên Role không được để trống.", Severity.Error);
StateHasChanged();
return;
}
var roleExist = await RoleManager.RoleExistsAsync(NewRoleName.ToUpper());
if (roleExist)
{
Snackbar.Add(" Role đã tồn tại.", Severity.Warning);
CreateRoleVisible = false;
NewRoleName = "";
StateHasChanged();
return;
}
var newRole = new ApplicationRole
{
Name = NewRoleName,
NormalizedName = NewRoleName.ToUpper(),
CreatedDate = DateTime.UtcNow
};
var result = await RoleManager.CreateAsync(newRole);
if (result.Succeeded)
{
Roles.Add(newRole);
Snackbar.Add(" Tạo Role thành công!", Severity.Success);
await LoadAllRoles();
CreateRoleVisible = false;
NewRoleName = "";
StateHasChanged();
}
else
{
Snackbar.Add(" Tạo Role thất bại.", Severity.Error);
StateHasChanged();
}
}
private async Task SaveEditRole()
{
if (string.IsNullOrWhiteSpace(EditRoleName))
{
Snackbar.Add("Tên Role không được để trống.", Severity.Error);
StateHasChanged();
return;
}
var role = await RoleManager.FindByIdAsync(CurrentRoleId);
if (role != null)
{
role.Name = EditRoleName;
role.NormalizedName = EditRoleName.ToUpper();
var result = await RoleManager.UpdateAsync(role);
if (result.Succeeded)
{
var existingRole = Roles.FirstOrDefault(r => r.Id == role.Id);
if (existingRole != null)
{
existingRole.Name = role.Name;
}
Snackbar.Add("Role đã được sửa thành công!", Severity.Success);
await LoadAllRoles();
await LoadUsersWithRoles();
EditRoleVisible = false;
EditRoleName = "";
StateHasChanged();
}
else
{
Snackbar.Add("Sửa Role thất bại.", Severity.Error);
EditRoleVisible = false;
StateHasChanged();
}
}
else
{
Snackbar.Add("Không tìm thấy role với ID đã cho.", Severity.Error);
EditRoleVisible = false;
StateHasChanged();
}
}
private async Task ConfirmDelRole()
{
if (string.IsNullOrEmpty(RoleIdToDelete))
{
Snackbar.Add(" Không tìm thấy Role để xóa.", Severity.Error);
return;
}
var role = await RoleManager.FindByIdAsync(RoleIdToDelete);
if (role != null)
{
var result = await RoleManager.DeleteAsync(role);
if (result.Succeeded)
{
Snackbar.Add(" Đã xóa Role thành công.", Severity.Success);
Roles = await RoleManager.Roles
.OrderBy(r => r.CreatedDate)
.ToListAsync();
await LoadAllRoles();
await LoadUsersWithRoles();
}
else
{
Snackbar.Add(" Xóa Role thất bại.", Severity.Error);
}
}
else
{
Snackbar.Add(" Không tìm thấy Role để xóa.", Severity.Error);
}
DelRoleVisible = false;
RoleIdToDelete = "";
StateHasChanged();
}
public class UserRoleModel
{
public string? UserName { get; set; }
public List<string> Roles { get; set; } = new List<string>();
public string? UserId { get; set; }
}
}