This commit is contained in:
MOHD ARIFF 2024-12-17 16:30:35 +08:00
parent 3cfcfd7a3a
commit 3610536233
12 changed files with 636 additions and 210 deletions

View File

@ -8,6 +8,7 @@ using static System.Runtime.InteropServices.JavaScript.JSType;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
using System.Text.Json; using System.Text.Json;
using System.ComponentModel.DataAnnotations;
namespace PSTW_CentralSystem.Controllers.API namespace PSTW_CentralSystem.Controllers.API
{ {
@ -17,14 +18,14 @@ namespace PSTW_CentralSystem.Controllers.API
public class AdminAPI : Controller public class AdminAPI : Controller
{ {
private readonly ILogger<AdminAPI> _logger; private readonly ILogger<AdminAPI> _logger;
private readonly IdentityDBContext _authDbContext; private readonly IdentityDBContext _identityDbContext;
private readonly UserManager<UserModel> _userManager; private readonly UserManager<UserModel> _userManager;
private readonly SignInManager<UserModel> _signInManager; private readonly SignInManager<UserModel> _signInManager;
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)
{ {
_logger = logger; _logger = logger;
_authDbContext = authDbContext; _identityDbContext = authDbContext;
_userManager = userManager; _userManager = userManager;
_signInManager = signInManager; _signInManager = signInManager;
} }
@ -96,7 +97,7 @@ namespace PSTW_CentralSystem.Controllers.API
List<UserModel> userInfo = new List<UserModel>(); List<UserModel> userInfo = new List<UserModel>();
// Fetch all users excluding those with roles SuperAdmin or SystemAdmin // Fetch all users excluding those with roles SuperAdmin or SystemAdmin
var allUsers = await _authDbContext.Users var allUsers = await _identityDbContext.Users
.Include(u => u.Department) .Include(u => u.Department)
.ToListAsync(); .ToListAsync();
@ -113,7 +114,7 @@ namespace PSTW_CentralSystem.Controllers.API
} }
else else
{ {
userInfo = await _authDbContext.Users.Include(u => u.Department).ToListAsync(); userInfo = await _identityDbContext.Users.Include(u => u.Department).ToListAsync();
} }
var userList = userInfo.Select(u => new var userList = userInfo.Select(u => new
{ {
@ -130,5 +131,95 @@ namespace PSTW_CentralSystem.Controllers.API
return StatusCode(500, $"An error occurred: {ex.Message}"); return StatusCode(500, $"An error occurred: {ex.Message}");
} }
} }
[HttpPost("GetDepartmentWithCompanyList")]
public async Task<IActionResult> GetDepartmentWithCompanyList()
{
var companyList = await _identityDbContext.Companies
.Include(c => c.Departments)
.Select(c => new {
c.CompanyId,
c.CompanyName,
Departments = c.Departments
.OrderBy(d => d.DepartmentId)
.Select(d => new { d.DepartmentId, d.DepartmentName, d.DepartmentCode })
})
.ToListAsync();
return Json(companyList);
}
[HttpPost("GetDepartmentWithCompany")]
public async Task<DepartmentCompany> GetDepartmentWithCompany(int companyId, int departmentId)
{
var departmentList = await _identityDbContext.Departments.FirstOrDefaultAsync(d => d.DepartmentId == departmentId);
var companyList = await _identityDbContext.Companies.FirstOrDefaultAsync(c => c.CompanyId == companyId);
// Create a new list to store departments with their company name
var departmentWithCompany = new DepartmentCompany
{
DepartmentId = departmentList!.DepartmentId,
DepartmentName = departmentList.DepartmentName,
CompanyId = departmentList.CompanyId,
CompanyName = companyList?.CompanyName
};
// Return the constructed list as JSON
return departmentWithCompany;
}
[HttpPost("AddCompanyDepartment")]
public async Task<IActionResult> AddCompanyDepartment([FromBody] UpdateDepartmentCompany departmentCompanyDetails)
{
try
{
CompanyModel companyModel = new CompanyModel
{
CompanyName = departmentCompanyDetails.Company!
};
_identityDbContext.Companies.Add(companyModel);
await _identityDbContext.SaveChangesAsync();
foreach (var department in departmentCompanyDetails.Department!)
{
DepartmentModel departmentModel = new DepartmentModel
{
CompanyId = companyModel.CompanyId,
DepartmentName = department.DepartmentName ?? string.Empty,
DepartmentCode = department.DepartmentCode ?? string.Empty
};
_identityDbContext.Departments.Add(departmentModel);
await _identityDbContext.SaveChangesAsync();
}
return Ok( new { message = "Company and department added successfully" });
}
catch (Exception ex)
{
return StatusCode(500, new { message = $"An error occurred: {ex.Message}" });
}
}
public class UpdateDepartmentCompany
{
[Required]
public string? Company { get; set; }
[Required]
public List<DepartmentInfo>? Department { get; set; }
}
public class DepartmentInfo
{
[Required]
public string? DepartmentName { get; set; }
[Required]
public string? DepartmentCode { get; set; }
}
public class DepartmentCompany
{
public int DepartmentId { get; set; }
public string? DepartmentName { get; set; }
public int CompanyId { get; set; }
public string? CompanyName { get; set; }
}
} }
} }

View File

@ -11,10 +11,10 @@ namespace PSTW_CentralSystem.Controllers.API
[ApiController] [ApiController]
[Route("[controller]")] [Route("[controller]")]
public class IdentityAPI : ControllerBase public class IdentityAPI : Controller
{ {
private readonly ILogger<IdentityAPI> _logger; private readonly ILogger<IdentityAPI> _logger;
private readonly IdentityDBContext _authDbContext; private readonly IdentityDBContext _identityDbContext;
private readonly UserManager<UserModel> _userManager; private readonly UserManager<UserModel> _userManager;
private readonly SignInManager<UserModel> _signInManager; private readonly SignInManager<UserModel> _signInManager;
// Communication Key for API. Not API authentication key // Communication Key for API. Not API authentication key
@ -24,7 +24,7 @@ namespace PSTW_CentralSystem.Controllers.API
public IdentityAPI(ILogger<IdentityAPI> logger, IdentityDBContext authDbContext, UserManager<UserModel> userManager, SignInManager<UserModel> signInManager) public IdentityAPI(ILogger<IdentityAPI> logger, IdentityDBContext authDbContext, UserManager<UserModel> userManager, SignInManager<UserModel> signInManager)
{ {
_logger = logger; _logger = logger;
_authDbContext = authDbContext; _identityDbContext = authDbContext;
_userManager = userManager; _userManager = userManager;
_signInManager = signInManager; _signInManager = signInManager;
} }
@ -38,15 +38,15 @@ namespace PSTW_CentralSystem.Controllers.API
var userRole = await _userManager.GetRolesAsync(user!); var userRole = await _userManager.GetRolesAsync(user!);
if (user == null) if (user == null)
{ {
return NotFound(new { message = $"Unable to load user with ID '{_userManager.GetUserId(User)}'."}); return NotFound(new { message = $"Unable to load user with ID '{_userManager.GetUserId(User)}'." });
} }
var userInfo = await _authDbContext.Users.Include(u => u.Department).Select(u => new var userInfo = await _identityDbContext.Users.Include(u => u.Department).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,
role = userRole, role = userRole,
}).Where(u => u.id == user.Id).FirstOrDefaultAsync(); }).Where(u => u.id == user.Id).FirstOrDefaultAsync();
@ -133,17 +133,68 @@ namespace PSTW_CentralSystem.Controllers.API
if (existUser == null) if (existUser == null)
{ {
await _userManager.CreateAsync(ldapuser); await _userManager.CreateAsync(ldapuser);
//await _userManager.SetLockoutEnabledAsync(ldapuser, false); await _signInManager.SignInAsync(ldapuser, false);
//return RedirectToAction("AssignRoleAfterLdap", "IdentityController");
return Ok(new { RedirectUrl = Url.Action("ComDeptAssignment", "Identity") }); return Ok(new { RedirectUrl = Url.Action("ComDeptAssignment", "Identity") });
}; };
await _signInManager.SignInAsync(existUser, false); await _signInManager.SignInAsync(existUser, false);
//return RedirectToAction("Index", "HomeController");
if (existUser.UserStatus == null || existUser.UserStatus != 0)
{
return Ok(new { RedirectUrl = Url.Action("ComDeptAssignment", "Identity") });
}
return Ok(new { RedirectUrl = Url.Action("Index", "Home") }); return Ok(new { RedirectUrl = Url.Action("Index", "Home") });
} }
#region Company
[HttpPost("CompanyDepartmentList")]
public async Task<IActionResult> CompanyDepartmentList()
{
var companyList = await _identityDbContext.Companies
.Include(c => c.Departments)
.Select(c => new {
c.CompanyId,
c.CompanyName,
Departments = c.Departments
.OrderBy(d => d.DepartmentId)
.Select(d => new { d.DepartmentId, d.DepartmentName })
})
.ToListAsync();
return Json(companyList);
}
#endregion Company
#region Department
[HttpPost("DepartmentCompanyList")]
public async Task<IActionResult> DepartmentCompanyList()
{
var itemDepartment = await _identityDbContext.Departments
.Include(d => d.Company) // Include the related Company entity
.Select(d => new
{
d.DepartmentId,
d.DepartmentName,
d.CompanyId,
d.Company.CompanyName,
})
.ToListAsync();
//return Json(await GetDepartmentWithCompanyList());
return Json(itemDepartment);
}
#endregion Department
[HttpPost("UserComptDeptAssignment")]
public async Task<IActionResult> UserComptDeptAssignment([FromBody] UserModel userModel)
{
return Ok();
}
public async Task<UserModel?> doUserExists(string username) public async Task<UserModel?> doUserExists(string username)
{ {

View File

@ -197,44 +197,6 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
#endregion Product #endregion Product
#region Company
[HttpPost("CompanyDepartmentList")]
public async Task<IActionResult> CompanyDepartmentList()
{
var companyList = await _identityDbContext.Companies
.Include(c => c.Departments)
.Select(c => new { c.CompanyId, c.CompanyName, Departments = c.Departments
.OrderBy(d => d.DepartmentId)
.Select(d => new { d.DepartmentId, d.DepartmentName })
})
.ToListAsync();
return Json(companyList);
}
#endregion Company
#region Department
[HttpPost("DepartmentCompanyList")]
public async Task<IActionResult> DepartmentCompanyList()
{
var itemDepartment = await _identityDbContext.Departments
.Include(d => d.Company) // Include the related Company entity
.Select(d => new
{
d.DepartmentId,
d.DepartmentName,
d.CompanyId,
d.Company.CompanyName,
})
.ToListAsync();
//return Json(await GetDepartmentWithCompanyList());
return Json(itemDepartment);
}
#endregion Department
#region Supplier #region Supplier

View File

@ -63,5 +63,13 @@ namespace PSTW_CentralSystem.Controllers
{ {
return View(); return View();
} }
public IActionResult RoleAdmin()
{
return View();
}
public IActionResult CompDeptAdmin()
{
return View();
}
} }
} }

View File

@ -25,7 +25,7 @@ namespace PSTW_CentralSystem.Controllers
public async Task<IActionResult> ComDeptAssignment() public async Task<IActionResult> ComDeptAssignment()
{ {
var thisUser = await _userManager.GetUserAsync(User); var thisUser = await _userManager.GetUserAsync(User);
return View(thisUser.Id); return View(thisUser);
} }
} }

View File

@ -51,7 +51,8 @@ namespace PSTW_CentralSystem.DBContext
Email = "admin@pstw.com.my", Email = "admin@pstw.com.my",
NormalizedEmail = "ADMIN@PSTW.COM.MY", NormalizedEmail = "ADMIN@PSTW.COM.MY",
SecurityStamp = Guid.NewGuid().ToString(), SecurityStamp = Guid.NewGuid().ToString(),
EmailConfirmed = true EmailConfirmed = true,
UserStatus = 1,
}; };
var systemAdmin = new UserModel var systemAdmin = new UserModel
{ {
@ -62,7 +63,8 @@ namespace PSTW_CentralSystem.DBContext
Email = "sysadmin@pstw.com.my", Email = "sysadmin@pstw.com.my",
NormalizedEmail = "SYSADMIN@PSTW.COM.MY", NormalizedEmail = "SYSADMIN@PSTW.COM.MY",
SecurityStamp = Guid.NewGuid().ToString(), SecurityStamp = Guid.NewGuid().ToString(),
EmailConfirmed = true EmailConfirmed = true,
UserStatus = 1,
}; };
// Hash the password // Hash the password

View File

@ -9,7 +9,7 @@ namespace PSTW_CentralSystem.Models
public int DepartmentId { get; set; } public int DepartmentId { get; set; }
public required string DepartmentName { get; set; } public required string DepartmentName { get; set; }
public required string DepartmentCode { get; set; } public required string DepartmentCode { get; set; }
public required int CompanyId { get; set; } public int CompanyId { get; set; }
[ForeignKey("CompanyId")] [ForeignKey("CompanyId")]
public virtual CompanyModel? Company { get; set; } public virtual CompanyModel? Company { get; set; }

View File

@ -0,0 +1,341 @@
@*
For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
ViewData["Title"] = "Company & Department Administration";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div id="app">
<div class="row">
<div class="card-header">
<button id="addCompDeptBtn" class="btn btn-success col-md-3 col-lg-3 m-1 col-12"><i class="fa fa-plus"></i>&nbsp;Add Company & Department</button>
</div>
<div class="col-md-12 col-lg-12">
<div class="card">
<div class="card-body">
<h4 class="card-title">Company And Department</h4>
<div class="col-md-12 col-lg-12">
<div>
<table class="table table-bordered table-hover table-striped no-wrap" id="userDatatable" style="width:100%;border-style: solid; border-width: 1px"></table>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- ADD COMPANY DEPARTMENT MODAL -->
<div class="modal fade" id="registerCompDept" tabindex="-2" role="dialog" aria-labelledby="addCompDeptModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-xl" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addCompDeptModalLabel">Add Item</h5>
<button type="button" class="closeModal" data-dismiss="modal" aria-label="Close" v-on:click="showItemModal=false">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="container-fluid">
<form v-on:submit.prevent="addCompanyDepartment" data-aos="fade-right">
<div class="register" data-aos="fade-right">
<div class="row" data-aos="fade-right">
<div class="col-md-12">
<h3 class="register-heading">REGISTER COMPANY & DEPARTMENT</h3>
<div class="row register-form d-flex justify-content-center">
<div class="col-md-9">
<!-- Company Input -->
<div class="form-group row">
<label class="col-sm-3 col-form-label">Company:</label>
<div class="col-sm-4">
<input type="text" class="form-control col-md-10" v-model="company" required>
</div>
<!-- Add Department -->
<div class="col-sm-4">
<button type="button"
class="btn f-icon d-flex align-items-center text-success"
style="height: 36px; width: auto"
v-on:click="departments.push({ departmentName: '', departmentCode: '' })">
<i class="fas fa-plus-square fa-lg"></i>&ensp;Add Department
</button>
<span class="text-danger">*Click to add more department</span>
</div>
</div>
<!-- Department Inputs -->
<div class="form-group row">
<span class="text-danger">*Department code only accept 2 alphabets character. This code will be use for the item identification</span>
<label class="col-sm-3 col-form-label">Department:</label>
<div class="col-sm-8">
<div class="row mb-2 align-items-center" v-for="(department, index) in departments" :key="index">
<div class="col-10">
<input type="text" class="form-control"
v-model="departments[index].departmentName"
placeholder="Department Name"
v-on:input="updateUppercase($event, index, 'departmentName')"
required>
<input type="text" class="form-control"
minlength="2" maxlength="2" pattern="[a-zA-Z]{2}"
v-model="departments[index].departmentCode"
placeholder="Department Code"
v-on:input="updateUppercase($event, index, 'departmentCode')"
required>
</div>
<div class="col-2">
<button type="button" class="btn btn-danger" v-on:click="removeDepartment(index)">
Remove
</button>
</div>
</div>
</div>
</div>
</div>
</div>
@* Submit and Reset Buttons *@
<div class="row">
<div class="col-sm-8 col-md-12 d-flex justify-content-center">
<button type="button" v-on:click="resetDetails()" class="btn btn-secondary m-1">Reset</button>
<button type="submit" class="btn btn-primary m-1" :disabled="departments.length == 0">Submit</button>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<!-- DELETE MODAL -->
<div class="modal fade" id="confirm-dialog" tabindex="-1" role="dialog" aria-labelledby="confirm-dialog-title" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="confirm-dialog-title">Confirmation</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close" v-on:click="hideModal">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div v-if="selectedModule">
<div class="modal-body">
<p>Are you sure you want to delete module {{ selectedModule.moduleName }}?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal" v-on:click="hideModal">Cancel</button>
<input type="hidden" id="delete-id">
<a id="confirmButton" href="#" class="btn btn-danger" v-on:click="confirmDelete(selectedModule)">Confirm</a>
</div>
</div>
<div v-else><p>Loading...</p></div>
</div>
</div>
</div>
</div>
@section Scripts {
@{
await Html.RenderPartialAsync("_ValidationScriptsPartial");
}
<script>
const app = Vue.createApp({
data() {
return {
userList: null,
selectedModule: null,
compDeptList: null,
company: null,
departments: [{
departmentName: '',
departmentCode: '',
}],
};
},
watch: {
// departments: {
// handler() {
// // Code to be executed when the 'departments' data property changes
// console.log(this.departments);
// },
// deep: true, // Watch nested changes inside the departments array
// },
},
mounted() {
this.fetchCompDept();
},
methods: {
async fetchCompDept() {
fetch('/AdminAPI/GetDepartmentWithCompanyList', {
method: 'POST'
})
.then(response => response.json())
.then(data => {
console.log(data)
this.compDeptList = data ? data : [];
this.initiateTable();
})
.catch(error => {
console.error('There was a problem with the fetch operation:', error);
});
},
editCompDept(compDept) {
// Check if the user ID exists
if (module.settingId) {
// Redirect the user to the edit user page
window.location.href = 'ModuleSetting/' + module.settingId;
} else {
console.error('Module ID not found');
}
},
deleteCompDept(compDept) {
this.selectedModule = module; // Set selected user
$('#confirm-dialog').modal('show'); // Show the modal
// console.log(this.selectedModule);
},
confirmDelete(compDept) {
fetch(`/ModuleAPI/DeleteModule/${module.settingId}`, {
method: 'POST'
})
.then(response => {
if (!response.ok) {
throw new Error('Failed to delete module');
}
// Remove the deleted user from the userData array
const index = this.moduleData.findIndex(u => u.settingId === module.settingId);
if (index !== -1) {
alert("Module deleted successfully");
this.moduleData.splice(index, 1);
}
this.hideModal(); // Hide the modal after deletion
})
.catch(error => {
console.error('Failed to delete module with status:', error);
});
},
hideModal() {
$('#confirm-dialog').modal('hide');
},
initiateTable() {
self = this;
// Flatten the data to create rows for each department
var flatData = [];
self.compDeptList.forEach(function (company) {
company.departments.forEach(function (department) {
flatData.push({
companyId: company.companyId,
companyName: company.companyName,
departmentName: department.departmentName,
departmentCode: department.departmentCode
});
});
});
this.itemDatatable = $('#userDatatable').DataTable({
"data": flatData,
"columns": [
{
"title": "Department Name",
"data": "departmentName",
},
{
"title": "Department Code",
"data": "departmentCode",
},
{
"title": "Delete",
"data": "companyId",
"render": function (data) {
var deleteButton = `<button type="button" class="btn btn-danger delete-btn" data-id="${data}">Delete</button>`;
return deleteButton;
},
}
],
"rowGroup": {
"dataSrc": "companyName" // Group rows by the companyName column
},
responsive: true,
})
// Attach click event listener to the delete buttons
$('#itemDatatable tbody').on('click', '.delete-btn', function () {
const itemId = $(this).data('id');
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;
},
async addCompanyDepartment() {
try {
// Show the loading modal
$('#loadingModal').modal('show');
// Perform the fetch request
const response = await fetch('/AdminAPI/AddCompanyDepartment', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
Company: this.company,
Department: this.departments,
}),
});
// Check if the response is OK
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.message);
}
const data = await response.json();
this.fetchCompDept();
$('#registerCompDept').modal('hide');
alert("Company and department successfully added");
}
catch (error) {
console.error('Failed to add company and department:', error);
alert(error.message);
}
finally {
$('#loadingModal').modal('hide');
}
},
removeDepartment(index) {
this.departments.splice(index, 1);
},
updateUppercase(event, index, key) {
this.departments[index][key] = event.target.value.toUpperCase();
},
resetDetails(){
this.company = null;
this.departments = [{
departmentName: '',
departmentCode: '',
}];
}
}
})
$(function () {
app.mount('#app');
// Attach a click event listener to elements with the class 'btn-success'.
$('#addCompDeptBtn').on('click', function () {
// Show the modal with the ID 'addManufacturerModal'.
$('#registerCompDept').modal('show');
});
$('.closeModal').on('click', function () {
// Show the modal with the ID 'addManufacturerModal'.
$('.modal').modal('hide');
});
});
</script>
}

View File

@ -30,4 +30,16 @@
</div> </div>
</a> </a>
</div> </div>
<div class="col-md-6 col-lg-3">
<a asp-controller="Admin" asp-action="CompDeptAdmin">
<div class="card card-hover">
<div class="box bg-cyan text-center">
<h1 class="font-light text-white">
<i class="fas fa-building"></i>
</h1>
<h6 class="text-white">Company Department Administration</h6>
</div>
</div>
</a>
</div>
</div> </div>

View File

@ -62,10 +62,10 @@
}; };
}, },
mounted() { mounted() {
this.fetchModule(); this.fetchUsers();
}, },
methods: { methods: {
fetchModule() { fetchUsers() {
fetch('/AdminAPI/GetUserList', { fetch('/AdminAPI/GetUserList', {
method: 'POST' method: 'POST'
}) })
@ -78,7 +78,7 @@
console.error('There was a problem with the fetch operation:', error); console.error('There was a problem with the fetch operation:', error);
}); });
}, },
editModule(module) { editUser(user) {
// Check if the user ID exists // Check if the user ID exists
if (module.settingId) { if (module.settingId) {
// Redirect the user to the edit user page // Redirect the user to the edit user page
@ -87,13 +87,13 @@
console.error('Module ID not found'); console.error('Module ID not found');
} }
}, },
deleteModule(module) { deleteUser(user) {
this.selectedModule = module; // Set selected user this.selectedModule = module; // Set selected user
$('#confirm-dialog').modal('show'); // Show the modal $('#confirm-dialog').modal('show'); // Show the modal
// console.log(this.selectedModule); // console.log(this.selectedModule);
}, },
confirmDelete(module) { confirmDelete(user) {
fetch(`/ModuleAPI/DeleteModule/${module.settingId}`, { fetch(`/ModuleAPI/DeleteModule/${module.settingId}`, {
method: 'POST' method: 'POST'
}) })
@ -149,9 +149,13 @@
{ {
"title": "Delete", "title": "Delete",
"data": "id", "data": "id",
"render": function (data) { "render": function (data, type, row, meta) {
if (!row.role.includes("SuperAdmin") && !row.role.includes("SystemAdmin")) {
var deleteButton = `<button type="button" class="btn btn-danger delete-btn" data-id="${data}">Delete</button>`; var deleteButton = `<button type="button" class="btn btn-danger delete-btn" data-id="${data}">Delete</button>`;
return deleteButton; return deleteButton;
} else {
return ""; // Return empty string if role is "SuperAdmin" or "SystemAdmin"
}
}, },
} }
], ],

View File

@ -4,51 +4,51 @@
@{ @{
ViewData["Title"] = "Company & Department Assignment"; ViewData["Title"] = "Company & Department Assignment";
Layout = "~/Views/Shared/_Layout.cshtml"; Layout = "~/Views/Shared/_Layout.cshtml";
int userId = ViewBag.UserId; @model UserModel?
} }
<p> <p>
@* <a asp-action="UserCreate">Create New</a> *@ @* <a asp-action="UserCreate">Create New</a> *@
</p> </p>
@userId;
<div id="app"> <div id="app">
<div class="row"> <div class="row">
<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">Update Compulsory Details</h4>
<div class="col-md-12 col-lg-12"> <div class="col-md-12 col-lg-12">
<div> <div>
<table class="table table-bordered border-primary" id="userDatatable"></table> <p><h5>User ID: @Model?.Id</h5></p>
<p><h5>User Name: @Model?.UserName</h5></p>
<div class="row">
<form>
<div class="col-md-6 col-lg-6">
<div class="form-group">
<label for="company">Company</label>
<select id="company" name="company" class="form-select" v-model="selectedCompany">
<option value="" selected>Select Company</option>
<option v-for="(company, index) in companyList" :key="index" :value="company.companyName">{{ company.companyName }}</option>
</select>
</div>
</div>
<div class="col-md-6 col-lg-6">
<div class="form-group">
<label for="department">Department</label>
<select id="department" name="department" class="form-select" v-model="selectedDepartment">
<option value="" selected>Select Department</option>
<option v-for="(department, index) in departmentList" :key="index" :value="department.departmentId">{{ department.departmentName }}</option>
</select>
</div>
</div>
</form>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- MODAL -->
<div class="modal fade" id="confirm-dialog" tabindex="-1" role="dialog" aria-labelledby="confirm-dialog-title" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="confirm-dialog-title">Confirmation</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close" v-on:click="hideModal">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div v-if="selectedModule">
<div class="modal-body">
<p>Are you sure you want to delete module {{ selectedModule.moduleName }}?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal" v-on:click="hideModal">Cancel</button>
<input type="hidden" id="delete-id">
<a id="confirmButton" href="#" class="btn btn-danger" v-on:click="confirmDelete(selectedModule)">Confirm</a>
</div>
</div>
<div v-else><p>Loading...</p></div>
</div>
</div>
</div> </div>
</div> </div>
@section Scripts { @section Scripts {
@ -60,13 +60,50 @@
data() { data() {
return { return {
userList: null, userList: null,
selectedModule: null selectedModule: null,
companyList: null,
company: '',
selectedDepartment: '',
selectedCompany: '',
}; };
}, },
mounted() { mounted() {
this.fetchModule(); this.fetchModule();
this.fetchCompanies();
},
computed: {
// Computed property to dynamically update departmentList based on selectedCompany
departmentList() {
// If selectedCompany is empty, return an empty array to prevent errors
if (!this.selectedCompany) {
this.selectedDepartment = ''
return [];
}
const selectedCompanyObj = this.companyList.find(c => c.companyName === this.selectedCompany);
// Ensure that the selected company exists before accessing its departments
return selectedCompanyObj ? selectedCompanyObj.departments : [];
},
}, },
methods: { methods: {
async fetchCompanies() {
try {
const response = await fetch('/IdentityAPI/CompanyDepartmentList', {
method: 'POST', // Specify the HTTP method
headers: {
'Content-Type': 'application/json'
}
});
if (!response.ok) {
throw new Error('Failed to fetch companies');
}
this.companyList = await response.json();
} catch (error) {
console.error('Error fetching products:', error);
}
},
fetchModule() { fetchModule() {
fetch('/AdminAPI/GetUserList', { fetch('/AdminAPI/GetUserList', {
method: 'POST' method: 'POST'
@ -82,121 +119,39 @@
console.error('There was a problem with the fetch operation:', error); console.error('There was a problem with the fetch operation:', error);
}); });
}, },
editModule(module) { async updateInfo() {
// Check if the user ID exists const uid = @Model?.Id;
if (module.settingId) { try {
// Redirect the user to the edit user page // Show the loading modal
window.location.href = 'ModuleSetting/' + module.settingId; $('#loadingModal').modal('show');
} else {
console.error('Module ID not found');
}
},
deleteModule(module) {
this.selectedModule = module; // Set selected user
$('#confirm-dialog').modal('show'); // Show the modal
// console.log(this.selectedModule); // Perform the fetch request
const response = await fetch(`/IdentityAPI/UserComptDeptAssignment/${uid}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
}, },
confirmDelete(module) { body: JSON.stringify(this.selectedDepartment),
fetch(`/ModuleAPI/DeleteModule/${module.settingId}`, { });
method: 'POST'
}) // Check if the response is OK
.then(response => {
if (!response.ok) { if (!response.ok) {
throw new Error('Failed to delete module'); const errorData = await response.json();
throw new Error(errorData.message);
} }
// Remove the deleted user from the userData array
const index = this.moduleData.findIndex(u => u.settingId === module.settingId);
if (index !== -1) {
alert("Module deleted successfully");
this.moduleData.splice(index, 1);
}
this.hideModal(); // Hide the modal after deletion
})
.catch(error => {
console.error('Failed to delete module with status:', error);
});
},
hideModal() {
$('#confirm-dialog').modal('hide');
},
initiateTable() {
self = this;
this.itemDatatable = $('#userDatatable').DataTable({
"data": this.userList,
"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",
"data": "email",
},
{
"title": "Company Name",
"data": "company",
},
{
"title": "Department",
"data": "department",
},
{
"title": "Role",
"data": "role",
},
{
"title": "Delete",
"data": "id",
"render": function (data) {
var deleteButton = `<button type="button" class="btn btn-danger delete-btn" data-id="${data}">Delete</button>`;
return deleteButton;
},
}
],
responsive: true,
drawCallback: function (settings) {
// Generate QR codes after rows are rendered
const api = this.api();
api.rows().every(function () {
const data = this.data(); // Row data
const containerId = `qr${data.uniqueID}`;
const container = $(`#${containerId}`);
// console.log(container[0]);
if (container) {
// Generate QR code only if not already generated
new QRCode(container[0], {
text: data.qrString,
width: 150,
height: 150,
colorDark: "#000000",
colorLight: "#ffffff",
correctLevel: QRCode.CorrectLevel.H
});
}
});
},
})
// Attach click event listener to the delete buttons const data = await response.json();
$('#itemDatatable tbody').on('click', '.delete-btn', function () { this.fetchCompDept();
const itemId = $(this).data('id'); $('#registerCompDept').modal('hide');
self.deleteItem(itemId); alert("Company and department successfully added");
}); }
catch (error) {
$('#itemDatatable tbody').on('click', '.print-btn', function () { console.error('Failed to add company and department:', error);
const itemId = $(this).data('id'); alert(error.message);
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 finally {
// console.log(imageSrc); $('#loadingModal').modal('hide');
self.printItem(itemId, imageSrc); }
});
this.loading = false;
}, },
} }
}) })

View File

@ -70,7 +70,7 @@
<div class="lds-pos"></div> <div class="lds-pos"></div>
</div> </div>
</div> </div>
<div class="modal fade" id="loadingModal" data-bs-backdrop="static" tabindex="-1" aria-hidden="true"> <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-body text-center"> <div class="modal-body text-center">