From fb71c682163403f6060cfbc37361d5e598e834f6 Mon Sep 17 00:00:00 2001 From: cp3hnu Date: Mon, 24 Feb 2025 08:48:00 +0800 Subject: [PATCH 1/2] =?UTF-8?q?chore:=20=E9=A2=9C=E8=89=B2=E6=95=B4?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- react-ui/.storybook/tsconfig.json | 1 + .../src/components/BasicTableInfo/index.less | 4 +- react-ui/src/components/InfoGroup/index.less | 2 +- .../ResourceSelectorModal/index.less | 14 ++-- .../pages/Experiment/Comparison/index.less | 4 +- .../CreateForm/ParameterRange/index.less | 2 +- .../Model/components/ModelMetrics/index.less | 2 +- .../components/RobotFrame/index.less | 2 +- react-ui/src/stories/KFModal.mdx | 45 +++++++++++ react-ui/src/stories/KFModal.stories.tsx | 5 +- react-ui/src/stories/docs/Colors.mdx | 77 +++++++++++++++++++ react-ui/src/stories/docs/Git-Commit.mdx | 25 ++++++ react-ui/src/stories/docs/Less.mdx | 2 +- react-ui/src/styles/theme.less | 12 +-- react-ui/tsconfig.json | 1 + 15 files changed, 171 insertions(+), 27 deletions(-) create mode 100644 react-ui/src/stories/KFModal.mdx create mode 100644 react-ui/src/stories/docs/Colors.mdx create mode 100644 react-ui/src/stories/docs/Git-Commit.mdx diff --git a/react-ui/.storybook/tsconfig.json b/react-ui/.storybook/tsconfig.json index 601d7708..e30a508b 100644 --- a/react-ui/.storybook/tsconfig.json +++ b/react-ui/.storybook/tsconfig.json @@ -21,6 +21,7 @@ "incremental": true, // 通过读写磁盘上的文件来启用增量编译 "noFallthroughCasesInSwitch": true, // 报告switch语句中的fallthrough案例错误 "strictNullChecks": true, // 启用严格的null检查 + "importHelpers": true, "baseUrl": "./" } } diff --git a/react-ui/src/components/BasicTableInfo/index.less b/react-ui/src/components/BasicTableInfo/index.less index 479fe332..1207d033 100644 --- a/react-ui/src/components/BasicTableInfo/index.less +++ b/react-ui/src/components/BasicTableInfo/index.less @@ -4,7 +4,7 @@ flex-wrap: wrap; align-items: stretch; width: 100%; - border: 1px solid @border-color-base; + border: 1px solid @border-color; border-bottom: none; border-radius: 4px; @@ -12,7 +12,7 @@ display: flex; align-items: stretch; width: 25%; - border-bottom: 1px solid @border-color-base; + border-bottom: 1px solid @border-color; &__label { flex: none; diff --git a/react-ui/src/components/InfoGroup/index.less b/react-ui/src/components/InfoGroup/index.less index 4dccf4c7..94c56187 100644 --- a/react-ui/src/components/InfoGroup/index.less +++ b/react-ui/src/components/InfoGroup/index.less @@ -4,7 +4,7 @@ &__content { padding: 20px @content-padding; background-color: white; - border: 1px solid @border-color-base; + border: 1px solid @border-color; border-top: none; border-radius: 0 0 4px 4px; } diff --git a/react-ui/src/components/ResourceSelectorModal/index.less b/react-ui/src/components/ResourceSelectorModal/index.less index cffe4caf..1581e510 100644 --- a/react-ui/src/components/ResourceSelectorModal/index.less +++ b/react-ui/src/components/ResourceSelectorModal/index.less @@ -22,8 +22,8 @@ height: 398px; margin-right: 15px; padding: 15px; - background-color: @background-color-primary; - border: 1px solid @border-color; + background-color: rgba(22, 100, 255, 0.03); + border: 1px solid rgba(22, 100, 255, 0.3); border-radius: 8px; &__search { @@ -31,7 +31,7 @@ padding-left: 0; background-color: transparent; border-width: 0; - border-bottom: 1px solid @border-color-secondary; + border-bottom: 1px solid rgba(22, 100, 255, 0.1); border-radius: 0; } @@ -45,8 +45,8 @@ width: calc(100% - 488px - 15px); height: 398px; padding: 15px; - background-color: @background-color-primary; - border: 1px solid @border-color; + background-color: rgba(22, 100, 255, 0.03); + border: 1px solid rgba(22, 100, 255, 0.3); border-radius: 8px; &__title { @@ -56,7 +56,7 @@ color: @text-color; font-size: @font-size; line-height: 46px; - border-bottom: 1px solid @border-color-secondary; + border-bottom: 1px solid rgba(22, 100, 255, 0.1); } &__files { height: calc(100% - 75px); @@ -68,7 +68,7 @@ color: @text-color-secondary; font-size: 13px; word-break: break-all; - background: @background-color-gray; + background: rgba(4, 3, 3, 0.06); border-radius: 4px; } } diff --git a/react-ui/src/pages/Experiment/Comparison/index.less b/react-ui/src/pages/Experiment/Comparison/index.less index 3be69ed9..4dce8268 100644 --- a/react-ui/src/pages/Experiment/Comparison/index.less +++ b/react-ui/src/pages/Experiment/Comparison/index.less @@ -29,7 +29,7 @@ div { flex: 1; height: 1px; - background-color: @border-color-base; + background-color: @border-color; } p { @@ -45,7 +45,7 @@ .ant-table-thead { .ant-table-cell { background-color: rgb(247, 247, 247); - border-color: @border-color-base !important; + border-color: @border-color !important; } } .ant-table-tbody { diff --git a/react-ui/src/pages/HyperParameter/components/CreateForm/ParameterRange/index.less b/react-ui/src/pages/HyperParameter/components/CreateForm/ParameterRange/index.less index 61091050..25edd4bc 100644 --- a/react-ui/src/pages/HyperParameter/components/CreateForm/ParameterRange/index.less +++ b/react-ui/src/pages/HyperParameter/components/CreateForm/ParameterRange/index.less @@ -15,7 +15,7 @@ } } &__desc { - margin-bottom: 20px; + margin-bottom: 15px; padding: 4px 8px; color: @text-color-tertiary; font-size: 13px; diff --git a/react-ui/src/pages/Model/components/ModelMetrics/index.less b/react-ui/src/pages/Model/components/ModelMetrics/index.less index 77b763d8..03123746 100644 --- a/react-ui/src/pages/Model/components/ModelMetrics/index.less +++ b/react-ui/src/pages/Model/components/ModelMetrics/index.less @@ -12,7 +12,7 @@ .ant-table-thead { .ant-table-cell { background-color: rgb(247, 247, 247); - border-color: @border-color-base !important; + border-color: @border-color !important; } } .ant-table-tbody { diff --git a/react-ui/src/pages/Workspace/components/RobotFrame/index.less b/react-ui/src/pages/Workspace/components/RobotFrame/index.less index a203ecc3..f6ecbe07 100644 --- a/react-ui/src/pages/Workspace/components/RobotFrame/index.less +++ b/react-ui/src/pages/Workspace/components/RobotFrame/index.less @@ -23,7 +23,7 @@ width: 100%; height: 60px; padding: 0 15px; - border-bottom: 1px solid @border-color-base; + border-bottom: 1px solid @border-color; } &__iframe { diff --git a/react-ui/src/stories/KFModal.mdx b/react-ui/src/stories/KFModal.mdx new file mode 100644 index 00000000..8bd711bf --- /dev/null +++ b/react-ui/src/stories/KFModal.mdx @@ -0,0 +1,45 @@ +import { Meta, Title, Subtitle, Description, Primary, Controls, Stories } from '@storybook/blocks'; +import * as KFModalStories from "./KFModal.stories" + + + + +<Subtitle /> +<Description /> + +## Usage + +为了风格统一,应用中的其它 Modal 应该使用 **KFModal** 进行封装,例如 **CodeSelectorModal** + +```ts +export interface CodeSelectorModalProps extends Omit<ModalProps, 'onOk'> { + onOk?: (params: CodeConfigData | undefined) => void; +} + +function CodeSelectorModal({ onOk, ...rest }: CodeSelectorModalProps) { + return ( + <KFModal + {...rest} + title="选择代码配置" + image={require('@/assets/img/modal-code-config.png')} + width={920} + footer={null} + destroyOnClose + > + <div>children</div> + </KFModal> + ); +} + +export default CodeSelectorModal; + +``` + +## Primary + +<Primary /> + +<Controls /> + +<Stories /> + diff --git a/react-ui/src/stories/KFModal.stories.tsx b/react-ui/src/stories/KFModal.stories.tsx index 763aaf31..d1c30a91 100644 --- a/react-ui/src/stories/KFModal.stories.tsx +++ b/react-ui/src/stories/KFModal.stories.tsx @@ -15,7 +15,7 @@ const meta = { layout: 'centered', }, // 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' }, @@ -38,6 +38,7 @@ export default meta; type Story = StoryObj<typeof meta>; // More on writing stories with args: https://storybook.js.org/docs/writing-stories/args +/** 作为子组件时,通过 `open` 属性打开或关闭 */ export const Primary: Story = { args: { title: '创建实验', @@ -71,7 +72,7 @@ export const Primary: Story = { }, }; -/** 通过 `openAntdModal` 函数打开 */ +/** 推荐通过 `openAntdModal` 函数打开 */ export const OpenByFunction: Story = { render: function Render() { const handleClick = () => { diff --git a/react-ui/src/stories/docs/Colors.mdx b/react-ui/src/stories/docs/Colors.mdx new file mode 100644 index 00000000..c90bddc8 --- /dev/null +++ b/react-ui/src/stories/docs/Colors.mdx @@ -0,0 +1,77 @@ + +import { Meta, ColorPalette, ColorItem } from '@storybook/blocks'; + +<Meta title="Documentation/Colors" /> + +# Colors + +<ColorPalette> + <ColorItem + title="theme.color.primary" + subtitle="主题色" + colors={{ "primary-color": '#1664ff' }} + /> + <ColorItem + title="theme.color.primary-hover" + subtitle="主题色:hover" + colors={{ "primary-color-hover": "#69b1ff" }} + /> + <ColorItem + title="theme.color.underline" + subtitle="链接的下划线" + colors={{ "underline-color": "#5d93ff" }} + /> + <ColorItem + title="theme.color.success" + subtitle="成功色" + colors={{ "success-color": '#6ac21d' }} + /> + <ColorItem + title="theme.color.error" + subtitle="失败色" + colors={{ "error-color": '#c73131' }} + /> + <ColorItem + title="theme.color.warning" + subtitle="警告色" + colors={{ "warning-color": '#f98e1b' }} + /> + <ColorItem + title="theme.color.warning" + subtitle="终止" + colors={{ "abort-color": '#8a8a8a' }} + /> + <ColorItem + title="theme.color.warning" + subtitle="等待运行" + colors={{ "pending-color": '#ecb934' }} + /> + <ColorItem + title="theme.color.background" + subtitle="背景色" + colors={{ + "background-color": '#f9fafb', + "sider-background-color": '#f2f5f7' + }} + /> + <ColorItem + title="theme.color.font" + subtitle="字体颜色" + colors={{ + "text-color": '#1d1d20', + "text-color-secondary": '#575757', + "text-color-tertiary": '#8a8a8a', + "text-disabled-color": 'rgba(0, 0, 0, 0.25)', + }} + /> + <ColorItem + title="theme.color.placeholder" + subtitle="placeholder 颜色" + colors={{ "text-placeholder-color": 'rgba(0, 0, 0, 0.25)' }} + /> + <ColorItem + title="theme.color.border" + subtitle="边框色" + colors={{ "border-color": '#eaeaea' }} + /> +</ColorPalette> \ No newline at end of file diff --git a/react-ui/src/stories/docs/Git-Commit.mdx b/react-ui/src/stories/docs/Git-Commit.mdx new file mode 100644 index 00000000..26e81138 --- /dev/null +++ b/react-ui/src/stories/docs/Git-Commit.mdx @@ -0,0 +1,25 @@ +import { Meta } from '@storybook/blocks'; + +<Meta title="Documentation/Git Commit" /> + +# Git 提交规范 + +遵循 [Angular Commit Message Guidelines](https://github.com/angular/angular/blob/22b96b9/CONTRIBUTING.md#-commit-message-guidelines) 规范: + +- feat: 增加新功能 +- fix: 修复 bug +- build: 更改构建系统或外部依赖(例如:gulp, broccoli, npm) +- ci: 更改CI配置文件和脚本(例如:Travis, Circle, BrowserStack, SauceLabs) +- docs: 更改文档 +- perf: 提高性能的修改 +- refactor: 重构,但是即不是新增功能,也不是修复 bug +- style: 修改格式或样式,但是不会影响代码的运行(例如:删除空白、添加分号等) +- test: 添加测试 +- chore: 其它不修改 src 或测试文件的更改 + +例如 + +```sh +$ git commit -m "feat: 集成 Storybook 框架" +``` + diff --git a/react-ui/src/stories/docs/Less.mdx b/react-ui/src/stories/docs/Less.mdx index 1b3a6632..2fc5b9bd 100644 --- a/react-ui/src/stories/docs/Less.mdx +++ b/react-ui/src/stories/docs/Less.mdx @@ -1,4 +1,4 @@ -import { Meta, Controls } from '@storybook/blocks'; +import { Meta } from '@storybook/blocks'; <Meta title="Documentation/Less" /> diff --git a/react-ui/src/styles/theme.less b/react-ui/src/styles/theme.less index ff7813f9..d044889f 100644 --- a/react-ui/src/styles/theme.less +++ b/react-ui/src/styles/theme.less @@ -8,6 +8,7 @@ @primary-color: #1664ff; // 主色调 @primary-color-secondary: #4e89ff; @primary-color-hover: #69b1ff; +@sider-background-color: #f2f5f7; // 侧边栏背景颜色 @background-color: #f9fafb; // 页面背景颜色 @text-color: #1d1d20; @text-color-secondary: #575757; @@ -20,19 +21,12 @@ @abort-color: #8a8a8a; @pending-color: #ecb934; @underline-color: #5d93ff; +@border-color: #eaeaea; -@border-color-base: #eaeaea; -@border-color: rgba(22, 100, 255, 0.3); -@border-color-secondary: rgba(22, 100, 255, 0.1); -@background-color-primary: rgba(22, 100, 255, 0.03); -@background-color-gray: rgba(4, 3, 3, 0.06); - +@link-hover-color: #69b1ff; @heading-color: rgba(0, 0, 0, 0.85); @input-icon-hover-color: rgba(0, 0, 0, 0.85); -@link-hover-color: #69b1ff; -@sider-background-color: #f2f5f7; - @workspace-background: linear-gradient( 179.03deg, rgba(138, 138, 138, 0.06) 0%, diff --git a/react-ui/tsconfig.json b/react-ui/tsconfig.json index 55ce7f74..4eb2830b 100644 --- a/react-ui/tsconfig.json +++ b/react-ui/tsconfig.json @@ -21,6 +21,7 @@ "incremental": true, // 通过读写磁盘上的文件来启用增量编译 "noFallthroughCasesInSwitch": true, // 报告switch语句中的fallthrough案例错误 "strictNullChecks": true, // 启用严格的null检查 + "importHelpers": true, "baseUrl": "./", "paths": { "@/*": ["src/*"], From 1e97edd8d65dd475165b1f978821622b45261493 Mon Sep 17 00:00:00 2001 From: cp3hnu <cp3hnu@gmail.com> Date: Tue, 25 Feb 2025 09:47:47 +0800 Subject: [PATCH 2/2] =?UTF-8?q?docs:=20=E4=BF=AE=E6=94=B9msw=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=A4=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- react-ui/.storybook/main.ts | 2 +- react-ui/package.json | 2 +- .../src/components/DisabledInput/index.tsx | 21 --- .../{DisabledInput => FormInfo}/index.less | 13 +- react-ui/src/components/FormInfo/index.tsx | 41 ++++++ .../components/ExperimentInstance/index.tsx | 2 +- .../components/ExperimentInstance/index.tsx | 18 +-- .../components/ExperimentParameter/index.tsx | 25 ++-- react-ui/src/pages/Experiment/index.jsx | 2 +- .../src/stories/CodeSelectorModal.stories.tsx | 1 + react-ui/src/stories/FormInfo.stories.tsx | 124 ++++++++++++++++++ react-ui/src/stories/KFModal.stories.tsx | 9 +- .../stories/ResourceSelectorModal.stories.tsx | 1 + react-ui/src/stories/docs/Less.mdx | 2 +- react-ui/static/favicon.ico | Bin 0 -> 4286 bytes .../{public => static}/mockServiceWorker.js | 0 16 files changed, 213 insertions(+), 50 deletions(-) delete mode 100644 react-ui/src/components/DisabledInput/index.tsx rename react-ui/src/components/{DisabledInput => FormInfo}/index.less (55%) create mode 100644 react-ui/src/components/FormInfo/index.tsx create mode 100644 react-ui/src/stories/FormInfo.stories.tsx create mode 100644 react-ui/static/favicon.ico rename react-ui/{public => static}/mockServiceWorker.js (100%) diff --git a/react-ui/.storybook/main.ts b/react-ui/.storybook/main.ts index 820a0eeb..54824837 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: ['../public'], + staticDirs: ['../static'], docs: { defaultName: 'Documentation', }, diff --git a/react-ui/package.json b/react-ui/package.json index 2b2cfd4b..56a4b735 100644 --- a/react-ui/package.json +++ b/react-ui/package.json @@ -166,7 +166,7 @@ }, "msw": { "workerDirectory": [ - "public" + "static" ] } } diff --git a/react-ui/src/components/DisabledInput/index.tsx b/react-ui/src/components/DisabledInput/index.tsx deleted file mode 100644 index 3a31def8..00000000 --- a/react-ui/src/components/DisabledInput/index.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { Typography } from 'antd'; -import styles from './index.less'; - -type DisabledInputProps = { - value?: any; - valuePropName?: string; -}; - -/** - * 模拟禁用的输入框,但是完全显示内容 - */ -function DisabledInput({ value, valuePropName }: DisabledInputProps) { - const data = valuePropName ? value[valuePropName] : value; - return ( - <div className={styles['disabled-input']}> - <Typography.Text ellipsis={{ tooltip: data }}>{data}</Typography.Text> - </div> - ); -} - -export default DisabledInput; diff --git a/react-ui/src/components/DisabledInput/index.less b/react-ui/src/components/FormInfo/index.less similarity index 55% rename from react-ui/src/components/DisabledInput/index.less rename to react-ui/src/components/FormInfo/index.less index 06808c5a..868404c7 100644 --- a/react-ui/src/components/DisabledInput/index.less +++ b/react-ui/src/components/FormInfo/index.less @@ -1,4 +1,5 @@ -.disabled-input { +.form-info { + min-height: 32px; padding: 4px 11px; color: @text-disabled-color; font-size: @font-size-input; @@ -6,4 +7,14 @@ border: 1px solid #d9d9d9; border-radius: 6px; cursor: not-allowed; + + .ant-typography { + margin: 0 !important; + } +} + +.form-info--multiline { + .ant-typography { + white-space: pre-wrap; + } } diff --git a/react-ui/src/components/FormInfo/index.tsx b/react-ui/src/components/FormInfo/index.tsx new file mode 100644 index 00000000..a784e433 --- /dev/null +++ b/react-ui/src/components/FormInfo/index.tsx @@ -0,0 +1,41 @@ +import { Typography } from 'antd'; +import classNames from 'classnames'; +import './index.less'; + +type FormInfoProps = { + /** 自定义类名 */ + value?: any; + /** 如果 `value` 是对象时,取对象的哪个属性作为值 */ + valuePropName?: string; + /** 是否是多行 */ + multiline?: boolean; + /** 自定义类名 */ + className?: string; + /** 自定义样式 */ + style?: React.CSSProperties; +}; + +/** + * 模拟禁用的输入框,但是内容超长时,hover 时显示所有内容 + */ +function FormInfo({ value, valuePropName, className, style, multiline = false }: FormInfoProps) { + const data = value && typeof value === 'object' && valuePropName ? value[valuePropName] : value; + return ( + <div + className={classNames( + 'form-info', + { + 'form-info--multiline': multiline, + }, + className, + )} + style={style} + > + <Typography.Paragraph ellipsis={multiline ? false : { tooltip: data }}> + {data} + </Typography.Paragraph> + </div> + ); +} + +export default FormInfo; diff --git a/react-ui/src/pages/AutoML/components/ExperimentInstance/index.tsx b/react-ui/src/pages/AutoML/components/ExperimentInstance/index.tsx index ea319dc8..ab713f48 100644 --- a/react-ui/src/pages/AutoML/components/ExperimentInstance/index.tsx +++ b/react-ui/src/pages/AutoML/components/ExperimentInstance/index.tsx @@ -107,7 +107,7 @@ function ExperimentInstanceComponent({ }; if (!experimentInsList || experimentInsList.length === 0) { - return null; + return <div style={{ textAlign: 'center' }}>暂无实验实例</div>; } return ( diff --git a/react-ui/src/pages/Experiment/components/ExperimentInstance/index.tsx b/react-ui/src/pages/Experiment/components/ExperimentInstance/index.tsx index 4d68d93c..9b37dba8 100644 --- a/react-ui/src/pages/Experiment/components/ExperimentInstance/index.tsx +++ b/react-ui/src/pages/Experiment/components/ExperimentInstance/index.tsx @@ -20,7 +20,7 @@ import TensorBoardStatusCell from '../TensorBoardStatus'; import styles from './index.less'; type ExperimentInstanceProps = { - experimentInList?: ExperimentInstance[]; + experimentInsList?: ExperimentInstance[]; experimentInsTotal: number; onClickInstance?: (instance: ExperimentInstance) => void; onClickTensorBoard?: (instance: ExperimentInstance) => void; @@ -30,7 +30,7 @@ type ExperimentInstanceProps = { }; function ExperimentInstanceComponent({ - experimentInList, + experimentInsList, experimentInsTotal, onClickInstance, onClickTensorBoard, @@ -40,8 +40,8 @@ function ExperimentInstanceComponent({ }: ExperimentInstanceProps) { const { message } = App.useApp(); const allIntanceIds = useMemo(() => { - return experimentInList?.map((item) => item.id) || []; - }, [experimentInList]); + return experimentInsList?.map((item) => item.id) || []; + }, [experimentInsList]); const [ selectedIns, setSelectedIns, @@ -57,7 +57,7 @@ function ExperimentInstanceComponent({ if (allIntanceIds.length === 0) { setSelectedIns([]); } - }, [experimentInList]); + }, [experimentInsList]); // 删除实验实例确认 const handleRemove = (instance: ExperimentInstance) => { @@ -118,8 +118,8 @@ function ExperimentInstanceComponent({ } }; - if (!experimentInList || experimentInList.length === 0) { - return null; + if (!experimentInsList || experimentInsList.length === 0) { + return <div style={{ textAlign: 'center' }}>暂无数据</div>; } return ( @@ -152,7 +152,7 @@ function ExperimentInstanceComponent({ </div> </div> - {experimentInList.map((item, index) => ( + {experimentInsList.map((item, index) => ( <div key={item.id} className={classNames(styles.tableExpandBox, styles.tableExpandBoxContent)} @@ -244,7 +244,7 @@ function ExperimentInstanceComponent({ </div> </div> ))} - {experimentInsTotal > experimentInList.length ? ( + {experimentInsTotal > experimentInsList.length ? ( <div className={styles.loadMoreBox}> <Button type="link" onClick={onLoadMore}> 更多 diff --git a/react-ui/src/pages/Experiment/components/ExperimentParameter/index.tsx b/react-ui/src/pages/Experiment/components/ExperimentParameter/index.tsx index 82f75e2c..235e3087 100644 --- a/react-ui/src/pages/Experiment/components/ExperimentParameter/index.tsx +++ b/react-ui/src/pages/Experiment/components/ExperimentParameter/index.tsx @@ -1,11 +1,10 @@ -import ParameterInput from '@/components/ParameterInput'; +import FormInfo from '@/components/FormInfo'; import ParameterSelect from '@/components/ParameterSelect'; import SubAreaTitle from '@/components/SubAreaTitle'; import { useComputingResource } from '@/hooks/resource'; import { PipelineNodeModelSerialize } from '@/types'; -import { Form, Input, Select } from 'antd'; +import { Form, Select } from 'antd'; import styles from './index.less'; -const { TextArea } = Input; type ExperimentParameterProps = { nodeData: PipelineNodeModelSerialize; @@ -64,7 +63,7 @@ function ExperimentParameter({ nodeData }: ExperimentParameterProps) { }, ]} > - <Input disabled /> + <FormInfo /> </Form.Item> <Form.Item label="任务ID" @@ -76,7 +75,7 @@ function ExperimentParameter({ nodeData }: ExperimentParameterProps) { }, ]} > - <Input disabled /> + <FormInfo /> </Form.Item> <div className={styles['experiment-parameter__title']}> <SubAreaTitle @@ -94,14 +93,14 @@ function ExperimentParameter({ nodeData }: ExperimentParameterProps) { }, ]} > - <Input disabled /> + <FormInfo /> </Form.Item> <Form.Item label="工作目录" name="working_directory"> - <Input disabled /> + <FormInfo /> </Form.Item> <Form.Item label="启动命令" name="command"> - <TextArea disabled /> + <FormInfo multiline /> </Form.Item> <Form.Item label="资源规格" @@ -123,14 +122,14 @@ function ExperimentParameter({ nodeData }: ExperimentParameterProps) { /> </Form.Item> <Form.Item label="挂载路径" name="mount_path"> - <Input disabled /> + <FormInfo /> </Form.Item> <Form.Item label="环境变量" name="env_variables"> - <TextArea disabled /> + <FormInfo multiline /> </Form.Item> {controlStrategyList.map((item) => ( <Form.Item key={item.key} name={['control_strategy', item.key]} label={item.value.label}> - <ParameterInput disabled /> + <FormInfo valuePropName="showValue" /> </Form.Item> ))} <div className={styles['experiment-parameter__title']}> @@ -149,7 +148,7 @@ function ExperimentParameter({ nodeData }: ExperimentParameterProps) { {item.value.type === 'select' ? ( <ParameterSelect disabled /> ) : ( - <ParameterInput disabled /> + <FormInfo valuePropName="showValue" /> )} </Form.Item> ))} @@ -166,7 +165,7 @@ function ExperimentParameter({ nodeData }: ExperimentParameterProps) { label={item.value.label + '(' + item.key + ')'} rules={[{ required: item.value.require ? true : false }]} > - <ParameterInput disabled /> + <FormInfo valuePropName="showValue" /> </Form.Item> ))} </Form> diff --git a/react-ui/src/pages/Experiment/index.jsx b/react-ui/src/pages/Experiment/index.jsx index de8504f5..70345689 100644 --- a/react-ui/src/pages/Experiment/index.jsx +++ b/react-ui/src/pages/Experiment/index.jsx @@ -537,7 +537,7 @@ function Experiment() { expandable={{ expandedRowRender: (record) => ( <ExperimentInstance - experimentInList={experimentInList} + experimentInsList={experimentInList} experimentInsTotal={experimentInsTotal} onClickInstance={(item) => gotoInstanceInfo(item, record)} onClickTensorBoard={handleTensorboard} diff --git a/react-ui/src/stories/CodeSelectorModal.stories.tsx b/react-ui/src/stories/CodeSelectorModal.stories.tsx index 59026ec6..a042f238 100644 --- a/react-ui/src/stories/CodeSelectorModal.stories.tsx +++ b/react-ui/src/stories/CodeSelectorModal.stories.tsx @@ -71,6 +71,7 @@ export const Primary: Story = { /** 通过 `openAntdModal` 函数打开 */ export const OpenByFunction: Story = { + name: '通过函数的方式打开', render: function Render(args) { const handleClick = () => { const { close } = openAntdModal(CodeSelectorModal, { diff --git a/react-ui/src/stories/FormInfo.stories.tsx b/react-ui/src/stories/FormInfo.stories.tsx new file mode 100644 index 00000000..b822427f --- /dev/null +++ b/react-ui/src/stories/FormInfo.stories.tsx @@ -0,0 +1,124 @@ +import FormInfo from '@/components/FormInfo'; +import type { Meta, StoryObj } from '@storybook/react'; +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', + component: FormInfo, + parameters: { + // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout + // layout: 'centered', + }, + // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs + tags: ['autodocs'], + // More on argTypes: https://storybook.js.org/docs/api/argtypes + argTypes: { + // backgroundColor: { control: 'color' }, + }, + // Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked: https://storybook.js.org/docs/essentials/actions#action-args + // args: { onClick: fn() }, +} satisfies Meta<typeof FormInfo>; + +export default meta; +type Story = StoryObj<typeof meta>; + +// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args +export const InForm: Story = { + render: () => { + return ( + <Form + name="form" + style={{ width: 300 }} + labelCol={{ flex: '100px' }} + initialValues={{ + text: '文本', + large_text: + '超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本', + multiline_text: `多行文本\n超长文本超长文本超长文本超长文本\n 多行文本`, + object_text: { + value: 1, + showValue: '对象文本', + }, + input_text: + '超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本', + antd_select: 1, + select_text: 1, + select_large_text: 1, + }} + > + <Form.Item label="文本" name="text"> + <FormInfo /> + </Form.Item> + <Form.Item label="超长文本" name="large_text"> + <FormInfo /> + </Form.Item> + <Form.Item label="多行文本" name="multiline_text"> + <FormInfo multiline /> + </Form.Item> + <Form.Item label="对象" name="object_text"> + <FormInfo valuePropName="showValue" /> + </Form.Item> + <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 + options={[ + { + label: + '超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本', + value: 1, + }, + ]} + /> + </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> + <Form.Item label="Long Select" name="select_large_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> + </Form> + ); + }, +}; diff --git a/react-ui/src/stories/KFModal.stories.tsx b/react-ui/src/stories/KFModal.stories.tsx index d1c30a91..024a2708 100644 --- a/react-ui/src/stories/KFModal.stories.tsx +++ b/react-ui/src/stories/KFModal.stories.tsx @@ -3,7 +3,7 @@ import KFModal from '@/components/KFModal'; import { openAntdModal } from '@/utils/modal'; import { useArgs } from '@storybook/preview-api'; import type { Meta, StoryObj } from '@storybook/react'; -import { fn } from '@storybook/test'; +import { expect, fn, screen, userEvent, within } from '@storybook/test'; import { Button } from 'antd'; // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export @@ -70,10 +70,17 @@ export const Primary: Story = { </> ); }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + await userEvent.click(canvas.getByRole('button', { name: /打开 KFModal/i })); + const dialog = await screen.findByRole('dialog'); + await expect(dialog).toBeInTheDocument(); + }, }; /** 推荐通过 `openAntdModal` 函数打开 */ export const OpenByFunction: Story = { + name: '通过函数的方式打开', render: function Render() { const handleClick = () => { const { close } = openAntdModal(KFModal, { diff --git a/react-ui/src/stories/ResourceSelectorModal.stories.tsx b/react-ui/src/stories/ResourceSelectorModal.stories.tsx index 9e72efd2..b39cb45e 100644 --- a/react-ui/src/stories/ResourceSelectorModal.stories.tsx +++ b/react-ui/src/stories/ResourceSelectorModal.stories.tsx @@ -182,6 +182,7 @@ export const Mirror: Story = { /** 通过 `openAntdModal` 函数打开 */ export const OpenByFunction: Story = { + name: '通过函数的方式打开', args: { type: ResourceSelectorType.Mirror, }, diff --git a/react-ui/src/stories/docs/Less.mdx b/react-ui/src/stories/docs/Less.mdx index 2fc5b9bd..9098d96d 100644 --- a/react-ui/src/stories/docs/Less.mdx +++ b/react-ui/src/stories/docs/Less.mdx @@ -148,7 +148,7 @@ function CodeConfigItem({ item, onClick }: CodeConfigItemProps) { ``` -### 一些建议 +### 一点建议 如果你陷入嵌套地狱,比如 diff --git a/react-ui/static/favicon.ico b/react-ui/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..408b8a236709dc94679a96a769597c3d94443a93 GIT binary patch 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 literal 0 HcmV?d00001 diff --git a/react-ui/public/mockServiceWorker.js b/react-ui/static/mockServiceWorker.js similarity index 100% rename from react-ui/public/mockServiceWorker.js rename to react-ui/static/mockServiceWorker.js