updated project-infra-each modelForm able to taking recently added item

This commit is contained in:
Pramod Mahajan 2025-04-10 02:07:47 +05:30
parent 67a3648227
commit c45130b611
10 changed files with 201 additions and 216 deletions

View File

@ -34,7 +34,7 @@ const BuildingModel = ({
id: "",
name: "",
description: "",
projectId: project.id,
projectId: project?.id,
});
useEffect(() => {
@ -48,7 +48,7 @@ const BuildingModel = ({
return () => {
setValue("name", null);
};
}, [clearTrigger, onClearComplete, editingBuilding, project.id]);
}, [clearTrigger, onClearComplete, editingBuilding, project?.id]);
const {
register,
@ -101,7 +101,7 @@ const BuildingModel = ({
onClick={onClose}
></button>
<h5 className="text-center mb-2">
Manage Buildings - {project.name}
Manage Buildings - {project?.name}
</h5>
<form onSubmit={handleSubmit(onSubmitHandler)} className="row g-2">
<div className="col-12">
@ -116,9 +116,9 @@ const BuildingModel = ({
<option value="0">Add New Building</option>
{buildings &&
buildings?.length > 0 &&
buildings.map((building) => (
{project &&
project?.buildings?.length > 0 &&
project?.buildings.map((building) => (
<option key={building.id} value={building.id}>
{building.name}
</option>

View File

@ -26,10 +26,10 @@ const FloorModel = ({
onClearComplete,
} ) =>
{
const [ buildings, setBuildings ] = useState( [] )
const projects_Details = getCachedData( "projectInfo" )
const [formData, setFormData] = useState(defaultModel);
const [selectedBuilding, setSelectedBuilding] = useState({});
const [ selectedBuilding, setSelectedBuilding ] = useState( {} );
const [buildings, setBuildings] = useState(project?.buildings || []);
// Initialize the form with React Hook Form
const {
@ -56,6 +56,7 @@ const FloorModel = ({
// Handle building selection change
const handleBuildigChange = (e) => {
const buildingId = e.target.value;
console.log(buildingId)
const building = buildings.find((b) => b.id === Number(buildingId));
if (building) {
setSelectedBuilding(building);
@ -84,7 +85,7 @@ const FloorModel = ({
// Handle floor selection change
const handleFloorChange = (e) => {
const id = e.target.value;
const floor = buildings[getValues("buildingId")].floors.find((b) => b.id === Number(id));
const floor = selectedBuilding.floors.find((b) => b.id === Number(id));
if (floor) {
setFormData({
id: floor.id,
@ -108,12 +109,8 @@ const FloorModel = ({
const onFormSubmit = (data) => {
onSubmit(data);
};
useEffect( () =>
{
setBuildings(projects_Details.data?.buildings)
}, [ projects_Details ] )
console.log(getValues("buildingId"))
console.log(buildings)
return (
<div className="modal-dialog modal-lg modal-simple modal-edit-user">
@ -172,9 +169,9 @@ const FloorModel = ({
</option>
) )} */}
{buildings &&
buildings[getValues("buildingId")]?.length > 0 &&
buildings[getValues("buildingId")]?.map((floor) => (
{selectedBuilding &&
selectedBuilding?.floors.length > 0 &&
selectedBuilding?.floors.map((floor) => (
<option key={floor.id} value={floor.id}>
{floor.floorName}
</option>

View File

@ -82,7 +82,7 @@ const WorkAreaModel = ({ project, onSubmit, clearTrigger, onClearComplete, onClo
const handleBuildingChange = (e) => {
const { value } = e.target;
const building = project.buildings.find((b) => b.id === Number(value));
const building = project?.buildings.find((b) => b.id === Number(value));
setSelectedBuilding(building);
setSelectedFloor(null); // Reset selected floor on building change
reset(defaultModel); // Reset the form when a new building is selected
@ -90,7 +90,7 @@ const WorkAreaModel = ({ project, onSubmit, clearTrigger, onClearComplete, onClo
const onSubmitForm = ( data ) =>
{
console.log(data)
let WorkArea = {
id: data.id,
areaName: data.areaName,
@ -103,7 +103,8 @@ const WorkAreaModel = ({ project, onSubmit, clearTrigger, onClearComplete, onClo
const handleCancel = () => {
reset(defaultModel); // Reset the form to initial state
setSelectedFloor(null);
setSelectedBuilding(null);
setSelectedBuilding( null );
onClose()
};
return (
@ -127,7 +128,7 @@ const WorkAreaModel = ({ project, onSubmit, clearTrigger, onClearComplete, onClo
onChange={handleBuildingChange}
>
<option value="0">Select Building</option>
{project.buildings.map((building) => (
{project?.buildings?.map((building) => (
<option key={building.id} value={building.id}>
{building.name}
</option>
@ -171,7 +172,7 @@ const WorkAreaModel = ({ project, onSubmit, clearTrigger, onClearComplete, onClo
onChange={handleWorkAreaChange}
>
<option value="0">Create New Work Area</option>
{selectedFloor?.workAreas.map((workArea) => (
{selectedFloor?.workAreas?.map((workArea) => (
<option key={workArea.id} value={workArea.id}>
{workArea.areaName}
</option>

View File

@ -20,12 +20,7 @@ const WorkItem = ({ workItem, forBuilding, forFloor, forWorkArea }) => {
setItemName("");
};
// const showCreateItemModal = (modalData) => {
// openModal(
// <AssignRoleModel assignData={modalData} onClose={closedModal} />,
// handleAssignTask ,"lg"
// );
// };
useEffect(() => {
setNewWorkItem(workItem);

View File

@ -5,80 +5,69 @@ import FloorModel from "./Infrastructure/FloorModel";
import showToast from "../../services/toastService";
import WorkAreaModel from "./Infrastructure/WorkAreaModel";
import TaskModel from "./Infrastructure/TaskModel";
import ProjectRepository, {TasksRepository} from "../../repositories/ProjectRepository";
import ProjectRepository, {
TasksRepository,
} from "../../repositories/ProjectRepository";
import ProjectModal from "./ProjectModal";
import {useHasUserPermission} from "../../hooks/useHasUserPermission";
import {MANAGE_PROJECT_INFRA} from "../../utils/constants";
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
import { MANAGE_PROJECT_INFRA } from "../../utils/constants";
import InfraTable from "./Infrastructure/InfraTable";
import {cacheData} from "../../slices/apiDataManager";
import { cacheData, getCachedData } from "../../slices/apiDataManager";
import { useProjectDetails } from "../../hooks/useProjects";
const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) => {
const ProjectInfra = ({
data,
activityMaster,
onDataChange,
eachSiteEngineer,
}) => {
const [expandedBuildings, setExpandedBuildings] = useState([]);
const [project, setProject] = useState(data);
const[modalConfig,setModalConfig] = useState({type:null,data:null});
const [ isModalOpen, setIsModalOpen ] = useState( false )
const ManageInfra = useHasUserPermission(MANAGE_PROJECT_INFRA)
const { projects_Details, loading } = useProjectDetails(data.id);
const [project, setProject] = useState(projects_Details);
const [modalConfig, setModalConfig] = useState({ type: null, data: null });
const [isModalOpen, setIsModalOpen] = useState(false);
const ManageInfra = useHasUserPermission(MANAGE_PROJECT_INFRA);
const [buildings, setBuildings] = useState(data.buildings);
const [isBuildingModalOpen, setIsBuildingModalOpen] = useState(false);
const [isFloorModalOpen, setIsFloorModalOpen] = useState(false);
const [isWorkAreaModelOpen, setIsWorkAreaModalOpen] = useState(false);
const [isTaskModelOpen, setIsTaskModalOpen] = useState(false);
const [isAssignRoleModal,setIsAssingRoleModal] = useState(false)
const [isAssignRoleModal, setIsAssingRoleModal] = useState(false);
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
const [clearFormTrigger, setClearFormTrigger] = useState(false);
const [ CurrentBuilding, setCurrentBuilding ] = useState( "" )
const [CurrentBuilding, setCurrentBuilding] = useState("");
const [showModal, setShowModal] = useState(false);
useEffect(() => {
setProject(data);
setBuildings(data.buildings);
}, [data]);
setProject(projects_Details);
}, [data, projects_Details]);
const openFloorModel = (projectData) => {
setIsFloorModalOpen(true);
};
const closeFloorModel = () => {
setIsFloorModalOpen(false);
};
const openAssignModel=(assignData)=>{
setCurrentBuilding(assignData)
setIsAssingRoleModal(true)
}
const openAssignModel = (assignData) => {
setCurrentBuilding(assignData);
setIsAssingRoleModal(true);
};
const openBuildingModel = (projectData) => {
setIsBuildingModalOpen(true);
};
const submitData = async (infraObject) => {
try
{
console.log(infraObject)
let response = await ProjectRepository.manageProjectInfra( infraObject );
try {
let response = await ProjectRepository.manageProjectInfra(infraObject);
const entity = response.data;
const updatedProject = { ...project };
// Handle the building data
if (entity.building) {
const { id, name, description } = entity.building;
const updatedBuildings = updatedProject.buildings.map((building) =>
building.id === id
? { ...building, name, description }
: building
const updatedBuildings = updatedProject?.buildings?.map((building) =>
building.id === id ? { ...building, name, description } : building
);
// Add building if it doesn't exist
@ -87,107 +76,111 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
id: id,
name,
description,
floor: [],
floors: [],
});
}
updatedProject.buildings = updatedBuildings;
// Update the cache for buildings
cacheData( "projectInfo", {projectId: updatedProject.id, data: updatedProject} );
setProject(updatedProject)
cacheData("projectInfo", {
projectId: updatedProject.id,
data: updatedProject,
});
setProject((prevProject) => ({
...prevProject,
buildings: updatedBuildings,
}));
}
// Handle the floor data
else if ( entity.floor )
{
else if (entity.floor) {
const { buildingId, id, floorName } = entity.floor;
const updatedBuildings = updatedProject.buildings.map((building) =>
const updatedBuildings = updatedProject?.buildings?.map((building) =>
building.id == buildingId
? {
...building,
floors: building.floors.map( ( floor ) =>
floor.id === id
? {
...floor,
floorName, // Update the floor name only
// Keep other properties as they are (including workArea)
}
: floor
)
// Add the new floor if it doesn't already exist
.concat(
!building.floors.some((floor) => floor.id === id)
? [{ id: id, floorName, workArea: null }] // New floor added with workArea set to null
: []
),
}
...building,
floors: building.floors
.map((floor) =>
floor.id === id
? {
...floor,
floorName, // Update the floor name only
// Keep other properties as they are (including workArea)
}
: floor
)
// Add the new floor if it doesn't already exist
.concat(
!building.floors.some((floor) => floor.id === id)
? [{ id: id, floorName, workAreas: [] }] // New floor added with workArea set to null
: []
),
}
: building
);
updatedProject.buildings = updatedBuildings;
// Cache the updated project
cacheData( "projectInfo", {projectId: updatedProject.id, data: updatedProject} );
setProject(updatedProject)
cacheData("projectInfo", {
projectId: updatedProject.id,
data: updatedProject,
});
setProject(updatedProject);
}
// Handle the work area data
else if ( entity.workArea )
{
let buildingId = infraObject[0].workArea.buildingId
else if (entity.workArea) {
let buildingId = infraObject[0].workArea.buildingId;
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,
floors: building.floors.map((floor) =>
floor.id == floorId
? {
...floor,
workAreas: floor.workAreas.some((workArea) => workArea.id === id)
? floor.workAreas.map((workArea) =>
workArea.id === id
? { ...workArea, areaName }
: workArea
)
: [
...floor.workAreas,
{ id, areaName, workItems: null },
],
}
: floor
),
}
...building,
floors: building.floors.map((floor) =>
floor.id == floorId
? {
...floor,
workAreas: floor.workAreas.some(
(workArea) => workArea.id === id
)
? floor.workAreas.map((workArea) =>
workArea.id === id
? { ...workArea, areaName }
: workArea
)
: [
...floor.workAreas,
{ id, areaName, workItems: [] },
],
}
: floor
),
}
: building
);
updatedProject.buildings = updatedBuildings;
// Update the cache for work areas
cacheData( "projectInfo", {projectId: updatedProject.id, data: updatedProject} );
setProject(updatedProject)
cacheData("projectInfo", {
projectId: updatedProject.id,
data: updatedProject,
});
setProject(updatedProject);
}
// Handle the task (workItem) data
else {
console.error("Unsupported data type for submitData", entity);
}
} catch ( Err )
{
showToast("Somthing wrong","error")
} catch (Err) {
console.log(Err);
showToast("Somthing wrong", "error");
}
handleClose()
handleClose();
};
const closeBuildingModel = () => {
setIsBuildingModalOpen(false);
};
@ -206,7 +199,6 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
};
const handleFloorModelFormSubmit = (updatedFloor) => {
if (updatedFloor.id == "") delete updatedFloor.id;
submitData([
{
building: null,
@ -222,11 +214,9 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
const closeWorkAreaModel = () => {
setIsWorkAreaModalOpen(false);
};
const handleWorkAreaModelFormSubmit = (updatedModel) => {
if (updatedModel.id == "") delete updatedModel.id;
submitData([
{
building: null,
@ -242,11 +232,10 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
const closeTaskModel = () => {
setIsTaskModalOpen(false);
};
const handleTaskModelFormSubmit = ( updatedModel ) =>
{
const handleTaskModelFormSubmit = (updatedModel) => {
// debugger
if (updatedModel.id == "") updatedModel.id = 0;
const updatedProject = { ...project };
@ -254,47 +243,49 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
.then((response) => {
onDataChange("task-change");
showToast("Details updated successfully.", "success");
// setClearFormTrigger( true );
// setClearFormTrigger( true );
if (response?.data[0]) {
const { workItemId,workItem} = response.data[0];
const { workItemId, workItem } = response.data[0];
const updatedBuildings = updatedProject.buildings.map((building) =>
building.id == updatedModel.buildingID
? {
...building,
floors: building.floors.map((floor) =>
floor.id == updatedModel.floorId
? {
...floor,
workAreas: floor.workAreas.map((workArea) =>
workArea.id === workItem?.workAreaId
? {
...workArea,
workItems: workArea.workItems.some((existingItem) => existingItem.workItemId === workItem.workItemId)
? workArea.workItems // If the workItemId already exists, keep the current workItems
: [...workArea.workItems, workItem],
}
: workArea
),
}
: floor
),
}
...building,
floors: building.floors.map((floor) =>
floor.id == updatedModel.floorId
? {
...floor,
workAreas: floor.workAreas.map((workArea) =>
workArea.id === workItem?.workAreaId
? {
...workArea,
workItems: workArea.workItems.some(
(existingItem) =>
existingItem.workItemId ===
workItem.workItemId
)
? workArea.workItems // If the workItemId already exists, keep the current workItems
: [...workArea.workItems, workItem],
}
: workArea
),
}
: floor
),
}
: building
);
updatedProject.buildings = updatedBuildings;
cacheData( "projectInfo", {projectId: updatedProject.id, data: updatedProject} );
setProject(updatedProject)
setProject(updatedProject);
cacheData("projectInfo", {
projectId: updatedProject.id,
data: updatedProject,
});
console.log(project);
}
})
.catch((error) => {
showToast(error.message, "error");
@ -307,55 +298,53 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
);
};
const handleModalData = (type,modaldata)=>{
setModalConfig({type:type,data:modaldata})
}
const handleModalData = (type, modaldata) => {
setModalConfig({ type: type, data: modaldata });
};
const openModal = () => {
const modalElement = document.getElementById('building-model');
const modalElement = document.getElementById("building-model");
const modal = new Modal(modalElement, {
backdrop: false,
keyboard: true,
focus: true
focus: true,
});
modal.show()
modal.show();
};
const closeModal = () => {
setIsModalOpen(false);
setModalConfig(null)
setModalConfig(null);
const modalElement = document.getElementById('building-model');
const modalElement = document.getElementById("building-model");
if (modalElement) {
modalElement.classList.remove('show'); // Remove modal visibility class
modalElement.style.display = 'none'; // Hide the modal element
modalElement.classList.remove("show"); // Remove modal visibility class
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
const backdropElement = document.querySelector('.modal-backdrop');
const backdropElement = document.querySelector(".modal-backdrop");
if (backdropElement) {
backdropElement.classList.remove('modal-backdrop'); // Remove backdrop class
backdropElement.style.display = 'none'; // Hide the backdrop element
backdropElement.classList.remove("modal-backdrop"); // Remove backdrop class
backdropElement.style.display = "none"; // Hide the backdrop element
}
document.body.style.overflow = 'auto';
document.body.style.overflow = "auto";
};
const handleShow = () => setShowModal(true);
const handleClose = () => setShowModal( false );
const handleClose = () => setShowModal(false);
return (
<>
<div
className={`modal fade ${showModal ? 'show' : ''}`}
className={`modal fade ${showModal ? "show" : ""}`}
tabIndex="-1"
role="dialog"
style={{ display: showModal ? 'block' : 'none' }}
style={{ display: showModal ? "block" : "none" }}
aria-hidden={!showModal}
>
<BuildingModel
project={data}
project={project}
onClose={handleClose}
onSubmit={handleBuildingModelFormSubmit}
clearTrigger={clearFormTrigger}
@ -368,11 +357,11 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
id="floor-model"
tabIndex="-1"
role="dialog"
style={{ display: 'block' }}
style={{ display: "block" }}
aria-hidden="false"
>
<FloorModel
project={data}
project={project}
onClose={closeFloorModel}
onSubmit={handleFloorModelFormSubmit}
clearTrigger={clearFormTrigger}
@ -387,12 +376,11 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
id="work-area-model"
tabIndex="-1"
role="dialog"
style={{ display: 'block' }}
style={{ display: "block" }}
aria-hidden="false"
>
<WorkAreaModel
project={data}
// building={null}
project={project}
onClose={closeWorkAreaModel}
onSubmit={handleWorkAreaModelFormSubmit}
clearTrigger={clearFormTrigger}
@ -407,11 +395,11 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
id="task-model"
tabIndex="-1"
role="dialog"
style={{ display: 'block' }}
style={{ display: "block" }}
aria-hidden="false"
>
<TaskModel
project={data}
project={project}
activities={activityMaster}
onClose={closeTaskModel}
onSubmit={handleTaskModelFormSubmit}
@ -421,22 +409,23 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
</div>
)}
{isModalOpen && (
<ProjectModal modalConfig={modalConfig} closeModal={closeModal} />
<ProjectModal modalConfig={modalConfig} closeModal={closeModal} />
)}
<div className="col-md-12 col-lg-12 col-xl-12 order-0 mb-4">
<div className="card">
<div className="card-body" style={{ padding: "0.5rem" }}>
<div className="align-items-center">
<div className="row ">
<div className={`col-12 text-end mb-1 ${!ManageInfra && 'd-none'} `} >
<div
className={`col-12 text-end mb-1 ${
!ManageInfra && "d-none"
} `}
>
<button
type="button"
className="link-button link-button-sm m-1 "
onClick={handleShow}
>
<i className="bx bx-plus-circle me-2"></i>
@ -450,8 +439,6 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
<i className="bx bx-plus-circle me-2"></i>
Manage Floors
</button>
<button
type="button"
className="link-button m-1"
@ -471,7 +458,13 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
</div>
</div>
<div className="row ">
<InfraTable buildings={project.buildings} project={data}/>
{loading && <p>Loading....</p>}
{project && project.buildings?.length > 0 && (
<InfraTable
buildings={project?.buildings}
project={project}
/>
)}
</div>
</div>
</div>

View File

@ -91,14 +91,15 @@ export const useProjectDetails =(projectId)=>{
const [error, setError] = useState("");
const fetchData = async () => {
setLoading(true)
setLoading( true )
const project_cache = getCachedData("projectInfo");
if (!project_cache || project_cache?.projectId !== projectId) {
if (!project_cache || project_cache?.projectId != projectId) {
ProjectRepository.getProjectByprojectId(projectId)
.then( ( response ) =>
{
setProject_Details( response.data );
cacheData("projectInfo", {projectId,data: response.data} );
cacheData("projectInfo", {projectId:projectId,data: response.data} );
setLoading(false)
})
.catch((error) => {

View File

@ -25,7 +25,6 @@ const AttendancePage = () => {
const { projects, loading: projectLoading } = useProjects();
const {attendance, loading: attLoading} = useAttendace( selectedProject );
const [ attendances, setAttendances ] = useState();
const [empRoles, setEmpRoles] = useState(null);
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
const [modelConfig, setModelConfig] = useState();
@ -71,7 +70,7 @@ const AttendancePage = () => {
const handleSubmit = ( formData ) =>
{
debugger
dispatch( markCurrentAttendance( formData ) ).then( ( action ) =>
{
const updatedAttendance = attendances.map(item =>
@ -146,7 +145,7 @@ const AttendancePage = () => {
>
{!projectLoading && projects?.filter(project =>
loginUser?.projects?.map(Number).includes(project.id)).map((project)=>(
<option value={project.id}>{project.name}</option>
<option value={project.id} key={project.id}>{project.name}</option>
))}
{projectLoading && <option value="Loading..." disabled>Loading...</option> }
</select>
@ -179,7 +178,6 @@ const AttendancePage = () => {
Logs
</button>
</li>
<li className={`nav-item ${!DoRegularized && 'd-none'}`}>
<button
type="button"

View File

@ -130,9 +130,8 @@ const LoginPage = () => {
name="rememberMe"
{...register("rememberMe")}
/>
<label className="form-check-label ms-2" htmlFor="remember-me">
{" "}
Remember Me{" "}
<label className="form-check-label ms-2" >
Remember Me
</label>
</div>
<Link

View File

@ -14,6 +14,7 @@ import {MANAGE_PROJECT} from "../../utils/constants";
const ProjectList = () =>
{
const {profile: loginUser} = useProfile();
const [showModal, setShowModal] = useState(false);
const {projects, loading, error, refetch} = useProjects();

View File

@ -35,7 +35,7 @@ axiosClient.interceptors.response.use(
(response) => response,
async (error) => {
debugger;
const originalRequest = error.config;
if (!originalRequest) {