- {(ApprovedTaskRights || ReportTaskRights) ? (
-
-
- {isLoading && (
)}
- {( !isLoading && projectInfra?.length === 0 ) && (
No Result Found
)}
- {(!isLoading && projectInfra?.length > 0) && (
)}
+
+
- ) : (
-
-
-
Access Denied: You don't have permission to perform this action. !
-
- )}
-
);
};
export default InfraPlanning;
+
diff --git a/src/hooks/useHasUserPermission.js b/src/hooks/useHasUserPermission.js
index cefeea6c..b4ec3e52 100644
--- a/src/hooks/useHasUserPermission.js
+++ b/src/hooks/useHasUserPermission.js
@@ -1,16 +1,26 @@
-
import { useSelectedProject } from "../slices/apiDataManager";
import { useAllProjectLevelPermissions, useProfile } from "./useProfile";
export const useHasUserPermission = (permission) => {
const selectedProject = useSelectedProject();
const { profile } = useProfile();
- const { data: projectPermissions = [], isLoading, isError } = useAllProjectLevelPermissions(selectedProject);
+ const {
+ data: projectPermissions = [],
+ isLoading,
+ isError,
+ } = useAllProjectLevelPermissions(selectedProject);
if (isLoading || !permission) return false;
const globalPerms = profile?.featurePermissions ?? [];
const projectPerms = projectPermissions ?? [];
-
- return globalPerms.includes(permission) || projectPerms.includes(permission);
+ if (selectedProject) {
+ if (projectPerms.length === 0) {
+ return projectPerms.includes(permission);
+ } else {
+ return projectPerms.includes(permission);
+ }
+ } else {
+ return globalPerms.includes(permission);
+ }
};
diff --git a/src/hooks/useProjectAccess.js b/src/hooks/useProjectAccess.js
new file mode 100644
index 00000000..a3ff27ac
--- /dev/null
+++ b/src/hooks/useProjectAccess.js
@@ -0,0 +1,26 @@
+import { useNavigate } from "react-router-dom";
+import { useEffect } from "react";
+import { useHasUserPermission } from "./useHasUserPermission";
+import { useAllProjectLevelPermissions } from "./useProfile";
+import { VIEW_PROJECTS } from "../utils/constants";
+import showToast from "../services/toastService";
+
+export const useProjectAccess = (projectId) => {
+ const { data: projectPermissions, isLoading, isFetched } =
+ useAllProjectLevelPermissions(projectId);
+
+ const canView = useHasUserPermission(VIEW_PROJECTS);
+ const navigate = useNavigate();
+
+ useEffect(() => {
+ if (projectId && isFetched && !isLoading && !canView) {
+ showToast("You don't have permission to view project details", "warning");
+ navigate("/projects");
+ }
+ }, [projectId, isFetched, isLoading, canView, navigate]);
+
+ return {
+ canView,
+ loading: isLoading || !isFetched,
+ };
+};
diff --git a/src/hooks/useProjects.js b/src/hooks/useProjects.js
index a9815fc2..ee399b19 100644
--- a/src/hooks/useProjects.js
+++ b/src/hooks/useProjects.js
@@ -177,6 +177,7 @@ export const useProjectInfra = (projectId) => {
data: projectInfra,
isLoading,
error,
+ isFetched
} = useQuery({
queryKey: ["ProjectInfra", projectId],
queryFn: async () => {
@@ -190,7 +191,7 @@ export const useProjectInfra = (projectId) => {
},
});
- return { projectInfra, isLoading, error };
+ return { projectInfra, isLoading, error, isFetched };
};
export const useProjectTasks = (workAreaId, IsExpandedArea = false) => {
diff --git a/src/pages/Directory/DirectoryPage.jsx b/src/pages/Directory/DirectoryPage.jsx
index 40dc51e3..8e17b802 100644
--- a/src/pages/Directory/DirectoryPage.jsx
+++ b/src/pages/Directory/DirectoryPage.jsx
@@ -21,6 +21,7 @@ import ContactProfile from "../../components/Directory/ContactProfile";
import GlobalModel from "../../components/common/GlobalModel";
import { exportToCSV } from "../../utils/exportUtils";
import ConfirmModal from "../../components/common/ConfirmModal";
+import { useSelectedProject } from "../../slices/apiDataManager";
const NotesPage = lazy(() => import("./NotesPage"));
const ContactsPage = lazy(() => import("./ContactsPage"));
diff --git a/src/pages/project/ProjectDetails.jsx b/src/pages/project/ProjectDetails.jsx
index f7ccabbe..b57f9362 100644
--- a/src/pages/project/ProjectDetails.jsx
+++ b/src/pages/project/ProjectDetails.jsx
@@ -1,5 +1,6 @@
-import { useSelector, useDispatch } from "react-redux"; // Import useSelector
import React, { useState, useEffect, useCallback } from "react";
+import { useDispatch } from "react-redux";
+import { useNavigate } from "react-router-dom";
import ProjectOverview from "../../components/Project/ProjectOverview";
import AboutProject from "../../components/Project/AboutProject";
@@ -9,63 +10,43 @@ 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,
- clearCacheKey,
- getCachedData,
- useSelectedProject,
-} from "../../slices/apiDataManager";
-import "./ProjectDetails.css";
-import { useProjectDetails } from "../../hooks/useProjects";
+import { useSelectedProject } from "../../slices/apiDataManager";
+import { useProjectDetails, useProjectName } from "../../hooks/useProjects";
import { ComingSoonPage } from "../Misc/ComingSoonPage";
import eventBus from "../../services/eventBus";
import ProjectProgressChart from "../../components/Dashboard/ProjectProgressChart";
-import { useProjectName } from "../../hooks/useProjects";
import AttendanceOverview from "../../components/Dashboard/AttendanceChart";
import { setProjectId } from "../../slices/localVariablesSlice";
-import ProjectDocument from "../../components/Project/ProjectDocuments";
import ProjectDocuments from "../../components/Project/ProjectDocuments";
import ProjectSetting from "../../components/Project/ProjectSetting";
import DirectoryPage from "../Directory/DirectoryPage";
-import { useHasAnyPermission } from "../../hooks/useExpense";
-import { VIEW_PROJECTS } from "../../utils/constants";
-import { useNavigate, useRoutes } from "react-router-dom";
-import { useHasUserPermission } from "../../hooks/useHasUserPermission";
+import { useProjectAccess } from "../../hooks/useProjectAccess"; // ✅ new
+
+import "./ProjectDetails.css";
const ProjectDetails = () => {
const projectId = useSelectedProject();
- const CanViewProject = useHasUserPermission(VIEW_PROJECTS);
- const navigate = useNavigate();
-
- const { projectNames, fetchData } = useProjectName();
const dispatch = useDispatch();
+ const { projectNames } = useProjectName();
+ const { projects_Details, loading: projectLoading, refetch } =
+ useProjectDetails(projectId);
+
+ const { canView, loading: permsLoading } = useProjectAccess(projectId);
+
useEffect(() => {
- if (!CanViewProject) {
- navigate("/dashboard");
+ if (!projectId && projectNames.length > 0) {
+ dispatch(setProjectId(projectNames[0].id));
}
- if (projectId == null) {
- dispatch(setProjectId(projectNames[0]?.id));
- }
- }, [projectNames]);
+ }, [projectId, projectNames, dispatch]);
- const {
- projects_Details,
- loading: projectLoading,
- error: projectError,
- refetch,
- } = useProjectDetails(projectId);
-
- const [activePill, setActivePill] = useState(() => {
- return localStorage.getItem("lastActiveProjectTab") || "profile";
- });
+ const [activePill, setActivePill] = useState(
+ localStorage.getItem("lastActiveProjectTab") || "profile"
+ );
const handler = useCallback(
(msg) => {
- if (
- msg.keyword === "Update_Project" &&
- projects_Details?.id === msg.response.id
- ) {
+ if (msg.keyword === "Update_Project" && projects_Details?.id === msg.response.id) {
refetch();
}
},
@@ -79,69 +60,42 @@ const ProjectDetails = () => {
const handlePillClick = (pillKey) => {
setActivePill(pillKey);
- localStorage.setItem("lastActiveProjectTab", pillKey);
+ localStorage.setItem("lastActiveProjectTab", pillKey);
};
- const renderContent = () => {
- if (projectLoading || !projects_Details) return
;
+ if (projectLoading || permsLoading || !projects_Details) {
+ return
;
+ }
+ const renderContent = () => {
switch (activePill) {
case "profile":
- return (
- <>
-
- >
- );
-
- case "teams":
return (
-
);
-
+ case "teams":
+ return
;
case "infra":
return
;
-
case "workplan":
return
;
-
case "directory":
- return (
-
-
-
- );
+ return
;
case "documents":
- return (
-
- );
+ return
;
case "setting":
- return (
-
- );
-
+ return
;
default:
return
;
}
@@ -156,7 +110,6 @@ const ProjectDetails = () => {
{ label: projects_Details?.name || "Project", link: null },
]}
/>
-