building-admin-dashboard-customizations

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Medusa 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
    references/data-loading.md
    first
  • Building forms/modals? → MUST load
    references/forms.md
    first
  • Displaying data in tables/lists? → MUST load
    references/display-patterns.md
    first
  • Selecting from large datasets? → MUST load
    references/table-selection.md
    first
  • Adding navigation? → MUST load
    references/navigation.md
    first
  • Styling components? → MUST load
    references/typography.md
    first
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
undefined

Find 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

按优先级划分的规则类别

PriorityCategoryImpactPrefix
1Data LoadingCRITICAL
data-
2Design SystemCRITICAL
design-
3Data DisplayHIGH (includes CRITICAL price rule)
display-
4TypographyHIGH
typo-
5Forms & ModalsMEDIUM
form-
6Selection PatternsMEDIUM
select-
优先级类别影响前缀
1数据加载关键
data-
2设计系统关键
design-
3数据展示高(包含关键价格规则)
display-
4排版
typo-
5表单与模态框
form-
6选择模式
select-

Quick Reference

快速参考

1. Data Loading (CRITICAL)

1. 数据加载(关键)

  • data-display-on-mount
    - Display queries MUST load on mount (no enabled condition based on UI state)
  • data-separate-queries
    - Separate display queries from modal/form queries
  • data-invalidate-display
    - Invalidate display queries after mutations, not just modal queries
  • data-loading-states
    - Always show loading states (Spinner), not empty states
  • data-pnpm-install-first
    - pnpm users MUST install @tanstack/react-query BEFORE coding
  • data-display-on-mount
    - 展示数据的查询必须在组件挂载时加载(不能基于UI状态设置enabled条件)
  • data-separate-queries
    - 将展示数据的查询与模态框/表单的查询分离
  • data-invalidate-display
    - 执行变更后,需使展示数据的查询失效,而非仅使模态框查询失效
  • data-loading-states
    - 始终展示加载状态(Spinner),而非空状态
  • data-pnpm-install-first
    - pnpm用户必须在编码前安装@tanstack/react-query

2. Design System (CRITICAL)

2. 设计系统(关键)

  • design-semantic-colors
    - Always use semantic color classes (bg-ui-bg-base, text-ui-fg-subtle), never hardcoded
  • design-spacing
    - Use px-6 py-4 for section padding, gap-2 for lists, gap-3 for items
  • design-button-size
    - Always use size="small" for buttons in widgets and tables
  • design-medusa-components
    - Always use Medusa UI components (Container, Button, Text), not raw HTML
  • design-semantic-colors
    - 始终使用语义化颜色类(bg-ui-bg-base, text-ui-fg-subtle),绝不要硬编码颜色
  • design-spacing
    - 区块内边距使用px-6 py-4,列表使用gap-2,列表项使用gap-3
  • design-button-size
    - 在小组件和表格中,按钮始终使用size="small"
  • design-medusa-components
    - 始终使用Medusa UI组件(Container, Button, Text),而非原生HTML元素

3. Data Display (HIGH)

3. 数据展示(高)

  • display-price-format
    - 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

4. Typography (HIGH)

4. 排版(高)

  • typo-text-component
    - Always use Text component from @medusajs/ui, never plain span/p tags
  • typo-labels
    - Use
    <Text size="small" leading="compact" weight="plus">
    for labels/headings
  • typo-descriptions
    - Use
    <Text size="small" leading="compact" className="text-ui-fg-subtle">
    for descriptions
  • typo-no-heading-widgets
    - Never use Heading for small sections in widgets (use Text instead)
  • typo-text-component
    - 始终使用@medusajs/ui中的Text组件,而非普通的span/p标签
  • typo-labels
    - 标签/标题使用
    <Text size="small" leading="compact" weight="plus">
  • typo-descriptions
    - 描述文本使用
    <Text size="small" leading="compact" className="text-ui-fg-subtle">
  • typo-no-heading-widgets
    - 小组件中的小型区块绝不要使用Heading组件(改用Text组件)

5. Forms & Modals (MEDIUM)

5. 表单与模态框(中)

  • form-focusmodal-create
    - Use FocusModal for creating new entities
  • form-drawer-edit
    - Use Drawer for editing existing entities
  • form-disable-pending
    - Always disable actions during mutations (disabled={mutation.isPending})
  • form-show-loading
    - Show loading state on submit button (isLoading={mutation.isPending})
  • form-focusmodal-create
    - 创建新实体时使用FocusModal
  • form-drawer-edit
    - 编辑现有实体时使用Drawer
  • form-disable-pending
    - 执行变更期间,始终禁用操作按钮(disabled={mutation.isPending})
  • form-show-loading
    - 在提交按钮上展示加载状态(isLoading={mutation.isPending})

6. Selection Patterns (MEDIUM)

6. 选择模式(中)

  • select-small-datasets
    - Use Select component for 2-10 options (statuses, types, etc.)
  • select-large-datasets
    - Use DataTable with FocusModal for large datasets (products, categories, etc.)
  • select-search-config
    - Must pass search configuration to useDataTable to avoid "search not enabled" error
  • select-small-datasets
    - 选项数量为2-10个时使用Select组件(如状态、类型等)
  • select-large-datasets
    - 大型数据集(如产品、分类等)使用DataTable搭配FocusModal
  • select-search-config
    - 必须为useDataTable配置搜索功能,避免出现“search not enabled”错误

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 patterns
Each 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
building-with-medusa
skill.
Admin 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-medusa
技能。

Widget 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 MyWidget
UI 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 MyWidget
UI路由用于创建新的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 CustomPage

Common 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
    enabled
    based on UI state
  • 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 dev

2. Access the Admin Dashboard

2. 访问Admin仪表盘

Open your browser and navigate to:
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
    label
    you configured)
  • 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
undefined

Implementation 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:
  1. Navigate to [specific admin page, e.g., "Products"]
  2. Select [an entity, e.g., "any product"]
  3. Scroll to [zone location, e.g., "the bottom of the page"]
  4. You'll see your "[widget name]" widget
For UI Routes:
  1. Look for "[page label]" in the admin navigation
  2. Or navigate directly to http://localhost:9000/app/[route-path]
针对小组件:
  1. 导航至[具体Admin页面,如“产品页面”]
  2. 选择[一个实体,如“任意产品”]
  3. 滚动至[区域位置,如“页面底部”]
  4. 你将看到“[小组件名称]”小组件
针对UI路由:
  1. 在Admin导航中查找“[页面标签]”
  2. 或直接导航至http://localhost:9000/app/[route-path]

What to Test

测试内容

  1. [Specific test case 1]
  2. [Specific test case 2]
  3. [Specific test case 3]
undefined
  1. [具体测试用例1]
  2. [具体测试用例2]
  3. [具体测试用例3]
undefined