| @@ -17,7 +17,6 @@ import styles from './index.less'; | |||
| export type LogGroupProps = ExperimentLog & { | |||
| status?: ExperimentStatus; // 实验状态 | |||
| listId: string; | |||
| }; | |||
| type Log = { | |||
| @@ -32,7 +31,6 @@ function LogGroup({ | |||
| log_content = '', | |||
| start_time, | |||
| status, | |||
| listId, | |||
| }: LogGroupProps) { | |||
| const [collapse, setCollapse] = useState(true); | |||
| const [logList, setLogList, logListRef] = useStateRef<Log[]>([]); | |||
| @@ -42,6 +40,7 @@ function LogGroup({ | |||
| const preStatusRef = useRef<ExperimentStatus | undefined>(undefined); | |||
| const socketRef = useRef<WebSocket | undefined>(undefined); | |||
| const retryRef = useRef(2); // 等待 2 秒,重试 3 次 | |||
| const elementRef = useRef<HTMLDivElement | null>(null); | |||
| useEffect(() => { | |||
| scrollToBottom(false); | |||
| @@ -124,7 +123,7 @@ function LogGroup({ | |||
| const setupSockect = () => { | |||
| let { host } = location; | |||
| if (process.env.NODE_ENV === 'development') { | |||
| host = '172.20.32.181:31213'; | |||
| host = '172.20.32.197:31213'; | |||
| } | |||
| const socket = new WebSocket( | |||
| `ws://${host}/newlog/realtimeLog?start=${start_time}&query={pod="${pod_name}"}`, | |||
| @@ -150,7 +149,7 @@ function LogGroup({ | |||
| }); | |||
| socket.addEventListener('message', (event) => { | |||
| console.log('message received.', event); | |||
| // console.log('message received.', event); | |||
| if (!event.data) { | |||
| return; | |||
| } | |||
| @@ -201,15 +200,15 @@ function LogGroup({ | |||
| // 滚动到底部 | |||
| const scrollToBottom = (smooth: boolean = true) => { | |||
| const element = document.getElementById(listId); | |||
| if (element) { | |||
| const optons: ScrollToOptions = { | |||
| top: element.scrollHeight, | |||
| behavior: smooth ? 'smooth' : 'instant', | |||
| }; | |||
| element.scrollTo(optons); | |||
| } | |||
| // const element = document.getElementById(listId); | |||
| // if (element) { | |||
| // const optons: ScrollToOptions = { | |||
| // top: element.scrollHeight, | |||
| // behavior: smooth ? 'smooth' : 'instant', | |||
| // }; | |||
| // element.scrollTo(optons); | |||
| // } | |||
| elementRef?.current?.scrollIntoView({ block: 'end', behavior: smooth ? 'smooth' : 'instant' }); | |||
| }; | |||
| const showLog = (log_type === 'resource' && !collapse) || log_type === 'normal'; | |||
| @@ -217,7 +216,7 @@ function LogGroup({ | |||
| const showMoreBtn = | |||
| status !== ExperimentStatus.Running && showLog && !completed && logText !== ''; | |||
| return ( | |||
| <div className={styles['log-group']}> | |||
| <div className={styles['log-group']} ref={elementRef}> | |||
| {log_type === 'resource' && ( | |||
| <div className={styles['log-group__pod']} onClick={handleCollapse}> | |||
| <div className={styles['log-group__pod__name']}>{pod_name}</div> | |||
| @@ -1,8 +1,9 @@ | |||
| import { ExperimentStatus } from '@/enums'; | |||
| import { getQueryByExperimentLog } from '@/services/experiment/index.js'; | |||
| import { to } from '@/utils/promise'; | |||
| import classNames from 'classnames'; | |||
| import dayjs from 'dayjs'; | |||
| import { useEffect, useRef, useState } from 'react'; | |||
| import React, { useEffect, useRef, useState } from 'react'; | |||
| import LogGroup from '../LogGroup'; | |||
| import styles from './index.less'; | |||
| @@ -14,23 +15,25 @@ export type ExperimentLog = { | |||
| }; | |||
| type LogListProps = { | |||
| idPrefix?: string; // 当一个页面有多个日志组件时,使用这个变量作为唯一性标识 | |||
| instanceName: string; // 实验实例 name | |||
| instanceNamespace: string; // 实验实例 namespace | |||
| pipelineNodeId: string; // 流水线节点 id | |||
| workflowId?: string; // 实验实例工作流 id | |||
| instanceNodeStartTime?: string; // 实验实例节点开始运行时间 | |||
| instanceNodeStatus?: ExperimentStatus; | |||
| className?: string; | |||
| style?: React.CSSProperties; | |||
| }; | |||
| function LogList({ | |||
| idPrefix, | |||
| instanceName, | |||
| instanceNamespace, | |||
| pipelineNodeId, | |||
| workflowId, | |||
| instanceNodeStartTime, | |||
| instanceNodeStatus, | |||
| className, | |||
| style, | |||
| }: LogListProps) { | |||
| const [logList, setLogList] = useState<ExperimentLog[]>([]); | |||
| const preStatusRef = useRef<ExperimentStatus | undefined>(undefined); | |||
| @@ -88,15 +91,10 @@ function LogList({ | |||
| } | |||
| }; | |||
| // 当一个页面有多个日志组件时,使用这个变量作为唯一性标识 | |||
| const listId = idPrefix ? `${idPrefix}-log-list` : 'log-list'; | |||
| return ( | |||
| <div className={styles['log-list']} id={listId}> | |||
| <div className={classNames(styles['log-list'], className)} id="log-list" style={style}> | |||
| {logList.length > 0 ? ( | |||
| logList.map((v) => ( | |||
| <LogGroup key={v.pod_name} {...v} listId={listId} status={instanceNodeStatus} /> | |||
| )) | |||
| logList.map((v) => <LogGroup key={v.pod_name} {...v} status={instanceNodeStatus} />) | |||
| ) : ( | |||
| <div className={styles['log-list__empty']}>暂无日志</div> | |||
| )} | |||
| @@ -38,8 +38,7 @@ | |||
| .cell-index { | |||
| position: relative; | |||
| width: 100%; | |||
| padding-left: 20px; | |||
| text-align: left; | |||
| white-space: nowrap; | |||
| &__best-tag { | |||
| margin-left: 8px; | |||
| @@ -47,8 +46,8 @@ | |||
| color: @success-color; | |||
| font-weight: normal; | |||
| font-size: 13px; | |||
| white-space: nowrap; | |||
| background-color: .addAlpha(@success-color, 0.1) []; | |||
| // border: 1px solid .addAlpha(@success-color, 0.5) []; | |||
| border-radius: 2px; | |||
| } | |||
| } | |||
| @@ -32,8 +32,7 @@ function ExperimentHistory({ trialList = [] }: ExperimentHistoryProps) { | |||
| title: '序号', | |||
| dataIndex: 'index', | |||
| key: 'index', | |||
| width: 120, | |||
| align: 'center', | |||
| width: 110, | |||
| render: (_text, record, index: number) => { | |||
| return ( | |||
| <div className={styles['cell-index']}> | |||
| @@ -46,7 +46,6 @@ function ExperimentLog({ instanceInfo, nodes }: ExperimentLogProps) { | |||
| <div className={styles['experiment-log__tabs__log']}> | |||
| {frameworkCloneNodeStatus && ( | |||
| <LogList | |||
| idPrefix="git-clone-framework" | |||
| instanceName={instanceInfo.argo_ins_name} | |||
| instanceNamespace={instanceInfo.argo_ins_ns} | |||
| pipelineNodeId={frameworkCloneNodeStatus.displayName} | |||
| @@ -66,7 +65,6 @@ function ExperimentLog({ instanceInfo, nodes }: ExperimentLogProps) { | |||
| <div className={styles['experiment-log__tabs__log']}> | |||
| {trainCloneNodeStatus && ( | |||
| <LogList | |||
| idPrefix="git-clone-train" | |||
| instanceName={instanceInfo.argo_ins_name} | |||
| instanceNamespace={instanceInfo.argo_ins_ns} | |||
| pipelineNodeId={trainCloneNodeStatus.displayName} | |||
| @@ -86,7 +84,6 @@ function ExperimentLog({ instanceInfo, nodes }: ExperimentLogProps) { | |||
| <div className={styles['experiment-log__tabs__log']}> | |||
| {hpoNodeStatus && ( | |||
| <LogList | |||
| idPrefix="auto-hpo" | |||
| instanceName={instanceInfo.argo_ins_name} | |||
| instanceNamespace={instanceInfo.argo_ins_ns} | |||
| pipelineNodeId={hpoNodeStatus.displayName} | |||
| @@ -211,20 +211,20 @@ function Component() { | |||
| 说明你需要拆分组件了 | |||
| ```tsx | |||
| function Component1() { | |||
| function Component() { | |||
| return ( | |||
| <div className="component1"> | |||
| <div className="component1__element1"> | |||
| <div className="component"> | |||
| <div className="component__element1"> | |||
| <Component1></Component1> | |||
| </div> | |||
| </div> | |||
| ) | |||
| } | |||
| function Component() { | |||
| function SubComponent() { | |||
| return ( | |||
| <div className="component"> | |||
| <div className="component__element1"> | |||
| <Component1></Component1> | |||
| <div className="sub-component"> | |||
| <div className="sub-component__element1"> | |||
| </div> | |||
| </div> | |||
| ) | |||