Geraeteformular zum Anlegen und Bearbeiten ergaenzen
Schliesst die letzte offene Luecke aus Phase 1. Bis dahin liessen sich Geraete
nur ueber den Import erfassen — fuer einen Bestand richtig, fuer ein einzelnes
nachbeschafftes Geraet umstaendlich.
Neu:
- /geraete/neu und /geraete/<id>/bearbeiten, beide ueber dieselbe Komponente
- Die Lagerung ist ein Umschalter statt zweier Auswahlfelder. Standort und
Fahrzeug schliessen sich aus; so kann der Fehler gar nicht erst entstehen,
den die Datenbank sonst abweisen wuerde. Beim Wechsel des Fahrzeugs wird die
Raumangabe zurueckgesetzt.
- Prueftermin und Lebensdauerende werden beim Tippen vorgerechnet, mit
denselben Funktionen wie auf dem Server. Beim Speichern rechnet der Server
erneut und behaelt das letzte Wort.
- Gibt es nur einen Standort, ist er beim Anlegen vorbelegt.
- Knopf "Neues Geraet" in der Liste, "Bearbeiten" auf der Detailseite
Behoben:
- Das Formular stuerzte beim ersten Rechnen ab. Die Vorgabewerte lagen in einem
"use client"-Modul und wurden von einer Server-Komponente importiert; dort
kommt nur eine Client-Referenz an, kein Objekt, und das Spreaden ergibt lauter
undefined. Die Werte liegen jetzt in geraet-formular-werte.ts ohne
"use client".
- Das Sternchen an Pflichtfeldern wurde von Sprachausgaben mitgelesen
("Bezeichnung Stern"). Es traegt jetzt aria-hidden; dass ein Feld ausgefuellt
werden muss, sagt bereits das required-Attribut.
- Fehlermeldungen in Formularen sind eindeutig ansteuerbar. Next.js haengt
einen eigenen Routen-Ansager mit der Rolle "alert" in jede Seite.
Tests:
- 7 neue Playwright-Tests zum Formular, darunter die Lagerungsregel und die
Fristenvorschau
- Zwei davon laufen nicht unter Touch-Emulation: Chromium nimmt dort keine
zeichenweise Eingabe in Datumsfelder an. Begruendet uebersprungen, die
Rechnung selbst deckt qr-und-fristen.test.ts ab.
- Insgesamt 104 Unit-Tests und 56 E2E-Tests gruen
Anleitung, Changelog, Devlog, Aufwandsschaetzung und Roadmap fortgeschrieben.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
47b8e36a38
commit
1744403620
@@ -0,0 +1,55 @@
|
||||
import Link from "next/link";
|
||||
import { redirect } from "next/navigation";
|
||||
import { ArrowLeft } from "lucide-react";
|
||||
import { aktuelleSitzung } from "@/lib/auth";
|
||||
import { hatRecht } from "@/lib/authz";
|
||||
import { fuerOrganisation } from "@/lib/db";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { GeraetFormular } from "@/components/stammdaten/geraet-formular";
|
||||
import { LEERES_GERAET } from "@/components/stammdaten/geraet-formular-werte";
|
||||
|
||||
export const metadata = { title: "Neues Gerät" };
|
||||
|
||||
/**
|
||||
* Ein einzelnes Gerät anlegen.
|
||||
*
|
||||
* Der übliche Weg für einen Bestand ist der Import; dieses Formular ist für
|
||||
* den Neuzugang zwischendurch — die eine Motorsäge, die nachbeschafft wurde.
|
||||
*/
|
||||
export default async function NeuesGeraetSeite() {
|
||||
const sitzung = await aktuelleSitzung();
|
||||
if (!sitzung) redirect("/anmelden");
|
||||
if (!hatRecht(sitzung, "geraet.bearbeiten")) redirect("/geraete");
|
||||
|
||||
// Gibt es nur einen Standort, wird er vorbelegt — das ist bei den meisten
|
||||
// Wehren der Fall, und ein Pflichtfeld weniger ist ein Klick weniger.
|
||||
const standorte = await fuerOrganisation(sitzung.organisationId, (db) =>
|
||||
db.standort.findMany({
|
||||
where: { geloeschtAm: null, aktiv: true },
|
||||
select: { id: true },
|
||||
take: 2,
|
||||
}),
|
||||
);
|
||||
|
||||
const vorgabe = {
|
||||
...LEERES_GERAET,
|
||||
standortId: standorte.length === 1 ? (standorte[0]?.id ?? null) : null,
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="mx-auto max-w-4xl space-y-4">
|
||||
<Button variant="ghost" size="sm" asChild className="-ml-2">
|
||||
<Link href="/geraete">
|
||||
<ArrowLeft aria-hidden />
|
||||
Zurück zur Liste
|
||||
</Link>
|
||||
</Button>
|
||||
|
||||
<GeraetFormular
|
||||
vorgabe={vorgabe}
|
||||
titel="Neues Gerät"
|
||||
beschreibung="Für einzelne Neuzugänge. Größere Bestände gehen schneller über den Import."
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user