Menüs ersetzen die fest verdrahtete Navigation (Arbeitspaket A)

Migration 20260912000500 legt eine Tabelle menu an: ein Menü je Platz
(header, footer) und Sprache, Elementbaum als JSON, Version für
dieselbe Konflikterkennung wie bei Seiten.

Ein Eintrag verweist auf eine Seite, auf ein Sprungziel innerhalb
einer Seite oder auf eine Adresse (HTTPS, lokaler Pfad, mailto:,
tel:). Seitenverweise speichern die Seiten-ID, nie den Pfad - ein
Eintrag folgt damit einer umbenannten Seite. Beim Rendern fallen
Einträge zu gelöschten oder unveröffentlichten Seiten heraus, ohne
den gespeicherten Baum zu ändern und ohne die übrigen Einträge zu
verlieren.

Die Verwaltung nutzt eine nummerierte Zeilenliste statt Drag-and-drop
und funktioniert damit vollständig ohne JavaScript; Untermenüs in der
Ausgabe über details/summary.

tests/bootstrap.php verwirft var/cache/test je Lauf. Ohne Debug prüft
Symfony weder den kompilierten Container noch die Vorlagen auf
Aktualität, was zweimal ein falsches Testergebnis erzeugt hat.

Geprüft: 79 PHP-Tests / 285 Assertions unter PHP 8.2.12 und 8.4.22,
11 JavaScript-Modelltests, Lint/Format/Container, Migration zuerst
gegen eine Datenbankkopie, wiederholtes Seeding. Keine Browser- oder
Lighthouse-Läufe.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
kantarciandClaude Opus 5 committed 2026-09-12 10:59:23 +02:00
1 parent 4a60adf7d7
commit de9d6e3da8
22 files changed
+765 -19

No files matched your search

+2
View File
@@ -13,3 +13,5 @@
.notice.ok{background:#edf3dc;color:#315b49;border:1px solid #c5d89a}.notice{margin-top:24px}.create-panel{margin-top:34px;background:white;border:1px solid var(--line);border-radius:10px}.create-panel>summary{padding:20px 24px;font-size:13px;font-weight:600;cursor:pointer;border-radius:10px}.create-panel[open]>summary{border-bottom:1px solid var(--line)}.create-form{padding:6px 24px 26px}.create-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:0 24px}.create-form .primary{margin-top:24px}.create-form code{background:#f0f4e9;padding:1px 5px;border-radius:4px}.delete-panel>summary{font-size:12px;font-weight:600;color:#943a2e;cursor:pointer;padding:11px 13px;border:1px solid var(--line);border-radius:7px;list-style:none}.delete-panel[open]{position:relative}.delete-panel[open]>form{position:absolute;right:0;top:calc(100% + 8px);z-index:2;width:290px;background:white;border:1px solid var(--line);border-radius:10px;padding:18px;box-shadow:0 14px 40px #203b3422}.delete-panel p{font-size:12px;line-height:1.6;color:var(--muted)}
@media (max-width:720px){.page-card{flex-wrap:wrap}.pages-main{margin-block:40px}.delete-panel[open]>form{position:static;width:100%;box-shadow:none;margin-top:10px}}
.admin-links{display:flex;flex-wrap:wrap;gap:10px;margin:0}.menu-section{margin-top:46px}.menu-form{background:white;border:1px solid var(--line);border-radius:10px;padding:8px 24px 26px}.menu-form>label:first-of-type{margin-top:18px}.menu-form>input[name=name]{max-width:420px}.menu-table{width:100%;border-collapse:collapse;margin-top:24px;display:block;overflow-x:auto}.menu-table th{text-align:left;font-size:11px;letter-spacing:.4px;color:var(--muted);padding:0 8px 8px;font-weight:700;white-space:nowrap}.menu-table td{padding:4px 8px 4px 0;vertical-align:top}.menu-table input,.menu-table select{font-size:12px;min-height:38px;padding:8px 10px}.menu-table td:first-child input{width:78px}.menu-table td:nth-child(2) select{width:140px}.menu-table td:nth-child(3) input{min-width:170px}.menu-table td:nth-child(4) select{width:104px}.menu-table td:nth-child(5) select{min-width:190px}.menu-table td:nth-child(6) input{width:130px}.menu-table td:nth-child(7) input{min-width:190px}.menu-row-new input,.menu-row-new select{background:#fafbf8}.menu-form .primary{margin-top:20px}.menu-form code{background:#f0f4e9;padding:1px 5px;border-radius:4px}