mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-17 13:13:35 +08:00
5.7 KiB
5.7 KiB
Sidebar Redesign — Project Filter + Time-Grouped Session List
Summary
Redesign the desktop app sidebar to match the original Claude Code desktop app:
- Replace project-grouped session list with a flat, time-grouped list (Today / Yesterday / Last 7 days / Last 30 days / Older)
- Add a ProjectFilter dropdown at the top for multi-select project filtering
- Keep existing features: search, right-click menu (rename + delete), active session indicator, missing dir warning
Approach
Plan A: Frontend-only refactor — modify Sidebar.tsx, add ProjectFilter.tsx, update sessionStore.ts. No backend API changes.
Components
1. ProjectFilter (desktop/src/components/layout/ProjectFilter.tsx)
New component providing a multi-select project dropdown.
UI structure:
- Trigger button: displays current filter state
- All selected → "All projects"
- N selected → "N projects"
- Dropdown arrow (chevron) on the right
- Dropdown panel (absolute positioned, below trigger):
- "All projects" option (toggles select-all / deselect-all)
- Separator line
- Per-project items: folder icon + project name + checkmark when selected
- Project name extracted from sanitized projectPath (last segment)
Behavior:
- Default state: "All projects" (empty
selectedProjectsarray = show all) - Click a project → toggle its selection
- Click "All projects" → select all (clear the filter)
- If all projects are individually selected → treat as "All projects"
- Clicking outside the dropdown closes it
Data source: Extract unique projectPath values from the full session list (sessions.map(s => s.projectPath)), deduplicated and sorted alphabetically.
2. Sidebar Layout (desktop/src/components/layout/Sidebar.tsx)
Layout (top to bottom):
- + New session button (existing)
- Scheduled button (existing)
- ProjectFilter dropdown + settings icon (right side)
- Search sessions input (existing)
- Time-grouped session list (scrollable, main content area)
- Settings button (bottom, existing)
Time grouping logic — groupByTime(sessions):
type TimeGroup = 'Today' | 'Yesterday' | 'Last 7 days' | 'Last 30 days' | 'Older'
function groupByTime(sessions: SessionListItem[]): Map<TimeGroup, SessionListItem[]> {
const now = new Date()
const startOfToday = startOfDay(now)
const startOfYesterday = startOfDay(subDays(now, 1))
const sevenDaysAgo = startOfDay(subDays(now, 7))
const thirtyDaysAgo = startOfDay(subDays(now, 30))
// Classify each session by modifiedAt into time buckets
// Within each bucket, sessions are already sorted by modifiedAt desc (from API)
}
No external date library needed — use native Date arithmetic.
Removed logic:
getProjectDisplayName()functiongroupedSessionsuseMemo that groups by projectPath- Per-project group headers and collapsible groups
Preserved logic:
- Search filtering (by title, case-insensitive)
- Active session highlighting (background color)
- Status dot (left side of each session item)
- Right-click context menu (rename + delete)
- "missing dir" warning badge
- Relative timestamp on hover
3. Session Store Changes (desktop/src/stores/sessionStore.ts)
New state fields:
selectedProjects: string[] // empty = all projects (no filter)
availableProjects: string[] // unique project paths from all sessions
New actions:
setSelectedProjects: (projects: string[]) => void
Modified behavior:
fetchSessions()called withoutprojectparameter (fetch all sessions)availableProjectscomputed after fetching:[...new Set(sessions.map(s => s.projectPath))]- Filtering by selectedProjects happens in
Sidebar.tsxvia useMemo, not in the store
4. Session List Item Rendering
Each session item renders as:
[status dot] Session title text... [4h]
- Status dot: small circle, brand color when active (connected), tertiary when inactive
- Title: single line, text-ellipsis overflow
- Timestamp: relative format (now / 5m / 2h / 3d / 1mo), shown on hover (matching current behavior)
- Selected state:
surface-selectedbackground color - Hover state:
surface-hoverbackground color - Missing dir: orange "missing dir" badge after title
What Does NOT Change
- Backend API (
/api/sessions,/api/sessions/recent-projects) — no changes - Session CRUD operations (create, delete, rename, activate)
- WebSocket connection logic
- Right-click context menu items
- Search functionality (filter by title)
- Settings button at bottom
- Overall sidebar width and theme variables
File Change Summary
| File | Change Type | Description |
|---|---|---|
desktop/src/components/layout/ProjectFilter.tsx |
New | Multi-select project dropdown |
desktop/src/components/layout/Sidebar.tsx |
Modify | Replace project grouping with time grouping, integrate ProjectFilter |
desktop/src/stores/sessionStore.ts |
Modify | Add selectedProjects/availableProjects state |
Error Handling
- Empty state: if no sessions match filter + search, show "No sessions found" message
- API failure: existing error handling in sessionStore remains unchanged
- Missing projects: if a session's projectPath doesn't match any known project, it still appears in "All projects" view
Testing
- Verify time grouping correctly classifies sessions into Today/Yesterday/Last 7 days/Last 30 days/Older
- Verify ProjectFilter multi-select toggles work correctly
- Verify search + project filter work together (intersection)
- Verify right-click menu still works
- Verify active session highlighting persists across filter changes