# Terminal Dashboard
## One-Liner
**The Terminal Dashboard provides a terminal-first workspace with resizable panes, floating panels, and integrated tools for session monitoring and orchestration.**
---
## Pain Points Solved
| Pain Point | Current State | Terminal Dashboard Solution |
|------------|---------------|-----------------------------|
| **Scattered terminals** | Multiple terminal windows | Unified tmux-style grid layout |
| **No context linkage** | Can't associate terminal output with issues | Association highlight provider |
| **Panel overload** | Fixed layout wastes space | Floating panels (mutually exclusive) |
| **Missing tools** | Switch between apps | Integrated issues, queue, inspector, scheduler |
| **Limited workspace** | Can't see code and terminals together | Resizable three-column layout |
---
## Overview
**Location**: `ccw/frontend/src/pages/TerminalDashboardPage.tsx`
**Purpose**: Terminal-first layout for multi-terminal session management with integrated tools and resizable panels.
**Access**: Navigation → Terminal Dashboard (`/terminal-dashboard`)
**Layout**:
```
+--------------------------------------------------------------------------+
| Dashboard Toolbar (panel toggles, layout presets, fullscreen) |
+--------------------------------------------------------------------------+
| +----------------+-------------------------------------------+------------+ |
| | Session | Terminal Grid (tmux-style) | File | |
| | Group Tree | +----------+ +----------+ | Sidebar | |
| | (resizable) | | Term 1 | | Term 2 | | (resizable)| |
| | | +----------+ +----------+ | | |
| | | +----------+ +----------+ | | |
| | | | Term 3 | | Term 4 | | | |
| | | +----------+ +----------+ | | |
| +----------------+-------------------------------------------+------------+ |
+--------------------------------------------------------------------------+
| [Floating Panel: Issues+Queue OR Inspector OR Execution OR Scheduler] |
+--------------------------------------------------------------------------+
```
---
## Live Demo
:::demo TerminalDashboardOverview
# terminal-dashboard-overview.tsx
/**
* Terminal Dashboard Overview Demo
* Shows the three-column layout with resizable panes and toolbar
*/
export function TerminalDashboardOverview() {
const [fileSidebarOpen, setFileSidebarOpen] = React.useState(true)
const [sessionSidebarOpen, setSessionSidebarOpen] = React.useState(true)
const [activePanel, setActivePanel] = React.useState(null)
return (
{/* Toolbar */}
Terminal Dashboard
{['Sessions', 'Files', 'Issues', 'Queue', 'Inspector', 'Scheduler'].map((item) => (
))}
{/* Main Layout */}
{/* Session Sidebar */}
{sessionSidebarOpen && (
Session Groups
{['Active Sessions', 'Completed', 'Archived'].map((group) => (
))}
)}
{/* Terminal Grid */}
{[1, 2, 3, 4].map((i) => (
$ Terminal {i}
Working directory: /project
Type a command to begin...
))}
{/* File Sidebar */}
{fileSidebarOpen && (
Project Files
{['src', 'docs', 'tests', 'package.json', 'README.md'].map((item) => (
📁
{item}
))}
)}
{/* Floating Panel */}
{activePanel && (
{activePanel} Panel
{activePanel} content placeholder
)}
)
}
:::
---
## Core Features
| Feature | Description |
|---------|-------------|
| **Three-Column Layout** | Resizable panes using Allotment: Session tree (left), Terminal grid (center), File sidebar (right) |
| **Terminal Grid** | Tmux-style split panes with layout presets (single, split-h, split-v, grid-2x2) |
| **Session Group Tree** | Hierarchical view of CLI sessions with grouping by tags |
| **Floating Panels** | Mutually exclusive overlay panels (Issues+Queue, Inspector, Execution Monitor, Scheduler) |
| **Association Highlight** | Cross-panel linking between terminals, issues, and queue items |
| **Layout Presets** | Quick layout buttons: single pane, horizontal split, vertical split, 2x2 grid |
| **Launch CLI** | Config modal for creating new CLI sessions with tool, model, and settings |
| **Fullscreen Mode** | Immersive mode hides app chrome (header + sidebar) |
| **Feature Flags** | Panel visibility controlled by feature flags (queue, inspector, execution monitor) |
---
## Component Hierarchy
```
TerminalDashboardPage
├── AssociationHighlightProvider (context)
├── DashboardToolbar
│ ├── Layout Preset Buttons (Single | Split-H | Split-V | Grid-2x2)
│ ├── Panel Toggles (Sessions | Files | Issues | Queue | Inspector | Execution | Scheduler)
│ ├── Fullscreen Toggle
│ └── Launch CLI Button
├── Allotment (Three-Column Layout)
│ ├── SessionGroupTree
│ │ └── Session Group Items (collapsible)
│ ├── TerminalGrid
│ │ ├── GridGroupRenderer (recursive)
│ │ └── TerminalPane
│ └── FileSidebarPanel
│ └── File Tree View
└── FloatingPanel (multiple, mutually exclusive)
├── Issues+Queue (split panel)
│ ├── IssuePanel
│ └── QueueListColumn
├── QueuePanel (feature flag)
├── InspectorContent (feature flag)
├── ExecutionMonitorPanel (feature flag)
└── SchedulerPanel
```
---
## Props API
### TerminalDashboardPage
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| - | - | - | This page component accepts no props (state managed via hooks and Zustand stores) |
### DashboardToolbar
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `activePanel` | `PanelId \| null` | `null` | Currently active floating panel |
| `onTogglePanel` | `(panelId: PanelId) => void` | - | Callback to toggle panel visibility |
| `isFileSidebarOpen` | `boolean` | `true` | File sidebar visibility state |
| `onToggleFileSidebar` | `() => void` | - | Toggle file sidebar callback |
| `isSessionSidebarOpen` | `boolean` | `true` | Session sidebar visibility state |
| `onToggleSessionSidebar` | `() => void` | - | Toggle session sidebar callback |
| `isFullscreen` | `boolean` | `false` | Fullscreen mode state |
| `onToggleFullscreen` | `() => void` | - | Toggle fullscreen callback |
### FloatingPanel
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `isOpen` | `boolean` | `false` | Panel open state |
| `onClose` | `() => void` | - | Close callback |
| `title` | `string` | - | Panel title |
| `side` | `'left' \| 'right'` | `'left'` | Panel side |
| `width` | `number` | `400` | Panel width in pixels |
| `children` | `ReactNode` | - | Panel content |
---
## State Management
### Local State
| State | Type | Description |
|-------|------|-------------|
| `activePanel` | `PanelId \| null` | Currently active floating panel (mutually exclusive) |
| `isFileSidebarOpen` | `boolean` | File sidebar visibility |
| `isSessionSidebarOpen` | `boolean` | Session sidebar visibility |
### Zustand Stores
| Store | Selector | Purpose |
|-------|----------|---------|
| `workflowStore` | `selectProjectPath` | Current project path for file sidebar |
| `appStore` | `selectIsImmersiveMode` | Fullscreen mode state |
| `configStore` | `featureFlags` | Feature flag configuration |
| `terminalGridStore` | Grid layout and focused pane state |
| `executionMonitorStore` | Active execution count |
| `queueSchedulerStore` | Scheduler status and settings |
### Panel ID Type
```typescript
type PanelId = 'issues' | 'queue' | 'inspector' | 'execution' | 'scheduler';
```
---
## Usage Examples
### Basic Terminal Dashboard
```tsx
import { TerminalDashboardPage } from '@/pages/TerminalDashboardPage'
// The terminal dashboard is automatically rendered at /terminal-dashboard
// No props needed - layout state managed internally
```
### Using FloatingPanel Component
```tsx
import { FloatingPanel } from '@/components/terminal-dashboard/FloatingPanel'
import { IssuePanel } from '@/components/terminal-dashboard/IssuePanel'
function CustomLayout() {
const [isOpen, setIsOpen] = useState(false)
return (
setIsOpen(false)}
title="Issues"
side="left"
width={700}
>
)
}
```
### Panel Toggle Pattern
```tsx
import { useState, useCallback } from 'react'
function usePanelToggle() {
const [activePanel, setActivePanel] = useState(null)
const togglePanel = useCallback((panelId: string) => {
setActivePanel((prev) => (prev === panelId ? null : panelId))
}, [])
const closePanel = useCallback(() => {
setActivePanel(null)
}, [])
return { activePanel, togglePanel, closePanel }
}
```
---
## Interactive Demos
### Layout Presets Demo
:::demo TerminalLayoutPresets
# terminal-layout-presets.tsx
/**
* Terminal Layout Presets Demo
* Interactive layout preset buttons
*/
export function TerminalLayoutPresets() {
const [layout, setLayout] = React.useState('grid-2x2')
const layouts = {
single: 'grid-cols-1 grid-rows-1',
'split-h': 'grid-cols-2 grid-rows-1',
'split-v': 'grid-cols-1 grid-rows-2',
'grid-2x2': 'grid-cols-2 grid-rows-2',
}
return (
Terminal Layout Presets
{Object.keys(layouts).map((preset) => (
))}
{Array.from({ length: layout === 'single' ? 1 : layout.includes('2x') ? 4 : 2 }).map((_, i) => (
$ Terminal {i + 1}
Ready for input...
))}
)
}
:::
### Floating Panels Demo
:::demo FloatingPanelsDemo
# floating-panels-demo.tsx
/**
* Floating Panels Demo
* Mutually exclusive overlay panels
*/
export function FloatingPanelsDemo() {
const [activePanel, setActivePanel] = React.useState(null)
const panels = [
{ id: 'issues', title: 'Issues + Queue', side: 'left', width: 700 },
{ id: 'queue', title: 'Queue', side: 'right', width: 400 },
{ id: 'inspector', title: 'Inspector', side: 'right', width: 360 },
{ id: 'execution', title: 'Execution Monitor', side: 'right', width: 380 },
{ id: 'scheduler', title: 'Scheduler', side: 'right', width: 340 },
]
return (
Floating Panels
{panels.map((panel) => (
))}
{activePanel ? `"${panels.find((p) => p.id === activePanel)?.title}" panel is open` : 'Click a button to open a floating panel'}
{/* Floating Panel Overlay */}
{activePanel && (
p.id === activePanel)?.side === 'left' ? 'left-6' : 'right-6'
}`}
style={{ width: panels.find((p) => p.id === activePanel)?.width }}
>
{panels.find((p) => p.id === activePanel)?.title}
)}
)
}
:::
### Resizable Panes Demo
:::demo ResizablePanesDemo
# resizable-panes-demo.tsx
/**
* Resizable Panes Demo
* Simulates the Allotment resizable split behavior
*/
export function ResizablePanesDemo() {
const [leftWidth, setLeftWidth] = React.useState(240)
const [rightWidth, setRightWidth] = React.useState(280)
const [isDragging, setIsDragging] = React.useState(null)
const handleDragStart = (side) => (e) => {
setIsDragging(side)
e.preventDefault()
}
React.useEffect(() => {
const handleMouseMove = (e) => {
if (isDragging === 'left') {
setLeftWidth(Math.max(180, Math.min(320, e.clientX)))
} else if (isDragging === 'right') {
setRightWidth(Math.max(200, Math.min(400, window.innerWidth - e.clientX)))
}
}
const handleMouseUp = () => setIsDragging(null)
if (isDragging) {
window.addEventListener('mousemove', handleMouseMove)
window.addEventListener('mouseup', handleMouseUp)
return () => {
window.removeEventListener('mousemove', handleMouseMove)
window.removeEventListener('mouseup', handleMouseUp)
}
}
}, [isDragging])
return (
{/* Left Sidebar */}
Session Groups
{['Active Sessions', 'Completed'].map((g) => (
{g}
))}
{/* Left Drag Handle */}
{/* Main Content */}
Terminal Grid Area
{/* Right Drag Handle */}
{/* Right Sidebar */}
Project Files
{['src/', 'docs/', 'tests/'].map((f) => (
{f}
))}
)
}
:::
---
## Configuration
### Feature Flags
| Flag | Controls |
|------|----------|
| `dashboardQueuePanelEnabled` | Queue panel visibility |
| `dashboardInspectorEnabled` | Inspector panel visibility |
| `dashboardExecutionMonitorEnabled` | Execution Monitor panel visibility |
### Layout Presets
| Preset | Layout |
|--------|--------|
| **Single** | One terminal pane |
| **Split-H** | Two panes side by side |
| **Split-V** | Two panes stacked vertically |
| **Grid-2x2** | Four panes in 2x2 grid |
### Panel Types
| Panel | Content | Position | Feature Flag |
|-------|---------|----------|--------------|
| **Issues+Queue** | Combined Issues panel + Queue list column | Left (overlay) | - |
| **Queue** | Full queue management panel | Right (overlay) | `dashboardQueuePanelEnabled` |
| **Inspector** | Association chain inspector | Right (overlay) | `dashboardInspectorEnabled` |
| **Execution Monitor** | Real-time execution tracking | Right (overlay) | `dashboardExecutionMonitorEnabled` |
| **Scheduler** | Queue scheduler controls | Right (overlay) | - |
---
## Accessibility
- **Keyboard Navigation**:
- Tab - Navigate through toolbar buttons
- Enter/Space - Activate toolbar buttons
- Escape - Close floating panels
- F11 - Toggle fullscreen mode
- **ARIA Attributes**:
- `aria-label` on toolbar buttons
- `aria-expanded` on sidebar toggles
- `aria-hidden` on inactive floating panels
- `role="dialog"` on floating panels
- **Screen Reader Support**:
- Panel state announced when toggled
- Layout changes announced
- Focus management when panels open/close
---
## Related Links
- [Orchestrator](/features/orchestrator) - Visual workflow editor
- [Sessions](/features/sessions) - Session management
- [Issue Hub](/features/issue-hub) - Issues, queue, discovery
- [Explorer](/features/explorer) - File explorer
- [Queue](/features/queue) - Queue management standalone page