feat(reporting): enhance date handling and export functionality

- Improved date range handling in ReportingControllerBaseWithTimezone to support various date formats from the frontend, ensuring robust parsing and timezone conversion.
- Updated SQL queries to use consistent table aliases for clarity.
- Added export functionality for project members and tasks in ProjectReportsDrawer, allowing users to download relevant data.
- Enhanced the Excel export handler in ProjectsReports to streamline project data exports based on the current session's team name.
This commit is contained in:
chamikaJ
2025-07-29 13:05:55 +05:30
parent 29b8c1b2af
commit b915de2b93
3 changed files with 111 additions and 31 deletions

View File

@@ -1,5 +1,5 @@
import { Drawer, Typography, Flex, Button, Dropdown } from '@/shared/antd-imports';
import React, { useState } from 'react';
import React, { useState, useCallback } from 'react';
import { useAppSelector } from '../../../../hooks/useAppSelector';
import { useAppDispatch } from '../../../../hooks/useAppDispatch';
import { setSelectedProject, toggleProjectReportsDrawer } from '../project-reports-slice';
@@ -8,6 +8,8 @@ import ProjectReportsDrawerTabs from './ProjectReportsDrawerTabs';
import { colors } from '../../../../styles/colors';
import { useTranslation } from 'react-i18next';
import { IRPTProject } from '@/types/reporting/reporting.types';
import { useAuthService } from '../../../../hooks/useAuth';
import { reportingExportApiService } from '@/api/reporting/reporting-export.api.service';
type ProjectReportsDrawerProps = {
selectedProject: IRPTProject | null;
@@ -17,6 +19,8 @@ const ProjectReportsDrawer = ({ selectedProject }: ProjectReportsDrawerProps) =>
const { t } = useTranslation('reporting-projects-drawer');
const dispatch = useAppDispatch();
const currentSession = useAuthService().getCurrentSession();
const [exporting, setExporting] = useState<boolean>(false);
// get drawer open state and project list from the reducer
const isDrawerOpen = useAppSelector(
@@ -35,6 +39,54 @@ const ProjectReportsDrawer = ({ selectedProject }: ProjectReportsDrawerProps) =>
}
};
// Export handlers
const handleExportMembers = useCallback(() => {
if (!selectedProject?.id) return;
try {
setExporting(true);
const teamName = currentSession?.team_name || 'Team';
reportingExportApiService.exportProjectMembers(
selectedProject.id,
selectedProject.name,
teamName
);
} catch (error) {
console.error('Error exporting project members:', error);
} finally {
setExporting(false);
}
}, [selectedProject, currentSession?.team_name]);
const handleExportTasks = useCallback(() => {
if (!selectedProject?.id) return;
try {
setExporting(true);
const teamName = currentSession?.team_name || 'Team';
reportingExportApiService.exportProjectTasks(
selectedProject.id,
selectedProject.name,
teamName
);
} catch (error) {
console.error('Error exporting project tasks:', error);
} finally {
setExporting(false);
}
}, [selectedProject, currentSession?.team_name]);
const handleExportClick = useCallback((key: string) => {
switch (key) {
case '1':
handleExportMembers();
break;
case '2':
handleExportTasks();
break;
default:
break;
}
}, [handleExportMembers, handleExportTasks]);
return (
<Drawer
open={isDrawerOpen}
@@ -56,9 +108,15 @@ const ProjectReportsDrawer = ({ selectedProject }: ProjectReportsDrawerProps) =>
{ key: '1', label: t('membersButton') },
{ key: '2', label: t('tasksButton') },
],
onClick: ({ key }) => handleExportClick(key),
}}
>
<Button type="primary" icon={<DownOutlined />} iconPosition="end">
<Button
type="primary"
loading={exporting}
icon={<DownOutlined />}
iconPosition="end"
>
{t('exportButton')}
</Button>
</Dropdown>

View File

@@ -28,9 +28,8 @@ const ProjectsReports = () => {
// Memoize the Excel export handler to prevent recreation on every render
const handleExcelExport = useCallback(() => {
if (currentSession?.team_name) {
reportingExportApiService.exportProjects(currentSession.team_name);
}
const teamName = currentSession?.team_name || 'Team';
reportingExportApiService.exportProjects(teamName);
}, [currentSession?.team_name]);
// Memoize the archived checkbox handler to prevent recreation on every render