Files
2026-02-09 12:35:27 +03:00

110 lines
3.9 KiB
Markdown

# 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