feat: enhance AchievementCard and ManagerSummaryService logic

- Added logic to differentiate between regular achievements and todos in `AchievementCard`, changing background color accordingly.
- Updated todos count display to only show for non-todo achievements, improving clarity.
- Refactored `ManagerSummaryService` to remove outdated filters and allow unlimited display of accomplishments and challenges, enhancing data visibility.
- Simplified priority handling by including 'urgent' as a high priority, ensuring better task categorization.
This commit is contained in:
Julien Froidefond
2025-09-29 22:37:00 +02:00
parent 1d7c2b5e1a
commit c647725536
2 changed files with 14 additions and 75 deletions

View File

@@ -34,9 +34,14 @@ export function AchievementCard({
maxTags = 2, maxTags = 2,
className = '' className = ''
}: AchievementCardProps) { }: AchievementCardProps) {
// Détecter si c'est un todo (ID commence par "todo-")
const isTodo = achievement.id.startsWith('todo-');
return ( return (
<div className={`relative border border-[var(--border)] rounded-lg p-3 transition-all duration-200 group ${className}`} style={{ <div className={`relative border border-[var(--border)] rounded-lg p-3 transition-all duration-200 group ${className}`} style={{
backgroundColor: 'color-mix(in srgb, var(--success) 5%, var(--card))' backgroundColor: isTodo
? 'color-mix(in srgb, var(--accent) 8%, var(--card))'
: 'color-mix(in srgb, var(--success) 5%, var(--card))'
}}> }}>
{/* Barre colorée gauche */} {/* Barre colorée gauche */}
<div className="absolute left-0 top-0 bottom-0 w-1 bg-green-500 rounded-l-lg"></div> <div className="absolute left-0 top-0 bottom-0 w-1 bg-green-500 rounded-l-lg"></div>
@@ -81,8 +86,8 @@ export function AchievementCard({
</p> </p>
)} )}
{/* Count de todos */} {/* Count de todos - seulement pour les tâches, pas pour les todos standalone */}
{achievement.todosCount !== undefined && achievement.todosCount > 0 && ( {!isTodo && achievement.todosCount !== undefined && achievement.todosCount > 0 && (
<div className="flex items-center gap-1 text-xs text-[var(--muted-foreground)]"> <div className="flex items-center gap-1 text-xs text-[var(--muted-foreground)]">
<span>📋</span> <span>📋</span>
<span>{achievement.todosCount} todo{achievement.todosCount > 1 ? 's' : ''}</span> <span>{achievement.todosCount} todo{achievement.todosCount > 1 ? 's' : ''}</span>

View File

@@ -132,22 +132,6 @@ export class ManagerSummaryService {
gte: startDate, gte: startDate,
lte: endDate lte: endDate
} }
},
// Tâches avec status 'done' et updatedAt dans la période
{
status: 'done',
updatedAt: {
gte: startDate,
lte: endDate
}
},
// Tâches avec status 'archived' récemment (aussi des accomplissements)
{
status: 'archived',
updatedAt: {
gte: startDate,
lte: endDate
}
} }
] ]
}, },
@@ -233,15 +217,12 @@ export class ManagerSummaryService {
// Convertir priorité task en impact accomplissement // Convertir priorité task en impact accomplissement
let impact: 'high' | 'medium' | 'low'; let impact: 'high' | 'medium' | 'low';
if (priority === 'high') { if (priority === 'high' || priority === 'urgent') {
impact = 'high'; impact = 'high';
} else if (priority === 'medium') { } else if (priority === 'medium') {
impact = 'medium'; impact = 'medium';
} else { } else {
// Pour les low priority, ne garder que si c'est vraiment significatif // Pour les low priority, tout prendre
if (!this.isSignificantTask(task.title)) {
continue;
}
impact = 'low'; impact = 'low';
} }
@@ -300,7 +281,7 @@ export class ManagerSummaryService {
} }
return b.completedAt.getTime() - a.completedAt.getTime(); return b.completedAt.getTime() - a.completedAt.getTime();
}) })
.slice(0, 12); // Plus d'items maintenant qu'on filtre mieux // Pas de limite - afficher tous les accomplissements
} }
/** /**
@@ -393,15 +374,12 @@ export class ManagerSummaryService {
// Convertir priorité task en priorité challenge // Convertir priorité task en priorité challenge
let priority: 'high' | 'medium' | 'low'; let priority: 'high' | 'medium' | 'low';
if (taskPriority === 'high') { if (taskPriority === 'high' || taskPriority === 'urgent') {
priority = 'high'; priority = 'high';
} else if (taskPriority === 'medium') { } else if (taskPriority === 'medium') {
priority = 'medium'; priority = 'medium';
} else { } else {
// Pour les low priority, ne garder que si c'est vraiment challengeant // Pour les low priority, tout prendre
if (!this.isChallengingTask(task.title)) {
return;
}
priority = 'low'; priority = 'low';
} }
@@ -463,7 +441,7 @@ export class ManagerSummaryService {
const priorityOrder = { high: 3, medium: 2, low: 1 }; const priorityOrder = { high: 3, medium: 2, low: 1 };
return priorityOrder[b.priority] - priorityOrder[a.priority]; return priorityOrder[b.priority] - priorityOrder[a.priority];
}) })
.slice(0, 10); // Plus d'items maintenant qu'on filtre mieux // Pas de limite - afficher tous les challenges
} }
/** /**
@@ -501,50 +479,6 @@ export class ManagerSummaryService {
return blockers; return blockers;
} }
/**
* Détermine si une tâche est significative
*/
private static isSignificantTask(title: string): boolean {
const significantKeywords = [
'release', 'deploy', 'launch', 'milestone',
'architecture', 'design', 'strategy',
'integration', 'migration', 'optimization'
];
return significantKeywords.some(keyword => title.toLowerCase().includes(keyword));
}
/**
* Détermine si une checkbox est significative
*/
private static isSignificantCheckbox(text: string): boolean {
const content = text.toLowerCase();
return content.length > 30 || // Checkboxes détaillées
content.includes('meeting') ||
content.includes('review') ||
content.includes('call') ||
content.includes('presentation');
}
/**
* Détermine si une tâche représente un défi
*/
private static isChallengingTask(title: string): boolean {
const challengingKeywords = [
'complex', 'difficult', 'challenge',
'architecture', 'performance', 'security',
'integration', 'migration', 'optimization'
];
return challengingKeywords.some(keyword => title.toLowerCase().includes(keyword));
}
/**
* Analyse les patterns dans les checkboxes pour identifier des enjeux
*/
private static analyzeCheckboxPatterns(): UpcomingChallenge[] {
// Pour l'instant, retourner un array vide
// À implémenter selon les besoins spécifiques
return [];
}
/** /**
* Calcule les métriques résumées * Calcule les métriques résumées