diff --git a/react-ui/src/components/ParameterSelect/index.tsx b/react-ui/src/components/ParameterSelect/index.tsx index 2c9f862f..a6a911e5 100644 --- a/react-ui/src/components/ParameterSelect/index.tsx +++ b/react-ui/src/components/ParameterSelect/index.tsx @@ -4,22 +4,35 @@ * @Description: 参数下拉选择组件,支持资源规格、数据集、模型、服务 */ -import { PipelineNodeModelParameter } from '@/types'; import { to } from '@/utils/promise'; -import { Select } from 'antd'; +import { Select, type SelectProps } from 'antd'; import { useEffect, useState } from 'react'; import { paramSelectConfig } from './config'; -type ParameterSelectProps = { - value?: PipelineNodeModelParameter; - onChange?: (value: PipelineNodeModelParameter) => void; - disabled?: boolean; +/** 值类型 */ +export type ParameterSelectValue = { + /** 类型,参数名是和后台保持一致的 */ + item_type: 'dataset' | 'model' | 'service' | 'resource'; + /** 值 */ + value?: any; + /** 占位符 */ + placeholder?: string; + /** 其它属性 */ + [key: string]: any; }; -function ParameterSelect({ value, onChange, disabled = false }: ParameterSelectProps) { +interface ParameterSelectProps extends SelectProps { + /** 值 */ + value?: ParameterSelectValue; + /** 修改后回调 */ + onChange?: (value: ParameterSelectValue) => void; +} + +/** 参数选择器,支持资源规格、数据集、模型、服务 */ +function ParameterSelect({ value, onChange, ...rest }: ParameterSelectProps) { const [options, setOptions] = useState([]); - const valueNonNullable = value ?? ({} as PipelineNodeModelParameter); - const { item_type } = valueNonNullable; + const valueNotNullable = value ?? ({} as ParameterSelectValue); + const { item_type } = valueNotNullable; const propsConfig = paramSelectConfig[item_type]; useEffect(() => { @@ -28,7 +41,7 @@ function ParameterSelect({ value, onChange, disabled = false }: ParameterSelectP const hangleChange = (e: string) => { onChange?.({ - ...valueNonNullable, + ...valueNotNullable, value: e, }); }; @@ -47,14 +60,14 @@ function ParameterSelect({ value, onChange, disabled = false }: ParameterSelectP return ( { + return ( +
+ + {props.label} + +
+ ); + }} + disabled + options={[ + { + label: + '超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本', + value: 1, + }, + ]} + /> + ); }, diff --git a/react-ui/src/stories/ParameterSelect.stories.tsx b/react-ui/src/stories/ParameterSelect.stories.tsx new file mode 100644 index 00000000..6aed4e31 --- /dev/null +++ b/react-ui/src/stories/ParameterSelect.stories.tsx @@ -0,0 +1,126 @@ +import ParameterSelect, { ParameterSelectValue } from '@/components/ParameterSelect'; +import { useArgs } from '@storybook/preview-api'; +import type { Meta, StoryObj } from '@storybook/react'; +import { fn } from '@storybook/test'; +import { Col, Form, Row } from 'antd'; +import { http, HttpResponse } from 'msw'; +import { computeResourceData, datasetListData, modelListData, serviceListData } from './mockData'; + +// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export +const meta = { + title: 'Components/ParameterSelect 参数选择器', + component: ParameterSelect, + parameters: { + // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout + // layout: 'centered', + msw: { + handlers: [ + http.get('/api/mmp/newdataset/queryDatasets', () => { + return HttpResponse.json(datasetListData); + }), + http.get('/api/mmp/newmodel/queryModels', () => { + return HttpResponse.json(modelListData); + }), + http.get('/api/mmp/service', () => { + return HttpResponse.json(serviceListData); + }), + http.get('/api/mmp/computingResource', () => { + return HttpResponse.json(computeResourceData); + }), + ], + }, + }, + // 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: { onChange: fn() }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args +export const Primary: Story = { + args: { + value: { + item_type: 'dataset', + placeholder: '请选择数据集', + }, + style: { width: 400 }, + size: 'large', + }, + render: function Render(args) { + const [{ value }, updateArgs] = useArgs(); + function handleChange(value?: ParameterSelectValue) { + updateArgs({ value: value }); + args.onChange?.(value); + } + + return ; + }, +}; + +export const InForm: Story = { + render: ({ onChange }) => { + return ( +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ ); + }, +}; diff --git a/react-ui/src/stories/mockData.ts b/react-ui/src/stories/mockData.ts index 3d910b06..11b5ffa2 100644 --- a/react-ui/src/stories/mockData.ts +++ b/react-ui/src/stories/mockData.ts @@ -546,3 +546,250 @@ export const codeListData = { empty: false, }, }; + +export const serviceListData = { + code: 200, + msg: '操作成功', + data: { + content: [ + { + id: 25, + service_name: '测试1224', + service_type: 'video', + service_type_name: '视频', + description: '测试', + create_by: 'admin', + update_by: 'admin', + create_time: '2024-12-24T16:01:02.000+08:00', + update_time: '2024-12-24T16:01:02.000+08:00', + state: 1, + version_count: 2, + }, + { + id: 12, + service_name: '介电材料', + service_type: 'text', + service_type_name: '文本', + description: 'test', + create_by: 'admin', + update_by: 'admin', + create_time: '2024-11-27T09:30:23.000+08:00', + update_time: '2024-11-27T09:30:23.000+08:00', + state: 1, + version_count: 0, + }, + { + id: 7, + service_name: '手写体识别', + service_type: 'image', + service_type_name: '图片', + description: '手写体识别服务', + create_by: 'admin', + update_by: 'admin', + create_time: '2024-10-10T10:14:00.000+08:00', + update_time: '2024-10-10T10:14:00.000+08:00', + state: 1, + version_count: 5, + }, + ], + pageable: { + sort: { + unsorted: true, + sorted: false, + empty: true, + }, + pageNumber: 0, + pageSize: 10, + offset: 0, + paged: true, + unpaged: false, + }, + last: true, + totalPages: 1, + totalElements: 3, + sort: { + unsorted: true, + sorted: false, + empty: true, + }, + first: true, + number: 0, + numberOfElements: 3, + size: 10, + empty: false, + }, +}; + +export const computeResourceData = { + code: 200, + msg: '操作成功', + data: { + content: [ + { + id: 15, + computing_resource: 'GPU', + standard: + '{"name":"CPU-GPU","value":{"detail_type":"3060","gpu":0,"cpu":1,"memory":"2GB"}}', + description: 'GPU: 0, CPU:1, 内存: 2GB', + create_by: 'admin', + create_time: '2024-04-19T00:00:00.000+08:00', + update_by: 'admin', + update_time: '2024-04-19T00:00:00.000+08:00', + state: 1, + used_state: null, + node: null, + }, + { + id: 16, + computing_resource: 'GPU', + standard: + '{"name":"CPU-GPU","value":{"detail_type":"3060","gpu":0,"cpu":2,"memory":"4GB"}}', + description: 'GPU: 0, CPU:2, 内存: 4GB', + create_by: 'admin', + create_time: '2024-04-19T00:00:00.000+08:00', + update_by: 'admin', + update_time: '2024-04-19T00:00:00.000+08:00', + state: 1, + used_state: null, + node: null, + }, + { + id: 17, + computing_resource: 'GPU', + standard: + '{"name":"CPU-GPU","value":{"detail_type":"3060","gpu":0,"cpu":4,"memory":"8GB"}}', + description: 'GPU: 0, CPU:4, 内存: 8GB', + create_by: 'admin', + create_time: '2024-04-19T00:00:00.000+08:00', + update_by: 'admin', + update_time: '2024-04-19T00:00:00.000+08:00', + state: 1, + used_state: null, + node: null, + }, + { + id: 18, + computing_resource: 'GPU', + standard: + '{"name":"CPU-GPU","value":{"detail_type":"3060","gpu":1,"cpu":1,"memory":"2GB"}}', + description: 'GPU: 1, CPU:1, 内存: 2GB', + create_by: 'admin', + create_time: '2024-04-19T00:00:00.000+08:00', + update_by: 'admin', + update_time: '2024-04-19T00:00:00.000+08:00', + state: 1, + used_state: null, + node: null, + }, + { + id: 19, + computing_resource: 'GPU', + standard: + '{"name":"CPU-GPU","value":{"detail_type":"3060","gpu":1,"cpu":2,"memory":"4GB"}}', + description: 'GPU: 1, CPU:2, 内存: 4GB', + create_by: 'admin', + create_time: '2024-04-19T00:00:00.000+08:00', + update_by: 'admin', + update_time: '2024-04-19T00:00:00.000+08:00', + state: 1, + used_state: null, + node: null, + }, + { + id: 20, + computing_resource: 'GPU', + standard: + '{"name":"CPU-GPU","value":{"detail_type":"3060","gpu":1,"cpu":4,"memory":"8GB"}}', + description: 'GPU: 1, CPU:4, 内存: 8GB', + create_by: 'admin', + create_time: '2024-04-19T00:00:00.000+08:00', + update_by: 'admin', + update_time: '2024-04-19T00:00:00.000+08:00', + state: 1, + used_state: null, + node: null, + }, + { + id: 21, + computing_resource: 'GPU', + standard: + '{"name":"CPU-GPU","value":{"detail_type":"3060","gpu":2,"cpu":2,"memory":"4GB"}}', + description: 'GPU: 2, CPU:2, 内存: 4GB', + create_by: 'admin', + create_time: '2024-04-19T00:00:00.000+08:00', + update_by: 'admin', + update_time: '2024-04-19T00:00:00.000+08:00', + state: 1, + used_state: null, + node: null, + }, + { + id: 22, + computing_resource: 'GPU', + standard: + '{"name":"CPU-GPU","value":{"detail_type":"3060","gpu":2,"cpu":4,"memory":"8GB"}}', + description: 'GPU: 2, CPU:4, 内存: 8GB', + create_by: 'admin', + create_time: '2024-04-19T00:00:00.000+08:00', + update_by: 'admin', + update_time: '2024-04-19T00:00:00.000+08:00', + state: 1, + used_state: null, + node: null, + }, + { + id: 23, + computing_resource: 'GPU', + standard: + '{"name":"CPU-GPU","value":{"detail_type":"RTX 3080 Ti","gpu":1,"cpu":1,"memory":"2GB"}}', + description: 'GPU: 1, CPU:1, 内存: 2GB, 显存: 12GB', + create_by: 'admin', + create_time: '2024-04-19T11:38:07.000+08:00', + update_by: 'admin', + update_time: '2024-04-19T11:38:07.000+08:00', + state: 1, + used_state: null, + node: null, + }, + { + id: 24, + computing_resource: 'GPU', + standard: + '{"name":"CPU-GPU","value":{"detail_type":"RTX 3080","gpu":1,"cpu":2,"memory":"4GB"}}', + description: 'GPU: 1, CPU:2, 内存: 4GB, 显存: 10GB', + create_by: 'admin', + create_time: '2024-04-19T11:39:40.000+08:00', + update_by: 'admin', + update_time: '2024-04-19T11:39:40.000+08:00', + state: 1, + used_state: null, + node: null, + }, + ], + pageable: { + sort: { + unsorted: true, + sorted: false, + empty: true, + }, + pageNumber: 0, + pageSize: 1000, + offset: 0, + paged: true, + unpaged: false, + }, + last: true, + totalPages: 1, + totalElements: 10, + sort: { + unsorted: true, + sorted: false, + empty: true, + }, + first: true, + number: 0, + numberOfElements: 10, + size: 1000, + empty: false, + }, +};