import React, { useState } from 'react'; import { useDroppable } from '@dnd-kit/core'; import { SortableContext, verticalListSortingStrategy } from '@dnd-kit/sortable'; import { useSelector } from 'react-redux'; import { Button, Typography } from 'antd'; import { PlusOutlined, RightOutlined, DownOutlined } from '@ant-design/icons'; import { ITaskListGroup } from '@/types/tasks/taskList.types'; import { IProjectTask } from '@/types/project/projectTasksViewModel.types'; import { IGroupBy, COLUMN_KEYS } from '@/features/tasks/tasks.slice'; import { RootState } from '@/app/store'; import TaskRow from './TaskRow'; import AddTaskListRow from '@/pages/projects/projectView/taskList/task-list-table/task-list-table-rows/add-task-list-row'; const { Text } = Typography; interface TaskGroupProps { group: ITaskListGroup; projectId: string; currentGrouping: IGroupBy; selectedTaskIds: string[]; onAddTask?: (groupId: string) => void; onToggleCollapse?: (groupId: string) => void; onSelectTask?: (taskId: string, selected: boolean) => void; onToggleSubtasks?: (taskId: string) => void; } const TaskGroup: React.FC = ({ group, projectId, currentGrouping, selectedTaskIds, onAddTask, onToggleCollapse, onSelectTask, onToggleSubtasks, }) => { const [isCollapsed, setIsCollapsed] = useState(false); const { setNodeRef, isOver } = useDroppable({ id: group.id, data: { type: 'group', groupId: group.id, }, }); // Get column visibility from Redux store const columns = useSelector((state: RootState) => state.taskReducer.columns); // Helper function to check if a column is visible const isColumnVisible = (columnKey: string) => { const column = columns.find(col => col.key === columnKey); return column ? column.pinned : true; // Default to visible if column not found }; // Get task IDs for sortable context const taskIds = group.tasks.map(task => task.id!); // Calculate group statistics const completedTasks = group.tasks.filter( task => task.status_category?.is_done || task.complete_ratio === 100 ).length; const totalTasks = group.tasks.length; const completionRate = totalTasks > 0 ? Math.round((completedTasks / totalTasks) * 100) : 0; // Get group color based on grouping type const getGroupColor = () => { if (group.color_code) return group.color_code; // Fallback colors based on group value switch (currentGrouping) { case 'status': return group.id === 'todo' ? '#faad14' : group.id === 'doing' ? '#1890ff' : '#52c41a'; case 'priority': return group.id === 'critical' ? '#ff4d4f' : group.id === 'high' ? '#fa8c16' : group.id === 'medium' ? '#faad14' : '#52c41a'; case 'phase': return '#722ed1'; default: return '#d9d9d9'; } }; const handleToggleCollapse = () => { setIsCollapsed(!isCollapsed); onToggleCollapse?.(group.id); }; const handleAddTask = () => { onAddTask?.(group.id); }; return (
{/* Group Header Row */}
{/* Column Headers */} {!isCollapsed && totalTasks > 0 && (
Key
Task
{isColumnVisible(COLUMN_KEYS.PROGRESS) && (
Progress
)} {isColumnVisible(COLUMN_KEYS.ASSIGNEES) && (
Members
)} {isColumnVisible(COLUMN_KEYS.LABELS) && (
Labels
)} {isColumnVisible(COLUMN_KEYS.STATUS) && (
Status
)} {isColumnVisible(COLUMN_KEYS.PRIORITY) && (
Priority
)} {isColumnVisible(COLUMN_KEYS.TIME_TRACKING) && (
Time Tracking
)}
)} {/* Tasks List */} {!isCollapsed && (
{group.tasks.length === 0 ? (
No tasks in this group
) : (
{group.tasks.map((task, index) => ( ))}
)} {/* Add Task Row - Always show when not collapsed */}
)}
); }; export default TaskGroup;