From 78a50f6db41bd1c66ab98bb35f94445e21441138 Mon Sep 17 00:00:00 2001 From: Kartik Sharma Date: Wed, 30 Jul 2025 12:30:50 +0530 Subject: [PATCH] When a project is selected, the last selected project will be displayed. --- src/components/Layout/Header.jsx | 72 +++++++++++++++++++-------- src/components/Project/ProjectNav.jsx | 30 +++++------ src/pages/project/ProjectDetails.jsx | 4 +- src/slices/apiDataManager.jsx | 16 +++++- src/slices/localVariablesSlice.jsx | 2 + 5 files changed, 84 insertions(+), 40 deletions(-) diff --git a/src/components/Layout/Header.jsx b/src/components/Layout/Header.jsx index 006b5c74..dc38ccae 100644 --- a/src/components/Layout/Header.jsx +++ b/src/components/Layout/Header.jsx @@ -3,6 +3,7 @@ import { cacheData, clearAllCache, getCachedData, + useSelectedproject, } from "../../slices/apiDataManager"; import AuthRepository from "../../repositories/AuthRepository"; import { useDispatch, useSelector } from "react-redux"; @@ -12,18 +13,18 @@ import { useProfile } from "../../hooks/useProfile"; import { useLocation, useNavigate, useParams } from "react-router-dom"; import Avatar from "../../components/common/Avatar"; import { useChangePassword } from "../Context/ChangePasswordContext"; -import { useProjects } from "../../hooks/useProjects"; +import { useProjects, useProjectName } from "../../hooks/useProjects"; // Make sure useProjects is imported if needed elsewhere import { useCallback, useEffect, useState } from "react"; -import { useProjectName } from "../../hooks/useProjects"; import eventBus from "../../services/eventBus"; import { useHasUserPermission } from "../../hooks/useHasUserPermission"; import { MANAGE_PROJECT } from "../../utils/constants"; +import { useMemo } from "react"; const Header = () => { const { profile } = useProfile(); const location = useLocation(); const dispatch = useDispatch(); - const { data, loading } = useMaster(); + const { data, loading: masterLoading } = useMaster(); // Renamed loading to masterLoading for clarity const navigate = useNavigate(); const HasManageProjectPermission = useHasUserPermission(MANAGE_PROJECT); @@ -33,7 +34,6 @@ const Header = () => { /^\/dashboard$/.test(location.pathname) || /^\/$/.test(location.pathname); // Define the specific project status IDs you want to filter by - // Changed to explicitly include only 'Active', 'On Hold', 'In Progress' const allowedProjectStatusIds = [ "603e994b-a27f-4e5d-a251-f3d69b0498ba", // On Hold "cdad86aa-8a56-4ff4-b633-9c629057dfef", // In Progress @@ -67,7 +67,6 @@ const Header = () => { window.location.href = "/auth/login"; }) .catch((error) => { - // Even if logout API fails, clear local storage and redirect localStorage.removeItem("jwtToken"); localStorage.removeItem("refreshToken"); localStorage.removeItem("user"); @@ -86,17 +85,19 @@ const Header = () => { navigate(`/employee/${profile?.employeeInfo?.id}?for=attendance`); }; - const { projectNames, loading: projectLoading, fetchData } = useProjectName(); + const { projectNames, loading: projectLoading, fetchData } = useProjectName(); // Renamed loading to projectLoading - const selectedProject = useSelector( - (store) => store.localVariables.projectId - ); + const selectedProject = useSelectedproject(); + + // Filter projects for the dropdown based on the current path and allowed statuses + const projectsForDropdown = useMemo(() => { + if (!projectNames) return []; // Return empty array if projectNames is not yet fetched + + return isDashboard + ? projectNames + : projectNames?.filter(project => allowedProjectStatusIds.includes(project.projectStatusId)); + }, [projectNames, isDashboard, allowedProjectStatusIds]); - const projectsForDropdown = isDashboard - ? projectNames // On dashboard, show all projects - : projectNames?.filter(project => - allowedProjectStatusIds.includes(project.projectStatusId) - ); // Determine the display text for the project section let currentProjectDisplayName = "Loading..."; @@ -117,8 +118,21 @@ const Header = () => { currentProjectDisplayName = selectedProjectObj ? selectedProjectObj.name : "Unknown Project"; } } + // Determine the display text for the project dropdown + let displayText = "Loading..."; // Default to loading + if (!projectLoading && projectNames) { // Only update if not loading and projectNames is available + if (selectedProject === null) { + displayText = "All Projects"; + } else { + // Find the selected project from the full projectNames list + const selectedProjectObj = projectNames.find( // Use projectNames directly here + (p) => p?.id === selectedProject + ); + displayText = selectedProjectObj ? selectedProjectObj.name : "All Projects"; // Fallback to "All Projects" if selected project is not found + } } + const { openChangePassword } = useChangePassword(); // Effect to set initial projectId based on scenarios @@ -128,6 +142,8 @@ const Header = () => { projectNames.length > 0 && selectedProject === undefined && // Only set if no project is explicitly selected yet !getCachedData("hasReceived") // To avoid re-setting on every render + selectedProject === undefined && // Only set default if no project is currently selected + !getCachedData("hasReceived") // Check if this flag is still relevant for your caching strategy ) { if (projectNames.length === 1) { // If only one project exists, automatically select it @@ -140,9 +156,11 @@ const Header = () => { const firstAllowedProject = projectNames.find(project => allowedProjectStatusIds.includes(project.projectStatusId)); dispatch(setProjectId(firstAllowedProject?.id || null)); } + const firstAllowedProject = projectNames.find(project => allowedProjectStatusIds.includes(project.projectStatusId)); + dispatch(setProjectId(firstAllowedProject?.id || null)); // Fallback to null if no allowed projects } } - }, [projectNames, selectedProject, dispatch, isDashboard]); + }, [projectNames, selectedProject, dispatch, isDashboard, allowedProjectStatusIds]); const handler = useCallback( @@ -163,7 +181,7 @@ const Header = () => { const newProjectHandler = useCallback( async (msg) => { if (HasManageProjectPermission && msg.keyword === "Create_Project") { - await fetchData(); + await fetchData(); } else if (projectNames?.some((item) => item.id === msg.response.id)) { await fetchData(); } @@ -186,16 +204,19 @@ const Header = () => { }; }, [handler, newProjectHandler]); - const handleProjectChange = (project) => { - dispatch(setProjectId(project)); // Always set the projectId - if (isProjectPath && project !== null) { - navigate("/projects/details"); // Navigate only if on /projects and a specific project is selected + const handleProjectChange = (projectId) => { + dispatch(setProjectId(projectId)); + if (isProjectPath && projectId !== null) { + navigate(`/projects/details?resetDates=true`); + } else if (isProjectPath && projectId === null) { + navigate("/projects"); + } else if (isDashboard) { } }; - // Determine if the dropdown should be shown: Only if there are genuinely multiple projects - const shouldShowDropdown = projectNames && projectNames.length > 1; + const shouldShowDropdown = + isDashboard || (projectsForDropdown && projectsForDropdown.length > 1); return (