| @@ -58,3 +58,5 @@ mvnw | |||
| # web | |||
| **/node_modules | |||
| *storybook.log | |||
| @@ -48,3 +48,5 @@ pnpm-lock.yaml | |||
| /src/pages/CodeConfig/components/AddCodeConfigModal/index.tsx | |||
| /src/pages/CodeConfig/components/CodeConfigItem/index.tsx | |||
| /src/pages/Dataset/components/ResourceItem/index.tsx | |||
| *storybook.log | |||
| @@ -0,0 +1 @@ | |||
| v18.16.0 | |||
| @@ -4,17 +4,23 @@ | |||
| * @Description: 用于 BasicInfo 和 BasicTableInfo 组件的子组件 | |||
| */ | |||
| import { Typography } from 'antd'; | |||
| import React from 'react'; | |||
| import BasicInfoItemValue from './BasicInfoItemValue'; | |||
| import { type BasicInfoData, type BasicInfoLink } from './types'; | |||
| type BasicInfoItemProps = { | |||
| /** 基础信息 */ | |||
| data: BasicInfoData; | |||
| /** 标题宽度 */ | |||
| labelWidth: number; | |||
| /** 自定义类名前缀 */ | |||
| classPrefix: string; | |||
| /** 标题是否显示省略号 */ | |||
| labelEllipsis?: boolean; | |||
| }; | |||
| function BasicInfoItem({ data, labelWidth, classPrefix }: BasicInfoItemProps) { | |||
| function BasicInfoItem({ data, labelWidth, classPrefix, labelEllipsis }: BasicInfoItemProps) { | |||
| const { label, value, format, ellipsis } = data; | |||
| const formatValue = format ? format(value) : value; | |||
| const myClassName = `${classPrefix}__item`; | |||
| @@ -54,7 +60,9 @@ function BasicInfoItem({ data, labelWidth, classPrefix }: BasicInfoItemProps) { | |||
| return ( | |||
| <div className={myClassName} key={label}> | |||
| <div className={`${myClassName}__label`} style={{ width: labelWidth }}> | |||
| {label} | |||
| <Typography.Text ellipsis={labelEllipsis !== false ? { tooltip: label } : false}> | |||
| {label} | |||
| </Typography.Text> | |||
| </div> | |||
| {valueComponent} | |||
| </div> | |||
| @@ -4,23 +4,24 @@ | |||
| * @Description: 用于 BasicInfoItem 的组件 | |||
| */ | |||
| import { Link } from '@umijs/max'; | |||
| import { isEmpty } from '@/utils'; | |||
| import { Typography } from 'antd'; | |||
| import React from 'react'; | |||
| import { Link } from 'react-router-dom'; | |||
| type BasicInfoItemValueProps = { | |||
| /** 值是否显示省略号 */ | |||
| ellipsis?: boolean; | |||
| /** 自定义类名前缀 */ | |||
| classPrefix: string; | |||
| value: string | React.ReactNode; | |||
| /** 值 */ | |||
| value?: string; | |||
| /** 内部链接 */ | |||
| link?: string; | |||
| /** 外部链接 */ | |||
| url?: string; | |||
| }; | |||
| function BasicInfoItemValue({ value, link, url, ellipsis, classPrefix }: BasicInfoItemValueProps) { | |||
| if (React.isValidElement(value)) { | |||
| return value; | |||
| } | |||
| const myClassName = `${classPrefix}__item__value`; | |||
| let component = undefined; | |||
| if (url && value) { | |||
| @@ -36,12 +37,12 @@ function BasicInfoItemValue({ value, link, url, ellipsis, classPrefix }: BasicIn | |||
| </Link> | |||
| ); | |||
| } else { | |||
| component = <span className={`${myClassName}__text`}>{value ?? '--'}</span>; | |||
| component = <span className={`${myClassName}__text`}>{!isEmpty(value) ? value : '--'}</span>; | |||
| } | |||
| return ( | |||
| <div className={myClassName}> | |||
| <Typography.Text ellipsis={ellipsis ? { tooltip: value } : false}> | |||
| <Typography.Text ellipsis={ellipsis !== false ? { tooltip: value } : false}> | |||
| {component} | |||
| </Typography.Text> | |||
| </div> | |||
| @@ -20,6 +20,10 @@ | |||
| text-align: justify; | |||
| text-align-last: justify; | |||
| .ant-typography { | |||
| width: 100% !important; | |||
| } | |||
| &::after { | |||
| position: absolute; | |||
| content: ':'; | |||
| @@ -31,10 +35,12 @@ | |||
| flex: 1; | |||
| flex-direction: column; | |||
| gap: 5px 0; | |||
| min-width: 0; | |||
| } | |||
| &__value { | |||
| flex: 1; | |||
| min-width: 0; | |||
| margin-left: 16px; | |||
| font-size: @font-size-content; | |||
| line-height: 1.6; | |||
| @@ -5,14 +5,29 @@ import './index.less'; | |||
| import type { BasicInfoData, BasicInfoLink } from './types'; | |||
| export type { BasicInfoData, BasicInfoLink }; | |||
| type BasicInfoProps = { | |||
| export type BasicInfoProps = { | |||
| /** 基础信息 */ | |||
| datas: BasicInfoData[]; | |||
| /** 标题宽度 */ | |||
| labelWidth: number; | |||
| /** 标题是否显示省略号 */ | |||
| labelEllipsis?: boolean; | |||
| /** 自定义类名 */ | |||
| className?: string; | |||
| /** 自定义样式 */ | |||
| style?: React.CSSProperties; | |||
| labelWidth: number; | |||
| }; | |||
| export default function BasicInfo({ datas, className, style, labelWidth }: BasicInfoProps) { | |||
| /** | |||
| * 基础信息展示组件,用于展示基础信息,一行两列,支持格式化数据 | |||
| */ | |||
| export default function BasicInfo({ | |||
| datas, | |||
| className, | |||
| labelEllipsis, | |||
| style, | |||
| labelWidth, | |||
| }: BasicInfoProps) { | |||
| return ( | |||
| <div className={classNames('kf-basic-info', className)} style={style}> | |||
| {datas.map((item) => ( | |||
| @@ -21,6 +36,7 @@ export default function BasicInfo({ datas, className, style, labelWidth }: Basic | |||
| data={item} | |||
| labelWidth={labelWidth} | |||
| classPrefix="kf-basic-info" | |||
| labelEllipsis={labelEllipsis} | |||
| /> | |||
| ))} | |||
| </div> | |||
| @@ -1,22 +1,20 @@ | |||
| import classNames from 'classnames'; | |||
| import { BasicInfoProps } from '../BasicInfo'; | |||
| import BasicInfoItem from '../BasicInfo/BasicInfoItem'; | |||
| import { type BasicInfoData, type BasicInfoLink } from '../BasicInfo/types'; | |||
| import './index.less'; | |||
| export type { BasicInfoData, BasicInfoLink }; | |||
| type BasicTableInfoProps = { | |||
| datas: BasicInfoData[]; | |||
| className?: string; | |||
| style?: React.CSSProperties; | |||
| labelWidth: number; | |||
| }; | |||
| /** | |||
| * 表格基础信息展示组件,用于展示基础信息,一行四列,支持格式化数据 | |||
| */ | |||
| export default function BasicTableInfo({ | |||
| datas, | |||
| className, | |||
| style, | |||
| labelWidth, | |||
| }: BasicTableInfoProps) { | |||
| labelEllipsis, | |||
| }: BasicInfoProps) { | |||
| const remainder = datas.length % 4; | |||
| const array = []; | |||
| if (remainder > 0) { | |||
| @@ -36,6 +34,7 @@ export default function BasicTableInfo({ | |||
| key={`${item.label}-${index}`} | |||
| data={item} | |||
| labelWidth={labelWidth} | |||
| labelEllipsis={labelEllipsis} | |||
| classPrefix="kf-basic-table-info" | |||
| /> | |||
| ))} | |||
| @@ -46,28 +46,23 @@ function AutoMLBasic({ info, className, runStatus, isInstance = false }: AutoMLB | |||
| { | |||
| label: '实验名称', | |||
| value: info.ml_name, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '实验描述', | |||
| value: info.ml_description, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '创建人', | |||
| value: info.create_by, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '创建时间', | |||
| value: info.create_time, | |||
| ellipsis: true, | |||
| format: formatDate, | |||
| }, | |||
| { | |||
| label: '更新时间', | |||
| value: info.update_time, | |||
| ellipsis: true, | |||
| format: formatDate, | |||
| }, | |||
| ]; | |||
| @@ -81,18 +76,15 @@ function AutoMLBasic({ info, className, runStatus, isInstance = false }: AutoMLB | |||
| { | |||
| label: '任务类型', | |||
| value: info.task_type, | |||
| ellipsis: true, | |||
| format: formatEnum(autoMLTaskTypeOptions), | |||
| }, | |||
| { | |||
| label: '特征预处理算法', | |||
| value: info.include_feature_preprocessor, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '排除的特征预处理算法', | |||
| value: info.exclude_feature_preprocessor, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: info.task_type === AutoMLTaskType.Regression ? '回归算法' : '分类算法', | |||
| @@ -100,7 +92,6 @@ function AutoMLBasic({ info, className, runStatus, isInstance = false }: AutoMLB | |||
| info.task_type === AutoMLTaskType.Regression | |||
| ? info.include_regressor | |||
| : info.include_classifier, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: info.task_type === AutoMLTaskType.Regression ? '排除的回归算法' : '排除的分类算法', | |||
| @@ -108,91 +99,73 @@ function AutoMLBasic({ info, className, runStatus, isInstance = false }: AutoMLB | |||
| info.task_type === AutoMLTaskType.Regression | |||
| ? info.exclude_regressor | |||
| : info.exclude_classifier, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '集成方式', | |||
| value: info.ensemble_class, | |||
| ellipsis: true, | |||
| format: formatEnum(autoMLEnsembleClassOptions), | |||
| }, | |||
| { | |||
| label: '集成模型数量', | |||
| value: info.ensemble_size, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '集成最佳模型数量', | |||
| value: info.ensemble_nbest, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '最大数量', | |||
| value: info.max_models_on_disc, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '内存限制(MB)', | |||
| value: info.memory_limit, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '单次时间限制(秒)', | |||
| value: info.per_run_time_limit, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '搜索时间限制(秒)', | |||
| value: info.time_left_for_this_task, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '重采样策略', | |||
| value: info.resampling_strategy, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '交叉验证折数', | |||
| value: info.folds, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '是否打乱', | |||
| value: info.shuffle, | |||
| ellipsis: true, | |||
| format: formatBoolean, | |||
| }, | |||
| { | |||
| label: '训练集比率', | |||
| value: info.train_size, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '测试集比率', | |||
| value: info.test_size, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '计算指标', | |||
| value: info.scoring_functions, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '随机种子', | |||
| value: info.seed, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '数据集', | |||
| value: info.dataset, | |||
| ellipsis: true, | |||
| format: formatDataset, | |||
| }, | |||
| { | |||
| label: '预测目标列', | |||
| value: info.target_columns, | |||
| ellipsis: true, | |||
| }, | |||
| ]; | |||
| }, [info]); | |||
| @@ -205,18 +178,15 @@ function AutoMLBasic({ info, className, runStatus, isInstance = false }: AutoMLB | |||
| { | |||
| label: '指标名称', | |||
| value: info.metric_name, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '优化方向', | |||
| value: info.greater_is_better, | |||
| ellipsis: true, | |||
| format: formatOptimizeMode, | |||
| }, | |||
| { | |||
| label: '指标权重', | |||
| value: info.metrics, | |||
| ellipsis: true, | |||
| format: formatMetricsWeight, | |||
| }, | |||
| ]; | |||
| @@ -231,12 +201,10 @@ function AutoMLBasic({ info, className, runStatus, isInstance = false }: AutoMLB | |||
| { | |||
| label: '启动时间', | |||
| value: formatDate(runStatus.startedAt), | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '执行时长', | |||
| value: elapsedTime(runStatus.startedAt, runStatus.finishedAt), | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '状态', | |||
| @@ -259,7 +227,6 @@ function AutoMLBasic({ info, className, runStatus, isInstance = false }: AutoMLB | |||
| </div> | |||
| </Flex> | |||
| ), | |||
| ellipsis: true, | |||
| }, | |||
| ]; | |||
| }, [runStatus]); | |||
| @@ -19,50 +19,41 @@ const getDatasetDatas = (data: DatasetData): BasicInfoData[] => [ | |||
| { | |||
| label: '数据集名称', | |||
| value: data.name, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '版本', | |||
| value: data.version, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '创建人', | |||
| value: data.create_by, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '更新时间', | |||
| value: data.update_time, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '数据来源', | |||
| value: data.dataset_source, | |||
| format: formatSource, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '训练任务', | |||
| value: data.train_task, | |||
| format: formatTrainTask, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '处理代码', | |||
| value: data.processing_code, | |||
| format: formatCodeConfig, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '数据集分类', | |||
| value: data.data_type, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '研究方向', | |||
| value: data.data_tag, | |||
| ellipsis: true, | |||
| }, | |||
| ]; | |||
| @@ -61,28 +61,23 @@ function HyperParameterBasic({ | |||
| { | |||
| label: '实验名称', | |||
| value: info.name, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '实验描述', | |||
| value: info.description, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '创建人', | |||
| value: info.create_by, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '创建时间', | |||
| value: info.create_time, | |||
| ellipsis: true, | |||
| format: formatDate, | |||
| }, | |||
| { | |||
| label: '更新时间', | |||
| value: info.update_time, | |||
| ellipsis: true, | |||
| format: formatDate, | |||
| }, | |||
| ]; | |||
| @@ -96,75 +91,62 @@ function HyperParameterBasic({ | |||
| { | |||
| label: '代码', | |||
| value: info.code, | |||
| ellipsis: true, | |||
| format: formatCodeConfig, | |||
| }, | |||
| { | |||
| label: '主函数代码文件', | |||
| value: info.main_py, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '镜像', | |||
| value: info.image, | |||
| format: formatMirror, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '数据集', | |||
| value: info.dataset, | |||
| ellipsis: true, | |||
| format: formatDataset, | |||
| }, | |||
| { | |||
| label: '模型', | |||
| value: info.model, | |||
| ellipsis: true, | |||
| format: formatModel, | |||
| }, | |||
| { | |||
| label: '总实验次数', | |||
| value: info.num_samples, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '搜索算法', | |||
| value: info.search_alg, | |||
| format: formatEnum(searchAlgorithms), | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '调度算法', | |||
| value: info.scheduler, | |||
| format: formatEnum(schedulerAlgorithms), | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '单次试验最大时间', | |||
| value: info.max_t, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '最小试验数', | |||
| value: info.min_samples_required, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '优化方向', | |||
| value: info.mode, | |||
| ellipsis: true, | |||
| format: formatOptimizeMode, | |||
| }, | |||
| { | |||
| label: '指标', | |||
| value: info.metric, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '资源规格', | |||
| value: info.resource, | |||
| format: formatResource, | |||
| ellipsis: true, | |||
| }, | |||
| ]; | |||
| }, [info]); | |||
| @@ -51,80 +51,65 @@ function VersionBasicInfo({ info }: BasicInfoProps) { | |||
| { | |||
| label: '服务名称', | |||
| value: info?.service_name, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '版本名称', | |||
| value: info?.version, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '代码配置', | |||
| value: info?.code_config, | |||
| format: formatCodeConfig, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '镜像', | |||
| value: info?.image, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '状态', | |||
| value: info?.run_state, | |||
| format: formatStatus, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '模型', | |||
| value: info?.model, | |||
| format: formatModel, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '资源规格', | |||
| value: info?.resource, | |||
| format: formatResource, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '挂载路径', | |||
| value: info?.mount_path, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: 'API URL', | |||
| value: info?.url, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '副本数量', | |||
| value: info?.replicas, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '创建时间', | |||
| value: info?.create_time, | |||
| format: formatDate, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '更新时间', | |||
| value: info?.update_time, | |||
| format: formatDate, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '环境变量', | |||
| value: info?.env_variables, | |||
| format: formatEnvText, | |||
| ellipsis: true, | |||
| }, | |||
| { | |||
| label: '描述', | |||
| value: info?.description, | |||
| ellipsis: true, | |||
| }, | |||
| ]; | |||