Files
resolutionflow/docs/superpowers/specs/2026-03-15-sidebar-redesign-design.md
chihlasm 357f8e2d08 feat: sidebar redesign — activity feed, grouped nav, AI split (#107)
* docs: add 5 sidebar icon color concepts for UX review

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(ui): add semantic icon colors and updated icons to sidebar nav

Swap generic icons for more descriptive alternatives (Network, Wrench,
FileOutput, Library, Code2, Lightbulb) and assign each nav item a unique
semantic color for instant visual landmarks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(ui): default Sessions page to Active tab, reorder tabs

Active sessions are what engineers care about most. Tab order is now
Active, Prepared, Completed, All.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: add sidebar grouping and AI naming concept mockups

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: add sidebar redesign context and decision summary

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 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>

* feat: add sidebar stats Pydantic schemas

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test: add failing tests for sidebar stats endpoint

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add sidebar stats endpoint with daily stats and activity feed

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add sidebar API client, stats bar, activity feed components

New components: SidebarStatsBar, SidebarActivityFeed, ActivityItem.
New API client for sidebar stats endpoint. Pulse-dot CSS animation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: restructure sidebar with stats bar, activity feed, and grouped nav

Dashboard-first layout with Resolve/Build/Insights groups.
AI split: FlowPilot (Resolve) + Flow Assist (Build).
Stats bar: Resolved/Active/In Session daily counters.
Activity feed: active sessions with CW ticket #, recent completions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: remove pinned flows frontend (PinnedFlowsSection, store, API, pin buttons)

Removed: PinnedFlowsSection component, pinnedFlowsStore, pinnedFlows API client.
Cleaned: pin buttons from TreeGridView, TreeListView, TreeTableView.
Cleaned: favorites section from QuickStartPage, pin props from TreeLibraryPage.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add FlowAssistPage placeholder and /flow-assist route

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: real-time sidebar stats via session-changed events

Sidebar now refreshes stats when sessions are created or completed,
not just on page navigation. Uses window event bus pattern (same as
folder-changed events in codebase).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: live-ticking In Session timer using active session start times

SidebarStatsBar now computes active session elapsed time client-side
from started_at timestamps, ticking every 60s. Backend only returns
completed session minutes to avoid double-counting.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: sidebar In Session timer ticks every second and shows seconds

Timer now uses 1s interval (not 60s) and displays seconds when under
a minute so it matches the session timer in the flow UI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: trigger PR environment redeploy

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* debug: add console.log to SidebarStatsBar for timer investigation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: parse sidebar timestamps as UTC (append Z suffix)

Backend returns naive UTC timestamps without timezone indicator.
JS Date() treats bare ISO strings as local time, causing the timer
to compute negative elapsed time (future timestamps). Appending 'Z'
forces UTC parsing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: rename 'In Session' to 'Total Time' for clarity

Makes it clear the timer is an aggregate of all sessions today,
not just the current one.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 01:35:16 -04:00

14 KiB

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:

.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.

  • 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., -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