diff --git a/k8s/build.sh b/k8s/build.sh
index a84e56f1..e8f19b3c 100755
--- a/k8s/build.sh
+++ b/k8s/build.sh
@@ -41,25 +41,6 @@ fi
baseDir="/home/somuns/ci4s"
cd ${baseDir}
-# 拉取指定分支的最新代码
-echo "Checking out and pulling branch $branch..."
-
-git stash
-git checkout $branch
-if [ $? -ne 0 ]; then
- echo "切换到分支 $branch 失败,请检查分支名称是否正确!"
- exit 1
-fi
-
-git stash
-git pull origin $branch
-if [ $? -ne 0 ]; then
- echo "拉取代码失败,请检查网络或联系管理员!"
- exit 1
-fi
-
-chmod +777 ${baseDir}/k8s/*.sh
-
# 创建目录
mkdir -p ${baseDir}/k8s/dockerfiles/jar
mkdir -p ${baseDir}/k8s/dockerfiles/html
diff --git a/k8s/build_and_deploy.sh b/k8s/build_and_deploy.sh
index eacc9c6b..ef582cf3 100755
--- a/k8s/build_and_deploy.sh
+++ b/k8s/build_and_deploy.sh
@@ -7,7 +7,6 @@ startTime=$(date +%s)
baseDir="/home/somuns/ci4s"
cd ${baseDir}
-
#build
# 默认参数
branch="master"
@@ -50,6 +49,25 @@ if [[ ! " ${valid_envs[@]} " =~ " $env " ]]; then
exit 1
fi
+# 拉取指定分支的最新代码
+echo "Checking out and pulling branch $branch..."
+
+git stash
+git checkout $branch
+if [ $? -ne 0 ]; then
+ echo "切换到分支 $branch 失败,请检查分支名称是否正确!"
+ exit 1
+fi
+
+git stash
+git pull origin $branch
+if [ $? -ne 0 ]; then
+ echo "拉取代码失败,请检查网络或联系管理员!"
+ exit 1
+fi
+
+chmod +777 ${baseDir}/k8s/*.sh
+
echo "start build"
sh ${baseDir}/k8s/build.sh -b ${branch} -s ${service}
if [ $? -ne 0 ]; then
diff --git a/k8s/template-yaml/k8s-3nacos.yaml b/k8s/template-yaml/k8s-3nacos.yaml
index c21d6cf5..225c6b23 100644
--- a/k8s/template-yaml/k8s-3nacos.yaml
+++ b/k8s/template-yaml/k8s-3nacos.yaml
@@ -37,6 +37,10 @@ spec:
- containerPort: 8848
- containerPort: 9848
- containerPort: 9849
+ initContainers:
+ - name: init-mydb
+ image: busybox:1.31
+ command: [ 'sh', '-c', 'nc -zv mysql.argo.svc 3306' ]
restartPolicy: Always
---
diff --git a/k8s/template-yaml/k8s-7management.yaml b/k8s/template-yaml/k8s-7management.yaml
index 4fcddb15..edc1c621 100644
--- a/k8s/template-yaml/k8s-7management.yaml
+++ b/k8s/template-yaml/k8s-7management.yaml
@@ -26,10 +26,11 @@ spec:
volumeMounts:
- name: resource-volume
mountPath: /home/resource/
+ subPath: mini-model-platform-data
volumes:
- name: resource-volume
- persistentVolumeClaim:
- claimName: platform-data-pvc-nfs
+ hostPath:
+ path: /platform-data
---
apiVersion: v1
kind: Service
diff --git a/react-ui/.npmrc b/react-ui/.npmrc
new file mode 100644
index 00000000..dd026c83
--- /dev/null
+++ b/react-ui/.npmrc
@@ -0,0 +1 @@
+save-prefix=~
diff --git a/react-ui/config/config.ts b/react-ui/config/config.ts
index 515b79cb..c10b23b6 100644
--- a/react-ui/config/config.ts
+++ b/react-ui/config/config.ts
@@ -1,6 +1,5 @@
// https://umijs.org/config/
import { defineConfig } from '@umijs/max';
-import { join } from 'path';
import defaultSettings from './defaultSettings';
import proxy from './proxy';
import routes from './routes';
@@ -145,20 +144,7 @@ export default defineConfig({
* @description 基于 openapi 的规范生成serve 和mock,能减少很多样板代码
* @doc https://pro.ant.design/zh-cn/docs/openapi/
*/
- openAPI: [
- {
- requestLibPath: "import { request } from '@umijs/max'",
- // 或者使用在线的版本
- // schemaPath: "https://gw.alipayobjects.com/os/antfincdn/M%24jrzTTYJN/oneapi.json"
- schemaPath: join(__dirname, 'oneapi.json'),
- mock: false,
- },
- {
- requestLibPath: "import { request } from '@umijs/max'",
- schemaPath: 'https://gw.alipayobjects.com/os/antfincdn/CA1dOm%2631B/openapi.json',
- projectName: 'swagger',
- },
- ],
+ // openAPI: [],
// mfsu: {
// strategy: 'normal',
// },
diff --git a/react-ui/config/oneapi.json b/react-ui/config/oneapi.json
deleted file mode 100644
index c77d988b..00000000
--- a/react-ui/config/oneapi.json
+++ /dev/null
@@ -1,593 +0,0 @@
-{
- "openapi": "3.0.1",
- "info": {
- "title": "Ant Design Pro",
- "version": "1.0.0"
- },
- "servers": [
- {
- "url": "http://localhost:8000/"
- },
- {
- "url": "https://localhost:8000/"
- }
- ],
- "paths": {
- "/api/currentUser": {
- "get": {
- "tags": ["api"],
- "description": "获取当前的用户",
- "operationId": "currentUser",
- "responses": {
- "200": {
- "description": "Success",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/CurrentUser"
- }
- }
- }
- },
- "401": {
- "description": "Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/ErrorResponse"
- }
- }
- }
- }
- }
- },
- "x-swagger-router-controller": "api"
- },
- "/api/login/captcha": {
- "post": {
- "description": "发送验证码",
- "operationId": "getFakeCaptcha",
- "tags": ["login"],
- "parameters": [
- {
- "name": "phone",
- "in": "query",
- "description": "手机号",
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "Success",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/FakeCaptcha"
- }
- }
- }
- }
- }
- }
- },
- "/api/login/outLogin": {
- "post": {
- "description": "登录接口",
- "operationId": "outLogin",
- "tags": ["login"],
- "responses": {
- "200": {
- "description": "Success",
- "content": {
- "application/json": {
- "schema": {
- "type": "object"
- }
- }
- }
- },
- "401": {
- "description": "Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/ErrorResponse"
- }
- }
- }
- }
- }
- },
- "x-swagger-router-controller": "api"
- },
- "/api/login/account": {
- "post": {
- "tags": ["login"],
- "description": "登录接口",
- "operationId": "login",
- "requestBody": {
- "description": "登录系统",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/LoginParams"
- }
- }
- },
- "required": true
- },
- "responses": {
- "200": {
- "description": "Success",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/LoginResult"
- }
- }
- }
- },
- "401": {
- "description": "Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/ErrorResponse"
- }
- }
- }
- }
- },
- "x-codegen-request-body-name": "body"
- },
- "x-swagger-router-controller": "api"
- },
- "/api/notices": {
- "summary": "getNotices",
- "description": "NoticeIconItem",
- "get": {
- "tags": ["api"],
- "operationId": "getNotices",
- "responses": {
- "200": {
- "description": "Success",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/NoticeIconList"
- }
- }
- }
- }
- }
- }
- },
- "/api/rule": {
- "get": {
- "tags": ["rule"],
- "description": "获取规则列表",
- "operationId": "rule",
- "parameters": [
- {
- "name": "current",
- "in": "query",
- "description": "当前的页码",
- "schema": {
- "type": "number"
- }
- },
- {
- "name": "pageSize",
- "in": "query",
- "description": "页面的容量",
- "schema": {
- "type": "number"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "Success",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/RuleList"
- }
- }
- }
- },
- "401": {
- "description": "Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/ErrorResponse"
- }
- }
- }
- }
- }
- },
- "post": {
- "tags": ["rule"],
- "description": "新建规则",
- "operationId": "addRule",
- "responses": {
- "200": {
- "description": "Success",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/RuleListItem"
- }
- }
- }
- },
- "401": {
- "description": "Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/ErrorResponse"
- }
- }
- }
- }
- }
- },
- "put": {
- "tags": ["rule"],
- "description": "新建规则",
- "operationId": "updateRule",
- "responses": {
- "200": {
- "description": "Success",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/RuleListItem"
- }
- }
- }
- },
- "401": {
- "description": "Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/ErrorResponse"
- }
- }
- }
- }
- }
- },
- "delete": {
- "tags": ["rule"],
- "description": "删除规则",
- "operationId": "removeRule",
- "responses": {
- "200": {
- "description": "Success",
- "content": {
- "application/json": {
- "schema": {
- "type": "object"
- }
- }
- }
- },
- "401": {
- "description": "Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/ErrorResponse"
- }
- }
- }
- }
- }
- },
- "x-swagger-router-controller": "api"
- },
- "/swagger": {
- "x-swagger-pipe": "swagger_raw"
- }
- },
- "components": {
- "schemas": {
- "CurrentUser": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string"
- },
- "avatar": {
- "type": "string"
- },
- "userid": {
- "type": "string"
- },
- "email": {
- "type": "string"
- },
- "signature": {
- "type": "string"
- },
- "title": {
- "type": "string"
- },
- "group": {
- "type": "string"
- },
- "tags": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "key": {
- "type": "string"
- },
- "label": {
- "type": "string"
- }
- }
- }
- },
- "notifyCount": {
- "type": "integer",
- "format": "int32"
- },
- "unreadCount": {
- "type": "integer",
- "format": "int32"
- },
- "country": {
- "type": "string"
- },
- "access": {
- "type": "string"
- },
- "geographic": {
- "type": "object",
- "properties": {
- "province": {
- "type": "object",
- "properties": {
- "label": {
- "type": "string"
- },
- "key": {
- "type": "string"
- }
- }
- },
- "city": {
- "type": "object",
- "properties": {
- "label": {
- "type": "string"
- },
- "key": {
- "type": "string"
- }
- }
- }
- }
- },
- "address": {
- "type": "string"
- },
- "phone": {
- "type": "string"
- }
- }
- },
- "LoginResult": {
- "type": "object",
- "properties": {
- "status": {
- "type": "string"
- },
- "type": {
- "type": "string"
- },
- "currentAuthority": {
- "type": "string"
- }
- }
- },
- "PageParams": {
- "type": "object",
- "properties": {
- "current": {
- "type": "number"
- },
- "pageSize": {
- "type": "number"
- }
- }
- },
- "RuleListItem": {
- "type": "object",
- "properties": {
- "key": {
- "type": "integer",
- "format": "int32"
- },
- "disabled": {
- "type": "boolean"
- },
- "href": {
- "type": "string"
- },
- "avatar": {
- "type": "string"
- },
- "name": {
- "type": "string"
- },
- "owner": {
- "type": "string"
- },
- "desc": {
- "type": "string"
- },
- "callNo": {
- "type": "integer",
- "format": "int32"
- },
- "status": {
- "type": "integer",
- "format": "int32"
- },
- "updatedAt": {
- "type": "string",
- "format": "datetime"
- },
- "createdAt": {
- "type": "string",
- "format": "datetime"
- },
- "progress": {
- "type": "integer",
- "format": "int32"
- }
- }
- },
- "RuleList": {
- "type": "object",
- "properties": {
- "data": {
- "type": "array",
- "items": {
- "$ref": "#/components/schemas/RuleListItem"
- }
- },
- "total": {
- "type": "integer",
- "description": "列表的内容总数",
- "format": "int32"
- },
- "success": {
- "type": "boolean"
- }
- }
- },
- "FakeCaptcha": {
- "type": "object",
- "properties": {
- "code": {
- "type": "integer",
- "format": "int32"
- },
- "status": {
- "type": "string"
- }
- }
- },
- "LoginParams": {
- "type": "object",
- "properties": {
- "username": {
- "type": "string"
- },
- "password": {
- "type": "string"
- },
- "autoLogin": {
- "type": "boolean"
- },
- "type": {
- "type": "string"
- }
- }
- },
- "ErrorResponse": {
- "required": ["errorCode"],
- "type": "object",
- "properties": {
- "errorCode": {
- "type": "string",
- "description": "业务约定的错误码"
- },
- "errorMessage": {
- "type": "string",
- "description": "业务上的错误信息"
- },
- "success": {
- "type": "boolean",
- "description": "业务上的请求是否成功"
- }
- }
- },
- "NoticeIconList": {
- "type": "object",
- "properties": {
- "data": {
- "type": "array",
- "items": {
- "$ref": "#/components/schemas/NoticeIconItem"
- }
- },
- "total": {
- "type": "integer",
- "description": "列表的内容总数",
- "format": "int32"
- },
- "success": {
- "type": "boolean"
- }
- }
- },
- "NoticeIconItemType": {
- "title": "NoticeIconItemType",
- "description": "已读未读列表的枚举",
- "type": "string",
- "properties": {},
- "enum": ["notification", "message", "event"]
- },
- "NoticeIconItem": {
- "type": "object",
- "properties": {
- "id": {
- "type": "string"
- },
- "extra": {
- "type": "string",
- "format": "any"
- },
- "key": { "type": "string" },
- "read": {
- "type": "boolean"
- },
- "avatar": {
- "type": "string"
- },
- "title": {
- "type": "string"
- },
- "status": {
- "type": "string"
- },
- "datetime": {
- "type": "string",
- "format": "date"
- },
- "description": {
- "type": "string"
- },
- "type": {
- "extensions": {
- "x-is-enum": true
- },
- "$ref": "#/components/schemas/NoticeIconItemType"
- }
- }
- }
- }
- }
-}
diff --git a/react-ui/config/proxy.ts b/react-ui/config/proxy.ts
index f8875e9d..35232b47 100644
--- a/react-ui/config/proxy.ts
+++ b/react-ui/config/proxy.ts
@@ -20,7 +20,7 @@ export default {
// localhost:8000/api/** -> https://preview.pro.ant.design/api/**
'/api/': {
// 要代理的地址
- target: 'http://172.20.32.181:31213', // 开发环境
+ target: 'http://172.20.32.185:31213', // 开发环境
// target: 'http://172.20.32.98:8082',
// target: 'http://172.20.32.150:8082',
// 配置了这个可以从 http 代理到 https
@@ -29,7 +29,7 @@ export default {
// pathRewrite: { '^/api': '' },
},
'/profile/avatar/': {
- target: 'http://172.20.32.181:31213',
+ target: 'http://172.20.32.185:31213',
changeOrigin: true,
},
},
diff --git a/react-ui/package.json b/react-ui/package.json
index d5c09dbd..aebf21ca 100644
--- a/react-ui/package.json
+++ b/react-ui/package.json
@@ -60,7 +60,7 @@
"@antv/hierarchy": "^0.6.12",
"@types/crypto-js": "^4.2.2",
"@umijs/route-utils": "^4.0.1",
- "antd": "^5.4.4",
+ "antd": "~5.21.4",
"classnames": "^2.3.2",
"crypto-js": "^4.2.0",
"echarts": "^5.5.0",
@@ -111,7 +111,7 @@
"umi-presets-pro": "^2.0.0"
},
"engines": {
- "node": ">=12.0.0"
+ "node": ">=16.14.0"
},
"create-umi": {
"ignoreScript": [
diff --git a/react-ui/src/app.tsx b/react-ui/src/app.tsx
index e6a09fb5..4f911013 100644
--- a/react-ui/src/app.tsx
+++ b/react-ui/src/app.tsx
@@ -118,18 +118,10 @@ export const layout: RuntimeConfig['layout'] = ({ initialState }) => {
width: '331px',
},
],
- // links: isDev
- // ? [
- //
- //
- // OpenAPI 文档
- // ,
- // ]
- // : [],
// 自定义 403 页面
// unAccessible:
unAccessible
,
- // 增加一个 loading 的状态
childrenRender: (children) => {
+ // 增加一个 loading 的状态
// if (initialState?.loading) return ;
return (
@@ -236,6 +228,7 @@ export const antd: RuntimeAntdConfig = (memo) => {
memo.theme.components.Table = {
headerBg: 'rgba(242, 244, 247, 0.36)',
headerBorderRadius: 4,
+ rowSelectedBg: 'rgba(22, 100, 255, 0.05)',
};
memo.theme.components.Tabs = {
titleFontSize: 16,
diff --git a/react-ui/src/assets/img/code-name-icon.png b/react-ui/src/assets/img/code-name-icon.png
new file mode 100644
index 00000000..1e7991a9
Binary files /dev/null and b/react-ui/src/assets/img/code-name-icon.png differ
diff --git a/react-ui/src/assets/img/creatBy.png b/react-ui/src/assets/img/creatBy.png
index de3341cb..12f2e384 100644
Binary files a/react-ui/src/assets/img/creatBy.png and b/react-ui/src/assets/img/creatBy.png differ
diff --git a/react-ui/src/assets/img/metrics-title-icon.png b/react-ui/src/assets/img/metrics-title-icon.png
new file mode 100644
index 00000000..66cd461f
Binary files /dev/null and b/react-ui/src/assets/img/metrics-title-icon.png differ
diff --git a/react-ui/src/assets/img/model-metrics.png b/react-ui/src/assets/img/model-metrics.png
new file mode 100644
index 00000000..3379db8a
Binary files /dev/null and b/react-ui/src/assets/img/model-metrics.png differ
diff --git a/react-ui/src/assets/img/robot.png b/react-ui/src/assets/img/robot.png
index c1379ef3..9e179741 100644
Binary files a/react-ui/src/assets/img/robot.png and b/react-ui/src/assets/img/robot.png differ
diff --git a/react-ui/src/assets/img/total-icon.png b/react-ui/src/assets/img/total-icon.png
new file mode 100644
index 00000000..38c44a50
Binary files /dev/null and b/react-ui/src/assets/img/total-icon.png differ
diff --git a/react-ui/src/components/BasicInfo/index.less b/react-ui/src/components/BasicInfo/index.less
index 53fcb46c..e4570868 100644
--- a/react-ui/src/components/BasicInfo/index.less
+++ b/react-ui/src/components/BasicInfo/index.less
@@ -5,48 +5,49 @@
gap: 20px 40px;
align-items: flex-start;
width: 80%;
-}
-.kf-basic-info-item {
- display: flex;
- align-items: flex-start;
- width: calc(50% - 20px);
- font-size: 16px;
- line-height: 1.6;
+ &__item {
+ display: flex;
+ align-items: flex-start;
+ width: calc(50% - 20px);
- &__label {
- position: relative;
- flex: none;
- color: @text-color-secondary;
- text-align: justify;
- text-align-last: justify;
+ &__label {
+ position: relative;
+ flex: none;
+ color: @text-color-secondary;
+ font-size: @font-size-content;
+ line-height: 1.6;
+ text-align: justify;
+ text-align-last: justify;
- &::after {
- position: absolute;
- content: ':';
+ &::after {
+ position: absolute;
+ content: ':';
+ }
}
- }
- &__list-value {
- display: flex;
- flex: 1;
- flex-direction: column;
- gap: 5px 0;
- }
+ &__value-container {
+ display: flex;
+ flex: 1;
+ flex-direction: column;
+ gap: 5px 0;
+ }
- &__value {
- flex: 1;
- margin-left: 16px;
- white-space: pre-line;
- word-break: break-all;
- }
+ &__value {
+ flex: 1;
+ margin-left: 16px;
+ font-size: @font-size-content;
+ line-height: 1.6;
+ word-break: break-all;
- &__text {
- color: @text-color;
- }
+ &__text {
+ color: @text-color;
+ }
- &__link:hover {
- text-decoration: underline @underline-color;
- text-underline-offset: 3px;
+ &__link:hover {
+ text-decoration: underline @underline-color;
+ text-underline-offset: 3px;
+ }
+ }
}
}
diff --git a/react-ui/src/components/BasicInfo/index.tsx b/react-ui/src/components/BasicInfo/index.tsx
index af56ded0..bd07db34 100644
--- a/react-ui/src/components/BasicInfo/index.tsx
+++ b/react-ui/src/components/BasicInfo/index.tsx
@@ -1,4 +1,5 @@
import { Link } from '@umijs/max';
+import { Typography } from 'antd';
import classNames from 'classnames';
import './index.less';
@@ -11,6 +12,7 @@ export type BasicInfoLink = {
export type BasicInfoData = {
label: string;
value?: any;
+ ellipsis?: boolean;
format?: (_value?: any) => string | BasicInfoLink | BasicInfoLink[] | undefined;
};
@@ -18,45 +20,73 @@ type BasicInfoProps = {
datas: BasicInfoData[];
className?: string;
style?: React.CSSProperties;
- labelWidth?: number;
+ labelWidth: number;
};
-function BasicInfo({ datas, className, style, labelWidth = 100 }: BasicInfoProps) {
+type BasicInfoItemProps = {
+ data: BasicInfoData;
+ labelWidth: number;
+ classPrefix: string;
+};
+
+type BasicInfoItemValueProps = BasicInfoLink & {
+ ellipsis?: boolean;
+ classPrefix: string;
+};
+
+export default function BasicInfo({ datas, className, style, labelWidth }: BasicInfoProps) {
return (
{datas.map((item) => (
-
+
))}
);
}
-type BasicInfoItemProps = {
- data: BasicInfoData;
- labelWidth?: number;
-};
-function BasicInfoItem({ data, labelWidth = 100 }: BasicInfoItemProps) {
- const { label, value, format } = data;
+export function BasicInfoItem({ data, labelWidth, classPrefix }: BasicInfoItemProps) {
+ const { label, value, format, ellipsis } = data;
const formatValue = format ? format(value) : value;
+ const myClassName = `${classPrefix}__item`;
let valueComponent = undefined;
if (Array.isArray(formatValue)) {
valueComponent = (
-
+
{formatValue.map((item: BasicInfoLink) => (
-
+
))}
);
} else if (typeof formatValue === 'object' && formatValue) {
valueComponent = (
-
+
);
} else {
- valueComponent =
;
+ valueComponent = (
+
+ );
}
return (
-
-
+
+
{label}
{valueComponent}
@@ -64,35 +94,36 @@ function BasicInfoItem({ data, labelWidth = 100 }: BasicInfoItemProps) {
);
}
-type BasicInfoItemValueProps = {
- value: string;
- link?: string;
- url?: string;
-};
-
-function BasicInfoItemValue({ value, link, url }: BasicInfoItemValueProps) {
+export function BasicInfoItemValue({
+ value,
+ link,
+ url,
+ ellipsis,
+ classPrefix,
+}: BasicInfoItemValueProps) {
+ const myClassName = `${classPrefix}__item__value`;
+ let component = undefined;
if (url && value) {
- return (
-
+ component = (
+
{value}
);
} else if (link && value) {
- return (
-
+ component = (
+
{value}
);
} else {
- return (
-
{value ?? '--'}
- );
+ component =
{value ?? '--'};
}
-}
-export default BasicInfo;
+ return (
+
+
+ {component}
+
+
+ );
+}
diff --git a/react-ui/src/components/BasicTableInfo/index.less b/react-ui/src/components/BasicTableInfo/index.less
new file mode 100644
index 00000000..314b05ca
--- /dev/null
+++ b/react-ui/src/components/BasicTableInfo/index.less
@@ -0,0 +1,60 @@
+.kf-basic-table-info {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ align-items: stretch;
+ width: 100%;
+ border: 1px solid @border-color-base;
+ border-bottom: none;
+ border-radius: 4px;
+
+ &__item {
+ display: flex;
+ align-items: stretch;
+ width: 25%;
+ border-bottom: 1px solid @border-color-base;
+
+ &__label {
+ flex: none;
+ padding: 12px 20px;
+ color: @text-color-secondary;
+ font-size: 14px;
+ text-align: left;
+ background-color: .addAlpha(#606b7a, 0.05) [];
+ }
+
+ &__value-container {
+ display: flex;
+ flex: 1;
+ flex-direction: column;
+ align-items: flex-start;
+ min-width: 0;
+ }
+
+ &__value {
+ flex: 1;
+ min-width: 0;
+ margin: 0 !important;
+ padding: 12px 20px 4px;
+ font-size: @font-size;
+ word-break: break-all;
+
+ & + & {
+ padding-top: 0;
+ }
+
+ &:last-child {
+ padding-bottom: 12px;
+ }
+
+ &__text {
+ color: @text-color;
+ }
+
+ &__link:hover {
+ text-decoration: underline @underline-color;
+ text-underline-offset: 3px;
+ }
+ }
+ }
+}
diff --git a/react-ui/src/components/BasicTableInfo/index.tsx b/react-ui/src/components/BasicTableInfo/index.tsx
new file mode 100644
index 00000000..df167ae2
--- /dev/null
+++ b/react-ui/src/components/BasicTableInfo/index.tsx
@@ -0,0 +1,43 @@
+import classNames from 'classnames';
+import { BasicInfoItem, type BasicInfoData, type BasicInfoLink } from '../BasicInfo';
+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) {
+ const remainder = datas.length % 4;
+ const array = [];
+ if (remainder > 0) {
+ for (let i = 0; i < 4 - remainder; i++) {
+ array.push({
+ label: '',
+ value: '',
+ });
+ }
+ }
+ const showDatas = [...datas, ...array];
+
+ return (
+
+ {showDatas.map((item) => (
+
+ ))}
+
+ );
+}
diff --git a/react-ui/src/components/CommonTableCell/index.tsx b/react-ui/src/components/CommonTableCell/index.tsx
deleted file mode 100644
index c86ef9a9..00000000
--- a/react-ui/src/components/CommonTableCell/index.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * @Author: 赵伟
- * @Date: 2024-04-28 14:18:11
- * @Description: 自定义 Table 单元格,没有数据时展示 --
- */
-
-import { Tooltip } from 'antd';
-
-function renderCell(text?: any | null) {
- return
{text ?? '--'};
-}
-
-function CommonTableCell(ellipsis: boolean = false) {
- if (ellipsis) {
- return (text?: any | 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
deleted file mode 100644
index ea629ba7..00000000
--- a/react-ui/src/components/DateTableCell/index.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * @Author: 赵伟
- * @Date: 2024-04-28 14:18:11
- * @Description: 自定义 Table 日期类单元格
- */
-
-import { formatDate } from '@/utils/date';
-import dayjs from 'dayjs';
-
-function DateTableCell(text?: string | null) {
- if (text === undefined || text === null || text === '') {
- return
--;
- }
- if (!dayjs(text).isValid()) {
- return
无效的日期;
- }
- return
{formatDate(text)};
-}
-
-export default DateTableCell;
diff --git a/react-ui/src/components/IFramePage/index.tsx b/react-ui/src/components/IFramePage/index.tsx
index c4ab9d3f..861a0c05 100644
--- a/react-ui/src/components/IFramePage/index.tsx
+++ b/react-ui/src/components/IFramePage/index.tsx
@@ -19,7 +19,7 @@ const getRequestAPI = (type: IframePageType): (() => Promise
) => {
case IframePageType.DatasetAnnotation:
return getLabelStudioUrl;
case IframePageType.AppDevelopment:
- return () => Promise.resolve({ code: 200, data: 'http://172.20.32.181:30080/' });
+ return () => Promise.resolve({ code: 200, data: 'http://172.20.32.185:30080/' });
case IframePageType.DevEnv:
return () =>
Promise.resolve({
diff --git a/react-ui/src/components/KFModal/index.less b/react-ui/src/components/KFModal/index.less
index b034672d..fafc6f7d 100644
--- a/react-ui/src/components/KFModal/index.less
+++ b/react-ui/src/components/KFModal/index.less
@@ -20,7 +20,7 @@
height: 40px;
padding: 0 30px;
font-size: @font-size-content;
- border-radius: 10px;
+ border-radius: 6px;
}
.ant-btn-default {
border-color: transparent;
diff --git a/react-ui/src/components/RobotFrame/index.less b/react-ui/src/components/RobotFrame/index.less
index e3e5662e..a203ecc3 100644
--- a/react-ui/src/components/RobotFrame/index.less
+++ b/react-ui/src/components/RobotFrame/index.less
@@ -23,7 +23,7 @@
width: 100%;
height: 60px;
padding: 0 15px;
- border-bottom: 1px solid #e8e8e8;
+ border-bottom: 1px solid @border-color-base;
}
&__iframe {
diff --git a/react-ui/src/components/RobotFrame/index.tsx b/react-ui/src/components/RobotFrame/index.tsx
index 7905265d..1c8e8cf2 100644
--- a/react-ui/src/components/RobotFrame/index.tsx
+++ b/react-ui/src/components/RobotFrame/index.tsx
@@ -9,7 +9,7 @@ type RobotFrameProps = {
};
function RobotFrame({ onClose, visible }: RobotFrameProps) {
- const url = 'http://172.20.32.181:30080/chat/EruwZfxVgDkWdLYs';
+ const url = 'http://172.20.32.185:30080/chat/EruwZfxVgDkWdLYs';
const openUrl = () => {
window.open(url, '_blank');
};
diff --git a/react-ui/src/components/SubAreaTitle/index.tsx b/react-ui/src/components/SubAreaTitle/index.tsx
index 0458f715..cd07b206 100644
--- a/react-ui/src/components/SubAreaTitle/index.tsx
+++ b/react-ui/src/components/SubAreaTitle/index.tsx
@@ -9,7 +9,7 @@ import './index.less';
type SubAreaTitleProps = {
title: string;
- image: string;
+ image?: string;
style?: React.CSSProperties;
className?: string;
};
@@ -17,8 +17,10 @@ type SubAreaTitleProps = {
function SubAreaTitle({ title, image, style, className }: SubAreaTitleProps) {
return (
-

-
{title}
+ {image && (
+

+ )}
+
{title}
);
}
diff --git a/react-ui/src/enums/pagesEnums.ts b/react-ui/src/enums/pagesEnums.ts
index 756d3325..d11eb8b5 100644
--- a/react-ui/src/enums/pagesEnums.ts
+++ b/react-ui/src/enums/pagesEnums.ts
@@ -1,3 +1,4 @@
export enum PageEnum {
LOGIN = '/user/login',
+ Authorize = '/authorize',
}
diff --git a/react-ui/src/hooks/index.ts b/react-ui/src/hooks/index.ts
index adf61e7d..f5ef64af 100644
--- a/react-ui/src/hooks/index.ts
+++ b/react-ui/src/hooks/index.ts
@@ -5,7 +5,7 @@
*/
import { FormInstance } from 'antd';
import { debounce } from 'lodash';
-import { useCallback, useEffect, useRef, useState } from 'react';
+import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
/**
* 生成具有初始值的状态引用
*
@@ -156,3 +156,45 @@ export const useEffectWhen = (effect: () => void, deps: React.DependencyList, wh
}
}, [when]);
};
+
+// 选择、全选操作
+export const useCheck = (list: T[]) => {
+ const [selected, setSelected] = useState([]);
+
+ const checked = useMemo(() => {
+ return selected.length === list.length && selected.length > 0;
+ }, [selected, list]);
+
+ const indeterminate = useMemo(() => {
+ return selected.length > 0 && selected.length < list.length;
+ }, [selected, list]);
+
+ const checkAll = useCallback(() => {
+ setSelected(checked ? [] : list);
+ }, [list, checked]);
+
+ const isSingleChecked = useCallback((item: T) => selected.includes(item), [selected]);
+
+ const checkSingle = useCallback(
+ (item: T) => {
+ setSelected((prev) => {
+ if (isSingleChecked(item)) {
+ return prev.filter((i) => i !== item);
+ } else {
+ return [...prev, item];
+ }
+ });
+ },
+ [selected, isSingleChecked],
+ );
+
+ return [
+ selected,
+ setSelected,
+ checked,
+ indeterminate,
+ checkAll,
+ isSingleChecked,
+ checkSingle,
+ ] as const;
+};
diff --git a/react-ui/src/hooks/pageCacheState.ts b/react-ui/src/hooks/pageCacheState.ts
index 9268a07a..e320b0a6 100644
--- a/react-ui/src/hooks/pageCacheState.ts
+++ b/react-ui/src/hooks/pageCacheState.ts
@@ -4,6 +4,7 @@
* @Description: 页面状态缓存,pop 回到这个页面的时候,重新构建之前的状态
*/
+import { parseJsonText } from '@/utils';
import { useCallback, useState } from 'react';
const pageKeys: string[] = [];
@@ -14,11 +15,7 @@ const getCacheState = (key: string) => {
const jsonStr = sessionStorage.getItem(key);
if (jsonStr) {
removeCacheState(key);
- try {
- return JSON.parse(jsonStr);
- } catch (error) {
- return undefined;
- }
+ return parseJsonText(jsonStr);
}
return undefined;
};
diff --git a/react-ui/src/overrides.less b/react-ui/src/overrides.less
index af9591fe..f676890e 100644
--- a/react-ui/src/overrides.less
+++ b/react-ui/src/overrides.less
@@ -79,6 +79,12 @@
background-color: #fff;
}
+.ant-table-row-selected {
+ .ant-table-cell {
+ color: @primary-color;
+ }
+}
+
.ant-pro-page-container {
overflow-y: auto;
}
@@ -162,7 +168,7 @@
height: 40px;
padding: 0 30px;
font-size: @font-size-content;
- border-radius: 10px;
+ border-radius: 6px;
}
.ant-btn-default {
border-color: transparent;
diff --git a/react-ui/src/pages/CodeConfig/List/index.less b/react-ui/src/pages/CodeConfig/List/index.less
index 4108b486..d4cb1b4a 100644
--- a/react-ui/src/pages/CodeConfig/List/index.less
+++ b/react-ui/src/pages/CodeConfig/List/index.less
@@ -1,47 +1,46 @@
-.code-config-list {
- display: flex;
- flex: 1;
- flex-direction: column;
+.code-config {
height: 100%;
- height: 100%;
- padding: 20px 0;
- background: white;
- box-shadow: 0px 3px 6px rgba(146, 146, 146, 0.09);
- &__header {
+ &__list {
display: flex;
- align-items: center;
- justify-content: space-between;
- height: 32px;
- margin-bottom: 30px;
- padding: 0 30px;
- color: @text-color;
- font-size: 15px;
- }
+ flex-direction: column;
+ height: calc(100% - 60px);
+ margin-top: 10px;
+ padding: 30px 30px 0;
+ background: white;
+ border-radius: 10px;
+ box-shadow: 0px 2px 12px rgba(180, 182, 191, 0.09);
- &__content {
- display: flex;
- flex: 1;
- flex-wrap: wrap;
- gap: 20px;
- align-content: flex-start;
- width: 100%;
- margin-bottom: 30px;
- padding: 0 30px;
- overflow-y: auto;
- }
+ &__header {
+ display: flex;
+ align-items: center;
+ height: 32px;
+ color: @text-color;
+ font-size: 15px;
+ }
- &__empty {
- display: flex;
- flex: 1;
- align-items: center;
- justify-content: center;
- }
+ &__content {
+ display: flex;
+ flex: 1 1 0%;
+ flex-wrap: wrap;
+ gap: 20px;
+ align-content: flex-start;
+ width: 100%;
+ margin: 25px 0;
+ overflow-y: auto;
+ }
+
+ &__empty {
+ display: flex;
+ flex: 1;
+ align-items: center;
+ justify-content: center;
+ }
- :global {
- .ant-pagination {
- margin-right: 30px;
- text-align: right;
+ :global {
+ .ant-pagination {
+ margin-bottom: 25px;
+ }
}
}
}
diff --git a/react-ui/src/pages/CodeConfig/List/index.tsx b/react-ui/src/pages/CodeConfig/List/index.tsx
index 847d30ec..e8a2557f 100644
--- a/react-ui/src/pages/CodeConfig/List/index.tsx
+++ b/react-ui/src/pages/CodeConfig/List/index.tsx
@@ -1,5 +1,12 @@
+/*
+ * @Author: 赵伟
+ * @Date: 2024-10-10 09:55:12
+ * @Description: 代码配置
+ */
+
import KFEmpty, { EmptyType } from '@/components/KFEmpty';
import KFIcon from '@/components/KFIcon';
+import PageTitle from '@/components/PageTitle';
import { deleteCodeConfigReq, getCodeConfigListReq } from '@/services/codeConfig';
import { getGitUrl } from '@/utils';
import { openAntdModal } from '@/utils/modal';
@@ -127,64 +134,69 @@ function CodeConfigList() {
};
return (
-
-
-
数据总数:{total} 个
-
+
+
+
+
+ 数据总数:{total} 个
setInputText(e.target.value)}
value={inputText}
/>
}
>
新建代码配置
-
- {dataList && dataList.length !== 0 && (
- <>
-
- {dataList.map((item) => (
-
- ))}
-
-
+
+ {dataList.map((item) => (
+
+ ))}
+
+
+ >
+ )}
+ {dataList && dataList.length === 0 && (
+
- >
- )}
- {dataList && dataList.length === 0 && (
-
- )}
+ )}
+
);
}
diff --git a/react-ui/src/pages/CodeConfig/components/CodeConfigItem/index.less b/react-ui/src/pages/CodeConfig/components/CodeConfigItem/index.less
index 1f1a9a92..41415a9a 100644
--- a/react-ui/src/pages/CodeConfig/components/CodeConfigItem/index.less
+++ b/react-ui/src/pages/CodeConfig/components/CodeConfigItem/index.less
@@ -2,51 +2,97 @@
position: relative;
width: calc(25% - 15px);
padding: 20px;
- background: white;
- border: 1px solid #eaeaea;
+ background: linear-gradient(180deg, #f7faff 0%, #ffffff 100%);
+ border: 2px solid white;
border-radius: 4px;
+ box-shadow: 0px 3px 10px rgba(164, 169, 181, 0.13);
cursor: pointer;
+ &:hover {
+ border-color: @primary-color;
+ }
+
@media screen and (max-width: 1860px) {
& {
width: calc(33.33% - 13.33px);
}
}
- &__name {
+ &__icon {
+ flex: none;
+ width: 16px;
+ height: 16px;
margin-right: 10px;
+ }
+
+ &__name {
+ position: relative;
+ margin-right: 20px;
margin-bottom: 0 !important;
color: @text-color;
+ font-weight: 500;
font-size: 16px;
+
+ &::after {
+ position: absolute;
+ top: 14px;
+ left: 0;
+ width: 100%;
+ height: 6px;
+ background: linear-gradient(
+ to right,
+ .addAlpha(@primary-color, 0.4) [] 0,
+ .addAlpha(@primary-color, 0) [] 100%
+ );
+ content: '';
+ }
+ }
+
+ &:hover &__name {
+ color: @primary-color;
}
&__tag {
- padding: 2px 11px;
- font-size: 12px;
- border-radius: 1000px;
+ flex: none;
+ padding: 1px 10px;
+ font-size: 13px;
+ border-radius: 2px;
&--public {
color: @primary-color;
- background-color: .addAlpha(@primary-color, 0.08) [];
- border-color: .addAlpha(@primary-color, 0.5) [];
+ background-color: .addAlpha(@primary-color, 0.1) [];
+ border: 1px solid .addAlpha(@primary-color, 0.5) [];
}
&--private {
color: @warning-color;
- background-color: .addAlpha(@warning-color, 0.08) [];
- border-color: .addAlpha(@warning-color, 0.5) [];
+ background-color: .addAlpha(@warning-color, 0.1) [];
+ border: 1px solid .addAlpha(@warning-color, 0.5) [];
}
}
+ :global {
+ .ant-btn {
+ flex: none;
+ color: #808080;
+ }
+ }
+
+ &__url-box {
+ margin-bottom: 15px;
+ padding: 14px;
+ background-color: .addAlpha(@primary-color, 0.04) [];
+ border-radius: 4px;
+ }
+
&__url {
- margin-bottom: 10px;
- color: @text-color-secondary;
+ margin-bottom: 15px !important;
+ color: @text-color;
font-size: 14px;
}
&__branch {
- margin-bottom: 20px;
- color: @text-color-tertiary;
+ color: @text-color-secondary;
font-size: 14px;
}
@@ -59,13 +105,4 @@
color: #808080;
font-size: 13px;
}
-
- &:hover {
- border-color: @primary-color;
- box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.1);
- }
-
- &:hover &__name {
- color: @primary-color;
- }
}
diff --git a/react-ui/src/pages/CodeConfig/components/CodeConfigItem/index.tsx b/react-ui/src/pages/CodeConfig/components/CodeConfigItem/index.tsx
index fe062bac..de903f47 100644
--- a/react-ui/src/pages/CodeConfig/components/CodeConfigItem/index.tsx
+++ b/react-ui/src/pages/CodeConfig/components/CodeConfigItem/index.tsx
@@ -19,6 +19,11 @@ function CodeConfigItem({ item, onClick, onEdit, onRemove }: CodeConfigItemProps
return (
onClick?.(item)}>
+
-
- {item.git_url}
-
-
{item.git_branch}
+
+
+ {item.git_url}
+
+
{item.git_branch}
+

{
key: ResourceInfoTabKeys.Introduction,
label: `${typeName}简介`,
icon:
,
- children:
,
+ children: (
+
+ ),
},
{
key: ResourceInfoTabKeys.Version,
diff --git a/react-ui/src/pages/Dataset/components/ResourceIntro/index.less b/react-ui/src/pages/Dataset/components/ResourceIntro/index.less
index 57d40216..6ac9223b 100644
--- a/react-ui/src/pages/Dataset/components/ResourceIntro/index.less
+++ b/react-ui/src/pages/Dataset/components/ResourceIntro/index.less
@@ -1,10 +1,25 @@
.resource-intro {
width: 100%;
- margin-top: 24px;
- &__basic {
- width: 100%;
- }
- &__usage {
- width: 100%;
+
+ &__top {
+ padding: 20px 30px;
+ background: white;
+ border-radius: 0 0 10px 10px;
+ box-shadow: 0px 2px 12px rgba(180, 182, 191, 0.09);
+
+ pre {
+ margin-bottom: 0 !important;
+ }
+
+ &__title {
+ margin: 15px 0;
+ color: @text-color-secondary;
+ font-size: 14px;
+ }
+
+ &__desc {
+ color: @text-color;
+ font-size: @font-size;
+ }
}
}
diff --git a/react-ui/src/pages/Dataset/components/ResourceIntro/index.tsx b/react-ui/src/pages/Dataset/components/ResourceIntro/index.tsx
index 2ee7fb24..0aa3b7e3 100644
--- a/react-ui/src/pages/Dataset/components/ResourceIntro/index.tsx
+++ b/react-ui/src/pages/Dataset/components/ResourceIntro/index.tsx
@@ -1,4 +1,4 @@
-import BasicInfo, { BasicInfoData } from '@/components/BasicInfo';
+import BasicTableInfo, { BasicInfoData } from '@/components/BasicTableInfo';
import SubAreaTitle from '@/components/SubAreaTitle';
import { ResourceInfoTabKeys } from '@/pages/Dataset/components/ResourceInfo';
import {
@@ -8,13 +8,19 @@ import {
ProjectDependency,
ResourceType,
TrainTask,
+ resourceConfig,
} from '@/pages/Dataset/config';
+import ModelMetrics from '@/pages/Model/components/ModelMetrics';
import { getGitUrl } from '@/utils';
import styles from './index.less';
type ResourceIntroProps = {
resourceType: ResourceType;
info: DatasetData | ModelData;
+ resourceId: number;
+ identifier: string;
+ owner: string;
+ version?: string;
};
const formatDataset = (datasets?: DatasetData[]) => {
@@ -27,29 +33,6 @@ const formatDataset = (datasets?: DatasetData[]) => {
}));
};
-const formatParams = (map?: Record
, space: string = '') => {
- if (!map || Object.keys(map).length === 0) {
- return undefined;
- }
- return Object.entries(map)
- .map(([key, value]) => `${space}${key} : ${value}`)
- .join('\n');
-};
-
-const formatMetrics = (map?: Record) => {
- if (!map || Object.keys(map).length === 0) {
- return undefined;
- }
- return Object.entries(map)
- .map(([key, value]) => {
- if (typeof value === 'object' && value !== null) {
- return `${key} : \n${formatParams(value, ' ')}`;
- }
- return `${key} : ${value}`;
- })
- .join('\n');
-};
-
const getProjectUrl = (project?: ProjectDependency) => {
if (!project || !project.url || !project.branch) {
return undefined;
@@ -93,49 +76,50 @@ 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: formatProject,
+ ellipsis: true,
},
{
label: '数据集分类',
value: data.data_type,
+ ellipsis: true,
},
{
label: '研究方向',
value: data.data_tag,
- },
- {
- label: '数据集描述',
- value: data.description,
- },
- {
- label: '版本描述',
- value: data.version_desc,
+ ellipsis: true,
},
];
@@ -143,77 +127,79 @@ const getModelDatas = (data: ModelData): 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.image,
+ ellipsis: true,
},
{
label: '训练代码',
value: data.project_depency,
format: formatProject,
+ ellipsis: true,
},
{
label: '训练数据集',
value: data.train_datasets,
format: formatDataset,
+ ellipsis: true,
},
{
label: '测试数据集',
value: data.test_datasets,
format: formatDataset,
- },
- {
- label: '参数',
- value: data.params,
- format: formatParams,
- },
- {
- label: '指标',
- value: data.metrics,
- format: formatMetrics,
+ ellipsis: true,
},
{
label: '模型来源',
value: data.model_source,
format: formatSource,
+ ellipsis: true,
},
{
label: '训练任务',
value: data.train_task,
format: formatTrainTask,
+ ellipsis: true,
},
{
label: '模型框架',
value: data.model_type,
+ ellipsis: true,
},
{
label: '模型能力',
value: data.model_tag,
- },
- {
- label: '模型描述',
- value: data.description,
- },
- {
- label: '版本描述',
- value: data.version_desc,
+ ellipsis: true,
},
];
-function ResourceIntro({ resourceType, info }: ResourceIntroProps) {
+function ResourceIntro({
+ resourceType,
+ info,
+ resourceId,
+ identifier,
+ owner,
+ version,
+}: ResourceIntroProps) {
+ const config = resourceConfig[resourceType];
const basicDatas: BasicInfoData[] =
resourceType === ResourceType.Dataset
? getDatasetDatas(info as DatasetData)
@@ -221,23 +207,37 @@ function ResourceIntro({ resourceType, info }: ResourceIntroProps) {
return (
-
-
-
+
+
+
+
+
+
{`${config.name}描述`}
+
{info.description ?? '暂无描述'}
+
版本描述
+
{info.version_desc ?? '暂无描述'}
+
+
-
-
+ {resourceType === ResourceType.Model && version && (
+
+ )}
);
}
diff --git a/react-ui/src/pages/Dataset/components/ResourceItem/index.less b/react-ui/src/pages/Dataset/components/ResourceItem/index.less
index edd97f85..01be647c 100644
--- a/react-ui/src/pages/Dataset/components/ResourceItem/index.less
+++ b/react-ui/src/pages/Dataset/components/ResourceItem/index.less
@@ -13,13 +13,37 @@
}
}
+ &:hover {
+ border-color: @primary-color;
+ box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.1);
+ }
+
&__name {
position: relative;
display: inline-block;
height: 24px;
margin: 0 10px 0 0 !important;
color: @text-color;
+ font-weight: 500;
font-size: 16px;
+
+ &::after {
+ position: absolute;
+ top: 14px;
+ left: 0;
+ width: 100%;
+ height: 6px;
+ background: linear-gradient(
+ to right,
+ .addAlpha(@primary-color, 0.3) [] 0,
+ .addAlpha(@primary-color, 0) [] 100%
+ );
+ content: '';
+ }
+ }
+
+ &:hover &__name {
+ color: @primary-color;
}
&__description {
@@ -37,25 +61,4 @@
color: #808080;
font-size: 13px;
}
-
- &:hover {
- border-color: @primary-color;
- box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.1);
-
- .resource-item__name {
- color: @primary-color;
- }
- }
-}
-
-.resource-item__name {
- &::after {
- position: absolute;
- top: 14px;
- left: 0;
- width: 100%;
- height: 6px;
- background: linear-gradient(to right, rgba(22, 100, 255, 0.3) 0, rgba(22, 100, 255, 0) 100%);
- content: '';
- }
}
diff --git a/react-ui/src/pages/Dataset/components/ResourceList/index.less b/react-ui/src/pages/Dataset/components/ResourceList/index.less
index edceb96b..7226c7bc 100644
--- a/react-ui/src/pages/Dataset/components/ResourceList/index.less
+++ b/react-ui/src/pages/Dataset/components/ResourceList/index.less
@@ -33,7 +33,6 @@
:global {
.ant-pagination {
margin-right: 30px;
- text-align: right;
}
}
diff --git a/react-ui/src/pages/Dataset/components/ResourceList/index.tsx b/react-ui/src/pages/Dataset/components/ResourceList/index.tsx
index 739f3245..08546bc7 100644
--- a/react-ui/src/pages/Dataset/components/ResourceList/index.tsx
+++ b/react-ui/src/pages/Dataset/components/ResourceList/index.tsx
@@ -204,6 +204,7 @@ function ResourceList(
))}
['columns'] = [
{
title: '序号',
dataIndex: 'index',
key: 'index',
width: 80,
- render(_text: string, _record: ResourceFileData, index: number) {
- return {index + 1};
- },
+ render: tableCellRender(false, TableCellValueType.Index),
},
{
title: '文件名称',
dataIndex: 'file_name',
key: 'file_name',
- render: (text: string, record: ResourceFileData) => (
- downloadAlone(record)}>
- {text}
-
- ),
+ render: tableCellRender(false, TableCellValueType.Link, {
+ onClick: downloadAlone,
+ }),
},
{
title: '文件大小',
dataIndex: 'file_size',
key: 'file_size',
- render: CommonTableCell(),
+ render: tableCellRender(),
},
{
title: '更新时间',
dataIndex: 'update_time',
key: 'update_time',
- render: DateTableCell,
+ render: tableCellRender(false, TableCellValueType.Date),
},
{
title: '操作',
@@ -91,7 +86,7 @@ function ResourceVersion({ resourceType, info }: ResourceVersionProps) {
return (
-
+
-
+
record.run_id || record.experiment_ins_id}
/>
diff --git a/react-ui/src/pages/Experiment/Info/index.jsx b/react-ui/src/pages/Experiment/Info/index.jsx
index a958794b..c96d781e 100644
--- a/react-ui/src/pages/Experiment/Info/index.jsx
+++ b/react-ui/src/pages/Experiment/Info/index.jsx
@@ -3,7 +3,7 @@ import { useStateRef, useVisible } from '@/hooks';
import { getExperimentIns } from '@/services/experiment/index.js';
import { getWorkflowById } from '@/services/pipeline/index.js';
import themes from '@/styles/theme.less';
-import { fittingString } from '@/utils';
+import { fittingString, parseJsonText } from '@/utils';
import { elapsedTime, formatDate } from '@/utils/date';
import { to } from '@/utils/promise';
import G6, { Util } from '@antv/g6';
@@ -88,7 +88,7 @@ function ExperimentText() {
setExperimentIns(res.data);
const { status, nodes_status, argo_ins_ns, argo_ins_name } = res.data;
const workflowData = workflowRef.current;
- const experimentStatusObjs = JSON.parse(nodes_status);
+ const experimentStatusObjs = parseJsonText(nodes_status);
workflowData.nodes.forEach((item) => {
const experimentNode = experimentStatusObjs?.[item.id];
updateWorkflowNode(item, experimentNode);
diff --git a/react-ui/src/pages/Experiment/components/AddExperimentModal/index.tsx b/react-ui/src/pages/Experiment/components/AddExperimentModal/index.tsx
index 126e0557..2b7e80c5 100644
--- a/react-ui/src/pages/Experiment/components/AddExperimentModal/index.tsx
+++ b/react-ui/src/pages/Experiment/components/AddExperimentModal/index.tsx
@@ -2,7 +2,8 @@ import createExperimentIcon from '@/assets/img/create-experiment.png';
import editExperimentIcon from '@/assets/img/edit-experiment.png';
import KFModal from '@/components/KFModal';
import { type PipelineGlobalParam } from '@/types';
-import { Form, Input, Radio, Select, type FormRule } from 'antd';
+import { to } from '@/utils/promise';
+import { Button, Form, Input, Radio, Select, type FormRule } from 'antd';
import { useState } from 'react';
import styles from './index.less';
@@ -17,7 +18,7 @@ type AddExperimentModalProps = {
isAdd: boolean;
open: boolean;
onCancel: () => void;
- onFinish: () => void;
+ onFinish: (values: any, isRun: boolean) => void;
workflowList: Workflow[];
initialValues: FormData;
};
@@ -113,25 +114,45 @@ function AddExperimentModal({
form.setFieldValue('global_param', []);
}
};
+
+ const handleRun = async (run: boolean) => {
+ const [values, error] = await to(form.validateFields());
+ if (!error && values) {
+ onFinish(values, run);
+ }
+ };
+
+ const footer = [
+ ,
+ ,
+ ];
+ if (!isAdd) {
+ footer.push(
+ ,
+ );
+ }
+
return (