feat(task-management): enhance task details and subtask handling

- Added subtask-related properties to the Task interface for better management of subtasks.
- Implemented functionality to show and add subtasks directly within the task list, improving user interaction.
- Updated task rendering logic to accommodate new subtask features, enhancing overall task management experience.
- Removed unused components and optimized imports across various task management files for cleaner code.
This commit is contained in:
chamikaJ
2025-07-02 12:38:24 +05:30
parent c29ba6ea69
commit 2064c0833c
20 changed files with 521 additions and 2069 deletions

View File

@@ -1,36 +1,80 @@
import { Input } from 'antd';
import React, { useState } from 'react';
import { Input, Button } from 'antd';
import React, { useRef, useEffect, useState } from 'react';
import { useAppSelector } from '../../../../../../hooks/useAppSelector';
import { colors } from '../../../../../../styles/colors';
import { useTranslation } from 'react-i18next';
const AddSubTaskListRow = () => {
const [isEdit, setIsEdit] = useState<boolean>(false);
interface AddSubTaskListRowProps {
visibleColumns: { key: string; label: string; width: number }[];
taskColumnKey: string;
onAdd: (name: string) => void;
onCancel: () => void;
parentTaskId: string;
}
// localization
const AddSubTaskListRow: React.FC<AddSubTaskListRowProps> = ({
visibleColumns,
taskColumnKey,
onAdd,
onCancel,
}) => {
const [subtaskName, setSubtaskName] = useState('');
const inputRef = useRef<any>(null);
const { t } = useTranslation('task-list-table');
// get data theme data from redux
const themeMode = useAppSelector(state => state.themeReducer.mode);
const customBorderColor = themeMode === 'dark' && ' border-[#303030]';
const customBorderColor = themeMode === 'dark' ? ' border-[#303030]' : '';
useEffect(() => {
inputRef.current?.focus();
}, []);
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter' && subtaskName.trim()) {
onAdd(subtaskName.trim());
setSubtaskName('');
} else if (e.key === 'Escape') {
onCancel();
}
};
return (
<div className={`border-t ${customBorderColor}`}>
{isEdit ? (
<Input
className="h-12 w-full rounded-none"
style={{ borderColor: colors.skyBlue }}
placeholder={t('addTaskInputPlaceholder')}
onBlur={() => setIsEdit(false)}
/>
) : (
<Input
onFocus={() => setIsEdit(true)}
className="w-[300px] border-none"
value={t('addSubTaskText')}
/>
)}
</div>
<tr className={`add-subtask-row${customBorderColor}`}>
{visibleColumns.map(col => (
<td key={col.key} style={{ padding: 0, background: 'inherit' }}>
{col.key === taskColumnKey ? (
<div style={{ display: 'flex', alignItems: 'center', padding: '4px 0' }}>
<Input
ref={inputRef}
value={subtaskName}
onChange={e => setSubtaskName(e.target.value)}
onKeyDown={handleKeyDown}
onBlur={onCancel}
placeholder={t('enterSubtaskName')}
style={{ width: '100%' }}
autoFocus
/>
<Button
size="small"
type="primary"
style={{ marginLeft: 8 }}
disabled={!subtaskName.trim()}
onClick={() => {
if (subtaskName.trim()) {
onAdd(subtaskName.trim());
setSubtaskName('');
}
}}
>
{t('add')}
</Button>
<Button size="small" style={{ marginLeft: 4 }} onClick={onCancel}>
{t('cancel')}
</Button>
</div>
) : null}
</td>
))}
</tr>
);
};

View File

@@ -1365,6 +1365,7 @@ const TaskListTable: React.FC<TaskListTableProps> = ({ taskList, tableId, active
const [contextMenuPosition, setContextMenuPosition] = useState({ x: 0, y: 0 });
const [editingTaskId, setEditingTaskId] = useState<string | null>(null);
const [editColumnKey, setEditColumnKey] = useState<string | null>(null);
const [showAddSubtaskFor, setShowAddSubtaskFor] = useState<string | null>(null);
const toggleTaskExpansion = (taskId: string) => {
const task = displayTasks.find(t => t.id === taskId);
@@ -1857,14 +1858,38 @@ const TaskListTable: React.FC<TaskListTableProps> = ({ taskList, tableId, active
{renderTaskRow(updatedTask)}
{updatedTask.show_sub_tasks && (
<>
{updatedTask?.sub_tasks?.map(subtask =>
{updatedTask?.sub_tasks?.map(subtask =>
subtask?.id ? renderTaskRow(subtask, true) : null
)}
<tr key={`add-subtask-${updatedTask.id}`}>
<td colSpan={visibleColumns.length + 1}>
<AddTaskListRow groupId={tableId} parentTask={updatedTask.id} />
</td>
</tr>
{showAddSubtaskFor !== updatedTask.id && (
<tr key={`add-subtask-link-${updatedTask.id}`}>
<td colSpan={visibleColumns.length + 1}>
<div
style={{
padding: '8px 16px',
color: '#1677ff',
cursor: 'pointer',
fontWeight: 500,
background: '#f6f8fa'
}}
onClick={() => setShowAddSubtaskFor(updatedTask.id)}
>
+ Add Sub Task
</div>
</td>
</tr>
)}
{showAddSubtaskFor === updatedTask.id && (
<tr key={`add-subtask-input-${updatedTask.id}`}>
<td colSpan={visibleColumns.length + 1}>
<AddTaskListRow
groupId={tableId}
parentTask={updatedTask.id}
onCancel={() => setShowAddSubtaskFor(null)}
/>
</td>
</tr>
)}
</>
)}
</React.Fragment>