Merge pull request 'OnField_Issues_Oct_2W' (#455) from OnField_Issues_Oct_2W into OnFieldWork_V1

Reviewed-on: #455
Merged
This commit is contained in:
pramod.mahajan 2025-10-07 04:10:40 +00:00
commit 2f2215ab8a
5 changed files with 111 additions and 89 deletions

View File

@ -12,6 +12,7 @@ import { useAttendancesLogs } from "../../hooks/useAttendance";
import { queryClient } from "../../layouts/AuthLayout"; import { queryClient } from "../../layouts/AuthLayout";
import { ITEMS_PER_PAGE } from "../../utils/constants"; import { ITEMS_PER_PAGE } from "../../utils/constants";
import Pagination from "../common/Pagination"; import Pagination from "../common/Pagination";
import { useNavigate } from "react-router-dom";
const usePagination = (data, itemsPerPage) => { const usePagination = (data, itemsPerPage) => {
const [currentPage, setCurrentPage] = useState(1); const [currentPage, setCurrentPage] = useState(1);
@ -34,7 +35,7 @@ const usePagination = (data, itemsPerPage) => {
}; };
}; };
const AttendanceLog = ({ handleModalData, searchTerm ,organizationId}) => { const AttendanceLog = ({ handleModalData, searchTerm, organizationId }) => {
// const selectedProject = useSelector( // const selectedProject = useSelector(
// (store) => store.localVariables.projectId // (store) => store.localVariables.projectId
// ); // );
@ -46,6 +47,7 @@ const AttendanceLog = ({ handleModalData, searchTerm ,organizationId}) => {
const [isRefreshing, setIsRefreshing] = useState(false); const [isRefreshing, setIsRefreshing] = useState(false);
const [processedData, setProcessedData] = useState([]); const [processedData, setProcessedData] = useState([]);
const navigate = useNavigate();
const today = new Date(); const today = new Date();
today.setHours(0, 0, 0, 0); today.setHours(0, 0, 0, 0);
@ -86,48 +88,48 @@ const AttendanceLog = ({ handleModalData, searchTerm ,organizationId}) => {
organizationId organizationId
); );
const filtering = useCallback((dataToFilter) => { const filtering = useCallback((dataToFilter) => {
const filteredData = showPending const filteredData = showPending
? dataToFilter.filter((item) => item.checkOutTime === null) ? dataToFilter.filter((item) => item.checkOutTime === null)
: dataToFilter; : dataToFilter;
const group1 = filteredData const group1 = filteredData
.filter((d) => d.activity === 1 && isSameDay(d.checkInTime)) .filter((d) => d.activity === 1 && isSameDay(d.checkInTime))
.sort(sortByName); .sort(sortByName);
const group2 = filteredData const group2 = filteredData
.filter((d) => d.activity === 4 && isSameDay(d.checkOutTime)) .filter((d) => d.activity === 4 && isSameDay(d.checkOutTime))
.sort(sortByName); .sort(sortByName);
const group3 = filteredData const group3 = filteredData
.filter((d) => d.activity === 1 && isBeforeToday(d.checkInTime)) .filter((d) => d.activity === 1 && isBeforeToday(d.checkInTime))
.sort(sortByName); .sort(sortByName);
const group4 = filteredData.filter( const group4 = filteredData.filter(
(d) => d.activity === 4 && isBeforeToday(d.checkOutTime) (d) => d.activity === 4 && isBeforeToday(d.checkOutTime)
); );
const group5 = filteredData const group5 = filteredData
.filter((d) => d.activity === 2 && isBeforeToday(d.checkOutTime)) .filter((d) => d.activity === 2 && isBeforeToday(d.checkOutTime))
.sort(sortByName); .sort(sortByName);
const group6 = filteredData const group6 = filteredData
.filter((d) => d.activity === 5) .filter((d) => d.activity === 5)
.sort(sortByName); .sort(sortByName);
const sortedList = [...group1, ...group2, ...group3, ...group4, ...group5, ...group6]; const sortedList = [...group1, ...group2, ...group3, ...group4, ...group5, ...group6];
// Group by date // Group by date
const groupedByDate = sortedList.reduce((acc, item) => { const groupedByDate = sortedList.reduce((acc, item) => {
const date = (item.checkInTime || item.checkOutTime)?.split("T")[0]; const date = (item.checkInTime || item.checkOutTime)?.split("T")[0];
if (date) { if (date) {
acc[date] = acc[date] || []; acc[date] = acc[date] || [];
acc[date].push(item); acc[date].push(item);
} }
return acc; return acc;
}, {}); }, {});
const sortedDates = Object.keys(groupedByDate).sort( const sortedDates = Object.keys(groupedByDate).sort(
(a, b) => new Date(b) - new Date(a) (a, b) => new Date(b) - new Date(a)
); );
const finalData = sortedDates.flatMap((date) => groupedByDate[date]); const finalData = sortedDates.flatMap((date) => groupedByDate[date]);
setProcessedData(finalData); setProcessedData(finalData);
}, [showPending]); }, [showPending]);
useEffect(() => { useEffect(() => {
@ -146,31 +148,31 @@ const AttendanceLog = ({ handleModalData, searchTerm ,organizationId}) => {
}); });
}, [processedData, searchTerm]); }, [processedData, searchTerm]);
// const filteredSearchData = useMemo(() => { // const filteredSearchData = useMemo(() => {
// let tempData = processedData; // let tempData = processedData;
// if (searchTerm) { // if (searchTerm) {
// const lowercasedSearchTerm = searchTerm.toLowerCase(); // const lowercasedSearchTerm = searchTerm.toLowerCase();
// tempData = tempData.filter((item) => { // tempData = tempData.filter((item) => {
// const fullName = `${item.firstName} ${item.lastName}`.toLowerCase(); // const fullName = `${item.firstName} ${item.lastName}`.toLowerCase();
// return fullName.includes(lowercasedSearchTerm); // return fullName.includes(lowercasedSearchTerm);
// }); // });
// } // }
// if (filters?.selectedOrganization) { // if (filters?.selectedOrganization) {
// tempData = tempData.filter( // tempData = tempData.filter(
// (item) => item.organization?.name === filters.selectedOrganization // (item) => item.organization?.name === filters.selectedOrganization
// ); // );
// } // }
// if (filters?.selectedServices?.length > 0) { // if (filters?.selectedServices?.length > 0) {
// tempData = tempData.filter((item) => // tempData = tempData.filter((item) =>
// filters.selectedServices.includes(item.service?.name) // filters.selectedServices.includes(item.service?.name)
// ); // );
// } // }
// return tempData; // return tempData;
// }, [processedData, searchTerm, filters]); // }, [processedData, searchTerm, filters]);
const { const {
@ -265,7 +267,7 @@ const AttendanceLog = ({ handleModalData, searchTerm ,organizationId}) => {
<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> </div>
<div className="table-responsive text-nowrap" style={{ minHeight: "200px" }}> <div className="table-responsive text-nowrap" style={{ minHeight: "200px" }}>
{isLoading ? ( {isLoading ? (
@ -326,7 +328,12 @@ const AttendanceLog = ({ handleModalData, searchTerm ,organizationId}) => {
lastName={attendance.lastName} lastName={attendance.lastName}
/> />
<div className="d-flex flex-column"> <div className="d-flex flex-column">
<a href="#" className="text-heading text-truncate"> <a
onClick={() =>
navigate(`/employee/${attendance.employeeId}?for=attendance`)
}
className="text-heading text-truncate cursor-pointer"
>
<span className="fw-normal"> <span className="fw-normal">
{attendance.firstName} {attendance.lastName} {attendance.firstName} {attendance.lastName}
</span> </span>
@ -373,11 +380,11 @@ const AttendanceLog = ({ handleModalData, searchTerm ,organizationId}) => {
</div> </div>
)} )}
{filteredSearchData.length > ITEMS_PER_PAGE && ( {filteredSearchData.length > ITEMS_PER_PAGE && (
<Pagination <Pagination
currentPage={currentPage} currentPage={currentPage}
totalPages={totalPages} totalPages={totalPages}
onPageChange={paginate} onPageChange={paginate}
/> />
)} )}
</> </>
); );

View File

@ -10,12 +10,14 @@ 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";
import Pagination from "../common/Pagination"; import Pagination from "../common/Pagination";
import { useNavigate } from "react-router-dom";
const Regularization = ({ handleRequest, searchTerm,projectId, organizationId, IncludeInActive }) => { const Regularization = ({ handleRequest, searchTerm, projectId, organizationId, IncludeInActive }) => {
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();
const [regularizesList, setregularizedList] = useState([]); const [regularizesList, setregularizedList] = useState([]);
const navigate = useNavigate();
const { regularizes, loading, error, refetch } = const { regularizes, loading, error, refetch } =
useRegularizationRequests(selectedProject, organizationId, IncludeInActive); useRegularizationRequests(selectedProject, organizationId, IncludeInActive);
@ -149,7 +151,17 @@ const Regularization = ({ handleRequest, searchTerm,projectId, organizationId, I
lastName={att.lastName} lastName={att.lastName}
/> />
<div className="d-flex flex-column"> <div className="d-flex flex-column">
<a href="#" className="text-heading text-truncate"> {/* <a href="#" className="text-heading text-truncate">
<span className="fw-normal">
{att.firstName} {att.lastName}
</span>
</a> */}
<a
onClick={() =>
navigate(`/employee/${att.employeeId}?for=attendance`)
}
className="text-heading text-truncate cursor-pointer"
>
<span className="fw-normal"> <span className="fw-normal">
{att.firstName} {att.lastName} {att.firstName} {att.lastName}
</span> </span>
@ -191,10 +203,10 @@ const Regularization = ({ handleRequest, searchTerm,projectId, organizationId, I
)} )}
{!loading && totalPages > 1 && ( {!loading && totalPages > 1 && (
<Pagination <Pagination
currentPage={currentPage} currentPage={currentPage}
totalPages={totalPages} totalPages={totalPages}
onPageChange={paginate} onPageChange={paginate}
/> />
)} )}
</div> </div>
); );

View File

@ -1,4 +1,4 @@
import { useCallback, useEffect, useState,useMemo } from "react"; import { useCallback, useEffect, useState, useMemo } from "react";
import getGreetingMessage from "../../utils/greetingHandler"; import getGreetingMessage from "../../utils/greetingHandler";
import { import {
cacheData, cacheData,
@ -14,7 +14,7 @@ import { useProfile } from "../../hooks/useProfile";
import { useLocation, useNavigate, useParams } from "react-router-dom"; import { useLocation, useNavigate, useParams } from "react-router-dom";
import Avatar from "../../components/common/Avatar"; import Avatar from "../../components/common/Avatar";
import { useChangePassword } from "../Context/ChangePasswordContext"; import { useChangePassword } from "../Context/ChangePasswordContext";
import { useProjects } from "../../hooks/useProjects"; import { useProjects } from "../../hooks/useProjects";
import { useProjectName } from "../../hooks/useProjects"; import { useProjectName } from "../../hooks/useProjects";
import eventBus from "../../services/eventBus"; import eventBus from "../../services/eventBus";
import { useHasUserPermission } from "../../hooks/useHasUserPermission"; import { useHasUserPermission } from "../../hooks/useHasUserPermission";
@ -22,7 +22,7 @@ import { ALLOW_PROJECTSTATUS_ID, MANAGE_PROJECT, UUID_REGEX } from "../../utils/
import { useAuthModal, useLogout } from "../../hooks/useAuth"; import { useAuthModal, useLogout } from "../../hooks/useAuth";
const Header = () => { const Header = () => {
const { profile } = useProfile(); const { profile } = useProfile();
const { data: masterData } = useMaster(); const { data: masterData } = useMaster();
const location = useLocation(); const location = useLocation();
const dispatch = useDispatch(); const dispatch = useDispatch();
@ -40,11 +40,12 @@ const Header = () => {
const isProjectPath = pathname === "/projects"; const isProjectPath = pathname === "/projects";
const isDirectory = pathname === "/directory"; const isDirectory = pathname === "/directory";
const isEmployeeList = pathname === "/employees"; const isEmployeeList = pathname === "/employees";
const isMasters = pathname === "/masters";
// const isExpense = pathname === "/expenses"; // const isExpense = pathname === "/expenses";
const isEmployeeProfile = UUID_REGEX.test(pathname); const isEmployeeProfile = UUID_REGEX.test(pathname);
const hideDropPaths = const hideDropPaths =
isDirectory || isEmployeeList || isEmployeeProfile; isDirectory || isEmployeeList || isMasters || isEmployeeProfile;
const showProjectDropdown = !hideDropPaths; const showProjectDropdown = !hideDropPaths;
@ -57,8 +58,8 @@ const Header = () => {
isDashboardPath isDashboardPath
? projectNames ? projectNames
: projectNames?.filter((project) => : projectNames?.filter((project) =>
ALLOW_PROJECTSTATUS_ID.includes(project.projectStatusId) ALLOW_PROJECTSTATUS_ID.includes(project.projectStatusId)
), ),
[projectNames, isDashboardPath] [projectNames, isDashboardPath]
); );
@ -66,11 +67,11 @@ const Header = () => {
if (projectLoading) return "Loading..."; if (projectLoading) return "Loading...";
if (!projectNames?.length) return "No Projects Assigned"; if (!projectNames?.length) return "No Projects Assigned";
if (projectNames.length === 1) return projectNames[0].name; if (projectNames.length === 1) return projectNames[0].name;
if (selectedProject === null) return "All Projects"; if (selectedProject === null) return "All Projects";
const selectedObj = projectNames.find((p) => p.id === selectedProject); const selectedObj = projectNames.find((p) => p.id === selectedProject);
return selectedObj return selectedObj
? selectedObj.name ? selectedObj.name
: projectNames[0]?.name || "No Projects Assigned"; : projectNames[0]?.name || "No Projects Assigned";
}, [projectLoading, projectNames, selectedProject]); }, [projectLoading, projectNames, selectedProject]);
// ===== Role Helper ===== // ===== Role Helper =====
@ -199,13 +200,13 @@ const Header = () => {
style={{ overflow: "auto", maxHeight: "300px" }} style={{ overflow: "auto", maxHeight: "300px" }}
> >
<li> <li>
<button <button
className="dropdown-item" className="dropdown-item"
onClick={() => handleProjectChange(null)} onClick={() => handleProjectChange(null)}
>All Project</button> >All Project</button>
</li> </li>
{[...projectsForDropdown] {[...projectsForDropdown]
.sort((a, b) => a?.name?.localeCompare(b.name)) .sort((a, b) => a?.name?.localeCompare(b.name))
.map((project) => ( .map((project) => (
@ -231,7 +232,7 @@ const Header = () => {
<ul className="navbar-nav flex-row align-items-center ms-md-auto"> <ul className="navbar-nav flex-row align-items-center ms-md-auto">
{/* {HasManageProjectPermission && ( */} {/* {HasManageProjectPermission && ( */}
{/* )} */} {/* )} */}
<li className="nav-item navbar-dropdown dropdown-user dropdown"> <li className="nav-item navbar-dropdown dropdown-user dropdown">
<a <a

View File

@ -35,6 +35,7 @@ const ProjectCard = ({ project }) => {
const handleViewProject = () => { const handleViewProject = () => {
dispatch(setProjectId(project.id)); dispatch(setProjectId(project.id));
localStorage.setItem("lastActiveProjectTab","profile")
navigate(`/projects/details`); navigate(`/projects/details`);
}; };
const handleViewActivities = () => { const handleViewActivities = () => {

View File

@ -131,6 +131,7 @@ const ProjectListView = ({
const handleMoveDetails = (project) => { const handleMoveDetails = (project) => {
dispatch(setProjectId(project)); dispatch(setProjectId(project));
localStorage.setItem("lastActiveProjectTab","profile")
navigate("/projects/details"); navigate("/projects/details");
}; };
return ( return (