From 4d708b44438ba6db10eb390324c2c8e08a1d9b8d Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Sat, 9 May 2026 08:50:26 +0200 Subject: [PATCH] feat(iace): add withdrawn filter to norms library frontend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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) --- .../sdk/iace/library/_components/NormenTab.tsx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/admin-compliance/app/sdk/iace/library/_components/NormenTab.tsx b/admin-compliance/app/sdk/iace/library/_components/NormenTab.tsx index 9c6e460..50d9183 100644 --- a/admin-compliance/app/sdk/iace/library/_components/NormenTab.tsx +++ b/admin-compliance/app/sdk/iace/library/_components/NormenTab.tsx @@ -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 | 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) { + {norms.length} Normen{filtered.length !== norms.length && ` (${filtered.length} gefiltert)`}