docs: add stage 1.5 shadcn ui plan

This commit is contained in:
hailin
2026-07-01 11:34:21 +08:00
parent 28f6588adf
commit 8f07980a48

View File

@@ -0,0 +1,601 @@
# Stage 1.5 shadcn UI Foundation Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Formalize shadcn/ui in the Vite frontend, build a reusable Chinese enterprise admin App component layer, and redesign the existing ticket and solution pages around a production workbench experience.
**Architecture:** Keep shadcn-generated primitives under `frontend/src/components/ui` and project-owned product components under `frontend/src/components/app`. Business pages should compose App components for layout, table, filters, detail workbench, status, priority, and empty states while preserving existing backend API contracts.
**Tech Stack:** React 19, Vite 6, TypeScript, Tailwind CSS v3, shadcn/ui, Radix UI, lucide-react, npm.
---
## Source Spec
- `docs/superpowers/specs/2026-07-01-stage-1-5-shadcn-ui-foundation-design.md`
## Scope
Stage 1.5 is frontend-only unless shadcn initialization unexpectedly requires a metadata adjustment. Do not add knowledge base, Agent, Skill, MCP, model gateway, or new backend behavior.
## File Structure
Expected created or modified files:
- Create: `frontend/components.json`
- Modify: `frontend/package.json`
- Modify: `frontend/package-lock.json`
- Modify: `frontend/tailwind.config.ts`
- Modify: `frontend/src/styles/globals.css`
- Create or replace shadcn primitives in `frontend/src/components/ui/*`
- Modify: `frontend/src/app/router.tsx`
- Modify: `frontend/src/app/layout/AppShell.tsx`
- Replace or remove: `frontend/src/app/layout/Sidebar.tsx`
- Replace or remove: `frontend/src/app/layout/Topbar.tsx`
- Create: `frontend/src/components/app/AppSidebar.tsx`
- Create: `frontend/src/components/app/AppTopbar.tsx`
- Modify: `frontend/src/components/app/AppPageHeader.tsx`
- Create: `frontend/src/components/app/AppDataTable.tsx`
- Create: `frontend/src/components/app/AppFilterBar.tsx`
- Create: `frontend/src/components/app/AppDetailLayout.tsx`
- Create: `frontend/src/components/app/AppSection.tsx`
- Modify: `frontend/src/components/app/AppEmptyState.tsx`
- Modify: `frontend/src/components/app/AppStatusBadge.tsx`
- Modify: `frontend/src/components/app/AppPriorityBadge.tsx`
- Modify: `frontend/src/features/design-system/DesignSystemPreview.tsx`
- Create: `frontend/src/features/workbench/WorkbenchPage.tsx`
- Modify: `frontend/src/features/tickets/TicketListPage.tsx`
- Modify: `frontend/src/features/tickets/TicketCreatePage.tsx`
- Modify: `frontend/src/features/tickets/TicketDetailPage.tsx`
- Modify: `frontend/src/features/tickets/TicketStatusTimeline.tsx`
- Modify: `frontend/src/features/tickets/TicketComments.tsx`
- Modify: `frontend/src/features/solutions/SolutionListPage.tsx`
- Modify: `frontend/src/features/solutions/SolutionLinkPanel.tsx`
## Task 1: Initialize shadcn/ui
**Files:**
- Create: `frontend/components.json`
- Modify: `frontend/package.json`
- Modify: `frontend/package-lock.json`
- Modify: `frontend/tailwind.config.ts`
- Modify: `frontend/src/styles/globals.css`
- Create or replace: `frontend/src/components/ui/*`
- [ ] **Step 1: Capture current shadcn state**
Run:
```bash
cd frontend
npx shadcn@latest info
```
Expected before initialization:
```text
config: null
components: []
```
- [ ] **Step 2: Initialize shadcn for the existing Vite app**
Run:
```bash
cd frontend
npx shadcn@latest init
```
Select options that preserve the existing project shape:
```text
Framework: Vite
TypeScript: yes
Tailwind CSS file: src/styles/globals.css
Tailwind config: tailwind.config.ts
Import alias: @
Use CSS variables: yes
Base color: neutral or zinc
```
Do not accept changes that move the app to Next.js or switch the package manager away from npm.
- [ ] **Step 3: Add the required shadcn primitives**
Run:
```bash
cd frontend
npx shadcn@latest add button badge card input textarea select label separator sidebar breadcrumb dropdown-menu table tabs sheet dialog tooltip skeleton sonner
```
If the CLI reports that one component name is unavailable, retry without only that component and document the exact skipped name in this plan's execution notes.
- [ ] **Step 4: Verify shadcn state**
Run:
```bash
cd frontend
npx shadcn@latest info
```
Expected:
```text
config: present
components: non-empty
```
- [ ] **Step 5: Run frontend typecheck**
Run:
```bash
cd frontend
npm run typecheck
```
Expected: exit code `0`. If shadcn overwrote local component APIs, fix imports and variants in Task 2 instead of editing business pages in this task.
- [ ] **Step 6: Commit**
Run:
```bash
git add frontend/components.json frontend/package.json frontend/package-lock.json frontend/tailwind.config.ts frontend/src/styles/globals.css frontend/src/components/ui
git commit -m "feat: initialize shadcn ui"
```
## Task 2: Build the App Component Layer
**Files:**
- Modify: `frontend/src/app/layout/AppShell.tsx`
- Create: `frontend/src/components/app/AppSidebar.tsx`
- Create: `frontend/src/components/app/AppTopbar.tsx`
- Modify: `frontend/src/components/app/AppPageHeader.tsx`
- Create: `frontend/src/components/app/AppDataTable.tsx`
- Create: `frontend/src/components/app/AppFilterBar.tsx`
- Create: `frontend/src/components/app/AppDetailLayout.tsx`
- Create: `frontend/src/components/app/AppSection.tsx`
- Modify: `frontend/src/components/app/AppEmptyState.tsx`
- Modify: `frontend/src/components/app/AppStatusBadge.tsx`
- Modify: `frontend/src/components/app/AppPriorityBadge.tsx`
- [ ] **Step 1: Replace the layout imports**
`frontend/src/app/layout/AppShell.tsx` should import from the App component layer:
```tsx
import type * as React from 'react'
import { AppSidebar } from '@/components/app/AppSidebar'
import { AppTopbar } from '@/components/app/AppTopbar'
type AppShellProps = {
children: React.ReactNode
}
export function AppShell({ children }: AppShellProps) {
return (
<div className="min-h-screen bg-background text-foreground">
<AppSidebar />
<div className="min-h-screen lg:pl-72">
<AppTopbar />
{children}
</div>
</div>
)
}
```
- [ ] **Step 2: Create Chinese sidebar navigation**
`frontend/src/components/app/AppSidebar.tsx` should define grouped navigation:
```tsx
import { Bot, BriefcaseBusiness, Database, Home, Library, Settings, ShieldCheck, Ticket } from 'lucide-react'
const navGroups = [
{
label: '工作台',
items: [{ href: '#/', label: '运营总览', icon: Home }]
},
{
label: '业务处理',
items: [
{ href: '#/tickets', label: '工单中心', icon: Ticket },
{ href: '#/tickets/new', label: '创建工单', icon: BriefcaseBusiness },
{ href: '#/solutions', label: '解决方案库', icon: Library }
]
},
{
label: '平台能力',
items: [
{ href: '#/knowledge', label: '知识库', icon: Database },
{ href: '#/agents', label: 'Agent 配置', icon: Bot },
{ href: '#/system', label: '系统治理', icon: ShieldCheck },
{ href: '#/design-system', label: '设计系统', icon: Settings }
]
}
]
```
Render the groups in a fixed left sidebar, using lucide icons and Chinese labels only.
- [ ] **Step 3: Create topbar and breadcrumb placeholder**
`frontend/src/components/app/AppTopbar.tsx` should show:
```text
AI 工单平台 / 当前工作区
```
and right-side placeholders:
```text
本地环境
系统管理员
```
Use `Badge` for `本地环境`, `Button` with `variant="ghost"` for `系统管理员`, `Separator` between breadcrumb and right-side controls, and lucide icons for visible icon buttons.
- [ ] **Step 4: Create reusable data table wrapper**
`frontend/src/components/app/AppDataTable.tsx` should accept:
```tsx
type AppDataTableColumn<Row> = {
key: string
header: React.ReactNode
cell: (row: Row) => React.ReactNode
className?: string
}
type AppDataTableProps<Row> = {
columns: AppDataTableColumn<Row>[]
rows: Row[]
getRowKey: (row: Row) => React.Key
emptyTitle: string
emptyDescription?: string
toolbar?: React.ReactNode
footer?: React.ReactNode
onRowClick?: (row: Row) => void
}
```
Use shadcn `Table` primitives internally. Keep row height stable and use Chinese empty-state copy from props.
- [ ] **Step 5: Create filter and detail helpers**
Create:
```text
AppFilterBar: section wrapper for search input, select filters, and reset/actions.
AppDetailLayout: responsive detail layout with main and side columns.
AppSection: titled section wrapper with optional description and action.
```
These components must not know about ticket-specific fields.
- [ ] **Step 6: Update badge and empty-state components**
Ensure status labels are Chinese:
```text
pending_info=待补充
pending=待处理
in_progress=处理中
pending_confirm=待确认
resolved=已解决
closed=已关闭
```
Ensure priority labels are Chinese:
```text
low=低
medium=中
high=高
urgent=紧急
```
- [ ] **Step 7: Run frontend typecheck**
Run:
```bash
cd frontend
npm run typecheck
```
Expected: exit code `0`.
- [ ] **Step 8: Commit**
Run:
```bash
git add frontend/src/app/layout frontend/src/components/app
git commit -m "feat: add enterprise app ui layer"
```
## Task 3: Add Chinese Workbench and Routing
**Files:**
- Modify: `frontend/src/app/router.tsx`
- Create: `frontend/src/features/workbench/WorkbenchPage.tsx`
- Modify: `frontend/src/features/design-system/DesignSystemPreview.tsx`
- [ ] **Step 1: Add the default workbench route**
In `frontend/src/app/router.tsx`, change the default route from `/tickets` to `/` and route `/` to `WorkbenchPage`.
Required behavior:
```text
#/ -> WorkbenchPage
#/tickets -> TicketListPage
#/tickets/new -> TicketCreatePage
#/tickets/:id -> TicketDetailPage
#/solutions -> SolutionListPage
#/design-system -> DesignSystemPreview
```
- [ ] **Step 2: Create workbench page**
`WorkbenchPage` should load tickets with `listTickets({})` and show Chinese operational sections:
```text
今日工作台
待处理工单
处理中
高优先级
已解决
最近工单
快捷入口
```
Use the existing ticket API only. Counts can be computed from the loaded list.
- [ ] **Step 3: Update design system preview**
The preview page should demonstrate:
```text
按钮
状态标签
优先级标签
筛选条
数据表格
详情区块
空状态
```
All visible text must be Chinese.
- [ ] **Step 4: Run frontend typecheck**
Run:
```bash
cd frontend
npm run typecheck
```
Expected: exit code `0`.
- [ ] **Step 5: Commit**
Run:
```bash
git add frontend/src/app/router.tsx frontend/src/features/workbench frontend/src/features/design-system/DesignSystemPreview.tsx
git commit -m "feat: add chinese workbench page"
```
## Task 4: Redesign Ticket Pages
**Files:**
- Modify: `frontend/src/features/tickets/TicketListPage.tsx`
- Modify: `frontend/src/features/tickets/TicketCreatePage.tsx`
- Modify: `frontend/src/features/tickets/TicketDetailPage.tsx`
- Modify: `frontend/src/features/tickets/TicketStatusTimeline.tsx`
- Modify: `frontend/src/features/tickets/TicketComments.tsx`
- [ ] **Step 1: Redesign ticket list as a table workbench**
Use `AppPageHeader`, `AppFilterBar`, `AppDataTable`, `AppStatusBadge`, and `AppPriorityBadge`.
Required Chinese table columns:
```text
编号
标题
状态
优先级
关联系统
影响范围
创建时间
操作
```
Required actions:
```text
新建工单
查看详情
重置筛选
```
- [ ] **Step 2: Redesign ticket creation page**
Use Chinese sections:
```text
创建工单
问题描述
处理属性
影响范围
AI 建单辅助
```
Use Chinese labels:
```text
工单标题
问题描述
优先级
关联系统
影响范围
运行环境
提交工单
```
The AI panel must clearly say:
```text
后续阶段将接入建单 Agent,用于补全字段、追问缺失信息和推荐相似问题。
```
- [ ] **Step 3: Redesign ticket detail as an operations workspace**
Use `AppDetailLayout` with:
```text
Main column: 工单概览, 问题描述, 处理动态, 评论协作
Side column: 关键字段, 关联解决方案, AI 支持分析
```
Status transition buttons must show Chinese labels instead of raw enum values.
- [ ] **Step 4: Localize ticket timeline and comments**
Replace touched English labels with Chinese:
```text
状态流转
评论协作
暂无评论
发表回复
```
- [ ] **Step 5: Run frontend typecheck**
Run:
```bash
cd frontend
npm run typecheck
```
Expected: exit code `0`.
- [ ] **Step 6: Commit**
Run:
```bash
git add frontend/src/features/tickets
git commit -m "feat: redesign ticket workbench ui"
```
## Task 5: Redesign Solution Pages and Final Verification
**Files:**
- Modify: `frontend/src/features/solutions/SolutionListPage.tsx`
- Modify: `frontend/src/features/solutions/SolutionLinkPanel.tsx`
- Modify: `docs/frontend/design-system.md`
- [ ] **Step 1: Redesign solution list**
Use Chinese copy and table/list structure:
```text
解决方案库
沉淀可复用的问题特征、排查步骤和处理方案。
搜索解决方案
状态
引用次数
查看关联
```
Use badges for published/draft status:
```text
published=已发布
draft=草稿
```
- [ ] **Step 2: Localize solution link panel**
Use Chinese labels:
```text
关联解决方案
推荐方案
已采纳
暂无关联方案
```
- [ ] **Step 3: Update design system docs**
Update `docs/frontend/design-system.md` so it documents:
```text
shadcn/ui primitives
App component layer
Chinese-first frontend copy rule
Business pages must use AppDataTable/AppFilterBar/AppDetailLayout for repeated patterns
```
- [ ] **Step 4: Run final frontend verification**
Run:
```bash
cd frontend
npm run typecheck
npm run build
```
Expected: both commands exit `0`.
- [ ] **Step 5: Run shadcn info**
Run:
```bash
cd frontend
npx shadcn@latest info
```
Expected:
```text
components.json exists
components list is non-empty
```
- [ ] **Step 6: Commit**
Run:
```bash
git add frontend/src/features/solutions docs/frontend/design-system.md
git commit -m "feat: polish solution ui and design docs"
```
## Final Review Checklist
- [ ] `frontend/components.json` exists.
- [ ] App sidebar/topbar text is Chinese.
- [ ] Workbench default route exists at `#/`.
- [ ] Ticket list is a table-like enterprise view, not a simple card/list dump.
- [ ] Ticket create page uses Chinese labels and includes a future AI helper panel.
- [ ] Ticket detail uses a main/side workbench layout.
- [ ] Solution list and solution link panel are Chinese.
- [ ] Touched frontend text is Chinese.
- [ ] `cd frontend && npm run typecheck` passes.
- [ ] `cd frontend && npm run build` passes.