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:
1269
docs/superpowers/plans/2026-03-15-sidebar-redesign.md
Normal file
1269
docs/superpowers/plans/2026-03-15-sidebar-redesign.md
Normal file
File diff suppressed because it is too large
Load Diff
271
docs/superpowers/specs/2026-03-15-sidebar-redesign-design.md
Normal file
271
docs/superpowers/specs/2026-03-15-sidebar-redesign-design.md
Normal 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
|
||||
Reference in New Issue
Block a user