Major UI overhaul plans; Other random docs
This commit is contained in:
858
UI-DESIGN-SYSTEM.md
Normal file
858
UI-DESIGN-SYSTEM.md
Normal file
@@ -0,0 +1,858 @@
|
||||
# ResolutionFlow UI Design System & Layout Architecture
|
||||
|
||||
> **Purpose:** This document defines the new app-shell layout, design tokens, component patterns, and workspace 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
|
||||
> **Reference Mockup:** `docs/mockups/resolutionflow-workspaces-mockup.html` (interactive, open in browser)
|
||||
> **Note:** If the mockup file is not yet in the repo, it should be placed at the path above. The mockup is also available as a project output artifact.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Layout Architecture](#1-layout-architecture)
|
||||
2. [Design Tokens](#2-design-tokens)
|
||||
3. [Workspace System](#3-workspace-system)
|
||||
4. [Sidebar Components](#4-sidebar-components)
|
||||
5. [Top Bar](#5-top-bar)
|
||||
6. [Main Content Area](#6-main-content-area)
|
||||
7. [Component Patterns](#7-component-patterns)
|
||||
8. [Icon System](#8-icon-system)
|
||||
9. [Animation & Transitions](#9-animation--transitions)
|
||||
10. [Data Model Changes](#10-data-model-changes)
|
||||
11. [Migration Strategy](#11-migration-strategy)
|
||||
12. [Implementation Phases](#12-implementation-phases)
|
||||
|
||||
---
|
||||
|
||||
## 1. Layout Architecture
|
||||
|
||||
### Overview
|
||||
|
||||
ResolutionFlow transitions from a top-nav + full-width content layout to a **persistent sidebar + top bar + main workspace** layout. This mirrors the UX patterns MSP engineers already use in ConnectWise Automate, Datto RMM, and HaloPSA.
|
||||
|
||||
### Shell Structure
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────┐
|
||||
│ TOP BAR (56px) — Logo, Search, Quick Actions, User │
|
||||
├──────────────┬───────────────────────────────────────┤
|
||||
│ SIDEBAR │ MAIN CONTENT AREA │
|
||||
│ (260px) │ │
|
||||
│ │ Page Header + Actions │
|
||||
│ Workspace │ Quick Stats Row │
|
||||
│ Switcher │ Filters Bar │
|
||||
│ │ Content Sections │
|
||||
│ Navigation │ (trees/flows list, sessions, etc.) │
|
||||
│ │ │
|
||||
│ Categories │ │
|
||||
│ Tags │ │
|
||||
│ │ │
|
||||
│ ─────────── │ │
|
||||
│ Team │ │
|
||||
│ Settings │ │
|
||||
└──────────────┴───────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### CSS Grid Implementation
|
||||
|
||||
```tsx
|
||||
// AppLayout.tsx - new shell structure
|
||||
<div className="app-shell">
|
||||
<header className="topbar">...</header>
|
||||
<nav className="sidebar">...</nav>
|
||||
<main className="main-content">
|
||||
<Outlet />
|
||||
</main>
|
||||
</div>
|
||||
```
|
||||
|
||||
```css
|
||||
.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
|
||||
|
||||
```css
|
||||
:root {
|
||||
--sidebar-w: 260px;
|
||||
}
|
||||
```
|
||||
|
||||
This variable should be used consistently for sidebar width, logo area width calculations, and responsive breakpoints.
|
||||
|
||||
---
|
||||
|
||||
## 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.) with both light and dark mode values. Continue using these for shadcn components.
|
||||
|
||||
### NEW Design Tokens for App Shell
|
||||
|
||||
These are already added to `index.css` within the `:root` block (the app is dark-only, all tokens live in `:root`):
|
||||
|
||||
```css
|
||||
:root {
|
||||
/* Existing tokens... */
|
||||
|
||||
/* App Shell tokens */
|
||||
--sidebar-bg: 240 10% 4.5%; /* #0c0c0f - slightly lighter than app bg */
|
||||
--sidebar-hover: 240 6% 12%; /* #1e1e23 */
|
||||
--sidebar-active: 243 75% 59% / 0.08; /* brand purple at 8% opacity */
|
||||
--border-subtle: 240 6% 12%; /* #1f1f23 - lighter border for sections */
|
||||
--text-dimmed: 240 4% 24%; /* #3f3f46 - very dim text for timestamps */
|
||||
}
|
||||
```
|
||||
|
||||
### Semantic Status Colors
|
||||
|
||||
These map to session/tree status indicators and MUST be used consistently:
|
||||
|
||||
| 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
|
||||
|
||||
Categories use a fixed palette of distinguishable colors for their dot indicators:
|
||||
|
||||
```typescript
|
||||
// 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;
|
||||
```
|
||||
|
||||
Categories are assigned colors based on their creation order (index % length). Colors are stored on the category model in the database.
|
||||
|
||||
> **Migration needed:** The `tree_categories` table already has `display_order` and `is_active` columns. Add a `color` column:
|
||||
> ```sql
|
||||
> ALTER TABLE tree_categories ADD COLUMN color VARCHAR(7) DEFAULT '#3b82f6';
|
||||
> ```
|
||||
> Backfill existing categories with colors from the palette based on their `display_order`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Workspace System
|
||||
|
||||
### Concept
|
||||
|
||||
Workspaces are the top-level organizational context. They sit **above** the existing folder system — a workspace scopes which trees/flows are visible, while user folders remain available within each workspace for personal organization. When a user switches workspace, the sidebar categories, tags, stats, filters, and main content all adapt.
|
||||
|
||||
> **Important:** Workspaces do NOT replace the existing `UserFolder` system. Folders are per-user personal organization that continue to work within the active workspace context. The folder sidebar, drag-and-drop, and folder-tree junction table are preserved. Workspaces filter what content is available; folders organize it.
|
||||
|
||||
The layout, navigation structure, and component patterns stay identical — only the DATA changes.
|
||||
|
||||
### Workspace Types (Initial Set)
|
||||
|
||||
| Workspace | Description | Icon | Accent Color |
|
||||
|-----------|-------------|------|-------------|
|
||||
| Troubleshooting | Break/fix decision trees | 🔧 | `#ef4444` (red) |
|
||||
| Procedures | Step-by-step operational flows | 📋 | `#3b82f6` (blue) |
|
||||
| Policies | Compliance & policy builders | 📜 | `#8b5cf6` (violet) |
|
||||
| Finance | Billing & procurement flows | 💰 | `#22c55e` (green) |
|
||||
|
||||
**Users and admins can create custom workspaces.** The four above are defaults.
|
||||
|
||||
### Workspace Switcher Component
|
||||
|
||||
Located at the top of the sidebar, below the nav section label. It's a dropdown that shows:
|
||||
|
||||
1. **Current workspace** — icon, name, description, chevron
|
||||
2. **Dropdown options** — all available workspaces with flow counts
|
||||
3. **"Add workspace…"** — link at bottom to create new
|
||||
|
||||
```
|
||||
┌─────────────────────────────┐
|
||||
│ 🔧 Troubleshooting │
|
||||
│ Break/fix decision trees │
|
||||
│ ▼ │
|
||||
├─────────────────────────────┤
|
||||
│ 🔧 Troubleshooting 42 │ ← active (highlighted)
|
||||
│ 📋 Procedures 18 │
|
||||
│ 📜 Policies 7 │
|
||||
│ 💰 Finance 4 │
|
||||
│─────────────────────────────│
|
||||
│ + Add workspace… │
|
||||
└─────────────────────────────┘
|
||||
```
|
||||
|
||||
### Behavior on Workspace Switch
|
||||
|
||||
When the user selects a new workspace:
|
||||
|
||||
1. Sidebar content fades out (200ms opacity transition)
|
||||
2. Data updates:
|
||||
- Categories list → filtered to workspace
|
||||
- Tags cloud → filtered to workspace
|
||||
- Nav badge counts → reflect workspace totals
|
||||
- "All Trees" label → changes (e.g., "All Procedures")
|
||||
- "Tree Editor" label → changes (e.g., "Flow Editor")
|
||||
- Search placeholder → adapts
|
||||
3. Main content fades out/in (200ms opacity transition)
|
||||
- Page title changes
|
||||
- Stats row updates
|
||||
- Filter chips update
|
||||
- Tree/flow list filters to workspace
|
||||
- Sessions panel filters to workspace
|
||||
4. "New Tree" button label → adapts (e.g., "New Procedure")
|
||||
5. Toast notification confirms switch: "Switched to **Procedures**"
|
||||
|
||||
### Data Model
|
||||
|
||||
See [Section 10: Data Model Changes](#10-data-model-changes) for backend schema.
|
||||
|
||||
---
|
||||
|
||||
## 4. Sidebar Components
|
||||
|
||||
### Structure (top to bottom)
|
||||
|
||||
```
|
||||
1. Workspace Switcher (dropdown)
|
||||
2. ─── divider ───
|
||||
3. Primary Navigation
|
||||
- Dashboard (grid icon)
|
||||
- All Trees/Flows (cube icon) [badge: count]
|
||||
- Tree/Flow Editor (pencil icon)
|
||||
- Sessions (clock icon) [badge: active count]
|
||||
- Exports (file 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 (gear icon)
|
||||
```
|
||||
|
||||
### Nav Item Component
|
||||
|
||||
```tsx
|
||||
interface NavItemProps {
|
||||
href: string;
|
||||
icon: LucideIcon;
|
||||
label: string;
|
||||
badge?: number | 'dot';
|
||||
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 in dark mode)
|
||||
- Icon: full opacity
|
||||
|
||||
**Inactive state styling:**
|
||||
- Background: transparent
|
||||
- Text: `text-muted-foreground`
|
||||
- Icon: 70% opacity
|
||||
- Hover: `var(--sidebar-hover)` background
|
||||
|
||||
### Category Item Component
|
||||
|
||||
```tsx
|
||||
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` (Outfit font)
|
||||
- Hover: `var(--sidebar-hover)` background, text brightens
|
||||
|
||||
### Tag Cloud Component
|
||||
|
||||
```tsx
|
||||
interface TagCloudProps {
|
||||
tags: string[];
|
||||
onTagClick: (tag: string) => void;
|
||||
activeTags?: string[];
|
||||
}
|
||||
```
|
||||
|
||||
Renders as flex-wrap container of small chip elements:
|
||||
- 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] | [Search Input (⌘K)] | ──flex grow── | [Quick Launch] [Notifications] [Avatar]
|
||||
```
|
||||
|
||||
### Logo Area
|
||||
|
||||
- Width: `calc(var(--sidebar-w) - 40px)` — aligns with sidebar content
|
||||
- Contains: ResolutionFlow logo SVG (32x32) + branded wordmark
|
||||
- Wordmark: "Resolution" in white + "Flow" in gradient text
|
||||
|
||||
### Search Bar
|
||||
|
||||
- Flex: 1, max-width 480px
|
||||
- Placeholder adapts to workspace context (e.g., "Search trees, sessions, tags…")
|
||||
- Left icon: magnifying glass (Lucide `Search`)
|
||||
- Right badge: keyboard shortcut hint `⌘K` (styled as small pill)
|
||||
- Border: `border-border`, focus: `border-brand-gradient-from`
|
||||
|
||||
### 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
|
||||
|
||||
Every page in the main content follows this vertical flow:
|
||||
|
||||
```
|
||||
1. Page Header (title + action buttons)
|
||||
2. Quick Stats Row (4 cards)
|
||||
3. Filters Bar (chips)
|
||||
4. Content Sections (grouped lists, panels)
|
||||
```
|
||||
|
||||
Not every page needs all sections. The Dashboard uses all four. The Tree Editor page would only use the page header and then the editor workspace.
|
||||
|
||||
### 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` (10px)
|
||||
- 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)]`
|
||||
|
||||
Special value styles:
|
||||
- `.gradient` → `text-gradient-brand`
|
||||
- Colored → direct color style (e.g., amber for warnings)
|
||||
|
||||
### Filters Bar
|
||||
|
||||
Horizontal row of filter chips with a divider before "More Filters":
|
||||
|
||||
```
|
||||
[All*] [Recently Used] [My Trees] [Team Trees] [Defaults] | [⊗ More Filters]
|
||||
```
|
||||
|
||||
Active chip: purple-tinted background/border (same as sidebar tag active state).
|
||||
|
||||
### Section Groups
|
||||
|
||||
Collapsible sections with header:
|
||||
|
||||
```
|
||||
[●] SECTION TITLE 5 [▼]
|
||||
─────────────────────────────
|
||||
```
|
||||
|
||||
- Dot: 8px gradient circle
|
||||
- Title: `font-heading text-[0.8125rem] font-bold uppercase tracking-wide`
|
||||
- Count: pill with `bg-surface` background
|
||||
- Collapse: chevron button (toggles section visibility)
|
||||
|
||||
### Tree/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
|
||||
|
||||
**Icon box:** 36x36px rounded-lg with category-tinted background and emoji.
|
||||
|
||||
**Info column:**
|
||||
- Name: `font-heading text-sm font-semibold`
|
||||
- Meta row: tags (small chips) + step/solution count
|
||||
|
||||
**Category column:** color dot + name in `font-label text-xs`
|
||||
|
||||
**Actions:** Three-dot menu, opacity 0 until row hover.
|
||||
|
||||
### 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 │
|
||||
└──────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Session row grid:
|
||||
```
|
||||
grid-template-columns: 8px 1fr 140px 80px 100px
|
||||
dot name progress ticket time
|
||||
```
|
||||
|
||||
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 (creates "cut out" effect)
|
||||
|
||||
### Toast Notifications
|
||||
|
||||
Fixed-position toast notification (current app uses top-right via Sonner — keep this position for consistency):
|
||||
- Background: `bg-card`
|
||||
- Border: brand gradient border
|
||||
- Border radius: `rounded-xl`
|
||||
- Shadow: `shadow-xl` with heavy dark shadow
|
||||
- Content: emoji icon + message text (supports `<strong>` for emphasis)
|
||||
- Auto-dismiss: 2000ms with fade out
|
||||
|
||||
---
|
||||
|
||||
## 8. Icon System
|
||||
|
||||
### Primary Source: Lucide React
|
||||
|
||||
All icons use [Lucide React](https://lucide.dev) at consistent sizes:
|
||||
|
||||
| Context | Size | Lucide Prop |
|
||||
|---------|------|-------------|
|
||||
| Nav items | 18px | `size={18}` |
|
||||
| Buttons | 16px | `size={16}` |
|
||||
| Top bar actions | 18px | `size={18}` |
|
||||
| Section headers | 14px | `size={14}` |
|
||||
| Filter chips | 14px | `size={14}` |
|
||||
|
||||
### Navigation Icon Mapping
|
||||
|
||||
| Nav Item | Lucide Icon |
|
||||
|----------|-------------|
|
||||
| Dashboard | `LayoutGrid` |
|
||||
| All Trees/Flows | `Box` |
|
||||
| Tree/Flow Editor | `PenLine` |
|
||||
| Sessions | `Clock` |
|
||||
| Exports | `FileText` |
|
||||
| Step Library | `Bookmark` |
|
||||
| Team | `Users` |
|
||||
| Settings | `Settings` |
|
||||
| Search | `Search` |
|
||||
| Quick Launch | `Zap` |
|
||||
| Notifications | `Bell` |
|
||||
| New Tree | `Plus` |
|
||||
| Import | `Upload` |
|
||||
| Filter | `Filter` |
|
||||
| Collapse | `ChevronDown` |
|
||||
| More Actions | `MoreHorizontal` |
|
||||
|
||||
### Category Emoji Icons
|
||||
|
||||
Categories in the tree list use emoji as visual anchors inside tinted icon boxes. These are set per-tree or per-category and stored as a string field.
|
||||
|
||||
Default emoji per common categories:
|
||||
- Networking: 🌐
|
||||
- Active Directory: 🔒
|
||||
- Email/Exchange: 📧
|
||||
- Server Issues: 🖥️
|
||||
- VPN/Remote: 🔌
|
||||
- Citrix/RDS: 🖥️
|
||||
- Printers: 🖨️
|
||||
- Backup/DR: 🔄
|
||||
- Onboarding: 👤
|
||||
- Security: 🔐
|
||||
|
||||
---
|
||||
|
||||
## 9. Animation & Transitions
|
||||
|
||||
### Page/Section Load
|
||||
|
||||
Staggered fade-in using CSS animation:
|
||||
|
||||
```css
|
||||
.fade-in {
|
||||
animation: fadeIn 0.3s ease forwards;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: translateY(6px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
```
|
||||
|
||||
Apply with incrementing `animation-delay` on child sections:
|
||||
- Stats row: 50ms
|
||||
- Filters: 100ms
|
||||
- Section 1: 150ms
|
||||
- Section 2: 200ms
|
||||
|
||||
### Workspace Switch
|
||||
|
||||
Coordinated fade transition:
|
||||
1. Sidebar content: `opacity → 0` (200ms)
|
||||
2. Main content: `opacity → 0` (200ms)
|
||||
3. Data swap (instant)
|
||||
4. Both: `opacity → 1` (200ms)
|
||||
|
||||
### Interactive Elements
|
||||
|
||||
| Element | Property | Duration | Easing |
|
||||
|---------|----------|----------|--------|
|
||||
| Nav item hover | background-color | 120ms | ease |
|
||||
| Button hover | transform, box-shadow | 150ms | ease |
|
||||
| Tree 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 |
|
||||
|
||||
### Workspace Dropdown
|
||||
|
||||
```css
|
||||
@keyframes dropIn {
|
||||
from { opacity: 0; transform: translateY(-4px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Data Model Changes
|
||||
|
||||
### New: `workspaces` Table
|
||||
|
||||
```sql
|
||||
CREATE TABLE workspaces (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name VARCHAR(100) NOT NULL,
|
||||
slug VARCHAR(100) NOT NULL UNIQUE,
|
||||
description TEXT,
|
||||
icon VARCHAR(10), -- emoji character
|
||||
accent_color VARCHAR(7), -- hex color (e.g., '#ef4444')
|
||||
account_id UUID REFERENCES accounts(id) ON DELETE CASCADE,
|
||||
is_default BOOLEAN DEFAULT FALSE,
|
||||
sort_order INTEGER DEFAULT 0,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
```
|
||||
|
||||
**Default workspaces (seeded):**
|
||||
|
||||
| name | slug | icon | accent_color | is_default |
|
||||
|------|------|------|-------------|------------|
|
||||
| Troubleshooting | troubleshooting | 🔧 | #ef4444 | true |
|
||||
| Procedures | procedures | 📋 | #3b82f6 | false |
|
||||
| Policies | policies | 📜 | #8b5cf6 | false |
|
||||
| Finance | finance | 💰 | #22c55e | false |
|
||||
|
||||
### Modified: `trees` Table
|
||||
|
||||
Add column:
|
||||
|
||||
```sql
|
||||
ALTER TABLE trees ADD COLUMN workspace_id UUID REFERENCES workspaces(id);
|
||||
```
|
||||
|
||||
All existing trees get assigned to the "troubleshooting" workspace via data migration.
|
||||
|
||||
> **Note:** The `trees` table already has a `tree_type` column with values `'troubleshooting'` and `'procedural'`. The workspace system is a superset of this — `tree_type` controls tree behavior (branching vs linear), while `workspace_id` controls organizational context. Both fields coexist. The data migration should map existing `tree_type='troubleshooting'` trees to the Troubleshooting workspace and `tree_type='procedural'` trees to the Procedures workspace.
|
||||
|
||||
### Modified: `tree_categories` Table
|
||||
|
||||
Add column:
|
||||
|
||||
```sql
|
||||
ALTER TABLE tree_categories ADD COLUMN workspace_id UUID REFERENCES workspaces(id);
|
||||
```
|
||||
|
||||
Categories become workspace-scoped. A category belongs to one workspace. The existing `account_id` column remains for tenancy — `workspace_id` is an additional organizational dimension within an account.
|
||||
|
||||
### Modified: `tree_tags` Table
|
||||
|
||||
Tags remain global (cross-workspace) but the popular tags query filters by workspace context. The existing `account_id` scoping on tags is preserved.
|
||||
|
||||
### API Changes
|
||||
|
||||
**New endpoints:**
|
||||
|
||||
```
|
||||
GET /api/v1/workspaces -- list all workspaces for user's account
|
||||
POST /api/v1/workspaces -- create workspace (admin)
|
||||
PATCH /api/v1/workspaces/{id} -- update workspace
|
||||
DELETE /api/v1/workspaces/{id} -- soft delete workspace
|
||||
```
|
||||
|
||||
**Modified endpoints:**
|
||||
|
||||
```
|
||||
GET /api/v1/trees?workspace_id={uuid} -- add workspace filter
|
||||
GET /api/v1/categories?workspace_id={uuid} -- categories are a separate router (categories.py)
|
||||
GET /api/v1/sessions?workspace_id={uuid}
|
||||
```
|
||||
|
||||
> **Note:** Categories have their own dedicated router at `/api/v1/categories` (not nested under `/trees/categories`). Tags are at `/api/v1/tags`. Folders are at `/api/v1/folders`. See `backend/app/api/router.py` for the full route registry.
|
||||
|
||||
### Frontend State
|
||||
|
||||
```typescript
|
||||
// store/workspaceStore.ts
|
||||
interface WorkspaceState {
|
||||
workspaces: Workspace[];
|
||||
activeWorkspaceId: string | null;
|
||||
setActiveWorkspace: (id: string) => void;
|
||||
// Persisted in localStorage as 'active-workspace-id'
|
||||
}
|
||||
```
|
||||
|
||||
All tree/session/category queries include the active workspace ID as a filter parameter.
|
||||
|
||||
---
|
||||
|
||||
## 11. Migration Strategy
|
||||
|
||||
### From Current Layout to App Shell
|
||||
|
||||
The current `AppLayout.tsx` uses a top-nav bar with horizontal nav links and an `<Outlet>` for full-width page content. The migration:
|
||||
|
||||
1. **AppLayout.tsx** → Complete rewrite to CSS Grid shell (topbar + sidebar + main)
|
||||
2. **BrandLogo + BrandWordmark** → Move into topbar logo area
|
||||
3. **Nav links** → Move into sidebar as vertical nav items with icons
|
||||
4. **ThemeToggle** → Move into sidebar footer or top bar
|
||||
5. **User menu** → Avatar in top bar with dropdown
|
||||
6. **Outlet** → Renders inside `<main>` grid cell
|
||||
|
||||
### Page-by-Page Adaptation
|
||||
|
||||
| Page | Changes Needed |
|
||||
|------|---------------|
|
||||
| TreeLibraryPage | Becomes the "Dashboard" or "All Trees" view in main content area. Add stats row, filters, and grouped list layout |
|
||||
| TreeNavigationPage | Renders in main content. Scratchpad overlay unchanged (fixed position) |
|
||||
| TreeEditorPage | Renders in main content. Full-width editor workspace |
|
||||
| SessionHistoryPage | Renders in main content. Add filters and session list |
|
||||
| SessionDetailPage | Renders in main content. Minimal changes |
|
||||
| SettingsPage | Renders in main content. Minimal changes |
|
||||
| LoginPage / RegisterPage | **No change** — these render outside the app shell (no sidebar) |
|
||||
|
||||
---
|
||||
|
||||
## 12. Implementation Phases
|
||||
|
||||
### Phase A: Foundation (Backend + Shell)
|
||||
|
||||
1. Create `workspace` table, model, schemas, migration
|
||||
2. Add `workspace_id` to `tree` and `tree_category` tables
|
||||
3. Seed default workspaces
|
||||
4. Data migration: assign all existing trees to "troubleshooting" workspace
|
||||
5. Create workspace API endpoints
|
||||
6. Create `workspaceStore` (Zustand + localStorage)
|
||||
7. **Rewrite `AppLayout.tsx`** to CSS Grid shell with topbar + sidebar + main
|
||||
8. Move existing nav items into sidebar
|
||||
9. Add workspace switcher component (static, no data yet)
|
||||
|
||||
### Phase B: Sidebar Components
|
||||
|
||||
1. Build `NavItem` component with active state + badge
|
||||
2. Build `CategoryList` component with color dots
|
||||
3. Build `TagCloud` component
|
||||
4. Build `WorkspaceSwitcher` dropdown with animations
|
||||
5. Wire workspace switcher to `workspaceStore`
|
||||
6. Update tree/session queries to include workspace filter
|
||||
|
||||
### Phase C: Main Content Redesign
|
||||
|
||||
1. Build `QuickStats` row component
|
||||
2. Build `FiltersBar` component
|
||||
3. Build `SectionGroup` collapsible component
|
||||
4. Build `TreeListItem` component (grid layout)
|
||||
5. Build `SessionsPanel` component
|
||||
6. Redesign `TreeLibraryPage` as Dashboard using new components
|
||||
7. Add search bar with ⌘K shortcut
|
||||
|
||||
### Phase D: Polish & Integration
|
||||
|
||||
1. Add workspace switch animations (fade transitions)
|
||||
2. Add toast notifications for workspace switch
|
||||
3. Responsive breakpoints (collapse sidebar on mobile)
|
||||
4. Update all page components to work within new shell
|
||||
5. E2E testing of workspace switching flow
|
||||
6. Performance testing (workspace switch should be <200ms)
|
||||
|
||||
---
|
||||
|
||||
## Appendix A: File Structure for New Components
|
||||
|
||||
```
|
||||
frontend/src/
|
||||
├── components/
|
||||
│ ├── layout/
|
||||
│ │ ├── AppLayout.tsx ← REWRITE (CSS Grid shell)
|
||||
│ │ ├── TopBar.tsx ← NEW
|
||||
│ │ ├── Sidebar.tsx ← NEW
|
||||
│ │ ├── NavItem.tsx ← NEW
|
||||
│ │ └── ProtectedRoute.tsx (unchanged)
|
||||
│ ├── workspace/
|
||||
│ │ ├── WorkspaceSwitcher.tsx ← NEW
|
||||
│ │ ├── CategoryList.tsx ← NEW
|
||||
│ │ └── TagCloud.tsx ← NEW
|
||||
│ ├── dashboard/
|
||||
│ │ ├── QuickStats.tsx ← NEW
|
||||
│ │ ├── FiltersBar.tsx ← NEW
|
||||
│ │ ├── SectionGroup.tsx ← NEW
|
||||
│ │ ├── TreeListItem.tsx ← NEW
|
||||
│ │ └── SessionsPanel.tsx ← NEW
|
||||
│ └── common/
|
||||
│ ├── Toast.tsx ← NEW
|
||||
│ └── ... (existing)
|
||||
├── store/
|
||||
│ ├── workspaceStore.ts ← NEW
|
||||
│ └── ... (existing)
|
||||
├── api/
|
||||
│ ├── workspaces.ts ← NEW
|
||||
│ └── ... (existing)
|
||||
├── types/
|
||||
│ ├── workspace.ts ← NEW
|
||||
│ └── ... (existing)
|
||||
└── constants/
|
||||
└── categoryColors.ts ← NEW
|
||||
```
|
||||
|
||||
## 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 |
|
||||
| Tree 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 |
|
||||
| Search input | Inter | 400 | 0.8125rem (13px) | normal |
|
||||
|
||||
## Appendix C: Workspace-Specific Adaptations
|
||||
|
||||
When a workspace is active, these elements adapt:
|
||||
|
||||
| Element | Troubleshooting | Procedures | Policies | Finance |
|
||||
|---------|----------------|------------|----------|---------|
|
||||
| "All ___" nav label | All Trees | All Procedures | All Policies | All Finance Flows |
|
||||
| Editor nav label | Tree Editor | Flow Editor | Policy Editor | Flow Editor |
|
||||
| New button label | New Tree | New Procedure | New Policy | New Flow |
|
||||
| Search placeholder | Search trees, sessions, tags… | Search procedures, runbooks… | Search policies, compliance… | Search billing, procurement… |
|
||||
| Stat 1 label | Active Trees | Active Procedures | Active Policies | Active Flows |
|
||||
| Stat 2 label | Sessions Today | Runs This Week | Pending Review | Runs This Month |
|
||||
| Stat 3 label | Open Sessions | In Progress | Compliance Score | Cost Saved |
|
||||
| Stat 4 label | Docs Generated | Avg Completion | Last Audit | Pending Approvals |
|
||||
Reference in New Issue
Block a user