feat(PBI-76): migrate pbi-list to user-settings store
Same pattern as sprint-backlog: replaces local useState + localStorage hydration/persist with selectors from useUserSettingsStore. filterPopoverOpen blijft lokaal — die was nooit gepersisteerd in pbi-list. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c10def601b
commit
f7602d2582
1 changed files with 16 additions and 45 deletions
|
|
@ -1,6 +1,6 @@
|
|||
'use client'
|
||||
|
||||
import { useState, useTransition, useEffect } from 'react'
|
||||
import { useState, useTransition } from 'react'
|
||||
import {
|
||||
DndContext,
|
||||
DragEndEvent,
|
||||
|
|
@ -30,7 +30,7 @@ import {
|
|||
type SortDir,
|
||||
} from '@/components/shared/backlog-filter-popover'
|
||||
import { useShallow } from 'zustand/react/shallow'
|
||||
import { readLocalStoragePref } from '@/lib/use-local-storage-pref'
|
||||
import { useUserSettingsStore } from '@/stores/user-settings/store'
|
||||
import { useProductWorkspaceStore } from '@/stores/product-workspace/store'
|
||||
import { selectVisiblePbis } from '@/stores/product-workspace/selectors'
|
||||
import type { BacklogPbi as WorkspacePbi } from '@/stores/product-workspace/types'
|
||||
|
|
@ -199,12 +199,21 @@ export function PbiList({ productId, isDemo }: PbiListProps) {
|
|||
// voorkomt re-render op ongerelateerde store-mutaties (G2).
|
||||
const pbis = useProductWorkspaceStore(useShallow(selectVisiblePbis)) as WorkspacePbi[]
|
||||
const selectedPbiId = useProductWorkspaceStore((s) => s.context.activePbiId)
|
||||
const [filterPriority, setFilterPriority] = useState<number | 'all'>('all')
|
||||
const [filterStatus, setFilterStatus] = useState<PbiStatusFilter>('all')
|
||||
const [sortMode, setSortMode] = useState<SortMode>('priority')
|
||||
const [sortDir, setSortDir] = useState<SortDir>('asc')
|
||||
const prefs = useUserSettingsStore(
|
||||
useShallow((s) => s.entities.settings.views?.pbiList ?? {}),
|
||||
)
|
||||
const setPref = useUserSettingsStore((s) => s.setPref)
|
||||
const filterPriority = prefs.filterPriority ?? 'all'
|
||||
const filterStatus: PbiStatusFilter = prefs.filterStatus ?? 'all'
|
||||
const sortMode: SortMode = prefs.sort ?? 'priority'
|
||||
const sortDir: SortDir = prefs.sortDir ?? 'asc'
|
||||
const setFilterPriority = (v: number | 'all') =>
|
||||
void setPref(['views', 'pbiList', 'filterPriority'], v)
|
||||
const setFilterStatus = (v: PbiStatusFilter) =>
|
||||
void setPref(['views', 'pbiList', 'filterStatus'], v)
|
||||
const setSortMode = (v: SortMode) => void setPref(['views', 'pbiList', 'sort'], v)
|
||||
const setSortDir = (v: SortDir) => void setPref(['views', 'pbiList', 'sortDir'], v)
|
||||
const [filterPopoverOpen, setFilterPopoverOpen] = useState(false)
|
||||
const [prefsLoaded, setPrefsLoaded] = useState(false)
|
||||
const [dialogState, setDialogState] = useState<PbiDialogState | null>(null)
|
||||
const [activeDragId, setActiveDragId] = useState<string | null>(null)
|
||||
const [selectionMode, setSelectionMode] = useState(false)
|
||||
|
|
@ -226,44 +235,6 @@ export function PbiList({ productId, isDemo }: PbiListProps) {
|
|||
})
|
||||
}
|
||||
|
||||
// Hydrate prefs post-mount; SSR + first client render use defaults so no
|
||||
// hydration mismatch. Users with saved == default see no change; others see
|
||||
// one filter update right after hydration.
|
||||
useEffect(() => {
|
||||
/* eslint-disable react-hooks/set-state-in-effect */
|
||||
setSortMode(readLocalStoragePref<SortMode>(
|
||||
'scrum4me:pbi_sort',
|
||||
(raw) => (raw === 'priority' || raw === 'code' || raw === 'date') ? raw : null,
|
||||
'priority',
|
||||
))
|
||||
setFilterPriority(readLocalStoragePref<number | 'all'>(
|
||||
'scrum4me:pbi_filter_priority',
|
||||
(raw) => {
|
||||
if (raw === 'all') return 'all'
|
||||
const n = parseInt(raw, 10)
|
||||
return Number.isInteger(n) && n >= 1 && n <= 4 ? n : null
|
||||
},
|
||||
'all',
|
||||
))
|
||||
setFilterStatus(readLocalStoragePref<PbiStatusFilter>(
|
||||
'scrum4me:pbi_filter_status',
|
||||
(raw) => (raw === 'ready' || raw === 'blocked' || raw === 'done' || raw === 'all') ? raw : null,
|
||||
'all',
|
||||
))
|
||||
setSortDir(readLocalStoragePref<SortDir>(
|
||||
'scrum4me:pbi_sort_dir',
|
||||
(raw) => (raw === 'asc' || raw === 'desc') ? raw : null,
|
||||
'asc',
|
||||
))
|
||||
setPrefsLoaded(true)
|
||||
/* eslint-enable react-hooks/set-state-in-effect */
|
||||
}, [])
|
||||
|
||||
useEffect(() => { if (prefsLoaded) localStorage.setItem('scrum4me:pbi_sort', sortMode) }, [sortMode, prefsLoaded])
|
||||
useEffect(() => { if (prefsLoaded) localStorage.setItem('scrum4me:pbi_filter_priority', String(filterPriority)) }, [filterPriority, prefsLoaded])
|
||||
useEffect(() => { if (prefsLoaded) localStorage.setItem('scrum4me:pbi_filter_status', filterStatus) }, [filterStatus, prefsLoaded])
|
||||
useEffect(() => { if (prefsLoaded) localStorage.setItem('scrum4me:pbi_sort_dir', sortDir) }, [sortDir, prefsLoaded])
|
||||
|
||||
// pbis komen al gesorteerd binnen via selectVisiblePbis (priority + sort_order).
|
||||
// Geen aparte order/priority maps meer — workspace-store entities zijn de waarheid.
|
||||
const pbiMap = Object.fromEntries(pbis.map(p => [p.id, p]))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue