feat(enhanced-kanban): implement real-time task and group reordering with socket integration
- Added socket functionality to emit task sort order changes during drag-and-drop operations. - Enhanced group drop handling to include API calls for updating group order, with error handling and alerts for failed updates. - Integrated authentication and socket context to manage project and team information effectively.
This commit is contained in:
@@ -13,11 +13,19 @@ import { fetchStatusesCategories } from '@/features/taskAttributes/taskStatusSli
|
|||||||
import { useAppSelector } from '@/hooks/useAppSelector';
|
import { useAppSelector } from '@/hooks/useAppSelector';
|
||||||
import KanbanGroup from './KanbanGroup';
|
import KanbanGroup from './KanbanGroup';
|
||||||
import EnhancedKanbanCreateSection from '../EnhancedKanbanCreateSection';
|
import EnhancedKanbanCreateSection from '../EnhancedKanbanCreateSection';
|
||||||
|
import { useSocket } from '@/socket/socketContext';
|
||||||
|
import { SocketEvents } from '@/shared/socket-events';
|
||||||
|
import { useAuthService } from '@/hooks/useAuth';
|
||||||
|
import { statusApiService } from '@/api/taskAttributes/status/status.api.service';
|
||||||
|
import alertService from '@/services/alerts/alertService';
|
||||||
|
import logger from '@/utils/errorLogger';
|
||||||
|
|
||||||
const EnhancedKanbanBoardNativeDnD: React.FC<{ projectId: string }> = ({ projectId }) => {
|
const EnhancedKanbanBoardNativeDnD: React.FC<{ projectId: string }> = ({ projectId }) => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
const authService = useAuthService();
|
||||||
|
const { socket } = useSocket();
|
||||||
|
const project = useAppSelector((state: RootState) => state.projectReducer.project);
|
||||||
|
const teamId = authService.getCurrentSession()?.team_id;
|
||||||
const {
|
const {
|
||||||
taskGroups,
|
taskGroups,
|
||||||
loadingGroups,
|
loadingGroups,
|
||||||
@@ -62,7 +70,7 @@ const EnhancedKanbanBoardNativeDnD: React.FC<{ projectId: string }> = ({ project
|
|||||||
if (dragType !== 'group') return;
|
if (dragType !== 'group') return;
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
};
|
};
|
||||||
const handleGroupDrop = (e: React.DragEvent, targetGroupId: string) => {
|
const handleGroupDrop = async (e: React.DragEvent, targetGroupId: string) => {
|
||||||
if (dragType !== 'group') return;
|
if (dragType !== 'group') return;
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (!draggedGroupId || draggedGroupId === targetGroupId) return;
|
if (!draggedGroupId || draggedGroupId === targetGroupId) return;
|
||||||
@@ -75,6 +83,30 @@ const EnhancedKanbanBoardNativeDnD: React.FC<{ projectId: string }> = ({ project
|
|||||||
reorderedGroups.splice(toIdx, 0, moved);
|
reorderedGroups.splice(toIdx, 0, moved);
|
||||||
dispatch(reorderGroups({ fromIndex: fromIdx, toIndex: toIdx, reorderedGroups }));
|
dispatch(reorderGroups({ fromIndex: fromIdx, toIndex: toIdx, reorderedGroups }));
|
||||||
dispatch(reorderEnhancedKanbanGroups({ fromIndex: fromIdx, toIndex: toIdx, reorderedGroups }) as any);
|
dispatch(reorderEnhancedKanbanGroups({ fromIndex: fromIdx, toIndex: toIdx, reorderedGroups }) as any);
|
||||||
|
|
||||||
|
// API call for group order
|
||||||
|
try {
|
||||||
|
const columnOrder = reorderedGroups.map(group => group.id);
|
||||||
|
const requestBody = { status_order: columnOrder };
|
||||||
|
const response = await statusApiService.updateStatusOrder(requestBody, projectId);
|
||||||
|
if (!response.done) {
|
||||||
|
// Revert the change if API call fails
|
||||||
|
const revertedGroups = [...reorderedGroups];
|
||||||
|
const [movedBackGroup] = revertedGroups.splice(toIdx, 1);
|
||||||
|
revertedGroups.splice(fromIdx, 0, movedBackGroup);
|
||||||
|
dispatch(reorderGroups({ fromIndex: toIdx, toIndex: fromIdx, reorderedGroups: revertedGroups }));
|
||||||
|
alertService.error('Failed to update column order', 'Please try again');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Revert the change if API call fails
|
||||||
|
const revertedGroups = [...reorderedGroups];
|
||||||
|
const [movedBackGroup] = revertedGroups.splice(toIdx, 1);
|
||||||
|
revertedGroups.splice(fromIdx, 0, movedBackGroup);
|
||||||
|
dispatch(reorderGroups({ fromIndex: toIdx, toIndex: fromIdx, reorderedGroups: revertedGroups }));
|
||||||
|
alertService.error('Failed to update column order', 'Please try again');
|
||||||
|
logger.error('Failed to update column order', error);
|
||||||
|
}
|
||||||
|
|
||||||
setDraggedGroupId(null);
|
setDraggedGroupId(null);
|
||||||
setDragType(null);
|
setDragType(null);
|
||||||
};
|
};
|
||||||
@@ -173,7 +205,37 @@ const EnhancedKanbanBoardNativeDnD: React.FC<{ projectId: string }> = ({ project
|
|||||||
updatedTargetTasks,
|
updatedTargetTasks,
|
||||||
}) as any);
|
}) as any);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Socket emit for task order
|
||||||
|
if (socket && projectId && teamId && movedTask) {
|
||||||
|
let toSortOrder = -1;
|
||||||
|
let toLastIndex = false;
|
||||||
|
if (insertIdx === targetGroup.tasks.length) {
|
||||||
|
toSortOrder = -1;
|
||||||
|
toLastIndex = true;
|
||||||
|
} else if (targetGroup.tasks[insertIdx]) {
|
||||||
|
toSortOrder = typeof targetGroup.tasks[insertIdx].sort_order === 'number'
|
||||||
|
? targetGroup.tasks[insertIdx].sort_order
|
||||||
|
: -1;
|
||||||
|
toLastIndex = false;
|
||||||
|
} else if (targetGroup.tasks.length > 0) {
|
||||||
|
const lastSortOrder = targetGroup.tasks[targetGroup.tasks.length - 1].sort_order;
|
||||||
|
toSortOrder = typeof lastSortOrder === 'number' ? lastSortOrder : -1;
|
||||||
|
toLastIndex = false;
|
||||||
|
}
|
||||||
|
socket.emit(SocketEvents.TASK_SORT_ORDER_CHANGE.toString(), {
|
||||||
|
project_id: projectId,
|
||||||
|
from_index: movedTask.sort_order,
|
||||||
|
to_index: toSortOrder,
|
||||||
|
to_last_index: toLastIndex,
|
||||||
|
from_group: sourceGroup.id,
|
||||||
|
to_group: targetGroup.id,
|
||||||
|
group_by: 'status',
|
||||||
|
task: movedTask,
|
||||||
|
team_id: teamId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
setDraggedTaskId(null);
|
setDraggedTaskId(null);
|
||||||
setDraggedTaskGroupId(null);
|
setDraggedTaskGroupId(null);
|
||||||
setHoveredGroupId(null);
|
setHoveredGroupId(null);
|
||||||
|
|||||||
Reference in New Issue
Block a user