Files
NapCatQQ/napcat.webui/src/components/log_com/history.tsx
时瑾 06f6a542f5 refactor: 优化eslint配置,提升代码质量 (#1341)
* feat: 统一并标准化eslint

* lint: napcat.webui

* lint: napcat.webui

* lint: napcat.core

* build: fix

* lint: napcat.webui

* refactor: 重构eslint

* Update README.md
2025-11-03 16:30:45 +08:00

137 lines
3.7 KiB
TypeScript

import { Button } from '@heroui/button';
import { Card, CardBody, CardHeader } from '@heroui/card';
import { Select, SelectItem } from '@heroui/select';
import type { Selection } from '@react-types/shared';
import { useEffect, useRef, useState } from 'react';
import { colorizeLogLevel } from '@/utils/terminal';
import PageLoading from '../page_loading';
import XTerm from '../xterm';
import type { XTermRef } from '../xterm';
import LogLevelSelect from './log_level_select';
export interface HistoryLogsProps {
list: string[]
onSelect: (name: string) => void
selectedLog?: string
refreshList: () => void
refreshLog: () => void
listLoading?: boolean
logLoading?: boolean
listError?: Error
logContent?: string
}
const HistoryLogs: React.FC<HistoryLogsProps> = (props) => {
const {
list,
onSelect,
selectedLog,
refreshList,
refreshLog,
listLoading,
logContent,
listError,
logLoading,
} = props;
const Xterm = useRef<XTermRef>(null);
const [logLevel, setLogLevel] = useState<Selection>(
new Set(['info', 'warn', 'error'])
);
const logToColored = (log: string) => {
const logs = log
.split('\n')
.map((line) => {
const colored = colorizeLogLevel(line);
return colored;
})
.filter((log) => {
if (logLevel === 'all') {
return true;
}
return logLevel.has(log.level);
})
.map((log) => log.content)
.join('\r\n');
return logs;
};
const onDownloadLog = () => {
if (!logContent) {
return;
}
const blob = new Blob([logContent], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `${selectedLog}.log`;
a.click();
URL.revokeObjectURL(url);
};
useEffect(() => {
if (!Xterm.current || !logContent) {
return;
}
Xterm.current.clear();
const _logContent = logToColored(logContent);
Xterm.current.write(_logContent + '\r\nnapcat@webui:~$ ');
}, [logContent, logLevel]);
return (
<>
<title> - NapCat WebUI</title>
<Card className='max-w-full h-full bg-opacity-50 backdrop-blur-sm'>
<CardHeader className='flex-row justify-start gap-3'>
<Select
label='选择日志'
size='sm'
isLoading={listLoading}
errorMessage={listError?.message}
classNames={{
trigger:
'hover:!bg-content3 bg-opacity-50 backdrop-blur-sm hover:!bg-opacity-60',
}}
placeholder='选择日志'
onChange={(e) => {
const value = e.target.value;
if (!value) {
return;
}
onSelect(value);
}}
selectedKeys={[selectedLog || '']}
items={list.map((name) => ({
value: name,
label: name,
}))}
>
{(item) => (
<SelectItem key={item.value} value={item.value}>
{item.label}
</SelectItem>
)}
</Select>
<LogLevelSelect
selectedKeys={logLevel}
onSelectionChange={setLogLevel}
/>
<Button className='flex-shrink-0' onPress={onDownloadLog}>
</Button>
<Button onPress={refreshList}></Button>
<Button onPress={refreshLog}></Button>
</CardHeader>
<CardBody className='relative'>
<PageLoading loading={logLoading} />
<XTerm className='w-full h-full' ref={Xterm} />
</CardBody>
</Card>
</>
);
};
export default HistoryLogs;