2017-06-29 12:54:02 -06:00
|
|
|
import * as React from "react";
|
2018-08-01 18:20:50 -06:00
|
|
|
import {
|
|
|
|
CeleryNode, LegalArgString, If, Execute, Nothing,
|
|
|
|
SequenceBodyItem as Step, TaggedSequence
|
|
|
|
} from "farmbot";
|
2018-07-13 14:56:01 -06:00
|
|
|
import { FLOAT_NUMERIC_FIELDS, NUMERIC_FIELDS } from "../interfaces";
|
2017-06-29 12:54:02 -06:00
|
|
|
import { ExecuteBlock } from "./tile_execute";
|
2017-08-01 13:21:23 -06:00
|
|
|
import { StepParams, StepInputProps, StepTitleBarProps } from "../interfaces";
|
2018-02-27 09:02:35 -07:00
|
|
|
import { defensiveClone, move as arrayMover } from "../../util";
|
2017-06-29 12:54:02 -06:00
|
|
|
import { TileIf } from "./tile_if";
|
|
|
|
import { TileWait } from "./tile_wait";
|
|
|
|
import { TileMoveAbsolute } from "./tile_move_absolute";
|
|
|
|
import { TileMoveRelative } from "./tile_move_relative";
|
|
|
|
import { TileReadPin } from "./tile_read_pin";
|
|
|
|
import { TileSendMessage } from "./tile_send_message";
|
|
|
|
import { TileWritePin } from "./tile_write_pin";
|
|
|
|
import { TileExecuteScript } from "./tile_execute_script";
|
|
|
|
import { TileTakePhoto } from "./tile_take_photo";
|
|
|
|
import { overwrite } from "../../api/crud";
|
|
|
|
import { TileFindHome } from "./tile_find_home";
|
2018-09-06 08:53:48 -06:00
|
|
|
import { MarkAs } from "./mark_as";
|
2018-11-12 14:06:52 -07:00
|
|
|
import { TileUnknown } from "./tile_unknown";
|
2018-11-12 15:13:27 -07:00
|
|
|
import { forceSetStepTag } from "../../resources/sequence_tagging";
|
2019-02-04 07:32:26 -07:00
|
|
|
import { compact, assign } from "lodash";
|
2019-02-26 20:12:02 -07:00
|
|
|
import { TileSetServoAngle } from "./tile_set_servo_angle";
|
|
|
|
import { TileSystemAction } from "./tile_system_action";
|
|
|
|
import { TileTogglePin } from "./tile_toggle_pin";
|
|
|
|
import { TileFirmwareAction } from "./tile_firmware_action";
|
|
|
|
import { TileSetZero } from "./tile_set_zero";
|
|
|
|
import { TileCalibrate } from "./tile_calibrate";
|
|
|
|
import { TileMoveHome } from "./tile_move_home";
|
2019-04-02 13:59:37 -06:00
|
|
|
import { t } from "../../i18next_wrapper";
|
2019-08-22 09:02:54 -06:00
|
|
|
import { TileAssertion } from "./tile_assertion";
|
2019-12-21 21:43:41 -07:00
|
|
|
import { TileEmergencyStop } from "./tile_emergency_stop";
|
2019-12-26 09:25:03 -07:00
|
|
|
import { TileReboot } from "./tile_reboot";
|
2017-06-29 12:54:02 -06:00
|
|
|
|
|
|
|
interface MoveParams {
|
|
|
|
step: Step;
|
|
|
|
to: number;
|
|
|
|
from: number;
|
|
|
|
sequence: TaggedSequence
|
|
|
|
}
|
|
|
|
|
|
|
|
export function move({ step, sequence, to, from }: MoveParams) {
|
2017-08-28 05:49:13 -06:00
|
|
|
const copy = defensiveClone(step);
|
|
|
|
const next = defensiveClone(sequence);
|
|
|
|
const seq = next.body;
|
2017-06-29 12:54:02 -06:00
|
|
|
seq.body = seq.body || [];
|
|
|
|
if (from > to) {
|
2017-07-18 09:34:39 -06:00
|
|
|
seq.body = arrayMover(seq.body, from, to);
|
2017-06-29 12:54:02 -06:00
|
|
|
} else {
|
|
|
|
seq.body.splice(to, 0, defensiveClone(copy));
|
|
|
|
delete seq.body[from];
|
2019-02-04 07:32:26 -07:00
|
|
|
seq.body = compact(seq.body);
|
2017-06-29 12:54:02 -06:00
|
|
|
}
|
|
|
|
return overwrite(sequence, next.body);
|
2017-07-18 09:34:39 -06:00
|
|
|
}
|
2017-06-29 12:54:02 -06:00
|
|
|
|
|
|
|
interface CopyParams {
|
|
|
|
step: Step;
|
|
|
|
index: number;
|
|
|
|
sequence: TaggedSequence
|
|
|
|
}
|
|
|
|
|
|
|
|
export function splice({ step, sequence, index }: CopyParams) {
|
2018-11-12 15:13:27 -07:00
|
|
|
const copy = forceSetStepTag(defensiveClone(step));
|
2017-08-28 05:49:13 -06:00
|
|
|
const next = defensiveClone(sequence);
|
|
|
|
const seq = next.body;
|
2017-06-29 12:54:02 -06:00
|
|
|
seq.body = seq.body || [];
|
|
|
|
seq.body.splice(index, 0, copy);
|
|
|
|
return overwrite(sequence, next.body);
|
2017-07-18 09:34:39 -06:00
|
|
|
}
|
2017-06-29 12:54:02 -06:00
|
|
|
|
|
|
|
interface RemoveParams {
|
|
|
|
index: number;
|
|
|
|
dispatch: Function;
|
|
|
|
sequence: TaggedSequence;
|
2018-08-30 19:25:58 -06:00
|
|
|
confirmStepDeletion: boolean;
|
2017-06-29 12:54:02 -06:00
|
|
|
}
|
|
|
|
|
2018-08-30 19:25:58 -06:00
|
|
|
export function remove(props: RemoveParams) {
|
|
|
|
const { dispatch, index, sequence, confirmStepDeletion } = props;
|
|
|
|
if (!confirmStepDeletion ||
|
2017-10-04 20:05:58 -06:00
|
|
|
confirm(t("Are you sure you want to delete this step?"))) {
|
|
|
|
const original = sequence;
|
|
|
|
const update = defensiveClone(original);
|
|
|
|
update.body.body = (update.body.body || []);
|
|
|
|
delete update.body.body[index];
|
2019-02-04 07:32:26 -07:00
|
|
|
update.body.body = compact(update.body.body);
|
2017-10-04 20:05:58 -06:00
|
|
|
dispatch(overwrite(original, update.body));
|
|
|
|
}
|
2017-06-29 12:54:02 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
export function updateStep(props: StepInputProps) {
|
|
|
|
return (e: React.FormEvent<HTMLInputElement>) => {
|
2017-08-28 05:49:13 -06:00
|
|
|
const { dispatch, step, index, sequence, field } = props;
|
|
|
|
const stepCopy = defensiveClone(step);
|
|
|
|
const seqCopy = defensiveClone(sequence).body;
|
|
|
|
const val = e.currentTarget.value;
|
|
|
|
const isNumeric = NUMERIC_FIELDS.includes(field);
|
2017-06-29 12:54:02 -06:00
|
|
|
seqCopy.body = seqCopy.body || [];
|
|
|
|
|
|
|
|
if (isNumeric) {
|
|
|
|
numericNonsense(val, stepCopy, field);
|
|
|
|
} else {
|
2019-02-04 07:32:26 -07:00
|
|
|
assign(stepCopy.args, { [field]: val });
|
2017-07-18 09:34:39 -06:00
|
|
|
}
|
2017-06-29 12:54:02 -06:00
|
|
|
|
|
|
|
seqCopy.body[index] = stepCopy;
|
2018-02-27 09:02:35 -07:00
|
|
|
dispatch(overwrite(sequence, seqCopy));
|
2017-06-29 12:54:02 -06:00
|
|
|
};
|
2017-07-18 09:34:39 -06:00
|
|
|
}
|
2017-06-29 12:54:02 -06:00
|
|
|
|
2017-08-01 13:21:23 -06:00
|
|
|
export function updateStepTitle(props: StepTitleBarProps) {
|
|
|
|
return (e: React.FormEvent<HTMLInputElement>) => {
|
2017-08-28 05:49:13 -06:00
|
|
|
const { dispatch, step, index, sequence } = props;
|
|
|
|
const stepCopy = defensiveClone(step);
|
|
|
|
const seqCopy = defensiveClone(sequence).body;
|
|
|
|
const val = e.currentTarget.value;
|
2017-08-01 13:21:23 -06:00
|
|
|
seqCopy.body = seqCopy.body || [];
|
2017-08-01 14:29:48 -06:00
|
|
|
if (val == "") {
|
|
|
|
delete stepCopy.comment;
|
|
|
|
} else {
|
|
|
|
stepCopy.comment = val;
|
|
|
|
}
|
2017-08-01 13:21:23 -06:00
|
|
|
seqCopy.body[index] = stepCopy;
|
|
|
|
dispatch(overwrite(sequence, seqCopy));
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-06-29 12:54:02 -06:00
|
|
|
function numericNonsense(val: string, copy: CeleryNode, field: LegalArgString) {
|
2018-07-13 14:56:01 -06:00
|
|
|
const parsedNumber = FLOAT_NUMERIC_FIELDS.includes(field)
|
|
|
|
? parseFloat(val)
|
|
|
|
: parseInt(val, 10);
|
2019-02-04 07:32:26 -07:00
|
|
|
return assign(copy.args, { [field]: parsedNumber });
|
2017-06-29 12:54:02 -06:00
|
|
|
}
|
|
|
|
|
2019-02-26 20:12:02 -07:00
|
|
|
// tslint:disable-next-line:cyclomatic-complexity
|
2018-02-27 09:02:35 -07:00
|
|
|
export function renderCeleryNode(props: StepParams) {
|
2017-06-29 12:54:02 -06:00
|
|
|
switch (props.currentStep.kind) {
|
|
|
|
case "_if": return <TileIf {...props} />;
|
|
|
|
case "execute_script": return <TileExecuteScript {...props} />;
|
2018-02-16 09:09:23 -07:00
|
|
|
case "execute": return <ExecuteBlock {...props} />;
|
2017-06-29 12:54:02 -06:00
|
|
|
case "find_home": return <TileFindHome {...props} />;
|
2018-02-16 09:09:23 -07:00
|
|
|
case "move_absolute": return <TileMoveAbsolute {...props} />;
|
|
|
|
case "move_relative": return <TileMoveRelative {...props} />;
|
|
|
|
case "read_pin": return <TileReadPin {...props} />;
|
|
|
|
case "send_message": return <TileSendMessage {...props} />;
|
|
|
|
case "take_photo": return <TileTakePhoto {...props} />;
|
|
|
|
case "wait": return <TileWait {...props} />;
|
|
|
|
case "write_pin": return <TileWritePin {...props} />;
|
2018-09-06 13:43:43 -06:00
|
|
|
case "resource_update": return <MarkAs {...props} />;
|
2019-02-26 20:12:02 -07:00
|
|
|
case "set_servo_angle": return <TileSetServoAngle {...props} />;
|
|
|
|
case "toggle_pin": return <TileTogglePin {...props} />;
|
|
|
|
case "zero": return <TileSetZero {...props} />;
|
|
|
|
case "calibrate": return <TileCalibrate {...props} />;
|
|
|
|
case "home": return <TileMoveHome {...props} />;
|
2019-12-21 21:43:41 -07:00
|
|
|
case "reboot":
|
2019-12-26 09:25:03 -07:00
|
|
|
return <TileReboot {...props} />;
|
2019-12-21 21:43:41 -07:00
|
|
|
case "check_updates":
|
|
|
|
case "factory_reset":
|
2019-02-26 20:12:02 -07:00
|
|
|
return <TileFirmwareAction {...props} />;
|
|
|
|
case "sync": case "dump_info": case "power_off": case "read_status":
|
2019-12-21 21:43:41 -07:00
|
|
|
case "emergency_lock":
|
|
|
|
return <TileEmergencyStop {...props} />;
|
|
|
|
case "emergency_unlock":
|
|
|
|
case "install_first_party_farmware":
|
|
|
|
return <TileSystemAction {...props} />;
|
2019-08-22 09:02:54 -06:00
|
|
|
case "assertion": return <TileAssertion {...props} />;
|
2018-11-12 14:06:52 -07:00
|
|
|
default: return <TileUnknown {...props} />;
|
2017-06-29 12:54:02 -06:00
|
|
|
}
|
2017-07-18 09:34:39 -06:00
|
|
|
}
|
2017-06-29 12:54:02 -06:00
|
|
|
|
2019-09-23 12:56:35 -06:00
|
|
|
const checkBranch =
|
|
|
|
(branch: Execute | Nothing, _step: If, sequence: TaggedSequence) => {
|
|
|
|
return (branch.kind === "execute")
|
|
|
|
&& (branch.args.sequence_id === sequence.body.id);
|
|
|
|
};
|
2017-07-18 09:34:39 -06:00
|
|
|
|
2017-06-29 12:54:02 -06:00
|
|
|
export function isRecursive(step: If, sequence: TaggedSequence) {
|
|
|
|
return checkBranch(step.args._else, step, sequence)
|
|
|
|
|| checkBranch(step.args._then, step, sequence);
|
|
|
|
}
|