docs: add stage 1.5 shadcn ui plan
This commit is contained in:
@@ -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.
|
||||
Reference in New Issue
Block a user