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