diff --git a/worklenz-frontend/src/components/task-drawer/shared/info-tab/details/task-drawer-due-date/task-drawer-due-date.tsx b/worklenz-frontend/src/components/task-drawer/shared/info-tab/details/task-drawer-due-date/task-drawer-due-date.tsx index 66f9b277..19c59c5c 100644 --- a/worklenz-frontend/src/components/task-drawer/shared/info-tab/details/task-drawer-due-date/task-drawer-due-date.tsx +++ b/worklenz-frontend/src/components/task-drawer/shared/info-tab/details/task-drawer-due-date/task-drawer-due-date.tsx @@ -14,6 +14,8 @@ import { ITaskViewModel } from '@/types/tasks/task.types'; import { IProjectTask } from '@/types/project/projectTasksViewModel.types'; import { useAppDispatch } from '@/hooks/useAppDispatch'; import { setStartDate, setTaskEndDate } from '@/features/task-drawer/task-drawer.slice'; +import { updateEnhancedKanbanTaskStartDate, updateEnhancedKanbanTaskEndDate } from '@/features/enhanced-kanban/enhanced-kanban.slice'; +import useTabSearchParam from '@/hooks/useTabSearchParam'; interface TaskDrawerDueDateProps { task: ITaskViewModel; t: TFunction; @@ -24,6 +26,7 @@ const TaskDrawerDueDate = ({ task, t, form }: TaskDrawerDueDateProps) => { const { socket } = useSocket(); const [isShowStartDate, setIsShowStartDate] = useState(false); const dispatch = useAppDispatch(); + const { tab } = useTabSearchParam(); // Date handling const startDayjs = task?.start_date ? dayjs(task.start_date) : null; const dueDayjs = task?.end_date ? dayjs(task.end_date) : null; @@ -63,6 +66,10 @@ const TaskDrawerDueDate = ({ task, t, form }: TaskDrawerDueDateProps) => { (data: IProjectTask) => { dispatch(setStartDate(data)); + // Also update enhanced kanban if on board tab + if (tab === 'board') { + dispatch(updateEnhancedKanbanTaskStartDate({ task: data })); + } } ); } catch (error) { @@ -88,6 +95,10 @@ const TaskDrawerDueDate = ({ task, t, form }: TaskDrawerDueDateProps) => { (data: IProjectTask) => { dispatch(setTaskEndDate(data)); + // Also update enhanced kanban if on board tab + if (tab === 'board') { + dispatch(updateEnhancedKanbanTaskEndDate({ task: data })); + } } ); } catch (error) { diff --git a/worklenz-frontend/src/features/enhanced-kanban/enhanced-kanban.slice.ts b/worklenz-frontend/src/features/enhanced-kanban/enhanced-kanban.slice.ts index f4974f0f..486a2312 100644 --- a/worklenz-frontend/src/features/enhanced-kanban/enhanced-kanban.slice.ts +++ b/worklenz-frontend/src/features/enhanced-kanban/enhanced-kanban.slice.ts @@ -794,6 +794,104 @@ const enhancedKanbanSlice = createSlice({ state.groupCache[sectionId] = group; } }, + + // Enhanced Kanban end date update (for use in task drawer and socket events) + updateEnhancedKanbanTaskEndDate: ( + state, + action: PayloadAction<{ + task: IProjectTask; + }> + ) => { + const { task } = action.payload; + + // Find the task and update it + const result = findTaskInAllGroups(state.taskGroups, task.id || ''); + if (result) { + result.task.end_date = task.end_date; + // Update cache + state.taskCache[task.id!] = result.task; + } + }, + + // Enhanced Kanban start date update (for use in task drawer and socket events) + updateEnhancedKanbanTaskStartDate: ( + state, + action: PayloadAction<{ + task: IProjectTask; + }> + ) => { + const { task } = action.payload; + + // Find the task and update it + const result = findTaskInAllGroups(state.taskGroups, task.id || ''); + if (result) { + result.task.start_date = task.start_date; + // Update cache + state.taskCache[task.id!] = result.task; + } + }, + + // Enhanced Kanban subtask update (for use in task drawer and socket events) + updateEnhancedKanbanSubtask: ( + state, + action: PayloadAction<{ + sectionId: string; + subtask: IProjectTask; + mode: 'add' | 'delete'; + }> + ) => { + const { sectionId, subtask, mode } = action.payload; + const parentTaskId = subtask?.parent_task_id || null; + + if (!parentTaskId) return; + + // Function to update a task with a new subtask + const updateTaskWithSubtask = (task: IProjectTask): boolean => { + if (!task) return false; + + // Initialize sub_tasks array if it doesn't exist + if (!task.sub_tasks) { + task.sub_tasks = []; + } + + if (mode === 'add') { + // Increment subtask count + task.sub_tasks_count = (task.sub_tasks_count || 0) + 1; + + // Add the subtask + task.sub_tasks.push({ ...subtask }); + } else { + // Remove the subtask + task.sub_tasks = task.sub_tasks.filter(t => t.id !== subtask.id); + task.sub_tasks_count = Math.max(0, (task.sub_tasks_count || 1) - 1); + } + + // Update cache + state.taskCache[task.id!] = task; + return true; + }; + + // First try to find the task in the specified section + if (sectionId) { + const section = state.taskGroups.find(sec => sec.id === sectionId); + if (section) { + const task = section.tasks.find(task => task.id === parentTaskId); + if (task && updateTaskWithSubtask(task)) { + // Update group cache + state.groupCache[sectionId] = section; + return; + } + } + } + + // If not found in the specified section, try all groups + const result = findTaskInAllGroups(state.taskGroups, parentTaskId); + if (result) { + updateTaskWithSubtask(result.task); + // Update group cache + state.groupCache[result.groupId] = result.group; + } + }, }, extraReducers: (builder) => { builder @@ -926,6 +1024,9 @@ export const { updateEnhancedKanbanTaskLabels, updateEnhancedKanbanTaskProgress, updateEnhancedKanbanTaskName, + updateEnhancedKanbanTaskEndDate, + updateEnhancedKanbanTaskStartDate, + updateEnhancedKanbanSubtask, } = enhancedKanbanSlice.actions; export default enhancedKanbanSlice.reducer; \ No newline at end of file