feat(KanbanFilters): add filter for hiding completed tasks older than 7 days

- Enhanced KanbanFilters component to include a new filter option for hiding tasks completed more than 15 days ago.
- Updated GeneralFilters component to display the new filter and its count.
- Modified TasksContext to calculate and provide the count of old completed tasks.
- Adjusted KanbanFiltersProps and related types to accommodate the new filter functionality.
This commit is contained in:
Julien Froidefond
2025-10-10 17:02:20 +02:00
parent 5dcfa19b0c
commit 583efaa8c5
4 changed files with 86 additions and 3 deletions

View File

@@ -39,7 +39,8 @@ export function KanbanFilters({
hiddenStatuses: propsHiddenStatuses, hiddenStatuses: propsHiddenStatuses,
onToggleStatusVisibility, onToggleStatusVisibility,
}: KanbanFiltersProps) { }: KanbanFiltersProps) {
const { regularTasks, activeFiltersCount } = useTasksContext(); const { regularTasks, activeFiltersCount, oldCompletedTasksCount } =
useTasksContext();
const { preferences, toggleColumnVisibility } = useUserPreferences(); const { preferences, toggleColumnVisibility } = useUserPreferences();
// Utiliser les props si disponibles, sinon utiliser le context // Utiliser les props si disponibles, sinon utiliser le context
@@ -130,6 +131,13 @@ export function KanbanFilters({
}); });
}; };
const handleHideCompletedOlderThan15DaysFilterToggle = () => {
onFiltersChange({
...filters,
hideCompletedOlderThan15Days: !filters.hideCompletedOlderThan15Days,
});
};
return ( return (
<ControlPanel className="bg-[var(--card)]/50 border-b border-[var(--border)]/50 backdrop-blur-sm"> <ControlPanel className="bg-[var(--card)]/50 border-b border-[var(--border)]/50 backdrop-blur-sm">
<div className="container mx-auto px-6 py-4"> <div className="container mx-auto px-6 py-4">
@@ -219,10 +227,17 @@ export function KanbanFilters({
<GeneralFilters <GeneralFilters
showWithDueDate={filters.showWithDueDate} showWithDueDate={filters.showWithDueDate}
showCompletedLast7Days={filters.showCompletedLast7Days} showCompletedLast7Days={filters.showCompletedLast7Days}
hideCompletedOlderThan15Days={
filters.hideCompletedOlderThan15Days
}
oldCompletedTasksCount={oldCompletedTasksCount || 0}
onDueDateFilterToggle={handleDueDateFilterToggle} onDueDateFilterToggle={handleDueDateFilterToggle}
onCompletedLast7DaysFilterToggle={ onCompletedLast7DaysFilterToggle={
handleCompletedLast7DaysFilterToggle handleCompletedLast7DaysFilterToggle
} }
onHideCompletedOlderThan15DaysFilterToggle={
handleHideCompletedOlderThan15DaysFilterToggle
}
/> />
</div> </div>

View File

@@ -1,21 +1,29 @@
'use client'; 'use client';
import { FilterChip } from '@/components/ui'; import { FilterChip } from '@/components/ui';
import { Calendar, CheckCircle } from 'lucide-react'; import { Calendar, CheckCircle, Clock } from 'lucide-react';
interface GeneralFiltersProps { interface GeneralFiltersProps {
showWithDueDate?: boolean; showWithDueDate?: boolean;
showCompletedLast7Days?: boolean; showCompletedLast7Days?: boolean;
hideCompletedOlderThan15Days?: boolean;
oldCompletedTasksCount?: number;
onDueDateFilterToggle: () => void; onDueDateFilterToggle: () => void;
onCompletedLast7DaysFilterToggle: () => void; onCompletedLast7DaysFilterToggle: () => void;
onHideCompletedOlderThan15DaysFilterToggle: () => void;
} }
export function GeneralFilters({ export function GeneralFilters({
showWithDueDate = false, showWithDueDate = false,
showCompletedLast7Days = false, showCompletedLast7Days = false,
hideCompletedOlderThan15Days = false,
oldCompletedTasksCount = 0,
onDueDateFilterToggle, onDueDateFilterToggle,
onCompletedLast7DaysFilterToggle, onCompletedLast7DaysFilterToggle,
onHideCompletedOlderThan15DaysFilterToggle,
}: GeneralFiltersProps) { }: GeneralFiltersProps) {
console.log('GeneralFilters render:', { oldCompletedTasksCount });
return ( return (
<div className="space-y-2"> <div className="space-y-2">
<label className="block text-xs font-mono font-medium text-[var(--muted-foreground)] uppercase tracking-wider"> <label className="block text-xs font-mono font-medium text-[var(--muted-foreground)] uppercase tracking-wider">
@@ -37,6 +45,15 @@ export function GeneralFilters({
> >
Complété les 7 derniers jours Complété les 7 derniers jours
</FilterChip> </FilterChip>
<FilterChip
onClick={onHideCompletedOlderThan15DaysFilterToggle}
variant={hideCompletedOlderThan15Days ? 'selected' : 'default'}
icon={<Clock className="w-4 h-4" />}
count={oldCompletedTasksCount}
>
Masquer terminés +7j
</FilterChip>
</div> </div>
</div> </div>
); );

View File

@@ -34,6 +34,7 @@ interface TasksContextType {
filteredTasks: Task[]; filteredTasks: Task[];
pinnedTasks: Task[]; // Tâches avec tags épinglés (objectifs) pinnedTasks: Task[]; // Tâches avec tags épinglés (objectifs)
activeFiltersCount: number; // Nombre de filtres actifs activeFiltersCount: number; // Nombre de filtres actifs
oldCompletedTasksCount: number; // Nombre de tâches terminées depuis +15j
// Tags // Tags
tags: Tag[]; tags: Tag[];
tagsLoading: boolean; tagsLoading: boolean;
@@ -64,6 +65,11 @@ export function TasksProvider({
const { preferences, updateKanbanFilters, updateViewPreferences } = const { preferences, updateKanbanFilters, updateViewPreferences } =
useUserPreferences(); useUserPreferences();
// Fonction utilitaire pour identifier les statuts terminés
const isCompletedStatus = (status: TaskStatus): boolean => {
return ['done', 'cancelled', 'archived'].includes(status);
};
// Construire l'objet KanbanFilters à partir des préférences // Construire l'objet KanbanFilters à partir des préférences
const kanbanFilters: KanbanFilters = useMemo( const kanbanFilters: KanbanFilters = useMemo(
() => ({ () => ({
@@ -79,6 +85,8 @@ export function TasksProvider({
showWithDueDate: preferences.kanbanFilters.showWithDueDate || false, showWithDueDate: preferences.kanbanFilters.showWithDueDate || false,
showCompletedLast7Days: showCompletedLast7Days:
preferences.kanbanFilters.showCompletedLast7Days || false, preferences.kanbanFilters.showCompletedLast7Days || false,
hideCompletedOlderThan15Days:
preferences.kanbanFilters.hideCompletedOlderThan15Days || false,
// Filtres Jira // Filtres Jira
showJiraOnly: preferences.kanbanFilters.showJiraOnly || false, showJiraOnly: preferences.kanbanFilters.showJiraOnly || false,
hideJiraTasks: preferences.kanbanFilters.hideJiraTasks || false, hideJiraTasks: preferences.kanbanFilters.hideJiraTasks || false,
@@ -106,6 +114,7 @@ export function TasksProvider({
sortBy: newFilters.sortBy, sortBy: newFilters.sortBy,
showWithDueDate: newFilters.showWithDueDate, showWithDueDate: newFilters.showWithDueDate,
showCompletedLast7Days: newFilters.showCompletedLast7Days, showCompletedLast7Days: newFilters.showCompletedLast7Days,
hideCompletedOlderThan15Days: newFilters.hideCompletedOlderThan15Days,
// Filtres Jira // Filtres Jira
showJiraOnly: newFilters.showJiraOnly, showJiraOnly: newFilters.showJiraOnly,
hideJiraTasks: newFilters.hideJiraTasks, hideJiraTasks: newFilters.hideJiraTasks,
@@ -277,12 +286,25 @@ export function TasksProvider({
filtered = filtered.filter( filtered = filtered.filter(
(task) => (task) =>
task.status === 'done' && isCompletedStatus(task.status) &&
task.completedAt && task.completedAt &&
task.completedAt >= sevenDaysAgo task.completedAt >= sevenDaysAgo
); );
} }
// Filtre pour masquer les tâches terminées depuis plus de 7 jours
if (kanbanFilters.hideCompletedOlderThan15Days) {
const sevenDaysAgo = new Date();
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
filtered = filtered.filter(
(task) =>
!isCompletedStatus(task.status) ||
!task.completedAt ||
task.completedAt >= sevenDaysAgo
);
}
// Tri des tâches // Tri des tâches
if (kanbanFilters.sortBy) { if (kanbanFilters.sortBy) {
const sortOption = getSortOption(kanbanFilters.sortBy); const sortOption = getSortOption(kanbanFilters.sortBy);
@@ -302,6 +324,33 @@ export function TasksProvider({
return filtered; return filtered;
}, [regularTasks, kanbanFilters]); }, [regularTasks, kanbanFilters]);
// Calculer le nombre de tickets terminés depuis plus de 7 jours
const oldCompletedTasksCount = useMemo(() => {
if (!regularTasks || regularTasks.length === 0) return 0;
const sevenDaysAgo = new Date();
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
const oldTasks = regularTasks.filter(
(task) =>
isCompletedStatus(task.status) &&
task.completedAt &&
task.completedAt < sevenDaysAgo
);
console.log('Debug old completed tasks:', {
sevenDaysAgo: sevenDaysAgo.toISOString(),
oldTasks: oldTasks.map((t) => ({
title: t.title,
status: t.status,
completedAt: t.completedAt,
isOld: t.completedAt ? t.completedAt < sevenDaysAgo : false,
})),
});
return oldTasks.length;
}, [regularTasks]);
const contextValue: TasksContextType = { const contextValue: TasksContextType = {
...tasksState, ...tasksState,
regularTasks, regularTasks,
@@ -313,6 +362,7 @@ export function TasksProvider({
filteredTasks, filteredTasks,
pinnedTasks, pinnedTasks,
activeFiltersCount, activeFiltersCount,
oldCompletedTasksCount,
}; };
return ( return (

View File

@@ -85,6 +85,7 @@ export interface KanbanFilters {
sortBy?: string; sortBy?: string;
showWithDueDate?: boolean; showWithDueDate?: boolean;
showCompletedLast7Days?: boolean; showCompletedLast7Days?: boolean;
hideCompletedOlderThan15Days?: boolean;
// Filtres spécifiques Jira // Filtres spécifiques Jira
showJiraOnly?: boolean; showJiraOnly?: boolean;
hideJiraTasks?: boolean; hideJiraTasks?: boolean;