mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-14 07:24:52 +09:00
Hide or disable controls in the web interface that the user for the control connection it's connected as don't have the requisite permissions to use.
103 lines
3.0 KiB
React
103 lines
3.0 KiB
React
import React, { useEffect, useContext, useRef, useState } from "react";
|
|
import { Typography } from "antd";
|
|
|
|
import { libLink } from "@clusterio/lib";
|
|
|
|
import { useAccount } from "../model/account";
|
|
import ControlContext from "./ControlContext";
|
|
|
|
const { Paragraph } = Typography;
|
|
|
|
|
|
function formatParsedOutput(parsed, key) {
|
|
let time = "";
|
|
if (parsed.format === "seconds") {
|
|
time = <span className="factorio-time">{parsed.time.padStart(8)} </span>;
|
|
} else if (parsed.format === "date") {
|
|
time = <span className="factorio-time">{parsed.time} </span>;
|
|
}
|
|
|
|
let info = "";
|
|
if (parsed.type === "log") {
|
|
let level = parsed.level;
|
|
if (level === "Script") {
|
|
level = <span className="factorio-script">{level}</span>;
|
|
} else if (level === "Verbose") {
|
|
level = <span className="factorio-verbose">{level}</span>;
|
|
} else if (level === "Info") {
|
|
level = <span className="factorio-info">{level}</span>;
|
|
} else if (parsed.level === "Warning") {
|
|
level = <span className="factorio-warning">{level}</span>;
|
|
} else if (parsed.level === "Error") {
|
|
level = <span className="factorio-error">{level}</span>;
|
|
}
|
|
|
|
info = <>{level} <span className="factorio-filename">{parsed.file}: </span></>;
|
|
|
|
} else if (parsed.type === "action") {
|
|
info = <>[<span className="factorio-action">{parsed.action}</span>] </>;
|
|
}
|
|
|
|
return <span key={key}>{time}{info}{parsed.message}<br/></span>;
|
|
}
|
|
|
|
function formatLog(info, key) {
|
|
if (info.level === "server" && info.parsed) {
|
|
return formatParsedOutput(info.parsed, key);
|
|
}
|
|
let level = <span className={`log-${info.level}`}>{info.level}</span>;
|
|
return <span key={key}>[{level}] {info.message}<br/></span>;
|
|
}
|
|
|
|
export default function InstanceConsole(props) {
|
|
let account = useAccount();
|
|
let control = useContext(ControlContext);
|
|
let anchor = useRef();
|
|
let [pastLines, setPastLines] = useState([<span key={0}>{"Loading past entries..."}<br/></span>]);
|
|
let [lines, setLines] = useState([]);
|
|
|
|
useEffect(() => {
|
|
// Scroll view to the anchor so it sticks to the bottom
|
|
let parent = anchor.current.parentElement;
|
|
parent.scrollTop = parent.scrollHeight - parent.clientHeight;
|
|
|
|
if (account.hasPermission("core.log.query")) {
|
|
libLink.messages.queryLog.send(control, {
|
|
all: false,
|
|
master: false,
|
|
slave_ids: [],
|
|
instance_ids: [props.id],
|
|
max_level: null,
|
|
limit: 400,
|
|
order: "desc",
|
|
}).then(result => {
|
|
setPastLines(result.log.map((info, index) => formatLog(info, index)).reverse());
|
|
}).catch(err => {
|
|
setPastLines([<span key={0}>{`Error loading log: ${err.message}`}<br/></span>]);
|
|
});
|
|
} else {
|
|
setPastLines([]);
|
|
}
|
|
|
|
function logHandler(info) {
|
|
setLines(currentLines => currentLines.concat(
|
|
[formatLog(info, currentLines.length)]
|
|
));
|
|
}
|
|
|
|
control.onInstanceLog(props.id, logHandler);
|
|
return () => {
|
|
control.offInstanceLog(props.id, logHandler);
|
|
};
|
|
}, [props.id]);
|
|
|
|
return <>
|
|
<Paragraph code className="instance-console">
|
|
{pastLines}
|
|
{lines}
|
|
<div className="scroll-anchor" ref={anchor} />
|
|
</Paragraph>
|
|
</>;
|
|
}
|
|
|