This commit is contained in:
MOHD ARIFF 2024-12-18 14:37:58 +08:00
parent 3610536233
commit a1e2bf6ae0
13 changed files with 269 additions and 100 deletions

View File

@ -21,13 +21,15 @@ namespace PSTW_CentralSystem.Controllers.API
private readonly IdentityDBContext _identityDbContext; private readonly IdentityDBContext _identityDbContext;
private readonly UserManager<UserModel> _userManager; private readonly UserManager<UserModel> _userManager;
private readonly SignInManager<UserModel> _signInManager; private readonly SignInManager<UserModel> _signInManager;
private readonly RoleManager<RoleModel> _roleManager;
public AdminAPI(ILogger<AdminAPI> logger, IdentityDBContext authDbContext, UserManager<UserModel> userManager, SignInManager<UserModel> signInManager) public AdminAPI(ILogger<AdminAPI> logger, IdentityDBContext authDbContext, UserManager<UserModel> userManager, SignInManager<UserModel> signInManager, RoleManager<RoleModel> roleManager)
{ {
_logger = logger; _logger = logger;
_identityDbContext = authDbContext; _identityDbContext = authDbContext;
_userManager = userManager; _userManager = userManager;
_signInManager = signInManager; _signInManager = signInManager;
_roleManager = roleManager;
} }
[HttpPost("GetClassAndMethodInformation")] [HttpPost("GetClassAndMethodInformation")]
@ -86,6 +88,7 @@ namespace PSTW_CentralSystem.Controllers.API
// Return the list as JSON // Return the list as JSON
return Json(controllerAndMethodList); return Json(controllerAndMethodList);
} }
[HttpPost("GetUserList")] [HttpPost("GetUserList")]
public async Task<IActionResult> GetUserList() public async Task<IActionResult> GetUserList()
{ {
@ -98,7 +101,7 @@ namespace PSTW_CentralSystem.Controllers.API
// Fetch all users excluding those with roles SuperAdmin or SystemAdmin // Fetch all users excluding those with roles SuperAdmin or SystemAdmin
var allUsers = await _identityDbContext.Users var allUsers = await _identityDbContext.Users
.Include(u => u.Department) .Include(u => u.Department.Company)
.ToListAsync(); .ToListAsync();
if (userRole == null || userRole.Count == 0) if (userRole == null || userRole.Count == 0)
@ -114,15 +117,16 @@ namespace PSTW_CentralSystem.Controllers.API
} }
else else
{ {
userInfo = await _identityDbContext.Users.Include(u => u.Department).ToListAsync(); userInfo = allUsers;
} }
var userList = userInfo.Select(u => new var userList = userInfo.Select(u => new
{ {
id = u.Id, id = u.Id,
email = u.NormalizedEmail, email = u.NormalizedEmail,
company = u.Department?.Company?.CompanyName, company = u.Department?.Company?.CompanyName,
department = u.Department, department = u.Department?.DepartmentName,
role = _userManager.GetRolesAsync(u).Result role = _userManager.GetRolesAsync(u).Result,
status = u.UserInfoStatus,
}).ToList(); }).ToList();
return Ok(new { UserInfo = userList }); return Ok(new { UserInfo = userList });
} }
@ -132,6 +136,43 @@ namespace PSTW_CentralSystem.Controllers.API
} }
} }
[HttpPatch("UpdateUserStatusAndRole/{id}")]
public async Task<IActionResult> UpdateUserStatusAndRole(int id, [FromBody] string role)
{
try
{
var user = await _identityDbContext.Users.FindAsync(id);
if (user == null)
{
return NotFound(new { message = "User not found" });
}
var existingUserRoles = await _userManager.GetRolesAsync(user);
if (existingUserRoles != null && existingUserRoles.Count > 0) {
await _userManager.RemoveFromRolesAsync(user, existingUserRoles);
}
await _userManager.AddToRoleAsync(user, role);
user.UserInfoStatus = 1;
await _identityDbContext.SaveChangesAsync();
return Ok(new { message = "User updated successfully" });
}
catch (Exception ex)
{
return StatusCode(500, $"An error occurred: {ex.Message}");
}
}
[HttpPost("GetRoleList")]
public async Task<IActionResult> GetRoleList()
{
var roles = await _roleManager.Roles.Select(r => new { r.Id, r.Name }).Where(r => r.Name != "SuperAdmin" && r.Name != "SystemAdmin").ToListAsync();
return Json(roles);
}
[HttpPost("GetDepartmentWithCompanyList")] [HttpPost("GetDepartmentWithCompanyList")]
public async Task<IActionResult> GetDepartmentWithCompanyList() public async Task<IActionResult> GetDepartmentWithCompanyList()
{ {
@ -160,12 +201,13 @@ namespace PSTW_CentralSystem.Controllers.API
DepartmentId = departmentList!.DepartmentId, DepartmentId = departmentList!.DepartmentId,
DepartmentName = departmentList.DepartmentName, DepartmentName = departmentList.DepartmentName,
CompanyId = departmentList.CompanyId, CompanyId = departmentList.CompanyId,
CompanyName = companyList?.CompanyName CompanyName = companyList?.CompanyName,
}; };
// Return the constructed list as JSON // Return the constructed list as JSON
return departmentWithCompany; return departmentWithCompany;
} }
[HttpPost("AddCompanyDepartment")] [HttpPost("AddCompanyDepartment")]
public async Task<IActionResult> AddCompanyDepartment([FromBody] UpdateDepartmentCompany departmentCompanyDetails) public async Task<IActionResult> AddCompanyDepartment([FromBody] UpdateDepartmentCompany departmentCompanyDetails)
{ {

View File

@ -62,11 +62,6 @@ namespace PSTW_CentralSystem.Controllers.API
return StatusCode(500, $"An error occurred: {ex.Message}"); return StatusCode(500, $"An error occurred: {ex.Message}");
} }
} }
public class LdapLoginCredential
{
public required string username { get; set; }
public required string password { get; set; }
}
[HttpPost("LdapLogin")] [HttpPost("LdapLogin")]
public async Task<IActionResult> LdapLogin([FromBody] LdapLoginCredential ldapLoginInfo) public async Task<IActionResult> LdapLogin([FromBody] LdapLoginCredential ldapLoginInfo)
@ -140,7 +135,7 @@ namespace PSTW_CentralSystem.Controllers.API
await _signInManager.SignInAsync(existUser, false); await _signInManager.SignInAsync(existUser, false);
if (existUser.UserStatus == null || existUser.UserStatus != 0) if (existUser.UserInfoStatus == null || existUser.UserInfoStatus != 0)
{ {
return Ok(new { RedirectUrl = Url.Action("ComDeptAssignment", "Identity") }); return Ok(new { RedirectUrl = Url.Action("ComDeptAssignment", "Identity") });
} }
@ -190,10 +185,23 @@ namespace PSTW_CentralSystem.Controllers.API
#endregion Department #endregion Department
[HttpPost("UserComptDeptAssignment")] [HttpPost("UserComptDeptAssignment/{id}")]
public async Task<IActionResult> UserComptDeptAssignment([FromBody] UserModel userModel) public async Task<IActionResult> UserComptDeptAssignment([FromBody] UserDeptAssignment userDeptAssignment, int id)
{ {
return Ok(); var deptId = userDeptAssignment.departmentId;
if (deptId <= 0)
{
return BadRequest(new { message = "Invalid department ID provided." });
}
var user = await _userManager.FindByIdAsync(id.ToString());
if(user == null)
{
return NotFound( new { message = $"Unable to load user with ID '{id}'." });
}
user.UserInfoStatus = 0;
user.departmentId = deptId;
await _userManager.UpdateAsync(user);
return Ok( new { message = "User updated successfully", RedirectUrl = Url.Action("Index", "Home") });
} }
public async Task<UserModel?> doUserExists(string username) public async Task<UserModel?> doUserExists(string username)
@ -202,6 +210,15 @@ namespace PSTW_CentralSystem.Controllers.API
return user != null ? user : null; return user != null ? user : null;
} }
public class LdapLoginCredential
{
public required string username { get; set; }
public required string password { get; set; }
}
public class UserDeptAssignment()
{
public required int departmentId { get; set; }
}
class userLdapInfo() class userLdapInfo()
{ {
public required bool Authenticated { get; set; } public required bool Authenticated { get; set; }

View File

@ -52,7 +52,7 @@ namespace PSTW_CentralSystem.DBContext
NormalizedEmail = "ADMIN@PSTW.COM.MY", NormalizedEmail = "ADMIN@PSTW.COM.MY",
SecurityStamp = Guid.NewGuid().ToString(), SecurityStamp = Guid.NewGuid().ToString(),
EmailConfirmed = true, EmailConfirmed = true,
UserStatus = 1, UserInfoStatus = 1,
}; };
var systemAdmin = new UserModel var systemAdmin = new UserModel
{ {
@ -64,7 +64,7 @@ namespace PSTW_CentralSystem.DBContext
NormalizedEmail = "SYSADMIN@PSTW.COM.MY", NormalizedEmail = "SYSADMIN@PSTW.COM.MY",
SecurityStamp = Guid.NewGuid().ToString(), SecurityStamp = Guid.NewGuid().ToString(),
EmailConfirmed = true, EmailConfirmed = true,
UserStatus = 1, UserInfoStatus = 1,
}; };
// Hash the password // Hash the password

View File

@ -12,7 +12,7 @@ using PSTW_CentralSystem.DBContext;
namespace PSTW_CentralSystem.Migrations namespace PSTW_CentralSystem.Migrations
{ {
[DbContext(typeof(IdentityDBContext))] [DbContext(typeof(IdentityDBContext))]
[Migration("20241206015840_Initiate")] [Migration("20241218060528_Initiate")]
partial class Initiate partial class Initiate
{ {
/// <inheritdoc /> /// <inheritdoc />
@ -329,13 +329,13 @@ namespace PSTW_CentralSystem.Migrations
b.Property<bool>("TwoFactorEnabled") b.Property<bool>("TwoFactorEnabled")
.HasColumnType("tinyint(1)"); .HasColumnType("tinyint(1)");
b.Property<int?>("UserInfoStatus")
.HasColumnType("int");
b.Property<string>("UserName") b.Property<string>("UserName")
.HasMaxLength(256) .HasMaxLength(256)
.HasColumnType("varchar(256)"); .HasColumnType("varchar(256)");
b.Property<int?>("UserStatus")
.HasColumnType("int");
b.Property<int?>("departmentId") b.Property<int?>("departmentId")
.HasColumnType("int"); .HasColumnType("int");
@ -357,34 +357,36 @@ namespace PSTW_CentralSystem.Migrations
{ {
Id = 1, Id = 1,
AccessFailedCount = 0, AccessFailedCount = 0,
ConcurrencyStamp = "b58597b6-2835-4ff6-b437-11ec7a213434", ConcurrencyStamp = "f89f9499-14a5-4bba-a003-5bbb0ef1bb12",
Email = "admin@pstw.com.my", Email = "admin@pstw.com.my",
EmailConfirmed = true, EmailConfirmed = true,
FullName = "MAAdmin", FullName = "MAAdmin",
LockoutEnabled = false, LockoutEnabled = false,
NormalizedEmail = "ADMIN@PSTW.COM.MY", NormalizedEmail = "ADMIN@PSTW.COM.MY",
NormalizedUserName = "ADMIN@PSTW.COM.MY", NormalizedUserName = "ADMIN@PSTW.COM.MY",
PasswordHash = "AQAAAAIAAYagAAAAECA03al9kGFTKlmmTls3wiH4NV7HlL76680Qx6lR7d77LHJwIN6/Wt1MBCP9TE1qfg==", PasswordHash = "AQAAAAIAAYagAAAAEDue4k8/8FwBvdJbbgBDLH+ibzmThXls6CmbJd99AdlrbPZrOWvWxlkv7cwVsPSM9g==",
PhoneNumberConfirmed = false, PhoneNumberConfirmed = false,
SecurityStamp = "0f649a27-6566-436c-bc27-d1a6b8e7f846", SecurityStamp = "d5684375-c368-409a-82e1-1e44fa05de60",
TwoFactorEnabled = false, TwoFactorEnabled = false,
UserInfoStatus = 1,
UserName = "admin@pstw.com.my" UserName = "admin@pstw.com.my"
}, },
new new
{ {
Id = 2, Id = 2,
AccessFailedCount = 0, AccessFailedCount = 0,
ConcurrencyStamp = "cf9424fc-8afc-4f59-a0a6-34574676273c", ConcurrencyStamp = "d19f378c-eef5-4cf7-8ec6-c6b3904e4749",
Email = "sysadmin@pstw.com.my", Email = "sysadmin@pstw.com.my",
EmailConfirmed = true, EmailConfirmed = true,
FullName = "SysAdmin", FullName = "SysAdmin",
LockoutEnabled = false, LockoutEnabled = false,
NormalizedEmail = "SYSADMIN@PSTW.COM.MY", NormalizedEmail = "SYSADMIN@PSTW.COM.MY",
NormalizedUserName = "SYSADMIN@PSTW.COM.MY", NormalizedUserName = "SYSADMIN@PSTW.COM.MY",
PasswordHash = "AQAAAAIAAYagAAAAEMkwXv250FjOjdLEAY2a/aEF3g3iu9xCVORV/MH37kVcj8vgJez+LlfJtjklaschLg==", PasswordHash = "AQAAAAIAAYagAAAAEDme/kiOHre+s0r9XvpwSr5dZIoWIbSJhI5B19mCjH4ZFoBBlF6Pay9WYJ2jcVZgfw==",
PhoneNumberConfirmed = false, PhoneNumberConfirmed = false,
SecurityStamp = "8efe9683-78fb-404d-96a9-b8b7302c03b2", SecurityStamp = "7875eac4-323d-43cb-a083-940e52877171",
TwoFactorEnabled = false, TwoFactorEnabled = false,
UserInfoStatus = 1,
UserName = "sysadmin@pstw.com.my" UserName = "sysadmin@pstw.com.my"
}); });
}); });

View File

@ -131,7 +131,7 @@ namespace PSTW_CentralSystem.Migrations
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
FullName = table.Column<string>(type: "longtext", nullable: true) FullName = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"), .Annotation("MySql:CharSet", "utf8mb4"),
UserStatus = table.Column<int>(type: "int", nullable: true), UserInfoStatus = table.Column<int>(type: "int", nullable: true),
departmentId = table.Column<int>(type: "int", nullable: true), departmentId = table.Column<int>(type: "int", nullable: true),
UserName = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true) UserName = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"), .Annotation("MySql:CharSet", "utf8mb4"),
@ -277,11 +277,11 @@ namespace PSTW_CentralSystem.Migrations
migrationBuilder.InsertData( migrationBuilder.InsertData(
table: "AspNetUsers", table: "AspNetUsers",
columns: new[] { "Id", "AccessFailedCount", "ConcurrencyStamp", "Email", "EmailConfirmed", "FullName", "LockoutEnabled", "LockoutEnd", "NormalizedEmail", "NormalizedUserName", "PasswordHash", "PhoneNumber", "PhoneNumberConfirmed", "SecurityStamp", "TwoFactorEnabled", "UserName", "UserStatus", "departmentId" }, columns: new[] { "Id", "AccessFailedCount", "ConcurrencyStamp", "Email", "EmailConfirmed", "FullName", "LockoutEnabled", "LockoutEnd", "NormalizedEmail", "NormalizedUserName", "PasswordHash", "PhoneNumber", "PhoneNumberConfirmed", "SecurityStamp", "TwoFactorEnabled", "UserInfoStatus", "UserName", "departmentId" },
values: new object[,] values: new object[,]
{ {
{ 1, 0, "b58597b6-2835-4ff6-b437-11ec7a213434", "admin@pstw.com.my", true, "MAAdmin", false, null, "ADMIN@PSTW.COM.MY", "ADMIN@PSTW.COM.MY", "AQAAAAIAAYagAAAAECA03al9kGFTKlmmTls3wiH4NV7HlL76680Qx6lR7d77LHJwIN6/Wt1MBCP9TE1qfg==", null, false, "0f649a27-6566-436c-bc27-d1a6b8e7f846", false, "admin@pstw.com.my", null, null }, { 1, 0, "f89f9499-14a5-4bba-a003-5bbb0ef1bb12", "admin@pstw.com.my", true, "MAAdmin", false, null, "ADMIN@PSTW.COM.MY", "ADMIN@PSTW.COM.MY", "AQAAAAIAAYagAAAAEDue4k8/8FwBvdJbbgBDLH+ibzmThXls6CmbJd99AdlrbPZrOWvWxlkv7cwVsPSM9g==", null, false, "d5684375-c368-409a-82e1-1e44fa05de60", false, 1, "admin@pstw.com.my", null },
{ 2, 0, "cf9424fc-8afc-4f59-a0a6-34574676273c", "sysadmin@pstw.com.my", true, "SysAdmin", false, null, "SYSADMIN@PSTW.COM.MY", "SYSADMIN@PSTW.COM.MY", "AQAAAAIAAYagAAAAEMkwXv250FjOjdLEAY2a/aEF3g3iu9xCVORV/MH37kVcj8vgJez+LlfJtjklaschLg==", null, false, "8efe9683-78fb-404d-96a9-b8b7302c03b2", false, "sysadmin@pstw.com.my", null, null } { 2, 0, "d19f378c-eef5-4cf7-8ec6-c6b3904e4749", "sysadmin@pstw.com.my", true, "SysAdmin", false, null, "SYSADMIN@PSTW.COM.MY", "SYSADMIN@PSTW.COM.MY", "AQAAAAIAAYagAAAAEDme/kiOHre+s0r9XvpwSr5dZIoWIbSJhI5B19mCjH4ZFoBBlF6Pay9WYJ2jcVZgfw==", null, false, "7875eac4-323d-43cb-a083-940e52877171", false, 1, "sysadmin@pstw.com.my", null }
}); });
migrationBuilder.InsertData( migrationBuilder.InsertData(

View File

@ -326,13 +326,13 @@ namespace PSTW_CentralSystem.Migrations
b.Property<bool>("TwoFactorEnabled") b.Property<bool>("TwoFactorEnabled")
.HasColumnType("tinyint(1)"); .HasColumnType("tinyint(1)");
b.Property<int?>("UserInfoStatus")
.HasColumnType("int");
b.Property<string>("UserName") b.Property<string>("UserName")
.HasMaxLength(256) .HasMaxLength(256)
.HasColumnType("varchar(256)"); .HasColumnType("varchar(256)");
b.Property<int?>("UserStatus")
.HasColumnType("int");
b.Property<int?>("departmentId") b.Property<int?>("departmentId")
.HasColumnType("int"); .HasColumnType("int");
@ -354,34 +354,36 @@ namespace PSTW_CentralSystem.Migrations
{ {
Id = 1, Id = 1,
AccessFailedCount = 0, AccessFailedCount = 0,
ConcurrencyStamp = "b58597b6-2835-4ff6-b437-11ec7a213434", ConcurrencyStamp = "f89f9499-14a5-4bba-a003-5bbb0ef1bb12",
Email = "admin@pstw.com.my", Email = "admin@pstw.com.my",
EmailConfirmed = true, EmailConfirmed = true,
FullName = "MAAdmin", FullName = "MAAdmin",
LockoutEnabled = false, LockoutEnabled = false,
NormalizedEmail = "ADMIN@PSTW.COM.MY", NormalizedEmail = "ADMIN@PSTW.COM.MY",
NormalizedUserName = "ADMIN@PSTW.COM.MY", NormalizedUserName = "ADMIN@PSTW.COM.MY",
PasswordHash = "AQAAAAIAAYagAAAAECA03al9kGFTKlmmTls3wiH4NV7HlL76680Qx6lR7d77LHJwIN6/Wt1MBCP9TE1qfg==", PasswordHash = "AQAAAAIAAYagAAAAEDue4k8/8FwBvdJbbgBDLH+ibzmThXls6CmbJd99AdlrbPZrOWvWxlkv7cwVsPSM9g==",
PhoneNumberConfirmed = false, PhoneNumberConfirmed = false,
SecurityStamp = "0f649a27-6566-436c-bc27-d1a6b8e7f846", SecurityStamp = "d5684375-c368-409a-82e1-1e44fa05de60",
TwoFactorEnabled = false, TwoFactorEnabled = false,
UserInfoStatus = 1,
UserName = "admin@pstw.com.my" UserName = "admin@pstw.com.my"
}, },
new new
{ {
Id = 2, Id = 2,
AccessFailedCount = 0, AccessFailedCount = 0,
ConcurrencyStamp = "cf9424fc-8afc-4f59-a0a6-34574676273c", ConcurrencyStamp = "d19f378c-eef5-4cf7-8ec6-c6b3904e4749",
Email = "sysadmin@pstw.com.my", Email = "sysadmin@pstw.com.my",
EmailConfirmed = true, EmailConfirmed = true,
FullName = "SysAdmin", FullName = "SysAdmin",
LockoutEnabled = false, LockoutEnabled = false,
NormalizedEmail = "SYSADMIN@PSTW.COM.MY", NormalizedEmail = "SYSADMIN@PSTW.COM.MY",
NormalizedUserName = "SYSADMIN@PSTW.COM.MY", NormalizedUserName = "SYSADMIN@PSTW.COM.MY",
PasswordHash = "AQAAAAIAAYagAAAAEMkwXv250FjOjdLEAY2a/aEF3g3iu9xCVORV/MH37kVcj8vgJez+LlfJtjklaschLg==", PasswordHash = "AQAAAAIAAYagAAAAEDme/kiOHre+s0r9XvpwSr5dZIoWIbSJhI5B19mCjH4ZFoBBlF6Pay9WYJ2jcVZgfw==",
PhoneNumberConfirmed = false, PhoneNumberConfirmed = false,
SecurityStamp = "8efe9683-78fb-404d-96a9-b8b7302c03b2", SecurityStamp = "7875eac4-323d-43cb-a083-940e52877171",
TwoFactorEnabled = false, TwoFactorEnabled = false,
UserInfoStatus = 1,
UserName = "sysadmin@pstw.com.my" UserName = "sysadmin@pstw.com.my"
}); });
}); });

View File

@ -300,7 +300,7 @@ namespace PSTW_CentralSystem.Migrations.InventoryDB
b.Property<string>("UserName") b.Property<string>("UserName")
.HasColumnType("longtext"); .HasColumnType("longtext");
b.Property<int?>("UserStatus") b.Property<int?>("UserInfoStatus")
.HasColumnType("int"); .HasColumnType("int");
b.Property<int?>("departmentId") b.Property<int?>("departmentId")

View File

@ -297,7 +297,7 @@ namespace PSTW_CentralSystem.Migrations.InventoryDB
b.Property<string>("UserName") b.Property<string>("UserName")
.HasColumnType("longtext"); .HasColumnType("longtext");
b.Property<int?>("UserStatus") b.Property<int?>("UserInfoStatus")
.HasColumnType("int"); .HasColumnType("int");
b.Property<int?>("departmentId") b.Property<int?>("departmentId")

View File

@ -8,7 +8,7 @@ namespace PSTW_CentralSystem.Models
{ {
// Add custom properties // Add custom properties
public string? FullName { get; set; } public string? FullName { get; set; }
public int? UserStatus { get; set; } public int? UserInfoStatus { get; set; }
public int? departmentId { get; set; } public int? departmentId { get; set; }
[ForeignKey("departmentId")] [ForeignKey("departmentId")]
public virtual DepartmentModel? Department { get; set; } public virtual DepartmentModel? Department { get; set; }

View File

@ -150,6 +150,7 @@
departmentName: '', departmentName: '',
departmentCode: '', departmentCode: '',
}], }],
compDeptDatatable: null,
}; };
}, },
watch: { watch: {
@ -173,6 +174,9 @@
.then(data => { .then(data => {
console.log(data) console.log(data)
this.compDeptList = data ? data : []; this.compDeptList = data ? data : [];
if (this.compDeptDatatable != null) {
this.compDeptDatatable.clear().destroy();
}
this.initiateTable(); this.initiateTable();
}) })
.catch(error => { .catch(error => {
@ -231,9 +235,14 @@
}); });
}); });
}); });
this.itemDatatable = $('#userDatatable').DataTable({ this.compDeptDatatable = $('#userDatatable').DataTable({
"data": flatData, "data": flatData,
"columns": [ "columns": [
{
"title": "Company Name",
"data": "companyName",
"visible": false,
},
{ {
"title": "Department Name", "title": "Department Name",
"data": "departmentName", "data": "departmentName",
@ -255,6 +264,7 @@
"dataSrc": "companyName" // Group rows by the companyName column "dataSrc": "companyName" // Group rows by the companyName column
}, },
responsive: true, responsive: true,
ordering: false,
}) })
// Attach click event listener to the delete buttons // Attach click event listener to the delete buttons
@ -306,6 +316,9 @@
alert(error.message); alert(error.message);
} }
finally { finally {
await new Promise(resolve => {
$('#loadingModal').on('shown.bs.modal', resolve);
});
$('#loadingModal').modal('hide'); $('#loadingModal').modal('hide');
} }
}, },
@ -327,13 +340,10 @@
$(function () { $(function () {
app.mount('#app'); app.mount('#app');
// Attach a click event listener to elements with the class 'btn-success'.
$('#addCompDeptBtn').on('click', function () { $('#addCompDeptBtn').on('click', function () {
// Show the modal with the ID 'addManufacturerModal'.
$('#registerCompDept').modal('show'); $('#registerCompDept').modal('show');
}); });
$('.closeModal').on('click', function () { $('.closeModal').on('click', function () {
// Show the modal with the ID 'addManufacturerModal'.
$('.modal').modal('hide'); $('.modal').modal('hide');
}); });
}); });

View File

@ -14,10 +14,10 @@
<div class="col-md-12 col-lg-12"> <div class="col-md-12 col-lg-12">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<h4 class="card-title">Latest Posts</h4> <h4 class="card-title">User List</h4>
<div class="col-md-12 col-lg-12"> <div class="col-md-12 col-lg-12">
<div> <div>
<table class="table table-bordered table-hover table-striped no-wrap" id="userDatatable" style="width:100%;border-style: solid; border-width: 1px"></table> <table class="table table-bordered table-hover table-striped no-wrap align-middle" id="userDatatable" style="width:100%;border-style: solid; border-width: 1px"></table>
</div> </div>
</div> </div>
</div> </div>
@ -54,25 +54,51 @@
await Html.RenderPartialAsync("_ValidationScriptsPartial"); await Html.RenderPartialAsync("_ValidationScriptsPartial");
} }
<script> <script>
$(function () {
app.mount('#app');
});
const app = Vue.createApp({ const app = Vue.createApp({
data() { data() {
return { return {
userList: null, userList: null,
selectedModule: null roleList: null,
selectedModule: null,
selectedRole: [],
userDatatable: null,
}; };
}, },
mounted() { mounted() {
this.fetchUsers(); this.fetchUsers();
this.fetchRoles();
}, },
methods: { methods: {
fetchUsers() { async fetchUsers() {
fetch('/AdminAPI/GetUserList', { fetch('/AdminAPI/GetUserList', {
method: 'POST' method: 'POST'
}) })
.then(response => response.json()) .then(response => response.json())
.then(data => { .then(data => {
this.userList = data.userInfo.length ? data.userInfo : []; this.userList = data.userInfo.length ? data.userInfo : [];
this.initiateTable(); this.$nextTick(() => {
if (this.userDatatable != null) {
this.userDatatable.clear().destroy();
}
this.initiateTable();
});
})
.catch(error => {
console.error('There was a problem with the fetch operation:', error);
});
},
async fetchRoles() {
fetch('/AdminAPI/GetRoleList', {
method: 'POST'
})
.then(response => response.json())
.then(data => {
this.roleList = data.length ? data : [];
}) })
.catch(error => { .catch(error => {
console.error('There was a problem with the fetch operation:', error); console.error('There was a problem with the fetch operation:', error);
@ -116,20 +142,11 @@
hideModal() { hideModal() {
$('#confirm-dialog').modal('hide'); $('#confirm-dialog').modal('hide');
}, },
initiateTable() { async initiateTable() {
self = this; self = this;
console.log(self.userList) this.userDatatable = $('#userDatatable').DataTable({
this.itemDatatable = $('#userDatatable').DataTable({
"data": self.userList, "data": self.userList,
"columns": [ "columns": [
{
"title": "UID",
"data": "id",
"createdCell": function (td, cellData, rowData, row, col) {
// Assign a unique ID to the <td> element
$(td).attr('id', `qr${cellData}`);
},
},
{ {
"title": "Email", "title": "Email",
"data": "email", "data": "email",
@ -145,6 +162,52 @@
{ {
"title": "Role", "title": "Role",
"data": "role", "data": "role",
"render": function (data, type, row, meta) {
if (data.length > 0) {
return data;
} else {
var thisCol = `
<div class="row">
<div class="col-md-6">
<select class="form-select role-select" data-id="${row.id}">
<option value="" selected disabled>Select Role</option>
${self.roleList && self.roleList.map(role => `<option value="${role.name}">${role.name}</option>`).join('')}
</select>
</div>
<div class="col-md-6">
<button type="button" class="btn btn-primary update-btn" data-id="${row.id}">Update</button>
</div>
</div>`
return thisCol;
}
},
},
{
"title": "Info Status",
"data": "status",
"render": function (data, type, row, meta) {
return data == 1 ? `Info Complete`: `Info Incomplete`;
},
"createdCell": function (td, cellData, rowData, row, col) {
// Add text-danger or text-success class to the <td>
if (cellData == 1) {
$(td).addClass('text-success');
} else {
$(td).addClass('text-danger');
}
},
},
{
"title": "User Details",
"data": "id",
"render": function (data, type, row, meta) {
if (!row.role.includes("SuperAdmin") && !row.role.includes("SystemAdmin")) {
var detailsButton = `<button type="button" class="btn btn-danger details-btn" data-id="${data}">Details</button>`;
return detailsButton;
} else {
return ""; // Return empty string if role is "SuperAdmin" or "SystemAdmin"
}
},
}, },
{ {
"title": "Delete", "title": "Delete",
@ -160,29 +223,59 @@
} }
], ],
responsive: true, responsive: true,
order: [[5, 'asc']],
}) })
// Attach click event listener to the delete buttons // Attach click event listener to the button
$('#userDatatable tbody').on('change', '.role-select', function () {
const userId = $(this).data('id');
const role = $(this).val();
self.selectedRole[userId] = role;
});
// Attach click event listener to the update button
$('#userDatatable tbody').on('click', '.update-btn', function () {
const userId = $(this).data('id');
const thisUserRole = self.selectedRole[userId];
self.updateInfo(thisUserRole, userId);
});
// Attach click event listener to the delete button
$('#itemDatatable tbody').on('click', '.delete-btn', function () { $('#itemDatatable tbody').on('click', '.delete-btn', function () {
const itemId = $(this).data('id'); const itemId = $(this).data('id');
self.deleteItem(itemId); self.deleteItem(itemId);
}); });
$('#itemDatatable tbody').on('click', '.print-btn', function () {
const itemId = $(this).data('id');
var $row = $(this).closest('tr'); // get the row containing the button
var imageSrc = $row.find('img').attr('src'); // find the img element in the row and get its src
// console.log(imageSrc);
self.printItem(itemId, imageSrc);
});
this.loading = false; this.loading = false;
}, },
async updateInfo(thisUserRole, thisUserId) {
try
{
const response = await fetch(`/AdminAPI/UpdateUserStatusAndRole/${thisUserId}`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(thisUserRole)
});
if (!response.ok) {
throw new Error('Failed to update role');
}
console.log('Role updated successfully');
}
catch (error) {
console.error('Failed to update role:', error);
}
// console.log("User ID:" + thisUserId + " Role:" + thisUserRole);
//How to reload the table with new data from this.userList
this.fetchUsers();
},
} }
}) })
$(function () {
app.mount('#app');
});
</script> </script>
} }

View File

@ -23,7 +23,7 @@
<p><h5>User ID: @Model?.Id</h5></p> <p><h5>User ID: @Model?.Id</h5></p>
<p><h5>User Name: @Model?.UserName</h5></p> <p><h5>User Name: @Model?.UserName</h5></p>
<div class="row"> <div class="row">
<form> <form v-on:submit.prevent="updateInfo">
<div class="col-md-6 col-lg-6"> <div class="col-md-6 col-lg-6">
<div class="form-group"> <div class="form-group">
<label for="company">Company</label> <label for="company">Company</label>
@ -42,6 +42,11 @@
</select> </select>
</div> </div>
</div> </div>
<div class="col-md-6 col-lg-6">
<div class="form-group">
<button class="btn btn-primary" type="submit">Update</button>
</div>
</div>
</form> </form>
</div> </div>
</div> </div>
@ -68,7 +73,6 @@
}; };
}, },
mounted() { mounted() {
this.fetchModule();
this.fetchCompanies(); this.fetchCompanies();
}, },
computed: { computed: {
@ -104,34 +108,25 @@
console.error('Error fetching products:', error); console.error('Error fetching products:', error);
} }
}, },
fetchModule() {
fetch('/AdminAPI/GetUserList', {
method: 'POST'
})
.then(response => response.json())
.then(data => {
if (data.length > 0) {
this.userList = data.length ? data : [];
}
this.initiateTable();
})
.catch(error => {
console.error('There was a problem with the fetch operation:', error);
});
},
async updateInfo() { async updateInfo() {
if (!this.selectedDepartment) {
alert("Please select a valid department.");
return;
}
const uid = @Model?.Id; const uid = @Model?.Id;
try { try {
// Show the loading modal // Show the loading modal
$('#loadingModal').modal('show'); $('#loadingModal').modal('show');
const payload = {
departmentId: this.selectedDepartment,
};
// Perform the fetch request // Perform the fetch request
const response = await fetch(`/IdentityAPI/UserComptDeptAssignment/${uid}`, { const response = await fetch(`/IdentityAPI/UserComptDeptAssignment/${uid}`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}, },
body: JSON.stringify(this.selectedDepartment), body: JSON.stringify(payload),
}); });
// Check if the response is OK // Check if the response is OK
@ -141,15 +136,18 @@
} }
const data = await response.json(); const data = await response.json();
this.fetchCompDept(); window.location.href = data.redirectUrl;
$('#registerCompDept').modal('hide');
alert("Company and department successfully added"); alert("Company and department successfully added");
} }
catch (error) { catch (error) {
console.error('Failed to add company and department:', error); console.error('Failed to add company and department:', error);
alert(error.message); const message = error.message || "An unexpected error occurred. Please try again.";
alert(message);
} }
finally { finally {
await new Promise(resolve => {
$('#loadingModal').on('shown.bs.modal', resolve);
});
$('#loadingModal').modal('hide'); $('#loadingModal').modal('hide');
} }
}, },

View File

@ -73,6 +73,11 @@
<div class="modal fade" id="loadingModal" data-bs-backdrop="static" tabindex="-1" aria-hidden="true" style="z-index: 1051;"> <div class="modal fade" id="loadingModal" data-bs-backdrop="static" tabindex="-1" aria-hidden="true" style="z-index: 1051;">
<div class="modal-dialog modal-dialog-centered"> <div class="modal-dialog modal-dialog-centered">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header">
<button type="button" class="closeModal" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body text-center"> <div class="modal-body text-center">
<div class="spinner-border text-primary" role="status"> <div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Loading...</span> <span class="visually-hidden">Loading...</span>