Display Only "Re-activate" Button for Inactive Employees in Action Column #348

Merged
pramod.mahajan merged 2 commits from Kartik_Bug#944 into Issues_Aug_1W 2025-08-23 04:37:21 +00:00
3 changed files with 80 additions and 57 deletions

View File

@ -277,27 +277,37 @@ export const useSuspendEmployee = ({
); );
return useMutation({ return useMutation({
mutationFn: async (employeeId) => { // Expect both employeeId and active status
mutationFn: async ({ employeeId, active }) => {
setemployeeLodaing(true); setemployeeLodaing(true);
return await EmployeeRepository.deleteEmployee(employeeId); return await EmployeeRepository.deleteEmployee(employeeId, active);
}, },
onSuccess: (_, employeeId) => { onSuccess: (_, { employeeId, active }) => {
showToast("Employee suspended successfully.", "success"); const message =
active === false
? "Employee suspended successfully."
: "Employee reactivated successfully.";
showToast(message, "success");
setIsDeleteModalOpen(false); setIsDeleteModalOpen(false);
// Invalidate only the required employee-related queries // Invalidate relevant queries
queryClient.invalidateQueries({ queryKey: ["employee", employeeId] }); queryClient.invalidateQueries({ queryKey: ["employee", employeeId] });
queryClient.invalidateQueries({ queryKey: ["allEmployees"] }); queryClient.invalidateQueries({ queryKey: ["allEmployees"] });
if (selectedProjectId) { if (selectedProjectId) {
queryClient.invalidateQueries({ queryKey: ["projectEmployees", selectedProjectId] }); queryClient.invalidateQueries({
queryKey: ["projectEmployees", selectedProjectId],
});
} }
}, },
onError: (error) => { onError: (error) => {
showToast( showToast(
error.response?.data?.message || error.message || "An unexpected error occurred", error.response?.data?.message ||
error.message ||
"An unexpected error occurred",
"error" "error"
); );
setIsDeleteModalOpen(false); setIsDeleteModalOpen(false);
@ -309,6 +319,7 @@ export const useSuspendEmployee = ({
}); });
}; };
export const useUpdateEmployeeRoles = ({ export const useUpdateEmployeeRoles = ({
onClose, onClose,
resetForm, resetForm,

View File

@ -176,12 +176,10 @@ const EmployeeList = () => {
useEffect(() => { useEffect(() => {
if (!loading && Array.isArray(employees)) { if (!loading && Array.isArray(employees)) {
const sorted = [...employees].sort((a, b) => { const sorted = [...employees].sort((a, b) => {
const nameA = `${a.firstName || ""}${a.middleName || ""}${ const nameA = `${a.firstName || ""}${a.middleName || ""}${a.lastName || ""
a.lastName || "" }`.toLowerCase();
}`.toLowerCase(); const nameB = `${b.firstName || ""}${b.middleName || ""}${b.lastName || ""
const nameB = `${b.firstName || ""}${b.middleName || ""}${ }`.toLowerCase();
b.lastName || ""
}`.toLowerCase();
return nameA?.localeCompare(nameB); return nameA?.localeCompare(nameB);
}); });
@ -274,12 +272,21 @@ const EmployeeList = () => {
> >
<ConfirmModal <ConfirmModal
type={"delete"} type={"delete"}
header={"Suspend Employee"} header={
message={"Are you sure you want delete?"} selectedEmpFordelete?.isActive
onSubmit={suspendEmployee} ? "Suspend Employee"
: "Reactivate Employee"
}
message={`Are you sure you want to ${selectedEmpFordelete?.isActive ? "suspend" : "reactivate"
} this employee?`}
onSubmit={() =>
suspendEmployee({
employeeId: selectedEmpFordelete.id,
active: !selectedEmpFordelete.isActive,
})
}
onClose={() => setIsDeleteModalOpen(false)} onClose={() => setIsDeleteModalOpen(false)}
loading={employeeLodaing} loading={employeeLodaing}
paramData={selectedEmpFordelete}
/> />
</div> </div>
)} )}
@ -503,9 +510,8 @@ const EmployeeList = () => {
Status Status
</th> </th>
<th <th
className={`sorting_disabled ${ className={`sorting_disabled ${!Manage_Employee && "d-none"
!Manage_Employee && "d-none" }`}
}`}
rowSpan="1" rowSpan="1"
colSpan="1" colSpan="1"
style={{ width: "50px" }} style={{ width: "50px" }}
@ -525,9 +531,9 @@ const EmployeeList = () => {
)} )}
{/* Conditional messages for no data or no search results */} {/* Conditional messages for no data or no search results */}
{!loading && {!loading &&
displayData?.length === 0 && displayData?.length === 0 &&
searchText && searchText &&
!showAllEmployees ? ( !showAllEmployees ? (
<tr> <tr>
<td colSpan={8}> <td colSpan={8}>
<small className="muted"> <small className="muted">
@ -537,8 +543,8 @@ const EmployeeList = () => {
</tr> </tr>
) : null} ) : null}
{!loading && {!loading &&
displayData?.length === 0 && displayData?.length === 0 &&
(!searchText || showAllEmployees) ? ( (!searchText || showAllEmployees) ? (
<tr> <tr>
<td <td
colSpan={8} colSpan={8}
@ -630,47 +636,56 @@ const EmployeeList = () => {
<i className="bx bx-dots-vertical-rounded bx-md"></i> <i className="bx bx-dots-vertical-rounded bx-md"></i>
</button> </button>
<div className="dropdown-menu dropdown-menu-end"> <div className="dropdown-menu dropdown-menu-end">
{/* View always visible */}
<button <button
onClick={() => onClick={() => navigate(`/employee/${item.id}`)}
navigate(`/employee/${item.id}`)
}
className="dropdown-item py-1" className="dropdown-item py-1"
> >
<i className="bx bx-detail bx-sm"></i> View <i className="bx bx-detail bx-sm"></i> View
</button> </button>
<button
className="dropdown-item py-1" {/* If ACTIVE employee */}
onClick={() => { {item.isActive && (
handleEmployeeModel(item.id);
}}
>
<i className="bx bx-edit bx-sm"></i> Edit
</button>
{!item.isSystem && (
<> <>
<button <button
className="dropdown-item py-1" className="dropdown-item py-1"
onClick={() => onClick={() => handleEmployeeModel(item.id)}
handleOpenDelete(item.id)
}
> >
<i className="bx bx-task-x bx-sm"></i>{" "} <i className="bx bx-edit bx-sm"></i> Edit
Suspend
</button> </button>
{/* Suspend only when active */}
{item.isActive && (
<button
className="dropdown-item py-1"
onClick={() => handleOpenDelete(item)}
>
<i className="bx bx-task-x bx-sm"></i> Suspend
</button>
)}
<button <button
className="dropdown-item py-1" className="dropdown-item py-1"
type="button" type="button"
data-bs-toggle="modal" data-bs-toggle="modal"
data-bs-target="#managerole-modal" data-bs-target="#managerole-modal"
onClick={() => onClick={() => setEmpForManageRole(item.id)}
setEmpForManageRole(item.id)
}
> >
<i className="bx bx-cog bx-sm"></i>{" "} <i className="bx bx-cog bx-sm"></i> Manage Role
Manage Role
</button> </button>
</> </>
)} )}
{/* If INACTIVE employee AND inactive toggle is ON */}
{!item.isActive && showInactive && (
<button
className="dropdown-item py-1"
onClick={() => handleOpenDelete(item)}
>
<i className="bx bx-refresh bx-sm me-1"></i> Re-activate
</button>
)}
</div> </div>
</div> </div>
</td> </td>
@ -687,9 +702,8 @@ const EmployeeList = () => {
<nav aria-label="Page"> <nav aria-label="Page">
<ul className="pagination pagination-sm justify-content-end py-1"> <ul className="pagination pagination-sm justify-content-end py-1">
<li <li
className={`page-item ${ className={`page-item ${currentPage === 1 ? "disabled" : ""
currentPage === 1 ? "disabled" : "" }`}
}`}
> >
<button <button
className="page-link btn-xs" className="page-link btn-xs"
@ -702,9 +716,8 @@ const EmployeeList = () => {
{[...Array(totalPages)]?.map((_, index) => ( {[...Array(totalPages)]?.map((_, index) => (
<li <li
key={index} key={index}
className={`page-item ${ className={`page-item ${currentPage === index + 1 ? "active" : ""
currentPage === index + 1 ? "active" : "" }`}
}`}
> >
<button <button
className="page-link" className="page-link"
@ -716,9 +729,8 @@ const EmployeeList = () => {
))} ))}
<li <li
className={`page-item ${ className={`page-item ${currentPage === totalPages ? "disabled" : ""
currentPage === totalPages ? "disabled" : "" }`}
}`}
> >
<button <button
className="page-link" className="page-link"

View File

@ -10,7 +10,7 @@ const EmployeeRepository = {
updateEmployee: (id, data) => api.put(`/users/${id}`, data), updateEmployee: (id, data) => api.put(`/users/${id}`, data),
// deleteEmployee: ( id ) => api.delete( `/users/${ id }` ), // deleteEmployee: ( id ) => api.delete( `/users/${ id }` ),
getEmployeeProfile: (id) => api.get(`/api/employee/profile/get/${id}`), getEmployeeProfile: (id) => api.get(`/api/employee/profile/get/${id}`),
deleteEmployee: (id) => api.delete(`/api/employee/${id}`), deleteEmployee: (id,active) => api.delete(`/api/employee/${id}?active=${active}`),
getEmployeeName: (projectId, search) => { getEmployeeName: (projectId, search) => {
const params = new URLSearchParams(); const params = new URLSearchParams();