feat(bausteine): Abschnitte, die mehrere Vorlagen teilen (#57)
This commit was merged in pull request #57.
This commit is contained in:
@@ -13,7 +13,9 @@ import { Vorschau } from "@/components/vorlagen/vorschau";
|
||||
import {
|
||||
alsEditorAufbau,
|
||||
alsStruktur,
|
||||
bausteineAnreichern,
|
||||
neuerAbschnitt,
|
||||
neuerBausteinAbschnitt,
|
||||
neuerSchritt,
|
||||
neueVariable,
|
||||
umsortieren,
|
||||
@@ -67,20 +69,33 @@ type SpeicherZustand = {
|
||||
readonly gespeichertesJson: string;
|
||||
};
|
||||
|
||||
export type EinsetzbarerBaustein = {
|
||||
readonly bausteinVersionId: string;
|
||||
readonly name: string;
|
||||
readonly titel: string;
|
||||
readonly version: number;
|
||||
readonly anzahlSchritte: number;
|
||||
};
|
||||
|
||||
export function Editor({
|
||||
version,
|
||||
lesend,
|
||||
darfBearbeiten,
|
||||
beispielDatum,
|
||||
bausteine = [],
|
||||
}: {
|
||||
version: EditorVersion;
|
||||
lesend: boolean;
|
||||
darfBearbeiten: boolean;
|
||||
/** Heutiges Datum, auf dem Server formatiert — siehe `beispielwerte`. */
|
||||
beispielDatum: string;
|
||||
/** Veröffentlichte Bausteine, die sich einsetzen lassen (#030). */
|
||||
bausteine?: readonly EinsetzbarerBaustein[];
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [aufbau, setzeAufbau] = useState<EditorAufbau>(() => alsEditorAufbau(version.struktur));
|
||||
const [aufbau, setzeAufbau] = useState<EditorAufbau>(() =>
|
||||
bausteineAnreichern(alsEditorAufbau(version.struktur), bausteine),
|
||||
);
|
||||
const aktuellesJson = useMemo(() => JSON.stringify(alsStruktur(aufbau)), [aufbau]);
|
||||
|
||||
/**
|
||||
@@ -92,8 +107,8 @@ export function Editor({
|
||||
* Speichern in die Datenbank.
|
||||
*/
|
||||
const anfangsJson = useMemo(
|
||||
() => JSON.stringify(alsStruktur(alsEditorAufbau(version.struktur))),
|
||||
[version.struktur],
|
||||
() => JSON.stringify(alsStruktur(bausteineAnreichern(alsEditorAufbau(version.struktur), bausteine))),
|
||||
[version.struktur, bausteine],
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -359,17 +374,52 @@ export function Editor({
|
||||
</SortierBereich>
|
||||
)}
|
||||
{lesend ? null : (
|
||||
<TextKnopf
|
||||
beschriftung={
|
||||
abschnitteVoll ? `Höchstens ${GRENZEN.abschnitte} Abschnitte` : "Abschnitt hinzufügen"
|
||||
}
|
||||
aus={abschnitteVoll}
|
||||
aufKlick={() => {
|
||||
const abschnitt = neuerAbschnitt();
|
||||
setzeZuletztAngelegt(abschnitt.kennung);
|
||||
abschnitteSetzen([...aufbau.abschnitte, abschnitt]);
|
||||
}}
|
||||
/>
|
||||
<div className="flex flex-wrap items-center gap-3">
|
||||
<TextKnopf
|
||||
beschriftung={
|
||||
abschnitteVoll ? `Höchstens ${GRENZEN.abschnitte} Abschnitte` : "Abschnitt hinzufügen"
|
||||
}
|
||||
aus={abschnitteVoll}
|
||||
aufKlick={() => {
|
||||
const abschnitt = neuerAbschnitt();
|
||||
setzeZuletztAngelegt(abschnitt.kennung);
|
||||
abschnitteSetzen([...aufbau.abschnitte, abschnitt]);
|
||||
}}
|
||||
/>
|
||||
{/*
|
||||
Bausteine nur anbieten, wenn es welche gibt. Ein leeres
|
||||
Auswahlfeld mit „keine Bausteine“ wäre eine Frage ohne Antwort
|
||||
(#030).
|
||||
*/}
|
||||
{bausteine.length > 0 ? (
|
||||
<label className="flex min-w-0 items-center gap-2 text-sm">
|
||||
<span className="shrink-0 text-nebentext">Baustein einsetzen</span>
|
||||
<select
|
||||
aria-label="Baustein einsetzen"
|
||||
value=""
|
||||
disabled={abschnitteVoll}
|
||||
onChange={(ereignis) => {
|
||||
const gewaehlt = bausteine.find(
|
||||
(eintrag) => eintrag.bausteinVersionId === ereignis.target.value,
|
||||
);
|
||||
if (!gewaehlt) return;
|
||||
const abschnitt = neuerBausteinAbschnitt(gewaehlt);
|
||||
setzeZuletztAngelegt(abschnitt.kennung);
|
||||
abschnitteSetzen([...aufbau.abschnitte, abschnitt]);
|
||||
}}
|
||||
className="min-h-11 min-w-0 rounded-pille border border-linie bg-flaeche-hoch px-4 text-sm md:min-h-10"
|
||||
>
|
||||
<option value="">auswählen …</option>
|
||||
{bausteine.map((eintrag) => (
|
||||
<option key={eintrag.bausteinVersionId} value={eintrag.bausteinVersionId}>
|
||||
{eintrag.name} (Fassung {eintrag.version}, {eintrag.anzahlSchritte}{" "}
|
||||
{eintrag.anzahlSchritte === 1 ? "Schritt" : "Schritte"})
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
) : null}
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user