| @@ -17,6 +17,7 @@ export enum ModelDeploymentStatus { | |||||
| Running = 'Running', // 运行中 | Running = 'Running', // 运行中 | ||||
| Stopped = 'Stopped', // 已停止 | Stopped = 'Stopped', // 已停止 | ||||
| Failed = 'Failed', // 失败 | Failed = 'Failed', // 失败 | ||||
| Pending = 'Pending', // 挂起中 | |||||
| } | } | ||||
| export const modelDeploymentStatusOptions = [ | export const modelDeploymentStatusOptions = [ | ||||
| @@ -25,4 +26,5 @@ export const modelDeploymentStatusOptions = [ | |||||
| { label: '运行中', value: ModelDeploymentStatus.Running }, | { label: '运行中', value: ModelDeploymentStatus.Running }, | ||||
| { label: '已停止', value: ModelDeploymentStatus.Stopped }, | { label: '已停止', value: ModelDeploymentStatus.Stopped }, | ||||
| { label: '失败', value: ModelDeploymentStatus.Failed }, | { label: '失败', value: ModelDeploymentStatus.Failed }, | ||||
| { label: '挂起中', value: ModelDeploymentStatus.Pending }, | |||||
| ]; | ]; | ||||
| @@ -126,13 +126,3 @@ export const useResetFormOnCloseModal = (form: FormInstance, open: boolean) => { | |||||
| } | } | ||||
| }, [form, prevOpen, open]); | }, [form, prevOpen, open]); | ||||
| }; | }; | ||||
| export const useInputModel = <T>(initialValue: T) => { | |||||
| const [value, setValue] = useState<T>(initialValue); | |||||
| const updateValue = useCallback((e: any) => { | |||||
| setValue(e.target?.value); | |||||
| }, []); | |||||
| return [value, updateValue]; | |||||
| }; | |||||
| @@ -4,6 +4,7 @@ import { to } from '@/utils/promise'; | |||||
| import { type SelectProps } from 'antd'; | import { type SelectProps } from 'antd'; | ||||
| import { useCallback, useEffect, useState } from 'react'; | import { useCallback, useEffect, useState } from 'react'; | ||||
| // 获取资源规格 | |||||
| export function useComputingResource() { | export function useComputingResource() { | ||||
| const [resourceStandardList, setResourceStandardList] = useState<ComputingResource[]>([]); | const [resourceStandardList, setResourceStandardList] = useState<ComputingResource[]>([]); | ||||
| @@ -1,6 +1,7 @@ | |||||
| import { getSessionStorageItem, removeSessionStorageItem } from '@/utils/sessionStorage'; | import { getSessionStorageItem, removeSessionStorageItem } from '@/utils/sessionStorage'; | ||||
| import { useEffect, useState } from 'react'; | import { useEffect, useState } from 'react'; | ||||
| // 获取缓存数据 | |||||
| export function useSessionStorage<T>(key: string, isObject: boolean, initialValue: T) { | export function useSessionStorage<T>(key: string, isObject: boolean, initialValue: T) { | ||||
| const [storage, setStorage] = useState<T>(initialValue); | const [storage, setStorage] = useState<T>(initialValue); | ||||
| @@ -7,6 +7,7 @@ import { getDictSelectOption } from '@/services/system/dict'; | |||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import { getFileListFromEvent, validateUploadFiles } from '@/utils/ui'; | import { getFileListFromEvent, validateUploadFiles } from '@/utils/ui'; | ||||
| import { | import { | ||||
| App, | |||||
| Button, | Button, | ||||
| Form, | Form, | ||||
| Input, | Input, | ||||
| @@ -14,7 +15,6 @@ import { | |||||
| Select, | Select, | ||||
| Upload, | Upload, | ||||
| UploadFile, | UploadFile, | ||||
| message, | |||||
| type ModalProps, | type ModalProps, | ||||
| type UploadProps, | type UploadProps, | ||||
| } from 'antd'; | } from 'antd'; | ||||
| @@ -32,6 +32,7 @@ interface AddDatasetModalProps extends Omit<ModalProps, 'onOk'> { | |||||
| function AddDatasetModal({ typeList, tagList, onOk, ...rest }: AddDatasetModalProps) { | function AddDatasetModal({ typeList, tagList, onOk, ...rest }: AddDatasetModalProps) { | ||||
| const [uuid] = useState(Date.now()); | const [uuid] = useState(Date.now()); | ||||
| const [clusterOptions, setClusterOptions] = useState<DictValueEnumObj[]>([]); | const [clusterOptions, setClusterOptions] = useState<DictValueEnumObj[]>([]); | ||||
| const { message } = App.useApp(); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| getClusterOptions(); | getClusterOptions(); | ||||
| @@ -6,13 +6,13 @@ import { addModel } from '@/services/dataset/index.js'; | |||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import { getFileListFromEvent, validateUploadFiles } from '@/utils/ui'; | import { getFileListFromEvent, validateUploadFiles } from '@/utils/ui'; | ||||
| import { | import { | ||||
| App, | |||||
| Button, | Button, | ||||
| Form, | Form, | ||||
| Input, | Input, | ||||
| Select, | Select, | ||||
| Upload, | Upload, | ||||
| UploadFile, | UploadFile, | ||||
| message, | |||||
| type ModalProps, | type ModalProps, | ||||
| type UploadProps, | type UploadProps, | ||||
| } from 'antd'; | } from 'antd'; | ||||
| @@ -28,6 +28,8 @@ interface AddModelModalProps extends Omit<ModalProps, 'onOk'> { | |||||
| function AddModelModal({ typeList, tagList, onOk, ...rest }: AddModelModalProps) { | function AddModelModal({ typeList, tagList, onOk, ...rest }: AddModelModalProps) { | ||||
| const [uuid] = useState(Date.now()); | const [uuid] = useState(Date.now()); | ||||
| const { message } = App.useApp(); | |||||
| // 上传组件参数 | // 上传组件参数 | ||||
| const uploadProps: UploadProps = { | const uploadProps: UploadProps = { | ||||
| action: '/api/mmp/models/upload', | action: '/api/mmp/models/upload', | ||||
| @@ -5,12 +5,12 @@ import { ResourceType, resourceConfig } from '@/pages/Dataset/types'; | |||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import { getFileListFromEvent, validateUploadFiles } from '@/utils/ui'; | import { getFileListFromEvent, validateUploadFiles } from '@/utils/ui'; | ||||
| import { | import { | ||||
| App, | |||||
| Button, | Button, | ||||
| Form, | Form, | ||||
| Input, | Input, | ||||
| Upload, | Upload, | ||||
| UploadFile, | UploadFile, | ||||
| message, | |||||
| type ModalProps, | type ModalProps, | ||||
| type UploadProps, | type UploadProps, | ||||
| } from 'antd'; | } from 'antd'; | ||||
| @@ -33,6 +33,7 @@ function AddVersionModal({ | |||||
| ...rest | ...rest | ||||
| }: AddVersionModalProps) { | }: AddVersionModalProps) { | ||||
| const [uuid] = useState(Date.now()); | const [uuid] = useState(Date.now()); | ||||
| const { message } = App.useApp(); | |||||
| // 上传组件参数 | // 上传组件参数 | ||||
| const uploadProps: UploadProps = { | const uploadProps: UploadProps = { | ||||
| @@ -5,7 +5,7 @@ import { openAntdModal } from '@/utils/modal'; | |||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import { modalConfirm } from '@/utils/ui'; | import { modalConfirm } from '@/utils/ui'; | ||||
| import { useNavigate } from '@umijs/max'; | import { useNavigate } from '@umijs/max'; | ||||
| import { Button, Input, Pagination, PaginationProps, message } from 'antd'; | |||||
| import { App, Button, Input, Pagination, PaginationProps } from 'antd'; | |||||
| import { Ref, forwardRef, useEffect, useImperativeHandle, useState } from 'react'; | import { Ref, forwardRef, useEffect, useImperativeHandle, useState } from 'react'; | ||||
| import { CategoryData, ResourceData, ResourceType, resourceConfig } from '../../types'; | import { CategoryData, ResourceData, ResourceType, resourceConfig } from '../../types'; | ||||
| import AddDatasetModal from '../AddDatasetModal'; | import AddDatasetModal from '../AddDatasetModal'; | ||||
| @@ -53,6 +53,7 @@ function ResourceList( | |||||
| ); | ); | ||||
| const [searchText, setSearchText] = useState(initialSearchText); | const [searchText, setSearchText] = useState(initialSearchText); | ||||
| const [inputText, setInputText] = useState(initialSearchText); | const [inputText, setInputText] = useState(initialSearchText); | ||||
| const { message } = App.useApp(); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| getDataList(); | getDataList(); | ||||
| @@ -11,7 +11,7 @@ import { downLoadZip } from '@/utils/downloadfile'; | |||||
| import { openAntdModal } from '@/utils/modal'; | import { openAntdModal } from '@/utils/modal'; | ||||
| import { modalConfirm } from '@/utils/ui'; | import { modalConfirm } from '@/utils/ui'; | ||||
| import { useParams, useSearchParams } from '@umijs/max'; | import { useParams, useSearchParams } from '@umijs/max'; | ||||
| import { Button, Input, Select, Table, Tabs, message } from 'antd'; | |||||
| import { App, Button, Input, Select, Table, Tabs } from 'antd'; | |||||
| import { useEffect, useRef, useState } from 'react'; | import { useEffect, useRef, useState } from 'react'; | ||||
| import AddVersionModal from './components/AddVersionModal'; | import AddVersionModal from './components/AddVersionModal'; | ||||
| import Styles from './intro.less'; | import Styles from './intro.less'; | ||||
| @@ -19,6 +19,7 @@ const { Search } = Input; | |||||
| const { TabPane } = Tabs; | const { TabPane } = Tabs; | ||||
| const Dataset = () => { | const Dataset = () => { | ||||
| const { message } = App.useApp(); | |||||
| const [formList, setFormList] = useState([]); | const [formList, setFormList] = useState([]); | ||||
| const [datasetDetailObj, setDatasetDetailObj] = useState({}); | const [datasetDetailObj, setDatasetDetailObj] = useState({}); | ||||
| const [version, setVersion] = useState(null); | const [version, setVersion] = useState(null); | ||||
| @@ -97,6 +97,11 @@ function AddExperimentModal({ | |||||
| wrapperCol: { span: 20 }, | wrapperCol: { span: 20 }, | ||||
| }; | }; | ||||
| const paramLayout = { | |||||
| labelCol: { span: 8 }, | |||||
| wrapperCol: { span: 16 }, | |||||
| }; | |||||
| // 除了流水线选择发生变化 | // 除了流水线选择发生变化 | ||||
| const handleWorkflowChange = (id: string | number) => { | const handleWorkflowChange = (id: string | number) => { | ||||
| const pipeline: Workflow | undefined = workflowList.find((v) => v.id === id); | const pipeline: Workflow | undefined = workflowList.find((v) => v.id === id); | ||||
| @@ -187,7 +192,7 @@ function AddExperimentModal({ | |||||
| fields.map(({ key, name, ...restField }) => ( | fields.map(({ key, name, ...restField }) => ( | ||||
| <Form.Item | <Form.Item | ||||
| {...restField} | {...restField} | ||||
| {...layout} | |||||
| {...paramLayout} | |||||
| key={key} | key={key} | ||||
| label={getParamType(globalParam[name])} | label={getParamType(globalParam[name])} | ||||
| name={[name, 'param_value']} | name={[name, 'param_value']} | ||||
| @@ -1,9 +1,7 @@ | |||||
| import SubAreaTitle from '@/components/SubAreaTitle'; | import SubAreaTitle from '@/components/SubAreaTitle'; | ||||
| import { getComputingResourceReq } from '@/services/pipeline'; | |||||
| import { useComputingResource } from '@/hooks/resource'; | |||||
| import { PipelineNodeModelSerialize } from '@/types'; | import { PipelineNodeModelSerialize } from '@/types'; | ||||
| import { to } from '@/utils/promise'; | |||||
| import { Form, Input, Select, type FormProps } from 'antd'; | import { Form, Input, Select, type FormProps } from 'antd'; | ||||
| import { useEffect, useState } from 'react'; | |||||
| import styles from './index.less'; | import styles from './index.less'; | ||||
| const { TextArea } = Input; | const { TextArea } = Input; | ||||
| @@ -13,24 +11,7 @@ type ExperimentParameterProps = { | |||||
| }; | }; | ||||
| function ExperimentParameter({ form, nodeData }: ExperimentParameterProps) { | function ExperimentParameter({ form, nodeData }: ExperimentParameterProps) { | ||||
| const [resourceStandardList, setResourceStandardList] = useState([]); // 资源规模列表 | |||||
| useEffect(() => { | |||||
| getComputingResource(); | |||||
| }, []); | |||||
| // 获取资源规格列表数据 | |||||
| const getComputingResource = async () => { | |||||
| const params = { | |||||
| page: 0, | |||||
| size: 1000, | |||||
| resource_type: '', | |||||
| }; | |||||
| const [res] = await to(getComputingResourceReq(params)); | |||||
| if (res && res.data && res.data.content) { | |||||
| setResourceStandardList(res.data.content); | |||||
| } | |||||
| }; | |||||
| const [resourceStandardList] = useComputingResource(); // 资源规模 | |||||
| // 控制策略 | // 控制策略 | ||||
| const controlStrategyList = Object.entries(nodeData.control_strategy ?? {}).map( | const controlStrategyList = Object.entries(nodeData.control_strategy ?? {}).map( | ||||
| @@ -18,7 +18,7 @@ import themes from '@/styles/theme.less'; | |||||
| import { elapsedTime, formatDate } from '@/utils/date'; | import { elapsedTime, formatDate } from '@/utils/date'; | ||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import { modalConfirm } from '@/utils/ui'; | import { modalConfirm } from '@/utils/ui'; | ||||
| import { Button, ConfigProvider, Space, Table, message } from 'antd'; | |||||
| import { App, Button, ConfigProvider, Space, Table } from 'antd'; | |||||
| import classNames from 'classnames'; | import classNames from 'classnames'; | ||||
| import { useEffect, useRef, useState } from 'react'; | import { useEffect, useRef, useState } from 'react'; | ||||
| import { useNavigate } from 'react-router-dom'; | import { useNavigate } from 'react-router-dom'; | ||||
| @@ -47,6 +47,7 @@ function Experiment() { | |||||
| const [isAdd, setIsAdd] = useState(true); | const [isAdd, setIsAdd] = useState(true); | ||||
| const [isModalOpen, setIsModalOpen] = useState(false); | const [isModalOpen, setIsModalOpen] = useState(false); | ||||
| const [addFormData, setAddFormData] = useState({}); | const [addFormData, setAddFormData] = useState({}); | ||||
| const { message } = App.useApp(); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| getList(); | getList(); | ||||
| @@ -18,7 +18,7 @@ export enum ExperimentStatus { | |||||
| export const experimentStatusInfo: Record<ExperimentStatus, StatusInfo | undefined> = { | export const experimentStatusInfo: Record<ExperimentStatus, StatusInfo | undefined> = { | ||||
| Running: { | Running: { | ||||
| label: '运行中', | label: '运行中', | ||||
| color: '#165bff', | |||||
| color: '#1664ff', | |||||
| icon: '/assets/images/running-icon.png', | icon: '/assets/images/running-icon.png', | ||||
| }, | }, | ||||
| Succeeded: { | Succeeded: { | ||||
| @@ -53,7 +53,7 @@ export const experimentStatusInfo: Record<ExperimentStatus, StatusInfo | undefin | |||||
| }, | }, | ||||
| Omitted: { | Omitted: { | ||||
| label: '未执行', | label: '未执行', | ||||
| color: '#8a8a8ae', | |||||
| color: '#8a8a8a', | |||||
| icon: '/assets/images/omitted-icon.png', | icon: '/assets/images/omitted-icon.png', | ||||
| }, | }, | ||||
| }; | }; | ||||
| @@ -18,7 +18,7 @@ import { | |||||
| } from '@/utils/sessionStorage'; | } from '@/utils/sessionStorage'; | ||||
| import { getFileListFromEvent, validateUploadFiles } from '@/utils/ui'; | import { getFileListFromEvent, validateUploadFiles } from '@/utils/ui'; | ||||
| import { useNavigate } from '@umijs/max'; | import { useNavigate } from '@umijs/max'; | ||||
| import { Button, Col, Form, Input, Row, Upload, UploadFile, message, type UploadProps } from 'antd'; | |||||
| import { App, Button, Col, Form, Input, Row, Upload, UploadFile, type UploadProps } from 'antd'; | |||||
| import { omit } from 'lodash'; | import { omit } from 'lodash'; | ||||
| import { useEffect, useState } from 'react'; | import { useEffect, useState } from 'react'; | ||||
| import styles from './index.less'; | import styles from './index.less'; | ||||
| @@ -49,6 +49,7 @@ function MirrorCreate() { | |||||
| const navgite = useNavigate(); | const navgite = useNavigate(); | ||||
| const [form] = Form.useForm(); | const [form] = Form.useForm(); | ||||
| const [nameDisabled, setNameDisabled] = useState(false); | const [nameDisabled, setNameDisabled] = useState(false); | ||||
| const { message } = App.useApp(); | |||||
| const uploadProps: UploadProps = { | const uploadProps: UploadProps = { | ||||
| action: '/api/mmp/image/upload', | action: '/api/mmp/image/upload', | ||||
| @@ -68,11 +68,13 @@ function MirrorInfo() { | |||||
| pageSize: 10, | pageSize: 10, | ||||
| }, | }, | ||||
| ); | ); | ||||
| const isPublic = searchParams.get('isPublic') === 'true'; | |||||
| const { message } = App.useApp(); | const { message } = App.useApp(); | ||||
| const isPublic = searchParams.get('isPublic') === 'true'; | |||||
| useEffect(() => { | useEffect(() => { | ||||
| getMirrorInfo(); | getMirrorInfo(); | ||||
| }, []); | }, []); | ||||
| useEffect(() => { | useEffect(() => { | ||||
| getMirrorVersionList(); | getMirrorVersionList(); | ||||
| }, [pagination]); | }, [pagination]); | ||||
| @@ -15,12 +15,12 @@ import { mirrorNameKey, setSessionStorageItem } from '@/utils/sessionStorage'; | |||||
| import { modalConfirm } from '@/utils/ui'; | import { modalConfirm } from '@/utils/ui'; | ||||
| import { useNavigate } from '@umijs/max'; | import { useNavigate } from '@umijs/max'; | ||||
| import { | import { | ||||
| App, | |||||
| Button, | Button, | ||||
| ConfigProvider, | ConfigProvider, | ||||
| Input, | Input, | ||||
| Table, | Table, | ||||
| Tabs, | Tabs, | ||||
| message, | |||||
| type TablePaginationConfig, | type TablePaginationConfig, | ||||
| type TableProps, | type TableProps, | ||||
| type TabsProps, | type TabsProps, | ||||
| @@ -64,6 +64,7 @@ function MirrorList() { | |||||
| pageSize: 10, | pageSize: 10, | ||||
| }, | }, | ||||
| ); | ); | ||||
| const { message } = App.useApp(); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| getMirrorList(); | getMirrorList(); | ||||
| @@ -174,13 +175,14 @@ function MirrorList() { | |||||
| title: '版本数据', | title: '版本数据', | ||||
| dataIndex: 'version_count', | dataIndex: 'version_count', | ||||
| key: 'version_count', | key: 'version_count', | ||||
| width: 100, | |||||
| width: '15%', | |||||
| render: CommonTableCell(), | render: CommonTableCell(), | ||||
| }, | }, | ||||
| { | { | ||||
| title: '镜像描述', | title: '镜像描述', | ||||
| dataIndex: 'description', | dataIndex: 'description', | ||||
| key: 'description', | key: 'description', | ||||
| width: '35%', | |||||
| render: CommonTableCell(true), | render: CommonTableCell(true), | ||||
| ellipsis: { showTitle: false }, | ellipsis: { showTitle: false }, | ||||
| }, | }, | ||||
| @@ -188,7 +190,7 @@ function MirrorList() { | |||||
| title: '创建时间', | title: '创建时间', | ||||
| dataIndex: 'create_time', | dataIndex: 'create_time', | ||||
| key: 'create_time', | key: 'create_time', | ||||
| width: 200, | |||||
| width: '20%', | |||||
| render: DateTableCell, | render: DateTableCell, | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -1,7 +1,7 @@ | |||||
| /* | /* | ||||
| * @Author: 赵伟 | * @Author: 赵伟 | ||||
| * @Date: 2024-04-18 18:35:41 | * @Date: 2024-04-18 18:35:41 | ||||
| * @Description: | |||||
| * @Description: 镜像状态组件 | |||||
| */ | */ | ||||
| import { MirrorVersionStatus } from '@/enums'; | import { MirrorVersionStatus } from '@/enums'; | ||||
| import styles from './index.less'; | import styles from './index.less'; | ||||
| @@ -26,7 +26,7 @@ const statusInfo: Record<MirrorVersionStatus, MirrorVersionStatusInfo> = { | |||||
| }, | }, | ||||
| }; | }; | ||||
| function MirrorStatusCell(status: MirrorVersionStatus) { | |||||
| function MirrorStatusCell(status?: MirrorVersionStatus | null) { | |||||
| if (status === null || status === undefined || !statusInfo[status]) { | if (status === null || status === undefined || !statusInfo[status]) { | ||||
| return <span>--</span>; | return <span>--</span>; | ||||
| } | } | ||||
| @@ -12,7 +12,7 @@ import { downLoadZip } from '@/utils/downloadfile'; | |||||
| import { openAntdModal } from '@/utils/modal'; | import { openAntdModal } from '@/utils/modal'; | ||||
| import { modalConfirm } from '@/utils/ui'; | import { modalConfirm } from '@/utils/ui'; | ||||
| import { useParams, useSearchParams } from '@umijs/max'; | import { useParams, useSearchParams } from '@umijs/max'; | ||||
| import { Button, Input, Select, Table, Tabs, message } from 'antd'; | |||||
| import { App, Button, Input, Select, Table, Tabs } from 'antd'; | |||||
| import { useEffect, useRef, useState } from 'react'; | import { useEffect, useRef, useState } from 'react'; | ||||
| import Styles from './intro.less'; | import Styles from './intro.less'; | ||||
| const { Search } = Input; | const { Search } = Input; | ||||
| @@ -26,6 +26,7 @@ const Dataset = () => { | |||||
| const locationParams = useParams(); //新版本获取路由参数接口 | const locationParams = useParams(); //新版本获取路由参数接口 | ||||
| const [searchParams] = useSearchParams(); | const [searchParams] = useSearchParams(); | ||||
| const [wordList, setWordList] = useState([]); | const [wordList, setWordList] = useState([]); | ||||
| const { message } = App.useApp(); | |||||
| const isPublic = searchParams.get('isPublic') === 'true'; | const isPublic = searchParams.get('isPublic') === 'true'; | ||||
| const getModelByDetail = () => { | const getModelByDetail = () => { | ||||
| @@ -164,7 +164,7 @@ function ModelDeploymentInfo() { | |||||
| </Col> | </Col> | ||||
| <Col span={10}> | <Col span={10}> | ||||
| <div className={styles['model-deployment-info__basic__item']}> | <div className={styles['model-deployment-info__basic__item']}> | ||||
| <div className={styles['label']}>资源规格</div> | |||||
| <div className={styles['label']}>资源规格:</div> | |||||
| <div className={styles['value']}> | <div className={styles['value']}> | ||||
| {modelDeployementInfo?.resource | {modelDeployementInfo?.resource | ||||
| ? getResourceDescription(modelDeployementInfo.resource) | ? getResourceDescription(modelDeployementInfo.resource) | ||||
| @@ -174,7 +174,7 @@ function ModelDeploymentInfo() { | |||||
| </Col> | </Col> | ||||
| </Row> | </Row> | ||||
| <Row gutter={40}> | <Row gutter={40}> | ||||
| <Col span={24}> | |||||
| <Col span={18}> | |||||
| <div className={styles['model-deployment-info__basic__item']}> | <div className={styles['model-deployment-info__basic__item']}> | ||||
| <div className={styles['label']}>描 述:</div> | <div className={styles['label']}>描 述:</div> | ||||
| <div className={styles['value']}>{modelDeployementInfo?.description ?? '--'}</div> | <div className={styles['value']}>{modelDeployementInfo?.description ?? '--'}</div> | ||||
| @@ -249,7 +249,8 @@ function ModelDeployment() { | |||||
| </Button> | </Button> | ||||
| )} | )} | ||||
| {(record.status === ModelDeploymentStatus.Running || | {(record.status === ModelDeploymentStatus.Running || | ||||
| record.status === ModelDeploymentStatus.Init) && ( | |||||
| record.status === ModelDeploymentStatus.Init || | |||||
| record.status === ModelDeploymentStatus.Pending) && ( | |||||
| <Button | <Button | ||||
| type="link" | type="link" | ||||
| size="small" | size="small" | ||||
| @@ -6,10 +6,14 @@ | |||||
| } | } | ||||
| &--stopped { | &--stopped { | ||||
| color: @warning-color; | |||||
| color: @abort-color; | |||||
| } | } | ||||
| &--error { | &--error { | ||||
| color: @error-color; | color: @error-color; | ||||
| } | } | ||||
| &--pending { | |||||
| color: @warning-color; | |||||
| } | |||||
| } | } | ||||
| @@ -28,9 +28,13 @@ export const statusInfo: Record<ModelDeploymentStatus, ModelDeploymentStatusInfo | |||||
| classname: styles['model-deployment-status-cell--error'], | classname: styles['model-deployment-status-cell--error'], | ||||
| text: '失败', | text: '失败', | ||||
| }, | }, | ||||
| [ModelDeploymentStatus.Pending]: { | |||||
| classname: styles['model-deployment-status-cell--pending'], | |||||
| text: '挂起中', | |||||
| }, | |||||
| }; | }; | ||||
| function ModelDeploymentStatusCell(status: ModelDeploymentStatus | undefined) { | |||||
| function ModelDeploymentStatusCell(status?: ModelDeploymentStatus | null) { | |||||
| if (status === null || status === undefined || !statusInfo[status]) { | if (status === null || status === undefined || !statusInfo[status]) { | ||||
| return <span>--</span>; | return <span>--</span>; | ||||
| } | } | ||||
| @@ -26,13 +26,7 @@ export type ModelDeploymentData = { | |||||
| // 操作类型 | // 操作类型 | ||||
| export enum ModelDeploymentOperationType { | export enum ModelDeploymentOperationType { | ||||
| Create = 'create', | |||||
| Update = 'update', | |||||
| Restart = 'restart', | |||||
| Create = 'Create', | |||||
| Update = 'Update', | |||||
| Restart = 'Restart', | |||||
| } | } | ||||
| // 状态 | |||||
| export type ModelDeploymentStatusInfo = { | |||||
| text: string; | |||||
| classname: string; | |||||
| }; | |||||
| @@ -1,4 +1,5 @@ | |||||
| import { DictOptionType, DictValueEnumObj } from '@/components/DictTag'; | import { DictOptionType, DictValueEnumObj } from '@/components/DictTag'; | ||||
| import KFModal from '@/components/KFModal'; | |||||
| import { | import { | ||||
| ProForm, | ProForm, | ||||
| ProFormCaptcha, | ProFormCaptcha, | ||||
| @@ -9,9 +10,8 @@ import { | |||||
| ProFormTextArea, | ProFormTextArea, | ||||
| } from '@ant-design/pro-components'; | } from '@ant-design/pro-components'; | ||||
| import { FormattedMessage, useIntl } from '@umijs/max'; | import { FormattedMessage, useIntl } from '@umijs/max'; | ||||
| import { Form, Modal } from 'antd'; | |||||
| import { Form } from 'antd'; | |||||
| import React, { useEffect } from 'react'; | import React, { useEffect } from 'react'; | ||||
| import KFModal from '@/components/KFModal'; | |||||
| /** | /** | ||||
| * 定时任务调度 Edit Form | * 定时任务调度 Edit Form | ||||
| * | * | ||||
| @@ -3,7 +3,7 @@ import { useStateRef, useVisible } from '@/hooks'; | |||||
| import { getWorkflowById, saveWorkflow } from '@/services/pipeline/index.js'; | import { getWorkflowById, saveWorkflow } from '@/services/pipeline/index.js'; | ||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import G6 from '@antv/g6'; | import G6 from '@antv/g6'; | ||||
| import { Button, message } from 'antd'; | |||||
| import { App, Button } from 'antd'; | |||||
| import { useEffect, useRef } from 'react'; | import { useEffect, useRef } from 'react'; | ||||
| import { useNavigate, useParams } from 'react-router-dom'; | import { useNavigate, useParams } from 'react-router-dom'; | ||||
| import { s8 } from '../../../utils'; | import { s8 } from '../../../utils'; | ||||
| @@ -24,7 +24,7 @@ const EditPipeline = () => { | |||||
| const propsRef = useRef(); | const propsRef = useRef(); | ||||
| const [paramsDrawerOpen, openParamsDrawer, closeParamsDrawer] = useVisible(false); | const [paramsDrawerOpen, openParamsDrawer, closeParamsDrawer] = useVisible(false); | ||||
| const [globalParam, setGlobalParam, globalParamRef] = useStateRef([]); | const [globalParam, setGlobalParam, globalParamRef] = useStateRef([]); | ||||
| const { message } = App.useApp(); | |||||
| let sourceAnchorIdx, targetAnchorIdx; | let sourceAnchorIdx, targetAnchorIdx; | ||||
| const onDragEnd = (val) => { | const onDragEnd = (val) => { | ||||
| @@ -1,14 +1,17 @@ | |||||
| import KFIcon from '@/components/KFIcon'; | import KFIcon from '@/components/KFIcon'; | ||||
| import ParameterInput from '@/components/ParameterInput'; | import ParameterInput from '@/components/ParameterInput'; | ||||
| import SubAreaTitle from '@/components/SubAreaTitle'; | import SubAreaTitle from '@/components/SubAreaTitle'; | ||||
| import { getComputingResourceReq } from '@/services/pipeline'; | |||||
| import { useComputingResource } from '@/hooks/resource'; | |||||
| import { openAntdModal } from '@/utils/modal'; | import { openAntdModal } from '@/utils/modal'; | ||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import { Button, Drawer, Form, Input, Select } from 'antd'; | import { Button, Drawer, Form, Input, Select } from 'antd'; | ||||
| import { pick } from 'lodash'; | import { pick } from 'lodash'; | ||||
| import { forwardRef, useEffect, useImperativeHandle, useState } from 'react'; | |||||
| import { forwardRef, useImperativeHandle, useState } from 'react'; | |||||
| import PropsLabel from '../components/PropsLabel'; | import PropsLabel from '../components/PropsLabel'; | ||||
| import ResourceSelectorModal, { ResourceSelectorType } from '../components/ResourceSelectorModal'; | |||||
| import ResourceSelectorModal, { | |||||
| ResourceSelectorType, | |||||
| selectorTypeConfig, | |||||
| } from '../components/ResourceSelectorModal'; | |||||
| import styles from './props.less'; | import styles from './props.less'; | ||||
| import { canInput, createMenuItems } from './utils'; | import { canInput, createMenuItems } from './utils'; | ||||
| const { TextArea } = Input; | const { TextArea } = Input; | ||||
| @@ -19,26 +22,9 @@ const Props = forwardRef(({ onParentChange }, ref) => { | |||||
| const [open, setOpen] = useState(false); | const [open, setOpen] = useState(false); | ||||
| const [selectedModel, setSelectedModel] = useState(undefined); // 选择的模型,为了再次打开时恢复原来的选择 | const [selectedModel, setSelectedModel] = useState(undefined); // 选择的模型,为了再次打开时恢复原来的选择 | ||||
| const [selectedDataset, setSelectedDataset] = useState(undefined); // 选择的数据集,为了再次打开时恢复原来的选择 | const [selectedDataset, setSelectedDataset] = useState(undefined); // 选择的数据集,为了再次打开时恢复原来的选择 | ||||
| const [resourceStandardList, setResourceStandardList] = useState([]); // 资源规模列表 | |||||
| const [resourceStandardList, filterResourceStandard] = useComputingResource(); // 资源规模 | |||||
| const [menuItems, setMenuItems] = useState([]); | const [menuItems, setMenuItems] = useState([]); | ||||
| useEffect(() => { | |||||
| getComputingResource(); | |||||
| }, []); | |||||
| // 获取资源规格列表数据 | |||||
| const getComputingResource = async () => { | |||||
| const params = { | |||||
| page: 0, | |||||
| size: 1000, | |||||
| resource_type: '', | |||||
| }; | |||||
| const [res] = await to(getComputingResourceReq(params)); | |||||
| if (res && res.data && res.data.content) { | |||||
| setResourceStandardList(res.data.content); | |||||
| } | |||||
| }; | |||||
| const afterOpenChange = () => { | const afterOpenChange = () => { | ||||
| if (!open) { | if (!open) { | ||||
| console.log('zzzzz', form.getFieldsValue()); | console.log('zzzzz', form.getFieldsValue()); | ||||
| @@ -57,6 +43,7 @@ const Props = forwardRef(({ onParentChange }, ref) => { | |||||
| const onClose = () => { | const onClose = () => { | ||||
| setOpen(false); | setOpen(false); | ||||
| }; | }; | ||||
| useImperativeHandle(ref, () => ({ | useImperativeHandle(ref, () => ({ | ||||
| getFieldsValue: async () => { | getFieldsValue: async () => { | ||||
| const [propsRes, propsError] = await to(form.validateFields()); | const [propsRes, propsError] = await to(form.validateFields()); | ||||
| @@ -155,18 +142,16 @@ const Props = forwardRef(({ onParentChange }, ref) => { | |||||
| // 获取选择数据集、模型后面按钮 icon | // 获取选择数据集、模型后面按钮 icon | ||||
| const getSelectBtnIcon = (item) => { | const getSelectBtnIcon = (item) => { | ||||
| const type = item.item_type; | const type = item.item_type; | ||||
| let selectorType; | |||||
| if (type === 'dataset') { | if (type === 'dataset') { | ||||
| return <KFIcon type="icon-xuanzeshujuji" />; | |||||
| selectorType = ResourceSelectorType.Dataset; | |||||
| } else if (type === 'model') { | } else if (type === 'model') { | ||||
| return <KFIcon type="icon-xuanzemoxing" />; | |||||
| selectorType = ResourceSelectorType.Model; | |||||
| } else { | } else { | ||||
| return <KFIcon type="icon-xuanzejingxiang" />; | |||||
| selectorType = ResourceSelectorType.Mirror; | |||||
| } | } | ||||
| }; | |||||
| // 筛选资源规格 | |||||
| const filterResourceStandard = (input, { computing_resource = '' }) => { | |||||
| return computing_resource.toLocaleLowerCase().includes(input.toLocaleLowerCase()); | |||||
| return <KFIcon type={selectorTypeConfig[selectorType].buttonIcon} />; | |||||
| }; | }; | ||||
| // 参数回填 | // 参数回填 | ||||
| @@ -12,7 +12,7 @@ import { | |||||
| } from '@/services/pipeline/index.js'; | } from '@/services/pipeline/index.js'; | ||||
| import themes from '@/styles/theme.less'; | import themes from '@/styles/theme.less'; | ||||
| import { modalConfirm } from '@/utils/ui'; | import { modalConfirm } from '@/utils/ui'; | ||||
| import { Button, ConfigProvider, Form, Input, Space, Table, message } from 'antd'; | |||||
| import { App, Button, ConfigProvider, Form, Input, Space, Table } from 'antd'; | |||||
| import classNames from 'classnames'; | import classNames from 'classnames'; | ||||
| import { useEffect, useRef, useState } from 'react'; | import { useEffect, useRef, useState } from 'react'; | ||||
| import { useNavigate } from 'react-router-dom'; | import { useNavigate } from 'react-router-dom'; | ||||
| @@ -28,6 +28,7 @@ const Pipeline = () => { | |||||
| const [pipeList, setPipeList] = useState([]); | const [pipeList, setPipeList] = useState([]); | ||||
| const [total, setTotal] = useState(0); | const [total, setTotal] = useState(0); | ||||
| const [isModalOpen, setIsModalOpen] = useState(false); | const [isModalOpen, setIsModalOpen] = useState(false); | ||||
| const { message } = App.useApp(); | |||||
| const editTable = (e, record) => { | const editTable = (e, record) => { | ||||
| e.stopPropagation(); | e.stopPropagation(); | ||||
| getWorkflowById(record.id).then((ret) => { | getWorkflowById(record.id).then((ret) => { | ||||
| @@ -66,7 +67,7 @@ const Pipeline = () => { | |||||
| } else { | } else { | ||||
| addWorkflow(values).then((ret) => { | addWorkflow(values).then((ret) => { | ||||
| console.log(ret); | console.log(ret); | ||||
| if (ret.code == 200) { | |||||
| if (ret.code === 200) { | |||||
| navgite({ pathname: `/pipeline/template/${ret.data.id}/${ret.data.name}` }); | navgite({ pathname: `/pipeline/template/${ret.data.id}/${ret.data.name}` }); | ||||
| } | } | ||||
| }); | }); | ||||
| @@ -3,7 +3,7 @@ | |||||
| * @Date: 2024-03-25 13:52:54 | * @Date: 2024-03-25 13:52:54 | ||||
| * @Description: 网络请求配置,详情请参考 https://umijs.org/docs/max/request | * @Description: 网络请求配置,详情请参考 https://umijs.org/docs/max/request | ||||
| */ | */ | ||||
| import type { RequestConfig } from '@umijs/max'; | |||||
| import type { AxiosRequestConfig, AxiosResponse, RequestConfig } from '@umijs/max'; | |||||
| import { message } from 'antd'; | import { message } from 'antd'; | ||||
| import { clearSessionToken, getAccessToken } from './access'; | import { clearSessionToken, getAccessToken } from './access'; | ||||
| import { setRemoteMenu } from './services/session'; | import { setRemoteMenu } from './services/session'; | ||||
| @@ -16,8 +16,8 @@ import { gotoLoginPage } from './utils/ui'; | |||||
| export const requestConfig: RequestConfig = { | export const requestConfig: RequestConfig = { | ||||
| errorConfig: {}, | errorConfig: {}, | ||||
| requestInterceptors: [ | requestInterceptors: [ | ||||
| (url: any, options: { headers: any }) => { | |||||
| const headers = options.headers ? options.headers : []; | |||||
| (url: string, options: AxiosRequestConfig) => { | |||||
| const headers = options.headers ?? {}; | |||||
| const authHeader = headers['Authorization']; | const authHeader = headers['Authorization']; | ||||
| const isToken = headers['isToken']; | const isToken = headers['isToken']; | ||||
| if (!authHeader && isToken !== false) { | if (!authHeader && isToken !== false) { | ||||
| @@ -30,7 +30,7 @@ export const requestConfig: RequestConfig = { | |||||
| }, | }, | ||||
| ], | ], | ||||
| responseInterceptors: [ | responseInterceptors: [ | ||||
| (response: any) => { | |||||
| (response: AxiosResponse) => { | |||||
| const { status, data } = response || {}; | const { status, data } = response || {}; | ||||
| if (status >= 200 && status < 300) { | if (status >= 200 && status < 300) { | ||||
| if (data && (data instanceof Blob || data.code === 200)) { | if (data && (data instanceof Blob || data.code === 200)) { | ||||
| @@ -14,6 +14,7 @@ | |||||
| @success-color: #1ace62; | @success-color: #1ace62; | ||||
| @error-color: #c73131; | @error-color: #c73131; | ||||
| @warning-color: #f98e1b; | @warning-color: #f98e1b; | ||||
| @abort-color: #8a8a8a; | |||||
| @border-color: rgba(22, 100, 255, 0.3); | @border-color: rgba(22, 100, 255, 0.3); | ||||
| @border-color-secondary: rgba(22, 100, 255, 0.1); | @border-color-secondary: rgba(22, 100, 255, 0.1); | ||||
| @@ -29,7 +29,7 @@ export function parseJsonText(text?: string | null): any | null { | |||||
| } | } | ||||
| } | } | ||||
| // Underscore-to-camelCase | |||||
| // underscore-to-camelCase | |||||
| export function underscoreToCamelCase(obj: Record<string, any>) { | export function underscoreToCamelCase(obj: Record<string, any>) { | ||||
| const newObj: Record<string, any> = {}; | const newObj: Record<string, any> = {}; | ||||
| for (const key in obj) { | for (const key in obj) { | ||||
| @@ -47,6 +47,7 @@ export function underscoreToCamelCase(obj: Record<string, any>) { | |||||
| return newObj; | return newObj; | ||||
| } | } | ||||
| // camelCase-to-underscore | |||||
| export function camelCaseToUnderscore(obj: Record<string, any>) { | export function camelCaseToUnderscore(obj: Record<string, any>) { | ||||
| const newObj: Record<string, any> = {}; | const newObj: Record<string, any> = {}; | ||||
| for (const key in obj) { | for (const key in obj) { | ||||
| @@ -61,3 +62,21 @@ export function camelCaseToUnderscore(obj: Record<string, any>) { | |||||
| } | } | ||||
| return newObj; | return newObj; | ||||
| } | } | ||||
| // null 转 undefined | |||||
| export function nullToUndefined(obj: Record<string, any>) { | |||||
| const newObj: Record<string, any> = {}; | |||||
| for (const key in obj) { | |||||
| if (obj.hasOwnProperty(key)) { | |||||
| const value = obj[key]; | |||||
| if (value === null) { | |||||
| newObj[key] = undefined; | |||||
| } else if (typeof value === 'object' && value !== null) { | |||||
| newObj[key] = nullToUndefined(value); | |||||
| } else { | |||||
| newObj[key] = value; | |||||
| } | |||||
| } | |||||
| } | |||||
| return newObj; | |||||
| } | |||||
| @@ -9,6 +9,8 @@ import zhCN from 'antd/locale/zh_CN'; | |||||
| import React, { useState } from 'react'; | import React, { useState } from 'react'; | ||||
| import { createRoot } from 'react-dom/client'; | import { createRoot } from 'react-dom/client'; | ||||
| const destroyFns: (() => void)[] = []; | |||||
| /** | /** | ||||
| * Function to open an Ant Design modal. | * Function to open an Ant Design modal. | ||||
| * | * | ||||
| @@ -16,7 +18,6 @@ import { createRoot } from 'react-dom/client'; | |||||
| * @param modalProps - The modal properties. | * @param modalProps - The modal properties. | ||||
| * @return An object with a destroy method to close the modal. | * @return An object with a destroy method to close the modal. | ||||
| */ | */ | ||||
| export const openAntdModal = <T extends Omit<ModalProps, 'onOk'>>( | export const openAntdModal = <T extends Omit<ModalProps, 'onOk'>>( | ||||
| modal: (props: T) => React.ReactNode, | modal: (props: T) => React.ReactNode, | ||||
| modalProps: T, | modalProps: T, | ||||
| @@ -29,6 +30,11 @@ export const openAntdModal = <T extends Omit<ModalProps, 'onOk'>>( | |||||
| let timeoutId: ReturnType<typeof setTimeout>; | let timeoutId: ReturnType<typeof setTimeout>; | ||||
| function destroy() { | function destroy() { | ||||
| const index = destroyFns.indexOf(close); | |||||
| if (index !== -1) { | |||||
| destroyFns.splice(index, 1); | |||||
| } | |||||
| root.unmount(); | root.unmount(); | ||||
| } | } | ||||
| @@ -79,6 +85,8 @@ export const openAntdModal = <T extends Omit<ModalProps, 'onOk'>>( | |||||
| render({ ...modalProps, open: true }); | render({ ...modalProps, open: true }); | ||||
| destroyFns.push(close); | |||||
| return { | return { | ||||
| close, | close, | ||||
| }; | }; | ||||
| @@ -88,19 +96,23 @@ export const openAntdModal = <T extends Omit<ModalProps, 'onOk'>>( | |||||
| * Generates a custom hook for managing an Ant Design modal. | * Generates a custom hook for managing an Ant Design modal. | ||||
| * | * | ||||
| * @param modal - The function that renders the modal content. | * @param modal - The function that renders the modal content. | ||||
| * @param key - The key for the modal. | |||||
| * @param defaultProps - The default modal properties. | |||||
| * @return The modal component, open function, and close function. | * @return The modal component, open function, and close function. | ||||
| */ | */ | ||||
| export const useAntdModal = <T extends ModalProps>( | |||||
| export const useModal = <T extends ModalProps>( | |||||
| modal: (props: T) => React.ReactNode, | modal: (props: T) => React.ReactNode, | ||||
| key: React.Key, | |||||
| defaultProps?: T, | |||||
| ) => { | ) => { | ||||
| const [visible, setVisible] = useState(false); | const [visible, setVisible] = useState(false); | ||||
| const [props, setProps] = useState<T>({} as T); | |||||
| const [props, setProps] = useState<T>(defaultProps || ({} as T)); | |||||
| const CustomModel = modal; | const CustomModel = modal; | ||||
| const open = (props: T) => { | const open = (props: T) => { | ||||
| setProps(props); | |||||
| setProps((prev) => ({ | |||||
| ...prev, | |||||
| ...props, | |||||
| })); | |||||
| setVisible(true); | setVisible(true); | ||||
| }; | }; | ||||
| @@ -108,5 +120,14 @@ export const useAntdModal = <T extends ModalProps>( | |||||
| setVisible(false); | setVisible(false); | ||||
| }; | }; | ||||
| return [<CustomModel key={key} open={visible} {...props} />, open, close] as const; | |||||
| return [<CustomModel key="modal" open={visible} {...props} />, open, close] as const; | |||||
| }; | |||||
| // 关闭没有手动关闭的 Modal | |||||
| export const closeAllModals = () => { | |||||
| let close = destroyFns.pop(); | |||||
| while (close) { | |||||
| close(); | |||||
| close = destroyFns.pop(); | |||||
| } | |||||
| }; | }; | ||||
| @@ -7,6 +7,7 @@ import { PageEnum } from '@/enums/pagesEnums'; | |||||
| import themes from '@/styles/theme.less'; | import themes from '@/styles/theme.less'; | ||||
| import { history } from '@umijs/max'; | import { history } from '@umijs/max'; | ||||
| import { Modal, message, type ModalFuncProps, type UploadFile } from 'antd'; | import { Modal, message, type ModalFuncProps, type UploadFile } from 'antd'; | ||||
| import { closeAllModals } from './modal'; | |||||
| // 自定义 Confirm 弹框 | // 自定义 Confirm 弹框 | ||||
| export function modalConfirm({ title, content, onOk, ...rest }: ModalFuncProps) { | export function modalConfirm({ title, content, onOk, ...rest }: ModalFuncProps) { | ||||
| @@ -58,6 +59,7 @@ export const gotoLoginPage = (toHome: boolean = true) => { | |||||
| console.log('pathname', pathname); | console.log('pathname', pathname); | ||||
| console.log('search', search); | console.log('search', search); | ||||
| if (window.location.pathname !== PageEnum.LOGIN) { | if (window.location.pathname !== PageEnum.LOGIN) { | ||||
| closeAllModals(); | |||||
| history.replace({ | history.replace({ | ||||
| pathname: PageEnum.LOGIN, | pathname: PageEnum.LOGIN, | ||||
| search: newSearch, | search: newSearch, | ||||