2017-07-04 07:20:51 -06:00
|
|
|
import * as React from "react";
|
2017-07-07 10:50:52 -06:00
|
|
|
import { Collapse } from "@blueprintjs/core";
|
|
|
|
import { Markdown } from "../ui/index";
|
|
|
|
import { TickerListProps } from "./interfaces";
|
2017-11-07 18:16:38 -07:00
|
|
|
import { formatLogTime } from "../logs/index";
|
2018-08-30 19:25:58 -06:00
|
|
|
import { safeNumericSetting } from "../session";
|
2018-04-02 09:23:09 -06:00
|
|
|
import { ErrorBoundary } from "../error_boundary";
|
2018-08-01 18:20:50 -06:00
|
|
|
import { ALLOWED_MESSAGE_TYPES, TaggedLog, SpecialStatus } from "farmbot";
|
2018-05-17 14:12:33 -06:00
|
|
|
import { filterByVerbosity } from "../logs/components/logs_table";
|
|
|
|
import { isNumber } from "lodash";
|
2018-08-30 19:25:58 -06:00
|
|
|
import { GetWebAppConfigValue } from "../config_storage/actions";
|
2018-09-14 06:39:37 -06:00
|
|
|
import { Link } from "../link";
|
2019-02-26 20:12:02 -07:00
|
|
|
import { MessageType } from "../sequences/interfaces";
|
2019-04-02 13:59:37 -06:00
|
|
|
import { t } from "../i18next_wrapper";
|
2019-04-09 23:17:03 -06:00
|
|
|
import { TimeSettings } from "../interfaces";
|
2017-12-11 04:50:41 -07:00
|
|
|
|
2018-05-17 14:12:33 -06:00
|
|
|
/** Get current verbosity filter level for a message type from WebAppConfig. */
|
2018-08-30 19:25:58 -06:00
|
|
|
const getFilterLevel = (getConfigValue: GetWebAppConfigValue) =>
|
|
|
|
(type: ALLOWED_MESSAGE_TYPES): number => {
|
|
|
|
const filterLevel =
|
|
|
|
getConfigValue(safeNumericSetting(type + "_log"));
|
|
|
|
return isNumber(filterLevel) ? filterLevel : 1;
|
|
|
|
};
|
2017-12-11 04:50:41 -07:00
|
|
|
|
2018-05-17 14:12:33 -06:00
|
|
|
/** Generate a fallback TaggedLog to display in the first line of the ticker. */
|
|
|
|
const generateFallbackLog = (uuid: string, message: string): TaggedLog => {
|
|
|
|
return {
|
|
|
|
kind: "Log",
|
|
|
|
uuid,
|
|
|
|
specialStatus: SpecialStatus.SAVED,
|
|
|
|
body: {
|
|
|
|
message,
|
2019-02-26 20:12:02 -07:00
|
|
|
type: MessageType.debug,
|
2018-03-31 12:10:36 -06:00
|
|
|
verbosity: -1,
|
2017-12-11 04:50:41 -07:00
|
|
|
channels: [], created_at: NaN
|
2018-05-17 14:12:33 -06:00
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
/** Choose the log to display in the first line of the ticker. */
|
2018-08-30 19:25:58 -06:00
|
|
|
const getfirstTickerLog = (getConfigValue: GetWebAppConfigValue) =>
|
|
|
|
(logs: TaggedLog[]): TaggedLog => {
|
|
|
|
if (logs.length == 0) {
|
|
|
|
return generateFallbackLog("no_logs_yet", t("No logs yet."));
|
2017-12-11 04:50:41 -07:00
|
|
|
} else {
|
2018-08-30 19:25:58 -06:00
|
|
|
const filteredLogs =
|
|
|
|
filterByVerbosity(getFilterLevel(getConfigValue), logs);
|
|
|
|
if (filteredLogs.length > 0) {
|
|
|
|
return filteredLogs[0];
|
|
|
|
} else {
|
|
|
|
return generateFallbackLog("no_logs_to_display",
|
|
|
|
t("No logs to display. Visit Logs page to view filters."));
|
|
|
|
}
|
2017-12-11 04:50:41 -07:00
|
|
|
}
|
2018-08-30 19:25:58 -06:00
|
|
|
};
|
2017-07-07 10:50:52 -06:00
|
|
|
|
2018-05-17 14:12:33 -06:00
|
|
|
/** Format a single log for display in the ticker. */
|
2019-04-09 23:17:03 -06:00
|
|
|
const Ticker = (log: TaggedLog, timeSettings: TimeSettings) => {
|
2018-05-17 14:12:33 -06:00
|
|
|
const { message, type, created_at } = log.body;
|
2019-04-16 11:00:00 -06:00
|
|
|
const time = created_at ? formatLogTime(created_at, timeSettings) : "";
|
2018-05-17 14:12:33 -06:00
|
|
|
return <div key={log.uuid} className="status-ticker-wrapper">
|
2018-01-20 07:46:44 -07:00
|
|
|
<div className={`saucer ${type}`} />
|
|
|
|
<label className="status-ticker-message">
|
|
|
|
<Markdown>
|
2018-11-30 21:59:18 -07:00
|
|
|
{message.replace(/\s+/g, " ") || t("Loading")}
|
2018-01-20 07:46:44 -07:00
|
|
|
</Markdown>
|
|
|
|
</label>
|
|
|
|
<label className="status-ticker-created-at">
|
2018-11-30 21:59:18 -07:00
|
|
|
{t(time)}
|
2018-01-20 07:46:44 -07:00
|
|
|
</label>
|
|
|
|
</div>;
|
2017-07-07 10:50:52 -06:00
|
|
|
};
|
2017-07-04 07:20:51 -06:00
|
|
|
|
2018-05-17 14:12:33 -06:00
|
|
|
/** The logs ticker, with closed/open views, and a link to the Logs page. */
|
2019-12-10 12:53:20 -07:00
|
|
|
export const TickerList = (props: TickerListProps) => {
|
2018-04-02 09:23:09 -06:00
|
|
|
return <ErrorBoundary>
|
2019-09-23 12:56:35 -06:00
|
|
|
<div className="ticker-list" onClick={props.toggle("tickerListOpen")}>
|
2018-04-02 09:23:09 -06:00
|
|
|
<div className="first-ticker">
|
2018-08-30 19:25:58 -06:00
|
|
|
{Ticker(getfirstTickerLog(props.getConfigValue)(props.logs),
|
2019-04-09 23:17:03 -06:00
|
|
|
props.timeSettings)}
|
2018-04-02 09:23:09 -06:00
|
|
|
</div>
|
|
|
|
<Collapse isOpen={props.tickerListOpen}>
|
2018-08-30 19:25:58 -06:00
|
|
|
{filterByVerbosity(getFilterLevel(props.getConfigValue), props.logs)
|
2018-05-17 14:12:33 -06:00
|
|
|
// Don't use first log again since it's already displayed in first row
|
2018-04-02 09:23:09 -06:00
|
|
|
.filter((_, index) => index !== 0)
|
2019-04-09 23:17:03 -06:00
|
|
|
.map((log: TaggedLog) => Ticker(log, props.timeSettings))}
|
2018-04-02 09:23:09 -06:00
|
|
|
</Collapse>
|
|
|
|
<Collapse isOpen={props.tickerListOpen}>
|
|
|
|
<Link to={"/app/logs"}>
|
|
|
|
<div className="logs-page-link">
|
|
|
|
<label>
|
|
|
|
{t("Filter logs")}
|
|
|
|
</label>
|
|
|
|
</div>
|
|
|
|
</Link>
|
|
|
|
</Collapse>
|
2017-07-07 10:50:52 -06:00
|
|
|
</div>
|
2018-04-02 09:23:09 -06:00
|
|
|
</ErrorBoundary>;
|
2017-07-07 01:10:36 -06:00
|
|
|
};
|