From 278e221c759b24e8e3234b88329b34cba00d9bda Mon Sep 17 00:00:00 2001 From: chamikaJ Date: Fri, 11 Jul 2025 11:18:30 +0530 Subject: [PATCH] feat(task-list): add TaskListSkeleton component for improved loading state - Introduced TaskListSkeleton to provide a visual loading state for the task list, enhancing user experience during data fetching. - Updated TaskListV2Table to utilize TaskListSkeleton instead of a generic Skeleton component, allowing for a more tailored loading interface. - The new skeleton component includes customizable column widths and multiple rows to better represent the task list structure while loading. --- .../task-list-v2/TaskListV2Table.tsx | 5 +- .../components/TaskListSkeleton.tsx | 178 ++++++++++++++++++ 2 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 worklenz-frontend/src/components/task-list-v2/components/TaskListSkeleton.tsx diff --git a/worklenz-frontend/src/components/task-list-v2/TaskListV2Table.tsx b/worklenz-frontend/src/components/task-list-v2/TaskListV2Table.tsx index ac5227fe..c208882f 100644 --- a/worklenz-frontend/src/components/task-list-v2/TaskListV2Table.tsx +++ b/worklenz-frontend/src/components/task-list-v2/TaskListV2Table.tsx @@ -63,6 +63,7 @@ import OptimizedBulkActionBar from '@/components/task-management/optimized-bulk- import CustomColumnModal from '@/pages/projects/projectView/taskList/task-list-table/custom-columns/custom-column-modal/custom-column-modal'; import AddTaskRow from './components/AddTaskRow'; import { AddCustomColumnButton, CustomColumnHeader } from './components/CustomColumnComponents'; +import TaskListSkeleton from './components/TaskListSkeleton'; // Hooks and utilities import { useTaskSocketHandlers } from '@/hooks/useTaskSocketHandlers'; @@ -597,7 +598,9 @@ const TaskListV2Section: React.FC = () => { ); // Loading and error states - if (loading || loadingColumns) return ; + if (loading || loadingColumns) { + return ; + } if (error) return (
diff --git a/worklenz-frontend/src/components/task-list-v2/components/TaskListSkeleton.tsx b/worklenz-frontend/src/components/task-list-v2/components/TaskListSkeleton.tsx new file mode 100644 index 00000000..54351f60 --- /dev/null +++ b/worklenz-frontend/src/components/task-list-v2/components/TaskListSkeleton.tsx @@ -0,0 +1,178 @@ +import React from 'react'; +import { Skeleton } from 'antd'; +import ImprovedTaskFilters from '@/components/task-management/improved-task-filters'; + +interface TaskListSkeletonProps { + visibleColumns?: Array<{ + id: string; + width: string; + isSticky?: boolean; + }>; +} + +const TaskListSkeleton: React.FC = ({ visibleColumns }) => { + // Default columns if none provided + const defaultColumns = [ + { id: 'dragHandle', width: '40px' }, + { id: 'checkbox', width: '40px' }, + { id: 'taskKey', width: '100px' }, + { id: 'title', width: '300px' }, + { id: 'assignees', width: '120px' }, + { id: 'status', width: '120px' }, + { id: 'priority', width: '100px' }, + { id: 'dueDate', width: '120px' }, + ]; + + const columns = visibleColumns || defaultColumns; + + // Generate multiple skeleton rows + const skeletonRows = Array.from({ length: 8 }, (_, index) => ( +
+ {columns.map((column, colIndex) => { + const columnStyle = { + width: column.width, + flexShrink: 0, + }; + + return ( +
+ {column.id === 'dragHandle' || column.id === 'checkbox' ? ( + + ) : column.id === 'title' ? ( +
+ +
+ ) : column.id === 'assignees' ? ( +
+ + +
+ ) : ( + + )} +
+ ); + })} +
+ )); + + return ( +
+
+ {/* Table Container */} +
+ {/* Skeleton Content */} +
+ {/* Skeleton Column Headers */} +
+
+ {columns.map((column, index) => { + const columnStyle = { + width: column.width, + flexShrink: 0, + }; + + return ( +
+ {column.id === 'dragHandle' || column.id === 'checkbox' ? ( + + ) : ( + + )} +
+ ); + })} + {/* Add Custom Column Button Skeleton */} +
+ +
+
+
+ + {/* Skeleton Group Headers and Rows */} +
+ {/* First Group */} +
+ {/* Group Header Skeleton */} +
+ +
+ +
+ +
+ + {/* Group Tasks Skeleton */} + {skeletonRows.slice(0, 3)} +
+ + {/* Second Group */} +
+ {/* Group Header Skeleton */} +
+ +
+ +
+ +
+ + {/* Group Tasks Skeleton */} + {skeletonRows.slice(3, 6)} +
+ + {/* Third Group */} +
+ {/* Group Header Skeleton */} +
+ +
+ +
+ +
+ + {/* Group Tasks Skeleton */} + {skeletonRows.slice(6, 8)} +
+
+
+
+
+
+ ); +}; + +export default TaskListSkeleton; \ No newline at end of file