feat: add runtime logs tab to settings page

This commit is contained in:
Haitao Pan 2026-06-03 14:29:37 +08:00
parent 1470a67a06
commit fe1502520d
5 changed files with 100 additions and 4 deletions

View File

@ -73,6 +73,12 @@ mobile:
build_modes: [debug, profile, release]
description: Mobile WebRTC Remote Desktop view
ui_surface: settings_page
logs:
enabled: true
release_tier: stable
build_modes: [debug, profile, release]
description: Mobile runtime logs view
ui_surface: settings_page
account_access:
enabled: true
release_tier: stable
@ -174,6 +180,12 @@ desktop:
build_modes: [debug, profile, release]
description: Desktop WebRTC Remote Desktop view
ui_surface: settings_page
logs:
enabled: true
release_tier: stable
build_modes: [debug, profile, release]
description: Desktop runtime logs view
ui_surface: settings_page
account_access:
enabled: true
release_tier: stable
@ -269,6 +281,12 @@ web:
build_modes: [debug, profile, release]
description: Web archived task management
ui_surface: settings_page
logs:
enabled: true
release_tier: stable
build_modes: [debug, profile, release]
description: Web runtime logs view
ui_surface: settings_page
account_access:
enabled: true
release_tier: stable

View File

@ -48,6 +48,7 @@ abstract final class UiFeatureKeys {
static const settingsGateway = 'settings.gateway';
static const settingsArchivedTasks = 'settings.archived_tasks';
static const settingsRemoteDesktop = 'settings.remote_desktop';
static const settingsLogs = 'settings.logs';
static const settingsAccountAccess = 'settings.account_access';
static const settingsVaultServer = 'settings.vault_server';
static const settingsExperimentalCanvas = 'settings.experimental_canvas';
@ -368,6 +369,7 @@ class UiFeatureAccess {
UiFeatureKeys.settingsGateway: SettingsTab.gateway,
UiFeatureKeys.settingsArchivedTasks: SettingsTab.archivedTasks,
UiFeatureKeys.settingsRemoteDesktop: SettingsTab.remoteDesktop,
UiFeatureKeys.settingsLogs: SettingsTab.logs,
};
bool isEnabledPath(String path) {

View File

@ -0,0 +1,67 @@
import 'package:flutter/material.dart';
import '../../app/app_controller.dart';
import '../../i18n/app_language.dart';
import '../../theme/app_palette.dart';
class SettingsLogsPanel extends StatefulWidget {
const SettingsLogsPanel({super.key, required this.controller});
final AppController controller;
@override
State<SettingsLogsPanel> createState() => _SettingsLogsPanelState();
}
class _SettingsLogsPanelState extends State<SettingsLogsPanel> {
@override
Widget build(BuildContext context) {
final palette = context.palette;
final theme = Theme.of(context);
return Column(
key: const ValueKey('settings-logs-panel'),
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Row(
children: [
Icon(Icons.terminal_outlined, color: palette.textSecondary),
const SizedBox(width: 10),
Expanded(
child: Text(
appText('运行日志', 'Runtime Logs'),
style: theme.textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w700,
),
),
),
],
),
const SizedBox(height: 12),
Container(
height: 400,
decoration: BoxDecoration(
color: palette.surfaceContainerHighest,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: palette.outlineVariant),
),
padding: const EdgeInsets.all(16),
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.monitor_heart_outlined, size: 48, color: palette.textSecondary.withOpacity(0.5)),
const SizedBox(height: 16),
Text(
appText('暂无日志数据', 'No log data available'),
style: theme.textTheme.bodyMedium?.copyWith(
color: palette.textSecondary,
),
),
],
),
),
),
],
);
}
}

View File

@ -17,6 +17,7 @@ import '../../widgets/surface_card.dart';
import 'settings_account_panel.dart';
import 'settings_about_panel.dart';
import 'settings_archived_tasks_panel.dart';
import 'settings_logs_panel.dart';
import 'settings_remote_desktop_panel.dart';
Future<Map<String, dynamic>> loadBridgeMetadataForSettingsAbout({
@ -529,6 +530,11 @@ class _SettingsPageState extends State<SettingsPage> {
key: const ValueKey('settings-remote-desktop-panel-card'),
child: SettingsRemoteDesktopPanel(controller: controller),
),
] else if (currentTab == SettingsTab.logs) ...[
SurfaceCard(
key: const ValueKey('settings-logs-panel-card'),
child: SettingsLogsPanel(controller: controller),
),
],
],
);
@ -564,9 +570,11 @@ class _SettingsTabSelector extends StatelessWidget {
icon: Icon(
tab == SettingsTab.remoteDesktop
? Icons.desktop_windows_outlined
: (tab == SettingsTab.archivedTasks
? Icons.inventory_2_outlined
: Icons.hub_outlined),
: (tab == SettingsTab.logs
? Icons.terminal_outlined
: (tab == SettingsTab.archivedTasks
? Icons.inventory_2_outlined
: Icons.hub_outlined)),
),
label: Text(tab.label),
),

View File

@ -149,13 +149,14 @@ extension AssistantModeCopy on AssistantMode {
};
}
enum SettingsTab { gateway, archivedTasks, remoteDesktop }
enum SettingsTab { gateway, archivedTasks, remoteDesktop, logs }
extension SettingsTabCopy on SettingsTab {
String get label => switch (this) {
SettingsTab.gateway => appText('集成', 'Integrations'),
SettingsTab.archivedTasks => appText('归档任务', 'Archived tasks'),
SettingsTab.remoteDesktop => appText('远程桌面', 'Remote Desktop'),
SettingsTab.logs => appText('运行日志', 'Runtime Logs'),
};
}