agentleFS
gpustackgpustack/gpustack-ui/.claude/skills/create-crud-page/SKILL.md

create-crud-page

Skill100 starsChanged 38 days agoApache-2.0View on GitHub

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.

The file

We split this skill into the rules it gives an agent

12 rules. About 0 are common, 0 are distinctive, and 12 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈0

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 12

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Wait for the answer, then read/fetch it.

    line 15
  2. Very specific:

    Before anything: reuse common components, hooks, and utils from @gpustack/core-ui whenever possible.

    line 25
  3. Very specific:

    Create the module under src/pages/{module}:

    line 31
  4. Very specific:

    Use FormDrawer from @gpustack/core-ui.

    line 48
  5. Very specific:

    If a table cell's render logic/structure is complex, extract it into xxx-cell.tsx.

    line 49
  6. Very specific:

    Tab-based forms: use ScrollSpyTabs from @gpustack/core-ui, wrapping the Form or FormContext.Provider.

    line 66
  7. Very specific:

    Required-field validation: use getRuleMessage for standard input/select.

    line 67
  8. Very specific:

    Use useRequest from @gpustack/core-ui, or useQueryData (same underlying method).

    line 87
  9. Very specific:

    Drawer/Modal open/close: use useBodyScroll from @gpustack/core-ui.

    line 97
  10. Very specific:

    Permission-gated visibility: use Access / useAccess. Ref: src/pages/access/index.tsx.

    line 99
  11. Very specific:

    Styles: avoid styled-components for complex/large styling.

    line 100
  12. Very specific:

    Use StatusTag from @gpustack/core-ui for status display.

    line 104

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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 → module api-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), the services request 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 -modal suffix even though it is built with FormDrawer).
  • Use FormDrawer from @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 ScrollSpyTabs from @gpustack/core-ui, wrapping the Form or FormContext.Provider. Do not use tabs unless necessary.
  • Required-field validation: use getRuleMessage for standard input/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: useTableFetch from @gpustack/core-ui.
  • Data display:
    • Standard table → Ant Design Table. Ref: src/pages/users/index.tsx.
    • Expandable/collapsible rows → Table from @gpustack/core-ui. Ref: src/pages/model-routes/index.tsx.
    • Card-style lists → use InfiniteScrollerProvider. Ref: src/pages/backends/index.tsx.

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 useRequest from @gpustack/core-ui, or useQueryData (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 → Empty with image={Empty.PRESENTED_IMAGE_SIMPLE}.

Common UI conventions

  • Drawer/Modal open/close: use useBodyScroll from @gpustack/core-ui. Ref: src/pages/model-routes/hooks/use-create-route.ts.
  • Status display (success/failed/processing/warning): use StatusTag, never Tag from antd directly. See Status display below. Ref: src/pages/llmodels/components/table-list.tsx.
  • Permission-gated visibility: use Access / useAccess. Ref: src/pages/access/index.tsx.
  • Styles: avoid styled-components for complex/large styling. Prefer createStyles for component-scoped dynamic styles, CSS Modules (xxx.module.less) for static structured styles.

Status display

Use StatusTag from @gpustack/core-ui for status display. Do not use Tag from antd directly.

  1. Define the mapping from business status values to UI status values in the module's config/index.ts:
import { StatusMaps } from '@/config';
import { StatusType } from '@/config/types';

export const XxxStatusValueMap = {
  Running: 'running',
  Pending: 'pending',
  Failed: 'failed'
};

export const XxxStatusLabelMap: Record<string, string> = {
  [XxxStatusValueMap.Running]: 'Running',
  [XxxStatusValueMap.Pending]: 'Pending',
  [XxxStatusValueMap.Failed]: 'Failed'
};

export const status: Record<string, StatusType> = {
  [XxxStatusValueMap.Running]: StatusMaps.success,
  [XxxStatusValueMap.Pending]: StatusMaps.transitioning,
  [XxxStatusValueMap.Failed]: StatusMaps.error
};
  1. In table columns, pass only the UI status value and display text required by StatusTag:
<StatusTag
  statusValue={{
    status: status[value],
    text: XxxStatusLabelMap[value] || value,
    message: record.state_message
  }}
/>

statusValue.status must be a value mapped from StatusMaps (success, transitioning, warning, error, inactive). Do not pass business status values such as running or pending directly.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.