Changes in Manage Buckets popup and Employess component Checkbox add.
This commit is contained in:
parent
deaf10c302
commit
32fdc39e5c
@ -16,6 +16,7 @@ const CardViewDirectory = ({
|
||||
}) => {
|
||||
const { buckets } = useBuckets();
|
||||
const { dirActions, setDirActions } = useDir();
|
||||
|
||||
return (
|
||||
<div
|
||||
className="card text-start border-1"
|
||||
@ -24,9 +25,8 @@ const CardViewDirectory = ({
|
||||
<div className="card-body px-1 py-2 pb-0">
|
||||
<div className="d-flex justify-content-between">
|
||||
<div
|
||||
className={`d-flex align-items-center ${
|
||||
IsActive && "cursor-pointer"
|
||||
}`}
|
||||
className={`d-flex align-items-center ${IsActive && "cursor-pointer"
|
||||
}`}
|
||||
onClick={() => {
|
||||
if (IsActive) {
|
||||
setIsOpenModalNote(true);
|
||||
@ -89,11 +89,10 @@ const CardViewDirectory = ({
|
||||
)}
|
||||
{!IsActive && (
|
||||
<i
|
||||
className={`bx ${
|
||||
dirActions.action && dirActions.id === contact.id
|
||||
className={`bx ${dirActions.action && dirActions.id === contact.id
|
||||
? "bx-loader-alt bx-spin"
|
||||
: "bx-recycle"
|
||||
} me-1 text-primary cursor-pointer`}
|
||||
} me-1 text-primary cursor-pointer`}
|
||||
title="Restore"
|
||||
onClick={() => {
|
||||
setDirActions({ action: false, id: contact.id });
|
||||
@ -114,9 +113,8 @@ const CardViewDirectory = ({
|
||||
</ul>
|
||||
</div>
|
||||
<div
|
||||
className={`card-footer text-start px-1 py-1 ${
|
||||
IsActive && "cursor-pointer"
|
||||
}`}
|
||||
className={`card-footer text-start px-1 py-1 ${IsActive && "cursor-pointer"
|
||||
}`}
|
||||
onClick={() => {
|
||||
if (IsActive) {
|
||||
setIsOpenModalNote(true);
|
||||
@ -151,17 +149,19 @@ const CardViewDirectory = ({
|
||||
</ul>
|
||||
)}
|
||||
|
||||
{contact?.contactCategory?.name ? (
|
||||
<ul className="list-inline m-0 ms-2">
|
||||
{contact?.tags?.length > 0 ? (
|
||||
<ul className="list-inline m-0 ms-2">
|
||||
<li className="list-inline-item me-2 my-1">
|
||||
<i className="fa-solid fa-tag fs-6 ms-1"></i>
|
||||
</li>
|
||||
<li className="list-inline-item text-small active">
|
||||
{contact?.contactCategory?.name}
|
||||
</li>
|
||||
{contact.tags.map((tag, index) => (
|
||||
<li key={index} className="list-inline-item text-small active">
|
||||
{tag.name}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
) : (
|
||||
<ul className="list-inline m-0 ms-2">
|
||||
<ul className="list-inline m-0 ms-2">
|
||||
<li className="list-inline-item me-2 my-1">
|
||||
<i className="fa-solid fa-tag fs-6 ms-1"></i>
|
||||
</li>
|
||||
|
@ -66,7 +66,6 @@ const ManageBucket = () => {
|
||||
const cache_buckets = getCachedData("buckets") || [];
|
||||
let response;
|
||||
|
||||
// Utility: Compare arrays regardless of order
|
||||
const arraysAreEqual = (a, b) => {
|
||||
if (a.length !== b.length) return false;
|
||||
const setA = new Set(a);
|
||||
@ -74,11 +73,9 @@ const ManageBucket = () => {
|
||||
return [...setA].every((id) => setB.has(id));
|
||||
};
|
||||
|
||||
// UPDATE existing bucket
|
||||
if (selected_bucket) {
|
||||
const payload = { ...data, id: selected_bucket.id };
|
||||
|
||||
// 1. Update bucket details
|
||||
response = await DirectoryRepository.UpdateBuckets(
|
||||
selected_bucket.id,
|
||||
payload
|
||||
@ -91,14 +88,12 @@ const ManageBucket = () => {
|
||||
cacheData("buckets", updatedBuckets);
|
||||
setBucketList(updatedBuckets);
|
||||
|
||||
// 2. Update employee assignments if they changed
|
||||
const existingEmployeeIds = selected_bucket?.employeeIds || [];
|
||||
const employeesToUpdate = selectedEmployee.filter((emp) => {
|
||||
const isExisting = existingEmployeeIds.includes(emp.employeeId);
|
||||
return (!isExisting && emp.isActive) || (isExisting && !emp.isActive);
|
||||
});
|
||||
|
||||
// Create a filtered list of active employee IDs to compare
|
||||
const newActiveEmployeeIds = selectedEmployee
|
||||
.filter((emp) => {
|
||||
const isExisting = existingEmployeeIds.includes(emp.employeeId);
|
||||
@ -110,7 +105,7 @@ const ManageBucket = () => {
|
||||
|
||||
if (
|
||||
!arraysAreEqual(newActiveEmployeeIds, existingEmployeeIds) &&
|
||||
employeesToUpdate.length != 0
|
||||
employeesToUpdate.length !== 0
|
||||
) {
|
||||
try {
|
||||
response = await DirectoryRepository.AssignedBuckets(
|
||||
@ -135,7 +130,6 @@ const ManageBucket = () => {
|
||||
showToast("Bucket Updated Successfully", "success");
|
||||
}
|
||||
|
||||
// CREATE new bucket
|
||||
else {
|
||||
response = await DirectoryRepository.CreateBuckets(data);
|
||||
|
||||
@ -163,7 +157,7 @@ const ManageBucket = () => {
|
||||
const resp = await DirectoryRepository.DeleteBucket(deleteBucket);
|
||||
const cache_buckets = getCachedData("buckets") || [];
|
||||
const updatedBuckets = cache_buckets.filter(
|
||||
(bucket) => bucket.id != deleteBucket
|
||||
(bucket) => bucket.id !== deleteBucket
|
||||
);
|
||||
cacheData("buckets", updatedBuckets);
|
||||
setBucketList(updatedBuckets);
|
||||
@ -193,6 +187,8 @@ const ManageBucket = () => {
|
||||
select_bucket(null);
|
||||
setAction_bucket(false);
|
||||
setSubmitting(false);
|
||||
reset({ name: "", description: "" });
|
||||
setSelectEmployee([]);
|
||||
};
|
||||
|
||||
const sortedBucktesList = sortedBuckteList?.filter((bucket) => {
|
||||
@ -200,11 +196,12 @@ const ManageBucket = () => {
|
||||
const name = bucket.name?.toLowerCase();
|
||||
return name?.includes(term);
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
{deleteBucket && (
|
||||
<div
|
||||
className={`modal fade ${deleteBucket ? "show" : ""}`}
|
||||
className={`modal fade ${deleteBucket ? "show" : ""}`}
|
||||
tabIndex="-1"
|
||||
role="dialog"
|
||||
style={{
|
||||
@ -215,15 +212,14 @@ const ManageBucket = () => {
|
||||
<ConfirmModal
|
||||
type={"delete"}
|
||||
header={"Delete Bucket"}
|
||||
message={"Are you sure you want delete?"}
|
||||
message={"Are you sure you want to delete this bucket?"}
|
||||
onSubmit={handleDeleteContact}
|
||||
onClose={() => setDeleteBucket(null)}
|
||||
// loading={IsDeleting}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="container m-0 p-0" style={{ minHeight: "200px" }}>
|
||||
<div className="container m-0 p-0" style={{ minHeight: "00px" }}>
|
||||
<div className="d-flex justify-content-center">
|
||||
<p className="fs-6 fw-semibold m-0">Manage Buckets</p>
|
||||
</div>
|
||||
@ -254,10 +250,15 @@ const ManageBucket = () => {
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className={`btn btn-sm btn-primary ms-auto ${
|
||||
className={`btn btn-sm btn-primary ms-auto ${
|
||||
action_bucket ? "d-none" : ""
|
||||
}`}
|
||||
onClick={() => setAction_bucket(true)}
|
||||
onClick={() => {
|
||||
setAction_bucket(true);
|
||||
select_bucket(null);
|
||||
reset({ name: "", description: "" });
|
||||
setSelectEmployee([]);
|
||||
}}
|
||||
>
|
||||
<i className="bx bx-plus-circle me-2"></i>
|
||||
Add Bucket
|
||||
@ -265,113 +266,73 @@ const ManageBucket = () => {
|
||||
</div>
|
||||
<div>
|
||||
{!action_bucket ? (
|
||||
<div className="table-responsive text-nowrap pt-1 px-2 px-sm-0 mt-3">
|
||||
<table className="table px-2">
|
||||
<thead className="p-0">
|
||||
<tr className="p-0">
|
||||
<th
|
||||
colSpan={2}
|
||||
className="cursor-pointer"
|
||||
onClick={() => requestSort((e) => `${e.name} `)}
|
||||
>
|
||||
<div className="d-flex justify-content-start align-items-center gap-1 mx-2">
|
||||
<span>Name {getSortIcon()}</span>
|
||||
</div>
|
||||
</th>
|
||||
<th className="text-start d-none d-sm-table-cell">
|
||||
<div className="d-flex align-items-center justify-content-center gap-1">
|
||||
<span>Description</span>
|
||||
</div>
|
||||
</th>
|
||||
<th>Contacts</th>
|
||||
<th>
|
||||
<div className="d-flex align-items-center justify-content-center gap-1">
|
||||
<span>Action</span>
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody className="table-border-bottom-0 overflow-auto">
|
||||
{loading && (
|
||||
<tr className="mt-10">
|
||||
<td colSpan={5}>
|
||||
{" "}
|
||||
<div className="d-flex justify-content-center align-items-center py-5">
|
||||
Loading...
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
{!loading && buckets.length == 0 && (
|
||||
<tr>
|
||||
<td colSpan={5}>
|
||||
<div className="d-flex justify-content-center align-items-center py-5">
|
||||
Bucket Not Available.
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
{!loading && sortedBucktesList.length == 0 && (
|
||||
<tr>
|
||||
<td className="text-center py-4 h-25" colSpan={5}>
|
||||
<div className="d-flex justify-content-center align-items-center py-5">
|
||||
No Matching Bucket Found.
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
{!loading &&
|
||||
sortedBucktesList.map((bucket) => (
|
||||
<tr key={bucket.id}>
|
||||
<td colSpan={2} className="text-start text-wrap">
|
||||
<i className="bx bx-right-arrow-alt me-1"></i>{" "}
|
||||
{bucket.name}
|
||||
</td>
|
||||
<td
|
||||
className="text-start d-none d-sm-table-cell text-truncate"
|
||||
style={{
|
||||
maxWidth: "300px",
|
||||
whiteSpace: "wrap",
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
}}
|
||||
title={bucket.description}
|
||||
>
|
||||
{bucket.description}
|
||||
</td>
|
||||
<td>{bucket.numberOfContacts}</td>
|
||||
<td className="justify-content-center">
|
||||
{(DirManager ||
|
||||
DirAdmin ||
|
||||
bucket?.createdBy?.id ===
|
||||
profile?.employeeInfo?.id) && (
|
||||
<div className="d-flex justify-content-center align-items-center gap-2">
|
||||
<div className="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-3 pt-3 px-2 px-sm-0">
|
||||
{loading && (
|
||||
<div className="col-12">
|
||||
<div className="d-flex justify-content-center align-items-center py-5">
|
||||
Loading...
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{!loading && buckets.length === 0 && (
|
||||
<div className="col-12">
|
||||
<div className="d-flex justify-content-center align-items-center py-5">
|
||||
No Buckets Available.
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{!loading && sortedBucktesList.length === 0 && (
|
||||
<div className="col-12">
|
||||
<div className="d-flex justify-content-center align-items-center py-5">
|
||||
No Matching Bucket Found.
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{!loading &&
|
||||
sortedBucktesList.map((bucket) => (
|
||||
<div className="col" key={bucket.id}>
|
||||
<div className="card h-100">
|
||||
<div className="card-body">
|
||||
<h6 className="card-title d-flex justify-content-between align-items-center">
|
||||
<span>{bucket.name}</span>
|
||||
{(DirManager || DirAdmin || bucket?.createdBy?.id === profile?.employeeInfo?.id) && (
|
||||
<div className="d-flex gap-2">
|
||||
<i
|
||||
className="bx bx-edit bx-sm text-primary cursor-pointer "
|
||||
className="bx bx-edit bx-sm text-primary cursor-pointer"
|
||||
onClick={() => {
|
||||
select_bucket(bucket);
|
||||
setAction_bucket(true);
|
||||
const initialSelectedEmployees = employeesList
|
||||
.filter(emp => bucket.employeeIds?.includes(emp.employeeId))
|
||||
.map(emp => ({ ...emp, isActive: true }));
|
||||
setSelectEmployee(initialSelectedEmployees);
|
||||
}}
|
||||
></i>
|
||||
<i
|
||||
className="bx bx-trash bx-sm text-danger cursor-pointer"
|
||||
className="bx bx-trash bx-sm text-danger cursor-pointer ms-0"
|
||||
onClick={() => setDeleteBucket(bucket?.id)}
|
||||
></i>
|
||||
</div>
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</h6>
|
||||
<h6 className="card-subtitle mb-2 text-muted">
|
||||
Contacts: {bucket.numberOfContacts}
|
||||
</h6>
|
||||
<p className="card-text text-start" title={bucket.description}>
|
||||
{bucket.description || "No description available."}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="px-2 px-sm-0">
|
||||
<div className="">
|
||||
<label className="form-label">Bucket Name</label>
|
||||
<div className="mb-3">
|
||||
<label htmlFor="bucketName" className="form-label">Bucket Name</label>
|
||||
<input
|
||||
id="bucketName"
|
||||
className="form-control form-control-sm"
|
||||
{...register("name")}
|
||||
/>
|
||||
@ -379,9 +340,10 @@ const ManageBucket = () => {
|
||||
<small className="danger-text">{errors.name.message}</small>
|
||||
)}
|
||||
</div>
|
||||
<div className="">
|
||||
<label className="form-label">Bucket Discription</label>
|
||||
<div className="mb-3">
|
||||
<label htmlFor="bucketDescription" className="form-label">Bucket Description</label>
|
||||
<textarea
|
||||
id="bucketDescription"
|
||||
className="form-control form-control-sm"
|
||||
rows="3"
|
||||
{...register("description")}
|
||||
@ -401,9 +363,10 @@ const ManageBucket = () => {
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className="mt-2 d-flex justify-content-center gap-3">
|
||||
<div className="mt-4 d-flex justify-content-center gap-3">
|
||||
<button
|
||||
onClick={() => handleBack()}
|
||||
type="button"
|
||||
onClick={handleBack}
|
||||
className="btn btn-sm btn-secondary"
|
||||
disabled={isSubmitting}
|
||||
>
|
||||
@ -426,4 +389,4 @@ const ManageBucket = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ManageBucket;
|
||||
export default ManageBucket;
|
@ -159,6 +159,23 @@ const ProfileContactDirectory = ({ contact, setOpen_contact, closeModal }) => {
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{contactProfile?.tags?.length > 0 && (
|
||||
<div className="d-flex mb-2">
|
||||
<div style={{ width: "100px", minWidth: "100px" }}>
|
||||
<p className="m-0">Tags : </p>
|
||||
</div>
|
||||
<div>
|
||||
<ul className="list-inline mb-0">
|
||||
{contactProfile.tags.map((tag, index) => (
|
||||
<li key={index} className="list-inline-item">
|
||||
<i className="fa-solid fa-tag me-1"></i>
|
||||
{tag.name}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{contactProfile?.buckets?.length > 0 && (
|
||||
<div className="d-flex ">
|
||||
|
@ -6,25 +6,19 @@
|
||||
"text": "Dashboard",
|
||||
"icon": "bx bx-home",
|
||||
"available": true,
|
||||
"link": "/projects"
|
||||
},
|
||||
{
|
||||
"text": "Projects",
|
||||
"icon": "bx bx-building-house",
|
||||
"available": true,
|
||||
"link": "/dashboard"
|
||||
},
|
||||
{
|
||||
"text": "Projects",
|
||||
"icon": "bx bx-layout",
|
||||
{
|
||||
"text": "Employees",
|
||||
"icon": "bx bx-user",
|
||||
"available": true,
|
||||
"link": "/ui",
|
||||
"submenu": [
|
||||
{
|
||||
"text": "Project List",
|
||||
"available": true,
|
||||
"link": "/projects"
|
||||
},
|
||||
{
|
||||
"text": "Employees",
|
||||
"available": true,
|
||||
"link": "/employees"
|
||||
}
|
||||
]
|
||||
"link": "/employees"
|
||||
},
|
||||
{
|
||||
"text": "Activities",
|
||||
|
@ -216,7 +216,7 @@ const AttendancePage = () => {
|
||||
|
||||
|
||||
</ul>
|
||||
<div className="tab-content attedanceTabs py-2 px-1 px-sm-3">
|
||||
<div className="tab-content attedanceTabs py-0 px-1 px-sm-3">
|
||||
{projectLoading && <span>Loading..</span>}
|
||||
{!projectLoading && !attendances && <span>Not Found</span>}
|
||||
|
||||
|
@ -9,7 +9,7 @@ import { useEmployeesAllOrByProjectId } from "../../hooks/useEmployees";
|
||||
import { useProjects } from "../../hooks/useProjects";
|
||||
import { useProfile } from "../../hooks/useProfile";
|
||||
import { hasUserPermission } from "../../utils/authUtils";
|
||||
import { ITEMS_PER_PAGE, MANAGE_EMPLOYEES } from "../../utils/constants";
|
||||
import { MANAGE_EMPLOYEES } from "../../utils/constants";
|
||||
import { clearCacheKey } from "../../slices/apiDataManager";
|
||||
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
||||
import SuspendEmp from "../../components/Employee/SuspendEmp";
|
||||
@ -23,28 +23,24 @@ import EmployeeRepository from "../../repositories/EmployeeRepository";
|
||||
import ManageEmployee from "../../components/Employee/ManageEmployee";
|
||||
import ConfirmModal from "../../components/common/ConfirmModal";
|
||||
import { useSelector } from "react-redux";
|
||||
import GlobalModel from "../../components/common/GlobalModel";
|
||||
import AssignToProject from "./AssignToProject";
|
||||
|
||||
const EmployeeList = () => {
|
||||
const selectedProjectId = useSelector(
|
||||
(store) => store.localVariables.projectId
|
||||
);
|
||||
const [selectedProject, setSelectedProject] = useState(
|
||||
() => selectedProjectId || ""
|
||||
);
|
||||
const selectedProjectId = useSelector((store) => store.localVariables.projectId);
|
||||
const [selectedProject, setSelectedProject] = useState(() => selectedProjectId || "");
|
||||
const { projects, loading: projectLoading } = useProjects();
|
||||
const [showInactive, setShowInactive] = useState(false);
|
||||
const [showAllEmployees, setShowAllEmployees] = useState(false); // New state for "All Employee"
|
||||
const Manage_Employee = useHasUserPermission(MANAGE_EMPLOYEES);
|
||||
|
||||
// Modify the hook to conditionally pass selectedProject or null based on showAllEmployees
|
||||
const { employees, loading, setLoading, error, recallEmployeeData } =
|
||||
useEmployeesAllOrByProjectId(selectedProject, showInactive);
|
||||
useEmployeesAllOrByProjectId(showAllEmployees ? null : selectedProject, showInactive);
|
||||
const [projectsList, setProjectsList] = useState(projects || []);
|
||||
|
||||
const [employeeList, setEmployeeList] = useState([]);
|
||||
const [modelConfig, setModelConfig] = useState();
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [itemsPerPage] = useState(ITEMS_PER_PAGE);
|
||||
const [itemsPerPage] = useState(15);
|
||||
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
|
||||
const [isEmployeeModalOpen, setIsEmployeeModalOpen] = useState(false);
|
||||
const [searchText, setSearchText] = useState("");
|
||||
@ -54,8 +50,7 @@ const EmployeeList = () => {
|
||||
const [IsDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||
const [selectedEmpFordelete, setSelectedEmpFordelete] = useState(null);
|
||||
const [employeeLodaing, setemployeeLodaing] = useState(false);
|
||||
const [selectedEmployee, setSelectEmployee] = useState(null);
|
||||
const [IsOpenAsssingModal, setOpenAssignModal] = useState(false);
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handleSearch = (e) => {
|
||||
@ -78,19 +73,17 @@ const EmployeeList = () => {
|
||||
if (!loading && Array.isArray(employees)) {
|
||||
// Sort by full name (firstName + lastName)
|
||||
const sorted = [...employees].sort((a, b) => {
|
||||
const nameA = `${a.firstName || ""}${a.middleName || ""}${
|
||||
a.lastName || ""
|
||||
}`.toLowerCase();
|
||||
const nameB = `${b.firstName || ""}${b.middleName || ""}${
|
||||
b.lastName || ""
|
||||
}`.toLowerCase();
|
||||
const nameA = `${a.firstName || ""}${a.middleName || ""}${b.lastName || ""
|
||||
}`.toLowerCase();
|
||||
const nameB = `${b.firstName || ""}${b.middleName || ""}${b.lastName || ""
|
||||
}`.toLowerCase();
|
||||
return nameA.localeCompare(nameB);
|
||||
});
|
||||
|
||||
setEmployeeList(sorted);
|
||||
setFilteredData(sorted);
|
||||
}
|
||||
}, [loading, employees, selectedProject]);
|
||||
}, [loading, employees, selectedProject, showAllEmployees]); // Add showAllEmployees to dependencies
|
||||
|
||||
const displayData = searchText ? filteredData : employeeList;
|
||||
const indexOfLastItem = currentPage * itemsPerPage;
|
||||
@ -187,6 +180,15 @@ const EmployeeList = () => {
|
||||
recallEmployeeData(e.target.checked);
|
||||
};
|
||||
|
||||
// New handler for "All Employee" toggle
|
||||
const handleAllEmployeesToggle = (e) => {
|
||||
const isChecked = e.target.checked;
|
||||
setShowAllEmployees(isChecked);
|
||||
// If "All Employees" is checked, we don't want to filter by project,
|
||||
// so we pass null for selected project. Otherwise, use the currently selected project.
|
||||
recallEmployeeData(showInactive, isChecked ? null : selectedProject);
|
||||
};
|
||||
|
||||
const handleEmployeeModel = (id) => {
|
||||
setSelecedEmployeeId(id);
|
||||
setShowModal(true);
|
||||
@ -199,38 +201,42 @@ const EmployeeList = () => {
|
||||
};
|
||||
|
||||
const handleProjectSelection = (e) => {
|
||||
setSelectedProject(e.target.value);
|
||||
const newProjectId = e.target.value;
|
||||
setSelectedProject(newProjectId);
|
||||
// If a specific project is selected, uncheck "All Employees"
|
||||
if (newProjectId) {
|
||||
setShowAllEmployees(false);
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
setSelectedProject(selectedProjectId || "");
|
||||
}, [selectedProjectId]);
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
{isCreateModalOpen && (
|
||||
<ManageEmp employeeId={modelConfig} onClosed={closeModal} />
|
||||
)}
|
||||
{showModal && (
|
||||
<div
|
||||
className={`modal fade ${showModal ? "show" : ""} `}
|
||||
tabIndex="-1"
|
||||
role="dialog"
|
||||
style={{ display: showModal ? "block" : "none" }}
|
||||
aria-hidden={!showModal}
|
||||
>
|
||||
<div className="modal-dialog modal-xl modal-dialog-centered ">
|
||||
<div
|
||||
className="modal-content overflow-y-auto overflow-x-hidden"
|
||||
style={{ maxHeight: "90vh" }}
|
||||
>
|
||||
<ManageEmployee
|
||||
employeeId={selectedEmployeeId}
|
||||
onClosed={closeModal}
|
||||
/>
|
||||
</div>
|
||||
{showModal && (<div
|
||||
className={`modal fade ${showModal ? "show" : ""} `}
|
||||
tabIndex="-1"
|
||||
role="dialog"
|
||||
style={{ display: showModal ? "block" : "none" }}
|
||||
aria-hidden={!showModal}
|
||||
>
|
||||
<div className="modal-dialog modal-xl modal-dialog-centered ">
|
||||
<div
|
||||
className="modal-content overflow-y-auto overflow-x-hidden"
|
||||
style={{ maxHeight: "90vh" }}
|
||||
>
|
||||
<ManageEmployee
|
||||
employeeId={selectedEmployeeId}
|
||||
onClosed={closeModal}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>)}
|
||||
|
||||
{IsDeleteModalOpen && (
|
||||
<div
|
||||
@ -257,18 +263,6 @@ const EmployeeList = () => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{IsOpenAsssingModal && (
|
||||
<GlobalModel
|
||||
isOpen={IsOpenAsssingModal}
|
||||
closeModal={() => setOpenAssignModal(false)}
|
||||
>
|
||||
<AssignToProject
|
||||
employee={selectedEmployee}
|
||||
onClose={() => setOpenAssignModal(false)}
|
||||
/>
|
||||
</GlobalModel>
|
||||
)}
|
||||
|
||||
<div className="container-xxl flex-grow-1 container-p-y">
|
||||
<Breadcrumb
|
||||
data={[
|
||||
@ -279,43 +273,25 @@ const EmployeeList = () => {
|
||||
<div className="row">
|
||||
<div className="card ">
|
||||
<div className="card-datatable table-responsive pt-2">
|
||||
|
||||
<div
|
||||
id="DataTables_Table_0_wrapper"
|
||||
className="dataTables_wrapper dt-bootstrap5 no-footer"
|
||||
style={{ width: "98%" }}
|
||||
>
|
||||
<div className="row mb-2 ">
|
||||
<div className="row mb-2 ">
|
||||
<div className="col-md-3 col-sm-6 ">
|
||||
<div className="ms-0">
|
||||
<div
|
||||
className="dataTables_length text-start"
|
||||
id="DataTables_Table_0_length"
|
||||
>
|
||||
<label>
|
||||
<select
|
||||
id="project-select"
|
||||
onChange={handleProjectSelection}
|
||||
name="DataTables_Table_0_length"
|
||||
aria-controls="DataTables_Table_0"
|
||||
className="form-select form-select-sm"
|
||||
value={selectedProject}
|
||||
>
|
||||
{projectLoading ? (
|
||||
<option value="Loading">Loading...</option>
|
||||
) : (
|
||||
<>
|
||||
<option value="">All Employees</option>
|
||||
{Array.isArray(projects) &&
|
||||
projects.map((item) => (
|
||||
<option key={item.id} value={item.id}>
|
||||
{item.name}
|
||||
</option>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
<div className="form-check text-start">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="form-check-input"
|
||||
id="allEmployeesCheckbox"
|
||||
checked={showAllEmployees}
|
||||
onChange={handleAllEmployeesToggle}
|
||||
/>
|
||||
<label className="form-check-label" htmlFor="allEmployeesCheckbox">
|
||||
All Employees
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-md-9 col-sm-6">
|
||||
@ -387,9 +363,8 @@ const EmployeeList = () => {
|
||||
</li>
|
||||
</ul>
|
||||
<button
|
||||
className={`btn btn-sm add-new btn-primary ${
|
||||
!Manage_Employee && "d-none"
|
||||
}`}
|
||||
className={`btn btn-sm add-new btn-primary ${!Manage_Employee && "d-none"
|
||||
}`}
|
||||
tabIndex="0"
|
||||
type="button"
|
||||
onClick={() => {
|
||||
@ -408,25 +383,24 @@ const EmployeeList = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={`text-end mb-2 ${selectedProject ? "d-none" : ""}`}
|
||||
>
|
||||
<label className="switch switch-primary">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="switch-input"
|
||||
checked={showInactive}
|
||||
onChange={handleToggle}
|
||||
/>
|
||||
<span className="switch-toggle-slider">
|
||||
<span className="switch-on"></span>
|
||||
<span className="switch-off"></span>
|
||||
</span>
|
||||
<span className="switch-label">
|
||||
Show Inactive Employees
|
||||
</span>
|
||||
</label>
|
||||
<div className="d-flex justify-content-end mb-2">
|
||||
{/* Show Inactive Employees Checkbox */}
|
||||
<div className={`${showAllEmployees ? '' : selectedProject ? 'd-none' : ''}`}>
|
||||
<div className="form-check">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="form-check-input"
|
||||
id="inactiveEmployeesCheckbox"
|
||||
checked={showInactive}
|
||||
onChange={handleToggle}
|
||||
/>
|
||||
<label className="form-check-label" htmlFor="inactiveEmployeesCheckbox">
|
||||
Show Inactive Employees
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table
|
||||
className="datatables-users table border-top dataTable no-footer dtr-column text-nowrap"
|
||||
id="DataTables_Table_0"
|
||||
@ -502,9 +476,8 @@ const EmployeeList = () => {
|
||||
Status
|
||||
</th>
|
||||
<th
|
||||
className={`sorting_disabled ${
|
||||
!Manage_Employee && "d-none"
|
||||
}`}
|
||||
className={`sorting_disabled ${!Manage_Employee && "d-none"
|
||||
}`}
|
||||
rowSpan="1"
|
||||
colSpan="1"
|
||||
style={{ width: "50px" }}
|
||||
@ -667,16 +640,6 @@ const EmployeeList = () => {
|
||||
<i className="bx bx-cog bx-sm"></i>{" "}
|
||||
Manage Role
|
||||
</button>
|
||||
<button
|
||||
className="dropdown-item py-1"
|
||||
onClick={() => {
|
||||
setSelectEmployee(item),
|
||||
setOpenAssignModal(true);
|
||||
}}
|
||||
>
|
||||
<i className="bx bx-select-multiple"></i>{" "}
|
||||
Assign Project
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
@ -691,55 +654,50 @@ const EmployeeList = () => {
|
||||
<div style={{ width: "1%" }}></div>
|
||||
|
||||
{/* Pagination */}
|
||||
{!loading &&
|
||||
employeeList?.length > 0 &&
|
||||
currentItems.length > ITEMS_PER_PAGE && (
|
||||
<nav aria-label="Page navigation">
|
||||
<ul className="pagination pagination-sm justify-content-end py-1">
|
||||
<li
|
||||
className={`page-item ${
|
||||
currentPage === 1 ? "disabled" : ""
|
||||
}`}
|
||||
{!loading && displayData.length > itemsPerPage && (
|
||||
<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)}
|
||||
>
|
||||
<button
|
||||
className="page-link btn-xs"
|
||||
onClick={() => paginate(currentPage - 1)}
|
||||
>
|
||||
«
|
||||
</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>
|
||||
))}
|
||||
«
|
||||
</button>
|
||||
</li>
|
||||
|
||||
{[...Array(totalPages)]?.map((_, index) => (
|
||||
<li
|
||||
className={`page-item ${
|
||||
currentPage === totalPages ? "disabled" : ""
|
||||
}`}
|
||||
key={index}
|
||||
className={`page-item ${currentPage === index + 1 ? "active" : ""
|
||||
}`}
|
||||
>
|
||||
<button
|
||||
className="page-link"
|
||||
onClick={() => paginate(currentPage + 1)}
|
||||
onClick={() => paginate(index + 1)}
|
||||
>
|
||||
»
|
||||
{index + 1}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
)}
|
||||
))}
|
||||
|
||||
<li
|
||||
className={`page-item ${currentPage === totalPages ? "disabled" : ""
|
||||
}`}
|
||||
>
|
||||
<button
|
||||
className="page-link"
|
||||
onClick={() => paginate(currentPage + 1)}
|
||||
>
|
||||
»
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
)}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -749,4 +707,4 @@ const EmployeeList = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default EmployeeList;
|
||||
export default EmployeeList;
|
Loading…
x
Reference in New Issue
Block a user