feat(studio): central error helpers + inline log viewer + Today CTAs
Some checks failed
Security / Security check (push) Failing after 1s
Some checks failed
Security / Security check (push) Failing after 1s
Bundles the error-UX overhaul and the inline log viewer:
- New `FaiLog` (`~/.fai/logs/studio-errors.log`, 256 KiB rotation,
JSON-per-line). Every operator-visible failure is appended so
`fai admin doctor` and the new viewer can show the trail
without the operator having to reproduce the failure.
- New `showFaiErrorSnack` / `showFaiErrorDialog` helpers wrap
`FaiErrorBox` in copyable surfaces; 27 ad-hoc
`SnackBar(content: Text(e.toString()))` sites swept to use
them (settings, doctor, audit, store, module sheet, system-AI
editor, flow output).
- New `FaiLogViewer` modal (`showFaiLogViewer`) renders log
files inline with line numbers, JSON-key + `[level]` token
colouring, Copy-all, Refresh, Open-externally. Doctor's
daemon-paths panel grows a "View" button next to "Open" for
every `.log` row and now also lists the Studio errors log.
- Today carousel: CTAs now actually re-run search after a
`filterCategory` / `runQuery` story is tapped (was only
flipping the chip state). Fallback story list bumped to 8.
- Editor bumped to git ref carrying 0.15.0 (type-token
colouring + analyzer diagnostics).
Studio bumped to 0.62.0.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
parent
2731062a13
commit
8f5cd2528b
22 changed files with 1087 additions and 134 deletions
|
|
@ -5,6 +5,7 @@
|
|||
import 'package:fai_client_sdk/fai_client_sdk.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../data/error_presentation.dart';
|
||||
import '../data/hub.dart';
|
||||
import '../data/hub_auth_token.dart';
|
||||
import '../data/registry_token.dart';
|
||||
|
|
@ -92,10 +93,7 @@ class _FaiSettingsDialogState extends State<FaiSettingsDialog> {
|
|||
).showSnackBar(SnackBar(content: Text(l.hubAuthTokenSavedToast)));
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
final l = AppLocalizations.of(context)!;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(l.hubAuthTokenSaveFailedToast(e.toString()))),
|
||||
);
|
||||
showFaiErrorSnack(context, 'auth.hub-token.save', e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -111,10 +109,7 @@ class _FaiSettingsDialogState extends State<FaiSettingsDialog> {
|
|||
).showSnackBar(SnackBar(content: Text(l.hubAuthTokenClearedToast)));
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
final l = AppLocalizations.of(context)!;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(l.hubAuthTokenSaveFailedToast(e.toString()))),
|
||||
);
|
||||
showFaiErrorSnack(context, 'auth.hub-token.clear', e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -139,10 +134,7 @@ class _FaiSettingsDialogState extends State<FaiSettingsDialog> {
|
|||
).showSnackBar(SnackBar(content: Text(l.registryTokenSavedToast)));
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
final l = AppLocalizations.of(context)!;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(l.registryTokenSaveFailedToast(e.toString()))),
|
||||
);
|
||||
showFaiErrorSnack(context, 'auth.registry-token.save', e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -157,10 +149,7 @@ class _FaiSettingsDialogState extends State<FaiSettingsDialog> {
|
|||
).showSnackBar(SnackBar(content: Text(l.registryTokenClearedToast)));
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
final l = AppLocalizations.of(context)!;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(l.registryTokenSaveFailedToast(e.toString()))),
|
||||
);
|
||||
showFaiErrorSnack(context, 'auth.registry-token.clear', e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -190,10 +179,7 @@ class _FaiSettingsDialogState extends State<FaiSettingsDialog> {
|
|||
).showSnackBar(SnackBar(content: Text(l.addedN8nToast(draft.name))));
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
final l = AppLocalizations.of(context)!;
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text(l.addFailedToast(e.toString()))));
|
||||
showFaiErrorSnack(context, 'settings.n8n.add', e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -204,10 +190,7 @@ class _FaiSettingsDialogState extends State<FaiSettingsDialog> {
|
|||
setState(() => _n8nEndpoints = list);
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
final l = AppLocalizations.of(context)!;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(l.removeFailedToast(e.toString()))),
|
||||
);
|
||||
showFaiErrorSnack(context, 'settings.n8n.remove', e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -218,10 +201,7 @@ class _FaiSettingsDialogState extends State<FaiSettingsDialog> {
|
|||
setState(() => _n8nEndpoints = list);
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
final l = AppLocalizations.of(context)!;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(l.refreshFailedToast(e.toString()))),
|
||||
);
|
||||
showFaiErrorSnack(context, 'settings.n8n.refresh', e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -251,10 +231,7 @@ class _FaiSettingsDialogState extends State<FaiSettingsDialog> {
|
|||
).showSnackBar(SnackBar(content: Text(l.addedMcpToast(draft.name))));
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
final l = AppLocalizations.of(context)!;
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text(l.addFailedToast(e.toString()))));
|
||||
showFaiErrorSnack(context, 'settings.mcp.add', e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -265,10 +242,7 @@ class _FaiSettingsDialogState extends State<FaiSettingsDialog> {
|
|||
setState(() => _mcpClients = list);
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
final l = AppLocalizations.of(context)!;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(l.removeFailedToast(e.toString()))),
|
||||
);
|
||||
showFaiErrorSnack(context, 'settings.mcp.remove', e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -279,10 +253,7 @@ class _FaiSettingsDialogState extends State<FaiSettingsDialog> {
|
|||
setState(() => _mcpClients = list);
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
final l = AppLocalizations.of(context)!;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(l.refreshFailedToast(e.toString()))),
|
||||
);
|
||||
showFaiErrorSnack(context, 'settings.mcp.refresh', e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue