docs: add sidebar redesign spec and implementation plan

Design spec covers: activity zone with daily stats + session feed,
nav grouping (Resolve/Build/Insights), AI split (FlowPilot + Flow Assist),
pinned flows removal. Implementation plan has 5 chunks, 12 tasks, 39 steps.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-03-15 15:06:14 -04:00
parent cc2f59aa85
commit 575a4fe8cf
2 changed files with 1540 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,271 @@
# Sidebar Redesign — Design Spec
> **Date:** 2026-03-15
> **Branch:** `design/sidebar-icon-concepts`
> **Status:** Approved for implementation
---
## Overview
Redesign the ResolutionFlow sidebar from a flat nav list with a pinned flows section into a structured, activity-aware navigation organized around engineer workflow stages. The sidebar becomes a "shift dashboard" — showing what you're working on, how your day is going, and organizing tools by what you do with them.
## Goals
1. **Surface active work** — engineers should see their in-progress sessions and CW ticket context without navigating away
2. **Organize by workflow** — group nav items into Resolve (working tickets) / Build (authoring flows) / Insights (reviewing results)
3. **Provide daily pulse** — lightweight stats (resolved today, active, time in session) visible at a glance
4. **Clarify AI tools** — split the single "AI Assistant" into two purpose-specific tools (FlowPilot for troubleshooting, Flow Assist for authoring)
5. **Remove low-value features** — pinned/quick access flows are too static for the dynamic MSP workflow
## Full Sidebar Layout (top to bottom)
```
┌─────────────────────────┐
│ Stats Bar │ ← 3 counters: Resolved / Active / In Session
│ [7 done] [2 open] [2h] │
├─────────────────────────┤
│ ● Activity │ ← "Activity" label with emerald clock icon
│ ● O365 Mail Flow #4829 │ ← green dot = active, blue ticket #
│ ● DHCP Scope #4828 │ ← amber dot = paused/idle
│ · · · · · · · · · · · │ ← subtle sub-divider
│ · DNS Resolution 2h │ ← muted dot + relative time
│ · Printer Spooler 5h │
├─────────────────────────┤ ← glass-border divider
│ ▣ Dashboard │ ← standalone, no group label
│ │
│ RESOLVE │ ← group label (JetBrains Mono, uppercase)
│ ◷ Sessions [3] │
│ ⬡ All Flows [32] │
│ ◉ FlowPilot │
│ </> Script Library │
│ │
│ BUILD │
│ 🔧 Flow Editor │
│ ✦ Flow Assist │
│ ⊞ Step Library │
│ 💡 KB Accelerator │
│ │
│ INSIGHTS │
│ 📄 Exports │
│ 📊 Analytics │
│ │
│ ── flex spacer ── │ ← pushes footer to bottom
├─────────────────────────┤ ← glass-border divider
│ 📖 User Guides │
│ 💬 Feedback │
│ ⚙ Account │
│ ◁ Collapse │
└─────────────────────────┘
```
No brand/logo section at top (unchanged from current). Dashboard sits below the divider with no group label — it's visually separated from the activity zone by the divider and from the "Resolve" label by standard spacing (same as current "first nav item before first group" pattern).
## What Changes
### Removed
- **Pinned Flows section** — the entire `PinnedFlowsSection` component, `pinnedFlowsStore`, and `pinnedFlows` API module. MSP engineers' work is too dynamic for static pinning; the activity feed replaces this.
- **Single "AI Assistant" nav item** — replaced by two distinct items
### Added
#### 1. Daily Stats Bar (top of sidebar)
Three compact counters in a horizontal row (`display: flex; gap: 2px`), each counter is a flex-1 cell.
| Stat | Color | Source |
|------|-------|--------|
| Resolved | `#34d399` (emerald) | Count of sessions completed today with `outcome = 'resolved'` |
| Active | `#22d3ee` (cyan) | Count of sessions where `completed_at IS NULL` |
| In Session | `#8891a0` (muted) | Sum of time spent in active sessions today (new metric — snapshot, acceptable to be stale) |
**Dimensions:** `padding: 8px 12px 4px` on the container. Each stat cell: `padding: 6px 4px`, `border-radius: 6px`, `background: rgba(255,255,255,0.02)`. Value: `JetBrains Mono, 14px, font-weight: 600`. Label: `JetBrains Mono, 7px, uppercase, letter-spacing: 0.1em, color: #3d4350`.
Stats reset daily. "In Session" is a snapshot value computed server-side — it does not live-update as a timer.
#### 2. Activity Feed (below stats bar)
Two sub-sections separated by a subtle divider (`1px solid rgba(255,255,255,0.03)`):
**Active sessions (max 5):**
- Green pulsing dot — currently active session
- Amber dot (`#f59e0b`, design system amber) — paused/idle session (started but not interacted with recently)
- Flow name (truncated, `13px`, `color: #e2e8f0`)
- ConnectWise ticket number in blue (`#60a5fa`, `JetBrains Mono, 9px`) — only shown if the user's team has a PSA connection AND the session is linked to a ticket
- If more than 5 active sessions, show a "View all in Sessions →" link styled as `text-muted-foreground, 11px, hover:text-foreground`
**Green pulsing dot animation:**
```css
.active-dot {
width: 7px; height: 7px; border-radius: 50%;
background: #34d399;
box-shadow: 0 0 6px rgba(52,211,153,0.5);
animation: pulse-dot 2s ease-in-out infinite;
}
@keyframes pulse-dot {
0%, 100% { box-shadow: 0 0 4px rgba(52,211,153,0.4); }
50% { box-shadow: 0 0 8px rgba(52,211,153,0.7); }
}
```
**Recent completions:**
- Small muted dot (`4px`, `#3d4350`)
- Flow name in muted text (`11.5px`, `color: #6b7280`)
- Relative timestamp (`JetBrains Mono, 9px`, `color: #5a6170`)
- Show last 3 completed sessions from today
The activity section has an "Activity" header: `JetBrains Mono, 9px, uppercase, letter-spacing: 0.12em, color: #5a6170`, with a small emerald clock SVG icon (10px).
**Activity feed height:** The zone scrolls with the rest of the sidebar — no independent scroll container. The overall sidebar already has `handleSidebarWheel` for scroll forwarding. With max 5 active + 3 recent, the zone is ~280px max which is acceptable.
**Refresh:** Data fetches on mount (same as current). No polling. Navigating back to a page that renders the sidebar triggers a re-mount/re-fetch. A future enhancement could add polling or WebSocket updates but that's out of scope.
#### 3. Nav Grouping (Concept A3)
Dashboard stands alone at the top (no group label, no special treatment — just a regular `NavItem` above the first group label).
**Resolve** — what engineers do when working tickets:
- Sessions (Clock, emerald `#34d399`, badge: active count)
- All Flows (Network, violet `#a78bfa`, badge: total count, with type sub-items)
- FlowPilot (Brain, fuchsia `#e879f9`) — NEW: in-session AI copilot
- Script Library (Code2, teal `#2dd4bf`)
**Build** — authoring and improving flows:
- Flow Editor (Wrench, amber `#f59e0b`)
- Flow Assist (WandSparkles, pink `#f472b6`) — NEW: conversational flow builder AI
- Step Library (Library, orange `#fb923c`)
- KB Accelerator (Lightbulb, rose `#fb7185`)
**Insights** — reviewing results:
- Exports (FileOutput, blue `#60a5fa`)
- Analytics (BarChart3, sky `#38bdf8`)
Group labels use `JetBrains Mono`, `0.5625rem`, uppercase, `letter-spacing: 0.12em`, `color: #5a6170`, `padding: 14px 12px 5px` (first group: `padding-top: 8px`).
#### 4. AI Assistant Split
| Nav Item | Group | Icon | Color | Purpose | Route |
|----------|-------|------|-------|---------|-------|
| FlowPilot | Resolve | Brain | `#e879f9` (fuchsia) | In-session AI copilot — suggests next steps, explains errors, provides ticket context during active troubleshooting | `/assistant` (existing route, rename label in UI only) |
| Flow Assist | Build | WandSparkles | `#f472b6` (pink) | Conversational flow builder — standalone page with a chat interface for generating flows from natural language. Renders a full-page chat UI (similar to `AssistantChatPage`) that creates flows via the AI chat service with `flow_type` selection. NOT a modal wrapper — it's a dedicated page. | `/flow-assist` (new route + new page component `FlowAssistPage`) |
Both names are already in use internally (FlowPilot in the copilot panel, Flow Assist in the editor AI panel). This just promotes them to top-level navigation.
**Note:** `Wand2` is an alias for `WandSparkles` in lucide-react@0.563.0. Use `WandSparkles` as the canonical import.
### Footer (unchanged structure)
- User Guides (BookOpen, lime `#a3e635`)
- Feedback (MessageSquareText, indigo `#818cf8`)
- Account (Settings, no color)
- Collapse (PanelLeftClose, no color)
### Collapsed Sidebar
When collapsed, the stats bar and activity feed are hidden. Icon-only nav items are shown in a flat list (no group labels). The collapsed view includes all 13 nav items including the two new AI items:
- Dashboard (LayoutGrid, cyan)
- Sessions (Clock, emerald)
- All Flows (Network, violet)
- FlowPilot (Brain, fuchsia)
- Script Library (Code2, teal)
- Flow Editor (Wrench, amber)
- Flow Assist (WandSparkles, pink)
- Step Library (Library, orange)
- KB Accelerator (Lightbulb, rose)
- Exports (FileOutput, blue)
- Analytics (BarChart3, sky)
- User Guides (BookOpen, lime)
- Feedback (MessageSquareText, indigo)
Account and Collapse remain in the footer section of the collapsed view (same as current).
## Data Requirements
### New Backend Endpoint
**`GET /api/v1/sessions/sidebar-stats`** — lightweight endpoint for sidebar data, returns:
```json
{
"resolved_today": 7,
"active_count": 2,
"total_session_minutes_today": 134,
"active_sessions": [
{
"session_id": "uuid",
"tree_name": "O365 Mail Flow",
"tree_id": "uuid",
"tree_type": "troubleshooting",
"started_at": "2026-03-15T14:30:00Z",
"ticket_number": "#48291"
}
],
"recent_completions": [
{
"session_id": "uuid",
"tree_name": "DNS Resolution",
"tree_id": "uuid",
"tree_type": "troubleshooting",
"completed_at": "2026-03-15T12:15:00Z"
}
]
}
```
**Query parameters:**
- `tz_offset` (integer, required): Client's UTC offset in minutes (e.g., `-300` for EST). Used to compute "today" boundaries. Frontend sends `new Date().getTimezoneOffset()`.
**Backend logic:**
- `resolved_today`: `SELECT COUNT(*) FROM sessions WHERE user_id = :uid AND completed_at >= :today_start AND outcome = 'resolved'`
- `active_count`: `SELECT COUNT(*) FROM sessions WHERE user_id = :uid AND completed_at IS NULL`
- `total_session_minutes_today`: Sum of `EXTRACT(EPOCH FROM (COALESCE(completed_at, now()) - started_at)) / 60` for all sessions where `started_at >= :today_start`
- `active_sessions`: Up to 5, ordered by `started_at DESC`, with joined tree name/type
- `recent_completions`: Up to 3 completed today, ordered by `completed_at DESC`
- `ticket_number`: Populated from PSA connection context if available (depends on CW integration state — nullable)
- `today_start`: Computed as midnight in the client's timezone, converted to UTC using `tz_offset`
**Sessions spanning midnight:** A session started yesterday that is still active today counts toward `total_session_minutes_today` for its full duration (from `started_at`, not from midnight). It also appears in `active_sessions`. This matches user intuition — "I've been on this for 3 hours" regardless of when midnight fell.
### Frontend Components
**New components:**
- `SidebarStatsBar` — three-stat row component
- `SidebarActivityFeed` — active sessions + recents feed with "Activity" header
- `ActivityItem` — single activity row (dot + name + ticket/timestamp)
- `FlowAssistPage` — standalone page for conversational flow building
**Modified components:**
- `Sidebar.tsx` — major restructure: remove PinnedFlowsSection, add stats bar + activity feed, reorganize nav into groups with labels, add FlowPilot + Flow Assist items, update collapsed view icon set
- `router.tsx` — add `/flow-assist` route
- `NavItem.tsx` — no changes needed (already supports `iconColor` prop)
**Removed:**
- `PinnedFlowsSection.tsx`
- `pinnedFlowsStore.ts`
- `api/pinnedFlows.ts` (if it exists)
- Related pinning UI in flow cards/pages (pin buttons, pin actions)
## Visual Reference
Mockups created during brainstorming are in `.superpowers/brainstorm/` (HTML files, open in browser). The approved composite is `a3-full-sidebar.html` showing the "With AI Split" variant.
## Out of Scope
- ConnectWise ticket deep-linking (future — just display the number for now)
- Team activity feed (showing what other engineers are doing — potential future enhancement)
- Removing the pinned flows backend API/database tables (just remove frontend usage; backend cleanup is separate)
- Changes to the analytics pages themselves
- Mobile/responsive sidebar behavior (current behavior unchanged)
- Polling/WebSocket for live activity updates (fetch on mount only)
## Edge Cases
- **No active sessions:** Stats bar shows "0" for Active and "0m" for In Session. Activity section shows only recents (or "No activity today" placeholder if no recents either).
- **No CW integration:** Ticket numbers simply don't appear. Activity items show flow name only.
- **Many active sessions:** Activity feed caps at 5 active sessions with a "View all in Sessions →" link below.
- **Midnight rollover:** Stats reset based on client timezone offset passed to the API. Frontend sends `tz_offset` on each sidebar fetch.
- **Sessions spanning midnight:** Count full duration from `started_at`, not partial duration from midnight.
- **New user / no sessions ever:** Stats bar shows all zeros. Activity section shows an empty state: "No activity today".
## Accessibility
- Pulsing green dot: add `aria-label="Active session"` to the dot element
- Amber dot: `aria-label="Paused session"`
- Stats bar values: wrap in elements with `aria-label` combining value + label (e.g., "7 resolved today")
- Activity items: render as `<button>` elements (clickable to navigate to session) with descriptive `title` attributes