Implemented signalR for create and update project
This commit is contained in:
parent
f8ee3d3a86
commit
164f3cc02f
@ -1,9 +1,13 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import moment from "moment";
|
||||
import { getProjectStatusName } from "../../utils/projectStatus";
|
||||
const AboutProject = ({ data }) => {
|
||||
const [CurrentProject, setCurrentProject] = useState(data);
|
||||
|
||||
useEffect(() => {
|
||||
setCurrentProject(data);
|
||||
}, [data]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{data && (
|
||||
|
@ -12,10 +12,15 @@ const ProjectBanner = ({ project_data }) => {
|
||||
const [showModal, setShowModal] = useState(false);
|
||||
const manageProject = useHasUserPermission(MANAGE_PROJECT);
|
||||
const [CurrentProject, setCurrentProject] = useState(project_data);
|
||||
|
||||
if (project_data == null) {
|
||||
return <span>incomplete project information</span>;
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setCurrentProject(project_data);
|
||||
}, [project_data]);
|
||||
|
||||
const handleShow = () => setShowModal(true);
|
||||
const handleClose = () => setShowModal(false);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import moment from "moment";
|
||||
import { getDateDifferenceInDays } from "../../utils/dateUtils";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
@ -22,6 +22,9 @@ const ProjectCard = ({ projectData, recall }) => {
|
||||
const ManageProject = useHasUserPermission(MANAGE_PROJECT);
|
||||
const [modifyProjectLoading, setMdifyProjectLoading] = useState(false);
|
||||
|
||||
useEffect(()=>{
|
||||
setProjectInfo(projectData);
|
||||
},[projectData])
|
||||
const handleShow = async () => {
|
||||
try {
|
||||
setMdifyProjectLoading(true);
|
||||
|
@ -58,7 +58,7 @@ const AttendancePage = () => {
|
||||
setAttendances(updatedAttendance);
|
||||
}
|
||||
},
|
||||
[selectedProject, attrecall]
|
||||
[selectedProject,attendances]
|
||||
);
|
||||
|
||||
const getRole = (roleId) => {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { useParams } from "react-router-dom";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useState, useEffect, useCallback } from "react";
|
||||
|
||||
import ActivityTimeline from "../../components/Project/ActivityTimeline";
|
||||
import ProjectOverview from "../../components/Project/ProjectOverview";
|
||||
@ -11,7 +11,7 @@ import ProjectInfra from "../../components/Project/ProjectInfra";
|
||||
import Loader from "../../components/common/Loader";
|
||||
import WorkPlan from "../../components/Project/WorkPlan";
|
||||
import Breadcrumb from "../../components/common/Breadcrumb";
|
||||
import { cacheData, getCachedData } from "../../slices/apiDataManager";
|
||||
import { cacheData, clearCacheKey, getCachedData } from "../../slices/apiDataManager";
|
||||
import ProjectRepository from "../../repositories/ProjectRepository";
|
||||
import { ActivityeRepository } from "../../repositories/MastersRepository";
|
||||
import "./ProjectDetails.css";
|
||||
@ -23,6 +23,7 @@ import { useDispatch } from "react-redux";
|
||||
import { setProjectId } from "../../slices/localVariablesSlice";
|
||||
import { ComingSoonPage } from "../Misc/ComingSoonPage";
|
||||
import Directory from "../Directory/Directory";
|
||||
import eventBus from "../../services/eventBus";
|
||||
|
||||
const ProjectDetails = () => {
|
||||
let { projectId } = useParams();
|
||||
@ -121,7 +122,7 @@ const ProjectDetails = () => {
|
||||
case "directory": {
|
||||
return (
|
||||
<div className="row">
|
||||
<Directory IsPage={ false} prefernceContacts={projectDetails.id} />
|
||||
<Directory IsPage={false} prefernceContacts={projectDetails.id} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -137,6 +138,31 @@ const ProjectDetails = () => {
|
||||
setProjectDetails(projects_Details);
|
||||
}, [projects_Details, projectId]);
|
||||
|
||||
const handler = useCallback(
|
||||
(msg) => {
|
||||
if (msg.keyword === "Update_Project" && project.id === msg.response.id) {
|
||||
clearCacheKey("projectInfo")
|
||||
ProjectRepository.getProjectByprojectId(projectId)
|
||||
.then((response) => {
|
||||
setProjectDetails(response.data);
|
||||
setProject(response.data);
|
||||
cacheData("projectInfo", { projectId, data: response.data });
|
||||
setLoading(false);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
setError("Failed to fetch data.");
|
||||
setLoading(false);
|
||||
});
|
||||
}
|
||||
},
|
||||
[project,handleDataChange]
|
||||
);
|
||||
useEffect(() => {
|
||||
eventBus.on("project", handler);
|
||||
return () => eventBus.off("project", handler);
|
||||
}, [handler]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useState, useEffect, useCallback } from "react";
|
||||
import ProjectCard from "../../components/Project/ProjectCard";
|
||||
import ManageProjectInfo from "../../components/Project/ManageProjectInfo";
|
||||
import Breadcrumb from "../../components/common/Breadcrumb";
|
||||
@ -11,6 +11,8 @@ import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
||||
import { useProfile } from "../../hooks/useProfile";
|
||||
import { ITEMS_PER_PAGE, MANAGE_PROJECT } from "../../utils/constants";
|
||||
import ProjectListView from "./ProjectListView";
|
||||
import eventBus from "../../services/eventBus";
|
||||
import { clearApiCacheKey } from "../../slices/apiCacheSlice";
|
||||
|
||||
const ProjectList = () => {
|
||||
const { profile: loginUser } = useProfile();
|
||||
@ -37,7 +39,7 @@ const ProjectList = () => {
|
||||
const handleShow = () => setShowModal(true);
|
||||
const handleClose = () => setShowModal(false);
|
||||
|
||||
const sortingProject = (projects) =>{
|
||||
const sortingProject = (projects) => {
|
||||
if (!loading && Array.isArray(projects)) {
|
||||
const grouped = {};
|
||||
projects.forEach((project) => {
|
||||
@ -56,10 +58,10 @@ const ProjectList = () => {
|
||||
|
||||
setProjectList(sortedGrouped);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
sortingProject(projects)
|
||||
sortingProject(projects);
|
||||
}, [projects, loginUser?.projects, loading]);
|
||||
|
||||
useEffect(() => {
|
||||
@ -70,16 +72,16 @@ const ProjectList = () => {
|
||||
}
|
||||
}, [loginUser, HasManageProjectPermission]);
|
||||
|
||||
const handleSubmitForm = (newProject,setloading,reset) => {
|
||||
const handleSubmitForm = (newProject, setloading, reset) => {
|
||||
ProjectRepository.manageProject(newProject)
|
||||
.then((response) => {
|
||||
const cachedProjects = getCachedData("projectslist") || [];
|
||||
const updatedProjects = [...cachedProjects, response.data];
|
||||
cacheData("projectslist", updatedProjects);
|
||||
setProjectList( ( prev ) => [ ...prev, response.data ] );
|
||||
setloading( false )
|
||||
reset()
|
||||
sortingProject(getCachedData("projectslist"))
|
||||
setProjectList((prev) => [...prev, response.data]);
|
||||
setloading(false);
|
||||
reset();
|
||||
sortingProject(getCachedData("projectslist"));
|
||||
showToast("Project Created successfully.", "success");
|
||||
setShowModal(false);
|
||||
})
|
||||
@ -123,7 +125,7 @@ const ProjectList = () => {
|
||||
indexOfLastItem
|
||||
);
|
||||
const totalPages = Math.ceil(filteredProjects.length / itemsPerPage);
|
||||
|
||||
console.log("filtter", currentItems);
|
||||
useEffect(() => {
|
||||
const tooltipTriggerList = Array.from(
|
||||
document.querySelectorAll('[data-bs-toggle="tooltip"]')
|
||||
@ -131,6 +133,31 @@ const ProjectList = () => {
|
||||
tooltipTriggerList.forEach((el) => new bootstrap.Tooltip(el));
|
||||
}, []);
|
||||
|
||||
const handler = useCallback(
|
||||
async (msg) => {
|
||||
if (HasManageProject && msg.keyword === "Create_Project") {
|
||||
const updatedProjects = [...projectList, msg.response];
|
||||
cacheData("projectslist", updatedProjects);
|
||||
setProjectList(updatedProjects);
|
||||
sortingProject(updatedProjects);
|
||||
}
|
||||
|
||||
if (
|
||||
msg.keyword === "Update_Project" &&
|
||||
projectList.some((item) => item.id === msg.response.id)
|
||||
) {
|
||||
await refetch();
|
||||
sortingProject(projects);
|
||||
}
|
||||
},
|
||||
[HasManageProject, projects, sortingProject]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
eventBus.on("project", handler);
|
||||
return () => eventBus.off("project", handler);
|
||||
}, [handler]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
@ -200,49 +227,48 @@ const ProjectList = () => {
|
||||
<i className="bx bx-list-ul bx-sm"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="dropdown ms-3">
|
||||
<a
|
||||
className="dropdown-toggle hide-arrow cursor-pointer"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-expanded="false"
|
||||
>
|
||||
<i className="bx bx-filter bx-lg"></i>
|
||||
</a>
|
||||
<ul className="dropdown-menu p-2 text-capitalize">
|
||||
{[
|
||||
{
|
||||
id: "b74da4c2-d07e-46f2-9919-e75e49b12731",
|
||||
label: "Active",
|
||||
},
|
||||
{
|
||||
id: "603e994b-a27f-4e5d-a251-f3d69b0498ba",
|
||||
label: "On Hold",
|
||||
},
|
||||
{
|
||||
id: "ef1c356e-0fe0-42df-a5d3-8daee355492d",
|
||||
label: "Inactive",
|
||||
},
|
||||
{
|
||||
id: "33deaef9-9af1-4f2a-b443-681ea0d04f81",
|
||||
label: "Completed",
|
||||
},
|
||||
].map(({ id, label }) => (
|
||||
<li key={id}>
|
||||
<div className="form-check">
|
||||
<input
|
||||
className="form-check-input "
|
||||
type="checkbox"
|
||||
checked={selectedStatuses.includes(id)}
|
||||
onChange={() => handleStatusChange(id)}
|
||||
/>
|
||||
<label className="form-check-label">{label}</label>
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="dropdown ms-3">
|
||||
<a
|
||||
className="dropdown-toggle hide-arrow cursor-pointer"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-expanded="false"
|
||||
>
|
||||
<i className="bx bx-filter bx-lg"></i>
|
||||
</a>
|
||||
<ul className="dropdown-menu p-2 text-capitalize">
|
||||
{[
|
||||
{
|
||||
id: "b74da4c2-d07e-46f2-9919-e75e49b12731",
|
||||
label: "Active",
|
||||
},
|
||||
{
|
||||
id: "603e994b-a27f-4e5d-a251-f3d69b0498ba",
|
||||
label: "On Hold",
|
||||
},
|
||||
{
|
||||
id: "ef1c356e-0fe0-42df-a5d3-8daee355492d",
|
||||
label: "Inactive",
|
||||
},
|
||||
{
|
||||
id: "33deaef9-9af1-4f2a-b443-681ea0d04f81",
|
||||
label: "Completed",
|
||||
},
|
||||
].map(({ id, label }) => (
|
||||
<li key={id}>
|
||||
<div className="form-check">
|
||||
<input
|
||||
className="form-check-input "
|
||||
type="checkbox"
|
||||
checked={selectedStatuses.includes(id)}
|
||||
onChange={() => handleStatusChange(id)}
|
||||
/>
|
||||
<label className="form-check-label">{label}</label>
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
@ -341,7 +367,11 @@ const ProjectList = () => {
|
||||
</tr>
|
||||
) : (
|
||||
currentItems.map((project) => (
|
||||
<ProjectListView key={project.id} projectData={project} recall={sortingProject} />
|
||||
<ProjectListView
|
||||
key={project.id}
|
||||
projectData={project}
|
||||
recall={sortingProject}
|
||||
/>
|
||||
))
|
||||
)}
|
||||
</tbody>
|
||||
@ -349,7 +379,11 @@ const ProjectList = () => {
|
||||
</div>
|
||||
) : (
|
||||
currentItems.map((project) => (
|
||||
<ProjectCard key={project.id} projectData={project} recall={sortingProject} />
|
||||
<ProjectCard
|
||||
key={project.id}
|
||||
projectData={project}
|
||||
recall={sortingProject}
|
||||
/>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
|
@ -22,6 +22,10 @@ const ProjectListView = ({ projectData, recall }) => {
|
||||
const navigate = useNavigate();
|
||||
const ManageProject = useHasUserPermission(MANAGE_PROJECT);
|
||||
|
||||
useEffect(()=>{
|
||||
setProjectInfo(projectData);
|
||||
},[projectData])
|
||||
|
||||
const handleShow = async () => {
|
||||
try {
|
||||
const response = await ProjectRepository.getProjectByprojectId(
|
||||
|
@ -3,6 +3,7 @@ import { clearCacheKey, getCachedData } from "../slices/apiDataManager";
|
||||
import showToast from "./toastService";
|
||||
import eventBus from "./eventBus";
|
||||
import { useSelector } from "react-redux";
|
||||
import { clearApiCacheKey } from "../slices/apiCacheSlice";
|
||||
const base_Url = process.env.VITE_BASE_URL;
|
||||
// const base_Url = "https://devapi.marcoaiot.com";
|
||||
let connection = null;
|
||||
@ -25,19 +26,30 @@ export function startSignalR(loggedUser) {
|
||||
)
|
||||
.toISOString()
|
||||
.split("T")[0];
|
||||
connection.on("Attendance", (data) => {
|
||||
const checkIn = data.response.checkInTime.substring(0, 10);
|
||||
if (data.loginUserId != loggedUser?.employeeInfo.id) {
|
||||
if (today === checkIn) {
|
||||
eventBus.emit("attendance", data);
|
||||
}
|
||||
var onlyDate = Number(checkIn.substring(8, 10));
|
||||
connection.on("NotificationEventHandler", (data) => {
|
||||
// console.log("Notification received:", data);
|
||||
if (data.keyword == "Attendance") {
|
||||
const checkIn = data.response.checkInTime.substring(0, 10);
|
||||
if (data.loginUserId != loggedUser?.employeeInfo.id) {
|
||||
if (today === checkIn) {
|
||||
eventBus.emit("attendance", data);
|
||||
}
|
||||
var onlyDate = Number(checkIn.substring(8, 10));
|
||||
|
||||
var afterTwoDay = checkIn.substring(0, 8) + (onlyDate + 2).toString().padStart(2, "0");;
|
||||
if(afterTwoDay <= today && (data.response.activity == 4 || data.response.activity == 5)){
|
||||
eventBus.emit("regularization", data);
|
||||
var afterTwoDay =
|
||||
checkIn.substring(0, 8) + (onlyDate + 2).toString().padStart(2, "0");
|
||||
if (
|
||||
afterTwoDay <= today &&
|
||||
(data.response.activity == 4 || data.response.activity == 5)
|
||||
) {
|
||||
eventBus.emit("regularization", data);
|
||||
}
|
||||
eventBus.emit("attendance_log", data);
|
||||
}
|
||||
eventBus.emit("attendance_log", data);
|
||||
}
|
||||
if (data.keyword == "Create_Project" || data.keyword == "Update_Project") {
|
||||
clearCacheKey("projectslist");
|
||||
eventBus.emit("project", data);
|
||||
}
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user