feat: remove Filters

This commit is contained in:
Julien Froidefond
2025-09-18 09:56:46 +02:00
parent 7394b16999
commit fefcc91a03

View File

@@ -340,35 +340,6 @@ export function KanbanFilters({ filters, onFiltersChange, hiddenStatuses: propsH
</div>
<Button
variant="ghost"
onClick={() => setIsExpanded(!isExpanded)}
className="flex items-center gap-2"
>
<svg
className="w-4 h-4"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z" />
</svg>
Filtres
{activeFiltersCount > 0 && (
<span className="bg-[var(--primary)] text-[var(--primary-foreground)] text-xs px-2 py-0.5 rounded-full font-medium">
{activeFiltersCount}
</span>
)}
<svg
className={`w-4 h-4 transition-transform ${isExpanded ? 'rotate-180' : ''}`}
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
</svg>
</Button>
{activeFiltersCount > 0 && (
<Button
variant="ghost"
@@ -381,218 +352,217 @@ export function KanbanFilters({ filters, onFiltersChange, hiddenStatuses: propsH
</div>
{/* Filtres étendus */}
{isExpanded && (
<div className="mt-4 border-t border-[var(--border)]/50 pt-4">
{/* Grille responsive pour les filtres principaux */}
<div className="grid grid-cols-1 lg:grid-cols-[auto_1fr] gap-6 lg:gap-8">
{/* Filtres par priorité */}
<div className="mt-4 border-t border-[var(--border)]/50 pt-4">
{/* Grille responsive pour les filtres principaux */}
<div className="grid grid-cols-1 lg:grid-cols-[auto_1fr] gap-6 lg:gap-8">
{/* Filtres par priorité */}
<div className="space-y-3">
<label className="block text-xs font-mono font-medium text-[var(--muted-foreground)] uppercase tracking-wider">
Priorités
</label>
<div className="grid grid-cols-2 gap-2">
{priorityOptions.filter(priority => priority.count > 0).map((priority) => (
<button
key={priority.value}
onClick={() => handlePriorityToggle(priority.value)}
className={`flex items-center gap-2 px-3 py-2 rounded-lg border transition-all text-xs font-medium whitespace-nowrap ${
filters.priorities?.includes(priority.value)
? 'border-cyan-400 bg-cyan-400/10 text-cyan-400'
: 'border-[var(--border)] bg-[var(--card)] text-[var(--muted-foreground)] hover:border-[var(--border)]'
}`}
>
<div
className="w-2 h-2 rounded-full"
style={{ backgroundColor: getPriorityColorHex(priority.color) }}
/>
{priority.label} ({priority.count})
</button>
))}
</div>
</div>
{/* Filtres par tags */}
{availableTags.length > 0 && (
<div className="space-y-3">
<label className="block text-xs font-mono font-medium text-[var(--muted-foreground)] uppercase tracking-wider">
Priorités
Tags
</label>
<div className="grid grid-cols-2 gap-2">
{priorityOptions.filter(priority => priority.count > 0).map((priority) => (
<div className="flex flex-wrap gap-2 max-h-32 overflow-y-auto">
{sortedTags.filter(tag => (tagCounts[tag.name] || 0) > 0).map((tag) => (
<button
key={priority.value}
onClick={() => handlePriorityToggle(priority.value)}
className={`flex items-center gap-2 px-3 py-2 rounded-lg border transition-all text-xs font-medium whitespace-nowrap ${
filters.priorities?.includes(priority.value)
key={tag.id}
onClick={() => handleTagToggle(tag.name)}
className={`flex items-center gap-2 px-3 py-2 rounded-lg border transition-all text-xs font-medium ${
filters.tags?.includes(tag.name)
? 'border-cyan-400 bg-cyan-400/10 text-cyan-400'
: 'border-[var(--border)] bg-[var(--card)] text-[var(--muted-foreground)] hover:border-[var(--border)]'
}`}
>
<div
className="w-2 h-2 rounded-full"
style={{ backgroundColor: getPriorityColorHex(priority.color) }}
className="w-2 h-2 rounded-full"
style={{ backgroundColor: tag.color }}
/>
{priority.label} ({priority.count})
{tag.name} ({tagCounts[tag.name]})
</button>
))}
</div>
</div>
{/* Filtres par tags */}
{availableTags.length > 0 && (
<div className="space-y-3">
<label className="block text-xs font-mono font-medium text-[var(--muted-foreground)] uppercase tracking-wider">
Tags
</label>
<div className="flex flex-wrap gap-2 max-h-32 overflow-y-auto">
{sortedTags.filter(tag => (tagCounts[tag.name] || 0) > 0).map((tag) => (
<button
key={tag.id}
onClick={() => handleTagToggle(tag.name)}
className={`flex items-center gap-2 px-3 py-2 rounded-lg border transition-all text-xs font-medium ${
filters.tags?.includes(tag.name)
? 'border-cyan-400 bg-cyan-400/10 text-cyan-400'
: 'border-[var(--border)] bg-[var(--card)] text-[var(--muted-foreground)] hover:border-[var(--border)]'
}`}
>
<div
className="w-2 h-2 rounded-full"
style={{ backgroundColor: tag.color }}
/>
{tag.name} ({tagCounts[tag.name]})
</button>
))}
</div>
</div>
)}
</div>
{/* Filtres Jira - Ligne séparée mais intégrée */}
{hasJiraTasks && (
<div className="border-t border-[var(--border)]/30 pt-4 mt-4">
<div className="flex items-center gap-4 mb-3">
<label className="block text-xs font-mono font-medium text-[var(--muted-foreground)] uppercase tracking-wider">
🔌 Jira
</label>
{/* Toggle Jira Show/Hide - inline avec le titre */}
<div className="flex gap-1">
<Button
variant={filters.showJiraOnly ? "primary" : "ghost"}
onClick={() => handleJiraToggle('show')}
size="sm"
className="text-xs px-2 py-1 h-auto"
>
🔹 Seul
</Button>
<Button
variant={filters.hideJiraTasks ? "danger" : "ghost"}
onClick={() => handleJiraToggle('hide')}
size="sm"
className="text-xs px-2 py-1 h-auto"
>
🚫 Mask
</Button>
<Button
variant={(!filters.showJiraOnly && !filters.hideJiraTasks) ? "primary" : "ghost"}
onClick={() => handleJiraToggle('all')}
size="sm"
className="text-xs px-2 py-1 h-auto"
>
📋 All
</Button>
</div>
</div>
{/* Projets et Types en 2 colonnes */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
{/* Projets Jira */}
{availableJiraProjects.length > 0 && (
<div>
<label className="block text-xs font-medium text-[var(--muted-foreground)] mb-2">
Projets
</label>
<div className="flex flex-wrap gap-1">
{availableJiraProjects.map((project) => (
<button
key={project}
onClick={() => handleJiraProjectToggle(project)}
className={`px-2 py-1 rounded border transition-all text-xs font-medium ${
filters.jiraProjects?.includes(project)
? 'border-blue-400 bg-blue-400/10 text-blue-400'
: 'border-[var(--border)] bg-[var(--card)] text-[var(--muted-foreground)] hover:border-[var(--border)]'
}`}
>
📋 {project}
</button>
))}
</div>
</div>
)}
{/* Types Jira */}
{availableJiraTypes.length > 0 && (
<div>
<label className="block text-xs font-medium text-[var(--muted-foreground)] mb-2">
Types
</label>
<div className="flex flex-wrap gap-1">
{availableJiraTypes.map((type) => (
<button
key={type}
onClick={() => handleJiraTypeToggle(type)}
className={`px-2 py-1 rounded border transition-all text-xs font-medium ${
filters.jiraTypes?.includes(type)
? 'border-purple-400 bg-purple-400/10 text-purple-400'
: 'border-[var(--border)] bg-[var(--card)] text-[var(--muted-foreground)] hover:border-[var(--border)]'
}`}
>
{type === 'Feature' && '✨ '}
{type === 'Story' && '📖 '}
{type === 'Task' && '📝 '}
{type === 'Bug' && '🐛 '}
{type === 'Support' && '🛠️ '}
{type === 'Enabler' && '🔧 '}
{type}
</button>
))}
</div>
</div>
)}
</div>
</div>
)}
{/* Visibilité des colonnes */}
<div className="col-span-full border-t border-[var(--border)]/50 pt-6 mt-4">
<ColumnVisibilityToggle
hiddenStatuses={hiddenStatuses}
onToggleStatus={toggleStatusVisibility}
tasks={regularTasks}
className="text-xs"
/>
</div>
{/* Résumé des filtres actifs */}
{activeFiltersCount > 0 && (
<div className="bg-[var(--card)]/30 rounded-lg p-3 border border-[var(--border)]/50 mt-4">
<div className="text-xs text-[var(--muted-foreground)] font-mono uppercase tracking-wider mb-2">
Filtres actifs
</div>
<div className="space-y-1 text-xs">
{filters.search && (
<div className="text-[var(--muted-foreground)]">
Recherche: <span className="text-cyan-400">&ldquo;{filters.search}&rdquo;</span>
</div>
)}
{(filters.priorities?.filter(Boolean).length || 0) > 0 && (
<div className="text-[var(--muted-foreground)]">
Priorités: <span className="text-cyan-400">{filters.priorities?.filter(Boolean).join(', ')}</span>
</div>
)}
{(filters.tags?.filter(Boolean).length || 0) > 0 && (
<div className="text-[var(--muted-foreground)]">
Tags: <span className="text-cyan-400">{filters.tags?.filter(Boolean).join(', ')}</span>
</div>
)}
{filters.showJiraOnly && (
<div className="text-[var(--muted-foreground)]">
Affichage: <span className="text-blue-400">Jira seulement</span>
</div>
)}
{filters.hideJiraTasks && (
<div className="text-[var(--muted-foreground)]">
Affichage: <span className="text-red-400">Masquer Jira</span>
</div>
)}
{(filters.jiraProjects?.filter(Boolean).length || 0) > 0 && (
<div className="text-[var(--muted-foreground)]">
Projets Jira: <span className="text-blue-400">{filters.jiraProjects?.filter(Boolean).join(', ')}</span>
</div>
)}
{(filters.jiraTypes?.filter(Boolean).length || 0) > 0 && (
<div className="text-[var(--muted-foreground)]">
Types Jira: <span className="text-purple-400">{filters.jiraTypes?.filter(Boolean).join(', ')}</span>
</div>
)}
</div>
</div>
)}
</div>
)}
{/* Filtres Jira - Ligne séparée mais intégrée */}
{hasJiraTasks && (
<div className="border-t border-[var(--border)]/30 pt-4 mt-4">
<div className="flex items-center gap-4 mb-3">
<label className="block text-xs font-mono font-medium text-[var(--muted-foreground)] uppercase tracking-wider">
🔌 Jira
</label>
{/* Toggle Jira Show/Hide - inline avec le titre */}
<div className="flex gap-1">
<Button
variant={filters.showJiraOnly ? "primary" : "ghost"}
onClick={() => handleJiraToggle('show')}
size="sm"
className="text-xs px-2 py-1 h-auto"
>
🔹 Seul
</Button>
<Button
variant={filters.hideJiraTasks ? "danger" : "ghost"}
onClick={() => handleJiraToggle('hide')}
size="sm"
className="text-xs px-2 py-1 h-auto"
>
🚫 Mask
</Button>
<Button
variant={(!filters.showJiraOnly && !filters.hideJiraTasks) ? "primary" : "ghost"}
onClick={() => handleJiraToggle('all')}
size="sm"
className="text-xs px-2 py-1 h-auto"
>
📋 All
</Button>
</div>
</div>
{/* Projets et Types en 2 colonnes */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
{/* Projets Jira */}
{availableJiraProjects.length > 0 && (
<div>
<label className="block text-xs font-medium text-[var(--muted-foreground)] mb-2">
Projets
</label>
<div className="flex flex-wrap gap-1">
{availableJiraProjects.map((project) => (
<button
key={project}
onClick={() => handleJiraProjectToggle(project)}
className={`px-2 py-1 rounded border transition-all text-xs font-medium ${
filters.jiraProjects?.includes(project)
? 'border-blue-400 bg-blue-400/10 text-blue-400'
: 'border-[var(--border)] bg-[var(--card)] text-[var(--muted-foreground)] hover:border-[var(--border)]'
}`}
>
📋 {project}
</button>
))}
</div>
</div>
)}
{/* Types Jira */}
{availableJiraTypes.length > 0 && (
<div>
<label className="block text-xs font-medium text-[var(--muted-foreground)] mb-2">
Types
</label>
<div className="flex flex-wrap gap-1">
{availableJiraTypes.map((type) => (
<button
key={type}
onClick={() => handleJiraTypeToggle(type)}
className={`px-2 py-1 rounded border transition-all text-xs font-medium ${
filters.jiraTypes?.includes(type)
? 'border-purple-400 bg-purple-400/10 text-purple-400'
: 'border-[var(--border)] bg-[var(--card)] text-[var(--muted-foreground)] hover:border-[var(--border)]'
}`}
>
{type === 'Feature' && '✨ '}
{type === 'Story' && '📖 '}
{type === 'Task' && '📝 '}
{type === 'Bug' && '🐛 '}
{type === 'Support' && '🛠️ '}
{type === 'Enabler' && '🔧 '}
{type}
</button>
))}
</div>
</div>
)}
</div>
</div>
)}
{/* Visibilité des colonnes */}
<div className="col-span-full border-t border-[var(--border)]/50 pt-6 mt-4">
<ColumnVisibilityToggle
hiddenStatuses={hiddenStatuses}
onToggleStatus={toggleStatusVisibility}
tasks={regularTasks}
className="text-xs"
/>
</div>
{/* Résumé des filtres actifs */}
{activeFiltersCount > 0 && (
<div className="bg-[var(--card)]/30 rounded-lg p-3 border border-[var(--border)]/50 mt-4">
<div className="text-xs text-[var(--muted-foreground)] font-mono uppercase tracking-wider mb-2">
Filtres actifs
</div>
<div className="space-y-1 text-xs">
{filters.search && (
<div className="text-[var(--muted-foreground)]">
Recherche: <span className="text-cyan-400">&ldquo;{filters.search}&rdquo;</span>
</div>
)}
{(filters.priorities?.filter(Boolean).length || 0) > 0 && (
<div className="text-[var(--muted-foreground)]">
Priorités: <span className="text-cyan-400">{filters.priorities?.filter(Boolean).join(', ')}</span>
</div>
)}
{(filters.tags?.filter(Boolean).length || 0) > 0 && (
<div className="text-[var(--muted-foreground)]">
Tags: <span className="text-cyan-400">{filters.tags?.filter(Boolean).join(', ')}</span>
</div>
)}
{filters.showJiraOnly && (
<div className="text-[var(--muted-foreground)]">
Affichage: <span className="text-blue-400">Jira seulement</span>
</div>
)}
{filters.hideJiraTasks && (
<div className="text-[var(--muted-foreground)]">
Affichage: <span className="text-red-400">Masquer Jira</span>
</div>
)}
{(filters.jiraProjects?.filter(Boolean).length || 0) > 0 && (
<div className="text-[var(--muted-foreground)]">
Projets Jira: <span className="text-blue-400">{filters.jiraProjects?.filter(Boolean).join(', ')}</span>
</div>
)}
{(filters.jiraTypes?.filter(Boolean).length || 0) > 0 && (
<div className="text-[var(--muted-foreground)]">
Types Jira: <span className="text-purple-400">{filters.jiraTypes?.filter(Boolean).join(', ')}</span>
</div>
)}
</div>
</div>
)}
</div>
</div>
{/* Dropdown de tri rendu via portail pour éviter les problèmes de z-index */}