ST-1230: Sorteerstate en -logica toevoegen aan IdeaList (#126)
* feat(ideas): STATUS_SORT_ORDER + sorteerstate (ST-cmotjj9uf000104l5i70so19b) - Voeg STATUS_SORT_ORDER toe: workflow-volgorde map (draft→plan_failed) - Zet standaard sortDir op 'desc' conform AC (code aflopend bij laden) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(ideas): sorted useMemo + tabel-render koppelen (ST-cmotjj9uf000104l5i70so19b) - Voeg sorted useMemo toe na filtered: locale-aware sort met STATUS_SORT_ORDER - Ideeën zonder product sorteren achteraan bij oplopende productsortering - Vervang filtered.length/filtered.map door sorted in tabel-render Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
6015357905
commit
a28f0249e5
1 changed files with 28 additions and 3 deletions
|
|
@ -70,6 +70,11 @@ const STATUS_FILTERS: { value: IdeaStatusApi; label: string }[] = [
|
||||||
{ value: 'plan_failed', label: 'Plan mislukt' },
|
{ value: 'plan_failed', label: 'Plan mislukt' },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const STATUS_SORT_ORDER: Record<IdeaStatusApi, number> = {
|
||||||
|
draft: 0, grilling: 1, grilled: 2, planning: 3,
|
||||||
|
plan_ready: 4, planned: 5, grill_failed: 6, plan_failed: 7,
|
||||||
|
}
|
||||||
|
|
||||||
function SortHeader({
|
function SortHeader({
|
||||||
col,
|
col,
|
||||||
label,
|
label,
|
||||||
|
|
@ -113,7 +118,7 @@ export function IdeaList({ ideas, products, isDemo }: IdeaListProps) {
|
||||||
|
|
||||||
// Sort state
|
// Sort state
|
||||||
const [sortKey, setSortKey] = useState<SortKey>('code')
|
const [sortKey, setSortKey] = useState<SortKey>('code')
|
||||||
const [sortDir, setSortDir] = useState<'asc' | 'desc'>('asc')
|
const [sortDir, setSortDir] = useState<'asc' | 'desc'>('desc')
|
||||||
|
|
||||||
// Create-form state
|
// Create-form state
|
||||||
const [showCreate, setShowCreate] = useState(false)
|
const [showCreate, setShowCreate] = useState(false)
|
||||||
|
|
@ -149,6 +154,26 @@ export function IdeaList({ ideas, products, isDemo }: IdeaListProps) {
|
||||||
})
|
})
|
||||||
}, [ideas, search, productFilter, statusFilter, sortKey, sortDir])
|
}, [ideas, search, productFilter, statusFilter, sortKey, sortDir])
|
||||||
|
|
||||||
|
const sorted = useMemo(() => {
|
||||||
|
return [...filtered].sort((a, b) => {
|
||||||
|
let cmp = 0
|
||||||
|
if (sortKey === 'code') {
|
||||||
|
cmp = (a.code ?? '').localeCompare(b.code ?? '', 'nl', { numeric: true })
|
||||||
|
} else if (sortKey === 'title') {
|
||||||
|
cmp = a.title.localeCompare(b.title, 'nl')
|
||||||
|
} else if (sortKey === 'product') {
|
||||||
|
const aN = a.product?.name ?? ''
|
||||||
|
const bN = b.product?.name ?? ''
|
||||||
|
if (!aN && bN) return sortDir === 'asc' ? 1 : -1
|
||||||
|
if (aN && !bN) return sortDir === 'asc' ? -1 : 1
|
||||||
|
cmp = aN.localeCompare(bN, 'nl')
|
||||||
|
} else {
|
||||||
|
cmp = (STATUS_SORT_ORDER[a.status] ?? 99) - (STATUS_SORT_ORDER[b.status] ?? 99)
|
||||||
|
}
|
||||||
|
return sortDir === 'asc' ? cmp : -cmp
|
||||||
|
})
|
||||||
|
}, [filtered, sortKey, sortDir])
|
||||||
|
|
||||||
function handleSort(col: SortKey) {
|
function handleSort(col: SortKey) {
|
||||||
if (sortKey === col) {
|
if (sortKey === col) {
|
||||||
setSortDir((d) => (d === 'asc' ? 'desc' : 'asc'))
|
setSortDir((d) => (d === 'asc' ? 'desc' : 'asc'))
|
||||||
|
|
@ -311,7 +336,7 @@ export function IdeaList({ ideas, products, isDemo }: IdeaListProps) {
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Tabel */}
|
{/* Tabel */}
|
||||||
{filtered.length === 0 ? (
|
{sorted.length === 0 ? (
|
||||||
<p className="text-sm text-muted-foreground py-8 text-center">
|
<p className="text-sm text-muted-foreground py-8 text-center">
|
||||||
{ideas.length === 0
|
{ideas.length === 0
|
||||||
? 'Nog geen ideeën — start hierboven met "Nieuw idee".'
|
? 'Nog geen ideeën — start hierboven met "Nieuw idee".'
|
||||||
|
|
@ -329,7 +354,7 @@ export function IdeaList({ ideas, products, isDemo }: IdeaListProps) {
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{filtered.map((idea) => {
|
{sorted.map((idea) => {
|
||||||
const badge = getIdeaStatusBadge(API_TO_DB[idea.status])
|
const badge = getIdeaStatusBadge(API_TO_DB[idea.status])
|
||||||
return (
|
return (
|
||||||
<TableRow
|
<TableRow
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue