feat(studio): localise Settings sidebar + add inline help docs + Approvals doc
Some checks failed
Security / Security check (push) Failing after 1s

Three operator-UX gaps closed:

  - Settings dialog's six-category sidebar (General / Appearance /
    System AI / Integrations / Security / Maintenance) was
    hardcoded English; now flows through AppLocalizations
    ("Allgemein" / "Darstellung" / "System-KI" / "Integrationen" /
    "Sicherheit" / "Wartung"). Same for the per-panel title +
    description.
  - Per-channel daemon-action labels ('enable autostart' /
    'disable autostart' / 'daemon restart' etc.) and the
    OK / Failed result line in the toast also moved to l10n,
    so the system-action feedback reads as one language.
  - New 'Approvals' doc bundle (en + de) under assets/docs/,
    registered as a fifth doc card on Welcome plus exposed via
    the new public  helper. The
    Approvals, Audit and Doctor app-bars grow a Help icon button
    next to Refresh that opens the matching doc in the existing
    bottom-sheet reader — no extra screen, no learning curve.

Studio bumped to 0.67.0; editor path-override pulls in 0.20.1
(flow-list row polish).

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
flemming-it 2026-06-09 01:57:46 +02:00
parent 2be7d241bf
commit 28fafce7dc
15 changed files with 681 additions and 36 deletions

View file

@ -8,6 +8,7 @@ import '../l10n/app_localizations.dart';
import '../theme/theme.dart';
import '../theme/tokens.dart';
import '../widgets/widgets.dart';
import 'welcome.dart' show showFaiDoc;
class DoctorPage extends StatefulWidget {
const DoctorPage({super.key});
@ -36,6 +37,11 @@ class _DoctorPageState extends State<DoctorPage> {
appBar: AppBar(
title: Text(AppLocalizations.of(context)!.doctorTitle),
actions: [
IconButton(
icon: const Icon(Icons.help_outline, size: 18),
tooltip: AppLocalizations.of(context)!.helpTooltip,
onPressed: () => showFaiDoc(context, 'architecture'),
),
IconButton(
icon: const Icon(Icons.refresh, size: 18),
tooltip: AppLocalizations.of(context)!.doctorRecheckTooltip,
@ -504,12 +510,13 @@ class _DaemonActionsCardState extends State<_DaemonActionsCard> {
});
final r = await action();
if (!mounted) return;
final l = AppLocalizations.of(context)!;
setState(() {
_busy = false;
_output =
(r.ok
? 'OK · $label\n${r.stdout}'
: 'Failed · $label\n${r.stderr.isEmpty ? r.stdout : r.stderr}')
? '${l.daemonActionResultOk(label)}\n${r.stdout}'
: '${l.daemonActionResultFailed(label)}\n${r.stderr.isEmpty ? r.stdout : r.stderr}')
.trim();
});
// Refresh the status pill restart / stop / start all
@ -594,7 +601,7 @@ class _DaemonActionsCardState extends State<_DaemonActionsCard> {
onPressed: _busy
? null
: () => _run(
'daemon restart',
l.daemonActionRestart,
() => SystemActions.faiDaemon(['restart']),
),
icon: const Icon(Icons.restart_alt, size: 16),
@ -605,7 +612,7 @@ class _DaemonActionsCardState extends State<_DaemonActionsCard> {
onPressed: _busy
? null
: () => _run(
'daemon start',
l.daemonActionStart,
() => SystemActions.faiDaemon(['start']),
),
icon: const Icon(Icons.play_arrow, size: 16),
@ -615,7 +622,7 @@ class _DaemonActionsCardState extends State<_DaemonActionsCard> {
onPressed: _busy
? null
: () => _run(
'daemon stop',
l.daemonActionStop,
() => SystemActions.faiDaemon(['stop']),
),
icon: const Icon(Icons.stop_circle_outlined, size: 16),
@ -625,7 +632,7 @@ class _DaemonActionsCardState extends State<_DaemonActionsCard> {
onPressed: _busy
? null
: () => _run(
'daemon status',
l.daemonActionStatus,
() => SystemActions.faiDaemon(['status']),
),
icon: const Icon(Icons.health_and_safety_outlined, size: 16),