mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-03-07 16:41:06 +08:00
feat: add queue management and terminal dashboard documentation in Chinese
- Introduced comprehensive documentation for the queue management feature, detailing its pain points, core functionalities, and component structure. - Added terminal dashboard documentation, highlighting its layout, core features, and usage examples. - Created an index page in Chinese for Claude Code Workflow, summarizing its purpose and core features, along with quick links to installation and guides.
This commit is contained in:
607
docs/zh-CN/features/dashboard.md
Normal file
607
docs/zh-CN/features/dashboard.md
Normal file
@@ -0,0 +1,607 @@
|
||||
# 仪表板
|
||||
|
||||
## 一句话概述
|
||||
**仪表板通过直观的基于小部件的界面,提供项目工作流状态、统计信息和最近活动的概览。**
|
||||
|
||||
---
|
||||
|
||||
## 解决的痛点
|
||||
|
||||
| 痛点 | 当前状态 | 仪表板解决方案 |
|
||||
|------|----------|----------------|
|
||||
| **项目可见性不足** | 无法查看整体项目健康状况 | 带有技术栈和开发索引的项目信息横幅 |
|
||||
| **指标分散** | 统计信息分布在多个位置 | 集中式统计数据,带有迷你趋势图 |
|
||||
| **工作流状态未知** | 难以跟踪会话进度 | 带有状态细分的饼图 |
|
||||
| **最近工作丢失** | 无法快速访问活动会话 | 带有任务详情的会话轮播 |
|
||||
| **索引状态不明确** | 不知道代码是否已索引 | 实时索引状态指示器 |
|
||||
|
||||
---
|
||||
|
||||
## 概述
|
||||
|
||||
**位置**: `ccw/frontend/src/pages/HomePage.tsx`
|
||||
|
||||
**用途**: 仪表板主页,提供项目概览、统计信息、工作流状态和最近活动监控。
|
||||
|
||||
**访问**: 导航 → 仪表板(默认首页,路径为 `/`)
|
||||
|
||||
**布局**:
|
||||
```
|
||||
+--------------------------------------------------------------------------+
|
||||
| 仪表板头部(标题 + 刷新) |
|
||||
+--------------------------------------------------------------------------+
|
||||
| WorkflowTaskWidget(组合卡片) |
|
||||
| +--------------------------------------------------------------------+ |
|
||||
| | 项目信息横幅(可展开) | |
|
||||
| | - 项目名称、描述、技术栈徽章 | |
|
||||
| | - 快速统计(功能、bug修复、增强) | |
|
||||
| | - 索引状态指示器 | |
|
||||
| +----------------------------------+---------------------------------+ |
|
||||
| | 统计部分 | 工作流状态 | 任务详情(轮播) | |
|
||||
| | - 6 个迷你卡片 | - 饼图 | - 会话导航 | |
|
||||
| | - 迷你趋势图 | - 图例 | - 任务列表(2 列) | |
|
||||
| +----------------+-----------------+-------------------------------+ |
|
||||
+--------------------------------------------------------------------------+
|
||||
| RecentSessionsWidget |
|
||||
| +--------------------------------------------------------------------+ |
|
||||
| | 标签页:所有任务 | 工作流 | 轻量任务 | |
|
||||
| | +---------------+---------------+-------------------------------+ | |
|
||||
| | | 带有状态、进度、标签、时间的任务卡片 | | |
|
||||
| | +---------------------------------------------------------------+ | |
|
||||
+--------------------------------------------------------------------------+
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 实时演示
|
||||
|
||||
:::demo DashboardOverview
|
||||
# dashboard-overview.tsx
|
||||
/**
|
||||
* 仪表板概览演示
|
||||
* 显示带有小部件的主仪表板布局
|
||||
*/
|
||||
export function DashboardOverview() {
|
||||
return (
|
||||
<div className="space-y-6 p-6 bg-background min-h-[600px]">
|
||||
{/* 头部 */}
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold">仪表板</h1>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
项目概览和活动监控
|
||||
</p>
|
||||
</div>
|
||||
<button className="px-3 py-1.5 text-sm border rounded-md hover:bg-accent">
|
||||
刷新
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* 工作流统计小部件 */}
|
||||
<div className="border rounded-lg overflow-hidden">
|
||||
<div className="p-4 border-b bg-muted/30">
|
||||
<h2 className="font-semibold">项目概览与统计</h2>
|
||||
</div>
|
||||
<div className="p-4">
|
||||
<div className="grid grid-cols-3 gap-4">
|
||||
<div className="space-y-3">
|
||||
<div className="text-xs font-medium text-muted-foreground">统计数据</div>
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
{[
|
||||
{ label: '活动会话', value: '12', color: 'text-blue-500' },
|
||||
{ label: '总任务', value: '48', color: 'text-green-500' },
|
||||
{ label: '已完成', value: '35', color: 'text-emerald-500' },
|
||||
{ label: '待处理', value: '8', color: 'text-amber-500' },
|
||||
].map((stat, i) => (
|
||||
<div key={i} className="p-2 bg-muted/50 rounded">
|
||||
<div className={`text-lg font-bold ${stat.color}`}>{stat.value}</div>
|
||||
<div className="text-xs text-muted-foreground truncate">{stat.label}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
<div className="text-xs font-medium text-muted-foreground">工作流状态</div>
|
||||
<div className="flex items-center justify-center h-24">
|
||||
<div className="relative w-20 h-20">
|
||||
<svg className="w-full h-full -rotate-90" viewBox="0 0 36 36">
|
||||
<circle cx="18" cy="18" r="15" fill="none" stroke="currentColor" strokeWidth="3" className="text-muted opacity-20"/>
|
||||
<circle cx="18" cy="18" r="15" fill="none" stroke="currentColor" strokeWidth="3" className="text-blue-500" strokeDasharray="70 100"/>
|
||||
</svg>
|
||||
<div className="absolute inset-0 flex items-center justify-center text-xs font-bold">70%</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-xs text-center space-y-1">
|
||||
<div className="flex items-center justify-center gap-1">
|
||||
<div className="w-2 h-2 rounded-full bg-blue-500"/>
|
||||
<span>已完成:70%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
<div className="text-xs font-medium text-muted-foreground">最近会话</div>
|
||||
<div className="p-3 bg-accent/20 rounded border">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<span className="text-sm font-medium">功能:身份验证流程</span>
|
||||
<span className="text-xs px-2 py-0.5 rounded-full bg-green-500/20 text-green-600">运行中</span>
|
||||
</div>
|
||||
<div className="space-y-1.5">
|
||||
<div className="flex items-center gap-2 text-xs">
|
||||
<div className="w-3 h-3 rounded bg-green-500"/>
|
||||
<span>实现登录表单</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 text-xs">
|
||||
<div className="w-3 h-3 rounded bg-amber-500"/>
|
||||
<span>添加 OAuth 提供商</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 text-xs">
|
||||
<div className="w-3 h-3 rounded bg-muted"/>
|
||||
<span className="text-muted-foreground">测试流程</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 最近会话小部件 */}
|
||||
<div className="border rounded-lg overflow-hidden">
|
||||
<div className="border-b bg-muted/30">
|
||||
<div className="flex gap-1 p-2">
|
||||
{['所有任务', '工作流', '轻量任务'].map((tab, i) => (
|
||||
<button
|
||||
key={tab}
|
||||
className={`px-3 py-1.5 text-xs rounded-md transition-colors ${
|
||||
i === 0 ? 'bg-background text-foreground' : 'text-muted-foreground hover:bg-foreground/5'
|
||||
}`}
|
||||
>
|
||||
{tab}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-4">
|
||||
<div className="grid grid-cols-3 gap-3">
|
||||
{[
|
||||
{ name: '重构 UI 组件', status: '进行中', progress: 65 },
|
||||
{ name: '修复登录 Bug', status: '待处理', progress: 0 },
|
||||
{ name: '添加深色模式', status: '已完成', progress: 100 },
|
||||
].map((task, i) => (
|
||||
<div key={i} className="p-3 bg-muted/30 rounded border cursor-pointer hover:border-primary/30">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<span className="text-xs font-medium line-clamp-1">{task.name}</span>
|
||||
<span className={`text-xs px-1.5 py-0.5 rounded ${
|
||||
task.status === '已完成' ? 'bg-green-500/20 text-green-600' :
|
||||
task.status === '进行中' ? 'bg-blue-500/20 text-blue-600' :
|
||||
'bg-gray-500/20 text-gray-600'
|
||||
}`}>{task.status}</span>
|
||||
</div>
|
||||
{task.progress > 0 && task.progress < 100 && (
|
||||
<div className="w-full h-1.5 bg-muted rounded-full overflow-hidden">
|
||||
<div className="h-full bg-blue-500 rounded-full" style={{ width: `${task.progress}%` }}/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## 核心功能
|
||||
|
||||
| 功能 | 描述 |
|
||||
|------|------|
|
||||
| **项目信息横幅** | 可展开的横幅,显示项目名称、描述、技术栈(语言、框架、架构)、开发索引(功能/bug修复/增强)和实时索引状态 |
|
||||
| **统计部分** | 6 个迷你统计卡片(活动会话、总任务、已完成任务、待处理任务、失败任务、今日活动),带有 7 天迷你趋势图 |
|
||||
| **工作流状态饼图** | 环形图显示会话状态细分(已完成、进行中、计划中、已暂停、已归档),附带百分比 |
|
||||
| **会话轮播** | 自动轮播(5秒间隔)的会话卡片,带有任务列表、进度条和手动导航箭头 |
|
||||
| **最近会话小部件** | 所有任务类型的标签页视图,带有筛选、状态徽章和进度指示器 |
|
||||
| **实时更新** | 统计数据每 60 秒自动刷新,索引状态每 30 秒刷新 |
|
||||
|
||||
---
|
||||
|
||||
## 组件层次结构
|
||||
|
||||
```
|
||||
HomePage
|
||||
├── DashboardHeader
|
||||
│ ├── 标题
|
||||
│ └── 刷新操作按钮
|
||||
├── WorkflowTaskWidget
|
||||
│ ├── ProjectInfoBanner(可展开)
|
||||
│ │ ├── 项目名称和描述
|
||||
│ │ ├── 技术栈徽章
|
||||
│ │ ├── 快速统计卡片
|
||||
│ │ ├── 索引状态指示器
|
||||
│ │ ├── 架构部分
|
||||
│ │ ├── 关键组件
|
||||
│ │ └── 设计模式
|
||||
│ ├── 统计部分
|
||||
│ │ └── MiniStatCard(6 个卡片,带迷你趋势图)
|
||||
│ ├── WorkflowStatusChart
|
||||
│ │ └── 饼图与图例
|
||||
│ └── SessionCarousel
|
||||
│ ├── 导航箭头
|
||||
│ └── 会话卡片(任务列表)
|
||||
└── RecentSessionsWidget
|
||||
├── 标签导航(全部 | 工作流 | 轻量任务)
|
||||
├── 任务网格
|
||||
│ └── TaskItemCard
|
||||
└── 加载/空状态
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Props API
|
||||
|
||||
### HomePage 组件
|
||||
|
||||
| Prop | 类型 | 默认值 | 描述 |
|
||||
|------|------|--------|------|
|
||||
| - | - | - | 此页面组件不接受任何 props(数据通过 hooks 获取) |
|
||||
|
||||
### WorkflowTaskWidget
|
||||
|
||||
| Prop | 类型 | 默认值 | 描述 |
|
||||
|------|------|--------|------|
|
||||
| `className` | `string` | `undefined` | 用于样式的额外 CSS 类 |
|
||||
|
||||
### RecentSessionsWidget
|
||||
|
||||
| Prop | 类型 | 默认值 | 描述 |
|
||||
|------|------|--------|------|
|
||||
| `className` | `string` | `undefined` | 用于样式的额外 CSS 类 |
|
||||
| `maxItems` | `number` | `6` | 要显示的最大项目数量 |
|
||||
|
||||
---
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 基础仪表板
|
||||
|
||||
```tsx
|
||||
import { HomePage } from '@/pages/HomePage'
|
||||
|
||||
// 仪表板在根路由 (/) 自动渲染
|
||||
// 不需要 props - 数据通过 hooks 获取
|
||||
```
|
||||
|
||||
### 嵌入 WorkflowTaskWidget
|
||||
|
||||
```tsx
|
||||
import { WorkflowTaskWidget } from '@/components/dashboard/widgets/WorkflowTaskWidget'
|
||||
|
||||
function CustomDashboard() {
|
||||
return (
|
||||
<div className="p-6">
|
||||
<WorkflowTaskWidget />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### 自定义最近会话小部件
|
||||
|
||||
```tsx
|
||||
import { RecentSessionsWidget } from '@/components/dashboard/widgets/RecentSessionsWidget'
|
||||
|
||||
function ActivityFeed() {
|
||||
return (
|
||||
<div className="p-6">
|
||||
<RecentSessionsWidget maxItems={10} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 状态管理
|
||||
|
||||
### 本地状态
|
||||
|
||||
| 状态 | 类型 | 描述 |
|
||||
|------|------|------|
|
||||
| `hasError` | `boolean` | 关键错误的错误跟踪 |
|
||||
| `projectExpanded` | `boolean` | 项目信息横幅展开状态 |
|
||||
| `currentSessionIndex` | `number` | 轮播中活动会话的索引 |
|
||||
| `activeTab` | `'all' \| 'workflow' \| 'lite'` | 最近会话小部件筛选标签页 |
|
||||
|
||||
### Store 选择器(Zustand)
|
||||
|
||||
| Store | 选择器 | 用途 |
|
||||
|-------|--------|------|
|
||||
| `appStore` | `selectIsImmersiveMode` | 检查沉浸模式是否激活 |
|
||||
|
||||
### 自定义 Hooks(数据获取)
|
||||
|
||||
| Hook | 描述 | 重新获取间隔 |
|
||||
|------|-------------|--------------|
|
||||
| `useWorkflowStatusCounts` | 会话状态分布数据 | - |
|
||||
| `useDashboardStats` | 带迷你趋势图的统计数据 | 60 秒 |
|
||||
| `useProjectOverview` | 项目信息和技术栈 | - |
|
||||
| `useIndexStatus` | 实时索引状态 | 30 秒 |
|
||||
| `useSessions` | 活动会话数据 | - |
|
||||
| `useLiteTasks` | 最近小部件的轻量任务数据 | - |
|
||||
|
||||
---
|
||||
|
||||
## 交互演示
|
||||
|
||||
### 统计卡片演示
|
||||
|
||||
:::demo MiniStatCards
|
||||
# mini-stat-cards.tsx
|
||||
/**
|
||||
* 迷你统计卡片演示
|
||||
* 带有迷你趋势图的独立统计卡片
|
||||
*/
|
||||
export function MiniStatCards() {
|
||||
const stats = [
|
||||
{ label: '活动会话', value: 12, trend: [8, 10, 9, 11, 10, 12, 12], color: 'blue' },
|
||||
{ label: '总任务', value: 48, trend: [40, 42, 45, 44, 46, 47, 48], color: 'green' },
|
||||
{ label: '已完成', value: 35, trend: [25, 28, 30, 32, 33, 34, 35], color: 'emerald' },
|
||||
{ label: '待处理', value: 8, trend: [12, 10, 11, 9, 8, 7, 8], color: 'amber' },
|
||||
{ label: '失败', value: 5, trend: [3, 4, 3, 5, 4, 5, 5], color: 'red' },
|
||||
{ label: '今日活动', value: 23, trend: [5, 10, 15, 18, 20, 22, 23], color: 'purple' },
|
||||
]
|
||||
|
||||
const colorMap = {
|
||||
blue: 'text-blue-500 bg-blue-500/10',
|
||||
green: 'text-green-500 bg-green-500/10',
|
||||
emerald: 'text-emerald-500 bg-emerald-500/10',
|
||||
amber: 'text-amber-500 bg-amber-500/10',
|
||||
red: 'text-red-500 bg-red-500/10',
|
||||
purple: 'text-purple-500 bg-purple-500/10',
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="p-6 bg-background">
|
||||
<h3 className="text-sm font-semibold mb-4">带迷你趋势图的统计</h3>
|
||||
<div className="grid grid-cols-2 md:grid-cols-3 gap-4">
|
||||
{stats.map((stat, i) => (
|
||||
<div key={i} className="p-4 border rounded-lg bg-card">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<span className="text-xs text-muted-foreground">{stat.label}</span>
|
||||
<div className={`w-2 h-2 rounded-full ${colorMap[stat.color].split(' ')[1]}`}/>
|
||||
</div>
|
||||
<div className={`text-2xl font-bold ${colorMap[stat.color].split(' ')[0]}`}>{stat.value}</div>
|
||||
<div className="mt-2 h-8 flex items-end gap-0.5">
|
||||
{stat.trend.map((v, j) => (
|
||||
<div
|
||||
key={j}
|
||||
className="flex-1 rounded-t"
|
||||
style={{
|
||||
height: `${(v / Math.max(...stat.trend)) * 100}%`,
|
||||
backgroundColor: v === stat.value ? 'currentColor' : 'rgba(59, 130, 246, 0.3)',
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
:::
|
||||
|
||||
### 项目信息横幅演示
|
||||
|
||||
:::demo ProjectInfoBanner
|
||||
# project-info-banner.tsx
|
||||
/**
|
||||
* 项目信息横幅演示
|
||||
* 带有技术栈的可展开项目信息
|
||||
*/
|
||||
export function ProjectInfoBanner() {
|
||||
const [expanded, setExpanded] = React.useState(false)
|
||||
|
||||
return (
|
||||
<div className="p-6 bg-background">
|
||||
<h3 className="text-sm font-semibold mb-4">项目信息横幅</h3>
|
||||
<div className="border rounded-lg overflow-hidden">
|
||||
{/* 横幅头部 */}
|
||||
<div className="p-4 bg-muted/30 flex items-center justify-between">
|
||||
<div>
|
||||
<h4 className="font-semibold">我的项目</h4>
|
||||
<p className="text-sm text-muted-foreground">使用 React 构建的现代化 Web 应用</p>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => setExpanded(!expanded)}
|
||||
className="p-2 rounded-md hover:bg-accent"
|
||||
>
|
||||
<svg className={`w-5 h-5 transition-transform ${expanded ? 'rotate-180' : ''}`} fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* 技术栈徽章 */}
|
||||
<div className="px-4 pb-3 flex flex-wrap gap-2">
|
||||
{['TypeScript', 'React', 'Vite', 'Tailwind CSS', 'Zustand'].map((tech) => (
|
||||
<span key={tech} className="px-2 py-1 text-xs rounded-full bg-primary/10 text-primary">
|
||||
{tech}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* 展开内容 */}
|
||||
{expanded && (
|
||||
<div className="p-4 border-t bg-muted/20 space-y-4">
|
||||
<div>
|
||||
<h5 className="text-xs font-semibold mb-2">架构</h5>
|
||||
<div className="text-sm text-muted-foreground space-y-1">
|
||||
<div>• 基于组件的 UI 架构</div>
|
||||
<div>• 集中式状态管理</div>
|
||||
<div>• RESTful API 集成</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h5 className="text-xs font-semibold mb-2">关键组件</h5>
|
||||
<div className="grid grid-cols-2 gap-2 text-sm">
|
||||
{['会话管理器', '仪表板', '任务调度器', '分析'].map((comp) => (
|
||||
<div key={comp} className="flex items-center gap-2">
|
||||
<div className="w-1.5 h-1.5 rounded-full bg-primary"/>
|
||||
{comp}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
:::
|
||||
|
||||
### 会话轮播演示
|
||||
|
||||
:::demo SessionCarousel
|
||||
# session-carousel.tsx
|
||||
/**
|
||||
* 会话轮播演示
|
||||
* 带有导航的自动轮播会话卡片
|
||||
*/
|
||||
export function SessionCarousel() {
|
||||
const [currentIndex, setCurrentIndex] = React.useState(0)
|
||||
const sessions = [
|
||||
{
|
||||
name: '功能:用户身份验证',
|
||||
status: 'running',
|
||||
tasks: [
|
||||
{ name: '实现登录表单', status: 'completed' },
|
||||
{ name: '添加 OAuth 提供商', status: 'in-progress' },
|
||||
{ name: '创建会话管理', status: 'pending' },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Bug 修复:内存泄漏',
|
||||
status: 'running',
|
||||
tasks: [
|
||||
{ name: '识别泄漏源', status: 'completed' },
|
||||
{ name: '修复清理处理器', status: 'in-progress' },
|
||||
{ name: '添加单元测试', status: 'pending' },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: '重构:API 层',
|
||||
status: 'planning',
|
||||
tasks: [
|
||||
{ name: '设计新接口', status: 'pending' },
|
||||
{ name: '迁移现有端点', status: 'pending' },
|
||||
{ name: '更新文档', status: 'pending' },
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
const statusColors = {
|
||||
completed: 'bg-green-500',
|
||||
'in-progress': 'bg-amber-500',
|
||||
pending: 'bg-muted',
|
||||
}
|
||||
|
||||
React.useEffect(() => {
|
||||
const timer = setInterval(() => {
|
||||
setCurrentIndex((i) => (i + 1) % sessions.length)
|
||||
}, 5000)
|
||||
return () => clearInterval(timer)
|
||||
}, [sessions.length])
|
||||
|
||||
return (
|
||||
<div className="p-6 bg-background">
|
||||
<h3 className="text-sm font-semibold mb-4">会话轮播(每 5 秒自动轮播)</h3>
|
||||
<div className="border rounded-lg p-4 bg-card">
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<span className="text-sm font-medium">会话 {currentIndex + 1} / {sessions.length}</span>
|
||||
<div className="flex gap-1">
|
||||
{sessions.map((_, i) => (
|
||||
<button
|
||||
key={i}
|
||||
onClick={() => setCurrentIndex(i)}
|
||||
className={`w-2 h-2 rounded-full transition-colors ${
|
||||
i === currentIndex ? 'bg-primary' : 'bg-muted-foreground/30'
|
||||
}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="p-4 bg-accent/20 rounded border">
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<span className="font-medium">{sessions[currentIndex].name}</span>
|
||||
<span className={`text-xs px-2 py-1 rounded-full ${
|
||||
sessions[currentIndex].status === 'running' ? 'bg-green-500/20 text-green-600' : 'bg-blue-500/20 text-blue-600'
|
||||
}`}>
|
||||
{sessions[currentIndex].status === 'running' ? '运行中' : sessions[currentIndex].status === 'planning' ? '计划中' : sessions[currentIndex].status}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
{sessions[currentIndex].tasks.map((task, i) => (
|
||||
<div key={i} className="flex items-center gap-2 text-sm">
|
||||
<div className={`w-3 h-3 rounded ${statusColors[task.status]}`}/>
|
||||
<span className={task.status === 'pending' ? 'text-muted-foreground' : ''}>{task.name}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-between mt-3">
|
||||
<button
|
||||
onClick={() => setCurrentIndex((i) => (i - 1 + sessions.length) % sessions.length)}
|
||||
className="px-3 py-1.5 text-sm border rounded-md hover:bg-accent"
|
||||
>
|
||||
← 上一页
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setCurrentIndex((i) => (i + 1) % sessions.length)}
|
||||
className="px-3 py-1.5 text-sm border rounded-md hover:bg-accent"
|
||||
>
|
||||
下一页 →
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## 可访问性
|
||||
|
||||
- **键盘导航**:
|
||||
- <kbd>Tab</kbd> - 在交互元素之间导航
|
||||
- <kbd>Enter</kbd>/<kbd>Space</kbd> - 激活按钮和卡片
|
||||
- <kbd>方向键</kbd> - 导航轮播会话
|
||||
|
||||
- **ARIA 属性**:
|
||||
- 导航按钮上的 `aria-label`
|
||||
- 可展开部分的 `aria-expanded`
|
||||
- 实时更新的 `aria-live` 区域
|
||||
|
||||
- **屏幕阅读器支持**:
|
||||
- 所有图表都有文字描述
|
||||
- 状态指示器包含文字标签
|
||||
- 导航被正确宣布
|
||||
|
||||
---
|
||||
|
||||
## 相关链接
|
||||
|
||||
- [会话](/features/sessions) - 查看和管理所有会话
|
||||
- [终端仪表板](/features/terminal) - 终端优先监控界面
|
||||
- [队列](/features/queue) - 问题执行队列管理
|
||||
- [内存](/features/memory) - 持久化内存管理
|
||||
- [设置](/features/settings) - 全局应用设置
|
||||
Reference in New Issue
Block a user