diff --git a/.kilocode/rules/specify-rules.md b/.kilocode/rules/specify-rules.md index d24793b..117d923 100644 --- a/.kilocode/rules/specify-rules.md +++ b/.kilocode/rules/specify-rules.md @@ -33,6 +33,8 @@ Auto-generated from all feature plans. Last updated: 2025-12-19 - N/A (UI reorganization and API integration) (015-frontend-nav-redesign) - SQLite (`auth.db`) for Users, Roles, Permissions, and Mappings. (016-multi-user-auth) - SQLite (existing `tasks.db` for results, `auth.db` for permissions, `mappings.db` or new `plugins.db` for provider config/metadata) (017-llm-analysis-plugin) +- Python 3.9+ (Backend), Node.js 18+ (Frontend) + FastAPI, SvelteKit, Tailwind CSS, SQLAlchemy, WebSocket (existing) (019-superset-ux-redesign) +- SQLite (tasks.db, auth.db, migrations.db) - no new database tables required (019-superset-ux-redesign) - Python 3.9+ (Backend), Node.js 18+ (Frontend Build) (001-plugin-arch-svelte-ui) @@ -53,9 +55,9 @@ cd src; pytest; ruff check . Python 3.9+ (Backend), Node.js 18+ (Frontend Build): Follow standard conventions ## Recent Changes +- 019-superset-ux-redesign: Added Python 3.9+ (Backend), Node.js 18+ (Frontend) + FastAPI, SvelteKit, Tailwind CSS, SQLAlchemy, WebSocket (existing) - 017-llm-analysis-plugin: Added Python 3.9+ (Backend), Node.js 18+ (Frontend) - 016-multi-user-auth: Added Python 3.9+ (Backend), Node.js 18+ (Frontend) -- 015-frontend-nav-redesign: Added Python 3.9+ (Backend), Node.js 18+ (Frontend) + FastAPI (Backend), SvelteKit + Tailwind CSS (Frontend) diff --git a/docs/design/resource_centric_layout.md b/docs/design/resource_centric_layout.md new file mode 100644 index 0000000..b9247a2 --- /dev/null +++ b/docs/design/resource_centric_layout.md @@ -0,0 +1,145 @@ +# Design Document: Resource-Centric UI & Unified Task Experience + +## 1. Core Philosophy + +The application moves from a **Task-Centric** model (where users navigate to "Migration Tool" or "Git Tool") to a **Resource-Centric** model. Users navigate to the object they want to manage (Dashboard, Dataset) and perform actions on it. + +**Goals:** +1. **Context preservation:** Users shouldn't lose their place in a list just to see a log. +2. **Discoverability:** All actions available for a resource are grouped together. +3. **Traceability:** Every action is explicitly linked to a Task ID with accessible logs. + +--- + +## 2. Navigation Structure (Navbar) + +**Old Menu:** +`[Home] [Migration] [Git Manager] [Mapper] [Settings] [Logout]` + +**New Menu:** +`[Superset Manager] [Dashboards] [Datasets] [Storage] | [Activity (0)] [Settings] [User]` + +* **Dashboards**: Main hub for all dashboard operations (Migrate, Backup, Git). +* **Datasets**: Hub for dataset documentation and mapping. +* **Storage**: File management (Backups, Repositories). +* **Activity**: Global indicator of running tasks. Clicking it opens the Task Drawer. + +--- + +## 3. Page Layouts + +### 3.1. Dashboard Hub (`/dashboards`) + +The central place for managing Superset Dashboards. + +**Wireframe:** +```text ++-----------------------------------------------------------------------+ +| Select Source Env: [ Development (v) ] [ Refresh ] | ++-----------------------------------------------------------------------+ +| Search: [ Filter by title... ] | ++-----------------------------------------------------------------------+ +| Title | Slug | Git Status | Last Task | Actions | +|------------------|-------------|---------------|-----------|----------| +| Sales Report | sales-2023 | 🌿 main (OK) | (v) Done | [ ... ] | +| HR Analytics | hr-dash | - | ( ) Idle | [ ... ] | +| Logs Monitor | logs-v2 | 🌿 dev (Diff) | (@) Run.. | [ ... ] | ++-----------------------------------------------------------------------+ +``` + +**Interaction Details:** +1. **Source Env Selector**: Loads dashboards via `superset_client.get_dashboards`. +2. **Status Column ("Last Task")**: + * Shows the status of the *last known action* for this dashboard in the current session. + * **States**: `Idle`, `Running` (Spinner), `Waiting Input` (Orange Key), `Success` (Green Check), `Error` (Red X). + * **Click Action**: Clicking the icon/badge opens the **Task Drawer**. +3. **Actions Menu ([ ... ])**: + * **Migrate**: Opens `DeploymentModal` (Simplified: just Target Env selector). + * **Backup**: Immediately triggers `BackupPlugin`. + * **Git Operations**: + * *Init Repo* (if Git Status is empty). + * *Commit/Push*, *History*, *Checkout* (if Git initialized). + * **Validate**: Triggers LLM Analysis. + +### 3.2. Dataset Hub (`/datasets`) + +The central place for managing physical datasets and semantic layers. + +**Wireframe:** +```text ++-----------------------------------------------------------------------+ +| Select Source Env: [ Production (v) ] | ++-----------------------------------------------------------------------+ +| Table Name | Schema | Mapped Fields | Last Task | Actions | +|------------------|-------------|---------------|-----------|----------| +| fact_orders | public | 15 / 20 | (v) Done | [ ... ] | +| dim_users | auth | 0 / 5 | ( ) Idle | [ ... ] | ++-----------------------------------------------------------------------+ +``` + +**Actions Menu ([ ... ])**: +* **Map Columns**: Opens the Mapping Modal (replaces `MapperPage`). +* **Generate Docs**: Triggers `DocumentationPlugin`. + +--- + +## 4. The Global Task Drawer + +**Concept:** A slide-out panel that overlays the right side of the screen. It persists in the DOM layout (Global Layout) but is hidden until triggered. + +**Trigger Points:** +1. Clicking a **Status Badge** in any Grid row (Dashboard or Dataset). +2. Clicking the **Activity** indicator in the Navbar. + +**Layout:** +```text ++---------------------------------------------------------------+ +| Task: Migration "Sales Report" [X] Close | +| ID: 1234-5678-uuid | +| Status: WAITING_INPUT (Paused) | ++---------------------------------------------------------------+ +| | +| [Log Stream Area] | +| 10:00:01 [INFO] Starting migration... | +| 10:00:02 [INFO] Exporting dashboard... | +| 10:00:05 [WARN] Target DB requires password! | +| | ++---------------------------------------------------------------+ +| INTERACTIVE AREA (Dynamic) | +| | +| Target Database: "Production DB" | +| Enter Password: [ ********** ] | +| | +| [ Cancel ] [ Resume Task ] | ++---------------------------------------------------------------+ +``` + +**Behavior:** +* **Context Aware**: If I trigger a migration on "Sales Report", the Drawer automatically opens and subscribes to that task's ID. +* **Multi-Tasking**: I can close the drawer (click [X]) to let the task run in the background. The "Activity" badge in the navbar increments. +* **Input Handling**: Components like `PasswordPrompt` or `MissingMappingModal` are no longer center-screen modals blocking the whole UI. They are rendered *inside* the Interactive Area of the Drawer. + +--- + +## 5. Technical Component Architecture + +### 5.1. Stores (`stores/tasks.js`) +Needs a new reactive store structure to map Resources to Tasks. + +```javascript +// Map resource UUIDs to their active/latest task UUIDs +export const resourceTaskMap = writable({ + "dashboard-uuid-1": { taskId: "task-uuid-A", status: "RUNNING" }, + "dataset-uuid-2": { taskId: "task-uuid-B", status: "SUCCESS" } +}); + +// The currently focused task in the Drawer +export const activeDrawerTask = writable(null); // { taskId: "..." } +export const isDrawerOpen = writable(false); +``` + +### 5.2. Components +* `DashboardHub.svelte`: Main page. +* `DatasetHub.svelte`: Main page. +* `GlobalTaskDrawer.svelte`: Lives in `+layout.svelte`. Connects to `activeDrawerTask`. +* `ActionMenu.svelte`: Reusable dropdown for grids. \ No newline at end of file diff --git a/specs/019-superset-ux-redesign/checklists/requirements.md b/specs/019-superset-ux-redesign/checklists/requirements.md new file mode 100644 index 0000000..5692176 --- /dev/null +++ b/specs/019-superset-ux-redesign/checklists/requirements.md @@ -0,0 +1,46 @@ +# Specification Quality Checklist: Superset-Style UX Redesign + +**Purpose**: Validate specification completeness and quality before proceeding to planning +**Created**: 2026-02-08 +**Feature**: [specs/019-superset-ux-redesign/spec.md](../spec.md) + +## Content Quality + +- [x] No implementation details (languages, frameworks, APIs) +- [x] Focused on user value and business needs +- [x] Written for non-technical stakeholders +- [x] All mandatory sections completed + +## UX Consistency + +- [x] Functional requirements fully support the 'Happy Path' in ux_reference.md +- [x] Error handling requirements match the 'Error Experience' in ux_reference.md +- [x] No requirements contradict the defined User Persona or Context +- [x] Top navbar design is consistent with mockups in ux_reference.md +- [x] Settings consolidation aligns with sidebar navigation structure + +## Requirement Completeness + +- [x] No [NEEDS CLARIFICATION] markers remain +- [x] Requirements are testable and unambiguous +- [x] Success criteria are measurable +- [x] Success criteria are technology-agnostic (no implementation details) +- [x] All acceptance scenarios are defined +- [x] Edge cases are identified +- [x] Scope is clearly bounded +- [x] Dependencies and assumptions identified + +## Feature Readiness + +- [x] All functional requirements have clear acceptance criteria +- [x] User scenarios cover primary flows (6 user stories defined) +- [x] Feature meets measurable outcomes defined in Success Criteria +- [x] No implementation details leak into specification + +## Notes + +- The specification has been updated to align with the "Resource-Centric" philosophy described in `docs/design/resource_centric_layout.md`. +- All "Tool-Centric" references (Migration Tool, Git Tool) have been replaced with "Resource Hubs" (Dashboard Hub, Dataset Hub). +- The Task Drawer is now the central mechanism for all task interactions. +- **New additions**: Top Navigation Bar design (User Story 5) and Consolidated Settings experience (User Story 6). +- Functional requirements have been reorganized into logical groups: Navigation & Layout, Resource Hubs, Task Management, Settings & Configuration. diff --git a/specs/019-superset-ux-redesign/contracts/api.md b/specs/019-superset-ux-redesign/contracts/api.md new file mode 100644 index 0000000..55a2b3a --- /dev/null +++ b/specs/019-superset-ux-redesign/contracts/api.md @@ -0,0 +1,242 @@ +# API Contracts: Superset-Style UX Redesign + +**Feature**: 019-superset-ux-redesign +**Date**: 2026-02-09 + +## Overview + +This document defines the API contracts for new endpoints required by the Resource-Centric UI. All endpoints follow existing patterns in the codebase. + +## New Endpoints + +### 1. Dashboard Hub API + +#### GET /api/dashboards + +**Purpose**: Fetch list of dashboards from a specific environment for the Dashboard Hub grid. + +**Query Parameters**: +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| env_id | string | Yes | Environment ID to fetch dashboards from | +| search | string | No | Filter by title/slug | + +**Response**: +```json +{ + "dashboards": [ + { + "id": "uuid-string", + "title": "Sales Report", + "slug": "sales-2023", + "url": "/superset/dashboard/sales-2023", + "git_status": { + "branch": "main", + "sync_status": "OK" | "DIFF" | null + }, + "last_task": { + "task_id": "task-uuid", + "status": "SUCCESS" | "RUNNING" | "ERROR" | "WAITING_INPUT" | null + } + } + ] +} +``` + +**Errors**: +- `404`: Environment not found +- `503`: Superset connection error + +--- + +### 2. Dataset Hub API + +#### GET /api/datasets + +**Purpose**: Fetch list of datasets from a specific environment for the Dataset Hub grid. + +**Query Parameters**: +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| env_id | string | Yes | Environment ID to fetch datasets from | +| search | string | No | Filter by table name | + +**Response**: +```json +{ + "datasets": [ + { + "id": "uuid-string", + "table_name": "fact_orders", + "schema": "public", + "database": "Production DB", + "mapped_fields": { + "total": 20, + "mapped": 15 + }, + "last_task": { + "task_id": "task-uuid", + "status": "SUCCESS" | null + } + } + ] +} +``` + +--- + +### 3. Activity API + +#### GET /api/activity + +**Purpose**: Fetch summary of active and recent tasks for the navbar indicator. + +**Response**: +```json +{ + "active_count": 3, + "recent_tasks": [ + { + "task_id": "task-uuid", + "resource_name": "Sales Report", + "resource_type": "dashboard", + "status": "RUNNING", + "started_at": "2026-02-09T10:00:00Z" + } + ] +} +``` + +--- + +### 4. Consolidated Settings API + +#### GET /api/settings + +**Purpose**: Fetch all settings categories for the consolidated settings page. + +**Response**: +```json +{ + "environments": [ + { "id": "1", "name": "Development", "url": "http://dev...", "status": "OK" } + ], + "connections": [ + { "id": "1", "name": "Prod Clickhouse", "type": "clickhouse" } + ], + "llm": { + "provider": "openai", + "model": "gpt-4", + "enabled": true + }, + "logging": { + "level": "INFO", + "task_log_level": "DEBUG", + "belief_scope_enabled": false + } +} +``` + +--- + +## WebSocket Events (Existing) + +The Task Drawer subscribes to existing WebSocket events: + +### task:status +```json +{ + "task_id": "uuid", + "status": "RUNNING" | "SUCCESS" | "ERROR" | "WAITING_INPUT" +} +``` + +### task:log +```json +{ + "task_id": "uuid", + "timestamp": "2026-02-09T10:00:00Z", + "level": "INFO", + "source": "plugin", + "message": "Starting migration..." +} +``` + +### task:input_required +```json +{ + "task_id": "uuid", + "input_type": "password" | "mapping_selection", + "prompt": "Enter database password" +} +``` + +--- + +## Module Contracts (Semantic Protocol) + +### SidebarStore (frontend/src/lib/stores/sidebar.js) + +```javascript +// [DEF:SidebarStore:Store] +// @TIER: STANDARD +// @PURPOSE: Manage sidebar visibility and navigation state +// @LAYER: UI +// @INVARIANT: isExpanded state is always synced with localStorage + +// @UX_STATE: Idle -> Sidebar visible with current state +// @UX_STATE: Toggling -> Animation plays for 200ms + +export const sidebarStore = writable({ + isExpanded: true, + activeCategory: 'dashboards', + activeItem: '/dashboards', + isMobileOpen: false +}); + +export function toggleSidebar() { /* ... */ } +export function setActiveItem(path) { /* ... */ } +// [/DEF:SidebarStore] +``` + +### TaskDrawerStore (frontend/src/lib/stores/taskDrawer.js) + +```javascript +// [DEF:TaskDrawerStore:Store] +// @TIER: CRITICAL +// @PURPOSE: Manage Task Drawer visibility and resource-to-task mapping +// @LAYER: UI +// @INVARIANT: resourceTaskMap always reflects current task associations + +// @UX_STATE: Closed -> Drawer hidden, no active task +// @UX_STATE: Open -> Drawer visible, logs streaming +// @UX_STATE: InputRequired -> Interactive form rendered in drawer + +export const taskDrawerStore = writable({ + isOpen: false, + activeTaskId: null, + resourceTaskMap: {} +}); + +export function openDrawerForTask(taskId) { /* ... */ } +export function closeDrawer() { /* ... */ } +export function updateResourceTask(resourceId, taskId, status) { /* ... */ } +// [/DEF:TaskDrawerStore] +``` + +### ActivityStore (frontend/src/lib/stores/activity.js) + +```javascript +// [DEF:ActivityStore:Store] +// @TIER: STANDARD +// @PURPOSE: Track active task count for navbar indicator +// @LAYER: UI +// @RELATION: DEPENDS_ON -> WebSocket connection + +export const activityStore = derived(taskDrawerStore, ($drawer) => { + const activeCount = Object.values($drawer.resourceTaskMap) + .filter(t => t.status === 'RUNNING').length; + return { activeCount }; +}); +// [/DEF:ActivityStore] +``` diff --git a/specs/019-superset-ux-redesign/data-model.md b/specs/019-superset-ux-redesign/data-model.md new file mode 100644 index 0000000..9b035fb --- /dev/null +++ b/specs/019-superset-ux-redesign/data-model.md @@ -0,0 +1,122 @@ +# Data Model: Superset-Style UX Redesign + +**Feature**: 019-superset-ux-redesign +**Date**: 2026-02-09 + +## Overview + +This feature primarily introduces frontend state management and UI components. No new database tables are required. The data model focuses on client-side stores for managing UI state. + +## Frontend Stores + +### 1. SidebarStore + +**Purpose**: Manage sidebar visibility and collapse state + +```typescript +interface SidebarState { + isExpanded: boolean; // true = full width, false = icons only + activeCategory: string; // 'dashboards' | 'datasets' | 'storage' | 'admin' + activeItem: string; // Current route path + isMobileOpen: boolean; // For mobile overlay mode +} +``` + +**Persistence**: localStorage key `sidebar_state` + +### 2. TaskDrawerStore + +**Purpose**: Manage Task Drawer visibility and resource-to-task mapping + +```typescript +interface TaskDrawerState { + isOpen: boolean; + activeTaskId: string | null; + resourceTaskMap: Record; +} +``` + +**Example**: +```javascript +resourceTaskMap: { + "dashboard-uuid-123": { taskId: "task-abc", status: "RUNNING" }, + "dataset-uuid-456": { taskId: "task-def", status: "SUCCESS" } +} +``` + +### 3. ActivityStore + +**Purpose**: Track count of active tasks for navbar indicator + +```typescript +interface ActivityState { + activeCount: number; // Number of RUNNING tasks + recentTasks: TaskSummary[]; // Last 5 tasks for quick access +} + +interface TaskSummary { + taskId: string; + resourceName: string; + resourceType: 'dashboard' | 'dataset'; + status: string; + startedAt: string; +} +``` + +### 4. SettingsStore + +**Purpose**: Cache settings data for consolidated settings page + +```typescript +interface SettingsState { + activeTab: 'environments' | 'connections' | 'llm' | 'logging' | 'system'; + environments: Environment[]; + connections: Connection[]; + llmSettings: LLMSettings; + loggingSettings: LoggingSettings; +} +``` + +## Backend Entities (Existing) + +The following entities are used but not modified: + +### Task (from `backend/src/models/task.py`) +- `id`: UUID +- `status`: Enum (RUNNING, SUCCESS, ERROR, WAITING_INPUT) +- `plugin_name`: String +- `created_at`: DateTime +- `metadata`: JSON (includes `resource_id`, `resource_type`) + +### Environment (from `backend/src/models/connection.py`) +- Used for Source Environment selector in hubs + +## State Transitions + +### Task Status in Resource Grid + +``` +IDLE β†’ (user triggers action) β†’ RUNNING +RUNNING β†’ (task needs input) β†’ WAITING_INPUT +RUNNING β†’ (task completes) β†’ SUCCESS +RUNNING β†’ (task fails) β†’ ERROR +WAITING_INPUT β†’ (user provides input) β†’ RUNNING +``` + +### Sidebar State Flow + +``` +Expanded ←→ Collapsed (user toggle) +Hidden (mobile) β†’ Overlay Open (hamburger click) β†’ Hidden (outside click) +``` + +### Task Drawer State Flow + +``` +Closed β†’ Open (click status badge or activity indicator) +Open β†’ Closed (click X or select different task) +Open β†’ Open+DifferentTask (click different status badge) +``` diff --git a/specs/019-superset-ux-redesign/plan.md b/specs/019-superset-ux-redesign/plan.md new file mode 100644 index 0000000..1d1327f --- /dev/null +++ b/specs/019-superset-ux-redesign/plan.md @@ -0,0 +1,107 @@ +# Implementation Plan: Superset-Style UX Redesign + +**Branch**: `019-superset-ux-redesign` | **Date**: 2026-02-09 | **Spec**: [spec.md](./spec.md) +**Input**: Feature specification from `/specs/019-superset-ux-redesign/spec.md` + +## Summary + +Redesign the application from a **Task-Centric** model (users navigate to tools) to a **Resource-Centric** model (users navigate to resources like Dashboards, Datasets). Key components include: +- Persistent left sidebar with resource categories +- Global Task Drawer for monitoring background operations +- Dashboard Hub and Dataset Hub as primary management interfaces +- Unified top navigation bar with activity indicator +- Consolidated Settings section + +## Technical Context + +**Language/Version**: Python 3.9+ (Backend), Node.js 18+ (Frontend) +**Primary Dependencies**: FastAPI, SvelteKit, Tailwind CSS, SQLAlchemy, WebSocket (existing) +**Storage**: SQLite (tasks.db, auth.db, migrations.db) - no new database tables required +**Testing**: pytest (backend), Vitest/Playwright (frontend) +**Target Platform**: Web (Desktop primary, responsive for mobile) +**Project Type**: Web application (frontend + backend) +**Performance Goals**: Task Drawer opens < 200ms, sidebar animation < 300ms +**Constraints**: No blocking modals for task inputs, real-time log streaming via WebSocket +**Scale/Scope**: ~20 new frontend components, 5 new API endpoints, 3 new stores + +## Constitution Check + +*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* + +| Principle | Status | Notes | +|-----------|--------|-------| +| I. Semantic Protocol Compliance | βœ… PASS | All new components will use [DEF] anchors and @UX_STATE tags | +| II. Everything is a Plugin | βœ… PASS | No new plugins required; existing plugins (Migration, Backup, Git) will be triggered from Resource Hubs | +| III. Unified Frontend Experience | βœ… PASS | Using existing component library, i18n system, and requestApi wrapper | +| IV. Security & Access Control | βœ… PASS | ADMIN section visibility controlled by existing RBAC | +| V. Independent Testability | βœ… PASS | Each User Story has defined independent test scenarios | +| VI. Asynchronous Execution | βœ… PASS | Task Drawer integrates with existing TaskManager and WebSocket | + +## Project Structure + +### Documentation (this feature) + +```text +specs/019-superset-ux-redesign/ +β”œβ”€β”€ plan.md # This file +β”œβ”€β”€ spec.md # Feature specification +β”œβ”€β”€ ux_reference.md # UX mockups and flows +β”œβ”€β”€ research.md # Phase 0 output +β”œβ”€β”€ data-model.md # Phase 1 output +β”œβ”€β”€ quickstart.md # Phase 1 output +β”œβ”€β”€ contracts/ # Phase 1 output +β”‚ └── api.md # API contracts +β”œβ”€β”€ checklists/ +β”‚ └── requirements.md # Spec quality checklist +└── tasks.md # Phase 2 output (NOT created yet) +``` + +### Source Code (repository root) + +```text +backend/ +β”œβ”€β”€ src/ +β”‚ β”œβ”€β”€ api/routes/ +β”‚ β”‚ β”œβ”€β”€ dashboards.py # NEW: Dashboard hub API +β”‚ β”‚ β”œβ”€β”€ datasets.py # NEW: Dataset hub API +β”‚ β”‚ └── settings.py # EXTEND: Consolidated settings +β”‚ └── services/ +β”‚ └── resource_service.py # NEW: Shared resource logic +└── tests/ + +frontend/ +β”œβ”€β”€ src/ +β”‚ β”œβ”€β”€ lib/ +β”‚ β”‚ β”œβ”€β”€ components/ +β”‚ β”‚ β”‚ β”œβ”€β”€ layout/ +β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ Sidebar.svelte # NEW: Left sidebar +β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ TopNavbar.svelte # NEW: Top navigation +β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ TaskDrawer.svelte # NEW: Global task drawer +β”‚ β”‚ β”‚ β”‚ └── Breadcrumbs.svelte # NEW: Breadcrumb nav +β”‚ β”‚ β”‚ └── hubs/ +β”‚ β”‚ β”‚ β”œβ”€β”€ DashboardHub.svelte # NEW: Dashboard management +β”‚ β”‚ β”‚ β”œβ”€β”€ DatasetHub.svelte # NEW: Dataset management +β”‚ β”‚ β”‚ └── SettingsPage.svelte # NEW: Consolidated settings +β”‚ β”‚ β”œβ”€β”€ stores/ +β”‚ β”‚ β”‚ β”œβ”€β”€ sidebar.js # NEW: Sidebar state +β”‚ β”‚ β”‚ β”œβ”€β”€ taskDrawer.js # NEW: Drawer state + resource-task map +β”‚ β”‚ β”‚ └── activity.js # NEW: Activity indicator count +β”‚ β”‚ └── i18n/ +β”‚ β”‚ └── en.json # EXTEND: New navigation labels +β”‚ └── routes/ +β”‚ β”œβ”€β”€ /dashboards/+page.svelte # NEW +β”‚ β”œβ”€β”€ /datasets/+page.svelte # NEW +β”‚ β”œβ”€β”€ /settings/+page.svelte # NEW +β”‚ └── /+layout.svelte # EXTEND: Add sidebar + drawer +└── tests/ +``` + +**Structure Decision**: Web application structure with new `layout/` and `hubs/` component directories. The Sidebar and TaskDrawer live in the root `+layout.svelte` for global availability. + +## Complexity Tracking + +> No Constitution violations. All changes use existing patterns. + +| Violation | Why Needed | Simpler Alternative Rejected Because | +|-----------|------------|-------------------------------------| +| N/A | N/A | N/A | diff --git a/specs/019-superset-ux-redesign/quickstart.md b/specs/019-superset-ux-redesign/quickstart.md new file mode 100644 index 0000000..56e9db3 --- /dev/null +++ b/specs/019-superset-ux-redesign/quickstart.md @@ -0,0 +1,115 @@ +# Quickstart: Superset-Style UX Redesign + +**Feature**: 019-superset-ux-redesign +**Date**: 2026-02-09 + +## Prerequisites + +- Node.js 18+ (for frontend) +- Python 3.9+ (for backend) +- Existing backend running on `http://localhost:8000` +- Existing frontend running on `http://localhost:5173` + +## Implementation Order + +### Phase 1: Core Layout (P1) + +1. **Create Sidebar Component** (`frontend/src/lib/components/layout/Sidebar.svelte`) + - Categories: DASHBOARDS, DATASETS, STORAGE, ADMIN + - Collapse/expand toggle + - Active item highlighting + - Mobile responsive (hamburger menu) + +2. **Create TopNavbar Component** (`frontend/src/lib/components/layout/TopNavbar.svelte`) + - Logo/brand + - Search placeholder + - Activity indicator (badge count) + - User menu dropdown + +3. **Create SidebarStore** (`frontend/src/lib/stores/sidebar.js`) + - `isExpanded` state with localStorage persistence + - `activeCategory` and `activeItem` tracking + +4. **Update Root Layout** (`frontend/src/routes/+layout.svelte`) + - Import Sidebar and TopNavbar + - Create main content area with proper spacing + +### Phase 2: Task Drawer (P1) + +5. **Create TaskDrawerStore** (`frontend/src/lib/stores/taskDrawer.js`) + - `isOpen` state + - `activeTaskId` + - `resourceTaskMap` for resource-to-task mapping + +6. **Create TaskDrawer Component** (`frontend/src/lib/components/layout/TaskDrawer.svelte`) + - Slide-out panel from right + - Log stream area (reuse TaskLogViewer) + - Interactive area for inputs (PasswordPrompt, etc.) + +7. **Create ActivityStore** (`frontend/src/lib/stores/activity.js`) + - Derived store counting active tasks + - Connect to WebSocket for real-time updates + +### Phase 3: Resource Hubs (P2) + +8. **Create Dashboard Hub** (`frontend/src/routes/dashboards/+page.svelte`) + - Environment selector + - Dashboard grid with columns: Title, Slug, Git Status, Last Task, Actions + - Actions menu: Migrate, Backup, Git Operations + +9. **Create Dataset Hub** (`frontend/src/routes/datasets/+page.svelte`) + - Environment selector + - Dataset grid with columns: Table Name, Schema, Mapped Fields, Last Task, Actions + +10. **Create Backend APIs** (`backend/src/api/routes/`) + - `GET /api/dashboards?env_id=X` + - `GET /api/datasets?env_id=X` + - `GET /api/activity` + +### Phase 4: Settings Consolidation (P2) + +11. **Create Settings Page** (`frontend/src/routes/settings/+page.svelte`) + - Tabbed interface: Environments, Connections, LLM, Logging, System + - Role-based visibility for admin tabs + +12. **Create Settings API** (`backend/src/api/routes/settings.py`) + - `GET /api/settings` (consolidated) + +## Testing + +### Manual Testing Checklist + +- [ ] Sidebar collapses/expands with animation +- [ ] Sidebar state persists after page refresh +- [ ] Activity indicator shows correct count +- [ ] Task Drawer opens when clicking status badge +- [ ] Task Drawer shows real-time logs +- [ ] Dashboard Hub loads dashboards from selected environment +- [ ] Actions menu triggers correct operations +- [ ] Settings page shows all categories (admin) / limited (non-admin) + +### Automated Tests + +```bash +# Frontend component tests +cd frontend && npm run test -- --grep "Sidebar|TaskDrawer|DashboardHub" + +# Backend API tests +cd backend && pytest tests/test_dashboards_api.py tests/test_datasets_api.py +``` + +## Key Files Reference + +| Component | Path | +|-----------|------| +| Sidebar | `frontend/src/lib/components/layout/Sidebar.svelte` | +| TopNavbar | `frontend/src/lib/components/layout/TopNavbar.svelte` | +| TaskDrawer | `frontend/src/lib/components/layout/TaskDrawer.svelte` | +| DashboardHub | `frontend/src/routes/dashboards/+page.svelte` | +| DatasetHub | `frontend/src/routes/datasets/+page.svelte` | +| SettingsPage | `frontend/src/routes/settings/+page.svelte` | +| sidebarStore | `frontend/src/lib/stores/sidebar.js` | +| taskDrawerStore | `frontend/src/lib/stores/taskDrawer.js` | +| activityStore | `frontend/src/lib/stores/activity.js` | +| dashboards API | `backend/src/api/routes/dashboards.py` | +| datasets API | `backend/src/api/routes/datasets.py` | diff --git a/specs/019-superset-ux-redesign/research.md b/specs/019-superset-ux-redesign/research.md new file mode 100644 index 0000000..2ef7a6c --- /dev/null +++ b/specs/019-superset-ux-redesign/research.md @@ -0,0 +1,109 @@ +# 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 diff --git a/specs/019-superset-ux-redesign/spec.md b/specs/019-superset-ux-redesign/spec.md new file mode 100644 index 0000000..9b1861b --- /dev/null +++ b/specs/019-superset-ux-redesign/spec.md @@ -0,0 +1,175 @@ +# Feature Specification: Superset-Style UX Redesign + +**Feature Branch**: `019-superset-ux-redesign` +**Reference UX**: [ux_reference.md](./ux_reference.md) +**Created**: 2026-02-08 +**Status**: Draft +**Input**: User description: "Π― Ρ…ΠΎΡ‡Ρƒ ΠΏΠ΅Ρ€Π΅Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ UX ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ, уйдя ΠΎΡ‚ ΠΊΠ°Ρ€Ρ‚ΠΎΡ‡Π΅ΠΊ Π΄Π°ΡˆΠ±ΠΎΡ€Π΄Π° ΠΊ структурС сходной ΠΊ Apache Superset. ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ ΠΊ Resource-Centric ΠΌΠΎΠ΄Π΅Π»ΠΈ." + +## User Scenarios & Testing *(mandatory)* + +### User Story 1 - Resource-Centric Navigation (Priority: P1) + +As a user, I want to navigate the application through a persistent left sidebar that focuses on resources (Dashboards, Datasets, Storage) rather than tools, so I can manage my data objects more intuitively. + +**Why this priority**: This is the core shift in the application's philosophy. It defines how users find and interact with everything else. + +**Independent Test**: Can be tested by clicking "Dashboards" or "Datasets" in the sidebar and verifying the correct resource hub loads. + +**Acceptance Scenarios**: + +1. **Given** the application has loaded, **When** I view the left sidebar, **Then** I see primary resource links: DASHBOARDS, DATASETS, STORAGE. +2. **Given** I am on any page, **When** I click "Dashboards", **Then** I am taken to the Dashboard Hub showing a list of all available dashboards from the selected environment. +3. **Given** I am on a mobile device, **When** I view the application, **Then** the sidebar is hidden by default and accessible via hamburger menu. + +--- + +### User Story 2 - Global Task Drawer & Activity Monitoring (Priority: P1) + +As a user, I want to see a global activity indicator and a slide-out Task Drawer, so I can monitor running tasks (migrations, backups) without losing my current context in a resource list. + +**Why this priority**: Context preservation is a key goal of the redesign. Users must be able to trigger an action and see its progress without leaving the page. + +**Independent Test**: Trigger a "Backup" on a dashboard and verify the Task Drawer opens automatically with the log stream. + +**Acceptance Scenarios**: + +1. **Given** a task is running, **When** I look at the navbar, **Then** I see an "Activity" indicator with the count of active tasks. +2. **Given** I click the "Activity" indicator or a status badge in a grid, **When** the Task Drawer opens, **Then** I see the real-time log stream for the selected task. +3. **Given** a task requires input (e.g., password), **When** the Task Drawer is open, **Then** the input form is rendered inside the drawer's interactive area. + +--- + +### User Story 3 - Dashboard Hub Management (Priority: P2) + +As a user, I want a central hub for dashboards where I can see their Git status and trigger actions like Migrate or Backup from a single row, so I don't have to switch between different tools. + +**Why this priority**: Consolidates multiple existing tools (Migration, Git, Backup) into a single resource-focused view. + +**Independent Test**: Navigate to `/dashboards`, select an environment, and verify the grid displays Title, Slug, Git Status, and Last Task status. + +**Acceptance Scenarios**: + +1. **Given** I am in the Dashboard Hub, **When** I click the "Actions" menu for a dashboard, **Then** I see options for Migrate, Backup, and Git Operations. +2. **Given** a dashboard is linked to Git, **When** I view the grid, **Then** I see its current branch and sync status (OK/Diff). +3. **Given** I click "Migrate", **When** the deployment modal opens, **Then** it only asks for the target environment, keeping the source context from the hub. + +--- + +### User Story 4 - Dataset Hub & Semantic Mapping (Priority: P2) + +As a user, I want a dedicated hub for datasets where I can manage documentation and field mappings, so I can ensure data consistency across environments. + +**Why this priority**: Moves dataset management from a secondary tool to a primary resource. + +**Independent Test**: Navigate to `/datasets` and verify the list of tables/schemas is displayed with mapping progress. + +**Acceptance Scenarios**: + +1. **Given** I am in the Dataset Hub, **When** I view a dataset row, **Then** I see the "Mapped Fields" count (e.g., 15/20). +2. **Given** I click "Map Columns" in the actions menu, **Then** the mapping interface opens (replacing the old standalone Mapper page). + +--- + +### User Story 5 - Unified Top Navigation Bar (Priority: P1) + +As a user, I want a consistent top navigation bar with a global activity indicator, search placeholder, and user menu, so I can always access critical functions regardless of my current location in the app. + +**Why this priority**: The top navbar is the global command center. It must be established early to provide consistent access to activity monitoring and user settings. + +**Independent Test**: Navigate to any page and verify the top bar shows: Logo, Search, Activity indicator, and User menu. + +**Acceptance Scenarios**: + +1. **Given** the application has loaded, **When** I view the top navigation bar, **Then** I see (from left to right): Logo/Brand, Global Search (placeholder), Activity indicator with badge count, User avatar/menu. +2. **Given** I click the User avatar, **When** the dropdown opens, **Then** I see options for: Profile, Settings, Logout. +3. **Given** there are running tasks, **When** I view the Activity indicator, **Then** I see a badge with the count of active tasks. +4. **Given** I click the Activity indicator, **When** the Task Drawer is not open, **Then** the Task Drawer slides out showing the list of recent/active tasks. + +--- + +### User Story 6 - Consolidated Settings Experience (Priority: P2) + +As an administrator, I want all system settings (Environments, Connections, LLM, Logging) consolidated into a single "Settings" section accessible from the sidebar, so I don't have to hunt through multiple pages to configure the system. + +**Why this priority**: Reduces cognitive load by grouping all configuration in one place. Depends on navigation being established. + +**Independent Test**: Navigate to Settings from the sidebar and verify all configuration categories are listed. + +**Acceptance Scenarios**: + +1. **Given** I am logged in as admin, **When** I click "Settings" in the sidebar, **Then** I am taken to a Settings overview page with categories: Environments, Connections, LLM Providers, Logging, System. +2. **Given** I am on the Settings page, **When** I click "Environments", **Then** I see the environment management interface (add/edit/delete Superset instances). +3. **Given** I am on the Settings page, **When** I click "Connections", **Then** I see database connection configurations. +4. **Given** I am a non-admin user, **When** I view the sidebar, **Then** the "Settings" section is either hidden or shows only user-preference items (theme, language). + +--- + +### Edge Cases + +- **Deep Navigation**: Breadcrumbs should handle long paths by truncating middle segments with an ellipsis. +- **Task Interruption**: If the drawer is closed while a task is running, the task must continue in the background, and the navbar indicator must reflect its status. +- **Permission Changes**: If a user's role changes, the sidebar must immediately hide/show restricted sections (like ADMIN) without a full page reload if possible. +- **Empty States**: Resource hubs must show helpful empty states when no environments are configured or no resources are found. + +## Requirements *(mandatory)* + +### Functional Requirements + +**Navigation & Layout** +- **FR-001**: System MUST implement a persistent left sidebar with resource-centric categories (DASHBOARDS, DATASETS, STORAGE, ADMIN). +- **FR-002**: System MUST implement a Global Task Drawer that slides out from the right, capable of displaying log streams and interactive forms. +- **FR-003**: System MUST provide a top navigation bar containing: Logo/Brand, Global Search (placeholder), Activity indicator, User menu. +- **FR-004**: System MUST display breadcrumb navigation at the top of the content area for all pages. +- **FR-005**: System MUST persist sidebar collapse/expand state in local storage. +- **FR-006**: System MUST highlight the active resource/category in the sidebar. + +**Resource Hubs** +- **FR-007**: System MUST implement a Dashboard Hub (`/dashboards`) that aggregates Migration, Git, and Backup actions for individual dashboards. +- **FR-008**: System MUST implement a Dataset Hub (`/datasets`) for managing table metadata and field mappings. +- **FR-009**: System MUST support a "Source Environment" selector at the top of resource hubs to fetch metadata from different Superset instances. + +**Task Management** +- **FR-010**: System MUST provide a Navbar "Activity" indicator showing the number of active background tasks. +- **FR-011**: System MUST render interactive task prompts (like `PasswordPrompt`) inside the Task Drawer instead of global modals. +- **FR-012**: System MUST allow users to close the Task Drawer while a task continues running in the background. + +**Settings & Configuration** +- **FR-013**: System MUST consolidate all admin settings into a single "Settings" section with categories: Environments, Connections, LLM Providers, Logging, System. +- **FR-014**: System MUST hide admin-only settings categories from non-admin users. +- **FR-015**: System MUST provide user-preference settings (theme, language) accessible to all users. + +### Key Entities + +- **Resource (Dashboard/Dataset)**: The primary object of management, identified by a unique ID/Slug. +- **Task**: An asynchronous operation (Migration, Backup, Git Sync) associated with a Resource. +- **Task Drawer**: A global UI component for monitoring and interacting with Tasks. +- **Environment**: A Superset instance configuration (Source/Target) used to fetch or deploy resources. + +## Success Criteria *(mandatory)* + +### Measurable Outcomes + +- **SC-001**: Users can trigger a migration for a specific dashboard in exactly 2 clicks from the Dashboard Hub. +- **SC-002**: Task Drawer opens and starts streaming logs within 200ms of a status badge click. +- **SC-003**: 100% of existing "Tool" functionality (Migration, Git, Mapper) is accessible via the new Resource Hubs. +- **SC-004**: Users can monitor a running task while simultaneously browsing other resources in the grid. +- **SC-005**: Zero "blocking" modals used for task-related inputs; all moved to the Task Drawer. + +## Assumptions + +- The backend `task_manager` already supports task IDs and log streaming (confirmed by existing code). +- `superset_client` can fetch dashboard/dataset lists efficiently. +- Users prefer a "Resource-First" workflow similar to modern data platforms. + +## Dependencies + +- `backend/src/core/task_manager`: For task state and log persistence. +- `frontend/src/components/TaskLogViewer`: To be integrated into the Task Drawer. +- `frontend/src/lib/stores/tasks.js`: New store required to track resource-to-task mapping. + +## Out of Scope + +- Redesigning the actual Superset dashboard viewing experience (we manage metadata, not the iframe). +- Real-time collaboration features (multiple users editing the same mapping). +- Mobile-first optimization (responsive is required, but desktop is the primary target). diff --git a/specs/019-superset-ux-redesign/tasks.md b/specs/019-superset-ux-redesign/tasks.md new file mode 100644 index 0000000..bf08904 --- /dev/null +++ b/specs/019-superset-ux-redesign/tasks.md @@ -0,0 +1,265 @@ +# Tasks: Superset-Style UX Redesign + +**Input**: Design documents from `/specs/019-superset-ux-redesign/` +**Prerequisites**: plan.md βœ…, spec.md βœ…, research.md βœ…, data-model.md βœ…, contracts/ βœ… + +**Tests**: Not explicitly requested - implementation tasks only. + +**Organization**: Tasks are grouped by user story to enable independent implementation and testing of each story. + +## Format: `[ID] [P?] [Story] Description` + +- **[P]**: Can run in parallel (different files, no dependencies) +- **[Story]**: Which user story this task belongs to (e.g., US1, US2, US3) +- Include exact file paths in descriptions + +## Path Conventions + +- **Web app**: `backend/src/`, `frontend/src/` + +--- + +## Phase 1: Setup (Shared Infrastructure) + +**Purpose**: Create new directory structure and stores for layout state + +- [ ] T001 Create `frontend/src/lib/components/layout/` directory for shared layout components +- [ ] T002 Create `frontend/src/lib/components/hubs/` directory for resource hub pages +- [ ] T003 [P] Create `frontend/src/lib/stores/sidebar.js` with persistentStore pattern for sidebar state +- [ ] T004 [P] Create `frontend/src/lib/stores/taskDrawer.js` with resourceTaskMap store +- [ ] T005 [P] Create `frontend/src/lib/stores/activity.js` as derived store from taskDrawer + +--- + +## Phase 2: Foundational (Blocking Prerequisites) + +**Purpose**: Core layout components that MUST be complete before ANY user story can be implemented + +**⚠️ CRITICAL**: No user story work can begin until this phase is complete + +- [ ] T006 Create `frontend/src/lib/components/layout/Sidebar.svelte` with categories: DASHBOARDS, DATASETS, STORAGE, ADMIN +- [ ] T007 Create `frontend/src/lib/components/layout/TopNavbar.svelte` with Logo, Search placeholder, Activity indicator, User menu +- [ ] T008 Create `frontend/src/lib/components/layout/Breadcrumbs.svelte` for page hierarchy navigation +- [ ] T009 Update `frontend/src/routes/+layout.svelte` to include Sidebar, TopNavbar, and main content area +- [ ] T010 Add i18n keys for navigation labels in `frontend/src/lib/i18n/translations/en.json` +- [ ] T011 Add i18n keys for navigation labels in `frontend/src/lib/i18n/translations/ru.json` + +**Checkpoint**: Foundation ready - user story implementation can now begin + +--- + +## Phase 3: User Story 1 - Resource-Centric Navigation (Priority: P1) 🎯 MVP + +**Goal**: Users can navigate through a persistent left sidebar with resource categories + +**Independent Test**: Click "Dashboards" or "Datasets" in sidebar and verify correct hub loads + +### Implementation for User Story 1 + +- [ ] T012 [US1] Implement sidebar collapse/expand toggle with animation in `frontend/src/lib/components/layout/Sidebar.svelte` +- [ ] T013 [US1] Add mobile hamburger menu toggle in `frontend/src/lib/components/layout/TopNavbar.svelte` +- [ ] T014 [US1] Implement active item highlighting in sidebar using `sidebarStore` +- [ ] T015 [US1] Add localStorage persistence for sidebar state (collapsed/expanded) +- [ ] T016 [US1] Implement responsive sidebar (overlay mode on mobile < 768px) +- [ ] T017 [US1] Verify implementation matches ux_reference.md (Sidebar mockups) + +**Checkpoint**: Sidebar navigation fully functional and responsive + +--- + +## Phase 4: User Story 2 - Global Task Drawer & Activity Monitoring (Priority: P1) 🎯 MVP + +**Goal**: Users can monitor running tasks without losing context via a slide-out drawer + +**Independent Test**: Trigger a Backup and verify Task Drawer opens with log stream + +### Implementation for User Story 2 + +- [ ] T018 [US2] Create `frontend/src/lib/components/layout/TaskDrawer.svelte` as slide-out panel from right +- [ ] T019 [US2] Integrate existing `TaskLogViewer` component inside Task Drawer +- [ ] T020 [US2] Implement Activity indicator badge in TopNavbar showing `activeCount` from store +- [ ] T021 [US2] Connect Task Drawer to WebSocket for real-time log streaming +- [ ] T022 [US2] Implement interactive area in drawer for `PasswordPrompt` and other inputs +- [ ] T023 [US2] Add close button that allows task to continue running in background +- [ ] T024 [US2] Implement drawer open trigger from Activity indicator click +- [ ] T025 [US2] Verify implementation matches ux_reference.md (Task Drawer mockup) + +**Checkpoint**: Task Drawer fully functional with real-time logs + +--- + +## Phase 5: User Story 5 - Unified Top Navigation Bar (Priority: P1) 🎯 MVP + +**Goal**: Consistent top navbar with Logo, Search, Activity, and User menu + +**Independent Test**: Navigate to any page and verify top bar shows all elements + +### Implementation for User Story 5 + +- [ ] T026 [US5] Implement Logo/Brand link in TopNavbar that returns to Home +- [ ] T027 [US5] Add Global Search placeholder (non-functional, for future) in TopNavbar +- [ ] T028 [US5] Implement User menu dropdown with Profile, Settings, Logout options +- [ ] T029 [US5] Connect User menu Logout to authentication logout flow +- [ ] T030 [US5] Verify implementation matches ux_reference.md (Top Navigation Bar mockup) + +**Checkpoint**: Top navbar complete with all elements + +--- + +## Phase 6: User Story 3 - Dashboard Hub Management (Priority: P2) + +**Goal**: Central hub for dashboards with Git status and action triggers + +**Independent Test**: Navigate to `/dashboards`, select environment, verify grid displays correctly + +### Backend for User Story 3 + +- [ ] T031 [P] [US3] Create `backend/src/api/routes/dashboards.py` with GET /api/dashboards endpoint +- [ ] T032 [P] [US3] Create `backend/src/services/resource_service.py` for shared resource fetching logic +- [ ] T033 [US3] Implement dashboard list fetching with Git status and last task status + +### Frontend for User Story 3 + +- [ ] T034 [US3] Create `frontend/src/routes/dashboards/+page.svelte` as Dashboard Hub +- [ ] T035 [US3] Implement environment selector dropdown at top of Dashboard Hub +- [ ] T036 [US3] Create dashboard grid with columns: Title, Slug, Git Status, Last Task, Actions +- [ ] T037 [US3] Implement Actions menu with Migrate, Backup, Git Operations options +- [ ] T038 [US3] Connect Actions menu to existing plugin triggers (Migration, Backup, Git) +- [ ] T039 [US3] Implement status badge click to open Task Drawer with correct task +- [ ] T040 [US3] Add empty state when no environments configured or no dashboards found +- [ ] T041 [US3] Verify implementation matches ux_reference.md (Dashboard Hub Grid mockup) + +**Checkpoint**: Dashboard Hub fully functional + +--- + +## Phase 7: User Story 4 - Dataset Hub & Semantic Mapping (Priority: P2) + +**Goal**: Dedicated hub for datasets with mapping progress + +**Independent Test**: Navigate to `/datasets` and verify list with mapping progress + +### Backend for User Story 4 + +- [ ] T042 [P] [US4] Create `backend/src/api/routes/datasets.py` with GET /api/datasets endpoint +- [ ] T043 [US4] Implement dataset list fetching with mapped fields count + +### Frontend for User Story 4 + +- [ ] T044 [US4] Create `frontend/src/routes/datasets/+page.svelte` as Dataset Hub +- [ ] T045 [US4] Implement dataset grid with columns: Table Name, Schema, Mapped Fields, Last Task, Actions +- [ ] T046 [US4] Implement "Map Columns" action that opens mapping interface +- [ ] T047 [US4] Add empty state when no datasets found +- [ ] T048 [US4] Verify implementation matches ux_reference.md + +**Checkpoint**: Dataset Hub fully functional + +--- + +## Phase 8: User Story 6 - Consolidated Settings Experience (Priority: P2) + +**Goal**: All settings consolidated into single section with categories + +**Independent Test**: Navigate to Settings and verify all categories listed + +### Backend for User Story 6 + +- [ ] T049 [P] [US6] Extend `backend/src/api/routes/settings.py` with GET /api/settings endpoint +- [ ] T050 [US6] Implement consolidated settings response with all categories + +### Frontend for User Story 6 + +- [ ] T051 [US6] Create `frontend/src/routes/settings/+page.svelte` as Settings page +- [ ] T052 [US6] Implement tabbed navigation: Environments, Connections, LLM, Logging, System +- [ ] T053 [US6] Reuse existing settings components within each tab +- [ ] T054 [US6] Implement role-based visibility (hide admin tabs for non-admin users) +- [ ] T055 [US6] Add user-preference settings (theme, language) accessible to all users +- [ ] T056 [US6] Verify implementation matches ux_reference.md (Settings Page mockup) + +**Checkpoint**: Settings page fully functional + +--- + +## Phase 9: Polish & Cross-Cutting Concerns + +**Purpose**: Improvements that affect multiple user stories + +- [ ] T057 [P] Add breadcrumb navigation to all new pages +- [ ] T058 [P] Implement breadcrumb truncation for deep paths (>3 levels) +- [ ] T059 Remove old card-based dashboard grid if no longer needed +- [ ] T060 [P] Add skeleton loaders for resource hub grids +- [ ] T061 [P] Add error banners for environment connection failures +- [ ] T062 Run quickstart.md validation for all user stories +- [ ] T063 Final UX review against ux_reference.md + +--- + +## Dependencies & Execution Order + +### Phase Dependencies + +- **Setup (Phase 1)**: No dependencies - can start immediately +- **Foundational (Phase 2)**: Depends on Setup completion - BLOCKS all user stories +- **User Stories (Phase 3-8)**: All depend on Foundational phase completion + - US1, US2, US5 (P1) can proceed in parallel + - US3, US4, US6 (P2) can proceed after P1 stories or in parallel +- **Polish (Phase 9)**: Depends on all desired user stories being complete + +### User Story Dependencies + +- **US1 (P1)**: Can start after Foundational - No dependencies on other stories +- **US2 (P1)**: Can start after Foundational - Uses stores from Setup +- **US5 (P1)**: Can start after Foundational - Uses TopNavbar from Foundational +- **US3 (P2)**: Can start after Foundational - Uses Task Drawer from US2 +- **US4 (P2)**: Can start after Foundational - Uses Task Drawer from US2 +- **US6 (P2)**: Can start after Foundational - Uses Sidebar from US1 + +### Parallel Opportunities + +- T003, T004, T005 can run in parallel (different store files) +- T031, T032 can run in parallel (different backend files) +- T042 can run in parallel with T031 +- T049 can run in parallel with other backend tasks +- T057, T058, T060, T061 can run in parallel (different concerns) + +--- + +## Implementation Strategy + +### MVP First (P1 Stories Only) + +1. Complete Phase 1: Setup +2. Complete Phase 2: Foundational (CRITICAL - blocks all stories) +3. Complete Phase 3: User Story 1 (Sidebar Navigation) +4. Complete Phase 4: User Story 2 (Task Drawer) +5. Complete Phase 5: User Story 5 (Top Navbar) +6. **STOP and VALIDATE**: Test all P1 stories independently +7. Deploy/demo if ready + +### Full Delivery + +1. MVP First (above) +2. Add User Story 3 (Dashboard Hub) β†’ Test independently +3. Add User Story 4 (Dataset Hub) β†’ Test independently +4. Add User Story 6 (Settings) β†’ Test independently +5. Complete Polish phase +6. Final validation + +--- + +## Summary + +| Metric | Value | +|--------|-------| +| Total Tasks | 63 | +| Setup Tasks | 5 | +| Foundational Tasks | 6 | +| US1 (Sidebar) Tasks | 6 | +| US2 (Task Drawer) Tasks | 8 | +| US5 (Top Navbar) Tasks | 5 | +| US3 (Dashboard Hub) Tasks | 11 | +| US4 (Dataset Hub) Tasks | 7 | +| US6 (Settings) Tasks | 8 | +| Polish Tasks | 7 | +| Parallel Opportunities | 15+ | +| MVP Scope | Phases 1-5 (25 tasks) | diff --git a/specs/019-superset-ux-redesign/ux_reference.md b/specs/019-superset-ux-redesign/ux_reference.md new file mode 100644 index 0000000..bff3055 --- /dev/null +++ b/specs/019-superset-ux-redesign/ux_reference.md @@ -0,0 +1,125 @@ +# UX Reference: Superset-Style Redesign + +## Persona +**Alex, Data Engineer / Superset Admin** +Alex manages dozens of dashboards across Dev, Staging, and Prod. Alex needs to quickly move changes between environments, check if a dashboard is in sync with Git, and fix mapping issues without losing context. + +## Context +The current UI is "Tool-Centric" (Go to Migration Tool -> Select Dashboard). The new UI is "Resource-Centric" (Go to Dashboards -> Find "Sales" -> Click Migrate). + +## Happy Path: Migrating a Dashboard + +1. **Discovery**: Alex opens the app and lands on the **Dashboard Hub**. +2. **Selection**: Alex selects "Production" from the environment dropdown. The grid populates with production dashboards. +3. **Status Check**: Alex sees that "Sales Overview" has a "Diff" status in the Git column. +4. **Action**: Alex clicks the `[...]` menu on the "Sales Overview" row and selects **Migrate**. +5. **Configuration**: A small modal appears asking for the **Target Environment**. Alex selects "Staging" and clicks "Start". +6. **Monitoring**: The modal closes. The "Last Task" column for "Sales Overview" changes to a **Spinner**. +7. **Contextual Logs**: Alex clicks the Spinner. The **Task Drawer** slides out from the right. +8. **Interaction**: The logs show the migration is paused because a database password is required. A password field appears *inside* the drawer. +9. **Completion**: Alex enters the password. The migration finishes. The drawer shows a green "Success" message. Alex closes the drawer and is still looking at the Dashboard Hub list. + +## Mockups + +### Top Navigation Bar +```text ++-----------------------------------------------------------------------+ +| [≑] Superset Tools [πŸ” Search...] [Activity (3)] [πŸ‘€ β–Ό] | ++-----------------------------------------------------------------------+ +``` +- **[≑] Hamburger**: Mobile-only toggle for sidebar. +- **Logo**: Returns to Home/Dashboard Hub. +- **Search**: Placeholder for future global search. +- **Activity (3)**: Badge shows count of running tasks. Clicking opens Task Drawer. +- **User Menu**: Dropdown with Profile, Settings, Logout. + +### Sidebar (Expanded) +```text ++------------------+ +| β–½ DASHBOARDS | +| Overview | ++------------------+ +| β–½ DATASETS | +| All Datasets | ++------------------+ +| β–½ STORAGE | +| Backups | +| Repositories | ++------------------+ +| β–½ ADMIN | +| Users | +| Roles | +| Settings | ++------------------+ +| [β—€ Collapse] | ++------------------+ +``` + +### Sidebar (Collapsed) +```text ++---+ +| D | (Dashboards - Active) +| T | (Datasets) +| S | (Storage) ++---+ +| A | (Admin) ++---+ +| β–Ά | ++---+ +``` + +### Dashboard Hub Grid +```text ++-----------------------------------------------------------------------+ +| Env: [ Production (v) ] [ Refresh ] | ++-----------------------------------------------------------------------+ +| Title | Git Status | Last Task | Actions | +|-----------------|---------------|-----------|-------------------------| +| Sales Report | [v] main | [v] Done | [ Migrate ] [ Backup ] | +| HR Analytics | [!] Diff | [@] Run.. | [ Commit ] [ ... ] | ++-----------------------------------------------------------------------+ +``` + +### Settings Page (Consolidated) +```text ++-----------------------------------------------------------------------+ +| Settings | ++-----------------------------------------------------------------------+ +| [Environments] [Connections] [LLM Providers] [Logging] [System] | ++-----------------------------------------------------------------------+ +| | +| Environments | +| +-------------------------------------------------------------+ | +| | Name | URL | Status | Actions | | +| |--------------|------------------------|----------|---------| | +| | Development | http://dev.superset... | [v] OK | [Edit] | | +| | Production | http://prod.superset...| [!] Error| [Edit] | | +| +-------------------------------------------------------------+ | +| | ++-----------------------------------------------------------------------+ +``` + +### Task Drawer (Active) +```text + +---------------------------------------+ + | Task: Migration (Sales) [X] | + +---------------------------------------+ + | [INFO] Exporting... | + | [INFO] Validating... | + | [WARN] Password required | + | | + | Password: [**********] | + | [ Resume ] [ Cancel ] | + +---------------------------------------+ +``` + +## Error Experience + +### Scenario: Migration Fails +- **Visual Cue**: The "Last Task" badge in the grid turns **Red (X)**. +- **Notification**: A toast message appears: "Migration Failed: Database Connection Error". +- **Resolution**: Alex clicks the Red (X). The Task Drawer opens, scrolled to the bottom, highlighting the error in red. Alex can see the full stack trace or error message to debug. + +### Scenario: Environment Offline +- **Visual Cue**: When selecting an environment, a "Connection Error" banner appears at the top of the grid. +- **Action**: The "Refresh" button turns into a "Retry" button.