Konfigurationsbereich auffindbar machen

Der Bereich war sichtbar, wurde aber übersehen: ein 12-Pixel-Knopf, der an der
Überschrift klebte, während "Handel pausieren" und "Training starten" jeweils in
einer eigenen Box mit normalgroßem Knopf sitzen. 71x26 px gegenüber 90x58 und
79x58 - das liest sich nicht als Bedienelement.

Der Bereich sieht jetzt aus wie die beiden anderen: eigene Panel-Box, Knopf
"Konfiguration bearbeiten" in gleicher Größe (114x58 px, 14px Schrift), daneben
eine Zeile, die sagt, was dahintersteckt. Geöffnet heißt der Knopf
"Konfiguration schließen".

Zwei neue Tests halten die drei Haupt-Bedienelemente auf gleicher Linie: keine
Inline-Styles, die Schrift oder Polsterung verkleinern, und jeder Knopf muss in
einer Panel-Box stehen statt in einer Überschrift.

233 Tests (6 neue), ruff sauber. Im Browser durchgespielt: öffnen, 76 Felder,
risk.cooldown_bars_after_exit geändert und sofort wirksam, schließen.
This commit is contained in:
Tobias Zimmermann
2026-08-23 14:06:40 +02:00
parent 17fef9abe5
commit db31bc93f7
2 changed files with 51 additions and 10 deletions
+12 -3
View File
@@ -131,8 +131,15 @@ _DASHBOARD = r"""<!doctype html>
</div> </div>
</section> </section>
<section id="config-section" hidden> <section id="config-section" hidden>
<h2>Konfiguration <button id="cfg-toggle" class="ghost" style="font-size:12px;padding:3px 9px">anzeigen</button></h2> <h2>Konfiguration</h2>
<div class="panel" id="cfg-panel" hidden> <div class="panel">
<div class="row">
<button id="cfg-toggle">Konfiguration bearbeiten</button>
<span class="hint" id="cfg-summary" style="margin:0">
Alle Einstellungen ändern Risiko, Strategie, Lernmodell, Börse.
</span>
</div>
<div id="cfg-panel" hidden style="margin-top:14px; border-top:1px solid var(--line); padding-top:14px">
<div class="hint" id="cfg-meta"></div> <div class="hint" id="cfg-meta"></div>
<div id="cfg-sections"></div> <div id="cfg-sections"></div>
<div class="row" style="margin-top:14px; border-top:1px solid var(--line); padding-top:14px"> <div class="row" style="margin-top:14px; border-top:1px solid var(--line); padding-top:14px">
@@ -142,6 +149,7 @@ _DASHBOARD = r"""<!doctype html>
<span class="hint" id="cfg-hint" style="margin:0"></span> <span class="hint" id="cfg-hint" style="margin:0"></span>
</div> </div>
</div> </div>
</div>
</section> </section>
<section><h2 style="font-size:15px">Offene Positionen</h2><div class="overflow"><table id="pos"></table></div></section> <section><h2 style="font-size:15px">Offene Positionen</h2><div class="overflow"><table id="pos"></table></div></section>
@@ -393,7 +401,8 @@ async function loadConfig() {
$("cfg-toggle").addEventListener("click", async () => { $("cfg-toggle").addEventListener("click", async () => {
cfgOpen = !cfgOpen; cfgOpen = !cfgOpen;
$("cfg-panel").hidden = !cfgOpen; $("cfg-panel").hidden = !cfgOpen;
$("cfg-toggle").textContent = cfgOpen ? "ausblenden" : "anzeigen"; $("cfg-toggle").textContent = cfgOpen ? "Konfiguration schließen" : "Konfiguration bearbeiten";
$("cfg-toggle").className = cfgOpen ? "ghost" : "";
if (cfgOpen) await loadConfig(); if (cfgOpen) await loadConfig();
}); });
+32
View File
@@ -145,6 +145,38 @@ def test_hidden_sections_are_unhidden_by_the_status_loop(section_id: str):
) )
PRIMARY_BUTTONS = ["trade-btn", "train-btn", "cfg-toggle"]
@pytest.mark.parametrize("button_id", PRIMARY_BUTTONS)
def test_primary_buttons_are_not_shrunk_by_inline_styles(button_id: str):
"""Die Haupt-Bedienelemente sollen gleich aussehen.
Der Konfigurationsknopf war einmal ein 12-Pixel-Anhängsel an einer Überschrift und
wurde schlicht übersehen. Inline-Styles, die Schrift oder Polsterung verkleinern,
gehören hier nicht hin.
"""
match = re.search(rf'<button id="{button_id}"([^>]*)>', _DASHBOARD)
assert match is not None, f"Knopf #{button_id} fehlt"
attributes = match.group(1)
for verboten in ("font-size", "padding"):
assert verboten not in attributes, (
f"#{button_id} verkleinert sich per Inline-Style ({verboten}) gegenüber den anderen"
)
@pytest.mark.parametrize("button_id", PRIMARY_BUTTONS)
def test_primary_buttons_sit_inside_a_panel(button_id: str):
"""Ein Knopf direkt in der Überschrift liest sich nicht als Bedienelement."""
match = re.search(rf'<button id="{button_id}"[^>]*>', _DASHBOARD)
before = _DASHBOARD[: match.start()]
letzte_ueberschrift = before.rfind("<h2>")
letztes_panel = before.rfind('class="panel"')
assert letztes_panel > letzte_ueberschrift, (
f"#{button_id} steht in einer Überschrift statt in einer Panel-Box"
)
def test_render_functions_are_called_by_the_status_loop(): def test_render_functions_are_called_by_the_status_loop():
body = function_body(script_body(), "refresh") body = function_body(script_body(), "refresh")
for name in ("renderTrading", "renderTraining"): for name in ("renderTrading", "renderTraining"):