diff --git a/frontend/__test_support__/control_panel_state.ts b/frontend/__test_support__/control_panel_state.ts
index 30fdacdeb..c90ff8580 100644
--- a/frontend/__test_support__/control_panel_state.ts
+++ b/frontend/__test_support__/control_panel_state.ts
@@ -10,6 +10,9 @@ export const panelState = (): ControlPanelState => {
pin_bindings: false,
danger_zone: false,
power_and_reset: false,
- pin_guard: false
+ pin_guard: false,
+ farm_designer: false,
+ firmware: false,
+ farmbot_os: false,
};
};
diff --git a/frontend/__test_support__/fake_state/bot.ts b/frontend/__test_support__/fake_state/bot.ts
index 98151048c..d236854cf 100644
--- a/frontend/__test_support__/fake_state/bot.ts
+++ b/frontend/__test_support__/fake_state/bot.ts
@@ -1,19 +1,10 @@
import { Everything } from "../../interfaces";
+import { panelState } from "../control_panel_state";
export const bot: Everything["bot"] = {
"consistent": true,
"stepSize": 100,
- "controlPanelState": {
- homing_and_calibration: false,
- motors: false,
- encoders: false,
- endstops: false,
- error_handling: false,
- pin_bindings: false,
- danger_zone: false,
- power_and_reset: false,
- pin_guard: false,
- },
+ "controlPanelState": panelState(),
"hardware": {
"gpio_registry": {},
"mcu_params": {
diff --git a/frontend/constants.ts b/frontend/constants.ts
index 2c9f6449d..15b21f9a1 100644
--- a/frontend/constants.ts
+++ b/frontend/constants.ts
@@ -1005,10 +1005,11 @@ export enum DeviceSetting {
pinBindings = `Pin Bindings`,
// FarmBot OS
+ farmbot = `FarmBot`,
name = `name`,
timezone = `timezone`,
camera = `camera`,
- firmware = `firmware`,
+ firmware = `Firmware`,
applySoftwareUpdates = `update time`,
farmbotOSAutoUpdate = `auto update`,
farmbotOS = `Farmbot OS`,
@@ -1024,6 +1025,20 @@ export enum DeviceSetting {
autoFactoryReset = `Automatic Factory Reset`,
connectionAttemptPeriod = `Connection Attempt Period`,
changeOwnership = `Change Ownership`,
+
+ // Farm Designer
+ farmDesigner = `Farm Designer`,
+ animations = `Plant animations`,
+ trail = `Virtual FarmBot trail`,
+ dynamicMap = `Dynamic map size`,
+ mapSize = `Map size`,
+ rotateMap = `Rotate map`,
+ mapOrigin = `Map origin`,
+ confirmPlantDeletion = `Confirm plant deletion`,
+
+ // Firmware
+ firmwareSection = `Firmware`,
+ flashFirmware = `Flash firmware`,
}
export namespace DiagnosticMessages {
diff --git a/frontend/devices/components/__tests__/hardware_settings_test.tsx b/frontend/devices/components/__tests__/hardware_settings_test.tsx
index e70b25e6c..90120882f 100644
--- a/frontend/devices/components/__tests__/hardware_settings_test.tsx
+++ b/frontend/devices/components/__tests__/hardware_settings_test.tsx
@@ -31,7 +31,7 @@ describe("", () => {
it("renders", () => {
const wrapper = mount();
- ["expand all", "x axis", "motors"].map(string =>
+ ["expand all", "motors"].map(string =>
expect(wrapper.text().toLowerCase()).toContain(string));
});
diff --git a/frontend/devices/components/fbos_settings/__tests__/power_and_reset_test.tsx b/frontend/devices/components/fbos_settings/__tests__/power_and_reset_test.tsx
index fc5cd3893..a88c28944 100644
--- a/frontend/devices/components/fbos_settings/__tests__/power_and_reset_test.tsx
+++ b/frontend/devices/components/fbos_settings/__tests__/power_and_reset_test.tsx
@@ -6,6 +6,13 @@ jest.mock("../../../../api/crud", () => ({
save: jest.fn(),
}));
+let mockDev = false;
+jest.mock("../../../../account/dev/dev_support", () => ({
+ DevSettings: {
+ futureFeaturesEnabled: () => mockDev,
+ }
+}));
+
import * as React from "react";
import { PowerAndReset } from "../power_and_reset";
import { mount } from "enzyme";
@@ -21,6 +28,10 @@ import {
import { edit, save } from "../../../../api/crud";
describe("", () => {
+ beforeEach(() => {
+ mockDev = false;
+ });
+
const fakeConfig = fakeFbosConfig();
const state = fakeState();
state.resources = buildResourceIndex([fakeConfig]);
@@ -36,11 +47,22 @@ describe("", () => {
const p = fakeProps();
p.controlPanelState.power_and_reset = true;
const wrapper = mount();
- ["Power and Reset", "Restart", "Shutdown", "Restart Firmware",
+ ["Power and Reset", "Restart", "Shutdown",
"Factory Reset", "Automatic Factory Reset",
"Connection Attempt Period", "Change Ownership"]
.map(string => expect(wrapper.text().toLowerCase())
.toContain(string.toLowerCase()));
+ expect(wrapper.text().toLowerCase())
+ .toContain("Restart Firmware".toLowerCase());
+ });
+
+ it("doesn't render restart firmware", () => {
+ mockDev = true;
+ const p = fakeProps();
+ p.controlPanelState.power_and_reset = true;
+ const wrapper = mount();
+ expect(wrapper.text().toLowerCase())
+ .not.toContain("Restart Firmware".toLowerCase());
});
it("renders as closed", () => {
diff --git a/frontend/devices/components/fbos_settings/firmware_hardware_status.tsx b/frontend/devices/components/fbos_settings/firmware_hardware_status.tsx
index 84fd94fc7..b85c3b3f0 100644
--- a/frontend/devices/components/fbos_settings/firmware_hardware_status.tsx
+++ b/frontend/devices/components/fbos_settings/firmware_hardware_status.tsx
@@ -26,7 +26,7 @@ export const FirmwareHardwareStatusIcon =
return ;
};
-const lookup = (value: string | undefined) =>
+export const lookup = (value: string | undefined) =>
value && Object.keys(FIRMWARE_CHOICES_DDI).includes(value)
? FIRMWARE_CHOICES_DDI[value].label : undefined;
diff --git a/frontend/devices/components/fbos_settings/power_and_reset.tsx b/frontend/devices/components/fbos_settings/power_and_reset.tsx
index 2a9fb27c3..5464fc31c 100644
--- a/frontend/devices/components/fbos_settings/power_and_reset.tsx
+++ b/frontend/devices/components/fbos_settings/power_and_reset.tsx
@@ -9,6 +9,7 @@ import { Content, DeviceSetting } from "../../../constants";
import { reboot, powerOff, restartFirmware } from "../../actions";
import { t } from "../../../i18next_wrapper";
import { Highlight } from "../maybe_highlight";
+import { DevSettings } from "../../../account/dev/dev_support";
export function PowerAndReset(props: PowerAndResetProps) {
const { dispatch, sourceFbosConfig, botOnline } = props;
@@ -35,13 +36,14 @@ export function PowerAndReset(props: PowerAndResetProps) {
buttonText={t("SHUTDOWN")}
color={"red"}
action={powerOff} />
-
+ {!DevSettings.futureFeaturesEnabled() &&
+ }
-
-
-
+
-
;
}
diff --git a/frontend/devices/components/hardware_settings/encoders.tsx b/frontend/devices/components/hardware_settings/encoders.tsx
index 34eafd9f7..40a7fa219 100644
--- a/frontend/devices/components/hardware_settings/encoders.tsx
+++ b/frontend/devices/components/hardware_settings/encoders.tsx
@@ -7,6 +7,7 @@ import { Header } from "./header";
import { Collapse } from "@blueprintjs/core";
import { hasEncoders } from "../firmware_hardware_support";
import { Highlight } from "../maybe_highlight";
+import { SpacePanelHeader } from "./space_panel_header";
export function Encoders(props: EncodersProps) {
@@ -30,6 +31,9 @@ export function Encoders(props: EncodersProps) {
panel={"encoders"}
dispatch={dispatch} />
+
+
+
+
+
+
+
+
+
+
+
+
=> {
@@ -43,6 +44,9 @@ export function Motors(props: MotorsProps) {
panel={"motors"}
dispatch={dispatch} />
+
+
+
;
HOMING_PANEL.map(s => SETTING_PANEL_LOOKUP[s] = "homing_and_calibration");
@@ -86,6 +116,9 @@ PIN_GUARD_PANEL.map(s => SETTING_PANEL_LOOKUP[s] = "pin_guard");
DANGER_ZONE_PANEL.map(s => SETTING_PANEL_LOOKUP[s] = "danger_zone");
PIN_BINDINGS_PANEL.map(s => SETTING_PANEL_LOOKUP[s] = "pin_bindings");
POWER_AND_RESET_PANEL.map(s => SETTING_PANEL_LOOKUP[s] = "power_and_reset");
+FARM_DESIGNER_PANEL.map(s => SETTING_PANEL_LOOKUP[s] = "farm_designer");
+FIRMWARE_PANEL.map(s => SETTING_PANEL_LOOKUP[s] = "firmware");
+FARMBOT_PANEL.map(s => SETTING_PANEL_LOOKUP[s] = "farmbot_os");
/** Keep string up until first `(` character (trailing whitespace removed). */
const stripUnits = (settingName: string) => trim(settingName.split("(")[0]);
diff --git a/frontend/devices/interfaces.ts b/frontend/devices/interfaces.ts
index 566c863aa..7335c30a1 100644
--- a/frontend/devices/interfaces.ts
+++ b/frontend/devices/interfaces.ts
@@ -254,4 +254,7 @@ export interface ControlPanelState {
danger_zone: boolean;
pin_bindings: boolean;
power_and_reset: boolean;
+ farm_designer: boolean;
+ firmware: boolean;
+ farmbot_os: boolean;
}
diff --git a/frontend/devices/reducer.ts b/frontend/devices/reducer.ts
index 9e0ef7416..daffac9c7 100644
--- a/frontend/devices/reducer.ts
+++ b/frontend/devices/reducer.ts
@@ -32,7 +32,10 @@ export const initialState = (): BotState => ({
pin_bindings: false,
danger_zone: false,
power_and_reset: false,
- pin_guard: false
+ pin_guard: false,
+ farm_designer: false,
+ firmware: false,
+ farmbot_os: false,
},
hardware: {
gpio_registry: {},
@@ -124,6 +127,10 @@ export const botReducer = generateReducer(initialState())
s.controlPanelState.pin_bindings = a.payload;
s.controlPanelState.pin_guard = a.payload;
s.controlPanelState.danger_zone = a.payload;
+ s.controlPanelState.power_and_reset = a.payload;
+ s.controlPanelState.farm_designer = a.payload;
+ s.controlPanelState.firmware = a.payload;
+ s.controlPanelState.farmbot_os = a.payload;
return s;
})
.add(Actions.FETCH_OS_UPDATE_INFO_OK, (s, { payload }) => {
diff --git a/frontend/nav/__tests__/nav_links_test.tsx b/frontend/nav/__tests__/nav_links_test.tsx
index db3682ccb..81547832a 100644
--- a/frontend/nav/__tests__/nav_links_test.tsx
+++ b/frontend/nav/__tests__/nav_links_test.tsx
@@ -3,6 +3,11 @@ jest.mock("../../history", () => ({
getPathArray: jest.fn(() => mockPath.split("/")),
}));
+let mockDev = false;
+jest.mock("../../account/dev/dev_support", () => ({
+ DevSettings: { futureFeaturesEnabled: () => mockDev }
+}));
+
import * as React from "react";
import { shallow, mount } from "enzyme";
import { NavLinks } from "../nav_links";
@@ -27,6 +32,12 @@ describe("", () => {
expect(wrapper.text().toLowerCase()).not.toContain("tools");
});
+ it("doesn't show link", () => {
+ mockDev = true;
+ const wrapper = mount();
+ expect(wrapper.text().toLowerCase()).not.toContain("device");
+ });
+
it("shows active link", () => {
mockPath = "/app/designer";
const wrapper = shallow();
diff --git a/frontend/nav/nav_links.tsx b/frontend/nav/nav_links.tsx
index 4ddfca62e..87cdfcbb8 100644
--- a/frontend/nav/nav_links.tsx
+++ b/frontend/nav/nav_links.tsx
@@ -7,6 +7,7 @@ import {
import { Link } from "../link";
import { t } from "../i18next_wrapper";
import { betterCompact } from "../util";
+import { DevSettings } from "../account/dev/dev_support";
/** Uses a slug and a child path to compute the `href` of a navbar link. */
export type LinkComputeFn = (slug: string, childPath: string) => string;
@@ -27,7 +28,8 @@ interface NavLinkParams {
export const getLinks = (): NavLinkParams[] => betterCompact([
{ name: "Farm Designer", icon: "leaf", slug: "designer" },
{ name: "Controls", icon: "keyboard-o", slug: "controls" },
- { name: "Device", icon: "cog", slug: "device" },
+ DevSettings.futureFeaturesEnabled() ? undefined :
+ { name: "Device", icon: "cog", slug: "device" },
{
name: "Sequences", icon: "server", slug: "sequences",
computeHref: computeEditorUrlFromState("Sequence")