Merge branch 'fix/enhanced-task-board' into fix/get-pull-6-26
This commit is contained in:
@@ -45,6 +45,7 @@ import alertService from '@/services/alerts/alertService';
|
||||
import { IGroupBy } from '@/features/enhanced-kanban/enhanced-kanban.slice';
|
||||
import EnhancedKanbanCreateSection from './EnhancedKanbanCreateSection';
|
||||
import ImprovedTaskFilters from '../task-management/improved-task-filters';
|
||||
import { fetchStatusesCategories } from '@/features/taskAttributes/taskStatusSlice';
|
||||
|
||||
// Import the TaskListFilters component
|
||||
const TaskListFilters = React.lazy(() => import('@/pages/projects/projectView/taskList/task-list-filters/task-list-filters'));
|
||||
@@ -66,7 +67,7 @@ const EnhancedKanbanBoard: React.FC<EnhancedKanbanBoardProps> = ({ projectId, cl
|
||||
const { teamId } = useAppSelector((state: RootState) => state.auth);
|
||||
const groupBy = useSelector((state: RootState) => state.enhancedKanbanReducer.groupBy);
|
||||
const project = useAppSelector((state: RootState) => state.projectReducer.project);
|
||||
|
||||
const { statusCategories, status: existingStatuses } = useAppSelector((state) => state.taskStatusReducer);
|
||||
// Local state for drag overlay
|
||||
const [activeTask, setActiveTask] = useState<any>(null);
|
||||
const [activeGroup, setActiveGroup] = useState<any>(null);
|
||||
@@ -86,6 +87,9 @@ const EnhancedKanbanBoard: React.FC<EnhancedKanbanBoardProps> = ({ projectId, cl
|
||||
if (projectId) {
|
||||
dispatch(fetchEnhancedKanbanGroups(projectId) as any);
|
||||
}
|
||||
if (!statusCategories.length) {
|
||||
dispatch(fetchStatusesCategories() as any);
|
||||
}
|
||||
}, [dispatch, projectId]);
|
||||
|
||||
// Get all task IDs for sortable context
|
||||
|
||||
@@ -38,9 +38,11 @@ const EnhancedKanbanCreateTaskCard: React.FC<EnhancedKanbanCreateTaskCardProps>
|
||||
const groupBy = useAppSelector(state => state.enhancedKanbanReducer.groupBy);
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
const timer = setTimeout(() => {
|
||||
inputRef.current?.focus();
|
||||
}, 100);
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
}, []);
|
||||
|
||||
const createRequestBody = (): ITaskCreateRequest | null => {
|
||||
@@ -66,18 +68,30 @@ const EnhancedKanbanCreateTaskCard: React.FC<EnhancedKanbanCreateTaskCardProps>
|
||||
}, 100);
|
||||
};
|
||||
|
||||
const resetForNextTask = () => {
|
||||
setNewTaskName('');
|
||||
setCreatingTask(false);
|
||||
// Keep the card visible for creating the next task
|
||||
setTimeout(() => {
|
||||
inputRef.current?.focus();
|
||||
}, 100);
|
||||
};
|
||||
|
||||
const handleAddTask = async () => {
|
||||
if (creatingTask || !projectId || !currentSession || newTaskName.trim() === '') return;
|
||||
setCreatingTask(true);
|
||||
|
||||
const body = createRequestBody();
|
||||
if (!body) return;
|
||||
if (!body) {
|
||||
setCreatingTask(true);
|
||||
setShowNewCard(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Real-time socket event handler
|
||||
const eventHandler = (task: IProjectTask) => {
|
||||
setCreatingTask(false);
|
||||
dispatch(addTaskToGroup({ sectionId, task: { ...task, id: task.id || nanoid(), name: task.name || newTaskName.trim() } }));
|
||||
socket?.off(SocketEvents.QUICK_TASK.toString(), eventHandler);
|
||||
resetForm();
|
||||
resetForNextTask();
|
||||
};
|
||||
socket?.once(SocketEvents.QUICK_TASK.toString(), eventHandler);
|
||||
socket?.emit(SocketEvents.QUICK_TASK.toString(), JSON.stringify(body));
|
||||
@@ -89,6 +103,13 @@ const EnhancedKanbanCreateTaskCard: React.FC<EnhancedKanbanCreateTaskCardProps>
|
||||
setCreatingTask(false);
|
||||
};
|
||||
|
||||
const handleBlur = () => {
|
||||
if (newTaskName.trim() === '') {
|
||||
setCreatingTask(false);
|
||||
setShowNewCard(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Flex
|
||||
ref={cardRef}
|
||||
@@ -111,9 +132,11 @@ const EnhancedKanbanCreateTaskCard: React.FC<EnhancedKanbanCreateTaskCardProps>
|
||||
>
|
||||
<Input
|
||||
ref={inputRef}
|
||||
autoFocus
|
||||
value={newTaskName}
|
||||
onChange={e => setNewTaskName(e.target.value)}
|
||||
onPressEnter={handleAddTask}
|
||||
onBlur={handleBlur}
|
||||
placeholder={t('newTaskNamePlaceholder')}
|
||||
style={{
|
||||
width: '100%',
|
||||
|
||||
@@ -7,7 +7,7 @@ import { fetchStatuses, fetchStatusesCategories } from '@/features/taskAttribute
|
||||
import { useMixpanelTracking } from '@/hooks/useMixpanelTracking';
|
||||
import useTabSearchParam from '@/hooks/useTabSearchParam';
|
||||
import { fetchTaskGroups } from '@/features/tasks/tasks.slice';
|
||||
import { fetchBoardTaskGroups } from '@/features/board/board-slice';
|
||||
|
||||
import { deleteStatusToggleDrawer } from '@/features/projects/status/DeleteStatusSlice';
|
||||
import { Drawer, Alert, Card, Select, Button, Typography, Badge } from 'antd';
|
||||
import { DownOutlined } from '@ant-design/icons';
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
import { statusApiService } from '@/api/taskAttributes/status/status.api.service';
|
||||
import { phasesApiService } from '@/api/taskAttributes/phases/phases.api.service';
|
||||
import logger from '@/utils/errorLogger';
|
||||
import { fetchEnhancedKanbanGroups } from '@/features/enhanced-kanban/enhanced-kanban.slice';
|
||||
const { Title, Text } = Typography;
|
||||
const { Option } = Select;
|
||||
|
||||
@@ -43,8 +44,8 @@ const DeleteStatusDrawer: React.FC = () => {
|
||||
|
||||
const refreshTasks = useCallback(() => {
|
||||
if (!projectId) return;
|
||||
const fetchAction = projectView === 'list' ? fetchTaskGroups : fetchBoardTaskGroups;
|
||||
dispatch(fetchAction(projectId));
|
||||
const fetchAction = projectView === 'list' ? fetchTaskGroups : fetchEnhancedKanbanGroups;
|
||||
dispatch(fetchAction(projectId) as any);
|
||||
}, [projectId, projectView, dispatch]);
|
||||
|
||||
const handleDrawerOpenChange = () => {
|
||||
@@ -71,7 +72,7 @@ const DeleteStatusDrawer: React.FC = () => {
|
||||
dispatch(fetchStatuses(projectId));
|
||||
refreshTasks();
|
||||
dispatch(fetchStatusesCategories());
|
||||
} else{
|
||||
} else {
|
||||
console.error('Error deleting status', res);
|
||||
}
|
||||
} else if (groupBy === IGroupBy.PHASE) {
|
||||
@@ -83,7 +84,7 @@ const DeleteStatusDrawer: React.FC = () => {
|
||||
|
||||
} catch (error) {
|
||||
logger.error('Error deleting section', error);
|
||||
}finally {
|
||||
} finally {
|
||||
setDeletingStatus(false);
|
||||
}
|
||||
};
|
||||
@@ -98,7 +99,7 @@ const DeleteStatusDrawer: React.FC = () => {
|
||||
open={isDelteStatusDrawerOpen}
|
||||
afterOpenChange={handleDrawerOpenChange}
|
||||
>
|
||||
<Alert type="warning" message={selectedForDelete?.message.replace("$","")} />
|
||||
<Alert type="warning" message={selectedForDelete?.message.replace("$", "")} />
|
||||
|
||||
<Card className="text-center" style={{ marginTop: 16 }}>
|
||||
<Title level={5}>{selectedForDelete?.name}</Title>
|
||||
|
||||
Reference in New Issue
Block a user