Kategorien:
- Oberkategorien lassen sich per Pfeil zuklappen; ihre Unterkategorien
verschwinden dann aus der Liste. Ausgeblendet wird ueber die gesamte
Vorfahrenkette, nicht nur eine Ebene, damit auch mehrstufige Baeume stimmen.
- Ist eine Kategorie zugeklappt, zeigt ein Badge, wie viele Eintraege darunter
liegen - sonst waere nicht erkennbar, dass dort noch etwas ist.
- Zeilen ohne Unterkategorien bekommen einen Platzhalter, damit alle Namen
buendig stehen.
Badges in Zellen:
- In der Karten-Ansicht verteilte das Raster mehrere Elemente einer Zelle auf
zwei Rasterzellen - deshalb rutschte "eingebaut" unter die Beschriftung.
Jetzt Flexfluss, alle Teile stehen hinter der Beschriftung.
- Einheiten-Tabelle: Name und "eingebaut" liegen in einer Zeile zusammen.
Geprueft: "npm run build" laeuft durch.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Waagerechtes Scrollen in einem Block war die falsche Antwort auf zu wenig
Platz - man sieht nicht, dass es weitergeht, und auf dem Trackpad ist es
muehsam. Das Scrollen ist ersatzlos weg.
Stattdessen stellt sich jede Tabelle unter 700px verfuegbarer Breite auf
Karten um: eine Karte je Zeile, jede Angabe mit ihrer Beschriftung davor.
Die Beschriftung kommt aus data-label an der Zelle, die Kopfzeile wird
ausgeblendet. Zellen ohne Beschriftung (Vorschaubild, Aktionsknoepfe) bleiben
ohne eigene Zeile.
Ausgeloest wird das per Container-Abfrage, nicht per Bildschirmbreite. Damit
richtet sich die Darstellung nach dem Platz, den die Tabelle wirklich hat -
sie stellt sich also auch um, wenn das Fenster nur die halbe Bildschirmbreite
einnimmt oder ein Block danebensteht.
Dazu die Aufteilung neben dem Block: Die Tabelle hat mehr Spalten als der
Block und bekommt jetzt den groesseren Anteil (1,5 zu 1, Block mindestens
340px). Vorher waren beide gleich breit, wodurch die Tabelle unnoetig frueh in
die Kartenansicht gerutscht waere, obwohl daneben Platz frei war.
Durchgerechnet: Bei 1920 voller Breite bleibt es eine Tabelle (802px) mit
komfortablem Block daneben (534px). Bei halber Bildschirmbreite stapelt sich
die Seite und die Tabelle wird zur Karte. In keinem Fall wird etwas
abgeschnitten und nirgends muss seitwaerts gescrollt werden.
Lange Zeichenketten in Zellen brechen jetzt um (overflow-wrap), da kein
Scrollen mehr auffaengt, was hinauslaeuft.
Dabei aufgefallen: In der Produkttabelle stand nach dem Ergaenzen der
Kategorie-Spalte noch colSpan={7} statt 8 - die Zeile "Keine Produkte
gefunden" ueberspannte die Tabelle nicht mehr ganz. Alle colSpan-Angaben sind
jetzt gegen die Spaltenzahl gegengeprueft.
Getestet: Web-Build laeuft durch, Spaltenzahl und colSpan stimmen in allen
fuenf betroffenen Tabellen ueberein, die Umbruchpunkte sind durchgerechnet.
Die Darstellung im Browser habe ich nicht selbst angesehen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Rueckfragen liefen bisher ueber window.confirm. Das reisst aus der Oberflaeche,
zeigt den Hostnamen, laesst sich nicht gestalten und die Knoepfe heissen immer
"OK/Abbrechen". Neu ist ein eigener Dialog (src/confirm.jsx) als Provider mit
dem Hook useConfirm. Der Aufruf bleibt so einfach wie vorher, weil er eine
Zusage zurueckgibt:
if (!(await confirm({ title: "…?", message: "…" }))) return;
Damit sind alle neun Stellen umgestellt: Gruppen, Kategorien, Lagerorte,
Einheiten, Benutzer, API-Tokens, Produkt und Charge loeschen sowie das Ersetzen
beim Import. Jede Rueckfrage hat jetzt einen sprechenden Titel, einen Satz zu
den Folgen und einen benannten Knopf ("Loeschen", "Widerrufen", "Ersetzen")
statt eines nichtssagenden OK. Unwiderrufliche Schritte sind rot.
Kuenftig gilt: keine Browserdialoge mehr.
Export: Dateinamen tragen jetzt Datum und Uhrzeit
(bestand_2026-07-22_2130.csv, project-good-backup_2026-07-22_2130.json). Ohne
Zeitstempel hiessen mehrere Ausleitungen alle gleich und der Browser haengte
(1), (2) an - dann war nicht mehr erkennbar, welche die aktuelle ist. Der
Zeitstempel entsteht an beiden Enden gleich: im Content-Disposition-Kopf des
Backends und im Dateinamen, den der Browser setzt. Im JSON steht zusaetzlich
die Ortszeit neben dem bereits vorhandenen UTC-Zeitpunkt. Die CSV bleibt
inhaltlich unveraendert - eine zusaetzliche Spalte oder Kopfzeile wuerde die
Datei in Excel nur stoeren.
Notizen an Gruppen-Codes: Codes, die beim Zuordnen eines Artikels automatisch
entstehen, hatten bisher keine Moeglichkeit, eine Notiz zu bekommen - die liess
sich nur beim Anlegen von Hand mitgeben. Neu PATCH /groups/{id}/barcodes/{code}
und ein Notizfeld in der Liste, das beim Verlassen speichert. Leeren entfernt
die Notiz.
Getestet: 57 pytest-Tests unveraendert gruen, Web-Build laeuft durch. Gegen die
laufende API geprueft: Zeitstempel in beiden Content-Disposition-Koepfen und im
JSON-Inhalt; Notiz an einem automatisch angelegten Code setzen, aendern und
leeren, unbekannter Code antwortet mit 404. Die Dialoge selbst habe ich nicht
im Browser angeklickt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Einheiten (neu):
- Tabelle units (name, kind=count|weight|volume, factor, is_builtin); eingebaut
Stueck/Gramm/Kilogramm/Milliliter/Liter, Admin kann eigene anlegen (z.B. Pfund=500g).
- Bestaende bleiben intern in kanonischer Basis (Stueck/Gramm/Milliliter);
Product.display_unit_id und Group.min_stock_unit_id als nullable FKs.
- Neuer Umrechnungs-Service (services/conversion.py) ersetzt die feste Einheitenlogik;
Ein-/Auslagern und Gruppen-Mindestbestand rechnen ueber den Faktor.
- Gruppen-Mindestbestand mit Einheit; Gruppenbestand summiert nur Produkte
passender Art. Neue Verwaltungsseite "Einheiten" (Admin).
- Schonende Migration beim Start: ADD COLUMN IF NOT EXISTS (Postgres), damit
bestehende Installationen ihre Daten behalten.
Chargen:
- PATCH /lots/{id} und DELETE /lots/{id}: Menge/MHD korrigieren, Charge loeschen
(wird als Korrektur-Bewegung protokolliert). Bearbeitung im Produktdetail.
Auslagern:
- Optionales lot_id: gezielt aus einer bestimmten Charge/MHD abbuchen statt FEFO;
Auswahl-Dropdown in der Auslagern-Seite.
Sonstiges: Roadmap aktualisiert, Tests fuer die Umrechnung.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>