feat(iace): add withdrawn filter to norms library frontend
- Add withdrawn/valid_until/replaced_by to Norm interface - Add Status filter (Aktiv/Zurueckgezogen) — defaults to "Aktiv" - Withdrawn norms hidden by default, viewable via filter Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -15,6 +15,9 @@ export interface Norm {
|
||||
mandatory: boolean
|
||||
relevant_sections: string[]
|
||||
beuth_url: string
|
||||
withdrawn?: boolean
|
||||
valid_until?: string
|
||||
replaced_by?: string
|
||||
}
|
||||
|
||||
const PER_PAGE = 50
|
||||
@@ -30,6 +33,11 @@ const MANDATORY_OPTIONS = [
|
||||
{ value: 'ja', label: 'Pflicht: Ja' },
|
||||
{ value: 'nein', label: 'Pflicht: Nein' },
|
||||
]
|
||||
const STATUS_OPTIONS = [
|
||||
{ value: '', label: 'Status: Alle' },
|
||||
{ value: 'active', label: 'Aktiv' },
|
||||
{ value: 'withdrawn', label: 'Zurueckgezogen' },
|
||||
]
|
||||
|
||||
interface Props { norms: Norm[] }
|
||||
|
||||
@@ -38,6 +46,7 @@ export default function NormenTab({ norms }: Props) {
|
||||
const [debounced, setDebounced] = useState('')
|
||||
const [typeFilter, setTypeFilter] = useState('')
|
||||
const [mandatoryFilter, setMandatoryFilter] = useState('')
|
||||
const [statusFilter, setStatusFilter] = useState('active')
|
||||
const [page, setPage] = useState(1)
|
||||
const timer = useRef<ReturnType<typeof setTimeout> | null>(null)
|
||||
|
||||
@@ -46,7 +55,7 @@ export default function NormenTab({ norms }: Props) {
|
||||
return () => { if (timer.current) clearTimeout(timer.current) }
|
||||
}, [search])
|
||||
|
||||
useEffect(() => { setPage(1) }, [debounced, typeFilter, mandatoryFilter])
|
||||
useEffect(() => { setPage(1) }, [debounced, typeFilter, mandatoryFilter, statusFilter])
|
||||
|
||||
const filtered = useMemo(() => {
|
||||
const q = debounced.toLowerCase()
|
||||
@@ -55,9 +64,11 @@ export default function NormenTab({ norms }: Props) {
|
||||
if (typeFilter && n.norm_type !== typeFilter) return false
|
||||
if (mandatoryFilter === 'ja' && !n.mandatory) return false
|
||||
if (mandatoryFilter === 'nein' && n.mandatory) return false
|
||||
if (statusFilter === 'active' && n.withdrawn) return false
|
||||
if (statusFilter === 'withdrawn' && !n.withdrawn) return false
|
||||
return true
|
||||
})
|
||||
}, [norms, debounced, typeFilter, mandatoryFilter])
|
||||
}, [norms, debounced, typeFilter, mandatoryFilter, statusFilter])
|
||||
|
||||
const totalPages = Math.ceil(filtered.length / PER_PAGE)
|
||||
const pageItems = filtered.slice((page - 1) * PER_PAGE, page * PER_PAGE)
|
||||
@@ -70,6 +81,7 @@ export default function NormenTab({ norms }: Props) {
|
||||
</div>
|
||||
<FilterDropdown label="Normtyp" value={typeFilter} options={TYPE_OPTIONS} onChange={setTypeFilter} />
|
||||
<FilterDropdown label="Pflicht" value={mandatoryFilter} options={MANDATORY_OPTIONS} onChange={setMandatoryFilter} />
|
||||
<FilterDropdown label="Status" value={statusFilter} options={STATUS_OPTIONS} onChange={setStatusFilter} />
|
||||
<span className="text-sm text-gray-500 dark:text-gray-400 ml-auto">
|
||||
{norms.length} Normen{filtered.length !== norms.length && ` (${filtered.length} gefiltert)`}
|
||||
</span>
|
||||
|
||||
Reference in New Issue
Block a user