4.2 KiB
name, description
| name | description |
|---|---|
| create-crud-page | Scaffold a CRUD list/table page module in the gpustack-ui monorepo. Use when creating a new page module, building a list/table page, adding a create/edit drawer, or setting up the components/config/forms/hooks/services structure for a feature. |
Create a CRUD Table Page
Inputs (do this first)
-
The argument passed to this skill is the module name (e.g.
/create-crud-page api-keys→ moduleapi-keys). If no name was given, ask for it. -
Always ask the user for the API documentation before generating any code, even if a module name was provided:
Where is the API documentation for this module? (OpenAPI/Swagger URL, schema file path, or an interface description)
-
Wait for the answer, then read/fetch it. Derive
config/types.ts(FormData,ListItem), theservicesrequest hooks, and form fields from that schema. Do not guess field names or endpoints — if the doc is missing details, ask. -
Also ask which form layout to scaffold:
Should the form use tabs? (1) a plain form without tabs, or (2) a tabbed form
Choose the form structure in section 3 accordingly. Default to no tabs unless the user picks tabs or the schema clearly has many grouped sections.
Before anything: reuse common components, hooks, and utils from @gpustack/core-ui whenever possible.
Reference implementation for sections below: src/pages/model-routes.
Module structure
Create the module under src/pages/{module}:
{module}
├── components
├── config
├── forms
├── hooks
├── index.tsx
└── services
1. components
Module-specific components.
- The create/edit form component is named
add-xxx-modal.tsx(repo convention — keep the-modalsuffix even though it is built withFormDrawer). - Use
FormDrawerfrom@gpustack/core-ui. - If a table cell's render logic/structure is complex, extract it into
xxx-cell.tsx.
2. config
config
├── index.ts # static configs & constants
└── types.ts # TypeScript types
Naming: form types → FormData; table list item types → ListItem.
3. forms
Main form component goes in forms/index.tsx.
- Complex interactions (Form.Item split across components): create a dedicated Form Context and wrap with
FormContext.Provider. - Tab-based forms: use
ScrollSpyTabsfrom@gpustack/core-ui, wrapping theFormorFormContext.Provider. Do not use tabs unless necessary. - Required-field validation: use
getRuleMessagefor standardinput/select. - For cascading selectors and async race protection, follow the form-patterns skill.
4. hooks
- Table columns →
use-xxx-columns.tsx. - Open/close hooks for
add-xxx-modal.tsx→use-create-xxx.ts.
5. index.tsx (list page entry)
- Data fetching:
useTableFetchfrom@gpustack/core-ui. - Data display:
- Standard table → Ant Design
Table. Ref:src/pages/users/index.tsx. - Expandable/collapsible rows →
Tablefrom@gpustack/core-ui. Ref:src/pages/model-routes/index.tsx. - Card-style lists → use
InfiniteScrollerProvider. Ref:src/pages/backends/index.tsx.
- Standard table → Ant Design
6. services
request is injected via a provider — do not create a centralized apis directory like in gpustack-ui. Define request hooks directly in services.
- Use
useRequestfrom@gpustack/core-ui, oruseQueryData(same underlying method). - Ref:
src/pages/gpu-service/storage-types/services/use-create-storage-type.ts.
7. Empty data
- Page table lists →
NoResult. - Simple (non-page) tables →
Emptywithimage={Empty.PRESENTED_IMAGE_SIMPLE}.
Common UI conventions
- Drawer/Modal open/close: use
useBodyScrollfrom@gpustack/core-ui. Ref:src/pages/model-routes/hooks/use-create-route.ts. - Status display (success/failed/processing/warning): use
StatusTag. Ref:src/pages/llmodels/components/table-list.tsx. - Permission-gated visibility: use
Access/useAccess. Ref:src/pages/access/index.tsx. - Styles: avoid
styled-componentsfor complex/large styling. PrefercreateStylesfor component-scoped dynamic styles, CSS Modules (xxx.module.less) for static structured styles.