diff --git a/react-ui/config/routes.ts b/react-ui/config/routes.ts index cd81e412..0e502c59 100644 --- a/react-ui/config/routes.ts +++ b/react-ui/config/routes.ts @@ -131,7 +131,7 @@ export default [ { name: '数据集简介', path: ':id', - component: './Dataset/datasetIntro', + component: './Dataset/intro', }, ], }, @@ -147,7 +147,7 @@ export default [ { name: '模型简介', path: ':id', - component: './Model/modelIntro', + component: './Model/intro', }, ], }, @@ -188,14 +188,23 @@ export default [ ], }, { - name: 'modelDseployment', - path: '/modelDseployment', + name: 'modelDeployment', + path: '/modelDeployment', routes: [ { - name: '模型部署', + name: '模型列表', path: '', - key: 'modelDseployment', - component: './missingPage.jsx', + component: './ModelDeployment/list', + }, + { + name: '镜像详情', + path: ':id', + component: './ModelDeployment/info', + }, + { + name: '创建镜像', + path: 'create', + component: './ModelDeployment/create', }, ], }, diff --git a/react-ui/public/assets/images/compoent-icon-6.png b/react-ui/public/assets/images/compoent-icon-6.png deleted file mode 100644 index 47e7fa9b..00000000 Binary files a/react-ui/public/assets/images/compoent-icon-6.png and /dev/null differ diff --git a/react-ui/public/assets/images/icon/流水线-1.png b/react-ui/public/assets/images/icon/流水线-1.png deleted file mode 100644 index 7fbb9266..00000000 Binary files a/react-ui/public/assets/images/icon/流水线-1.png and /dev/null differ diff --git a/react-ui/public/assets/images/mindspore模型转换.png b/react-ui/public/assets/images/mindspore模型转换.png deleted file mode 100644 index 73620da3..00000000 Binary files a/react-ui/public/assets/images/mindspore模型转换.png and /dev/null differ diff --git a/react-ui/public/assets/images/pipelieEditIcon.png b/react-ui/public/assets/images/pipelieEditIcon.png deleted file mode 100644 index 936bf97c..00000000 Binary files a/react-ui/public/assets/images/pipelieEditIcon.png and /dev/null differ diff --git a/react-ui/public/assets/images/pipeline-edit-icon.png b/react-ui/public/assets/images/pipeline-edit-icon.png deleted file mode 100644 index 936bf97c..00000000 Binary files a/react-ui/public/assets/images/pipeline-edit-icon.png and /dev/null differ diff --git a/react-ui/public/assets/images/component-icon-1-Failed.png b/react-ui/public/assets/images/pipeline/component-icon-1-Failed.png similarity index 100% rename from react-ui/public/assets/images/component-icon-1-Failed.png rename to react-ui/public/assets/images/pipeline/component-icon-1-Failed.png diff --git a/react-ui/public/assets/images/component-icon-1-Omitted.png b/react-ui/public/assets/images/pipeline/component-icon-1-Omitted.png similarity index 100% rename from react-ui/public/assets/images/component-icon-1-Omitted.png rename to react-ui/public/assets/images/pipeline/component-icon-1-Omitted.png diff --git a/react-ui/public/assets/images/component-icon-1-Pending.png b/react-ui/public/assets/images/pipeline/component-icon-1-Pending.png similarity index 100% rename from react-ui/public/assets/images/component-icon-1-Pending.png rename to react-ui/public/assets/images/pipeline/component-icon-1-Pending.png diff --git a/react-ui/public/assets/images/component-icon-1-Running.png b/react-ui/public/assets/images/pipeline/component-icon-1-Running.png similarity index 100% rename from react-ui/public/assets/images/component-icon-1-Running.png rename to react-ui/public/assets/images/pipeline/component-icon-1-Running.png diff --git a/react-ui/public/assets/images/component-icon-1-Skipped.png b/react-ui/public/assets/images/pipeline/component-icon-1-Skipped.png similarity index 100% rename from react-ui/public/assets/images/component-icon-1-Skipped.png rename to react-ui/public/assets/images/pipeline/component-icon-1-Skipped.png diff --git a/react-ui/public/assets/images/component-icon-1-Succeeded.png b/react-ui/public/assets/images/pipeline/component-icon-1-Succeeded.png similarity index 100% rename from react-ui/public/assets/images/component-icon-1-Succeeded.png rename to react-ui/public/assets/images/pipeline/component-icon-1-Succeeded.png diff --git a/react-ui/public/assets/images/component-icon-1.png b/react-ui/public/assets/images/pipeline/component-icon-1.png similarity index 100% rename from react-ui/public/assets/images/component-icon-1.png rename to react-ui/public/assets/images/pipeline/component-icon-1.png diff --git a/react-ui/public/assets/images/component-icon-2-Failed.png b/react-ui/public/assets/images/pipeline/component-icon-2-Failed.png similarity index 100% rename from react-ui/public/assets/images/component-icon-2-Failed.png rename to react-ui/public/assets/images/pipeline/component-icon-2-Failed.png diff --git a/react-ui/public/assets/images/component-icon-2-Omitted.png b/react-ui/public/assets/images/pipeline/component-icon-2-Omitted.png similarity index 100% rename from react-ui/public/assets/images/component-icon-2-Omitted.png rename to react-ui/public/assets/images/pipeline/component-icon-2-Omitted.png diff --git a/react-ui/public/assets/images/component-icon-2-Pending.png b/react-ui/public/assets/images/pipeline/component-icon-2-Pending.png similarity index 100% rename from react-ui/public/assets/images/component-icon-2-Pending.png rename to react-ui/public/assets/images/pipeline/component-icon-2-Pending.png diff --git a/react-ui/public/assets/images/component-icon-2-Running.png b/react-ui/public/assets/images/pipeline/component-icon-2-Running.png similarity index 100% rename from react-ui/public/assets/images/component-icon-2-Running.png rename to react-ui/public/assets/images/pipeline/component-icon-2-Running.png diff --git a/react-ui/public/assets/images/component-icon-2-Skipped.png b/react-ui/public/assets/images/pipeline/component-icon-2-Skipped.png similarity index 100% rename from react-ui/public/assets/images/component-icon-2-Skipped.png rename to react-ui/public/assets/images/pipeline/component-icon-2-Skipped.png diff --git a/react-ui/public/assets/images/component-icon-2-Succeeded.png b/react-ui/public/assets/images/pipeline/component-icon-2-Succeeded.png similarity index 100% rename from react-ui/public/assets/images/component-icon-2-Succeeded.png rename to react-ui/public/assets/images/pipeline/component-icon-2-Succeeded.png diff --git a/react-ui/public/assets/images/component-icon-2.png b/react-ui/public/assets/images/pipeline/component-icon-2.png similarity index 100% rename from react-ui/public/assets/images/component-icon-2.png rename to react-ui/public/assets/images/pipeline/component-icon-2.png diff --git a/react-ui/public/assets/images/component-icon-3-Failed.png b/react-ui/public/assets/images/pipeline/component-icon-3-Failed.png similarity index 100% rename from react-ui/public/assets/images/component-icon-3-Failed.png rename to react-ui/public/assets/images/pipeline/component-icon-3-Failed.png diff --git a/react-ui/public/assets/images/component-icon-3-Omitted.png b/react-ui/public/assets/images/pipeline/component-icon-3-Omitted.png similarity index 100% rename from react-ui/public/assets/images/component-icon-3-Omitted.png rename to react-ui/public/assets/images/pipeline/component-icon-3-Omitted.png diff --git a/react-ui/public/assets/images/component-icon-3-Pending.png b/react-ui/public/assets/images/pipeline/component-icon-3-Pending.png similarity index 100% rename from react-ui/public/assets/images/component-icon-3-Pending.png rename to react-ui/public/assets/images/pipeline/component-icon-3-Pending.png diff --git a/react-ui/public/assets/images/component-icon-3-Running.png b/react-ui/public/assets/images/pipeline/component-icon-3-Running.png similarity index 100% rename from react-ui/public/assets/images/component-icon-3-Running.png rename to react-ui/public/assets/images/pipeline/component-icon-3-Running.png diff --git a/react-ui/public/assets/images/component-icon-3-Skipped.png b/react-ui/public/assets/images/pipeline/component-icon-3-Skipped.png similarity index 100% rename from react-ui/public/assets/images/component-icon-3-Skipped.png rename to react-ui/public/assets/images/pipeline/component-icon-3-Skipped.png diff --git a/react-ui/public/assets/images/component-icon-3-Succeeded.png b/react-ui/public/assets/images/pipeline/component-icon-3-Succeeded.png similarity index 100% rename from react-ui/public/assets/images/component-icon-3-Succeeded.png rename to react-ui/public/assets/images/pipeline/component-icon-3-Succeeded.png diff --git a/react-ui/public/assets/images/component-icon-3.png b/react-ui/public/assets/images/pipeline/component-icon-3.png similarity index 100% rename from react-ui/public/assets/images/component-icon-3.png rename to react-ui/public/assets/images/pipeline/component-icon-3.png diff --git a/react-ui/public/assets/images/component-icon-4-Failed.png b/react-ui/public/assets/images/pipeline/component-icon-4-Failed.png similarity index 100% rename from react-ui/public/assets/images/component-icon-4-Failed.png rename to react-ui/public/assets/images/pipeline/component-icon-4-Failed.png diff --git a/react-ui/public/assets/images/component-icon-4-Omitted.png b/react-ui/public/assets/images/pipeline/component-icon-4-Omitted.png similarity index 100% rename from react-ui/public/assets/images/component-icon-4-Omitted.png rename to react-ui/public/assets/images/pipeline/component-icon-4-Omitted.png diff --git a/react-ui/public/assets/images/component-icon-4-Pending.png b/react-ui/public/assets/images/pipeline/component-icon-4-Pending.png similarity index 100% rename from react-ui/public/assets/images/component-icon-4-Pending.png rename to react-ui/public/assets/images/pipeline/component-icon-4-Pending.png diff --git a/react-ui/public/assets/images/component-icon-4-Running.png b/react-ui/public/assets/images/pipeline/component-icon-4-Running.png similarity index 100% rename from react-ui/public/assets/images/component-icon-4-Running.png rename to react-ui/public/assets/images/pipeline/component-icon-4-Running.png diff --git a/react-ui/public/assets/images/component-icon-4-Skipped.png b/react-ui/public/assets/images/pipeline/component-icon-4-Skipped.png similarity index 100% rename from react-ui/public/assets/images/component-icon-4-Skipped.png rename to react-ui/public/assets/images/pipeline/component-icon-4-Skipped.png diff --git a/react-ui/public/assets/images/component-icon-4-Succeeded.png b/react-ui/public/assets/images/pipeline/component-icon-4-Succeeded.png similarity index 100% rename from react-ui/public/assets/images/component-icon-4-Succeeded.png rename to react-ui/public/assets/images/pipeline/component-icon-4-Succeeded.png diff --git a/react-ui/public/assets/images/component-icon-4.png b/react-ui/public/assets/images/pipeline/component-icon-4.png similarity index 100% rename from react-ui/public/assets/images/component-icon-4.png rename to react-ui/public/assets/images/pipeline/component-icon-4.png diff --git a/react-ui/public/assets/images/component-icon-5-Failed.png b/react-ui/public/assets/images/pipeline/component-icon-5-Failed.png similarity index 100% rename from react-ui/public/assets/images/component-icon-5-Failed.png rename to react-ui/public/assets/images/pipeline/component-icon-5-Failed.png diff --git a/react-ui/public/assets/images/component-icon-5-Omitted.png b/react-ui/public/assets/images/pipeline/component-icon-5-Omitted.png similarity index 100% rename from react-ui/public/assets/images/component-icon-5-Omitted.png rename to react-ui/public/assets/images/pipeline/component-icon-5-Omitted.png diff --git a/react-ui/public/assets/images/component-icon-5-Pending.png b/react-ui/public/assets/images/pipeline/component-icon-5-Pending.png similarity index 100% rename from react-ui/public/assets/images/component-icon-5-Pending.png rename to react-ui/public/assets/images/pipeline/component-icon-5-Pending.png diff --git a/react-ui/public/assets/images/component-icon-5-Running.png b/react-ui/public/assets/images/pipeline/component-icon-5-Running.png similarity index 100% rename from react-ui/public/assets/images/component-icon-5-Running.png rename to react-ui/public/assets/images/pipeline/component-icon-5-Running.png diff --git a/react-ui/public/assets/images/component-icon-5-Skipped.png b/react-ui/public/assets/images/pipeline/component-icon-5-Skipped.png similarity index 100% rename from react-ui/public/assets/images/component-icon-5-Skipped.png rename to react-ui/public/assets/images/pipeline/component-icon-5-Skipped.png diff --git a/react-ui/public/assets/images/component-icon-5-Succeeded.png b/react-ui/public/assets/images/pipeline/component-icon-5-Succeeded.png similarity index 100% rename from react-ui/public/assets/images/component-icon-5-Succeeded.png rename to react-ui/public/assets/images/pipeline/component-icon-5-Succeeded.png diff --git a/react-ui/public/assets/images/component-icon-5.png b/react-ui/public/assets/images/pipeline/component-icon-5.png similarity index 100% rename from react-ui/public/assets/images/component-icon-5.png rename to react-ui/public/assets/images/pipeline/component-icon-5.png diff --git a/react-ui/public/assets/images/component-icon-6-Failed.png b/react-ui/public/assets/images/pipeline/component-icon-6-Failed.png similarity index 100% rename from react-ui/public/assets/images/component-icon-6-Failed.png rename to react-ui/public/assets/images/pipeline/component-icon-6-Failed.png diff --git a/react-ui/public/assets/images/component-icon-6-Omitted.png b/react-ui/public/assets/images/pipeline/component-icon-6-Omitted.png similarity index 100% rename from react-ui/public/assets/images/component-icon-6-Omitted.png rename to react-ui/public/assets/images/pipeline/component-icon-6-Omitted.png diff --git a/react-ui/public/assets/images/component-icon-6-Pending.png b/react-ui/public/assets/images/pipeline/component-icon-6-Pending.png similarity index 100% rename from react-ui/public/assets/images/component-icon-6-Pending.png rename to react-ui/public/assets/images/pipeline/component-icon-6-Pending.png diff --git a/react-ui/public/assets/images/component-icon-6-Running.png b/react-ui/public/assets/images/pipeline/component-icon-6-Running.png similarity index 100% rename from react-ui/public/assets/images/component-icon-6-Running.png rename to react-ui/public/assets/images/pipeline/component-icon-6-Running.png diff --git a/react-ui/public/assets/images/component-icon-6-Skipped.png b/react-ui/public/assets/images/pipeline/component-icon-6-Skipped.png similarity index 100% rename from react-ui/public/assets/images/component-icon-6-Skipped.png rename to react-ui/public/assets/images/pipeline/component-icon-6-Skipped.png diff --git a/react-ui/public/assets/images/component-icon-6-Succeeded.png b/react-ui/public/assets/images/pipeline/component-icon-6-Succeeded.png similarity index 100% rename from react-ui/public/assets/images/component-icon-6-Succeeded.png rename to react-ui/public/assets/images/pipeline/component-icon-6-Succeeded.png diff --git a/react-ui/public/assets/images/component-icon-6.png b/react-ui/public/assets/images/pipeline/component-icon-6.png similarity index 100% rename from react-ui/public/assets/images/component-icon-6.png rename to react-ui/public/assets/images/pipeline/component-icon-6.png diff --git a/react-ui/public/assets/images/component-icon-7-Failed.png b/react-ui/public/assets/images/pipeline/component-icon-7-Failed.png similarity index 100% rename from react-ui/public/assets/images/component-icon-7-Failed.png rename to react-ui/public/assets/images/pipeline/component-icon-7-Failed.png diff --git a/react-ui/public/assets/images/component-icon-7-Omitted.png b/react-ui/public/assets/images/pipeline/component-icon-7-Omitted.png similarity index 100% rename from react-ui/public/assets/images/component-icon-7-Omitted.png rename to react-ui/public/assets/images/pipeline/component-icon-7-Omitted.png diff --git a/react-ui/public/assets/images/component-icon-7-Pending.png b/react-ui/public/assets/images/pipeline/component-icon-7-Pending.png similarity index 100% rename from react-ui/public/assets/images/component-icon-7-Pending.png rename to react-ui/public/assets/images/pipeline/component-icon-7-Pending.png diff --git a/react-ui/public/assets/images/component-icon-7-Running.png b/react-ui/public/assets/images/pipeline/component-icon-7-Running.png similarity index 100% rename from react-ui/public/assets/images/component-icon-7-Running.png rename to react-ui/public/assets/images/pipeline/component-icon-7-Running.png diff --git a/react-ui/public/assets/images/component-icon-7-Skipped.png b/react-ui/public/assets/images/pipeline/component-icon-7-Skipped.png similarity index 100% rename from react-ui/public/assets/images/component-icon-7-Skipped.png rename to react-ui/public/assets/images/pipeline/component-icon-7-Skipped.png diff --git a/react-ui/public/assets/images/component-icon-7-Succeeded.png b/react-ui/public/assets/images/pipeline/component-icon-7-Succeeded.png similarity index 100% rename from react-ui/public/assets/images/component-icon-7-Succeeded.png rename to react-ui/public/assets/images/pipeline/component-icon-7-Succeeded.png diff --git a/react-ui/public/assets/images/component-icon-7.png b/react-ui/public/assets/images/pipeline/component-icon-7.png similarity index 100% rename from react-ui/public/assets/images/component-icon-7.png rename to react-ui/public/assets/images/pipeline/component-icon-7.png diff --git a/react-ui/public/assets/images/component-icon-8-Failed.png b/react-ui/public/assets/images/pipeline/component-icon-8-Failed.png similarity index 100% rename from react-ui/public/assets/images/component-icon-8-Failed.png rename to react-ui/public/assets/images/pipeline/component-icon-8-Failed.png diff --git a/react-ui/public/assets/images/component-icon-8-Omitted.png b/react-ui/public/assets/images/pipeline/component-icon-8-Omitted.png similarity index 100% rename from react-ui/public/assets/images/component-icon-8-Omitted.png rename to react-ui/public/assets/images/pipeline/component-icon-8-Omitted.png diff --git a/react-ui/public/assets/images/component-icon-8-Pending.png b/react-ui/public/assets/images/pipeline/component-icon-8-Pending.png similarity index 100% rename from react-ui/public/assets/images/component-icon-8-Pending.png rename to react-ui/public/assets/images/pipeline/component-icon-8-Pending.png diff --git a/react-ui/public/assets/images/component-icon-8-Running.png b/react-ui/public/assets/images/pipeline/component-icon-8-Running.png similarity index 100% rename from react-ui/public/assets/images/component-icon-8-Running.png rename to react-ui/public/assets/images/pipeline/component-icon-8-Running.png diff --git a/react-ui/public/assets/images/component-icon-8-Skipped.png b/react-ui/public/assets/images/pipeline/component-icon-8-Skipped.png similarity index 100% rename from react-ui/public/assets/images/component-icon-8-Skipped.png rename to react-ui/public/assets/images/pipeline/component-icon-8-Skipped.png diff --git a/react-ui/public/assets/images/component-icon-8-Succeeded.png b/react-ui/public/assets/images/pipeline/component-icon-8-Succeeded.png similarity index 100% rename from react-ui/public/assets/images/component-icon-8-Succeeded.png rename to react-ui/public/assets/images/pipeline/component-icon-8-Succeeded.png diff --git a/react-ui/public/assets/images/component-icon-8.png b/react-ui/public/assets/images/pipeline/component-icon-8.png similarity index 100% rename from react-ui/public/assets/images/component-icon-8.png rename to react-ui/public/assets/images/pipeline/component-icon-8.png diff --git a/react-ui/public/assets/images/pytorch推理.png b/react-ui/public/assets/images/pytorch推理.png deleted file mode 100644 index 11f2d37f..00000000 Binary files a/react-ui/public/assets/images/pytorch推理.png and /dev/null differ diff --git a/react-ui/public/assets/images/pytorch训练.png b/react-ui/public/assets/images/pytorch训练.png deleted file mode 100644 index 81677987..00000000 Binary files a/react-ui/public/assets/images/pytorch训练.png and /dev/null differ diff --git a/react-ui/public/assets/images/sjj-icon-1.png b/react-ui/public/assets/images/sjj-icon-1.png deleted file mode 100644 index 3f2e7d4f..00000000 Binary files a/react-ui/public/assets/images/sjj-icon-1.png and /dev/null differ diff --git a/react-ui/public/assets/images/tensorflow模型转换.png b/react-ui/public/assets/images/tensorflow模型转换.png deleted file mode 100644 index 4e58c5d7..00000000 Binary files a/react-ui/public/assets/images/tensorflow模型转换.png and /dev/null differ diff --git a/react-ui/public/assets/images/发送通知.png b/react-ui/public/assets/images/发送通知.png deleted file mode 100644 index 9e4d563a..00000000 Binary files a/react-ui/public/assets/images/发送通知.png and /dev/null differ diff --git a/react-ui/src/app.tsx b/react-ui/src/app.tsx index 66005f50..becc1abc 100644 --- a/react-ui/src/app.tsx +++ b/react-ui/src/app.tsx @@ -184,10 +184,14 @@ export function render(oldRender: () => void) { oldRender(); return; } - getRoutersInfo().then((res) => { - setRemoteMenu(res); - oldRender(); - }); + getRoutersInfo() + .then((res) => { + setRemoteMenu(res); + oldRender(); + }) + .catch(() => { + oldRender(); + }); } // 主题修改 diff --git a/react-ui/src/assets/img/model-deployment.zip b/react-ui/src/assets/img/model-deployment.zip new file mode 100644 index 00000000..1bd161a1 Binary files /dev/null and b/react-ui/src/assets/img/model-deployment.zip differ diff --git a/react-ui/src/components/CommonTableCell/index.tsx b/react-ui/src/components/CommonTableCell/index.tsx index 65a1dff2..6c2f35b0 100644 --- a/react-ui/src/components/CommonTableCell/index.tsx +++ b/react-ui/src/components/CommonTableCell/index.tsx @@ -4,8 +4,18 @@ * @Description: 自定义 Table 单元格,没有数据时展示 -- */ -function CommonTableCell(text?: string | null) { +import { Tooltip } from 'antd'; + +function renderCell(text?: string | null) { return {text ?? '--'}; } +function CommonTableCell(ellipsis: boolean = false) { + if (ellipsis) { + return (text?: string | null) => {renderCell(text)}; + } else { + return renderCell; + } +} + export default CommonTableCell; diff --git a/react-ui/src/components/DateTableCell/index.tsx b/react-ui/src/components/DateTableCell/index.tsx index 0b4efe93..ea629ba7 100644 --- a/react-ui/src/components/DateTableCell/index.tsx +++ b/react-ui/src/components/DateTableCell/index.tsx @@ -4,6 +4,7 @@ * @Description: 自定义 Table 日期类单元格 */ +import { formatDate } from '@/utils/date'; import dayjs from 'dayjs'; function DateTableCell(text?: string | null) { @@ -13,7 +14,7 @@ function DateTableCell(text?: string | null) { if (!dayjs(text).isValid()) { return 无效的日期; } - return {dayjs(text).format('YYYY-MM-DD HH:mm:ss')}; + return {formatDate(text)}; } export default DateTableCell; diff --git a/react-ui/src/components/KFModal/index.tsx b/react-ui/src/components/KFModal/index.tsx index 0105324f..8fea54bc 100644 --- a/react-ui/src/components/KFModal/index.tsx +++ b/react-ui/src/components/KFModal/index.tsx @@ -12,11 +12,12 @@ import './index.less'; export interface KFModalProps extends ModalProps { image?: string; } -function KFModal({ title, image, children, className = '', ...rest }: KFModalProps) { +function KFModal({ title, image, children, className = '', centered, ...rest }: KFModalProps) { return ( } > {children} diff --git a/react-ui/src/components/RightContent/index.tsx b/react-ui/src/components/RightContent/index.tsx index 70e57e23..75d86186 100644 --- a/react-ui/src/components/RightContent/index.tsx +++ b/react-ui/src/components/RightContent/index.tsx @@ -2,6 +2,7 @@ import { useEmotionCss } from '@ant-design/use-emotion-css'; import { useModel } from '@umijs/max'; import React from 'react'; import Avatar from './AvatarDropdown'; +// import { SelectLang } from '@umijs/max'; export type SiderTheme = 'light' | 'dark'; diff --git a/react-ui/src/pages/Dataset/components/AddDatasetModal/index.less b/react-ui/src/pages/Dataset/components/AddDatasetModal/index.less index 529521af..66022fdd 100644 --- a/react-ui/src/pages/Dataset/components/AddDatasetModal/index.less +++ b/react-ui/src/pages/Dataset/components/AddDatasetModal/index.less @@ -4,6 +4,6 @@ } .upload-button { - height: 48px; + height: 46px; font-size: 15px; } diff --git a/react-ui/src/pages/Dataset/components/AddDatasetModal/index.tsx b/react-ui/src/pages/Dataset/components/AddDatasetModal/index.tsx index c83d5143..dbb8fc84 100644 --- a/react-ui/src/pages/Dataset/components/AddDatasetModal/index.tsx +++ b/react-ui/src/pages/Dataset/components/AddDatasetModal/index.tsx @@ -23,7 +23,7 @@ import { useEffect, useState } from 'react'; import { CategoryData } from '../../type'; import styles from './index.less'; -interface AddDatasetModalProps extends ModalProps { +interface AddDatasetModalProps extends Omit { typeList: CategoryData[]; tagList: CategoryData[]; onOk: () => void; @@ -94,15 +94,7 @@ function AddDatasetModal({ typeList, tagList, onOk, ...rest }: AddDatasetModalPr }} destroyOnClose > -
+ @@ -142,6 +136,8 @@ function AddDatasetModal({ typeList, tagList, onOk, ...rest }: AddDatasetModalPr placeholder="请选择研究方向/应用领域" options={tagList} fieldNames={{ label: 'name', value: 'id' }} + optionFilterProp="name" + showSearch /> diff --git a/react-ui/src/pages/Model/components/AddModelModal/index.tsx b/react-ui/src/pages/Dataset/components/AddModelModal/index.tsx similarity index 93% rename from react-ui/src/pages/Model/components/AddModelModal/index.tsx rename to react-ui/src/pages/Dataset/components/AddModelModal/index.tsx index e04b1ba1..21e76faa 100644 --- a/react-ui/src/pages/Model/components/AddModelModal/index.tsx +++ b/react-ui/src/pages/Dataset/components/AddModelModal/index.tsx @@ -18,9 +18,9 @@ import { } from 'antd'; import { omit } from 'lodash'; import { useState } from 'react'; -import styles from './index.less'; +import styles from '../AddDatasetModal/index.less'; -interface AddModelModalProps extends ModalProps { +interface AddModelModalProps extends Omit { typeList: CategoryData[]; tagList: CategoryData[]; onOk: () => void; @@ -76,15 +76,7 @@ function AddModelModal({ typeList, tagList, onOk, ...rest }: AddModelModalProps) form: 'form', }} > - + @@ -148,6 +142,8 @@ function AddModelModal({ typeList, tagList, onOk, ...rest }: AddModelModalProps) placeholder="请选择模型标签" options={tagList} fieldNames={{ label: 'name', value: 'id' }} + optionFilterProp="name" + showSearch /> { + resourceType: ResourceType; + resourceId: number; + initialName: string; + onOk: () => void; +} + +function AddVersionModal({ + resourceType, + resourceId, + initialName, + onOk, + ...rest +}: AddVersionModalProps) { + const [uuid] = useState(Date.now()); + + // 上传组件参数 + const uploadProps: UploadProps = { + action: resourceConfig[resourceType].uploadAction, + headers: { + Authorization: getAccessToken() || '', + }, + defaultFileList: [], + }; + + // 上传请求 + const createDatasetVersion = async (params: any) => { + const request = resourceConfig[resourceType].addVersionReq; + const [res] = await to(request(params)); + if (res) { + message.success('创建成功'); + onOk?.(); + } + }; + + // 提交 + const onFinish = (formData: any) => { + const fileList: UploadFile[] = formData['fileList'] ?? []; + if (validateUploadFiles(fileList)) { + const otherParams = omit(formData, ['fileList']); + const params = fileList.map((item) => { + const data = item.response?.data?.[0] ?? {}; + return { + ...otherParams, + [resourceConfig[resourceType].idParamKey]: resourceId, + file_name: data.fileName, + file_size: data.fileSize, + url: data.url, + }; + }); + createDatasetVersion(params); + } + }; + + const name = resourceConfig[resourceType].name; + const accept = resourceConfig[resourceType].uploadAccept; + return ( + + + + + + + + + + + + + + + {resourceType === ResourceType.Dataset && ( +
只允许上传.zip格式文件
+ )} +
+
+ +
+ ); +} + +export default AddVersionModal; diff --git a/react-ui/src/pages/Dataset/components/ResourceList/index.tsx b/react-ui/src/pages/Dataset/components/ResourceList/index.tsx index b07cb5bf..59ff87f6 100644 --- a/react-ui/src/pages/Dataset/components/ResourceList/index.tsx +++ b/react-ui/src/pages/Dataset/components/ResourceList/index.tsx @@ -1,6 +1,6 @@ import KFIcon from '@/components/KFIcon'; import { CommonTabKeys } from '@/enums'; -import AddModelModal from '@/pages/Model/components/AddModelModal'; +import AddModelModal from '@/pages/Dataset/components/AddModelModal'; import { openAntdModal } from '@/utils/modal'; import { to } from '@/utils/promise'; import { modalConfirm } from '@/utils/ui'; diff --git a/react-ui/src/pages/Dataset/datasetIntro.jsx b/react-ui/src/pages/Dataset/intro.jsx similarity index 63% rename from react-ui/src/pages/Dataset/datasetIntro.jsx rename to react-ui/src/pages/Dataset/intro.jsx index 16128aeb..85539c9a 100644 --- a/react-ui/src/pages/Dataset/datasetIntro.jsx +++ b/react-ui/src/pages/Dataset/intro.jsx @@ -1,56 +1,25 @@ -import { getAccessToken } from '@/access'; import KFIcon from '@/components/KFIcon'; -import KFModal from '@/components/KFModal'; +import { ResourceType } from '@/pages/Dataset/type'; import { - addDatasetVersionDetail, deleteDatasetVersion, getDatasetById, getDatasetVersionIdList, getDatasetVersionsById, } from '@/services/dataset/index.js'; +import { formatDate } from '@/utils/date'; import { downLoadZip } from '@/utils/downloadfile'; +import { openAntdModal } from '@/utils/modal'; import { modalConfirm } from '@/utils/ui'; -import { UploadOutlined } from '@ant-design/icons'; import { useParams, useSearchParams } from '@umijs/max'; -import { Button, Form, Input, Select, Table, Tabs, Upload, message } from 'antd'; -import moment from 'moment'; +import { Button, Input, Select, Table, Tabs, message } from 'antd'; import { useEffect, useRef, useState } from 'react'; -import Styles from './index.less'; +import AddVersionModal from './components/AddVersionModal'; +import Styles from './intro.less'; const { Search } = Input; const { TabPane } = Tabs; const Dataset = () => { - const props = { - action: '/api/mmp/dataset/upload', - // headers: { - // 'X-Requested-With': null - // }, - headers: { - Authorization: getAccessToken(), - 'X-Requested-With': null, - }, - onChange({ file, fileList }) { - if (file.status !== 'uploading') { - console.log(file, fileList); - setFormList( - fileList.map((item) => { - return { - ...form.getFieldsValue(), - dataset_id: locationParams.id, - file_name: item.response.code === 200 ? item.response.data[0].fileName : null, - file_size: item.response.code === 200 ? item.response.data[0].fileSize : null, - url: item.response.code === 200 ? item.response.data[0].url : null, - }; - }), - ); - } - }, - defaultFileList: [], - }; - const [form] = Form.useForm(); const [formList, setFormList] = useState([]); - const [dialogTitle, setDialogTitle] = useState('新建版本'); - const [isModalOpen, setIsModalOpen] = useState(false); const [datasetDetailObj, setDatasetDetailObj] = useState({}); const [version, setVersion] = useState(null); const [versionList, setVersionList] = useState([]); @@ -58,8 +27,8 @@ const Dataset = () => { const [searchParams] = useSearchParams(); const [wordList, setWordList] = useState([]); const [activeTabKey, setActiveTabKey] = useState('1'); - const [uuid, setUuid] = useState(Date.now()); const isPublic = searchParams.get('isPublic') === 'true'; + const getDatasetByDetail = () => { getDatasetById(locationParams.id).then((ret) => { console.log(ret); @@ -93,21 +62,17 @@ const Dataset = () => { return () => {}; }, []); const showModal = () => { - form.resetFields(); - form.setFieldsValue({ name: datasetDetailObj.name }); - - setDialogTitle('创建新版本'); - setUuid(Date.now()); - setIsModalOpen(true); - }; - const handleCancel = () => { - setIsModalOpen(false); - }; - const handleExport = async () => { - const hide = message.loading('正在下载'); - hide(); - downLoadZip(`/api/mmp/dataset/downloadAllFiles`, { dataset_id: locationParams.id, version }); + const { close } = openAntdModal(AddVersionModal, { + resourceType: ResourceType.Dataset, + resourceId: locationParams.id, + initialName: datasetDetailObj.name, + onOk: () => { + getDatasetVersionList(); + close(); + }, + }); }; + const deleteDataset = () => { modalConfirm({ title: '删除后,该数据集版本将不可恢复', @@ -120,19 +85,26 @@ const Dataset = () => { }, }); }; - const onFinish = (values) => { - addDatasetVersionDetail(formList).then((ret) => { - getDatasetVersionList(); - setIsModalOpen(false); - message.success('创建成功'); - }); - }; // 获取版本下的文件列表 const getDatasetVersions = (params) => { getDatasetVersionIdList(params).then((res) => { setWordList(res?.data?.content ?? []); }); }; + + const handleExport = async () => { + const hide = message.loading('正在下载'); + hide(); + downLoadZip(`/api/mmp/dataset/downloadAllFiles`, { dataset_id: locationParams.id, version }); + }; + + const downloadAlone = (e, record) => { + console.log(record); + const hide = message.loading('正在下载'); + hide(); + downLoadZip(`/api/mmp/dataset/download/${record.id}`); + }; + const handleChange = (value) => { console.log(value); if (value) { @@ -142,15 +114,7 @@ const Dataset = () => { setVersion(null); } }; - const onFinishFailed = (errorInfo) => { - console.log('Failed:', errorInfo); - }; - const downloadAlone = (e, record) => { - console.log(record); - const hide = message.loading('正在下载'); - hide(); - downLoadZip(`/api/mmp/dataset/download/${record.id}`); - }; + const columns = [ { title: '序号', @@ -182,7 +146,7 @@ const Dataset = () => { title: '更新时间', dataIndex: 'update_time', key: 'update_time', - render: (text) => {moment(text).format('YYYY-MM-DD HH:mm:ss')}, + render: (text) => {formatDate(text)}, }, { title: '操作', @@ -292,98 +256,6 @@ const Dataset = () => { - -
- - - - - - - - - - - - -
只允许上传.zip,.tgz格式文件
-
-
-
-
); }; diff --git a/react-ui/src/pages/Dataset/index.less b/react-ui/src/pages/Dataset/intro.less similarity index 100% rename from react-ui/src/pages/Dataset/index.less rename to react-ui/src/pages/Dataset/intro.less diff --git a/react-ui/src/pages/Dataset/type.tsx b/react-ui/src/pages/Dataset/type.tsx index 91808ea2..3bc7f2fe 100644 --- a/react-ui/src/pages/Dataset/type.tsx +++ b/react-ui/src/pages/Dataset/type.tsx @@ -1,6 +1,8 @@ import KFIcon from '@/components/KFIcon'; import { CommonTabKeys } from '@/enums'; import { + addDatasetVersionDetail, + addModelsVersionDetail, deleteDataset, deleteModel, getDatasetList, @@ -18,9 +20,9 @@ export enum ResourceType { } type ResourceTypeKeys = keyof typeof ResourceType; -type ResourceTypeValues = (typeof ResourceType)[ResourceTypeKeys]; +export type ResourceTypeValues = (typeof ResourceType)[ResourceTypeKeys]; -export type ResourceTypeInfo = { +type ResourceTypeInfo = { getList: (params: any) => Promise; getVersions: (params: any) => Promise; getFiles: (params: any) => Promise; @@ -37,6 +39,10 @@ export type ResourceTypeInfo = { iconPathPrefix: string; // 图标路径前缀 deleteModalTitle: string; // 删除弹框的title addBtnTitle: string; // 新增按钮的title + addVersionReq: (params: any) => Promise; + idParamKey: string; + uploadAction: string; + uploadAccept?: string; }; export const resourceConfig: Record = { @@ -68,6 +74,10 @@ export const resourceConfig: Record = { iconPathPrefix: 'dataset', deleteModalTitle: '确定删除该条数据集实例吗?', addBtnTitle: '新建数据集', + addVersionReq: addDatasetVersionDetail, + idParamKey: 'dataset_id', + uploadAction: '/api/mmp/dataset/upload', + uploadAccept: '.zip,.tgz', }, [ResourceType.Model]: { getList: getModelList, @@ -97,6 +107,10 @@ export const resourceConfig: Record = { iconPathPrefix: 'model', deleteModalTitle: '确定删除该条模型实例吗?', addBtnTitle: '新建模型', + addVersionReq: addModelsVersionDetail, + idParamKey: 'models_id', + uploadAction: '/api/mmp/models/upload', + uploadAccept: undefined, }, }; diff --git a/react-ui/src/pages/Experiment/experimentText/addExperimentModal.less b/react-ui/src/pages/Experiment/components/AddExperimentModal/index.less similarity index 100% rename from react-ui/src/pages/Experiment/experimentText/addExperimentModal.less rename to react-ui/src/pages/Experiment/components/AddExperimentModal/index.less diff --git a/react-ui/src/pages/Experiment/experimentText/addExperimentModal.tsx b/react-ui/src/pages/Experiment/components/AddExperimentModal/index.tsx similarity index 99% rename from react-ui/src/pages/Experiment/experimentText/addExperimentModal.tsx rename to react-ui/src/pages/Experiment/components/AddExperimentModal/index.tsx index f5b2bfc4..2300c0f1 100644 --- a/react-ui/src/pages/Experiment/experimentText/addExperimentModal.tsx +++ b/react-ui/src/pages/Experiment/components/AddExperimentModal/index.tsx @@ -4,7 +4,7 @@ import KFModal from '@/components/KFModal'; import { type PipelineGlobalParam } from '@/types'; import { Form, Input, Radio, Select, type FormRule } from 'antd'; import { useState } from 'react'; -import styles from './addExperimentModal.less'; +import styles from './index.less'; type FormData = { name?: string; diff --git a/react-ui/src/pages/Experiment/experimentText/paramsModal.less b/react-ui/src/pages/Experiment/components/ViewParamsModal/index.less similarity index 100% rename from react-ui/src/pages/Experiment/experimentText/paramsModal.less rename to react-ui/src/pages/Experiment/components/ViewParamsModal/index.less diff --git a/react-ui/src/pages/Experiment/experimentText/paramsModal.tsx b/react-ui/src/pages/Experiment/components/ViewParamsModal/index.tsx similarity index 91% rename from react-ui/src/pages/Experiment/experimentText/paramsModal.tsx rename to react-ui/src/pages/Experiment/components/ViewParamsModal/index.tsx index 1bdb0cec..f860135a 100644 --- a/react-ui/src/pages/Experiment/experimentText/paramsModal.tsx +++ b/react-ui/src/pages/Experiment/components/ViewParamsModal/index.tsx @@ -6,8 +6,8 @@ import parameterImg from '@/assets/img/modal-parameter.png'; import KFModal from '@/components/KFModal'; import { type PipelineGlobalParam } from '@/types'; -import { getParamType } from './addExperimentModal'; -import styles from './paramsModal.less'; +import { getParamType } from '../AddExperimentModal'; +import styles from './index.less'; type ParamsModalProps = { open: boolean; @@ -24,6 +24,7 @@ function ParamsModal({ open, onCancel, globalParam = [] }: ParamsModalProps) { onOk={onCancel} onCancel={onCancel} cancelButtonProps={{ style: { display: 'none' } }} + width={825} >
{globalParam?.map((item) => ( diff --git a/react-ui/src/pages/Experiment/experimentText/index.jsx b/react-ui/src/pages/Experiment/experimentText/index.jsx index a5ed2ffc..6d70e060 100644 --- a/react-ui/src/pages/Experiment/experimentText/index.jsx +++ b/react-ui/src/pages/Experiment/experimentText/index.jsx @@ -1,17 +1,16 @@ import { useVisible } from '@/hooks'; import { getExperimentIns } from '@/services/experiment/index.js'; import { getWorkflowById } from '@/services/pipeline/index.js'; -import { elapsedTime } from '@/utils/date'; +import { elapsedTime, formatDate } from '@/utils/date'; import { useEmotionCss } from '@ant-design/use-emotion-css'; import G6 from '@antv/g6'; import { Button } from 'antd'; -import momnet from 'moment'; import { useEffect, useRef, useState } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; import { s8 } from '../../../utils'; +import ParamsModal from '../components/ViewParamsModal'; import { experimentStatusInfo } from '../status'; import styles from './index.less'; -import ParamsModal from './paramsModal'; import Props from './props'; function ExperimentText() { @@ -389,9 +388,7 @@ function ExperimentText() {
-
- 启动时间:{momnet(message.create_time).format('YYYY-MM-DD HH:mm:ss')} -
+
启动时间:{formatDate(message.create_time)}
执行时长: {message.finish_time diff --git a/react-ui/src/pages/Experiment/experimentText/props.jsx b/react-ui/src/pages/Experiment/experimentText/props.jsx index 7683c833..98ef4984 100644 --- a/react-ui/src/pages/Experiment/experimentText/props.jsx +++ b/react-ui/src/pages/Experiment/experimentText/props.jsx @@ -1,5 +1,5 @@ import { getNodeResult, getQueryByExperimentLog } from '@/services/experiment/index.js'; -import { elapsedTime } from '@/utils/date'; +import { elapsedTime, formatDate } from '@/utils/date'; import { downLoadZip } from '@/utils/downloadfile'; import { DatabaseOutlined, ProfileOutlined } from '@ant-design/icons'; import { Drawer, Form, Input, Tabs, message } from 'antd'; @@ -419,7 +419,7 @@ const Props = forwardRef(({ onParentChange }, ref) => {
- 启动时间:{moment(stagingItem.experimentStartTime).format('YYYY-MM-DD HH:mm:ss')} + 启动时间:{formatDate(stagingItem.experimentStartTime)}
耗时: diff --git a/react-ui/src/pages/Experiment/index.jsx b/react-ui/src/pages/Experiment/index.jsx index 611c18c6..43db02f9 100644 --- a/react-ui/src/pages/Experiment/index.jsx +++ b/react-ui/src/pages/Experiment/index.jsx @@ -14,16 +14,15 @@ import { } from '@/services/experiment/index.js'; import { getWorkflow } from '@/services/pipeline/index.js'; import themes from '@/styles/theme.less'; -import { elapsedTime } from '@/utils/date'; +import { elapsedTime, formatDate } from '@/utils/date'; import { to } from '@/utils/promise'; import { modalConfirm } from '@/utils/ui'; import { Button, ConfigProvider, Space, Table, message } from 'antd'; import classNames from 'classnames'; -import momnet from 'moment'; import { useEffect, useRef, useState } from 'react'; import { useNavigate } from 'react-router-dom'; +import AddExperimentModal from './components/AddExperimentModal'; import TensorBoardStatus, { TensorBoardStatusEnum } from './components/TensorBoardStatus'; -import AddExperimentModal from './experimentText/addExperimentModal'; import Styles from './index.less'; import { experimentStatusInfo } from './status'; @@ -442,9 +441,7 @@ function Experiment() { ? elapsedTime(new Date(item.create_time), new Date(item.finish_time)) : elapsedTime(new Date(item.create_time), new Date())}
-
- {momnet(item.create_time).format('YYYY-MM-DD HH:mm:ss')} -
+
{formatDate(item.create_time)}
{ - const props = { - action: '/api/mmp/models/upload', - // headers: { - // 'X-Requested-With': null - // }, - headers: { - Authorization: getAccessToken(), - 'X-Requested-With': null, - }, - onChange({ file, fileList }) { - if (file.status !== 'uploading') { - console.log(file, fileList); - setFormList( - fileList.map((item) => { - return { - ...form.getFieldsValue(), - models_id: locationParams.id, - file_name: item.response.code === 200 ? item.response.data[0].fileName : null, - file_size: item.response.code === 200 ? item.response.data[0].fileSize : null, - url: item.response.code === 200 ? item.response.data[0].url : null, - }; - }), - ); - } - }, - defaultFileList: [], - }; - const [form] = Form.useForm(); const [formList, setFormList] = useState([]); - const [dialogTitle, setDialogTitle] = useState('新建版本'); - const [isModalOpen, setIsModalOpen] = useState(false); const [datasetDetailObj, setDatasetDetailObj] = useState({}); const [version, setVersion] = useState(null); const [versionList, setVersionList] = useState([]); const locationParams = useParams(); //新版本获取路由参数接口 const [searchParams] = useSearchParams(); - console.log(locationParams); const [wordList, setWordList] = useState([]); - const [uuid, setUuid] = useState(Date.now()); const isPublic = searchParams.get('isPublic') === 'true'; + const getModelByDetail = () => { getModelById(locationParams.id).then((ret) => { console.log(ret); @@ -92,16 +60,17 @@ const Dataset = () => { return () => {}; }, []); const showModal = () => { - form.resetFields(); - form.setFieldsValue({ name: datasetDetailObj.name }); - - setDialogTitle('创建新版本'); - setUuid(Date.now()); - setIsModalOpen(true); - }; - const handleCancel = () => { - setIsModalOpen(false); + const { close } = openAntdModal(AddVersionModal, { + resourceType: ResourceType.Model, + resourceId: locationParams.id, + initialName: datasetDetailObj.name, + onOk: () => { + getModelVersionsList(); + close(); + }, + }); }; + const deleteDataset = () => { modalConfirm({ title: '删除后,该版本将不可恢复', @@ -117,13 +86,7 @@ const Dataset = () => { }, }); }; - const onFinish = () => { - addModelsVersionDetail(formList).then((ret) => { - getModelVersionsList(); - setIsModalOpen(false); - message.success('创建成功'); - }); - }; + const getModelVersions = (params) => { getModelVersionIdList(params).then((ret) => { setWordList(ret?.data?.content ?? []); @@ -149,9 +112,7 @@ const Dataset = () => { setVersion(''); } }; - const onFinishFailed = (errorInfo) => { - console.log('Failed:', errorInfo); - }; + const columns = [ { title: '序号', @@ -183,7 +144,7 @@ const Dataset = () => { title: '更新时间', dataIndex: 'update_time', key: 'update_time', - render: (text) => {moment(text).format('YYYY-MM-DD HH:mm:ss')}, + render: (text) => {formatDate(text)}, }, { title: '操作', @@ -294,96 +255,6 @@ const Dataset = () => {
- -
- - - - - - - - - - - - - - -
-
); }; diff --git a/react-ui/src/pages/Model/index.less b/react-ui/src/pages/Model/intro.less similarity index 100% rename from react-ui/src/pages/Model/index.less rename to react-ui/src/pages/Model/intro.less diff --git a/react-ui/src/pages/ModelDeployment/components/MirrorStatusCell/index.less b/react-ui/src/pages/ModelDeployment/components/MirrorStatusCell/index.less new file mode 100644 index 00000000..043bf411 --- /dev/null +++ b/react-ui/src/pages/ModelDeployment/components/MirrorStatusCell/index.less @@ -0,0 +1,11 @@ +.mirror-status-cell { + color: @text-color; + + &--success { + color: @success-color; + } + + &--error { + color: @error-color; + } +} diff --git a/react-ui/src/pages/ModelDeployment/components/MirrorStatusCell/index.tsx b/react-ui/src/pages/ModelDeployment/components/MirrorStatusCell/index.tsx new file mode 100644 index 00000000..3702825f --- /dev/null +++ b/react-ui/src/pages/ModelDeployment/components/MirrorStatusCell/index.tsx @@ -0,0 +1,39 @@ +/* + * @Author: 赵伟 + * @Date: 2024-04-18 18:35:41 + * @Description: + */ +import { MirrorVersionStatus } from '@/enums'; +import styles from './index.less'; + +type MirrorVersionStatusKeys = keyof typeof MirrorVersionStatus; +type MirrorVersionStatusValues = (typeof MirrorVersionStatus)[MirrorVersionStatusKeys]; + +export type MirrorVersionStatusInfo = { + text: string; + classname: string; +}; + +const statusInfo: Record = { + [MirrorVersionStatus.Building]: { + text: '构建中', + classname: styles['mirror-status-cell'], + }, + [MirrorVersionStatus.Available]: { + classname: styles['mirror-status-cell--success'], + text: '可用', + }, + [MirrorVersionStatus.Failed]: { + classname: styles['mirror-status-cell--error'], + text: '构建失败', + }, +}; + +function MirrorStatusCell(status: MirrorVersionStatus) { + if (status === null || status === undefined || !statusInfo[status]) { + return --; + } + return {statusInfo[status].text}; +} + +export default MirrorStatusCell; diff --git a/react-ui/src/pages/ModelDeployment/create.less b/react-ui/src/pages/ModelDeployment/create.less new file mode 100644 index 00000000..63c00764 --- /dev/null +++ b/react-ui/src/pages/ModelDeployment/create.less @@ -0,0 +1,17 @@ +.model-deployment-create { + height: 100%; + + &__content { + height: calc(100% - 60px); + margin-top: 10px; + padding: 30px 30px 10px; + overflow: auto; + background-color: white; + border-radius: 10px; + + &__type { + color: @text-color; + font-size: @font-size-input-lg; + } + } +} diff --git a/react-ui/src/pages/ModelDeployment/create.tsx b/react-ui/src/pages/ModelDeployment/create.tsx new file mode 100644 index 00000000..cc2c43ff --- /dev/null +++ b/react-ui/src/pages/ModelDeployment/create.tsx @@ -0,0 +1,297 @@ +/* + * @Author: 赵伟 + * @Date: 2024-04-16 13:58:08 + * @Description: 创建模型部署 + */ +import PageTitle from '@/components/PageTitle'; +import SubAreaTitle from '@/components/SubAreaTitle'; +import { CommonTabKeys } from '@/enums'; +import { createMirrorReq } from '@/services/mirror'; +import { getComputingResourceReq } from '@/services/pipeline'; +import { to } from '@/utils/promise'; +import { getSessionItemThenRemove, mirrorNameKey } from '@/utils/sessionStorage'; +import { validateUploadFiles } from '@/utils/ui'; +import { useNavigate } from '@umijs/max'; +import { Button, Col, Form, Input, Row, Select, UploadFile, message, type SelectProps } from 'antd'; +import { omit } from 'lodash'; +import { useEffect, useState } from 'react'; +import styles from './create.less'; + +type FormData = { + name: string; + tag: string; + description: string; + path?: string; + upload_type: string; + fileList?: UploadFile[]; +}; + +function ModelDeploymentCreate() { + const navgite = useNavigate(); + const [form] = Form.useForm(); + const [nameDisabled, setNameDisabled] = useState(false); + const [resourceStandardList, setResourceStandardList] = useState([]); + + useEffect(() => { + const name = getSessionItemThenRemove(mirrorNameKey); + if (name) { + form.setFieldValue('name', name); + setNameDisabled(true); + } + 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 filterResourceStandard: SelectProps['filterOption'] = ( + input: string, + { computing_resource = '' }, + ) => { + return computing_resource.toLocaleLowerCase().includes(input.toLocaleLowerCase()); + }; + + // 创建公网、本地镜像 + const createPublicMirror = async (formData: FormData) => { + const upload_type = formData['upload_type']; + let params; + if (upload_type === CommonTabKeys.Public) { + params = { + ...omit(formData, ['upload_type']), + upload_type: 0, + image_type: 0, + }; + } else { + const fileList = formData['fileList'] ?? []; + if (validateUploadFiles(fileList)) { + const file = fileList[0]; + params = { + ...omit(formData, ['fileList', 'upload_type']), + path: file.response.data.url, + file_size: file.response.data.fileSize, + upload_type: 1, + image_type: 0, + }; + } + } + + const [res] = await to(createMirrorReq(params)); + if (res) { + message.success('创建成功'); + navgite(-1); + } + }; + + // 提交 + const handleSubmit = (values: FormData) => { + createPublicMirror(values); + }; + + // 取消 + const cancel = () => { + navgite(-1); + }; + + return ( +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ ); +} + +export default ModelDeploymentCreate; diff --git a/react-ui/src/pages/ModelDeployment/info.less b/react-ui/src/pages/ModelDeployment/info.less new file mode 100644 index 00000000..c77a7070 --- /dev/null +++ b/react-ui/src/pages/ModelDeployment/info.less @@ -0,0 +1,53 @@ +.model-deployment-info { + height: 100%; + + &__basic { + &__item { + display: flex; + align-items: flex-start; + font-size: 16px; + line-height: 1.6; + + .label { + width: 80px; + color: @text-color-secondary; + } + + .value { + flex: 1; + color: @text-color; + } + } + } + + &__content { + height: calc(100% - 60px); + margin-top: 10px; + padding: 30px 30px 0; + background-color: white; + border-radius: 10px; + + &__title { + display: flex; + align-items: center; + } + + &__table { + :global { + .ant-table-wrapper { + height: 100%; + .ant-spin-nested-loading { + height: 100%; + } + .ant-spin-container { + height: 100%; + } + .ant-table { + height: calc(100% - 74px); + overflow: auto; + } + } + } + } + } +} diff --git a/react-ui/src/pages/ModelDeployment/info.tsx b/react-ui/src/pages/ModelDeployment/info.tsx new file mode 100644 index 00000000..3e4e8a81 --- /dev/null +++ b/react-ui/src/pages/ModelDeployment/info.tsx @@ -0,0 +1,148 @@ +/* + * @Author: 赵伟 + * @Date: 2024-04-16 13:58:08 + * @Description: 镜像详情 + */ +import KFIcon from '@/components/KFIcon'; +import PageTitle from '@/components/PageTitle'; +import SubAreaTitle from '@/components/SubAreaTitle'; +import { getMirrorInfoReq } from '@/services/mirror'; +import { formatDate } from '@/utils/date'; +import { to } from '@/utils/promise'; +import { useNavigate, useParams } from '@umijs/max'; +import { Col, Row, Tabs, type TabsProps } from 'antd'; +import { useEffect, useState } from 'react'; +import styles from './info.less'; + +type MirrorInfoData = { + name?: string; + description?: string; + version_count?: string; + create_time?: string; +}; + +type MirrorVersionData = { + id: number; + version: string; + url: string; + status: string; + file_size: string; + create_time: string; +}; + +const tabItems = [ + { + key: '1', + label: '预测', + icon: , + }, + { + key: '2', + label: '调用指南', + icon: , + }, + { + key: '3', + label: '服务日志', + icon: , + }, +]; + +function ModelDeploymentInfo() { + const navigate = useNavigate(); + const urlParams = useParams(); + + const [mirrorInfo, setMirrorInfo] = useState({}); + + const [activeTab, setActiveTab] = useState('1'); + useEffect(() => { + getMirrorInfo(); + }, []); + + // 获取镜像详情 + const getMirrorInfo = async () => { + const id = Number(urlParams.id); + const [res] = await to(getMirrorInfoReq(id)); + if (res && res.data) { + const { name = '', description = '', version_count = '', create_time: time } = res.data; + const create_time = formatDate(time); + setMirrorInfo({ + name, + description, + version_count, + create_time, + }); + } + }; + + // 切换 Tab,重置数据 + const hanleTabChange: TabsProps['onChange'] = (value) => { + setActiveTab(value); + }; + + return ( +
+ +
+
+ +
+ + +
+
服务名称:
+
{mirrorInfo.name}
+
+ + +
+
镜像:
+
{mirrorInfo.version_count ?? '--'}
+
+ +
+ + +
+
状态:
+
{mirrorInfo.name}
+
+ + +
+
模型:
+
{mirrorInfo.version_count ?? '--'}
+
+ +
+ + +
+
环境变量:
+
{mirrorInfo.name}
+
+ +
+ + +
+
描述:
+
{mirrorInfo.description}
+
+ +
+
+
+ +
+
+
+
+ ); +} + +export default ModelDeploymentInfo; diff --git a/react-ui/src/pages/ModelDeployment/list.less b/react-ui/src/pages/ModelDeployment/list.less new file mode 100644 index 00000000..9e521f70 --- /dev/null +++ b/react-ui/src/pages/ModelDeployment/list.less @@ -0,0 +1,21 @@ +.model-deployment { + height: 100%; + &__content { + height: calc(100% - 60px); + margin-top: 10px; + padding: 20px 30px 0; + background-color: white; + border-radius: 10px; + + &__filter { + display: flex; + align-items: center; + justify-content: space-between; + } + + &__table { + height: calc(100% - 32px - 28px); + margin-top: 28px; + } + } +} diff --git a/react-ui/src/pages/ModelDeployment/list.tsx b/react-ui/src/pages/ModelDeployment/list.tsx new file mode 100644 index 00000000..bfad5a22 --- /dev/null +++ b/react-ui/src/pages/ModelDeployment/list.tsx @@ -0,0 +1,283 @@ +/* + * @Author: 赵伟 + * @Date: 2024-04-16 13:58:08 + * @Description: 模型部署列表 + */ +import CommonTableCell from '@/components/CommonTableCell'; +import DateTableCell from '@/components/DateTableCell'; +import KFIcon from '@/components/KFIcon'; +import PageTitle from '@/components/PageTitle'; +import { useCacheState } from '@/hooks/pageCacheState'; +import { deleteMirrorReq, getMirrorListReq } from '@/services/mirror'; +import themes from '@/styles/theme.less'; +import { to } from '@/utils/promise'; +import { modalConfirm } from '@/utils/ui'; +import { useNavigate } from '@umijs/max'; +import { + App, + Button, + ConfigProvider, + Input, + Table, + type TablePaginationConfig, + type TableProps, +} from 'antd'; +import { type SearchProps } from 'antd/es/input'; +import classNames from 'classnames'; +import { useEffect, useState } from 'react'; +import styles from './list.less'; + +export type MirrorData = { + id: number; + name: string; + description: string; + create_time: string; +}; + +function ModelDeployment() { + const navigate = useNavigate(); + const { message } = App.useApp(); + const [cacheState, setCacheState] = useCacheState(); + const [searchText, setSearchText] = useState(cacheState?.searchText); + const [inputText, setInputText] = useState(cacheState?.searchText); + const [tableData, setTableData] = useState([]); + const [total, setTotal] = useState(0); + const [pagination, setPagination] = useState>( + cacheState?.pagination ?? { + current: 1, + pageSize: 10, + }, + ); + + useEffect(() => { + getMirrorList(); + }, [pagination, searchText]); + + // 获取镜像列表 + const getMirrorList = async () => { + const params: Record = { + page: pagination.current - 1, + size: pagination.pageSize, + name: searchText, + image_type: 1, + }; + const [res] = await to(getMirrorListReq(params)); + if (res && res.data) { + const { content = [], totalElements = 0 } = res.data; + setTableData(content); + setTotal(totalElements); + } + }; + + // 删除镜像 + const deleteMirror = async (id: number) => { + const [res] = await to(deleteMirrorReq(id)); + if (res) { + message.success('删除成功'); + // 如果是一页的唯一数据,删除时,请求第一页的数据 + // 否则直接刷新这一页的数据 + // 避免回到第一页 + if (tableData.length > 1) { + setPagination((prev) => ({ + ...prev, + current: 1, + })); + } else { + getMirrorList(); + } + } + }; + + // 搜索 + const onSearch: SearchProps['onSearch'] = (value) => { + setSearchText(value); + }; + + // 查看详情 + const toDetail = (record: MirrorData) => { + navigate(`/modelDeployment/${record.id}`); + setCacheState({ + pagination, + searchText, + }); + }; + + // 处理删除 + const handleMirrorDelete = (record: MirrorData) => { + modalConfirm({ + title: '删除后,该镜像将不可恢复', + content: '是否确认删除?', + onOk: () => { + deleteMirror(record.id); + }, + }); + }; + + // 创建镜像 + const createMirror = () => { + navigate(`/modelDeployment/create`); + setCacheState({ + pagination, + searchText, + }); + }; + + // 分页切换 + const handleTableChange: TableProps['onChange'] = (pagination, filters, sorter, { action }) => { + if (action === 'paginate') { + setPagination(pagination); + } + // console.log(pagination, filters, sorter, action); + }; + + const columns: TableProps['columns'] = [ + { + title: '序号', + dataIndex: 'index', + key: 'index', + width: 100, + align: 'center', + render(text, record, index) { + return {(pagination.current - 1) * pagination.pageSize + index + 1}; + }, + }, + { + title: '服务名称', + dataIndex: 'name', + key: 'name', + width: '30%', + render: CommonTableCell(), + }, + { + title: '模型', + dataIndex: 'version_count', + key: 'version_count', + width: '20%', + render: CommonTableCell(), + }, + { + title: '状态', + dataIndex: 'version_count', + key: 'version_count', + width: '10%', + render: CommonTableCell(), + }, + { + title: '创建人', + dataIndex: 'description', + key: 'description', + render: CommonTableCell(true), + width: '20%', + ellipsis: { showTitle: false }, + }, + { + title: '更新时间', + dataIndex: 'create_time', + key: 'create_time', + width: '20%', + render: DateTableCell, + }, + { + title: '操作', + dataIndex: 'operation', + width: 350, + key: 'operation', + render: (_: any, record: MirrorData) => ( +
+ + + + + + +
+ ), + }, + ]; + + return ( +
+ +
+
+ setInputText(e.target.value)} + style={{ width: 300 }} + value={inputText} + /> + +
+
+ + + + + ); +} + +export default ModelDeployment; diff --git a/react-ui/src/pages/Pipeline/editPipeline/globalParamsDrawer.less b/react-ui/src/pages/Pipeline/components/GlobalParamsDrawer/index.less similarity index 100% rename from react-ui/src/pages/Pipeline/editPipeline/globalParamsDrawer.less rename to react-ui/src/pages/Pipeline/components/GlobalParamsDrawer/index.less diff --git a/react-ui/src/pages/Pipeline/editPipeline/globalParamsDrawer.tsx b/react-ui/src/pages/Pipeline/components/GlobalParamsDrawer/index.tsx similarity index 95% rename from react-ui/src/pages/Pipeline/editPipeline/globalParamsDrawer.tsx rename to react-ui/src/pages/Pipeline/components/GlobalParamsDrawer/index.tsx index 817d6dc6..e61423fd 100644 --- a/react-ui/src/pages/Pipeline/editPipeline/globalParamsDrawer.tsx +++ b/react-ui/src/pages/Pipeline/components/GlobalParamsDrawer/index.tsx @@ -1,7 +1,4 @@ -import { - getParamComponent, - getParamRules, -} from '@/pages/Experiment/experimentText/addExperimentModal'; +import { getParamComponent, getParamRules } from '@/pages/Experiment/components/AddExperimentModal'; import { type PipelineGlobalParam } from '@/types'; import { to } from '@/utils/promise'; import { modalConfirm } from '@/utils/ui'; @@ -9,7 +6,7 @@ import { DeleteOutlined, PlusOutlined } from '@ant-design/icons'; import { Button, Drawer, Form, Input, Radio, Tooltip } from 'antd'; import { NamePath } from 'antd/es/form/interface'; import { forwardRef, useImperativeHandle } from 'react'; -import styles from './globalParamsDrawer.less'; +import styles from './index.less'; type GlobalParamsDrawerProps = { open: boolean; @@ -22,7 +19,7 @@ const GlobalParamsDrawer = forwardRef( const [form] = Form.useForm(); useImperativeHandle(ref, () => ({ - getFieldsValue: async () => { + validateFields: async () => { const [values, error] = await to(form.validateFields()); if (!error && values) { return values; @@ -30,6 +27,9 @@ const GlobalParamsDrawer = forwardRef( return Promise.reject(error); } }, + getFieldsValue: () => { + return form.getFieldsValue(); + }, })); // 处理参数类型变化 diff --git a/react-ui/src/pages/Pipeline/components/PropsLabel/index.less b/react-ui/src/pages/Pipeline/components/PropsLabel/index.less new file mode 100644 index 00000000..2df39c02 --- /dev/null +++ b/react-ui/src/pages/Pipeline/components/PropsLabel/index.less @@ -0,0 +1,6 @@ +.props-label { + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; +} diff --git a/react-ui/src/pages/Pipeline/components/PropsLabel/index.tsx b/react-ui/src/pages/Pipeline/components/PropsLabel/index.tsx new file mode 100644 index 00000000..04197b75 --- /dev/null +++ b/react-ui/src/pages/Pipeline/components/PropsLabel/index.tsx @@ -0,0 +1,44 @@ +import { Button, Dropdown, type MenuProps } from 'antd'; +import { useEffect } from 'react'; +import styles from './index.less'; + +type PropsLabelProps = { + title: string; + menuItems: MenuProps['items']; + onClick?: (key: string) => void; +}; + +function PropsLabel({ title, menuItems, onClick }: PropsLabelProps) { + useEffect(() => {}, []); + + const handleItemClick: MenuProps['onClick'] = (e) => { + const keyPath = e.keyPath.reverse(); + if (keyPath[0] === 'global') { + onClick?.(`\${${e.key}}`); + } else { + onClick?.(`{{${keyPath.join('.')}}}`); + } + }; + + return ( +
+ {title} + + + +
+ ); +} + +export default PropsLabel; diff --git a/react-ui/src/pages/Pipeline/editPipeline/editPipeline.less b/react-ui/src/pages/Pipeline/editPipeline/editPipeline.less index 68188b26..382cc587 100644 --- a/react-ui/src/pages/Pipeline/editPipeline/editPipeline.less +++ b/react-ui/src/pages/Pipeline/editPipeline/editPipeline.less @@ -3,6 +3,17 @@ width: 100%; height: 100%; } +.editPipelineProps { + :global { + label { + width: 100%; + + &::after { + display: none; + } + } + } +} .editPipelinePropsContent { display: flex; align-items: center; diff --git a/react-ui/src/pages/Pipeline/editPipeline/index.jsx b/react-ui/src/pages/Pipeline/editPipeline/index.jsx index be5366dd..0c067f58 100644 --- a/react-ui/src/pages/Pipeline/editPipeline/index.jsx +++ b/react-ui/src/pages/Pipeline/editPipeline/index.jsx @@ -1,27 +1,26 @@ import KFIcon from '@/components/KFIcon'; -import { useVisible } from '@/hooks'; +import { useStateRef, useVisible } from '@/hooks'; import { getWorkflowById, saveWorkflow } from '@/services/pipeline/index.js'; import { to } from '@/utils/promise'; import { useEmotionCss } from '@ant-design/use-emotion-css'; import G6 from '@antv/g6'; import { Button, message } from 'antd'; -import { useEffect, useRef, useState } from 'react'; +import { useEffect, useRef } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; import { s8 } from '../../../utils'; +import GlobalParamsDrawer from '../components/GlobalParamsDrawer'; import Styles from './editPipeline.less'; -import GlobalParamsDrawer from './globalParamsDrawer'; import ModelMenus from './modelMenus'; import Props from './props'; +import { findAllParentNodes, findFirstDuplicate } from './utils'; let graph = null; const EditPipeline = () => { - const propsRef = useRef(); const navgite = useNavigate(); - // const [contextMenu,setContextMenu]=useState({}) let contextMenu = {}; const locationParams = useParams(); //新版本获取路由参数接口 - let sourceAnchorIdx, targetAnchorIdx; + const pipelineContainer = useEmotionCss(() => { return { display: 'flex', @@ -59,8 +58,11 @@ const EditPipeline = () => { }); const graphRef = useRef(); const paramsDrawerRef = useRef(); + const propsRef = useRef(); const [paramsDrawerOpen, openParamsDrawer, closeParamsDrawer] = useVisible(false); - const [globalParam, setGlobalParam] = useState([]); + const [globalParam, setGlobalParam, globalParamRef] = useStateRef([]); + + let sourceAnchorIdx, targetAnchorIdx; const onDragEnd = (val) => { console.log(val, 'eee'); @@ -93,17 +95,24 @@ const EditPipeline = () => { } }; const savePipeline = async (val) => { - const [res, error] = await to(paramsDrawerRef.current.getFieldsValue()); + const [res, error] = await to(paramsDrawerRef.current.validateFields()); if (error) { message.error('全局参数配置有误'); openParamsDrawer(); return; } + + const duplicateName = findFirstDuplicate(res.global_param || []); + if (duplicateName) { + message.error('全局参数配置有重复的参数名称:' + duplicateName); + openParamsDrawer(); + return; + } + const [propsRes, propsError] = await to(propsRef.current.getFieldsValue()); console.log(await to(propsRef.current.getFieldsValue())); if (propsError) { message.error('基本信息必填项需配置'); - // handlerClick(); return; } propsRef.current.propClose(); @@ -128,12 +137,19 @@ const EditPipeline = () => { }; const handlerClick = (e) => { e.stopPropagation(); - // console.log(propsRef, graph); - propsRef.current.showDrawer(e); + if (e.target.get('name') !== 'anchor-point' && e.item) { + graph.setItemState(e.item, 'nodeClicked', true); + const parentNodes = findAllParentNodes(graph, e.item); + // 如果没有打开过全局参数抽屉,获取不到全局参数 + const globalParams = + paramsDrawerRef.current.getFieldsValue().global_param || globalParamRef.current; + propsRef.current.showDrawer(e, globalParams, parentNodes); + } }; const getGraphData = (data) => { + console.log('graph', graph); if (graph) { - console.log(graph); + console.log(data); graph.data(data); graph.render(); } else { @@ -275,14 +291,13 @@ const EditPipeline = () => { if (graph && ret.data && ret.data.dag) { getGraphData(JSON.parse(ret.data.dag)); } - // graph&&graph.data(JSON.parse(ret.dag)) - // graph.render() }); }; const handlerContextMenu = (e) => { e.stopPropagation(); // this.menuType = e.item._cfg.type; }; + // 上下文菜单 const initMenu = () => { // const selectedNodes = this.selectedNodes; contextMenu = new G6.Menu({ @@ -330,8 +345,8 @@ const EditPipeline = () => { initGraph(); }; useEffect(() => { - getFirstWorkflow(locationParams.id); initMenu(); + getFirstWorkflow(locationParams.id); return () => { graph.off('node:mouseenter', (e) => { @@ -449,7 +464,7 @@ const EditPipeline = () => { }, 'rect', ); - console.log(graphRef, 'graphRef'); + graph = new G6.Graph({ container: graphRef.current, grid: true, @@ -600,13 +615,7 @@ const EditPipeline = () => { // handlerClick(e); // } // }); - graph.on('node:click', (e) => { - console.log(e.target.get('name')); - if (e.target.get('name') !== 'anchor-point' && e.item) { - graph.setItemState(e.item, 'nodeClicked', true); - handlerClick(e); - } - }); + graph.on('node:click', handlerClick); graph.on('aftercreateedge', (e) => { // update the sourceAnchor and targetAnchor for the newly added edge graph.updateItem(e.edge, { diff --git a/react-ui/src/pages/Pipeline/editPipeline/modelMenus.jsx b/react-ui/src/pages/Pipeline/editPipeline/modelMenus.jsx index deb3846a..181a4139 100644 --- a/react-ui/src/pages/Pipeline/editPipeline/modelMenus.jsx +++ b/react-ui/src/pages/Pipeline/editPipeline/modelMenus.jsx @@ -2,23 +2,6 @@ import { getComponentAll } from '@/services/pipeline/index.js'; import { Collapse } from 'antd'; import { useEffect, useState } from 'react'; import Styles from './modelMenus.less'; -const items = [ - { - key: '1', - label: 'This is panel header 1', - children: [1, 2, 3, 4, 5], - }, - { - key: '2', - label: 'This is panel header 2', - children: [1, 2, 3, 4, 5], - }, - { - key: '3', - label: 'This is panel header 3', - children: [1, 2, 3, 4, 5], - }, -]; const ModelMenus = ({ onParDragEnd }) => { const [modelMenusList, setModelMenusList] = useState([]); useEffect(() => { @@ -36,7 +19,7 @@ const ModelMenus = ({ onParDragEnd }) => { x: e.clientX, y: e.clientY, label: data.component_label, - img: `/assets/images/${data.icon_path}.png`, + img: `/assets/images/pipeline/${data.icon_path}.png`, }); }; const { Panel } = Collapse; @@ -64,7 +47,7 @@ const ModelMenus = ({ onParDragEnd }) => { > {ele.component_label} diff --git a/react-ui/src/pages/Pipeline/editPipeline/props.jsx b/react-ui/src/pages/Pipeline/editPipeline/props.jsx index df77d981..6f7d2586 100644 --- a/react-ui/src/pages/Pipeline/editPipeline/props.jsx +++ b/react-ui/src/pages/Pipeline/editPipeline/props.jsx @@ -5,22 +5,25 @@ import { to } from '@/utils/promise'; import { Button, Drawer, Form, Input, Select } from 'antd'; import { pick } from 'lodash'; import { forwardRef, useEffect, useImperativeHandle, useState } from 'react'; +import PropsLabel from '../components/PropsLabel'; import ResourceSelectorModal, { ResourceSelectorType } from '../components/ResourceSelectorModal'; import Styles from './editPipeline.less'; +import { createMenuItems } from './utils'; const { TextArea } = Input; + const Props = forwardRef(({ onParentChange }, ref) => { const [form] = Form.useForm(); - const [stagingItem, setStagingItem] = useState({}); const [open, setOpen] = useState(false); - const [selectedModel, setSelectedModel] = useState(undefined); - const [selectedDataset, setSelectedDataset] = useState(undefined); - const [resourceStandardList, setResourceStandardList] = useState([]); - + const [selectedModel, setSelectedModel] = useState(undefined); // 选择的模型,为了再次打开时恢复原来的选择 + const [selectedDataset, setSelectedDataset] = useState(undefined); // 选择的数据集,为了再次打开时恢复原来的选择 + const [resourceStandardList, setResourceStandardList] = useState([]); // 资源规模列表 + const [items, setItems] = useState([]); useEffect(() => { getComputingResource(); }, []); + // 获取资源规格列表数据 const getComputingResource = async () => { const params = { page: 0, @@ -35,49 +38,22 @@ const Props = forwardRef(({ onParentChange }, ref) => { const afterOpenChange = () => { if (!open) { - console.log(stagingItem, form.getFieldsValue()); - // 禁止校验 guard-for-in - /* eslint-disable */ - for (let i in form.getFieldsValue()) { - for (let j in stagingItem.in_parameters) { - if (i == j) { - console.log(j, i); - stagingItem.in_parameters[j].value = form.getFieldsValue()[i]; - } - } - for (let p in stagingItem.out_parameters) { - if (i == p) { - stagingItem.out_parameters[p].value = form.getFieldsValue()[i]; - } - } - for (let k in stagingItem.control_strategy) { - if (i == k) { - stagingItem.control_strategy[k].value = form.getFieldsValue()[i]; - } - } - } - /* eslint-enable */ - // setStagingItem({...stagingItem,}) - console.log(stagingItem.control_strategy); + // console.log('zzzz', stagingItem, form.getFieldsValue()); + const control_strategy = form.getFieldValue('control_strategy'); + const in_parameters = form.getFieldValue('in_parameters'); + const out_parameters = form.getFieldValue('out_parameters'); onParentChange({ ...stagingItem, - control_strategy: JSON.stringify(stagingItem.control_strategy), - in_parameters: JSON.stringify(stagingItem.in_parameters), - out_parameters: JSON.stringify(stagingItem.out_parameters), ...form.getFieldsValue(), + control_strategy: JSON.stringify(control_strategy), + in_parameters: JSON.stringify(in_parameters), + out_parameters: JSON.stringify(out_parameters), }); - // onParentChange({...stagingItem,...form.getFieldsValue()}) } }; const onClose = () => { setOpen(false); }; - const onFinish = (values) => { - console.log('Success:', values); - }; - const onFinishFailed = (errorInfo) => { - console.log('Failed:', errorInfo); - }; useImperativeHandle(ref, () => ({ getFieldsValue: async () => { const [propsRes, propsError] = await to(form.validateFields()); @@ -88,30 +64,27 @@ const Props = forwardRef(({ onParentChange }, ref) => { return Promise.reject(propsError); } }, - showDrawer(e) { + showDrawer(e, params, parentNodes) { if (e.item && e.item.getModel()) { - // console.log(e.item.getModel().in_parameters); form.resetFields(); - form.setFieldsValue({ - ...e.item.getModel(), - in_parameters: JSON.parse(e.item.getModel().in_parameters), - out_parameters: JSON.parse(e.item.getModel().out_parameters), - control_strategy: JSON.parse(e.item.getModel().control_strategy), - }); + const model = e.item.getModel(); + const nodeData = { + ...model, + in_parameters: JSON.parse(model.in_parameters), + out_parameters: JSON.parse(model.out_parameters), + control_strategy: JSON.parse(model.control_strategy), + }; setStagingItem({ - ...e.item.getModel(), - in_parameters: JSON.parse(e.item.getModel().in_parameters), - out_parameters: JSON.parse(e.item.getModel().out_parameters), - control_strategy: JSON.parse(e.item.getModel().control_strategy), + ...nodeData, + }); + form.setFieldsValue({ + ...nodeData, }); - // form.setFieldsValue({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters)}) - // setStagingItem({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters)}) - // setTimeout(() => { - // console.log(stagingItem); - // }, (500)); setSelectedModel(undefined); setSelectedDataset(undefined); setOpen(true); + + setItems(createMenuItems(params, parentNodes)); } }, propClose: async () => { @@ -119,16 +92,12 @@ const Props = forwardRef(({ onParentChange }, ref) => { const [openRes, propsError] = await to(setOpen(false)); console.log(setOpen(false)); }, - // propClose() { - - // setOpen(false); - // }, })); // 选择数据集、模型 const selectResource = (name, item) => { let type; - let resource = undefined; + let resource; switch (item.item_type) { case 'dataset': type = ResourceSelectorType.Dataset; @@ -154,7 +123,7 @@ const Props = forwardRef(({ onParentChange }, ref) => { } else { const jsonObj = pick(res, ['id', 'version', 'path']); const value = JSON.stringify(jsonObj); - form.setFieldValue(name, value); + form.setFieldValue(name, { ...item, value }); } if (type === ResourceSelectorType.Dataset) { @@ -187,16 +156,26 @@ const Props = forwardRef(({ onParentChange }, ref) => { } }; + // 筛选资源规格 const filterResourceStandard = (input, { computing_resource = '' }) => { return computing_resource.toLocaleLowerCase().includes(input.toLocaleLowerCase()); }; // 控制策略 - const controlStrategy = stagingItem.control_strategy; + const controlStrategyList = Object.entries(stagingItem.control_strategy ?? {}).map( + ([key, value]) => ({ key, value }), + ); + // 输入参数 - const inParameters = stagingItem.in_parameters; + const inParametersList = Object.entries(stagingItem.in_parameters ?? {}).map(([key, value]) => ({ + key, + value, + })); + // 输出参数 - const outParameters = stagingItem.out_parameters; + const outParametersList = Object.entries(stagingItem.out_parameters ?? {}).map( + ([key, value]) => ({ key, value }), + ); return ( <> @@ -209,15 +188,15 @@ const Props = forwardRef(({ onParentChange }, ref) => { onClose={onClose} afterOpenChange={afterOpenChange} open={open} - width={420} + width={520} + className={Styles.editPipelineProps} > { style={{ maxWidth: 600, }} - initialValues={{ - remember: true, - }} - onFinish={onFinish} - onFinishFailed={onFinishFailed} autoComplete="off" >
@@ -250,7 +224,7 @@ const Props = forwardRef(({ onParentChange }, ref) => { }, ]} > - + {
- +
- - + { + form.setFieldValue('working_directory', value); + }} + /> + } + > + - - -