feat(enhanced-kanban): enhance TaskCard with task selection and improved UI
- Added task selection functionality by dispatching actions on card click to show the task drawer. - Introduced labels display for tasks, enhancing visual organization. - Improved task content layout with priority indicators and due date formatting. - Integrated AvatarGroup and LazyAssigneeSelector for better assignee management and visibility.
This commit is contained in:
@@ -1,7 +1,13 @@
|
||||
import React, { memo } from 'react';
|
||||
import React, { memo, useCallback } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { RootState } from '@/app/store';
|
||||
import { IProjectTask } from '@/types/project/projectTasksViewModel.types';
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
import { setSelectedTaskId, setShowTaskDrawer } from '@/features/task-drawer/task-drawer.slice';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import AvatarGroup from '@/components/AvatarGroup';
|
||||
import LazyAssigneeSelectorWrapper from '@/components/task-management/lazy-assignee-selector';
|
||||
import { format } from 'date-fns';
|
||||
|
||||
interface TaskCardProps {
|
||||
task: IProjectTask;
|
||||
@@ -25,6 +31,15 @@ const TaskCard: React.FC<TaskCardProps> = memo(({
|
||||
const themeMode = useSelector((state: RootState) => state.themeReducer.mode);
|
||||
const background = themeMode === 'dark' ? '#23272f' : '#fff';
|
||||
const color = themeMode === 'dark' ? '#fff' : '#23272f';
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation('kanban-board');
|
||||
|
||||
const handleCardClick = useCallback((e: React.MouseEvent, id: string) => {
|
||||
// Prevent the event from propagating to parent elements
|
||||
e.stopPropagation();
|
||||
dispatch(setSelectedTaskId(id));
|
||||
dispatch(setShowTaskDrawer(true));
|
||||
}, [dispatch]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -32,7 +47,7 @@ const TaskCard: React.FC<TaskCardProps> = memo(({
|
||||
<div
|
||||
style={{
|
||||
height: 80,
|
||||
background: themeMode === 'dark' ? '#2a2a2a' : '#f0f0f0',
|
||||
background: themeMode === 'dark' ? '#2a2a2a' : '#f0f0f0',
|
||||
borderRadius: 6,
|
||||
border: `5px`
|
||||
}}
|
||||
@@ -48,12 +63,51 @@ const TaskCard: React.FC<TaskCardProps> = memo(({
|
||||
onDragOver={e => onTaskDragOver(e, groupId, idx)}
|
||||
onDrop={e => onTaskDrop(e, groupId, idx)}
|
||||
style={{ background, color }}
|
||||
onClick={e => handleCardClick(e, task.id!)}
|
||||
>
|
||||
<div className="task-content">
|
||||
<div className="task-title">{task.name}</div>
|
||||
<div className="task-key">{task.task_key}</div>
|
||||
<div className="task-assignees">
|
||||
{task.assignees?.map(a => a.name).join(', ')}
|
||||
<div className="task_labels" style={{ display: 'flex', gap: 4, marginBottom: 4 }}>
|
||||
{task.labels?.map(label => (
|
||||
<div
|
||||
key={label.id}
|
||||
className="task-label"
|
||||
style={{
|
||||
backgroundColor: label.color_code,
|
||||
display: 'inline-block',
|
||||
borderRadius: '4px',
|
||||
padding: '2px 8px',
|
||||
color: '#fff',
|
||||
fontSize: 8,
|
||||
marginRight: 4,
|
||||
whiteSpace: 'nowrap',
|
||||
minWidth: 0
|
||||
}}
|
||||
>
|
||||
{label.name}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="task-content" style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<div
|
||||
className="w-2 h-2 rounded-full"
|
||||
style={{ backgroundColor: task.priority_color || '#d9d9d9' }}
|
||||
/>
|
||||
<div className="task-title" style={{ marginLeft: 8 }}>{task.name}</div>
|
||||
</div>
|
||||
|
||||
<div className="task-assignees-row" style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', width: '100%' }}>
|
||||
<div className="task-assignees" style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<AvatarGroup
|
||||
members={task.names || []}
|
||||
maxCount={3}
|
||||
isDarkMode={themeMode === 'dark'}
|
||||
size={24}
|
||||
/>
|
||||
<LazyAssigneeSelectorWrapper task={task} groupId={groupId} isDarkMode={themeMode === 'dark'} />
|
||||
</div>
|
||||
<div className="task-due-date" style={{ fontSize: 10, color: '#888', marginLeft: 8, whiteSpace: 'nowrap' }}>
|
||||
{task.end_date ? format(new Date(task.end_date), 'MMM d, yyyy') : ''}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user