Consolidate category/project filters into a shared TaskFiltersContext + add List filter
Was duplicating categoryFilter/projectFilter useState + filter logic in every view (Board/List/Today/Shared/Assigned/Dispatch). Moved to one global context (same pattern as SearchContext) with a single <TaskFilterBar/> drop-in, and added the missing List filter dimension on top. List filter is deliberately omitted (showList=false) on ListView, Shared, Assigned, and Dispatch -- ListView is already scoped to one list by its route, and the other three show tasks whose list_id doesn't belong to the viewer's own lists (shared tasks live in their owner's lists; assigned tasks are always unfiled after transfer; dispatch is cross-user) -- filtering any of them by "my lists" could only ever return zero results.
This commit is contained in:
parent
4eab3c29ed
commit
3145c1fc07
9 changed files with 137 additions and 52 deletions
|
|
@ -1,9 +1,11 @@
|
|||
import { useState } from 'react'
|
||||
import { Check, ChevronDown, Tag, FolderKanban, type LucideIcon } from 'lucide-react'
|
||||
import { Check, ChevronDown, Tag, FolderKanban, ListChecks, type LucideIcon } from 'lucide-react'
|
||||
import type { Priority } from '../types'
|
||||
import { PRIORITY_LABELS } from '../types'
|
||||
import { useCategories } from '../context/CategoriesContext'
|
||||
import { useProjects } from '../context/ProjectsContext'
|
||||
import { useLists } from '../context/ListsContext'
|
||||
import { useTaskFilters } from '../context/TaskFiltersContext'
|
||||
|
||||
export function PriorityBadge({ priority }: { priority: Priority }) {
|
||||
if (priority === 'medium') return null
|
||||
|
|
@ -75,6 +77,34 @@ export function ProjectFilter({ selected, onChange }: { selected: number[]; onCh
|
|||
return <FilterChips items={projects} selected={selected} onChange={onChange} label="Project" icon={FolderKanban} />
|
||||
}
|
||||
|
||||
export function ListFilter({ selected, onChange }: { selected: number[]; onChange: (ids: number[]) => void }) {
|
||||
const { lists } = useLists()
|
||||
return <FilterChips items={lists} selected={selected} onChange={onChange} label="List" icon={ListChecks} />
|
||||
}
|
||||
|
||||
// One drop-in filter row for category + project + (optionally) list, reading
|
||||
// straight from the global TaskFiltersContext — the "easy way to filter any
|
||||
// view" version. Pass showList={false} for views already scoped to one list
|
||||
// (e.g. ListView itself), where a list chip would be redundant/confusing.
|
||||
export function TaskFilterBar({ showList = true }: { showList?: boolean }) {
|
||||
const { categoryIds, setCategoryIds, projectIds, setProjectIds, listIds, setListIds } = useTaskFilters()
|
||||
return (
|
||||
<div className="filter-row">
|
||||
<div className="filter-section">
|
||||
<CategoryFilter selected={categoryIds} onChange={setCategoryIds} />
|
||||
</div>
|
||||
<div className="filter-section">
|
||||
<ProjectFilter selected={projectIds} onChange={setProjectIds} />
|
||||
</div>
|
||||
{showList && (
|
||||
<div className="filter-section">
|
||||
<ListFilter selected={listIds} onChange={setListIds} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function formatDate(iso: string | null | undefined): string {
|
||||
if (!iso) return '—'
|
||||
return new Date(iso).toLocaleDateString('en-GB', { day: 'numeric', month: 'short', year: 'numeric' })
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue