Adding Filter Icon in Attendance tab and add functionality in all Attendance component. #416
@ -62,11 +62,47 @@ const Attendance = ({ getRole, handleModalData, searchTerm }) => {
|
|||||||
const role = item.jobRoleName?.toLowerCase() || "";
|
const role = item.jobRoleName?.toLowerCase() || "";
|
||||||
return (
|
return (
|
||||||
fullName.includes(lowercasedSearchTerm) ||
|
fullName.includes(lowercasedSearchTerm) ||
|
||||||
role.includes(lowercasedSearchTerm) // ✅ also search by role
|
role.includes(lowercasedSearchTerm) // also search by role
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}, [group1, group2, searchTerm]);
|
}, [group1, group2, searchTerm]);
|
||||||
|
|
||||||
|
// const finalFilteredData = useMemo(() => {
|
||||||
|
// const combinedData = [...group1, ...group2];
|
||||||
|
|
||||||
|
// let tempData = combinedData;
|
||||||
|
|
||||||
|
// // Search filter
|
||||||
|
// if (searchTerm) {
|
||||||
|
// const lowercasedSearchTerm = searchTerm.toLowerCase();
|
||||||
|
// tempData = tempData.filter((item) => {
|
||||||
|
// const fullName = `${item.firstName} ${item.lastName}`.toLowerCase();
|
||||||
|
// const role = item.jobRoleName?.toLowerCase() || "";
|
||||||
|
// return (
|
||||||
|
// fullName.includes(lowercasedSearchTerm) ||
|
||||||
|
// role.includes(lowercasedSearchTerm) // also search by role
|
||||||
|
// );
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Organization filter
|
||||||
|
// if (filters?.selectedOrganization) {
|
||||||
|
// tempData = tempData.filter(
|
||||||
|
// (item) => item.organization?.name === filters.selectedOrganization
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Services filter
|
||||||
|
// if (filters?.selectedServices?.length > 0) {
|
||||||
|
// tempData = tempData.filter((item) =>
|
||||||
|
// filters.selectedServices.includes(item.service?.name)
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return tempData;
|
||||||
|
// }, [group1, group2, searchTerm, filters]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const { currentPage, totalPages, currentItems, paginate } = usePagination(
|
const { currentPage, totalPages, currentItems, paginate } = usePagination(
|
||||||
finalFilteredData,
|
finalFilteredData,
|
||||||
@ -116,7 +152,7 @@ const Attendance = ({ getRole, handleModalData, searchTerm }) => {
|
|||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
className="table-responsive text-nowrap h-100"
|
className="table-responsive text-nowrap h-100"
|
||||||
style={{ minHeight: "200px" }} // 🔹 Ensures fixed height
|
style={{ minHeight: "200px" }} // Ensures fixed height
|
||||||
>
|
>
|
||||||
<div className="d-flex text-start align-items-center py-2">
|
<div className="d-flex text-start align-items-center py-2">
|
||||||
<strong>Date : {formatUTCToLocalTime(todayDate)}</strong>
|
<strong>Date : {formatUTCToLocalTime(todayDate)}</strong>
|
||||||
|
@ -150,6 +150,33 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
|
|||||||
});
|
});
|
||||||
}, [processedData, searchTerm]);
|
}, [processedData, searchTerm]);
|
||||||
|
|
||||||
|
// const filteredSearchData = useMemo(() => {
|
||||||
|
// let tempData = processedData;
|
||||||
|
|
||||||
|
// if (searchTerm) {
|
||||||
|
// const lowercasedSearchTerm = searchTerm.toLowerCase();
|
||||||
|
// tempData = tempData.filter((item) => {
|
||||||
|
// const fullName = `${item.firstName} ${item.lastName}`.toLowerCase();
|
||||||
|
// return fullName.includes(lowercasedSearchTerm);
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (filters?.selectedOrganization) {
|
||||||
|
// tempData = tempData.filter(
|
||||||
|
// (item) => item.organization?.name === filters.selectedOrganization
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (filters?.selectedServices?.length > 0) {
|
||||||
|
// tempData = tempData.filter((item) =>
|
||||||
|
// filters.selectedServices.includes(item.service?.name)
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return tempData;
|
||||||
|
// }, [processedData, searchTerm, filters]);
|
||||||
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
currentPage,
|
currentPage,
|
||||||
totalPages,
|
totalPages,
|
||||||
@ -242,14 +269,7 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
|
|||||||
<label className="form-check-label ms-0">Show Pending</label>
|
<label className="form-check-label ms-0">Show Pending</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-2 m-0 text-end">
|
|
||||||
<i
|
|
||||||
className={`bx bx-refresh cursor-pointer fs-4 ${isFetching ? "spin" : ""
|
|
||||||
}`}
|
|
||||||
title="Refresh"
|
|
||||||
onClick={() => refetch()}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="table-responsive text-nowrap" style={{ minHeight: "200px" }}>
|
<div className="table-responsive text-nowrap" style={{ minHeight: "200px" }}>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
@ -344,7 +364,7 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
) : (
|
) : (
|
||||||
<div className="my-4"><span className="text-secondary">No Record Available !</span></div>
|
<div className="my-12"><span className="text-secondary">No data available for the selected date range. Please Select another date.</span></div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{paginatedAttendances?.length == 0 && filteredSearchData?.length > 0 && (
|
{paginatedAttendances?.length == 0 && filteredSearchData?.length > 0 && (
|
||||||
|
@ -10,7 +10,7 @@ import eventBus from "../../services/eventBus";
|
|||||||
import { cacheData, clearCacheKey, useSelectedProject } from "../../slices/apiDataManager";
|
import { cacheData, clearCacheKey, useSelectedProject } from "../../slices/apiDataManager";
|
||||||
import { useQueryClient } from "@tanstack/react-query";
|
import { useQueryClient } from "@tanstack/react-query";
|
||||||
|
|
||||||
const Regularization = ({ handleRequest, searchTerm }) => {
|
const Regularization = ({ handleRequest, searchTerm }) => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
// var selectedProject = useSelector((store) => store.localVariables.projectId);
|
// var selectedProject = useSelector((store) => store.localVariables.projectId);
|
||||||
const selectedProject = useSelectedProject();
|
const selectedProject = useSelectedProject();
|
||||||
@ -59,6 +59,36 @@ const Regularization = ({ handleRequest, searchTerm }) => {
|
|||||||
});
|
});
|
||||||
}, [regularizesList, searchTerm]);
|
}, [regularizesList, searchTerm]);
|
||||||
|
|
||||||
|
// const filteredSearchData = useMemo(() => {
|
||||||
|
// let sortedList = [...regularizesList].sort(sortByName);
|
||||||
|
|
||||||
|
// // Search filter
|
||||||
|
// if (searchTerm) {
|
||||||
|
// const lowercasedSearchTerm = searchTerm.toLowerCase();
|
||||||
|
// sortedList = sortedList.filter((item) => {
|
||||||
|
// const fullName = `${item.firstName} ${item.lastName}`.toLowerCase();
|
||||||
|
// return fullName.includes(lowercasedSearchTerm);
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Organization filter
|
||||||
|
// if (filters?.selectedOrganization) {
|
||||||
|
// sortedList = sortedList.filter(
|
||||||
|
// (item) => item.organization?.name === filters.selectedOrganization
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Services filter
|
||||||
|
// if (filters?.selectedServices?.length > 0) {
|
||||||
|
// sortedList = sortedList.filter((item) =>
|
||||||
|
// filters.selectedServices.includes(item.service?.name)
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return sortedList;
|
||||||
|
// }, [regularizesList, searchTerm, filters]);
|
||||||
|
|
||||||
|
|
||||||
const { currentPage, totalPages, currentItems, paginate } =
|
const { currentPage, totalPages, currentItems, paginate } =
|
||||||
usePagination(filteredSearchData, 20);
|
usePagination(filteredSearchData, 20);
|
||||||
|
|
||||||
|
@ -39,6 +39,10 @@ const AttendancePage = () => {
|
|||||||
const [modelConfig, setModelConfig] = useState();
|
const [modelConfig, setModelConfig] = useState();
|
||||||
const DoRegularized = useHasUserPermission(REGULARIZE_ATTENDANCE);
|
const DoRegularized = useHasUserPermission(REGULARIZE_ATTENDANCE);
|
||||||
const { projectNames, loading: projectLoading, fetchData } = useProjectName();
|
const { projectNames, loading: projectLoading, fetchData } = useProjectName();
|
||||||
|
const [appliedFilters, setAppliedFilters] = useState({
|
||||||
|
selectedOrganization: "",
|
||||||
|
selectedServices: [],
|
||||||
|
});
|
||||||
|
|
||||||
const [formData, setFormData] = useState({
|
const [formData, setFormData] = useState({
|
||||||
markTime: "",
|
markTime: "",
|
||||||
@ -95,11 +99,11 @@ const AttendancePage = () => {
|
|||||||
{(modelConfig?.action === 0 ||
|
{(modelConfig?.action === 0 ||
|
||||||
modelConfig?.action === 1 ||
|
modelConfig?.action === 1 ||
|
||||||
modelConfig?.action === 2) && (
|
modelConfig?.action === 2) && (
|
||||||
<CheckCheckOutmodel
|
<CheckCheckOutmodel
|
||||||
modeldata={modelConfig}
|
modeldata={modelConfig}
|
||||||
closeModal={closeModal}
|
closeModal={closeModal}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{/* For view logs */}
|
{/* For view logs */}
|
||||||
{modelConfig?.action === 6 && (
|
{modelConfig?.action === 6 && (
|
||||||
<AttendLogs Id={modelConfig?.id} closeModal={closeModal} />
|
<AttendLogs Id={modelConfig?.id} closeModal={closeModal} />
|
||||||
@ -128,9 +132,8 @@ const AttendancePage = () => {
|
|||||||
<li className="nav-item">
|
<li className="nav-item">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`nav-link ${
|
className={`nav-link ${activeTab === "all" ? "active" : ""
|
||||||
activeTab === "all" ? "active" : ""
|
} fs-6`}
|
||||||
} fs-6`}
|
|
||||||
onClick={() => handleTabChange("all")}
|
onClick={() => handleTabChange("all")}
|
||||||
data-bs-toggle="tab"
|
data-bs-toggle="tab"
|
||||||
data-bs-target="#navs-top-home"
|
data-bs-target="#navs-top-home"
|
||||||
@ -141,9 +144,8 @@ const AttendancePage = () => {
|
|||||||
<li className="nav-item">
|
<li className="nav-item">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`nav-link ${
|
className={`nav-link ${activeTab === "logs" ? "active" : ""
|
||||||
activeTab === "logs" ? "active" : ""
|
} fs-6`}
|
||||||
} fs-6`}
|
|
||||||
onClick={() => handleTabChange("logs")}
|
onClick={() => handleTabChange("logs")}
|
||||||
data-bs-toggle="tab"
|
data-bs-toggle="tab"
|
||||||
data-bs-target="#navs-top-profile"
|
data-bs-target="#navs-top-profile"
|
||||||
@ -155,9 +157,8 @@ const AttendancePage = () => {
|
|||||||
<li className={`nav-item ${!DoRegularized ? "d-none" : ""}`}>
|
<li className={`nav-item ${!DoRegularized ? "d-none" : ""}`}>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`nav-link ${
|
className={`nav-link ${activeTab === "regularization" ? "active" : ""
|
||||||
activeTab === "regularization" ? "active" : ""
|
} fs-6`}
|
||||||
} fs-6`}
|
|
||||||
onClick={() => handleTabChange("regularization")}
|
onClick={() => handleTabChange("regularization")}
|
||||||
data-bs-toggle="tab"
|
data-bs-toggle="tab"
|
||||||
data-bs-target="#navs-top-messages"
|
data-bs-target="#navs-top-messages"
|
||||||
@ -169,7 +170,38 @@ const AttendancePage = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Single search input that moves */}
|
{/* Single search input that moves */}
|
||||||
<div className="col-12 col-md-auto mt-2 mt-md-0 ms-md-auto px-2">
|
{/* <div className="col-12 col-md-auto mt-2 mt-md-0 ms-md-auto d-flex gap-2 align-items-center">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control form-control-sm"
|
||||||
|
placeholder="Search Employee..."
|
||||||
|
value={searchTerm}
|
||||||
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
|
style={{ minWidth: "200px" }}
|
||||||
|
/>
|
||||||
|
</div> */}
|
||||||
|
|
||||||
|
{/* 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
|
||||||
|
className="form-select form-select-sm"
|
||||||
|
style={{ minWidth: "180px" }}
|
||||||
|
value={appliedFilters.selectedOrganization}
|
||||||
|
onChange={(e) =>
|
||||||
|
setAppliedFilters((prev) => ({
|
||||||
|
...prev,
|
||||||
|
selectedOrganization: e.target.value,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<option value="">All Organizations</option>
|
||||||
|
<option value="Org A">Org A</option>
|
||||||
|
<option value="Org B">Org B</option>
|
||||||
|
<option value="Org C">Org C</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
{/* Search Input */}
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="form-control form-control-sm"
|
className="form-control form-control-sm"
|
||||||
@ -179,6 +211,7 @@ const AttendancePage = () => {
|
|||||||
style={{ minWidth: "200px" }}
|
style={{ minWidth: "200px" }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -204,7 +237,9 @@ const AttendancePage = () => {
|
|||||||
)}
|
)}
|
||||||
{activeTab === "regularization" && DoRegularized && (
|
{activeTab === "regularization" && DoRegularized && (
|
||||||
<div className="tab-pane fade show active py-0">
|
<div className="tab-pane fade show active py-0">
|
||||||
<Regularization searchTerm={searchTerm} />
|
<Regularization
|
||||||
|
searchTerm={searchTerm}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user