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:
- 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)ΒΆ
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ΒΆ
- PanelMenu - Main container component
- QuickAccessGrid - Pinnable shortcut tiles
- RecentlyVisited - History list with entity context
- MenuSection - Collapsible group with header
- MenuSearch - Filter input with keyboard nav
- 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ΒΆ
- Current state: Static sidebar with grouped sections
- Add search: Non-breaking enhancement
- Add badges: Requires API integration
- Add recently visited: localStorage-based
- Add quick access: localStorage-based with pin UI
- Full panel: Major UI change, consider feature flag
Questions to ResolveΒΆ
- Should preferences sync to server or stay local-only?
- Show "Recently Visited" for all users or just admins?
- Include quick access tiles on mobile or simplify?
- 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.