diff --git a/react-ui/src/pages/AutoML/List/index.tsx b/react-ui/src/pages/AutoML/List/index.tsx index 8006675a..13e3dcbe 100644 --- a/react-ui/src/pages/AutoML/List/index.tsx +++ b/react-ui/src/pages/AutoML/List/index.tsx @@ -26,6 +26,7 @@ import { ConfigProvider, Input, Table, + Tooltip, type TablePaginationConfig, type TableProps, } from 'antd'; @@ -276,13 +277,18 @@ function AutoMLList() { {newText && newText.length > 0 ? newText.map((item, index) => { return ( - + placement="top" + title={experimentStatusInfo[item as ExperimentStatus].label} + > + + ); }) : null} diff --git a/react-ui/src/pages/AutoML/components/CreateForm/TrialConfig.tsx b/react-ui/src/pages/AutoML/components/CreateForm/TrialConfig.tsx index c9e5b61f..f0fdfa5d 100644 --- a/react-ui/src/pages/AutoML/components/CreateForm/TrialConfig.tsx +++ b/react-ui/src/pages/AutoML/components/CreateForm/TrialConfig.tsx @@ -1,5 +1,6 @@ import SubAreaTitle from '@/components/SubAreaTitle'; import { AutoMLTaskType } from '@/enums'; +import { modalConfirm } from '@/utils/ui'; import { MinusCircleOutlined, PlusCircleOutlined } from '@ant-design/icons'; import { Button, Col, Flex, Form, Input, InputNumber, Radio, Row, Select } from 'antd'; import { classificationMetrics, regressionMetrics } from './ExecuteConfig'; @@ -72,8 +73,15 @@ function TrialConfig() { shape="circle" size="middle" type="text" - onClick={() => remove(name)} icon={} + onClick={() => { + modalConfirm({ + title: '确定要删除该指标权重吗?', + onOk: () => { + remove(name); + }, + }); + }} > {index === fields.length - 1 && ( diff --git a/react-ui/src/pages/Experiment/components/ExperimentStatusCell/index.less b/react-ui/src/pages/Experiment/components/ExperimentStatusCell/index.less index a5df71aa..67d76fc6 100644 --- a/react-ui/src/pages/Experiment/components/ExperimentStatusCell/index.less +++ b/react-ui/src/pages/Experiment/components/ExperimentStatusCell/index.less @@ -1,12 +1,3 @@ .experiment-status-cell { height: 100%; - &__label { - display: none; - } -} - -.experiment-status-cell:hover { - .experiment-status-cell__label { - display: inline; - } } diff --git a/react-ui/src/pages/Experiment/index.jsx b/react-ui/src/pages/Experiment/index.jsx index 998fb436..373f8b54 100644 --- a/react-ui/src/pages/Experiment/index.jsx +++ b/react-ui/src/pages/Experiment/index.jsx @@ -1,5 +1,7 @@ import KFIcon from '@/components/KFIcon'; +import PageTitle from '@/components/PageTitle'; import { ExperimentStatus, TensorBoardStatus } from '@/enums'; +import { useCacheState } from '@/hooks/pageCacheState'; import { deleteExperimentById, getExperiment, @@ -16,14 +18,14 @@ import themes from '@/styles/theme.less'; import { to } from '@/utils/promise'; import tableCellRender, { TableCellValueType } from '@/utils/table'; import { modalConfirm } from '@/utils/ui'; -import { App, Button, ConfigProvider, Dropdown, Space, Table } from 'antd'; +import { App, Button, ConfigProvider, Dropdown, Input, Space, Table, Tooltip } from 'antd'; import classNames from 'classnames'; -import { useEffect, useRef, useState } from 'react'; +import { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { ComparisonType } from './Comparison/config'; import AddExperimentModal from './components/AddExperimentModal'; import ExperimentInstance from './components/ExperimentInstance'; -import Styles from './index.less'; +import styles from './index.less'; import { experimentStatusInfo } from './status'; // 定时器 @@ -47,32 +49,34 @@ function Experiment() { const [isModalOpen, setIsModalOpen] = useState(false); const [addFormData, setAddFormData] = useState({}); const [experimentInsTotal, setExperimentInsTotal] = useState(0); + const [cacheState, setCacheState] = useCacheState(); + const [searchText, setSearchText] = useState(cacheState?.searchText); + const [inputText, setInputText] = useState(cacheState?.searchText); + const [pagination, setPagination] = useState( + cacheState?.pagination ?? { + current: 1, + pageSize: 10, + }, + ); const { message } = App.useApp(); - const pageOption = useRef({ page: 1, size: 10 }); - const paginationProps = { - showSizeChanger: true, - showQuickJumper: true, - showTotal: () => `共${total}条`, - total: total, - page: pageOption.current.page, - size: pageOption.current.size, - onChange: (current, size) => paginationChange(current, size), - }; useEffect(() => { - getExperimentList(); getWorkflowList(); return () => { clearExperimentInTimers(); }; }, []); + useEffect(() => { + getExperimentList(); + }, [pagination, searchText]); + // 获取实验列表 const getExperimentList = async () => { const params = { - offset: 0, - page: pageOption.current.page - 1, - size: pageOption.current.size, + page: pagination.current - 1, + size: pagination.pageSize, + name: searchText || undefined, }; const [res] = await to(getExperiment(params)); if (res && res.data && Array.isArray(res.data.content)) { @@ -94,6 +98,15 @@ function Experiment() { } }; + // 搜索 + const onSearch = (value) => { + setSearchText(value); + setPagination((prev) => ({ + ...prev, + current: 1, + })); + }; + // 获取实验实例列表 const getQueryByExperiment = async (experimentId, page) => { const params = { @@ -259,11 +272,11 @@ function Experiment() { }; // 当前页面切换 - const paginationChange = async (current, size) => { - pageOption.current = { - page: current, - size: size, - }; + const paginationChange = async (current, pageSize) => { + setPagination({ + current, + pageSize, + }); getExperimentList(); }; // 运行实验 @@ -278,14 +291,23 @@ function Experiment() { } }; + // 跳转, 缓存当前状态 + const navigateToUrl = (url) => { + setCacheState({ + pagination, + searchText, + }); + navigate(url); + }; + // 跳转到流水线 const gotoPipeline = (record) => { - navigate({ pathname: `/pipeline/template/info/${record.workflow_id}` }); + navigateToUrl(`/pipeline/template/info/${record.workflow_id}`); }; // 跳转到实验实例详情 const gotoInstanceInfo = (item, record) => { - navigate({ pathname: `/pipeline/experiment/instance/${record.workflow_id}/${item.id}` }); + navigateToUrl(`/pipeline/experiment/instance/${record.workflow_id}/${item.id}`); }; // 处理 TensorBoard 操作 @@ -340,7 +362,7 @@ function Experiment() { }, ], onClick: ({ key }) => { - navigate(`/pipeline/experiment/compare?type=${key}&id=${experimentId}`); + navigateToUrl(`/pipeline/experiment/compare?type=${key}&id=${experimentId}`); }, }; }; @@ -392,13 +414,14 @@ function Experiment() { {newText && newText.length > 0 ? newText.map((item, index) => { return ( - + + + ); }) : null} @@ -479,41 +502,61 @@ function Experiment() { }, ]; return ( -
-
- -
-
- ( - gotoInstanceInfo(item, record)} - onClickTensorBoard={handleTensorboard} - onRemove={() => { - refreshExperimentIns(record.id); - refreshExperimentList(); - }} - onTerminate={handleInstanceTerminate} - onLoadMore={() => loadMoreExperimentIns()} - > - ), - onExpand: (e, a) => { - expandChange(e, a); - }, - expandedRowKeys: [expandedRowKeys], - rowExpandable: (record) => true, - }} - /> +
+ +
+
+ setInputText(e.target.value)} + style={{ width: 300 }} + value={inputText} + allowClear + /> + +
+
+
`共${total}条`, + onChange: paginationChange, + }} + rowKey="id" + scroll={{ y: 'calc(100% - 55px)' }} + expandable={{ + expandedRowRender: (record) => ( + gotoInstanceInfo(item, record)} + onClickTensorBoard={handleTensorboard} + onRemove={() => { + refreshExperimentIns(record.id); + refreshExperimentList(); + }} + onTerminate={handleInstanceTerminate} + onLoadMore={() => loadMoreExperimentIns()} + > + ), + onExpand: (e, a) => { + expandChange(e, a); + }, + expandedRowKeys: [expandedRowKeys], + rowExpandable: (record) => true, + }} + /> + {isModalOpen && ( diff --git a/react-ui/src/pages/Experiment/index.less b/react-ui/src/pages/Experiment/index.less index b13e1145..0791397a 100644 --- a/react-ui/src/pages/Experiment/index.less +++ b/react-ui/src/pages/Experiment/index.less @@ -1,28 +1,21 @@ -.experimentBox { +.experiment-list { height: 100%; - .experimentTopBox { - display: flex; - align-items: center; - justify-content: flex-end; - width: 100%; - height: 49px; - margin-bottom: 10px; - padding-right: 30px; - background-image: url(@/assets/img/page-title-bg.png); - background-repeat: no-repeat; - background-position: top center; - background-size: 100% 100%; - } - .experimentTable { + &__content { height: calc(100% - 60px); - :global { - .ant-table-wrapper .ant-table { - // overflow-y: auto; - height: calc(100% - 48px); - } - .ant-table-row-expand-icon-cell { - padding: 0 30px; - } + 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/Mirror/Create/index.tsx b/react-ui/src/pages/Mirror/Create/index.tsx index c0e09cdc..c4e89ce2 100644 --- a/react-ui/src/pages/Mirror/Create/index.tsx +++ b/react-ui/src/pages/Mirror/Create/index.tsx @@ -150,8 +150,8 @@ function MirrorCreate() { message: '请输入镜像名称', }, { - pattern: /^[a-zA-Z0-9_-]*$/, - message: '只支持字母、数字、下划线、中横线', + pattern: /^[a-z0-9/_-]*$/, + message: '只支持小写字母、数字、下划线(_)、中横线(-)、斜杠(/)', }, ]} > @@ -178,7 +178,7 @@ function MirrorCreate() { }, { pattern: /^[a-zA-Z0-9_-]*$/, - message: '只支持字母、数字、下划线、中横线', + message: '只支持字母、数字、下划线(_)、中横线(-)', }, ]} > diff --git a/react-ui/src/pages/ModelDeployment/CreateVersion/index.less b/react-ui/src/pages/ModelDeployment/CreateVersion/index.less index 2527a233..0460788f 100644 --- a/react-ui/src/pages/ModelDeployment/CreateVersion/index.less +++ b/react-ui/src/pages/ModelDeployment/CreateVersion/index.less @@ -11,9 +11,31 @@ background-color: white; border-radius: 10px; - &__type { - color: @text-color; - font-size: @font-size-input-lg; + &__env { + margin-bottom: 0 !important; + + // 增加样式权重 + & &__add-btn { + border-color: .addAlpha(@primary-color, 0.5) []; + box-shadow: none !important; + &:hover { + border-style: solid; + } + } + } + + :global { + .ant-btn.ant-btn-icon-only .anticon { + font-size: 20px; + } + + .ant-btn-variant-text:disabled { + color: rgba(0, 0, 0, 0.25); + } + + .ant-btn-variant-text { + color: #565658; + } } } } diff --git a/react-ui/src/pages/ModelDeployment/CreateVersion/index.tsx b/react-ui/src/pages/ModelDeployment/CreateVersion/index.tsx index 29f8e739..b8de0bcf 100644 --- a/react-ui/src/pages/ModelDeployment/CreateVersion/index.tsx +++ b/react-ui/src/pages/ModelDeployment/CreateVersion/index.tsx @@ -4,11 +4,10 @@ * @Description: 创建服务版本 */ import CodeSelect from '@/components/CodeSelect'; -import KFIcon from '@/components/KFIcon'; import PageTitle from '@/components/PageTitle'; import ResourceSelect, { - requiredValidator, ResourceSelectorType, + requiredValidator, type ParameterInputObject, } from '@/components/ResourceSelect'; import SubAreaTitle from '@/components/SubAreaTitle'; @@ -22,7 +21,7 @@ import { changePropertyName } from '@/utils'; import { to } from '@/utils/promise'; import SessionStorage from '@/utils/sessionStorage'; import { modalConfirm } from '@/utils/ui'; -import { PlusOutlined } from '@ant-design/icons'; +import { MinusCircleOutlined, PlusCircleOutlined, PlusOutlined } from '@ant-design/icons'; import { useNavigate, useParams } from '@umijs/max'; import { App, Button, Col, Flex, Form, Input, InputNumber, Row, Select } from 'antd'; import { omit, pick } from 'lodash'; @@ -411,7 +410,7 @@ function CreateServiceVersion() { { pattern: /^\/[a-zA-Z0-9._/-]+$/, message: - '请输入正确的挂载路径,以 / 开头,只支持字母、数字、点、下划线、中横线、斜杠', + '请输入正确的挂载路径,以斜杠(/)开头,只支持字母、数字、点(.)、下划线(_)、中横线(-)、斜杠(/)', }, ]} > @@ -426,82 +425,100 @@ function CreateServiceVersion() { - - {(fields, { add, remove }) => ( - <> - - - - {fields.length === 0 ? ( - - ) : null} - - - - {fields.map(({ key, name, ...restField }) => ( - - - - - = - - - - - - ))} - {fields.length > 0 ? ( - - ) : null} - - )} - + + + + + {(fields, { add, remove }) => ( + <> + {fields.map(({ key, name, ...restField }, index) => ( + + + + + = + + + + + + {index === fields.length - 1 && ( + + )} + + + ))} + {fields.length === 0 && ( + + + + )} + + )} + + + + + - -
-
+
+ +
+
+ setInputText(e.target.value)} + style={{ width: 300 }} + value={inputText} + allowClear + /> + +
+
+
`共${total}条`, + onChange: paginationChange, + }} + rowKey="id" + scroll={{ y: 'calc(100% - 55px)' }} + /> + paramMap = JsonUtils.jsonToMap(inParameters); Map model = (Map) paramMap.get("--model_name"); String value = (String) model.get("value"); - if (!value.startsWith("{{")) { + if (StringUtils.isNotEmpty(value) && !value.startsWith("{{")) { Map valueMap = JsonUtils.jsonToMap(value); insertAssetWorkFlow(workflowId, workflowName, Long.valueOf((String) valueMap.get("id")), (String) valueMap.get("version"), Constant.Asset_Type_Model); }