Web: Kategorie-Filter mit vollem Pfad (Oberkategorie findet Unterkategorien)

Der Kategorie-Spaltenfilter zeigte nur die Blatt-Kategorien, die an Produkten haengen - die Oberkategorie (z.B. 'Klamotten') fehlte, obwohl darunter (kurze Hosen, T-Shirts) etwas eingelagert ist. Kategorie wird jetzt als voller Pfad 'Klamotten -> kurze Hosen' gefuehrt; Freitext 'Klamotten' findet damit alles darunter. Betrifft Produkt- und Einzelstueckliste. (Lagerorte nutzen den Pfad bereits.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-07-27 17:13:11 +02:00
parent 76dc29ac72
commit 487c5f5f38
3 changed files with 44 additions and 9 deletions

View File

@@ -1,4 +1,4 @@
import { useEffect, useState } from "react";
import { useEffect, useMemo, useState } from "react";
import { Link } from "react-router-dom";
import { api } from "../api";
import { useAuth } from "../auth";
@@ -6,6 +6,7 @@ import Icon from "../components/Icon";
import DataTable from "../components/DataTable";
import { ProduktThumb } from "../components/ProduktBild";
import { locationOptions, locationPathById } from "../locationPath";
import { categoryPathMap } from "../categoryPath";
/**
* Liste aller Einzelstücke (physische Exemplare, jedes mit eigener UID/Lagerort)
@@ -17,18 +18,22 @@ export default function ItemList() {
const [items, setItems] = useState([]);
const [locations, setLocations] = useState([]);
const [shops, setShops] = useState([]);
const [categories, setCategories] = useState([]);
const [error, setError] = useState(null);
async function load() {
try {
const [is, ls, ss] = await Promise.all([
api.listAllItems(), api.listLocations(), api.listShops(),
const [is, ls, ss, cs] = await Promise.all([
api.listAllItems(), api.listLocations(), api.listShops(), api.listCategories(),
]);
setItems(is); setLocations(ls); setShops(ss);
setItems(is); setLocations(ls); setShops(ss); setCategories(cs);
} catch (err) { setError(err.message); }
}
useEffect(() => { load(); }, []);
// Kategorie als voller Pfad, damit "Klamotten" auch die Unterkategorien findet.
const catPfad = useMemo(() => categoryPathMap(categories), [categories]);
async function patch(it, body) {
try { await api.updateItem(it.id, body); await load(); }
catch (err) { setError(err.message); }
@@ -47,8 +52,9 @@ export default function ItemList() {
render: (it) => it.product_name || "" },
{ key: "brand", header: "Marke", width: 140, filterText: (it) => it.product_brand || "",
render: (it) => <span className="muted">{it.product_brand || ""}</span> },
{ key: "category", header: "Kategorie", width: 160, filterText: (it) => it.category_name || "",
render: (it) => <span className="muted">{it.category_name || ""}</span> },
{ key: "category", header: "Kategorie", width: 200,
filterText: (it) => catPfad.get(it.category_id) || it.category_name || "",
render: (it) => <span className="muted">{catPfad.get(it.category_id) || it.category_name || ""}</span> },
{ key: "location", header: "Lagerort", width: 220,
filterText: (it) => locationPathById(it.location_id, locations),
render: (it) => (isAdmin ? (