diff --git a/docs/superpowers/plans/2026-07-01-stage-1-5-shadcn-ui-foundation.md b/docs/superpowers/plans/2026-07-01-stage-1-5-shadcn-ui-foundation.md new file mode 100644 index 0000000..b07c834 --- /dev/null +++ b/docs/superpowers/plans/2026-07-01-stage-1-5-shadcn-ui-foundation.md @@ -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 ( +
+ +
+ + {children} +
+
+ ) +} +``` + +- [ ] **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 = { + key: string + header: React.ReactNode + cell: (row: Row) => React.ReactNode + className?: string +} + +type AppDataTableProps = { + columns: AppDataTableColumn[] + 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.