Lagerorte: ueberall ein aufklappbarer Baum statt flacher Pfadliste

Die Lagerort-Auswahl schrieb in jeder Zeile den ganzen Pfad aus
("Hedingen → Guido Zimmer → Kallax → Fach Oben Links → Oben"). Bei einem
tiefen Baum ist das eine Wand aus Wiederholungen, und Geschwister stehen
nur zufaellig beieinander.

Jetzt dasselbe Auswahlfeld wie bei den Kategorien: eingerueckter Baum,
Aeste ein- und ausklappbar. Geschlossen steht weiter der volle Pfad da -
"Oben" allein waere nicht eindeutig, genau dafuer war der Pfad gedacht.

CategorySelect konnte das schon und war auf Lagerort-Codes vorbereitet
(seine IDs duerfen Zeichenketten sein). Dazu kam nur LocationSelect als
duenne Huelle: Baumaufbau und die Umrechnung "" <-> null, damit die 16
Aufrufstellen weiter mit dem leeren String fuer "kein Ort" arbeiten.

Zwei Kleinigkeiten dabei: CategorySelect bekommt showRoot, weil bei den
Mindestbestaenden "nichts gewaehlt" kein gueltiger Wert ist - dort heisst
die oberste Zeile "Ueberall". Und LocationSelect sortiert Geschwister
selbst nach Namen; der Server sortiert zeichenweise, dort stuende "Fach
oben Rechts" hinter "Fach Unten Rechts".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-10-24 17:37:00 +02:00
co-authored by Claude Opus 5
parent 290ff9341a
commit 7cb61d226f
12 changed files with 113 additions and 91 deletions
+41
View File
@@ -0,0 +1,41 @@
import CategorySelect from "./CategorySelect";
import { asTree } from "../categoryTree";
/**
* Lagerort-Auswahl als aufklappbarer Baum – dieselbe Darstellung wie bei den
* Kategorien, denn Lagerorte sind genauso verschachtelt (Hedingen → Kallax →
* Fach Oben Links → Oben). Vorher stand überall ein flaches <select>, in dem
* jede Zeile den ganzen Pfad ausschrieb; Geschwister standen dadurch nur
* zufällig beieinander.
*
* `CategorySelect` kann beides – seine IDs dürfen Zeichenketten sein, und
* Lagerort-Codes sind welche. Hier kommt nur der Baumaufbau dazu und die
* Umrechnung "" ↔ null, damit die Aufrufstellen weiter mit dem leeren String
* für „kein Ort" arbeiten wie beim <select> zuvor.
*/
export default function LocationSelect({
value,
onChange,
locations,
rootLabel = "– ohne –",
extraOptions = [],
showRoot = true,
disabled = false,
title,
}) {
return (
<CategorySelect
value={value === "" || value == null ? null : value}
onChange={(id) => onChange(id == null ? "" : id)}
// Nach Namen sortieren, bevor der Baum entsteht: Der Server sortiert
// zeichenweise, dort stuende „Fach oben Rechts" hinter „Fach Unten
// Rechts". asTree uebernimmt die Reihenfolge der Geschwister unveraendert.
nodes={asTree([...(locations || [])].sort((a, b) => a.name.localeCompare(b.name, "de")))}
rootLabel={rootLabel}
extraOptions={extraOptions}
showRoot={showRoot}
disabled={disabled}
title={title}
/>
);
}