trello_fake/types/task.ts

177 lines
5.9 KiB
TypeScript

// types/task.ts
// Estado de la tarea en Dolibarr
export type TaskStatus = '0' | '1' | '2'; // 0: borrador, 1: validada, 2: cerrada/completada
// Prioridad de la tarea
export type TaskPriority = '0' | '1' | '2' | '3'; // 0: ninguna, 1: baja, 2: media, 3: alta
// Interface para los datos crudos que vienen de Dolibarr
export interface DolibarrTask {
id: string | number;
ref: string;
label: string;
description: string;
fk_project: string | number;
fk_task_parent: string | number;
date_start: number | null;
date_end: number | null;
dateo: number | null; // fecha planificada inicio
datee: number | null; // fecha planificada fin
date_c: number | null;
date_m: number | null;
duration_effective: number; // segundos trabajados
planned_workload: number; // segundos planificados
progress: number | string;
priority: string | number;
budget_amount: string | number;
rang: number;
status: string;
note_public: string;
note_private: string;
fk_user_creat: string | number;
fk_user_valid: string | number;
// Campos adicionales que puede devolver la API
timespent?: number;
array_options?: Record<string, unknown>;
}
// Interface normalizada para la UI
export interface Task {
id: number;
ref: string;
title: string;
description: string;
projectId: number;
parentTaskId: number | null;
status: TaskStatus;
priority: TaskPriority;
progress: number;
plannedHours: number;
workedHours: number;
budget: number;
startDate: string | null;
endDate: string | null;
plannedStartDate: string | null;
plannedEndDate: string | null;
createdAt: string;
updatedAt: string;
createdBy: number;
order: number;
}
// Configuración de estados de tarea
export const TASK_STATUS_CONFIG: Record<TaskStatus, { label: string; color: string; bgClass: string }> = {
'0': {
label: 'Borrador',
color: 'gray',
bgClass: 'bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-300'
},
'1': {
label: 'Validada',
color: 'blue',
bgClass: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400'
},
'2': {
label: 'Completada',
color: 'green',
bgClass: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400'
},
};
// Configuración de prioridades
export const TASK_PRIORITY_CONFIG: Record<TaskPriority, { label: string; color: string; bgClass: string }> = {
'0': {
label: 'Sin prioridad',
color: 'gray',
bgClass: 'bg-gray-100 text-gray-600 dark:bg-gray-800 dark:text-gray-400'
},
'1': {
label: 'Baja',
color: 'blue',
bgClass: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400'
},
'2': {
label: 'Media',
color: 'yellow',
bgClass: 'bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400'
},
'3': {
label: 'Alta',
color: 'red',
bgClass: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400'
},
};
// Helper para convertir timestamp a fecha ISO
function timestampToDateString(timestamp: number | null | undefined): string | null {
if (!timestamp || timestamp === 0) {
return null;
}
return new Date(timestamp * 1000).toISOString().split('T')[0];
}
// Helper para convertir segundos a horas
function secondsToHours(seconds: number | null | undefined): number {
if (!seconds) return 0;
return Math.round((seconds / 3600) * 10) / 10; // Redondear a 1 decimal
}
// Función para mapear tarea de Dolibarr al formato UI
export function mapDolibarrTask(dolibarr: DolibarrTask): Task {
const progress = typeof dolibarr.progress === 'string'
? parseFloat(dolibarr.progress)
: (dolibarr.progress || 0);
const priority = String(dolibarr.priority || '0') as TaskPriority;
const validPriorities: TaskPriority[] = ['0', '1', '2', '3'];
const safePriority: TaskPriority = validPriorities.includes(priority) ? priority : '0';
const status = String(dolibarr.status || '0') as TaskStatus;
const validStatuses: TaskStatus[] = ['0', '1', '2'];
const safeStatus: TaskStatus = validStatuses.includes(status) ? status : '0';
return {
id: typeof dolibarr.id === 'string' ? parseInt(dolibarr.id) : dolibarr.id,
ref: dolibarr.ref || '',
title: dolibarr.label || 'Sin título',
description: dolibarr.description || '',
projectId: typeof dolibarr.fk_project === 'string'
? parseInt(dolibarr.fk_project)
: dolibarr.fk_project,
parentTaskId: dolibarr.fk_task_parent
? (typeof dolibarr.fk_task_parent === 'string'
? parseInt(dolibarr.fk_task_parent)
: dolibarr.fk_task_parent)
: null,
status: safeStatus,
priority: safePriority,
progress: Math.min(Math.max(progress, 0), 100), // Asegurar entre 0-100
plannedHours: secondsToHours(dolibarr.planned_workload),
workedHours: secondsToHours(dolibarr.duration_effective || dolibarr.timespent),
budget: typeof dolibarr.budget_amount === 'string'
? parseFloat(dolibarr.budget_amount) || 0
: (dolibarr.budget_amount || 0),
startDate: timestampToDateString(dolibarr.date_start),
endDate: timestampToDateString(dolibarr.date_end),
plannedStartDate: timestampToDateString(dolibarr.dateo),
plannedEndDate: timestampToDateString(dolibarr.datee),
createdAt: timestampToDateString(dolibarr.date_c) || new Date().toISOString().split('T')[0],
updatedAt: timestampToDateString(dolibarr.date_m) || new Date().toISOString().split('T')[0],
createdBy: typeof dolibarr.fk_user_creat === 'string'
? parseInt(dolibarr.fk_user_creat)
: (dolibarr.fk_user_creat || 0),
order: dolibarr.rang || 0,
};
}
// Helper para obtener label de estado
export function getTaskStatusLabel(status: TaskStatus): string {
return TASK_STATUS_CONFIG[status]?.label || 'Desconocido';
}
// Helper para obtener label de prioridad
export function getTaskPriorityLabel(priority: TaskPriority): string {
return TASK_PRIORITY_CONFIG[priority]?.label || 'Sin prioridad';
}