feat(project-view): optimize component loading and enhance configuration

- Introduced lazy loading for project view components and chart components to reduce initial bundle size.
- Centralized Ant Design imports in a new `antd-imports.ts` file for better tree-shaking and maintainability.
- Updated project view header and task list components to utilize centralized imports, improving consistency and performance.
- Enhanced project view constants to streamline component rendering and improve user experience.
This commit is contained in:
chamikaJ
2025-06-25 13:05:38 +05:30
parent 680e84d19b
commit 7b326e8ff0
7 changed files with 389 additions and 79 deletions

View File

@@ -0,0 +1,25 @@
import React, { Suspense } from 'react';
import { Spin } from 'antd';
// Lazy load chart components to reduce initial bundle size
const LazyBar = React.lazy(() => import('react-chartjs-2').then(module => ({ default: module.Bar })));
const LazyDoughnut = React.lazy(() => import('react-chartjs-2').then(module => ({ default: module.Doughnut })));
interface ChartLoaderProps {
type: 'bar' | 'doughnut';
data: any;
options?: any;
[key: string]: any;
}
const ChartLoader: React.FC<ChartLoaderProps> = ({ type, ...props }) => {
const ChartComponent = type === 'bar' ? LazyBar : LazyDoughnut;
return (
<Suspense fallback={<Spin size="large" />}>
<ChartComponent {...props} />
</Suspense>
);
};
export default ChartLoader;

View File

@@ -1,12 +1,12 @@
import React, { ReactNode } from 'react';
import ProjectViewInsights from '@/pages/projects/projectView/insights/project-view-insights';
import ProjectViewFiles from '@/pages/projects/projectView/files/project-view-files';
import ProjectViewMembers from '@/pages/projects/projectView/members/project-view-members';
import ProjectViewUpdates from '@/pages/projects/project-view-1/updates/project-view-updates';
import ProjectViewTaskList from '@/pages/projects/projectView/taskList/project-view-task-list';
import ProjectViewBoard from '@/pages/projects/projectView/board/project-view-board';
import ProjectViewEnhancedTasks from '@/pages/projects/projectView/enhancedTasks/project-view-enhanced-tasks';
import ProjectViewEnhancedBoard from '@/pages/projects/projectView/enhancedBoard/project-view-enhanced-board';
// Lazy load all project view components to reduce initial bundle size
const ProjectViewInsights = React.lazy(() => import('@/pages/projects/projectView/insights/project-view-insights'));
const ProjectViewFiles = React.lazy(() => import('@/pages/projects/projectView/files/project-view-files'));
const ProjectViewMembers = React.lazy(() => import('@/pages/projects/projectView/members/project-view-members'));
const ProjectViewUpdates = React.lazy(() => import('@/pages/projects/project-view-1/updates/project-view-updates'));
const ProjectViewEnhancedTasks = React.lazy(() => import('@/pages/projects/projectView/enhancedTasks/project-view-enhanced-tasks'));
const ProjectViewEnhancedBoard = React.lazy(() => import('@/pages/projects/projectView/enhancedBoard/project-view-enhanced-board'));
// type of a tab items
type TabItems = {
@@ -28,57 +28,31 @@ export const tabItems: TabItems[] = [
},
{
index: 1,
key: 'task-list-v1',
label: 'Task List v1',
isPinned: true,
element: React.createElement(ProjectViewTaskList),
},
{
index: 2,
key: 'board',
label: 'Board',
isPinned: true,
element: React.createElement(ProjectViewEnhancedBoard),
},
{
index: 3,
key: 'board-v1',
label: 'Board v1',
isPinned: true,
element: React.createElement(ProjectViewBoard),
},
// {
// index: 3,
// key: 'workload',
// label: 'Workload',
// element: React.createElement(ProjectViewWorkload),
// },
// {
// index: 4,
// key: 'roadmap',
// label: 'Roadmap',
// element: React.createElement(ProjectViewRoadmap),
// },
{
index: 5,
index: 2,
key: 'project-insights-member-overview',
label: 'Insights',
element: React.createElement(ProjectViewInsights),
},
{
index: 6,
index: 3,
key: 'all-attachments',
label: 'Files',
element: React.createElement(ProjectViewFiles),
},
{
index: 7,
index: 4,
key: 'members',
label: 'Members',
element: React.createElement(ProjectViewMembers),
},
{
index: 8,
index: 5,
key: 'updates',
label: 'Updates',
element: React.createElement(ProjectViewUpdates),

View File

@@ -1,4 +1,10 @@
import {
import {
Button,
Dropdown,
Flex,
Tag,
Tooltip,
Typography,
ArrowLeftOutlined,
BellFilled,
BellOutlined,
@@ -9,10 +15,9 @@ import {
SaveOutlined,
SettingOutlined,
SyncOutlined,
UsergroupAddOutlined,
} from '@ant-design/icons';
UsergroupAddOutlined
} from '@/shared/antd-imports';
import { PageHeader } from '@ant-design/pro-components';
import { Button, Dropdown, Flex, Tag, Tooltip, Typography } from 'antd';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';

View File

@@ -1,9 +1,20 @@
import React, { useEffect, useState, useMemo, useCallback } from 'react';
import { PushpinFilled, PushpinOutlined, QuestionCircleOutlined } from '@ant-design/icons';
import { Badge, Button, ConfigProvider, Flex, Tabs, TabsProps, Tooltip } from 'antd';
import { useLocation, useNavigate, useParams, useSearchParams } from 'react-router-dom';
import { createPortal } from 'react-dom';
// Centralized Ant Design imports
import {
Button,
ConfigProvider,
Flex,
Tooltip,
Badge,
Tabs,
PushpinFilled,
PushpinOutlined,
type TabsProps
} from '@/shared/antd-imports';
import { useAppDispatch } from '@/hooks/useAppDispatch';
import { useAppSelector } from '@/hooks/useAppSelector';
import { getProject, setProjectId, setProjectView } from '@/features/project/project.slice';

View File

@@ -1,4 +1,5 @@
import { useEffect, useState, useMemo, lazy, Suspense } from 'react';
import { Empty } from '@/shared/antd-imports';
import Flex from 'antd/es/flex';
import Skeleton from 'antd/es/skeleton';
import { useSearchParams } from 'react-router-dom';
@@ -10,7 +11,6 @@ import { useAppDispatch } from '@/hooks/useAppDispatch';
import { fetchTaskGroups, fetchTaskListColumns } from '@/features/tasks/tasks.slice';
import { fetchStatusesCategories } from '@/features/taskAttributes/taskStatusSlice';
import { fetchPhasesByProjectId } from '@/features/projects/singleProject/phase/phases.slice';
import { Empty } from 'antd';
import useTabSearchParam from '@/hooks/useTabSearchParam';
const ProjectViewTaskList = () => {

View File

@@ -0,0 +1,198 @@
/**
* Optimized Ant Design imports for maximum tree-shaking
*
* This file provides:
* - Granular imports from antd/es for better tree-shaking
* - Only commonly used components to reduce bundle size
* - Separate icon imports to avoid loading entire icon set
*/
// Core Components - Import as default exports for better tree-shaking
import Button from 'antd/es/button';
import Input from 'antd/es/input';
import Select from 'antd/es/select';
import Typography from 'antd/es/typography';
import Card from 'antd/es/card';
import Spin from 'antd/es/spin';
import Empty from 'antd/es/empty';
import Space from 'antd/es/space';
import Tooltip from 'antd/es/tooltip';
import Badge from 'antd/es/badge';
import Popconfirm from 'antd/es/popconfirm';
import Checkbox from 'antd/es/checkbox';
import Dropdown from 'antd/es/dropdown';
import Menu from 'antd/es/menu';
import Modal from 'antd/es/modal';
import Tag from 'antd/es/tag';
import Avatar from 'antd/es/avatar';
import List from 'antd/es/list';
import Table from 'antd/es/table';
import Flex from 'antd/es/flex';
import Divider from 'antd/es/divider';
import Progress from 'antd/es/progress';
import Result from 'antd/es/result';
import Skeleton from 'antd/es/skeleton';
import Alert from 'antd/es/alert';
import Tabs from 'antd/es/tabs';
import ConfigProvider from 'antd/es/config-provider';
// Date & Time Components
import DatePicker from 'antd/es/date-picker';
import TimePicker from 'antd/es/time-picker';
// Form Components
import Form from 'antd/es/form';
import InputNumber from 'antd/es/input-number';
// Layout Components
import Row from 'antd/es/row';
import Col from 'antd/es/col';
import Layout from 'antd/es/layout';
import Drawer from 'antd/es/drawer';
// Message and Notification - Import separately
import message from 'antd/es/message';
import notification from 'antd/es/notification';
// Theme
import theme from 'antd/es/theme';
// Re-export all components
export {
Button,
Input,
Select,
Typography,
Card,
Spin,
Empty,
Space,
Tooltip,
Badge,
Popconfirm,
Checkbox,
Dropdown,
Menu,
Modal,
Tag,
Avatar,
List,
Table,
Flex,
Divider,
Progress,
Result,
Skeleton,
Alert,
Tabs,
ConfigProvider,
DatePicker,
TimePicker,
Form,
InputNumber,
Row,
Col,
Layout,
Drawer,
message,
notification,
theme
};
// Icons - Import only commonly used ones
export {
EditOutlined,
DeleteOutlined,
PlusOutlined,
MoreOutlined,
CheckOutlined,
CloseOutlined,
CalendarOutlined,
ClockCircleOutlined,
UserOutlined,
TeamOutlined,
TagOutlined,
BarsOutlined,
AppstoreOutlined,
FilterOutlined,
SearchOutlined,
SettingOutlined,
DownOutlined,
RightOutlined,
LeftOutlined,
UpOutlined,
ArrowLeftOutlined,
BellFilled,
BellOutlined,
SaveOutlined,
SyncOutlined,
PushpinFilled,
PushpinOutlined,
UsergroupAddOutlined,
ImportOutlined
} from '@ant-design/icons';
// TypeScript Types - Import only commonly used ones
export type {
ButtonProps,
InputProps,
InputRef,
SelectProps,
TypographyProps,
CardProps,
TooltipProps,
DropdownProps,
MenuProps,
DatePickerProps,
FormProps,
FormInstance,
FlexProps,
TabsProps,
TableProps,
TableColumnsType
} from 'antd';
// Dayjs
export { default as dayjs } from 'dayjs';
export type { Dayjs } from 'dayjs';
// Optimized message utilities
export const appMessage = {
success: (content: string) => message.success(content),
error: (content: string) => message.error(content),
warning: (content: string) => message.warning(content),
info: (content: string) => message.info(content),
loading: (content: string) => message.loading(content),
};
export const appNotification = {
success: (config: any) => notification.success(config),
error: (config: any) => notification.error(config),
warning: (config: any) => notification.warning(config),
info: (config: any) => notification.info(config),
};
// Default configurations
export const antdConfig = {
datePickerDefaults: {
format: 'MMM DD, YYYY',
placeholder: 'Set Date',
size: 'small' as const,
},
buttonDefaults: {
size: 'small' as const,
},
inputDefaults: {
size: 'small' as const,
},
selectDefaults: {
size: 'small' as const,
showSearch: true,
},
};
export default {
config: antdConfig,
message: appMessage,
notification: appNotification,
};