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:
@@ -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;
|
||||
Reference in New Issue
Block a user