mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-03-01 15:03:57 +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:
@@ -1,7 +1,6 @@
|
||||
# Dashboard
|
||||
|
||||
## One-Liner
|
||||
|
||||
**The Dashboard provides an at-a-glance overview of your project's workflow status, statistics, and recent activity through an intuitive widget-based interface.**
|
||||
|
||||
---
|
||||
@@ -18,16 +17,15 @@
|
||||
|
||||
---
|
||||
|
||||
## Page Overview
|
||||
## Overview
|
||||
|
||||
**Location**: `ccw/frontend/src/pages/HomePage.tsx`
|
||||
|
||||
**Purpose**: Dashboard home page providing project overview, statistics, workflow status, and recent activity monitoring.
|
||||
|
||||
**Access**: Navigation → Dashboard (default home page)
|
||||
|
||||
### Layout
|
||||
**Access**: Navigation → Dashboard (default home page at `/`)
|
||||
|
||||
**Layout**:
|
||||
```
|
||||
+--------------------------------------------------------------------------+
|
||||
| Dashboard Header (title + refresh) |
|
||||
@@ -55,6 +53,149 @@
|
||||
|
||||
---
|
||||
|
||||
## Live Demo
|
||||
|
||||
:::demo DashboardOverview
|
||||
# dashboard-overview.tsx
|
||||
/**
|
||||
* Dashboard Overview Demo
|
||||
* Shows the main dashboard layout with widgets
|
||||
*/
|
||||
export function DashboardOverview() {
|
||||
return (
|
||||
<div className="space-y-6 p-6 bg-background min-h-[600px]">
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold">Dashboard</h1>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Project overview and activity monitoring
|
||||
</p>
|
||||
</div>
|
||||
<button className="px-3 py-1.5 text-sm border rounded-md hover:bg-accent">
|
||||
Refresh
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Workflow Stats Widget */}
|
||||
<div className="border rounded-lg overflow-hidden">
|
||||
<div className="p-4 border-b bg-muted/30">
|
||||
<h2 className="font-semibold">Project Overview & Statistics</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">Statistics</div>
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
{[
|
||||
{ label: 'Active Sessions', value: '12', color: 'text-blue-500' },
|
||||
{ label: 'Total Tasks', value: '48', color: 'text-green-500' },
|
||||
{ label: 'Completed', value: '35', color: 'text-emerald-500' },
|
||||
{ label: 'Pending', 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">Workflow Status</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>Completed: 70%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
<div className="text-xs font-medium text-muted-foreground">Recent Session</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">Feature: Auth Flow</span>
|
||||
<span className="text-xs px-2 py-0.5 rounded-full bg-green-500/20 text-green-600">Running</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>Implement login</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 text-xs">
|
||||
<div className="w-3 h-3 rounded bg-amber-500"/>
|
||||
<span>Add 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">Test flow</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Recent Sessions Widget */}
|
||||
<div className="border rounded-lg overflow-hidden">
|
||||
<div className="border-b bg-muted/30">
|
||||
<div className="flex gap-1 p-2">
|
||||
{['All Tasks', 'Workflow', 'Lite Tasks'].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: 'Refactor UI Components', status: 'In Progress', progress: 65 },
|
||||
{ name: 'Fix Login Bug', status: 'Pending', progress: 0 },
|
||||
{ name: 'Add Dark Mode', status: 'Completed', 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 === 'Completed' ? 'bg-green-500/20 text-green-600' :
|
||||
task.status === 'In Progress' ? '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>
|
||||
)
|
||||
}
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## Core Features
|
||||
|
||||
| Feature | Description |
|
||||
@@ -68,85 +209,399 @@
|
||||
|
||||
---
|
||||
|
||||
## Usage Guide
|
||||
## Component Hierarchy
|
||||
|
||||
### Basic Workflow
|
||||
|
||||
1. **View Project Overview**: Check the project info banner for tech stack and development index
|
||||
2. **Monitor Statistics**: Review mini stat cards for current project metrics and trends
|
||||
3. **Track Workflow Status**: View pie chart for session status distribution
|
||||
4. **Browse Active Sessions**: Use session carousel to see task details and progress
|
||||
5. **Access Recent Work**: Switch between All Tasks/Workflow/Lite Tasks tabs to find specific sessions
|
||||
|
||||
### Key Interactions
|
||||
|
||||
| Interaction | How to Use |
|
||||
|-------------|------------|
|
||||
| **Expand Project Details** | Click the chevron button in the project banner to show architecture, components, patterns |
|
||||
| **Navigate Sessions** | Click arrow buttons or wait for auto-rotation (5s interval) in the carousel |
|
||||
| **View Session Details** | Click on any session card to navigate to session detail page |
|
||||
| **Filter Recent Tasks** | Click tab buttons to filter by task type (All/Workflow/Lite) |
|
||||
| **Refresh Dashboard** | Click the refresh button in the header to reload all data |
|
||||
|
||||
### Index Status Indicator
|
||||
|
||||
| Status | Icon | Meaning |
|
||||
|--------|------|---------|
|
||||
| **Building** | Pulsing blue dot | Code index is being built/updated |
|
||||
| **Completed** | Green dot | Index is up-to-date |
|
||||
| **Idle** | Gray dot | Index status is unknown/idle |
|
||||
| **Failed** | Red dot | Index build failed |
|
||||
```
|
||||
HomePage
|
||||
├── DashboardHeader
|
||||
│ ├── Title
|
||||
│ └── Refresh Action Button
|
||||
├── WorkflowTaskWidget
|
||||
│ ├── ProjectInfoBanner (expandable)
|
||||
│ │ ├── Project Name & Description
|
||||
│ │ ├── Tech Stack Badges
|
||||
│ │ ├── Quick Stats Cards
|
||||
│ │ ├── Index Status Indicator
|
||||
│ │ ├── Architecture Section
|
||||
│ │ ├── Key Components
|
||||
│ │ └── Design Patterns
|
||||
│ ├── Stats Section
|
||||
│ │ └── MiniStatCard (6 cards with Sparkline)
|
||||
│ ├── WorkflowStatusChart
|
||||
│ │ └── Pie Chart with Legend
|
||||
│ └── SessionCarousel
|
||||
│ ├── Navigation Arrows
|
||||
│ └── Session Cards (Task List)
|
||||
└── RecentSessionsWidget
|
||||
├── Tab Navigation (All | Workflow | Lite)
|
||||
├── Task Grid
|
||||
│ └── TaskItemCard
|
||||
└── Loading/Empty States
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Components Reference
|
||||
## Props API
|
||||
|
||||
### Main Components
|
||||
### HomePage Component
|
||||
|
||||
| Component | Location | Purpose |
|
||||
|-----------|----------|---------|
|
||||
| `DashboardHeader` | `@/components/dashboard/DashboardHeader.tsx` | Page header with title and refresh action |
|
||||
| `WorkflowTaskWidget` | `@/components/dashboard/widgets/WorkflowTaskWidget.tsx` | Combined widget with project info, stats, workflow status, and session carousel |
|
||||
| `RecentSessionsWidget` | `@/components/dashboard/widgets/RecentSessionsWidget.tsx` | Recent sessions across workflow and lite tasks |
|
||||
| `MiniStatCard` | (internal to WorkflowTaskWidget) | Individual stat card with optional sparkline |
|
||||
| `HomeEmptyState` | (internal to WorkflowTaskWidget) | Empty state display when no sessions exist |
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| - | - | - | This page component accepts no props (data fetched via hooks) |
|
||||
|
||||
### State Management
|
||||
### WorkflowTaskWidget
|
||||
|
||||
- **Local state**:
|
||||
- `hasError` - Error tracking for critical failures
|
||||
- `projectExpanded` - Project info banner expansion state
|
||||
- `currentSessionIndex` - Active session in carousel
|
||||
- `activeTab` - Recent sessions widget filter tab
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `className` | `string` | `undefined` | Additional CSS classes for styling |
|
||||
|
||||
- **Custom hooks**:
|
||||
- `useWorkflowStatusCounts` - Session status distribution data
|
||||
- `useDashboardStats` - Statistics with auto-refresh (60s)
|
||||
- `useProjectOverview` - Project information and tech stack
|
||||
- `useIndexStatus` - Real-time index status (30s refresh)
|
||||
- `useSessions` - Active sessions data
|
||||
- `useLiteTasks` - Lite tasks data for recent widget
|
||||
### RecentSessionsWidget
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `className` | `string` | `undefined` | Additional CSS classes |
|
||||
| `maxItems` | `number` | `6` | Maximum number of items to display |
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
## Usage Examples
|
||||
|
||||
No configuration required. The dashboard automatically fetches data from the backend.
|
||||
### Basic Dashboard
|
||||
|
||||
### Auto-Refresh Intervals
|
||||
```tsx
|
||||
import { HomePage } from '@/pages/HomePage'
|
||||
|
||||
| Data Type | Interval |
|
||||
|-----------|----------|
|
||||
| Dashboard stats | 60 seconds |
|
||||
| Index status | 30 seconds |
|
||||
| Discovery sessions | 3 seconds (on discovery page) |
|
||||
// The dashboard is automatically rendered at the root route (/)
|
||||
// No props needed - data is fetched via hooks
|
||||
```
|
||||
|
||||
### Embedding WorkflowTaskWidget
|
||||
|
||||
```tsx
|
||||
import { WorkflowTaskWidget } from '@/components/dashboard/widgets/WorkflowTaskWidget'
|
||||
|
||||
function CustomDashboard() {
|
||||
return (
|
||||
<div className="p-6">
|
||||
<WorkflowTaskWidget />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Custom Recent Sessions Widget
|
||||
|
||||
```tsx
|
||||
import { RecentSessionsWidget } from '@/components/dashboard/widgets/RecentSessionsWidget'
|
||||
|
||||
function ActivityFeed() {
|
||||
return (
|
||||
<div className="p-6">
|
||||
<RecentSessionsWidget maxItems={10} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## State Management
|
||||
|
||||
### Local State
|
||||
|
||||
| State | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `hasError` | `boolean` | Error tracking for critical failures |
|
||||
| `projectExpanded` | `boolean` | Project info banner expansion state |
|
||||
| `currentSessionIndex` | `number` | Active session index in carousel |
|
||||
| `activeTab` | `'all' \| 'workflow' \| 'lite'` | Recent sessions widget filter tab |
|
||||
|
||||
### Store Selectors (Zustand)
|
||||
|
||||
| Store | Selector | Purpose |
|
||||
|-------|----------|---------|
|
||||
| `appStore` | `selectIsImmersiveMode` | Check if immersive mode is active |
|
||||
|
||||
### Custom Hooks (Data Fetching)
|
||||
|
||||
| Hook | Description | Refetch Interval |
|
||||
|------|-------------|------------------|
|
||||
| `useWorkflowStatusCounts` | Session status distribution data | - |
|
||||
| `useDashboardStats` | Statistics with sparkline data | 60 seconds |
|
||||
| `useProjectOverview` | Project information and tech stack | - |
|
||||
| `useIndexStatus` | Real-time index status | 30 seconds |
|
||||
| `useSessions` | Active sessions data | - |
|
||||
| `useLiteTasks` | Lite tasks data for recent widget | - |
|
||||
|
||||
---
|
||||
|
||||
## Interactive Demos
|
||||
|
||||
### Statistics Cards Demo
|
||||
|
||||
:::demo MiniStatCards
|
||||
# mini-stat-cards.tsx
|
||||
/**
|
||||
* Mini Stat Cards Demo
|
||||
* Individual statistics cards with sparkline trends
|
||||
*/
|
||||
export function MiniStatCards() {
|
||||
const stats = [
|
||||
{ label: 'Active Sessions', value: 12, trend: [8, 10, 9, 11, 10, 12, 12], color: 'blue' },
|
||||
{ label: 'Total Tasks', value: 48, trend: [40, 42, 45, 44, 46, 47, 48], color: 'green' },
|
||||
{ label: 'Completed', value: 35, trend: [25, 28, 30, 32, 33, 34, 35], color: 'emerald' },
|
||||
{ label: 'Pending', value: 8, trend: [12, 10, 11, 9, 8, 7, 8], color: 'amber' },
|
||||
{ label: 'Failed', value: 5, trend: [3, 4, 3, 5, 4, 5, 5], color: 'red' },
|
||||
{ label: 'Today Activity', 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">Statistics with Sparklines</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>
|
||||
)
|
||||
}
|
||||
:::
|
||||
|
||||
### Project Info Banner Demo
|
||||
|
||||
:::demo ProjectInfoBanner
|
||||
# project-info-banner.tsx
|
||||
/**
|
||||
* Project Info Banner Demo
|
||||
* Expandable project information with tech stack
|
||||
*/
|
||||
export function ProjectInfoBanner() {
|
||||
const [expanded, setExpanded] = React.useState(false)
|
||||
|
||||
return (
|
||||
<div className="p-6 bg-background">
|
||||
<h3 className="text-sm font-semibold mb-4">Project Info Banner</h3>
|
||||
<div className="border rounded-lg overflow-hidden">
|
||||
{/* Banner Header */}
|
||||
<div className="p-4 bg-muted/30 flex items-center justify-between">
|
||||
<div>
|
||||
<h4 className="font-semibold">My Awesome Project</h4>
|
||||
<p className="text-sm text-muted-foreground">A modern web application built with React</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>
|
||||
|
||||
{/* Tech Stack Badges */}
|
||||
<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 Content */}
|
||||
{expanded && (
|
||||
<div className="p-4 border-t bg-muted/20 space-y-4">
|
||||
<div>
|
||||
<h5 className="text-xs font-semibold mb-2">Architecture</h5>
|
||||
<div className="text-sm text-muted-foreground space-y-1">
|
||||
<div>• Component-based UI architecture</div>
|
||||
<div>• Centralized state management</div>
|
||||
<div>• RESTful API integration</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h5 className="text-xs font-semibold mb-2">Key Components</h5>
|
||||
<div className="grid grid-cols-2 gap-2 text-sm">
|
||||
{['Session Manager', 'Dashboard', 'Task Scheduler', 'Analytics'].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>
|
||||
)
|
||||
}
|
||||
:::
|
||||
|
||||
### Session Carousel Demo
|
||||
|
||||
:::demo SessionCarousel
|
||||
# session-carousel.tsx
|
||||
/**
|
||||
* Session Carousel Demo
|
||||
* Auto-rotating session cards with navigation
|
||||
*/
|
||||
export function SessionCarousel() {
|
||||
const [currentIndex, setCurrentIndex] = React.useState(0)
|
||||
const sessions = [
|
||||
{
|
||||
name: 'Feature: User Authentication',
|
||||
status: 'running',
|
||||
tasks: [
|
||||
{ name: 'Implement login form', status: 'completed' },
|
||||
{ name: 'Add OAuth provider', status: 'in-progress' },
|
||||
{ name: 'Create session management', status: 'pending' },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Bug Fix: Memory Leak',
|
||||
status: 'running',
|
||||
tasks: [
|
||||
{ name: 'Identify leak source', status: 'completed' },
|
||||
{ name: 'Fix cleanup handlers', status: 'in-progress' },
|
||||
{ name: 'Add unit tests', status: 'pending' },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Refactor: API Layer',
|
||||
status: 'planning',
|
||||
tasks: [
|
||||
{ name: 'Design new interface', status: 'pending' },
|
||||
{ name: 'Migrate existing endpoints', status: 'pending' },
|
||||
{ name: 'Update documentation', 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">Session Carousel (auto-rotates every 5s)</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">Session {currentIndex + 1} of {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}
|
||||
</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"
|
||||
>
|
||||
← Previous
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setCurrentIndex((i) => (i + 1) % sessions.length)}
|
||||
className="px-3 py-1.5 text-sm border rounded-md hover:bg-accent"
|
||||
>
|
||||
Next →
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## Accessibility
|
||||
|
||||
- **Keyboard Navigation**:
|
||||
- <kbd>Tab</kbd> - Navigate through interactive elements
|
||||
- <kbd>Enter</kbd>/<kbd>Space</kbd> - Activate buttons and cards
|
||||
- <kbd>Arrow</kbd> keys - Navigate carousel sessions
|
||||
|
||||
- **ARIA Attributes**:
|
||||
- `aria-label` on navigation buttons
|
||||
- `aria-expanded` on expandable sections
|
||||
- `aria-live` regions for real-time updates
|
||||
|
||||
- **Screen Reader Support**:
|
||||
- All charts have text descriptions
|
||||
- Status indicators include text labels
|
||||
- Navigation is announced properly
|
||||
|
||||
---
|
||||
|
||||
## Related Links
|
||||
|
||||
- [Sessions](/features/sessions) - View and manage all sessions
|
||||
- [Terminal Dashboard](/features/terminal) - Terminal-first monitoring interface
|
||||
- [Queue](/features/queue) - Issue execution queue management
|
||||
- [Discovery](/features/discovery) - Discovery session tracking
|
||||
- [Memory](/features/memory) - Persistent memory management
|
||||
- [System Settings](/features/system-settings) - Global application settings
|
||||
- [Settings](/features/settings) - Global application settings
|
||||
|
||||
Reference in New Issue
Block a user