feat(project-view): add user permission-based tab filtering
- Implemented a new function to filter project view tabs based on user finance permissions, enhancing the user experience by conditionally displaying the finance tab. - Updated the project view component to utilize the new filtering function, ensuring that only authorized users can access finance-related features. - Refactored URL parameter handling to accommodate the filtered tab items, improving state management and user navigation.
This commit is contained in:
@@ -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;
|
||||
});
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
() => {
|
||||
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]
|
||||
};
|
||||
},
|
||||
[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);
|
||||
|
||||
Reference in New Issue
Block a user