chore: download log display
This commit is contained in:
@@ -2,8 +2,8 @@ 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 hasAnsi from 'has-ansi';
|
||||
import { memo, useEffect, useRef, useState } from 'react';
|
||||
import _ from 'lodash';
|
||||
import { memo, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import './index.less';
|
||||
|
||||
interface LogsViewerProps {
|
||||
@@ -15,7 +15,7 @@ interface LogsViewerProps {
|
||||
const LogsViewer: React.FC<LogsViewerProps> = (props) => {
|
||||
const { height, content, url } = props;
|
||||
const [nowrap, setNowrap] = useState(false);
|
||||
const [logsContent, setLogsContent] = useState(content || '');
|
||||
const [logsContent, setLogsContent] = useState<string[]>([]);
|
||||
const { setChunkRequest } = useSetChunkRequest();
|
||||
const chunkRequedtRef = useRef<any>(null);
|
||||
const scroller = useRef<any>(null);
|
||||
@@ -24,19 +24,50 @@ const LogsViewer: React.FC<LogsViewerProps> = (props) => {
|
||||
{ toBottom: true }
|
||||
);
|
||||
|
||||
const convert = new Convert();
|
||||
const convert = new Convert({
|
||||
newline: true,
|
||||
escapeXML: true
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
updateScrollerPosition();
|
||||
}, [logsContent]);
|
||||
|
||||
const getTrailingACount = useCallback((str: string) => {
|
||||
const match = str.match(/A+$/);
|
||||
return match ? match[0].length : 0;
|
||||
}, []);
|
||||
const parseHtmlStr = useCallback((htmlStr: string) => {
|
||||
const result: string[] = [];
|
||||
const htmlStrArr = _.filter(
|
||||
htmlStr?.split?.('<br/>'),
|
||||
(item: string) => item
|
||||
);
|
||||
|
||||
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);
|
||||
} else {
|
||||
result.push(item);
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}, []);
|
||||
|
||||
const updateContent = (newVal: string) => {
|
||||
if (hasAnsi(newVal)) {
|
||||
const htmlStr = `${convert.toHtml(newVal)}`;
|
||||
setLogsContent(htmlStr);
|
||||
} else {
|
||||
setLogsContent(newVal);
|
||||
}
|
||||
const htmlStr = `${convert.toHtml(newVal)}`;
|
||||
const list = parseHtmlStr(htmlStr);
|
||||
setLogsContent(list);
|
||||
};
|
||||
|
||||
const createChunkConnection = async () => {
|
||||
@@ -68,7 +99,13 @@ const LogsViewer: React.FC<LogsViewerProps> = (props) => {
|
||||
onWheel={handleContentWheel}
|
||||
>
|
||||
<div className={classNames('content', { 'line-break': nowrap })}>
|
||||
<div className="text">{logsContent}</div>
|
||||
<div className="text">
|
||||
{logsContent.map((item, index) => {
|
||||
return (
|
||||
<div key={index} dangerouslySetInnerHTML={{ __html: item }} />
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user