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
+7 -9
View File
@@ -4,6 +4,7 @@ import { useAuth } from "../auth";
import { useConfirm } from "../confirm";
import Icon from "../components/Icon";
import { locationOptions, locationPathById } from "../locationPath";
import LocationSelect from "../components/LocationSelect";
import { gruppenOptionen } from "../groupGraph";
import { anzahlWort, fmt, gebinde, grpFactor, grpPkgMode, grpUnit, kindShort } from "../units";
@@ -308,12 +309,10 @@ export default function MinStock() {
{isAdmin && (
<>
<select value={vonId(r.locId)}
<LocationSelect value={vonId(r.locId)} locations={locations}
title="Ort ändern – der Mindestbestand wird verschoben"
onChange={(e) => moveRow(r, e.target.value)}>
<option value={UEBERALL}>Überall</option>
{locationOptions(locations).map((o) => <option key={o.id} value={o.id}>{o.label}</option>)}
</select>
showRoot={false} extraOptions={[{ value: UEBERALL, label: "Überall" }]}
onChange={(id) => moveRow(r, id)} />
<button type="button" className="btn-icon danger" title="Mindestbestand löschen"
onClick={() => deleteRow(r)}><Icon name="trash" size={15} /></button>
</>
@@ -350,10 +349,9 @@ export default function MinStock() {
<div className="row">
<label className="grow" style={{ maxWidth: 360 }}>
Wo
<select value={draft.locId} onChange={(e) => setDraft({ ...draft, locId: e.target.value })}>
<option value={UEBERALL}>Überall (egal wo)</option>
{locationOptions(locations).map((o) => <option key={o.id} value={o.id}>{o.label}</option>)}
</select>
<LocationSelect value={draft.locId} locations={locations}
showRoot={false} extraOptions={[{ value: UEBERALL, label: "Überall (egal wo)" }]}
onChange={(id) => setDraft({ ...draft, locId: id })} />
</label>
<label className="seg-label">
Was