# 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
