refactor(task-list): unify date handling and enhance column widths

- Updated TaskRow component to handle both camelCase and snake_case date fields for created and updated timestamps.
- Adjusted column widths for due date, start date, completed date, created date, and last updated fields for better layout consistency.
- Ensured whitespace handling in date display spans for improved UI presentation.
This commit is contained in:
chamikaJ
2025-07-09 12:32:17 +05:30
parent 29a09ec500
commit 10c53d954e
4 changed files with 32 additions and 30 deletions

View File

@@ -161,9 +161,9 @@ const TaskRow: React.FC<TaskRowProps> = memo(({ taskId, projectId, visibleColumn
})(),
start: task.startDate ? formatDate(task.startDate) : null,
completed: task.completedAt ? formatDate(task.completedAt) : null,
created: task.created_at ? formatDate(task.created_at) : null,
created: (task.createdAt || task.created_at) ? formatDate(task.createdAt || task.created_at) : null,
updated: task.updatedAt ? formatDate(task.updatedAt) : null,
}), [task.dueDate, task.due_date, task.startDate, task.completedAt, task.created_at, task.updatedAt]);
}), [task.dueDate, task.due_date, task.startDate, task.completedAt, task.createdAt, task.created_at, task.updatedAt]);
// Memoize date values for DatePicker
const dateValues = useMemo(
@@ -517,11 +517,11 @@ const TaskRow: React.FC<TaskRowProps> = memo(({ taskId, projectId, visibleColumn
}}
>
{formattedDates.due ? (
<span className="text-sm text-gray-500 dark:text-gray-400">
<span className="text-sm text-gray-500 dark:text-gray-400 whitespace-nowrap">
{formattedDates.due}
</span>
) : (
<span className="text-sm text-gray-400 dark:text-gray-500">
<span className="text-sm text-gray-400 dark:text-gray-500 whitespace-nowrap">
{t('setDueDate')}
</span>
)}
@@ -640,11 +640,11 @@ const TaskRow: React.FC<TaskRowProps> = memo(({ taskId, projectId, visibleColumn
}}
>
{formattedDates.start ? (
<span className="text-sm text-gray-500 dark:text-gray-400">
<span className="text-sm text-gray-500 dark:text-gray-400 whitespace-nowrap">
{formattedDates.start}
</span>
) : (
<span className="text-sm text-gray-400 dark:text-gray-500">
<span className="text-sm text-gray-400 dark:text-gray-500 whitespace-nowrap">
{t('setStartDate')}
</span>
)}
@@ -657,11 +657,11 @@ const TaskRow: React.FC<TaskRowProps> = memo(({ taskId, projectId, visibleColumn
return (
<div className="flex items-center justify-center px-2" style={baseStyle}>
{formattedDates.completed ? (
<span className="text-sm text-gray-500 dark:text-gray-400">
<span className="text-sm text-gray-500 dark:text-gray-400 whitespace-nowrap">
{formattedDates.completed}
</span>
) : (
<span className="text-sm text-gray-400 dark:text-gray-500">-</span>
<span className="text-sm text-gray-400 dark:text-gray-500 whitespace-nowrap">-</span>
)}
</div>
);
@@ -670,24 +670,25 @@ const TaskRow: React.FC<TaskRowProps> = memo(({ taskId, projectId, visibleColumn
return (
<div className="flex items-center justify-center px-2" style={baseStyle}>
{formattedDates.created ? (
<span className="text-sm text-gray-500 dark:text-gray-400">
<span className="text-sm text-gray-500 dark:text-gray-400 whitespace-nowrap">
{formattedDates.created}
</span>
) : (
<span className="text-sm text-gray-400 dark:text-gray-500">-</span>
<span className="text-sm text-gray-400 dark:text-gray-500 whitespace-nowrap">-</span>
)}
</div>
);
case 'lastUpdated':
console.log('formattedDates.updated', formattedDates.updated);
return (
<div className="flex items-center justify-center px-2" style={baseStyle}>
{formattedDates.updated ? (
<span className="text-sm text-gray-500 dark:text-gray-400">
<span className="text-sm text-gray-500 dark:text-gray-400 whitespace-nowrap">
{formattedDates.updated}
</span>
) : (
<span className="text-sm text-gray-400 dark:text-gray-500">-</span>
<span className="text-sm text-gray-400 dark:text-gray-500 whitespace-nowrap">-</span>
)}
</div>
);
@@ -696,9 +697,9 @@ const TaskRow: React.FC<TaskRowProps> = memo(({ taskId, projectId, visibleColumn
return (
<div className="flex items-center justify-center px-2" style={baseStyle}>
{task.reporter ? (
<span className="text-sm text-gray-500 dark:text-gray-400">{task.reporter}</span>
<span className="text-sm text-gray-500 dark:text-gray-400 whitespace-nowrap">{task.reporter}</span>
) : (
<span className="text-sm text-gray-400 dark:text-gray-500">-</span>
<span className="text-sm text-gray-400 dark:text-gray-500 whitespace-nowrap">-</span>
)}
</div>
);

View File

@@ -21,16 +21,16 @@ export const BASE_COLUMNS = [
{ id: 'status', label: 'statusColumn', width: '120px', key: COLUMN_KEYS.STATUS },
{ id: 'assignees', label: 'assigneesColumn', width: '150px', key: COLUMN_KEYS.ASSIGNEES },
{ id: 'priority', label: 'priorityColumn', width: '120px', key: COLUMN_KEYS.PRIORITY },
{ id: 'dueDate', label: 'dueDateColumn', width: '120px', key: COLUMN_KEYS.DUE_DATE },
{ id: 'dueDate', label: 'dueDateColumn', width: '140px', key: COLUMN_KEYS.DUE_DATE },
{ id: 'progress', label: 'progressColumn', width: '120px', key: COLUMN_KEYS.PROGRESS },
{ id: 'labels', label: 'labelsColumn', width: 'auto', key: COLUMN_KEYS.LABELS },
{ id: 'phase', label: 'phaseColumn', width: '120px', key: COLUMN_KEYS.PHASE },
{ id: 'timeTracking', label: 'timeTrackingColumn', width: '120px', key: COLUMN_KEYS.TIME_TRACKING },
{ id: 'estimation', label: 'estimationColumn', width: '120px', key: COLUMN_KEYS.ESTIMATION },
{ id: 'startDate', label: 'startDateColumn', width: '120px', key: COLUMN_KEYS.START_DATE },
{ id: 'startDate', label: 'startDateColumn', width: '140px', key: COLUMN_KEYS.START_DATE },
{ id: 'dueTime', label: 'dueTimeColumn', width: '120px', key: COLUMN_KEYS.DUE_TIME },
{ id: 'completedDate', label: 'completedDateColumn', width: '120px', key: COLUMN_KEYS.COMPLETED_DATE },
{ id: 'createdDate', label: 'createdDateColumn', width: '120px', key: COLUMN_KEYS.CREATED_DATE },
{ id: 'lastUpdated', label: 'lastUpdatedColumn', width: '120px', key: COLUMN_KEYS.LAST_UPDATED },
{ id: 'completedDate', label: 'completedDateColumn', width: '140px', key: COLUMN_KEYS.COMPLETED_DATE },
{ id: 'createdDate', label: 'createdDateColumn', width: '140px', key: COLUMN_KEYS.CREATED_DATE },
{ id: 'lastUpdated', label: 'lastUpdatedColumn', width: '140px', key: COLUMN_KEYS.LAST_UPDATED },
{ id: 'reporter', label: 'reporterColumn', width: '120px', key: COLUMN_KEYS.REPORTER },
];

View File

@@ -171,10 +171,10 @@ export const fetchTasks = createAsyncThunk(
logged: convertTimeValue(task.time_spent),
},
customFields: {},
createdAt: task.created_at || new Date().toISOString(),
updatedAt: task.updated_at || new Date().toISOString(),
created_at: task.created_at || new Date().toISOString(),
updated_at: task.updated_at || new Date().toISOString(),
createdAt: task.createdAt || task.created_at || new Date().toISOString(),
updatedAt: task.updatedAt || task.updated_at || new Date().toISOString(),
created_at: task.createdAt || task.created_at || new Date().toISOString(),
updated_at: task.updatedAt || task.updated_at || new Date().toISOString(),
order: typeof task.sort_order === 'number' ? task.sort_order : 0,
// Ensure all Task properties are mapped, even if undefined in API response
sub_tasks: task.sub_tasks || [],
@@ -285,10 +285,10 @@ export const fetchTasksV3 = createAsyncThunk(
},
customFields: {},
custom_column_values: task.custom_column_values || {},
createdAt: task.created_at || now,
updatedAt: task.updated_at || now,
created_at: task.created_at || now,
updated_at: task.updated_at || now,
createdAt: task.createdAt || task.created_at || now,
updatedAt: task.updatedAt || task.updated_at || now,
created_at: task.createdAt || task.created_at || now,
updated_at: task.updatedAt || task.updated_at || now,
order: typeof task.sort_order === 'number' ? task.sort_order : 0,
sub_tasks: task.sub_tasks || [],
sub_tasks_count: task.sub_tasks_count || 0,

View File

@@ -19,9 +19,10 @@ export interface Task {
dueDate?: string; // Alternative due date field
startDate?: string; // Start date field
completedAt?: string; // Completion date
updatedAt?: string; // Update timestamp
created_at: string;
updated_at: string;
updatedAt?: string; // Update timestamp (camelCase from API)
createdAt?: string; // Creation timestamp (camelCase from API)
created_at: string; // Creation timestamp (snake_case, legacy)
updated_at: string; // Update timestamp (snake_case, legacy)
sub_tasks?: Task[];
sub_tasks_count?: number;
show_sub_tasks?: boolean;