From 928342d35237af72a64de1b68c71ecc06580ffe1 Mon Sep 17 00:00:00 2001 From: Scarriffle Date: Sun, 26 Jul 2026 00:01:32 +0200 Subject: [PATCH] Web: Unterkategorien umsortieren (uebergeordnete Kategorie aenderbar) In der Kategorien-Verwaltung gibt es je Zeile eine Spalte "Uebergeordnet" mit Auswahl - so laesst sich eine (Unter-)Kategorie unter eine andere haengen oder auf die oberste Ebene holen. Zielauswahl auf denselben Typ beschraenkt und um die eigenen Unterkategorien bereinigt; das Backend verhindert Ringe zusaetzlich. Co-Authored-By: Claude Opus 4.8 --- web/src/pages/Categories.jsx | 40 ++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/web/src/pages/Categories.jsx b/web/src/pages/Categories.jsx index 2d1bad8..cb24026 100644 --- a/web/src/pages/Categories.jsx +++ b/web/src/pages/Categories.jsx @@ -95,6 +95,19 @@ export default function Categories() { const nameById = Object.fromEntries(categories.map((c) => [c.id, c.name])); const parentOf = Object.fromEntries(categories.map((c) => [c.id, c.parent_id])); const childCount = (id) => categories.filter((c) => c.parent_id === id).length; + // Eigene Unterkategorien (rekursiv) – als Ziel beim Verschieben ausgeschlossen, + // sonst entstünde ein Ring. + function descendantIds(id) { + const result = new Set(); + const stack = [id]; + while (stack.length) { + const cur = stack.pop(); + for (const kid of categories.filter((c) => c.parent_id === cur)) { + if (!result.has(kid.id)) { result.add(kid.id); stack.push(kid.id); } + } + } + return result; + } function versteckt(id) { let p = parentOf[id]; while (p != null) { @@ -135,6 +148,7 @@ export default function Categories() { Kategorie Art + Übergeordnet Artikel @@ -143,6 +157,12 @@ export default function Categories() { {sichtbar.map((c) => { const kinder = childCount(c.id); const zu = collapsed.has(c.id); + // Mögliche neue Elternkategorien: gleicher Typ, nicht sie selbst + // und keine ihrer Unterkategorien. + const desc = descendantIds(c.id); + const parentOptions = tree.filter( + (o) => o.tracking === c.tracking && o.id !== c.id && !desc.has(o.id), + ); return ( @@ -164,9 +184,6 @@ export default function Categories() { {zu && kinder > 0 && ( {kinder} ausgeblendet )} - {c.depth > 0 && c.parent_id && nameById[c.parent_id] && ( - in {nameById[c.parent_id]} - )} @@ -180,6 +197,21 @@ export default function Categories() { {MODUS[c.tracking] || c.tracking} )} + + {isAdmin ? ( + + ) : ( + {c.parent_id ? nameById[c.parent_id] : "–"} + )} + {c.product_count}