diff --git a/src/components/label-selector/index.tsx b/src/components/label-selector/index.tsx index e63eeafd..7407d905 100644 --- a/src/components/label-selector/index.tsx +++ b/src/components/label-selector/index.tsx @@ -5,6 +5,7 @@ import Inner from './inner'; interface LabelSelectorProps { labels: Record; label?: string; + btnText?: string; description?: React.ReactNode; onChange?: (labels: Record) => void; } @@ -13,6 +14,7 @@ const LabelSelector: React.FC = ({ labels, onChange, label, + btnText, description }) => { const [labelsData, setLabelsData] = useState({}); @@ -48,6 +50,7 @@ const LabelSelector: React.FC = ({ return ( ; label?: string; + btnText?: string; labelList: Array<{ key: string; value: string }>; onLabelListChange: (list: { key: string; value: string }[]) => void; onChange?: (labels: Record) => void; @@ -20,6 +21,7 @@ const Inner: React.FC = ({ onChange, onLabelListChange, label, + btnText, description }) => { const intl = useIntl(); @@ -97,7 +99,7 @@ const Inner: React.FC = ({ > {' '} {intl.formatMessage({ - id: 'common.button.addSelector' + id: btnText || 'common.button.addSelector' })} diff --git a/src/components/logs-viewer/index.tsx b/src/components/logs-viewer/index.tsx index 544591a9..9f1f7fc4 100644 --- a/src/components/logs-viewer/index.tsx +++ b/src/components/logs-viewer/index.tsx @@ -2,7 +2,6 @@ import useSetChunkRequest from '@/hooks/use-chunk-request'; import useContainerScroll from '@/hooks/use-container-scorll'; import Convert from 'ansi-to-html'; import classNames from 'classnames'; -import _ from 'lodash'; import { memo, useCallback, useEffect, useRef, useState } from 'react'; import './index.less'; @@ -26,47 +25,59 @@ const LogsViewer: React.FC = (props) => { const convert = new Convert({ newline: true, - escapeXML: true + escapeXML: true, + stream: false }); useEffect(() => { updateScrollerPosition(); }, [logsContent]); - const getTrailingACount = useCallback((str: string) => { - const match = str.match(/A+$/); - return match ? match[0].length : 0; + const endsWithAnsiEscapeSequence = useCallback((str: string) => { + const ansiEscapeRegex = /\x1B\[[0-9;]*[A-Za-z]$/; + return ansiEscapeRegex.test(str); }, []); - const parseHtmlStr = useCallback((htmlStr: string) => { - const result: string[] = []; - const htmlStrArr = _.filter( - htmlStr?.split?.('
'), - (item: string) => item - ); + const getCursorUpLines = useCallback((str: string) => { + const match = str.match(/\x1B\[(\d*)A$/); - htmlStrArr.forEach((item: string, index: number) => { - const aCount = getTrailingACount(item); - if (aCount > 0) { - console.log('aCount========', { - htmlStrArr, - aCount, - item, - length: result.length, - result: [...result] - }); - const placeIndex = result.length - aCount; - result[placeIndex] = item.slice(0, -aCount); + if (match) { + return match[1] === '' ? 1 : parseInt(match[1], 10); + } else { + return null; + } + }, []); + + const parseHtmlStr = useCallback((logStr: string) => { + const result: string[] = []; + const lines = logStr?.split?.('\n'); + + lines.forEach((line: string, index: number) => { + const upCount = getCursorUpLines(line); + if (endsWithAnsiEscapeSequence(line)) { + if (upCount) { + const placeIndex = result.length - upCount; + result[placeIndex] = line; + } else { + result.push(line); + } } else { - result.push(item); + if (line.includes('\r')) { + const parts = line.split('\r'); + const lastLine = parts[parts.length - 1]; + result.push(lastLine); + } else { + result.push(line); + } } }); - return result; + return result.map((item) => { + return convert.toHtml(item); + }); }, []); const updateContent = (newVal: string) => { - const htmlStr = `${convert.toHtml(newVal)}`; - const list = parseHtmlStr(htmlStr); + const list = parseHtmlStr(newVal); setLogsContent(list); }; diff --git a/src/components/logs-viewer/text.ts b/src/components/logs-viewer/text.ts deleted file mode 100644 index 61324208..00000000 --- a/src/components/logs-viewer/text.ts +++ /dev/null @@ -1,56 +0,0 @@ -export const text = `reflection-llama-3.1-70b -Hugging Face / Reflection-Llama-3.1-70B.Q6_K*.gguf -0 / 1 -2024-09-10 17:42:25 -reflection-llama-3.1-70b-2cDWS -0.42% -2024-09-10 17:42:25 - -gemma2-27b -Ollama Library / gemma2:27b -0 / 1 -2024-09-10 16:54:13 -gemma2-27b-m37dz -58.98% -2024-09-10 16:54:13 - -查看日志 -2024-09-10T17:42:27+08:00 - gpustack.worker.downloaders - INFO - Downloading model leafspark/Reflection-Llama-3.1-70B-GGUF/Reflection-Llama-3.1-70B.Q6_K*.gguf - -Fetching 2 files: 0%| | 0/2 [00:00 = (props) => { id: 'resources.table.labels' })} labels={labels} + btnText="common.button.addLabel" onChange={handleLabelsChange} > diff --git a/src/pages/resources/components/workers.tsx b/src/pages/resources/components/workers.tsx index d7322d55..c240321d 100644 --- a/src/pages/resources/components/workers.tsx +++ b/src/pages/resources/components/workers.tsx @@ -29,7 +29,7 @@ const { Column } = Table; const ActionList = [ { - label: 'resources.button.edittags', + label: 'common.button.edit', key: 'edit', icon: },