# Research: Superset-Style UX Redesign **Feature**: 019-superset-ux-redesign **Date**: 2026-02-09 ## Research Tasks ### 1. SvelteKit Layout Patterns for Persistent UI **Decision**: Use root `+layout.svelte` for Sidebar and TaskDrawer **Rationale**: - SvelteKit's layout components persist across route changes by default - Placing Sidebar and TaskDrawer in the root layout ensures they are always available - Slot-based composition allows content pages to render in the main area **Alternatives Considered**: - Per-page imports: Rejected due to code duplication and state management complexity - Web Components: Rejected as SvelteKit native layouts are more idiomatic ### 2. Real-time Task Updates via WebSocket **Decision**: Extend existing WebSocket infrastructure for Task Drawer **Rationale**: - Backend already has WebSocket support in `backend/src/app.py` - TaskManager emits events that can be broadcast to connected clients - Existing `TaskLogViewer` component already subscribes to task updates **Implementation Notes**: - Create a new store `taskDrawer.js` that subscribes to WebSocket events - Map resource IDs to task IDs using a reactive `resourceTaskMap` store - Activity indicator reads from a derived store counting active tasks ### 3. Sidebar State Persistence **Decision**: Use Svelte stores with `localStorage` sync **Rationale**: - User preference for collapsed/expanded sidebar should persist across sessions - Svelte's `writable` stores can be extended with localStorage sync - Pattern already used in other parts of the application **Code Pattern**: ```javascript function persistentStore(key, defaultValue) { const stored = localStorage.getItem(key); const store = writable(stored ? JSON.parse(stored) : defaultValue); store.subscribe(value => localStorage.setItem(key, JSON.stringify(value))); return store; } ``` ### 4. Resource-to-Task Mapping **Decision**: Create a new store `resourceTaskMap` in `taskDrawer.js` **Rationale**: - Need to track which task is associated with which resource (dashboard/dataset) - When user clicks a status badge, the drawer opens with the correct task - Map structure: `{ resourceUuid: { taskId, status } }` **Alternatives Considered**: - Backend tracking: Rejected to avoid additional API calls - URL-based task ID: Rejected as it doesn't support background tasks ### 5. Settings Consolidation **Decision**: Create a unified Settings page with tabbed navigation **Rationale**: - Current settings are scattered across multiple pages - Tabbed interface allows grouping: Environments, Connections, LLM, Logging, System - Existing settings APIs can be consolidated into a single route **Implementation Notes**: - Reuse existing settings components where possible - Add role-based visibility for admin-only tabs - Use SvelteKit's nested routes for each settings tab ### 6. Responsive Sidebar Behavior **Decision**: CSS media queries + conditional rendering **Rationale**: - Desktop (≥1024px): Sidebar visible by default, collapsible - Tablet (768-1023px): Sidebar collapsed to icons - Mobile (<768px): Sidebar hidden, hamburger menu in top navbar **Implementation Notes**: - Use Tailwind's responsive prefixes (`md:`, `lg:`) - Overlay mode on mobile with backdrop click-to-close - Store sidebar state in `sidebar.js` store ## Resolved Clarifications | Item | Resolution | |------|------------| | Animation timing | Sidebar: 200ms ease-in-out, Drawer: 150ms slide | | Empty states | Show illustration + message + CTA button | | Breadcrumb depth limit | Truncate middle items with ellipsis after 3 levels | | Activity badge polling | Real-time via WebSocket, no polling needed | ## Dependencies Confirmed - `backend/src/core/task_manager`: ✅ Available for task state - `backend/src/core/superset_client`: ✅ Available for resource fetching - `frontend/src/lib/api.js`: ✅ requestApi wrapper available - `frontend/src/lib/i18n`: ✅ i18n system available