Files
stash/ui/v2.5/src/components/Settings/SettingsLogsPanel.tsx
Infinite c31205c47f Linting
2020-03-01 21:04:31 +01:00

122 lines
3.3 KiB
TypeScript

import React, { useState } from "react";
import { Form, Col } from 'react-bootstrap';
import * as GQL from "src/core/generated-graphql";
import { StashService } from "src/core/StashService";
function convertTime(logEntry: GQL.LogEntryDataFragment) {
function pad(val : number) {
var ret = val.toString();
if (val <= 9) {
ret = "0" + ret;
}
return ret;
}
var date = new Date(logEntry.time);
var month = date.getMonth() + 1;
var day = date.getDate();
var dateStr = date.getFullYear() + "-" + pad(month) + "-" + pad(day);
dateStr += " " + pad(date.getHours()) + ":" + pad(date.getMinutes()) + ":" + pad(date.getSeconds());
return dateStr;
}
function levelClass(level : string) {
return level.toLowerCase().trim();
}
interface ILogElementProps {
logEntry : LogEntry
}
const LogElement: React.FC<ILogElementProps> = ({ logEntry }) => {
// pad to maximum length of level enum
var level = logEntry.level.padEnd(GQL.LogLevel.Progress.length);
return (
<>
<span>{logEntry.time}</span>&nbsp;
<span className={levelClass(logEntry.level)}>{level}</span>&nbsp;
<span>{logEntry.message}</span>
<br/>
</>
);
}
class LogEntry {
public time: string;
public level: string;
public message: string;
public id: string;
private static nextId: number = 0;
public constructor(logEntry: GQL.LogEntryDataFragment) {
this.time = convertTime(logEntry);
this.level = logEntry.level;
this.message = logEntry.message;
var id = LogEntry.nextId++;
this.id = id.toString();
}
}
// maximum number of log entries to display. Subsequent entries will truncate
// the list, dropping off the oldest entries first.
const MAX_LOG_ENTRIES = 200;
const logLevels = ["Debug", "Info", "Warning", "Error"];
export const SettingsLogsPanel: React.FC = () => {
const { data, error } = StashService.useLoggingSubscribe();
const { data: existingData } = StashService.useLogs();
const [logLevel, setLogLevel] = useState<string>("Info");
const oldData = (existingData?.logs ?? []).map(e => new LogEntry(e));
const newData = (data?.loggingSubscribe ?? []).map(e => new LogEntry(e));
const filteredLogEntries = [...newData.reverse(), ...oldData]
.filter(filterByLogLevel).slice(0, MAX_LOG_ENTRIES);
const maybeRenderError = error
? <div className={"error"}>Error connecting to log server: {error.message}</div>
: '';
function filterByLogLevel(logEntry : LogEntry) {
if (logLevel === "Debug")
return true;
var logLevelIndex = logLevels.indexOf(logLevel);
var levelIndex = logLevels.indexOf(logEntry.level);
return levelIndex >= logLevelIndex;
}
return (
<>
<h4>Logs</h4>
<Form.Row id="log-level">
<Col xs={1}>
<Form.Label>Log Level</Form.Label>
</Col>
<Col xs={2}>
<Form.Control
as="select"
defaultValue={logLevel}
onChange={(event) => setLogLevel(event.currentTarget.value)}
>
{ logLevels.map(level => (<option key={level} value={level}>{level}</option>)) }
</Form.Control>
</Col>
</Form.Row>
<div className="logs">
{maybeRenderError}
{filteredLogEntries.map((logEntry) =>
<LogElement logEntry={logEntry} key={logEntry.id}/>
)}
</div>
</>
);
};