From 165d414fef9e7c0db7cf7fa65817e7cb3e0b9032 Mon Sep 17 00:00:00 2001 From: Julien Froidefond Date: Mon, 15 Sep 2025 08:35:55 +0200 Subject: [PATCH] feat: enhance column visibility toggle with task counts - Added `tasks` prop to `ColumnVisibilityToggle` for displaying task counts per status. - Updated `KanbanFilters` to calculate and show counts for priorities and tags, improving filter visibility. - Integrated task counts into UI elements for better user feedback on task distribution across statuses, priorities, and tags. --- components/kanban/Board.tsx | 1 + components/kanban/ColumnVisibilityToggle.tsx | 16 +++++++++-- components/kanban/KanbanFilters.tsx | 29 ++++++++++++++++---- components/kanban/SwimlanesBoard.tsx | 1 + 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/components/kanban/Board.tsx b/components/kanban/Board.tsx index 0d1c899..d759ac2 100644 --- a/components/kanban/Board.tsx +++ b/components/kanban/Board.tsx @@ -134,6 +134,7 @@ export function KanbanBoard({ tasks, onCreateTask, onDeleteTask, onEditTask, onU diff --git a/components/kanban/ColumnVisibilityToggle.tsx b/components/kanban/ColumnVisibilityToggle.tsx index 0b6ebb1..cb68aab 100644 --- a/components/kanban/ColumnVisibilityToggle.tsx +++ b/components/kanban/ColumnVisibilityToggle.tsx @@ -1,21 +1,33 @@ 'use client'; -import { TaskStatus } from '@/lib/types'; +import { useMemo } from 'react'; +import { Task, TaskStatus } from '@/lib/types'; import { getAllStatuses } from '@/lib/status-config'; interface ColumnVisibilityToggleProps { hiddenStatuses: Set; onToggleStatus: (status: TaskStatus) => void; + tasks: Task[]; className?: string; } export function ColumnVisibilityToggle({ hiddenStatuses, onToggleStatus, + tasks, className = "" }: ColumnVisibilityToggleProps) { const statuses = getAllStatuses(); + // Calculer les compteurs pour chaque statut + const statusCounts = useMemo(() => { + const counts: Record = {}; + statuses.forEach(status => { + counts[status.key] = tasks.filter(task => task.status === status.key).length; + }); + return counts; + }, [tasks, statuses]); + return (
@@ -32,7 +44,7 @@ export function ColumnVisibilityToggle({ }`} title={hiddenStatuses.has(statusConfig.key) ? `Afficher ${statusConfig.label}` : `Masquer ${statusConfig.label}`} > - {hiddenStatuses.has(statusConfig.key) ? '👁️‍🗨️' : '👁️'} {statusConfig.label} + {hiddenStatuses.has(statusConfig.key) ? '👁️‍🗨️' : '👁️'} {statusConfig.label} ({statusCounts[statusConfig.key] || 0}) ))}
diff --git a/components/kanban/KanbanFilters.tsx b/components/kanban/KanbanFilters.tsx index 8ed43c0..df93b50 100644 --- a/components/kanban/KanbanFilters.tsx +++ b/components/kanban/KanbanFilters.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useState, useEffect, useRef } from 'react'; +import { useState, useEffect, useRef, useMemo } from 'react'; import { createPortal } from 'react-dom'; import { TaskPriority } from '@/lib/types'; import { Button } from '@/components/ui/Button'; @@ -26,7 +26,7 @@ interface KanbanFiltersProps { } export function KanbanFilters({ filters, onFiltersChange }: KanbanFiltersProps) { - const { tags: availableTags } = useTasksContext(); + const { tags: availableTags, tasks } = useTasksContext(); const [isExpanded, setIsExpanded] = useState(false); const [isSortExpanded, setIsSortExpanded] = useState(false); const sortDropdownRef = useRef(null); @@ -113,10 +113,29 @@ export function KanbanFilters({ filters, onFiltersChange }: KanbanFiltersProps) const activeFiltersCount = (filters.tags?.length || 0) + (filters.priorities?.length || 0) + (filters.search ? 1 : 0); + // Calculer les compteurs pour les priorités + const priorityCounts = useMemo(() => { + const counts: Record = {}; + getAllPriorities().forEach(priority => { + counts[priority.key] = tasks.filter(task => task.priority === priority.key).length; + }); + return counts; + }, [tasks]); + + // Calculer les compteurs pour les tags + const tagCounts = useMemo(() => { + const counts: Record = {}; + availableTags.forEach(tag => { + counts[tag.name] = tasks.filter(task => task.tags?.includes(tag.name)).length; + }); + return counts; + }, [tasks, availableTags]); + const priorityOptions = getAllPriorities().map(priorityConfig => ({ value: priorityConfig.key, label: priorityConfig.label, - color: priorityConfig.color + color: priorityConfig.color, + count: priorityCounts[priorityConfig.key] || 0 })); return ( @@ -270,7 +289,7 @@ export function KanbanFilters({ filters, onFiltersChange }: KanbanFiltersProps) className="w-2 h-2 rounded-full" style={{ backgroundColor: getPriorityColorHex(priority.color) }} /> - {priority.label} + {priority.label} ({priority.count}) ))} @@ -297,7 +316,7 @@ export function KanbanFilters({ filters, onFiltersChange }: KanbanFiltersProps) className="w-2 h-2 rounded-full" style={{ backgroundColor: tag.color }} /> - {tag.name} + {tag.name} ({tagCounts[tag.name] || 0}) ))} diff --git a/components/kanban/SwimlanesBoard.tsx b/components/kanban/SwimlanesBoard.tsx index 1bbc475..61cfc25 100644 --- a/components/kanban/SwimlanesBoard.tsx +++ b/components/kanban/SwimlanesBoard.tsx @@ -200,6 +200,7 @@ export function SwimlanesBoard({