Browse Source

docs: 修改msw文件夹

pull/172/head
cp3hnu 11 months ago
parent
commit
1e97edd8d6
16 changed files with 213 additions and 50 deletions
  1. +1
    -1
      react-ui/.storybook/main.ts
  2. +1
    -1
      react-ui/package.json
  3. +0
    -21
      react-ui/src/components/DisabledInput/index.tsx
  4. +12
    -1
      react-ui/src/components/FormInfo/index.less
  5. +41
    -0
      react-ui/src/components/FormInfo/index.tsx
  6. +1
    -1
      react-ui/src/pages/AutoML/components/ExperimentInstance/index.tsx
  7. +9
    -9
      react-ui/src/pages/Experiment/components/ExperimentInstance/index.tsx
  8. +12
    -13
      react-ui/src/pages/Experiment/components/ExperimentParameter/index.tsx
  9. +1
    -1
      react-ui/src/pages/Experiment/index.jsx
  10. +1
    -0
      react-ui/src/stories/CodeSelectorModal.stories.tsx
  11. +124
    -0
      react-ui/src/stories/FormInfo.stories.tsx
  12. +8
    -1
      react-ui/src/stories/KFModal.stories.tsx
  13. +1
    -0
      react-ui/src/stories/ResourceSelectorModal.stories.tsx
  14. +1
    -1
      react-ui/src/stories/docs/Less.mdx
  15. BIN
      react-ui/static/favicon.ico
  16. +0
    -0
      react-ui/static/mockServiceWorker.js

+ 1
- 1
react-ui/.storybook/main.ts View File

@@ -16,7 +16,7 @@ const config: StorybookConfig = {
name: '@storybook/react-webpack5', name: '@storybook/react-webpack5',
options: {}, options: {},
}, },
staticDirs: ['../public'],
staticDirs: ['../static'],
docs: { docs: {
defaultName: 'Documentation', defaultName: 'Documentation',
}, },


+ 1
- 1
react-ui/package.json View File

@@ -166,7 +166,7 @@
}, },
"msw": { "msw": {
"workerDirectory": [ "workerDirectory": [
"public"
"static"
] ]
} }
} }

+ 0
- 21
react-ui/src/components/DisabledInput/index.tsx View File

@@ -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;

react-ui/src/components/DisabledInput/index.less → react-ui/src/components/FormInfo/index.less View File

@@ -1,4 +1,5 @@
.disabled-input {
.form-info {
min-height: 32px;
padding: 4px 11px; padding: 4px 11px;
color: @text-disabled-color; color: @text-disabled-color;
font-size: @font-size-input; font-size: @font-size-input;
@@ -6,4 +7,14 @@
border: 1px solid #d9d9d9; border: 1px solid #d9d9d9;
border-radius: 6px; border-radius: 6px;
cursor: not-allowed; cursor: not-allowed;

.ant-typography {
margin: 0 !important;
}
}

.form-info--multiline {
.ant-typography {
white-space: pre-wrap;
}
} }

+ 41
- 0
react-ui/src/components/FormInfo/index.tsx View File

@@ -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;

+ 1
- 1
react-ui/src/pages/AutoML/components/ExperimentInstance/index.tsx View File

@@ -107,7 +107,7 @@ function ExperimentInstanceComponent({
}; };


if (!experimentInsList || experimentInsList.length === 0) { if (!experimentInsList || experimentInsList.length === 0) {
return null;
return <div style={{ textAlign: 'center' }}>暂无实验实例</div>;
} }


return ( return (


+ 9
- 9
react-ui/src/pages/Experiment/components/ExperimentInstance/index.tsx View File

@@ -20,7 +20,7 @@ import TensorBoardStatusCell from '../TensorBoardStatus';
import styles from './index.less'; import styles from './index.less';


type ExperimentInstanceProps = { type ExperimentInstanceProps = {
experimentInList?: ExperimentInstance[];
experimentInsList?: ExperimentInstance[];
experimentInsTotal: number; experimentInsTotal: number;
onClickInstance?: (instance: ExperimentInstance) => void; onClickInstance?: (instance: ExperimentInstance) => void;
onClickTensorBoard?: (instance: ExperimentInstance) => void; onClickTensorBoard?: (instance: ExperimentInstance) => void;
@@ -30,7 +30,7 @@ type ExperimentInstanceProps = {
}; };


function ExperimentInstanceComponent({ function ExperimentInstanceComponent({
experimentInList,
experimentInsList,
experimentInsTotal, experimentInsTotal,
onClickInstance, onClickInstance,
onClickTensorBoard, onClickTensorBoard,
@@ -40,8 +40,8 @@ function ExperimentInstanceComponent({
}: ExperimentInstanceProps) { }: ExperimentInstanceProps) {
const { message } = App.useApp(); const { message } = App.useApp();
const allIntanceIds = useMemo(() => { const allIntanceIds = useMemo(() => {
return experimentInList?.map((item) => item.id) || [];
}, [experimentInList]);
return experimentInsList?.map((item) => item.id) || [];
}, [experimentInsList]);
const [ const [
selectedIns, selectedIns,
setSelectedIns, setSelectedIns,
@@ -57,7 +57,7 @@ function ExperimentInstanceComponent({
if (allIntanceIds.length === 0) { if (allIntanceIds.length === 0) {
setSelectedIns([]); setSelectedIns([]);
} }
}, [experimentInList]);
}, [experimentInsList]);


// 删除实验实例确认 // 删除实验实例确认
const handleRemove = (instance: ExperimentInstance) => { 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 ( return (
@@ -152,7 +152,7 @@ function ExperimentInstanceComponent({
</div> </div>
</div> </div>


{experimentInList.map((item, index) => (
{experimentInsList.map((item, index) => (
<div <div
key={item.id} key={item.id}
className={classNames(styles.tableExpandBox, styles.tableExpandBoxContent)} className={classNames(styles.tableExpandBox, styles.tableExpandBoxContent)}
@@ -244,7 +244,7 @@ function ExperimentInstanceComponent({
</div> </div>
</div> </div>
))} ))}
{experimentInsTotal > experimentInList.length ? (
{experimentInsTotal > experimentInsList.length ? (
<div className={styles.loadMoreBox}> <div className={styles.loadMoreBox}>
<Button type="link" onClick={onLoadMore}> <Button type="link" onClick={onLoadMore}>
更多 更多


+ 12
- 13
react-ui/src/pages/Experiment/components/ExperimentParameter/index.tsx View File

@@ -1,11 +1,10 @@
import ParameterInput from '@/components/ParameterInput';
import FormInfo from '@/components/FormInfo';
import ParameterSelect from '@/components/ParameterSelect'; import ParameterSelect from '@/components/ParameterSelect';
import SubAreaTitle from '@/components/SubAreaTitle'; import SubAreaTitle from '@/components/SubAreaTitle';
import { useComputingResource } from '@/hooks/resource'; import { useComputingResource } from '@/hooks/resource';
import { PipelineNodeModelSerialize } from '@/types'; import { PipelineNodeModelSerialize } from '@/types';
import { Form, Input, Select } from 'antd';
import { Form, Select } from 'antd';
import styles from './index.less'; import styles from './index.less';
const { TextArea } = Input;


type ExperimentParameterProps = { type ExperimentParameterProps = {
nodeData: PipelineNodeModelSerialize; nodeData: PipelineNodeModelSerialize;
@@ -64,7 +63,7 @@ function ExperimentParameter({ nodeData }: ExperimentParameterProps) {
}, },
]} ]}
> >
<Input disabled />
<FormInfo />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="任务ID" label="任务ID"
@@ -76,7 +75,7 @@ function ExperimentParameter({ nodeData }: ExperimentParameterProps) {
}, },
]} ]}
> >
<Input disabled />
<FormInfo />
</Form.Item> </Form.Item>
<div className={styles['experiment-parameter__title']}> <div className={styles['experiment-parameter__title']}>
<SubAreaTitle <SubAreaTitle
@@ -94,14 +93,14 @@ function ExperimentParameter({ nodeData }: ExperimentParameterProps) {
}, },
]} ]}
> >
<Input disabled />
<FormInfo />
</Form.Item> </Form.Item>
<Form.Item label="工作目录" name="working_directory"> <Form.Item label="工作目录" name="working_directory">
<Input disabled />
<FormInfo />
</Form.Item> </Form.Item>


<Form.Item label="启动命令" name="command"> <Form.Item label="启动命令" name="command">
<TextArea disabled />
<FormInfo multiline />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="资源规格" label="资源规格"
@@ -123,14 +122,14 @@ function ExperimentParameter({ nodeData }: ExperimentParameterProps) {
/> />
</Form.Item> </Form.Item>
<Form.Item label="挂载路径" name="mount_path"> <Form.Item label="挂载路径" name="mount_path">
<Input disabled />
<FormInfo />
</Form.Item> </Form.Item>
<Form.Item label="环境变量" name="env_variables"> <Form.Item label="环境变量" name="env_variables">
<TextArea disabled />
<FormInfo multiline />
</Form.Item> </Form.Item>
{controlStrategyList.map((item) => ( {controlStrategyList.map((item) => (
<Form.Item key={item.key} name={['control_strategy', item.key]} label={item.value.label}> <Form.Item key={item.key} name={['control_strategy', item.key]} label={item.value.label}>
<ParameterInput disabled />
<FormInfo valuePropName="showValue" />
</Form.Item> </Form.Item>
))} ))}
<div className={styles['experiment-parameter__title']}> <div className={styles['experiment-parameter__title']}>
@@ -149,7 +148,7 @@ function ExperimentParameter({ nodeData }: ExperimentParameterProps) {
{item.value.type === 'select' ? ( {item.value.type === 'select' ? (
<ParameterSelect disabled /> <ParameterSelect disabled />
) : ( ) : (
<ParameterInput disabled />
<FormInfo valuePropName="showValue" />
)} )}
</Form.Item> </Form.Item>
))} ))}
@@ -166,7 +165,7 @@ function ExperimentParameter({ nodeData }: ExperimentParameterProps) {
label={item.value.label + '(' + item.key + ')'} label={item.value.label + '(' + item.key + ')'}
rules={[{ required: item.value.require ? true : false }]} rules={[{ required: item.value.require ? true : false }]}
> >
<ParameterInput disabled />
<FormInfo valuePropName="showValue" />
</Form.Item> </Form.Item>
))} ))}
</Form> </Form>


+ 1
- 1
react-ui/src/pages/Experiment/index.jsx View File

@@ -537,7 +537,7 @@ function Experiment() {
expandable={{ expandable={{
expandedRowRender: (record) => ( expandedRowRender: (record) => (
<ExperimentInstance <ExperimentInstance
experimentInList={experimentInList}
experimentInsList={experimentInList}
experimentInsTotal={experimentInsTotal} experimentInsTotal={experimentInsTotal}
onClickInstance={(item) => gotoInstanceInfo(item, record)} onClickInstance={(item) => gotoInstanceInfo(item, record)}
onClickTensorBoard={handleTensorboard} onClickTensorBoard={handleTensorboard}


+ 1
- 0
react-ui/src/stories/CodeSelectorModal.stories.tsx View File

@@ -71,6 +71,7 @@ export const Primary: Story = {


/** 通过 `openAntdModal` 函数打开 */ /** 通过 `openAntdModal` 函数打开 */
export const OpenByFunction: Story = { export const OpenByFunction: Story = {
name: '通过函数的方式打开',
render: function Render(args) { render: function Render(args) {
const handleClick = () => { const handleClick = () => {
const { close } = openAntdModal(CodeSelectorModal, { const { close } = openAntdModal(CodeSelectorModal, {


+ 124
- 0
react-ui/src/stories/FormInfo.stories.tsx View File

@@ -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>
);
},
};

+ 8
- 1
react-ui/src/stories/KFModal.stories.tsx View File

@@ -3,7 +3,7 @@ import KFModal from '@/components/KFModal';
import { openAntdModal } from '@/utils/modal'; import { openAntdModal } from '@/utils/modal';
import { useArgs } from '@storybook/preview-api'; import { useArgs } from '@storybook/preview-api';
import type { Meta, StoryObj } from '@storybook/react'; 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'; import { Button } from 'antd';


// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export // 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` 函数打开 */ /** 推荐通过 `openAntdModal` 函数打开 */
export const OpenByFunction: Story = { export const OpenByFunction: Story = {
name: '通过函数的方式打开',
render: function Render() { render: function Render() {
const handleClick = () => { const handleClick = () => {
const { close } = openAntdModal(KFModal, { const { close } = openAntdModal(KFModal, {


+ 1
- 0
react-ui/src/stories/ResourceSelectorModal.stories.tsx View File

@@ -182,6 +182,7 @@ export const Mirror: Story = {


/** 通过 `openAntdModal` 函数打开 */ /** 通过 `openAntdModal` 函数打开 */
export const OpenByFunction: Story = { export const OpenByFunction: Story = {
name: '通过函数的方式打开',
args: { args: {
type: ResourceSelectorType.Mirror, type: ResourceSelectorType.Mirror,
}, },


+ 1
- 1
react-ui/src/stories/docs/Less.mdx View File

@@ -148,7 +148,7 @@ function CodeConfigItem({ item, onClick }: CodeConfigItemProps) {


``` ```


### 一建议
### 一建议


如果你陷入嵌套地狱,比如 如果你陷入嵌套地狱,比如




BIN
react-ui/static/favicon.ico View File

Before After

react-ui/public/mockServiceWorker.js → react-ui/static/mockServiceWorker.js View File


Loading…
Cancel
Save