refactor(task-list): update subtask and indicator visibility logic
- Modified subtask visibility conditions across TaskCard, EnhancedKanbanTaskCard, KanbanTaskCard, and TaskRow components to only display when the count is greater than 1. - Enhanced task indicators for comments and attachments to follow the same visibility logic. - Added new dependencies for task management types to support subscriber and attachment features.
This commit is contained in:
@@ -284,7 +284,7 @@ const TaskCard: React.FC<taskProps> = ({ task }) => {
|
|||||||
format={value => formatDate(value)}
|
format={value => formatDate(value)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{task.sub_tasks_count && task.sub_tasks_count > 0 && (
|
{task.sub_tasks_count && task.sub_tasks_count > 1 && (
|
||||||
<Button
|
<Button
|
||||||
onClick={() => setIsSubTaskShow(!isSubTaskShow)}
|
onClick={() => setIsSubTaskShow(!isSubTaskShow)}
|
||||||
size="small"
|
size="small"
|
||||||
@@ -306,7 +306,7 @@ const TaskCard: React.FC<taskProps> = ({ task }) => {
|
|||||||
|
|
||||||
{isSubTaskShow &&
|
{isSubTaskShow &&
|
||||||
task.sub_tasks_count &&
|
task.sub_tasks_count &&
|
||||||
task.sub_tasks_count > 0 &&
|
task.sub_tasks_count > 1 &&
|
||||||
task.sub_tasks?.map(subtask => <SubTaskCard subtask={subtask} />)}
|
task.sub_tasks?.map(subtask => <SubTaskCard subtask={subtask} />)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -191,29 +191,31 @@ const EnhancedKanbanTaskCard: React.FC<EnhancedKanbanTaskCardProps> = React.memo
|
|||||||
<Flex gap={4} align="center">
|
<Flex gap={4} align="center">
|
||||||
<CustomDueDatePicker task={task} onDateChange={setDueDate} />
|
<CustomDueDatePicker task={task} onDateChange={setDueDate} />
|
||||||
|
|
||||||
{/* Subtask Section */}
|
{/* Subtask Section - only show if count > 1 */}
|
||||||
<Button
|
{task.sub_tasks_count != null && Number(task.sub_tasks_count) > 1 && (
|
||||||
onClick={handleSubtaskButtonClick}
|
<Button
|
||||||
size="small"
|
onClick={handleSubtaskButtonClick}
|
||||||
style={{
|
size="small"
|
||||||
padding: 0,
|
|
||||||
}}
|
|
||||||
type="text"
|
|
||||||
>
|
|
||||||
<Tag
|
|
||||||
bordered={false}
|
|
||||||
style={{
|
style={{
|
||||||
display: 'flex',
|
padding: 0,
|
||||||
alignItems: 'center',
|
|
||||||
margin: 0,
|
|
||||||
backgroundColor: themeWiseColor('white', '#1e1e1e', themeMode),
|
|
||||||
}}
|
}}
|
||||||
|
type="text"
|
||||||
>
|
>
|
||||||
<ForkOutlined rotate={90} />
|
<Tag
|
||||||
<span>{task.sub_tasks_count}</span>
|
bordered={false}
|
||||||
{task.show_sub_tasks ? <CaretDownFilled /> : <CaretRightFilled />}
|
style={{
|
||||||
</Tag>
|
display: 'flex',
|
||||||
</Button>
|
alignItems: 'center',
|
||||||
|
margin: 0,
|
||||||
|
backgroundColor: themeWiseColor('white', '#1e1e1e', themeMode),
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ForkOutlined rotate={90} />
|
||||||
|
<span>{task.sub_tasks_count || 0}</span>
|
||||||
|
{task.show_sub_tasks ? <CaretDownFilled /> : <CaretRightFilled />}
|
||||||
|
</Tag>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical gap={8}>
|
<Flex vertical gap={8}>
|
||||||
|
|||||||
@@ -195,12 +195,12 @@ const KanbanTaskCard: React.FC<TaskRowProps> = ({
|
|||||||
<ClockCircleOutlined /> {task.time_spent_string}
|
<ClockCircleOutlined /> {task.time_spent_string}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{task.comments_count && task.comments_count > 0 && (
|
{task.comments_count && task.comments_count > 1 && (
|
||||||
<span className="kanban-task-indicator">
|
<span className="kanban-task-indicator">
|
||||||
<MessageOutlined /> {task.comments_count}
|
<MessageOutlined /> {task.comments_count}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{task.attachments_count && task.attachments_count > 0 && (
|
{task.attachments_count && task.attachments_count > 1 && (
|
||||||
<span className="kanban-task-indicator">
|
<span className="kanban-task-indicator">
|
||||||
<PaperClipOutlined /> {task.attachments_count}
|
<PaperClipOutlined /> {task.attachments_count}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import React, { memo, useMemo, useCallback, useState } from 'react';
|
import React, { memo, useMemo, useCallback, useState } from 'react';
|
||||||
import { useSortable } from '@dnd-kit/sortable';
|
import { useSortable } from '@dnd-kit/sortable';
|
||||||
import { CSS } from '@dnd-kit/utilities';
|
import { CSS } from '@dnd-kit/utilities';
|
||||||
import { CheckCircleOutlined, HolderOutlined, CloseOutlined, DownOutlined, RightOutlined, DoubleRightOutlined, ArrowsAltOutlined } from '@ant-design/icons';
|
import { CheckCircleOutlined, HolderOutlined, CloseOutlined, DownOutlined, RightOutlined, DoubleRightOutlined, ArrowsAltOutlined, CommentOutlined, EyeOutlined, PaperClipOutlined, MinusCircleOutlined, RetweetOutlined } from '@ant-design/icons';
|
||||||
import { Checkbox, DatePicker } from 'antd';
|
import { Checkbox, DatePicker, Tooltip } from 'antd';
|
||||||
import { dayjs, taskManagementAntdConfig } from '@/shared/antd-imports';
|
import { dayjs, taskManagementAntdConfig } from '@/shared/antd-imports';
|
||||||
import { Task } from '@/types/task-management.types';
|
import { Task } from '@/types/task-management.types';
|
||||||
import { InlineMember } from '@/types/teamMembers/inlineMember.types';
|
import { InlineMember } from '@/types/teamMembers/inlineMember.types';
|
||||||
@@ -49,7 +49,6 @@ interface TaskLabelsCellProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const TaskLabelsCell: React.FC<TaskLabelsCellProps> = memo(({ labels, isDarkMode }) => {
|
const TaskLabelsCell: React.FC<TaskLabelsCellProps> = memo(({ labels, isDarkMode }) => {
|
||||||
console.log('labels', labels);
|
|
||||||
if (!labels) {
|
if (!labels) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -302,7 +301,7 @@ const TaskRow: React.FC<TaskRowProps> = memo(({ taskId, projectId, visibleColumn
|
|||||||
<button
|
<button
|
||||||
onClick={handleToggleExpansion}
|
onClick={handleToggleExpansion}
|
||||||
className={`flex h-4 w-4 items-center justify-center rounded-sm text-xs mr-1 hover:border hover:border-blue-500 hover:bg-blue-50 dark:hover:bg-blue-900/20 hover:scale-110 transition-all duration-300 ease-out ${
|
className={`flex h-4 w-4 items-center justify-center rounded-sm text-xs mr-1 hover:border hover:border-blue-500 hover:bg-blue-50 dark:hover:bg-blue-900/20 hover:scale-110 transition-all duration-300 ease-out ${
|
||||||
task.sub_tasks_count && Number(task.sub_tasks_count) > 0
|
task.sub_tasks_count != null && Number(task.sub_tasks_count) > 0
|
||||||
? 'opacity-100'
|
? 'opacity-100'
|
||||||
: 'opacity-0 group-hover:opacity-100'
|
: 'opacity-0 group-hover:opacity-100'
|
||||||
}`}
|
}`}
|
||||||
@@ -327,8 +326,8 @@ const TaskRow: React.FC<TaskRowProps> = memo(({ taskId, projectId, visibleColumn
|
|||||||
{taskDisplayName}
|
{taskDisplayName}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{/* Subtask count indicator */}
|
{/* Subtask count indicator - only show if count > 1 */}
|
||||||
{!isSubtask && task.sub_tasks_count && Number(task.sub_tasks_count) > 0 && (
|
{!isSubtask && task.sub_tasks_count != null && task.sub_tasks_count !== 0 && (
|
||||||
<div className="flex items-center gap-1 px-2 py-1 bg-blue-50 dark:bg-blue-900/20 rounded-md">
|
<div className="flex items-center gap-1 px-2 py-1 bg-blue-50 dark:bg-blue-900/20 rounded-md">
|
||||||
<span className="text-xs text-blue-600 dark:text-blue-400 font-medium">
|
<span className="text-xs text-blue-600 dark:text-blue-400 font-medium">
|
||||||
{task.sub_tasks_count}
|
{task.sub_tasks_count}
|
||||||
@@ -336,6 +335,55 @@ const TaskRow: React.FC<TaskRowProps> = memo(({ taskId, projectId, visibleColumn
|
|||||||
<DoubleRightOutlined className="text-xs text-blue-600 dark:text-blue-400" />
|
<DoubleRightOutlined className="text-xs text-blue-600 dark:text-blue-400" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Task indicators */}
|
||||||
|
<div className="flex items-center gap-1 ml-2">
|
||||||
|
{/* Comments count indicator - only show if count > 1 */}
|
||||||
|
{task.comments_count != null && task.comments_count !== 0 && (
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
|
<CommentOutlined
|
||||||
|
className="text-gray-500 dark:text-gray-400"
|
||||||
|
style={{ fontSize: 14 }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Subscribers indicator */}
|
||||||
|
{task.has_subscribers && (
|
||||||
|
<EyeOutlined
|
||||||
|
className="text-gray-500 dark:text-gray-400"
|
||||||
|
style={{ fontSize: 14 }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Attachments count indicator - only show if count > 1 */}
|
||||||
|
{task.attachments_count != null && task.attachments_count !== 0 && (
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
|
<PaperClipOutlined
|
||||||
|
className="text-gray-500 dark:text-gray-400"
|
||||||
|
style={{ fontSize: 14 }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Dependencies indicator */}
|
||||||
|
{task.has_dependencies && (
|
||||||
|
<MinusCircleOutlined
|
||||||
|
className="text-gray-500 dark:text-gray-400"
|
||||||
|
style={{ fontSize: 14 }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Recurring task indicator */}
|
||||||
|
{task.schedule_id && (
|
||||||
|
<Tooltip title="Recurring Task">
|
||||||
|
<RetweetOutlined
|
||||||
|
className="text-gray-500 dark:text-gray-400"
|
||||||
|
style={{ fontSize: 14 }}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -659,6 +707,11 @@ const TaskRow: React.FC<TaskRowProps> = memo(({ taskId, projectId, visibleColumn
|
|||||||
task,
|
task,
|
||||||
task.labels, // Explicit dependency for labels updates
|
task.labels, // Explicit dependency for labels updates
|
||||||
task.phase, // Explicit dependency for phase updates
|
task.phase, // Explicit dependency for phase updates
|
||||||
|
task.comments_count, // Explicit dependency for comments count updates
|
||||||
|
task.has_subscribers, // Explicit dependency for subscribers updates
|
||||||
|
task.attachments_count, // Explicit dependency for attachments count updates
|
||||||
|
task.has_dependencies, // Explicit dependency for dependencies updates
|
||||||
|
task.schedule_id, // Explicit dependency for recurring task updates
|
||||||
taskDisplayName,
|
taskDisplayName,
|
||||||
convertedTask,
|
convertedTask,
|
||||||
|
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ const AddSubtaskRow: React.FC<AddSubtaskRowProps> = memo(({
|
|||||||
className="flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 transition-colors h-full"
|
className="flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 transition-colors h-full"
|
||||||
>
|
>
|
||||||
<PlusOutlined className="text-xs" />
|
<PlusOutlined className="text-xs" />
|
||||||
{t('addSubtaskText')}
|
{t('addSubTaskText')}
|
||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<Input
|
<Input
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ const TaskListTaskCell = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const renderSubtasksCountLabel = (taskId: string, isSubTask: boolean, subTasksCount: number) => {
|
const renderSubtasksCountLabel = (taskId: string, isSubTask: boolean, subTasksCount: number) => {
|
||||||
if (!taskId) return null;
|
if (!taskId || subTasksCount <= 1) return null;
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
onClick={() => handleToggleExpansion(taskId)}
|
onClick={() => handleToggleExpansion(taskId)}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ export interface Task {
|
|||||||
comments_count?: number;
|
comments_count?: number;
|
||||||
attachments_count?: number;
|
attachments_count?: number;
|
||||||
has_dependencies?: boolean;
|
has_dependencies?: boolean;
|
||||||
|
has_subscribers?: boolean;
|
||||||
schedule_id?: string | null;
|
schedule_id?: string | null;
|
||||||
order?: number;
|
order?: number;
|
||||||
reporter?: string; // Reporter field
|
reporter?: string; // Reporter field
|
||||||
|
|||||||
Reference in New Issue
Block a user