diff --git a/frontend/css/global.scss b/frontend/css/global.scss index a931b08d9..d9bd52f18 100644 --- a/frontend/css/global.scss +++ b/frontend/css/global.scss @@ -187,6 +187,15 @@ fieldset { } } +.throttle-display { + .throttle-row { + display: flex; + .saucer { + margin-right: 1rem; + } + } +} + .wifi-strength-display { position: relative; .percent-bar { diff --git a/frontend/devices/__tests__/actions_test.ts b/frontend/devices/__tests__/actions_test.ts index 4a8431a91..0799d4271 100644 --- a/frontend/devices/__tests__/actions_test.ts +++ b/frontend/devices/__tests__/actions_test.ts @@ -264,8 +264,11 @@ describe("isLog()", function () { it("filters sensitive logs", () => { const log = { message: "NERVESPSKWPASSWORD" }; + console.error = jest.fn(); const result = actions.isLog(log); expect(result).toBe(false); + expect(console.error).toHaveBeenCalledWith( + expect.stringContaining("Refusing to display log")); }); }); diff --git a/frontend/devices/actions.ts b/frontend/devices/actions.ts index b315d2558..2668b4821 100644 --- a/frontend/devices/actions.ts +++ b/frontend/devices/actions.ts @@ -33,8 +33,7 @@ export const FEATURE_MIN_VERSIONS_URL = "https://raw.githubusercontent.com/FarmBot/farmbot_os/staging/" + "FEATURE_MIN_VERSIONS.json"; // Already filtering messages in FarmBot OS and the API- this is just for -// an additional layer of safety. If sensitive data ever hits a client, it will -// be reported to Rollbar for investigation. +// an additional layer of safety. const BAD_WORDS = ["WPA", "PSK", "PASSWORD", "NERVES"]; export function isLog(x: unknown): x is Log { diff --git a/frontend/devices/components/fbos_settings/fbos_details.tsx b/frontend/devices/components/fbos_settings/fbos_details.tsx index a3e5e4067..05ff9a07f 100644 --- a/frontend/devices/components/fbos_settings/fbos_details.tsx +++ b/frontend/devices/components/fbos_settings/fbos_details.tsx @@ -9,6 +9,7 @@ import { SourceFbosConfig, ShouldDisplay, Feature } from "../../interfaces"; import { ConfigurationName } from "farmbot"; import { t } from "../../../i18next_wrapper"; import { LastSeen } from "./last_seen_row"; +import { Popover } from "@blueprintjs/core"; /** Return an indicator color for the given temperature (C). */ export const colorFromTemp = (temp: number | undefined): string => { @@ -28,10 +29,15 @@ export const colorFromTemp = (temp: number | undefined): string => { } }; +interface ChipTemperatureDisplayProps { + chip?: string; + temperature: number | undefined; +} + /** RPI CPU temperature display row: label, temperature, indicator. */ -export function ChipTemperatureDisplay({ chip, temperature }: { - chip?: string, temperature: number | undefined -}): JSX.Element { +export function ChipTemperatureDisplay( + { chip, temperature }: ChipTemperatureDisplayProps +): JSX.Element { return
{chip && chip.toUpperCase()} {t("CPU temperature")}: @@ -41,15 +47,20 @@ export function ChipTemperatureDisplay({ chip, temperature }: {
{t("WiFi Strength")}:
@@ -100,6 +111,36 @@ export const colorFromThrottle =
}
};
+const THROTTLE_COLOR_KEY = () => ({
+ red: t("active"),
+ yellow: t("occurred"),
+ green: t("clear")
+});
+
+interface ThrottleIndicatorProps {
+ throttleDataString: string;
+ throttleType: ThrottleType;
+}
+
+/** Saucer with color and title indicating throttle state. */
+const ThrottleIndicator = (props: ThrottleIndicatorProps) => {
+ const { throttleDataString, throttleType } = props;
+ const throttleColor = colorFromThrottle(throttleDataString, throttleType);
+ return
{key}
+{chip && chip.toUpperCase()} {t("Voltage")}:
-{title}: @@ -136,8 +187,12 @@ const CommitDisplay = ({ title, repo, commit }: {
; }; +interface UptimeDisplayProps { + uptime_sec: number; +} + /** FBOS uptime display row: label and uptime in relevant unit. */ -const UptimeDisplay = ({ uptime_sec }: { uptime_sec: number }): JSX.Element => { +const UptimeDisplay = ({ uptime_sec }: UptimeDisplayProps): JSX.Element => { const convertUptime = (seconds: number) => { if (seconds >= 172800) { return `${Math.round(seconds / 86400)} ${t("days")}`; @@ -152,9 +207,15 @@ const UptimeDisplay = ({ uptime_sec }: { uptime_sec: number }): JSX.Element => { return{t("Uptime")}: {convertUptime(uptime_sec)}
; }; -export const betaReleaseOptIn = ({ sourceFbosConfig, shouldDisplay }: { - sourceFbosConfig: SourceFbosConfig, shouldDisplay: ShouldDisplay -}) => { +interface BetaReleaseOptInParams { + sourceFbosConfig: SourceFbosConfig; + shouldDisplay: ShouldDisplay; +} + +/** Generate params for BetaReleaseOptInButton. */ +export const betaReleaseOptIn = ( + { sourceFbosConfig, shouldDisplay }: BetaReleaseOptInParams +) => { if (shouldDisplay(Feature.use_update_channel)) { const betaOptIn = sourceFbosConfig("update_channel" as ConfigurationName); const betaOptInValue = betaOptIn.value !== "stable"; @@ -172,34 +233,39 @@ export const betaReleaseOptIn = ({ sourceFbosConfig, shouldDisplay }: { } }; +interface BetaReleaseOptInButtonProps { + dispatch: Function; + sourceFbosConfig: SourceFbosConfig; + shouldDisplay: ShouldDisplay; +} + /** Label and toggle button for opting in to FBOS beta releases. */ -const BetaReleaseOptInButton = - ({ dispatch, sourceFbosConfig, shouldDisplay }: { - dispatch: Function, - sourceFbosConfig: SourceFbosConfig, - shouldDisplay: ShouldDisplay, - }): JSX.Element => { - const { betaOptIn, betaOptInValue, update } = - betaReleaseOptIn({ sourceFbosConfig, shouldDisplay }); - return ; - }; +const BetaReleaseOptInButton = ( + { dispatch, sourceFbosConfig, shouldDisplay }: BetaReleaseOptInButtonProps +): JSX.Element => { + const { betaOptIn, betaOptInValue, update } = + betaReleaseOptIn({ sourceFbosConfig, shouldDisplay }); + return ; +}; /** Current technical information about FarmBot OS running on the device. */ export function FbosDetails(props: FbosDetailsProps) { const { env, commit, target, node_name, firmware_version, firmware_commit, - soc_temp, wifi_level, uptime, memory_usage, disk_usage, throttled - } = props.botInfoSettings; + soc_temp, wifi_level, uptime, memory_usage, disk_usage, throttled, + wifi_level_percent, + // tslint:disable-next-line:no-any + } = props.botInfoSettings as any; return{t("Disk usage")}: {disk_usage}%
}