737 lines
21 KiB
Dart
737 lines
21 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
import '../i18n/app_language.dart';
|
|
|
|
enum WorkspaceDestination {
|
|
assistant,
|
|
tasks,
|
|
skills,
|
|
nodes,
|
|
agents,
|
|
mcpServer,
|
|
clawHub,
|
|
secrets,
|
|
aiGateway,
|
|
settings,
|
|
account,
|
|
}
|
|
|
|
extension WorkspaceDestinationCopy on WorkspaceDestination {
|
|
String get label => switch (this) {
|
|
WorkspaceDestination.assistant => appText('助手', 'Assistant'),
|
|
WorkspaceDestination.tasks => appText('任务', 'Tasks'),
|
|
WorkspaceDestination.skills => appText('技能', 'Skills'),
|
|
WorkspaceDestination.nodes => appText('节点', 'Nodes'),
|
|
WorkspaceDestination.agents => appText('代理', 'Agents'),
|
|
WorkspaceDestination.mcpServer => 'MCP Hub',
|
|
WorkspaceDestination.clawHub => 'ClawHub',
|
|
WorkspaceDestination.secrets => appText('密钥', 'Secrets'),
|
|
WorkspaceDestination.aiGateway => 'LLM API',
|
|
WorkspaceDestination.settings => appText('设置', 'Settings'),
|
|
WorkspaceDestination.account => appText('账号', 'Account'),
|
|
};
|
|
|
|
IconData get icon => switch (this) {
|
|
WorkspaceDestination.assistant => Icons.chat_bubble_outline_rounded,
|
|
WorkspaceDestination.tasks => Icons.layers_rounded,
|
|
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,
|
|
WorkspaceDestination.settings => Icons.tune_rounded,
|
|
WorkspaceDestination.account => Icons.account_circle_rounded,
|
|
};
|
|
|
|
String get description => switch (this) {
|
|
WorkspaceDestination.assistant => appText(
|
|
'AI 主入口,优先承接自然输入和高频工作发起。',
|
|
'Primary AI entry point for natural input and frequent task starts.',
|
|
),
|
|
WorkspaceDestination.tasks => appText(
|
|
'任务队列、运行态、失败项和调度历史的统一视图。',
|
|
'Unified view for queue, running, failed, and history.',
|
|
),
|
|
WorkspaceDestination.skills => appText(
|
|
'管理技能包与能力扩展,浏览和安装 ClawHub 技能。',
|
|
'Manage skill packages and extensions, browse and install from ClawHub.',
|
|
),
|
|
WorkspaceDestination.nodes => appText(
|
|
'管理边缘节点与实例,监控运行状态与负载。',
|
|
'Manage edge nodes and instances, monitor status and load.',
|
|
),
|
|
WorkspaceDestination.agents => appText(
|
|
'管理代理实例,配置行为与能力。',
|
|
'Manage agent instances, configure behaviors and capabilities.',
|
|
),
|
|
WorkspaceDestination.mcpServer => appText(
|
|
'管理 MCP Hub 连接与工具配置。',
|
|
'Manage MCP Hub connections and tool configurations.',
|
|
),
|
|
WorkspaceDestination.clawHub => appText(
|
|
'浏览和安装技能包、代理模板与连接器。',
|
|
'Browse and install skill packages, agent templates and connectors.',
|
|
),
|
|
WorkspaceDestination.secrets => appText(
|
|
'密钥与 Vault 配置统一收口到设置中心。',
|
|
'Secrets and Vault configuration now live in the Settings center.',
|
|
),
|
|
WorkspaceDestination.aiGateway => appText(
|
|
'LLM API 配置统一收口到设置中心。',
|
|
'LLM API configuration now lives in the Settings center.',
|
|
),
|
|
WorkspaceDestination.settings => appText(
|
|
'全局配置中心,只负责系统设置与诊断,不承担业务模块入口。',
|
|
'Global settings and diagnostics, separated from business modules.',
|
|
),
|
|
WorkspaceDestination.account => appText(
|
|
'用户身份、工作区切换与登录会话管理。',
|
|
'Identity, workspace switching, and session management.',
|
|
),
|
|
};
|
|
|
|
static WorkspaceDestination? fromJsonValue(String? value) {
|
|
if (value == null || value.trim().isEmpty) {
|
|
return null;
|
|
}
|
|
for (final item in WorkspaceDestination.values) {
|
|
if (item.name == value.trim()) {
|
|
return item;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
enum AssistantFocusEntry {
|
|
tasks,
|
|
skills,
|
|
nodes,
|
|
agents,
|
|
mcpServer,
|
|
clawHub,
|
|
secrets,
|
|
aiGateway,
|
|
settings,
|
|
language,
|
|
theme,
|
|
}
|
|
|
|
extension AssistantFocusEntryCopy on AssistantFocusEntry {
|
|
String get label => switch (this) {
|
|
AssistantFocusEntry.tasks => appText('任务', 'Tasks'),
|
|
AssistantFocusEntry.skills => appText('技能', 'Skills'),
|
|
AssistantFocusEntry.nodes => appText('节点', 'Nodes'),
|
|
AssistantFocusEntry.agents => appText('代理', 'Agents'),
|
|
AssistantFocusEntry.mcpServer => 'MCP Hub',
|
|
AssistantFocusEntry.clawHub => 'ClawHub',
|
|
AssistantFocusEntry.secrets => appText('密钥', 'Secrets'),
|
|
AssistantFocusEntry.aiGateway => 'LLM API',
|
|
AssistantFocusEntry.settings => appText('设置', 'Settings'),
|
|
AssistantFocusEntry.language => appText('语言', 'Language'),
|
|
AssistantFocusEntry.theme => appText('主题/亮度', 'Theme / Brightness'),
|
|
};
|
|
|
|
IconData get icon => switch (this) {
|
|
AssistantFocusEntry.tasks => Icons.layers_rounded,
|
|
AssistantFocusEntry.skills => Icons.auto_awesome_rounded,
|
|
AssistantFocusEntry.nodes => Icons.developer_board_rounded,
|
|
AssistantFocusEntry.agents => Icons.hub_rounded,
|
|
AssistantFocusEntry.mcpServer => Icons.dns_rounded,
|
|
AssistantFocusEntry.clawHub => Icons.extension_rounded,
|
|
AssistantFocusEntry.secrets => Icons.key_rounded,
|
|
AssistantFocusEntry.aiGateway => Icons.smart_toy_rounded,
|
|
AssistantFocusEntry.settings => Icons.tune_rounded,
|
|
AssistantFocusEntry.language => Icons.translate_rounded,
|
|
AssistantFocusEntry.theme => Icons.brightness_6_rounded,
|
|
};
|
|
|
|
String get description => switch (this) {
|
|
AssistantFocusEntry.tasks => appText(
|
|
'任务队列、运行态、失败项和调度历史的统一视图。',
|
|
'Unified view for queue, running, failed, and history.',
|
|
),
|
|
AssistantFocusEntry.skills => appText(
|
|
'管理技能包与能力扩展,浏览和安装 ClawHub 技能。',
|
|
'Manage skill packages and extensions, browse and install from ClawHub.',
|
|
),
|
|
AssistantFocusEntry.nodes => appText(
|
|
'管理边缘节点与实例,监控运行状态与负载。',
|
|
'Manage edge nodes and instances, monitor status and load.',
|
|
),
|
|
AssistantFocusEntry.agents => appText(
|
|
'管理代理实例,配置行为与能力。',
|
|
'Manage agent instances, configure behaviors and capabilities.',
|
|
),
|
|
AssistantFocusEntry.mcpServer => appText(
|
|
'管理 MCP Hub 连接与工具配置。',
|
|
'Manage MCP Hub connections and tool configurations.',
|
|
),
|
|
AssistantFocusEntry.clawHub => appText(
|
|
'浏览和安装技能包、代理模板与连接器。',
|
|
'Browse and install skill packages, agent templates and connectors.',
|
|
),
|
|
AssistantFocusEntry.secrets => appText(
|
|
'密钥与 Vault 配置统一收口到设置中心。',
|
|
'Secrets and Vault configuration now live in the Settings center.',
|
|
),
|
|
AssistantFocusEntry.aiGateway => appText(
|
|
'LLM API 配置统一收口到设置中心。',
|
|
'LLM API configuration now lives in the Settings center.',
|
|
),
|
|
AssistantFocusEntry.settings => appText(
|
|
'全局配置中心,只负责系统设置与诊断,不承担业务模块入口。',
|
|
'Global settings and diagnostics, separated from business modules.',
|
|
),
|
|
AssistantFocusEntry.language => appText(
|
|
'快速切换中英文界面语言,无需先进入设置页。',
|
|
'Switch the interface language quickly without opening Settings first.',
|
|
),
|
|
AssistantFocusEntry.theme => appText(
|
|
'快速切换浅色/深色亮度模式,方便在当前上下文立即调整外观。',
|
|
'Switch light and dark appearance modes directly from the current context.',
|
|
),
|
|
};
|
|
|
|
WorkspaceDestination? get destination => switch (this) {
|
|
AssistantFocusEntry.tasks => WorkspaceDestination.tasks,
|
|
AssistantFocusEntry.skills => WorkspaceDestination.skills,
|
|
AssistantFocusEntry.nodes => WorkspaceDestination.nodes,
|
|
AssistantFocusEntry.agents => WorkspaceDestination.agents,
|
|
AssistantFocusEntry.mcpServer => WorkspaceDestination.mcpServer,
|
|
AssistantFocusEntry.clawHub => WorkspaceDestination.clawHub,
|
|
AssistantFocusEntry.secrets => WorkspaceDestination.secrets,
|
|
AssistantFocusEntry.aiGateway => WorkspaceDestination.aiGateway,
|
|
AssistantFocusEntry.settings => WorkspaceDestination.settings,
|
|
AssistantFocusEntry.language => null,
|
|
AssistantFocusEntry.theme => null,
|
|
};
|
|
|
|
bool get opensSettingsPage =>
|
|
this == AssistantFocusEntry.language ||
|
|
this == AssistantFocusEntry.theme ||
|
|
this == AssistantFocusEntry.settings;
|
|
|
|
static AssistantFocusEntry? fromJsonValue(String? value) {
|
|
if (value == null || value.trim().isEmpty) {
|
|
return null;
|
|
}
|
|
for (final item in AssistantFocusEntry.values) {
|
|
if (item.name == value.trim()) {
|
|
return item;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
static AssistantFocusEntry fromDestination(WorkspaceDestination destination) {
|
|
return switch (destination) {
|
|
WorkspaceDestination.tasks => AssistantFocusEntry.tasks,
|
|
WorkspaceDestination.skills => AssistantFocusEntry.skills,
|
|
WorkspaceDestination.nodes => AssistantFocusEntry.nodes,
|
|
WorkspaceDestination.agents => AssistantFocusEntry.agents,
|
|
WorkspaceDestination.mcpServer => AssistantFocusEntry.mcpServer,
|
|
WorkspaceDestination.clawHub => AssistantFocusEntry.clawHub,
|
|
WorkspaceDestination.secrets => AssistantFocusEntry.secrets,
|
|
WorkspaceDestination.aiGateway => AssistantFocusEntry.aiGateway,
|
|
WorkspaceDestination.settings => AssistantFocusEntry.settings,
|
|
WorkspaceDestination.assistant || WorkspaceDestination.account =>
|
|
throw ArgumentError.value(
|
|
destination,
|
|
'destination',
|
|
'Focused assistant entries only support pinnable workspace targets.',
|
|
),
|
|
};
|
|
}
|
|
}
|
|
|
|
const List<AssistantFocusEntry> kAssistantNavigationDestinationDefaults =
|
|
<AssistantFocusEntry>[];
|
|
|
|
const List<AssistantFocusEntry> kAssistantNavigationDestinationCandidates =
|
|
<AssistantFocusEntry>[
|
|
AssistantFocusEntry.tasks,
|
|
AssistantFocusEntry.skills,
|
|
AssistantFocusEntry.nodes,
|
|
AssistantFocusEntry.agents,
|
|
AssistantFocusEntry.mcpServer,
|
|
AssistantFocusEntry.clawHub,
|
|
AssistantFocusEntry.secrets,
|
|
AssistantFocusEntry.aiGateway,
|
|
AssistantFocusEntry.settings,
|
|
AssistantFocusEntry.language,
|
|
AssistantFocusEntry.theme,
|
|
];
|
|
|
|
List<AssistantFocusEntry> normalizeAssistantNavigationDestinations(
|
|
Iterable<AssistantFocusEntry> destinations,
|
|
) {
|
|
final allowed = kAssistantNavigationDestinationCandidates.toSet();
|
|
final seen = <AssistantFocusEntry>{};
|
|
final normalized = <AssistantFocusEntry>[];
|
|
for (final destination in destinations) {
|
|
if (!allowed.contains(destination) || !seen.add(destination)) {
|
|
continue;
|
|
}
|
|
normalized.add(destination);
|
|
}
|
|
return normalized;
|
|
}
|
|
|
|
enum StatusTone { neutral, accent, success, warning, danger }
|
|
|
|
class StatusInfo {
|
|
const StatusInfo(this.label, this.tone);
|
|
|
|
final String label;
|
|
final StatusTone tone;
|
|
}
|
|
|
|
enum AppSidebarState { expanded, collapsed, hidden }
|
|
|
|
enum AssistantMode { code, office }
|
|
|
|
extension AssistantModeCopy on AssistantMode {
|
|
String get label => switch (this) {
|
|
AssistantMode.code => appText('代码开发', 'Code'),
|
|
AssistantMode.office => appText('日常办公', 'Office'),
|
|
};
|
|
}
|
|
|
|
enum TasksTab { queue, running, history, failed, scheduled }
|
|
|
|
extension TasksTabCopy on TasksTab {
|
|
String get label => switch (this) {
|
|
TasksTab.queue => appText('队列', 'Queue'),
|
|
TasksTab.running => appText('运行中', 'Running'),
|
|
TasksTab.history => appText('历史', 'History'),
|
|
TasksTab.failed => appText('失败', 'Failed'),
|
|
TasksTab.scheduled => appText('计划中', 'Scheduled'),
|
|
};
|
|
}
|
|
|
|
enum ModulesTab { gateway, nodes, agents, skills, clawHub, connectors }
|
|
|
|
extension ModulesTabCopy on ModulesTab {
|
|
String get label => switch (this) {
|
|
ModulesTab.gateway => appText('网关', 'Gateway'),
|
|
ModulesTab.nodes => appText('节点', 'Nodes'),
|
|
ModulesTab.agents => appText('代理', 'Agents'),
|
|
ModulesTab.skills => appText('技能', 'Skills'),
|
|
ModulesTab.clawHub => 'ClawHub',
|
|
ModulesTab.connectors => appText('连接器', 'Connectors'),
|
|
};
|
|
}
|
|
|
|
enum SecretsTab { vault, localStore, providers, audit }
|
|
|
|
extension SecretsTabCopy on SecretsTab {
|
|
String get label => switch (this) {
|
|
SecretsTab.vault => 'Vault',
|
|
SecretsTab.localStore => appText('本地存储', 'Local Store'),
|
|
SecretsTab.providers => appText('提供方', 'Providers'),
|
|
SecretsTab.audit => appText('审计', 'Audit'),
|
|
};
|
|
}
|
|
|
|
enum SettingsTab {
|
|
general,
|
|
workspace,
|
|
gateway,
|
|
agents,
|
|
appearance,
|
|
diagnostics,
|
|
experimental,
|
|
about,
|
|
}
|
|
|
|
extension SettingsTabCopy on SettingsTab {
|
|
String get label => switch (this) {
|
|
SettingsTab.general => appText('通用', 'General'),
|
|
SettingsTab.workspace => appText('工作区', 'Workspace'),
|
|
SettingsTab.gateway => appText('集成', 'Integrations'),
|
|
SettingsTab.agents => appText('多 Agent', 'Multi-Agent'),
|
|
SettingsTab.appearance => appText('外观', 'Appearance'),
|
|
SettingsTab.diagnostics => appText('诊断', 'Diagnostics'),
|
|
SettingsTab.experimental => appText('实验特性', 'Experimental'),
|
|
SettingsTab.about => appText('关于', 'About'),
|
|
};
|
|
}
|
|
|
|
enum AiGatewayTab { models, agents, endpoints, tools }
|
|
|
|
extension AiGatewayTabCopy on AiGatewayTab {
|
|
String get label => switch (this) {
|
|
AiGatewayTab.models => appText('模型', 'Models'),
|
|
AiGatewayTab.agents => appText('代理', 'Agents'),
|
|
AiGatewayTab.endpoints => appText('端点', 'Endpoints'),
|
|
AiGatewayTab.tools => appText('工具', 'Tools'),
|
|
};
|
|
}
|
|
|
|
enum SettingsDetailPage {
|
|
gatewayConnection,
|
|
aiGatewayIntegration,
|
|
vaultProvider,
|
|
externalAgents,
|
|
diagnosticsAdvanced,
|
|
}
|
|
|
|
extension SettingsDetailPageCopy on SettingsDetailPage {
|
|
String get label => switch (this) {
|
|
SettingsDetailPage.gatewayConnection => appText(
|
|
'Gateway 连接参数',
|
|
'Gateway Connection',
|
|
),
|
|
SettingsDetailPage.aiGatewayIntegration => appText(
|
|
'LLM 接入点',
|
|
'LLM Endpoints',
|
|
),
|
|
SettingsDetailPage.vaultProvider => appText(
|
|
'Vault 提供方参数',
|
|
'Vault Provider',
|
|
),
|
|
SettingsDetailPage.externalAgents => appText(
|
|
'多 Agent 协作参数',
|
|
'External Agents',
|
|
),
|
|
SettingsDetailPage.diagnosticsAdvanced => appText(
|
|
'高级诊断参数',
|
|
'Advanced Diagnostics',
|
|
),
|
|
};
|
|
|
|
SettingsTab get tab => switch (this) {
|
|
SettingsDetailPage.gatewayConnection ||
|
|
SettingsDetailPage.aiGatewayIntegration ||
|
|
SettingsDetailPage.vaultProvider => SettingsTab.gateway,
|
|
SettingsDetailPage.externalAgents => SettingsTab.agents,
|
|
SettingsDetailPage.diagnosticsAdvanced => SettingsTab.diagnostics,
|
|
};
|
|
}
|
|
|
|
@immutable
|
|
class SettingsNavigationContext {
|
|
const SettingsNavigationContext({
|
|
required this.rootLabel,
|
|
required this.destination,
|
|
this.sectionLabel,
|
|
this.modulesTab,
|
|
this.secretsTab,
|
|
this.aiGatewayTab,
|
|
this.settingsTab,
|
|
this.gatewayProfileIndex,
|
|
this.prefersGatewaySetupCode,
|
|
});
|
|
|
|
final String rootLabel;
|
|
final WorkspaceDestination destination;
|
|
final String? sectionLabel;
|
|
final ModulesTab? modulesTab;
|
|
final SecretsTab? secretsTab;
|
|
final AiGatewayTab? aiGatewayTab;
|
|
final SettingsTab? settingsTab;
|
|
final int? gatewayProfileIndex;
|
|
final bool? prefersGatewaySetupCode;
|
|
}
|
|
|
|
enum AccountTab { profile, workspace, sessions }
|
|
|
|
extension AccountTabCopy on AccountTab {
|
|
String get label => switch (this) {
|
|
AccountTab.profile => appText('资料', 'Profile'),
|
|
AccountTab.workspace => appText('工作区', 'Workspace'),
|
|
AccountTab.sessions => appText('会话', 'Sessions'),
|
|
};
|
|
}
|
|
|
|
class QuickAction {
|
|
const QuickAction({
|
|
required this.title,
|
|
required this.icon,
|
|
required this.caption,
|
|
});
|
|
|
|
final String title;
|
|
final IconData icon;
|
|
final String caption;
|
|
}
|
|
|
|
class RecentSession {
|
|
const RecentSession({
|
|
required this.title,
|
|
required this.timestamp,
|
|
required this.summary,
|
|
});
|
|
|
|
final String title;
|
|
final String timestamp;
|
|
final String summary;
|
|
}
|
|
|
|
class MetricSummary {
|
|
const MetricSummary({
|
|
required this.label,
|
|
required this.value,
|
|
required this.caption,
|
|
required this.icon,
|
|
this.status,
|
|
});
|
|
|
|
final String label;
|
|
final String value;
|
|
final String caption;
|
|
final IconData icon;
|
|
final StatusInfo? status;
|
|
}
|
|
|
|
class TaskSummary {
|
|
const TaskSummary({
|
|
required this.name,
|
|
required this.owner,
|
|
required this.status,
|
|
required this.startedAt,
|
|
required this.duration,
|
|
required this.surface,
|
|
});
|
|
|
|
final String name;
|
|
final String owner;
|
|
final StatusInfo status;
|
|
final String startedAt;
|
|
final String duration;
|
|
final String surface;
|
|
}
|
|
|
|
class ModuleSummary {
|
|
const ModuleSummary({
|
|
required this.name,
|
|
required this.description,
|
|
required this.status,
|
|
required this.meta,
|
|
required this.icon,
|
|
});
|
|
|
|
final String name;
|
|
final String description;
|
|
final StatusInfo status;
|
|
final String meta;
|
|
final IconData icon;
|
|
}
|
|
|
|
class NodeSummary {
|
|
const NodeSummary({
|
|
required this.name,
|
|
required this.type,
|
|
required this.region,
|
|
required this.heartbeat,
|
|
required this.load,
|
|
required this.status,
|
|
});
|
|
|
|
final String name;
|
|
final String type;
|
|
final String region;
|
|
final String heartbeat;
|
|
final String load;
|
|
final StatusInfo status;
|
|
}
|
|
|
|
class AgentSummary {
|
|
const AgentSummary({
|
|
required this.name,
|
|
required this.description,
|
|
required this.status,
|
|
required this.lastRun,
|
|
required this.capabilities,
|
|
});
|
|
|
|
final String name;
|
|
final String description;
|
|
final StatusInfo status;
|
|
final String lastRun;
|
|
final List<String> capabilities;
|
|
}
|
|
|
|
class SkillSummary {
|
|
const SkillSummary({
|
|
required this.name,
|
|
required this.type,
|
|
required this.source,
|
|
required this.status,
|
|
required this.version,
|
|
required this.modules,
|
|
});
|
|
|
|
final String name;
|
|
final String type;
|
|
final String source;
|
|
final StatusInfo status;
|
|
final String version;
|
|
final String modules;
|
|
}
|
|
|
|
class ConnectorSummary {
|
|
const ConnectorSummary({
|
|
required this.name,
|
|
required this.description,
|
|
required this.status,
|
|
required this.lastSync,
|
|
required this.permission,
|
|
});
|
|
|
|
final String name;
|
|
final String description;
|
|
final StatusInfo status;
|
|
final String lastSync;
|
|
final String permission;
|
|
}
|
|
|
|
class SecretSummary {
|
|
const SecretSummary({
|
|
required this.name,
|
|
required this.scope,
|
|
required this.status,
|
|
required this.updatedAt,
|
|
required this.provider,
|
|
});
|
|
|
|
final String name;
|
|
final String scope;
|
|
final StatusInfo status;
|
|
final String updatedAt;
|
|
final String provider;
|
|
}
|
|
|
|
class SecretReference {
|
|
const SecretReference({
|
|
required this.name,
|
|
required this.provider,
|
|
required this.module,
|
|
required this.status,
|
|
required this.maskedValue,
|
|
});
|
|
|
|
final String name;
|
|
final String provider;
|
|
final String module;
|
|
final StatusInfo status;
|
|
final String maskedValue;
|
|
}
|
|
|
|
class ProviderSummary {
|
|
const ProviderSummary({
|
|
required this.name,
|
|
required this.description,
|
|
required this.status,
|
|
required this.capabilities,
|
|
});
|
|
|
|
final String name;
|
|
final String description;
|
|
final StatusInfo status;
|
|
final List<String> capabilities;
|
|
}
|
|
|
|
class AuditSummary {
|
|
const AuditSummary({
|
|
required this.time,
|
|
required this.action,
|
|
required this.provider,
|
|
required this.target,
|
|
required this.module,
|
|
required this.status,
|
|
});
|
|
|
|
final String time;
|
|
final String action;
|
|
final String provider;
|
|
final String target;
|
|
final String module;
|
|
final StatusInfo status;
|
|
}
|
|
|
|
class SettingSummary {
|
|
const SettingSummary({
|
|
required this.title,
|
|
required this.description,
|
|
required this.value,
|
|
});
|
|
|
|
final String title;
|
|
final String description;
|
|
final String value;
|
|
}
|
|
|
|
class WorkspaceProfile {
|
|
const WorkspaceProfile({
|
|
required this.name,
|
|
required this.role,
|
|
required this.members,
|
|
required this.region,
|
|
});
|
|
|
|
final String name;
|
|
final String role;
|
|
final String members;
|
|
final String region;
|
|
}
|
|
|
|
class DetailPanelData {
|
|
const DetailPanelData({
|
|
required this.title,
|
|
required this.subtitle,
|
|
required this.icon,
|
|
required this.status,
|
|
required this.description,
|
|
required this.meta,
|
|
required this.sections,
|
|
required this.actions,
|
|
});
|
|
|
|
final String title;
|
|
final String subtitle;
|
|
final IconData icon;
|
|
final StatusInfo status;
|
|
final String description;
|
|
final List<String> meta;
|
|
final List<DetailSection> sections;
|
|
final List<String> actions;
|
|
}
|
|
|
|
class DetailSection {
|
|
const DetailSection({required this.title, required this.items});
|
|
|
|
final String title;
|
|
final List<DetailItem> items;
|
|
}
|
|
|
|
class DetailItem {
|
|
const DetailItem({required this.label, required this.value});
|
|
|
|
final String label;
|
|
final String value;
|
|
}
|
|
|
|
class CommandEntry {
|
|
const CommandEntry({
|
|
required this.title,
|
|
required this.subtitle,
|
|
required this.icon,
|
|
required this.keyword,
|
|
this.shortcut,
|
|
this.destination,
|
|
this.detail,
|
|
});
|
|
|
|
final String title;
|
|
final String subtitle;
|
|
final IconData icon;
|
|
final String keyword;
|
|
final String? shortcut;
|
|
final WorkspaceDestination? destination;
|
|
final DetailPanelData? detail;
|
|
}
|