From cc1618f51200478267e1b26040b1219cda989f5e Mon Sep 17 00:00:00 2001 From: flemming-it Date: Fri, 17 Jul 2026 23:23:15 +0200 Subject: [PATCH] fix(runs): plain-language empty state with a guide button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The empty state explained itself in operator jargon (detach, detached.enabled, operator config) and offered no way forward. Now it says what background runs are in everyday language and opens the built-in guide — which carries the exact activation steps — via a real button. DE and EN. Signed-off-by: flemming-it --- lib/l10n/app_de.arb | 5 +++-- lib/l10n/app_en.arb | 5 +++-- lib/pages/runs.dart | 8 ++++++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index b3e54d4..1d4169e 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -1701,8 +1701,9 @@ "workspaceProtectedHint": "Geschützt: logisch getrennt im gemeinsamen Hub — keine harte Prozessgrenze. Kritische Mandate nutzen einen abgeschotteten Bereich.", "runsTitle": "Läufe", "runsReloadTooltip": "Lauf-Liste neu laden", - "runsEmptyTitle": "Keine abgekoppelten Läufe", - "runsEmptyHint": "Mit detach gestartete Läufe stehen hier, bis sie fertig sind. Abgekoppelte Aufrufe sind optional — dazu detached.enabled in der Betreiber-Konfiguration aktivieren.", + "runsEmptyTitle": "Keine Läufe im Hintergrund", + "runsEmptyHint": "Hier erscheinen Läufe, die im Hintergrund weiterlaufen, während Sie anderes tun. Diese Funktion ist optional und standardmäßig ausgeschaltet — die Anleitung zeigt Schritt für Schritt, wie sie eingeschaltet wird.", + "runsEmptyGuideButton": "Anleitung öffnen", "runsCancelButton": "Abbrechen", "runsCancelSignalled": "Abbruch für {flow} ausgelöst.", "@runsCancelSignalled": {"placeholders": {"flow": {"type": "String"}}}, diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 45898d0..834ca33 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -1740,8 +1740,9 @@ "workspaceProtectedHint": "Protected: logically separated in the shared hub — no hard process barrier. Critical engagements use a sealed area.", "runsTitle": "Runs", "runsReloadTooltip": "Reload the runs list", - "runsEmptyTitle": "No detached runs", - "runsEmptyHint": "Runs submitted with detach stay here until they finish. Detached invocations are opt-in — enable detached.enabled in the operator config to use them.", + "runsEmptyTitle": "No background runs", + "runsEmptyHint": "Runs that keep working in the background while you do something else appear here. The feature is optional and off by default — the guide shows step by step how to turn it on.", + "runsEmptyGuideButton": "Open the guide", "runsCancelButton": "Cancel", "runsCancelSignalled": "Cancel signalled for {flow}.", "@runsCancelSignalled": {"placeholders": {"flow": {"type": "String"}}}, diff --git a/lib/pages/runs.dart b/lib/pages/runs.dart index bdbf2ee..89f4207 100644 --- a/lib/pages/runs.dart +++ b/lib/pages/runs.dart @@ -127,6 +127,14 @@ class _RunsPageState extends State { icon: Icons.rocket_launch_outlined, title: l.runsEmptyTitle, hint: l.runsEmptyHint, + // The guide carries the plain-language explanation plus + // the exact operator steps (config snippet) — a click + // target instead of a raw config key in the hint. + action: OutlinedButton.icon( + icon: const Icon(Icons.menu_book_outlined, size: 16), + label: Text(l.runsEmptyGuideButton), + onPressed: () => showFaiDoc(context, 'runs'), + ), ) : ListView.separated( padding: const EdgeInsets.all(ChainSpace.lg),