feat: shared backlog filter popover + sprint header polish (v1.3.3) (#184)

- Move sprint switcher into sprint header, centered between title and actions
- Extract BacklogFilterPopover as shared component used by sprint and product backlog
- Add sort options (code/priority/status) with single-pill asc/desc toggle
- Default sprint backlog status filter to OPEN, remove "alleen niet klaar" button
- Persist collapsed state and filter popover open in localStorage
- Fix hydration flicker: defer localStorage read to useEffect with prefsLoaded gate for writes
- Increase sprint switcher text size for readability

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Janpeter Visser 2026-05-10 11:12:04 +02:00 committed by GitHub
parent a9b53dedf0
commit 1f8cbacb0a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 424 additions and 330 deletions

View file

@ -115,10 +115,6 @@ export default function JobsColumn({
statusOptions,
emptyText,
}: JobsColumnProps) {
const [filterKinds, setFilterKinds] = useState<Set<ClaudeJobKind>>(() => new Set())
const [filterStatuses, setFilterStatuses] = useState<Set<ClaudeJobStatusApi>>(() => new Set())
const [prefsLoaded, setPrefsLoaded] = useState(false)
const kindKey = `${storageKeyPrefix}_filter_kind`
const statusKey = `${storageKeyPrefix}_filter_status`
@ -127,8 +123,11 @@ export default function JobsColumn({
[statusOptions]
)
const [filterKinds, setFilterKinds] = useState<Set<ClaudeJobKind>>(() => new Set())
const [filterStatuses, setFilterStatuses] = useState<Set<ClaudeJobStatusApi>>(() => new Set())
const [prefsLoaded, setPrefsLoaded] = useState(false)
useEffect(() => {
// Hydratie van localStorage post-mount: zetters intentioneel, voorkomt SSR-mismatch.
/* eslint-disable react-hooks/set-state-in-effect */
setFilterKinds(parseCsv<ClaudeJobKind>(localStorage.getItem(kindKey), KIND_VALUES))
setFilterStatuses(parseCsv<ClaudeJobStatusApi>(localStorage.getItem(statusKey), statusValues))
@ -136,13 +135,8 @@ export default function JobsColumn({
/* eslint-enable react-hooks/set-state-in-effect */
}, [kindKey, statusKey, statusValues])
useEffect(() => {
if (prefsLoaded) localStorage.setItem(kindKey, setToCsv(filterKinds))
}, [filterKinds, prefsLoaded, kindKey])
useEffect(() => {
if (prefsLoaded) localStorage.setItem(statusKey, setToCsv(filterStatuses))
}, [filterStatuses, prefsLoaded, statusKey])
useEffect(() => { if (prefsLoaded) localStorage.setItem(kindKey, setToCsv(filterKinds)) }, [filterKinds, prefsLoaded, kindKey])
useEffect(() => { if (prefsLoaded) localStorage.setItem(statusKey, setToCsv(filterStatuses)) }, [filterStatuses, prefsLoaded, statusKey])
function toggleKind(v: ClaudeJobKind) {
setFilterKinds((prev) => {