Merge branch 'feature/team-utilization' into feature/holiday-calendar-integration

This commit is contained in:
Chamika J
2025-07-28 10:01:24 +05:30
committed by GitHub
2 changed files with 39 additions and 9 deletions

View File

@@ -1,6 +1,9 @@
import React, { ReactNode, Suspense } from 'react';
import { InlineSuspenseFallback } from '@/components/suspense-fallback/suspense-fallback';
import i18n from '@/i18n';
import { hasFinanceViewPermission } from '@/utils/finance-permissions';
import { ILocalSession } from '@/types/auth/local-session.types';
import { IProjectViewModel } from '@/types/project/projectViewModel.types';
// Import core components synchronously to avoid suspense in main tabs
import ProjectViewEnhancedBoard from '@/pages/projects/projectView/enhancedBoard/project-view-enhanced-board';
@@ -164,3 +167,21 @@ export const updateTabLabels = () => {
console.error('Error updating tab labels:', error);
}
};
// Function to get filtered tab items based on user permissions
export const getFilteredTabItems = (
currentSession: ILocalSession | null,
currentProject?: IProjectViewModel | null
): TabItems[] => {
const hasFinancePermission = hasFinanceViewPermission(currentSession, currentProject);
return tabItems.filter(item => {
// Always show all tabs except finance
if (item.key !== 'finance') {
return true;
}
// Only show finance tab if user has permission
return hasFinancePermission;
});
};

View File

@@ -28,7 +28,7 @@ import { resetSelection } from '@/features/task-management/selection.slice';
import { resetFields } from '@/features/task-management/taskListFields.slice';
import { fetchLabels } from '@/features/taskAttributes/taskLabelSlice';
import { deselectAll } from '@/features/projects/bulkActions/bulkActionSlice';
import { tabItems, updateTabLabels } from '@/lib/project/project-view-constants';
import { tabItems, updateTabLabels, getFilteredTabItems } from '@/lib/project/project-view-constants';
import {
setSelectedTaskId,
setShowTaskDrawer,
@@ -39,6 +39,7 @@ import { setProjectId as setInsightsProjectId } from '@/features/projects/insigh
import { SuspenseFallback } from '@/components/suspense-fallback/suspense-fallback';
import { useTranslation } from 'react-i18next';
import { useTimerInitialization } from '@/hooks/useTimerInitialization';
import { useAuthService } from '@/hooks/useAuth';
// Import critical components synchronously to avoid suspense interruptions
import TaskDrawer from '@components/task-drawer/task-drawer';
@@ -73,14 +74,21 @@ const ProjectView = React.memo(() => {
// Optimize document title updates
useDocumentTitle(selectedProject?.name || t('projectView'));
// Get auth service and current session
const authService = useAuthService();
const currentSession = useMemo(() => authService.getCurrentSession(), [authService]);
// Memoize URL params to prevent unnecessary state updates
const urlParams = useMemo(
() => ({
tab: searchParams.get('tab') || tabItems[0].key,
pinnedTab: searchParams.get('pinned_tab') || '',
taskId: searchParams.get('task') || '',
}),
[searchParams]
() => {
const filteredTabItems = getFilteredTabItems(currentSession, selectedProject);
return {
tab: searchParams.get('tab') || filteredTabItems[0]?.key || 'tasks-list',
pinnedTab: searchParams.get('pinned_tab') || '',
taskId: searchParams.get('task') || '',
};
},
[searchParams, currentSession, selectedProject]
);
const [activeTab, setActiveTab] = useState<string>(urlParams.tab);
@@ -266,7 +274,8 @@ const ProjectView = React.memo(() => {
return [];
}
const menuItems = tabItems.map(item => ({
const filteredTabItems = getFilteredTabItems(currentSession, selectedProject);
const menuItems = filteredTabItems.map(item => ({
key: item.key,
label: (
<Flex align="center" gap={6} style={{ color: 'inherit' }}>
@@ -320,7 +329,7 @@ const ProjectView = React.memo(() => {
}));
return menuItems;
}, [pinnedTab, pinToDefaultTab, t, translationsReady]);
}, [pinnedTab, pinToDefaultTab, t, translationsReady, currentSession, selectedProject]);
// Optimized secondary components loading with better UX
const [shouldLoadSecondaryComponents, setShouldLoadSecondaryComponents] = useState(false);