import { Task, TaskPriority } from './types'; import { getPriorityConfig } from './status-config'; export type SortField = 'priority' | 'tags' | 'createdAt' | 'updatedAt' | 'dueDate' | 'title'; export type SortDirection = 'asc' | 'desc'; export interface SortConfig { field: SortField; direction: SortDirection; } export interface SortOption { key: string; label: string; field: SortField; direction: SortDirection; icon: string; } // Configuration des options de tri disponibles export const SORT_OPTIONS: SortOption[] = [ { key: 'priority-desc', label: 'Priorité (Urgente → Faible)', field: 'priority', direction: 'desc', icon: '🔥' }, { key: 'priority-asc', label: 'Priorité (Faible → Urgente)', field: 'priority', direction: 'asc', icon: '🔵' }, { key: 'tags-asc', label: 'Tags (A → Z)', field: 'tags', direction: 'asc', icon: '🏷️' }, { key: 'title-asc', label: 'Titre (A → Z)', field: 'title', direction: 'asc', icon: '📝' }, { key: 'title-desc', label: 'Titre (Z → A)', field: 'title', direction: 'desc', icon: '📝' }, { key: 'createdAt-desc', label: 'Date création (Récent → Ancien)', field: 'createdAt', direction: 'desc', icon: '📅' }, { key: 'createdAt-asc', label: 'Date création (Ancien → Récent)', field: 'createdAt', direction: 'asc', icon: '📅' }, { key: 'dueDate-asc', label: 'Échéance (Proche → Lointaine)', field: 'dueDate', direction: 'asc', icon: '⏰' }, { key: 'dueDate-desc', label: 'Échéance (Lointaine → Proche)', field: 'dueDate', direction: 'desc', icon: '⏰' } ]; // Tri par défaut : Priorité (desc) puis Tags (asc) export const DEFAULT_SORT: SortConfig[] = [ { field: 'priority', direction: 'desc' }, { field: 'tags', direction: 'asc' } ]; /** * Compare deux valeurs selon la direction de tri */ function compareValues(a: T, b: T, direction: SortDirection): number { if (a === b) return 0; if (a == null) return 1; if (b == null) return -1; const result = a < b ? -1 : 1; return direction === 'asc' ? result : -result; } /** * Obtient la valeur de priorité numérique pour le tri */ function getPriorityValue(priority: TaskPriority): number { return getPriorityConfig(priority).order; } /** * Obtient le premier tag pour le tri (ou chaîne vide si pas de tags) */ function getFirstTag(task: Task): string { return task.tags?.[0]?.toLowerCase() || ''; } /** * Compare deux tâches selon un critère de tri */ function compareTasksByField(a: Task, b: Task, sortConfig: SortConfig): number { const { field, direction } = sortConfig; switch (field) { case 'priority': return compareValues( getPriorityValue(a.priority), getPriorityValue(b.priority), direction ); case 'tags': return compareValues( getFirstTag(a), getFirstTag(b), direction ); case 'title': return compareValues( a.title.toLowerCase(), b.title.toLowerCase(), direction ); case 'createdAt': return compareValues( new Date(a.createdAt).getTime(), new Date(b.createdAt).getTime(), direction ); case 'updatedAt': return compareValues( new Date(a.updatedAt).getTime(), new Date(b.updatedAt).getTime(), direction ); case 'dueDate': return compareValues( a.dueDate ? new Date(a.dueDate).getTime() : null, b.dueDate ? new Date(b.dueDate).getTime() : null, direction ); default: return 0; } } /** * Trie un tableau de tâches selon une configuration de tri multiple */ export function sortTasks(tasks: Task[], sortConfigs: SortConfig[] = DEFAULT_SORT): Task[] { return [...tasks].sort((a, b) => { for (const sortConfig of sortConfigs) { const result = compareTasksByField(a, b, sortConfig); if (result !== 0) { return result; } } return 0; }); } /** * Utilitaire pour obtenir une option de tri par sa clé */ export function getSortOption(key: string): SortOption | undefined { return SORT_OPTIONS.find(option => option.key === key); } /** * Utilitaire pour créer une clé de tri */ export function createSortKey(field: SortField, direction: SortDirection): string { return `${field}-${direction}`; }