// Erstell-Dialoge für den Layouts-Baum (DOSSIER A3): „Neues Layout" und „Neues // Masterlayout". Beide liefern beim Bestätigen die Startwerte (Papier/Custom- // Grösse/Ausrichtung bzw. Master-Vorlage) nach oben; das Panel legt das Element // an und versetzt es direkt in den Inline-Rename-Modus. // // Muster wie ExportSaveDialog: `imp-*`-Overlay/Dialog, Klick auf Hintergrund + // Esc schliessen, Enter bestätigt. KEIN window.prompt/confirm (im Tauri-WKWebView // deaktiviert). Bezeichner englisch, UI-Text deutsch via t() (CONVENTIONS.md). import { useEffect, useState } from "react"; import { t } from "../i18n"; import type { LayoutOrientation, LayoutPaperFormat, MasterLayout, } from "../model/types"; import { PAPER_FORMAT_GROUPS } from "../panels/layoutModel"; /** Startwerte eines neuen Blatts/Masters (Grösse). */ export interface LayoutSizeStart { paper: LayoutPaperFormat; orientation: LayoutOrientation; customWidthMm?: number; customHeightMm?: number; } /** Startwerte eines neuen Layouts: entweder Master-Vorlage ODER freie Grösse. */ export interface NewLayoutStart extends LayoutSizeStart { /** Gebundenes Masterlayout (erbt dessen Papier/Ausrichtung); sonst undefined. */ masterId?: string; } type SizeMode = LayoutPaperFormat | "custom"; /** Baut die Grösse-Startwerte aus dem Grössen-Auswahlzustand. */ function sizeStart( mode: SizeMode, orientation: LayoutOrientation, wMm: number, hMm: number, ): LayoutSizeStart { if (mode === "custom") { return { paper: "a4", orientation, customWidthMm: Math.max(1, Math.round(wMm)), customHeightMm: Math.max(1, Math.round(hMm)), }; } return { paper: mode, orientation }; } /** Geteilte Grössen-Auswahl: Format (A4/A3) als Segment ODER freie mm-Felder + Ausrichtung. */ function SizePicker({ mode, setMode, orientation, setOrientation, wMm, setWMm, hMm, setHMm, }: { mode: SizeMode; setMode: (m: SizeMode) => void; orientation: LayoutOrientation; setOrientation: (o: LayoutOrientation) => void; wMm: number; setWMm: (v: number) => void; hMm: number; setHMm: (v: number) => void; }) { return ( <>
{t("layouts.size.format")}
{mode === "custom" ? (
×
) : (
{t("layouts.orientation")}
{(["portrait", "landscape"] as const).map((o) => ( ))}
)} ); } /** Overlay-Rahmen (geteilt von beiden Dialogen). */ function DialogFrame({ title, onClose, onConfirm, children, }: { title: string; onClose: () => void; onConfirm: () => void; children: React.ReactNode; }) { useEffect(() => { const onKey = (e: KeyboardEvent) => { if (e.key === "Escape") onClose(); else if (e.key === "Enter") onConfirm(); }; window.addEventListener("keydown", onKey); return () => window.removeEventListener("keydown", onKey); }, [onClose, onConfirm]); return (
e.stopPropagation()} >
{title}
{children}
); } /** Dialog „Neues Masterlayout" — Format/freie Grösse + Ausrichtung. */ export function NewMasterLayoutDialog({ onCreate, onClose, }: { onCreate: (start: LayoutSizeStart) => void; onClose: () => void; }) { const [mode, setMode] = useState("a4"); const [orientation, setOrientation] = useState("portrait"); const [wMm, setWMm] = useState(210); const [hMm, setHMm] = useState(297); const confirm = () => onCreate(sizeStart(mode, orientation, wMm, hMm)); return ( ); } /** * Dialog „Neues Layout" — Masterlayout als Vorlage (erbt dessen Grösse) ODER * freie Grösse (Format/Custom + Ausrichtung). */ export function NewLayoutDialog({ masters, onCreate, onClose, }: { masters: MasterLayout[]; onCreate: (start: NewLayoutStart) => void; onClose: () => void; }) { const hasMasters = masters.length > 0; const [source, setSource] = useState<"master" | "free">( hasMasters ? "master" : "free", ); const [masterId, setMasterId] = useState(masters[0]?.id ?? ""); const [mode, setMode] = useState("a4"); const [orientation, setOrientation] = useState("portrait"); const [wMm, setWMm] = useState(210); const [hMm, setHMm] = useState(297); const confirm = () => { if (source === "master" && masterId) { // Grösse erbt der Aufrufer vom Master; wir liefern nur die Bindung + eine // sinnvolle Rückfall-Grösse (A4 hoch), falls der Master unauflösbar ist. onCreate({ masterId, paper: "a4", orientation: "portrait" }); return; } onCreate(sizeStart(mode, orientation, wMm, hMm)); }; return (
{t("layouts.newLayout.source")}
{source === "master" ? (
{hasMasters ? ( ) : (
{t("layouts.newLayout.noMasters")}
)}
) : ( )}
); }