feat: Chargen- und Erntebilder einzeln pro Kachel pflegbar
Die Chargenseite (/charge/[code]) zeigt zwei Bildkacheln: links Ernte und Jahr, rechts den Standort. Gefuellt wurden sie aus einer Bilder-LISTE, in der allein die Reihenfolge entschied, welches Bild wohin kommt. Damit liess sich das zweite Bild nicht allein setzen. Wer nur ein Foto vom Standort pflegen wollte, bekam es auf Position 0 — also in die linke Kachel, wo Ernte und Jahr stehen sollten. Welche Kachel ein Bild fuellt, war im Formular ausserdem nirgends erkennbar. Jetzt zwei benannte Slots statt einer Liste, im Chargen- wie im Ernten-Formular: Bild 1 — linke Kachel auf der Chargenseite Bild 2 — rechte Kachel auf der Chargenseite (Standort) Jeder Slot hat eine eigene Vorschau, einen eigenen Auswahl- und einen eigenen Entfernen-Knopf. Beide tragen denselben Feldnamen "images" und werden in dieser Reihenfolge uebermittelt. Dafuer brauchte es einen positionserhaltenden Parser: strArray() trimmt und filtert leere Werte heraus, wodurch ein leerer erster Slot verschwunden und der zweite nach vorn gerutscht waere — genau der Fehler, der behoben werden sollte. Neu ist strArraySlots(), das leere Slots als "" stehen laesst und nur am Ende stehende entfernt (ein leeres Feld ergibt weiterhin [] statt ["", ""]). Die Konsumenten mussten entsprechend von "??" auf "||" wechseln: ein im Admin geleerter Slot kommt als leerer String an, nicht als undefined. Mit "??" haette dieser leere String als gueltiger Wert gegolten und das Erntebild darunter verdeckt (charge/[code], ernten, ernten/[year]/[type]). strArray/strArraySlots sind nach lib/form-fields.ts gewandert und werden aus _shared.ts re-exportiert — saemtliche bestehenden Importe bleiben unveraendert. Grund: _shared.ts zieht ueber lib/prisma.ts einen Datenbank-Adapter nach und liess sich ohne DATABASE_URL nicht testen. Als reine Funktionen ohne Datenbankbezug sind die beiden jetzt direkt pruefbar, passend zur bereits dokumentierten Teststrategie des Projekts. Sieben neue Tests decken den Kernfall ab (leerer erster Slot bleibt offen), mit Gegenprobe, dass strArray denselben Fall weiterhin zusammenrutschen laesst. Produktbilder bleiben bewusst bei der bisherigen Liste: dort ist die Bilderzahl offen und die Reihenfolge traegt keine Kachel-Bedeutung. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
1 parent
979d39e677
commit
ff365c3cb1
12 files changed
+182
-27
No files matched your search
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Reine Leser fuer FormData-Werte — ohne Datenbank- oder Next.js-Bezug,
|
||||
* damit sie sich unabhaengig testen lassen (siehe
|
||||
* app/admin/actions/image-slots.test.ts). Die Admin-Actions importieren sie
|
||||
* weiterhin ueber admin/actions/_shared.ts, das sie re-exportiert.
|
||||
*/
|
||||
|
||||
/** Alle Werte eines wiederholten Feldes, getrimmt, ohne leere Eintraege. */
|
||||
export function strArray(formData: FormData, key: string): string[] {
|
||||
return formData
|
||||
.getAll(key)
|
||||
.map((value) => String(value).trim())
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wie strArray, aber POSITIONSERHALTEND: ein leerer Eintrag bleibt als ""
|
||||
* stehen, statt herauszufallen.
|
||||
*
|
||||
* Gedacht fuer Felder, bei denen die Position eine Bedeutung traegt. Chargen-
|
||||
* und Erntebilder sind genau so ein Fall: Slot 1 fuellt die linke, Slot 2 die
|
||||
* rechte Kachel auf /charge/[code]. Mit strArray liesse sich das zweite Bild
|
||||
* gar nicht allein setzen — ohne erstes Bild rueckte das zweite auf Position 0
|
||||
* und landete in der falschen Kachel.
|
||||
*
|
||||
* Nur am Ende stehende leere Slots werden entfernt, damit ein vollstaendig
|
||||
* leeres Feld weiterhin ein leeres Array ergibt statt ["", ""].
|
||||
*/
|
||||
export function strArraySlots(formData: FormData, key: string): string[] {
|
||||
const slots = formData.getAll(key).map((value) => String(value).trim());
|
||||
while (slots.length > 0 && slots[slots.length - 1] === "") slots.pop();
|
||||
return slots;
|
||||
}
|
||||
Reference in new issue
Block a user