From e05169b7b4a0142dcfc7ac68e0a97758cbb8b00a Mon Sep 17 00:00:00 2001 From: shancds Date: Thu, 3 Jul 2025 11:33:31 +0530 Subject: [PATCH] refactor(enhanced-kanban): simplify EnhancedKanbanBoardNativeDnD component - Removed unused imports and commented-out code to clean up the component. - Consolidated task and group rendering logic by importing KanbanGroup directly. - Streamlined the code structure for better readability and maintainability. --- .../EnhancedKanbanBoardNativeDnD.tsx | 105 +----------------- .../KanbanGroup.tsx | 88 +++++++++++++++ .../EnhancedKanbanBoardNativeDnD/TaskCard.tsx | 64 +++++++++++ .../EnhancedKanbanBoardNativeDnD/index.ts | 3 + 4 files changed, 157 insertions(+), 103 deletions(-) create mode 100644 worklenz-frontend/src/components/enhanced-kanban/EnhancedKanbanBoardNativeDnD/KanbanGroup.tsx create mode 100644 worklenz-frontend/src/components/enhanced-kanban/EnhancedKanbanBoardNativeDnD/TaskCard.tsx create mode 100644 worklenz-frontend/src/components/enhanced-kanban/EnhancedKanbanBoardNativeDnD/index.ts diff --git a/worklenz-frontend/src/components/enhanced-kanban/EnhancedKanbanBoardNativeDnD/EnhancedKanbanBoardNativeDnD.tsx b/worklenz-frontend/src/components/enhanced-kanban/EnhancedKanbanBoardNativeDnD/EnhancedKanbanBoardNativeDnD.tsx index 2c87afe7..01600dfb 100644 --- a/worklenz-frontend/src/components/enhanced-kanban/EnhancedKanbanBoardNativeDnD/EnhancedKanbanBoardNativeDnD.tsx +++ b/worklenz-frontend/src/components/enhanced-kanban/EnhancedKanbanBoardNativeDnD/EnhancedKanbanBoardNativeDnD.tsx @@ -1,8 +1,6 @@ -import React, { useState, useEffect, useMemo } from 'react'; +import React, { useState, useEffect } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { RootState } from '@/app/store'; -import { ITaskListGroup } from '@/types/tasks/taskList.types'; -import { IProjectTask } from '@/types/project/projectTasksViewModel.types'; import '../EnhancedKanbanBoard.css'; import '../EnhancedKanbanGroup.css'; import '../EnhancedKanbanTaskCard.css'; @@ -13,108 +11,9 @@ import Empty from 'antd/es/empty'; import { reorderGroups, reorderEnhancedKanbanGroups, reorderTasks, reorderEnhancedKanbanTasks, fetchEnhancedKanbanLabels, fetchEnhancedKanbanGroups, fetchEnhancedKanbanTaskAssignees } from '@/features/enhanced-kanban/enhanced-kanban.slice'; import { fetchStatusesCategories } from '@/features/taskAttributes/taskStatusSlice'; import { useAppSelector } from '@/hooks/useAppSelector'; +import KanbanGroup from './KanbanGroup'; -// Minimal task card for prototype (reuse your styles) -const TaskCard: React.FC<{ - task: IProjectTask; - onTaskDragStart: (e: React.DragEvent, taskId: string, groupId: string) => void; - onTaskDragOver: (e: React.DragEvent, groupId: string, taskIdx: number) => void; - onTaskDrop: (e: React.DragEvent, groupId: string, taskIdx: number) => void; - groupId: string; - isDropIndicator: boolean; - idx: number; -}> = ({ task, onTaskDragStart, onTaskDragOver, onTaskDrop, groupId, isDropIndicator, idx }) => { - const themeMode = useSelector((state: RootState) => state.themeReducer.mode); - const background = themeMode === 'dark' ? '#23272f' : '#fff'; - const color = themeMode === 'dark' ? '#fff' : '#23272f'; - return ( - <> - {isDropIndicator && ( -
- )} -
onTaskDragStart(e, task.id!, groupId)} - onDragOver={e => onTaskDragOver(e, groupId, idx)} - onDrop={e => onTaskDrop(e, groupId, idx)} - style={{ background, color }} - > -
-
{task.name}
-
{task.task_key}
-
- {task.assignees?.map(a => a.name).join(', ')} -
-
-
- - ); -}; -// Minimal group column for prototype -const KanbanGroup: React.FC<{ - group: ITaskListGroup; - onGroupDragStart: (e: React.DragEvent, groupId: string) => void; - onGroupDragOver: (e: React.DragEvent) => void; - onGroupDrop: (e: React.DragEvent, groupId: string) => void; - onTaskDragStart: (e: React.DragEvent, taskId: string, groupId: string) => void; - onTaskDragOver: (e: React.DragEvent, groupId: string, taskIdx: number) => void; - onTaskDrop: (e: React.DragEvent, groupId: string, taskIdx: number) => void; - hoveredTaskIdx: number | null; - hoveredGroupId: string | null; -}> = ({ group, onGroupDragStart, onGroupDragOver, onGroupDrop, onTaskDragStart, onTaskDragOver, onTaskDrop, hoveredTaskIdx, hoveredGroupId }) => { - const themeMode = useAppSelector(state => state.themeReducer.mode); - const headerBackgroundColor = useMemo(() => { - if (themeMode === 'dark') { - return group.color_code_dark || group.color_code || '#1e1e1e'; - } - return group.color_code || '#f5f5f5'; - }, [themeMode, group.color_code, group.color_code_dark]); - return ( -
-
onGroupDragStart(e, group.id)} - onDragOver={onGroupDragOver} - onDrop={e => onGroupDrop(e, group.id)} - > -

{group.name}

- {group.tasks.length} -
-
onTaskDragOver(e, group.id, 0)} - // onDrop={e => onTaskDrop(e, group.id, 0)} - > - {/* Drop indicator at the top of the group */} - {hoveredGroupId === group.id && hoveredTaskIdx === 0 && ( -
- )} - {group.tasks.map((task, idx) => ( - - - - ))} - {/* Drop indicator at the end of the group */} - {hoveredGroupId === group.id && hoveredTaskIdx === group.tasks.length && ( -
- )} -
-
- ) -}; const EnhancedKanbanBoardNativeDnD: React.FC<{ projectId: string }> = ({ projectId }) => { const dispatch = useDispatch(); diff --git a/worklenz-frontend/src/components/enhanced-kanban/EnhancedKanbanBoardNativeDnD/KanbanGroup.tsx b/worklenz-frontend/src/components/enhanced-kanban/EnhancedKanbanBoardNativeDnD/KanbanGroup.tsx new file mode 100644 index 00000000..f69ad544 --- /dev/null +++ b/worklenz-frontend/src/components/enhanced-kanban/EnhancedKanbanBoardNativeDnD/KanbanGroup.tsx @@ -0,0 +1,88 @@ +import React, { memo, useMemo } from 'react'; +import { useAppSelector } from '@/hooks/useAppSelector'; +import { ITaskListGroup } from '@/types/tasks/taskList.types'; +import TaskCard from './TaskCard'; + +interface KanbanGroupProps { + group: ITaskListGroup; + onGroupDragStart: (e: React.DragEvent, groupId: string) => void; + onGroupDragOver: (e: React.DragEvent) => void; + onGroupDrop: (e: React.DragEvent, groupId: string) => void; + onTaskDragStart: (e: React.DragEvent, taskId: string, groupId: string) => void; + onTaskDragOver: (e: React.DragEvent, groupId: string, taskIdx: number) => void; + onTaskDrop: (e: React.DragEvent, groupId: string, taskIdx: number) => void; + hoveredTaskIdx: number | null; + hoveredGroupId: string | null; +} + +const KanbanGroup: React.FC = memo(({ + group, + onGroupDragStart, + onGroupDragOver, + onGroupDrop, + onTaskDragStart, + onTaskDragOver, + onTaskDrop, + hoveredTaskIdx, + hoveredGroupId +}) => { + const themeMode = useAppSelector(state => state.themeReducer.mode); + + const headerBackgroundColor = useMemo(() => { + if (themeMode === 'dark') { + return group.color_code_dark || group.color_code || '#1e1e1e'; + } + return group.color_code || '#f5f5f5'; + }, [themeMode, group.color_code, group.color_code_dark]); + + return ( +
+
onGroupDragStart(e, group.id)} + onDragOver={onGroupDragOver} + onDrop={e => onGroupDrop(e, group.id)} + > +

{group.name}

+ {group.tasks.length} +
+
+ {/* Drop indicator at the top of the group */} + {hoveredGroupId === group.id && hoveredTaskIdx === 0 && ( +
+
+
+ )} + + {group.tasks.map((task, idx) => ( + + + + ))} + + {/* Drop indicator at the end of the group */} + {hoveredGroupId === group.id && hoveredTaskIdx === group.tasks.length && ( +
+
+
+ )} +
+
+ ); +}); + +KanbanGroup.displayName = 'KanbanGroup'; + +export default KanbanGroup; \ No newline at end of file diff --git a/worklenz-frontend/src/components/enhanced-kanban/EnhancedKanbanBoardNativeDnD/TaskCard.tsx b/worklenz-frontend/src/components/enhanced-kanban/EnhancedKanbanBoardNativeDnD/TaskCard.tsx new file mode 100644 index 00000000..f70761c6 --- /dev/null +++ b/worklenz-frontend/src/components/enhanced-kanban/EnhancedKanbanBoardNativeDnD/TaskCard.tsx @@ -0,0 +1,64 @@ +import React, { memo } from 'react'; +import { useSelector } from 'react-redux'; +import { RootState } from '@/app/store'; +import { IProjectTask } from '@/types/project/projectTasksViewModel.types'; + +interface TaskCardProps { + task: IProjectTask; + onTaskDragStart: (e: React.DragEvent, taskId: string, groupId: string) => void; + onTaskDragOver: (e: React.DragEvent, groupId: string, taskIdx: number) => void; + onTaskDrop: (e: React.DragEvent, groupId: string, taskIdx: number) => void; + groupId: string; + isDropIndicator: boolean; + idx: number; +} + +const TaskCard: React.FC = memo(({ + task, + onTaskDragStart, + onTaskDragOver, + onTaskDrop, + groupId, + isDropIndicator, + idx +}) => { + const themeMode = useSelector((state: RootState) => state.themeReducer.mode); + const background = themeMode === 'dark' ? '#23272f' : '#fff'; + const color = themeMode === 'dark' ? '#fff' : '#23272f'; + + return ( + <> + {isDropIndicator && ( +
+ )} +
onTaskDragStart(e, task.id!, groupId)} + onDragOver={e => onTaskDragOver(e, groupId, idx)} + onDrop={e => onTaskDrop(e, groupId, idx)} + style={{ background, color }} + > +
+
{task.name}
+
{task.task_key}
+
+ {task.assignees?.map(a => a.name).join(', ')} +
+
+
+ + ); +}); + +TaskCard.displayName = 'TaskCard'; + +export default TaskCard; \ No newline at end of file diff --git a/worklenz-frontend/src/components/enhanced-kanban/EnhancedKanbanBoardNativeDnD/index.ts b/worklenz-frontend/src/components/enhanced-kanban/EnhancedKanbanBoardNativeDnD/index.ts new file mode 100644 index 00000000..1ddc40f1 --- /dev/null +++ b/worklenz-frontend/src/components/enhanced-kanban/EnhancedKanbanBoardNativeDnD/index.ts @@ -0,0 +1,3 @@ +export { default } from './EnhancedKanbanBoardNativeDnD'; +export { default as TaskCard } from './TaskCard'; +export { default as KanbanGroup } from './KanbanGroup'; \ No newline at end of file