From f3da9e5c3f80804df2133a3f5bb31f99e5a44a90 Mon Sep 17 00:00:00 2001 From: cp3hnu Date: Wed, 26 Feb 2025 11:24:32 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20storybook=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E4=B8=BB=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- react-ui/.storybook/blocks/StoryName.tsx | 19 ++ react-ui/.storybook/main.ts | 2 +- react-ui/.storybook/manager.ts | 6 + react-ui/.storybook/theme.ts | 7 + react-ui/package.json | 4 +- .../{static => public}/mockServiceWorker.js | 0 react-ui/src/components/BasicInfo/index.tsx | 6 + react-ui/src/stories/BasicInfo.stories.tsx | 2 +- .../src/stories/BasicTableInfo.stories.tsx | 2 +- react-ui/src/stories/CodeSelect.stories.tsx | 2 +- .../src/stories/CodeSelectorModal.stories.tsx | 38 +--- react-ui/src/stories/Config.stories.tsx | 2 +- react-ui/src/stories/FormInfo.stories.tsx | 2 +- .../src/stories/FullScreenFrame.stories.tsx | 2 +- react-ui/src/stories/IFramePage.stories.tsx | 2 +- react-ui/src/stories/InfoGroup.stories.tsx | 2 +- react-ui/src/stories/KFEmpty.stories.tsx | 2 +- react-ui/src/stories/KFIcon.stories.tsx | 2 +- react-ui/src/stories/KFModal.stories.tsx | 2 +- react-ui/src/stories/KFRadio.stories.tsx | 2 +- react-ui/src/stories/KFSpin.stories.tsx | 2 +- .../src/stories/MenuIconSelector.stories.tsx | 2 +- react-ui/src/stories/PageTitle.stories.tsx | 2 +- .../src/stories/ParameterInput.stories.tsx | 2 +- .../src/stories/ResourceSelect.stories.tsx | 2 +- .../src/stories/ResourceSelectorModal.mdx | 26 ++- .../stories/ResourceSelectorModal.stories.tsx | 197 ++++++------------ react-ui/src/stories/SubAreaTitle.stories.tsx | 2 +- react-ui/static/favicon.ico | Bin 4286 -> 0 bytes 29 files changed, 145 insertions(+), 196 deletions(-) create mode 100644 react-ui/.storybook/blocks/StoryName.tsx create mode 100644 react-ui/.storybook/manager.ts create mode 100644 react-ui/.storybook/theme.ts rename react-ui/{static => public}/mockServiceWorker.js (100%) delete mode 100644 react-ui/static/favicon.ico diff --git a/react-ui/.storybook/blocks/StoryName.tsx b/react-ui/.storybook/blocks/StoryName.tsx new file mode 100644 index 00000000..074c73cb --- /dev/null +++ b/react-ui/.storybook/blocks/StoryName.tsx @@ -0,0 +1,19 @@ +import { Of, useOf } from '@storybook/blocks'; + +/** + * A block that displays the story name or title from the of prop + * - if a story reference is passed, it renders the story name + * - if a meta reference is passed, it renders the stories' title + * - if nothing is passed, it defaults to the primary story + */ +export const StoryName = ({ of }: { of?: Of }) => { + const resolvedOf = useOf(of || 'story', ['story', 'meta']); + switch (resolvedOf.type) { + case 'story': { + return

{resolvedOf.story.name}

; + } + case 'meta': { + return

{resolvedOf.preparedMeta.title}

; + } + } +}; diff --git a/react-ui/.storybook/main.ts b/react-ui/.storybook/main.ts index 54824837..820a0eeb 100644 --- a/react-ui/.storybook/main.ts +++ b/react-ui/.storybook/main.ts @@ -16,7 +16,7 @@ const config: StorybookConfig = { name: '@storybook/react-webpack5', options: {}, }, - staticDirs: ['../static'], + staticDirs: ['../public'], docs: { defaultName: 'Documentation', }, diff --git a/react-ui/.storybook/manager.ts b/react-ui/.storybook/manager.ts new file mode 100644 index 00000000..baf80b25 --- /dev/null +++ b/react-ui/.storybook/manager.ts @@ -0,0 +1,6 @@ +import { addons } from '@storybook/manager-api'; +import theme from './theme'; + +addons.setConfig({ + theme: theme, +}); diff --git a/react-ui/.storybook/theme.ts b/react-ui/.storybook/theme.ts new file mode 100644 index 00000000..7b624111 --- /dev/null +++ b/react-ui/.storybook/theme.ts @@ -0,0 +1,7 @@ +import { create } from '@storybook/theming'; +export default create({ + base: 'light', + brandTitle: '组件库文档', + brandUrl: 'https://storybook.js.org/docs', + brandTarget: '_blank', +}); diff --git a/react-ui/package.json b/react-ui/package.json index 56a4b735..f2583d6b 100644 --- a/react-ui/package.json +++ b/react-ui/package.json @@ -96,9 +96,11 @@ "@storybook/addon-webpack5-compiler-babel": "~3.0.5", "@storybook/addon-webpack5-compiler-swc": "~2.0.0", "@storybook/blocks": "~8.5.3", + "@storybook/manager-api": "~8.6.0", "@storybook/react": "~8.5.3", "@storybook/react-webpack5": "~8.5.3", "@storybook/test": "~8.5.3", + "@storybook/theming": "~8.6.0", "@testing-library/react": "^14.0.0", "@types/antd": "^1.0.0", "@types/express": "^4.17.14", @@ -166,7 +168,7 @@ }, "msw": { "workerDirectory": [ - "static" + "public" ] } } diff --git a/react-ui/static/mockServiceWorker.js b/react-ui/public/mockServiceWorker.js similarity index 100% rename from react-ui/static/mockServiceWorker.js rename to react-ui/public/mockServiceWorker.js diff --git a/react-ui/src/components/BasicInfo/index.tsx b/react-ui/src/components/BasicInfo/index.tsx index 11eacfde..68622d7c 100644 --- a/react-ui/src/components/BasicInfo/index.tsx +++ b/react-ui/src/components/BasicInfo/index.tsx @@ -24,6 +24,12 @@ export type BasicInfoProps = { /** * 基础信息展示组件,用于展示基础信息,支持一行两列或一行三列,支持数据格式化 + * + * ### usage + * ```tsx + * import { BasicInfo } from '@/components/BasicInfo'; + * + * ``` */ export default function BasicInfo({ datas, diff --git a/react-ui/src/stories/BasicInfo.stories.tsx b/react-ui/src/stories/BasicInfo.stories.tsx index 80a0337c..eddbec12 100644 --- a/react-ui/src/stories/BasicInfo.stories.tsx +++ b/react-ui/src/stories/BasicInfo.stories.tsx @@ -6,7 +6,7 @@ import { Button } from 'antd'; // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export const meta = { - title: 'Components/BasicInfo', + title: 'Components/BasicInfo 基本信息', component: BasicInfo, parameters: { // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout diff --git a/react-ui/src/stories/BasicTableInfo.stories.tsx b/react-ui/src/stories/BasicTableInfo.stories.tsx index 82581f6a..cdde73fc 100644 --- a/react-ui/src/stories/BasicTableInfo.stories.tsx +++ b/react-ui/src/stories/BasicTableInfo.stories.tsx @@ -4,7 +4,7 @@ import * as BasicInfoStories from './BasicInfo.stories'; // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export const meta = { - title: 'Components/BasicTableInfo', + title: 'Components/BasicTableInfo 表格基本信息', component: BasicTableInfo, parameters: { // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout diff --git a/react-ui/src/stories/CodeSelect.stories.tsx b/react-ui/src/stories/CodeSelect.stories.tsx index b5520c96..08520603 100644 --- a/react-ui/src/stories/CodeSelect.stories.tsx +++ b/react-ui/src/stories/CodeSelect.stories.tsx @@ -8,7 +8,7 @@ import { codeListData } from './mockData'; // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export const meta = { - title: 'Components/CodeSelect', + title: 'Components/CodeSelect 代码配置选择器', component: CodeSelect, parameters: { // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout diff --git a/react-ui/src/stories/CodeSelectorModal.stories.tsx b/react-ui/src/stories/CodeSelectorModal.stories.tsx index a042f238..9faae0ae 100644 --- a/react-ui/src/stories/CodeSelectorModal.stories.tsx +++ b/react-ui/src/stories/CodeSelectorModal.stories.tsx @@ -1,6 +1,5 @@ import CodeSelectorModal from '@/components/CodeSelectorModal'; import { openAntdModal } from '@/utils/modal'; -import { useArgs } from '@storybook/preview-api'; import type { Meta, StoryObj } from '@storybook/react'; import { fn } from '@storybook/test'; import { Button } from 'antd'; @@ -9,7 +8,7 @@ import { codeListData } from './mockData'; // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export const meta = { - title: 'Components/CodeSelectorModal', + title: 'Components/CodeSelectorModal 代码选择对话框', component: CodeSelectorModal, parameters: { // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout @@ -39,39 +38,8 @@ export default meta; type Story = StoryObj; // More on writing stories with args: https://storybook.js.org/docs/writing-stories/args -export const Primary: Story = { - args: { - open: false, - }, - render: function Render({ onOk, onCancel, ...args }) { - const [{ open }, updateArgs] = useArgs(); - function onClick() { - updateArgs({ open: true }); - } - function handleOk(res: any) { - updateArgs({ open: false }); - onOk?.(res); - } - - function handleCancel() { - updateArgs({ open: false }); - onCancel?.(); - } - return ( - <> - - - - ); - }, -}; - -/** 通过 `openAntdModal` 函数打开 */ -export const OpenByFunction: Story = { - name: '通过函数的方式打开', +export const Primary: Story = { render: function Render(args) { const handleClick = () => { const { close } = openAntdModal(CodeSelectorModal, { @@ -84,7 +52,7 @@ export const OpenByFunction: Story = { }; return ( ); }, diff --git a/react-ui/src/stories/Config.stories.tsx b/react-ui/src/stories/Config.stories.tsx index 0287d718..5c2a42ce 100644 --- a/react-ui/src/stories/Config.stories.tsx +++ b/react-ui/src/stories/Config.stories.tsx @@ -4,7 +4,7 @@ import * as BasicInfoStories from './BasicInfo.stories'; // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export const meta = { - title: 'Components/ConfigInfo', + title: 'Components/ConfigInfo 配置信息', component: ConfigInfo, parameters: { // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout diff --git a/react-ui/src/stories/FormInfo.stories.tsx b/react-ui/src/stories/FormInfo.stories.tsx index b822427f..8e2d89de 100644 --- a/react-ui/src/stories/FormInfo.stories.tsx +++ b/react-ui/src/stories/FormInfo.stories.tsx @@ -4,7 +4,7 @@ import { Form, Input, Select, Typography } from 'antd'; // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export const meta = { - title: 'Components/FormInfo', + title: 'Components/FormInfo 表单信息', component: FormInfo, parameters: { // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout diff --git a/react-ui/src/stories/FullScreenFrame.stories.tsx b/react-ui/src/stories/FullScreenFrame.stories.tsx index fa334ed1..74dae50a 100644 --- a/react-ui/src/stories/FullScreenFrame.stories.tsx +++ b/react-ui/src/stories/FullScreenFrame.stories.tsx @@ -4,7 +4,7 @@ import { fn } from '@storybook/test'; // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export const meta = { - title: 'Components/FullScreenFrame', + title: 'Components/FullScreenFrame 全屏iframe', component: FullScreenFrame, parameters: { // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout diff --git a/react-ui/src/stories/IFramePage.stories.tsx b/react-ui/src/stories/IFramePage.stories.tsx index 3d1714e8..d5c6725b 100644 --- a/react-ui/src/stories/IFramePage.stories.tsx +++ b/react-ui/src/stories/IFramePage.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export const meta = { - title: 'Components/IFramePage', + title: 'Components/IFramePage iframe页面', component: IFramePage, parameters: { // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout diff --git a/react-ui/src/stories/InfoGroup.stories.tsx b/react-ui/src/stories/InfoGroup.stories.tsx index f3a6def8..3fe86b80 100644 --- a/react-ui/src/stories/InfoGroup.stories.tsx +++ b/react-ui/src/stories/InfoGroup.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export const meta = { - title: 'Components/InfoGroup', + title: 'Components/InfoGroup 信息分组', component: InfoGroup, parameters: { // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout diff --git a/react-ui/src/stories/KFEmpty.stories.tsx b/react-ui/src/stories/KFEmpty.stories.tsx index fef1d5bf..369695be 100644 --- a/react-ui/src/stories/KFEmpty.stories.tsx +++ b/react-ui/src/stories/KFEmpty.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { fn } from '@storybook/test'; // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export const meta = { - title: 'Components/KFEmpty', + title: 'Components/KFEmpty 空状态', component: KFEmpty, parameters: { // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout diff --git a/react-ui/src/stories/KFIcon.stories.tsx b/react-ui/src/stories/KFIcon.stories.tsx index 44cb274e..7367b302 100644 --- a/react-ui/src/stories/KFIcon.stories.tsx +++ b/react-ui/src/stories/KFIcon.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Button } from 'antd'; // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export const meta = { - title: 'Components/KFIcon', + title: 'Components/KFIcon 图标', component: KFIcon, parameters: { // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout diff --git a/react-ui/src/stories/KFModal.stories.tsx b/react-ui/src/stories/KFModal.stories.tsx index 024a2708..054634f2 100644 --- a/react-ui/src/stories/KFModal.stories.tsx +++ b/react-ui/src/stories/KFModal.stories.tsx @@ -8,7 +8,7 @@ import { Button } from 'antd'; // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export const meta = { - title: 'Components/KFModal', + title: 'Components/KFModal 对话框', component: KFModal, parameters: { // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout diff --git a/react-ui/src/stories/KFRadio.stories.tsx b/react-ui/src/stories/KFRadio.stories.tsx index c48c16e9..14bfd07c 100644 --- a/react-ui/src/stories/KFRadio.stories.tsx +++ b/react-ui/src/stories/KFRadio.stories.tsx @@ -5,7 +5,7 @@ import type { Meta, StoryObj } from '@storybook/react'; // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export const meta = { - title: 'Components/KFRadio', + title: 'Components/KFRadio 单选框', component: KFRadio, parameters: { // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout diff --git a/react-ui/src/stories/KFSpin.stories.tsx b/react-ui/src/stories/KFSpin.stories.tsx index 7f3185d2..75f9a872 100644 --- a/react-ui/src/stories/KFSpin.stories.tsx +++ b/react-ui/src/stories/KFSpin.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export const meta = { - title: 'Components/KFSpin', + title: 'Components/KFSpin 加载器', component: KFSpin, parameters: { // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout diff --git a/react-ui/src/stories/MenuIconSelector.stories.tsx b/react-ui/src/stories/MenuIconSelector.stories.tsx index f02fb77c..d89e7a6d 100644 --- a/react-ui/src/stories/MenuIconSelector.stories.tsx +++ b/react-ui/src/stories/MenuIconSelector.stories.tsx @@ -6,7 +6,7 @@ import { Button } from 'antd'; // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export const meta = { - title: 'Components/MenuIconSelector', + title: 'Components/MenuIconSelector 菜单图标选择器', component: MenuIconSelector, parameters: { // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout diff --git a/react-ui/src/stories/PageTitle.stories.tsx b/react-ui/src/stories/PageTitle.stories.tsx index 216591b1..b8eb31c7 100644 --- a/react-ui/src/stories/PageTitle.stories.tsx +++ b/react-ui/src/stories/PageTitle.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export const meta = { - title: 'Components/PageTitle', + title: 'Components/PageTitle 页面标题', component: PageTitle, parameters: { // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout diff --git a/react-ui/src/stories/ParameterInput.stories.tsx b/react-ui/src/stories/ParameterInput.stories.tsx index 9d9525e2..914b6196 100644 --- a/react-ui/src/stories/ParameterInput.stories.tsx +++ b/react-ui/src/stories/ParameterInput.stories.tsx @@ -5,7 +5,7 @@ import { useState } from 'react'; // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export const meta = { - title: 'Components/ParameterInput', + title: 'Components/ParameterInput 参数输入框', component: ParameterInput, parameters: { // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout diff --git a/react-ui/src/stories/ResourceSelect.stories.tsx b/react-ui/src/stories/ResourceSelect.stories.tsx index 28c314e3..93474d7f 100644 --- a/react-ui/src/stories/ResourceSelect.stories.tsx +++ b/react-ui/src/stories/ResourceSelect.stories.tsx @@ -21,7 +21,7 @@ import { // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export const meta = { - title: 'Components/ResourceSelect', + title: 'Components/ResourceSelect 资源选择器', component: ResourceSelect, parameters: { // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout diff --git a/react-ui/src/stories/ResourceSelectorModal.mdx b/react-ui/src/stories/ResourceSelectorModal.mdx index 28702123..f7e0c569 100644 --- a/react-ui/src/stories/ResourceSelectorModal.mdx +++ b/react-ui/src/stories/ResourceSelectorModal.mdx @@ -1,13 +1,22 @@ -import { Meta, Canvas } from '@storybook/blocks'; +import { Meta, Title, Subtitle, Description, Primary, Controls, Stories } from '@storybook/blocks'; import * as ResourceSelectorModalStories from "./ResourceSelectorModal.stories" +import { StoryName } from "../../.storybook/blocks/StoryName" + + + + +<Subtitle /> +<Description /> -<Meta of={ResourceSelectorModalStories} name="Usage" /> - -# Usage +### Usage 推荐通过 `openAntdModal` 函数打开 `ResourceSelectorModal`,打开 -> 处理 -> 关闭,整套代码在同一个地方 ```ts +import { openAntdModal } from '@/utils/modal'; +import ResourceSelectorModal } from '@/components/ResourceSelectorModal'; + +// 打开资源选择对话框 const handleClick = () => { const { close } = openAntdModal(ResourceSelectorModal, { type: ResourceSelectorType.Dataset, @@ -18,6 +27,11 @@ const handleClick = () => { }); ``` - -<Canvas of={ResourceSelectorModalStories.OpenByFunction} /> +### Primary + +<Primary /> + +<Controls /> + +<Stories of={ResourceSelectorModalStories} /> diff --git a/react-ui/src/stories/ResourceSelectorModal.stories.tsx b/react-ui/src/stories/ResourceSelectorModal.stories.tsx index b39cb45e..b43a8e5b 100644 --- a/react-ui/src/stories/ResourceSelectorModal.stories.tsx +++ b/react-ui/src/stories/ResourceSelectorModal.stories.tsx @@ -1,6 +1,5 @@ import ResourceSelectorModal, { ResourceSelectorType } from '@/components/ResourceSelectorModal'; import { openAntdModal } from '@/utils/modal'; -import { useArgs } from '@storybook/preview-api'; import type { Meta, StoryObj } from '@storybook/react'; import { fn } from '@storybook/test'; import { Button } from 'antd'; @@ -18,14 +17,42 @@ import { // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export const meta = { - title: 'Components/ResourceSelectorModal', + title: 'Components/ResourceSelectorModal 资源选择对话框', component: ResourceSelectorModal, parameters: { // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout layout: 'centered', + msw: { + handlers: [ + http.get('/api/mmp/newdataset/queryDatasets', () => { + return HttpResponse.json(datasetListData); + }), + http.get('/api/mmp/newdataset/getVersionList', () => { + return HttpResponse.json(datasetVersionData); + }), + http.get('/api/mmp/newdataset/getDatasetDetail', () => { + return HttpResponse.json(datasetDetailData); + }), + http.get('/api/mmp/newmodel/queryModels', () => { + return HttpResponse.json(modelListData); + }), + http.get('/api/mmp/newmodel/getVersionList', () => { + return HttpResponse.json(modelVersionData); + }), + http.get('/api/mmp/newmodel/getModelDetail', () => { + return HttpResponse.json(modelDetailData); + }), + http.get('/api/mmp/image', () => { + return HttpResponse.json(mirrorListData); + }), + http.get('/api/mmp/imageVersion', () => { + return HttpResponse.json(mirrorVerionData); + }), + ], + }, }, // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs - tags: ['autodocs'], + tags: ['!autodocs'], // More on argTypes: https://storybook.js.org/docs/api/argtypes argTypes: { // backgroundColor: { control: 'color' }, @@ -45,158 +72,58 @@ export default meta; type Story = StoryObj<typeof meta>; // More on writing stories with args: https://storybook.js.org/docs/writing-stories/args +/** 选择数据集 */ export const Dataset: Story = { args: { type: ResourceSelectorType.Dataset, - open: false, }, - parameters: { - msw: { - handlers: [ - http.get('/api/mmp/newdataset/queryDatasets', () => { - return HttpResponse.json(datasetListData); - }), - http.get('/api/mmp/newdataset/getVersionList', () => { - return HttpResponse.json(datasetVersionData); - }), - http.get('/api/mmp/newdataset/getDatasetDetail', () => { - return HttpResponse.json(datasetDetailData); - }), - ], - }, - }, - render: function Render({ onOk, onCancel, ...args }) { - const [{ open }, updateArgs] = useArgs(); - function onClick() { - updateArgs({ open: true }); - } - function handleOk(res: any) { - updateArgs({ open: false }); - onOk?.(res); - } - - function handleCancel() { - updateArgs({ open: false }); - onCancel?.(); - } - + render: function Render(args) { + const handleClick = () => { + const { close } = openAntdModal(ResourceSelectorModal, { + type: args.type, + onOk: (res) => { + const { onOk } = args; + onOk?.(res); + close(); + }, + }); + }; return ( - <> - <Button type="primary" onClick={onClick}> - 选择数据集 - </Button> - <ResourceSelectorModal {...args} open={open} onOk={handleOk} onCancel={handleCancel} /> - </> + <Button type="primary" onClick={handleClick}> + 选择数据集 + </Button> ); }, }; +/** 选择模型 */ export const Model: Story = { args: { type: ResourceSelectorType.Model, - open: false, - }, - parameters: { - msw: { - handlers: [ - http.get('/api/mmp/newmodel/queryModels', () => { - return HttpResponse.json(modelListData); - }), - http.get('/api/mmp/newmodel/getVersionList', () => { - return HttpResponse.json(modelVersionData); - }), - http.get('/api/mmp/newmodel/getModelDetail', () => { - return HttpResponse.json(modelDetailData); - }), - ], - }, }, - render: function Render({ onOk, onCancel, ...args }) { - const [{ open }, updateArgs] = useArgs(); - function onClick() { - updateArgs({ open: true }); - } - function handleOk(res: any) { - updateArgs({ open: false }); - onOk?.(res); - } - - function handleCancel() { - updateArgs({ open: false }); - onCancel?.(); - } - + render: function Render(args) { + const handleClick = () => { + const { close } = openAntdModal(ResourceSelectorModal, { + type: args.type, + onOk: (res) => { + const { onOk } = args; + onOk?.(res); + close(); + }, + }); + }; return ( - <> - <Button type="primary" onClick={onClick}> - 选择模型 - </Button> - <ResourceSelectorModal {...args} open={open} onOk={handleOk} onCancel={handleCancel} /> - </> + <Button type="primary" onClick={handleClick}> + 选择模型 + </Button> ); }, }; +/** 选择镜像 */ export const Mirror: Story = { args: { type: ResourceSelectorType.Mirror, - open: false, - }, - parameters: { - msw: { - handlers: [ - http.get('/api/mmp/image', () => { - return HttpResponse.json(mirrorListData); - }), - http.get('/api/mmp/imageVersion', () => { - return HttpResponse.json(mirrorVerionData); - }), - ], - }, - }, - render: function Render({ onOk, onCancel, ...args }) { - const [{ open }, updateArgs] = useArgs(); - function onClick() { - updateArgs({ open: true }); - } - function handleOk(res: any) { - updateArgs({ open: false }); - onOk?.(res); - } - - function handleCancel() { - updateArgs({ open: false }); - onCancel?.(); - } - - return ( - <> - <Button type="primary" onClick={onClick}> - 选择镜像 - </Button> - <ResourceSelectorModal {...args} open={open} onOk={handleOk} onCancel={handleCancel} /> - </> - ); - }, -}; - -/** 通过 `openAntdModal` 函数打开 */ -export const OpenByFunction: Story = { - name: '通过函数的方式打开', - args: { - type: ResourceSelectorType.Mirror, - }, - parameters: { - msw: { - handlers: [ - http.get('/api/mmp/image', () => { - return HttpResponse.json(mirrorListData); - }), - http.get('/api/mmp/imageVersion', () => { - return HttpResponse.json(mirrorVerionData); - }), - ], - }, }, render: function Render(args) { const handleClick = () => { @@ -211,7 +138,7 @@ export const OpenByFunction: Story = { }; return ( <Button type="primary" onClick={handleClick}> - 以函数的方式打开 + 选择镜像 </Button> ); }, diff --git a/react-ui/src/stories/SubAreaTitle.stories.tsx b/react-ui/src/stories/SubAreaTitle.stories.tsx index 9fad7d71..30506448 100644 --- a/react-ui/src/stories/SubAreaTitle.stories.tsx +++ b/react-ui/src/stories/SubAreaTitle.stories.tsx @@ -4,7 +4,7 @@ import type { Meta, StoryObj } from '@storybook/react'; // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export const meta = { - title: 'Components/SubAreaTitle', + title: 'Components/SubAreaTitle 子区域标题', component: SubAreaTitle, parameters: { // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout diff --git a/react-ui/static/favicon.ico b/react-ui/static/favicon.ico deleted file mode 100644 index 408b8a236709dc94679a96a769597c3d94443a93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4286 zcmb`GS!|V65XYytR1jqqq0-WpZj`OGKuZgy6ezoi`e5+IG%mEgU7>sFN(<_XhD0La zL5)5Tj88~3(S*gMf-%NKBqqjah(r{l2vMND-!lHr*WTJ*Z`&*B*Zex?o0&8JnRC7? z62)Iql9>N;YPQIH5y=2tQUu2DJ;Wk;26}c%pm&D^4)2uyS9V7QUfR7DUWRk<DZCaq zvU|;8iUp4BB5#-2FYSq>bVNB;?{=}!wt9E^=%ECSAHfA3!S}?TqmO8#@6g9&J%OHW zgY)<9C<q+haUFCFe&d|BnzOo9ohfr4jG2@cEcET3VjuQ+pm)2DOV75qtV6|9%pUD7 znk4;Vv3iOhg7ehY3AjjnCQP3Gp)Fz^+VUWLWOZ-R3HXHgbeJ@K`%sYtI_RNma|5`b z<IrmIiBF>bX0bY{*;y28b#6KXItG1KS5X{z`jc|`6me^}i8)U+#p)<bfY;$Ct7GF` zxC8e<;jGnBFdM{fTQ3fTK6ZQlaLj7oAa?tD4?UVH1FaiF)4g|X-HLYMzjPGDptTg8 z9oS;Ky`TvOtoDL_YL;Nd?xJ>U{-}C^Cj1A{AA-CG?Dh>0+uemx#utFGo&YmB?HlO< zI!0i$+Sbp7^PtdYx8=_V`KxX*TDkO*E83YSRtsyR-L^i4_><W8;2i6t*1`NNw>4)h z`C-4&b~rPGIcM!zM$J6KUbqW3`0dtpVjDe=9I=~oJ^g#-sV27^Zh?;AGV8oyp$Hb* zo#XZ4X|=AKf&GA46~2XbsD@m6h_Rd3(#u-0T65#@T?UgE%G*I%ZOE4XmMn1^v&F7o zB~~5tm~~^8hc;x2!ERd3Y-_M<W9*ikqo5(&K=)Pjv)~zGr=UM1C%EUVHKcK`Wu>R% zpy&1A`G@oy277RfHQIxeU~hwl!NK<{41|dV^G!~#)38c{Fz<A<SHcslpN2f<f5c&K zlVcm2=&31t9(>MOC>Fw5<6C_XzJ_<<8*&}2@%O_?i1%tYW=)~~<IHy&u5$(hV8Kn^ zKO^=mOmpf@AJCY!0sa7;fMZTmcC6c+9nCB$<h}sS@D$8;xJ##grH{IP>Y|mYVX4o& zL(a?O=3*P+B6&{O+>tfvGt14nIn8`C!}n?KG~2slbI(rQid|0K%IlyLFhKnG335i( zxJhmSm>I=<XXg8H8tJDIpLsX)A6Wh&=>OohQ@8v)yu+T`W9)N@zrk$Nu>77fgFmzX zSZDvzo1hVb-m(&yN&Zx9nX`Y{cdVU|{eSbm$Jw7DZcVy4HA}EdM61)qs?8AHvtYOn zr#2%18X-5x%QSV-7HwK1yr;wS_}Z`s;VMvX$w{|%Ng~>YShpr)id&r~L7b{ouLt`3 z!Kq2t2>F)0I1uI=O)c++n)I%rT6eME!&SHfC)}E}0`z=tbt-+Nh?b>bQ(prYGy;y< z)oIZVb7*av*fpGkInU~)gZ2E0QPijhYm8dI;x9!z+UUDg$&iu^7g+1~q+DUo3bW7N zk3KU5AGac5s8(_THLj0eC;2zxTR?R0g5bVYZsp>S!3GV(C47aBIkSqz;+FlZt(EhH zn79>-ec0n+_J*tXrdyd5?N%hA&o^QAS0+8`RwS0f`|u@v1!u^qgGHv_!MtSdI3+l` zc={EI=qJvAKF|pGf}FX)e$KNp&ggsf)xYQg*Pl37D-!0p{)A~>kHq@Ry&k#uq+xBd z(3&~o`WG2yKp$uXTq0)<h<0rfyOutxSXae!zTBnhYsk7)N%Tl>P25*m!YFM|pYzvp z_Le31-17KipcA3x@h6zmhaFW<E9UcEF%#Na2?wZM9Xl!~^d-heK6Tu(IC_Z7*RqAz zK*!-1@(PKIQ<5B7?!Ml&jB_hpDDJ-aC@p>LS-1uohM)00r~4i=d7}Qf`_c>Dq~+8? z->doJe4p-Huo+ImHL&4NIIa6)i?#GopO(fB=K2$*UlMhYS=dlaY!*2)#YR*OS4A#h b$9Oj3kA|q>xLFyGVJgfLx!Oe??e_QwVjhSf From 6c29c2b332f388580a5763a16afa045ddbac78af Mon Sep 17 00:00:00 2001 From: cp3hnu <cp3hnu@gmail.com> Date: Wed, 26 Feb 2025 15:06:55 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20=E4=BF=AE=E6=94=B9=E8=B6=85?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E5=AF=BB=E4=BC=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- react-ui/package.json | 2 +- react-ui/src/components/FormInfo/index.tsx | 31 ++++++++-- react-ui/src/hooks/resource.ts | 6 +- react-ui/src/pages/AutoML/Instance/index.tsx | 2 +- .../components/CreateMirrorModal/index.tsx | 4 +- .../Experiment/components/LogGroup/index.tsx | 2 +- .../pages/HyperParameter/Instance/index.tsx | 19 +++--- .../components/CreateForm/ExecuteConfig.tsx | 2 +- react-ui/src/pages/HyperParameter/types.ts | 2 +- react-ui/src/pages/Mirror/Create/index.tsx | 4 +- .../ModelDeployment/CreateVersion/index.tsx | 2 +- react-ui/src/stories/FormInfo.stories.tsx | 60 ++++++------------- react-ui/src/utils/format.ts | 6 +- 13 files changed, 70 insertions(+), 72 deletions(-) diff --git a/react-ui/package.json b/react-ui/package.json index f2583d6b..1a8d7ebc 100644 --- a/react-ui/package.json +++ b/react-ui/package.json @@ -8,7 +8,7 @@ "build": "max build", "deploy": "npm run build && npm run gh-pages", "dev": "npm run start:dev", - "dev-no-sso": "NO_SSO=true npm run start:dev", + "dev-no-sso": "cross-env NO_SSO=true npm run start:dev", "docker-hub:build": "docker build -f Dockerfile.hub -t ant-design-pro ./", "docker-prod:build": "docker-compose -f ./docker/docker-compose.yml build", "docker-prod:dev": "docker-compose -f ./docker/docker-compose.yml up", diff --git a/react-ui/src/components/FormInfo/index.tsx b/react-ui/src/components/FormInfo/index.tsx index a784e433..7e8e95ad 100644 --- a/react-ui/src/components/FormInfo/index.tsx +++ b/react-ui/src/components/FormInfo/index.tsx @@ -1,3 +1,4 @@ +import { formatEnum } from '@/utils/format'; import { Typography } from 'antd'; import classNames from 'classnames'; import './index.less'; @@ -7,8 +8,12 @@ type FormInfoProps = { value?: any; /** 如果 `value` 是对象时,取对象的哪个属性作为值 */ valuePropName?: string; - /** 是否是多行 */ - multiline?: boolean; + /** 是否是多行文本 */ + textArea?: boolean; + /** 是否是下拉框 */ + select?: boolean; + /** 下拉框数据 */ + options?: { label: string; value: any }[]; /** 自定义类名 */ className?: string; /** 自定义样式 */ @@ -18,20 +23,34 @@ type FormInfoProps = { /** * 模拟禁用的输入框,但是内容超长时,hover 时显示所有内容 */ -function FormInfo({ value, valuePropName, className, style, multiline = false }: FormInfoProps) { - const data = value && typeof value === 'object' && valuePropName ? value[valuePropName] : value; +function FormInfo({ + value, + valuePropName, + className, + select, + options, + style, + textArea = false, +}: FormInfoProps) { + let data = value; + if (value && typeof value === 'object' && valuePropName) { + data = value[valuePropName]; + } else if (select === true && options) { + data = formatEnum(options)(value); + } + return ( <div className={classNames( 'form-info', { - 'form-info--multiline': multiline, + 'form-info--multiline': textArea, }, className, )} style={style} > - <Typography.Paragraph ellipsis={multiline ? false : { tooltip: data }}> + <Typography.Paragraph ellipsis={textArea ? false : { tooltip: data }}> {data} </Typography.Paragraph> </div> diff --git a/react-ui/src/hooks/resource.ts b/react-ui/src/hooks/resource.ts index 0b491aeb..82a3ee78 100644 --- a/react-ui/src/hooks/resource.ts +++ b/react-ui/src/hooks/resource.ts @@ -15,11 +15,11 @@ import { useSnapshot } from 'umi'; // 获取资源规格 export function useComputingResource() { const [resourceStandardList, setResourceStandardList] = useState<ComputingResource[]>([]); - const computingResourceSnap = useSnapshot(computingResourceState); + const snap = useSnapshot(computingResourceState); useEffect(() => { - if (computingResourceSnap.computingResource.length > 0) { - setResourceStandardList(computingResourceSnap.computingResource as ComputingResource[]); + if (snap.computingResource.length > 0) { + setResourceStandardList(snap.computingResource as ComputingResource[]); } else { getComputingResource(); } diff --git a/react-ui/src/pages/AutoML/Instance/index.tsx b/react-ui/src/pages/AutoML/Instance/index.tsx index 947ac63d..aefee532 100644 --- a/react-ui/src/pages/AutoML/Instance/index.tsx +++ b/react-ui/src/pages/AutoML/Instance/index.tsx @@ -83,7 +83,7 @@ function AutoMLInstance() { const setupSSE = (name: string, namespace: string) => { let { origin } = location; if (process.env.NODE_ENV === 'development') { - origin = 'http://172.20.32.181:31213'; + origin = 'http://172.20.32.197:31213'; } const params = encodeURIComponent(`metadata.namespace=${namespace},metadata.name=${name}`); const evtSource = new EventSource( diff --git a/react-ui/src/pages/DevelopmentEnvironment/components/CreateMirrorModal/index.tsx b/react-ui/src/pages/DevelopmentEnvironment/components/CreateMirrorModal/index.tsx index 6af530e1..8d2b27fa 100644 --- a/react-ui/src/pages/DevelopmentEnvironment/components/CreateMirrorModal/index.tsx +++ b/react-ui/src/pages/DevelopmentEnvironment/components/CreateMirrorModal/index.tsx @@ -67,8 +67,8 @@ function CreateMirrorModal({ envId, onOk, ...rest }: CreateMirrorModalProps) { message: '请输入镜像Tag', }, { - pattern: /^[a-zA-Z0-9_-]*$/, - message: '只支持字母、数字、下划线(_)、中横线(-)', + pattern: /^[a-zA-Z0-9._-]+$/, + message: '版本只支持字母、数字、点(.)、下划线(_)、中横线(-)', }, ]} > diff --git a/react-ui/src/pages/Experiment/components/LogGroup/index.tsx b/react-ui/src/pages/Experiment/components/LogGroup/index.tsx index 1b448930..6dd31166 100644 --- a/react-ui/src/pages/Experiment/components/LogGroup/index.tsx +++ b/react-ui/src/pages/Experiment/components/LogGroup/index.tsx @@ -135,7 +135,7 @@ function LogGroup({ const setupSockect = () => { let { host } = location; if (process.env.NODE_ENV === 'development') { - host = '172.20.32.181:31213'; + host = '172.20.32.197:31213'; } const socket = new WebSocket( `ws://${host}/newlog/realtimeLog?start=${start_time}&query={pod="${pod_name}"}`, diff --git a/react-ui/src/pages/HyperParameter/Instance/index.tsx b/react-ui/src/pages/HyperParameter/Instance/index.tsx index 8d29521b..6a1d3931 100644 --- a/react-ui/src/pages/HyperParameter/Instance/index.tsx +++ b/react-ui/src/pages/HyperParameter/Instance/index.tsx @@ -1,7 +1,7 @@ import KFIcon from '@/components/KFIcon'; import { AutoMLTaskType, ExperimentStatus } from '@/enums'; import LogList from '@/pages/Experiment/components/LogList'; -import { getExperimentInsReq } from '@/services/autoML'; +import { getRayInsReq } from '@/services/hyperParameter'; import { NodeStatus } from '@/types'; import { parseJsonText } from '@/utils'; import { safeInvoke } from '@/utils/functional'; @@ -22,12 +22,11 @@ enum TabKeys { History = 'history', } -function AutoMLInstance() { +function HyperParameterInstance() { const [activeTab, setActiveTab] = useState<string>(TabKeys.Params); - const [autoMLInfo, setAutoMLInfo] = useState<HyperParameterData | undefined>(undefined); + const [experimentInfo, setExperimentInfo] = useState<HyperParameterData | undefined>(undefined); const [instanceInfo, setInstanceInfo] = useState<AutoMLInstanceData | undefined>(undefined); const params = useParams(); - // const autoMLId = safeInvoke(Number)(params.autoMLId); const instanceId = safeInvoke(Number)(params.id); const evtSourceRef = useRef<EventSource | null>(null); @@ -42,14 +41,14 @@ function AutoMLInstance() { // 获取实验实例详情 const getExperimentInsInfo = async (isStatusDetermined: boolean) => { - const [res] = await to(getExperimentInsReq(instanceId)); + const [res] = await to(getRayInsReq(instanceId)); if (res && res.data) { const info = res.data as AutoMLInstanceData; const { param, node_status, argo_ins_name, argo_ins_ns, status } = info; // 解析配置参数 const paramJson = parseJsonText(param); if (paramJson) { - setAutoMLInfo(paramJson); + setExperimentInfo(paramJson); } // 这个接口返回的状态有延时,SSE 返回的状态是最新的 @@ -83,7 +82,7 @@ function AutoMLInstance() { const setupSSE = (name: string, namespace: string) => { let { origin } = location; if (process.env.NODE_ENV === 'development') { - origin = 'http://172.20.32.181:31213'; + origin = 'http://172.20.32.197:31213'; } const params = encodeURIComponent(`metadata.namespace=${namespace},metadata.name=${name}`); const evtSource = new EventSource( @@ -142,7 +141,7 @@ function AutoMLInstance() { children: ( <HyperParameterBasic className={styles['auto-ml-instance__basic']} - info={autoMLInfo} + info={experimentInfo} runStatus={instanceInfo?.nodeStatus} isInstance /> @@ -189,7 +188,7 @@ function AutoMLInstance() { children: ( <ExperimentHistory fileUrl={instanceInfo?.run_history_path} - isClassification={autoMLInfo?.task_type === AutoMLTaskType.Classification} + isClassification={experimentInfo?.task_type === AutoMLTaskType.Classification} /> ), }, @@ -212,4 +211,4 @@ function AutoMLInstance() { ); } -export default AutoMLInstance; +export default HyperParameterInstance; diff --git a/react-ui/src/pages/HyperParameter/components/CreateForm/ExecuteConfig.tsx b/react-ui/src/pages/HyperParameter/components/CreateForm/ExecuteConfig.tsx index 1609328c..672f9094 100644 --- a/react-ui/src/pages/HyperParameter/components/CreateForm/ExecuteConfig.tsx +++ b/react-ui/src/pages/HyperParameter/components/CreateForm/ExecuteConfig.tsx @@ -109,7 +109,7 @@ function ExecuteConfig() { <Col span={10}> <Form.Item label="代码配置" - name="code" + name="code_config" rules={[ { validator: requiredValidator, diff --git a/react-ui/src/pages/HyperParameter/types.ts b/react-ui/src/pages/HyperParameter/types.ts index 1e610f20..f8508a88 100644 --- a/react-ui/src/pages/HyperParameter/types.ts +++ b/react-ui/src/pages/HyperParameter/types.ts @@ -12,7 +12,7 @@ export enum OperationType { export type FormData = { name: string; // 实验名称 description: string; // 实验描述 - code: ParameterInputObject; // 代码 + code_config: ParameterInputObject; // 代码 dataset: ParameterInputObject; // 数据集 model: ParameterInputObject; // 模型 image: ParameterInputObject; // 镜像 diff --git a/react-ui/src/pages/Mirror/Create/index.tsx b/react-ui/src/pages/Mirror/Create/index.tsx index 01a22031..681103bf 100644 --- a/react-ui/src/pages/Mirror/Create/index.tsx +++ b/react-ui/src/pages/Mirror/Create/index.tsx @@ -177,8 +177,8 @@ function MirrorCreate() { message: '请输入镜像Tag', }, { - pattern: /^[a-zA-Z0-9_-]*$/, - message: '只支持字母、数字、下划线(_)、中横线(-)', + pattern: /^[a-zA-Z0-9._-]+$/, + message: '版本只支持字母、数字、点(.)、下划线(_)、中横线(-)', }, ]} > diff --git a/react-ui/src/pages/ModelDeployment/CreateVersion/index.tsx b/react-ui/src/pages/ModelDeployment/CreateVersion/index.tsx index 38171380..430eae87 100644 --- a/react-ui/src/pages/ModelDeployment/CreateVersion/index.tsx +++ b/react-ui/src/pages/ModelDeployment/CreateVersion/index.tsx @@ -247,7 +247,7 @@ function CreateServiceVersion() { }, { pattern: /^[a-zA-Z0-9._-]+$/, - message: '版本只支持字母、数字、点、下划线、中横线', + message: '版本只支持字母、数字、点(.)、下划线(_)、中横线(-)', }, ]} > diff --git a/react-ui/src/stories/FormInfo.stories.tsx b/react-ui/src/stories/FormInfo.stories.tsx index 8e2d89de..09466a46 100644 --- a/react-ui/src/stories/FormInfo.stories.tsx +++ b/react-ui/src/stories/FormInfo.stories.tsx @@ -1,6 +1,6 @@ import FormInfo from '@/components/FormInfo'; import type { Meta, StoryObj } from '@storybook/react'; -import { Form, Input, Select, Typography } from 'antd'; +import { Form, Input, Select } from 'antd'; // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export const meta = { @@ -24,6 +24,14 @@ export default meta; type Story = StoryObj<typeof meta>; // More on writing stories with args: https://storybook.js.org/docs/writing-stories/args +export const Primary: Story = { + args: { + style: { width: '200px' }, + value: + '超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本', + }, +}; + export const InForm: Story = { render: () => { return ( @@ -40,11 +48,10 @@ export const InForm: Story = { value: 1, showValue: '对象文本', }, - input_text: - '超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本', - antd_select: 1, select_text: 1, - select_large_text: 1, + ant_input_text: + '超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本', + ant_select_text: 1, }} > <Form.Item label="文本" name="text"> @@ -54,7 +61,7 @@ export const InForm: Story = { <FormInfo /> </Form.Item> <Form.Item label="多行文本" name="multiline_text"> - <FormInfo multiline /> + <FormInfo textArea /> </Form.Item> <Form.Item label="对象" name="object_text"> <FormInfo valuePropName="showValue" /> @@ -62,12 +69,9 @@ export const InForm: Story = { <Form.Item label="无内容" name="empty_text"> <FormInfo /> </Form.Item> - <Form.Item label="Input" name="input_text"> - <Input disabled /> - </Form.Item> - <Form.Item label="Select" name="antd_select"> - <Select - disabled + <Form.Item label="Select" name="select_text"> + <FormInfo + select options={[ { label: @@ -77,37 +81,11 @@ export const InForm: Story = { ]} /> </Form.Item> - <Form.Item label="Select" name="select_text"> - <Select - labelRender={(props) => { - return ( - <div style={{ width: '100%', lineHeight: 'normal' }}> - <Typography.Text ellipsis={{ tooltip: props.label }} style={{ margin: 0 }}> - {props.label} - </Typography.Text> - </div> - ); - }} - disabled - options={[ - { - label: '选择文本', - value: 1, - }, - ]} - /> + <Form.Item label="Input" name="ant_input_text"> + <Input disabled /> </Form.Item> - <Form.Item label="Long Select" name="select_large_text"> + <Form.Item label="Select" name="ant_select_text"> <Select - labelRender={(props) => { - return ( - <div style={{ width: '100%', lineHeight: 'normal' }}> - <Typography.Text ellipsis={{ tooltip: props.label }} style={{ margin: 0 }}> - {props.label} - </Typography.Text> - </div> - ); - }} disabled options={[ { diff --git a/react-ui/src/utils/format.ts b/react-ui/src/utils/format.ts index c540e441..40d46fdc 100644 --- a/react-ui/src/utils/format.ts +++ b/react-ui/src/utils/format.ts @@ -122,10 +122,12 @@ export const formatBoolean = (value: boolean): string => { return value ? '是' : '否'; }; -type FormatEnum = (value: string | number) => string; +type FormatEnumFunc = (value: string | number) => string; // 格式化枚举 -export const formatEnum = (options: { value: string | number; label: string }[]): FormatEnum => { +export const formatEnum = ( + options: { value: string | number; label: string }[], +): FormatEnumFunc => { return (value: string | number) => { const option = options.find((item) => item.value === value); return option ? option.label : '--';