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:
@@ -138,6 +138,13 @@ export function KanbanFilters({ filters, onFiltersChange, hiddenStatuses: propsH
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleCompletedLast7DaysFilterToggle = () => {
|
||||||
|
onFiltersChange({
|
||||||
|
...filters,
|
||||||
|
showCompletedLast7Days: !filters.showCompletedLast7Days
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
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">
|
||||||
@@ -230,7 +237,9 @@ export function KanbanFilters({ filters, onFiltersChange, hiddenStatuses: propsH
|
|||||||
|
|
||||||
<GeneralFilters
|
<GeneralFilters
|
||||||
showWithDueDate={filters.showWithDueDate}
|
showWithDueDate={filters.showWithDueDate}
|
||||||
|
showCompletedLast7Days={filters.showCompletedLast7Days}
|
||||||
onDueDateFilterToggle={handleDueDateFilterToggle}
|
onDueDateFilterToggle={handleDueDateFilterToggle}
|
||||||
|
onCompletedLast7DaysFilterToggle={handleCompletedLast7DaysFilterToggle}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -55,4 +55,4 @@ export function KanbanHeader({
|
|||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -4,10 +4,17 @@ import { FilterChip } from '@/components/ui';
|
|||||||
|
|
||||||
interface GeneralFiltersProps {
|
interface GeneralFiltersProps {
|
||||||
showWithDueDate?: boolean;
|
showWithDueDate?: boolean;
|
||||||
|
showCompletedLast7Days?: boolean;
|
||||||
onDueDateFilterToggle: () => void;
|
onDueDateFilterToggle: () => void;
|
||||||
|
onCompletedLast7DaysFilterToggle: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function GeneralFilters({ showWithDueDate = false, onDueDateFilterToggle }: GeneralFiltersProps) {
|
export function GeneralFilters({
|
||||||
|
showWithDueDate = false,
|
||||||
|
showCompletedLast7Days = false,
|
||||||
|
onDueDateFilterToggle,
|
||||||
|
onCompletedLast7DaysFilterToggle
|
||||||
|
}: GeneralFiltersProps) {
|
||||||
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">
|
||||||
@@ -30,6 +37,23 @@ export function GeneralFilters({ showWithDueDate = false, onDueDateFilterToggle
|
|||||||
>
|
>
|
||||||
Avec date de fin
|
Avec date de fin
|
||||||
</FilterChip>
|
</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>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ interface FilterSummaryProps {
|
|||||||
priorities?: string[];
|
priorities?: string[];
|
||||||
tags?: string[];
|
tags?: string[];
|
||||||
showWithDueDate?: boolean;
|
showWithDueDate?: boolean;
|
||||||
|
showCompletedLast7Days?: boolean;
|
||||||
showJiraOnly?: boolean;
|
showJiraOnly?: boolean;
|
||||||
hideJiraTasks?: boolean;
|
hideJiraTasks?: boolean;
|
||||||
jiraProjects?: string[];
|
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
|
// Jira
|
||||||
if (filters.showJiraOnly) {
|
if (filters.showJiraOnly) {
|
||||||
filterItems.push({
|
filterItems.push({
|
||||||
|
|||||||
@@ -517,10 +517,11 @@ const TaskCard = forwardRef<HTMLDivElement, TaskCardProps>(
|
|||||||
</Badge>
|
</Badge>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Statut terminé */}
|
{/* Statut terminé avec date de résolution */}
|
||||||
{completedAt && (
|
{completedAt && (
|
||||||
<span className="text-emerald-400 font-mono font-bold">
|
<span className="text-emerald-400 font-mono font-bold flex items-center gap-1">
|
||||||
✓ DONE
|
<span>✓</span>
|
||||||
|
<span>{formatDateForDisplay(completedAt, 'DISPLAY_SHORT')}</span>
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ export function TasksProvider({ children, initialTasks, initialTags, initialStat
|
|||||||
swimlanesByTags: preferences.viewPreferences.swimlanesByTags || false,
|
swimlanesByTags: preferences.viewPreferences.swimlanesByTags || false,
|
||||||
swimlanesMode: preferences.viewPreferences.swimlanesMode || 'tags',
|
swimlanesMode: preferences.viewPreferences.swimlanesMode || 'tags',
|
||||||
showWithDueDate: preferences.kanbanFilters.showWithDueDate || false,
|
showWithDueDate: preferences.kanbanFilters.showWithDueDate || false,
|
||||||
|
showCompletedLast7Days: preferences.kanbanFilters.showCompletedLast7Days || 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,
|
||||||
@@ -82,6 +83,7 @@ export function TasksProvider({ children, initialTasks, initialTags, initialStat
|
|||||||
showCompleted: newFilters.showCompleted,
|
showCompleted: newFilters.showCompleted,
|
||||||
sortBy: newFilters.sortBy,
|
sortBy: newFilters.sortBy,
|
||||||
showWithDueDate: newFilters.showWithDueDate,
|
showWithDueDate: newFilters.showWithDueDate,
|
||||||
|
showCompletedLast7Days: newFilters.showCompletedLast7Days,
|
||||||
// Filtres Jira
|
// Filtres Jira
|
||||||
showJiraOnly: newFilters.showJiraOnly,
|
showJiraOnly: newFilters.showJiraOnly,
|
||||||
hideJiraTasks: newFilters.hideJiraTasks,
|
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
|
// Séparer les tâches épinglées (objectifs) des autres et les trier
|
||||||
const { pinnedTasks, regularTasks } = useMemo(() => {
|
const { pinnedTasks, regularTasks } = useMemo(() => {
|
||||||
const pinnedTagNames = tags.filter(tag => tag.isPinned).map(tag => tag.name);
|
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.priorities?.filter(Boolean).length || 0) +
|
||||||
(kanbanFilters.search ? 1 : 0) +
|
(kanbanFilters.search ? 1 : 0) +
|
||||||
(kanbanFilters.showWithDueDate ? 1 : 0) +
|
(kanbanFilters.showWithDueDate ? 1 : 0) +
|
||||||
|
(kanbanFilters.showCompletedLast7Days ? 1 : 0) +
|
||||||
(kanbanFilters.jiraProjects?.filter(Boolean).length || 0) +
|
(kanbanFilters.jiraProjects?.filter(Boolean).length || 0) +
|
||||||
(kanbanFilters.jiraTypes?.filter(Boolean).length || 0) +
|
(kanbanFilters.jiraTypes?.filter(Boolean).length || 0) +
|
||||||
(kanbanFilters.showJiraOnly ? 1 : 0) +
|
(kanbanFilters.showJiraOnly ? 1 : 0) +
|
||||||
@@ -220,6 +224,18 @@ export function TasksProvider({ children, initialTasks, initialTags, initialStat
|
|||||||
filtered = filtered.filter(task => task.dueDate != null);
|
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
|
// Tri des tâches
|
||||||
if (kanbanFilters.sortBy) {
|
if (kanbanFilters.sortBy) {
|
||||||
const sortOption = getSortOption(kanbanFilters.sortBy);
|
const sortOption = getSortOption(kanbanFilters.sortBy);
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ export interface KanbanFilters {
|
|||||||
showCompleted?: boolean;
|
showCompleted?: boolean;
|
||||||
sortBy?: string;
|
sortBy?: string;
|
||||||
showWithDueDate?: boolean;
|
showWithDueDate?: boolean;
|
||||||
|
showCompletedLast7Days?: boolean;
|
||||||
// Filtres spécifiques Jira
|
// Filtres spécifiques Jira
|
||||||
showJiraOnly?: boolean;
|
showJiraOnly?: boolean;
|
||||||
hideJiraTasks?: boolean;
|
hideJiraTasks?: boolean;
|
||||||
|
|||||||
Reference in New Issue
Block a user