feat(task-management): enhance task management UI with subtask functionality

- Updated task list components to support subtasks, including TaskRowWithSubtasks for rendering tasks with their subtasks.
- Introduced AddSubtaskRow for adding new subtasks directly within the task list.
- Enhanced TaskRow to handle task expansion and display subtask counts.
- Implemented optimistic updates for subtask creation to improve user experience.
- Added loading states for subtasks to provide visual feedback during data fetching.
- Refactored task management slice to manage subtasks and their loading states effectively.
This commit is contained in:
chamikaJ
2025-07-04 13:24:41 +05:30
parent 6f66367282
commit aab3ffe262
15 changed files with 879 additions and 326 deletions

View File

@@ -0,0 +1,139 @@
import React from 'react';
interface SubtaskLoadingSkeletonProps {
visibleColumns: Array<{
id: string;
width: string;
isSticky?: boolean;
}>;
}
const SubtaskLoadingSkeleton: React.FC<SubtaskLoadingSkeletonProps> = ({ visibleColumns }) => {
const renderColumn = (columnId: string, width: string) => {
const baseStyle = { width };
switch (columnId) {
case 'dragHandle':
return <div style={baseStyle} />;
case 'checkbox':
return <div style={baseStyle} />;
case 'taskKey':
return (
<div style={baseStyle} className="flex items-center">
<div className="h-4 w-12 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
</div>
);
case 'title':
return (
<div style={baseStyle} className="flex items-center">
{/* Subtask indentation */}
<div className="w-8" />
<div className="w-8" />
<div className="h-4 w-32 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
</div>
);
case 'status':
return (
<div style={baseStyle} className="flex items-center">
<div className="h-6 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
</div>
);
case 'assignees':
return (
<div style={baseStyle} className="flex items-center gap-1">
<div className="h-6 w-6 bg-gray-200 dark:bg-gray-700 rounded-full animate-pulse" />
<div className="h-6 w-6 bg-gray-200 dark:bg-gray-700 rounded-full animate-pulse" />
</div>
);
case 'priority':
return (
<div style={baseStyle} className="flex items-center">
<div className="h-6 w-16 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
</div>
);
case 'dueDate':
return (
<div style={baseStyle} className="flex items-center">
<div className="h-4 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
</div>
);
case 'progress':
return (
<div style={baseStyle} className="flex items-center">
<div className="h-2 w-16 bg-gray-200 dark:bg-gray-700 rounded-full animate-pulse" />
</div>
);
case 'labels':
return (
<div style={baseStyle} className="flex items-center gap-1">
<div className="h-5 w-12 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
<div className="h-5 w-16 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
</div>
);
case 'phase':
return (
<div style={baseStyle} className="flex items-center">
<div className="h-6 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
</div>
);
case 'timeTracking':
return (
<div style={baseStyle} className="flex items-center">
<div className="h-4 w-12 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
</div>
);
case 'estimation':
return (
<div style={baseStyle} className="flex items-center">
<div className="h-4 w-10 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
</div>
);
case 'startDate':
return (
<div style={baseStyle} className="flex items-center">
<div className="h-4 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
</div>
);
case 'completedDate':
return (
<div style={baseStyle} className="flex items-center">
<div className="h-4 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
</div>
);
case 'createdDate':
return (
<div style={baseStyle} className="flex items-center">
<div className="h-4 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
</div>
);
case 'lastUpdated':
return (
<div style={baseStyle} className="flex items-center">
<div className="h-4 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
</div>
);
case 'reporter':
return (
<div style={baseStyle} className="flex items-center">
<div className="h-4 w-16 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" />
</div>
);
default:
return <div style={baseStyle} />;
}
};
return (
<div className="bg-gray-50 dark:bg-gray-800/50 border-l-2 border-blue-200 dark:border-blue-700">
<div className="flex items-center min-w-max px-4 py-2 border-b border-gray-200 dark:border-gray-700">
{visibleColumns.map((column) => (
<div key={column.id}>
{renderColumn(column.id, column.width)}
</div>
))}
</div>
</div>
);
};
export default SubtaskLoadingSkeleton;