| @@ -21,6 +21,7 @@ const classificationAlgorithms = [ | |||
| 'lda', | |||
| 'liblinear_svc', | |||
| 'libsvm_svc', | |||
| 'tablenet', | |||
| 'mlp', | |||
| 'multinomial_nb', | |||
| 'passive_aggressive', | |||
| @@ -30,13 +31,7 @@ const classificationAlgorithms = [ | |||
| 'LightGBMClassification', | |||
| 'XGBoostClassification', | |||
| 'StackingClassification', | |||
| ].map((name) => { | |||
| if (name === 'mlp') { | |||
| return { label: 'tablenet', value: name }; | |||
| } else { | |||
| return { label: name, value: name }; | |||
| } | |||
| }); | |||
| ].map((name) => ({ label: name, value: name })); | |||
| // 回归算法 | |||
| const regressorAlgorithms = [ | |||
| @@ -159,12 +159,13 @@ function ExperimentText() { | |||
| return; | |||
| } | |||
| const { finishedAt, phase, nodes = {} } = statusData; | |||
| // 更新实验实例状态和结束时间 | |||
| setExperimentIns((prev) => ({ | |||
| ...prev, | |||
| finish_time: finishedAt, | |||
| status: phase, | |||
| })); | |||
| // setExperimentIns((prev) => ({ | |||
| // ...prev, | |||
| // finish_time: finishedAt, | |||
| // status: phase, | |||
| // })); | |||
| // 设置总 workflow 状态 | |||
| const tempWorkflowStatus = Object.values(nodes).find((node) => | |||
| @@ -238,7 +238,7 @@ function CreateServiceVersion() { | |||
| }, | |||
| { | |||
| pattern: /^[a-zA-Z0-9._-]+$/, | |||
| message: '版本只支持字母、数字、点(.)、下划线(_)、中横线(-)', | |||
| message: '服务支持字母、数字、点(.)、下划线(_)、中横线(-)', | |||
| }, | |||
| ]} | |||
| > | |||
| @@ -1,10 +1,9 @@ | |||
| import KFIcon from '@/components/KFIcon'; | |||
| import { ExperimentStatus, experimentStatusInfo } from '@/pages/Experiment/status'; | |||
| import { ExperimentInstance } from '@/types'; | |||
| import { elapsedTime, formatDate } from '@/utils/date'; | |||
| import { useNavigate } from '@umijs/max'; | |||
| import { Button, Empty } from 'antd'; | |||
| import { Empty } from 'antd'; | |||
| import styles from './index.less'; | |||
| import ExperimentInstanceComponent from './instance'; | |||
| type ExperimentTableProps = { | |||
| tableData: ExperimentInstance[]; | |||
| style?: React.CSSProperties; | |||
| @@ -26,31 +25,11 @@ function ExperimentTable({ tableData = [], style }: ExperimentTableProps) { | |||
| </div> | |||
| {Array.isArray(tableData) && tableData.length > 0 ? ( | |||
| tableData.map((item) => ( | |||
| <div className={styles['experiment-table__content']} key={item.id}> | |||
| <div className={styles['experiment-table__status']} style={{ paddingLeft: '6.5px' }}> | |||
| <img | |||
| src={experimentStatusInfo[item.status as ExperimentStatus]?.icon} | |||
| width={17} | |||
| height={17} | |||
| draggable={false} | |||
| alt="" | |||
| /> | |||
| </div> | |||
| <div className={styles['experiment-table__duration']}> | |||
| {elapsedTime(item.create_time, item.finish_time)} | |||
| </div> | |||
| <div className={styles['experiment-table__date']}>{formatDate(item.create_time)}</div> | |||
| <div className={styles['experiment-table__operation']}> | |||
| <Button | |||
| size="small" | |||
| type="link" | |||
| icon={<KFIcon type="icon-xiangqing2" font={14} />} | |||
| onClick={() => gotoExperiment(item)} | |||
| > | |||
| 详情 | |||
| </Button> | |||
| </div> | |||
| </div> | |||
| <ExperimentInstanceComponent | |||
| instance={item} | |||
| key={item.id} | |||
| onClick={() => gotoExperiment(item)} | |||
| /> | |||
| )) | |||
| ) : ( | |||
| <Empty | |||
| @@ -0,0 +1,76 @@ | |||
| import KFIcon from '@/components/KFIcon'; | |||
| import RunDuration from '@/components/RunDuration'; | |||
| import { ExperimentStatus } from '@/enums'; | |||
| import { useSSE, type MessageHandler } from '@/hooks/useSSE'; | |||
| import { experimentStatusInfo } from '@/pages/Experiment/status'; | |||
| import { ExperimentInstance, NodeStatus } from '@/types'; | |||
| import { formatDate } from '@/utils/date'; | |||
| import { getExperimentInstanceStatus, getWorkflowStatus } from '@/utils/experiment'; | |||
| import { Button } from 'antd'; | |||
| import { useCallback, useState } from 'react'; | |||
| import styles from './index.less'; | |||
| const NodePrefix = 'workflow'; | |||
| type ExperimentInstanceComponentProps = { | |||
| instance: ExperimentInstance; | |||
| onClick: () => void; | |||
| }; | |||
| function ExperimentInstanceComponent({ instance, onClick }: ExperimentInstanceComponentProps) { | |||
| const { experiment_id, id, argo_ins_name, argo_ins_ns, nodes_status } = instance; | |||
| const initialWorkflowStatus = getWorkflowStatus(nodes_status) as NodeStatus | undefined; | |||
| const [workflowStatus, setWorkflowStatus] = useState<NodeStatus | undefined>( | |||
| initialWorkflowStatus, | |||
| ); | |||
| const status = getExperimentInstanceStatus(instance.status as ExperimentStatus, workflowStatus); | |||
| const createTime = workflowStatus?.startedAt; | |||
| const finishTime = workflowStatus?.finishedAt; | |||
| const statusInfo = experimentStatusInfo[status]; | |||
| const handleSSEMessage: MessageHandler = useCallback( | |||
| ( | |||
| _experimentId: number, | |||
| _experimentInsId: number, | |||
| _status: string, | |||
| _finishTime: string, | |||
| nodes, | |||
| ) => { | |||
| if (nodes) { | |||
| // 设置总 workflow 状态 | |||
| const workflowStatus = Object.values(nodes).find((node: any) => | |||
| node.displayName.startsWith(NodePrefix), | |||
| ) as NodeStatus; | |||
| if (workflowStatus) { | |||
| setWorkflowStatus(workflowStatus); | |||
| } | |||
| } | |||
| }, | |||
| [], | |||
| ); | |||
| useSSE(experiment_id, id, status, argo_ins_name, argo_ins_ns, handleSSEMessage); | |||
| return ( | |||
| <div className={styles['experiment-table__content']} key={id}> | |||
| <div className={styles['experiment-table__status']} style={{ paddingLeft: '6.5px' }}> | |||
| <img src={statusInfo?.icon} width={17} height={17} draggable={false} alt="" /> | |||
| </div> | |||
| <div className={styles['experiment-table__duration']}> | |||
| <RunDuration createTime={createTime} finishTime={finishTime} /> | |||
| </div> | |||
| <div className={styles['experiment-table__date']}>{formatDate(createTime)}</div> | |||
| <div className={styles['experiment-table__operation']}> | |||
| <Button | |||
| size="small" | |||
| type="link" | |||
| icon={<KFIcon type="icon-xiangqing2" font={14} />} | |||
| onClick={onClick} | |||
| > | |||
| 详情 | |||
| </Button> | |||
| </div> | |||
| </div> | |||
| ); | |||
| } | |||
| export default ExperimentInstanceComponent; | |||