* feat: add workspace system and sidebar layout (UI design system Phase A+B) Backend: Workspace model, migration (036), schemas, CRUD API endpoints. Adds workspace_id to trees and categories, seeds 4 default workspaces per account, auto-assigns existing trees by tree_type. Frontend: Complete AppLayout rewrite from top-nav to CSS Grid shell with persistent sidebar + topbar. New components: WorkspaceSwitcher, NavItem, CategoryList, TagCloud, TopBar, Sidebar. Dashboard components: QuickStats, FiltersBar, SectionGroup, TreeListItem, SessionsPanel. WorkspaceStore with localStorage persistence. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add command palette search, dashboard rewrite, and shell height fixes (Phase C) - Add ⌘K command palette with debounced search across flows and sessions - Rewrite QuickStartPage as dashboard with stats, filters, sessions panel - Fix h-[calc(100vh-4rem)] → h-full across all pages for CSS Grid shell - Add active session count badge to sidebar Sessions nav item Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add sidebar collapse, category/tag filtering, and workspace CRUD (Phase D) - Sidebar collapse/expand toggle with icon-only rail mode (persisted) - Sidebar category/tag clicks navigate to /trees with URL params - TreeLibraryPage syncs filters from URL search params bidirectionally - Workspace create modal with icon picker and auto-slug generation - TopBar logo adapts to collapsed sidebar state Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add Quick Launch modal with actions and recent flows - Zap button opens Quick Launch with create/navigate shortcuts - Shows recent flows for quick session start - Keyboard navigation support (arrows + enter) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add activity notifications panel with session feed - Bell icon shows dot indicator for recent activity - Dropdown panel shows recent sessions with status icons - Links to session detail and sessions list page Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: remove workspace system, add pinned flows and label renames Replace workspace system with pinned flows API (pin/unpin/list/reorder). Rename user-facing labels: Tree→Flow, Procedure→Project. Add sidebar nav sub-items for flow type filtering. Remove 11 workspace files, add migrations 037-038, clean all workspace references. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: collapsed sidebar layout scaling and toggle button size Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: migrate auth pages to new design system Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: migrate TreeLibraryPage to new design system Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: migrate session pages to new design system Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: migrate TreeEditorPage to new design system Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: migrate TreeNavigationPage to new design system Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: migrate session sharing components to new design system Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: remove workspace dropdown animation (dead code) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: migrate common components to new design system Migrate 15 components from monochrome glass-card design to purple gradient accent design system tokens (bg-card, border-border, text-foreground, bg-gradient-brand, etc.) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: migrate procedural and step library components to new design system Migrate 10 components from monochrome glass-card design to purple gradient accent design system tokens. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: migrate admin pages and components to new design system Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: migrate remaining pages to new design system Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: migrate remaining components to new design system Migrates 38 files: tree-editor forms, session modals, step library, common components, library views, tree preview, and misc UI to use design tokens (bg-card, border-border, text-foreground, bg-accent, bg-gradient-brand) replacing old monochrome patterns. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: keep brand text visible on sidebar collapse, hide sub-items until hover - TopBar: always show "ResolutionFlow" text regardless of sidebar state - NavItem: sub-items (Troubleshooting, Projects) hidden by default, revealed on hover or when a child route is active Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
28 KiB
ResolutionFlow UI Design System & Layout Architecture
Purpose: This document defines the app-shell layout, design tokens, component patterns, and navigation architecture for ResolutionFlow. It is the single source of truth for all frontend UI work going forward. Last Updated: February 15, 2026 Status: Approved for implementation (v2 — workspace system removed, replaced with flat nav + type sub-items) Reference Mockup:
docs/mockups/resolutionflow-workspaces-mockup.html(interactive — note: mockup shows old workspace switcher design which has been superseded by this document)
IMPORTANT: Changes from Previous Version
This is version 2 of the design system. The following changes were made based on UX research and product decisions:
- Workspace system REMOVED. The workspace switcher, workspace table, workspace API,
workspaceStore, and all workspace-related components should be removed. Workspaces added unnecessary cognitive overhead and context-switching cost for the current scale of the product. - "Procedures" renamed to "Projects" in all user-facing labels. The
tree_typedatabase column retains the value'procedural'— only UI labels change. - "Trees" renamed to "Flows" in all user-facing labels. "Tree" is an internal/technical term. Users see "Flows" everywhere.
- Flow type filtering is handled via nav sub-items (All Flows → Troubleshooting / Projects), not workspaces.
- Pinned Flows section added to sidebar for quick access to favorites.
- Folder sidebar panel REMOVED from the flow library page. Folders remain in the database and API but are not displayed as a persistent second panel. Folder organization is deferred to a future release.
- Search bar centered in the top bar (flex spacers on both sides).
- Keyboard shortcut badge is platform-aware:
⌘Kon Mac,Ctrl+Kon Windows/Linux.
Files to Remove or Deprecate
These files were created for the workspace system and should be deleted:
frontend/src/store/workspaceStore.ts → DELETE (replace with flowFilterStore.ts)
frontend/src/api/workspaces.ts → DELETE
frontend/src/types/workspace.ts → DELETE (remove Workspace type)
frontend/src/components/workspace/ → DELETE entire directory
frontend/src/constants/workspaceLabels.ts → DELETE (replace with flowLabels.ts)
backend/app/models/workspace.py → DELETE
backend/app/api/endpoints/workspaces.py → DELETE
backend/app/schemas/workspace.py → DELETE (if exists)
Database Migration
Create a new migration that:
- Drops the
workspace_idcolumn fromtreestable (if added) - Drops the
workspace_idcolumn fromtree_categoriestable (if added) - Drops the
workspacestable - Does NOT touch the existing
tree_typecolumn — it stays as-is
Remove the workspace router from backend/app/api/router.py.
Table of Contents
- Layout Architecture
- Design Tokens
- Naming & Terminology
- Sidebar Components
- Top Bar
- Main Content Area
- Component Patterns
- Icon System
- Animation & Transitions
- Migration Strategy
- Implementation Phases
1. Layout Architecture
Overview
ResolutionFlow uses a persistent sidebar + top bar + main content layout. This mirrors the UX patterns MSP engineers already use in ConnectWise Automate, Datto RMM, and HaloPSA.
Shell Structure
┌──────────────────────────────────────────────────────┐
│ TOP BAR (56px) — Logo, ── Search (centered) ──, User│
├──────────────┬───────────────────────────────────────┤
│ SIDEBAR │ MAIN CONTENT AREA │
│ (260px) │ │
│ │ Page Header + Actions │
│ Pinned │ Quick Stats Row │
│ Flows │ Filters Bar │
│ │ Content Sections │
│ Navigation │ (flow list, sessions, etc.) │
│ + sub-items │ │
│ │ │
│ Categories │ │
│ Tags │ │
│ │ │
│ ─────────── │ │
│ Team │ │
│ Settings │ │
└──────────────┴───────────────────────────────────────┘
CSS Grid Implementation
// AppLayout.tsx
<div className="app-shell">
<header className="topbar">...</header>
<nav className="sidebar">...</nav>
<main className="main-content">
<Outlet />
</main>
</div>
.app-shell {
display: grid;
grid-template-columns: 260px 1fr;
grid-template-rows: 56px 1fr;
height: 100vh;
overflow: hidden;
}
.topbar {
grid-column: 1 / -1; /* spans full width */
}
.sidebar {
overflow-y: auto;
}
.main-content {
overflow-y: auto;
}
CSS Variable for Sidebar Width
:root {
--sidebar-w: 260px;
}
2. Design Tokens
Existing Tokens (Already in tailwind.config.js and index.css)
These are already implemented and MUST be used. Do NOT introduce new color values that duplicate or conflict with these.
Brand Colors (from tailwind.config.js)
| Token | Value | Usage |
|---|---|---|
brand.gradient.from |
#818cf8 |
Gradient start, primary accent |
brand.gradient.to |
#a78bfa |
Gradient end |
brand.dark.DEFAULT |
#09090b |
App background (dark mode) |
brand.dark.card |
#18181b |
Card backgrounds |
brand.dark.surface |
#12121c |
Elevated surface |
brand.text.primary |
#ffffff |
Primary text |
brand.text.secondary |
#a1a1aa |
Secondary text |
brand.text.muted |
#52525b |
Muted/dim text |
brand.border |
#27272a |
Standard borders |
Tailwind Utilities (from index.css)
| Utility | Description |
|---|---|
bg-gradient-brand |
linear-gradient(90deg, #818cf8, #a78bfa) |
bg-gradient-brand-hover |
linear-gradient(90deg, #6366f1, #9333ea) |
text-gradient-brand |
Gradient text effect (uses bg-clip-text) |
font-heading |
Plus Jakarta Sans |
font-sans |
Inter |
font-label |
Outfit |
shadcn/ui CSS Variables (from index.css)
All shadcn component tokens are defined via HSL CSS variables (--background, --foreground, --card, --primary, etc.) in :root. The app is dark-only — all tokens live in :root, not .dark.
App Shell Tokens (in index.css :root)
:root {
/* App Shell tokens */
--sidebar-bg: 240 10% 4.5%;
--sidebar-hover: 240 6% 12%;
--sidebar-active: 243 75% 59% / 0.08;
--border-subtle: 240 6% 12%;
--text-dimmed: 240 4% 24%;
}
Semantic Status Colors
| Status | Color | Tailwind Class | Usage |
|---|---|---|---|
| Success / Resolved | #22c55e |
text-green-500 / bg-green-500 |
Completed sessions, resolved |
| Warning / In Progress | #f59e0b |
text-amber-500 / bg-amber-500 |
Open/active sessions |
| Error / Critical | #ef4444 |
text-red-500 / bg-red-500 |
Failed, critical priority |
| Info | #3b82f6 |
text-blue-500 / bg-blue-500 |
Informational, default |
Category Colors
// constants/categoryColors.ts
export const CATEGORY_COLORS = [
'#3b82f6', // blue
'#22c55e', // green
'#f59e0b', // amber
'#ef4444', // red
'#8b5cf6', // violet
'#06b6d4', // cyan
'#ec4899', // pink
'#f97316', // orange
'#14b8a6', // teal
'#6366f1', // indigo
] as const;
Migration needed: Add
colorcolumn totree_categories:ALTER TABLE tree_categories ADD COLUMN color VARCHAR(7) DEFAULT '#3b82f6';
3. Naming & Terminology
User-Facing Labels
| Internal / Database | User-Facing Label | Context |
|---|---|---|
tree |
Flow | Universal term for all flow types |
tree_type = 'troubleshooting' |
Troubleshooting | Branching decision-tree flows |
tree_type = 'procedural' |
Project | Linear step-by-step flows (onboarding, migrations, etc.) |
tree_structure |
Flow structure | Internal — never shown to users |
tree_editor |
Flow Editor | The editor page |
session |
Session (troubleshooting) / Run (projects) | Active use of a flow |
Label Constants
Replace workspaceLabels.ts with a simpler type-based label system:
// constants/flowLabels.ts
export interface FlowTypeLabels {
navLabel: string;
newButton: string;
editorLabel: string;
searchPlaceholder: string;
}
export const FLOW_TYPE_LABELS: Record<string, FlowTypeLabels> = {
all: {
navLabel: 'All Flows',
newButton: '+ Create Flow',
editorLabel: 'Flow Editor',
searchPlaceholder: 'Search flows, sessions, tags…',
},
troubleshooting: {
navLabel: 'Troubleshooting',
newButton: '+ New Troubleshooting Flow',
editorLabel: 'Flow Editor',
searchPlaceholder: 'Search troubleshooting flows…',
},
procedural: {
navLabel: 'Projects',
newButton: '+ New Project',
editorLabel: 'Flow Editor',
searchPlaceholder: 'Search projects, runbooks…',
},
};
export function getFlowLabels(typeFilter: string): FlowTypeLabels {
return FLOW_TYPE_LABELS[typeFilter] || FLOW_TYPE_LABELS.all;
}
Where Labels Appear
- Sidebar nav: "All Flows" (parent), "Troubleshooting" (sub), "Projects" (sub)
- Page title on flow library: "Flow Library" (always — does not change with filter)
- "+ Create Flow" button in page header (adapts based on active type filter)
- Search bar placeholder in top bar (adapts based on active type filter)
- Flow Editor nav item: Always "Flow Editor"
4. Sidebar Components
Structure (top to bottom)
1. ─── PINNED FLOWS ─── (section, collapsible)
- Pinned flow items (star icon, click to start session)
- "Pin a flow…" hint if empty
2. ─── divider ───
3. Primary Navigation
- Dashboard (LayoutGrid icon)
- All Flows (Box icon) [badge: total count]
├─ Troubleshooting (sub-item, indented)
└─ Projects (sub-item, indented)
- Flow Editor (PenLine icon)
- Sessions (Clock icon) [badge: active count]
- Exports (FileText icon)
- Step Library (Bookmark icon) [dot: new items]
4. ─── divider ───
5. Categories Section
- Section label: "CATEGORIES"
- Category items with color dots and counts
6. ─── divider ───
7. Tags Section
- Section label: "POPULAR TAGS"
- Tag chips in a flex-wrap cloud
8. ─── spacer (flex-grow) ───
9. Footer (pinned to bottom)
- Team (Users icon)
- Settings (Settings icon)
Pinned Flows Section
interface PinnedFlow {
id: string;
name: string;
treeType: 'troubleshooting' | 'procedural';
categoryEmoji?: string;
}
interface PinnedFlowsSectionProps {
pinnedFlows: PinnedFlow[];
onFlowClick: (id: string) => void;
onUnpin: (id: string) => void;
}
Visual design:
- Section label:
PINNEDinfont-label text-[0.6875rem] uppercase tracking-wide text-muted-foreground - Each pinned flow: single line with emoji/icon + flow name (truncated) + quick-start button on hover
- Max 10 pinned flows visible; if more, show "View all pinned" link
- Empty state: subtle hint text "Star a flow to pin it here" with
text-muted-foreground text-xs - Collapsible via section header chevron
Data model:
- New junction table:
user_pinned_trees(user_id UUID, tree_id UUID, pinned_at TIMESTAMPTZ, display_order INTEGER) - API:
POST /api/v1/trees/{id}/pin,DELETE /api/v1/trees/{id}/pin,GET /api/v1/trees/pinned - Store: add
pinnedFlowsarray to existing auth or a new lightweightpinnedStore
Pin/unpin interaction:
- Pin via: star icon on flow cards in library, three-dot menu → "Pin to sidebar", right-click context menu
- Unpin via: right-click pinned item → "Unpin", or three-dot menu on flow card
- Toast on pin: "📌 Pinned Flow Name to sidebar"
- Toast on unpin: "Unpinned Flow Name"
Nav Item Component
interface NavItemProps {
href: string;
icon: LucideIcon;
label: string;
badge?: number | 'dot';
isActive?: boolean;
children?: NavSubItem[]; // for expandable sub-items
}
interface NavSubItem {
href: string;
label: string;
count?: number;
isActive?: boolean;
}
Active state styling:
- Background:
var(--sidebar-active)(brand purple at 8% opacity) - Left border accent: 3px gradient bar (brand gradient, rounded right corners)
- Text:
text-foreground(white) - Icon: full opacity
Inactive state styling:
- Background: transparent
- Text:
text-muted-foreground - Icon: 70% opacity
- Hover:
var(--sidebar-hover)background
Nav Sub-Items (Flow Type Filter)
Sub-items appear indented under "All Flows":
📦 All Flows 47
🔧 Troubleshooting 29
📋 Projects 18
Sub-item styling:
- Indented:
pl-9(aligns text with parent label, past the icon) - No icon of their own (the emoji/text suffices, or use a small dot)
- Font:
text-[0.8125rem] text-muted-foreground - Active: same purple highlight as parent but without the left accent bar
- Count: right-aligned in
font-label text-xs text-muted-foreground
Behavior:
- Clicking "All Flows" navigates to
/flows(or/trees— use existing route) with no type filter - Clicking "Troubleshooting" navigates to
/flows?type=troubleshooting - Clicking "Projects" navigates to
/flows?type=procedural - The active state highlights whichever is currently selected
- When a sub-item is active, the parent "All Flows" stays visually highlighted (dimmer) to show context
- Sub-items are always visible (not collapsible) — there are only 2
Flow library page behavior:
- Reads
typefrom URL search params (already implemented inTreeLibraryPage.tsx) - Filters the flow list accordingly
- Updates the page subtitle and "Create" button label via
getFlowLabels(typeFilter) - Categories, tags, stats, and sessions in the sidebar do NOT change — they show data across all types
Category Item Component
interface CategoryItemProps {
name: string;
color: string; // hex color for the dot
count: number;
onClick: () => void;
}
Renders as: [●] Category Name .............. 12
- 8px color dot (rounded full)
- Name in
text-sm text-muted-foreground - Count right-aligned in
font-label text-xs - Hover:
var(--sidebar-hover)background, text brightens
Tag Cloud Component
interface TagCloudProps {
tags: string[];
onTagClick: (tag: string) => void;
activeTags?: string[];
}
- Background:
bg-card, Border:border-border - Text:
font-label text-xs(Outfit) - Active: purple-tinted background and border
- Gap: 4px
5. Top Bar
Structure (left to right)
[Logo + Wordmark] | ──flex grow── | [Search Input (Ctrl+K / ⌘K)] | ──flex grow── | [Quick Launch] [Notifications] [Avatar]
The search bar is centered between the logo and action buttons using flex spacers on both sides.
Logo Area
- Width: fits content (not fixed to sidebar width)
- Contains: ResolutionFlow logo SVG (32x32) + branded wordmark
- Wordmark: "Resolution" in white + "Flow" in gradient text
Search Bar
- Width: 100%, max-width 480px
- Centered in the top bar via
flex-1spacers on both sides - Placeholder: "Search flows, sessions, tags…" (static — does NOT change with type filter)
- Left icon: magnifying glass (Lucide
Search) - Right badge: platform-aware keyboard shortcut hint
{navigator.platform?.toLowerCase().includes('mac') ? '⌘K' : 'Ctrl+K'} - Border:
border-border, focus:border-primary/30
Action Buttons
| Button | Icon | Behavior |
|---|---|---|
| Quick Launch | Zap (Lucide) |
Opens quick-launch modal to start a session fast |
| Notifications | Bell (Lucide) |
Opens notification panel. Red dot badge when unread |
| User Avatar | Initials circle | Opens user menu dropdown (profile, settings, logout) |
Avatar: 32px circle with brand gradient background, white initials in font-heading text-xs font-bold.
6. Main Content Area
Page Structure
1. Page Header (title + action buttons)
2. Quick Stats Row (4 cards)
3. Filters Bar (chips)
4. Content Sections (flow list, sessions panel)
Not every page uses all sections. Dashboard/Flow Library uses all four. Flow Editor uses only the header.
Quick Stats Row
4 stat cards in a CSS grid (grid-template-columns: repeat(4, 1fr)).
Each card:
- Background:
bg-card - Border:
border(subtle, brightens on hover) - Border radius:
rounded-xl - Padding: 16px 18px
- Label:
font-label text-[0.6875rem] uppercase tracking-wide text-muted-foreground - Value:
font-heading text-2xl font-bold - Meta:
text-[0.6875rem] text-[var(--text-dimmed)]
Stat cards for the Flow Library page:
| Stat | Label | Value Source |
|---|---|---|
| 1 | Active Flows | Total published flows (use text-gradient-brand) |
| 2 | Sessions Today | Sessions started today (number) |
| 3 | Open Sessions | In-progress sessions (use text-amber-500 if > 0) |
| 4 | Docs Generated | Export count this month |
Filters Bar
[All] [Recently Used] [My Flows] [Team Flows] [Defaults] | [⊗ More Filters]
Active chip: purple-tinted background/border.
Note: The "Troubleshooting" / "Projects" type filter is handled by the sidebar sub-items, NOT by filter chips in this bar. The filters bar is for orthogonal filters (ownership, recency, status).
Flow List Items
Grid layout per item:
grid-template-columns: 40px 1fr 130px 80px 100px 40px
icon info category uses updated actions
Each item:
- Background:
bg-card, transparent border - Hover:
border-border,bg-[var(--sidebar-hover)] - Border radius:
rounded-lg - Padding: 12px 16px
Pin star: Show a subtle star icon (Lucide Star) on hover, filled if pinned. Click to toggle pin.
Actions three-dot menu includes:
- Start Session
- Edit
- Duplicate
- Pin to Sidebar / Unpin from Sidebar
- Share
- Delete
Sessions Panel
Contained card with header and rows:
┌ Recent Sessions ──────── [View All] ┐
│ ● DNS Resolution Failure → step 4/12 TKT-4821 12 min ago │
│ ● Account Lockout → step 6/18 TKT-4819 45 min ago │
│ ✓ Mail Flow ✓ Resolved TKT-4815 Yesterday │
└──────────────────────────────────────┘
Status dot colors: bg-amber-500 (in-progress), bg-green-500 (completed).
7. Component Patterns
Buttons
| Variant | Background | Text | Shadow | Hover |
|---|---|---|---|---|
| Primary | bg-gradient-brand |
white | shadow-lg shadow-primary/20 |
Lift + stronger shadow |
| Secondary | bg-card |
text-muted-foreground |
border only | Border brightens |
Both: rounded-lg px-4 py-2 text-sm font-semibold, with icon support (16px Lucide icon + 6px gap).
Badges
- Count badge:
bg-card border border-border rounded-full px-2 text-[0.6875rem] font-label - Active count badge: purple-tinted background/border
- Dot badge: 6px circle,
bg-brand-gradient-from - Notification badge: 8px red circle with sidebar-bg border
Toast Notifications
Fixed-position, top-right (current Sonner config — keep as-is):
- Background:
bg-card - Border: brand gradient border
- Border radius:
rounded-xl - Auto-dismiss: 2000ms
8. Icon System
Primary Source: Lucide React
| Context | Size |
|---|---|
| Nav items | 18px |
| Buttons | 16px |
| Top bar actions | 18px |
| Section headers | 14px |
| Filter chips | 14px |
Navigation Icon Mapping
| Nav Item | Lucide Icon |
|---|---|
| Dashboard | LayoutGrid |
| All Flows | Box |
| Flow Editor | PenLine |
| Sessions | Clock |
| Exports | FileText |
| Step Library | Bookmark |
| Team | Users |
| Settings | Settings |
| Search | Search |
| Quick Launch | Zap |
| Notifications | Bell |
| Create Flow | Plus |
| Pin/Favorite | Star |
| More Actions | MoreHorizontal |
Category Emoji Icons
Default emoji per common categories:
- Networking: 🌐, Active Directory: 🔒, Email/Exchange: 📧, Server Issues: 🖥️
- VPN/Remote: 🔌, Printers: 🖨️, Backup/DR: 🔄, Onboarding: 👤, Security: 🔐
9. Animation & Transitions
Page/Section Load
Staggered fade-in with incrementing animation-delay:
- Stats row: 50ms
- Filters: 100ms
- Section 1: 150ms
- Section 2: 200ms
Interactive Elements
| Element | Property | Duration | Easing |
|---|---|---|---|
| Nav item hover | background-color | 120ms | ease |
| Button hover | transform, box-shadow | 150ms | ease |
| Flow item hover | background, border-color | 120ms | ease |
| Dropdown open | opacity, transform | 150ms | ease |
| Action buttons (three-dot) | opacity | 120ms | ease |
| Toast appear/disappear | opacity, transform | 300ms | ease |
| Pin star toggle | scale + color | 200ms | ease |
10. Migration Strategy
What to Remove
- WorkspaceSwitcher component and all workspace UI
- workspaceStore.ts — replace with
flowFilterStore.ts(or just use URL params, whichTreeLibraryPage.tsxalready does) - workspaceLabels.ts — replace with
flowLabels.ts - Workspace API (
backend/app/api/endpoints/workspaces.py) and model - Folder sidebar panel from
TreeLibraryPage— removeFolderSidebarimport and the column it occupies. TheUserFoldermodel, API, and database table remain untouched for future use. - All
workspace_idreferences in queries
What to Add
- Pinned flows —
user_pinned_treestable, API endpoints, sidebar section - Nav sub-items — update
Sidebar.tsxto render "Troubleshooting" and "Projects" as indented children of "All Flows" - flowLabels.ts — simple type-based label lookup
- Pin star on flow cards in the library grid/list views
What to Keep (Already Built)
- AppLayout.tsx CSS Grid shell — keep as-is
- TopBar.tsx — keep, but verify search is centered and keyboard shortcut is platform-aware (already fixed)
- Sidebar.tsx — keep structure, remove workspace switcher, add pinned flows section and nav sub-items
- NavItem.tsx — keep, extend to support
childrensub-items - CategoryList, TagCloud — keep as-is
- All existing pages — keep rendering inside the shell
Label Replacements (Global Find & Replace)
In all frontend files:
| Find | Replace With |
|---|---|
All Trees |
All Flows |
Tree Editor |
Flow Editor |
New Tree |
Create Flow |
All Procedures |
Projects |
New Procedure |
New Project |
Flow Library (page title) |
Flow Library (keep) |
In Sidebar.tsx nav items:
- Remove workspace switcher
- Add pinned flows section at top
- "All Flows" with sub-items "Troubleshooting" and "Projects"
11. Implementation Phases
Phase A: Cleanup & Labels
- Remove workspace-related files (see list above)
- Create down-migration to drop workspace tables/columns
- Remove workspace router from
backend/app/api/router.py - Create
constants/flowLabels.ts - Update all UI labels: Trees → Flows, Procedures → Projects
- Remove
FolderSidebarfromTreeLibraryPage(keep folder model/API) - Verify search bar is centered and shortcut is platform-aware in
TopBar.tsx
Phase B: Nav Sub-Items
- Extend
NavItemcomponent to supportchildrensub-items - Update
Sidebar.tsxto render "All Flows" with "Troubleshooting" and "Projects" children - Sub-items link to
/trees?type=troubleshootingand/trees?type=procedural - Verify
TreeLibraryPage.tsxcorrectly readstypefrom URL params (already does) - Add flow counts to sub-item badges
Phase C: Pinned Flows
- Create
user_pinned_treestable and Alembic migration - Create pin/unpin API endpoints (
POST /api/v1/trees/{id}/pin,DELETE /api/v1/trees/{id}/pin,GET /api/v1/trees/pinned) - Create Pydantic schemas for pinned flows
- Build
PinnedFlowsSectionsidebar component - Add pin star to flow cards in library (visible on hover, filled if pinned)
- Add "Pin to Sidebar" / "Unpin" to flow card three-dot menu
- Toast notifications for pin/unpin actions
Phase D: Polish
- Add category color column migration + backfill
- Verify all animations and transitions
- Responsive breakpoints (collapse sidebar on mobile)
- E2E testing of navigation flow
- Performance testing
Appendix A: File Structure for New/Modified Components
frontend/src/
├── components/
│ ├── layout/
│ │ ├── AppLayout.tsx (keep — CSS Grid shell)
│ │ ├── TopBar.tsx (keep — search centered, shortcut fixed)
│ │ ├── Sidebar.tsx (MODIFY — remove workspace switcher, add pinned + sub-items)
│ │ ├── NavItem.tsx (MODIFY — add children sub-item support)
│ │ └── ProtectedRoute.tsx (keep)
│ ├── sidebar/
│ │ ├── PinnedFlowsSection.tsx ← NEW
│ │ ├── CategoryList.tsx (keep or move from workspace/)
│ │ └── TagCloud.tsx (keep or move from workspace/)
│ ├── workspace/ ← DELETE entire directory
│ ├── dashboard/
│ │ ├── QuickStats.tsx (keep)
│ │ ├── FiltersBar.tsx (keep)
│ │ └── ...
│ └── common/
│ └── ...
├── store/
│ ├── workspaceStore.ts ← DELETE
│ └── ...
├── api/
│ ├── workspaces.ts ← DELETE
│ ├── pinnedFlows.ts ← NEW
│ └── ...
├── constants/
│ ├── workspaceLabels.ts ← DELETE
│ ├── flowLabels.ts ← NEW
│ └── categoryColors.ts (keep)
└── types/
└── ... (remove Workspace type if exists)
Appendix B: Typography Quick Reference
| Element | Font | Weight | Size | Tracking |
|---|---|---|---|---|
| Page titles | Plus Jakarta Sans (font-heading) |
700 | 1.375rem (22px) | -0.01em |
| Section titles | Plus Jakarta Sans | 700 | 0.8125rem (13px) | 0.04em, uppercase |
| Nav items | Inter (font-sans) |
500 | 0.8125rem (13px) | normal |
| Nav sub-items | Inter (font-sans) |
400 | 0.8125rem (13px) | normal |
| Flow names | Plus Jakarta Sans | 600 | 0.875rem (14px) | -0.005em |
| Stat values | Plus Jakarta Sans | 700 | 1.5rem (24px) | -0.02em |
| Stat labels | Outfit (font-label) |
600 | 0.6875rem (11px) | 0.05em, uppercase |
| Badges/counts | Outfit | 400 | 0.6875rem (11px) | normal |
| Timestamps | Inter | 400 | 0.6875rem (11px) | normal |
| Tags/chips | Outfit | 400 | 0.625rem (10px) | normal |
| Pinned flow names | Inter | 500 | 0.8125rem (13px) | normal |
| Search input | Inter | 400 | 0.8125rem (13px) | normal |