- Added taskManagementReducer, groupingReducer, and selectionReducer to the Redux store. - Organized imports and store configuration for better clarity and maintainability.
11 KiB
Enhanced Task Management: Technical Guide
Overview
The Enhanced Task Management system is a comprehensive React-based interface built on top of WorkLenz's existing task infrastructure. It provides a modern, grouped view with drag-and-drop functionality, bulk operations, and responsive design.
Architecture
Component Structure
src/components/task-management/
├── TaskListBoard.tsx # Main container with DnD context
├── TaskGroup.tsx # Individual group with collapse/expand
├── TaskRow.tsx # Task display with rich metadata
├── GroupingSelector.tsx # Grouping method switcher
└── BulkActionBar.tsx # Bulk operations toolbar
Integration Points
The system integrates with existing WorkLenz infrastructure:
- Redux Store: Uses
tasks.slice.tsfor state management - Types: Leverages existing TypeScript interfaces
- API Services: Works with existing task API endpoints
- WebSocket: Supports real-time updates via existing socket system
Core Components
TaskListBoard.tsx
Main orchestrator component that provides:
- DnD Context: @dnd-kit drag-and-drop functionality
- State Management: Redux integration for task data
- Event Handling: Drag events and bulk operations
- Layout Structure: Header controls and group container
Key Props
interface TaskListBoardProps {
projectId: string; // Required: Project identifier
className?: string; // Optional: Additional CSS classes
}
Redux Selectors Used
const {
taskGroups, // ITaskListGroup[] - Grouped task data
loadingGroups, // boolean - Loading state
error, // string | null - Error state
groupBy, // IGroupBy - Current grouping method
search, // string | null - Search filter
archived, // boolean - Show archived tasks
} = useSelector((state: RootState) => state.taskReducer);
TaskGroup.tsx
Renders individual task groups with:
- Collapsible Headers: Expand/collapse functionality
- Progress Indicators: Visual completion progress
- Drop Zones: Accept dropped tasks from other groups
- Group Statistics: Task counts and completion rates
Key Props
interface TaskGroupProps {
group: ITaskListGroup; // Group data with tasks
projectId: string; // Project context
currentGrouping: IGroupBy; // Current grouping mode
selectedTaskIds: string[]; // Selected task IDs
onAddTask?: (groupId: string) => void;
onToggleCollapse?: (groupId: string) => void;
}
TaskRow.tsx
Individual task display featuring:
- Rich Metadata: Progress, assignees, labels, due dates
- Drag Handles: Sortable within and between groups
- Selection: Multi-select with checkboxes
- Subtask Support: Expandable hierarchy display
Key Props
interface TaskRowProps {
task: IProjectTask; // Task data
projectId: string; // Project context
groupId: string; // Parent group ID
currentGrouping: IGroupBy; // Current grouping mode
isSelected: boolean; // Selection state
isDragOverlay?: boolean; // Drag overlay rendering
index?: number; // Position in group
onSelect?: (taskId: string, selected: boolean) => void;
onToggleSubtasks?: (taskId: string) => void;
}
State Management
Redux Integration
The system uses existing WorkLenz Redux patterns:
// Primary slice used
import {
fetchTaskGroups, // Async thunk for loading data
reorderTasks, // Update task order/group
setGroup, // Change grouping method
updateTaskStatus, // Update individual task status
updateTaskPriority, // Update individual task priority
// ... other existing actions
} from '@/features/tasks/tasks.slice';
Data Flow
- Component Mount:
TaskListBoarddispatchesfetchTaskGroups(projectId) - Group Changes:
setGroup(newGroupBy)triggers data reorganization - Drag Operations:
reorderTasks()updates task positions and properties - Real-time Updates: WebSocket events update Redux state automatically
Drag and Drop Implementation
DnD Kit Integration
Uses @dnd-kit for modern, accessible drag-and-drop:
// Sensors for different input methods
const sensors = useSensors(
useSensor(PointerSensor, {
activationConstraint: { distance: 8 }
}),
useSensor(KeyboardSensor, {
coordinateGetter: sortableKeyboardCoordinates
})
);
Drag Event Handling
const handleDragEnd = (event: DragEndEvent) => {
const { active, over } = event;
// Determine source and target
const sourceGroup = findTaskGroup(active.id);
const targetGroup = findTargetGroup(over?.id);
// Update task arrays and dispatch changes
dispatch(reorderTasks({
activeGroupId: sourceGroup.id,
overGroupId: targetGroup.id,
fromIndex: sourceIndex,
toIndex: targetIndex,
task: movedTask,
updatedSourceTasks,
updatedTargetTasks,
}));
};
Smart Property Updates
When tasks are moved between groups, properties update automatically:
- Status Grouping: Moving to "Done" group sets task status to "done"
- Priority Grouping: Moving to "High" group sets task priority to "high"
- Phase Grouping: Moving to "Testing" group sets task phase to "testing"
Bulk Operations
Selection State Management
// Local state for task selection
const [selectedTaskIds, setSelectedTaskIds] = useState<string[]>([]);
// Selection handlers
const handleTaskSelect = (taskId: string, selected: boolean) => {
if (selected) {
setSelectedTaskIds(prev => [...prev, taskId]);
} else {
setSelectedTaskIds(prev => prev.filter(id => id !== taskId));
}
};
Context-Aware Actions
Bulk actions adapt to current grouping:
// Only show status changes when not grouped by status
{currentGrouping !== 'status' && (
<Dropdown overlay={statusMenu}>
<Button>Change Status</Button>
</Dropdown>
)}
Performance Optimizations
Memoized Selectors
// Expensive group calculations are memoized
const taskGroups = useMemo(() => {
return createGroupsFromTasks(tasks, currentGrouping);
}, [tasks, currentGrouping]);
Virtual Scrolling Ready
For large datasets, the system is prepared for react-window integration:
// Large group detection
const shouldVirtualize = group.tasks.length > 100;
return shouldVirtualize ? (
<VirtualizedTaskList tasks={group.tasks} />
) : (
<StandardTaskList tasks={group.tasks} />
);
Optimistic Updates
UI updates immediately while API calls process in background:
// Immediate UI update
dispatch(updateTaskStatusOptimistically(taskId, newStatus));
// API call with rollback on error
try {
await updateTaskStatus(taskId, newStatus);
} catch (error) {
dispatch(rollbackTaskStatusUpdate(taskId));
}
Responsive Design
Breakpoint Strategy
/* Mobile-first responsive design */
.task-row {
padding: 12px;
}
@media (min-width: 768px) {
.task-row {
padding: 16px;
}
}
@media (min-width: 1024px) {
.task-row {
padding: 20px;
}
}
Progressive Enhancement
- Mobile: Essential information only
- Tablet: Additional metadata visible
- Desktop: Full feature set with optimal layout
Accessibility
ARIA Implementation
// Proper ARIA labels for screen readers
<div
role="button"
aria-label={`Move task ${task.name}`}
tabIndex={0}
{...dragHandleProps}
>
<DragOutlined />
</div>
Keyboard Navigation
- Tab: Navigate between elements
- Space: Select/deselect tasks
- Enter: Activate buttons
- Arrows: Navigate sortable lists with keyboard sensor
Focus Management
// Maintain focus during dynamic updates
useEffect(() => {
if (shouldFocusTask) {
taskRef.current?.focus();
}
}, [taskGroups]);
WebSocket Integration
Real-time Updates
The system subscribes to existing WorkLenz WebSocket events:
// Socket event handlers (existing WorkLenz patterns)
socket.on('TASK_STATUS_CHANGED', (data) => {
dispatch(updateTaskStatus(data));
});
socket.on('TASK_PROGRESS_UPDATED', (data) => {
dispatch(updateTaskProgress(data));
});
Live Collaboration
- Multiple users can work simultaneously
- Changes appear in real-time
- Conflict resolution through server-side validation
API Integration
Existing Endpoints Used
// Uses existing WorkLenz API services
import { tasksApiService } from '@/api/tasks/tasks.api.service';
// Task data fetching
tasksApiService.getTaskList(config);
// Task updates
tasksApiService.updateTask(taskId, changes);
// Bulk operations
tasksApiService.bulkUpdateTasks(taskIds, changes);
Error Handling
try {
await dispatch(fetchTaskGroups(projectId));
} catch (error) {
// Display user-friendly error message
message.error('Failed to load tasks. Please try again.');
logger.error('Task loading error:', error);
}
Testing Strategy
Component Testing
// Example test structure
describe('TaskListBoard', () => {
it('should render task groups correctly', () => {
const mockTasks = generateMockTasks(10);
render(<TaskListBoard projectId="test-project" />);
expect(screen.getByText('Tasks (10)')).toBeInTheDocument();
});
it('should handle drag and drop operations', async () => {
// Test drag and drop functionality
});
});
Integration Testing
- Redux state management
- API service integration
- WebSocket event handling
- Drag and drop operations
Development Guidelines
Code Organization
- Follow existing WorkLenz patterns
- Use TypeScript strictly
- Implement proper error boundaries
- Maintain accessibility standards
Performance Considerations
- Memoize expensive calculations
- Implement virtual scrolling for large datasets
- Debounce user input operations
- Optimize re-render cycles
Styling Standards
- Use existing Ant Design components
- Follow WorkLenz design system
- Implement responsive breakpoints
- Maintain dark mode compatibility
Future Enhancements
Planned Features
- Custom column integration
- Advanced filtering capabilities
- Kanban board view
- Enhanced time tracking
- Task templates
Extension Points
The system is designed for easy extension:
// Plugin architecture ready
interface TaskViewPlugin {
name: string;
component: React.ComponentType;
supportedGroupings: IGroupBy[];
}
const plugins: TaskViewPlugin[] = [
{ name: 'kanban', component: KanbanView, supportedGroupings: ['status'] },
{ name: 'timeline', component: TimelineView, supportedGroupings: ['phase'] },
];
Deployment Considerations
Bundle Size
- Tree-shake unused dependencies
- Code-split large components
- Optimize asset loading
Browser Compatibility
- Modern browsers (ES2020+)
- Graceful degradation for older browsers
- Progressive enhancement approach
Performance Monitoring
- Track component render times
- Monitor API response times
- Measure user interaction latency