peripheral form updates
parent
fd57e05074
commit
9a35a52c2b
|
@ -34,21 +34,26 @@ describe("<Peripherals />", () => {
|
||||||
expect(wrapper.instance().state.isEditing).toBeTruthy();
|
expect(wrapper.instance().state.isEditing).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
function attemptSave(num: number, errorString: string) {
|
it("save attempt: pin number undefined", () => {
|
||||||
const p = fakeProps();
|
const p = fakeProps();
|
||||||
p.peripherals[0].body.pin = num;
|
p.peripherals[0].body.pin = undefined;
|
||||||
p.peripherals[0].specialStatus = SpecialStatus.DIRTY;
|
p.peripherals[0].specialStatus = SpecialStatus.DIRTY;
|
||||||
const wrapper = mount(<Peripherals {...p} />);
|
const wrapper = mount(<Peripherals {...p} />);
|
||||||
clickButton(wrapper, 1, "save", { partial_match: true });
|
clickButton(wrapper, 1, "save", { partial_match: true });
|
||||||
expect(error).toHaveBeenLastCalledWith(errorString);
|
expect(error).toHaveBeenLastCalledWith("Please select a pin.");
|
||||||
}
|
expect(p.dispatch).not.toHaveBeenCalled();
|
||||||
|
|
||||||
it("save attempt: pin number too small", () => {
|
|
||||||
attemptSave(0, "Pin numbers are required and must be positive and unique.");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("save attempt: pin number too large", () => {
|
it("save attempt: pin number not unique", () => {
|
||||||
attemptSave(9999, "Pin numbers must be less than 1000.");
|
const p = fakeProps();
|
||||||
|
p.peripherals = [fakePeripheral(), fakePeripheral()];
|
||||||
|
p.peripherals[0].body.pin = 1;
|
||||||
|
p.peripherals[1].body.pin = 1;
|
||||||
|
p.peripherals[0].specialStatus = SpecialStatus.DIRTY;
|
||||||
|
const wrapper = mount(<Peripherals {...p} />);
|
||||||
|
clickButton(wrapper, 1, "save", { partial_match: true });
|
||||||
|
expect(error).toHaveBeenLastCalledWith("Pin numbers must be unique.");
|
||||||
|
expect(p.dispatch).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("saves", () => {
|
it("saves", () => {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
|
||||||
import { error } from "farmbot-toastr";
|
import { error } from "farmbot-toastr";
|
||||||
import { PeripheralList } from "./peripheral_list";
|
import { PeripheralList } from "./peripheral_list";
|
||||||
import { PeripheralForm } from "./peripheral_form";
|
import { PeripheralForm } from "./peripheral_form";
|
||||||
|
@ -9,7 +8,7 @@ import { PeripheralState } from "./interfaces";
|
||||||
import { getArrayStatus } from "../../resources/tagged_resources";
|
import { getArrayStatus } from "../../resources/tagged_resources";
|
||||||
import { saveAll, init } from "../../api/crud";
|
import { saveAll, init } from "../../api/crud";
|
||||||
import { ToolTips } from "../../constants";
|
import { ToolTips } from "../../constants";
|
||||||
import { uniq } from "lodash";
|
import { uniq, isNumber } from "lodash";
|
||||||
import { t } from "../../i18next_wrapper";
|
import { t } from "../../i18next_wrapper";
|
||||||
|
|
||||||
export class Peripherals
|
export class Peripherals
|
||||||
|
@ -23,22 +22,16 @@ export class Peripherals
|
||||||
|
|
||||||
maybeSave = () => {
|
maybeSave = () => {
|
||||||
const { peripherals } = this.props;
|
const { peripherals } = this.props;
|
||||||
const pinNums = peripherals.map(x => x.body.pin);
|
const pins = peripherals.map(x => x.body.pin);
|
||||||
const positivePins = pinNums.filter(x => x && x > 0);
|
const allAreUniq = uniq(pins).length === pins.length;
|
||||||
const smallPins = pinNums.filter(x => x && x < 1000);
|
const allArePins = pins.filter(x => isNumber(x)).length === pins.length;
|
||||||
// I hate adding client side validation, but this is a wonky endpoint - RC.
|
if (!allArePins) {
|
||||||
const allAreUniq = uniq(pinNums).length === pinNums.length;
|
return error(t("Please select a pin."));
|
||||||
const allArePositive = positivePins.length === pinNums.length;
|
|
||||||
const allAreSmall = smallPins.length === pinNums.length;
|
|
||||||
if (allAreUniq && allArePositive) {
|
|
||||||
if (allAreSmall) {
|
|
||||||
this.props.dispatch(saveAll(this.props.peripherals, this.toggle));
|
|
||||||
} else {
|
|
||||||
error(t("Pin numbers must be less than 1000."));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
error(t("Pin numbers are required and must be positive and unique."));
|
|
||||||
}
|
}
|
||||||
|
if (!allAreUniq) {
|
||||||
|
return error(t("Pin numbers must be unique."));
|
||||||
|
}
|
||||||
|
this.props.dispatch(saveAll(this.props.peripherals, this.toggle));
|
||||||
}
|
}
|
||||||
|
|
||||||
showPins = () => {
|
showPins = () => {
|
||||||
|
@ -56,7 +49,10 @@ export class Peripherals
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newPeripheral = (pin = 0, label = t("New Peripheral")) => {
|
newPeripheral = (
|
||||||
|
pin: number | undefined = undefined,
|
||||||
|
label = t("New Peripheral")
|
||||||
|
) => {
|
||||||
this.props.dispatch(init("Peripheral", { pin, label }));
|
this.props.dispatch(init("Peripheral", { pin, label }));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { PIN_MODES } from "../sequences/step_tiles/tile_pin_support";
|
||||||
import { t } from "../i18next_wrapper";
|
import { t } from "../i18next_wrapper";
|
||||||
import { TaggedPeripheral, TaggedSensor } from "farmbot";
|
import { TaggedPeripheral, TaggedSensor } from "farmbot";
|
||||||
import { UUID } from "../resources/interfaces";
|
import { UUID } from "../resources/interfaces";
|
||||||
|
import { isNumber } from "lodash";
|
||||||
|
|
||||||
const MODES: { [s: string]: string } = {
|
const MODES: { [s: string]: string } = {
|
||||||
0: t("Digital"),
|
0: t("Digital"),
|
||||||
|
@ -36,8 +37,9 @@ interface PinDropdownProps {
|
||||||
|
|
||||||
export const PinDropdown = (props: PinDropdownProps) =>
|
export const PinDropdown = (props: PinDropdownProps) =>
|
||||||
<FBSelect
|
<FBSelect
|
||||||
selectedItem={
|
selectedItem={isNumber(props.value)
|
||||||
{ label: t("Pin ") + `${props.value}`, value: props.value || "" }}
|
? { label: t("Pin ") + `${props.value}`, value: props.value || "" }
|
||||||
|
: { label: t("Select a pin "), value: "" }}
|
||||||
onChange={d => props.dispatch(edit(props.resource, {
|
onChange={d => props.dispatch(edit(props.resource, {
|
||||||
pin: parseInt(d.value.toString(), 10)
|
pin: parseInt(d.value.toString(), 10)
|
||||||
}))}
|
}))}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { EditPlantInfoProps, PlantOptions } from "../interfaces";
|
||||||
import { isString, isUndefined } from "lodash";
|
import { isString, isUndefined } from "lodash";
|
||||||
import { history, getPathArray } from "../../history";
|
import { history, getPathArray } from "../../history";
|
||||||
import { destroy, edit, save } from "../../api/crud";
|
import { destroy, edit, save } from "../../api/crud";
|
||||||
import { BooleanConfigKey } from "farmbot/dist/resources/configs/web_app";
|
import { BooleanSetting } from "../../session_keys";
|
||||||
|
|
||||||
@connect(mapStateToProps)
|
@connect(mapStateToProps)
|
||||||
export class PlantInfo extends React.Component<EditPlantInfoProps, {}> {
|
export class PlantInfo extends React.Component<EditPlantInfoProps, {}> {
|
||||||
|
@ -19,7 +19,7 @@ export class PlantInfo extends React.Component<EditPlantInfoProps, {}> {
|
||||||
get plant() { return this.props.findPlant(this.stringyID); }
|
get plant() { return this.props.findPlant(this.stringyID); }
|
||||||
get confirmDelete() {
|
get confirmDelete() {
|
||||||
const confirmSetting = this.props.getConfigValue(
|
const confirmSetting = this.props.getConfigValue(
|
||||||
"confirm_plant_deletion" as BooleanConfigKey);
|
BooleanSetting.confirm_plant_deletion);
|
||||||
return isUndefined(confirmSetting) ? true : confirmSetting;
|
return isUndefined(confirmSetting) ? true : confirmSetting;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,7 @@ const DESIGNER_SETTINGS =
|
||||||
{
|
{
|
||||||
title: t("Confirm plant deletion"),
|
title: t("Confirm plant deletion"),
|
||||||
description: t(Content.CONFIRM_PLANT_DELETION),
|
description: t(Content.CONFIRM_PLANT_DELETION),
|
||||||
setting: "confirm_plant_deletion" as BooleanConfigKey,
|
setting: BooleanSetting.confirm_plant_deletion,
|
||||||
defaultOn: true,
|
defaultOn: true,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
Loading…
Reference in New Issue