| @@ -0,0 +1,14 @@ | |||
| .kf-info-group { | |||
| width: 100%; | |||
| &__content { | |||
| padding: 20px @content-padding; | |||
| background-color: white; | |||
| border: 1px solid @border-color-base; | |||
| border-radius: 0 0 4px 4px; | |||
| &&--scroll { | |||
| padding: 0; | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,28 @@ | |||
| import classNames from 'classnames'; | |||
| import InfoGroupTitle from '../InfoGroupTitle'; | |||
| import './index.less'; | |||
| type InfoGroupProps = { | |||
| title: string; | |||
| contentScroll?: boolean; // 内容是否需要滚动,如果可以滚动,则取消 padding | |||
| className?: string; | |||
| style?: React.CSSProperties; | |||
| children?: React.ReactNode; | |||
| }; | |||
| function InfoGroup({ title, contentScroll = false, className, style, children }: InfoGroupProps) { | |||
| return ( | |||
| <div className={classNames('kf-info-group', className)} style={style}> | |||
| <InfoGroupTitle title={title} /> | |||
| <div | |||
| className={classNames('kf-info-group__content', { | |||
| 'kf-info-group__content--scroll': contentScroll, | |||
| })} | |||
| > | |||
| {children} | |||
| </div> | |||
| </div> | |||
| ); | |||
| } | |||
| export default InfoGroup; | |||
| @@ -1,4 +1,4 @@ | |||
| .config-title { | |||
| .kf-info-group-title { | |||
| width: 100%; | |||
| height: 56px; | |||
| padding-left: @content-padding; | |||
| @@ -10,7 +10,7 @@ | |||
| border: 1px solid #e8effb; | |||
| border-radius: 4px 4px 0 0; | |||
| &__img { | |||
| &__image { | |||
| width: 16px; | |||
| height: 16px; | |||
| margin-right: 10px; | |||
| @@ -0,0 +1,25 @@ | |||
| import { Flex } from 'antd'; | |||
| import classNames from 'classnames'; | |||
| import './index.less'; | |||
| type InfoGroupTitleProps = { | |||
| title: string; | |||
| className?: string; | |||
| style?: React.CSSProperties; | |||
| }; | |||
| function InfoGroupTitle({ title, style, className }: InfoGroupTitleProps) { | |||
| return ( | |||
| <Flex align="center" className={classNames('kf-info-group-title', className)} style={style}> | |||
| <img | |||
| src={require('@/assets/img/code-name-icon.png')} | |||
| className="kf-info-group-title__image" | |||
| alt="" | |||
| draggable={false} | |||
| /> | |||
| <span className="kf-info-group-title__text">{title}</span> | |||
| </Flex> | |||
| ); | |||
| } | |||
| export default InfoGroupTitle; | |||
| @@ -33,7 +33,7 @@ function AutoMLInstance() { | |||
| useEffect(() => { | |||
| if (instanceId) { | |||
| getExperimentInsInfo(); | |||
| getExperimentInsInfo(false); | |||
| } | |||
| return () => { | |||
| closeSSE(); | |||
| @@ -41,7 +41,7 @@ function AutoMLInstance() { | |||
| }, []); | |||
| // 获取实验实例详情 | |||
| const getExperimentInsInfo = async () => { | |||
| const getExperimentInsInfo = async (isStatusDetermined: boolean) => { | |||
| const [res] = await to(getExperimentInsReq(instanceId)); | |||
| if (res && res.data) { | |||
| const info = res.data as AutoMLInstanceData; | |||
| @@ -51,6 +51,14 @@ function AutoMLInstance() { | |||
| if (paramJson) { | |||
| setAutoMLInfo(paramJson); | |||
| } | |||
| // 这个接口返回的状态有延时,SSE 返回的状态是最新的 | |||
| // SSE 调用时,不需要解析 node_status, 也不要重新建立 SSE | |||
| if (!isStatusDetermined) { | |||
| setInstanceInfo(info); | |||
| return; | |||
| } | |||
| // 进行节点状态 | |||
| const nodeStatusJson = parseJsonText(node_status); | |||
| if (nodeStatusJson) { | |||
| @@ -103,7 +111,7 @@ function AutoMLInstance() { | |||
| statusData.phase !== ExperimentStatus.Running | |||
| ) { | |||
| closeSSE(); | |||
| getExperimentInsInfo(); | |||
| getExperimentInsInfo(true); | |||
| } | |||
| } | |||
| } | |||
| @@ -283,7 +283,6 @@ function AutoMLBasic({ info, className, runStatus, isInstance = false }: AutoMLB | |||
| title="运行信息" | |||
| data={instanceDatas} | |||
| labelWidth={70} | |||
| threeColumn | |||
| style={{ marginBottom: '20px' }} | |||
| /> | |||
| ) : ( | |||
| @@ -291,7 +290,6 @@ function AutoMLBasic({ info, className, runStatus, isInstance = false }: AutoMLB | |||
| title="基本信息" | |||
| data={basicDatas} | |||
| labelWidth={70} | |||
| threeColumn | |||
| style={{ marginBottom: '20px' }} | |||
| /> | |||
| )} | |||
| @@ -299,10 +297,9 @@ function AutoMLBasic({ info, className, runStatus, isInstance = false }: AutoMLB | |||
| title="配置信息" | |||
| data={configDatas} | |||
| labelWidth={150} | |||
| threeColumn | |||
| style={{ marginBottom: '20px' }} | |||
| /> | |||
| <ConfigInfo title="优化指标" data={metricsData} labelWidth={70} threeColumn /> | |||
| <ConfigInfo title="优化指标" data={metricsData} labelWidth={70} /> | |||
| </div> | |||
| ); | |||
| } | |||
| @@ -1,20 +1,10 @@ | |||
| .config-info { | |||
| flex: 1; | |||
| min-width: 0; | |||
| &__content { | |||
| padding: 20px; | |||
| padding: 20px @content-padding; | |||
| background-color: white; | |||
| border: 1px solid @border-color-base; | |||
| border-radius: 0 0 4px 4px; | |||
| } | |||
| :global { | |||
| .kf-basic-info { | |||
| width: 100%; | |||
| &__item { | |||
| width: calc((100% - 80px) / 3); | |||
| &__label { | |||
| font-size: @font-size; | |||
| text-align: left; | |||
| @@ -27,14 +17,4 @@ | |||
| } | |||
| } | |||
| } | |||
| &--three-column { | |||
| :global { | |||
| .kf-basic-info { | |||
| &__item { | |||
| width: calc((100% - 80px) / 3); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -1,7 +1,6 @@ | |||
| import BasicInfo, { type BasicInfoData } from '@/components/BasicInfo'; | |||
| import InfoGroup from '@/components/InfoGroup'; | |||
| import classNames from 'classnames'; | |||
| import { useEffect } from 'react'; | |||
| import ConfigTitle from '../ConfigTitle'; | |||
| import styles from './index.less'; | |||
| export * from '@/components/BasicInfo/format'; | |||
| export type { BasicInfoData }; | |||
| @@ -9,39 +8,18 @@ export type { BasicInfoData }; | |||
| type ConfigInfoProps = { | |||
| title: string; | |||
| data: BasicInfoData[]; | |||
| labelWidth: number; | |||
| className?: string; | |||
| style?: React.CSSProperties; | |||
| children?: React.ReactNode; | |||
| labelWidth: number; | |||
| threeColumn?: boolean; | |||
| }; | |||
| function ConfigInfo({ | |||
| title, | |||
| data, | |||
| className, | |||
| style, | |||
| children, | |||
| labelWidth, | |||
| threeColumn = false, | |||
| }: ConfigInfoProps) { | |||
| useEffect(() => {}, []); | |||
| function ConfigInfo({ title, data, labelWidth, className, style }: ConfigInfoProps) { | |||
| return ( | |||
| <div | |||
| className={classNames( | |||
| styles['config-info'], | |||
| { [styles['config-info--three-column']]: threeColumn }, | |||
| className, | |||
| )} | |||
| style={style} | |||
| > | |||
| <ConfigTitle title={title} /> | |||
| <InfoGroup title={title} className={classNames(styles['config-info'], className)} style={style}> | |||
| <div className={styles['config-info__content']}> | |||
| <BasicInfo datas={data} labelWidth={labelWidth} /> | |||
| {children} | |||
| </div> | |||
| </div> | |||
| </InfoGroup> | |||
| ); | |||
| } | |||
| @@ -1,22 +0,0 @@ | |||
| import { Flex } from 'antd'; | |||
| import styles from './index.less'; | |||
| type ConfigTitleProps = { | |||
| title: string; | |||
| }; | |||
| function ConfigTitle({ title }: ConfigTitleProps) { | |||
| return ( | |||
| <Flex align="center" className={styles['config-title']}> | |||
| <img | |||
| src={require('@/assets/img/code-name-icon.png')} | |||
| className={styles['config-title__img']} | |||
| alt="" | |||
| draggable={false} | |||
| /> | |||
| <span className={styles['config-title__text']}>{title}</span> | |||
| </Flex> | |||
| ); | |||
| } | |||
| export default ConfigTitle; | |||
| @@ -9,24 +9,18 @@ | |||
| &__text { | |||
| width: 100%; | |||
| height: 460px; | |||
| margin-bottom: 16px; | |||
| padding: 20px @content-padding; | |||
| overflow: auto; | |||
| white-space: pre-wrap; | |||
| border: 1px solid @border-color-base; | |||
| border-radius: 0 0 4px 4px; | |||
| } | |||
| &__image-container { | |||
| &__images { | |||
| display: flex; | |||
| align-items: flex-start; | |||
| width: 100%; | |||
| padding: 20px @content-padding; | |||
| overflow-x: auto; | |||
| border: 1px solid @border-color-base; | |||
| border-radius: 0 0 4px 4px; | |||
| &__image { | |||
| &__item { | |||
| height: 248px; | |||
| margin-right: 20px; | |||
| border: 1px solid rgba(96, 107, 122, 0.3); | |||
| @@ -1,7 +1,7 @@ | |||
| import InfoGroup from '@/components/InfoGroup'; | |||
| import { getFileReq } from '@/services/file'; | |||
| import { to } from '@/utils/promise'; | |||
| import { useEffect, useMemo, useState } from 'react'; | |||
| import ConfigTitle from '../ConfigTitle'; | |||
| import styles from './index.less'; | |||
| type ExperimentResultProps = { | |||
| @@ -35,20 +35,22 @@ function ExperimentResult({ fileUrl, imageUrl }: ExperimentResultProps) { | |||
| return ( | |||
| <div className={styles['experiment-result']}> | |||
| <ConfigTitle title="实验结果"></ConfigTitle> | |||
| <div className={styles['experiment-result__text']}>{result}</div> | |||
| <ConfigTitle title="可视化结果"></ConfigTitle> | |||
| <div className={styles['experiment-result__image-container']}> | |||
| {images.map((item, index) => ( | |||
| <img | |||
| key={index} | |||
| className={styles['experiment-result__image-container__image']} | |||
| src={item} | |||
| draggable={false} | |||
| alt="" | |||
| /> | |||
| ))} | |||
| </div> | |||
| <InfoGroup title="实验结果" contentScroll> | |||
| <div className={styles['experiment-result__text']}>{result}</div> | |||
| </InfoGroup> | |||
| <InfoGroup title="可视化结果" style={{ marginTop: '16px' }}> | |||
| <div className={styles['experiment-result__images']}> | |||
| {images.map((item, index) => ( | |||
| <img | |||
| key={index} | |||
| className={styles['experiment-result__images__item']} | |||
| src={item} | |||
| draggable={false} | |||
| alt="" | |||
| /> | |||
| ))} | |||
| </div> | |||
| </InfoGroup> | |||
| </div> | |||
| ); | |||
| } | |||