refactor(enhanced-kanban): improve code readability and integrate TaskListFilters component

- Refactored EnhancedKanbanBoard and EnhancedKanbanGroup components for better code organization and readability.
- Integrated TaskListFilters component to enhance task filtering capabilities within the kanban board.
- Cleaned up unnecessary whitespace and improved formatting for consistency across the codebase.
This commit is contained in:
shancds
2025-06-23 10:13:47 +05:30
parent f7ba4f202b
commit 67c26a973e
2 changed files with 60 additions and 49 deletions

View File

@@ -23,16 +23,18 @@ import {
verticalListSortingStrategy, verticalListSortingStrategy,
} from '@dnd-kit/sortable'; } from '@dnd-kit/sortable';
import { RootState } from '@/app/store'; import { RootState } from '@/app/store';
import { import {
fetchEnhancedKanbanGroups, fetchEnhancedKanbanGroups,
reorderEnhancedKanbanTasks, reorderEnhancedKanbanTasks,
setDragState setDragState
} from '@/features/enhanced-kanban/enhanced-kanban.slice'; } from '@/features/enhanced-kanban/enhanced-kanban.slice';
import EnhancedKanbanGroup from './EnhancedKanbanGroup'; import EnhancedKanbanGroup from './EnhancedKanbanGroup';
import EnhancedKanbanTaskCard from './EnhancedKanbanTaskCard'; import EnhancedKanbanTaskCard from './EnhancedKanbanTaskCard';
import PerformanceMonitor from './PerformanceMonitor'; import PerformanceMonitor from './PerformanceMonitor';
import './EnhancedKanbanBoard.css'; import './EnhancedKanbanBoard.css';
// Import the TaskListFilters component
const TaskListFilters = React.lazy(() => import('@/pages/projects/projectView/taskList/task-list-filters/task-list-filters'));
interface EnhancedKanbanBoardProps { interface EnhancedKanbanBoardProps {
projectId: string; projectId: string;
className?: string; className?: string;
@@ -40,14 +42,14 @@ interface EnhancedKanbanBoardProps {
const EnhancedKanbanBoard: React.FC<EnhancedKanbanBoardProps> = ({ projectId, className = '' }) => { const EnhancedKanbanBoard: React.FC<EnhancedKanbanBoardProps> = ({ projectId, className = '' }) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const { const {
taskGroups, taskGroups,
loadingGroups, loadingGroups,
error, error,
dragState, dragState,
performanceMetrics performanceMetrics
} = useSelector((state: RootState) => state.enhancedKanbanReducer); } = useSelector((state: RootState) => state.enhancedKanbanReducer);
// Local state for drag overlay // Local state for drag overlay
const [activeTask, setActiveTask] = useState<any>(null); const [activeTask, setActiveTask] = useState<any>(null);
const [activeGroup, setActiveGroup] = useState<any>(null); const [activeGroup, setActiveGroup] = useState<any>(null);
@@ -70,12 +72,12 @@ const EnhancedKanbanBoard: React.FC<EnhancedKanbanBoardProps> = ({ projectId, cl
}, [dispatch, projectId]); }, [dispatch, projectId]);
// Get all task IDs for sortable context // Get all task IDs for sortable context
const allTaskIds = useMemo(() => const allTaskIds = useMemo(() =>
taskGroups.flatMap(group => group.tasks.map(task => task.id!)), taskGroups.flatMap(group => group.tasks.map(task => task.id!)),
[taskGroups] [taskGroups]
); );
const allGroupIds = useMemo(() => const allGroupIds = useMemo(() =>
taskGroups.map(group => group.id), taskGroups.map(group => group.id),
[taskGroups] [taskGroups]
); );
@@ -86,13 +88,13 @@ const EnhancedKanbanBoard: React.FC<EnhancedKanbanBoardProps> = ({ projectId, cl
const intersections = pointerIntersections.length > 0 const intersections = pointerIntersections.length > 0
? pointerIntersections ? pointerIntersections
: rectIntersection(args); : rectIntersection(args);
let overId = getFirstCollision(intersections, 'id'); let overId = getFirstCollision(intersections, 'id');
if (overId) { if (overId) {
// Check if we're over a task or a group // Check if we're over a task or a group
const overGroup = taskGroups.find(g => g.id === overId); const overGroup = taskGroups.find(g => g.id === overId);
if (overGroup) { if (overGroup) {
// We're over a group, check if there are tasks in it // We're over a group, check if there are tasks in it
if (overGroup.tasks.length > 0) { if (overGroup.tasks.length > 0) {
@@ -103,7 +105,7 @@ const EnhancedKanbanBoard: React.FC<EnhancedKanbanBoardProps> = ({ projectId, cl
(container: any) => container.data.current?.type === 'task' (container: any) => container.data.current?.type === 'task'
), ),
}); });
if (taskIntersections.length > 0) { if (taskIntersections.length > 0) {
overId = taskIntersections[0].id; overId = taskIntersections[0].id;
} }
@@ -117,11 +119,11 @@ const EnhancedKanbanBoard: React.FC<EnhancedKanbanBoardProps> = ({ projectId, cl
const handleDragStart = (event: DragStartEvent) => { const handleDragStart = (event: DragStartEvent) => {
const { active } = event; const { active } = event;
const activeId = active.id as string; const activeId = active.id as string;
// Find the active task and group // Find the active task and group
let foundTask = null; let foundTask = null;
let foundGroup = null; let foundGroup = null;
for (const group of taskGroups) { for (const group of taskGroups) {
const task = group.tasks.find(t => t.id === activeId); const task = group.tasks.find(t => t.id === activeId);
if (task) { if (task) {
@@ -133,7 +135,7 @@ const EnhancedKanbanBoard: React.FC<EnhancedKanbanBoardProps> = ({ projectId, cl
setActiveTask(foundTask); setActiveTask(foundTask);
setActiveGroup(foundGroup); setActiveGroup(foundGroup);
// Update Redux drag state // Update Redux drag state
dispatch(setDragState({ dispatch(setDragState({
activeTaskId: activeId, activeTaskId: activeId,
@@ -144,7 +146,7 @@ const EnhancedKanbanBoard: React.FC<EnhancedKanbanBoardProps> = ({ projectId, cl
const handleDragOver = (event: DragOverEvent) => { const handleDragOver = (event: DragOverEvent) => {
const { active, over } = event; const { active, over } = event;
if (!over) { if (!over) {
setOverId(null); setOverId(null);
dispatch(setDragState({ overId: null })); dispatch(setDragState({ overId: null }));
@@ -153,21 +155,21 @@ const EnhancedKanbanBoard: React.FC<EnhancedKanbanBoardProps> = ({ projectId, cl
const activeId = active.id as string; const activeId = active.id as string;
const overId = over.id as string; const overId = over.id as string;
setOverId(overId); setOverId(overId);
// Update over ID in Redux // Update over ID in Redux
dispatch(setDragState({ overId })); dispatch(setDragState({ overId }));
}; };
const handleDragEnd = (event: DragEndEvent) => { const handleDragEnd = (event: DragEndEvent) => {
const { active, over } = event; const { active, over } = event;
// Reset local state // Reset local state
setActiveTask(null); setActiveTask(null);
setActiveGroup(null); setActiveGroup(null);
setOverId(null); setOverId(null);
// Reset Redux drag state // Reset Redux drag state
dispatch(setDragState({ dispatch(setDragState({
activeTaskId: null, activeTaskId: null,
@@ -258,8 +260,17 @@ const EnhancedKanbanBoard: React.FC<EnhancedKanbanBoardProps> = ({ projectId, cl
return ( return (
<div className={`enhanced-kanban-board ${className}`}> <div className={`enhanced-kanban-board ${className}`}>
{/* Performance Monitor - only show for large datasets */} {/* Performance Monitor - only show for large datasets */}
{performanceMetrics.totalTasks > 100 && <PerformanceMonitor />} {/* {performanceMetrics.totalTasks > 100 && <PerformanceMonitor />} */}
<Card
size="small"
className="mb-4"
styles={{ body: { padding: '12px 16px' } }}
>
<React.Suspense fallback={<div>Loading filters...</div>}>
<TaskListFilters position="board" />
</React.Suspense>
</Card>
{loadingGroups ? ( {loadingGroups ? (
<Card> <Card>
<div className="flex justify-center items-center py-8"> <div className="flex justify-center items-center py-8">
@@ -281,11 +292,11 @@ const EnhancedKanbanBoard: React.FC<EnhancedKanbanBoardProps> = ({ projectId, cl
<SortableContext items={allGroupIds} strategy={horizontalListSortingStrategy}> <SortableContext items={allGroupIds} strategy={horizontalListSortingStrategy}>
<div className="kanban-groups-container"> <div className="kanban-groups-container">
{taskGroups.map(group => ( {taskGroups.map(group => (
<EnhancedKanbanGroup <EnhancedKanbanGroup
key={group.id} key={group.id}
group={group} group={group}
activeTaskId={dragState.activeTaskId} activeTaskId={dragState.activeTaskId}
overId={overId} overId={overId as string | null}
/> />
))} ))}
</div> </div>
@@ -293,8 +304,8 @@ const EnhancedKanbanBoard: React.FC<EnhancedKanbanBoardProps> = ({ projectId, cl
<DragOverlay> <DragOverlay>
{activeTask && ( {activeTask && (
<EnhancedKanbanTaskCard <EnhancedKanbanTaskCard
task={activeTask} task={activeTask}
isDragOverlay={true} isDragOverlay={true}
/> />
)} )}

View File

@@ -15,10 +15,10 @@ interface EnhancedKanbanGroupProps {
// Performance threshold for virtualization // Performance threshold for virtualization
const VIRTUALIZATION_THRESHOLD = 50; const VIRTUALIZATION_THRESHOLD = 50;
const EnhancedKanbanGroup: React.FC<EnhancedKanbanGroupProps> = React.memo(({ const EnhancedKanbanGroup: React.FC<EnhancedKanbanGroupProps> = React.memo(({
group, group,
activeTaskId, activeTaskId,
overId overId
}) => { }) => {
const { setNodeRef, isOver } = useDroppable({ const { setNodeRef, isOver } = useDroppable({
id: group.id, id: group.id,
@@ -33,7 +33,7 @@ const EnhancedKanbanGroup: React.FC<EnhancedKanbanGroupProps> = React.memo(({
// Get task IDs for sortable context // Get task IDs for sortable context
const taskIds = group.tasks.map(task => task.id!); const taskIds = group.tasks.map(task => task.id!);
// Check if this group is the target for dropping // Check if this group is the target for dropping
const isTargetGroup = overId === group.id; const isTargetGroup = overId === group.id;
const isDraggingOver = isOver || isTargetGroup; const isDraggingOver = isOver || isTargetGroup;
@@ -56,7 +56,7 @@ const EnhancedKanbanGroup: React.FC<EnhancedKanbanGroupProps> = React.memo(({
// Memoize task rendering to prevent unnecessary re-renders // Memoize task rendering to prevent unnecessary re-renders
const renderTask = useMemo(() => (task: any, index: number) => ( const renderTask = useMemo(() => (task: any, index: number) => (
<EnhancedKanbanTaskCard <EnhancedKanbanTaskCard
key={task.id} key={task.id}
task={task} task={task}
isActive={task.id === activeTaskId} isActive={task.id === activeTaskId}
@@ -68,7 +68,7 @@ const EnhancedKanbanGroup: React.FC<EnhancedKanbanGroupProps> = React.memo(({
const shouldShowDropIndicators = isDraggingOver && !shouldVirtualize; const shouldShowDropIndicators = isDraggingOver && !shouldVirtualize;
return ( return (
<div <div
ref={setNodeRef} ref={setNodeRef}
className={`enhanced-kanban-group ${isDraggingOver ? 'drag-over' : ''}`} className={`enhanced-kanban-group ${isDraggingOver ? 'drag-over' : ''}`}
> >
@@ -81,14 +81,14 @@ const EnhancedKanbanGroup: React.FC<EnhancedKanbanGroupProps> = React.memo(({
</span> </span>
)} )}
</div> </div>
<div className="enhanced-kanban-group-tasks" ref={groupRef}> <div className="enhanced-kanban-group-tasks" ref={groupRef}>
{group.tasks.length === 0 && isDraggingOver && ( {group.tasks.length === 0 && isDraggingOver && (
<div className="drop-preview-empty"> <div className="drop-preview-empty">
<div className="drop-indicator">Drop here</div> <div className="drop-indicator">Drop here</div>
</div> </div>
)} )}
{shouldVirtualize ? ( {shouldVirtualize ? (
// Use virtualization for large task lists // Use virtualization for large task lists
<SortableContext items={taskIds} strategy={verticalListSortingStrategy}> <SortableContext items={taskIds} strategy={verticalListSortingStrategy}>
@@ -112,21 +112,21 @@ const EnhancedKanbanGroup: React.FC<EnhancedKanbanGroupProps> = React.memo(({
<div className="drop-line"></div> <div className="drop-line"></div>
</div> </div>
)} )}
<EnhancedKanbanTaskCard <EnhancedKanbanTaskCard
task={task} task={task}
isActive={task.id === activeTaskId} isActive={task.id === activeTaskId}
isDropTarget={overId === task.id} isDropTarget={overId === task.id}
/> />
{/* Show drop indicator after last task if dropping at the end */} {/* Show drop indicator after last task if dropping at the end */}
{shouldShowDropIndicators && {shouldShowDropIndicators &&
index === group.tasks.length - 1 && index === group.tasks.length - 1 &&
overId === group.id && ( overId === group.id && (
<div className="drop-preview-indicator"> <div className="drop-preview-indicator">
<div className="drop-line"></div> <div className="drop-line"></div>
</div> </div>
)} )}
</React.Fragment> </React.Fragment>
))} ))}
</SortableContext> </SortableContext>