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