feat(task-management): integrate real-time updates and enhance task row components
- Added useTaskSocketHandlers to TaskListV2 for real-time task updates. - Updated TaskRow to accept projectId prop for better context handling. - Replaced static status and priority displays with TaskStatusDropdown and TaskPriorityDropdown for improved interactivity. - Enhanced dropdown positioning logic in TaskStatusDropdown and TaskPriorityDropdown to handle scrollable containers effectively.
This commit is contained in:
@@ -55,6 +55,7 @@ import { TaskListField } from '@/types/task-list-field.types';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import ImprovedTaskFilters from '@/components/task-management/improved-task-filters';
|
||||
import OptimizedBulkActionBar from '@/components/task-management/optimized-bulk-action-bar';
|
||||
import { useTaskSocketHandlers } from '@/hooks/useTaskSocketHandlers';
|
||||
import { Bars3Icon } from '@heroicons/react/24/outline';
|
||||
import { HolderOutlined } from '@ant-design/icons';
|
||||
import { COLUMN_KEYS } from '@/features/tasks/tasks.slice';
|
||||
@@ -137,6 +138,9 @@ const TaskListV2: React.FC<TaskListV2Props> = ({ projectId }) => {
|
||||
|
||||
const fields = useAppSelector(state => state.taskManagementFields) || [];
|
||||
|
||||
// Enable real-time updates via socket handlers
|
||||
useTaskSocketHandlers();
|
||||
|
||||
// Filter visible columns based on fields
|
||||
const visibleColumns = useMemo(() => {
|
||||
return BASE_COLUMNS.filter(column => {
|
||||
@@ -497,6 +501,7 @@ const TaskListV2: React.FC<TaskListV2Props> = ({ projectId }) => {
|
||||
return (
|
||||
<TaskRow
|
||||
taskId={task.id}
|
||||
projectId={projectId}
|
||||
visibleColumns={visibleColumns}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -13,6 +13,8 @@ import { ClockIcon } from '@heroicons/react/24/outline';
|
||||
import AvatarGroup from '../AvatarGroup';
|
||||
import { DEFAULT_TASK_NAME } from '@/shared/constants';
|
||||
import TaskProgress from '@/pages/projects/project-view-1/taskList/taskListTable/taskListTableCells/TaskProgress';
|
||||
import TaskStatusDropdown from '@/components/task-management/task-status-dropdown';
|
||||
import TaskPriorityDropdown from '@/components/task-management/task-priority-dropdown';
|
||||
import { useAppSelector } from '@/hooks/useAppSelector';
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
import { selectTaskById } from '@/features/task-management/task-management.slice';
|
||||
@@ -20,6 +22,7 @@ import { selectIsTaskSelected, toggleTaskSelection } from '@/features/task-manag
|
||||
|
||||
interface TaskRowProps {
|
||||
taskId: string;
|
||||
projectId: string;
|
||||
visibleColumns: Array<{
|
||||
id: string;
|
||||
width: string;
|
||||
@@ -47,7 +50,7 @@ const formatDate = (dateString: string): string => {
|
||||
|
||||
// Memoized date formatter to avoid repeated date parsing
|
||||
|
||||
const TaskRow: React.FC<TaskRowProps> = memo(({ taskId, visibleColumns }) => {
|
||||
const TaskRow: React.FC<TaskRowProps> = memo(({ taskId, projectId, visibleColumns }) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const task = useAppSelector(state => selectTaskById(state, taskId));
|
||||
const isSelected = useAppSelector(state => selectIsTaskSelected(state, taskId));
|
||||
@@ -207,12 +210,11 @@ const TaskRow: React.FC<TaskRowProps> = memo(({ taskId, visibleColumns }) => {
|
||||
case 'status':
|
||||
return (
|
||||
<div style={baseStyle}>
|
||||
<span
|
||||
className="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium"
|
||||
style={statusStyle}
|
||||
>
|
||||
{task.status}
|
||||
</span>
|
||||
<TaskStatusDropdown
|
||||
task={task}
|
||||
projectId={projectId}
|
||||
isDarkMode={isDarkMode}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -236,12 +238,11 @@ const TaskRow: React.FC<TaskRowProps> = memo(({ taskId, visibleColumns }) => {
|
||||
case 'priority':
|
||||
return (
|
||||
<div style={baseStyle}>
|
||||
<span
|
||||
className="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium"
|
||||
style={priorityStyle}
|
||||
>
|
||||
{task.priority}
|
||||
</span>
|
||||
<TaskPriorityDropdown
|
||||
task={task}
|
||||
projectId={projectId}
|
||||
isDarkMode={isDarkMode}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
@@ -66,11 +66,18 @@ const TaskPriorityDropdown: React.FC<TaskPriorityDropdownProps> = ({
|
||||
};
|
||||
|
||||
if (isOpen && buttonRef.current) {
|
||||
// Calculate position
|
||||
// Calculate position with better handling of scrollable containers
|
||||
const rect = buttonRef.current.getBoundingClientRect();
|
||||
const viewportHeight = window.innerHeight;
|
||||
const dropdownHeight = 200; // Estimated dropdown height
|
||||
|
||||
// Check if dropdown would go below viewport
|
||||
const spaceBelow = viewportHeight - rect.bottom;
|
||||
const shouldShowAbove = spaceBelow < dropdownHeight && rect.top > dropdownHeight;
|
||||
|
||||
setDropdownPosition({
|
||||
top: rect.bottom + window.scrollY + 4,
|
||||
left: rect.left + window.scrollX,
|
||||
top: shouldShowAbove ? rect.top - dropdownHeight - 4 : rect.bottom + 4,
|
||||
left: rect.left,
|
||||
});
|
||||
|
||||
document.addEventListener('mousedown', handleClickOutside);
|
||||
|
||||
@@ -73,11 +73,18 @@ const TaskStatusDropdown: React.FC<TaskStatusDropdownProps> = ({
|
||||
};
|
||||
|
||||
if (isOpen && buttonRef.current) {
|
||||
// Calculate position
|
||||
// Calculate position with better handling of scrollable containers
|
||||
const rect = buttonRef.current.getBoundingClientRect();
|
||||
const viewportHeight = window.innerHeight;
|
||||
const dropdownHeight = 200; // Estimated dropdown height
|
||||
|
||||
// Check if dropdown would go below viewport
|
||||
const spaceBelow = viewportHeight - rect.bottom;
|
||||
const shouldShowAbove = spaceBelow < dropdownHeight && rect.top > dropdownHeight;
|
||||
|
||||
setDropdownPosition({
|
||||
top: rect.bottom + window.scrollY + 4,
|
||||
left: rect.left + window.scrollX,
|
||||
top: shouldShowAbove ? rect.top - dropdownHeight - 4 : rect.bottom + 4,
|
||||
left: rect.left,
|
||||
});
|
||||
|
||||
document.addEventListener('mousedown', handleClickOutside);
|
||||
|
||||
Reference in New Issue
Block a user