diff --git a/src/locales/en-US/models.ts b/src/locales/en-US/models.ts index 11a18927..9856dfce 100644 --- a/src/locales/en-US/models.ts +++ b/src/locales/en-US/models.ts @@ -284,5 +284,6 @@ export default { 'models.table.instanceView': 'Instance List', 'models.table.category': 'Category', 'models.instance.firstStart': 'First Deployment', + 'models.instance.lastStart': 'Last Startup', 'models.instance.startHistory': 'Startup History' }; diff --git a/src/locales/ja-JP/models.ts b/src/locales/ja-JP/models.ts index b498bfd3..9bdbfbf6 100644 --- a/src/locales/ja-JP/models.ts +++ b/src/locales/ja-JP/models.ts @@ -284,6 +284,7 @@ export default { 'models.table.instanceView': 'Instance List', 'models.table.category': 'Category', 'models.instance.firstStart': 'First Deployment', + 'models.instance.lastStart': 'Last Startup', 'models.instance.startHistory': 'Startup History' }; diff --git a/src/locales/ru-RU/models.ts b/src/locales/ru-RU/models.ts index fd160c0f..c42cddf2 100644 --- a/src/locales/ru-RU/models.ts +++ b/src/locales/ru-RU/models.ts @@ -288,6 +288,7 @@ export default { 'models.table.instanceView': 'Instance List', 'models.table.category': 'Category', 'models.instance.firstStart': 'First Deployment', + 'models.instance.lastStart': 'Last Startup', 'models.instance.startHistory': 'Startup History' }; diff --git a/src/locales/tr-TR/models.ts b/src/locales/tr-TR/models.ts index 28ac477f..5ed0a9cd 100644 --- a/src/locales/tr-TR/models.ts +++ b/src/locales/tr-TR/models.ts @@ -284,6 +284,7 @@ export default { 'models.table.instanceView': 'Instance List', 'models.table.category': 'Category', 'models.instance.firstStart': 'First Deployment', + 'models.instance.lastStart': 'Last Startup', 'models.instance.startHistory': 'Startup History' }; diff --git a/src/locales/zh-CN/models.ts b/src/locales/zh-CN/models.ts index a3ee6273..4447feb8 100644 --- a/src/locales/zh-CN/models.ts +++ b/src/locales/zh-CN/models.ts @@ -268,5 +268,6 @@ export default { 'models.table.instanceView': '实例列表', 'models.table.category': '类别', 'models.instance.firstStart': '首次部署', + 'models.instance.lastStart': '最近启动', 'models.instance.startHistory': '启动记录' }; diff --git a/src/pages/llmodels/components/view-logs-modal.tsx b/src/pages/llmodels/components/view-logs-modal.tsx index d8149324..c8fe4e65 100644 --- a/src/pages/llmodels/components/view-logs-modal.tsx +++ b/src/pages/llmodels/components/view-logs-modal.tsx @@ -1,8 +1,10 @@ import useSetChunkRequest from '@/hooks/use-chunk-request'; +import { formatOrdinal } from '@/utils'; import { CloseOutlined } from '@ant-design/icons'; import { BaseSelect, LogsViewer } from '@gpustack/core-ui'; import { useIntl } from '@umijs/max'; import { Button, Modal } from 'antd'; +import dayjs from 'dayjs'; import React, { useCallback, useEffect, useState } from 'react'; import { MODELS_API } from '../apis'; @@ -27,6 +29,7 @@ const ViewLogsModal: React.FC = (props) => { const [isDownloading, setIsDownloading] = useState( status === InstanceStatusMap.Downloading ); + const [record, setRecord] = useState(0); const [params, setParams] = useState({ follow: true }); @@ -95,6 +98,36 @@ const ViewLogsModal: React.FC = (props) => { worker_id: option.worker_id }); } + setRecord(value); + }; + + const renderLabel = (label: string, time: string) => { + return ( + + {label} + + {dayjs(time).format('YYYY-MM-DD HH:mm:ss')} + + + ); + }; + + const optionRender = (option: any) => { + const { data = {} } = option || {}; + let label = formatOrdinal(data.value); + if (data.value === 0) { + label = intl.formatMessage({ id: 'models.instance.firstStart' }); + } + if (data.isLast) { + label = intl.formatMessage({ id: 'models.instance.lastStart' }); + } + return renderLabel(label, data.start_at); + }; + + const labelRender = (option: any) => { + const data = countOptions.find((item) => item.value === option.value); + if (!data) return ''; + return optionRender({ data }); }; const renderTitle = () => { @@ -106,6 +139,7 @@ const ViewLogsModal: React.FC = (props) => { = (props) => { } options={countOptions} - labelRender={(option) => { - return ( - - {option?.label} - - ); - }} + labelRender={labelRender} + optionRender={optionRender} style={{ width: 400, marginRight: 16 @@ -159,7 +183,13 @@ const ViewLogsModal: React.FC = (props) => { url: `${MODELS_API}/${props.modelId}/instances`, handler: updateHandler }); - fetchData(props.id); + fetchData(props.id).then((list) => { + if (list.length === 1) { + setRecord(list[0].value); + } else if (list.length > 1) { + setRecord(list[1].value); + } + }); } else { cancelOnClose(); } diff --git a/src/pages/llmodels/config/types.ts b/src/pages/llmodels/config/types.ts index a4c68534..46230518 100644 --- a/src/pages/llmodels/config/types.ts +++ b/src/pages/llmodels/config/types.ts @@ -377,6 +377,12 @@ export interface DraftModelItem { } export interface InstanceRestartCount { - restart_counts: number[]; - workers: { id: number; name: string }[]; + workers: { + worker_id: number; + name: string; + restarts: { + restart_count: number; + started_at: string; + }[]; + }[]; } diff --git a/src/pages/llmodels/services/use-query-instance-restart-count.ts b/src/pages/llmodels/services/use-query-instance-restart-count.ts index ef48d6db..9cd7bca6 100644 --- a/src/pages/llmodels/services/use-query-instance-restart-count.ts +++ b/src/pages/llmodels/services/use-query-instance-restart-count.ts @@ -1,5 +1,4 @@ import { useQueryData } from '@/hooks/use-query-data-list'; -import { formatOrdinal } from '@/utils'; import { useIntl } from '@umijs/max'; import { useState } from 'react'; import { queryModelInstanceRestartCount } from '../apis'; @@ -14,24 +13,25 @@ export default function useQueryModelInstanceRestartCount() { const intl = useIntl(); const [dataList, setDataList] = useState< - { value: number; label: number | string; worker_id: number }[] + { value: number; label: React.ReactNode; worker_id: number }[] >([]); const fetchRestartCount = async (instance_id: number) => { const res = await fetchData(instance_id); - const workerId = res?.workers?.[0]?.id || 0; + const workerId = res?.workers?.[0]?.worker_id || 0; + const workerItem = res?.workers?.[0]; const dataList = - res?.restart_counts?.map((count, index) => { + workerItem?.restarts?.map((restart, index) => { return { - value: count, - label: - count === 0 - ? intl.formatMessage({ id: 'models.instance.firstStart' }) - : formatOrdinal(count), - worker_id: workerId + value: restart.restart_count, + label: restart.restart_count, + start_at: restart.started_at, + worker_id: workerId, + isLast: index === 1 }; }) || []; setDataList(dataList); + return dataList; }; return { countOptions: dataList,