18 KiB
18 KiB
Dashboard Design Specification
Overview
Dashboard 是用户进入系统后的第一个页面,用于快速了解:
- 数据标注质量和进度
- 当前模型状态和性能
- 系统最近发生的活动
目标用户:使用文档标注系统的客户,需要监控文档处理状态、标注质量和模型训练进度。
1. UI Layout
1.1 Overall Structure
+------------------------------------------------------------------+
| Header: Logo + Navigation + User Menu |
+------------------------------------------------------------------+
| |
| Stats Cards Row (4 cards, equal width) |
| |
| +---------------------------+ +------------------------------+ |
| | Data Quality Panel (50%) | | Active Model Panel (50%) | |
| +---------------------------+ +------------------------------+ |
| |
| +--------------------------------------------------------------+ |
| | Recent Activity Panel (full width) | |
| +--------------------------------------------------------------+ |
| |
| +--------------------------------------------------------------+ |
| | System Status Bar (full width) | |
| +--------------------------------------------------------------+ |
+------------------------------------------------------------------+
1.2 Responsive Breakpoints
| Breakpoint | Layout |
|---|---|
| Desktop (>1200px) | 4 cards row, 2-column panels |
| Tablet (768-1200px) | 2x2 cards, 2-column panels |
| Mobile (<768px) | 1 card per row, stacked panels |
2. Component Specifications
2.1 Stats Cards Row
4 个等宽卡片,显示核心统计数据。
+-------------+ +-------------+ +-------------+ +-------------+
| [icon] | | [icon] | | [icon] | | [icon] |
| 38 | | 25 | | 8 | | 5 |
| Total Docs | | Complete | | Incomplete | | Pending |
+-------------+ +-------------+ +-------------+ +-------------+
| Card | Icon | Value | Label | Color | Click Action |
|---|---|---|---|---|---|
| Total Documents | FileText | total_documents |
"Total Documents" | Gray | Navigate to Documents page |
| Complete | CheckCircle | annotation_complete |
"Complete" | Green | Navigate to Documents (filter: complete) |
| Incomplete | AlertCircle | annotation_incomplete |
"Incomplete" | Orange | Navigate to Documents (filter: incomplete) |
| Pending | Clock | pending |
"Pending" | Blue | Navigate to Documents (filter: pending) |
Card Design:
- Background: White with subtle border
- Icon: 24px, positioned top-left
- Value: 32px bold font
- Label: 14px muted color
- Hover: Slight shadow elevation
- Padding: 16px
2.2 Data Quality Panel
左侧面板,显示标注完整度和质量指标。
+---------------------------+
| DATA QUALITY |
| +-----------+ |
| | | |
| | 78% | Annotation |
| | | Complete |
| +-----------+ |
| |
| Complete: 25 |
| Incomplete: 8 |
| Pending: 5 |
| |
| [View Incomplete Docs] |
+---------------------------+
Components:
| Element | Spec |
|---|---|
| Title | "DATA QUALITY", 14px uppercase, muted |
| Progress Ring | 120px diameter, stroke width 12px |
| Percentage | 36px bold, centered in ring |
| Label | "Annotation Complete", 14px, below ring |
| Stats List | 14px, icon + label + value per row |
| Action Button | Text button, primary color |
Progress Ring Colors:
- Complete portion: Green (#22C55E)
- Remaining: Gray (#E5E7EB)
Completeness Calculation:
completeness_rate = annotation_complete / (annotation_complete + annotation_incomplete) * 100
2.3 Active Model Panel
右侧面板,显示当前生产模型信息。
+-------------------------------+
| ACTIVE MODEL |
| |
| v1.2.0 - Invoice Model |
| ----------------------------- |
| |
| mAP Precision Recall |
| 95.1% 94% 92% |
| |
| Activated: 2024-01-20 |
| Documents: 500 |
| |
| [Training] Run-2024-02 [====] |
+-------------------------------+
Components:
| Element | Spec |
|---|---|
| Title | "ACTIVE MODEL", 14px uppercase, muted |
| Version + Name | 18px bold (version) + 16px regular (name) |
| Divider | 1px border, full width |
| Metrics Row | 3 columns, equal width |
| Metric Value | 24px bold |
| Metric Label | 12px muted, below value |
| Info Rows | 14px, label: value format |
| Training Indicator | Shows when training is running |
Metric Colors:
- mAP >= 90%: Green
- mAP 80-90%: Yellow
- mAP < 80%: Red
Empty State (No Active Model):
+-------------------------------+
| ACTIVE MODEL |
| |
| [icon: Model] |
| No Active Model |
| |
| Train and activate a |
| model to see stats here |
| |
| [Go to Training] |
+-------------------------------+
Training In Progress:
| Training: Run-2024-02 |
| [=========> ] 45% |
| Started 2 hours ago |
2.4 Recent Activity Panel
全宽面板,显示最近 10 条系统活动。
+--------------------------------------------------------------+
| RECENT ACTIVITY [See All] |
+--------------------------------------------------------------+
| [rocket] Activated model v1.2.0 2 hours ago|
| [check] Training complete: Run-2024-01, mAP 95.1% yesterday|
| [edit] Modified INV-001.pdf invoice_number yesterday|
| [doc] Uploaded INV-005.pdf 2 days ago|
| [doc] Uploaded INV-004.pdf 2 days ago|
| [x] Training failed: Run-2024-00 3 days ago|
+--------------------------------------------------------------+
Activity Item Layout:
[Icon] [Description] [Timestamp]
| Element | Spec |
|---|---|
| Icon | 16px, color based on type |
| Description | 14px, truncate if too long |
| Timestamp | 12px muted, right-aligned |
| Row Height | 40px |
| Hover | Background highlight |
Activity Types and Icons:
| Type | Icon | Color | Description Format |
|---|---|---|---|
| document_uploaded | FileText | Blue | "Uploaded {filename}" |
| annotation_modified | Edit | Orange | "Modified {filename} {field_name}" |
| training_completed | CheckCircle | Green | "Training complete: {task_name}, mAP {mAP}%" |
| training_failed | XCircle | Red | "Training failed: {task_name}" |
| model_activated | Rocket | Purple | "Activated model {version}" |
Timestamp Formatting:
- < 1 minute: "just now"
- < 1 hour: "{n} minutes ago"
- < 24 hours: "{n} hours ago"
- < 7 days: "yesterday" / "{n} days ago"
-
= 7 days: "Jan 15" (date format)
Empty State:
+--------------------------------------------------------------+
| RECENT ACTIVITY |
| |
| [icon: Activity] |
| No recent activity |
| |
| Start by uploading documents or creating training jobs |
+--------------------------------------------------------------+
2.5 System Status Bar
底部状态栏,显示系统健康状态。
+--------------------------------------------------------------+
| Backend API: [*] Online Database: [*] Connected GPU: [*] Available |
+--------------------------------------------------------------+
| Status | Icon | Color |
|---|---|---|
| Online/Connected/Available | Filled circle | Green |
| Degraded/Slow | Filled circle | Yellow |
| Offline/Error/Unavailable | Filled circle | Red |
3. API Endpoints
3.1 Dashboard Statistics
GET /api/v1/admin/dashboard/stats
Response:
{
"total_documents": 38,
"annotation_complete": 25,
"annotation_incomplete": 8,
"pending": 5,
"completeness_rate": 75.76
}
Calculation Logic:
# annotation_complete: labeled documents with core fields
SELECT COUNT(*) FROM admin_documents d
WHERE d.status = 'labeled'
AND EXISTS (
SELECT 1 FROM admin_annotations a
WHERE a.document_id = d.document_id
AND a.class_id IN (0, 3) -- invoice_number OR ocr_number
)
AND EXISTS (
SELECT 1 FROM admin_annotations a
WHERE a.document_id = d.document_id
AND a.class_id IN (4, 5) -- bankgiro OR plusgiro
)
# annotation_incomplete: labeled but missing core fields
SELECT COUNT(*) FROM admin_documents d
WHERE d.status = 'labeled'
AND NOT (/* above conditions */)
# pending: pending + auto_labeling
SELECT COUNT(*) FROM admin_documents
WHERE status IN ('pending', 'auto_labeling')
3.2 Active Model Info
GET /api/v1/admin/dashboard/active-model
Response (with active model):
{
"model": {
"version_id": "uuid",
"version": "1.2.0",
"name": "Invoice Model",
"metrics_mAP": 0.951,
"metrics_precision": 0.94,
"metrics_recall": 0.92,
"document_count": 500,
"activated_at": "2024-01-20T15:00:00Z"
},
"running_training": {
"task_id": "uuid",
"name": "Run-2024-02",
"status": "running",
"started_at": "2024-01-25T10:00:00Z",
"progress": 45
}
}
Response (no active model):
{
"model": null,
"running_training": null
}
3.3 Recent Activity
GET /api/v1/admin/dashboard/activity?limit=10
Response:
{
"activities": [
{
"type": "model_activated",
"description": "Activated model v1.2.0",
"timestamp": "2024-01-25T12:00:00Z",
"metadata": {
"version_id": "uuid",
"version": "1.2.0"
}
},
{
"type": "training_completed",
"description": "Training complete: Run-2024-01, mAP 95.1%",
"timestamp": "2024-01-24T18:30:00Z",
"metadata": {
"task_id": "uuid",
"task_name": "Run-2024-01",
"mAP": 0.951
}
}
]
}
Activity Aggregation Query:
-- Union all activity sources, ordered by timestamp DESC, limit 10
(
SELECT 'document_uploaded' as type,
filename as entity_name,
created_at as timestamp,
document_id as entity_id
FROM admin_documents
ORDER BY created_at DESC
LIMIT 10
)
UNION ALL
(
SELECT 'annotation_modified' as type,
-- join to get filename and field name
...
FROM annotation_history
ORDER BY created_at DESC
LIMIT 10
)
UNION ALL
(
SELECT CASE WHEN status = 'completed' THEN 'training_completed'
WHEN status = 'failed' THEN 'training_failed' END as type,
name as entity_name,
completed_at as timestamp,
task_id as entity_id
FROM training_tasks
WHERE status IN ('completed', 'failed')
ORDER BY completed_at DESC
LIMIT 10
)
UNION ALL
(
SELECT 'model_activated' as type,
version as entity_name,
activated_at as timestamp,
version_id as entity_id
FROM model_versions
WHERE activated_at IS NOT NULL
ORDER BY activated_at DESC
LIMIT 10
)
ORDER BY timestamp DESC
LIMIT 10
4. UX Interactions
4.1 Loading States
| Component | Loading State |
|---|---|
| Stats Cards | Skeleton placeholder (gray boxes) |
| Data Quality Ring | Skeleton circle |
| Active Model | Skeleton lines |
| Recent Activity | Skeleton list items (5 rows) |
Loading Duration Thresholds:
- < 300ms: No loading state shown
- 300ms - 3s: Show skeleton
-
3s: Show skeleton + "Taking longer than expected" message
4.2 Error States
| Error Type | Display |
|---|---|
| API Error | Toast notification + retry button in affected panel |
| Network Error | Full page overlay with retry option |
| Partial Failure | Show available data, error badge on failed sections |
4.3 Refresh Behavior
| Trigger | Behavior |
|---|---|
| Page Load | Fetch all data |
| Manual Refresh | Button in header, refetch all |
| Auto Refresh | Every 30 seconds for activity panel |
| Focus Return | Refetch if page was hidden > 5 minutes |
4.4 Click Actions
| Element | Action |
|---|---|
| Total Documents card | Navigate to /documents |
| Complete card | Navigate to /documents?filter=complete |
| Incomplete card | Navigate to /documents?filter=incomplete |
| Pending card | Navigate to /documents?filter=pending |
| "View Incomplete Docs" button | Navigate to /documents?filter=incomplete |
| Activity item | Navigate to related entity |
| "Go to Training" button | Navigate to /training |
| Active Model version | Navigate to /models/{version_id} |
4.5 Tooltips
| Element | Tooltip Content |
|---|---|
| Completeness % | "25 of 33 labeled documents have complete annotations" |
| mAP metric | "Mean Average Precision at IoU 0.5" |
| Precision metric | "Proportion of correct positive predictions" |
| Recall metric | "Proportion of actual positives correctly identified" |
| Incomplete count | "Documents labeled but missing invoice_number/ocr_number or bankgiro/plusgiro" |
5. Data Model
5.1 TypeScript Types
// Dashboard Stats
interface DashboardStats {
total_documents: number;
annotation_complete: number;
annotation_incomplete: number;
pending: number;
completeness_rate: number;
}
// Active Model
interface ActiveModelInfo {
model: ModelVersion | null;
running_training: RunningTraining | null;
}
interface ModelVersion {
version_id: string;
version: string;
name: string;
metrics_mAP: number;
metrics_precision: number;
metrics_recall: number;
document_count: number;
activated_at: string;
}
interface RunningTraining {
task_id: string;
name: string;
status: 'running';
started_at: string;
progress: number;
}
// Activity
interface Activity {
type: ActivityType;
description: string;
timestamp: string;
metadata: Record<string, unknown>;
}
type ActivityType =
| 'document_uploaded'
| 'annotation_modified'
| 'training_completed'
| 'training_failed'
| 'model_activated';
// Activity Response
interface ActivityResponse {
activities: Activity[];
}
5.2 React Query Hooks
// useDashboardStats
const useDashboardStats = () => {
return useQuery({
queryKey: ['dashboard', 'stats'],
queryFn: () => api.get('/admin/dashboard/stats'),
refetchInterval: 30000, // 30 seconds
});
};
// useActiveModel
const useActiveModel = () => {
return useQuery({
queryKey: ['dashboard', 'active-model'],
queryFn: () => api.get('/admin/dashboard/active-model'),
refetchInterval: 60000, // 1 minute
});
};
// useRecentActivity
const useRecentActivity = (limit = 10) => {
return useQuery({
queryKey: ['dashboard', 'activity', limit],
queryFn: () => api.get(`/admin/dashboard/activity?limit=${limit}`),
refetchInterval: 30000,
});
};
6. Annotation Completeness Definition
6.1 Core Fields
A document is complete when it has annotations for:
| Requirement | Fields | Logic |
|---|---|---|
| Identifier | invoice_number (class_id=0) OR ocr_number (class_id=3) |
At least one |
| Payment Account | bankgiro (class_id=4) OR plusgiro (class_id=5) |
At least one |
6.2 Status Categories
| Category | Criteria |
|---|---|
| Complete | status=labeled AND has identifier AND has payment account |
| Incomplete | status=labeled AND (missing identifier OR missing payment account) |
| Pending | status IN (pending, auto_labeling) |
6.3 Filter Implementation
-- Complete documents
WHERE status = 'labeled'
AND document_id IN (
SELECT document_id FROM admin_annotations WHERE class_id IN (0, 3)
)
AND document_id IN (
SELECT document_id FROM admin_annotations WHERE class_id IN (4, 5)
)
-- Incomplete documents
WHERE status = 'labeled'
AND (
document_id NOT IN (
SELECT document_id FROM admin_annotations WHERE class_id IN (0, 3)
)
OR document_id NOT IN (
SELECT document_id FROM admin_annotations WHERE class_id IN (4, 5)
)
)
7. Implementation Checklist
Backend
- Create
/api/v1/admin/dashboard/statsendpoint - Create
/api/v1/admin/dashboard/active-modelendpoint - Create
/api/v1/admin/dashboard/activityendpoint - Add completeness calculation logic to document repository
- Implement activity aggregation query
Frontend
- Create
DashboardOverviewcomponent - Create
StatsCardcomponent - Create
DataQualityPanelcomponent with progress ring - Create
ActiveModelPanelcomponent - Create
RecentActivityPanelcomponent - Create
SystemStatusBarcomponent - Add React Query hooks for dashboard data
- Implement loading skeletons
- Implement error states
- Add navigation actions
- Add tooltips
Testing
- Unit tests for completeness calculation
- Unit tests for activity aggregation
- Integration tests for dashboard endpoints
- E2E tests for dashboard interactions