added newhook that return only organization employee for employee list (Active or Inactive)

This commit is contained in:
pramod.mahajan 2025-10-10 16:48:22 +05:30
parent dd944b3414
commit edce5ef614
6 changed files with 95 additions and 153 deletions

View File

@ -18,7 +18,7 @@ import { defatEmployeeObj, employeeSchema } from "./EmployeeSchema";
import { useOrganizationsList } from "../../hooks/useOrganization";
import { ITEMS_PER_PAGE } from "../../utils/constants";
const ManageEmployee = ({ employeeId, onClosed, IsAllEmployee }) => {
const ManageEmployee = ({ employeeId, onClosed }) => {
const dispatch = useDispatch();
const { mutate: updateEmployee, isPending } = useUpdateEmployee();
const {
@ -72,7 +72,7 @@ const ManageEmployee = ({ employeeId, onClosed, IsAllEmployee }) => {
data.email = null;
}
const payload = { ...data, IsAllEmployee };
const payload = { ...data };
if (employeeId) {
payload.id = employeeId;

View File

@ -327,7 +327,7 @@ const ManageProjectInfo = ({ project, onClose }) => {
<i className="bx bx-sm bx-info-circle"></i> Not found PMC and
Pomoter, find through SPRID or create new
</span>
<small className="cursor-pointer" onClick={handleOrganizaioFinder}>
<small className="cursor-pointer" onClick={handleOrganizaioFinder} >
<i className="bx bx-plus-circle text-primary"></i>
</small>
</div>
@ -367,14 +367,14 @@ const ManageProjectInfo = ({ project, onClose }) => {
className="btn btn-label-secondary btn-sm me-2"
onClick={handleCancel}
aria-label="Close"
disabled={isPending || isCreating}
disabled={isPending || isCreating || loading}
>
Cancel
</button>
<button
type="submit"
className="btn btn-primary btn-sm"
disabled={isPending || isCreating}
disabled={isPending || isCreating || loading}
>
{isPending||isCreating ? "Please Wait..." : project ? "Update" : "Submit"}
</button>

View File

@ -132,11 +132,15 @@ const ProjectListView = ({
return (
<div className="card page-min-h py-4 px-6 shadow-sm">
<div
className="table-responsive text-nowrap page-min-h"
>
<table className="table table-hover align-middle m-0">
<thead className="border-bottom">
<thead className="border-bottom ">
<tr>
{projectColumns.map((col) => (
<th key={col.key} colSpan={col.colSpan} className={col.className}>
<th key={col.key} colSpan={col.colSpan} className={`${col.className} table_header_border`}>
{col.label}
</th>
))}
@ -217,6 +221,7 @@ const ProjectListView = ({
))}
</tbody>
</table>
</div>
{isLoading && (
<div className="py-4">

View File

@ -12,14 +12,14 @@ import { queryClient } from "../layouts/AuthLayout";
// Query ---------------------------------------------------------------------------
export const useEmployee = (employeeId) => {
return useQuery({
return useQuery({
queryKey: ["employeeProfile", employeeId],
queryFn: async () => {
const res = await EmployeeRepository.getEmployeeProfile(employeeId)
const res = await EmployeeRepository.getEmployeeProfile(employeeId);
return res.data;
},
enabled:!!employeeId
});
enabled: !!employeeId,
});
};
export const useAllEmployees = (showInactive) => {
@ -137,7 +137,6 @@ export const useEmployeesAllOrByProjectId = (
return res.data;
}
};
const {
data: employees = [],
isLoading,
@ -158,6 +157,18 @@ export const useEmployeesAllOrByProjectId = (
};
};
// New Employee get list by CureentOrganization
export const useEmployeesByOrganization = (showInactive) => {
return useQuery({
queryKey: ["employeesByOrganization", showInactive],
queryFn: async () => {
const res = await EmployeeRepository.getAllEmployeeList(showInactive);
return res.data;
},
});
};
// ManageEmployee.jsx
export const useEmployeeProfile = (employeeId) => {
const isEnabled = !!employeeId;
@ -184,11 +195,11 @@ export const useEmployeeProfile = (employeeId) => {
};
};
export const useEmployeesName = (projectId, search,allEmployee) => {
export const useEmployeesName = (projectId, search, allEmployee) => {
return useQuery({
queryKey: ["employees", projectId, search,allEmployee],
queryKey: ["employees", projectId, search, allEmployee],
queryFn: async () =>
await EmployeeRepository.getEmployeeName(projectId, search,allEmployee),
await EmployeeRepository.getEmployeeName(projectId, search, allEmployee),
staleTime: 5 * 60 * 1000, // Optional: cache for 5 minutes
});
@ -208,9 +219,6 @@ export const useEmployeesNameByProject = (projectId) => {
// Mutation------------------------------------------------------------------
export const useUpdateEmployee = () => {
const selectedProject = useSelector(
(store) => store.localVariables.projectId
@ -225,7 +233,7 @@ export const useUpdateEmployee = () => {
const isAllEmployee = variables.IsAllEmployee;
// Cache invalidation
queryClient.invalidateQueries({ queryKey: ["employeeProfile",id] });
queryClient.invalidateQueries({ queryKey: ["employeeProfile", id] });
queryClient.invalidateQueries({ queryKey: ["allEmployees"] });
// queryClient.invalidateQueries(['employeeProfile', id]);
queryClient.invalidateQueries({ queryKey: ["projectEmployees"] });
@ -247,7 +255,6 @@ export const useUpdateEmployee = () => {
});
};
export const useSuspendEmployee = ({
setIsDeleteModalOpen,
setemployeeLodaing,
@ -300,7 +307,6 @@ export const useSuspendEmployee = ({
});
};
export const useUpdateEmployeeRoles = ({
onClose,
resetForm,
@ -334,4 +340,4 @@ export const useUpdateEmployeeRoles = ({
isError: mutation.isError,
error: mutation.error,
};
};
};

View File

@ -131,7 +131,7 @@ const AttendancePage = () => {
<div className="nav-align-top nav-tabs-shadow ">
{/* Tabs */}
<div className="nav-align-top nav-tabs-shadow bg-white border-bottom pt-5">
<div className="row align-items-center g-0 mb-3 mb-md-0 mx-5">
<div className="row align-items-center g-0 mb-3 mb-md-0 mx-1 mx-sm-5">
{/* Tabs */}
<div className="col-12 col-md">
<ul className="nav nav-tabs" role="tablist">
@ -181,9 +181,10 @@ const AttendancePage = () => {
{/* Search + Organization filter */}
<div className="col-12 col-md-auto mt-2 mt-md-0 ms-md-auto d-flex gap-2 align-items-center">
{/* Organization Dropdown */}
<select
<div className="row">
<div className="col-12 col-sm-6 mb-2 mb-sm-0">
<select
className="form-select form-select-sm"
style={{ minWidth: "180px" }}
value={appliedFilters.selectedOrganization}
onChange={(e) =>
setAppliedFilters((prev) => ({
@ -200,16 +201,21 @@ const AttendancePage = () => {
</option>
))}
</select>
{/* Search Input */}
</div>
<div className="col-12 col-sm-6">
{/* Search Input */}
<input
type="text"
className="form-control form-control-sm"
placeholder="Search Employee..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
style={{ minWidth: "200px" }}
/>
</div>
</div>
</div>
</div>
</div>

View File

@ -7,6 +7,7 @@ import Breadcrumb from "../../components/common/Breadcrumb";
import ManageEmp from "../../components/Employee/ManageRole";
import {
useEmployeesAllOrByProjectId,
useEmployeesByOrganization,
useSuspendEmployee,
} from "../../hooks/useEmployees";
import { useProjectName, useProjects } from "../../hooks/useProjects";
@ -36,6 +37,7 @@ import GlobalModel from "../../components/common/GlobalModel";
import usePagination from "../../hooks/usePagination";
import { setProjectId } from "../../slices/localVariablesSlice";
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
import Pagination from "../../components/common/Pagination";
const EmployeeList = () => {
const selectedProjectId = useSelector(
@ -46,15 +48,14 @@ const EmployeeList = () => {
const dispatch = useDispatch();
const [showInactive, setShowInactive] = useState(false);
const [showAllEmployees, setShowAllEmployees] = useState(false);
const Manage_Employee = useHasUserPermission(MANAGE_EMPLOYEES);
const { employees, loading, setLoading, error, recallEmployeeData } =
useEmployeesAllOrByProjectId(
showAllEmployees,
selectedProjectId,
showInactive
);
const {
data: employees,
isLoading: loading,
error,
refetch: recallEmployeeData,
} = useEmployeesByOrganization(showInactive);
const [employeeList, setEmployeeList] = useState([]);
const [modelConfig, setModelConfig] = useState();
@ -70,7 +71,6 @@ const EmployeeList = () => {
const [selectedEmpFordelete, setSelectedEmpFordelete] = useState(null);
const [employeeLodaing, setemployeeLodaing] = useState(false);
const ViewTeamMember = useHasUserPermission(VIEW_TEAM_MEMBERS);
const ViewAllEmployee = useHasUserPermission(VIEW_ALL_EMPLOYEES);
const { mutate: suspendEmployee, isPending: empLodaing } = useSuspendEmployee(
{
setIsDeleteModalOpen,
@ -157,7 +157,7 @@ const EmployeeList = () => {
const handleAllEmployeesToggle = (e) => {
const isChecked = e.target.checked;
setShowInactive(false);
setShowAllEmployees(isChecked);
// setShowAllEmployees(isChecked);
};
const handleEmployeeModel = (id) => {
@ -205,25 +205,16 @@ const EmployeeList = () => {
setCurrentPage((prevPage) => (prevPage !== 1 ? 1 : prevPage));
}
}, [loading, employees, selectedProjectId, showAllEmployees]);
useEffect(() => {
if (!showAllEmployees) {
recallEmployeeData(showInactive, selectedProjectId);
}
}, [selectedProjectId, showInactive, showAllEmployees, recallEmployeeData]);
}, [loading, employees, selectedProjectId, showInactive]);
const handler = useCallback(
(msg) => {
if (employees.some((item) => item.id == msg.employeeId)) {
setEmployeeList([]);
recallEmployeeData(
showInactive,
showAllEmployees ? null : selectedProjectId
); // Use selectedProjectId here
recallEmployeeData(showInactive);
}
},
[employees, showInactive, showAllEmployees, selectedProjectId] // Add all relevant dependencies
[employees, showInactive, showInactive, selectedProjectId] // Add all relevant dependencies
);
useEffect(() => {
@ -254,7 +245,6 @@ const EmployeeList = () => {
<ManageEmployee
employeeId={selectedEmployeeId}
onClosed={() => setShowModal(false)}
IsAllEmployee={showAllEmployees}
/>
</GlobalModel>
)}
@ -293,59 +283,39 @@ const EmployeeList = () => {
{ViewTeamMember ? (
// <div className="row">
<div className="card p-1">
<div className="card p-1 page-min-h">
<div className="card-datatable table-responsive pt-5 mx-5 py-10">
<div
id="DataTables_Table_0_wrapper"
className="dataTables_wrapper dt-bootstrap5 no-footer"
style={{ width: "100%" }}
>
<div className="d-flex flex-wrap align-items-center justify-content-between gap-3 mb-3">
{/* Switches: All Employees + Inactive */}
<div className="d-flex flex-wrap align-items-center gap-3">
{/* All Employees Switch */}
{ViewAllEmployee && (
<div className="form-check form-switch text-start">
<input
type="checkbox"
className="form-check-input"
role="switch"
id="allEmployeesCheckbox"
checked={showAllEmployees}
onChange={handleAllEmployeesToggle}
/>
<label
className="form-check-label ms-0"
htmlFor="allEmployeesCheckbox"
>
Show All Employees
</label>
</div>
)}
{/* Show Inactive Employees Switch */}
{showAllEmployees && (
<div className="form-check form-switch text-start">
<input
type="checkbox"
className="form-check-input"
role="switch"
id="inactiveEmployeesCheckbox"
checked={showInactive}
onChange={(e) => setShowInactive(e.target.checked)}
/>
<label
className="form-check-label ms-0"
htmlFor="inactiveEmployeesCheckbox"
>
Show Inactive Employees
</label>
</div>
)}
<div className="form-check form-switch text-start">
<input
type="checkbox"
className="form-check-input"
role="switch"
id="inactiveEmployeesCheckbox"
checked={showInactive}
onChange={(e) => setShowInactive(e.target.checked)}
/>
<label
className="form-check-label ms-0"
htmlFor="inactiveEmployeesCheckbox"
>
Show Inactive Employees
</label>
</div>
</div>
{/* Right side: Search + Export + Add Employee */}
<div className="d-flex flex-wrap align-items-center justify-content-end gap-3 flex-grow-1">
<div className="d-flex flex-wrap align-items-center justify-content-start justify-content-md-end gap-3 flex-grow-1">
{/* Search Input - ALWAYS ENABLED */}
<div className="dataTables_filter">
<label className="mb-0">
@ -431,7 +401,6 @@ const EmployeeList = () => {
className="datatables-users table border-top dataTable no-footer dtr-column text-nowrap"
id="DataTables_Table_0"
aria-describedby="DataTables_Table_0_info"
style={{ width: "100%" }}
ref={tableRef}
>
<thead>
@ -522,28 +491,27 @@ const EmployeeList = () => {
</td>
</tr>
)}
{/* Conditional messages for no data or no search results */}
{!loading &&
displayData?.length === 0 &&
searchText &&
!showAllEmployees ? (
(!searchText ) ? (
<tr>
<td colSpan={8}>
<small className="muted">
'{searchText}' employee not found
</small>{" "}
<td colSpan={8} className="border-0 py-3">
<div className="py-4">
No Data Found
</div>
</td>
</tr>
) : null}
{!loading &&
{!loading &&
displayData?.length === 0 &&
(!searchText || showAllEmployees) ? (
(searchText ) ? (
<tr>
<td
colSpan={8}
style={{ paddingTop: "20px", textAlign: "center" }}
>
No Data Found
<td colSpan={8} className="border-0 py-3">
<div className="py-4">
{`No match record found ${searchText} `}
</div>
</td>
</tr>
) : null}
@ -697,55 +665,12 @@ const EmployeeList = () => {
</tbody>
</table>
<div style={{ width: "1%" }}></div>
{/* Pagination */}
{!loading && displayData.length > ITEMS_PER_PAGE && (
<nav aria-label="Page">
<ul className="pagination pagination-sm justify-content-end py-1">
<li
className={`page-item ${
currentPage === 1 ? "disabled" : ""
}`}
>
<button
className="page-link btn-xs"
onClick={() => paginate(currentPage - 1)}
>
&laquo;
</button>
</li>
{[...Array(totalPages)]?.map((_, index) => (
<li
key={index}
className={`page-item ${
currentPage === index + 1 ? "active" : ""
}`}
>
<button
className="page-link"
onClick={() => paginate(index + 1)}
>
{index + 1}
</button>
</li>
))}
<li
className={`page-item ${
currentPage === totalPages ? "disabled" : ""
}`}
>
<button
className="page-link"
onClick={() => paginate(currentPage + 1)}
>
&raquo;
</button>
</li>
</ul>
</nav>
{displayData?.length > 0 && (
<Pagination
currentPage={currentPage}
totalPages={totalPages}
onPageChange={paginate}
/>
)}
</div>
</div>