commit
b3eb1fff13
|
@ -1 +1 @@
|
|||
<%# Intentionally blank template required by router for content generated by frontend. %>
|
||||
<h1 class="initial-loading-text">Loading...</h1>
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
<h1 class="initial-loading-text">Loading...</h1>
|
||||
<%# Intentionally blank template required by router for content generated by frontend. %>
|
||||
|
|
|
@ -12,27 +12,45 @@ describe("<SensorList/>", function () {
|
|||
const fakeProps = (): SensorListProps => {
|
||||
const pins: Pins = {
|
||||
50: {
|
||||
mode: 0,
|
||||
value: 1
|
||||
mode: 1,
|
||||
value: 500,
|
||||
},
|
||||
51: {
|
||||
mode: 1,
|
||||
value: 500
|
||||
}
|
||||
mode: 0,
|
||||
value: 1,
|
||||
},
|
||||
52: {
|
||||
mode: 0,
|
||||
value: 1,
|
||||
},
|
||||
53: {
|
||||
mode: 0,
|
||||
value: 0,
|
||||
},
|
||||
};
|
||||
const fakeSensor1 = fakeSensor();
|
||||
const fakeSensor2 = fakeSensor();
|
||||
const fakeSensor3 = fakeSensor();
|
||||
const fakeSensor4 = fakeSensor();
|
||||
fakeSensor1.body.id = 1;
|
||||
fakeSensor1.body.pin = 51;
|
||||
fakeSensor1.body.mode = 1;
|
||||
fakeSensor1.body.mode = 0;
|
||||
fakeSensor1.body.label = "GPIO 51";
|
||||
fakeSensor2.body.id = 2;
|
||||
fakeSensor2.body.pin = 50;
|
||||
fakeSensor2.body.mode = 0;
|
||||
fakeSensor2.body.mode = 1;
|
||||
fakeSensor2.body.label = "GPIO 50 - Moisture";
|
||||
fakeSensor3.body.id = 3;
|
||||
fakeSensor3.body.pin = 52;
|
||||
fakeSensor3.body.mode = 0;
|
||||
fakeSensor3.body.label = "GPIO 52 - Tool Verification";
|
||||
fakeSensor4.body.id = 4;
|
||||
fakeSensor4.body.pin = 53;
|
||||
fakeSensor4.body.mode = 0;
|
||||
fakeSensor4.body.label = "GPIO 53 - Tool Verification";
|
||||
return {
|
||||
dispatch: jest.fn(),
|
||||
sensors: [fakeSensor2, fakeSensor1],
|
||||
sensors: [fakeSensor2, fakeSensor1, fakeSensor3, fakeSensor4],
|
||||
pins,
|
||||
disabled: false
|
||||
};
|
||||
|
@ -42,12 +60,18 @@ describe("<SensorList/>", function () {
|
|||
const wrapper = mount(<SensorList {...fakeProps()} />);
|
||||
const labels = wrapper.find("label");
|
||||
const pinNumbers = wrapper.find("p");
|
||||
expect(labels.first().text()).toEqual("GPIO 51");
|
||||
expect(pinNumbers.first().text()).toEqual("51");
|
||||
expect(wrapper.find(".indicator").first().text()).toEqual("500");
|
||||
expect(labels.last().text()).toEqual("GPIO 50 - Moisture");
|
||||
expect(pinNumbers.last().text()).toEqual("50");
|
||||
expect(wrapper.find(".indicator").last().text()).toEqual("1");
|
||||
expect(labels.at(0).text()).toEqual("GPIO 51");
|
||||
expect(pinNumbers.at(0).text()).toEqual("51");
|
||||
expect(wrapper.find(".indicator").at(0).text()).toEqual("1");
|
||||
expect(labels.at(1).text()).toEqual("GPIO 50 - Moisture");
|
||||
expect(pinNumbers.at(1).text()).toEqual("50");
|
||||
expect(wrapper.find(".indicator").at(1).text()).toEqual("500");
|
||||
expect(labels.at(2).text()).toEqual("GPIO 52 - Tool Verification");
|
||||
expect(pinNumbers.at(2).text()).toEqual("52");
|
||||
expect(wrapper.find(".indicator").at(2).text()).toEqual("1 (NO TOOL)");
|
||||
expect(labels.at(3).text()).toEqual("GPIO 53 - Tool Verification");
|
||||
expect(pinNumbers.at(3).text()).toEqual("53");
|
||||
expect(wrapper.find(".indicator").at(3).text()).toEqual("0 (TOOL ON)");
|
||||
});
|
||||
|
||||
const expectedPayload = (pin_number: number, pin_mode: 0 | 1) =>
|
||||
|
@ -60,10 +84,10 @@ describe("<SensorList/>", function () {
|
|||
it("reads sensors", () => {
|
||||
const wrapper = mount(<SensorList {...fakeProps()} />);
|
||||
const readSensorBtn = wrapper.find("button");
|
||||
readSensorBtn.first().simulate("click");
|
||||
expect(mockDevice.readPin).toHaveBeenCalledWith(expectedPayload(51, 1));
|
||||
readSensorBtn.last().simulate("click");
|
||||
expect(mockDevice.readPin).toHaveBeenLastCalledWith(expectedPayload(50, 0));
|
||||
readSensorBtn.at(0).simulate("click");
|
||||
expect(mockDevice.readPin).toHaveBeenCalledWith(expectedPayload(51, 0));
|
||||
readSensorBtn.at(1).simulate("click");
|
||||
expect(mockDevice.readPin).toHaveBeenLastCalledWith(expectedPayload(50, 1));
|
||||
expect(mockDevice.readPin).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
|
|
|
@ -38,11 +38,17 @@ const SensorReadingDisplay =
|
|||
({ label, value, mode }: SensorReadingDisplayProps) => {
|
||||
const moistureSensor = label.toLowerCase().includes("moisture") ?
|
||||
"moisture-sensor" : "";
|
||||
return <div className={`sensor-reading-display ${moistureSensor}`}>
|
||||
const toolSensor = label.toLowerCase().includes("verification") ?
|
||||
"tool-verification-sensor" : "";
|
||||
const valueLabel = toolSensor
|
||||
? `${value} (${value ? t("NO TOOL") : t("TOOL ON")})`
|
||||
: value;
|
||||
return <div
|
||||
className={`sensor-reading-display ${moistureSensor} ${toolSensor}`}>
|
||||
{isNumber(value) && value >= 0 &&
|
||||
<div className="indicator" style={calcIndicatorStyle({ value, mode })}>
|
||||
<span style={calcValueStyle({ value, mode })}>
|
||||
{value}
|
||||
{valueLabel}
|
||||
</span>
|
||||
</div>}
|
||||
</div>;
|
||||
|
|
|
@ -312,6 +312,15 @@
|
|||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.step-block {
|
||||
display: flex;
|
||||
padding: 0;
|
||||
.step-block-drag {
|
||||
width: 100%;
|
||||
padding: 0.2rem 0.8rem;
|
||||
line-height: 3rem;
|
||||
}
|
||||
}
|
||||
&.quick-del {
|
||||
&:hover {
|
||||
background: lighten($red, 10%) !important;
|
||||
|
@ -334,6 +343,8 @@
|
|||
float: right;
|
||||
font-size: 1.4rem !important;
|
||||
padding-left: 1rem;
|
||||
line-height: 3rem;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.fb-toggle-button {
|
||||
|
|
|
@ -1195,6 +1195,11 @@ ul {
|
|||
&.moisture-sensor {
|
||||
background: linear-gradient(to right, rgba($blue, 0) 20%, $blue 80%, rgba($blue, 0) 85%);
|
||||
}
|
||||
&.tool-verification-sensor {
|
||||
span {
|
||||
margin-left: 3.5rem !important;
|
||||
}
|
||||
}
|
||||
border-style: solid;
|
||||
border-color: $dark_gray;
|
||||
border-width: 0.1px;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import React from "react";
|
||||
import { OtaTimeSelector, changeOtaHour, assertIsHour } from "..";
|
||||
import { OtaTimeSelector, changeOtaHour, assertIsHour } from "../ota_time_selector";
|
||||
import { shallow } from "enzyme";
|
||||
import { FBSelect } from "../../../../../ui";
|
||||
import { fakeDevice } from "../../../../../__test_support__/resource_index_builder";
|
||||
import { FBSelect } from "../../../../ui";
|
||||
import { fakeDevice } from "../../../../__test_support__/resource_index_builder";
|
||||
|
||||
describe("OTA time selector", () => {
|
||||
it("asserts that a variable is an HOUR", () => {
|
|
@ -1,9 +1,9 @@
|
|||
import { DropDownItem, FBSelect, Row, Col } from "../../../../ui";
|
||||
import { DropDownItem, FBSelect, Row, Col } from "../../../ui";
|
||||
import React from "react";
|
||||
import { t } from "../../../../i18next_wrapper";
|
||||
import { t } from "../../../i18next_wrapper";
|
||||
import { TaggedDevice } from "farmbot";
|
||||
import { edit, save } from "../../../../api/crud";
|
||||
import { ColWidth } from "../../farmbot_os_settings";
|
||||
import { edit, save } from "../../../api/crud";
|
||||
import { ColWidth } from "../farmbot_os_settings";
|
||||
|
||||
// tslint:disable-next-line:no-null-keyword
|
||||
const UNDEFINED = null as unknown as undefined;
|
|
@ -64,18 +64,22 @@ export class RawFarmDesigner extends React.Component<Props, Partial<State>> {
|
|||
return isBotOriginQuadrant(value) ? value : 2;
|
||||
}
|
||||
|
||||
state: State = {
|
||||
legend_menu_open: this.initializeSetting(BooleanSetting.legend_menu_open, false),
|
||||
show_plants: this.initializeSetting(BooleanSetting.show_plants, true),
|
||||
show_points: this.initializeSetting(BooleanSetting.show_points, true),
|
||||
show_spread: this.initializeSetting(BooleanSetting.show_spread, false),
|
||||
show_farmbot: this.initializeSetting(BooleanSetting.show_farmbot, true),
|
||||
show_images: this.initializeSetting(BooleanSetting.show_images, false),
|
||||
show_sensor_readings: this.initializeSetting(
|
||||
BooleanSetting.show_sensor_readings, false),
|
||||
bot_origin_quadrant: this.getBotOriginQuadrant(),
|
||||
zoom_level: calcZoomLevel(getZoomLevelIndex(this.props.getConfigValue))
|
||||
};
|
||||
getState(): State {
|
||||
const init = this.initializeSetting;
|
||||
return {
|
||||
legend_menu_open: init(BooleanSetting.legend_menu_open, false),
|
||||
show_plants: init(BooleanSetting.show_plants, true),
|
||||
show_points: init(BooleanSetting.show_points, true),
|
||||
show_spread: init(BooleanSetting.show_spread, false),
|
||||
show_farmbot: init(BooleanSetting.show_farmbot, true),
|
||||
show_images: init(BooleanSetting.show_images, false),
|
||||
show_sensor_readings: init(BooleanSetting.show_sensor_readings, false),
|
||||
bot_origin_quadrant: this.getBotOriginQuadrant(),
|
||||
zoom_level: calcZoomLevel(getZoomLevelIndex(this.props.getConfigValue)),
|
||||
};
|
||||
}
|
||||
|
||||
state: State = this.getState();
|
||||
|
||||
componentDidMount() {
|
||||
this.updateBotOriginQuadrant(this.state.bot_origin_quadrant)();
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
const mockDevice = { setUserEnv: jest.fn(() => Promise.resolve({})) };
|
||||
|
||||
jest.mock("../../../device", () => ({
|
||||
getDevice: () => {
|
||||
return mockDevice;
|
||||
}
|
||||
}));
|
||||
jest.mock("../../../device", () => ({ getDevice: () => mockDevice }));
|
||||
|
||||
jest.mock("../actions", () => ({ scanImage: jest.fn() }));
|
||||
jest.mock("../../images/actions", () => ({ selectImage: jest.fn() }));
|
||||
|
@ -90,4 +85,14 @@ describe("<CameraCalibration/>", () => {
|
|||
expect(p.saveFarmwareEnv)
|
||||
.toHaveBeenCalledWith("CAMERA_CALIBRATION_camera_offset_x", "10");
|
||||
});
|
||||
|
||||
it("saves string WeedDetectorConfig changes: API", () => {
|
||||
const p = fakeProps();
|
||||
p.shouldDisplay = () => true;
|
||||
const wrapper = shallow(<CameraCalibration {...p} />);
|
||||
wrapper.find("WeedDetectorConfig")
|
||||
.simulate("change", "CAMERA_CALIBRATION_image_bot_origin_location", 4);
|
||||
expect(p.saveFarmwareEnv).toHaveBeenCalledWith(
|
||||
"CAMERA_CALIBRATION_image_bot_origin_location", "\"BOTTOM_LEFT\"");
|
||||
});
|
||||
});
|
||||
|
|
|
@ -12,6 +12,7 @@ import { WeedDetectorConfig } from "../weed_detector/config";
|
|||
import { Feature } from "../../devices/interfaces";
|
||||
import { namespace } from "../weed_detector";
|
||||
import { t } from "../../i18next_wrapper";
|
||||
import { formatEnvKey } from "../weed_detector/remote_env/translators";
|
||||
|
||||
export class CameraCalibration extends
|
||||
React.Component<CameraCalibrationProps, {}> {
|
||||
|
@ -23,7 +24,8 @@ export class CameraCalibration extends
|
|||
|
||||
saveEnvVar = (key: WDENVKey, value: number) =>
|
||||
this.props.shouldDisplay(Feature.api_farmware_env)
|
||||
? this.props.dispatch(this.props.saveFarmwareEnv(key, "" + value))
|
||||
? this.props.dispatch(this.props.saveFarmwareEnv(
|
||||
key, JSON.stringify(formatEnvKey(key, value))))
|
||||
: envSave(key, value)
|
||||
|
||||
render() {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import * as React from "react";
|
||||
import { StepButtonParams } from "../../interfaces";
|
||||
import { StepButton, stepClick } from "../index";
|
||||
import { StepButtonParams } from "../interfaces";
|
||||
import { StepButton, stepClick } from "../step_buttons";
|
||||
import { shallow } from "enzyme";
|
||||
import { fakeSequence } from "../../../__test_support__/fake_state/resources";
|
||||
import { Actions } from "../../../constants";
|
||||
import { error } from "../../../toast/toast";
|
||||
import { fakeSequence } from "../../__test_support__/fake_state/resources";
|
||||
import { Actions } from "../../constants";
|
||||
import { error } from "../../toast/toast";
|
||||
|
||||
function props(): StepButtonParams {
|
||||
return {
|
|
@ -1,5 +1,5 @@
|
|||
import * as React from "react";
|
||||
import { StepButton } from "./step_buttons/index";
|
||||
import { StepButton } from "./step_buttons";
|
||||
import { scrollToBottom } from "../util";
|
||||
import { Row } from "../ui/index";
|
||||
import { TaggedSequence } from "farmbot";
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import * as React from "react";
|
||||
import { SequenceBodyItem as Step, TaggedSequence } from "farmbot";
|
||||
import { error } from "../../toast/toast";
|
||||
import { StepDragger, NULL_DRAGGER_ID } from "../../draggable/step_dragger";
|
||||
import { pushStep, closeCommandMenu } from "../actions";
|
||||
import { StepButtonParams } from "../interfaces";
|
||||
import { Col } from "../../ui/index";
|
||||
import { t } from "../../i18next_wrapper";
|
||||
import { error } from "../toast/toast";
|
||||
import { StepDragger, NULL_DRAGGER_ID } from "../draggable/step_dragger";
|
||||
import { pushStep, closeCommandMenu } from "./actions";
|
||||
import { StepButtonParams } from "./interfaces";
|
||||
import { Col } from "../ui/index";
|
||||
import { t } from "../i18next_wrapper";
|
||||
|
||||
export const stepClick =
|
||||
(dispatch: Function,
|
||||
|
@ -29,10 +29,12 @@ export function StepButton({ children, step, color, dispatch, current, index }:
|
|||
intent="step_splice"
|
||||
draggerId={NULL_DRAGGER_ID}>
|
||||
<button draggable={true}
|
||||
className={`fb-button full-width block ${color}`}
|
||||
className={`fb-button full-width block step-block ${color}`}
|
||||
onClick={stepClick(dispatch, step, current, index)}>
|
||||
{children}
|
||||
<i className="fa fa-arrows block-control" />
|
||||
<div className="step-block-drag">
|
||||
{children}
|
||||
<i className="fa fa-arrows block-control" />
|
||||
</div>
|
||||
</button>
|
||||
</StepDragger>
|
||||
</div>
|
Loading…
Reference in New Issue