Browse Source

Merge remote-tracking branch 'origin/dev' into dev-ray

dev-ray
chenzhihang 11 months ago
parent
commit
90ff5e8e76
40 changed files with 215 additions and 268 deletions
  1. +19
    -0
      react-ui/.storybook/blocks/StoryName.tsx
  2. +1
    -1
      react-ui/.storybook/main.ts
  3. +6
    -0
      react-ui/.storybook/manager.ts
  4. +7
    -0
      react-ui/.storybook/theme.ts
  5. +4
    -2
      react-ui/package.json
  6. +0
    -0
      react-ui/public/mockServiceWorker.js
  7. +6
    -0
      react-ui/src/components/BasicInfo/index.tsx
  8. +25
    -6
      react-ui/src/components/FormInfo/index.tsx
  9. +3
    -3
      react-ui/src/hooks/resource.ts
  10. +1
    -1
      react-ui/src/pages/AutoML/Instance/index.tsx
  11. +2
    -2
      react-ui/src/pages/DevelopmentEnvironment/components/CreateMirrorModal/index.tsx
  12. +1
    -1
      react-ui/src/pages/Experiment/components/LogGroup/index.tsx
  13. +9
    -10
      react-ui/src/pages/HyperParameter/Instance/index.tsx
  14. +1
    -1
      react-ui/src/pages/HyperParameter/components/CreateForm/ExecuteConfig.tsx
  15. +1
    -1
      react-ui/src/pages/HyperParameter/types.ts
  16. +2
    -2
      react-ui/src/pages/Mirror/Create/index.tsx
  17. +1
    -1
      react-ui/src/pages/ModelDeployment/CreateVersion/index.tsx
  18. +1
    -1
      react-ui/src/stories/BasicInfo.stories.tsx
  19. +1
    -1
      react-ui/src/stories/BasicTableInfo.stories.tsx
  20. +1
    -1
      react-ui/src/stories/CodeSelect.stories.tsx
  21. +3
    -35
      react-ui/src/stories/CodeSelectorModal.stories.tsx
  22. +1
    -1
      react-ui/src/stories/Config.stories.tsx
  23. +20
    -42
      react-ui/src/stories/FormInfo.stories.tsx
  24. +1
    -1
      react-ui/src/stories/FullScreenFrame.stories.tsx
  25. +1
    -1
      react-ui/src/stories/IFramePage.stories.tsx
  26. +1
    -1
      react-ui/src/stories/InfoGroup.stories.tsx
  27. +1
    -1
      react-ui/src/stories/KFEmpty.stories.tsx
  28. +1
    -1
      react-ui/src/stories/KFIcon.stories.tsx
  29. +1
    -1
      react-ui/src/stories/KFModal.stories.tsx
  30. +1
    -1
      react-ui/src/stories/KFRadio.stories.tsx
  31. +1
    -1
      react-ui/src/stories/KFSpin.stories.tsx
  32. +1
    -1
      react-ui/src/stories/MenuIconSelector.stories.tsx
  33. +1
    -1
      react-ui/src/stories/PageTitle.stories.tsx
  34. +1
    -1
      react-ui/src/stories/ParameterInput.stories.tsx
  35. +1
    -1
      react-ui/src/stories/ResourceSelect.stories.tsx
  36. +20
    -6
      react-ui/src/stories/ResourceSelectorModal.mdx
  37. +62
    -135
      react-ui/src/stories/ResourceSelectorModal.stories.tsx
  38. +1
    -1
      react-ui/src/stories/SubAreaTitle.stories.tsx
  39. +4
    -2
      react-ui/src/utils/format.ts
  40. BIN
      react-ui/static/favicon.ico

+ 19
- 0
react-ui/.storybook/blocks/StoryName.tsx View File

@@ -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 <h3 className="css-wzniqs">{resolvedOf.story.name}</h3>;
}
case 'meta': {
return <h3 className="css-wzniqs">{resolvedOf.preparedMeta.title}</h3>;
}
}
};

+ 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: ['../static'],
staticDirs: ['../public'],
docs: { docs: {
defaultName: 'Documentation', defaultName: 'Documentation',
}, },


+ 6
- 0
react-ui/.storybook/manager.ts View File

@@ -0,0 +1,6 @@
import { addons } from '@storybook/manager-api';
import theme from './theme';

addons.setConfig({
theme: theme,
});

+ 7
- 0
react-ui/.storybook/theme.ts View File

@@ -0,0 +1,7 @@
import { create } from '@storybook/theming';
export default create({
base: 'light',
brandTitle: '组件库文档',
brandUrl: 'https://storybook.js.org/docs',
brandTarget: '_blank',
});

+ 4
- 2
react-ui/package.json View File

@@ -8,7 +8,7 @@
"build": "max build", "build": "max build",
"deploy": "npm run build && npm run gh-pages", "deploy": "npm run build && npm run gh-pages",
"dev": "npm run start:dev", "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-hub:build": "docker build -f Dockerfile.hub -t ant-design-pro ./",
"docker-prod:build": "docker-compose -f ./docker/docker-compose.yml build", "docker-prod:build": "docker-compose -f ./docker/docker-compose.yml build",
"docker-prod:dev": "docker-compose -f ./docker/docker-compose.yml up", "docker-prod:dev": "docker-compose -f ./docker/docker-compose.yml up",
@@ -96,9 +96,11 @@
"@storybook/addon-webpack5-compiler-babel": "~3.0.5", "@storybook/addon-webpack5-compiler-babel": "~3.0.5",
"@storybook/addon-webpack5-compiler-swc": "~2.0.0", "@storybook/addon-webpack5-compiler-swc": "~2.0.0",
"@storybook/blocks": "~8.5.3", "@storybook/blocks": "~8.5.3",
"@storybook/manager-api": "~8.6.0",
"@storybook/react": "~8.5.3", "@storybook/react": "~8.5.3",
"@storybook/react-webpack5": "~8.5.3", "@storybook/react-webpack5": "~8.5.3",
"@storybook/test": "~8.5.3", "@storybook/test": "~8.5.3",
"@storybook/theming": "~8.6.0",
"@testing-library/react": "^14.0.0", "@testing-library/react": "^14.0.0",
"@types/antd": "^1.0.0", "@types/antd": "^1.0.0",
"@types/express": "^4.17.14", "@types/express": "^4.17.14",
@@ -166,7 +168,7 @@
}, },
"msw": { "msw": {
"workerDirectory": [ "workerDirectory": [
"static"
"public"
] ]
} }
} }

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


+ 6
- 0
react-ui/src/components/BasicInfo/index.tsx View File

@@ -24,6 +24,12 @@ export type BasicInfoProps = {


/** /**
* 基础信息展示组件,用于展示基础信息,支持一行两列或一行三列,支持数据格式化 * 基础信息展示组件,用于展示基础信息,支持一行两列或一行三列,支持数据格式化
*
* ### usage
* ```tsx
* import { BasicInfo } from '@/components/BasicInfo';
* <BasicInfo datas={datas} labelWidth={80} />
* ```
*/ */
export default function BasicInfo({ export default function BasicInfo({
datas, datas,


+ 25
- 6
react-ui/src/components/FormInfo/index.tsx View File

@@ -1,3 +1,4 @@
import { formatEnum } from '@/utils/format';
import { Typography } from 'antd'; import { Typography } from 'antd';
import classNames from 'classnames'; import classNames from 'classnames';
import './index.less'; import './index.less';
@@ -7,8 +8,12 @@ type FormInfoProps = {
value?: any; value?: any;
/** 如果 `value` 是对象时,取对象的哪个属性作为值 */ /** 如果 `value` 是对象时,取对象的哪个属性作为值 */
valuePropName?: string; valuePropName?: string;
/** 是否是多行 */
multiline?: boolean;
/** 是否是多行文本 */
textArea?: boolean;
/** 是否是下拉框 */
select?: boolean;
/** 下拉框数据 */
options?: { label: string; value: any }[];
/** 自定义类名 */ /** 自定义类名 */
className?: string; className?: string;
/** 自定义样式 */ /** 自定义样式 */
@@ -18,20 +23,34 @@ type FormInfoProps = {
/** /**
* 模拟禁用的输入框,但是内容超长时,hover 时显示所有内容 * 模拟禁用的输入框,但是内容超长时,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 ( return (
<div <div
className={classNames( className={classNames(
'form-info', 'form-info',
{ {
'form-info--multiline': multiline,
'form-info--multiline': textArea,
}, },
className, className,
)} )}
style={style} style={style}
> >
<Typography.Paragraph ellipsis={multiline ? false : { tooltip: data }}>
<Typography.Paragraph ellipsis={textArea ? false : { tooltip: data }}>
{data} {data}
</Typography.Paragraph> </Typography.Paragraph>
</div> </div>


+ 3
- 3
react-ui/src/hooks/resource.ts View File

@@ -15,11 +15,11 @@ import { useSnapshot } from 'umi';
// 获取资源规格 // 获取资源规格
export function useComputingResource() { export function useComputingResource() {
const [resourceStandardList, setResourceStandardList] = useState<ComputingResource[]>([]); const [resourceStandardList, setResourceStandardList] = useState<ComputingResource[]>([]);
const computingResourceSnap = useSnapshot(computingResourceState);
const snap = useSnapshot(computingResourceState);


useEffect(() => { useEffect(() => {
if (computingResourceSnap.computingResource.length > 0) {
setResourceStandardList(computingResourceSnap.computingResource as ComputingResource[]);
if (snap.computingResource.length > 0) {
setResourceStandardList(snap.computingResource as ComputingResource[]);
} else { } else {
getComputingResource(); getComputingResource();
} }


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

@@ -83,7 +83,7 @@ function AutoMLInstance() {
const setupSSE = (name: string, namespace: string) => { const setupSSE = (name: string, namespace: string) => {
let { origin } = location; let { origin } = location;
if (process.env.NODE_ENV === 'development') { 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 params = encodeURIComponent(`metadata.namespace=${namespace},metadata.name=${name}`);
const evtSource = new EventSource( const evtSource = new EventSource(


+ 2
- 2
react-ui/src/pages/DevelopmentEnvironment/components/CreateMirrorModal/index.tsx View File

@@ -67,8 +67,8 @@ function CreateMirrorModal({ envId, onOk, ...rest }: CreateMirrorModalProps) {
message: '请输入镜像Tag', message: '请输入镜像Tag',
}, },
{ {
pattern: /^[a-zA-Z0-9_-]*$/,
message: '只支持字母、数字、下划线(_)、中横线(-)',
pattern: /^[a-zA-Z0-9._-]+$/,
message: '版本只支持字母、数字、点(.)、下划线(_)、中横线(-)',
}, },
]} ]}
> >


+ 1
- 1
react-ui/src/pages/Experiment/components/LogGroup/index.tsx View File

@@ -135,7 +135,7 @@ function LogGroup({
const setupSockect = () => { const setupSockect = () => {
let { host } = location; let { host } = location;
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {
host = '172.20.32.181:31213';
host = '172.20.32.197:31213';
} }
const socket = new WebSocket( const socket = new WebSocket(
`ws://${host}/newlog/realtimeLog?start=${start_time}&query={pod="${pod_name}"}`, `ws://${host}/newlog/realtimeLog?start=${start_time}&query={pod="${pod_name}"}`,


+ 9
- 10
react-ui/src/pages/HyperParameter/Instance/index.tsx View File

@@ -1,7 +1,7 @@
import KFIcon from '@/components/KFIcon'; import KFIcon from '@/components/KFIcon';
import { AutoMLTaskType, ExperimentStatus } from '@/enums'; import { AutoMLTaskType, ExperimentStatus } from '@/enums';
import LogList from '@/pages/Experiment/components/LogList'; import LogList from '@/pages/Experiment/components/LogList';
import { getExperimentInsReq } from '@/services/autoML';
import { getRayInsReq } from '@/services/hyperParameter';
import { NodeStatus } from '@/types'; import { NodeStatus } from '@/types';
import { parseJsonText } from '@/utils'; import { parseJsonText } from '@/utils';
import { safeInvoke } from '@/utils/functional'; import { safeInvoke } from '@/utils/functional';
@@ -22,12 +22,11 @@ enum TabKeys {
History = 'history', History = 'history',
} }


function AutoMLInstance() {
function HyperParameterInstance() {
const [activeTab, setActiveTab] = useState<string>(TabKeys.Params); 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 [instanceInfo, setInstanceInfo] = useState<AutoMLInstanceData | undefined>(undefined);
const params = useParams(); const params = useParams();
// const autoMLId = safeInvoke(Number)(params.autoMLId);
const instanceId = safeInvoke(Number)(params.id); const instanceId = safeInvoke(Number)(params.id);
const evtSourceRef = useRef<EventSource | null>(null); const evtSourceRef = useRef<EventSource | null>(null);


@@ -42,14 +41,14 @@ function AutoMLInstance() {


// 获取实验实例详情 // 获取实验实例详情
const getExperimentInsInfo = async (isStatusDetermined: boolean) => { const getExperimentInsInfo = async (isStatusDetermined: boolean) => {
const [res] = await to(getExperimentInsReq(instanceId));
const [res] = await to(getRayInsReq(instanceId));
if (res && res.data) { if (res && res.data) {
const info = res.data as AutoMLInstanceData; const info = res.data as AutoMLInstanceData;
const { param, node_status, argo_ins_name, argo_ins_ns, status } = info; const { param, node_status, argo_ins_name, argo_ins_ns, status } = info;
// 解析配置参数 // 解析配置参数
const paramJson = parseJsonText(param); const paramJson = parseJsonText(param);
if (paramJson) { if (paramJson) {
setAutoMLInfo(paramJson);
setExperimentInfo(paramJson);
} }


// 这个接口返回的状态有延时,SSE 返回的状态是最新的 // 这个接口返回的状态有延时,SSE 返回的状态是最新的
@@ -83,7 +82,7 @@ function AutoMLInstance() {
const setupSSE = (name: string, namespace: string) => { const setupSSE = (name: string, namespace: string) => {
let { origin } = location; let { origin } = location;
if (process.env.NODE_ENV === 'development') { 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 params = encodeURIComponent(`metadata.namespace=${namespace},metadata.name=${name}`);
const evtSource = new EventSource( const evtSource = new EventSource(
@@ -142,7 +141,7 @@ function AutoMLInstance() {
children: ( children: (
<HyperParameterBasic <HyperParameterBasic
className={styles['auto-ml-instance__basic']} className={styles['auto-ml-instance__basic']}
info={autoMLInfo}
info={experimentInfo}
runStatus={instanceInfo?.nodeStatus} runStatus={instanceInfo?.nodeStatus}
isInstance isInstance
/> />
@@ -189,7 +188,7 @@ function AutoMLInstance() {
children: ( children: (
<ExperimentHistory <ExperimentHistory
fileUrl={instanceInfo?.run_history_path} 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;

+ 1
- 1
react-ui/src/pages/HyperParameter/components/CreateForm/ExecuteConfig.tsx View File

@@ -109,7 +109,7 @@ function ExecuteConfig() {
<Col span={10}> <Col span={10}>
<Form.Item <Form.Item
label="代码配置" label="代码配置"
name="code"
name="code_config"
rules={[ rules={[
{ {
validator: requiredValidator, validator: requiredValidator,


+ 1
- 1
react-ui/src/pages/HyperParameter/types.ts View File

@@ -12,7 +12,7 @@ export enum OperationType {
export type FormData = { export type FormData = {
name: string; // 实验名称 name: string; // 实验名称
description: string; // 实验描述 description: string; // 实验描述
code: ParameterInputObject; // 代码
code_config: ParameterInputObject; // 代码
dataset: ParameterInputObject; // 数据集 dataset: ParameterInputObject; // 数据集
model: ParameterInputObject; // 模型 model: ParameterInputObject; // 模型
image: ParameterInputObject; // 镜像 image: ParameterInputObject; // 镜像


+ 2
- 2
react-ui/src/pages/Mirror/Create/index.tsx View File

@@ -177,8 +177,8 @@ function MirrorCreate() {
message: '请输入镜像Tag', message: '请输入镜像Tag',
}, },
{ {
pattern: /^[a-zA-Z0-9_-]*$/,
message: '只支持字母、数字、下划线(_)、中横线(-)',
pattern: /^[a-zA-Z0-9._-]+$/,
message: '版本只支持字母、数字、点(.)、下划线(_)、中横线(-)',
}, },
]} ]}
> >


+ 1
- 1
react-ui/src/pages/ModelDeployment/CreateVersion/index.tsx View File

@@ -247,7 +247,7 @@ function CreateServiceVersion() {
}, },
{ {
pattern: /^[a-zA-Z0-9._-]+$/, pattern: /^[a-zA-Z0-9._-]+$/,
message: '版本只支持字母、数字、点、下划线、中横线',
message: '版本只支持字母、数字、点(.)、下划线(_)、中横线(-)',
}, },
]} ]}
> >


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

@@ -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 // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = { const meta = {
title: 'Components/BasicInfo',
title: 'Components/BasicInfo 基本信息',
component: BasicInfo, component: BasicInfo,
parameters: { parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout


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

@@ -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 // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = { const meta = {
title: 'Components/BasicTableInfo',
title: 'Components/BasicTableInfo 表格基本信息',
component: BasicTableInfo, component: BasicTableInfo,
parameters: { parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout


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

@@ -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 // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = { const meta = {
title: 'Components/CodeSelect',
title: 'Components/CodeSelect 代码配置选择器',
component: CodeSelect, component: CodeSelect,
parameters: { parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout


+ 3
- 35
react-ui/src/stories/CodeSelectorModal.stories.tsx View File

@@ -1,6 +1,5 @@
import CodeSelectorModal from '@/components/CodeSelectorModal'; import CodeSelectorModal from '@/components/CodeSelectorModal';
import { openAntdModal } from '@/utils/modal'; import { openAntdModal } from '@/utils/modal';
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 { fn } from '@storybook/test';
import { Button } from 'antd'; 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 // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = { const meta = {
title: 'Components/CodeSelectorModal',
title: 'Components/CodeSelectorModal 代码选择对话框',
component: CodeSelectorModal, component: CodeSelectorModal,
parameters: { parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout // 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<typeof meta>; type Story = StoryObj<typeof meta>;


// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args // 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 (
<>
<Button type="primary" onClick={onClick}>
选择代码配置
</Button>
<CodeSelectorModal {...args} open={open} onOk={handleOk} onCancel={handleCancel} />
</>
);
},
};

/** 通过 `openAntdModal` 函数打开 */
export const OpenByFunction: Story = {
name: '通过函数的方式打开',
export const Primary: Story = {
render: function Render(args) { render: function Render(args) {
const handleClick = () => { const handleClick = () => {
const { close } = openAntdModal(CodeSelectorModal, { const { close } = openAntdModal(CodeSelectorModal, {
@@ -84,7 +52,7 @@ export const OpenByFunction: Story = {
}; };
return ( return (
<Button type="primary" onClick={handleClick}> <Button type="primary" onClick={handleClick}>
以函数的方式打开
选择代码配置
</Button> </Button>
); );
}, },


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

@@ -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 // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = { const meta = {
title: 'Components/ConfigInfo',
title: 'Components/ConfigInfo 配置信息',
component: ConfigInfo, component: ConfigInfo,
parameters: { parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout


+ 20
- 42
react-ui/src/stories/FormInfo.stories.tsx View File

@@ -1,10 +1,10 @@
import FormInfo from '@/components/FormInfo'; import FormInfo from '@/components/FormInfo';
import type { Meta, StoryObj } from '@storybook/react'; 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 // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = { const meta = {
title: 'Components/FormInfo',
title: 'Components/FormInfo 表单信息',
component: FormInfo, component: FormInfo,
parameters: { parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout
@@ -24,6 +24,14 @@ export default meta;
type Story = StoryObj<typeof meta>; type Story = StoryObj<typeof meta>;


// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args // 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 = { export const InForm: Story = {
render: () => { render: () => {
return ( return (
@@ -40,11 +48,10 @@ export const InForm: Story = {
value: 1, value: 1,
showValue: '对象文本', showValue: '对象文本',
}, },
input_text:
'超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本',
antd_select: 1,
select_text: 1, select_text: 1,
select_large_text: 1,
ant_input_text:
'超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本',
ant_select_text: 1,
}} }}
> >
<Form.Item label="文本" name="text"> <Form.Item label="文本" name="text">
@@ -54,7 +61,7 @@ export const InForm: Story = {
<FormInfo /> <FormInfo />
</Form.Item> </Form.Item>
<Form.Item label="多行文本" name="multiline_text"> <Form.Item label="多行文本" name="multiline_text">
<FormInfo multiline />
<FormInfo textArea />
</Form.Item> </Form.Item>
<Form.Item label="对象" name="object_text"> <Form.Item label="对象" name="object_text">
<FormInfo valuePropName="showValue" /> <FormInfo valuePropName="showValue" />
@@ -62,12 +69,9 @@ export const InForm: Story = {
<Form.Item label="无内容" name="empty_text"> <Form.Item label="无内容" name="empty_text">
<FormInfo /> <FormInfo />
</Form.Item> </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={[ options={[
{ {
label: label:
@@ -77,37 +81,11 @@ export const InForm: Story = {
]} ]}
/> />
</Form.Item> </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>
<Form.Item label="Long Select" name="select_large_text">
<Form.Item label="Select" name="ant_select_text">
<Select <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 disabled
options={[ options={[
{ {


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

@@ -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 // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = { const meta = {
title: 'Components/FullScreenFrame',
title: 'Components/FullScreenFrame 全屏iframe',
component: FullScreenFrame, component: FullScreenFrame,
parameters: { parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout


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

@@ -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 // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = { const meta = {
title: 'Components/IFramePage',
title: 'Components/IFramePage iframe页面',
component: IFramePage, component: IFramePage,
parameters: { parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout


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

@@ -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 // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = { const meta = {
title: 'Components/InfoGroup',
title: 'Components/InfoGroup 信息分组',
component: InfoGroup, component: InfoGroup,
parameters: { parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout


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

@@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react';
import { fn } from '@storybook/test'; import { fn } from '@storybook/test';
// 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
const meta = { const meta = {
title: 'Components/KFEmpty',
title: 'Components/KFEmpty 空状态',
component: KFEmpty, component: KFEmpty,
parameters: { parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout


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

@@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react';
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
const meta = { const meta = {
title: 'Components/KFIcon',
title: 'Components/KFIcon 图标',
component: KFIcon, component: KFIcon,
parameters: { parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout


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

@@ -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 // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = { const meta = {
title: 'Components/KFModal',
title: 'Components/KFModal 对话框',
component: KFModal, component: KFModal,
parameters: { parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout


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

@@ -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 // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = { const meta = {
title: 'Components/KFRadio',
title: 'Components/KFRadio 单选框',
component: KFRadio, component: KFRadio,
parameters: { parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout


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

@@ -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 // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = { const meta = {
title: 'Components/KFSpin',
title: 'Components/KFSpin 加载器',
component: KFSpin, component: KFSpin,
parameters: { parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout


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

@@ -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 // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = { const meta = {
title: 'Components/MenuIconSelector',
title: 'Components/MenuIconSelector 菜单图标选择器',
component: MenuIconSelector, component: MenuIconSelector,
parameters: { parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout


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

@@ -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 // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = { const meta = {
title: 'Components/PageTitle',
title: 'Components/PageTitle 页面标题',
component: PageTitle, component: PageTitle,
parameters: { parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout


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

@@ -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 // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = { const meta = {
title: 'Components/ParameterInput',
title: 'Components/ParameterInput 参数输入框',
component: ParameterInput, component: ParameterInput,
parameters: { parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout


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

@@ -21,7 +21,7 @@ import {


// 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
const meta = { const meta = {
title: 'Components/ResourceSelect',
title: 'Components/ResourceSelect 资源选择器',
component: ResourceSelect, component: ResourceSelect,
parameters: { parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout


+ 20
- 6
react-ui/src/stories/ResourceSelectorModal.mdx View File

@@ -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 * as ResourceSelectorModalStories from "./ResourceSelectorModal.stories"
import { StoryName } from "../../.storybook/blocks/StoryName"

<Meta of={ResourceSelectorModalStories} />

<Title />
<Subtitle />
<Description />
<Meta of={ResourceSelectorModalStories} name="Usage" />
# Usage
### Usage
推荐通过 `openAntdModal` 函数打开 `ResourceSelectorModal`,打开 -> 处理 -> 关闭,整套代码在同一个地方 推荐通过 `openAntdModal` 函数打开 `ResourceSelectorModal`,打开 -> 处理 -> 关闭,整套代码在同一个地方


```ts ```ts
import { openAntdModal } from '@/utils/modal';
import ResourceSelectorModal } from '@/components/ResourceSelectorModal';

// 打开资源选择对话框
const handleClick = () => { const handleClick = () => {
const { close } = openAntdModal(ResourceSelectorModal, { const { close } = openAntdModal(ResourceSelectorModal, {
type: ResourceSelectorType.Dataset, type: ResourceSelectorType.Dataset,
@@ -18,6 +27,11 @@ const handleClick = () => {
}); });
``` ```


<Canvas of={ResourceSelectorModalStories.OpenByFunction} />
### Primary

<Primary />

<Controls />

<Stories of={ResourceSelectorModalStories} />

+ 62
- 135
react-ui/src/stories/ResourceSelectorModal.stories.tsx View File

@@ -1,6 +1,5 @@
import ResourceSelectorModal, { ResourceSelectorType } from '@/components/ResourceSelectorModal'; import ResourceSelectorModal, { ResourceSelectorType } from '@/components/ResourceSelectorModal';
import { openAntdModal } from '@/utils/modal'; import { openAntdModal } from '@/utils/modal';
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 { fn } from '@storybook/test';
import { Button } from 'antd'; 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 // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = { const meta = {
title: 'Components/ResourceSelectorModal',
title: 'Components/ResourceSelectorModal 资源选择对话框',
component: ResourceSelectorModal, component: ResourceSelectorModal,
parameters: { parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout
layout: 'centered', 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 // 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 // More on argTypes: https://storybook.js.org/docs/api/argtypes
argTypes: { argTypes: {
// backgroundColor: { control: 'color' }, // backgroundColor: { control: 'color' },
@@ -45,158 +72,58 @@ export default meta;
type Story = StoryObj<typeof meta>; type Story = StoryObj<typeof meta>;


// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args // More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
/** 选择数据集 */
export const Dataset: Story = { export const Dataset: Story = {
args: { args: {
type: ResourceSelectorType.Dataset, 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 ( 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 = { export const Model: Story = {
args: { args: {
type: ResourceSelectorType.Model, 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 ( 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 = { export const Mirror: Story = {
args: { args: {
type: ResourceSelectorType.Mirror, 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) { render: function Render(args) {
const handleClick = () => { const handleClick = () => {
@@ -211,7 +138,7 @@ export const OpenByFunction: Story = {
}; };
return ( return (
<Button type="primary" onClick={handleClick}> <Button type="primary" onClick={handleClick}>
以函数的方式打开
选择镜像
</Button> </Button>
); );
}, },


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

@@ -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 // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = { const meta = {
title: 'Components/SubAreaTitle',
title: 'Components/SubAreaTitle 子区域标题',
component: SubAreaTitle, component: SubAreaTitle,
parameters: { parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout


+ 4
- 2
react-ui/src/utils/format.ts View File

@@ -122,10 +122,12 @@ export const formatBoolean = (value: boolean): string => {
return value ? '是' : '否'; 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) => { return (value: string | number) => {
const option = options.find((item) => item.value === value); const option = options.find((item) => item.value === value);
return option ? option.label : '--'; return option ? option.label : '--';


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

Before After

Loading…
Cancel
Save