docs: add stage 1.7 ticket visual redesign spec
This commit is contained in:
@@ -0,0 +1,454 @@
|
||||
# Stage 1.7 Ticket Experience Visual Redesign Design
|
||||
|
||||
## Background
|
||||
|
||||
Stage 1.6 has established the enterprise governance baseline: login, session-authenticated APIs, backend-driven menus, roles, users, user groups, permission enforcement, and Docker bootstrap.
|
||||
|
||||
The ticket workflow is now protected and usable, but the current ticket UI still feels like a basic demo:
|
||||
|
||||
- The ticket list is a simple table with limited visual hierarchy.
|
||||
- The detail page exposes actions as flat buttons without enough workflow context.
|
||||
- The create page has rough spacing and a few English fallback strings remain in the detail page.
|
||||
- The UI does not yet communicate an enterprise support operations workflow.
|
||||
|
||||
Stage 1.7 intentionally prioritizes visual and interaction quality for the ticket surfaces before deeper backend capabilities such as SLA, batch operations, attachment upload, or row-level permissions.
|
||||
|
||||
## Decision
|
||||
|
||||
Create Stage 1.7 as a visual-first ticket experience stage:
|
||||
|
||||
```text
|
||||
Stage 1.6 = enterprise governance, login, permission menus, deployment bootstrap
|
||||
Stage 1.7 = ticket list/detail/create visual redesign using shadcn/ui
|
||||
Stage 1.8+ = deeper ticket workflow capabilities, SLA, attachments, batch operations
|
||||
Stage 2 = knowledge base and vector retrieval
|
||||
```
|
||||
|
||||
The frontend must use the existing shadcn/ui foundation. New visual work must compose shadcn primitives and existing app-level components rather than introducing a new UI library or ad hoc styled widgets.
|
||||
|
||||
## Goals
|
||||
|
||||
1. Redesign the ticket center as an enterprise operations table, not a simple record list.
|
||||
2. Redesign the ticket detail page around clear workflow context, status timeline, comments, and right-side metadata.
|
||||
3. Redesign the create ticket page into a polished grouped form with Chinese labels and helper copy.
|
||||
4. Keep all visible frontend copy in Chinese.
|
||||
5. Use shadcn/ui components for all new controls, feedback, overlays, status display, and layout surfaces.
|
||||
6. Add only the backend support needed for the redesigned UI, such as pagination, richer filters, and basic requester/assignee display fields.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- No SLA engine.
|
||||
- No real attachment upload pipeline.
|
||||
- No batch operations.
|
||||
- No Kanban board.
|
||||
- No row-level data permission.
|
||||
- No field-level permission.
|
||||
- No AI ticket drafting implementation.
|
||||
- No knowledge base retrieval implementation.
|
||||
- No new authentication or authorization model.
|
||||
- No replacement of the existing shadcn preset or theme.
|
||||
|
||||
## UI System Requirements
|
||||
|
||||
The implementation must use the existing project shadcn setup:
|
||||
|
||||
- Framework: Vite + React + TypeScript.
|
||||
- Styling: Tailwind CSS v3.
|
||||
- shadcn style: `radix-nova`.
|
||||
- Icon library: `lucide-react`.
|
||||
- Component source: local shadcn files under `frontend/src/components/ui`.
|
||||
|
||||
Required shadcn primitives for Stage 1.7:
|
||||
|
||||
- Already installed: `button`, `badge`, `card`, `dialog`, `input`, `label`, `pagination`, `select`, `separator`, `skeleton`, `sonner`, `table`, `tabs`, `textarea`, `tooltip`.
|
||||
- Add only if needed through `npx shadcn@latest add`: `sheet`, `popover`, `calendar`, `command`, `toggle-group`, `scroll-area`, `empty`.
|
||||
|
||||
Important compatibility rule:
|
||||
|
||||
- The project uses Tailwind CSS v3. Any newly generated shadcn component must be reviewed after `npx shadcn@latest add` and patched if the generated file contains Tailwind v4-only state selectors or syntax that does not compile or render correctly in the current project.
|
||||
|
||||
## Ticket List Redesign
|
||||
|
||||
Route:
|
||||
|
||||
```text
|
||||
#/tickets
|
||||
```
|
||||
|
||||
The page should become a dense operations console.
|
||||
|
||||
### Layout
|
||||
|
||||
Use a constrained full-width content area similar to the governance pages:
|
||||
|
||||
```text
|
||||
Header
|
||||
Metric cards
|
||||
View tabs
|
||||
Filter bar
|
||||
Ticket table
|
||||
Pagination footer
|
||||
```
|
||||
|
||||
### Header
|
||||
|
||||
Header copy:
|
||||
|
||||
```text
|
||||
工单中心
|
||||
集中查看、筛选和处理企业技术支持工单。
|
||||
```
|
||||
|
||||
Primary action:
|
||||
|
||||
```text
|
||||
新建工单
|
||||
```
|
||||
|
||||
### View Tabs
|
||||
|
||||
Use shadcn `Tabs`:
|
||||
|
||||
```text
|
||||
全部工单
|
||||
我的待办
|
||||
我创建的
|
||||
高优先级
|
||||
```
|
||||
|
||||
Stage 1.7 can implement these as frontend view filters if backend support is not yet complete. The backend should still accept a lightweight `view` query parameter if feasible:
|
||||
|
||||
```text
|
||||
all
|
||||
assigned_to_me
|
||||
created_by_me
|
||||
high_priority
|
||||
```
|
||||
|
||||
### Metrics
|
||||
|
||||
Use shadcn `Card` composition. Cards should be compact and operational:
|
||||
|
||||
```text
|
||||
待处理
|
||||
处理中
|
||||
待确认
|
||||
高优先级
|
||||
```
|
||||
|
||||
### Filters
|
||||
|
||||
Use shadcn `Input` and `Select`:
|
||||
|
||||
```text
|
||||
关键词
|
||||
状态
|
||||
优先级
|
||||
关联系统
|
||||
处理人
|
||||
```
|
||||
|
||||
Date range is intentionally deferred unless a lightweight implementation is available without pulling in extra date complexity.
|
||||
|
||||
### Table Columns
|
||||
|
||||
Use the existing `AppDataTable` or a refined ticket-specific table built from shadcn `Table`.
|
||||
|
||||
Required columns:
|
||||
|
||||
```text
|
||||
编号
|
||||
标题
|
||||
状态
|
||||
优先级
|
||||
关联系统
|
||||
影响范围
|
||||
处理人
|
||||
创建时间
|
||||
操作
|
||||
```
|
||||
|
||||
The title cell should show compact secondary metadata when available, such as environment or requester.
|
||||
|
||||
### Pagination
|
||||
|
||||
Use the existing shadcn-compatible `pagination` component.
|
||||
|
||||
The backend should return pagination metadata if implemented:
|
||||
|
||||
```json
|
||||
{
|
||||
"items": [],
|
||||
"page": 1,
|
||||
"page_size": 20,
|
||||
"total": 0,
|
||||
"total_pages": 0
|
||||
}
|
||||
```
|
||||
|
||||
If backend pagination is delayed, the frontend may paginate the loaded first 100 rows, but the preferred implementation is backend pagination.
|
||||
|
||||
## Ticket Detail Redesign
|
||||
|
||||
Route:
|
||||
|
||||
```text
|
||||
#/tickets/{id}
|
||||
```
|
||||
|
||||
The page should feel like a ticket operations workspace.
|
||||
|
||||
### Layout
|
||||
|
||||
Use a two-column layout:
|
||||
|
||||
```text
|
||||
Header with title, ticket number, status, priority
|
||||
Main column:
|
||||
问题描述
|
||||
处理记录
|
||||
评论与协作
|
||||
Side column:
|
||||
当前状态
|
||||
处理人
|
||||
请求人
|
||||
关联系统
|
||||
运行环境
|
||||
影响范围
|
||||
关联方案
|
||||
AI 支持分析(占位)
|
||||
```
|
||||
|
||||
### Header Actions
|
||||
|
||||
Replace flat status buttons with workflow-aware actions.
|
||||
|
||||
Use shadcn `Dialog` for status transition:
|
||||
|
||||
```text
|
||||
开始处理
|
||||
提交确认
|
||||
标记解决
|
||||
关闭工单
|
||||
```
|
||||
|
||||
The dialog must require a Chinese handling note:
|
||||
|
||||
```text
|
||||
处理说明
|
||||
请说明本次流转的原因、处理动作或待确认事项。
|
||||
```
|
||||
|
||||
### Timeline
|
||||
|
||||
The timeline must render Chinese event labels:
|
||||
|
||||
```text
|
||||
创建工单
|
||||
更新工单
|
||||
状态变更
|
||||
新增评论
|
||||
新增附件
|
||||
```
|
||||
|
||||
English loading/error fallbacks must be replaced:
|
||||
|
||||
```text
|
||||
无法加载工单
|
||||
正在加载工单
|
||||
```
|
||||
|
||||
### Comments
|
||||
|
||||
Comment UI should distinguish:
|
||||
|
||||
```text
|
||||
内部备注
|
||||
用户可见回复
|
||||
```
|
||||
|
||||
Stage 1.7 may still post to the existing comment endpoint, but the UI should present the two visibility options clearly.
|
||||
|
||||
## Ticket Create Redesign
|
||||
|
||||
Route:
|
||||
|
||||
```text
|
||||
#/tickets/new
|
||||
```
|
||||
|
||||
The create page should be a polished enterprise form, not a loose demo form.
|
||||
|
||||
### Layout
|
||||
|
||||
Use grouped sections:
|
||||
|
||||
```text
|
||||
基础信息
|
||||
影响与优先级
|
||||
环境与系统
|
||||
问题描述
|
||||
提交确认
|
||||
```
|
||||
|
||||
Recommended layout:
|
||||
|
||||
```text
|
||||
Main column: grouped form sections
|
||||
Side column: 建单提示 + AI 建单辅助占位
|
||||
```
|
||||
|
||||
### Required Fields
|
||||
|
||||
```text
|
||||
工单标题
|
||||
问题描述
|
||||
优先级
|
||||
```
|
||||
|
||||
Optional fields:
|
||||
|
||||
```text
|
||||
关联系统
|
||||
运行环境
|
||||
影响范围
|
||||
处理人
|
||||
```
|
||||
|
||||
### Behavior
|
||||
|
||||
- Submit success navigates to the ticket detail page.
|
||||
- Submit failure shows Chinese error feedback.
|
||||
- Empty required fields rely on native validation or shadcn field validation styling.
|
||||
- AI helper remains an understated placeholder, not the visual focus.
|
||||
|
||||
## Backend Support
|
||||
|
||||
Backend changes should remain narrow and visual-support oriented.
|
||||
|
||||
### List Query
|
||||
|
||||
Extend `GET /api/tickets` to support:
|
||||
|
||||
```text
|
||||
page
|
||||
page_size
|
||||
status
|
||||
priority
|
||||
q
|
||||
related_system
|
||||
assignee_id
|
||||
view
|
||||
```
|
||||
|
||||
Suggested response:
|
||||
|
||||
```json
|
||||
{
|
||||
"items": [],
|
||||
"page": 1,
|
||||
"page_size": 20,
|
||||
"total": 0,
|
||||
"total_pages": 0
|
||||
}
|
||||
```
|
||||
|
||||
### Ticket Output
|
||||
|
||||
Add basic display user fields to ticket output:
|
||||
|
||||
```json
|
||||
{
|
||||
"requester": {"id": 1, "display_name": "张三", "username": "zhangsan"},
|
||||
"assignee": {"id": 2, "display_name": "李四", "username": "lisi"}
|
||||
}
|
||||
```
|
||||
|
||||
Existing `requester_id` and `assignee_id` may remain if useful.
|
||||
|
||||
### Status Transition
|
||||
|
||||
The existing status transition endpoint can remain:
|
||||
|
||||
```text
|
||||
POST /api/tickets/{id}/status
|
||||
```
|
||||
|
||||
The frontend dialog should always send a non-empty remark. Backend validation for non-empty remark is preferred if it can be added with tests.
|
||||
|
||||
### Assignment
|
||||
|
||||
If needed for the detail side panel, use the existing `PATCH /api/tickets/{id}` with `assignee_id`. A dedicated assignment endpoint is deferred unless it materially simplifies UI code.
|
||||
|
||||
## Frontend File Scope
|
||||
|
||||
Expected files to touch:
|
||||
|
||||
```text
|
||||
frontend/src/features/tickets/types.ts
|
||||
frontend/src/features/tickets/api.ts
|
||||
frontend/src/features/tickets/TicketListPage.tsx
|
||||
frontend/src/features/tickets/TicketDetailPage.tsx
|
||||
frontend/src/features/tickets/TicketCreatePage.tsx
|
||||
frontend/src/features/tickets/TicketComments.tsx
|
||||
frontend/src/features/tickets/TicketStatusTimeline.tsx
|
||||
frontend/src/components/app/AppDataTable.tsx
|
||||
frontend/src/components/app/AppEmptyState.tsx
|
||||
```
|
||||
|
||||
Add small ticket-specific components only when they reduce page complexity:
|
||||
|
||||
```text
|
||||
frontend/src/features/tickets/TicketMetricCards.tsx
|
||||
frontend/src/features/tickets/TicketFilterBar.tsx
|
||||
frontend/src/features/tickets/TicketTransitionDialog.tsx
|
||||
frontend/src/features/tickets/TicketMetaPanel.tsx
|
||||
```
|
||||
|
||||
## Testing Requirements
|
||||
|
||||
Backend tests:
|
||||
|
||||
- Ticket list pagination returns metadata and items.
|
||||
- Ticket list filters by status, priority, related system, keyword, and view.
|
||||
- Ticket output includes requester and assignee display fields.
|
||||
- Status transition with an empty remark is rejected if backend validation is implemented.
|
||||
|
||||
Frontend verification:
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
npm run typecheck
|
||||
npm run build
|
||||
npx shadcn@latest info
|
||||
```
|
||||
|
||||
Backend verification:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
python -m pytest apps/tickets/tests -v
|
||||
python -m pytest apps/accounts/tests/test_permission_enforcement.py -v
|
||||
python -m ruff check .
|
||||
```
|
||||
|
||||
Browser visual smoke test:
|
||||
|
||||
- Login as seeded admin.
|
||||
- Open `#/tickets`.
|
||||
- Verify the ticket list renders Chinese tabs, metric cards, filters, table, and pagination.
|
||||
- Open a ticket detail page.
|
||||
- Verify status actions open a Chinese dialog requiring handling note.
|
||||
- Open `#/tickets/new`.
|
||||
- Verify grouped Chinese create form renders without overlap.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- Ticket list, detail, and create pages look like a coherent enterprise admin product.
|
||||
- All visible copy in ticket pages is Chinese.
|
||||
- New UI uses shadcn/ui components and existing app-level components.
|
||||
- No new UI library is introduced.
|
||||
- Backend changes are limited to pagination, filters, display fields, and remark validation if implemented.
|
||||
- Existing authentication and permission enforcement continue to work.
|
||||
- `npm run typecheck`, `npm run build`, backend ticket tests, and ruff pass.
|
||||
- Browser screenshots show no obvious text overlap, broken layout, or blank states on desktop.
|
||||
Reference in New Issue
Block a user