feat: implement dashboard widgets functionality
Backend: - Add dashboard API router with widget endpoints - Create dashboard schemas for widget data - Add dashboard tests Frontend: - Enhance Dashboard page with widget components - Add dashboard service for API calls - Create reusable dashboard components OpenSpec: - Archive add-dashboard-widgets change - Add dashboard capability specs 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
# Design: Dashboard Widgets
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Dashboard Page │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌────────┐ │
|
||||
│ │ My Tasks │ │ Due This │ │ Overdue │ │ Done % │ │
|
||||
│ │ 12 │ │ Week: 5 │ │ 2 │ │ 78% │ │
|
||||
│ └─────────────┘ └─────────────┘ └─────────────┘ └────────┘ │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ ┌──────────────────────────┐ ┌───────────────────────────┐ │
|
||||
│ │ My Workload │ │ Project Health │ │
|
||||
│ │ ┌────────────────────┐ │ │ ┌───────────────────────┐ │ │
|
||||
│ │ │ 32h / 40h (80%) │ │ │ │ 8 Healthy | 2 At Risk │ │ │
|
||||
│ │ │ ████████░░ │ │ │ │ Avg Score: 76% │ │ │
|
||||
│ │ └────────────────────┘ │ │ └───────────────────────┘ │ │
|
||||
│ └──────────────────────────┘ └───────────────────────────┘ │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ Quick Actions: [Spaces] [Workload] [Health] [Audit*] │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## API Design
|
||||
|
||||
### GET /api/dashboard
|
||||
|
||||
Single endpoint aggregates all dashboard data to minimize frontend requests.
|
||||
|
||||
```typescript
|
||||
interface DashboardResponse {
|
||||
task_stats: {
|
||||
assigned_count: number // Total tasks assigned to user
|
||||
due_this_week: number // Tasks with due_date in current week
|
||||
overdue_count: number // Tasks past due_date, not completed
|
||||
completion_rate: number // Percentage (0-100)
|
||||
}
|
||||
workload: {
|
||||
allocated_hours: number
|
||||
capacity_hours: number
|
||||
load_percentage: number
|
||||
load_level: 'normal' | 'warning' | 'overloaded'
|
||||
}
|
||||
health_summary: {
|
||||
total_projects: number
|
||||
healthy_count: number
|
||||
at_risk_count: number
|
||||
critical_count: number
|
||||
average_health_score: number
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Data Sources
|
||||
|
||||
| Widget | Source | Notes |
|
||||
|--------|--------|-------|
|
||||
| Task Statistics | `pjctrl_tasks` table | Filter by assignee_id = current user |
|
||||
| Workload | Existing `WorkloadService` | Reuse get_user_workload_detail() |
|
||||
| Health Summary | Existing `HealthService` | Reuse get_dashboard() summary |
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
1. **Single API Call**: Frontend makes one request instead of three
|
||||
2. **Query Optimization**: Task stats use COUNT queries, not full rows
|
||||
3. **Caching**: Health summary already cached in Redis (5 min TTL)
|
||||
4. **No N+1**: Avoid loading related entities for counts
|
||||
|
||||
## Component Structure
|
||||
|
||||
```
|
||||
frontend/src/
|
||||
├── pages/
|
||||
│ └── Dashboard.tsx # Main page (modified)
|
||||
├── components/
|
||||
│ ├── dashboard/
|
||||
│ │ ├── StatisticsCard.tsx # Single stat card
|
||||
│ │ ├── WorkloadWidget.tsx # Workload progress bar
|
||||
│ │ ├── HealthWidget.tsx # Health summary
|
||||
│ │ └── QuickActions.tsx # Navigation links
|
||||
└── services/
|
||||
└── dashboard.ts # API service (new)
|
||||
```
|
||||
|
||||
## Trade-offs
|
||||
|
||||
### Decision: Single vs Multiple API Endpoints
|
||||
|
||||
**Chosen**: Single `/api/dashboard` endpoint
|
||||
|
||||
**Rationale**:
|
||||
- Reduces network round-trips (1 vs 3)
|
||||
- Simpler frontend loading state management
|
||||
- Data is always consistent (same timestamp)
|
||||
|
||||
**Rejected Alternative**: Use existing endpoints directly
|
||||
- Would require 3 parallel requests
|
||||
- More complex error handling
|
||||
- Harder to ensure data consistency
|
||||
@@ -0,0 +1,38 @@
|
||||
# Proposal: add-dashboard-widgets
|
||||
|
||||
## Summary
|
||||
|
||||
Replace the placeholder Dashboard page with functional dashboard widgets that provide users with an at-a-glance overview of their work and system status.
|
||||
|
||||
## Motivation
|
||||
|
||||
The current Dashboard displays only a welcome message and placeholder text ("Features will be added as development progresses"). Users need a centralized view of:
|
||||
- Their assigned tasks and workload
|
||||
- Project health across the organization
|
||||
- Quick access to common actions
|
||||
- System statistics
|
||||
|
||||
## Scope
|
||||
|
||||
### In Scope
|
||||
- Dashboard statistics cards (my tasks, overdue, completion rate)
|
||||
- My workload summary widget (reuses existing `/workload/me` API)
|
||||
- Project health summary widget (reuses existing `/projects/health/dashboard` API)
|
||||
- Quick actions section with navigation links
|
||||
- Backend API endpoint for aggregated dashboard data
|
||||
|
||||
### Out of Scope
|
||||
- Customizable widget layout (future enhancement)
|
||||
- Real-time WebSocket updates for dashboard (can be added later)
|
||||
- Dashboard for specific roles (manager vs engineer views)
|
||||
|
||||
## Dependencies
|
||||
|
||||
Reuses existing APIs:
|
||||
- `GET /workload/me` - User workload summary
|
||||
- `GET /projects/health/dashboard` - Project health overview
|
||||
- `GET /api/projects/{project_id}/tasks` with `assignee_id` filter
|
||||
|
||||
## Risk Assessment
|
||||
|
||||
**Low Risk** - This change primarily adds a new frontend page using existing backend APIs. A new lightweight aggregation endpoint is added but doesn't modify existing data structures.
|
||||
@@ -0,0 +1,69 @@
|
||||
# Dashboard Capability
|
||||
|
||||
Provides users with an at-a-glance overview of their work, project health, and system statistics.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Dashboard Statistics
|
||||
|
||||
The system SHALL display aggregated statistics showing the user's task overview.
|
||||
|
||||
#### Scenario: User views task statistics
|
||||
- Given: User is authenticated
|
||||
- When: User navigates to Dashboard
|
||||
- Then: System displays:
|
||||
- Total tasks assigned to user
|
||||
- Tasks due this week
|
||||
- Overdue tasks count
|
||||
- Completion rate percentage
|
||||
|
||||
### Requirement: My Workload Widget
|
||||
|
||||
The system SHALL display the current user's workload summary for the current week.
|
||||
|
||||
#### Scenario: User views personal workload
|
||||
- Given: User is authenticated
|
||||
- When: User views Dashboard
|
||||
- Then: System displays:
|
||||
- Allocated hours vs capacity hours
|
||||
- Load percentage with visual indicator
|
||||
- Load level status (normal/warning/overloaded)
|
||||
|
||||
### Requirement: Project Health Summary
|
||||
|
||||
The system SHALL display an aggregated project health summary.
|
||||
|
||||
#### Scenario: User views project health overview
|
||||
- Given: User is authenticated
|
||||
- When: User views Dashboard
|
||||
- Then: System displays:
|
||||
- Total projects count
|
||||
- Healthy/At-Risk/Critical breakdown
|
||||
- Average health score
|
||||
- Projects with blockers count
|
||||
|
||||
### Requirement: Quick Actions
|
||||
|
||||
The system SHALL provide quick navigation links to common actions.
|
||||
|
||||
#### Scenario: User accesses quick actions
|
||||
- Given: User is authenticated
|
||||
- When: User views Dashboard
|
||||
- Then: System displays navigation links to:
|
||||
- Spaces page
|
||||
- Workload page
|
||||
- Project Health page
|
||||
- (Admin only) Audit page
|
||||
|
||||
### Requirement: Dashboard API Endpoint
|
||||
|
||||
The backend SHALL provide a single aggregated endpoint for dashboard data.
|
||||
|
||||
#### Scenario: Frontend fetches dashboard data
|
||||
- Given: User is authenticated
|
||||
- When: Frontend requests GET /api/dashboard
|
||||
- Then: Backend returns:
|
||||
- User task statistics
|
||||
- Current week workload summary
|
||||
- Project health summary
|
||||
- And: Response is optimized with single database query where possible
|
||||
@@ -0,0 +1,59 @@
|
||||
# Implementation Tasks
|
||||
|
||||
## Phase 1: Backend API
|
||||
|
||||
### Task 1.1: Create Dashboard Schema
|
||||
- [ ] Create `backend/app/schemas/dashboard.py` with response models
|
||||
- `TaskStatistics`: assigned_count, due_this_week, overdue_count, completion_rate
|
||||
- `DashboardResponse`: task_stats, workload_summary, health_summary
|
||||
- **Validation**: Schema imports without errors
|
||||
|
||||
### Task 1.2: Create Dashboard Router
|
||||
- [ ] Create `backend/app/api/dashboard/router.py`
|
||||
- [ ] Implement `GET /api/dashboard` endpoint
|
||||
- Query tasks assigned to current user
|
||||
- Reuse workload service for current week summary
|
||||
- Reuse health service for project summary
|
||||
- [ ] Register router in `backend/app/main.py`
|
||||
- **Validation**: `curl -H "Authorization: Bearer $TOKEN" http://localhost:8000/api/dashboard` returns valid JSON
|
||||
|
||||
## Phase 2: Frontend Implementation
|
||||
|
||||
### Task 2.1: Create Dashboard Service
|
||||
- [ ] Create `frontend/src/services/dashboard.ts`
|
||||
- [ ] Define TypeScript interfaces matching backend schema
|
||||
- [ ] Implement `getDashboard()` API function
|
||||
- **Validation**: TypeScript compiles without errors
|
||||
|
||||
### Task 2.2: Implement Dashboard Components
|
||||
- [ ] Create `StatisticsCard` component for task stats
|
||||
- [ ] Create `WorkloadWidget` component (reuse styles from WorkloadPage)
|
||||
- [ ] Create `HealthSummaryWidget` component
|
||||
- [ ] Create `QuickActions` component with navigation links
|
||||
- **Validation**: Components render without console errors
|
||||
|
||||
### Task 2.3: Integrate Dashboard Page
|
||||
- [ ] Replace placeholder content in `Dashboard.tsx`
|
||||
- [ ] Add loading state with Skeleton components
|
||||
- [ ] Add error handling with retry
|
||||
- [ ] Style components to match existing UI
|
||||
- **Validation**: Dashboard displays data correctly after login
|
||||
|
||||
## Phase 3: Testing & Polish
|
||||
|
||||
### Task 3.1: Add Backend Tests
|
||||
- [ ] Create `backend/tests/test_dashboard.py`
|
||||
- [ ] Test endpoint returns correct structure
|
||||
- [ ] Test data aggregation logic
|
||||
- **Validation**: `pytest tests/test_dashboard.py -v` passes
|
||||
|
||||
### Task 3.2: Visual Polish
|
||||
- [ ] Ensure responsive layout for mobile
|
||||
- [ ] Match color scheme with existing pages
|
||||
- [ ] Add subtle animations for loading states
|
||||
- **Validation**: Manual visual review on different screen sizes
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Tasks 2.x depend on Task 1.2 completion
|
||||
- Task 3.1 can run in parallel with Phase 2
|
||||
69
openspec/specs/dashboard/spec.md
Normal file
69
openspec/specs/dashboard/spec.md
Normal file
@@ -0,0 +1,69 @@
|
||||
# dashboard Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change add-dashboard-widgets. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: Dashboard Statistics
|
||||
|
||||
The system SHALL display aggregated statistics showing the user's task overview.
|
||||
|
||||
#### Scenario: User views task statistics
|
||||
- Given: User is authenticated
|
||||
- When: User navigates to Dashboard
|
||||
- Then: System displays:
|
||||
- Total tasks assigned to user
|
||||
- Tasks due this week
|
||||
- Overdue tasks count
|
||||
- Completion rate percentage
|
||||
|
||||
### Requirement: My Workload Widget
|
||||
|
||||
The system SHALL display the current user's workload summary for the current week.
|
||||
|
||||
#### Scenario: User views personal workload
|
||||
- Given: User is authenticated
|
||||
- When: User views Dashboard
|
||||
- Then: System displays:
|
||||
- Allocated hours vs capacity hours
|
||||
- Load percentage with visual indicator
|
||||
- Load level status (normal/warning/overloaded)
|
||||
|
||||
### Requirement: Project Health Summary
|
||||
|
||||
The system SHALL display an aggregated project health summary.
|
||||
|
||||
#### Scenario: User views project health overview
|
||||
- Given: User is authenticated
|
||||
- When: User views Dashboard
|
||||
- Then: System displays:
|
||||
- Total projects count
|
||||
- Healthy/At-Risk/Critical breakdown
|
||||
- Average health score
|
||||
- Projects with blockers count
|
||||
|
||||
### Requirement: Quick Actions
|
||||
|
||||
The system SHALL provide quick navigation links to common actions.
|
||||
|
||||
#### Scenario: User accesses quick actions
|
||||
- Given: User is authenticated
|
||||
- When: User views Dashboard
|
||||
- Then: System displays navigation links to:
|
||||
- Spaces page
|
||||
- Workload page
|
||||
- Project Health page
|
||||
- (Admin only) Audit page
|
||||
|
||||
### Requirement: Dashboard API Endpoint
|
||||
|
||||
The backend SHALL provide a single aggregated endpoint for dashboard data.
|
||||
|
||||
#### Scenario: Frontend fetches dashboard data
|
||||
- Given: User is authenticated
|
||||
- When: Frontend requests GET /api/dashboard
|
||||
- Then: Backend returns:
|
||||
- User task statistics
|
||||
- Current week workload summary
|
||||
- Project health summary
|
||||
- And: Response is optimized with single database query where possible
|
||||
|
||||
Reference in New Issue
Block a user