react-query-v2 : react-query intergrated inside attendance and gallery module #270

Merged
vikas.nale merged 16 commits from react-query-v2 into main 2025-07-24 09:41:21 +00:00
5 changed files with 78 additions and 58 deletions
Showing only changes of commit 43e173d0ef - Show all commits

View File

@ -10,7 +10,7 @@ import ProjectRepository from "../../repositories/ProjectRepository";
import Breadcrumb from "../../components/common/Breadcrumb"; import Breadcrumb from "../../components/common/Breadcrumb";
import {useProjectDetails, useProjectInfra, useProjects} from "../../hooks/useProjects"; import {useProjectDetails, useProjectInfra, useProjects} from "../../hooks/useProjects";
import {useHasUserPermission} from "../../hooks/useHasUserPermission"; import {useHasUserPermission} from "../../hooks/useHasUserPermission";
import {MANAGE_PROJECT_INFRA} from "../../utils/constants"; import {APPROVE_TASK, ASSIGN_REPORT_TASK, MANAGE_PROJECT_INFRA} from "../../utils/constants";
import {useDispatch, useSelector} from "react-redux"; import {useDispatch, useSelector} from "react-redux";
import {useProfile} from "../../hooks/useProfile"; import {useProfile} from "../../hooks/useProfile";
import {refreshData, setProjectId} from "../../slices/localVariablesSlice"; import {refreshData, setProjectId} from "../../slices/localVariablesSlice";
@ -27,6 +27,8 @@ const InfraPlanning = () =>
const ManageInfra = useHasUserPermission( MANAGE_PROJECT_INFRA ) const ManageInfra = useHasUserPermission( MANAGE_PROJECT_INFRA )
const ApprovedTaskRights = useHasUserPermission(APPROVE_TASK)
const ReportTaskRights = useHasUserPermission(ASSIGN_REPORT_TASK)
const reloadedData = useSelector( ( store ) => store.localVariables.reload ) const reloadedData = useSelector( ( store ) => store.localVariables.reload )
@ -44,7 +46,7 @@ const InfraPlanning = () =>
<div className="col-md-12 col-lg-12 col-xl-12 order-0 mb-4"> <div className="col-md-12 col-lg-12 col-xl-12 order-0 mb-4">
<div className="card"> <div className="card">
<div className="card-body" style={{ padding: "0.5rem" }}> <div className="card-body" style={{ padding: "0.5rem" }}>
{ManageInfra ? ( {(ApprovedTaskRights || ReportTaskRights) ? (
<div className="align-items-center"> <div className="align-items-center">
<div className="row "> <div className="row ">
{isLoading && ( <p>Loading...</p> )} {isLoading && ( <p>Loading...</p> )}

View File

@ -29,7 +29,8 @@ const Header = () => {
const HasManageProjectPermission = useHasUserPermission(MANAGE_PROJECT); const HasManageProjectPermission = useHasUserPermission(MANAGE_PROJECT);
const isDirectoryPath = /^\/directory$/.test(location.pathname); const isDirectoryPath = /^\/directory$/.test(location.pathname);
const isDashboard = /^\/dashboard$/.test(location.pathname) || /^\/$/.test(location.pathname); const isProjectPath = /^\/projects$/.test(location.pathname);
const isDashboard = /^\/dashboard$/.test(location.pathname) || /^\/$/.test(location.pathname) ;
const getRole = (roles, joRoleId) => { const getRole = (roles, joRoleId) => {
if (!Array.isArray(roles)) return "User"; if (!Array.isArray(roles)) return "User";
let role = roles.find((role) => role.id === joRoleId); let role = roles.find((role) => role.id === joRoleId);
@ -159,6 +160,15 @@ const Header = () => {
}; };
}, [handler, newProjectHandler]); }, [handler, newProjectHandler]);
const handleProjectChange =(project)=>{
if(isProjectPath){
dispatch(setProjectId(project))
navigate("/projects/details")
} else{
dispatch(setProjectId(project))
}
}
return ( return (
<nav <nav
className="layout-navbar container-fluid mb-3 navbar navbar-expand-xl navbar-detached align-items-center bg-navbar-theme" className="layout-navbar container-fluid mb-3 navbar navbar-expand-xl navbar-detached align-items-center bg-navbar-theme"
@ -212,7 +222,7 @@ const Header = () => {
<li key={project?.id}> <li key={project?.id}>
<button <button
className="dropdown-item" className="dropdown-item"
onClick={() => dispatch(setProjectId(project?.id))} onClick={()=>handleProjectChange(project?.id)}
> >
{project?.name} {project?.name}
{project?.shortName && ( {project?.shortName && (

View File

@ -15,8 +15,7 @@ import { useCreateTask } from "../../hooks/useTasks";
const AssignTask = ({ assignData, onClose, setAssigned }) => { const AssignTask = ({ assignData, onClose, setAssigned }) => {
const maxPlanned = const maxPlanned =
assignData?.workItem?.plannedWork - assignData?.workItem?.plannedWork - assignData?.workItem?.completedWork;
assignData?.workItem?.completedWork;
const schema = z.object({ const schema = z.object({
selectedEmployees: z selectedEmployees: z
.array(z.string()) .array(z.string())
@ -71,7 +70,7 @@ const AssignTask = ({ assignData, onClose, setAssigned }) => {
} else { } else {
console.warn("Bootstrap is not available. Popovers might not function."); console.warn("Bootstrap is not available. Popovers might not function.");
} }
}, []); }, []);
const selectedProject = useSelector( const selectedProject = useSelector(
(store) => store.localVariables.projectId (store) => store.localVariables.projectId
); );
@ -79,13 +78,13 @@ const AssignTask = ({ assignData, onClose, setAssigned }) => {
employees, employees,
loading: employeeLoading, loading: employeeLoading,
recallEmployeeData, recallEmployeeData,
} = useEmployeesAllOrByProjectId(selectedProject, false); } = useEmployeesAllOrByProjectId(false, selectedProject, false);
const dispatch = useDispatch(); const dispatch = useDispatch();
const { loading } = useMaster(); const { loading } = useMaster();
const {data:jobRoleData} = useMaster(); const { data: jobRoleData } = useMaster();
const [selectedRole, setSelectedRole] = useState("all"); const [selectedRole, setSelectedRole] = useState("all");
const [displayedSelection, setDisplayedSelection] = useState(""); const [displayedSelection, setDisplayedSelection] = useState("");
const { const {
handleSubmit, handleSubmit,
control, control,
@ -93,19 +92,19 @@ const AssignTask = ({ assignData, onClose, setAssigned }) => {
watch, watch,
formState: { errors }, formState: { errors },
reset, reset,
trigger, trigger,
} = useForm({ } = useForm({
defaultValues: { defaultValues: {
selectedEmployees: [], selectedEmployees: [],
description: "", description: "",
plannedTask: "", plannedTask: "",
}, },
resolver: zodResolver(schema), resolver: zodResolver(schema),
}); });
const handleCheckboxChange = (event, user) => { const handleCheckboxChange = (event, user) => {
const isChecked = event.target.checked; const isChecked = event.target.checked;
let updatedSelectedEmployees = watch("selectedEmployees") || []; let updatedSelectedEmployees = watch("selectedEmployees") || [];
if (isChecked) { if (isChecked) {
if (!updatedSelectedEmployees.includes(user.id)) { if (!updatedSelectedEmployees.includes(user.id)) {
@ -117,12 +116,12 @@ const AssignTask = ({ assignData, onClose, setAssigned }) => {
); );
} }
setValue("selectedEmployees", updatedSelectedEmployees); setValue("selectedEmployees", updatedSelectedEmployees);
trigger("selectedEmployees"); trigger("selectedEmployees");
}; };
useEffect(() => { useEffect(() => {
dispatch(changeMaster("Job Role")); dispatch(changeMaster("Job Role"));
return () => setSelectedRole("all"); return () => setSelectedRole("all");
}, [dispatch]); }, [dispatch]);
@ -137,11 +136,12 @@ const AssignTask = ({ assignData, onClose, setAssigned }) => {
(emp) => String(emp.jobRoleId || "") === selectedRole (emp) => String(emp.jobRoleId || "") === selectedRole
); );
const onSubmit = (data) => { const onSubmit = (data) => {
const selectedEmployeeIds = data.selectedEmployees; const selectedEmployeeIds = data.selectedEmployees;
const taskTeamWithDetails = selectedEmployeeIds?.map((empId) => empId)?.filter(Boolean); const taskTeamWithDetails = selectedEmployeeIds
?.map((empId) => empId)
?.filter(Boolean);
const formattedData = { const formattedData = {
taskTeam: taskTeamWithDetails, taskTeam: taskTeamWithDetails,
plannedTask: data.plannedTask, plannedTask: data.plannedTask,
@ -149,7 +149,10 @@ const AssignTask = ({ assignData, onClose, setAssigned }) => {
assignmentDate: new Date().toISOString(), assignmentDate: new Date().toISOString(),
workItemId: assignData?.workItem.id, workItemId: assignData?.workItem.id,
}; };
assignTask({payload:formattedData,workAreaId:assignData?.workArea?.id}); assignTask({
payload: formattedData,
workAreaId: assignData?.workArea?.id,
});
}; };
const closedModel = () => { const closedModel = () => {
@ -234,12 +237,12 @@ const AssignTask = ({ assignData, onClose, setAssigned }) => {
<div className="col-12 h-sm-25 overflow-auto mt-2"> <div className="col-12 h-sm-25 overflow-auto mt-2">
{selectedRole !== "" && ( {selectedRole !== "" && (
<div className="row"> <div className="row">
{loading ? ( // Assuming 'loading' here refers to master data loading {employeeLoading ? (
<div className="col-12"> <div className="col-12">
<p className="text-center">Loading roles...</p> <p className="text-center">Loading employees...</p>
</div> </div>
) : filteredEmployees?.length > 0 ? ( ) : filteredEmployees?.length > 0 ? (
filteredEmployees?.map((emp) => { filteredEmployees.map((emp) => {
const jobRole = jobRoleData?.find( const jobRole = jobRoleData?.find(
(role) => role?.id === emp?.jobRoleId (role) => role?.id === emp?.jobRoleId
); );
@ -331,7 +334,7 @@ const AssignTask = ({ assignData, onClose, setAssigned }) => {
"selectedEmployees", "selectedEmployees",
updatedSelected updatedSelected
); );
trigger("selectedEmployees"); trigger("selectedEmployees");
}} }}
> >
<i className="icon-base bx bx-x icon-md "></i> <i className="icon-base bx bx-x icon-md "></i>
@ -348,7 +351,6 @@ const AssignTask = ({ assignData, onClose, setAssigned }) => {
{!loading && errors.selectedEmployees && ( {!loading && errors.selectedEmployees && (
<div className="danger-text mt-1"> <div className="danger-text mt-1">
<p>{errors.selectedEmployees.message}</p>{" "} <p>{errors.selectedEmployees.message}</p>{" "}
</div> </div>
)} )}

View File

@ -125,7 +125,7 @@ const WorkArea = ({ workArea, floor, forBuilding }) => {
{isLoading || ProjectTaskList === undefined ? ( {isLoading || ProjectTaskList === undefined ? (
<div className="text-center py-2 text-muted">Loading activities...</div> <div className="text-center py-2 text-muted">Loading activities...</div>
) : ProjectTaskList?.length === 0 ? ( ) : ProjectTaskList?.length === 0 ? (
<div className="text-center py-2 text-muted">Loading activities...</div> <div className="text-center py-2 text-muted">No activities available for this work area.</div>
):ProjectTaskList?.length > 0 ? ( ):ProjectTaskList?.length > 0 ? (
<table className="table table-sm mx-1"> <table className="table table-sm mx-1">
<thead> <thead>
@ -144,7 +144,7 @@ const WorkArea = ({ workArea, floor, forBuilding }) => {
Today's Planned Today's Planned
</th> </th>
<th className="infra-activity-table-header">Progress</th> <th className="infra-activity-table-header">Progress</th>
{(ManageInfra || ManageAndAssignTak) && ( {(ManageInfra || ManageAndAssignTak) && (
<th className="infra-activity-table-header text-end"> <th className="infra-activity-table-header text-end">
<span className="px-2">Actions</span> <span className="px-2">Actions</span>
</th> </th>

View File

@ -22,16 +22,20 @@ const ProjectList = () => {
const { profile: loginUser } = useProfile(); const { profile: loginUser } = useProfile();
const [listView, setListView] = useState(false); const [listView, setListView] = useState(false);
const [showModal, setShowModal] = useState(false); const [showModal, setShowModal] = useState(false);
const selectedProject = useSelector((store)=>store.localVariables.projectId) const selectedProject = useSelector(
const dispatch = useDispatch() (store) => store.localVariables.projectId
);
const dispatch = useDispatch();
const { projects, loading, error, refetch } = useProjects(); const { projects, loading, error, refetch } = useProjects();
const [projectList, setProjectList] = useState([]); const [projectList, setProjectList] = useState([]);
const HasManageProjectPermission = useHasUserPermission(MANAGE_PROJECT); const HasManageProjectPermission = useHasUserPermission(MANAGE_PROJECT);
const [HasManageProject, setHasManageProject] = useState(HasManageProjectPermission); const [HasManageProject, setHasManageProject] = useState(
HasManageProjectPermission
);
const { mutate: createProject,isPending } = useCreateProject({ const { mutate: createProject, isPending } = useCreateProject({
onSuccessCallback: () => { onSuccessCallback: () => {
setShowModal(false); setShowModal(false);
}, },
@ -48,7 +52,9 @@ const ProjectList = () => {
const handleShow = () => setShowModal(true); const handleShow = () => setShowModal(true);
const handleClose = () => setShowModal(false); const handleClose = () => setShowModal(false);
useEffect(() => {
dispatch(setProjectId(null));
}, []);
const sortingProject = (projects) => { const sortingProject = (projects) => {
if (!loading && Array.isArray(projects)) { if (!loading && Array.isArray(projects)) {
const grouped = {}; const grouped = {};
@ -74,14 +80,10 @@ const ProjectList = () => {
}; };
useEffect(() => { useEffect(() => {
if(selectedProject == null){
dispatch(setProjectId(projects[0]?.id));
}
if (!loading && projects) { if (!loading && projects) {
sortingProject(projects); sortingProject(projects);
} }
}, [projects, loading, selectedStatuses]); }, [projects, loading, selectedStatuses]);
useEffect(() => { useEffect(() => {
setHasManageProject(loginUser ? HasManageProjectPermission : false); setHasManageProject(loginUser ? HasManageProjectPermission : false);
@ -114,12 +116,10 @@ const ProjectList = () => {
const totalPages = Math.ceil(filteredProjects.length / ITEMS_PER_PAGE); const totalPages = Math.ceil(filteredProjects.length / ITEMS_PER_PAGE);
const { const { currentItems, currentPage, paginate, setCurrentPage } = usePagination(
currentItems, filteredProjects,
currentPage, ITEMS_PER_PAGE
paginate, );
setCurrentPage,
} = usePagination(filteredProjects, ITEMS_PER_PAGE);
useEffect(() => { useEffect(() => {
const tooltipTriggerList = Array.from( const tooltipTriggerList = Array.from(
@ -130,17 +130,16 @@ const ProjectList = () => {
return ( return (
<> <>
{showModal && ( {showModal && (
<GlobalModel isOpen={showModal} closeModal={handleClose}> <GlobalModel isOpen={showModal} closeModal={handleClose}>
<ManageProjectInfo <ManageProjectInfo
project={null} project={null}
handleSubmitForm={handleSubmitForm} handleSubmitForm={handleSubmitForm}
onClose={handleClose} onClose={handleClose}
isPending={isPending} isPending={isPending}
/> />
</GlobalModel> </GlobalModel>
)} )}
<div className="container-fluid"> <div className="container-fluid">
<Breadcrumb <Breadcrumb
@ -211,7 +210,7 @@ const ProjectList = () => {
}, },
{ {
id: "cdad86aa-8a56-4ff4-b633-9c629057dfef", id: "cdad86aa-8a56-4ff4-b633-9c629057dfef",
label:"In Progress" label: "In Progress",
}, },
{ {
id: "603e994b-a27f-4e5d-a251-f3d69b0498ba", id: "603e994b-a27f-4e5d-a251-f3d69b0498ba",
@ -269,11 +268,14 @@ const ProjectList = () => {
{listView ? ( {listView ? (
<div className="card cursor-pointer"> <div className="card cursor-pointer">
<div className="card-body p-2"> <div className="card-body p-2">
<div className="table-responsive text-nowrap py-2 " style={{minHeight:"400px"}}> <div
className="table-responsive text-nowrap py-2 "
style={{ minHeight: "400px" }}
>
<table className="table m-3"> <table className="table m-3">
<thead> <thead>
<tr> <tr>
<th className="text-start" colSpan={5} > <th className="text-start" colSpan={5}>
Project Name Project Name
</th> </th>
<th className="mx-2 text-start">Contact Person</th> <th className="mx-2 text-start">Contact Person</th>
@ -298,8 +300,8 @@ const ProjectList = () => {
}, },
{ {
id: "cdad86aa-8a56-4ff4-b633-9c629057dfef", id: "cdad86aa-8a56-4ff4-b633-9c629057dfef",
label:"In Progress" label: "In Progress",
}, },
{ {
id: "603e994b-a27f-4e5d-a251-f3d69b0498ba", id: "603e994b-a27f-4e5d-a251-f3d69b0498ba",
label: "On Hold", label: "On Hold",
@ -342,7 +344,11 @@ const ProjectList = () => {
<tbody className="table-border-bottom-0 overflow-auto "> <tbody className="table-border-bottom-0 overflow-auto ">
{currentItems.length === 0 ? ( {currentItems.length === 0 ? (
<tr className="text-center"> <tr className="text-center">
<td colSpan="12" rowSpan='12'style={{height:"200px"}} > <td
colSpan="12"
rowSpan="12"
style={{ height: "200px" }}
>
No projects found No projects found
</td> </td>
</tr> </tr>