Fix n.n.: „+ Neu“ öffnet das Formular zur Neuanlage als modalen Dialog

Elf Listenansichten (Klassen, Buchungsvorlagen, Regelmäßige Buchungen,
Erinnerungen, Verträge, Adressen, Sparziele, Kredite, Abgleichregeln,
Budgets, Berichtsgruppen) zeigten das Formular unter der Liste. Jetzt
öffnet der Knopf „+ Neu“ es als Dialog.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
fds2610-bot 2026-10-01 09:50:08 +02:00
parent e0bfa33982
commit 932d17c128
19 changed files with 505 additions and 345 deletions

View file

@ -1,5 +1,10 @@
# Änderungen # Änderungen
## „+ Neu“ öffnet das Formular als Dialog (01.10.2026)
- Das Formular zur Neuanlage stand in elf Ansichten unter der Liste. Jetzt öffnet der Knopf „+ Neu“ es als modalen Dialog (`app.js`, `.neudialog`); nach dem Speichern erscheint die Liste wieder, mit dem neuen Eintrag. Betroffen: Klassen, Buchungsvorlagen, Regelmäßige Buchungen, Erinnerungen, Verträge, Adressen, Sparziele, Kredite, Abgleichregeln, Budgets, Berichtsgruppen.
- E2E: `neudialog.spec.js`; bestehende Specs öffnen den Dialog zuerst.
## Regelmäßige Buchungen: Klick zum Bearbeiten (01.10.2026) ## Regelmäßige Buchungen: Klick zum Bearbeiten (01.10.2026)
- In „Alle Reihen“ erscheinen alle Felder zunächst als Text und werden erst beim Anklicken zum Eingabefeld (`reihenliste.js`). Ja/Nein-Felder schalten per Klick um, „Speichern“ erscheint erst nach einer Änderung. Konto und Klasse stehen untereinander, die Spalte Name/Buchungstext nimmt den freien Platz. - In „Alle Reihen“ erscheinen alle Felder zunächst als Text und werden erst beim Anklicken zum Eingabefeld (`reihenliste.js`). Ja/Nein-Felder schalten per Klick um, „Speichern“ erscheint erst nach einer Änderung. Konto und Klasse stehen untereinander, die Spalte Name/Buchungstext nimmt den freien Platz.

View file

@ -1289,6 +1289,19 @@ table.splittabelle input.rechts { text-align: right; }
„Speichern“ und „Abbrechen“, damit es nicht im Vorbeigehen getroffen wird. */ „Speichern“ und „Abbrechen“, damit es nicht im Vorbeigehen getroffen wird. */
.splitdialog .knopfleiste .knopf.gefahr { margin-left: auto; } .splitdialog .knopfleiste .knopf.gefahr { margin-left: auto; }
/* „+ Neu“ in den Listenansichten: Das Formular zur Neuanlage liegt in einem
modalen Dialog, den der Knopf öffnet. Der Dialog trägt den Rahmen, das
Formular darin braucht ihn nicht noch einmal. */
.neudialog { max-height: 92vh; overflow-y: auto; }
.neudialog .formular.breit {
max-width: none;
padding: 0;
border: 0;
box-shadow: none;
background: none;
}
/* Die Formatwahl vor Import und Export – als Dialog auf der Verwaltungsseite /* Die Formatwahl vor Import und Export – als Dialog auf der Verwaltungsseite
und als Kachelinhalt auf der Ausweichseite, deshalb zwei Ebenen: der Dialog und als Kachelinhalt auf der Ausweichseite, deshalb zwei Ebenen: der Dialog
trägt den Rahmen, .formatwahl die Karten. */ trägt den Rahmen, .formatwahl die Karten. */

View file

@ -314,6 +314,20 @@
}); });
}); });
// „+ Neu“ in den Listenansichten: Der Knopf öffnet den Dialog mit dem
// Formular zur Neuanlage. Gespeichert wird per Formularversand; die Ansicht
// lädt danach neu und zeigt die Liste samt neuem Eintrag.
document.querySelectorAll('[data-neudialog]').forEach(function (knopf) {
knopf.addEventListener('click', function () {
const dialog = document.getElementById(knopf.dataset.neudialog);
if (dialog && typeof dialog.showModal === 'function') {
dialog.showModal();
const feld = dialog.querySelector('input:not([type=hidden]), select, textarea');
if (feld) { feld.focus(); }
}
});
});
// Übermittlungsprotokoll im Zahlungsverkehr: Ein Klick auf den Status holt das // Übermittlungsprotokoll im Zahlungsverkehr: Ein Klick auf den Status holt das
// Protokoll der Überweisung in einen modalen Dialog. Ohne <dialog> oder // Protokoll der Überweisung in einen modalen Dialog. Ohne <dialog> oder
// fetch bleibt der Status ein Link auf dieselbe Ansicht als eigene Seite. // fetch bleibt der Status ein Link auf dieselbe Ansicht als eigene Seite.

View file

@ -19,6 +19,7 @@ include __DIR__ . '/../layout/kopf.php';
</div> </div>
<div class="seitenaktionen"> <div class="seitenaktionen">
<button type="button" class="knopf primaer" id="neu-knopf" data-neudialog="neudialog">+ Neu</button>
<a href="/auswertungen" class="knopf">Zur Übersicht</a> <a href="/auswertungen" class="knopf">Zur Übersicht</a>
</div> </div>
@ -28,7 +29,7 @@ include __DIR__ . '/../layout/kopf.php';
und rücken unter „Nicht gruppiert“. und rücken unter „Nicht gruppiert“.
</p> </p>
<div class="kachel einzeln"> <dialog id="neudialog" class="splitdialog neudialog">
<h2>Neue Berichtsgruppe</h2> <h2>Neue Berichtsgruppe</h2>
<form method="post" action="/auswertungen/gruppen/neu" class="zeilenform"> <form method="post" action="/auswertungen/gruppen/neu" class="zeilenform">
<input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>"> <input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>">
@ -39,8 +40,9 @@ include __DIR__ . '/../layout/kopf.php';
<input type="number" name="sortierung" value="0" class="schmal"> <input type="number" name="sortierung" value="0" class="schmal">
</label> </label>
<button type="submit" class="knopf primaer">Anlegen</button> <button type="submit" class="knopf primaer">Anlegen</button>
<button type="submit" class="knopf" formmethod="dialog" formnovalidate>Abbrechen</button>
</form> </form>
</div> </dialog>
<?php <?php
$echte = array_filter($gruppen, static fn(array $eintrag): bool => $eintrag['gruppe'] !== null); $echte = array_filter($gruppen, static fn(array $eintrag): bool => $eintrag['gruppe'] !== null);

View file

@ -27,6 +27,7 @@ include __DIR__ . '/../layout/kopf.php';
</p> </p>
<div class="seitenaktionen"> <div class="seitenaktionen">
<button type="button" class="knopf primaer" id="neu-knopf" data-neudialog="neudialog">+ Neu</button>
<form method="post" action="/banking/regeln/pruefen" class="inline"> <form method="post" action="/banking/regeln/pruefen" class="inline">
<input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>"> <input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>">
<button type="submit" class="knopf" <button type="submit" class="knopf"
@ -147,16 +148,19 @@ include __DIR__ . '/../layout/kopf.php';
</table> </table>
<?php endif; ?> <?php endif; ?>
<form method="post" action="/banking/regeln/neu" class="formular breit"> <dialog id="neudialog" class="splitdialog neudialog">
<input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>"> <form method="post" action="/banking/regeln/neu" class="formular breit">
<h3>Neue Regel</h3> <input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>">
<h2>Neue Regel</h2>
<?php $regel = ['aktiv' => 1]; $idPrefix = 'neu_'; ?> <?php $regel = ['aktiv' => 1]; $idPrefix = 'neu_'; ?>
<?php include __DIR__ . '/regelfelder.php'; ?> <?php include __DIR__ . '/regelfelder.php'; ?>
<div class="knopfleiste"> <div class="knopfleiste">
<button type="submit" class="knopf primaer">Regel anlegen</button> <button type="submit" class="knopf primaer">Regel anlegen</button>
</div> <button type="submit" class="knopf" formmethod="dialog" formnovalidate>Abbrechen</button>
</form> </div>
</form>
</dialog>
<?php include __DIR__ . '/../layout/fuss.php'; ?> <?php include __DIR__ . '/../layout/fuss.php'; ?>

View file

@ -11,6 +11,7 @@ include __DIR__ . '/../layout/kopf.php';
<div class="seitenaktionen"> <div class="seitenaktionen">
<a href="/planung/budget" class="knopf primaer">Budgetplaner öffnen</a> <a href="/planung/budget" class="knopf primaer">Budgetplaner öffnen</a>
<button type="button" class="knopf primaer" id="neu-knopf" data-neudialog="neudialog">+ Neu</button>
<a href="/planung" class="knopf">Zurück zur Planung</a> <a href="/planung" class="knopf">Zurück zur Planung</a>
</div> </div>
@ -66,27 +67,28 @@ include __DIR__ . '/../layout/kopf.php';
</table> </table>
<?php endif; ?> <?php endif; ?>
<dialog id="neudialog" class="splitdialog neudialog">
<h2>Neues Budget</h2>
<form method="post" action="/planung/budget/neu" class="formular">
<input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>">
<label for="name">Name</label>
<input type="text" id="name" name="name" required>
<label for="jahr">Jahr</label>
<input type="number" id="jahr" name="jahr" value="<?= $jahr + 1 ?>" step="1" required>
<label for="beschreibung">Beschreibung <span class="optional">(optional)</span></label>
<input type="text" id="beschreibung" name="beschreibung">
<div class="knopfleiste">
<button type="submit" class="knopf primaer">Budget anlegen</button>
<button type="submit" class="knopf" formmethod="dialog" formnovalidate>Abbrechen</button>
</div>
</form>
</dialog>
<div class="kachelraster"> <div class="kachelraster">
<div class="kachel">
<header><h2>Neues Budget</h2></header>
<form method="post" action="/planung/budget/neu" class="formular">
<input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>">
<label for="name">Name</label>
<input type="text" id="name" name="name" required>
<label for="jahr">Jahr</label>
<input type="number" id="jahr" name="jahr" value="<?= $jahr + 1 ?>" step="1" required>
<label for="beschreibung">Beschreibung <span class="optional">(optional)</span></label>
<input type="text" id="beschreibung" name="beschreibung">
<div class="knopfleiste">
<button type="submit" class="knopf primaer">Budget anlegen</button>
</div>
</form>
</div>
<?php if ($budgets !== []): ?> <?php if ($budgets !== []): ?>
<div class="kachel"> <div class="kachel">
<header><h2>Budget kopieren</h2></header> <header><h2>Budget kopieren</h2></header>

View file

@ -22,6 +22,10 @@ include __DIR__ . '/../layout/kopf.php';
kündigen“, „Steuerbescheid prüfen“. Offene Erinnerungen erscheinen im Finanzkalender. kündigen“, „Steuerbescheid prüfen“. Offene Erinnerungen erscheinen im Finanzkalender.
</p> </p>
<div class="seitenaktionen">
<button type="button" class="knopf primaer" id="neu-knopf" data-neudialog="neudialog">+ Neu</button>
</div>
<?php if ($erinnerungen === []): ?> <?php if ($erinnerungen === []): ?>
<p class="platzhalter">Keine Erinnerungen.</p> <p class="platzhalter">Keine Erinnerungen.</p>
<?php else: ?> <?php else: ?>
@ -65,22 +69,25 @@ include __DIR__ . '/../layout/kopf.php';
</table> </table>
<?php endif; ?> <?php endif; ?>
<form method="post" action="/termine/erinnerungen/neu" class="formular breit"> <dialog id="neudialog" class="splitdialog neudialog">
<input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>"> <form method="post" action="/termine/erinnerungen/neu" class="formular breit">
<h3>Neue Erinnerung</h3> <input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>">
<h2>Neue Erinnerung</h2>
<label for="text">Erinnerung</label> <label for="text">Erinnerung</label>
<input type="text" id="text" name="text" required> <input type="text" id="text" name="text" required>
<label for="faellig_am">Fällig am</label> <label for="faellig_am">Fällig am</label>
<input type="date" id="faellig_am" name="faellig_am" value="<?= View::h(date('Y-m-d')) ?>" required> <input type="date" id="faellig_am" name="faellig_am" value="<?= View::h(date('Y-m-d')) ?>" required>
<label for="notiz">Notiz <span class="optional">(optional)</span></label> <label for="notiz">Notiz <span class="optional">(optional)</span></label>
<input type="text" id="notiz" name="notiz"> <input type="text" id="notiz" name="notiz">
<div class="knopfleiste"> <div class="knopfleiste">
<button type="submit" class="knopf primaer">Erinnerung anlegen</button> <button type="submit" class="knopf primaer">Erinnerung anlegen</button>
</div> <button type="submit" class="knopf" formmethod="dialog" formnovalidate>Abbrechen</button>
</form> </div>
</form>
</dialog>
<?php include __DIR__ . '/../layout/fuss.php'; ?> <?php include __DIR__ . '/../layout/fuss.php'; ?>

View file

@ -23,6 +23,10 @@ include __DIR__ . '/../layout/kopf.php';
<a href="/termine/erinnerungen" class="tab">Erinnerungen</a> <a href="/termine/erinnerungen" class="tab">Erinnerungen</a>
</div> </div>
<div class="seitenaktionen">
<button type="button" class="knopf primaer" id="neu-knopf" data-neudialog="neudialog">+ Neu</button>
</div>
<?php if ($vorschau['faellig'] > 0): ?> <?php if ($vorschau['faellig'] > 0): ?>
<div class="seitenaktionen"> <div class="seitenaktionen">
<span class="hinweis"> <span class="hinweis">
@ -217,78 +221,81 @@ include __DIR__ . '/../layout/kopf.php';
</table> </table>
<?php endif; ?> <?php endif; ?>
<form method="post" action="/termine/neu" class="formular breit"> <dialog id="neudialog" class="splitdialog neudialog">
<input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>"> <form method="post" action="/termine/neu" class="formular breit">
<h3>Neue regelmäßige Buchung</h3> <input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>">
<h2>Neue regelmäßige Buchung</h2>
<label for="name">Name</label> <label for="name">Name</label>
<input type="text" id="name" name="name" required placeholder="z. B. Miete"> <input type="text" id="name" name="name" required placeholder="z. B. Miete">
<label for="neu_konto">Konto</label> <label for="neu_konto">Konto</label>
<select id="neu_konto" name="konto_id" required> <select id="neu_konto" name="konto_id" required>
<?php foreach ($konten as $konto): ?> <?php foreach ($konten as $konto): ?>
<option value="<?= (int)$konto['id'] ?>"><?= View::h($konto['name']) ?></option> <option value="<?= (int)$konto['id'] ?>"><?= View::h($konto['name']) ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
<label for="neu_betrag">Betrag</label> <label for="neu_betrag">Betrag</label>
<input type="text" id="neu_betrag" name="betrag" inputmode="decimal" required <input type="text" id="neu_betrag" name="betrag" inputmode="decimal" required
placeholder="Ausgaben mit Minus, z. B. -850,00"> placeholder="Ausgaben mit Minus, z. B. -850,00">
<label for="neu_empfaenger">Empfänger</label> <label for="neu_empfaenger">Empfänger</label>
<input type="text" id="neu_empfaenger" name="empfaenger"> <input type="text" id="neu_empfaenger" name="empfaenger">
<label for="neu_buchungstext">Buchungstext</label> <label for="neu_buchungstext">Buchungstext</label>
<input type="text" id="neu_buchungstext" name="buchungstext"> <input type="text" id="neu_buchungstext" name="buchungstext">
<label for="neu_kategorie">Kategorie</label> <label for="neu_kategorie">Kategorie</label>
<select id="neu_kategorie" name="kategorie_id"> <select id="neu_kategorie" name="kategorie_id">
<option value="">– keine –</option> <option value="">– keine –</option>
<?php foreach ($kategorien as $kategorie): ?> <?php foreach ($kategorien as $kategorie): ?>
<option value="<?= (int)$kategorie['id'] ?>"><?= View::h($kategorie['pfad']) ?></option> <option value="<?= (int)$kategorie['id'] ?>"><?= View::h($kategorie['pfad']) ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
<label for="neu_klasse">Klasse</label> <label for="neu_klasse">Klasse</label>
<select id="neu_klasse" name="klasse_id"> <select id="neu_klasse" name="klasse_id">
<option value="">– keine –</option> <option value="">– keine –</option>
<?php foreach ($klassen as $klasse): ?> <?php foreach ($klassen as $klasse): ?>
<option value="<?= (int)$klasse['id'] ?>"><?= View::h($klasse['name']) ?></option> <option value="<?= (int)$klasse['id'] ?>"><?= View::h($klasse['name']) ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
<label for="neu_intervall">Rhythmus</label> <label for="neu_intervall">Rhythmus</label>
<select id="neu_intervall" name="intervall"> <select id="neu_intervall" name="intervall">
<?php foreach ($intervalle as $schluessel => $name): ?> <?php foreach ($intervalle as $schluessel => $name): ?>
<option value="<?= View::h($schluessel) ?>" <?= $schluessel === 'monatlich' ? 'selected' : '' ?>> <option value="<?= View::h($schluessel) ?>" <?= $schluessel === 'monatlich' ? 'selected' : '' ?>>
<?= View::h($name) ?> <?= View::h($name) ?>
</option> </option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
<label for="neu_beginn">Erster Termin</label> <label for="neu_beginn">Erster Termin</label>
<input type="date" id="neu_beginn" name="beginn" value="<?= View::h(date('Y-m-d')) ?>" required> <input type="date" id="neu_beginn" name="beginn" value="<?= View::h(date('Y-m-d')) ?>" required>
<label for="neu_ende">Letzter Termin <span class="optional">(optional)</span></label> <label for="neu_ende">Letzter Termin <span class="optional">(optional)</span></label>
<input type="date" id="neu_ende" name="ende"> <input type="date" id="neu_ende" name="ende">
<label class="ankreuzfeld"> <label class="ankreuzfeld">
<input type="checkbox" name="automatisch" value="1"> <input type="checkbox" name="automatisch" value="1">
automatisch buchen automatisch buchen
</label> </label>
<p class="feldhinweis"> <p class="feldhinweis">
Ohne Haken meldet sich die Reihe nur und wartet auf Bestätigung – richtig überall Ohne Haken meldet sich die Reihe nur und wartet auf Bestätigung – richtig überall
dort, wo der Betrag schwankt. dort, wo der Betrag schwankt.
</p> </p>
<label class="ankreuzfeld"> <label class="ankreuzfeld">
<input type="checkbox" name="aktiv" value="1" checked> aktiv <input type="checkbox" name="aktiv" value="1" checked> aktiv
</label> </label>
<div class="knopfleiste"> <div class="knopfleiste">
<button type="submit" class="knopf primaer">Reihe anlegen</button> <button type="submit" class="knopf primaer">Reihe anlegen</button>
</div> <button type="submit" class="knopf" formmethod="dialog" formnovalidate>Abbrechen</button>
</form> </div>
</form>
</dialog>
<?php include __DIR__ . '/../layout/fuss.php'; ?> <?php include __DIR__ . '/../layout/fuss.php'; ?>

View file

@ -25,6 +25,10 @@ include __DIR__ . '/../layout/kopf.php';
hinausgeht. hinausgeht.
</p> </p>
<div class="seitenaktionen">
<button type="button" class="knopf primaer" id="neu-knopf" data-neudialog="neudialog">+ Neu</button>
</div>
<form method="get" action="/vertraege/adressen" class="filterleiste"> <form method="get" action="/vertraege/adressen" class="filterleiste">
<label for="suche">Suchen</label> <label for="suche">Suchen</label>
<input type="search" id="suche" name="suche" value="<?= View::h($suche) ?>" <input type="search" id="suche" name="suche" value="<?= View::h($suche) ?>"
@ -126,57 +130,60 @@ include __DIR__ . '/../layout/kopf.php';
</table> </table>
<?php endif; ?> <?php endif; ?>
<form method="post" action="/vertraege/adressen/neu" class="formular breit"> <dialog id="neudialog" class="splitdialog neudialog">
<input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>"> <form method="post" action="/vertraege/adressen/neu" class="formular breit">
<h3>Neue Adresse</h3> <input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>">
<h2>Neue Adresse</h2>
<label for="name">Name</label> <label for="name">Name</label>
<input type="text" id="name" name="name" required> <input type="text" id="name" name="name" required>
<label for="zusatz">Zusatz <span class="optional">(optional)</span></label> <label for="zusatz">Zusatz <span class="optional">(optional)</span></label>
<input type="text" id="zusatz" name="zusatz"> <input type="text" id="zusatz" name="zusatz">
<label for="strasse">Straße</label> <label for="strasse">Straße</label>
<input type="text" id="strasse" name="strasse"> <input type="text" id="strasse" name="strasse">
<div class="feldpaar"> <div class="feldpaar">
<div> <div>
<label for="plz">PLZ</label> <label for="plz">PLZ</label>
<input type="text" id="plz" name="plz"> <input type="text" id="plz" name="plz">
</div>
<div>
<label for="ort">Ort</label>
<input type="text" id="ort" name="ort">
</div>
<div>
<label for="land">Land</label>
<input type="text" id="land" name="land">
</div>
</div> </div>
<div>
<label for="ort">Ort</label> <label for="iban">IBAN</label>
<input type="text" id="ort" name="ort"> <input type="text" id="iban" name="iban" placeholder="DE00 0000 0000 0000 0000 00">
<label for="bic">BIC</label>
<input type="text" id="bic" name="bic">
<div class="feldpaar">
<div>
<label for="email">E-Mail</label>
<input type="text" id="email" name="email">
</div>
<div>
<label for="telefon">Telefon</label>
<input type="text" id="telefon" name="telefon">
</div>
</div> </div>
<div>
<label for="land">Land</label> <label for="notiz">Notiz</label>
<input type="text" id="land" name="land"> <input type="text" id="notiz" name="notiz">
<div class="knopfleiste">
<button type="submit" class="knopf primaer">Adresse anlegen</button>
<button type="submit" class="knopf" formmethod="dialog" formnovalidate>Abbrechen</button>
</div> </div>
</div> </form>
</dialog>
<label for="iban">IBAN</label>
<input type="text" id="iban" name="iban" placeholder="DE00 0000 0000 0000 0000 00">
<label for="bic">BIC</label>
<input type="text" id="bic" name="bic">
<div class="feldpaar">
<div>
<label for="email">E-Mail</label>
<input type="text" id="email" name="email">
</div>
<div>
<label for="telefon">Telefon</label>
<input type="text" id="telefon" name="telefon">
</div>
</div>
<label for="notiz">Notiz</label>
<input type="text" id="notiz" name="notiz">
<div class="knopfleiste">
<button type="submit" class="knopf primaer">Adresse anlegen</button>
</div>
</form>
<?php include __DIR__ . '/../layout/fuss.php'; ?> <?php include __DIR__ . '/../layout/fuss.php'; ?>

View file

@ -23,6 +23,10 @@ include __DIR__ . '/../layout/kopf.php';
<a href="/vertraege/kredite" class="tab">Kredite</a> <a href="/vertraege/kredite" class="tab">Kredite</a>
</div> </div>
<div class="seitenaktionen">
<button type="button" class="knopf primaer" id="neu-knopf" data-neudialog="neudialog">+ Neu</button>
</div>
<?php if ($fristen !== []): ?> <?php if ($fristen !== []): ?>
<div class="kachel einzeln"> <div class="kachel einzeln">
<header><h2>Kündigungsfristen laufen ab</h2></header> <header><h2>Kündigungsfristen laufen ab</h2></header>
@ -131,80 +135,83 @@ include __DIR__ . '/../layout/kopf.php';
</table> </table>
<?php endif; ?> <?php endif; ?>
<form method="post" action="/vertraege/neu" class="formular breit"> <dialog id="neudialog" class="splitdialog neudialog">
<input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>"> <form method="post" action="/vertraege/neu" class="formular breit">
<h3>Neuer Vertrag</h3> <input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>">
<h2>Neuer Vertrag</h2>
<label for="name">Bezeichnung</label> <label for="name">Bezeichnung</label>
<input type="text" id="name" name="name" required placeholder="z. B. Hausratversicherung"> <input type="text" id="name" name="name" required placeholder="z. B. Hausratversicherung">
<label for="partner">Vertragspartner</label> <label for="partner">Vertragspartner</label>
<input type="text" id="partner" name="partner"> <input type="text" id="partner" name="partner">
<label for="adresse_id">Adresse <span class="optional">(optional)</span></label> <label for="adresse_id">Adresse <span class="optional">(optional)</span></label>
<select id="adresse_id" name="adresse_id"> <select id="adresse_id" name="adresse_id">
<option value="">– keine –</option> <option value="">– keine –</option>
<?php foreach ($adressen as $adresse): ?> <?php foreach ($adressen as $adresse): ?>
<option value="<?= (int)$adresse['id'] ?>"><?= View::h($adresse['name']) ?></option> <option value="<?= (int)$adresse['id'] ?>"><?= View::h($adresse['name']) ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
<label for="vertragsnummer">Vertragsnummer</label> <label for="vertragsnummer">Vertragsnummer</label>
<input type="text" id="vertragsnummer" name="vertragsnummer"> <input type="text" id="vertragsnummer" name="vertragsnummer">
<label for="betrag">Betrag je Zahlung</label> <label for="betrag">Betrag je Zahlung</label>
<input type="text" id="betrag" name="betrag" inputmode="decimal" value="0,00"> <input type="text" id="betrag" name="betrag" inputmode="decimal" value="0,00">
<label for="intervall">Rhythmus</label> <label for="intervall">Rhythmus</label>
<select id="intervall" name="intervall"> <select id="intervall" name="intervall">
<?php foreach ($intervalle as $schluessel => $name): ?> <?php foreach ($intervalle as $schluessel => $name): ?>
<option value="<?= View::h($schluessel) ?>" <?= $schluessel === 'monatlich' ? 'selected' : '' ?>> <option value="<?= View::h($schluessel) ?>" <?= $schluessel === 'monatlich' ? 'selected' : '' ?>>
<?= View::h($name) ?> <?= View::h($name) ?>
</option> </option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
<label for="kategorie_id">Kategorie</label> <label for="kategorie_id">Kategorie</label>
<select id="kategorie_id" name="kategorie_id"> <select id="kategorie_id" name="kategorie_id">
<option value="">– keine –</option> <option value="">– keine –</option>
<?php foreach ($kategorien as $kategorie): ?> <?php foreach ($kategorien as $kategorie): ?>
<option value="<?= (int)$kategorie['id'] ?>"><?= View::h($kategorie['pfad']) ?></option> <option value="<?= (int)$kategorie['id'] ?>"><?= View::h($kategorie['pfad']) ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
<div class="feldpaar"> <div class="feldpaar">
<div> <div>
<label for="beginn">Beginn</label> <label for="beginn">Beginn</label>
<input type="date" id="beginn" name="beginn"> <input type="date" id="beginn" name="beginn">
</div>
<div>
<label for="ende">Ende</label>
<input type="date" id="ende" name="ende">
</div>
<div>
<label for="kuendigungsfrist_tage">Kündigungsfrist (Tage)</label>
<input type="number" id="kuendigungsfrist_tage" name="kuendigungsfrist_tage" value="0" min="0">
</div>
</div> </div>
<div>
<label for="ende">Ende</label> <label for="regelmaessige_id">Zahlung über <span class="optional">(optional)</span></label>
<input type="date" id="ende" name="ende"> <select id="regelmaessige_id" name="regelmaessige_id">
<option value="">– keine regelmäßige Buchung –</option>
<?php foreach ($reihen as $reihe): ?>
<option value="<?= (int)$reihe['id'] ?>"><?= View::h($reihe['name']) ?></option>
<?php endforeach; ?>
</select>
<label for="notiz">Notiz</label>
<input type="text" id="notiz" name="notiz">
<label class="ankreuzfeld">
<input type="checkbox" name="aktiv" value="1" checked> aktiv
</label>
<div class="knopfleiste">
<button type="submit" class="knopf primaer">Vertrag anlegen</button>
<button type="submit" class="knopf" formmethod="dialog" formnovalidate>Abbrechen</button>
</div> </div>
<div> </form>
<label for="kuendigungsfrist_tage">Kündigungsfrist (Tage)</label> </dialog>
<input type="number" id="kuendigungsfrist_tage" name="kuendigungsfrist_tage" value="0" min="0">
</div>
</div>
<label for="regelmaessige_id">Zahlung über <span class="optional">(optional)</span></label>
<select id="regelmaessige_id" name="regelmaessige_id">
<option value="">– keine regelmäßige Buchung –</option>
<?php foreach ($reihen as $reihe): ?>
<option value="<?= (int)$reihe['id'] ?>"><?= View::h($reihe['name']) ?></option>
<?php endforeach; ?>
</select>
<label for="notiz">Notiz</label>
<input type="text" id="notiz" name="notiz">
<label class="ankreuzfeld">
<input type="checkbox" name="aktiv" value="1" checked> aktiv
</label>
<div class="knopfleiste">
<button type="submit" class="knopf primaer">Vertrag anlegen</button>
</div>
</form>
<?php include __DIR__ . '/../layout/fuss.php'; ?> <?php include __DIR__ . '/../layout/fuss.php'; ?>

View file

@ -21,6 +21,10 @@ include __DIR__ . '/../layout/kopf.php';
<span class="tab aktiv">Kredite</span> <span class="tab aktiv">Kredite</span>
</div> </div>
<div class="seitenaktionen">
<button type="button" class="knopf primaer" id="neu-knopf" data-neudialog="neudialog">+ Neu</button>
</div>
<?php if ($kredite !== []): ?> <?php if ($kredite !== []): ?>
<table class="liste zahlen"> <table class="liste zahlen">
<thead> <thead>
@ -201,58 +205,61 @@ include __DIR__ . '/../layout/kopf.php';
</form> </form>
<?php endif; ?> <?php endif; ?>
<form method="post" action="/vertraege/kredite/neu" class="formular breit"> <dialog id="neudialog" class="splitdialog neudialog">
<input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>"> <form method="post" action="/vertraege/kredite/neu" class="formular breit">
<h3>Neuer Kredit</h3> <input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>">
<p class="feldhinweis"> <h2>Neuer Kredit</h2>
Gerechnet wird als Annuitätendarlehen: gleichbleibende Rate, sinkender Zinsanteil. <p class="feldhinweis">
Der Tilgungsplan entsteht aus diesen Angaben und wird nicht gespeichert. Gerechnet wird als Annuitätendarlehen: gleichbleibende Rate, sinkender Zinsanteil.
</p> Der Tilgungsplan entsteht aus diesen Angaben und wird nicht gespeichert.
</p>
<label for="name">Name</label> <label for="name">Name</label>
<input type="text" id="name" name="name" required placeholder="z. B. Baufinanzierung"> <input type="text" id="name" name="name" required placeholder="z. B. Baufinanzierung">
<div class="feldpaar"> <div class="feldpaar">
<div> <div>
<label for="darlehensbetrag">Darlehensbetrag</label> <label for="darlehensbetrag">Darlehensbetrag</label>
<input type="text" id="darlehensbetrag" name="darlehensbetrag" inputmode="decimal" required> <input type="text" id="darlehensbetrag" name="darlehensbetrag" inputmode="decimal" required>
</div>
<div>
<label for="zinssatz">Zinssatz (%)</label>
<input type="text" id="zinssatz" name="zinssatz" inputmode="decimal" required>
</div>
<div>
<label for="rate">Rate</label>
<input type="text" id="rate" name="rate" inputmode="decimal" required>
</div>
</div> </div>
<div>
<label for="zinssatz">Zinssatz (%)</label>
<input type="text" id="zinssatz" name="zinssatz" inputmode="decimal" required>
</div>
<div>
<label for="rate">Rate</label>
<input type="text" id="rate" name="rate" inputmode="decimal" required>
</div>
</div>
<div class="feldpaar"> <div class="feldpaar">
<div> <div>
<label for="rhythmus">Rhythmus</label> <label for="rhythmus">Rhythmus</label>
<select id="rhythmus" name="rhythmus"> <select id="rhythmus" name="rhythmus">
<?php foreach (Kredit::RHYTHMUS_NAMEN as $schluessel => $name): ?> <?php foreach (Kredit::RHYTHMUS_NAMEN as $schluessel => $name): ?>
<option value="<?= View::h($schluessel) ?>"><?= View::h($name) ?></option> <option value="<?= View::h($schluessel) ?>"><?= View::h($name) ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
</div>
<div>
<label for="beginn">Beginn</label>
<input type="date" id="beginn" name="beginn" value="<?= View::h(date('Y-m-d')) ?>" required>
</div>
<div>
<label for="zinsbindung_bis">Zinsbindung bis</label>
<input type="date" id="zinsbindung_bis" name="zinsbindung_bis">
</div>
</div> </div>
<div>
<label for="beginn">Beginn</label>
<input type="date" id="beginn" name="beginn" value="<?= View::h(date('Y-m-d')) ?>" required>
</div>
<div>
<label for="zinsbindung_bis">Zinsbindung bis</label>
<input type="date" id="zinsbindung_bis" name="zinsbindung_bis">
</div>
</div>
<label class="ankreuzfeld"> <label class="ankreuzfeld">
<input type="checkbox" name="aktiv" value="1" checked> aktiv <input type="checkbox" name="aktiv" value="1" checked> aktiv
</label> </label>
<div class="knopfleiste"> <div class="knopfleiste">
<button type="submit" class="knopf primaer">Kredit anlegen</button> <button type="submit" class="knopf primaer">Kredit anlegen</button>
</div> <button type="submit" class="knopf" formmethod="dialog" formnovalidate>Abbrechen</button>
</form> </div>
</form>
</dialog>
<?php include __DIR__ . '/../layout/fuss.php'; ?> <?php include __DIR__ . '/../layout/fuss.php'; ?>

View file

@ -24,6 +24,10 @@ include __DIR__ . '/../layout/kopf.php';
auf dem Konto lag. auf dem Konto lag.
</p> </p>
<div class="seitenaktionen">
<button type="button" class="knopf primaer" id="neu-knopf" data-neudialog="neudialog">+ Neu</button>
</div>
<?php if ($ziele === []): ?> <?php if ($ziele === []): ?>
<p class="platzhalter">Noch kein Sparziel angelegt.</p> <p class="platzhalter">Noch kein Sparziel angelegt.</p>
<?php else: ?> <?php else: ?>
@ -93,46 +97,49 @@ include __DIR__ . '/../layout/kopf.php';
</div> </div>
<?php endif; ?> <?php endif; ?>
<form method="post" action="/vertraege/sparziele/neu" class="formular breit"> <dialog id="neudialog" class="splitdialog neudialog">
<input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>"> <form method="post" action="/vertraege/sparziele/neu" class="formular breit">
<h3>Neues Sparziel</h3> <input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>">
<h2>Neues Sparziel</h2>
<label for="name">Name</label> <label for="name">Name</label>
<input type="text" id="name" name="name" required placeholder="z. B. Neues Auto"> <input type="text" id="name" name="name" required placeholder="z. B. Neues Auto">
<label for="konto_id">Konto</label> <label for="konto_id">Konto</label>
<select id="konto_id" name="konto_id"> <select id="konto_id" name="konto_id">
<option value="">– keines –</option> <option value="">– keines –</option>
<?php foreach ($konten as $konto): ?> <?php foreach ($konten as $konto): ?>
<option value="<?= (int)$konto['id'] ?>"><?= View::h($konto['name']) ?></option> <option value="<?= (int)$konto['id'] ?>"><?= View::h($konto['name']) ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
<p class="feldhinweis">Der Stand des Ziels ist der Saldo dieses Kontos.</p> <p class="feldhinweis">Der Stand des Ziels ist der Saldo dieses Kontos.</p>
<div class="feldpaar"> <div class="feldpaar">
<div> <div>
<label for="zielbetrag">Zielbetrag</label> <label for="zielbetrag">Zielbetrag</label>
<input type="text" id="zielbetrag" name="zielbetrag" inputmode="decimal" required> <input type="text" id="zielbetrag" name="zielbetrag" inputmode="decimal" required>
</div>
<div>
<label for="startbetrag">Startbetrag</label>
<input type="text" id="startbetrag" name="startbetrag" inputmode="decimal" value="0,00">
</div>
<div>
<label for="zieldatum">Zieldatum</label>
<input type="date" id="zieldatum" name="zieldatum">
</div>
</div> </div>
<div>
<label for="startbetrag">Startbetrag</label> <label for="monatsrate">Geplante Monatsrate <span class="optional">(optional)</span></label>
<input type="text" id="startbetrag" name="startbetrag" inputmode="decimal" value="0,00"> <input type="text" id="monatsrate" name="monatsrate" inputmode="decimal">
<label for="notiz">Notiz</label>
<input type="text" id="notiz" name="notiz">
<div class="knopfleiste">
<button type="submit" class="knopf primaer">Sparziel anlegen</button>
<button type="submit" class="knopf" formmethod="dialog" formnovalidate>Abbrechen</button>
</div> </div>
<div> </form>
<label for="zieldatum">Zieldatum</label> </dialog>
<input type="date" id="zieldatum" name="zieldatum">
</div>
</div>
<label for="monatsrate">Geplante Monatsrate <span class="optional">(optional)</span></label>
<input type="text" id="monatsrate" name="monatsrate" inputmode="decimal">
<label for="notiz">Notiz</label>
<input type="text" id="notiz" name="notiz">
<div class="knopfleiste">
<button type="submit" class="knopf primaer">Sparziel anlegen</button>
</div>
</form>
<?php include __DIR__ . '/../layout/fuss.php'; ?> <?php include __DIR__ . '/../layout/fuss.php'; ?>

View file

@ -9,6 +9,7 @@ include __DIR__ . '/../layout/kopf.php';
?> ?>
<div class="seitenaktionen"> <div class="seitenaktionen">
<button type="button" class="knopf primaer" id="neu-knopf" data-neudialog="neudialog">+ Neu</button>
<a href="/verwaltung" class="knopf">Zurück zur Verwaltung</a> <a href="/verwaltung" class="knopf">Zurück zur Verwaltung</a>
<a href="/verwaltung/import" class="knopf">QIF-Import</a> <a href="/verwaltung/import" class="knopf">QIF-Import</a>
</div> </div>
@ -69,19 +70,22 @@ include __DIR__ . '/../layout/kopf.php';
</table> </table>
<?php endif; ?> <?php endif; ?>
<form method="post" action="/verwaltung/klassen/neu" class="formular breit"> <dialog id="neudialog" class="splitdialog neudialog">
<input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>"> <form method="post" action="/verwaltung/klassen/neu" class="formular breit">
<h3>Neue Klasse</h3> <input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>">
<h2>Neue Klasse</h2>
<label for="name">Name</label> <label for="name">Name</label>
<input type="text" id="name" name="name" required> <input type="text" id="name" name="name" required>
<label for="beschreibung">Beschreibung <span class="optional">(optional)</span></label> <label for="beschreibung">Beschreibung <span class="optional">(optional)</span></label>
<input type="text" id="beschreibung" name="beschreibung"> <input type="text" id="beschreibung" name="beschreibung">
<div class="knopfleiste"> <div class="knopfleiste">
<button type="submit" class="knopf primaer">Klasse anlegen</button> <button type="submit" class="knopf primaer">Klasse anlegen</button>
</div> <button type="submit" class="knopf" formmethod="dialog" formnovalidate>Abbrechen</button>
</form> </div>
</form>
</dialog>
<?php include __DIR__ . '/../layout/fuss.php'; ?> <?php include __DIR__ . '/../layout/fuss.php'; ?>

View file

@ -27,6 +27,10 @@ include __DIR__ . '/../layout/kopf.php';
die Splitzeilen im gleichen Verhältnis mitgezogen. die Splitzeilen im gleichen Verhältnis mitgezogen.
</p> </p>
<div class="seitenaktionen">
<button type="button" class="knopf primaer" id="neu-knopf" data-neudialog="neudialog">+ Neu</button>
</div>
<form method="get" action="/vorlagen" class="filterleiste"> <form method="get" action="/vorlagen" class="filterleiste">
<label for="suche">Suchen</label> <label for="suche">Suchen</label>
<input type="search" id="suche" name="suche" value="<?= View::h($suche) ?>" <input type="search" id="suche" name="suche" value="<?= View::h($suche) ?>"
@ -106,49 +110,52 @@ include __DIR__ . '/../layout/kopf.php';
</table> </table>
<?php endif; ?> <?php endif; ?>
<form method="post" action="/vorlagen/neu" class="formular breit"> <dialog id="neudialog" class="splitdialog neudialog">
<input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>"> <form method="post" action="/vorlagen/neu" class="formular breit">
<h3>Neue Vorlage</h3> <input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>">
<h2>Neue Vorlage</h2>
<label for="name">Name</label> <label for="name">Name</label>
<input type="text" id="name" name="name" required> <input type="text" id="name" name="name" required>
<label for="empfaenger">Empfänger</label> <label for="empfaenger">Empfänger</label>
<input type="text" id="empfaenger" name="empfaenger"> <input type="text" id="empfaenger" name="empfaenger">
<label for="konto_id">Konto</label> <label for="konto_id">Konto</label>
<select id="konto_id" name="konto_id"> <select id="konto_id" name="konto_id">
<option value="">– beim Buchen wählen –</option> <option value="">– beim Buchen wählen –</option>
<?php foreach ($konten as $konto): ?> <?php foreach ($konten as $konto): ?>
<option value="<?= (int)$konto['id'] ?>"><?= View::h($konto['name']) ?></option> <option value="<?= (int)$konto['id'] ?>"><?= View::h($konto['name']) ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
<label for="betrag">Betrag</label> <label for="betrag">Betrag</label>
<input type="text" id="betrag" name="betrag" inputmode="decimal" value="0,00"> <input type="text" id="betrag" name="betrag" inputmode="decimal" value="0,00">
<label for="kategorie_id">Kategorie</label> <label for="kategorie_id">Kategorie</label>
<select id="kategorie_id" name="kategorie_id"> <select id="kategorie_id" name="kategorie_id">
<option value="">– keine –</option> <option value="">– keine –</option>
<?php foreach ($kategorien as $kategorie): ?> <?php foreach ($kategorien as $kategorie): ?>
<option value="<?= (int)$kategorie['id'] ?>"><?= View::h($kategorie['pfad']) ?></option> <option value="<?= (int)$kategorie['id'] ?>"><?= View::h($kategorie['pfad']) ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
<label for="klasse_id">Klasse</label> <label for="klasse_id">Klasse</label>
<select id="klasse_id" name="klasse_id"> <select id="klasse_id" name="klasse_id">
<option value="">– keine –</option> <option value="">– keine –</option>
<?php foreach ($klassen as $klasse): ?> <?php foreach ($klassen as $klasse): ?>
<option value="<?= (int)$klasse['id'] ?>"><?= View::h($klasse['name']) ?></option> <option value="<?= (int)$klasse['id'] ?>"><?= View::h($klasse['name']) ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
<label for="buchungstext">Buchungstext</label> <label for="buchungstext">Buchungstext</label>
<input type="text" id="buchungstext" name="buchungstext"> <input type="text" id="buchungstext" name="buchungstext">
<div class="knopfleiste"> <div class="knopfleiste">
<button type="submit" class="knopf primaer">Vorlage anlegen</button> <button type="submit" class="knopf primaer">Vorlage anlegen</button>
</div> <button type="submit" class="knopf" formmethod="dialog" formnovalidate>Abbrechen</button>
</form> </div>
</form>
</dialog>
<?php include __DIR__ . '/../layout/fuss.php'; ?> <?php include __DIR__ . '/../layout/fuss.php'; ?>

View file

@ -54,8 +54,9 @@ test.describe('Buchungen', () => {
await page.click('.formular button[type="submit"]') await page.click('.formular button[type="submit"]')
await page.goto('/verwaltung/klassen') await page.goto('/verwaltung/klassen')
await page.click('#neu-knopf')
await page.fill('form[action="/verwaltung/klassen/neu"] #name', KLASSE) await page.fill('form[action="/verwaltung/klassen/neu"] #name', KLASSE)
await page.click('form[action="/verwaltung/klassen/neu"] button[type="submit"]') await page.click('form[action="/verwaltung/klassen/neu"] button.primaer')
await page.close() await page.close()
}) })

View file

@ -201,6 +201,7 @@ test.describe('Module der Phasen 4 bis 7', () => {
test('Eine falsche IBAN wird beim Anlegen einer Adresse abgewiesen', async ({ page }) => { test('Eine falsche IBAN wird beim Anlegen einer Adresse abgewiesen', async ({ page }) => {
await page.goto('/vertraege/adressen') await page.goto('/vertraege/adressen')
await page.click('#neu-knopf')
await page.fill('#name', 'E2E-Falschtest') await page.fill('#name', 'E2E-Falschtest')
await page.fill('#iban', 'DE02120300000000202052') await page.fill('#iban', 'DE02120300000000202052')
@ -211,6 +212,7 @@ test.describe('Module der Phasen 4 bis 7', () => {
test('Ein Kredit zeigt seinen gerechneten Tilgungsplan', async ({ page }) => { test('Ein Kredit zeigt seinen gerechneten Tilgungsplan', async ({ page }) => {
await page.goto('/vertraege/kredite') await page.goto('/vertraege/kredite')
await page.click('#neu-knopf')
await page.fill('#name', 'E2E-Darlehen') await page.fill('#name', 'E2E-Darlehen')
await page.fill('#darlehensbetrag', '100000') await page.fill('#darlehensbetrag', '100000')
@ -314,10 +316,11 @@ test.describe('Module der Phasen 4 bis 7', () => {
test('Regelmäßige Buchungen werden per Klick bearbeitbar', async ({ page }) => { test('Regelmäßige Buchungen werden per Klick bearbeitbar', async ({ page }) => {
await page.goto('/termine') await page.goto('/termine')
await page.click('#neu-knopf')
await page.fill('#name', 'E2E-Reihe') await page.fill('#name', 'E2E-Reihe')
await page.fill('#neu_betrag', '-12,50') await page.fill('#neu_betrag', '-12,50')
await page.fill('#neu_buchungstext', 'E2E-Text') await page.fill('#neu_buchungstext', 'E2E-Text')
await page.click('form[action="/termine/neu"] button[type="submit"]') await page.click('form[action="/termine/neu"] button.primaer')
const zeile = page.locator('table.reihen tr', { hasText: 'E2E-Reihe' }) const zeile = page.locator('table.reihen tr', { hasText: 'E2E-Reihe' })
await expect(zeile.locator('input[name="betrag"]')).toBeHidden() await expect(zeile.locator('input[name="betrag"]')).toBeHidden()
@ -398,6 +401,7 @@ test.describe('Module der Phasen 4 bis 7', () => {
// Erst eine Adresse anlegen, damit die Auswahl etwas zu bieten hat. // Erst eine Adresse anlegen, damit die Auswahl etwas zu bieten hat.
await page.goto('/vertraege/adressen') await page.goto('/vertraege/adressen')
await page.click('#neu-knopf')
await page.fill('#name', empfaenger) await page.fill('#name', empfaenger)
await page.fill('#iban', 'DE02120300000000202051') await page.fill('#iban', 'DE02120300000000202051')
await page.click('button:has-text("Adresse anlegen")') await page.click('button:has-text("Adresse anlegen")')

View file

@ -0,0 +1,60 @@
// @ts-check
const { test, expect } = require('@playwright/test')
const BENUTZER = process.env.E2E_USER || 'e2e'
const PASSWORT = process.env.E2E_PASSWORD || 'e2e-testpasswort'
const MARKE = Date.now().toString().slice(-6)
// Alle Listenansichten, in denen „+ Neu“ ein modales Formular zur Neuanlage öffnet.
const ANSICHTEN = [
'/verwaltung/klassen',
'/vorlagen',
'/termine',
'/termine/erinnerungen',
'/vertraege',
'/vertraege/adressen',
'/vertraege/sparziele',
'/vertraege/kredite',
'/banking/regeln',
'/planung/budget/verwaltung',
'/auswertungen/gruppen',
]
async function anmelden(page) {
await page.goto('/login')
await page.fill('#benutzername', BENUTZER)
await page.fill('#passwort', PASSWORT)
await page.click('button[type="submit"]')
await expect(page).toHaveURL(/\/$/)
}
test.describe('„+ Neu“ öffnet den Dialog zur Neuanlage', () => {
test.beforeEach(async ({ page }) => {
await anmelden(page)
})
for (const pfad of ANSICHTEN) {
test(`${pfad}: Dialog erst nach Klick, Abbrechen schließt ihn`, async ({ page }) => {
await page.goto(pfad)
await expect(page.locator('#neudialog')).toBeHidden()
await page.click('#neu-knopf')
await expect(page.locator('#neudialog')).toBeVisible()
await page.locator('#neudialog button', { hasText: 'Abbrechen' }).click()
await expect(page.locator('#neudialog')).toBeHidden()
})
}
test('Klasse anlegen: Dialog verschwindet, Eintrag steht in der Liste', async ({ page }) => {
const name = `E2E Dialogklasse ${MARKE}`
await page.goto('/verwaltung/klassen')
await page.click('#neu-knopf')
await page.fill('#neudialog #name', name)
await page.locator('#neudialog button[type="submit"]', { hasText: 'Klasse anlegen' }).click()
await expect(page.locator('#neudialog')).toBeHidden()
await expect(page.locator(`input[value="${name}"]`).first()).toBeVisible()
})
})

View file

@ -35,6 +35,7 @@ async function anmelden(page) {
*/ */
async function budgetAnlegen(page, name) { async function budgetAnlegen(page, name) {
await page.goto('/planung/budget/verwaltung') await page.goto('/planung/budget/verwaltung')
await page.click('#neu-knopf')
await page.fill('#name', name) await page.fill('#name', name)
await page.fill('#jahr', String(JAHR)) await page.fill('#jahr', String(JAHR))
await page.click('.formular button:has-text("Budget anlegen")') await page.click('.formular button:has-text("Budget anlegen")')

View file

@ -163,9 +163,10 @@ test.describe('Stammdaten', () => {
const name = `E2E Projekt ${MARKE}` const name = `E2E Projekt ${MARKE}`
await page.goto('/verwaltung/klassen') await page.goto('/verwaltung/klassen')
await page.click('#neu-knopf')
await page.fill('.formular #name', name) await page.fill('.formular #name', name)
await page.fill('.formular #beschreibung', 'aus dem E2E-Test') await page.fill('.formular #beschreibung', 'aus dem E2E-Test')
await page.click('.formular button[type="submit"]') await page.click('.formular button:has-text("Klasse anlegen")')
await expect(page.locator('.meldung-erfolg')).toBeVisible() await expect(page.locator('.meldung-erfolg')).toBeVisible()