Merge branch 'Issue_May_2W' of https://git.marcoaiot.com/admin/marco.pms.web into Issue_May_2W

This commit is contained in:
Pramod Mahajan 2025-05-09 17:45:50 +05:30
commit 067f7306d4
8 changed files with 224 additions and 119 deletions

View File

@ -185,7 +185,7 @@
height: 2.2rem; height: 2.2rem;
} }
.table > thead > tr :first-child { /* .table > thead > tr :first-child {
text-align: left; text-align: left;
padding-left: 50px !important; padding-left: 50px;
} } */

View File

@ -22,8 +22,8 @@ const Regularization = ({ handleRequest }) => {
const nameB = b.firstName.toLowerCase() + b.lastName.toLowerCase(); const nameB = b.firstName.toLowerCase() + b.lastName.toLowerCase();
return nameA.localeCompare(nameB); return nameA.localeCompare(nameB);
}; };
const filteredData = [...regularizesList]?.sort(sortByName);
const filteredData = regularizesList.sort(sortByName);
const { currentPage, totalPages, currentItems, paginate } = usePagination( const { currentPage, totalPages, currentItems, paginate } = usePagination(
filteredData, filteredData,

View File

@ -6,27 +6,29 @@ import { useHasUserPermission } from "../../../hooks/useHasUserPermission";
import { MANAGE_PROJECT_INFRA, MANAGE_TASK } from "../../../utils/constants"; import { MANAGE_PROJECT_INFRA, MANAGE_TASK } from "../../../utils/constants";
import ConfirmModal from "../../common/ConfirmModal"; import ConfirmModal from "../../common/ConfirmModal";
import ProjectRepository from '../../../repositories/ProjectRepository' import ProjectRepository from "../../../repositories/ProjectRepository";
import {useProjectDetails} from '../../../hooks/useProjects' import { useProjectDetails } from "../../../hooks/useProjects";
import showToast from "../../../services/toastService"; import showToast from "../../../services/toastService";
import {cacheData, getCachedData} from "../../../slices/apiDataManager"; import { cacheData, getCachedData } from "../../../slices/apiDataManager";
import {useDispatch} from "react-redux"; import { useDispatch } from "react-redux";
import {refreshData} from "../../../slices/localVariablesSlice"; import { refreshData } from "../../../slices/localVariablesSlice";
const WorkItem = ({ workItem, forBuilding, forFloor, forWorkArea }) => { const WorkItem = ({ workItem, forBuilding, forFloor, forWorkArea }) => {
const { projectId } = useParams(); const { projectId } = useParams();
const [itemName, setItemName] = useState(""); const [itemName, setItemName] = useState("");
const [NewWorkItem, setNewWorkItem] = useState(); const [NewWorkItem, setNewWorkItem] = useState();
const [isModalOpen, setIsModalOpen] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false);
const [ showModal, setShowModal ] = useState( false ); const [showModal, setShowModal] = useState(false);
const [showModal2, setShowModal2] = useState(false); const [showModal2, setShowModal2] = useState(false);
const ManageTasks = useHasUserPermission(MANAGE_TASK); const ManageTasks = useHasUserPermission(MANAGE_TASK);
const ManageInfra = useHasUserPermission( MANAGE_PROJECT_INFRA ); const ManageInfra = useHasUserPermission(MANAGE_PROJECT_INFRA);
const [ loadingDelete, setLoadingDelete ] = useState( false ) const [loadingDelete, setLoadingDelete] = useState(false);
const project = getCachedData("projectInfo"); const project = getCachedData("projectInfo");
const dispatch = useDispatch() const dispatch = useDispatch();
const {projects_Details} = useProjectDetails(projectId || project?.projectId) const { projects_Details } = useProjectDetails(
projectId || project?.projectId
);
const openModal = () => setIsModalOpen(true); const openModal = () => setIsModalOpen(true);
const closeModal = () => setIsModalOpen(false); const closeModal = () => setIsModalOpen(false);
@ -55,17 +57,14 @@ const WorkItem = ({ workItem, forBuilding, forFloor, forWorkArea }) => {
document.querySelectorAll('[data-bs-toggle="tooltip"]') document.querySelectorAll('[data-bs-toggle="tooltip"]')
); );
tooltipTriggerList.forEach((el) => new bootstrap.Tooltip(el)); tooltipTriggerList.forEach((el) => new bootstrap.Tooltip(el));
}, [] ); }, []);
const showModal1 = () => setShowModal(true); const showModal1 = () => setShowModal(true);
const closeModal1 = () => setShowModal( false ); const closeModal1 = () => setShowModal(false);
const showModalDelete = () => setShowModal2(true); const showModalDelete = () => setShowModal2(true);
const closeModalDelete = () => setShowModal2( false ); const closeModalDelete = () => setShowModal2(false);
const handleSubmit = async() => { const handleSubmit = async () => {
setLoadingDelete(true); setLoadingDelete(true);
try try
{ {
@ -100,28 +99,26 @@ const WorkItem = ({ workItem, forBuilding, forFloor, forWorkArea }) => {
: building : building
), ),
}; };
cacheData("projectInfo", { cacheData("projectInfo", {
projectId: newProject.id, projectId: newProject.id,
data: newProject, data: newProject,
}); });
dispatch( refreshData( true ) ); dispatch(refreshData(true));
closeModalDelete() closeModalDelete();
setLoadingDelete(false) setLoadingDelete(false);
showToast("Activity Deleted Successfully","success") showToast("Activity Deleted Successfully", "success");
} catch ( error ) } catch (error) {
{ setLoadingDelete(false);
setLoadingDelete( false ) closeModalDelete();
closeModalDelete()
const message = const message =
error.response?.data?.message || error.response?.data?.message ||
error.message || error.message ||
"An unexpected error occurred"; "An unexpected error occurred";
showToast( message, "error" ); showToast(message, "error");
} }
}; };
return ( return (
<> <>
{isModalOpen && ( {isModalOpen && (
@ -136,32 +133,45 @@ const WorkItem = ({ workItem, forBuilding, forFloor, forWorkArea }) => {
</div> </div>
)} )}
{showModal && <div {showModal && (
className={`modal fade ${showModal ? "show" : ""}`} <div
tabIndex="-1" className={`modal fade ${showModal ? "show" : ""}`}
role="dialog" tabIndex="-1"
style={{ display: showModal ? "block" : "none" }} role="dialog"
aria-hidden={!showModal} style={{ display: showModal ? "block" : "none" }}
> aria-hidden={!showModal}
<EditActivityModal >
workItem={workItem} <EditActivityModal
workArea={forWorkArea} workItem={workItem}
building={forBuilding} workArea={forWorkArea}
floor={forFloor} building={forBuilding}
onClose={closeModal1} floor={forFloor}
/> onClose={closeModal1}
</div>} />
</div>
)}
{showModal2 && <div
className={`modal fade ${showModal2 ? "show" : ""}`} {showModal2 && (
tabIndex="-1" <div
role="dialog" className={`modal fade ${showModal2 ? "show" : ""}`}
style={{ display: showModal2 ? "block" : "none" }} tabIndex="-1"
aria-hidden='false' role="dialog"
> style={{
<ConfirmModal type={"delete"} header={"Delete Activity"} message={"Are you sure you want delete?"} onSubmit={ handleSubmit} onClose={closeModalDelete} loading={loadingDelete}/> display: showModal2 ? "block" : "none",
</div> } backgroundColor: showModal2 ? "rgba(0,0,0,0.5)" : "transparent",
}}
aria-hidden="false"
>
<ConfirmModal
type={"delete"}
header={"Delete Activity"}
message={"Are you sure you want delete?"}
onSubmit={handleSubmit}
onClose={closeModalDelete}
loading={loadingDelete}
/>
</div>
)}
<tr> <tr>
<td className="text-start table-cell-small"> <td className="text-start table-cell-small">
@ -175,23 +185,30 @@ const WorkItem = ({ workItem, forBuilding, forFloor, forWorkArea }) => {
</td> </td>
{/* for mobile view */} {/* for mobile view */}
<td className="text-center d-sm-none d-sm-table-cell"> <td className="text-center d-sm-none d-sm-table-cell">
{hasWorkItem {hasWorkItem
? NewWorkItem?.workItem?.completedWork ?? workItem?.completedWork ?? "NA" ? NewWorkItem?.workItem?.completedWork ??
: "NA"}/{" "} workItem?.completedWork ??
"NA"
: "NA"}
/{" "}
{hasWorkItem {hasWorkItem
? NewWorkItem?.workItem?.plannedWork || workItem?.plannedWork ? NewWorkItem?.workItem?.plannedWork || workItem?.plannedWork
: "NA"} : "NA"}
</td> </td>
{/* for greather than mobile view ************* */} {/* for greather than mobile view ************* */}
<td className="text-center d-none d-md-table-cell"> <td className="text-center d-none d-md-table-cell">
{hasWorkItem {hasWorkItem
? NewWorkItem?.workItem?.plannedWork ?? workItem?.plannedWork ?? "NA" ? NewWorkItem?.workItem?.plannedWork ??
: "NA"} workItem?.plannedWork ??
"NA"
: "NA"}
</td> </td>
<td className="text-center d-none d-md-table-cell"> <td className="text-center d-none d-md-table-cell">
{hasWorkItem {hasWorkItem
? NewWorkItem?.workItem?.completedWork ?? workItem?.completedWork ?? "NA" ? NewWorkItem?.workItem?.completedWork ??
: "NA"} workItem?.completedWork ??
"NA"
: "NA"}
</td> </td>
<td className="text-center" style={{ width: "15%" }}> <td className="text-center" style={{ width: "15%" }}>
<div className="progress p-0"> <div className="progress p-0">
@ -232,7 +249,7 @@ const WorkItem = ({ workItem, forBuilding, forFloor, forWorkArea }) => {
</span> </span>
</button> </button>
)} )}
{ ManageInfra && ( {ManageInfra && (
<> <>
<button <button
aria-label="Modify" aria-label="Modify"

View File

@ -12,6 +12,7 @@ import { changeMaster } from "../../slices/localVariablesSlice";
import useMaster from "../../hooks/masterHook/useMaster"; import useMaster from "../../hooks/masterHook/useMaster";
import { useHasUserPermission } from "../../hooks/useHasUserPermission"; import { useHasUserPermission } from "../../hooks/useHasUserPermission";
import { ASSIGN_TO_PROJECT } from "../../utils/constants"; import { ASSIGN_TO_PROJECT } from "../../utils/constants";
import ConfirmModal from "../common/ConfirmModal";
const Teams = ({ project }) => { const Teams = ({ project }) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
@ -25,11 +26,13 @@ const Teams = ({ project }) => {
const [removingEmployeeId, setRemovingEmployeeId] = useState(null); const [removingEmployeeId, setRemovingEmployeeId] = useState(null);
const [assignedLoading, setAssignedLoading] = useState(false); const [assignedLoading, setAssignedLoading] = useState(false);
const [ employeeLodaing, setEmployeeLoading ] = useState( false ); const [ employeeLodaing, setEmployeeLoading ] = useState( false );
const [activeEmployee,setActiveEmployee] = useState(true) const [ activeEmployee, setActiveEmployee ] = useState( true )
const [deleteEmployee,setDeleteEmplyee] = useState(null)
const navigate = useNavigate(); const navigate = useNavigate();
const HasAssignUserPermission = useHasUserPermission(ASSIGN_TO_PROJECT); const HasAssignUserPermission = useHasUserPermission( ASSIGN_TO_PROJECT );
const[IsDeleteModal,setIsDeleteModal] = useState(false)
const fetchEmployees = async () => { const fetchEmployees = async () => {
try { try {
@ -39,7 +42,8 @@ const Teams = ({ project }) => {
ProjectRepository.getProjectAllocation(project.id) ProjectRepository.getProjectAllocation(project.id)
.then((response) => { .then((response) => {
setEmployees(response.data); setEmployees(response.data);
setFilteredEmployees(response.data.filter((emp) => emp.isActive)); setFilteredEmployees( response.data.filter( ( emp ) => emp.isActive ) );
console.log(response)
setEmployeeLoading(false); setEmployeeLoading(false);
}) })
.catch((error) => { .catch((error) => {
@ -52,16 +56,25 @@ const Teams = ({ project }) => {
} }
}; };
const submitAllocations = (items) => { const submitAllocations = (items,added) => {
ProjectRepository.manageProjectAllocation(items) ProjectRepository.manageProjectAllocation(items)
.then((response) => { .then((response) => {
showToast("Details updated successfully.", "success");
fetchEmployees(); fetchEmployees();
if ( added )
{
showToast("Employee Assigned Successfully", "success");
}else{
showToast("Removed Employee Successfully", "success");
}
setRemovingEmployeeId(null); setRemovingEmployeeId(null);
setAssignedLoading(false); setAssignedLoading( false );
setDeleteEmplyee( null )
closeDeleteModal()
}) })
.catch((error) => { .catch((error) => {
showToast(error.message, "error"); const message = error.response.data.message || error.message || "Error Occured during Api Call";
showToast( message, "error" );
closeDeleteModal()
}); });
}; };
@ -74,7 +87,8 @@ const Teams = ({ project }) => {
projectId: project.id, projectId: project.id,
status: false, status: false,
}, },
]); ] ,false);
}; };
const handleEmpAlicationFormSubmit = (allocaionObj) => { const handleEmpAlicationFormSubmit = (allocaionObj) => {
@ -87,7 +101,8 @@ const Teams = ({ project }) => {
}; };
}); });
submitAllocations(items); submitAllocations( items ,true);
}; };
const getRole = (jobRoleId) => { const getRole = (jobRoleId) => {
@ -140,6 +155,13 @@ const Teams = ({ project }) => {
} }
}; };
const deleteModalOpen = (item) =>
{
setDeleteEmplyee(item)
setIsDeleteModal(true)
}
const closeDeleteModal = ()=> setIsDeleteModal(false)
return ( return (
<> <>
<div <div
@ -160,6 +182,31 @@ const Teams = ({ project }) => {
></MapUsers> ></MapUsers>
</div> </div>
{IsDeleteModal && (
<div
className={`modal fade ${IsDeleteModal ? "show" : ""}`}
tabIndex="-1"
role="dialog"
style={{
display: IsDeleteModal ? "block" : "none",
backgroundColor: IsDeleteModal ? "rgba(0,0,0,0.5)" : "transparent",
}}
aria-hidden="false"
>
<ConfirmModal
type={"delete"}
header={"Removed Employee"}
message={"Are you sure you want delete?"}
onSubmit={removeAllocation}
onClose={closeDeleteModal}
loading={employeeLodaing}
paramData={deleteEmployee}
/>
</div>
)}
<div className="card card-action mb-6"> <div className="card card-action mb-6">
<div className="card-body"> <div className="card-body">
<div className="row"> <div className="row">
@ -259,7 +306,7 @@ const Teams = ({ project }) => {
type="button" type="button"
title="Remove from project" title="Remove from project"
className="btn p-0 dropdown-toggle hide-arrow" className="btn p-0 dropdown-toggle hide-arrow"
onClick={() => removeAllocation(item)} onClick={() => deleteModalOpen(item)}
> >
{" "} {" "}
{removingEmployeeId === item.id ? ( {removingEmployeeId === item.id ? (
@ -283,7 +330,7 @@ const Teams = ({ project }) => {
</tbody> </tbody>
</table> </table>
)} )}
{!employeeLodaing && employees.length == 0 && ( {(!employeeLodaing && employees.length == 0 )&& (
<span>No employees assigned to the project</span> <span>No employees assigned to the project</span>
)} )}
</div> </div>

View File

@ -1,6 +1,6 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
const ConfirmModal = ({ type, onSubmit, onClose, message, loading ,header}) => { const ConfirmModal = ({ type, onSubmit, onClose, message, loading ,header, paramData}) => {
const TypeofIcon = (type) => { const TypeofIcon = (type) => {
switch (type) { switch (type) {
@ -48,7 +48,7 @@ const ConfirmModal = ({ type, onSubmit, onClose, message, loading ,header}) => {
<div className='d-flex justify-content-end mt-4'> <div className='d-flex justify-content-end mt-4'>
<button <button
className='btn btn-primary btn-sm' className='btn btn-primary btn-sm'
onClick={onSubmit} onClick={()=>onSubmit(paramData)}
disabled={loading} disabled={loading}
> >
{loading ? "Please Wait..." : "Yes"} {loading ? "Please Wait..." : "Yes"}

View File

@ -21,6 +21,7 @@ import {
} from "../../utils/tableExportUtils"; } from "../../utils/tableExportUtils";
import EmployeeRepository from "../../repositories/EmployeeRepository"; import EmployeeRepository from "../../repositories/EmployeeRepository";
import ManageEmployee from "../../components/Employee/ManageEmployee"; import ManageEmployee from "../../components/Employee/ManageEmployee";
import ConfirmModal from "../../components/common/ConfirmModal";
const EmployeeList = () => { const EmployeeList = () => {
const { profile: loginUser } = useProfile(); const { profile: loginUser } = useProfile();
@ -42,7 +43,10 @@ const EmployeeList = () => {
const [searchText, setSearchText] = useState(""); const [searchText, setSearchText] = useState("");
const [filteredData, setFilteredData] = useState([]); const [filteredData, setFilteredData] = useState([]);
const [showModal, setShowModal] = useState(false); const [showModal, setShowModal] = useState(false);
const [selectedEmployeeId, setSelecedEmployeeId] = useState(); const [ selectedEmployeeId, setSelecedEmployeeId ] = useState();
const [ IsDeleteModalOpen, setIsDeleteModalOpen ] = useState( false )
const [ selectedEmpFordelete, setSelectedEmpFordelete ] = useState( null )
const[employeeLodaing,setemployeeLodaing] = useState(false)
const navigate = useNavigate(); const navigate = useNavigate();
@ -108,7 +112,7 @@ const EmployeeList = () => {
const handleClose = () => setShowModal(false); const handleClose = () => setShowModal(false);
const suspendEmployee = (id) => { const suspendEmployee = (id) => {
// console.log(id); setemployeeLodaing(true)
EmployeeRepository.deleteEmployee(id) EmployeeRepository.deleteEmployee(id)
.then((response) => { .then((response) => {
showToast("Employee deleted successfully.", "success"); showToast("Employee deleted successfully.", "success");
@ -117,14 +121,18 @@ const EmployeeList = () => {
clearCacheKey("allInactiveEmployeeList"); clearCacheKey("allInactiveEmployeeList");
clearCacheKey("employeeProfile"); clearCacheKey("employeeProfile");
setEmployeeList([]); setEmployeeList([]);
recallEmployeeData(showInactive); recallEmployeeData( showInactive );
setemployeeLodaing( false )
setIsDeleteModalOpen(false)
}) })
.catch((error) => { .catch((error) => {
const message = const message =
error.response?.data?.message || error.response?.data?.message ||
error.message || error.message ||
"An unexpected error occurred"; "An unexpected error occurred";
showToast(message, "error"); showToast( message, "error" );
setemployeeLodaing( false )
setIsDeleteModalOpen(false)
}); });
}; };
@ -170,6 +178,14 @@ const EmployeeList = () => {
setShowModal(true); setShowModal(true);
}; };
const handleOpenDelete = (employee) =>
{
console.log(employee)
setSelectedEmpFordelete( employee )
setIsDeleteModalOpen( true );
}
return ( return (
<> <>
{isCreateModalOpen && ( {isCreateModalOpen && (
@ -195,6 +211,31 @@ const EmployeeList = () => {
</div> </div>
</div> </div>
{IsDeleteModalOpen && (
<div
className={`modal fade ${IsDeleteModalOpen ? "show" : ""}`}
tabIndex="-1"
role="dialog"
style={{
display: IsDeleteModalOpen ? "block" : "none",
backgroundColor: IsDeleteModalOpen ? "rgba(0,0,0,0.5)" : "transparent",
}}
aria-hidden="false"
>
<ConfirmModal
type={"delete"}
header={"Suspend Employee"}
message={"Are you sure you want delete?"}
onSubmit={suspendEmployee}
onClose={()=>setIsDeleteModalOpen(false)}
loading={employeeLodaing}
paramData={selectedEmpFordelete}
/>
</div>
)}
<div className="container-xxl flex-grow-1 container-p-y"> <div className="container-xxl flex-grow-1 container-p-y">
<Breadcrumb <Breadcrumb
data={[ data={[
@ -375,7 +416,29 @@ const EmployeeList = () => {
aria-label="User: activate to sort column ascending" aria-label="User: activate to sort column ascending"
aria-sort="descending" aria-sort="descending"
> >
Name <div className="text-start ms-6">Name</div>
</th>
<th
className="sorting sorting_desc d-none d-sm-table-cell"
tabIndex="0"
aria-controls="DataTables_Table_0"
rowSpan="1"
colSpan="1"
aria-label="User: activate to sort column ascending"
aria-sort="descending"
>
<div className="text-start ms-5">Email</div>
</th>
<th
className="sorting sorting_desc d-none d-sm-table-cell"
tabIndex="0"
aria-controls="DataTables_Table_0"
rowSpan="1"
colSpan="1"
aria-label="User: activate to sort column ascending"
aria-sort="descending"
>
<div className="text-start ms-5">Contact</div>
</th> </th>
<th <th
className="sorting sorting_desc d-none d-sm-table-cell" className="sorting sorting_desc d-none d-sm-table-cell"
@ -386,29 +449,7 @@ const EmployeeList = () => {
aria-label="User: activate to sort column ascending" aria-label="User: activate to sort column ascending"
aria-sort="descending" aria-sort="descending"
> >
Email <div className="text-start ms-5">Role</div>
</th>
<th
className="sorting sorting_desc d-none d-sm-table-cell"
tabIndex="0"
aria-controls="DataTables_Table_0"
rowSpan="1"
colSpan="1"
aria-label="User: activate to sort column ascending"
aria-sort="descending"
>
Contact
</th>
<th
className="sorting sorting_desc d-none d-sm-table-cell"
tabIndex="0"
aria-controls="DataTables_Table_0"
rowSpan="1"
colSpan="1"
aria-label="User: activate to sort column ascending"
aria-sort="descending"
>
Role
</th> </th>
<th <th
@ -578,7 +619,7 @@ const EmployeeList = () => {
<> <>
<button <button
className="dropdown-item py-1" className="dropdown-item py-1"
onClick={() => suspendEmployee(item.id)} onClick={()=>handleOpenDelete(item.id)}
> >
<i className="bx bx-task-x bx-sm"></i>{" "} <i className="bx bx-task-x bx-sm"></i>{" "}
Suspend Suspend

View File

@ -72,8 +72,8 @@ const MasterTable = ({ data, columns, loading, handleModalData }) => {
<thead> <thead>
<tr> <tr>
<th></th> <th></th>
<th> {selectedMaster === "Activity" ? "Activity" : "Name"}</th> <th className="text-start"> {selectedMaster === "Activity" ? "Activity" : "Name"}</th>
<th> {selectedMaster === "Activity" ? "Unit" : "Description"}</th> <th className="text-start"> {selectedMaster === "Activity" ? "Unit" : "Description"}</th>
<th className={` ${!hasMasterPermission && "d-none"}`}> <th className={` ${!hasMasterPermission && "d-none"}`}>
Actions Actions
</th> </th>

View File

@ -266,7 +266,7 @@ const ProjectList = () => {
<th className="text-start" colSpan={5}> <th className="text-start" colSpan={5}>
Project Name Project Name
</th> </th>
<th className="mx-2">Project Manger</th> <th className="mx-2 text-start">Project Manger</th>
<th className="mx-2">START DATE</th> <th className="mx-2">START DATE</th>
<th className="mx-2">DEADLINE</th> <th className="mx-2">DEADLINE</th>
<th className="mx-2">Task</th> <th className="mx-2">Task</th>