Web: alle Kategorie-Auswahlen als aufklappbarer Baum

Statt der nativen "— —"-Dropdowns nutzen jetzt auch Produktformular
(Kategorie + Inline-"Neue Kategorie"-Elternwahl), Einlagern-Maske und
Produkte-Filter den CategorySelect-Baum. CategorySelect um optionale
Zusatz-Eintraege (extraOptions) erweitert, damit der Produkte-Filter
"Alle Kategorien"/"Ohne Kategorie" weiter anbietet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-07-26 13:07:36 +02:00
parent 956a472c04
commit dc66a6d7ff
4 changed files with 51 additions and 35 deletions

View File

@@ -6,6 +6,7 @@ import Icon from "../components/Icon";
import { ProduktThumb } from "../components/ProduktBild";
import { fmt, gebinde, unitShort } from "../units";
import { asTree } from "../categoryTree";
import CategorySelect from "../components/CategorySelect";
// Wie viele Basiseinheiten eine "Artikeleinheit" umfasst (Gebinde oder Produkteinheit).
function unitCount(p) {
@@ -83,14 +84,14 @@ export default function Products() {
<label className="grow" style={{ margin: 0 }}>
<input placeholder="Produkt suchen…" value={q} onChange={(e) => setQ(e.target.value)} />
</label>
<label style={{ margin: 0 }}>
<select value={categoryId} onChange={(e) => { setCategoryId(e.target.value); load(e.target.value); }}>
<option value="">Alle Kategorien</option>
<option value="0">Ohne Kategorie</option>
{asTree(categories).filter((c) => !typ || c.tracking === typ).map((c) => (
<option key={c.id} value={c.id}>{"— ".repeat(c.depth)}{c.name}</option>
))}
</select>
<label style={{ margin: 0, width: 230 }}>
<CategorySelect
value={categoryId}
nodes={asTree(categories).filter((c) => !typ || c.tracking === typ)}
rootLabel="Alle Kategorien"
extraOptions={[{ value: 0, label: "Ohne Kategorie" }]}
onChange={(id) => { const v = id == null ? "" : String(id); setCategoryId(v); load(v); }}
/>
</label>
<button className="btn"><Icon name="search" size={16} />Suchen</button>
</form>