一键导入
manage-bui-component-story
Create or Update BUI Component Story (project)
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Create or Update BUI Component Story (project)
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Bump version to next alpha and update dependencies after release.
Create a release branch, tag, and GitHub release for Backend.AI WebUI.
Enhance React component documentation with JSDoc, improved Storybook stories, and autodoc configuration.
Update React components with JSDoc and enhanced Storybook stories with autodoc functionality.
Generate Relay-based Nodes components with BAITable integration following established patterns (BAIUserNodes, SessionNodes, BAISchedulingHistoryNodes, BAIRouteNodes). Automatically creates component file with GraphQL fragment, type definitions, column configurations, and customization patterns. Minimal user input required - just provide GraphQL type name and the skill generates a complete starting template.
Use when creating a new React component under `react/src/` or `packages/backend.ai-ui/src/`, or refactoring one's file layout, import order, `'use memo'` placement, hook call order, or prop interface. Covers naming conventions (`BAI*`, `*Nodes`, `*Page`) and React 19 rules.
| name | manage-bui-component-story |
| description | Create or Update BUI Component Story (project) |
| model | sonnet |
| disable-model-invocation | true |
Generate or update Storybook story files for Backend.AI UI (BUI) components.
/manage-bui-component-story <component-names...>
component-names: One or more component names (e.g., BAIButton BAICard BAIModal)
BAIButtonpackages/backend.ai-ui/src/components/BAIButton.tsx# Single component
/manage-bui-component-story BAIButton
# Multiple components (batch)
/manage-bui-component-story BAIButton BAICard BAIModal
# With full path
/manage-bui-component-story packages/backend.ai-ui/src/components/BAIButton.tsx
For each component:
packages/backend.ai-ui/src/components/.stories.tsx file existsWhen the story file doesn't exist:
.stories.tsx following CSF 3 formatargs and comparison stories with renderIMPORTANT: Stories should ONLY demonstrate BAI-specific features, NOT Ant Design's original functionality.
When the story file already exists:
+ Added props: Add new argTypes for props not in story- Removed props: Remove argTypes for props no longer in component~ Changed props: Update argTypes for props with type changes// Component has new prop 'loading'
// → ADD argType:
loading: {
control: { type: 'boolean' },
description: 'Shows loading state',
table: {
type: { summary: 'boolean' },
defaultValue: { summary: 'false' },
},
},
// Component removed prop 'oldProp'
// → REMOVE from argTypes
// Component changed prop type
// status: 'default' | 'success' → 'default' | 'success' | 'warning'
// → UPDATE argType:
status: {
control: { type: 'select' },
options: ['default', 'success', 'warning'], // Updated options
// ...
},
// Example: BAIAlert.tsx
export interface BAIAlertProps extends AlertProps {
ghostInfoBg?: boolean; // BAI-specific: NOT in AlertProps
}
// AlertProps (message, type, closable, showIcon, etc.) are NOT BAI-specific
Decision criteria:
Check existing story files' title values to determine the correct category. Use the same category as similar components.
| Category | Components | Title Pattern |
|---|---|---|
| Alert | BAIAlert, BAIAlertIconWithTooltip | Alert/[Name] |
| Board | BAIBoardItemTitle | Board/[Name] |
| Button | BAIButton, BAIBackButton, BAIFetchKeyButton | Button/[Name] |
| Card | BAICard | Card/[Name] |
| Filter | BAIPropertyFilter, BAIGraphQLPropertyFilter | Filter/[Name] |
| Flex | BAIFlex | Flex/[Name] |
| Input | DynamicUnitInputNumber, DynamicUnitInputNumberWithSlider | Input/[Name] |
| Link | BAILink | Link/[Name] |
| Modal | BAIModal, BAIConfirmModalWithInput | Modal/[Name] |
| Notification | BAINotificationItem | Notification/[Name] |
| Row | BAIRowWrapWithDividers | Row/[Name] |
| Select | BAISelect | Select/[Name] |
| Statistic | BAIStatistic, BAINumberWithUnit, BAIResourceNumberWithIcon, BAIProgressWithLabel | Statistic/[Name] |
| Tag | BAITag, BooleanTag, BAIDoubleTag | Tag/[Name] |
| Text | BAIText, BAITextHighlighter | Text/[Name] |
| Relay Fragment | (components using GraphQL fragments) | Fragments/[Name] |
If no existing category fits, create a new one following the [Category]/[Name] pattern.
Create the story file at the same location as the component: BAIButton.tsx → BAIButton.stories.tsx
import BAIAlert from './BAIAlert';
import BAIFlex from './BAIFlex';
import type { Meta, StoryObj } from '@storybook/react-vite';
const meta: Meta<typeof BAIAlert> = {
title: 'Components/BAIAlert',
component: BAIAlert,
tags: ['autodocs'],
parameters: {
layout: 'padded',
docs: {
description: {
component: `
**BAIAlert** extends [Ant Design Alert](https://ant.design/components/alert).
## BAI-Specific Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| \`ghostInfoBg\` | \`boolean\` | \`true\` | Info alerts use container background |
For all other props, refer to [Ant Design Alert](https://ant.design/components/alert).
`,
},
},
},
argTypes: {
// BAI-specific props - document fully
ghostInfoBg: {
control: { type: 'boolean' },
description: 'When true, info alerts use container background',
table: {
type: { summary: 'boolean' },
defaultValue: { summary: 'true' },
},
},
},
};
export default meta;
type Story = StoryObj<typeof BAIAlert>;
// Default story: Use args for interactive Controls
export const Default: Story = {
name: 'Basic',
args: {
type: 'info',
message: 'Informational alert with ghost background',
showIcon: true,
ghostInfoBg: true, // BAI-specific prop MUST be included
},
};
// Comparison story: Use render for multiple components
export const GhostInfoBackground: Story = {
render: () => (
<BAIFlex direction="column" gap="md">
<BAIAlert type="info" message="Ghost enabled (default)" ghostInfoBg={true} showIcon />
<BAIAlert type="info" message="Ghost disabled" ghostInfoBg={false} showIcon />
</BAIFlex>
),
};
import { graphql, useLazyLoadQuery } from 'react-relay';
import RelayResolver from '../../tests/RelayResolver';
const QueryResolver = () => {
const { data_node } = useLazyLoadQuery<ComponentStoriesQuery>(
graphql`
query ComponentStoriesQuery {
data_node(id: "test-id") {
...ComponentFragment
}
}
`,
{},
);
return data_node && <ComponentName fragmentRef={data_node} />;
};
export const Default: Story = {
name: 'Basic',
render: () => (
<RelayResolver mockResolvers={{ DataNode: () => ({ field: 'value' }) }}>
<QueryResolver />
</RelayResolver>
),
};
args to enable interactive Controls, MUST include BAI-specific propsrender for layouts with multiple componentsargs should remain visible (not hidden)name: Only use when different from export name (e.g., Default → name: 'Basic')Space component// ❌ BAD: Stories for Ant Design features
export const AllTypes: Story = { ... }; // 'type' is Ant Design prop
export const Closable: Story = { ... }; // 'closable' is Ant Design prop
// GOOD: Only stories for BAI-specific props
export const GhostInfoBackground: Story = {
render: () => (
<BAIFlex direction="column" gap="md">
<BAIAlert type="info" message="Ghost enabled" ghostInfoBg={true} />
<BAIAlert type="info" message="Ghost disabled" ghostInfoBg={false} />
</BAIFlex>
),
};
| Story File | Reference For |
|---|---|
BAIFlex.stories.tsx | Ant Design extension with BAI-specific props |
BAICard.stories.tsx | Ant Design Card extension |
BAIPropertyFilter.stories.tsx | Complex component with interactive stories |
BAIGraphQLPropertyFilter.stories.tsx | BAI-specific component (not extending Ant Design) |
Located in packages/backend.ai-ui/src/components/.
After processing all components, output a summary:
## BUI Story Results
| Component | Action | Path | Status |
|-----------|--------|------|--------|
| BAICard | Created | .../BAICard.stories.tsx | Done |
| BAIModal | Updated | .../BAIModal.stories.tsx | Done |
| BAIFlex | Skipped | .../BAIFlex.stories.tsx | Up-to-date |
### Changes Made
- **BAICard**: Created new story with 3 BAI-specific props
- **BAIModal**: Added `loading` argType, removed `oldProp` argType
cd packages/backend.ai-ui && pnpm run storybooktags: ['autodocs'] for auto-documentationpackages/backend.ai-ui/src/components/