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>
14 KiB
Sidebar Redesign — Design Spec
Date: 2026-03-15 Branch:
design/sidebar-icon-conceptsStatus: 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
- Surface active work — engineers should see their in-progress sessions and CW ticket context without navigating away
- Organize by workflow — group nav items into Resolve (working tickets) / Build (authoring flows) / Insights (reviewing results)
- Provide daily pulse — lightweight stats (resolved today, active, time in session) visible at a glance
- Clarify AI tools — split the single "AI Assistant" into two purpose-specific tools (FlowPilot for troubleshooting, Flow Assist for authoring)
- 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
PinnedFlowsSectioncomponent,pinnedFlowsStore, andpinnedFlowsAPI 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:
.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:
{
"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.,-300for EST). Used to compute "today" boundaries. Frontend sendsnew 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 NULLtotal_session_minutes_today: Sum ofEXTRACT(EPOCH FROM (COALESCE(completed_at, now()) - started_at)) / 60for all sessions wherestarted_at >= :today_startactive_sessions: Up to 5, ordered bystarted_at DESC, with joined tree name/typerecent_completions: Up to 3 completed today, ordered bycompleted_at DESCticket_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 usingtz_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 componentSidebarActivityFeed— active sessions + recents feed with "Activity" headerActivityItem— 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 setrouter.tsx— add/flow-assistrouteNavItem.tsx— no changes needed (already supportsiconColorprop)
Removed:
PinnedFlowsSection.tsxpinnedFlowsStore.tsapi/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_offseton 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-labelcombining value + label (e.g., "7 resolved today") - Activity items: render as
<button>elements (clickable to navigate to session) with descriptivetitleattributes