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

This commit is contained in:
Pramod Mahajan 2025-04-08 16:00:11 +05:30
commit 9c0f98dbaf
7 changed files with 212 additions and 218 deletions

View File

@ -29,7 +29,7 @@ const InfraPlanning = () =>
useEffect( () => useEffect( () =>
{ {
dispatch(setProjectId(projects[0]?.id)) dispatch(setProjectId(projects[0]?.id))
}) },[projects])
return ( return (
<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">
@ -49,7 +49,7 @@ const InfraPlanning = () =>
{!project_listLoader && projects?.filter(project => {!project_listLoader && projects?.filter(project =>
LoggedUser?.projects?.map(Number).includes(project.id)).map((project)=>( LoggedUser?.projects?.map(Number).includes(project.id)).map((project)=>(
<option value={project.id}>{project.name}</option> <option key={project.id} value={project.id}>{project.name}</option>
))} ))}
</select> </select>
</div> </div>

View File

@ -26,7 +26,7 @@ const TaskModel = ({
activities, activities,
onSubmit, onSubmit,
clearTrigger, clearTrigger,
onClearComplete, onClearComplete,onClose
}) => { }) => {
const [formData, setFormData] = useState(defaultModel); const [formData, setFormData] = useState(defaultModel);
const [selectedBuilding, setSelectedBuilding] = useState(null); const [selectedBuilding, setSelectedBuilding] = useState(null);
@ -124,12 +124,7 @@ const TaskModel = ({
<div className="modal-content"> <div className="modal-content">
<div className="modal-body"> <div className="modal-body">
<div className="row"> <div className="row">
<button <button type="button" className="btn-close" aria-label="Close" onClick={onClose}/>
type="button"
className="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
<div className="text-center mb-1"> <div className="text-center mb-1">
<h5 className="mb-1">Manage Task</h5> <h5 className="mb-1">Manage Task</h5>
</div> </div>
@ -290,10 +285,9 @@ const TaskModel = ({
{formData.id !== "0" && formData.id !== "" ? "Edit Task" : "Add Task"} {formData.id !== "0" && formData.id !== "" ? "Edit Task" : "Add Task"}
</button> </button>
<button <button
type="reset" type="button"
className="btn btn-sm btn-label-secondary" className="btn btn-sm btn-label-secondary"
data-bs-dismiss="modal" onClick={onClose}
aria-label="Close"
> >
Cancel Cancel
</button> </button>

View File

@ -19,7 +19,7 @@ const defaultModel = {
floorId: "0", floorId: "0",
}; };
const WorkAreaModel = ({ project, onSubmit, clearTrigger, onClearComplete }) => { const WorkAreaModel = ({ project, onSubmit, clearTrigger, onClearComplete, onClose }) => {
const [selectedBuilding, setSelectedBuilding] = useState(null); const [selectedBuilding, setSelectedBuilding] = useState(null);
const [ selectedFloor, setSelectedFloor ] = useState( null ); const [ selectedFloor, setSelectedFloor ] = useState( null );
const [selectdWorkArea,setWorkArea] = useState() const [selectdWorkArea,setWorkArea] = useState()
@ -111,7 +111,7 @@ const WorkAreaModel = ({ project, onSubmit, clearTrigger, onClearComplete }) =>
<div className="modal-content"> <div className="modal-content">
<div className="modal-body"> <div className="modal-body">
<div className="row"> <div className="row">
<button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> <button type="button" className="btn-close" aria-label="Close" onClick={onClose}/>
<div className="text-center mb-1"> <div className="text-center mb-1">
<h5 className="mb-1">Manage Work Area</h5> <h5 className="mb-1">Manage Work Area</h5>
</div> </div>

View File

@ -44,14 +44,14 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
}; };
const closeFloorModel = () => { const closeFloorModel = () => {
setIsFloorModalOpen(false); setIsFloorModalOpen(false);
}; };
const openAssignModel=(assignData)=>{ const openAssignModel=(assignData)=>{
setCurrentBuilding(assignData) setCurrentBuilding(assignData)
setIsAssingRoleModal(true) setIsAssingRoleModal(true)
} }
@ -60,134 +60,134 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
const openBuildingModel = (projectData) => { const openBuildingModel = (projectData) => {
setIsBuildingModalOpen(true); setIsBuildingModalOpen(true);
}; };
const submitData = async (infraObject) => { const submitData = async (infraObject) => {
try try
{ {
console.log(infraObject) console.log(infraObject)
let response = await ProjectRepository.manageProjectInfra( infraObject ); let response = await ProjectRepository.manageProjectInfra( infraObject );
const entity = response.data; const entity = response.data;
const updatedProject = { ...project }; const updatedProject = { ...project };
// Handle the building data // Handle the building data
if (entity.building) { if (entity.building) {
const { id, name, description } = entity.building; const { id, name, description } = entity.building;
const updatedBuildings = updatedProject.buildings.map((building) => const updatedBuildings = updatedProject.buildings.map((building) =>
building.id === id building.id === id
? { ...building, name, description } ? { ...building, name, description }
: building : building
); );
// Add building if it doesn't exist // Add building if it doesn't exist
if (!updatedProject.buildings.some((building) => building.id === id)) { if (!updatedProject.buildings.some((building) => building.id === id)) {
updatedBuildings.push({ updatedBuildings.push({
id: id, id: id,
name, name,
description, description,
floor: [], floor: [],
}); });
} }
updatedProject.buildings = updatedBuildings; updatedProject.buildings = updatedBuildings;
// Update the cache for buildings // Update the cache for buildings
cacheData( "projectInfo", {projectId: updatedProject.id, data: updatedProject} ); cacheData( "projectInfo", {projectId: updatedProject.id, data: updatedProject} );
setProject(updatedProject) setProject(updatedProject)
} }
// Handle the floor data // Handle the floor data
else if ( entity.floor ) else if ( entity.floor )
{ {
const { buildingId, id, floorName } = entity.floor; const { buildingId, id, floorName } = entity.floor;
const updatedBuildings = updatedProject.buildings.map((building) => const updatedBuildings = updatedProject.buildings.map((building) =>
building.id == buildingId building.id == buildingId
? { ? {
...building, ...building,
floors: building.floors.map( ( floor ) => floors: building.floors.map( ( floor ) =>
floor.id === id floor.id === id
? { ? {
...floor, ...floor,
floorName, // Update the floor name only floorName, // Update the floor name only
// Keep other properties as they are (including workArea) // Keep other properties as they are (including workArea)
} }
: floor : floor
) )
// Add the new floor if it doesn't already exist // Add the new floor if it doesn't already exist
.concat( .concat(
!building.floors.some((floor) => floor.id === id) !building.floors.some((floor) => floor.id === id)
? [{ id: id, floorName, workArea: null }] // New floor added with workArea set to null ? [{ id: id, floorName, workArea: null }] // New floor added with workArea set to null
: [] : []
), ),
} }
: building : building
); );
updatedProject.buildings = updatedBuildings; updatedProject.buildings = updatedBuildings;
// Cache the updated project // Cache the updated project
cacheData( "projectInfo", {projectId: updatedProject.id, data: updatedProject} ); cacheData( "projectInfo", {projectId: updatedProject.id, data: updatedProject} );
setProject(updatedProject) setProject(updatedProject)
} }
// Handle the work area data // Handle the work area data
else if ( entity.workArea ) else if ( entity.workArea )
{ {
let buildingId = infraObject[0].workArea.buildingId
const { floorId, areaName, id } = entity.workArea; let buildingId = infraObject[0].workArea.buildingId
// Check if the workArea exists, otherwise create a new one
const updatedBuildings = updatedProject.buildings.map((building) => const { floorId, areaName, id } = entity.workArea;
// Check if the workArea exists, otherwise create a new one
const updatedBuildings = updatedProject.buildings.map((building) =>
building.id == buildingId building.id == buildingId
? { ? {
...building, ...building,
floors: building.floors.map((floor) => floors: building.floors.map((floor) =>
floor.id == floorId floor.id == floorId
? { ? {
...floor, ...floor,
workAreas: floor.workAreas.some((workArea) => workArea.id === id) workAreas: floor.workAreas.some((workArea) => workArea.id === id)
? floor.workAreas.map((workArea) => ? floor.workAreas.map((workArea) =>
workArea.id === id workArea.id === id
? { ...workArea, areaName } ? { ...workArea, areaName }
: workArea : workArea
) )
: [ : [
...floor.workAreas, ...floor.workAreas,
{ id, areaName, workItems: null }, { id, areaName, workItems: null },
], ],
} }
: floor : floor
), ),
} }
: building : building
); );
updatedProject.buildings = updatedBuildings; updatedProject.buildings = updatedBuildings;
// Update the cache for work areas // Update the cache for work areas
cacheData( "projectInfo", {projectId: updatedProject.id, data: updatedProject} ); cacheData( "projectInfo", {projectId: updatedProject.id, data: updatedProject} );
setProject(updatedProject) setProject(updatedProject)
} }
// Handle the task (workItem) data // Handle the task (workItem) data
else { else {
console.error("Unsupported data type for submitData", entity); console.error("Unsupported data type for submitData", entity);
} }
} catch ( Err ) } catch ( Err )
{ {
showToast("Somthing wrong","error") showToast("Somthing wrong","error")
} }
handleClose() handleClose()
}; };
const closeBuildingModel = () => { const closeBuildingModel = () => {
setIsBuildingModalOpen(false); setIsBuildingModalOpen(false);
}; };
@ -256,37 +256,37 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
showToast("Details updated successfully.", "success"); showToast("Details updated successfully.", "success");
// setClearFormTrigger( true ); // setClearFormTrigger( true );
if (response?.data[0]) { if (response?.data[0]) {
const { workItemId,workItem} = response.data[0]; const { workItemId,workItem} = response.data[0];
const updatedBuildings = updatedProject.buildings.map((building) => const updatedBuildings = updatedProject.buildings.map((building) =>
building.id == updatedModel.buildingID building.id == updatedModel.buildingID
? { ? {
...building, ...building,
floors: building.floors.map((floor) => floors: building.floors.map((floor) =>
floor.id == updatedModel.floorId floor.id == updatedModel.floorId
? { ? {
...floor, ...floor,
workAreas: floor.workAreas.map((workArea) => workAreas: floor.workAreas.map((workArea) =>
workArea.id === workItem?.workAreaId workArea.id === workItem?.workAreaId
? { ? {
...workArea, ...workArea,
workItems: workArea.workItems.some((existingItem) => existingItem.workItemId === workItem.workItemId) workItems: workArea.workItems.some((existingItem) => existingItem.workItemId === workItem.workItemId)
? workArea.workItems // If the workItemId already exists, keep the current workItems ? workArea.workItems // If the workItemId already exists, keep the current workItems
: [...workArea.workItems, workItem], : [...workArea.workItems, workItem],
} }
: workArea : workArea
), ),
} }
: floor : floor
), ),
} }
: building : building
); );
updatedProject.buildings = updatedBuildings; updatedProject.buildings = updatedBuildings;
cacheData( "projectInfo", {projectId: updatedProject.id, data: updatedProject} ); cacheData( "projectInfo", {projectId: updatedProject.id, data: updatedProject} );
setProject(updatedProject) setProject(updatedProject)
} }
@ -320,18 +320,18 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
modal.show() modal.show()
}; };
const closeModal = () => { const closeModal = () => {
setIsModalOpen(false); setIsModalOpen(false);
setModalConfig(null) setModalConfig(null)
const modalElement = document.getElementById('building-model'); const modalElement = document.getElementById('building-model');
if (modalElement) { if (modalElement) {
modalElement.classList.remove('show'); // Remove modal visibility class modalElement.classList.remove('show'); // Remove modal visibility class
modalElement.style.display = 'none'; // Hide the modal element modalElement.style.display = 'none'; // Hide the modal element
} }
document.body.classList.remove('modal-open'); // Remove modal-open class from body document.body.classList.remove('modal-open'); // Remove modal-open class from body
// Remove the modal backdrop // Remove the modal backdrop
const backdropElement = document.querySelector('.modal-backdrop'); const backdropElement = document.querySelector('.modal-backdrop');
if (backdropElement) { if (backdropElement) {
@ -339,7 +339,7 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
backdropElement.style.display = 'none'; // Hide the backdrop element backdropElement.style.display = 'none'; // Hide the backdrop element
} }
document.body.style.overflow = 'auto'; document.body.style.overflow = 'auto';
}; };
const handleShow = () => setShowModal(true); const handleShow = () => setShowModal(true);
@ -347,21 +347,21 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
return ( return (
<> <>
<div <div
className={`modal fade ${showModal ? 'show' : ''}`} className={`modal fade ${showModal ? 'show' : ''}`}
tabIndex="-1" tabIndex="-1"
role="dialog" role="dialog"
style={{ display: showModal ? 'block' : 'none' }} style={{ display: showModal ? 'block' : 'none' }}
aria-hidden={!showModal} aria-hidden={!showModal}
> >
<BuildingModel <BuildingModel
project={data} project={data}
onClose={handleClose} onClose={handleClose}
onSubmit={handleBuildingModelFormSubmit} onSubmit={handleBuildingModelFormSubmit}
clearTrigger={clearFormTrigger} clearTrigger={clearFormTrigger}
onClearComplete={() => setClearFormTrigger(false)} onClearComplete={() => setClearFormTrigger(false)}
></BuildingModel> ></BuildingModel>
</div> </div>
{isFloorModalOpen && ( {isFloorModalOpen && (
<div <div
className="modal fade show" className="modal fade show"
@ -383,10 +383,12 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
{isWorkAreaModelOpen && ( {isWorkAreaModelOpen && (
<div <div
className={`modal fade `} className="modal fade show"
id="work-area-model" id="work-area-model"
tabIndex="-1" tabIndex="-1"
aria-hidden="true" role="dialog"
style={{ display: 'block' }}
aria-hidden="false"
> >
<WorkAreaModel <WorkAreaModel
project={data} project={data}
@ -395,16 +397,18 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
onSubmit={handleWorkAreaModelFormSubmit} onSubmit={handleWorkAreaModelFormSubmit}
clearTrigger={clearFormTrigger} clearTrigger={clearFormTrigger}
onClearComplete={() => setClearFormTrigger(false)} onClearComplete={() => setClearFormTrigger(false)}
></WorkAreaModel> />
</div> </div>
)} )}
{isTaskModelOpen && ( {isTaskModelOpen && (
<div <div
className={`modal fade `} className="modal fade show"
id="task-model" id="task-model"
tabIndex="-1" tabIndex="-1"
aria-hidden="true" role="dialog"
style={{ display: 'block' }}
aria-hidden="false"
> >
<TaskModel <TaskModel
project={data} project={data}
@ -413,11 +417,11 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
onSubmit={handleTaskModelFormSubmit} onSubmit={handleTaskModelFormSubmit}
clearTrigger={clearFormTrigger} clearTrigger={clearFormTrigger}
onClearComplete={() => setClearFormTrigger(false)} onClearComplete={() => setClearFormTrigger(false)}
></TaskModel> />
</div> </div>
)} )}
{isModalOpen && ( {isModalOpen && (
<ProjectModal modalConfig={modalConfig} closeModal={closeModal} /> <ProjectModal modalConfig={modalConfig} closeModal={closeModal} />
)} )}
@ -432,27 +436,25 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
<button <button
type="button" type="button"
className="link-button link-button-sm m-1 " className="link-button link-button-sm m-1 "
onClick={handleShow} onClick={handleShow}
> >
<i className="bx bx-plus-circle me-2"></i> <i className="bx bx-plus-circle me-2"></i>
Manage Building Manage Building
</button> </button>
<button <button
type="button" type="button"
className="link-button m-1" className="link-button m-1"
onClick={() => openFloorModel()} onClick={() => openFloorModel()}
> >
<i className="bx bx-plus-circle me-2"></i> <i className="bx bx-plus-circle me-2"></i>
Manage Floors Manage Floors
</button> </button>
<button <button
type="button" type="button"
data-bs-toggle="modal"
className="link-button m-1" className="link-button m-1"
data-bs-target="#work-area-model"
onClick={() => openWorkAreaModel()} onClick={() => openWorkAreaModel()}
> >
<i className="bx bx-plus-circle me-2"></i> <i className="bx bx-plus-circle me-2"></i>
@ -460,9 +462,7 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
</button> </button>
<button <button
type="button" type="button"
data-bs-toggle="modal"
className="link-button m-1" className="link-button m-1"
data-bs-target="#task-model"
onClick={() => openTaskModel()} onClick={() => openTaskModel()}
> >
<i className="bx bx-plus-circle me-2"></i> <i className="bx bx-plus-circle me-2"></i>

View File

@ -4,6 +4,7 @@ import {
getCachedData, getCachedData,
} from "../slices/apiDataManager" } from "../slices/apiDataManager"
import ProjectRepository from "../repositories/ProjectRepository"; import ProjectRepository from "../repositories/ProjectRepository";
import { useProfile } from "./useProfile";
@ -84,7 +85,7 @@ export const useEmployeesByProjectAllocated = ( selectedProject ) =>
} }
export const useProjectDetails =(projectId)=>{ export const useProjectDetails =(projectId)=>{
const {profile} = useProfile();
const [projects_Details, setProject_Details] = useState(null); const [projects_Details, setProject_Details] = useState(null);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [error, setError] = useState(""); const [error, setError] = useState("");
@ -113,11 +114,11 @@ export const useProjectDetails =(projectId)=>{
}; };
useEffect(()=>{ useEffect(()=>{
if ( projectId ) if ( profile && (projectId != undefined) )
{ {
fetchData() fetchData()
} }
},[projectId]) },[projectId,profile])
return { projects_Details,loading,error,refetch:fetchData} return { projects_Details,loading,error,refetch:fetchData}

View File

@ -6,10 +6,19 @@ import ProjectRepository from "../../repositories/ProjectRepository";
import Breadcrumb from "../../components/common/Breadcrumb"; import Breadcrumb from "../../components/common/Breadcrumb";
import InfraPlanning from "../../components/Activities/InfraPlanning"; import InfraPlanning from "../../components/Activities/InfraPlanning";
import { cacheData, getCachedData } from "../../slices/apiDataManager"; import { cacheData, getCachedData } from "../../slices/apiDataManager";
import { useProfile } from "../../hooks/useProfile";
import { useDispatch, useSelector } from "react-redux";
import { useProjectDetails, useProjects } from "../../hooks/useProjects";
import { setProjectId } from "../../slices/localVariablesSlice";
var projectId; var projectId;
const TaskPlannng = () => { const TaskPlannng = () => {
const {profile} = useProfile();
const {projects,loading:project_listLoader,error:projects_error} = useProjects();
const dispatch = useDispatch();
const selectedProject = useSelector((store)=>store.localVariables.projectId);
const [project, setProject] = useState(null); const [project, setProject] = useState(null);
const [projectDetails, setProjectDetails] = useState(null); const [projectDetails, setProjectDetails] = useState(null);
@ -17,6 +26,10 @@ const TaskPlannng = () => {
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [error, setError] = useState(""); const [error, setError] = useState("");
useEffect( () =>
{
dispatch(setProjectId(projects[0]?.id))
},[projects])
const fetchActivities = async () => { const fetchActivities = async () => {
try { try {
@ -43,9 +56,9 @@ const TaskPlannng = () => {
const fetchData = async () => { const fetchData = async () => {
try { try {
const project_cache = getCachedData(`projectinfo-${1}`); const project_cache = getCachedData(`projectinfo-${selectedProject}`);
if (!project_cache) { if (!project_cache) {
ProjectRepository.getProjectByprojectId(1) ProjectRepository.getProjectByprojectId(selectedProject)
.then((response) => { .then((response) => {
setProjectDetails(response); setProjectDetails(response);
setProject(response); setProject(response);
@ -73,14 +86,16 @@ const TaskPlannng = () => {
}; };
const handleDataChange = (data) => { const handleDataChange = (data) => {
console.log("datachange")
fetchData(); fetchData();
}; };
useEffect(() => { useEffect(() => {
projectId =1 if((projects.length != 0)){
fetchData(); fetchData();
fetchActivities(); fetchActivities();
}, []); }
}, [selectedProject]);
return ( return (

View File

@ -325,7 +325,7 @@ const EmployeeList = () =>
<p>Loading...</p> <p>Loading...</p>
</td> </td>
</tr>} </tr>}
{( !loading && employeeList?.length === 0 ) && <td colSpan={8}>Not Data Found </td>} {!loading && employeeList?.length === 0 && (<td colSpan={8} style={{ paddingTop: '20px', textAlign: 'center' }}>No Data Found</td> )}
{( !loading && employeeList && currentItems.length === 0 && employeeList.length !==0 ) && <td colSpan={8}><small className="muted">'{searchText}' employee not found</small> </td>} {( !loading && employeeList && currentItems.length === 0 && employeeList.length !==0 ) && <td colSpan={8}><small className="muted">'{searchText}' employee not found</small> </td>}
{(currentItems && !loading) && currentItems.sort((a, b) => b.id - a.id).map((item) => ( {(currentItems && !loading) && currentItems.sort((a, b) => b.id - a.id).map((item) => (
@ -372,49 +372,33 @@ const EmployeeList = () =>
Active Active
</span> </span>
</td> </td>
<td className={`d-flex justify-content-end justify-content-sm-center ${!ManageEmployee && 'd-none'} `}> {ManageEmployee && (
<div className="d-flex align-items-center "> <td className="text-end">
<a <div className="dropdown">
className={`btn btn-icon dropdown-toggle hide-arrow`} <button className="btn btn-icon dropdown-toggle hide-arrow" data-bs-toggle="dropdown">
data-bs-toggle="dropdown" <i className="bx bx-dots-vertical-rounded bx-md"></i>
> </button>
<i className="bx bx-dots-vertical-rounded bx-md"></i> <div className="dropdown-menu dropdown-menu-end">
</a> <button onClick={() => navigate(`/employee/${item.id}`)} className="dropdown-item">
View
<div className="dropdown-menu dropdown-menu-end m-0"> </button>
{" "} <Link to={`/employee/manage/${item.id}`} className="dropdown-item">
<a Edit
</Link>
onClick={()=> navigate(`/employee/${item.id}`)} <button className="dropdown-item">Suspend</button>
className="dropdown-item" <button
> className="dropdown-item"
View type="button"
</a> data-bs-toggle="modal"
data-bs-target="#managerole-modal"
<Link onClick={() => handleConfigData(item.id)}
className={`dropdown-item `} >
to={`/employee/manage/${item.id}`} Manage Role
> </button>
Edit </div>
</Link>
<a className="dropdown-item">
Suspend
</a>
<a
className="dropdown-item"
type="button"
data-bs-toggle="modal"
data-bs-target="#managerole-modal"
onClick={() => {
handleConfigData(item.id);
}}
>
Manage Role
</a>
</div> </div>
</div> </td>
</td> )}
</tr> </tr>
) )} ) )}