building-admin-dashboard-customizations
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseMedusa Admin Dashboard Customizations
Medusa Admin 仪表盘自定义开发
Build custom UI extensions for the Medusa Admin dashboard using the Admin SDK and Medusa UI components.
Note: "UI Routes" are custom admin pages, different from backend API routes (which use building-with-medusa skill).
使用Admin SDK和Medusa UI组件为Medusa Admin仪表盘构建自定义UI扩展。
注意: "UI Routes"指的是自定义管理页面,与后端API路由不同(后者使用building-with-medusa技能)。
When to Apply
适用场景
Load this skill for ANY admin UI development task, including:
- Creating widgets for product/order/customer pages
- Building custom admin pages
- Implementing forms and modals
- Displaying data with tables or lists
- Adding navigation between pages
Also load these skills when:
- building-with-medusa: Building backend API routes that the admin UI calls
- building-storefronts: If working on storefront instead of admin dashboard
在进行任何Admin UI开发任务时都应加载本技能,包括:
- 为产品/订单/客户页面创建小组件
- 构建自定义管理页面
- 实现表单与模态框
- 使用表格或列表展示数据
- 添加页面间导航
同时在以下场景还需加载对应技能:
- building-with-medusa: 构建供Admin UI调用的后端API路由时
- building-storefronts: 若开发的是店铺前端而非Admin仪表盘时
CRITICAL: Load Reference Files When Needed
重要提示:按需加载参考文件
The quick reference below is NOT sufficient for implementation. You MUST load relevant reference files before writing code for that component.
Load these references based on what you're implementing:
- Creating widgets? → MUST load first
references/data-loading.md - Building forms/modals? → MUST load first
references/forms.md - Displaying data in tables/lists? → MUST load first
references/display-patterns.md - Selecting from large datasets? → MUST load first
references/table-selection.md - Adding navigation? → MUST load first
references/navigation.md - Styling components? → MUST load first
references/typography.md
Minimum requirement: Load at least 1-2 reference files relevant to your specific task before implementing.
以下快速参考内容不足以支撑实际开发。 在编写对应组件的代码前,你必须加载相关的参考文件。
根据你要实现的功能加载以下参考文件:
- 创建小组件? → 必须先加载
references/data-loading.md - 构建表单/模态框? → 必须先加载
references/forms.md - 使用表格/列表展示数据?** → 必须先加载
references/display-patterns.md - 从大型数据集中选择数据? → 必须先加载
references/table-selection.md - 添加导航? → 必须先加载
references/navigation.md - 组件样式设置? → 必须先加载
references/typography.md
最低要求: 在实现功能前,至少加载1-2个与你的具体任务相关的参考文件。
When to Use This Skill vs MedusaDocs MCP Server
何时使用本技能 vs MedusaDocs MCP服务器
⚠️ CRITICAL: This skill should be consulted FIRST for planning and implementation.
Use this skill for (PRIMARY SOURCE):
- Planning - Understanding how to structure admin UI features
- Component patterns - Widgets, pages, forms, tables, modals
- Design system - Typography, colors, spacing, semantic classes
- Data loading - Critical separate query pattern, cache invalidation
- Best practices - Correct vs incorrect patterns (e.g., display queries on mount)
- Critical rules - What NOT to do (common mistakes like conditional display queries)
Use MedusaDocs MCP server for (SECONDARY SOURCE):
- Specific component prop signatures after you know which component to use
- Available widget zones list
- JS SDK method details
- Configuration options reference
Why skills come first:
- Skills contain critical patterns like separate display/modal queries that MCP doesn't emphasize
- Skills show correct vs incorrect patterns; MCP shows what's possible
- Planning requires understanding patterns, not just API reference
⚠️ 重要提示:规划和实现时应首先参考本技能。
本技能的适用场景(主要参考来源):
- 规划 - 了解如何构建Admin UI功能的结构
- 组件模式 - 小组件、页面、表单、表格、模态框的实现模式
- 设计系统 - 排版、颜色、间距、语义化类名
- 数据加载 - 关键的独立查询模式、缓存失效策略
- 最佳实践 - 正确与错误的模式对比(例如:在组件挂载时加载显示数据查询)
- 关键规则 - 禁止操作(常见错误如条件性加载显示数据查询)
MedusaDocs MCP服务器的适用场景(次要参考来源):
- 确定要使用的组件后,查询该组件的具体属性签名
- 可用小组件区域列表
- JS SDK方法细节
- 配置选项参考
优先使用本技能的原因:
- 本技能包含MCP未重点强调的关键模式,如独立的显示/模态框查询
- 本技能展示正确与错误的模式对比;MCP仅展示可实现的功能
- 规划阶段需要理解实现模式,而非仅依赖API参考
Critical Setup Rules
关键设置规则
SDK Client Configuration
SDK客户端配置
CRITICAL: Always use exact configuration - different values cause errors:
tsx
// src/admin/lib/client.ts
import Medusa from "@medusajs/js-sdk"
export const sdk = new Medusa({
baseUrl: import.meta.env.VITE_BACKEND_URL || "/",
debug: import.meta.env.DEV,
auth: {
type: "session",
},
})重要提示: 请始终使用以下精确配置,不同的值会导致错误:
tsx
// src/admin/lib/client.ts
import Medusa from "@medusajs/js-sdk"
export const sdk = new Medusa({
baseUrl: import.meta.env.VITE_BACKEND_URL || "/",
debug: import.meta.env.DEV,
auth: {
type: "session",
},
})pnpm Users ONLY
仅针对pnpm用户
CRITICAL: Install peer dependencies BEFORE writing any code:
bash
undefined重要提示: 在编写任何代码前,请先安装对等依赖:
bash
undefinedFind exact version from dashboard
从仪表盘中查找精确版本
pnpm list @tanstack/react-query --depth=10 | grep @medusajs/dashboard
pnpm list @tanstack/react-query --depth=10 | grep @medusajs/dashboard
Install that exact version
安装该精确版本
pnpm add @tanstack/react-query@[exact-version]
pnpm add @tanstack/react-query@[exact-version]
If using navigation (Link component)
如果使用导航(Link组件)
pnpm list react-router-dom --depth=10 | grep @medusajs/dashboard
pnpm add react-router-dom@[exact-version]
**npm/yarn users:** DO NOT install these packages - already available.pnpm list react-router-dom --depth=10 | grep @medusajs/dashboard
pnpm add react-router-dom@[exact-version]
**npm/yarn用户:** 无需安装这些包 - 已默认提供。Rule Categories by Priority
按优先级划分的规则类别
| Priority | Category | Impact | Prefix |
|---|---|---|---|
| 1 | Data Loading | CRITICAL | |
| 2 | Design System | CRITICAL | |
| 3 | Data Display | HIGH (includes CRITICAL price rule) | |
| 4 | Typography | HIGH | |
| 5 | Forms & Modals | MEDIUM | |
| 6 | Selection Patterns | MEDIUM | |
| 优先级 | 类别 | 影响 | 前缀 |
|---|---|---|---|
| 1 | 数据加载 | 关键 | |
| 2 | 设计系统 | 关键 | |
| 3 | 数据展示 | 高(包含关键价格规则) | |
| 4 | 排版 | 高 | |
| 5 | 表单与模态框 | 中 | |
| 6 | 选择模式 | 中 | |
Quick Reference
快速参考
1. Data Loading (CRITICAL)
1. 数据加载(关键)
- - Display queries MUST load on mount (no enabled condition based on UI state)
data-display-on-mount - - Separate display queries from modal/form queries
data-separate-queries - - Invalidate display queries after mutations, not just modal queries
data-invalidate-display - - Always show loading states (Spinner), not empty states
data-loading-states - - pnpm users MUST install @tanstack/react-query BEFORE coding
data-pnpm-install-first
- - 展示数据的查询必须在组件挂载时加载(不能基于UI状态设置enabled条件)
data-display-on-mount - - 将展示数据的查询与模态框/表单的查询分离
data-separate-queries - - 执行变更后,需使展示数据的查询失效,而非仅使模态框查询失效
data-invalidate-display - - 始终展示加载状态(Spinner),而非空状态
data-loading-states - - pnpm用户必须在编码前安装@tanstack/react-query
data-pnpm-install-first
2. Design System (CRITICAL)
2. 设计系统(关键)
- - Always use semantic color classes (bg-ui-bg-base, text-ui-fg-subtle), never hardcoded
design-semantic-colors - - Use px-6 py-4 for section padding, gap-2 for lists, gap-3 for items
design-spacing - - Always use size="small" for buttons in widgets and tables
design-button-size - - Always use Medusa UI components (Container, Button, Text), not raw HTML
design-medusa-components
- - 始终使用语义化颜色类(bg-ui-bg-base, text-ui-fg-subtle),绝不要硬编码颜色
design-semantic-colors - - 区块内边距使用px-6 py-4,列表使用gap-2,列表项使用gap-3
design-spacing - - 在小组件和表格中,按钮始终使用size="small"
design-button-size - - 始终使用Medusa UI组件(Container, Button, Text),而非原生HTML元素
design-medusa-components
3. Data Display (HIGH)
3. 数据展示(高)
- - CRITICAL: Prices from Medusa are stored as-is ($49.99 = 49.99, NOT in cents). Display them directly - NEVER divide by 100
display-price-format
- - 关键:Medusa中的价格按实际值存储($49.99 = 49.99,而非以分为单位)。直接展示即可 - 绝不要除以100
display-price-format
4. Typography (HIGH)
4. 排版(高)
- - Always use Text component from @medusajs/ui, never plain span/p tags
typo-text-component - - Use
typo-labelsfor labels/headings<Text size="small" leading="compact" weight="plus"> - - Use
typo-descriptionsfor descriptions<Text size="small" leading="compact" className="text-ui-fg-subtle"> - - Never use Heading for small sections in widgets (use Text instead)
typo-no-heading-widgets
- - 始终使用@medusajs/ui中的Text组件,而非普通的span/p标签
typo-text-component - - 标签/标题使用
typo-labels<Text size="small" leading="compact" weight="plus"> - - 描述文本使用
typo-descriptions<Text size="small" leading="compact" className="text-ui-fg-subtle"> - - 小组件中的小型区块绝不要使用Heading组件(改用Text组件)
typo-no-heading-widgets
5. Forms & Modals (MEDIUM)
5. 表单与模态框(中)
- - Use FocusModal for creating new entities
form-focusmodal-create - - Use Drawer for editing existing entities
form-drawer-edit - - Always disable actions during mutations (disabled={mutation.isPending})
form-disable-pending - - Show loading state on submit button (isLoading={mutation.isPending})
form-show-loading
- - 创建新实体时使用FocusModal
form-focusmodal-create - - 编辑现有实体时使用Drawer
form-drawer-edit - - 执行变更期间,始终禁用操作按钮(disabled={mutation.isPending})
form-disable-pending - - 在提交按钮上展示加载状态(isLoading={mutation.isPending})
form-show-loading
6. Selection Patterns (MEDIUM)
6. 选择模式(中)
- - Use Select component for 2-10 options (statuses, types, etc.)
select-small-datasets - - Use DataTable with FocusModal for large datasets (products, categories, etc.)
select-large-datasets - - Must pass search configuration to useDataTable to avoid "search not enabled" error
select-search-config
- - 选项数量为2-10个时使用Select组件(如状态、类型等)
select-small-datasets - - 大型数据集(如产品、分类等)使用DataTable搭配FocusModal
select-large-datasets - - 必须为useDataTable配置搜索功能,避免出现“search not enabled”错误
select-search-config
Critical Data Loading Pattern
关键数据加载模式
ALWAYS follow this pattern - never load display data conditionally:
tsx
// ✅ CORRECT - Separate queries with proper responsibilities
const RelatedProductsWidget = ({ data: product }) => {
const [modalOpen, setModalOpen] = useState(false)
// Display query - loads on mount
const { data: displayProducts } = useQuery({
queryFn: () => fetchSelectedProducts(selectedIds),
queryKey: ["related-products-display", product.id],
// No 'enabled' condition - loads immediately
})
// Modal query - loads when needed
const { data: modalProducts } = useQuery({
queryFn: () => sdk.admin.product.list({ limit: 10, offset: 0 }),
queryKey: ["products-selection"],
enabled: modalOpen, // OK for modal-only data
})
// Mutation with proper invalidation
const updateProduct = useMutation({
mutationFn: updateFunction,
onSuccess: () => {
// Invalidate display data query to refresh UI
queryClient.invalidateQueries({ queryKey: ["related-products-display", product.id] })
// Also invalidate the entity query
queryClient.invalidateQueries({ queryKey: ["product", product.id] })
// Note: No need to invalidate modal selection query
},
})
return (
<Container>
{/* Display uses displayProducts */}
{displayProducts?.map(p => <div key={p.id}>{p.title}</div>)}
<FocusModal open={modalOpen} onOpenChange={setModalOpen}>
{/* Modal uses modalProducts */}
</FocusModal>
</Container>
)
}
// ❌ WRONG - Single query with conditional loading
const BrokenWidget = ({ data: product }) => {
const [modalOpen, setModalOpen] = useState(false)
const { data } = useQuery({
queryFn: () => sdk.admin.product.list(),
enabled: modalOpen, // ❌ Display breaks on page refresh!
})
// Trying to display from modal query
const displayItems = data?.filter(item => ids.includes(item.id)) // No data until modal opens
return <div>{displayItems?.map(...)}</div> // Empty on mount!
}Why this matters:
- On page refresh, modal is closed, so conditional query doesn't run
- User sees empty state instead of their data
- Display depends on modal interaction (broken UX)
请始终遵循以下模式 - 绝不要条件性加载展示数据:
tsx
// ✅ 正确 - 分离查询,明确职责
const RelatedProductsWidget = ({ data: product }) => {
const [modalOpen, setModalOpen] = useState(false)
// 展示数据查询 - 组件挂载时加载
const { data: displayProducts } = useQuery({
queryFn: () => fetchSelectedProducts(selectedIds),
queryKey: ["related-products-display", product.id],
// 无'enabled'条件 - 立即加载
})
// 模态框数据查询 - 按需加载
const { data: modalProducts } = useQuery({
queryFn: () => sdk.admin.product.list({ limit: 10, offset: 0 }),
queryKey: ["products-selection"],
enabled: modalOpen, // 仅模态框数据可使用条件加载
})
// 带正确失效策略的变更操作
const updateProduct = useMutation({
mutationFn: updateFunction,
onSuccess: () => {
// 使展示数据查询失效以刷新UI
queryClient.invalidateQueries({ queryKey: ["related-products-display", product.id] })
// 同时使实体查询失效
queryClient.invalidateQueries({ queryKey: ["product", product.id] })
// 注意:无需使模态框选择数据查询失效
},
})
return (
<Container>
{/* 展示区域使用displayProducts */}
{displayProducts?.map(p => <div key={p.id}>{p.title}</div>)}
<FocusModal open={modalOpen} onOpenChange={setModalOpen}>
{/* 模态框使用modalProducts */}
</FocusModal>
</Container>
)
}
// ❌ 错误 - 使用单个查询同时处理展示和模态框数据
const BrokenWidget = ({ data: product }) => {
const [modalOpen, setModalOpen] = useState(false)
const { data } = useQuery({
queryFn: () => sdk.admin.product.list(),
enabled: modalOpen, // ❌ 页面刷新时展示功能失效!
})
// 尝试从模态框查询中获取展示数据
const displayItems = data?.filter(item => ids.includes(item.id)) // 模态框未打开时无数据
return <div>{displayItems?.map(...)}</div> // 挂载时为空!
}该模式的重要性:
- 页面刷新时,模态框处于关闭状态,条件性查询不会执行
- 用户会看到空状态而非数据
- 数据展示依赖模态框交互(用户体验极差)
Common Mistakes Checklist
常见错误检查清单
Before implementing, verify you're NOT doing these:
Data Loading:
- Loading display data conditionally based on modal/UI state
- Using a single query for both display and modal
- Forgetting to invalidate display queries after mutations
- Not handling loading states (showing empty instead of spinner)
- pnpm users: Not installing @tanstack/react-query before coding
Design System:
- Using hardcoded colors instead of semantic classes
- Forgetting size="small" on buttons in widgets
- Not using px-6 py-4 for section padding
- Using raw HTML elements instead of Medusa UI components
Data Display:
- CRITICAL: Dividing prices by 100 when displaying (prices are stored as-is: $49.99 = 49.99, NOT in cents)
Typography:
- Using plain span/p tags instead of Text component
- Not using weight="plus" for labels
- Not using text-ui-fg-subtle for descriptions
- Using Heading in small widget sections
Forms:
- Using Drawer for creating (should use FocusModal)
- Using FocusModal for editing (should use Drawer)
- Not disabling buttons during mutations
- Not showing loading state on submit
Selection:
- Using DataTable for <10 items (overkill)
- Using Select for >10 items (poor UX)
- Not configuring search in useDataTable (causes error)
实现前,请确认你未进行以下操作:
数据加载:
- 根据模态框/UI状态条件性加载展示数据
- 使用单个查询同时处理展示和模态框数据
- 执行变更后忘记使展示数据查询失效
- 未处理加载状态(展示空状态而非加载动画)
- pnpm用户:编码前未安装@tanstack/react-query
设计系统:
- 使用硬编码颜色而非语义化类
- 小组件中的按钮未设置size="small"
- 区块内边距未使用px-6 py-4
- 使用原生HTML元素而非Medusa UI组件
数据展示:
- 关键错误:展示价格时除以100(价格按实际值存储:$49.99 = 49.99,而非以分为单位)
排版:
- 使用普通span/p标签而非Text组件
- 标签未使用weight="plus"
- 描述文本未使用text-ui-fg-subtle
- 在小组件的小型区块中使用Heading组件
表单:
- 创建时使用Drawer(应使用FocusModal)
- 编辑时使用FocusModal(应使用Drawer)
- 执行变更期间未禁用按钮
- 提交按钮未展示加载状态
选择功能:
- 选项数量<10时使用DataTable(过度设计)
- 选项数量>10时使用Select(用户体验差)
- useDataTable未配置搜索功能(会导致错误)
Reference Files Available
可用参考文件
Load these for detailed patterns:
references/data-loading.md - useQuery/useMutation patterns, cache invalidation
references/forms.md - FocusModal/Drawer patterns, validation
references/table-selection.md - Complete DataTable selection pattern
references/display-patterns.md - Lists, tables, cards for entities
references/typography.md - Text component patterns
references/navigation.md - Link, useNavigate, useParams patternsEach reference contains:
- Step-by-step implementation guides
- Correct vs incorrect code examples
- Common mistakes and solutions
- Complete working examples
加载以下文件获取详细实现模式:
references/data-loading.md - useQuery/useMutation模式、缓存失效
references/forms.md - FocusModal/Drawer模式、验证
references/table-selection.md - 完整的DataTable选择模式
references/display-patterns.md - 实体的列表、表格、卡片展示模式
references/typography.md - Text组件使用模式
references/navigation.md - Link, useNavigate, useParams使用模式每个参考文件包含:
- 分步实现指南
- 正确与错误的代码示例对比
- 常见错误及解决方案
- 完整可运行示例
Integration with Backend
与后端的集成
Admin UI connects to backend API routes:
tsx
// Fetch from custom backend route
const { data } = useQuery({
queryKey: ["reviews", product.id],
queryFn: () => sdk.client.fetch(`/admin/products/${product.id}/reviews`),
})
// Mutation to custom backend route
const createReview = useMutation({
mutationFn: (data) => sdk.client.fetch("/admin/reviews", {
method: "POST",
body: data
}),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["reviews", product.id] })
toast.success("Review created")
},
})For implementing backend API routes, load the skill.
building-with-medusaAdmin UI通过以下方式连接到后端API路由:
tsx
// 从自定义后端路由获取数据
const { data } = useQuery({
queryKey: ["reviews", product.id],
queryFn: () => sdk.client.fetch(`/admin/products/${product.id}/reviews`),
})
// 调用自定义后端路由执行变更
const createReview = useMutation({
mutationFn: (data) => sdk.client.fetch("/admin/reviews", {
method: "POST",
body: data
}),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["reviews", product.id] })
toast.success("Review created")
},
})如需实现后端API路由,请加载技能。
building-with-medusaWidget vs UI Route
小组件 vs UI路由
Widgets extend existing admin pages:
tsx
// src/admin/widgets/custom-widget.tsx
import { defineWidgetConfig } from "@medusajs/admin-sdk"
import { DetailWidgetProps } from "@medusajs/framework/types"
const MyWidget = ({ data }: DetailWidgetProps<HttpTypes.AdminProduct>) => {
return <Container>Widget content</Container>
}
export const config = defineWidgetConfig({
zone: "product.details.after",
})
export default MyWidgetUI Routes create new admin pages:
tsx
// src/admin/routes/custom-page/page.tsx
import { defineRouteConfig } from "@medusajs/admin-sdk"
const CustomPage = () => {
return <div>Page content</div>
}
export const config = defineRouteConfig({
label: "Custom Page",
})
export default CustomPage小组件用于扩展现有Admin页面:
tsx
// src/admin/widgets/custom-widget.tsx
import { defineWidgetConfig } from "@medusajs/admin-sdk"
import { DetailWidgetProps } from "@medusajs/framework/types"
const MyWidget = ({ data }: DetailWidgetProps<HttpTypes.AdminProduct>) => {
return <Container>Widget content</Container>
}
export const config = defineWidgetConfig({
zone: "product.details.after",
})
export default MyWidgetUI路由用于创建新的Admin页面:
tsx
// src/admin/routes/custom-page/page.tsx
import { defineRouteConfig } from "@medusajs/admin-sdk"
const CustomPage = () => {
return <div>Page content</div>
}
export const config = defineRouteConfig({
label: "Custom Page",
})
export default CustomPageCommon Issues & Solutions
常见问题与解决方案
"Cannot find module" errors (pnpm users):
- Install peer dependencies BEFORE coding
- Use exact versions from dashboard
"No QueryClient set" error:
- pnpm: Install @tanstack/react-query
- npm/yarn: Remove incorrectly installed package
"DataTable.Search not enabled":
- Must pass search configuration to useDataTable
Widget not refreshing:
- Invalidate display queries, not just modal queries
- Include all dependencies in query keys
Display empty on refresh:
- Display query has conditional based on UI state
enabled - Remove condition - display data must load on mount
"Cannot find module"错误(pnpm用户):
- 编码前安装对等依赖
- 使用仪表盘中的精确版本
"No QueryClient set"错误:
- pnpm用户:安装@tanstack/react-query
- npm/yarn用户:移除错误安装的该包
"DataTable.Search not enabled"错误:
- 必须为useDataTable配置搜索功能
小组件未刷新:
- 使展示数据的查询失效,而非仅使模态框查询失效
- 查询键中包含所有依赖项
页面刷新时展示为空:
- 展示数据的查询基于UI状态设置了条件性
enabled - 移除该条件 - 展示数据必须在组件挂载时加载
Next Steps - Testing Your Implementation
后续步骤 - 测试你的实现
After successfully implementing a feature, always provide these next steps to the user:
成功实现功能后,请始终向用户提供以下后续步骤:
1. Start the Development Server
1. 启动开发服务器
If the server isn't already running, start it:
bash
npm run dev # or pnpm dev / yarn dev如果服务器未运行,请启动:
bash
npm run dev # 或 pnpm dev / yarn dev2. Access the Admin Dashboard
2. 访问Admin仪表盘
Open your browser and navigate to:
- Admin Dashboard: http://localhost:9000/app
Log in with your admin credentials.
3. Navigate to Your Custom UI
3. 导航至你的自定义UI
For Widgets:
Navigate to the page where your widget is displayed. Common widget zones:
- Product widgets: Go to Products → Select a product → Your widget appears in the zone you configured (e.g., )
product.details.after - Order widgets: Go to Orders → Select an order → Your widget appears in the configured zone
- Customer widgets: Go to Customers → Select a customer → Your widget appears in the configured zone
For UI Routes (Custom Pages):
- Look for your custom page in the admin sidebar/navigation (based on the you configured)
label - Or navigate directly to:
http://localhost:9000/app/[your-route-path]
针对小组件:
导航至小组件所在的页面。常见小组件区域:
- 产品小组件: 进入产品页面 → 选择一个产品 → 你开发的小组件会显示在配置的区域(如)
product.details.after - 订单小组件: 进入订单页面 → 选择一个订单 → 你开发的小组件会显示在配置的区域
- 客户小组件: 进入客户页面 → 选择一个客户 → 你开发的小组件会显示在配置的区域
针对UI路由(自定义页面):
- 在Admin侧边栏/导航中查找你配置的自定义页面(基于你设置的)
label - 或直接导航至:
http://localhost:9000/app/[your-route-path]
4. Test Functionality
4. 测试功能
Depending on what was implemented, test:
- Forms: Try creating/editing entities, verify validation and error messages
- Tables: Test pagination, search, sorting, and row selection
- Data display: Verify data loads correctly and refreshes after mutations
- Modals: Open FocusModal/Drawer, test form submission, verify data updates
- Navigation: Click links and verify routing works correctly
根据实现的功能进行测试:
- 表单: 尝试创建/编辑实体,验证验证规则和错误提示
- 表格: 测试分页、搜索、排序和行选择功能
- 数据展示: 验证数据是否正确加载,执行变更后是否刷新
- 模态框: 打开FocusModal/Drawer,测试表单提交,验证数据是否更新
- 导航: 点击链接,验证路由是否正常工作
Format for Presenting Next Steps
后续步骤的展示格式
Always present next steps in a clear, actionable format after implementation:
markdown
undefined实现完成后,请始终以清晰、可操作的格式提供后续步骤:
markdown
undefinedImplementation Complete
实现完成
The [feature name] has been successfully implemented. Here's how to see it:
[功能名称]已成功实现。查看方式如下:
Start the Development Server
启动开发服务器
[command based on package manager]
[基于包管理器的命令]
Access the Admin Dashboard
访问Admin仪表盘
Open http://localhost:9000/app in your browser and log in.
View Your Custom UI
查看你的自定义UI
For Widgets:
- Navigate to [specific admin page, e.g., "Products"]
- Select [an entity, e.g., "any product"]
- Scroll to [zone location, e.g., "the bottom of the page"]
- You'll see your "[widget name]" widget
For UI Routes:
- Look for "[page label]" in the admin navigation
- Or navigate directly to http://localhost:9000/app/[route-path]
针对小组件:
- 导航至[具体Admin页面,如“产品页面”]
- 选择[一个实体,如“任意产品”]
- 滚动至[区域位置,如“页面底部”]
- 你将看到“[小组件名称]”小组件
针对UI路由:
- 在Admin导航中查找“[页面标签]”
- 或直接导航至http://localhost:9000/app/[route-path]
What to Test
测试内容
- [Specific test case 1]
- [Specific test case 2]
- [Specific test case 3]
undefined- [具体测试用例1]
- [具体测试用例2]
- [具体测试用例3]
undefined