feat: implement debounced search functionality in KanbanFilters
- Added local state for search input to improve user experience with immediate feedback. - Introduced a debounced search function to optimize filter updates, reducing unnecessary renders. - Ensured synchronization of local search state with external filter changes and cleaned up timeouts on component unmount.
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useState, useEffect, useRef, useMemo } from 'react';
|
import { useState, useEffect, useRef, useMemo, useCallback } from 'react';
|
||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
import { TaskPriority, TaskStatus } from '@/lib/types';
|
import { TaskPriority, TaskStatus } from '@/lib/types';
|
||||||
import { Button } from '@/components/ui/Button';
|
import { Button } from '@/components/ui/Button';
|
||||||
@@ -74,10 +74,40 @@ export function KanbanFilters({ filters, onFiltersChange, hiddenStatuses: propsH
|
|||||||
}
|
}
|
||||||
}, [isSortExpanded, isSwimlaneModeExpanded]);
|
}, [isSortExpanded, isSwimlaneModeExpanded]);
|
||||||
|
|
||||||
|
// État local pour la recherche pour une saisie fluide
|
||||||
|
const [localSearch, setLocalSearch] = useState(filters.search || '');
|
||||||
|
const searchTimeoutRef = useRef<number | undefined>(undefined);
|
||||||
|
|
||||||
|
// Fonction debouncée pour mettre à jour les filtres
|
||||||
|
const debouncedSearchChange = useCallback((search: string) => {
|
||||||
|
if (searchTimeoutRef.current) {
|
||||||
|
window.clearTimeout(searchTimeoutRef.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
searchTimeoutRef.current = window.setTimeout(() => {
|
||||||
|
onFiltersChange({ ...filters, search: search || undefined });
|
||||||
|
}, 300);
|
||||||
|
}, [filters, onFiltersChange]);
|
||||||
|
|
||||||
const handleSearchChange = (search: string) => {
|
const handleSearchChange = (search: string) => {
|
||||||
onFiltersChange({ ...filters, search: search || undefined });
|
setLocalSearch(search);
|
||||||
|
debouncedSearchChange(search);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Synchroniser l'état local quand les filtres changent de l'extérieur
|
||||||
|
useEffect(() => {
|
||||||
|
setLocalSearch(filters.search || '');
|
||||||
|
}, [filters.search]);
|
||||||
|
|
||||||
|
// Nettoyer le timeout au démontage
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
if (searchTimeoutRef.current) {
|
||||||
|
window.clearTimeout(searchTimeoutRef.current);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
const handleTagToggle = (tagName: string) => {
|
const handleTagToggle = (tagName: string) => {
|
||||||
const currentTags = filters.tags || [];
|
const currentTags = filters.tags || [];
|
||||||
const newTags = currentTags.includes(tagName)
|
const newTags = currentTags.includes(tagName)
|
||||||
@@ -195,7 +225,7 @@ export function KanbanFilters({ filters, onFiltersChange, hiddenStatuses: propsH
|
|||||||
<div className="flex-1 max-w-md">
|
<div className="flex-1 max-w-md">
|
||||||
<Input
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
value={filters.search || ''}
|
value={localSearch}
|
||||||
onChange={(e) => handleSearchChange(e.target.value)}
|
onChange={(e) => handleSearchChange(e.target.value)}
|
||||||
placeholder="Rechercher des tâches..."
|
placeholder="Rechercher des tâches..."
|
||||||
className="bg-[var(--card)] border-[var(--border)]"
|
className="bg-[var(--card)] border-[var(--border)]"
|
||||||
|
|||||||
Reference in New Issue
Block a user