feat: add filter for completed tasks in the last 7 days

- Implemented `showCompletedLast7Days` filter in `KanbanFilters` to toggle visibility of tasks completed in the last week.
- Updated `GeneralFilters` to include a new filter chip for the completed tasks toggle.
- Enhanced `TasksProvider` to filter tasks based on the new criteria, improving task management capabilities.
- Adjusted `FilterSummary` to display the active filter status for better user feedback.
This commit is contained in:
Julien Froidefond
2025-09-29 22:24:03 +02:00
parent dc46232dd7
commit 1d7c2b5e1a
7 changed files with 66 additions and 5 deletions

View File

@@ -138,6 +138,13 @@ export function KanbanFilters({ filters, onFiltersChange, hiddenStatuses: propsH
});
};
const handleCompletedLast7DaysFilterToggle = () => {
onFiltersChange({
...filters,
showCompletedLast7Days: !filters.showCompletedLast7Days
});
};
return (
<ControlPanel className="bg-[var(--card)]/50 border-b border-[var(--border)]/50 backdrop-blur-sm">
<div className="container mx-auto px-6 py-4">
@@ -230,7 +237,9 @@ export function KanbanFilters({ filters, onFiltersChange, hiddenStatuses: propsH
<GeneralFilters
showWithDueDate={filters.showWithDueDate}
showCompletedLast7Days={filters.showCompletedLast7Days}
onDueDateFilterToggle={handleDueDateFilterToggle}
onCompletedLast7DaysFilterToggle={handleCompletedLast7DaysFilterToggle}
/>
</div>

View File

@@ -55,4 +55,4 @@ export function KanbanHeader({
)}
</>
);
}
}

View File

@@ -4,10 +4,17 @@ import { FilterChip } from '@/components/ui';
interface GeneralFiltersProps {
showWithDueDate?: boolean;
showCompletedLast7Days?: boolean;
onDueDateFilterToggle: () => void;
onCompletedLast7DaysFilterToggle: () => void;
}
export function GeneralFilters({ showWithDueDate = false, onDueDateFilterToggle }: GeneralFiltersProps) {
export function GeneralFilters({
showWithDueDate = false,
showCompletedLast7Days = false,
onDueDateFilterToggle,
onCompletedLast7DaysFilterToggle
}: GeneralFiltersProps) {
return (
<div className="space-y-2">
<label className="block text-xs font-mono font-medium text-[var(--muted-foreground)] uppercase tracking-wider">
@@ -30,6 +37,23 @@ export function GeneralFilters({ showWithDueDate = false, onDueDateFilterToggle
>
Avec date de fin
</FilterChip>
<FilterChip
onClick={onCompletedLast7DaysFilterToggle}
variant={showCompletedLast7Days ? 'selected' : 'default'}
icon={
<svg
className="w-4 h-4"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
}
>
Complété les 7 derniers jours
</FilterChip>
</div>
</div>
);

View File

@@ -9,6 +9,7 @@ interface FilterSummaryProps {
priorities?: string[];
tags?: string[];
showWithDueDate?: boolean;
showCompletedLast7Days?: boolean;
showJiraOnly?: boolean;
hideJiraTasks?: boolean;
jiraProjects?: string[];
@@ -72,6 +73,15 @@ export function FilterSummary({
});
}
// Affichage complété les 7 derniers jours
if (filters.showCompletedLast7Days) {
filterItems.push({
label: 'Affichage',
value: 'Complété les 7 derniers jours',
variant: 'success'
});
}
// Jira
if (filters.showJiraOnly) {
filterItems.push({

View File

@@ -517,10 +517,11 @@ const TaskCard = forwardRef<HTMLDivElement, TaskCardProps>(
</Badge>
)}
{/* Statut terminé */}
{/* Statut terminé avec date de résolution */}
{completedAt && (
<span className="text-emerald-400 font-mono font-bold">
DONE
<span className="text-emerald-400 font-mono font-bold flex items-center gap-1">
<span></span>
<span>{formatDateForDisplay(completedAt, 'DISPLAY_SHORT')}</span>
</span>
)}

View File

@@ -61,6 +61,7 @@ export function TasksProvider({ children, initialTasks, initialTags, initialStat
swimlanesByTags: preferences.viewPreferences.swimlanesByTags || false,
swimlanesMode: preferences.viewPreferences.swimlanesMode || 'tags',
showWithDueDate: preferences.kanbanFilters.showWithDueDate || false,
showCompletedLast7Days: preferences.kanbanFilters.showCompletedLast7Days || false,
// Filtres Jira
showJiraOnly: preferences.kanbanFilters.showJiraOnly || false,
hideJiraTasks: preferences.kanbanFilters.hideJiraTasks || false,
@@ -82,6 +83,7 @@ export function TasksProvider({ children, initialTasks, initialTags, initialStat
showCompleted: newFilters.showCompleted,
sortBy: newFilters.sortBy,
showWithDueDate: newFilters.showWithDueDate,
showCompletedLast7Days: newFilters.showCompletedLast7Days,
// Filtres Jira
showJiraOnly: newFilters.showJiraOnly,
hideJiraTasks: newFilters.hideJiraTasks,
@@ -106,6 +108,7 @@ export function TasksProvider({ children, initialTasks, initialTags, initialStat
]);
};
// Séparer les tâches épinglées (objectifs) des autres et les trier
const { pinnedTasks, regularTasks } = useMemo(() => {
const pinnedTagNames = tags.filter(tag => tag.isPinned).map(tag => tag.name);
@@ -141,6 +144,7 @@ export function TasksProvider({ children, initialTasks, initialTags, initialStat
(kanbanFilters.priorities?.filter(Boolean).length || 0) +
(kanbanFilters.search ? 1 : 0) +
(kanbanFilters.showWithDueDate ? 1 : 0) +
(kanbanFilters.showCompletedLast7Days ? 1 : 0) +
(kanbanFilters.jiraProjects?.filter(Boolean).length || 0) +
(kanbanFilters.jiraTypes?.filter(Boolean).length || 0) +
(kanbanFilters.showJiraOnly ? 1 : 0) +
@@ -220,6 +224,18 @@ export function TasksProvider({ children, initialTasks, initialTags, initialStat
filtered = filtered.filter(task => task.dueDate != null);
}
// Filtre par tâches complétées les 7 derniers jours
if (kanbanFilters.showCompletedLast7Days) {
const sevenDaysAgo = new Date();
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
filtered = filtered.filter(task =>
task.status === 'done' &&
task.completedAt &&
task.completedAt >= sevenDaysAgo
);
}
// Tri des tâches
if (kanbanFilters.sortBy) {
const sortOption = getSortOption(kanbanFilters.sortBy);

View File

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