diff --git a/src/app/kanban/KanbanPageClient.tsx b/src/app/kanban/KanbanPageClient.tsx index b57d15f..a8f19b5 100644 --- a/src/app/kanban/KanbanPageClient.tsx +++ b/src/app/kanban/KanbanPageClient.tsx @@ -10,6 +10,7 @@ import { CreateTaskData } from '@/clients/tasks-client'; import { CreateTaskForm } from '@/components/forms/CreateTaskForm'; import { Button } from '@/components/ui/Button'; import { JiraQuickFilter } from '@/components/kanban/JiraQuickFilter'; +import { TfsQuickFilter } from '@/components/kanban/TfsQuickFilter'; import { FontSizeToggle } from '@/components/ui/FontSizeToggle'; import { MobileControls } from '@/components/kanban/MobileControls'; import { useIsMobile } from '@/hooks/useIsMobile'; @@ -119,6 +120,12 @@ function KanbanPageContent() { onFiltersChange={setKanbanFilters} /> + {/* Raccourcis TFS */} + + + + + + + + {/* Projets TFS */} + {availableTfsProjects.length > 0 && ( +
+ +
+ {availableTfsProjects.map((project) => ( + + ))} +
+
+ )} + + )} + {/* Visibilité des colonnes */}
{filters.jiraTypes?.filter(Boolean).join(', ')}
)} + {filters.showTfsOnly && ( +
+ Affichage: TFS seulement +
+ )} + {filters.hideTfsTasks && ( +
+ Affichage: Masquer TFS +
+ )} + {(filters.tfsProjects?.filter(Boolean).length || 0) > 0 && ( +
+ Projets TFS: {filters.tfsProjects?.filter(Boolean).join(', ')} +
+ )} )} diff --git a/src/components/kanban/MobileControls.tsx b/src/components/kanban/MobileControls.tsx index d3e067b..6437ce2 100644 --- a/src/components/kanban/MobileControls.tsx +++ b/src/components/kanban/MobileControls.tsx @@ -3,6 +3,7 @@ import { useState } from 'react'; import { Button } from '@/components/ui/Button'; import { JiraQuickFilter } from '@/components/kanban/JiraQuickFilter'; +import { TfsQuickFilter } from '@/components/kanban/TfsQuickFilter'; import { FontSizeToggle } from '@/components/ui/FontSizeToggle'; import { KanbanFilters } from '@/components/kanban/KanbanFilters'; @@ -147,15 +148,21 @@ export function MobileControls({ - {/* Section Jira */} + {/* Section Jira & TFS */}

- Raccourcis Jira + Raccourcis

- +
+ + +
)} diff --git a/src/components/kanban/TfsQuickFilter.tsx b/src/components/kanban/TfsQuickFilter.tsx new file mode 100644 index 0000000..1fbeae2 --- /dev/null +++ b/src/components/kanban/TfsQuickFilter.tsx @@ -0,0 +1,101 @@ +'use client'; + +import { useMemo } from 'react'; +import { useTasksContext } from '@/contexts/TasksContext'; +import { KanbanFilters } from './KanbanFilters'; + +interface TfsQuickFilterProps { + filters: KanbanFilters; + onFiltersChange: (filters: KanbanFilters) => void; +} + +export function TfsQuickFilter({ filters, onFiltersChange }: TfsQuickFilterProps) { + const { regularTasks } = useTasksContext(); + + // Vérifier s'il y a des tâches TFS dans le système + const hasTfsTasks = useMemo(() => { + return regularTasks.some(task => task.source === 'tfs'); + }, [regularTasks]); + + // Si pas de tâches TFS, on n'affiche rien + if (!hasTfsTasks) { + return null; + } + + // Déterminer l'état actuel + const currentMode = filters.showTfsOnly ? 'show' : filters.hideTfsTasks ? 'hide' : 'all'; + + const handleTfsCycle = () => { + const updates: Partial = {}; + + // Cycle : All -> TFS only -> No TFS -> All + switch (currentMode) { + case 'all': + // All -> TFS only + updates.showTfsOnly = true; + updates.hideTfsTasks = false; + break; + case 'show': + // TFS only -> No TFS + updates.showTfsOnly = false; + updates.hideTfsTasks = true; + break; + case 'hide': + // No TFS -> All + updates.showTfsOnly = false; + updates.hideTfsTasks = false; + break; + } + + onFiltersChange({ ...filters, ...updates }); + }; + + // Définir l'apparence selon l'état + const getButtonStyle = () => { + switch (currentMode) { + case 'show': + return 'bg-[var(--primary)]/20 text-[var(--primary)] border border-[var(--primary)]/30'; + case 'hide': + return 'bg-red-500/20 text-red-400 border border-red-400/30'; + default: + return 'bg-[var(--card)] text-[var(--muted-foreground)] border border-[var(--border)] hover:border-[var(--primary)]/50'; + } + }; + + const getButtonContent = () => { + switch (currentMode) { + case 'show': + return { icon: '🔷', text: 'TFS only' }; + case 'hide': + return { icon: '🚫', text: 'No TFS' }; + default: + return { icon: '📦', text: 'All tasks' }; + } + }; + + const getTooltip = () => { + switch (currentMode) { + case 'all': + return 'Cliquer pour afficher seulement TFS'; + case 'show': + return 'Cliquer pour masquer TFS'; + case 'hide': + return 'Cliquer pour afficher tout'; + default: + return 'Filtrer les tâches TFS'; + } + }; + + const content = getButtonContent(); + + return ( + + ); +} diff --git a/src/contexts/TasksContext.tsx b/src/contexts/TasksContext.tsx index c793a47..996d634 100644 --- a/src/contexts/TasksContext.tsx +++ b/src/contexts/TasksContext.tsx @@ -64,7 +64,11 @@ export function TasksProvider({ children, initialTasks, initialTags, initialStat showJiraOnly: preferences.kanbanFilters.showJiraOnly || false, hideJiraTasks: preferences.kanbanFilters.hideJiraTasks || false, jiraProjects: preferences.kanbanFilters.jiraProjects || [], - jiraTypes: preferences.kanbanFilters.jiraTypes || [] + jiraTypes: preferences.kanbanFilters.jiraTypes || [], + // Filtres TFS + showTfsOnly: preferences.kanbanFilters.showTfsOnly || false, + hideTfsTasks: preferences.kanbanFilters.hideTfsTasks || false, + tfsProjects: preferences.kanbanFilters.tfsProjects || [] }), [preferences]); // Fonction pour mettre à jour les filtres avec persistance @@ -80,7 +84,11 @@ export function TasksProvider({ children, initialTasks, initialTags, initialStat showJiraOnly: newFilters.showJiraOnly, hideJiraTasks: newFilters.hideJiraTasks, jiraProjects: newFilters.jiraProjects, - jiraTypes: newFilters.jiraTypes + jiraTypes: newFilters.jiraTypes, + // Filtres TFS + showTfsOnly: newFilters.showTfsOnly, + hideTfsTasks: newFilters.hideTfsTasks, + tfsProjects: newFilters.tfsProjects }; const viewPreferenceUpdates = { @@ -133,7 +141,10 @@ export function TasksProvider({ children, initialTasks, initialTags, initialStat (kanbanFilters.jiraProjects?.filter(Boolean).length || 0) + (kanbanFilters.jiraTypes?.filter(Boolean).length || 0) + (kanbanFilters.showJiraOnly ? 1 : 0) + - (kanbanFilters.hideJiraTasks ? 1 : 0); + (kanbanFilters.hideJiraTasks ? 1 : 0) + + (kanbanFilters.tfsProjects?.filter(Boolean).length || 0) + + (kanbanFilters.showTfsOnly ? 1 : 0) + + (kanbanFilters.hideTfsTasks ? 1 : 0); }, [kanbanFilters]); // Filtrage et tri des tâches régulières (pas les épinglées) @@ -187,6 +198,20 @@ export function TasksProvider({ children, initialTasks, initialTags, initialStat ); } + // Filtres spécifiques TFS + if (kanbanFilters.showTfsOnly) { + filtered = filtered.filter(task => task.source === 'tfs'); + } else if (kanbanFilters.hideTfsTasks) { + filtered = filtered.filter(task => task.source !== 'tfs'); + } + + // Filtre par projets TFS + if (kanbanFilters.tfsProjects?.length) { + filtered = filtered.filter(task => + task.source !== 'tfs' || kanbanFilters.tfsProjects!.includes(task.tfsProject || '') + ); + } + // Tri des tâches if (kanbanFilters.sortBy) { const sortOption = getSortOption(kanbanFilters.sortBy); diff --git a/src/lib/types.ts b/src/lib/types.ts index 4f12a95..5376b8e 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -76,6 +76,10 @@ export interface KanbanFilters { hideJiraTasks?: boolean; jiraProjects?: string[]; jiraTypes?: string[]; + // Filtres spécifiques TFS + showTfsOnly?: boolean; + hideTfsTasks?: boolean; + tfsProjects?: string[]; [key: string]: string | string[] | TaskPriority[] | boolean | undefined; }