在准备环境前提交次全部更改。
This commit is contained in:
79
apps/admin-web/src/components/LogStream.tsx
Normal file
79
apps/admin-web/src/components/LogStream.tsx
Normal file
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* 日志流展示组件。
|
||||
*
|
||||
* - 等宽字体展示日志行
|
||||
* - 自动滚动到底部(useRef + scrollIntoView)
|
||||
* - 提供"暂停自动滚动"按钮(toggle)
|
||||
*/
|
||||
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { Button } from "antd";
|
||||
import { PauseCircleOutlined, PlayCircleOutlined } from "@ant-design/icons";
|
||||
|
||||
export interface LogStreamProps {
|
||||
/** 可选的执行 ID,用于标题展示 */
|
||||
executionId?: string;
|
||||
/** 日志行数组 */
|
||||
lines: string[];
|
||||
}
|
||||
|
||||
const LogStream: React.FC<LogStreamProps> = ({ lines }) => {
|
||||
const [autoscroll, setAutoscroll] = useState(true);
|
||||
const bottomRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (autoscroll && bottomRef.current) {
|
||||
bottomRef.current.scrollIntoView({ behavior: "smooth" });
|
||||
}
|
||||
}, [lines, autoscroll]);
|
||||
|
||||
const handleToggle = () => {
|
||||
const next = !autoscroll;
|
||||
setAutoscroll(next);
|
||||
// 恢复时立即滚动到底部
|
||||
if (next && bottomRef.current) {
|
||||
bottomRef.current.scrollIntoView({ behavior: "smooth" });
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ display: "flex", flexDirection: "column", height: "100%" }}>
|
||||
<div style={{ marginBottom: 8, textAlign: "right" }}>
|
||||
<Button
|
||||
size="small"
|
||||
icon={autoscroll ? <PauseCircleOutlined /> : <PlayCircleOutlined />}
|
||||
onClick={handleToggle}
|
||||
>
|
||||
{autoscroll ? "暂停滚动" : "恢复滚动"}
|
||||
</Button>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
flex: 1,
|
||||
overflow: "auto",
|
||||
background: "#1e1e1e",
|
||||
color: "#d4d4d4",
|
||||
fontFamily: "'Cascadia Code', 'Fira Code', 'Consolas', monospace",
|
||||
fontSize: 13,
|
||||
lineHeight: 1.6,
|
||||
padding: 12,
|
||||
borderRadius: 4,
|
||||
minHeight: 300,
|
||||
}}
|
||||
>
|
||||
{lines.length === 0 ? (
|
||||
<div style={{ color: "#888" }}>暂无日志</div>
|
||||
) : (
|
||||
lines.map((line, i) => (
|
||||
<div key={i} style={{ whiteSpace: "pre-wrap", wordBreak: "break-all" }}>
|
||||
{line}
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
<div ref={bottomRef} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LogStream;
|
||||
Reference in New Issue
Block a user