Browse Source

Merge pull request '合并dev-zw' (#155) from dev-zw into dev

dev-complex-computation
cp3hnu 1 year ago
parent
commit
c2d2af9e25
17 changed files with 107 additions and 53 deletions
  1. +2
    -2
      react-ui/src/components/BasicTableInfo/index.tsx
  2. +5
    -1
      react-ui/src/pages/AutoML/List/index.tsx
  3. +5
    -1
      react-ui/src/pages/CodeConfig/List/index.tsx
  4. +4
    -2
      react-ui/src/pages/Dataset/components/AddDatasetModal/index.tsx
  5. +9
    -4
      react-ui/src/pages/Dataset/components/AddVersionModal/index.tsx
  6. +1
    -10
      react-ui/src/pages/Dataset/components/CategoryItem/index.less
  7. +8
    -1
      react-ui/src/pages/Dataset/components/CategoryItem/index.tsx
  8. +1
    -0
      react-ui/src/pages/Dataset/components/ResourceInfo/index.tsx
  9. +5
    -1
      react-ui/src/pages/Dataset/components/ResourceList/index.tsx
  10. +4
    -1
      react-ui/src/pages/Dataset/config.tsx
  11. +5
    -1
      react-ui/src/pages/Mirror/List/index.tsx
  12. +5
    -1
      react-ui/src/pages/ModelDeployment/List/index.tsx
  13. +5
    -1
      react-ui/src/pages/ModelDeployment/ServiceInfo/index.tsx
  14. +5
    -1
      react-ui/src/pages/Pipeline/components/CodeSelectorModal/index.tsx
  15. +10
    -7
      react-ui/src/pages/Pipeline/components/ResourceSelectorModal/config.tsx
  16. +1
    -1
      react-ui/src/pages/System/User/edit.tsx
  17. +32
    -18
      react-ui/src/utils/ui.tsx

+ 2
- 2
react-ui/src/components/BasicTableInfo/index.tsx View File

@@ -32,9 +32,9 @@ export default function BasicTableInfo({

return (
<div className={classNames('kf-basic-table-info', className)} style={style}>
{showDatas.map((item) => (
{showDatas.map((item, index) => (
<BasicInfoItem
key={item.label}
key={`${item.label}-${index}`}
data={item}
labelWidth={labelWidth}
classPrefix="kf-basic-table-info"


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

@@ -63,7 +63,7 @@ function AutoMLList() {
const params: Record<string, any> = {
page: pagination.current! - 1,
size: pagination.pageSize,
ml_name: searchText,
ml_name: searchText || undefined,
};
const [res] = await to(getAutoMLListReq(params));
if (res && res.data) {
@@ -76,6 +76,10 @@ function AutoMLList() {
// 搜索
const onSearch: SearchProps['onSearch'] = (value) => {
setSearchText(value);
setPagination((prev) => ({
...prev,
current: 1,
}));
};

// 删除模型部署


+ 5
- 1
react-ui/src/pages/CodeConfig/List/index.tsx View File

@@ -59,7 +59,7 @@ function CodeConfigList() {
const params = {
page: pagination.current! - 1,
size: pagination.pageSize,
code_repo_name: searchText !== '' ? searchText : undefined,
code_repo_name: searchText || undefined,
};
const [res] = await to(getCodeConfigListReq(params));
if (res && res.data && res.data.content) {
@@ -83,6 +83,10 @@ function CodeConfigList() {
// 搜索
const handleSearch = (value: string) => {
setSearchText(value);
setPagination((prev) => ({
...prev,
current: 1,
}));
};

// 删除


+ 4
- 2
react-ui/src/pages/Dataset/components/AddDatasetModal/index.tsx View File

@@ -4,7 +4,7 @@ import KFModal from '@/components/KFModal';
import { CategoryData, DataSource, ResourceType, resourceConfig } from '@/pages/Dataset/config';
import { addDataset } from '@/services/dataset/index.js';
import { to } from '@/utils/promise';
import { getFileListFromEvent, validateUploadFiles } from '@/utils/ui';
import { getFileListFromEvent, limitUploadFileType, validateUploadFiles } from '@/utils/ui';
import {
Button,
Form,
@@ -42,6 +42,8 @@ function AddDatasetModal({ typeList, tagList, onOk, ...rest }: AddDatasetModalPr
Authorization: getAccessToken() || '',
},
defaultFileList: [],
accept: '.zip,.tgz',
beforeUpload: limitUploadFileType('zip,tgz'),
};

// 获取集群版本数据
@@ -200,7 +202,7 @@ function AddDatasetModal({ typeList, tagList, onOk, ...rest }: AddDatasetModalPr
},
]}
>
<Upload {...uploadProps} data={{ uuid: uuid }} accept=".zip,.tgz">
<Upload {...uploadProps} data={{ uuid: uuid }}>
<Button
className={styles['upload-button']}
type="default"


+ 9
- 4
react-ui/src/pages/Dataset/components/AddVersionModal/index.tsx View File

@@ -21,8 +21,9 @@ import styles from '../AddDatasetModal/index.less';
interface AddVersionModalProps extends Omit<ModalProps, 'onOk'> {
resourceType: ResourceType;
resourceId: number;
identifier: string;
resoureName: string;
owner: string;
identifier: string;
is_public: boolean;
onOk: () => void;
}
@@ -31,6 +32,7 @@ function AddVersionModal({
resourceType,
resourceId,
resoureName,
owner,
identifier,
is_public,
onOk,
@@ -46,6 +48,8 @@ function AddVersionModal({
Authorization: getAccessToken() || '',
},
defaultFileList: [],
beforeUpload: config.beforeUpload,
accept: config.uploadAccept,
};

// 上传请求
@@ -74,6 +78,7 @@ function AddVersionModal({
id: resourceId,
identifier,
is_public,
owner,
[config.filePropKey]: version_vos,
...omit(formData, 'fileList'),
[config.sourceParamKey]: DataSource.Create,
@@ -83,7 +88,7 @@ function AddVersionModal({
};

const name = config.name;
const accept = config.uploadAccept;
return (
<KFModal
{...rest}
@@ -170,7 +175,7 @@ function AddVersionModal({
},
]}
>
<Upload {...uploadProps} data={{ uuid: uuid }} accept={accept}>
<Upload {...uploadProps} data={{ uuid: uuid }}>
<Button
className={styles['upload-button']}
type="default"
@@ -179,7 +184,7 @@ function AddVersionModal({
上传文件
</Button>
{resourceType === ResourceType.Dataset && (
<div className={styles['upload-tip']}>只允许上传 .zip 格式文件</div>
<div className={styles['upload-tip']}>只允许上传 .zip 和 .tgz 格式文件</div>
)}
</Upload>
</Form.Item>


+ 1
- 10
react-ui/src/pages/Dataset/components/CategoryItem/index.less View File

@@ -3,8 +3,7 @@
flex-direction: column;
align-items: center;
width: 92px;
height: 62px;
padding: 11px 8px 7px;
padding: 10px 8px 8px;
color: @text-color;
font-size: 12px;
border: 1px solid rgba(22, 100, 255, 0.05);
@@ -17,14 +16,6 @@
&__active-icon {
display: none;
}
&__name {
width: 100%;
margin-top: 4px;
overflow: hidden;
white-space: nowrap;
text-align: center;
text-overflow: ellipsis;
}

&:hover,
&--active {


+ 8
- 1
react-ui/src/pages/Dataset/components/CategoryItem/index.tsx View File

@@ -1,3 +1,4 @@
import { Typography } from 'antd';
import classNames from 'classnames';
import { CategoryData, ResourceType, resourceConfig } from '../../config';
import styles from './index.less';
@@ -32,7 +33,13 @@ function CategoryItem({ resourceType, item, isSelected, onClick }: CategoryItemP
alt=""
draggable={false}
/>
<span className={styles['category-item__name']}>{item.name}</span>
<Typography.Text
ellipsis={{ tooltip: item.name }}
style={{ color: 'inherit', marginTop: '4px' }}
>
{item.name}
</Typography.Text>
{/* <span className={styles['category-item__name']}>{item.name}</span> */}
</div>
);
}


+ 1
- 0
react-ui/src/pages/Dataset/components/ResourceInfo/index.tsx View File

@@ -119,6 +119,7 @@ const ResourceInfo = ({ resourceType }: ResourceInfoProps) => {
resourceType: resourceType,
resourceId: resourceId,
resoureName: info.name,
owner: info.owner,
identifier: info.identifier,
is_public: info.is_public,
onOk: () => {


+ 5
- 1
react-ui/src/pages/Dataset/components/ResourceList/index.tsx View File

@@ -89,7 +89,7 @@ function ResourceList(
is_public: isPublic,
[config.typeParamKey]: dataType,
[config.tagParamKey]: dataTag,
name: searchText !== '' ? searchText : undefined,
name: searchText || undefined,
};
const request = config.getList;
const [res] = await to(request(params));
@@ -115,6 +115,10 @@ function ResourceList(
// 搜索
const handleSearch = (value: string) => {
setSearchText(value);
setPagination((prev) => ({
...prev,
current: 1,
}));
};

// 删除


+ 4
- 1
react-ui/src/pages/Dataset/config.tsx View File

@@ -14,7 +14,8 @@ import {
getModelList,
getModelVersionList,
} from '@/services/dataset/index.js';
import type { TabsProps } from 'antd';
import { limitUploadFileType } from '@/utils/ui';
import type { TabsProps, UploadFile } from 'antd';

export enum ResourceType {
Model = 'Model', // 模型
@@ -49,6 +50,7 @@ type ResourceTypeInfo = {
addBtnTitle: string; // 新增按钮的title
uploadAction: string; // 上传接口 url
uploadAccept?: string; // 上传文件类型
beforeUpload?: (file: UploadFile) => boolean | string;
downloadAllAction: string; // 批量下载接口 url
downloadSingleAction: string; // 单个下载接口 url
};
@@ -87,6 +89,7 @@ export const resourceConfig: Record<ResourceType, ResourceTypeInfo> = {
addBtnTitle: '新建数据集',
uploadAction: '/api/mmp/newdataset/upload',
uploadAccept: '.zip,.tgz',
beforeUpload: limitUploadFileType('zip,tgz'),
downloadAllAction: '/api/mmp/newdataset/downloadAllFiles',
downloadSingleAction: '/api/mmp/newdataset/downloadSingleFile',
},


+ 5
- 1
react-ui/src/pages/Mirror/List/index.tsx View File

@@ -87,7 +87,7 @@ function MirrorList() {
const params: Record<string, any> = {
page: pagination.current! - 1,
size: pagination.pageSize,
name: searchText,
name: searchText || undefined,
image_type: activeTab === CommonTabKeys.Public ? 1 : 0,
};
const [res] = await to(getMirrorListReq(params));
@@ -120,6 +120,10 @@ function MirrorList() {
// 搜索
const onSearch: SearchProps['onSearch'] = (value) => {
setSearchText(value);
setPagination((prev) => ({
...prev,
current: 1,
}));
};

// 查看详情


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

@@ -69,7 +69,7 @@ function ModelDeployment() {
const params: Record<string, any> = {
page: pagination.current! - 1,
size: pagination.pageSize,
service_name: searchText,
service_name: searchText || undefined,
service_type: serviceType,
};
const [res] = await to(getServiceListReq(params));
@@ -102,6 +102,10 @@ function ModelDeployment() {
// 搜索
const onSearch: SearchProps['onSearch'] = (value) => {
setSearchText(value);
setPagination((prev) => ({
...prev,
current: 1,
}));
};

// 处理删除


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

@@ -110,7 +110,7 @@ function ServiceInfo() {
const params: Record<string, any> = {
page: pagination.current! - 1,
size: pagination.pageSize,
version: searchText,
version: searchText || undefined,
run_state: serviceStatus,
service_id: serviceId,
};
@@ -159,6 +159,10 @@ function ServiceInfo() {
// 搜索
const onSearch: SearchProps['onSearch'] = (value) => {
setSearchText(value);
setPagination((prev) => ({
...prev,
current: 1,
}));
};

// 处理删除


+ 5
- 1
react-ui/src/pages/Pipeline/components/CodeSelectorModal/index.tsx View File

@@ -40,7 +40,7 @@ function CodeSelectorModal({ onOk, ...rest }: CodeSelectorModalProps) {
const params = {
page: pagination.current! - 1,
size: pagination.pageSize,
code_repo_name: searchText !== '' ? searchText : undefined,
code_repo_name: searchText || undefined,
};
const [res] = await to(getCodeConfigListReq(params));
if (res && res.data && res.data.content) {
@@ -52,6 +52,10 @@ function CodeSelectorModal({ onOk, ...rest }: CodeSelectorModalProps) {
// 搜索
const handleSearch = (value: string) => {
setSearchText(value);
setPagination((prev) => ({
...prev,
current: 1,
}));
};

const handleClick = (item: CodeConfigData) => {


+ 10
- 7
react-ui/src/pages/Pipeline/components/ResourceSelectorModal/config.tsx View File

@@ -44,14 +44,14 @@ const convertMirrorToTreeData = (list: MirrorData[]): TreeDataNode[] => {
}));
};

// 数据集版本列表转为树形结构
const convertDatasetVersionToTreeData = (
// 数据集、模型版本列表转为树形结构
const convertResourceVersionToTreeData = (
parentId: string,
info: ResourceData,
list: ResourceVersionData[],
): TreeDataNode[] => {
return list.map((item: ResourceVersionData) => ({
...pick(info, ['id', 'name', 'owner', 'identifier']),
...pick(info, ['id', 'name', 'owner', 'identifier', 'is_public']),
version: item.name,
title: item.name,
key: `${parentId}-${item.name}`,
@@ -85,6 +85,7 @@ interface SelectorTypeInfo {
readonly buttontTitle: string; // 按钮 title
}

// 数据集选择
export class DatasetSelector implements SelectorTypeInfo {
readonly name = '数据集';
readonly modalIcon = datasetImg;
@@ -114,14 +115,14 @@ export class DatasetSelector implements SelectorTypeInfo {
const res = await getDatasetVersionList(pick(parentNode, ['owner', 'identifier']));
if (res && res.data) {
const list = res.data;
return convertDatasetVersionToTreeData(parentKey, parentNode, list);
return convertResourceVersionToTreeData(parentKey, parentNode, list);
} else {
return Promise.reject('获取数据集版本列表失败');
}
}

async getFiles(_parentKey: string, parentNode: ResourceData & ResourceVersionData) {
const params = pick(parentNode, ['owner', 'identifier', 'id', 'name', 'version']);
const params = pick(parentNode, ['owner', 'identifier', 'id', 'name', 'version', 'is_public']);
const res = await getDatasetInfo(params);
if (res && res.data) {
const path = res.data.relative_paths || '';
@@ -136,6 +137,7 @@ export class DatasetSelector implements SelectorTypeInfo {
}
}

// 模型选择
export class ModelSelector implements SelectorTypeInfo {
readonly name = '模型';
readonly modalIcon = modelImg;
@@ -165,14 +167,14 @@ export class ModelSelector implements SelectorTypeInfo {
const res = await getModelVersionList(pick(parentNode, ['owner', 'identifier']));
if (res && res.data) {
const list = res.data;
return convertDatasetVersionToTreeData(key, parentNode, list);
return convertResourceVersionToTreeData(key, parentNode, list);
} else {
return Promise.reject('获取模型版本列表失败');
}
}

async getFiles(_parentKey: string, parentNode: ResourceData & ResourceVersionData) {
const params = pick(parentNode, ['owner', 'identifier', 'id', 'name', 'version']);
const params = pick(parentNode, ['owner', 'identifier', 'id', 'name', 'version', 'is_public']);
const res = await getModelInfo(params);
if (res && res.data) {
const path = res.data.relative_paths || '';
@@ -187,6 +189,7 @@ export class ModelSelector implements SelectorTypeInfo {
}
}

// 镜像选择
export class MirrorSelector implements SelectorTypeInfo {
readonly name = '镜像';
readonly modalIcon = mirrorImg;


+ 1
- 1
react-ui/src/pages/System/User/edit.tsx View File

@@ -221,7 +221,7 @@ const UserForm: React.FC<UserFormProps> = (props) => {
allowClear
rules={[
{
required: false,
required: true,
message: <FormattedMessage id="请输入密码!" defaultMessage="请输入密码!" />,
},
]}


+ 32
- 18
react-ui/src/utils/ui.tsx View File

@@ -8,7 +8,7 @@ import { removeAllPageCacheState } from '@/hooks/pageCacheState';
import themes from '@/styles/theme.less';
import { type ClientInfo } from '@/types';
import { history } from '@umijs/max';
import { Modal, message, type ModalFuncProps, type UploadFile } from 'antd';
import { Modal, Upload, message, type ModalFuncProps, type UploadFile } from 'antd';
import { closeAllModals } from './modal';
import SessionStorage from './sessionStorage';

@@ -52,23 +52,6 @@ export function modalConfirm({
});
}

// 从事件中获取上传文件列表,用于 Upload + Form 中
export const getFileListFromEvent = (e: any) => {
const fileList: UploadFile[] = (Array.isArray(e) ? e : e?.fileList) || [];
return fileList.map((item) => {
if (item.status === 'done') {
const { response } = item;
if (response?.code !== 200) {
return {
...item,
status: 'error',
};
}
}
return item;
});
};

/**
* 跳转到登录页
* @param toHome 是否跳转到首页
@@ -97,6 +80,23 @@ export const gotoOAuth2 = () => {
}
};

// 从事件中获取上传文件列表,用于 Upload + Form 中
export const getFileListFromEvent = (e: any) => {
const fileList: UploadFile[] = (Array.isArray(e) ? e : e?.fileList) || [];
return fileList.map((item) => {
if (item.status === 'done') {
const { response } = item;
if (response?.code !== 200) {
return {
...item,
status: 'error',
};
}
}
return item;
});
};

/**
* 验证文件上传
*
@@ -128,6 +128,20 @@ export const validateUploadFiles = (files: UploadFile[], required: boolean = tru
return !hasError;
};

// 限制上传文件类型
export const limitUploadFileType = (type: string) => {
return (file: UploadFile): boolean | string => {
const acceptTypes = type.split(',').map((item) => item.trim());
const fileType = file.name.split('.').pop()?.trim();
if (!(fileType && acceptTypes.includes(fileType))) {
message.error(`文件类型不正确,只支持 "${acceptTypes.join('、')}" 类型的文件`);
file.status = 'error';
return Upload.LIST_IGNORE;
}
return true;
};
};

/**
* 滚动到底部
*


Loading…
Cancel
Save