diff --git a/web/src/components/CategorySelect.jsx b/web/src/components/CategorySelect.jsx index de8aff7..5910c9b 100644 --- a/web/src/components/CategorySelect.jsx +++ b/web/src/components/CategorySelect.jsx @@ -16,6 +16,9 @@ export default function CategorySelect({ onChange, nodes, rootLabel = "– oberste Ebene –", + // Zusätzliche Einträge über dem Baum, z.B. { value: 0, label: "Ohne Kategorie" } + // für Filter. Ihr Wert wird unverändert an onChange gereicht. + extraOptions = [], disabled = false, }) { const [open, setOpen] = useState(false); @@ -29,8 +32,10 @@ export default function CategorySelect({ const idset = new Set(nodes.map((n) => n.id)); const hasKids = (id) => nodes.some((n) => n.parent_id === id); - const selected = value == null || value === "" ? null : Number(value); - const label = selected == null ? rootLabel : nameById[selected] ?? rootLabel; + const isRoot = value == null || value === ""; + const extra = extraOptions.find((o) => String(o.value) === String(value)); + const selectedId = !isRoot && !extra ? Number(value) : null; + const label = isRoot ? rootLabel : extra ? extra.label : nameById[selectedId] ?? rootLabel; function place() { const r = btnRef.current?.getBoundingClientRect(); @@ -101,7 +106,7 @@ export default function CategorySelect({ aria-expanded={open} onClick={() => setOpen((o) => !o)} > - {label} + {label} @@ -113,12 +118,23 @@ export default function CategorySelect({ > + {extraOptions.map((o) => ( + + ))} {visible.map((n) => { const kids = hasKids(n.id); const zu = collapsed.has(n.id); @@ -139,7 +155,7 @@ export default function CategorySelect({ )}