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:
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user