misc fixes
parent
83d9cb8287
commit
cb44640ca5
|
@ -1,8 +1,3 @@
|
|||
let mockDev = false;
|
||||
jest.mock("../account/dev/dev_support", () => ({
|
||||
DevSettings: { futureFeaturesEnabled: () => mockDev }
|
||||
}));
|
||||
|
||||
jest.mock("react-redux", () => ({ connect: jest.fn() }));
|
||||
|
||||
let mockPath = "";
|
||||
|
@ -16,7 +11,7 @@ import { App, AppProps, mapStateToProps } from "../app";
|
|||
import { mount } from "enzyme";
|
||||
import { bot } from "../__test_support__/fake_state/bot";
|
||||
import {
|
||||
fakeUser, fakeWebAppConfig, fakeEnigma
|
||||
fakeUser, fakeWebAppConfig
|
||||
} from "../__test_support__/fake_state/resources";
|
||||
import { fakeState } from "../__test_support__/fake_state";
|
||||
import {
|
||||
|
@ -147,21 +142,4 @@ describe("mapStateToProps()", () => {
|
|||
const result = mapStateToProps(state);
|
||||
expect(result.axisInversion.x).toEqual(true);
|
||||
});
|
||||
|
||||
it("doesn't show API alerts", () => {
|
||||
const state = fakeState();
|
||||
state.resources = buildResourceIndex([fakeEnigma()]);
|
||||
mockDev = false;
|
||||
const props = mapStateToProps(state);
|
||||
expect(props.alertCount).toEqual(0);
|
||||
});
|
||||
|
||||
it("shows API alerts", () => {
|
||||
const state = fakeState();
|
||||
const enigma = fakeEnigma();
|
||||
state.resources = buildResourceIndex([enigma]);
|
||||
mockDev = true;
|
||||
const props = mapStateToProps(state);
|
||||
expect(props.alertCount).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -10,12 +10,11 @@ import {
|
|||
maybeFetchUser,
|
||||
maybeGetTimeSettings,
|
||||
getDeviceAccountSettings,
|
||||
selectAllEnigmas,
|
||||
} from "./resources/selectors";
|
||||
import { HotKeys } from "./hotkeys";
|
||||
import { ControlsPopup } from "./controls_popup";
|
||||
import { Content } from "./constants";
|
||||
import { validBotLocationData, validFwConfig, validFbosConfig, betterCompact } from "./util";
|
||||
import { validBotLocationData, validFwConfig, validFbosConfig } from "./util";
|
||||
import { BooleanSetting } from "./session_keys";
|
||||
import { getPathArray } from "./history";
|
||||
import {
|
||||
|
@ -29,7 +28,7 @@ import { t } from "./i18next_wrapper";
|
|||
import { ResourceIndex } from "./resources/interfaces";
|
||||
import { isBotOnline } from "./devices/must_be_online";
|
||||
import { getStatus } from "./connectivity/reducer_support";
|
||||
import { DevSettings } from "./account/dev/dev_support";
|
||||
import { getAlerts } from "./messages/state_to_props";
|
||||
|
||||
/** For the logger module */
|
||||
init();
|
||||
|
@ -56,10 +55,6 @@ export interface AppProps {
|
|||
export function mapStateToProps(props: Everything): AppProps {
|
||||
const webAppConfigValue = getWebAppConfigValue(() => props);
|
||||
const fbosConfig = validFbosConfig(getFbosConfig(props.resources.index));
|
||||
const botAlerts = betterCompact(Object.values(props.bot.hardware.enigmas || {}));
|
||||
const apiAlerts = selectAllEnigmas(props.resources.index).map(x => x.body);
|
||||
const alerts =
|
||||
botAlerts.concat(DevSettings.futureFeaturesEnabled() ? apiAlerts : []);
|
||||
return {
|
||||
timeSettings: maybeGetTimeSettings(props.resources.index),
|
||||
dispatch: props.dispatch,
|
||||
|
@ -80,7 +75,7 @@ export function mapStateToProps(props: Everything): AppProps {
|
|||
tour: props.resources.consumers.help.currentTour,
|
||||
resources: props.resources.index,
|
||||
autoSync: !!(fbosConfig && fbosConfig.auto_sync),
|
||||
alertCount: alerts.length,
|
||||
alertCount: getAlerts(props.resources.index, props.bot).length,
|
||||
};
|
||||
}
|
||||
/** Time at which the app gives up and asks the user to refresh */
|
||||
|
|
|
@ -422,8 +422,7 @@ export namespace Content {
|
|||
|
||||
// App Settings
|
||||
export const CONFIRM_STEP_DELETION =
|
||||
trim(`Show a confirmation dialog when the sequence delete step
|
||||
icon is pressed.`);
|
||||
trim(`Show a confirmation dialog when deleting a sequence step.`);
|
||||
|
||||
export const HIDE_WEBCAM_WIDGET =
|
||||
trim(`If not using a webcam, use this setting to remove the
|
||||
|
|
|
@ -13,7 +13,7 @@ describe("calcMicrostepsPerMm()", () => {
|
|||
});
|
||||
|
||||
it("calculates value with microstepping", () => {
|
||||
expect(calcMicrostepsPerMm(5, 4)).toEqual(20);
|
||||
expect(calcMicrostepsPerMm(5, 4)).toEqual(5);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -30,7 +30,7 @@ describe("calculateAxialLengths()", () => {
|
|||
firmwareSettings.movement_step_per_mm_z = 25;
|
||||
firmwareSettings.movement_microsteps_z = 4;
|
||||
expect(calculateAxialLengths({ firmwareSettings })).toEqual({
|
||||
x: 0, y: 20, z: 1
|
||||
x: 0, y: 20, z: 4
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,7 +4,8 @@ import { McuParams } from "farmbot";
|
|||
export const calcMicrostepsPerMm = (
|
||||
steps_per_mm: number | undefined,
|
||||
microsteps_per_step: number | undefined) =>
|
||||
(steps_per_mm || 1) * (microsteps_per_step || 1);
|
||||
// The firmware currently interprets steps_per_mm as microsteps_per_mm.
|
||||
(steps_per_mm || 1) * (1 || microsteps_per_step || 1);
|
||||
|
||||
const calcAxisLength = (
|
||||
nr_steps: number | undefined,
|
||||
|
|
|
@ -26,9 +26,6 @@
|
|||
0% {
|
||||
transform: translateX(-11rem)
|
||||
}
|
||||
90% {
|
||||
transform: translateX(1rem)
|
||||
}
|
||||
100% {
|
||||
transform: translateX(0)
|
||||
}
|
||||
|
|
|
@ -100,6 +100,7 @@ nav {
|
|||
}
|
||||
div {
|
||||
display: inline;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,6 +76,9 @@ export function EncodersAndEndStops(props: EncodersProps) {
|
|||
x={"encoder_scaling_x"}
|
||||
y={"encoder_scaling_y"}
|
||||
z={"encoder_scaling_z"}
|
||||
xScale={sourceFwConfig("movement_microsteps_x").value}
|
||||
yScale={sourceFwConfig("movement_microsteps_y").value}
|
||||
zScale={sourceFwConfig("movement_microsteps_z").value}
|
||||
intSize={shouldDisplay(Feature.long_scaling_factor) ? "long" : "short"}
|
||||
gray={encodersDisabled}
|
||||
sourceFwConfig={sourceFwConfig}
|
||||
|
|
|
@ -37,7 +37,7 @@ describe("<Tour />", () => {
|
|||
const wrapper = shallow<Tour>(<Tour steps={steps} />);
|
||||
wrapper.instance().callback(fakeCallbackData({ type: "tour:end" }));
|
||||
expect(wrapper.state()).toEqual({ run: false, index: 0 });
|
||||
expect(history.push).toHaveBeenCalledWith("/app/help");
|
||||
expect(history.push).toHaveBeenCalledWith("/app/messages");
|
||||
});
|
||||
|
||||
it("navigates through tour: next", () => {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import * as React from "react";
|
||||
|
||||
import Joyride, { Step as TourStep, CallBackProps } from "react-joyride";
|
||||
import { Color } from "../ui";
|
||||
import { history } from "../history";
|
||||
|
@ -44,7 +43,7 @@ export class Tour extends React.Component<TourProps, TourState> {
|
|||
}
|
||||
if (type === "tour:end") {
|
||||
this.setState({ run: false });
|
||||
history.push("/app/help");
|
||||
history.push("/app/messages");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ describe("<Alerts />", () => {
|
|||
apiFirmwareValue: undefined,
|
||||
timeSettings: fakeTimeSettings(),
|
||||
dispatch: jest.fn(),
|
||||
findApiAlertById: jest.fn(),
|
||||
});
|
||||
|
||||
it("renders no alerts", () => {
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
jest.mock("../../api/crud", () => ({ destroy: jest.fn() }));
|
||||
|
||||
import * as React from "react";
|
||||
import { mount } from "enzyme";
|
||||
import { AlertCard } from "../cards";
|
||||
import { AlertCardProps } from "../interfaces";
|
||||
import { fakeTimeSettings } from "../../__test_support__/fake_time_settings";
|
||||
import { FBSelect } from "../../ui";
|
||||
import { destroy } from "../../api/crud";
|
||||
|
||||
describe("<AlertCard />", () => {
|
||||
const fakeProps = (): AlertCardProps => ({
|
||||
|
@ -19,8 +22,13 @@ describe("<AlertCard />", () => {
|
|||
});
|
||||
|
||||
it("renders unknown card", () => {
|
||||
const wrapper = mount(<AlertCard {...fakeProps()} />);
|
||||
const p = fakeProps();
|
||||
p.alert.id = 1;
|
||||
p.findApiAlertById = () => "uuid";
|
||||
const wrapper = mount(<AlertCard {...p} />);
|
||||
expect(wrapper.text()).toContain("noun: verb (author)");
|
||||
wrapper.find(".fa-times").simulate("click");
|
||||
expect(destroy).toHaveBeenCalledWith("uuid");
|
||||
});
|
||||
|
||||
it("renders firmware card", () => {
|
||||
|
@ -28,6 +36,8 @@ describe("<AlertCard />", () => {
|
|||
p.alert.problem_tag = "farmbot_os.firmware.missing";
|
||||
const wrapper = mount(<AlertCard {...p} />);
|
||||
expect(wrapper.text()).toContain("Firmware missing");
|
||||
wrapper.find(".fa-times").simulate("click");
|
||||
expect(destroy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("renders seed data card", () => {
|
||||
|
|
|
@ -12,6 +12,7 @@ describe("<Messages />", () => {
|
|||
apiFirmwareValue: undefined,
|
||||
timeSettings: fakeTimeSettings(),
|
||||
dispatch: Function,
|
||||
findApiAlertById: jest.fn(),
|
||||
});
|
||||
|
||||
it("renders page", () => {
|
||||
|
|
|
@ -6,7 +6,9 @@ jest.mock("../../account/dev/dev_support", () => ({
|
|||
import { fakeState } from "../../__test_support__/fake_state";
|
||||
import { mapStateToProps } from "../state_to_props";
|
||||
import { buildResourceIndex } from "../../__test_support__/resource_index_builder";
|
||||
import { fakeEnigma, fakeFbosConfig } from "../../__test_support__/fake_state/resources";
|
||||
import {
|
||||
fakeEnigma, fakeFbosConfig
|
||||
} from "../../__test_support__/fake_state/resources";
|
||||
|
||||
describe("mapStateToProps()", () => {
|
||||
it("handles undefined", () => {
|
||||
|
@ -18,7 +20,9 @@ describe("mapStateToProps()", () => {
|
|||
|
||||
it("doesn't show API alerts", () => {
|
||||
const state = fakeState();
|
||||
state.resources = buildResourceIndex([fakeEnigma()]);
|
||||
const enigma = fakeEnigma();
|
||||
enigma.body.problem_tag = "api.seed_data.missing";
|
||||
state.resources = buildResourceIndex([enigma]);
|
||||
mockDev = false;
|
||||
const props = mapStateToProps(state);
|
||||
expect(props.alerts).toEqual([]);
|
||||
|
@ -27,6 +31,7 @@ describe("mapStateToProps()", () => {
|
|||
it("shows API alerts", () => {
|
||||
const state = fakeState();
|
||||
const enigma = fakeEnigma();
|
||||
enigma.body.problem_tag = "api.seed_data.missing";
|
||||
state.resources = buildResourceIndex([enigma]);
|
||||
mockDev = true;
|
||||
const props = mapStateToProps(state);
|
||||
|
@ -42,4 +47,13 @@ describe("mapStateToProps()", () => {
|
|||
const props = mapStateToProps(state);
|
||||
expect(props.apiFirmwareValue).toEqual("arduino");
|
||||
});
|
||||
|
||||
it("finds alert", () => {
|
||||
const state = fakeState();
|
||||
const alert = fakeEnigma();
|
||||
alert.body.id = 1;
|
||||
state.resources = buildResourceIndex([alert]);
|
||||
const props = mapStateToProps(state);
|
||||
expect(props.findApiAlertById(1)).toEqual(alert.uuid);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -37,6 +37,7 @@ export const Alerts = (props: AlertsProps) =>
|
|||
alert={x}
|
||||
dispatch={props.dispatch}
|
||||
apiFirmwareValue={props.apiFirmwareValue}
|
||||
timeSettings={props.timeSettings} />)}
|
||||
timeSettings={props.timeSettings}
|
||||
findApiAlertById={props.findApiAlertById} />)}
|
||||
</div>
|
||||
</div>;
|
||||
|
|
|
@ -3,7 +3,8 @@ import { t } from "../i18next_wrapper";
|
|||
import {
|
||||
AlertCardProps, AlertCardTemplateProps, FirmwareMissingProps,
|
||||
SeedDataMissingProps, SeedDataMissingState, TourNotTakenProps,
|
||||
CommonAlertCardProps
|
||||
CommonAlertCardProps,
|
||||
DismissAlertProps
|
||||
} from "./interfaces";
|
||||
import { formatLogTime } from "../logs";
|
||||
import {
|
||||
|
@ -13,20 +14,21 @@ import { DropDownItem, Row, Col, FBSelect, docLink } from "../ui";
|
|||
import { Content } from "../constants";
|
||||
import { TourList } from "../help/tour_list";
|
||||
import { splitProblemTag } from "./alerts";
|
||||
import { destroy } from "../api/crud";
|
||||
|
||||
export const AlertCard = (props: AlertCardProps) => {
|
||||
const { alert, timeSettings } = props;
|
||||
const commonProps = { alert, timeSettings };
|
||||
const { alert, timeSettings, findApiAlertById, dispatch } = props;
|
||||
const commonProps = { alert, timeSettings, findApiAlertById, dispatch };
|
||||
switch (alert.problem_tag) {
|
||||
case "farmbot_os.firmware.missing":
|
||||
return <FirmwareMissing {...commonProps}
|
||||
apiFirmwareValue={props.apiFirmwareValue} />;
|
||||
case "api.seed_data.missing":
|
||||
return <SeedDataMissing {...commonProps}
|
||||
dispatch={props.dispatch} />;
|
||||
dispatch={dispatch} />;
|
||||
case "api.tour.not_taken":
|
||||
return <TourNotTaken {...commonProps}
|
||||
dispatch={props.dispatch} />;
|
||||
dispatch={dispatch} />;
|
||||
case "api.user.not_welcomed":
|
||||
return <UserNotWelcomed {...commonProps} />;
|
||||
case "api.documentation.unread":
|
||||
|
@ -35,20 +37,27 @@ export const AlertCard = (props: AlertCardProps) => {
|
|||
return UnknownAlert(commonProps);
|
||||
}
|
||||
};
|
||||
const dismissAlert = (props: DismissAlertProps) => () =>
|
||||
(props.id && props.findApiAlertById && props.dispatch)
|
||||
? props.dispatch(destroy(props.findApiAlertById(props.id)))
|
||||
: () => { };
|
||||
|
||||
const AlertCardTemplate = (props: AlertCardTemplateProps) =>
|
||||
<div className={`problem-alert ${props.className}`}>
|
||||
const AlertCardTemplate = (props: AlertCardTemplateProps) => {
|
||||
const { alert, findApiAlertById, dispatch } = props;
|
||||
return <div className={`problem-alert ${props.className}`}>
|
||||
<div className="problem-alert-title">
|
||||
<i className="fa fa-exclamation-triangle" />
|
||||
<h3>{t(props.title)}</h3>
|
||||
<p>{formatLogTime(props.alert.created_at, props.timeSettings)}</p>
|
||||
<i className="fa fa-times" />
|
||||
<p>{formatLogTime(alert.created_at, props.timeSettings)}</p>
|
||||
<i className="fa fa-times"
|
||||
onClick={dismissAlert({ id: alert.id, findApiAlertById, dispatch })} />
|
||||
</div>
|
||||
<div className="problem-alert-content">
|
||||
<p>{t(props.message)}</p>
|
||||
{props.children}
|
||||
</div>
|
||||
</div>;
|
||||
};
|
||||
|
||||
const UnknownAlert = (props: CommonAlertCardProps) => {
|
||||
const { problem_tag, created_at, priority } = props.alert;
|
||||
|
@ -60,7 +69,9 @@ const UnknownAlert = (props: CommonAlertCardProps) => {
|
|||
title={`${t(noun)}: ${t(verb)} (${t(author)})`}
|
||||
message={t("Unknown problem of priority {{priority}} created at {{createdAt}}",
|
||||
{ priority, createdAt })}
|
||||
timeSettings={props.timeSettings} />;
|
||||
timeSettings={props.timeSettings}
|
||||
dispatch={props.dispatch}
|
||||
findApiAlertById={props.findApiAlertById} />;
|
||||
};
|
||||
|
||||
const FirmwareMissing = (props: FirmwareMissingProps) =>
|
||||
|
@ -69,7 +80,9 @@ const FirmwareMissing = (props: FirmwareMissingProps) =>
|
|||
className={"firmware-missing-alert"}
|
||||
title={t("Firmware missing")}
|
||||
message={t("Your device has no firmware installed.")}
|
||||
timeSettings={props.timeSettings}>
|
||||
timeSettings={props.timeSettings}
|
||||
dispatch={props.dispatch}
|
||||
findApiAlertById={props.findApiAlertById}>
|
||||
<FirmwareActions
|
||||
apiFirmwareValue={props.apiFirmwareValue}
|
||||
botOnline={true} />
|
||||
|
@ -92,7 +105,9 @@ class SeedDataMissing
|
|||
className={"seed-data-missing-alert"}
|
||||
title={t("Choose your FarmBot")}
|
||||
message={t(Content.SEED_DATA_SELECTION)}
|
||||
timeSettings={this.props.timeSettings}>
|
||||
timeSettings={this.props.timeSettings}
|
||||
dispatch={this.props.dispatch}
|
||||
findApiAlertById={this.props.findApiAlertById}>
|
||||
<Row>
|
||||
<Col xs={4}>
|
||||
<label>{t("Choose your FarmBot")}</label>
|
||||
|
@ -115,7 +130,9 @@ const TourNotTaken = (props: TourNotTakenProps) =>
|
|||
className={"tour-not-taken-alert"}
|
||||
title={t("Take a guided tour")}
|
||||
message={t(Content.TAKE_A_TOUR)}
|
||||
timeSettings={props.timeSettings}>
|
||||
timeSettings={props.timeSettings}
|
||||
dispatch={props.dispatch}
|
||||
findApiAlertById={props.findApiAlertById}>
|
||||
<p>{t("Choose a tour to begin")}:</p>
|
||||
<TourList dispatch={props.dispatch} />
|
||||
</AlertCardTemplate>;
|
||||
|
@ -126,7 +143,9 @@ const UserNotWelcomed = (props: CommonAlertCardProps) =>
|
|||
className={"user-not-welcomed-alert"}
|
||||
title={t("Welcome to the FarmBot Web App")}
|
||||
message={t(Content.WELCOME)}
|
||||
timeSettings={props.timeSettings}>
|
||||
timeSettings={props.timeSettings}
|
||||
dispatch={props.dispatch}
|
||||
findApiAlertById={props.findApiAlertById}>
|
||||
<p>
|
||||
{t("You're currently viewing the")} <b>{t("Message Center")}</b>.
|
||||
{t(Content.MESSAGE_CENTER_WELCOME)}
|
||||
|
@ -142,7 +161,9 @@ const DocumentationUnread = (props: CommonAlertCardProps) =>
|
|||
className={"documentation-unread-alert"}
|
||||
title={t("Learn more about the app")}
|
||||
message={t(Content.READ_THE_DOCS)}
|
||||
timeSettings={props.timeSettings}>
|
||||
timeSettings={props.timeSettings}
|
||||
dispatch={props.dispatch}
|
||||
findApiAlertById={props.findApiAlertById}>
|
||||
<p>
|
||||
{t("Head over to")}
|
||||
<a href={docLink()} target="_blank"
|
||||
|
|
|
@ -24,7 +24,8 @@ export class Messages extends React.Component<MessagesProps, {}> {
|
|||
<Alerts alerts={this.props.alerts}
|
||||
dispatch={this.props.dispatch}
|
||||
apiFirmwareValue={this.props.apiFirmwareValue}
|
||||
timeSettings={this.props.timeSettings} />
|
||||
timeSettings={this.props.timeSettings}
|
||||
findApiAlertById={this.props.findApiAlertById} />
|
||||
</Row>
|
||||
<Row>
|
||||
<div className="link-to-logs">
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
import { FirmwareHardware, Enigma } from "farmbot";
|
||||
import { TimeSettings } from "../interfaces";
|
||||
import { BotState } from "../devices/interfaces";
|
||||
import { UUID } from "../resources/interfaces";
|
||||
|
||||
export interface MessagesProps {
|
||||
alerts: Alert[];
|
||||
apiFirmwareValue: FirmwareHardware | undefined;
|
||||
timeSettings: TimeSettings;
|
||||
dispatch: Function;
|
||||
findApiAlertById(id: number): UUID;
|
||||
}
|
||||
|
||||
export interface AlertsProps {
|
||||
|
@ -14,6 +16,7 @@ export interface AlertsProps {
|
|||
apiFirmwareValue: string | undefined;
|
||||
timeSettings: TimeSettings;
|
||||
dispatch: Function;
|
||||
findApiAlertById(id: number): UUID;
|
||||
}
|
||||
|
||||
export interface ProblemTag {
|
||||
|
@ -36,11 +39,14 @@ export interface AlertCardProps {
|
|||
apiFirmwareValue: string | undefined;
|
||||
timeSettings: TimeSettings;
|
||||
dispatch: Function;
|
||||
findApiAlertById?(id: number): UUID;
|
||||
}
|
||||
|
||||
export interface CommonAlertCardProps {
|
||||
alert: Alert;
|
||||
timeSettings: TimeSettings;
|
||||
findApiAlertById?(id: number): UUID;
|
||||
dispatch?: Function;
|
||||
}
|
||||
|
||||
export interface AlertCardTemplateProps {
|
||||
|
@ -50,6 +56,14 @@ export interface AlertCardTemplateProps {
|
|||
message: string;
|
||||
timeSettings: TimeSettings;
|
||||
children?: React.ReactNode;
|
||||
findApiAlertById?(id: number): UUID;
|
||||
dispatch?: Function;
|
||||
}
|
||||
|
||||
export interface DismissAlertProps {
|
||||
id?: number;
|
||||
findApiAlertById?(id: number): UUID;
|
||||
dispatch?: Function;
|
||||
}
|
||||
|
||||
export interface FirmwareMissingProps extends CommonAlertCardProps {
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
import { Everything } from "../interfaces";
|
||||
import { MessagesProps } from "./interfaces";
|
||||
import { MessagesProps, Alert } from "./interfaces";
|
||||
import { validFbosConfig, betterCompact } from "../util";
|
||||
import { getFbosConfig } from "../resources/getters";
|
||||
import { sourceFbosConfigValue } from "../devices/components/source_config_value";
|
||||
import { DevSettings } from "../account/dev/dev_support";
|
||||
import { selectAllEnigmas, maybeGetTimeSettings } from "../resources/selectors";
|
||||
import {
|
||||
selectAllEnigmas, maybeGetTimeSettings, findResourceById
|
||||
} from "../resources/selectors";
|
||||
import { isFwHardwareValue } from "../devices/components/fbos_settings/board_type";
|
||||
import { ResourceIndex, UUID } from "../resources/interfaces";
|
||||
import { BotState } from "../devices/interfaces";
|
||||
|
||||
export const mapStateToProps = (props: Everything): MessagesProps => {
|
||||
const { hardware } = props.bot;
|
||||
|
@ -13,15 +17,23 @@ export const mapStateToProps = (props: Everything): MessagesProps => {
|
|||
const sourceFbosConfig =
|
||||
sourceFbosConfigValue(fbosConfig, hardware.configuration);
|
||||
const apiFirmwareValue = sourceFbosConfig("firmware_hardware").value;
|
||||
const botAlerts = betterCompact(Object.values(props.bot.hardware.enigmas || {}));
|
||||
const apiAlerts = selectAllEnigmas(props.resources.index).map(x => x.body);
|
||||
const alerts =
|
||||
botAlerts.concat(DevSettings.futureFeaturesEnabled() ? apiAlerts : []);
|
||||
const findApiAlertById = (id: number): UUID =>
|
||||
findResourceById(props.resources.index, "Enigma", id);
|
||||
return {
|
||||
alerts,
|
||||
alerts: getAlerts(props.resources.index, props.bot),
|
||||
apiFirmwareValue: isFwHardwareValue(apiFirmwareValue)
|
||||
? apiFirmwareValue : undefined,
|
||||
timeSettings: maybeGetTimeSettings(props.resources.index),
|
||||
dispatch: props.dispatch,
|
||||
findApiAlertById,
|
||||
};
|
||||
};
|
||||
|
||||
export const getAlerts =
|
||||
(resourceIndex: ResourceIndex, bot: BotState): Alert[] => {
|
||||
const botAlerts = betterCompact(Object.values(bot.hardware.enigmas || {}));
|
||||
const apiAlerts = selectAllEnigmas(resourceIndex).map(x => x.body)
|
||||
.filter(x => DevSettings.futureFeaturesEnabled() ||
|
||||
x.problem_tag !== "api.seed_data.missing");
|
||||
return botAlerts.concat(apiAlerts);
|
||||
};
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
import { stopIE } from "../stop_ie";
|
||||
|
||||
describe("stopIE()", () => {
|
||||
it("not IE", () => {
|
||||
expect(stopIE).not.toThrow();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,25 @@
|
|||
import { updatePageInfo, attachToRoot } from "../page";
|
||||
import React from "react";
|
||||
|
||||
describe("updatePageInfo()", () => {
|
||||
it("sets page title", () => {
|
||||
updatePageInfo("page name");
|
||||
expect(document.title).toEqual("Page name - FarmBot");
|
||||
});
|
||||
|
||||
it("sets page title: Farm Designer", () => {
|
||||
updatePageInfo("designer");
|
||||
expect(document.title).toEqual("Farm designer - FarmBot");
|
||||
});
|
||||
});
|
||||
|
||||
describe("attachToRoot()", () => {
|
||||
class Foo extends React.Component<{ text: string }> {
|
||||
render() { return <p>{this.props.text}</p>; }
|
||||
}
|
||||
it("attaches page", () => {
|
||||
attachToRoot(Foo, { text: "Bar" });
|
||||
expect(document.body.innerHTML).toEqual(`<div id="root"><p>Bar</p></div>`);
|
||||
expect(document.body.textContent).toEqual("Bar");
|
||||
});
|
||||
});
|
|
@ -4,14 +4,13 @@ import {
|
|||
Attributes
|
||||
} from "react";
|
||||
import { render } from "react-dom";
|
||||
|
||||
import { capitalize } from "lodash";
|
||||
import { t } from "../i18next_wrapper";
|
||||
|
||||
/** Dynamically change the meta title of the page. */
|
||||
export function updatePageInfo(pageName: string) {
|
||||
if (pageName === "designer") { pageName = "Farm Designer"; }
|
||||
document.title = t(capitalize(pageName));
|
||||
document.title = `${t(capitalize(pageName))} - FarmBot`;
|
||||
// Possibly add meta "content" here dynamically as well
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue