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