feat: 添加 MCP Server 导航项
- 在 WorkspaceDestination 枚举中添加 mcpServer - 更新侧边栏顺序:助手→任务→技能→节点→代理→MCP Server | ClawHub→密钥→AI Gateway - 创建 McpServerPage 展示 MCP 服务器连接状态 - 更新 app_shell.dart 路由映射
This commit is contained in:
parent
99c6aa9115
commit
e50bef97e4
@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
||||
import '../features/ai_gateway/ai_gateway_page.dart';
|
||||
import '../features/assistant/assistant_page.dart';
|
||||
import '../features/claw_hub/claw_hub_page.dart';
|
||||
import '../features/mcp_server/mcp_server_page.dart';
|
||||
import '../features/mobile/ios_mobile_shell.dart';
|
||||
import '../features/modules/modules_page.dart';
|
||||
import '../features/secrets/secrets_page.dart';
|
||||
@ -340,6 +341,10 @@ class _AppShellState extends State<AppShell> {
|
||||
onOpenDetail: onOpenDetail,
|
||||
initialTab: ModulesTab.agents,
|
||||
),
|
||||
WorkspaceDestination.mcpServer => McpServerPage(
|
||||
controller: widget.controller,
|
||||
onOpenDetail: onOpenDetail,
|
||||
),
|
||||
WorkspaceDestination.clawHub => ClawHubPage(
|
||||
controller: widget.controller,
|
||||
onOpenDetail: onOpenDetail,
|
||||
|
||||
172
lib/features/mcp_server/mcp_server_page.dart
Normal file
172
lib/features/mcp_server/mcp_server_page.dart
Normal file
@ -0,0 +1,172 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../app/app_controller.dart';
|
||||
import '../../i18n/app_language.dart';
|
||||
import '../../models/app_models.dart';
|
||||
import '../../runtime/runtime_models.dart';
|
||||
import '../../widgets/surface_card.dart';
|
||||
import '../../widgets/top_bar.dart';
|
||||
|
||||
class McpServerPage extends StatelessWidget {
|
||||
const McpServerPage({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.onOpenDetail,
|
||||
});
|
||||
|
||||
final AppController controller;
|
||||
final ValueChanged<DetailPanelData> onOpenDetail;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final items = controller.connectors;
|
||||
|
||||
return AnimatedBuilder(
|
||||
animation: controller,
|
||||
builder: (context, _) {
|
||||
return SingleChildScrollView(
|
||||
padding: const EdgeInsets.fromLTRB(32, 32, 32, 8),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TopBar(
|
||||
title: 'MCP Server',
|
||||
subtitle: appText(
|
||||
'管理 MCP 服务器连接与工具配置。',
|
||||
'Manage MCP server connections and tool configurations.',
|
||||
),
|
||||
trailing: Wrap(
|
||||
spacing: 12,
|
||||
runSpacing: 12,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 220,
|
||||
child: TextField(
|
||||
decoration: InputDecoration(
|
||||
hintText: appText('搜索服务器', 'Search servers'),
|
||||
prefixIcon: Icon(Icons.search_rounded),
|
||||
),
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () async {
|
||||
await controller.connectorsController.refresh();
|
||||
},
|
||||
icon: const Icon(Icons.refresh_rounded),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
if (items.isEmpty)
|
||||
SurfaceCard(
|
||||
child: Text(
|
||||
controller.connection.status ==
|
||||
RuntimeConnectionStatus.connected
|
||||
? appText(
|
||||
'当前没有连接的 MCP 服务器。',
|
||||
'No MCP servers connected.',
|
||||
)
|
||||
: appText(
|
||||
'连接 Gateway 后可查看 MCP 服务器。',
|
||||
'Connect a gateway to view MCP servers.',
|
||||
),
|
||||
),
|
||||
)
|
||||
else
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: items
|
||||
.map(
|
||||
(connector) => Padding(
|
||||
padding: const EdgeInsets.only(bottom: 12),
|
||||
child: SurfaceCard(
|
||||
onTap: () => onOpenDetail(
|
||||
DetailPanelData(
|
||||
title: connector.label,
|
||||
subtitle: appText('连接器', 'Connector'),
|
||||
icon: Icons.dns_rounded,
|
||||
status: StatusInfo(
|
||||
connector.status,
|
||||
connector.connected
|
||||
? StatusTone.success
|
||||
: StatusTone.neutral,
|
||||
),
|
||||
description: connector.detailLabel,
|
||||
meta: connector.meta,
|
||||
actions: [appText('配置', 'Configure')],
|
||||
sections: [
|
||||
DetailSection(
|
||||
title: appText('详情', 'Details'),
|
||||
items: [
|
||||
DetailItem(
|
||||
label: appText('ID', 'ID'),
|
||||
value: connector.id,
|
||||
),
|
||||
DetailItem(
|
||||
label: appText('状态', 'Status'),
|
||||
value: connector.status,
|
||||
),
|
||||
DetailItem(
|
||||
label: appText('已配置', 'Configured'),
|
||||
value: connector.configured
|
||||
? appText('是', 'Yes')
|
||||
: appText('否', 'No'),
|
||||
),
|
||||
DetailItem(
|
||||
label: appText('已启用', 'Enabled'),
|
||||
value: connector.enabled
|
||||
? appText('是', 'Yes')
|
||||
: appText('否', 'No'),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 4,
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
connector.label,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleMedium,
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
Text(
|
||||
connector.detailLabel,
|
||||
style:
|
||||
Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
connector.connected
|
||||
? appText('已连接', 'Connected')
|
||||
: appText('未连接', 'Disconnected'),
|
||||
),
|
||||
),
|
||||
const Icon(Icons.chevron_right_rounded),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -2,18 +2,19 @@ import 'package:flutter/material.dart';
|
||||
|
||||
import '../i18n/app_language.dart';
|
||||
|
||||
enum WorkspaceDestination {
|
||||
enum WorkspaceDestination {
|
||||
assistant,
|
||||
tasks,
|
||||
skills,
|
||||
nodes,
|
||||
agents,
|
||||
mcpServer,
|
||||
clawHub,
|
||||
secrets,
|
||||
aiGateway,
|
||||
settings,
|
||||
account,
|
||||
}
|
||||
}
|
||||
|
||||
extension WorkspaceDestinationCopy on WorkspaceDestination {
|
||||
String get label => switch (this) {
|
||||
@ -22,6 +23,7 @@ extension WorkspaceDestinationCopy on WorkspaceDestination {
|
||||
WorkspaceDestination.skills => appText('技能', 'Skills'),
|
||||
WorkspaceDestination.nodes => appText('节点', 'Nodes'),
|
||||
WorkspaceDestination.agents => appText('代理', 'Agents'),
|
||||
WorkspaceDestination.mcpServer => 'MCP Server',
|
||||
WorkspaceDestination.clawHub => 'ClawHub',
|
||||
WorkspaceDestination.secrets => appText('密钥', 'Secrets'),
|
||||
WorkspaceDestination.aiGateway => 'AI Gateway',
|
||||
@ -35,6 +37,7 @@ extension WorkspaceDestinationCopy on WorkspaceDestination {
|
||||
WorkspaceDestination.skills => Icons.auto_awesome_rounded,
|
||||
WorkspaceDestination.nodes => Icons.developer_board_rounded,
|
||||
WorkspaceDestination.agents => Icons.hub_rounded,
|
||||
WorkspaceDestination.mcpServer => Icons.dns_rounded,
|
||||
WorkspaceDestination.clawHub => Icons.extension_rounded,
|
||||
WorkspaceDestination.secrets => Icons.key_rounded,
|
||||
WorkspaceDestination.aiGateway => Icons.smart_toy_rounded,
|
||||
@ -63,6 +66,10 @@ extension WorkspaceDestinationCopy on WorkspaceDestination {
|
||||
'管理代理实例,配置行为与能力。',
|
||||
'Manage agent instances, configure behaviors and capabilities.',
|
||||
),
|
||||
WorkspaceDestination.mcpServer => appText(
|
||||
'管理 MCP 服务器连接与工具配置。',
|
||||
'Manage MCP server connections and tool configurations.',
|
||||
),
|
||||
WorkspaceDestination.clawHub => appText(
|
||||
'浏览和安装技能包、代理模板与连接器。',
|
||||
'Browse and install skill packages, agent templates and connectors.',
|
||||
|
||||
@ -43,6 +43,7 @@ class SidebarNavigation extends StatelessWidget {
|
||||
WorkspaceDestination.skills,
|
||||
WorkspaceDestination.nodes,
|
||||
WorkspaceDestination.agents,
|
||||
WorkspaceDestination.mcpServer,
|
||||
WorkspaceDestination.clawHub,
|
||||
WorkspaceDestination.secrets,
|
||||
WorkspaceDestination.aiGateway,
|
||||
@ -258,6 +259,7 @@ class _SidebarNavItemState extends State<SidebarNavItem> {
|
||||
WorkspaceDestination.skills => Icons.auto_awesome_rounded,
|
||||
WorkspaceDestination.nodes => Icons.developer_board_rounded,
|
||||
WorkspaceDestination.agents => Icons.hub_rounded,
|
||||
WorkspaceDestination.mcpServer => Icons.dns_rounded,
|
||||
WorkspaceDestination.clawHub => Icons.extension_rounded,
|
||||
WorkspaceDestination.secrets => Icons.key_rounded,
|
||||
WorkspaceDestination.aiGateway => Icons.smart_toy_rounded,
|
||||
@ -273,6 +275,7 @@ class _SidebarNavItemState extends State<SidebarNavItem> {
|
||||
WorkspaceDestination.skills => appText('技能', 'Skills'),
|
||||
WorkspaceDestination.nodes => appText('节点', 'Nodes'),
|
||||
WorkspaceDestination.agents => appText('代理', 'Agents'),
|
||||
WorkspaceDestination.mcpServer => 'MCP Server',
|
||||
WorkspaceDestination.clawHub => 'ClawHub',
|
||||
WorkspaceDestination.secrets => appText('密钥', 'Secrets'),
|
||||
WorkspaceDestination.aiGateway => 'AI Gateway',
|
||||
|
||||
Loading…
Reference in New Issue
Block a user