Skip to content

AWS-Style Panel Menu Design

Overview

Replace the current sidebar with an AWS Console-inspired navigation panel that adapts to user behavior and role.

AWS Console Menu Features (Reference)

AWS Console sidebar includes: 1. Pinned/Favorites - User-pinned services at top 2. Recently Visited - Last 5-10 accessed services 3. All Services - Grouped by category (Compute, Storage, etc.) 4. Search - Quick filter across all menu items 5. Collapse/Expand - Icon-only mode

Proposed cbapp Panel Features

1. Quick Access Section (Top)

Personalized shortcuts based on usage patterns:

┌─────────────────────────────┐
│ ⭐ Quick Access             │
│ ┌─────┐ ┌─────┐ ┌─────┐    │
│ │Queue│ │ AI  │ │Audit│    │
│ └─────┘ └─────┘ └─────┘    │
│ ┌─────┐ ┌─────┐            │
│ │Segs │ │Users│            │
│ └─────┘ └─────┘            │
└─────────────────────────────┘
  • Max 6 items
  • Default based on role, then learns from usage
  • User can pin/unpin items

2. Recently Visited

Auto-populated from navigation history:

┌─────────────────────────────┐
│ 🕒 Recently Visited         │
│  • Segment: Likely Voters   │
│  • Person: John Smith       │
│  • Event: Town Hall 12/15   │
│  • Report: Weekly Summary   │
└─────────────────────────────┘
  • Shows last 5 visited pages with context
  • Includes entity names, not just page types
  • Stored in localStorage + optional DB sync

3. Role-Based Sections

Field Staff View:

┌─────────────────────────────┐
│ 📋 My Tasks                 │
│  • Work Queue (12 pending)  │
│  • My Assignments           │
│  • Event Check-ins          │
│                             │
│ 📞 Outreach                 │
│  • Communications           │
│  • Call Lists               │
│                             │
│ 🤖 Tools                    │
│  • AI Assistant             │
│  • Map                      │
└─────────────────────────────┘

Director/Admin View:

┌─────────────────────────────┐
│ 📊 Overview                 │
│  • Dashboard                │
│  • Reports                  │
│  • Goals Progress           │
│                             │
│ 👥 Team                     │
│  • Work Queues (all)        │
│  • User Management          │
│  • Assignments              │
│                             │
│ 📁 Data                     │
│  • Audience                 │
│  • Segments                 │
│  • Tags                     │
│  • i360 Integration         │
│  • Import/Export            │
│                             │
│ 🤖 Tools                    │
│  • AI Assistant             │
│  • Map                      │
│                             │
│ ⚙️ Admin                    │
│  • Settings                 │
│  • Audit Log                │
└─────────────────────────────┘

4. Search/Filter

Quick search across menu items:

┌─────────────────────────────┐
│ 🔍 Search menu...           │
└─────────────────────────────┘
  • Fuzzy match on menu item names
  • Keyboard shortcut: Cmd/Ctrl + K
  • Shows matching items as you type

5. Badge Notifications

Show counts on menu items:

│  • Work Queue       ●12     │
│  • Communications    ●3     │
  • Pending work queue items
  • Unread communications
  • Upcoming events

Data Model

User Preferences (localStorage + DB)

{
  "pinnedItems": ["work-queue", "ai-chat", "segments"],
  "recentlyVisited": [
    {"path": "/segments/abc123", "title": "Likely Voters", "timestamp": "..."},
    {"path": "/persons/xyz789", "title": "John Smith", "timestamp": "..."}
  ],
  "sidebarCollapsed": false,
  "menuLayout": "panel"  // "panel" | "classic"
}

API Endpoint (Optional)

GET /api/users/me/preferences
PUT /api/users/me/preferences

Syncs preferences across devices.

Implementation Phases

Phase 1: Enhanced Current Sidebar

  • Add search filter at top
  • Add badges for counts
  • Persist collapsed state
  • Effort: Small

Phase 2: Quick Access + Recently Visited

  • Add localStorage tracking for page visits
  • Show Quick Access section with pinned items
  • Show Recently Visited section
  • Effort: Medium

Phase 3: Full Panel Mode

  • Redesign as slide-out panel (like AWS)
  • Grid layout for Quick Access
  • Role-adaptive sections
  • DB sync for preferences
  • Effort: Large

UI Components Needed

  1. PanelMenu - Main container component
  2. QuickAccessGrid - Pinnable shortcut tiles
  3. RecentlyVisited - History list with entity context
  4. MenuSection - Collapsible group with header
  5. MenuSearch - Filter input with keyboard nav
  6. MenuBadge - Notification count indicator

CSS Architecture

/* Panel container */
.panel-menu {
  width: 280px;
  height: 100vh;
  position: fixed;
  left: 0;
  top: 64px;
  background: var(--color-surface);
  border-right: 1px solid var(--color-border);
  overflow-y: auto;
  transition: width 0.2s ease;
}

.panel-menu.collapsed {
  width: 64px;
}

/* Quick access grid */
.quick-access-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  padding: 12px;
}

.quick-access-tile {
  aspect-ratio: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  background: var(--color-surface-alt);
  cursor: pointer;
  transition: all 0.15s ease;
}

.quick-access-tile:hover {
  background: var(--color-primary-light);
}

/* Menu sections */
.menu-section {
  border-bottom: 1px solid var(--color-border);
  padding-bottom: 8px;
  margin-bottom: 8px;
}

.menu-section-header {
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-text-secondary);
  padding: 12px 16px 8px;
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Badges */
.menu-badge {
  background: var(--color-primary);
  color: white;
  font-size: 0.65rem;
  font-weight: 600;
  padding: 2px 6px;
  border-radius: 10px;
  margin-left: auto;
}

JavaScript Architecture

// Navigation tracking
class NavigationTracker {
  constructor() {
    this.maxRecent = 10;
    this.storageKey = 'cbapp_nav_history';
  }

  trackVisit(path, title, entityType) {
    const history = this.getHistory();
    const entry = {
      path,
      title,
      entityType,
      timestamp: new Date().toISOString()
    };

    // Remove duplicate, add to front
    const filtered = history.filter(h => h.path !== path);
    filtered.unshift(entry);

    // Trim to max
    localStorage.setItem(
      this.storageKey,
      JSON.stringify(filtered.slice(0, this.maxRecent))
    );
  }

  getHistory() {
    try {
      return JSON.parse(localStorage.getItem(this.storageKey)) || [];
    } catch {
      return [];
    }
  }
}

// Quick access management
class QuickAccessManager {
  constructor() {
    this.storageKey = 'cbapp_quick_access';
    this.maxItems = 6;
  }

  getPinned() {
    try {
      return JSON.parse(localStorage.getItem(this.storageKey)) || [];
    } catch {
      return [];
    }
  }

  togglePin(itemId) {
    const pinned = this.getPinned();
    const index = pinned.indexOf(itemId);

    if (index >= 0) {
      pinned.splice(index, 1);
    } else if (pinned.length < this.maxItems) {
      pinned.push(itemId);
    }

    localStorage.setItem(this.storageKey, JSON.stringify(pinned));
    return pinned;
  }
}

// Menu search
function initMenuSearch() {
  const input = document.getElementById('menuSearch');
  const items = document.querySelectorAll('.menu-item');

  input.addEventListener('input', (e) => {
    const query = e.target.value.toLowerCase();

    items.forEach(item => {
      const text = item.textContent.toLowerCase();
      item.style.display = text.includes(query) ? '' : 'none';
    });

    // Show/hide sections based on visible items
    document.querySelectorAll('.menu-section').forEach(section => {
      const hasVisible = section.querySelector('.menu-item:not([style*="display: none"])');
      section.style.display = hasVisible ? '' : 'none';
    });
  });

  // Keyboard shortcut
  document.addEventListener('keydown', (e) => {
    if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
      e.preventDefault();
      input.focus();
    }
  });
}

Migration Path

  1. Current state: Static sidebar with grouped sections
  2. Add search: Non-breaking enhancement
  3. Add badges: Requires API integration
  4. Add recently visited: localStorage-based
  5. Add quick access: localStorage-based with pin UI
  6. Full panel: Major UI change, consider feature flag

Questions to Resolve

  1. Should preferences sync to server or stay local-only?
  2. Show "Recently Visited" for all users or just admins?
  3. Include quick access tiles on mobile or simplify?
  4. Allow users to switch between "panel" and "classic" modes?

Files to Modify

src/app/templates/layout.html          # Panel menu HTML
src/app/static/css/styles.css          # Panel styles
src/app/static/js/panel-menu.js        # NEW: Panel logic
src/api/routes/users.py                # Preferences endpoint (optional)
src/api/models/user.py                 # Preferences model (optional)

Timeline Estimate

  • Phase 1 (Search + Badges): 1-2 sessions
  • Phase 2 (Quick Access + Recent): 2-3 sessions
  • Phase 3 (Full Panel): 3-5 sessions

Total: ~6-10 development sessions for complete implementation.