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/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/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/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 ffeb3d3d..e4570868 100644 --- a/react-ui/src/components/BasicInfo/index.less +++ b/react-ui/src/components/BasicInfo/index.less @@ -38,13 +38,8 @@ margin-left: 16px; font-size: @font-size-content; line-height: 1.6; - white-space: pre-line; word-break: break-all; - &--ellipsis { - .singleLine(); - } - &__text { color: @text-color; } diff --git a/react-ui/src/components/BasicInfo/index.tsx b/react-ui/src/components/BasicInfo/index.tsx index 60cd5b57..bd07db34 100644 --- a/react-ui/src/components/BasicInfo/index.tsx +++ b/react-ui/src/components/BasicInfo/index.tsx @@ -120,13 +120,10 @@ export function BasicInfoItemValue({ } return ( - - {component} - +
+ + {component} + +
); } diff --git a/react-ui/src/components/BasicTableInfo/index.less b/react-ui/src/components/BasicTableInfo/index.less index cc3d0984..314b05ca 100644 --- a/react-ui/src/components/BasicTableInfo/index.less +++ b/react-ui/src/components/BasicTableInfo/index.less @@ -33,10 +33,10 @@ &__value { flex: 1; + min-width: 0; margin: 0 !important; padding: 12px 20px 4px; font-size: @font-size; - white-space: pre-line; word-break: break-all; & + & { @@ -47,10 +47,6 @@ padding-bottom: 12px; } - &--ellipsis { - .singleLine(); - } - &__text { color: @text-color; } 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/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 6f5bdbbc..f5ef64af 100644 --- a/react-ui/src/hooks/index.ts +++ b/react-ui/src/hooks/index.ts @@ -162,7 +162,7 @@ export const useCheck = (list: T[]) => { const [selected, setSelected] = useState([]); const checked = useMemo(() => { - return selected.length === list.length; + return selected.length === list.length && selected.length > 0; }, [selected, list]); const indeterminate = useMemo(() => { diff --git a/react-ui/src/overrides.less b/react-ui/src/overrides.less index 9e4b34cc..f676890e 100644 --- a/react-ui/src/overrides.less +++ b/react-ui/src/overrides.less @@ -168,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 c5d4abaa..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 !important; - 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}
+
{ + const handleTableChange: TableProps['onChange'] = ( + pagination, + _filters, + _sorter, + { action }, + ) => { if (action === 'paginate') { setPagination(pagination); } diff --git a/react-ui/src/pages/Experiment/Comparison/index.less b/react-ui/src/pages/Experiment/Comparison/index.less index b9198e74..3be69ed9 100644 --- a/react-ui/src/pages/Experiment/Comparison/index.less +++ b/react-ui/src/pages/Experiment/Comparison/index.less @@ -18,6 +18,26 @@ background-color: white; border-radius: 10px; + &__footer { + display: flex; + align-items: center; + padding-top: 20px; + color: @text-color-secondary; + font-size: 12px; + background-color: white; + + div { + flex: 1; + height: 1px; + background-color: @border-color-base; + } + + p { + flex: none; + margin: 0 8px; + } + } + :global { .ant-table-container { border: none !important; @@ -34,6 +54,13 @@ border-left: none !important; } } + .ant-table-tbody-virtual::after { + border-bottom: none !important; + } + .ant-table-footer { + padding: 0; + border: none !important; + } } } } diff --git a/react-ui/src/pages/Experiment/Comparison/index.tsx b/react-ui/src/pages/Experiment/Comparison/index.tsx index fe09198b..b900842c 100644 --- a/react-ui/src/pages/Experiment/Comparison/index.tsx +++ b/react-ui/src/pages/Experiment/Comparison/index.tsx @@ -1,13 +1,19 @@ -// import { useCacheState } from '@/hooks/pageCacheState'; +/* + * @Author: 赵伟 + * @Date: 2024-10-10 09:55:12 + * @Description: 实验对比 + */ + import { getExpEvaluateInfosReq, getExpMetricsReq, getExpTrainInfosReq, } from '@/services/experiment'; +import { tableSorter } from '@/utils'; import { to } from '@/utils/promise'; import tableCellRender, { TableCellValueType } from '@/utils/table'; import { useSearchParams } from '@umijs/max'; -import { App, Button, Table, /* TablePaginationConfig,*/ TableProps, Tooltip } from 'antd'; +import { App, Button, Table, TablePaginationConfig, TableProps, Tooltip } from 'antd'; import classNames from 'classnames'; import { useEffect, useMemo, useState } from 'react'; import ExperimentStatusCell from '../components/ExperimentStatusCell'; @@ -20,10 +26,10 @@ type TableData = { dataset: string[]; start_time: string; status: string; - metrics_names: string[]; - metrics: Record; - params_names: string[]; - params: Record; + metrics_names?: string[]; + metrics?: Record; + params_names?: string[]; + params?: Record; }; function ExperimentComparison() { @@ -31,18 +37,15 @@ function ExperimentComparison() { const comparisonType = searchParams.get('type') as ComparisonType; const experimentId = searchParams.get('id'); const [tableData, setTableData] = useState([]); - // const [cacheState, setCacheState] = useCacheState(); - // const [total, setTotal] = useState(0); const [selectedRowKeys, setSelectedRowKeys] = useState([]); - // const [loading, setLoading] = useState(false); + const [total, setTotal] = useState(0); + const [pagination, setPagination] = useState({ + current: 1, + pageSize: 10, + }); + const { message } = App.useApp(); const config = useMemo(() => comparisonConfig[comparisonType], [comparisonType]); - // const [pagination, setPagination] = useState( - // cacheState?.pagination ?? { - // current: 1, - // pageSize: 10, - // }, - // ); useEffect(() => { getComparisonData(); @@ -50,15 +53,17 @@ function ExperimentComparison() { // 获取对比数据列表 const getComparisonData = async () => { - // setLoading(true); const request = comparisonType === ComparisonType.Train ? getExpTrainInfosReq : getExpEvaluateInfosReq; - const [res] = await to(request(experimentId, { offset: '', limit: 50 })); - // setLoading(false); + const params = { + page: pagination.current! - 1, + size: pagination.pageSize, + }; + const [res] = await to(request(experimentId, params)); if (res && res.data) { - // const { content = [], totalElements = 0 } = res.data; - setTableData(res.data); - // setTotal(totalElements); + const { content = [], totalElements = 0 } = res.data; + setTableData(content); + setTotal(totalElements); } }; @@ -80,17 +85,10 @@ function ExperimentComparison() { getExpMetrics(); }; - // 分页切换 - // const handleTableChange: TableProps['onChange'] = (pagination, filters, sorter, { action }) => { - // if (action === 'paginate') { - // setPagination(pagination); - // } - // // console.log(pagination, filters, sorter, action); - // }; - // 选择行 - const rowSelection: TableProps['rowSelection'] = { + const rowSelection: TableProps['rowSelection'] = { type: 'checkbox', + columnWidth: 48, fixed: 'left', selectedRowKeys, onChange: (selectedRowKeys: React.Key[]) => { @@ -98,8 +96,24 @@ function ExperimentComparison() { }, }; + // 分页切换 + const handleTableChange: TableProps['onChange'] = ( + pagination, + _filters, + _sorter, + { action }, + ) => { + if (action === 'paginate') { + setPagination(pagination); + } + }; + const columns: TableProps['columns'] = useMemo(() => { - const first: TableData | undefined = tableData[0]; + const first: TableData | undefined = tableData.find( + (item) => item.metrics_names && item.metrics_names.length > 0, + ); + const metricsNames = first?.metrics_names ?? []; + const paramsNames = first?.params_names ?? []; return [ { title: '基本信息', @@ -147,7 +161,7 @@ function ExperimentComparison() { { title: `${config.title}参数`, align: 'center', - children: first?.params_names.map((name) => ({ + children: paramsNames.map((name) => ({ title: ( {name} @@ -159,14 +173,14 @@ function ExperimentComparison() { align: 'center', render: tableCellRender(true), ellipsis: { showTitle: false }, - sorter: (a, b) => a.params[name] - b.params[name], + sorter: (a, b) => tableSorter(a.params?.[name], b.params?.[name]), showSorterTooltip: false, })), }, { title: `${config.title}指标`, align: 'center', - children: first?.metrics_names.map((name) => ({ + children: metricsNames.map((name) => ({ title: ( {name} @@ -178,7 +192,7 @@ function ExperimentComparison() { align: 'center', render: tableCellRender(true), ellipsis: { showTitle: false }, - sorter: (a, b) => a.metrics[name] - b.metrics[name], + sorter: (a, b) => tableSorter(a.metrics?.[name], b.metrics?.[name]), showSorterTooltip: false, })), }, @@ -192,30 +206,21 @@ function ExperimentComparison() { 可视化对比
-
+
record.run_id || record.experiment_ins_id} /> diff --git a/react-ui/src/pages/Experiment/components/AddExperimentModal/index.tsx b/react-ui/src/pages/Experiment/components/AddExperimentModal/index.tsx index 4758a165..2b7e80c5 100644 --- a/react-ui/src/pages/Experiment/components/AddExperimentModal/index.tsx +++ b/react-ui/src/pages/Experiment/components/AddExperimentModal/index.tsx @@ -126,7 +126,7 @@ function AddExperimentModal({ , - , ]; diff --git a/react-ui/src/pages/Experiment/components/ExperimentInstance/index.less b/react-ui/src/pages/Experiment/components/ExperimentInstance/index.less index 56aa07e2..31df6572 100644 --- a/react-ui/src/pages/Experiment/components/ExperimentInstance/index.less +++ b/react-ui/src/pages/Experiment/components/ExperimentInstance/index.less @@ -4,7 +4,7 @@ width: 100%; padding: 0 0 0 33px; color: @text-color; - font-size: 15px; + font-size: 14px; & > div { padding: 0 16px; diff --git a/react-ui/src/pages/Experiment/components/ExperimentInstance/index.tsx b/react-ui/src/pages/Experiment/components/ExperimentInstance/index.tsx index 04508fb7..754034aa 100644 --- a/react-ui/src/pages/Experiment/components/ExperimentInstance/index.tsx +++ b/react-ui/src/pages/Experiment/components/ExperimentInstance/index.tsx @@ -129,7 +129,8 @@ function ExperimentInstanceComponent({ {selectedIns.length > 0 && ( +