feat(assignee-selector): enhance real-time updates and UI interactions

- Added socket event handling for quick assignee updates, dispatching changes to the enhanced Kanban state.
- Updated AssigneeSelector component to prevent event propagation on dropdown interactions.
- Integrated AvatarGroup and LazyAssigneeSelectorWrapper in EnhancedKanbanTaskCard for improved assignee display and selection.
This commit is contained in:
shancds
2025-07-01 18:21:52 +05:30
parent 0a92d38ccf
commit 87f73ee4c2
2 changed files with 27 additions and 9 deletions

View File

@@ -14,6 +14,7 @@ import { sortTeamMembers } from '@/utils/sort-team-members';
import { useAppDispatch } from '@/hooks/useAppDispatch';
import { toggleProjectMemberDrawer } from '@/features/projects/singleProject/members/projectMembersSlice';
import { updateTask } from '@/features/task-management/task-management.slice';
import { updateEnhancedKanbanTaskAssignees } from '@/features/enhanced-kanban/enhanced-kanban.slice';
interface AssigneeSelectorProps {
task: IProjectTask;
@@ -177,6 +178,12 @@ const AssigneeSelector: React.FC<AssigneeSelectorProps> = ({
// Emit socket event - the socket handler will update Redux with proper types
socket?.emit(SocketEvents.QUICK_ASSIGNEES_UPDATE.toString(), JSON.stringify(body));
socket?.once(
SocketEvents.QUICK_ASSIGNEES_UPDATE.toString(),
(data: any) => {
dispatch(updateEnhancedKanbanTaskAssignees(data));
}
);
// Remove from pending changes after a short delay (optimistic)
setTimeout(() => {
@@ -226,6 +233,7 @@ const AssigneeSelector: React.FC<AssigneeSelectorProps> = ({
{isOpen && createPortal(
<div
ref={dropdownRef}
onClick={e => e.stopPropagation()}
className={`
fixed z-9999 w-72 rounded-md shadow-lg border
${isDarkMode
@@ -284,12 +292,14 @@ const AssigneeSelector: React.FC<AssigneeSelectorProps> = ({
}}
>
<div className="relative">
<Checkbox
checked={checkMemberSelected(member.id || '')}
onChange={(checked) => handleMemberToggle(member.id || '', checked)}
disabled={member.pending_invitation || pendingChanges.has(member.id || '')}
isDarkMode={isDarkMode}
/>
<span onClick={e => e.stopPropagation()}>
<Checkbox
checked={checkMemberSelected(member.id || '')}
onChange={(checked) => handleMemberToggle(member.id || '', checked)}
disabled={member.pending_invitation || pendingChanges.has(member.id || '')}
isDarkMode={isDarkMode}
/>
</span>
{pendingChanges.has(member.id || '') && (
<div className={`absolute inset-0 flex items-center justify-center ${
isDarkMode ? 'bg-gray-800/50' : 'bg-white/50'

View File

@@ -13,7 +13,6 @@ import { useAppDispatch } from '@/hooks/useAppDispatch';
import { setShowTaskDrawer, setSelectedTaskId } from '@/features/task-drawer/task-drawer.slice';
import PrioritySection from '../board/taskCard/priority-section/priority-section';
import Typography from 'antd/es/typography';
import CustomAvatarGroup from '../board/custom-avatar-group';
import CustomDueDatePicker from '../board/custom-due-date-picker';
import { themeWiseColor } from '@/utils/themeWiseColor';
import { ForkOutlined } from '@ant-design/icons';
@@ -29,6 +28,8 @@ import BoardSubTaskCard from '@/pages/projects/projectView/board/board-section/b
import BoardCreateSubtaskCard from '@/pages/projects/projectView/board/board-section/board-sub-task-card/board-create-sub-task-card';
import { useTranslation } from 'react-i18next';
import EnhancedKanbanCreateSubtaskCard from './EnhancedKanbanCreateSubtaskCard';
import LazyAssigneeSelectorWrapper from '@/components/task-management/lazy-assignee-selector';
import AvatarGroup from '@/components/AvatarGroup';
interface EnhancedKanbanTaskCardProps {
task: IProjectTask;
@@ -179,8 +180,15 @@ const EnhancedKanbanTaskCard: React.FC<EnhancedKanbanTaskCardProps> = React.memo
marginBlock: 8,
}}
>
{task && <CustomAvatarGroup task={task} sectionId={sectionId} />}
<Flex align="center" gap={2}>
<AvatarGroup
members={task.names || []}
maxCount={3}
isDarkMode={themeMode === 'dark'}
size={24}
/>
<LazyAssigneeSelectorWrapper task={task} groupId={sectionId} isDarkMode={themeMode === 'dark'} />
</Flex>
<Flex gap={4} align="center">
<CustomDueDatePicker task={task} onDateChange={setDueDate} />