diff --git a/src/pages/llmodels/components/view-logs-modal.tsx b/src/pages/llmodels/components/view-logs-modal.tsx index 5d044dca..4da69827 100644 --- a/src/pages/llmodels/components/view-logs-modal.tsx +++ b/src/pages/llmodels/components/view-logs-modal.tsx @@ -1,13 +1,11 @@ import useSetChunkRequest from '@/hooks/use-chunk-request'; import { CloseOutlined, QuestionCircleOutlined } from '@ant-design/icons'; -import { LogsViewer } from '@gpustack/core-ui'; +import { BaseSelect, LogsViewer } from '@gpustack/core-ui'; import { useIntl } from '@umijs/max'; -import { Button, Modal, Tooltip } from 'antd'; -import dayjs from 'dayjs'; -import React, { useCallback, useEffect, useState } from 'react'; +import { Button, Checkbox, Modal, Tooltip } from 'antd'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { MODELS_API } from '../apis'; -import SealCascader from '@/components/seal-form/seal-cascader'; import { InstanceRealtimeLogStatus, InstanceStatusMap } from '../config'; import useQueryModelInstanceRestartCount from '../services/use-query-instance-restart-count'; @@ -29,16 +27,24 @@ const ViewLogsModal: React.FC = (props) => { const [isDownloading, setIsDownloading] = useState( status === InstanceStatusMap.Downloading ); - const [record, setRecord] = useState([]); + const [selectedWorkerID, setSelectedWorkerID] = useState(null); const [params, setParams] = useState({ follow: true }); + const [showPrevious, setShowPrevious] = useState(false); const logsViewerRef = React.useRef(null); const { countOptions, fetchData, cancelRequest } = useQueryModelInstanceRestartCount(); const requestRef = React.useRef(null); const contentRef = React.useRef(null); + const currentWorkerCountList = useMemo(() => { + return ( + countOptions?.find((option) => option.worker_id === selectedWorkerID) + ?.children || [] + ); + }, [countOptions, selectedWorkerID]); + const handleCancel = useCallback(() => { logsViewerRef.current?.abort(); onCancel(); @@ -82,10 +88,12 @@ const ViewLogsModal: React.FC = (props) => { const cancelOnClose = () => { logsViewerRef.current?.abort(); requestRef.current?.current?.cancel?.(); + setSelectedWorkerID(null); + setShowPrevious(false); cancelRequest(); }; - const handleOnChange = (value: number[], option: any) => { + const handleOnChange = (option: any) => { if (!option) { setParams({ follow: true @@ -93,76 +101,39 @@ const ViewLogsModal: React.FC = (props) => { } else { setParams({ follow: true, - watch: false, - restart_count: option.value, + watch: !option.previous, + previous: option.previous, worker_id: option.worker_id }); } - setRecord(value); + setSelectedWorkerID(option?.worker_id || null); }; - const renderLabel = (label: string, time: string) => { - return ( - - {label} - - {dayjs(time).format('YYYY-MM-DD HH:mm:ss')} - - - ); - }; - - const optionRender = (option: any) => { - const { data = {} } = option || {}; - if (data.isParent) { - return {data.label}; + const handleWorkerChange = (value: number, option: any) => { + setSelectedWorkerID(value); + setShowPrevious(false); + const counts = option?.children || []; + const lastItem = counts.find((item: any) => !item.previous); + if (lastItem) { + handleOnChange(lastItem); } - return renderLabel(data.label, data.start_at); - }; - - const handleOnCountChange = (value: any[], selectedOptions: any[]) => { - const option = selectedOptions?.[1]; - handleOnChange(value, option); }; const showCascader = countOptions?.some((option) => option.children!?.length >= 2) || countOptions?.length > 1; - const renderPrefix = () => { - return ( - - {intl.formatMessage({ id: 'models.instance.startHistory' })} - - - {intl.formatMessage({ - id: 'models.instance.previousRun' - })} - : - - {intl.formatMessage({ - id: 'models.instance.startHistory.tips' - })} - - } - > - - - + const handleOnChecked = (e: any) => { + const checked = e.target.checked; + const selectItem = currentWorkerCountList.find( + (item) => item.previous === checked ); + setShowPrevious(checked); + handleOnChange(selectItem); + }; + + const labelRender = (option: any) => { + return {option.label}; }; const renderTitle = () => { @@ -173,28 +144,63 @@ const ViewLogsModal: React.FC = (props) => { {showCascader && ( - triggerNode.parentNode} - optionNode={optionRender} - onChange={handleOnCountChange} - > + > + {currentWorkerCountList.length > 1 && ( + + + + {intl.formatMessage({ + id: 'models.instance.previousRun' + })} + : + + {intl.formatMessage({ + id: 'models.instance.startHistory.tips' + })} + + } + > + + {intl.formatMessage({ + id: 'models.instance.previousRun' + })} + + + + + )} + + {intl.formatMessage({ id: 'resources.worker' })} + + } + options={countOptions} + value={selectedWorkerID || undefined} + labelRender={labelRender} + onChange={handleWorkerChange} + style={{ width: 300 }} + > + )} +